Added shop, inventory, fixed plant and mutation definitions, and more..

This commit is contained in:
sarah committed 2026-08-30 20:47:28 +02:00
1 parent cd2759ce4e
commit 97204f2d3f
15 files changed
+2510 -351

No files matched your search

+500 -12
View File
@@ -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;
}