mirror of
https://git.srhtnin.garden/sarah/srhtnin.github.io.git
synced 2026-10-13 18:38:11 +02:00
Added shop, inventory, fixed plant and mutation definitions, and more..
This commit is contained in:
1 parent
cd2759ce4e
commit
97204f2d3f
15 files changed
+2510
-351
No files matched your search
+500
-12
@@ -5,8 +5,45 @@ const ApiUrl = "https://api.srhtnin.garden";
|
||||
|
||||
|
||||
function CreateNewSave() {
|
||||
const StartingSeeds = {};
|
||||
const StartingPlants = [];
|
||||
|
||||
if (
|
||||
typeof Plants !==
|
||||
"undefined"
|
||||
) {
|
||||
for (
|
||||
const Plant
|
||||
of Object.values(Plants)
|
||||
) {
|
||||
if (
|
||||
Plant.Shop
|
||||
?.StartingPlant !==
|
||||
true
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StartingSeeds[
|
||||
String(Plant.Id)
|
||||
] = 1;
|
||||
|
||||
StartingPlants.push(
|
||||
Plant.Id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
StartingPlants.length === 0
|
||||
) {
|
||||
StartingSeeds["1"] = 1;
|
||||
StartingPlants.push(1);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
Version: 1,
|
||||
Version: 2,
|
||||
Revision: 0,
|
||||
LastSavedAt: Date.now(),
|
||||
|
||||
@@ -17,13 +54,17 @@ function CreateNewSave() {
|
||||
Statistics: {
|
||||
CurrencyEarned: {
|
||||
Dew: 0
|
||||
}
|
||||
},
|
||||
|
||||
CurrencySpent: {
|
||||
Dew: 0
|
||||
},
|
||||
|
||||
SeedsPurchased: 0
|
||||
},
|
||||
|
||||
Seeds: {
|
||||
Unlocked: [
|
||||
"Rose"
|
||||
]
|
||||
Inventory: {
|
||||
Seeds: StartingSeeds
|
||||
},
|
||||
|
||||
Upgrades: {
|
||||
@@ -37,10 +78,7 @@ function CreateNewSave() {
|
||||
},
|
||||
|
||||
Discoveries: {
|
||||
Plants: [
|
||||
"Rose"
|
||||
],
|
||||
|
||||
Plants: StartingPlants,
|
||||
Mutations: []
|
||||
},
|
||||
|
||||
@@ -49,6 +87,445 @@ function CreateNewSave() {
|
||||
}
|
||||
|
||||
|
||||
function NormalizeSaveData(
|
||||
SaveData
|
||||
) {
|
||||
SaveData.Version = Math.max(
|
||||
Number(
|
||||
SaveData.Version ?? 1
|
||||
),
|
||||
2
|
||||
);
|
||||
|
||||
SaveData.Revision = Number(
|
||||
SaveData.Revision ?? 0
|
||||
);
|
||||
|
||||
SaveData.LastSavedAt = Number(
|
||||
SaveData.LastSavedAt ??
|
||||
Date.now()
|
||||
);
|
||||
|
||||
|
||||
SaveData.Currency ??= {};
|
||||
SaveData.Currency.Dew = Number(
|
||||
SaveData.Currency.Dew ?? 0
|
||||
);
|
||||
|
||||
|
||||
SaveData.Statistics ??= {};
|
||||
SaveData.Statistics.CurrencyEarned ??= {};
|
||||
SaveData.Statistics.CurrencySpent ??= {};
|
||||
|
||||
SaveData.Statistics.CurrencyEarned.Dew ??=
|
||||
SaveData.Currency.Dew;
|
||||
|
||||
SaveData.Statistics.CurrencySpent.Dew ??= 0;
|
||||
SaveData.Statistics.SeedsPurchased ??= 0;
|
||||
|
||||
|
||||
const HadSeedInventory =
|
||||
SaveData.Inventory
|
||||
?.Seeds !== undefined;
|
||||
|
||||
SaveData.Inventory ??= {};
|
||||
SaveData.Inventory.Seeds ??= {};
|
||||
|
||||
|
||||
/*
|
||||
* Migrate the old infinite seed unlock list
|
||||
* into the new finite seed inventory.
|
||||
*/
|
||||
|
||||
for (
|
||||
const LegacyPlant
|
||||
of SaveData.Seeds
|
||||
?.Unlocked ?? []
|
||||
) {
|
||||
const PlantId =
|
||||
ResolveLegacyPlantId(
|
||||
LegacyPlant
|
||||
);
|
||||
|
||||
if (PlantId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SaveData.Inventory.Seeds[
|
||||
String(PlantId)
|
||||
] ??= 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Existing saves predate inventory, so give them
|
||||
* one seed for each starting plant as a migration
|
||||
* safety net. New saves already contain these.
|
||||
*/
|
||||
|
||||
if (!HadSeedInventory) {
|
||||
for (
|
||||
const Plant
|
||||
of GetStartingPlantDefinitions()
|
||||
) {
|
||||
SaveData.Inventory.Seeds[
|
||||
String(Plant.Id)
|
||||
] ??= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (
|
||||
const InventoryKey
|
||||
of Object.keys(
|
||||
SaveData.Inventory.Seeds
|
||||
)
|
||||
) {
|
||||
const Amount = Math.max(
|
||||
0,
|
||||
Math.floor(
|
||||
Number(
|
||||
SaveData.Inventory.Seeds[
|
||||
InventoryKey
|
||||
] ?? 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
SaveData.Inventory.Seeds[
|
||||
InventoryKey
|
||||
] = Amount;
|
||||
}
|
||||
|
||||
|
||||
delete SaveData.Seeds;
|
||||
|
||||
|
||||
SaveData.Discoveries ??= {};
|
||||
|
||||
SaveData.Discoveries.Plants =
|
||||
NormalizePlantDiscoveries(
|
||||
SaveData.Discoveries.Plants ?? []
|
||||
);
|
||||
|
||||
SaveData.Discoveries.Mutations =
|
||||
NormalizeMutationDiscoveries(
|
||||
SaveData.Discoveries.Mutations ?? []
|
||||
);
|
||||
|
||||
|
||||
for (
|
||||
const Plant
|
||||
of GetStartingPlantDefinitions()
|
||||
) {
|
||||
if (
|
||||
!SaveData.Discoveries.Plants
|
||||
.includes(
|
||||
Plant.Id
|
||||
)
|
||||
) {
|
||||
SaveData.Discoveries.Plants.push(
|
||||
Plant.Id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SaveData.Discoveries.Plants.sort(
|
||||
(A, B) => A - B
|
||||
);
|
||||
|
||||
SaveData.Discoveries.Mutations.sort(
|
||||
(A, B) => A - B
|
||||
);
|
||||
|
||||
|
||||
SaveData.Upgrades ??= {};
|
||||
SaveData.Upgrades.PlotSize ??= 0;
|
||||
|
||||
|
||||
SaveData.Garden ??= {
|
||||
Width: 3,
|
||||
Height: 3,
|
||||
Plots: []
|
||||
};
|
||||
|
||||
SaveData.Garden.Width = Math.max(
|
||||
1,
|
||||
Number(
|
||||
SaveData.Garden.Width ?? 3
|
||||
)
|
||||
);
|
||||
|
||||
SaveData.Garden.Height = Math.max(
|
||||
1,
|
||||
Number(
|
||||
SaveData.Garden.Height ?? 3
|
||||
)
|
||||
);
|
||||
|
||||
SaveData.Garden.Plots ??= [];
|
||||
|
||||
|
||||
for (
|
||||
let PlotIndex = 0;
|
||||
PlotIndex <
|
||||
SaveData.Garden.Plots.length;
|
||||
PlotIndex++
|
||||
) {
|
||||
const Plot =
|
||||
SaveData.Garden.Plots[
|
||||
PlotIndex
|
||||
];
|
||||
|
||||
if (Plot === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
Plot.Plant === "Rose"
|
||||
) {
|
||||
Plot.Plant =
|
||||
"RedRose";
|
||||
}
|
||||
|
||||
if (
|
||||
typeof Plot.Plant ===
|
||||
"number"
|
||||
) {
|
||||
const PlantKey =
|
||||
ResolvePlantKeyById(
|
||||
Plot.Plant
|
||||
);
|
||||
|
||||
if (PlantKey !== null) {
|
||||
Plot.Plant = PlantKey;
|
||||
}
|
||||
}
|
||||
|
||||
Plot.PlantedAt = Number(
|
||||
Plot.PlantedAt ??
|
||||
Date.now()
|
||||
);
|
||||
|
||||
delete Plot.VisualVariant;
|
||||
delete Plot.AddedTags;
|
||||
}
|
||||
|
||||
|
||||
const RequiredPlots =
|
||||
SaveData.Garden.Width *
|
||||
SaveData.Garden.Height;
|
||||
|
||||
while (
|
||||
SaveData.Garden.Plots.length <
|
||||
RequiredPlots
|
||||
) {
|
||||
SaveData.Garden.Plots.push(null);
|
||||
}
|
||||
|
||||
if (
|
||||
SaveData.Garden.Plots.length >
|
||||
RequiredPlots
|
||||
) {
|
||||
SaveData.Garden.Plots.length =
|
||||
RequiredPlots;
|
||||
}
|
||||
|
||||
|
||||
SaveData.MutationCooldowns ??= {};
|
||||
|
||||
|
||||
return SaveData;
|
||||
}
|
||||
|
||||
|
||||
function GetStartingPlantDefinitions() {
|
||||
if (
|
||||
typeof Plants ===
|
||||
"undefined"
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Object.values(Plants)
|
||||
.filter(
|
||||
Plant =>
|
||||
Plant.Shop
|
||||
?.StartingPlant ===
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function ResolveLegacyPlantId(
|
||||
Value
|
||||
) {
|
||||
if (
|
||||
typeof Value ===
|
||||
"number"
|
||||
) {
|
||||
return Value;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof Value !==
|
||||
"string"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const LegacyPlantIds = {
|
||||
Rose: 1,
|
||||
RedRose: 1,
|
||||
DarkRose: 2,
|
||||
BlueRose: 3,
|
||||
PurpleRose: 4
|
||||
};
|
||||
|
||||
if (
|
||||
LegacyPlantIds[Value] !==
|
||||
undefined
|
||||
) {
|
||||
return LegacyPlantIds[Value];
|
||||
}
|
||||
|
||||
if (
|
||||
typeof Plants !==
|
||||
"undefined" &&
|
||||
Plants[Value] !== undefined
|
||||
) {
|
||||
return Plants[Value].Id;
|
||||
}
|
||||
|
||||
const NumericValue =
|
||||
Number(Value);
|
||||
|
||||
if (
|
||||
Number.isInteger(
|
||||
NumericValue
|
||||
) &&
|
||||
NumericValue > 0
|
||||
) {
|
||||
return NumericValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function ResolvePlantKeyById(
|
||||
PlantId
|
||||
) {
|
||||
if (
|
||||
typeof Plants ===
|
||||
"undefined"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (
|
||||
const [PlantKey, Plant]
|
||||
of Object.entries(Plants)
|
||||
) {
|
||||
if (
|
||||
Plant.Id ===
|
||||
Number(PlantId)
|
||||
) {
|
||||
return PlantKey;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function NormalizePlantDiscoveries(
|
||||
Values
|
||||
) {
|
||||
const PlantIds = [];
|
||||
|
||||
for (
|
||||
const Value
|
||||
of Values
|
||||
) {
|
||||
const PlantId =
|
||||
ResolveLegacyPlantId(
|
||||
Value
|
||||
);
|
||||
|
||||
if (
|
||||
PlantId !== null &&
|
||||
!PlantIds.includes(
|
||||
PlantId
|
||||
)
|
||||
) {
|
||||
PlantIds.push(
|
||||
PlantId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return PlantIds;
|
||||
}
|
||||
|
||||
|
||||
function NormalizeMutationDiscoveries(
|
||||
Values
|
||||
) {
|
||||
const MutationIds = [];
|
||||
|
||||
for (
|
||||
const Value
|
||||
of Values
|
||||
) {
|
||||
let MutationId = null;
|
||||
|
||||
if (
|
||||
typeof Value ===
|
||||
"number"
|
||||
) {
|
||||
MutationId = Value;
|
||||
} else if (
|
||||
typeof Value ===
|
||||
"string" &&
|
||||
typeof MutationSets !==
|
||||
"undefined" &&
|
||||
MutationSets[Value] !==
|
||||
undefined
|
||||
) {
|
||||
MutationId =
|
||||
MutationSets[Value].Id;
|
||||
} else {
|
||||
const NumericValue =
|
||||
Number(Value);
|
||||
|
||||
if (
|
||||
Number.isInteger(
|
||||
NumericValue
|
||||
) &&
|
||||
NumericValue > 0
|
||||
) {
|
||||
MutationId =
|
||||
NumericValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
MutationId !== null &&
|
||||
!MutationIds.includes(
|
||||
MutationId
|
||||
)
|
||||
) {
|
||||
MutationIds.push(
|
||||
MutationId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return MutationIds;
|
||||
}
|
||||
|
||||
|
||||
function GetSaveKey() {
|
||||
let SaveKey = localStorage.getItem(
|
||||
SaveKeyName
|
||||
@@ -96,7 +573,9 @@ function ReadLocalSave() {
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(RawSave);
|
||||
return NormalizeSaveData(
|
||||
JSON.parse(RawSave)
|
||||
);
|
||||
} catch (Error) {
|
||||
console.error(
|
||||
"Couldn't read local save:",
|
||||
@@ -185,10 +664,17 @@ async function ReadRemoteSave(
|
||||
return null;
|
||||
}
|
||||
|
||||
return Result.SaveData;
|
||||
return NormalizeSaveData(
|
||||
Result.SaveData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
async function SaveGame(SaveData) {
|
||||
NormalizeSaveData(
|
||||
SaveData
|
||||
);
|
||||
|
||||
SaveData.Revision++;
|
||||
SaveData.LastSavedAt = Date.now();
|
||||
|
||||
@@ -304,5 +790,7 @@ async function LoadGame() {
|
||||
return RemoteSave;
|
||||
}
|
||||
|
||||
WriteLocalSave(LocalSave);
|
||||
|
||||
return LocalSave;
|
||||
}
|
||||
Reference in new issue
Block a user