mirror of
https://git.srhtnin.garden/sarah/srhtnin.github.io.git
synced 2026-10-14 18:58:11 +02:00
BIG UPDATE: Plants and mutations moved to database. Fetchable with API.
This commit is contained in:
1 parent
5e6e376d8e
commit
dde47ff5a6
7 files changed
+272
-228
No files matched your search
Executable → Regular
File mode changed.
+71
-31
@@ -1,54 +1,90 @@
|
|||||||
const MutationTimeFeePerMinute = 15;
|
const MutationTimeFeePerMinute = 3;
|
||||||
|
|
||||||
const PlantKeysById = new Map();
|
const PlantKeysById = new Map();
|
||||||
const PlantsById = new Map();
|
const PlantsById = new Map();
|
||||||
const MutationsById = new Map();
|
const MutationsById = new Map();
|
||||||
|
|
||||||
|
let IndexedPlants = null;
|
||||||
|
let IndexedMutations = null;
|
||||||
|
|
||||||
for (
|
|
||||||
const [PlantKey, Plant]
|
function EnsureEconomyIndexes() {
|
||||||
of Object.entries(Plants)
|
if (
|
||||||
) {
|
IndexedPlants === Plants &&
|
||||||
if (PlantsById.has(Plant.Id)) {
|
IndexedMutations ===
|
||||||
throw new Error(
|
MutationSets
|
||||||
"Duplicate plant ID: " +
|
) {
|
||||||
Plant.Id
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlantKeysById.clear();
|
||||||
|
PlantsById.clear();
|
||||||
|
MutationsById.clear();
|
||||||
|
|
||||||
|
|
||||||
|
for (
|
||||||
|
const [PlantKey, Plant]
|
||||||
|
of Object.entries(Plants)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
PlantsById.has(
|
||||||
|
Plant.Id
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
"Duplicate plant ID: " +
|
||||||
|
Plant.Id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PlantKeysById.set(
|
||||||
|
Plant.Id,
|
||||||
|
PlantKey
|
||||||
|
);
|
||||||
|
|
||||||
|
PlantsById.set(
|
||||||
|
Plant.Id,
|
||||||
|
Plant
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlantKeysById.set(
|
|
||||||
Plant.Id,
|
|
||||||
PlantKey
|
|
||||||
);
|
|
||||||
|
|
||||||
PlantsById.set(
|
for (
|
||||||
Plant.Id,
|
const Mutation
|
||||||
Plant
|
of Object.values(
|
||||||
);
|
MutationSets
|
||||||
}
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
MutationsById.has(
|
||||||
|
Mutation.Id
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
"Duplicate mutation ID: " +
|
||||||
|
Mutation.Id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
MutationsById.set(
|
||||||
for (
|
Mutation.Id,
|
||||||
const Mutation
|
Mutation
|
||||||
of Object.values(MutationSets)
|
|
||||||
) {
|
|
||||||
if (MutationsById.has(Mutation.Id)) {
|
|
||||||
throw new Error(
|
|
||||||
"Duplicate mutation ID: " +
|
|
||||||
Mutation.Id
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MutationsById.set(
|
|
||||||
Mutation.Id,
|
IndexedPlants = Plants;
|
||||||
Mutation
|
IndexedMutations =
|
||||||
);
|
MutationSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function GetPlantKeyById(
|
function GetPlantKeyById(
|
||||||
PlantId
|
PlantId
|
||||||
) {
|
) {
|
||||||
|
EnsureEconomyIndexes();
|
||||||
|
|
||||||
return PlantKeysById.get(
|
return PlantKeysById.get(
|
||||||
Number(PlantId)
|
Number(PlantId)
|
||||||
) ?? null;
|
) ?? null;
|
||||||
@@ -58,6 +94,8 @@ function GetPlantKeyById(
|
|||||||
function GetPlantById(
|
function GetPlantById(
|
||||||
PlantId
|
PlantId
|
||||||
) {
|
) {
|
||||||
|
EnsureEconomyIndexes();
|
||||||
|
|
||||||
return PlantsById.get(
|
return PlantsById.get(
|
||||||
Number(PlantId)
|
Number(PlantId)
|
||||||
) ?? null;
|
) ?? null;
|
||||||
@@ -67,6 +105,8 @@ function GetPlantById(
|
|||||||
function GetMutationById(
|
function GetMutationById(
|
||||||
MutationId
|
MutationId
|
||||||
) {
|
) {
|
||||||
|
EnsureEconomyIndexes();
|
||||||
|
|
||||||
return MutationsById.get(
|
return MutationsById.get(
|
||||||
Number(MutationId)
|
Number(MutationId)
|
||||||
) ?? null;
|
) ?? null;
|
||||||
|
|||||||
@@ -8,6 +8,22 @@ const GardenUpdateInterval = 1000;
|
|||||||
|
|
||||||
|
|
||||||
async function StartGame() {
|
async function StartGame() {
|
||||||
|
try {
|
||||||
|
await LoadGameContent();
|
||||||
|
} catch (Error) {
|
||||||
|
console.error(
|
||||||
|
"Couldn't load Garden content:",
|
||||||
|
Error
|
||||||
|
);
|
||||||
|
|
||||||
|
SetGardenMessage(
|
||||||
|
"Couldn't load plant or mutation data."
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GameSave = await LoadGame();
|
GameSave = await LoadGame();
|
||||||
|
|
||||||
BindGardenTools();
|
BindGardenTools();
|
||||||
|
|||||||
+97
-110
@@ -1,114 +1,101 @@
|
|||||||
const MutationSets = {
|
let MutationSets = {};
|
||||||
RoseDarkening: {
|
|
||||||
Id: 1,
|
|
||||||
Name: "Rose darkening",
|
|
||||||
|
|
||||||
Description:
|
let MutationsLoadPromise = null;
|
||||||
"A mutation that seems to corrupt roses.",
|
let GameContentLoadPromise = null;
|
||||||
|
|
||||||
Priority: 10,
|
|
||||||
Rotation: "Any",
|
|
||||||
|
|
||||||
Chance: 0.1,
|
async function LoadMutations() {
|
||||||
Cooldown: 120000,
|
if (MutationsLoadPromise !== null) {
|
||||||
|
return MutationsLoadPromise;
|
||||||
Relations: {
|
|
||||||
PlantsUsed: [
|
|
||||||
1
|
|
||||||
],
|
|
||||||
|
|
||||||
PlantsCreated: [
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
Pattern: [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
Tags: ["Rose"],
|
|
||||||
Capture: "ParentA"
|
|
||||||
},
|
|
||||||
"Empty"
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
"Empty",
|
|
||||||
{
|
|
||||||
Tags: ["Rose"],
|
|
||||||
Capture: "ParentB"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
Success: [
|
|
||||||
[
|
|
||||||
"Empty",
|
|
||||||
"DarkRose"
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
"DarkRose",
|
|
||||||
"Empty"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
Failure: "Keep"
|
|
||||||
},
|
|
||||||
|
|
||||||
RoseDyePurple: {
|
|
||||||
Id: 2,
|
|
||||||
Name: "Rose dying purple",
|
|
||||||
|
|
||||||
Description:
|
|
||||||
"A colourful mutation that makes a purple rose.",
|
|
||||||
|
|
||||||
Priority: 20,
|
|
||||||
Rotation: "Any",
|
|
||||||
|
|
||||||
Chance: 1.0,
|
|
||||||
Cooldown: 100000,
|
|
||||||
|
|
||||||
Relations: {
|
|
||||||
PlantsUsed: [
|
|
||||||
1,
|
|
||||||
3
|
|
||||||
],
|
|
||||||
|
|
||||||
PlantsCreated: [
|
|
||||||
4
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
Pattern: [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
Tags: [
|
|
||||||
"Rose",
|
|
||||||
"Red"
|
|
||||||
],
|
|
||||||
Capture: "ParentA"
|
|
||||||
},
|
|
||||||
|
|
||||||
"Empty",
|
|
||||||
|
|
||||||
{
|
|
||||||
Tags: [
|
|
||||||
"Rose",
|
|
||||||
"Blue"
|
|
||||||
],
|
|
||||||
Capture: "ParentB"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
Success: [
|
|
||||||
[
|
|
||||||
"Empty",
|
|
||||||
"PurpleRose",
|
|
||||||
"Empty"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
Failure: "Keep"
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
MutationsLoadPromise =
|
||||||
|
LoadMutationsFromApi();
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await MutationsLoadPromise;
|
||||||
|
} catch (Error) {
|
||||||
|
MutationsLoadPromise = null;
|
||||||
|
|
||||||
|
throw Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function LoadMutationsFromApi() {
|
||||||
|
const Response =
|
||||||
|
await fetch(
|
||||||
|
ApiUrl + "/Mutations.php",
|
||||||
|
{
|
||||||
|
method: "GET",
|
||||||
|
|
||||||
|
headers: {
|
||||||
|
"Accept":
|
||||||
|
"application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!Response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
"Mutations API returned HTTP " +
|
||||||
|
Response.status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Result =
|
||||||
|
await Response.json();
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Result.Success ||
|
||||||
|
Result.Mutations === null ||
|
||||||
|
typeof Result.Mutations !==
|
||||||
|
"object" ||
|
||||||
|
Array.isArray(
|
||||||
|
Result.Mutations
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
Result.Error ??
|
||||||
|
"Mutations API returned invalid data."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MutationSets =
|
||||||
|
Result.Mutations;
|
||||||
|
|
||||||
|
|
||||||
|
return MutationSets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function LoadGameContent() {
|
||||||
|
if (GameContentLoadPromise === null) {
|
||||||
|
GameContentLoadPromise =
|
||||||
|
Promise.all([
|
||||||
|
LoadPlants(),
|
||||||
|
LoadMutations()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
await GameContentLoadPromise;
|
||||||
|
} catch (Error) {
|
||||||
|
GameContentLoadPromise = null;
|
||||||
|
|
||||||
|
throw Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
Plants: Plants,
|
||||||
|
Mutations: MutationSets
|
||||||
|
};
|
||||||
|
}
|
||||||
+70
-87
@@ -1,91 +1,74 @@
|
|||||||
const Plants = {
|
let Plants = {};
|
||||||
RedRose: {
|
|
||||||
Id: 1,
|
|
||||||
Name: "Red Rose",
|
|
||||||
|
|
||||||
Description:
|
let PlantsLoadPromise = null;
|
||||||
"A common red rose.",
|
|
||||||
|
|
||||||
Tags: [
|
|
||||||
"Rose",
|
|
||||||
"Flower",
|
|
||||||
"Red"
|
|
||||||
],
|
|
||||||
|
|
||||||
GrowthTime: 3600000,
|
async function LoadPlants() {
|
||||||
|
if (PlantsLoadPromise !== null) {
|
||||||
Effects: [],
|
return PlantsLoadPromise;
|
||||||
|
|
||||||
Shop: {
|
|
||||||
ShopPlant: true,
|
|
||||||
BaseCost: 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
DarkRose: {
|
|
||||||
Id: 2,
|
|
||||||
Name: "Dark Rose",
|
|
||||||
|
|
||||||
Description:
|
|
||||||
"A jet-black rose.",
|
|
||||||
|
|
||||||
Tags: [
|
|
||||||
"Rose",
|
|
||||||
"Flower",
|
|
||||||
"Black"
|
|
||||||
],
|
|
||||||
|
|
||||||
GrowthTime: 4000000,
|
|
||||||
|
|
||||||
Effects: [],
|
|
||||||
|
|
||||||
Shop: {
|
|
||||||
ShopPlant: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
BlueRose: {
|
|
||||||
Id: 3,
|
|
||||||
Name: "Blue Rose",
|
|
||||||
|
|
||||||
Description:
|
|
||||||
"An uncommon blue rose.",
|
|
||||||
|
|
||||||
Tags: [
|
|
||||||
"Rose",
|
|
||||||
"Flower",
|
|
||||||
"Blue"
|
|
||||||
],
|
|
||||||
|
|
||||||
GrowthTime: 3600000,
|
|
||||||
|
|
||||||
Effects: [],
|
|
||||||
|
|
||||||
Shop: {
|
|
||||||
ShopPlant: true,
|
|
||||||
BaseCost: 15
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
PurpleRose: {
|
|
||||||
Id: 4,
|
|
||||||
Name: "Purple Rose",
|
|
||||||
|
|
||||||
Description:
|
|
||||||
"A rare purple rose.",
|
|
||||||
|
|
||||||
Tags: [
|
|
||||||
"Rose",
|
|
||||||
"Flower",
|
|
||||||
"Purple"
|
|
||||||
],
|
|
||||||
|
|
||||||
GrowthTime: 3600000,
|
|
||||||
|
|
||||||
Effects: [],
|
|
||||||
|
|
||||||
Shop: {
|
|
||||||
ShopPlant: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
PlantsLoadPromise =
|
||||||
|
LoadPlantsFromApi();
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await PlantsLoadPromise;
|
||||||
|
} catch (Error) {
|
||||||
|
PlantsLoadPromise = null;
|
||||||
|
|
||||||
|
throw Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function LoadPlantsFromApi() {
|
||||||
|
const Response =
|
||||||
|
await fetch(
|
||||||
|
ApiUrl + "/Plants.php",
|
||||||
|
{
|
||||||
|
method: "GET",
|
||||||
|
|
||||||
|
headers: {
|
||||||
|
"Accept":
|
||||||
|
"application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!Response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
"Plants API returned HTTP " +
|
||||||
|
Response.status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Result =
|
||||||
|
await Response.json();
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Result.Success ||
|
||||||
|
Result.Plants === null ||
|
||||||
|
typeof Result.Plants !==
|
||||||
|
"object" ||
|
||||||
|
Array.isArray(
|
||||||
|
Result.Plants
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
Result.Error ??
|
||||||
|
"Plants API returned invalid data."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Plants =
|
||||||
|
Result.Plants;
|
||||||
|
|
||||||
|
|
||||||
|
return Plants;
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ async function StartProfile() {
|
|||||||
await RenderProfilePlayer();
|
await RenderProfilePlayer();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await LoadGameContent();
|
||||||
|
|
||||||
ProfileSave =
|
ProfileSave =
|
||||||
await LoadGame();
|
await LoadGame();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,22 @@ let ShopPurchasePending = false;
|
|||||||
|
|
||||||
|
|
||||||
async function StartShop() {
|
async function StartShop() {
|
||||||
|
try {
|
||||||
|
await LoadGameContent();
|
||||||
|
} catch (Error) {
|
||||||
|
console.error(
|
||||||
|
"Couldn't load Shop content:",
|
||||||
|
Error
|
||||||
|
);
|
||||||
|
|
||||||
|
SetShopMessage(
|
||||||
|
"Couldn't load plant or mutation data."
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ShopSave = await LoadGame();
|
ShopSave = await LoadGame();
|
||||||
|
|
||||||
RenderShop();
|
RenderShop();
|
||||||
|
|||||||
Reference in new issue
Block a user