mirror of
https://git.srhtnin.garden/sarah/srhtnin.github.io.git
synced 2026-10-13 18:38:11 +02:00
Made new simulation engine (which fixes dumb mutation bug).
This commit is contained in:
1 parent
8ec07731a7
commit
75e4f31ccd
6 files changed
+800
-127
No files matched your search
@@ -294,6 +294,7 @@ $PageSection = "Garden";
|
|||||||
<script src="/Scripts/Garden/Content.js"></script>
|
<script src="/Scripts/Garden/Content.js"></script>
|
||||||
<script src="/Scripts/Garden/Economy.js"></script>
|
<script src="/Scripts/Garden/Economy.js"></script>
|
||||||
<script src="/Scripts/Garden/Upgrades.js"></script>
|
<script src="/Scripts/Garden/Upgrades.js"></script>
|
||||||
|
<script src="/Scripts/Garden/Simulation.js"></script>
|
||||||
<script src="/Scripts/Garden/MutationEngine.js"></script>
|
<script src="/Scripts/Garden/MutationEngine.js"></script>
|
||||||
<script src="/Scripts/Garden/Users.js"></script>
|
<script src="/Scripts/Garden/Users.js"></script>
|
||||||
<script src="/Scripts/Garden/Garden.js"></script>
|
<script src="/Scripts/Garden/Garden.js"></script>
|
||||||
|
|||||||
+108
-81
@@ -65,19 +65,23 @@ async function StartGame() {
|
|||||||
|
|
||||||
GameSave = await LoadGame();
|
GameSave = await LoadGame();
|
||||||
|
|
||||||
|
const InitialSimulationResult =
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
Date.now()
|
||||||
|
);
|
||||||
|
|
||||||
BindGardenTools();
|
BindGardenTools();
|
||||||
BindGardenSelector();
|
BindGardenSelector();
|
||||||
BindQuickBuyControls();
|
BindQuickBuyControls();
|
||||||
EnsureSelectedSeed();
|
EnsureSelectedSeed();
|
||||||
|
|
||||||
const InitialMutationResult =
|
|
||||||
CheckAllGardenMutations(
|
|
||||||
GameSave
|
|
||||||
);
|
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
|
|
||||||
if (InitialMutationResult.Attempted) {
|
if (
|
||||||
|
InitialSimulationResult.Advanced ||
|
||||||
|
InitialSimulationResult.Dirty
|
||||||
|
) {
|
||||||
await SaveGame(
|
await SaveGame(
|
||||||
GameSave
|
GameSave
|
||||||
);
|
);
|
||||||
@@ -184,6 +188,13 @@ function BindGardenSelector() {
|
|||||||
async function SwitchGarden(
|
async function SwitchGarden(
|
||||||
Direction
|
Direction
|
||||||
) {
|
) {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
const GardenCount =
|
const GardenCount =
|
||||||
GameSave.Gardens.length;
|
GameSave.Gardens.length;
|
||||||
|
|
||||||
@@ -219,7 +230,8 @@ async function SwitchGarden(
|
|||||||
|
|
||||||
const MutationResult =
|
const MutationResult =
|
||||||
CheckGardenMutations(
|
CheckGardenMutations(
|
||||||
GameSave
|
GameSave,
|
||||||
|
ActionTime
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
@@ -348,49 +360,15 @@ function RenderGardenSelector() {
|
|||||||
|
|
||||||
|
|
||||||
function CheckAllGardenMutations(
|
function CheckAllGardenMutations(
|
||||||
SaveData
|
SaveData,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const OriginalGardenIndex =
|
return CheckAllGardenMutationsAtTime(
|
||||||
SaveData.ActiveGardenIndex;
|
|
||||||
|
|
||||||
const Result = {
|
|
||||||
Attempted: false,
|
|
||||||
Changed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
for (
|
|
||||||
let GardenIndex = 0;
|
|
||||||
GardenIndex <
|
|
||||||
SaveData.Gardens.length;
|
|
||||||
GardenIndex++
|
|
||||||
) {
|
|
||||||
SetActiveGardenIndex(
|
|
||||||
SaveData,
|
|
||||||
GardenIndex
|
|
||||||
);
|
|
||||||
|
|
||||||
const GardenResult =
|
|
||||||
CheckGardenMutations(
|
|
||||||
SaveData
|
|
||||||
);
|
|
||||||
|
|
||||||
Result.Attempted =
|
|
||||||
Result.Attempted ||
|
|
||||||
GardenResult.Attempted;
|
|
||||||
|
|
||||||
Result.Changed =
|
|
||||||
Result.Changed ||
|
|
||||||
GardenResult.Changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SetActiveGardenIndex(
|
|
||||||
SaveData,
|
SaveData,
|
||||||
OriginalGardenIndex
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1832,7 +1810,9 @@ function CreateGardenPlotTimer(
|
|||||||
0,
|
0,
|
||||||
Plant.GrowthTime -
|
Plant.GrowthTime -
|
||||||
(
|
(
|
||||||
Date.now() -
|
GetSimulationTime(
|
||||||
|
GameSave
|
||||||
|
) -
|
||||||
Plot.PlantedAt
|
Plot.PlantedAt
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -1905,6 +1885,13 @@ function FormatGardenRemainingTime(
|
|||||||
async function PlantSeed(
|
async function PlantSeed(
|
||||||
PlotIndex
|
PlotIndex
|
||||||
) {
|
) {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
GameSave.Garden.Plots[
|
GameSave.Garden.Plots[
|
||||||
PlotIndex
|
PlotIndex
|
||||||
@@ -1959,7 +1946,7 @@ async function PlantSeed(
|
|||||||
PlotIndex
|
PlotIndex
|
||||||
] = {
|
] = {
|
||||||
Plant: PlantKey,
|
Plant: PlantKey,
|
||||||
PlantedAt: Date.now()
|
PlantedAt: ActionTime
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1970,7 +1957,8 @@ async function PlantSeed(
|
|||||||
);
|
);
|
||||||
|
|
||||||
CheckGardenMutations(
|
CheckGardenMutations(
|
||||||
GameSave
|
GameSave,
|
||||||
|
ActionTime
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
@@ -1982,6 +1970,13 @@ async function PlantSeed(
|
|||||||
|
|
||||||
|
|
||||||
async function PlantManySeeds() {
|
async function PlantManySeeds() {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
EnsureSelectedSeed();
|
EnsureSelectedSeed();
|
||||||
|
|
||||||
if (SelectedSeedId === null) {
|
if (SelectedSeedId === null) {
|
||||||
@@ -2066,7 +2061,7 @@ async function PlantManySeeds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const PlantedAt = Date.now();
|
const PlantedAt = ActionTime;
|
||||||
|
|
||||||
for (
|
for (
|
||||||
let Index = 0;
|
let Index = 0;
|
||||||
@@ -2093,7 +2088,8 @@ async function PlantManySeeds() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
CheckGardenMutations(
|
CheckGardenMutations(
|
||||||
GameSave
|
GameSave,
|
||||||
|
ActionTime
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
@@ -2107,6 +2103,13 @@ async function PlantManySeeds() {
|
|||||||
async function HarvestPlant(
|
async function HarvestPlant(
|
||||||
PlotIndex
|
PlotIndex
|
||||||
) {
|
) {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
const Plot =
|
const Plot =
|
||||||
GameSave.Garden.Plots[
|
GameSave.Garden.Plots[
|
||||||
PlotIndex
|
PlotIndex
|
||||||
@@ -2166,7 +2169,8 @@ async function HarvestPlant(
|
|||||||
);
|
);
|
||||||
|
|
||||||
CheckGardenMutations(
|
CheckGardenMutations(
|
||||||
GameSave
|
GameSave,
|
||||||
|
ActionTime
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
@@ -2180,6 +2184,13 @@ async function HarvestPlant(
|
|||||||
async function RemovePlant(
|
async function RemovePlant(
|
||||||
PlotIndex
|
PlotIndex
|
||||||
) {
|
) {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
const Plot =
|
const Plot =
|
||||||
GameSave.Garden.Plots[
|
GameSave.Garden.Plots[
|
||||||
PlotIndex
|
PlotIndex
|
||||||
@@ -2257,7 +2268,8 @@ async function RemovePlant(
|
|||||||
);
|
);
|
||||||
|
|
||||||
CheckGardenMutations(
|
CheckGardenMutations(
|
||||||
GameSave
|
GameSave,
|
||||||
|
ActionTime
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
@@ -2271,6 +2283,13 @@ async function RemovePlant(
|
|||||||
async function FertilizePlant(
|
async function FertilizePlant(
|
||||||
PlotIndex
|
PlotIndex
|
||||||
) {
|
) {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
const Plot =
|
const Plot =
|
||||||
GameSave.Garden.Plots[
|
GameSave.Garden.Plots[
|
||||||
PlotIndex
|
PlotIndex
|
||||||
@@ -2330,7 +2349,8 @@ async function FertilizePlant(
|
|||||||
);
|
);
|
||||||
|
|
||||||
CheckGardenMutations(
|
CheckGardenMutations(
|
||||||
GameSave
|
GameSave,
|
||||||
|
ActionTime
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderGame();
|
RenderGame();
|
||||||
@@ -2342,6 +2362,13 @@ async function FertilizePlant(
|
|||||||
|
|
||||||
|
|
||||||
async function UseFutureSight() {
|
async function UseFutureSight() {
|
||||||
|
const ActionTime = Date.now();
|
||||||
|
|
||||||
|
AdvanceGameSimulation(
|
||||||
|
GameSave,
|
||||||
|
ActionTime
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!IsGardenToolUnlocked(
|
!IsGardenToolUnlocked(
|
||||||
GameSave,
|
GameSave,
|
||||||
@@ -2450,41 +2477,37 @@ function CreateFutureSightPreview() {
|
|||||||
|
|
||||||
|
|
||||||
async function GardenTick() {
|
async function GardenTick() {
|
||||||
RenderGarden();
|
|
||||||
RenderTools();
|
|
||||||
RenderNextHarvest();
|
|
||||||
RenderGardenOverview();
|
|
||||||
RenderGardenEconomy();
|
|
||||||
RenderGardenInfoLayout();
|
|
||||||
|
|
||||||
|
|
||||||
if (
|
|
||||||
SelectedGardenTool ===
|
|
||||||
"FutureSight" &&
|
|
||||||
FutureSightPreview !== null
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (MutationCheckPending) {
|
if (MutationCheckPending) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MutationCheckPending = true;
|
MutationCheckPending = true;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const MutationResult =
|
const SimulationResult =
|
||||||
CheckAllGardenMutations(
|
AdvanceGameSimulation(
|
||||||
GameSave
|
GameSave,
|
||||||
|
Date.now()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
SimulationResult.Attempted &&
|
||||||
|
FutureSightPreview !== null
|
||||||
|
) {
|
||||||
|
FutureSightPreview = null;
|
||||||
|
|
||||||
if (MutationResult.Attempted) {
|
if (
|
||||||
RenderGame();
|
SelectedGardenTool ===
|
||||||
|
"FutureSight"
|
||||||
|
) {
|
||||||
|
SelectedGardenTool =
|
||||||
|
"Trowel";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderGame();
|
||||||
|
|
||||||
|
if (SimulationResult.Dirty) {
|
||||||
await SaveGame(
|
await SaveGame(
|
||||||
GameSave
|
GameSave
|
||||||
);
|
);
|
||||||
@@ -2531,7 +2554,9 @@ function GetPlantGrowthProgress(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Age =
|
const Age =
|
||||||
Date.now() -
|
GetSimulationTime(
|
||||||
|
GameSave
|
||||||
|
) -
|
||||||
Plot.PlantedAt;
|
Plot.PlantedAt;
|
||||||
|
|
||||||
return Math.max(
|
return Math.max(
|
||||||
@@ -2733,7 +2758,9 @@ function RenderNextHarvest() {
|
|||||||
|
|
||||||
const Remaining =
|
const Remaining =
|
||||||
Harvest.Time -
|
Harvest.Time -
|
||||||
Date.now();
|
GetSimulationTime(
|
||||||
|
GameSave
|
||||||
|
);
|
||||||
|
|
||||||
const IncludePlantName =
|
const IncludePlantName =
|
||||||
HasOverview;
|
HasOverview;
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ const MaxMutationPasses = 100;
|
|||||||
|
|
||||||
|
|
||||||
function CheckGardenMutations(
|
function CheckGardenMutations(
|
||||||
SaveData
|
SaveData,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
SaveData.MutationCooldowns ??= {};
|
SaveData.MutationCooldowns ??= {};
|
||||||
|
|
||||||
@@ -23,13 +26,15 @@ function CheckGardenMutations(
|
|||||||
) {
|
) {
|
||||||
const Candidates =
|
const Candidates =
|
||||||
FindGardenMutationCandidates(
|
FindGardenMutationCandidates(
|
||||||
SaveData
|
SaveData,
|
||||||
|
AtTime
|
||||||
)
|
)
|
||||||
.filter(
|
.filter(
|
||||||
Candidate =>
|
Candidate =>
|
||||||
!IsMutationCandidateOnCooldown(
|
!IsMutationCandidateOnCooldown(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.sort(
|
.sort(
|
||||||
@@ -98,7 +103,8 @@ function CheckGardenMutations(
|
|||||||
if (
|
if (
|
||||||
!DoesMutationCandidateStillMatch(
|
!DoesMutationCandidateStillMatch(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
@@ -108,7 +114,8 @@ function CheckGardenMutations(
|
|||||||
if (
|
if (
|
||||||
IsMutationCandidateOnCooldown(
|
IsMutationCandidateOnCooldown(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
@@ -119,7 +126,8 @@ function CheckGardenMutations(
|
|||||||
|
|
||||||
StartMutationCandidateCooldown(
|
StartMutationCandidateCooldown(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -136,7 +144,9 @@ function CheckGardenMutations(
|
|||||||
|
|
||||||
|
|
||||||
const Succeeded =
|
const Succeeded =
|
||||||
Math.random() < Chance;
|
GetSimulationRandom(
|
||||||
|
SaveData
|
||||||
|
) < Chance;
|
||||||
|
|
||||||
|
|
||||||
if (Succeeded) {
|
if (Succeeded) {
|
||||||
@@ -151,7 +161,8 @@ function CheckGardenMutations(
|
|||||||
ApplyMutationResult(
|
ApplyMutationResult(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate,
|
Candidate,
|
||||||
Candidate.Success
|
Candidate.Success,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -176,7 +187,8 @@ function CheckGardenMutations(
|
|||||||
const Changed =
|
const Changed =
|
||||||
ApplyMutationFailure(
|
ApplyMutationFailure(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -226,7 +238,10 @@ function CheckGardenMutations(
|
|||||||
|
|
||||||
|
|
||||||
function FindGardenMutationCandidates(
|
function FindGardenMutationCandidates(
|
||||||
SaveData
|
SaveData,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const Candidates = [];
|
const Candidates = [];
|
||||||
|
|
||||||
@@ -283,7 +298,8 @@ function FindGardenMutationCandidates(
|
|||||||
Mutation,
|
Mutation,
|
||||||
Orientation,
|
Orientation,
|
||||||
OriginX,
|
OriginX,
|
||||||
OriginY
|
OriginY,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -307,7 +323,10 @@ function CreateMutationCandidate(
|
|||||||
Mutation,
|
Mutation,
|
||||||
Orientation,
|
Orientation,
|
||||||
OriginX,
|
OriginX,
|
||||||
OriginY
|
OriginY,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const Captures = {};
|
const Captures = {};
|
||||||
const Cells = [];
|
const Cells = [];
|
||||||
@@ -357,7 +376,8 @@ function CreateMutationCandidate(
|
|||||||
Plot,
|
Plot,
|
||||||
Matcher,
|
Matcher,
|
||||||
Mutation,
|
Mutation,
|
||||||
Captures
|
Captures,
|
||||||
|
AtTime
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
@@ -399,7 +419,10 @@ function CreateMutationCandidate(
|
|||||||
|
|
||||||
function DoesMutationCandidateStillMatch(
|
function DoesMutationCandidateStillMatch(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const RefreshedCandidate =
|
const RefreshedCandidate =
|
||||||
CreateMutationCandidate(
|
CreateMutationCandidate(
|
||||||
@@ -416,7 +439,8 @@ function DoesMutationCandidateStillMatch(
|
|||||||
Candidate.Rotation
|
Candidate.Rotation
|
||||||
},
|
},
|
||||||
Candidate.OriginX,
|
Candidate.OriginX,
|
||||||
Candidate.OriginY
|
Candidate.OriginY,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -437,7 +461,8 @@ function DoesPlotMatchMutationMatcher(
|
|||||||
Plot,
|
Plot,
|
||||||
Matcher,
|
Matcher,
|
||||||
Mutation,
|
Mutation,
|
||||||
Captures
|
Captures,
|
||||||
|
AtTime
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
Matcher === null ||
|
Matcher === null ||
|
||||||
@@ -470,7 +495,8 @@ function DoesPlotMatchMutationMatcher(
|
|||||||
true &&
|
true &&
|
||||||
!IsMutationPlantMature(
|
!IsMutationPlantMature(
|
||||||
Plot,
|
Plot,
|
||||||
Plant
|
Plant,
|
||||||
|
AtTime
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -566,7 +592,8 @@ function DoesPlotMatchMutationMatcher(
|
|||||||
|
|
||||||
function IsMutationPlantMature(
|
function IsMutationPlantMature(
|
||||||
Plot,
|
Plot,
|
||||||
Plant
|
Plant,
|
||||||
|
AtTime
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
Number(
|
Number(
|
||||||
@@ -578,7 +605,7 @@ function IsMutationPlantMature(
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
Date.now() -
|
AtTime -
|
||||||
Number(
|
Number(
|
||||||
Plot.PlantedAt ?? 0
|
Plot.PlantedAt ?? 0
|
||||||
) >=
|
) >=
|
||||||
@@ -589,7 +616,10 @@ function IsMutationPlantMature(
|
|||||||
|
|
||||||
function ApplyMutationFailure(
|
function ApplyMutationFailure(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const Failure =
|
const Failure =
|
||||||
Candidate.Mutation.Failure ??
|
Candidate.Mutation.Failure ??
|
||||||
@@ -631,7 +661,8 @@ function ApplyMutationFailure(
|
|||||||
return ApplyMutationResult(
|
return ApplyMutationResult(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate,
|
Candidate,
|
||||||
Failure
|
Failure,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,7 +674,10 @@ function ApplyMutationFailure(
|
|||||||
function ApplyMutationResult(
|
function ApplyMutationResult(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate,
|
Candidate,
|
||||||
ResultMatrix
|
ResultMatrix,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
if (!Array.isArray(ResultMatrix)) {
|
if (!Array.isArray(ResultMatrix)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -706,7 +740,8 @@ function ApplyMutationResult(
|
|||||||
const NewPlot =
|
const NewPlot =
|
||||||
CreateMutationResultPlot(
|
CreateMutationResultPlot(
|
||||||
ResultValue,
|
ResultValue,
|
||||||
Candidate.Captures
|
Candidate.Captures,
|
||||||
|
AtTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -749,7 +784,8 @@ function ApplyMutationResult(
|
|||||||
|
|
||||||
function CreateMutationResultPlot(
|
function CreateMutationResultPlot(
|
||||||
ResultValue,
|
ResultValue,
|
||||||
Captures
|
Captures,
|
||||||
|
AtTime
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
typeof ResultValue ===
|
typeof ResultValue ===
|
||||||
@@ -785,7 +821,7 @@ function CreateMutationResultPlot(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Plant: ResultValue,
|
Plant: ResultValue,
|
||||||
PlantedAt: Date.now()
|
PlantedAt: AtTime
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -841,7 +877,7 @@ function CreateMutationResultPlot(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Plant: ResultValue.Plant,
|
Plant: ResultValue.Plant,
|
||||||
PlantedAt: Date.now()
|
PlantedAt: AtTime
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,42 +1042,56 @@ function GetMutationPatternSpecificity(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function IsMutationCandidateOnCooldown(
|
function GetMutationCandidateCooldownUntil(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate
|
||||||
) {
|
) {
|
||||||
const CooldownUntil =
|
return Number(
|
||||||
Number(
|
SaveData.MutationCooldowns[
|
||||||
SaveData.MutationCooldowns[
|
GetMutationCooldownKey(
|
||||||
GetMutationCooldownKey(
|
Candidate
|
||||||
Candidate
|
)
|
||||||
)
|
] ?? 0
|
||||||
] ?? 0
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
|
|
||||||
return CooldownUntil > Date.now();
|
function IsMutationCandidateOnCooldown(
|
||||||
|
SaveData,
|
||||||
|
Candidate,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
GetMutationCandidateCooldownUntil(
|
||||||
|
SaveData,
|
||||||
|
Candidate
|
||||||
|
) > AtTime
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function StartMutationCandidateCooldown(
|
function StartMutationCandidateCooldown(
|
||||||
SaveData,
|
SaveData,
|
||||||
Candidate
|
Candidate,
|
||||||
|
AtTime = GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const Cooldown = Math.max(
|
const Cooldown = Math.max(
|
||||||
0,
|
SimulationMinimumEventInterval,
|
||||||
Number(
|
Number(
|
||||||
Candidate.Mutation.Cooldown ??
|
Candidate.Mutation.Cooldown ??
|
||||||
0
|
0
|
||||||
)
|
) || 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
SaveData.MutationCooldowns[
|
SaveData.MutationCooldowns[
|
||||||
GetMutationCooldownKey(
|
GetMutationCooldownKey(
|
||||||
Candidate
|
Candidate
|
||||||
)
|
)
|
||||||
] = Date.now() + Cooldown;
|
] = AtTime + Cooldown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+144
-2
@@ -15,6 +15,138 @@ const MaximumGardenNameLength = 32;
|
|||||||
const StartingGardenWidth = 4;
|
const StartingGardenWidth = 4;
|
||||||
const StartingGardenHeight = 4;
|
const StartingGardenHeight = 4;
|
||||||
|
|
||||||
|
const CurrentSaveVersion = 6;
|
||||||
|
|
||||||
|
|
||||||
|
function CreateSimulationRandomState() {
|
||||||
|
if (
|
||||||
|
typeof crypto !== "undefined" &&
|
||||||
|
typeof crypto.getRandomValues ===
|
||||||
|
"function"
|
||||||
|
) {
|
||||||
|
const Values =
|
||||||
|
new Uint32Array(1);
|
||||||
|
|
||||||
|
crypto.getRandomValues(
|
||||||
|
Values
|
||||||
|
);
|
||||||
|
|
||||||
|
return Values[0] >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
Date.now() ^
|
||||||
|
Math.floor(
|
||||||
|
Math.random() *
|
||||||
|
0xFFFFFFFF
|
||||||
|
)
|
||||||
|
) >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetLegacySimulationRandomState(
|
||||||
|
SaveData
|
||||||
|
) {
|
||||||
|
const Source =
|
||||||
|
String(
|
||||||
|
SaveData.LastSavedAt ?? 0
|
||||||
|
) +
|
||||||
|
":" +
|
||||||
|
String(
|
||||||
|
SaveData.Revision ?? 0
|
||||||
|
) +
|
||||||
|
":" +
|
||||||
|
String(
|
||||||
|
SaveData.Version ?? 0
|
||||||
|
);
|
||||||
|
|
||||||
|
let Hash = 2166136261;
|
||||||
|
|
||||||
|
for (
|
||||||
|
let Index = 0;
|
||||||
|
Index < Source.length;
|
||||||
|
Index++
|
||||||
|
) {
|
||||||
|
Hash ^= Source.charCodeAt(
|
||||||
|
Index
|
||||||
|
);
|
||||||
|
|
||||||
|
Hash = Math.imul(
|
||||||
|
Hash,
|
||||||
|
16777619
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Hash >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetSavedSimulationTime(
|
||||||
|
SaveData
|
||||||
|
) {
|
||||||
|
const Time = Number(
|
||||||
|
SaveData?.Simulation
|
||||||
|
?.LastProcessedAt
|
||||||
|
);
|
||||||
|
|
||||||
|
return Number.isFinite(Time)
|
||||||
|
? Time
|
||||||
|
: Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function NormalizeSimulationData(
|
||||||
|
SaveData
|
||||||
|
) {
|
||||||
|
const Now = Date.now();
|
||||||
|
|
||||||
|
if (
|
||||||
|
SaveData.Simulation === null ||
|
||||||
|
typeof SaveData.Simulation !==
|
||||||
|
"object" ||
|
||||||
|
Array.isArray(
|
||||||
|
SaveData.Simulation
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
SaveData.Simulation = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const LastProcessedAt = Number(
|
||||||
|
SaveData.Simulation
|
||||||
|
.LastProcessedAt ??
|
||||||
|
SaveData.LastSavedAt ??
|
||||||
|
Now
|
||||||
|
);
|
||||||
|
|
||||||
|
SaveData.Simulation.LastProcessedAt =
|
||||||
|
Math.min(
|
||||||
|
Now,
|
||||||
|
Math.max(
|
||||||
|
0,
|
||||||
|
Math.floor(
|
||||||
|
Number.isFinite(
|
||||||
|
LastProcessedAt
|
||||||
|
)
|
||||||
|
? LastProcessedAt
|
||||||
|
: Now
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const RandomState = Number(
|
||||||
|
SaveData.Simulation.RandomState
|
||||||
|
);
|
||||||
|
|
||||||
|
SaveData.Simulation.RandomState =
|
||||||
|
Number.isInteger(RandomState) &&
|
||||||
|
RandomState >= 0 &&
|
||||||
|
RandomState <= 0xFFFFFFFF
|
||||||
|
? RandomState >>> 0
|
||||||
|
: GetLegacySimulationRandomState(
|
||||||
|
SaveData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function CreateGardenData(
|
function CreateGardenData(
|
||||||
Name = DefaultGardenName
|
Name = DefaultGardenName
|
||||||
@@ -392,10 +524,16 @@ function CreateNewSave() {
|
|||||||
|
|
||||||
|
|
||||||
return NormalizeSaveData({
|
return NormalizeSaveData({
|
||||||
Version: 5,
|
Version: CurrentSaveVersion,
|
||||||
Revision: 0,
|
Revision: 0,
|
||||||
LastSavedAt: Date.now(),
|
LastSavedAt: Date.now(),
|
||||||
|
|
||||||
|
Simulation: {
|
||||||
|
LastProcessedAt: Date.now(),
|
||||||
|
RandomState:
|
||||||
|
CreateSimulationRandomState()
|
||||||
|
},
|
||||||
|
|
||||||
Currency: {
|
Currency: {
|
||||||
Dew: StartingDew
|
Dew: StartingDew
|
||||||
},
|
},
|
||||||
@@ -470,7 +608,7 @@ function NormalizeSaveData(
|
|||||||
Number(
|
Number(
|
||||||
SaveData.Version ?? 1
|
SaveData.Version ?? 1
|
||||||
),
|
),
|
||||||
5
|
CurrentSaveVersion
|
||||||
);
|
);
|
||||||
|
|
||||||
SaveData.Revision = Number(
|
SaveData.Revision = Number(
|
||||||
@@ -482,6 +620,10 @@ function NormalizeSaveData(
|
|||||||
Date.now()
|
Date.now()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NormalizeSimulationData(
|
||||||
|
SaveData
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
SaveData.Currency ??= {};
|
SaveData.Currency ??= {};
|
||||||
SaveData.Currency.Dew = Number(
|
SaveData.Currency.Dew = Number(
|
||||||
|
|||||||
@@ -0,0 +1,447 @@
|
|||||||
|
const SimulationMinimumEventInterval = 1000;
|
||||||
|
const MaximumSimulationSteps = 250000;
|
||||||
|
|
||||||
|
|
||||||
|
function GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
) {
|
||||||
|
return GetSavedSimulationTime(
|
||||||
|
SaveData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function SetSimulationTime(
|
||||||
|
SaveData,
|
||||||
|
Time
|
||||||
|
) {
|
||||||
|
SaveData.Simulation ??= {};
|
||||||
|
|
||||||
|
SaveData.Simulation.LastProcessedAt =
|
||||||
|
Math.max(
|
||||||
|
0,
|
||||||
|
Math.floor(
|
||||||
|
Number(Time) || 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return SaveData.Simulation.LastProcessedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetSimulationRandom(
|
||||||
|
SaveData
|
||||||
|
) {
|
||||||
|
SaveData.Simulation ??= {};
|
||||||
|
|
||||||
|
let State = Number(
|
||||||
|
SaveData.Simulation.RandomState ?? 0
|
||||||
|
) >>> 0;
|
||||||
|
|
||||||
|
State = (
|
||||||
|
State + 0x6D2B79F5
|
||||||
|
) >>> 0;
|
||||||
|
|
||||||
|
SaveData.Simulation.RandomState =
|
||||||
|
State;
|
||||||
|
|
||||||
|
let Value = State;
|
||||||
|
|
||||||
|
Value = Math.imul(
|
||||||
|
Value ^ Value >>> 15,
|
||||||
|
Value | 1
|
||||||
|
);
|
||||||
|
|
||||||
|
Value ^=
|
||||||
|
Value +
|
||||||
|
Math.imul(
|
||||||
|
Value ^ Value >>> 7,
|
||||||
|
Value | 61
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
(Value ^ Value >>> 14) >>> 0
|
||||||
|
) / 4294967296;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function MergeSimulationMutationResult(
|
||||||
|
Target,
|
||||||
|
Source
|
||||||
|
) {
|
||||||
|
Target.Attempted =
|
||||||
|
Target.Attempted ||
|
||||||
|
Source.Attempted;
|
||||||
|
|
||||||
|
Target.Changed =
|
||||||
|
Target.Changed ||
|
||||||
|
Source.Changed;
|
||||||
|
|
||||||
|
Target.SuccessfulMutations.push(
|
||||||
|
...(Source.SuccessfulMutations ?? [])
|
||||||
|
);
|
||||||
|
|
||||||
|
Target.NewlyDiscoveredMutations.push(
|
||||||
|
...(Source.NewlyDiscoveredMutations ?? [])
|
||||||
|
);
|
||||||
|
|
||||||
|
Target.NewlyDiscoveredPlants.push(
|
||||||
|
...(Source.NewlyDiscoveredPlants ?? [])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CreateSimulationResult(
|
||||||
|
StartTime,
|
||||||
|
TargetTime
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
StartTime,
|
||||||
|
TargetTime,
|
||||||
|
Advanced: TargetTime > StartTime,
|
||||||
|
Attempted: false,
|
||||||
|
Changed: false,
|
||||||
|
Dirty: false,
|
||||||
|
CaughtUp: StartTime >= TargetTime,
|
||||||
|
EndTime: StartTime,
|
||||||
|
Steps: 0,
|
||||||
|
SuccessfulMutations: [],
|
||||||
|
NewlyDiscoveredMutations: [],
|
||||||
|
NewlyDiscoveredPlants: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function FinalizeSimulationResult(
|
||||||
|
Result
|
||||||
|
) {
|
||||||
|
Result.SuccessfulMutations = [
|
||||||
|
...new Set(
|
||||||
|
Result.SuccessfulMutations
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
Result.NewlyDiscoveredMutations = [
|
||||||
|
...new Set(
|
||||||
|
Result.NewlyDiscoveredMutations
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
Result.NewlyDiscoveredPlants = [
|
||||||
|
...new Set(
|
||||||
|
Result.NewlyDiscoveredPlants
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
Result.Dirty =
|
||||||
|
Result.Attempted ||
|
||||||
|
Result.Changed;
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CheckAllGardenMutationsAtTime(
|
||||||
|
SaveData,
|
||||||
|
AtTime
|
||||||
|
) {
|
||||||
|
const OriginalGardenIndex =
|
||||||
|
SaveData.ActiveGardenIndex;
|
||||||
|
|
||||||
|
const Result = {
|
||||||
|
Attempted: false,
|
||||||
|
Changed: false,
|
||||||
|
SuccessfulMutations: [],
|
||||||
|
NewlyDiscoveredMutations: [],
|
||||||
|
NewlyDiscoveredPlants: []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (
|
||||||
|
let GardenIndex = 0;
|
||||||
|
GardenIndex < SaveData.Gardens.length;
|
||||||
|
GardenIndex++
|
||||||
|
) {
|
||||||
|
SetActiveGardenIndex(
|
||||||
|
SaveData,
|
||||||
|
GardenIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
const GardenResult =
|
||||||
|
CheckGardenMutations(
|
||||||
|
SaveData,
|
||||||
|
AtTime
|
||||||
|
);
|
||||||
|
|
||||||
|
MergeSimulationMutationResult(
|
||||||
|
Result,
|
||||||
|
GardenResult
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetActiveGardenIndex(
|
||||||
|
SaveData,
|
||||||
|
OriginalGardenIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetNextPlantMaturityTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime,
|
||||||
|
TargetTime
|
||||||
|
) {
|
||||||
|
let NextTime = null;
|
||||||
|
|
||||||
|
for (const Garden of SaveData.Gardens) {
|
||||||
|
for (const Plot of Garden.Plots) {
|
||||||
|
if (Plot === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Plant =
|
||||||
|
Plants[Plot.Plant];
|
||||||
|
|
||||||
|
if (Plant === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GrowthTime = Math.max(
|
||||||
|
0,
|
||||||
|
Number(
|
||||||
|
Plant.GrowthTime ?? 0
|
||||||
|
) || 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (GrowthTime <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MaturityTime =
|
||||||
|
Number(
|
||||||
|
Plot.PlantedAt ?? 0
|
||||||
|
) +
|
||||||
|
GrowthTime;
|
||||||
|
|
||||||
|
if (
|
||||||
|
MaturityTime <= CurrentTime ||
|
||||||
|
MaturityTime > TargetTime
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
NextTime === null ||
|
||||||
|
MaturityTime < NextTime
|
||||||
|
) {
|
||||||
|
NextTime = MaturityTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetNextMutationAttemptTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime,
|
||||||
|
TargetTime
|
||||||
|
) {
|
||||||
|
const OriginalGardenIndex =
|
||||||
|
SaveData.ActiveGardenIndex;
|
||||||
|
|
||||||
|
let NextTime = null;
|
||||||
|
|
||||||
|
for (
|
||||||
|
let GardenIndex = 0;
|
||||||
|
GardenIndex < SaveData.Gardens.length;
|
||||||
|
GardenIndex++
|
||||||
|
) {
|
||||||
|
SetActiveGardenIndex(
|
||||||
|
SaveData,
|
||||||
|
GardenIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
const Candidates =
|
||||||
|
FindGardenMutationCandidates(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const Candidate of Candidates) {
|
||||||
|
const CooldownUntil =
|
||||||
|
GetMutationCandidateCooldownUntil(
|
||||||
|
SaveData,
|
||||||
|
Candidate
|
||||||
|
);
|
||||||
|
|
||||||
|
const AttemptTime =
|
||||||
|
CooldownUntil > CurrentTime
|
||||||
|
? CooldownUntil
|
||||||
|
: CurrentTime +
|
||||||
|
SimulationMinimumEventInterval;
|
||||||
|
|
||||||
|
if (AttemptTime > TargetTime) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
NextTime === null ||
|
||||||
|
AttemptTime < NextTime
|
||||||
|
) {
|
||||||
|
NextTime = AttemptTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetActiveGardenIndex(
|
||||||
|
SaveData,
|
||||||
|
OriginalGardenIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetNextSimulationEventTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime,
|
||||||
|
TargetTime
|
||||||
|
) {
|
||||||
|
const MaturityTime =
|
||||||
|
GetNextPlantMaturityTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime,
|
||||||
|
TargetTime
|
||||||
|
);
|
||||||
|
|
||||||
|
const MutationTime =
|
||||||
|
GetNextMutationAttemptTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime,
|
||||||
|
TargetTime
|
||||||
|
);
|
||||||
|
|
||||||
|
if (MaturityTime === null) {
|
||||||
|
return MutationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MutationTime === null) {
|
||||||
|
return MaturityTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.min(
|
||||||
|
MaturityTime,
|
||||||
|
MutationTime
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function AdvanceGameSimulation(
|
||||||
|
SaveData,
|
||||||
|
TargetTime = Date.now()
|
||||||
|
) {
|
||||||
|
const SafeTargetTime = Math.max(
|
||||||
|
0,
|
||||||
|
Math.floor(
|
||||||
|
Number(TargetTime) ||
|
||||||
|
Date.now()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let CurrentTime = Math.min(
|
||||||
|
GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
),
|
||||||
|
SafeTargetTime
|
||||||
|
);
|
||||||
|
|
||||||
|
const Result =
|
||||||
|
CreateSimulationResult(
|
||||||
|
CurrentTime,
|
||||||
|
SafeTargetTime
|
||||||
|
);
|
||||||
|
|
||||||
|
SetSimulationTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime
|
||||||
|
);
|
||||||
|
|
||||||
|
for (
|
||||||
|
let Step = 0;
|
||||||
|
Step < MaximumSimulationSteps;
|
||||||
|
Step++
|
||||||
|
) {
|
||||||
|
Result.Steps = Step + 1;
|
||||||
|
|
||||||
|
const MutationResult =
|
||||||
|
CheckAllGardenMutationsAtTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime
|
||||||
|
);
|
||||||
|
|
||||||
|
MergeSimulationMutationResult(
|
||||||
|
Result,
|
||||||
|
MutationResult
|
||||||
|
);
|
||||||
|
|
||||||
|
if (CurrentTime >= SafeTargetTime) {
|
||||||
|
Result.CaughtUp = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NextTime =
|
||||||
|
GetNextSimulationEventTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime,
|
||||||
|
SafeTargetTime
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NextTime === null) {
|
||||||
|
CurrentTime = SafeTargetTime;
|
||||||
|
SetSimulationTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime
|
||||||
|
);
|
||||||
|
Result.CaughtUp = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentTime = Math.min(
|
||||||
|
SafeTargetTime,
|
||||||
|
Math.max(
|
||||||
|
CurrentTime + 1,
|
||||||
|
NextTime
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
SetSimulationTime(
|
||||||
|
SaveData,
|
||||||
|
CurrentTime
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.EndTime =
|
||||||
|
GetSimulationTime(
|
||||||
|
SaveData
|
||||||
|
);
|
||||||
|
|
||||||
|
const FinalResult =
|
||||||
|
FinalizeSimulationResult(
|
||||||
|
Result
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
FinalResult.Dirty &&
|
||||||
|
typeof WriteLocalSave ===
|
||||||
|
"function"
|
||||||
|
) {
|
||||||
|
WriteLocalSave(
|
||||||
|
SaveData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FinalResult;
|
||||||
|
}
|
||||||
@@ -692,7 +692,9 @@ function TakeFertilizerUse(
|
|||||||
|
|
||||||
function GetFutureSightCooldownRemaining(
|
function GetFutureSightCooldownRemaining(
|
||||||
SaveData,
|
SaveData,
|
||||||
Now = Date.now()
|
Now = GetSavedSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return Math.max(
|
return Math.max(
|
||||||
0,
|
0,
|
||||||
@@ -705,7 +707,9 @@ function GetFutureSightCooldownRemaining(
|
|||||||
|
|
||||||
function IsFutureSightReady(
|
function IsFutureSightReady(
|
||||||
SaveData,
|
SaveData,
|
||||||
Now = Date.now()
|
Now = GetSavedSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return GetFutureSightCooldownRemaining(
|
return GetFutureSightCooldownRemaining(
|
||||||
SaveData,
|
SaveData,
|
||||||
@@ -716,7 +720,9 @@ function IsFutureSightReady(
|
|||||||
|
|
||||||
function StartFutureSightCooldown(
|
function StartFutureSightCooldown(
|
||||||
SaveData,
|
SaveData,
|
||||||
Now = Date.now()
|
Now = GetSavedSimulationTime(
|
||||||
|
SaveData
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
SaveData.Tools ??= {};
|
SaveData.Tools ??= {};
|
||||||
SaveData.Tools.FutureSightCooldownUntil =
|
SaveData.Tools.FutureSightCooldownUntil =
|
||||||
|
|||||||
Reference in new issue
Block a user