Changed naming scheme of plant stages (1, 2, 3 instead of Seed, Sprout,

Mature).
This commit is contained in:
sarah committed 2026-08-30 17:43:00 +02:00
1 parent c558a4988f
commit bf15c48c10
7 files changed
+392 -104

No files matched your search

+218 -1
View File
@@ -103,6 +103,220 @@ function RenderPage(
);
}
function GeneratePlantImageManifest(
string $RootDirectory,
string $OutputDirectory
): void {
$PlantsDirectory =
$RootDirectory .
"/Assets/Img/Garden/Plants";
$Manifest = [];
if (!is_dir($PlantsDirectory)) {
return;
}
foreach (
new DirectoryIterator(
$PlantsDirectory
)
as $PlantDirectory
) {
if (
$PlantDirectory->isDot() ||
!$PlantDirectory->isDir()
) {
continue;
}
$PlantName =
$PlantDirectory->getFilename();
$Manifest[$PlantName] = [];
foreach (
new DirectoryIterator(
$PlantDirectory->getPathname()
)
as $VariantDirectory
) {
if (
$VariantDirectory->isDot() ||
!$VariantDirectory->isDir()
) {
continue;
}
$VariantName =
$VariantDirectory->getFilename();
$Images = [];
foreach (
new DirectoryIterator(
$VariantDirectory->getPathname()
)
as $Image
) {
if (!$Image->isFile()) {
continue;
}
if (
preg_match(
"/^([0-9]+)\.png$/i",
$Image->getFilename(),
$Matches
) !== 1
) {
continue;
}
$ImageNumber =
(int) $Matches[1];
if ($ImageNumber < 1) {
continue;
}
$Images[$ImageNumber] =
"/Assets/Img/Garden/Plants/" .
$PlantName .
"/" .
$VariantName .
"/" .
$Image->getFilename();
}
/*
* Sort numerically:
*
* 1.png
* 2.png
* ...
* 10.png
*
* instead of:
*
* 1.png
* 10.png
* 2.png
*/
ksort(
$Images,
SORT_NUMERIC
);
/*
* Require consecutive numbering.
*/
$ExpectedNumber = 1;
foreach (
array_keys($Images)
as $ImageNumber
) {
if (
$ImageNumber !==
$ExpectedNumber
) {
throw new RuntimeException(
"Missing plant image " .
$ExpectedNumber .
".png in " .
$PlantName .
"/" .
$VariantName
);
}
$ExpectedNumber++;
}
if (count($Images) === 0) {
continue;
}
$Manifest[
$PlantName
][
$VariantName
] = array_values(
$Images
);
}
if (
count(
$Manifest[$PlantName]
) === 0
) {
unset(
$Manifest[$PlantName]
);
} else {
ksort(
$Manifest[$PlantName],
SORT_NATURAL |
SORT_FLAG_CASE
);
}
}
ksort(
$Manifest,
SORT_NATURAL |
SORT_FLAG_CASE
);
$ManifestDirectory =
$OutputDirectory .
"/Scripts/Garden";
if (!is_dir($ManifestDirectory)) {
mkdir(
$ManifestDirectory,
0777,
true
);
}
$Json = json_encode(
$Manifest,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE |
JSON_THROW_ON_ERROR
);
file_put_contents(
$ManifestDirectory .
"/PlantImages.js",
"const PlantImages = " .
$Json .
";" .
PHP_EOL
);
echo
"Generated Scripts/Garden/PlantImages.js" .
PHP_EOL;
}
/*
* Remove the previous build.
@@ -134,6 +348,10 @@ foreach ($StaticDirectories as $Directory) {
);
}
GeneratePlantImageManifest(
$RootDirectory,
$OutputDirectory
);
/*
* Copy index.html.
@@ -145,7 +363,6 @@ foreach ($StaticDirectories as $Directory) {
"./"
);
/*
* Build PHP pages.
*/
+1
View File
@@ -103,6 +103,7 @@ $PageTitle = "Garden";
</section>
</main>
<script src="/Scripts/Garden/PlantImages.js"></script>
<script src="/Scripts/Garden/Plants.js"></script>
<script src="/Scripts/Garden/Mutations.js"></script>
<script src="/Scripts/Garden/Save.js"></script>
+155 -96
View File
@@ -179,6 +179,11 @@ function CreatePlotElement(
Button.type = "button";
/*
* Empty plot.
*/
if (Plot === null) {
Button.classList.add(
"GardenPlotEmpty"
@@ -210,38 +215,47 @@ function CreatePlotElement(
}
const Stage =
GetPlantStage(
/*
* Plant image.
*/
const ImagePath =
GetPlantImage(
Plot,
Plant
);
const Image =
document.createElement(
"img"
if (ImagePath !== null) {
const Image =
document.createElement(
"img"
);
Image.className =
"GardenPlant";
Image.alt =
Plant.Name;
Image.src =
ImagePath;
Button.appendChild(
Image
);
Image.className =
"GardenPlant";
Image.alt =
Plant.Name +
" - " +
Stage;
SetPlantImage(
Image,
Plot,
Plant,
Stage
);
Button.appendChild(
Image
);
}
if (Stage === "Mature") {
/*
* Mature plants can be harvested.
*/
if (
IsPlantMature(
Plot,
Plant
)
) {
Button.classList.add(
"GardenPlotMature"
);
@@ -340,10 +354,10 @@ async function HarvestPlant(
Plants[Plot.Plant];
if (
GetPlantStage(
!IsPlantMature(
Plot,
Plant
) !== "Mature"
)
) {
return;
}
@@ -413,36 +427,16 @@ function GetPlantGrowthProgress(
Date.now() -
Plot.PlantedAt;
return Math.min(
Age /
Plant.GrowthTime,
1
return Math.max(
0,
Math.min(
Age /
Plant.GrowthTime,
1
)
);
}
function GetPlantStage(
Plot,
Plant
) {
const Progress =
GetPlantGrowthProgress(
Plot,
Plant
);
if (Progress < 1 / 3) {
return "Seed";
}
if (Progress < 2 / 3) {
return "Sprout";
}
return "Mature";
}
function GetPlantTags(
Plot,
Plant
@@ -500,65 +494,130 @@ function GetPlantVariant(
}
function SetPlantImage(
Image,
function IsPlantMature(
Plot,
Plant,
Stage
Plant
) {
return (
GetPlantGrowthProgress(
Plot,
Plant
) >= 1
);
}
function GetPlantImages(
Plot,
Plant
) {
const Variants =
PlantImages[
Plot.Plant
];
if (Variants === undefined) {
return [];
}
const Variant =
GetPlantVariant(
Plot,
Plant
);
const BasePath =
"/Assets/Img/Garden/Plants/" +
Plot.Plant +
"/" +
Variant +
"/";
/*
* Preferred variant.
*/
if (
Array.isArray(
Variants[Variant]
) &&
Variants[Variant].length > 0
) {
return Variants[
Variant
];
}
/*
* Try the requested stage first.
*
* If that image doesn't exist,
* Mature.png becomes the fallback.
* Default visual fallback.
*/
const Candidates = [
BasePath + Stage + ".png",
BasePath + "Mature.png"
];
if (
Array.isArray(
Variants.Default
) &&
Variants.Default.length > 0
) {
return Variants.Default;
}
let CandidateIndex = 0;
Image.src =
Candidates[
CandidateIndex
];
/*
* Absolute fallback:
* use the first variant that has images.
*/
Image.addEventListener(
"error",
() => {
CandidateIndex++;
if (
CandidateIndex <
Candidates.length
) {
Image.src =
Candidates[
CandidateIndex
];
return;
}
Image.remove();
for (
const Images
of Object.values(
Variants
)
) {
if (
Array.isArray(Images) &&
Images.length > 0
) {
return Images;
}
);
}
return [];
}
function GetPlantImage(
Plot,
Plant
) {
const Images =
GetPlantImages(
Plot,
Plant
);
if (Images.length === 0) {
return null;
}
const Progress =
GetPlantGrowthProgress(
Plot,
Plant
);
const ImageIndex =
Math.min(
Math.floor(
Progress *
Images.length
),
Images.length - 1
);
return Images[
ImageIndex
];
}
+18 -7
View File
@@ -631,16 +631,12 @@ select {
width: 100%;
overflow-x: auto;
border: 3px solid var(--Surface2);
box-shadow:
3px 3px 0
var(--Crust);
}
.LeaderboardTable {
width: 100%;
width: auto;
min-width: 24rem;
margin: 0 auto;
border-collapse: collapse;
@@ -648,6 +644,12 @@ select {
background-color: var(--Base);
font-size: 1.2rem;
border: 3px solid var(--Surface2);
box-shadow:
3px 3px 0
var(--Crust);
}
.LeaderboardTable th {
@@ -686,6 +688,15 @@ select {
text-align: center;
}
.LeaderboardUsername {
min-width: 12rem;
}
.LeaderboardDewColumn,
.LeaderboardDew {
min-width: 7rem;
}
.LeaderboardDew {
color: var(--Green);
}