Added better info display upgrade.

This commit is contained in:
sarah committed 2026-09-02 23:09:31 +02:00
1 parent 11be2c8a52
commit 64807f3c7a
9 files changed
+855 -96

No files matched your search

+236 -25
View File
@@ -59,6 +59,7 @@ function RenderGame() {
RenderTools();
RenderGarden();
RenderNextHarvest();
RenderGardenOverview();
}
@@ -940,6 +941,7 @@ async function RemovePlant(
async function GardenTick() {
RenderGarden();
RenderNextHarvest();
RenderGardenOverview();
if (MutationCheckPending) {
@@ -1113,8 +1115,8 @@ function SetGardenMessage(
}
function GetNextHarvestTime() {
let NextHarvestTime = null;
function GetNextHarvestInfo() {
let NextHarvest = null;
for (
@@ -1138,46 +1140,63 @@ function GetNextHarvestTime() {
Plot.PlantedAt +
Plant.GrowthTime;
if (
HarvestTime <=
Date.now()
) {
return Date.now();
}
if (
NextHarvestTime === null ||
NextHarvest === null ||
HarvestTime <
NextHarvestTime
NextHarvest.Time
) {
NextHarvestTime =
HarvestTime;
NextHarvest = {
Time: HarvestTime,
Plant
};
}
}
return NextHarvestTime;
return NextHarvest;
}
function RenderNextHarvest() {
const Line =
document.getElementById(
"NextHarvestLine"
);
const Element =
document.getElementById(
"NextHarvest"
);
if (Element === null) {
if (
Line === null ||
Element === null
) {
return;
}
const HarvestTime =
GetNextHarvestTime();
const HasOverview =
HasGardenOverviewUpgrade(
GameSave
);
const ShowNextHarvest =
!HasOverview ||
GameSave.Preferences
.ShowNextHarvest !== false;
Line.hidden = !ShowNextHarvest;
if (!ShowNextHarvest) {
return;
}
if (HarvestTime === null) {
const Harvest =
GetNextHarvestInfo();
if (Harvest === null) {
Element.textContent =
"Nothing planted";
@@ -1190,13 +1209,19 @@ function RenderNextHarvest() {
const Remaining =
HarvestTime -
Harvest.Time -
Date.now();
const IncludePlantName =
HasOverview;
if (Remaining <= 0) {
Element.textContent =
"Ready now!";
IncludePlantName
? Harvest.Plant.Name +
" is ready!"
: "Ready now!";
Element.removeAttribute(
"title"
@@ -1206,18 +1231,24 @@ function RenderNextHarvest() {
}
Element.textContent =
const RemainingText =
FormatRemainingTime(
Remaining
);
Element.textContent =
IncludePlantName
? Harvest.Plant.Name +
" in " +
RemainingText
: RemainingText;
const HarvestDate =
new Date(
HarvestTime
Harvest.Time
);
Element.title =
"Ready at " +
HarvestDate.toLocaleTimeString(
@@ -1230,6 +1261,186 @@ function RenderNextHarvest() {
}
function RenderGardenOverview() {
const Overview =
document.getElementById(
"GardenOverviewDetails"
);
if (Overview === null) {
return;
}
if (
!HasGardenOverviewUpgrade(
GameSave
)
) {
Overview.hidden = true;
return;
}
const TotalPlots =
GameSave.Garden.Width *
GameSave.Garden.Height;
let PlantedPlots = 0;
let GrowingPlots = 0;
let ReadyPlots = 0;
for (
const Plot
of GameSave.Garden.Plots
) {
if (Plot === null) {
continue;
}
PlantedPlots++;
const Plant =
Plants[Plot.Plant];
if (Plant === undefined) {
continue;
}
if (
IsPlantMature(
Plot,
Plant
)
) {
ReadyPlots++;
} else {
GrowingPlots++;
}
}
const EmptyPlots =
Math.max(
0,
TotalPlots -
PlantedPlots
);
const Lines = [
{
LineId:
"GardenSizeOverviewLine",
ValueId:
"GardenSizeOverview",
Preference:
"ShowGardenSize",
Value:
GameSave.Garden.Width +
"×" +
GameSave.Garden.Height +
" (" +
TotalPlots.toLocaleString() +
")"
},
{
LineId:
"EmptyPlotsOverviewLine",
ValueId:
"EmptyPlotsOverview",
Preference:
"ShowEmptyPlots",
Value:
EmptyPlots.toLocaleString() +
"/" +
TotalPlots.toLocaleString()
},
{
LineId:
"PlantedPlotsOverviewLine",
ValueId:
"PlantedPlotsOverview",
Preference:
"ShowPlantedPlots",
Value:
PlantedPlots.toLocaleString() +
"/" +
TotalPlots.toLocaleString()
},
{
LineId:
"GrowingPlotsOverviewLine",
ValueId:
"GrowingPlotsOverview",
Preference:
"ShowGrowingPlots",
Value:
GrowingPlots.toLocaleString() +
"/" +
TotalPlots.toLocaleString()
},
{
LineId:
"ReadyPlotsOverviewLine",
ValueId:
"ReadyPlotsOverview",
Preference:
"ShowReadyPlots",
Value:
ReadyPlots.toLocaleString() +
"/" +
TotalPlots.toLocaleString()
}
];
let VisibleLines = 0;
for (
const Line
of Lines
) {
const LineElement =
document.getElementById(
Line.LineId
);
const ValueElement =
document.getElementById(
Line.ValueId
);
if (
LineElement === null ||
ValueElement === null
) {
continue;
}
const IsVisible =
GameSave.Preferences[
Line.Preference
] !== false;
LineElement.hidden =
!IsVisible;
ValueElement.textContent =
Line.Value;
if (IsVisible) {
VisibleLines++;
}
}
Overview.hidden =
VisibleLines === 0;
}
function FormatRemainingTime(
Milliseconds
) {
+226 -61
View File
@@ -75,45 +75,77 @@ async function StartProfile() {
function BindGardenDisplayPreferences() {
const PlantNamesButton =
document.getElementById(
"TogglePlantNamesButton"
);
const PreferenceButtons = [
[
"TogglePlantNamesButton",
"ShowPlantNames"
],
[
"ToggleGrowthTimersButton",
"ShowGrowthTimers"
],
[
"ToggleNextHarvestButton",
"ShowNextHarvest"
],
[
"ToggleGardenSizeButton",
"ShowGardenSize"
],
[
"ToggleEmptyPlotsButton",
"ShowEmptyPlots"
],
[
"TogglePlantedPlotsButton",
"ShowPlantedPlots"
],
[
"ToggleGrowingPlotsButton",
"ShowGrowingPlots"
],
[
"ToggleReadyPlotsButton",
"ShowReadyPlots"
]
];
const GrowthTimersButton =
document.getElementById(
"ToggleGrowthTimersButton"
);
if (
PlantNamesButton === null ||
GrowthTimersButton === null
for (
const [
ButtonId,
PreferenceName
]
of PreferenceButtons
) {
return;
const Button =
document.getElementById(
ButtonId
);
if (Button === null) {
continue;
}
Button.addEventListener(
"click",
() => {
ToggleGardenDisplayPreference(
PreferenceName
);
}
);
}
PlantNamesButton.addEventListener(
"click",
() => {
ToggleGardenDisplayPreference(
"ShowPlantNames"
);
}
);
GrowthTimersButton.addEventListener(
"click",
() => {
ToggleGardenDisplayPreference(
"ShowGrowthTimers"
);
}
);
}
function RenderGardenDisplayPreferences() {
RenderPlantInformationPreferences();
RenderGardenOverviewPreferences();
}
function RenderPlantInformationPreferences() {
const PlantNamesButton =
document.getElementById(
"TogglePlantNamesButton"
@@ -144,14 +176,19 @@ function RenderGardenDisplayPreferences() {
);
if (!IsOwned) {
PlantNamesButton.textContent =
"Plant names: Locked";
SetPreferenceButtonState(
PlantNamesButton,
"Plant names",
false,
true
);
GrowthTimersButton.textContent =
"Growth timers: Locked";
PlantNamesButton.disabled = true;
GrowthTimersButton.disabled = true;
SetPreferenceButtonState(
GrowthTimersButton,
"Growth timers",
false,
true
);
Message.textContent =
"Unlock Plant information in the Shop to use these settings.";
@@ -160,38 +197,166 @@ function RenderGardenDisplayPreferences() {
}
const ShowPlantNames =
SetPreferenceButtonState(
PlantNamesButton,
"Plant names",
ProfileSave.Preferences
.ShowPlantNames !== false;
.ShowPlantNames !== false
);
const ShowGrowthTimers =
SetPreferenceButtonState(
GrowthTimersButton,
"Growth timers",
ProfileSave.Preferences
.ShowGrowthTimers !== false;
PlantNamesButton.disabled = false;
GrowthTimersButton.disabled = false;
PlantNamesButton.textContent =
"Plant names: " +
(ShowPlantNames
? "On"
: "Off");
GrowthTimersButton.textContent =
"Growth timers: " +
(ShowGrowthTimers
? "On"
: "Off");
.ShowGrowthTimers !== false
);
Message.textContent =
"Plant names and growth timers can be changed independently.";
}
function RenderGardenOverviewPreferences() {
const Settings = [
[
"ToggleNextHarvestButton",
"Next harvest",
"ShowNextHarvest"
],
[
"ToggleGardenSizeButton",
"Garden size",
"ShowGardenSize"
],
[
"ToggleEmptyPlotsButton",
"Empty plots",
"ShowEmptyPlots"
],
[
"TogglePlantedPlotsButton",
"Planted plots",
"ShowPlantedPlots"
],
[
"ToggleGrowingPlotsButton",
"Growing",
"ShowGrowingPlots"
],
[
"ToggleReadyPlotsButton",
"Ready to harvest",
"ShowReadyPlots"
]
];
const Message =
document.getElementById(
"GardenOverviewDisplayMessage"
);
if (Message === null) {
return;
}
const IsOwned =
HasGardenOverviewUpgrade(
ProfileSave
);
for (
const [
ButtonId,
Label,
PreferenceName
]
of Settings
) {
const Button =
document.getElementById(
ButtonId
);
if (Button === null) {
continue;
}
SetPreferenceButtonState(
Button,
Label,
ProfileSave.Preferences[
PreferenceName
] !== false,
!IsOwned
);
}
Message.textContent =
IsOwned
? "Every Garden overview line can be changed independently."
: "Unlock Garden overview in the Shop to use these settings.";
}
function SetPreferenceButtonState(
Button,
Label,
IsEnabled,
IsLocked = false
) {
Button.disabled = IsLocked;
Button.textContent =
Label +
": " +
(IsLocked
? "Locked"
: IsEnabled
? "On"
: "Off");
}
async function ToggleGardenDisplayPreference(
PreferenceName
) {
const PlantInformationPreferences = [
"ShowPlantNames",
"ShowGrowthTimers"
];
const GardenOverviewPreferences = [
"ShowNextHarvest",
"ShowGardenSize",
"ShowEmptyPlots",
"ShowPlantedPlots",
"ShowGrowingPlots",
"ShowReadyPlots"
];
const IsPlantInformationPreference =
PlantInformationPreferences.includes(
PreferenceName
);
const IsGardenOverviewPreference =
GardenOverviewPreferences.includes(
PreferenceName
);
if (
!IsPlantInformationPreference &&
!IsGardenOverviewPreference
) {
return;
}
if (
IsPlantInformationPreference &&
!HasPlantInformationUpgrade(
ProfileSave
)
@@ -200,10 +365,10 @@ async function ToggleGardenDisplayPreference(
}
if (
PreferenceName !==
"ShowPlantNames" &&
PreferenceName !==
"ShowGrowthTimers"
IsGardenOverviewPreference &&
!HasGardenOverviewUpgrade(
ProfileSave
)
) {
return;
}
+37 -2
View File
@@ -67,12 +67,19 @@ function CreateNewSave() {
Upgrades: {
PlotSize: 0,
PlantInformation: false
PlantInformation: false,
GardenOverview: false
},
Preferences: {
ShowPlantNames: true,
ShowGrowthTimers: true
ShowGrowthTimers: true,
ShowNextHarvest: true,
ShowGardenSize: true,
ShowEmptyPlots: true,
ShowPlantedPlots: true,
ShowGrowingPlots: true,
ShowReadyPlots: true
},
Garden: {
@@ -249,6 +256,10 @@ function NormalizeSaveData(
SaveData.Upgrades.PlantInformation ===
true;
SaveData.Upgrades.GardenOverview =
SaveData.Upgrades.GardenOverview ===
true;
SaveData.Preferences ??= {};
@@ -260,6 +271,30 @@ function NormalizeSaveData(
SaveData.Preferences.ShowGrowthTimers !==
false;
SaveData.Preferences.ShowNextHarvest =
SaveData.Preferences.ShowNextHarvest !==
false;
SaveData.Preferences.ShowGardenSize =
SaveData.Preferences.ShowGardenSize !==
false;
SaveData.Preferences.ShowEmptyPlots =
SaveData.Preferences.ShowEmptyPlots !==
false;
SaveData.Preferences.ShowPlantedPlots =
SaveData.Preferences.ShowPlantedPlots !==
false;
SaveData.Preferences.ShowGrowingPlots =
SaveData.Preferences.ShowGrowingPlots !==
false;
SaveData.Preferences.ShowReadyPlots =
SaveData.Preferences.ShowReadyPlots !==
false;
SaveData.Garden ??= {
Width: 3,
+176 -1
View File
@@ -124,7 +124,8 @@ function RenderGardenUpgrades() {
CreateGardenExpansionCard(
"Row"
),
CreatePlantInformationUpgradeCard()
CreatePlantInformationUpgradeCard(),
CreateGardenOverviewUpgradeCard()
);
}
@@ -387,6 +388,122 @@ function CreatePlantInformationUpgradeCard() {
}
function CreateGardenOverviewUpgradeCard() {
const Cost =
GetGardenOverviewUpgradeCost();
const IsOwned =
HasGardenOverviewUpgrade(
ShopSave
);
const Card =
document.createElement(
"article"
);
Card.className =
"Panel ShopItem";
const Header =
document.createElement(
"div"
);
Header.className =
"ShopItemHeader";
const Name =
document.createElement(
"h3"
);
Name.textContent =
"Garden overview";
Header.appendChild(Name);
const Description =
document.createElement(
"p"
);
Description.textContent =
"Expand the Garden status box with detailed plot counts and the name of the next plant ready to harvest. Every overview line can be toggled on/off from the profile page.";
const Details =
document.createElement(
"div"
);
Details.className =
"ShopItemDetails";
Details.append(
CreateShopStat(
"Garden details",
IsOwned
? "Unlocked"
: "Locked"
),
CreateShopStat(
"Profile controls",
IsOwned
? "Unlocked"
: "Locked"
)
);
const BuyButton =
document.createElement(
"button"
);
BuyButton.className =
"ActionButton ShopBuyButton";
BuyButton.type = "button";
if (IsOwned) {
BuyButton.textContent =
"Purchased";
BuyButton.disabled = true;
} else {
BuyButton.textContent =
"Buy - " +
Cost.toLocaleString() +
" Dew";
BuyButton.disabled =
ShopSave.Currency.Dew < Cost ||
ShopPurchasePending;
BuyButton.addEventListener(
"click",
BuyGardenOverviewUpgrade
);
}
Card.append(
Header,
Description,
Details,
BuyButton
);
return Card;
}
function CreateShopSeedCard(
Plant
) {
@@ -1014,6 +1131,64 @@ async function BuyPlantInformationUpgrade() {
}
async function BuyGardenOverviewUpgrade() {
if (
ShopPurchasePending ||
HasGardenOverviewUpgrade(
ShopSave
)
) {
return;
}
const Cost =
GetGardenOverviewUpgradeCost();
if (
ShopSave.Currency.Dew <
Cost
) {
SetShopMessage(
"You don't have enough Dew for Garden overview."
);
return;
}
ShopPurchasePending = true;
try {
ShopSave.Currency.Dew -=
Cost;
ShopSave.Statistics.CurrencySpent.Dew +=
Cost;
UnlockGardenOverview(
ShopSave
);
SetShopMessage(
"Bought Garden overview for " +
Cost.toLocaleString() +
" Dew. All overview lines are now visible."
);
RenderShop();
await SaveGame(
ShopSave
);
} finally {
ShopPurchasePending = false;
RenderShop();
}
}
function SetShopMessage(
Message
) {
+47
View File
@@ -1,5 +1,6 @@
const GardenExpansionBaseCost = 1000;
const PlantInformationUpgradeCost = 500;
const GardenOverviewUpgradeCost = 1000;
function GetGardenColumnUpgradeCost(
@@ -142,3 +143,49 @@ function UnlockPlantInformation(
SaveData.Preferences.ShowGrowthTimers =
true;
}
function HasGardenOverviewUpgrade(
SaveData
) {
return (
SaveData
?.Upgrades
?.GardenOverview ===
true
);
}
function GetGardenOverviewUpgradeCost() {
return GardenOverviewUpgradeCost;
}
function UnlockGardenOverview(
SaveData
) {
SaveData.Upgrades ??= {};
SaveData.Preferences ??= {};
SaveData.Upgrades.GardenOverview =
true;
SaveData.Preferences.ShowNextHarvest =
true;
SaveData.Preferences.ShowGardenSize =
true;
SaveData.Preferences.ShowEmptyPlots =
true;
SaveData.Preferences.ShowPlantedPlots =
true;
SaveData.Preferences.ShowGrowingPlots =
true;
SaveData.Preferences.ShowReadyPlots =
true;
}