Added plant encyclopedia. PLEASE WORK

This commit is contained in:
sarah committed 2026-09-01 19:11:14 +02:00
1 parent 624b933347
commit f417ca67f8
7 files changed
+900 -2

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+1
View File
@@ -5,6 +5,7 @@ $NavbarPages = [
"Sarahtonin" => "/Pages/Sarahtonin.html",
"Garden" => "/Pages/Garden.html",
"Shop" => "/Pages/Shop.html",
"Plants" => "/Pages/Plants.html",
"Guide" => "/Pages/Guide.html",
"Profile" => "/Pages/Profile.html"
];
+2 -2
View File
@@ -71,7 +71,7 @@ $PageSection = "Guide";
id="Harvesting"
class="GuideSection"
>
<h2>Harvesting</h2>
<h3>Harvesting</h3>
<p>
Click a mature plant to harvest it. Harvesting gives
@@ -178,7 +178,7 @@ $PageSection = "Guide";
id="Discoveries"
class="GuideSection"
>
<h2>Discoveries</h2>
<h3>Discoveries</h3>
<p>
Discovering a new plant or mutation is saved with
+48
View File
@@ -0,0 +1,48 @@
<?php
$PageTitle = "Plants";
$PageSection = "Plants";
?>
<!DOCTYPE html>
<html lang="en" data-palette="CatppuccinMocha">
<?php require __DIR__ . "/Bits/Head.php"; ?>
<body>
<?php require __DIR__ . "/Bits/Navbar.php"; ?>
<main class="MainContainer">
<h1>Plant encyclopedia</h1>
<p>
Every plant you discover is recorded here.
Undiscovered plants stay hidden until you find
them in your Garden.
</p>
<div
id="PlantEncyclopediaList"
class="PlantEncyclopediaList"
></div>
<p
id="PlantEncyclopediaMessage"
class="PageMessage"
aria-live="polite"
>
Loading discovered plants...
</p>
</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>
<script src="/Scripts/Garden/Content.js"></script>
<script src="/Scripts/Garden/Economy.js"></script>
<script src="/Scripts/Garden/PlantEncyclopedia.js"></script>
</body>
</html>
+673
View File
@@ -0,0 +1,673 @@
let PlantEncyclopediaSave;
async function StartPlantEncyclopedia() {
try {
await LoadGameContent();
PlantEncyclopediaSave =
await LoadGame();
RenderPlantEncyclopedia();
} catch (Error) {
console.error(
"Couldn't load Plant encyclopedia:",
Error
);
SetPlantEncyclopediaMessage(
"Couldn't load your discovered plants."
);
}
}
function RenderPlantEncyclopedia() {
const List =
document.getElementById(
"PlantEncyclopediaList"
);
List.replaceChildren();
const DiscoveredPlants =
Object.values(Plants)
.filter(
Plant =>
HasDiscoveredPlant(
PlantEncyclopediaSave,
Plant.Id
)
)
.sort(
(A, B) =>
A.Id - B.Id
);
if (
DiscoveredPlants.length === 0
) {
SetPlantEncyclopediaMessage(
"No plants discovered yet."
);
return;
}
for (
const Plant
of DiscoveredPlants
) {
List.appendChild(
CreatePlantEncyclopediaCard(
Plant
)
);
}
SetPlantEncyclopediaMessage(
DiscoveredPlants.length === 1
? "1 plant discovered."
: DiscoveredPlants.length
.toLocaleString() +
" plants discovered."
);
}
function CreatePlantEncyclopediaCard(
Plant
) {
const Card =
document.createElement(
"article"
);
Card.className =
"Panel PlantEncyclopediaCard";
Card.id =
"Plant-" + Plant.Id;
const Header =
document.createElement(
"header"
);
Header.className =
"PlantEncyclopediaHeader";
const Number =
document.createElement(
"span"
);
Number.className =
"PlantEncyclopediaNumber";
Number.textContent =
String(
Plant.Id
).padStart(
3,
"0"
);
const Name =
document.createElement(
"h2"
);
Name.textContent =
Plant.Name;
Header.append(
Number,
Name
);
const Body =
document.createElement(
"div"
);
Body.className =
"PlantEncyclopediaBody";
Body.append(
CreatePlantEncyclopediaVisual(
Plant
),
CreatePlantEncyclopediaDetails(
Plant
),
CreatePlantEncyclopediaRelations(
Plant
)
);
Card.append(
Header,
Body
);
return Card;
}
function CreatePlantEncyclopediaVisual(
Plant
) {
const Visual =
document.createElement(
"div"
);
Visual.className =
"PlantTile PlantEncyclopediaVisual";
const PlantKey =
GetPlantKeyById(
Plant.Id
);
const Images =
PlantKey === null
? []
: PlantImages[
PlantKey
] ?? [];
if (Images.length === 0) {
const Missing =
document.createElement(
"span"
);
Missing.className =
"PlantEncyclopediaMissing";
Missing.textContent =
"No image";
Visual.appendChild(
Missing
);
return Visual;
}
const Image =
document.createElement(
"img"
);
Image.className =
"PlantSprite";
Image.src =
Images[
Images.length - 1
];
Image.alt =
Plant.Name;
Visual.appendChild(
Image
);
return Visual;
}
function CreatePlantEncyclopediaDetails(
Plant
) {
const Details =
document.createElement(
"div"
);
Details.className =
"PlantEncyclopediaDetails";
const Description =
document.createElement(
"p"
);
Description.className =
"PlantEncyclopediaDescription";
Description.textContent =
Plant.Description ||
"No description.";
Details.appendChild(
Description
);
const Tags =
Array.isArray(
Plant.Tags
)
? Plant.Tags
: [];
Details.appendChild(
CreatePlantEncyclopediaStat(
"Tags",
Tags.length === 0
? "None"
: Tags.join(", ")
)
);
Details.appendChild(
CreatePlantEncyclopediaStat(
"Growth",
FormatPlantEncyclopediaTime(
Plant.GrowthTime
)
)
);
const Reward =
GetPlantHarvestReward(
PlantEncyclopediaSave,
Plant.Id
);
Details.appendChild(
CreatePlantEncyclopediaStat(
"Reward",
Reward === null
? "Unavailable"
: Reward.toLocaleString() +
" Dew"
)
);
const RecipeProgress =
GetPlantRecipeProgress(
Plant.Id
);
Details.appendChild(
CreatePlantEncyclopediaStat(
"Found recipes",
RecipeProgress.Found
.toLocaleString() +
"/" +
RecipeProgress.Total
.toLocaleString()
)
);
return Details;
}
function CreatePlantEncyclopediaStat(
Name,
Value
) {
const Row =
document.createElement(
"div"
);
Row.className =
"PlantEncyclopediaStat";
const NameElement =
document.createElement(
"span"
);
NameElement.className =
"PlantEncyclopediaStatName";
NameElement.textContent =
Name;
const ValueElement =
document.createElement(
"span"
);
ValueElement.textContent =
Value;
Row.append(
NameElement,
ValueElement
);
return Row;
}
function CreatePlantEncyclopediaRelations(
Plant
) {
const Relations =
document.createElement(
"div"
);
Relations.className =
"PlantEncyclopediaRelations";
Relations.append(
CreatePlantMutationRelationGroup(
"Created by",
GetPlantRelatedMutations(
Plant.Id,
"PlantsCreated"
)
),
CreatePlantMutationRelationGroup(
"Used in",
GetPlantRelatedMutations(
Plant.Id,
"PlantsUsed"
)
)
);
return Relations;
}
function CreatePlantMutationRelationGroup(
Heading,
Mutations
) {
const Group =
document.createElement(
"section"
);
Group.className =
"PlantEncyclopediaRelationGroup";
const Title =
document.createElement(
"h3"
);
Title.textContent =
Heading;
const List =
document.createElement(
"ul"
);
List.className =
"PlantEncyclopediaRelationList";
if (Mutations.length === 0) {
const Empty =
document.createElement(
"li"
);
Empty.className =
"PlantEncyclopediaRelationEmpty";
Empty.textContent =
"None";
List.appendChild(
Empty
);
} else {
for (
const Mutation
of Mutations
) {
List.appendChild(
CreatePlantMutationRelation(
Mutation
)
);
}
}
Group.append(
Title,
List
);
return Group;
}
function CreatePlantMutationRelation(
Mutation
) {
const Item =
document.createElement(
"li"
);
if (
!HasDiscoveredMutation(
PlantEncyclopediaSave,
Mutation.Id
)
) {
Item.className =
"PlantEncyclopediaRelationUnknown";
Item.textContent =
"????????";
return Item;
}
const Link =
document.createElement(
"a"
);
Link.href =
"/Pages/Mutations.html#Mutation-" +
Mutation.Id;
Link.textContent =
Mutation.Name;
Item.appendChild(
Link
);
return Item;
}
function GetPlantRelatedMutations(
PlantId,
RelationName
) {
return Object.values(
MutationSets
)
.filter(
Mutation =>
Mutation.Relations?.[
RelationName
]?.includes(
Number(PlantId)
)
)
.sort(
(A, B) =>
A.Id - B.Id
);
}
function GetPlantRecipeProgress(
PlantId
) {
const RelatedMutationIds =
new Set();
for (
const Mutation
of Object.values(
MutationSets
)
) {
const Relations =
Mutation.Relations ?? {};
const IsRelated =
Relations.PlantsCreated
?.includes(
Number(PlantId)
) ||
Relations.PlantsUsed
?.includes(
Number(PlantId)
);
if (IsRelated) {
RelatedMutationIds.add(
Mutation.Id
);
}
}
let Found = 0;
for (
const MutationId
of RelatedMutationIds
) {
if (
HasDiscoveredMutation(
PlantEncyclopediaSave,
MutationId
)
) {
Found++;
}
}
return {
Found: Found,
Total: RelatedMutationIds.size
};
}
function FormatPlantEncyclopediaTime(
Milliseconds
) {
const TotalMinutes =
Math.max(
1,
Math.ceil(
Number(
Milliseconds
) /
60000
)
);
const Hours =
Math.floor(
TotalMinutes /
60
);
const Minutes =
TotalMinutes %
60;
if (
Hours > 0 &&
Minutes > 0
) {
return (
Hours +
"h " +
Minutes +
"m"
);
}
if (Hours > 0) {
return Hours + "h";
}
return Minutes + "m";
}
function SetPlantEncyclopediaMessage(
Message
) {
const Element =
document.getElementById(
"PlantEncyclopediaMessage"
);
if (Element !== null) {
Element.textContent =
Message;
}
}
document.addEventListener(
"DOMContentLoaded",
StartPlantEncyclopedia
);
+176
View File
@@ -1299,3 +1299,179 @@ select {
height: 3rem;
}
}
/*
* Plant encyclopedia
*/
.PlantEncyclopediaList {
display: flex;
flex-direction: column;
gap: 1rem;
margin-top: 1.5rem;
}
.PlantEncyclopediaCard {
overflow: hidden;
box-shadow: 3px 3px 0 var(--Crust);
}
.PlantEncyclopediaHeader {
display: flex;
gap: 0.75rem;
align-items: baseline;
padding: 0.75rem 1rem;
background-color: var(--Surface0);
border-bottom: 3px solid var(--Surface2);
}
.PlantEncyclopediaHeader h2 {
margin: 0;
color: var(--Green);
}
.PlantEncyclopediaNumber {
flex: 0 0 auto;
color: var(--Overlay2);
font-size: 1.1rem;
}
.PlantEncyclopediaBody {
display: grid;
grid-template-columns:
7rem
minmax(0, 1fr)
minmax(10rem, 0.8fr);
gap: 1rem;
padding: 1rem;
align-items: start;
}
.PlantEncyclopediaVisual {
display: flex;
width: 7rem;
height: 7rem;
align-items: center;
justify-content: center;
background-color: var(--Base);
}
.PlantEncyclopediaMissing {
padding: 0.5rem;
color: var(--Overlay1);
text-align: center;
}
.PlantEncyclopediaDescription {
margin-bottom: 0.75rem;
}
.PlantEncyclopediaStat {
display: flex;
justify-content: space-between;
gap: 0.75rem;
padding: 0.35rem 0;
border-bottom: 2px solid var(--Surface0);
}
.PlantEncyclopediaStat:last-child {
border-bottom: 0;
}
.PlantEncyclopediaStatName {
flex: 0 0 auto;
color: var(--Subtext1);
}
.PlantEncyclopediaStat > :last-child {
min-width: 0;
text-align: right;
overflow-wrap: anywhere;
}
.PlantEncyclopediaRelations {
min-width: 0;
background-color: var(--Base);
border: 3px solid var(--Surface2);
}
.PlantEncyclopediaRelationGroup {
padding: 0.65rem 0.75rem;
}
.PlantEncyclopediaRelationGroup +
.PlantEncyclopediaRelationGroup {
border-top: 3px solid var(--Surface2);
}
.PlantEncyclopediaRelationGroup h3 {
margin-bottom: 0.5rem;
color: var(--Peach);
font-size: 1rem;
}
.PlantEncyclopediaRelationList {
max-height: 7rem;
margin: 0;
padding-left: 1.25rem;
overflow-y: auto;
}
.PlantEncyclopediaRelationList li {
margin-bottom: 0.35rem;
}
.PlantEncyclopediaRelationList li:last-child {
margin-bottom: 0;
}
.PlantEncyclopediaRelationUnknown,
.PlantEncyclopediaRelationEmpty {
color: var(--Overlay1);
}
@media (max-width: 700px) {
.PlantEncyclopediaBody {
grid-template-columns: 1fr;
}
.PlantEncyclopediaVisual {
width: min(8rem, 100%);
height: auto;
aspect-ratio: 1;
justify-self: center;
}
.PlantEncyclopediaStat > :last-child {
text-align: left;
}
.PlantEncyclopediaStat {
flex-direction: column;
gap: 0.2rem;
}
}