mirror of
https://git.srhtnin.garden/sarah/srhtnin.github.io.git
synced 2026-10-13 18:38:11 +02:00
Added search and sort.
This commit is contained in:
1 parent
ba27ff9fd7
commit
fbc44883d4
7 files changed
+979
-40
No files matched your search
@@ -25,6 +25,31 @@ $PageSection = "Mutations";
|
|||||||
currently capable of discovering.
|
currently capable of discovering.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="CatalogueControls"
|
||||||
|
aria-label="Mutation search and sorting"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="MutationEncyclopediaSearchInput"
|
||||||
|
type="search"
|
||||||
|
placeholder="Search mutations..."
|
||||||
|
aria-label="Search mutations"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
|
||||||
|
<select
|
||||||
|
id="MutationEncyclopediaSortSelect"
|
||||||
|
aria-label="Sort mutations"
|
||||||
|
>
|
||||||
|
<option value="IdAsc">ID</option>
|
||||||
|
<option value="NameAsc">Name A-Z</option>
|
||||||
|
<option value="ChanceDesc">Chance high-low</option>
|
||||||
|
<option value="ChanceAsc">Chance low-high</option>
|
||||||
|
<option value="CooldownAsc">Cooldown short-long</option>
|
||||||
|
<option value="CooldownDesc">Cooldown long-short</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="MutationEncyclopediaList"
|
id="MutationEncyclopediaList"
|
||||||
class="MutationEncyclopediaList"
|
class="MutationEncyclopediaList"
|
||||||
|
|||||||
@@ -23,6 +23,33 @@ $PageSection = "Plants";
|
|||||||
them in your Garden.
|
them in your Garden.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="CatalogueControls"
|
||||||
|
aria-label="Plant search and sorting"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="PlantEncyclopediaSearchInput"
|
||||||
|
type="search"
|
||||||
|
placeholder="Search plants..."
|
||||||
|
aria-label="Search plants"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
|
||||||
|
<select
|
||||||
|
id="PlantEncyclopediaSortSelect"
|
||||||
|
aria-label="Sort plants"
|
||||||
|
>
|
||||||
|
<option value="IdAsc">ID</option>
|
||||||
|
<option value="NameAsc">Name A-Z</option>
|
||||||
|
<option value="GrowthAsc">Growth short-long</option>
|
||||||
|
<option value="GrowthDesc">Growth long-short</option>
|
||||||
|
<option value="RewardAsc">Reward low-high</option>
|
||||||
|
<option value="RewardDesc">Reward high-low</option>
|
||||||
|
<option value="DphDesc">DPH high-low</option>
|
||||||
|
<option value="DphAsc">DPH low-high</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="PlantEncyclopediaList"
|
id="PlantEncyclopediaList"
|
||||||
class="PlantEncyclopediaList"
|
class="PlantEncyclopediaList"
|
||||||
|
|||||||
@@ -95,6 +95,37 @@ $PageSection = "Shop";
|
|||||||
id="SeedsContent"
|
id="SeedsContent"
|
||||||
class="ShopSectionContent"
|
class="ShopSectionContent"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
class="CatalogueControls"
|
||||||
|
aria-label="Seed search and sorting"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="ShopSeedSearchInput"
|
||||||
|
type="search"
|
||||||
|
placeholder="Search plants..."
|
||||||
|
aria-label="Search plants"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
|
||||||
|
<select
|
||||||
|
id="ShopSeedSortSelect"
|
||||||
|
aria-label="Sort seeds"
|
||||||
|
>
|
||||||
|
<option value="IdAsc">ID</option>
|
||||||
|
<option value="NameAsc">Name A-Z</option>
|
||||||
|
<option value="PriceAsc">Price low-high</option>
|
||||||
|
<option value="PriceDesc">Price high-low</option>
|
||||||
|
<option value="GrowthAsc">Growth short-long</option>
|
||||||
|
<option value="GrowthDesc">Growth long-short</option>
|
||||||
|
<option value="RewardAsc">Reward low-high</option>
|
||||||
|
<option value="RewardDesc">Reward high-low</option>
|
||||||
|
<option value="DphDesc">DPH high-low</option>
|
||||||
|
<option value="DphAsc">DPH low-high</option>
|
||||||
|
<option value="InventoryDesc">Inventory high-low</option>
|
||||||
|
<option value="InventoryAsc">Inventory low-high</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="ShopSeedList"
|
id="ShopSeedList"
|
||||||
class="ShopSeedList"
|
class="ShopSeedList"
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
let MutationEncyclopediaSave;
|
let MutationEncyclopediaSave;
|
||||||
|
let MutationEncyclopediaSearchQuery = "";
|
||||||
|
let MutationEncyclopediaSortMode = "IdAsc";
|
||||||
|
|
||||||
|
|
||||||
async function StartMutationEncyclopedia() {
|
async function StartMutationEncyclopedia() {
|
||||||
@@ -8,6 +10,7 @@ async function StartMutationEncyclopedia() {
|
|||||||
MutationEncyclopediaSave =
|
MutationEncyclopediaSave =
|
||||||
await LoadGame();
|
await LoadGame();
|
||||||
|
|
||||||
|
BindMutationEncyclopediaControls();
|
||||||
RenderMutationEncyclopedia();
|
RenderMutationEncyclopedia();
|
||||||
} catch (Error) {
|
} catch (Error) {
|
||||||
console.error(
|
console.error(
|
||||||
@@ -22,6 +25,51 @@ async function StartMutationEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function BindMutationEncyclopediaControls() {
|
||||||
|
const SearchInput =
|
||||||
|
document.getElementById(
|
||||||
|
"MutationEncyclopediaSearchInput"
|
||||||
|
);
|
||||||
|
|
||||||
|
const SortSelect =
|
||||||
|
document.getElementById(
|
||||||
|
"MutationEncyclopediaSortSelect"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (SearchInput !== null) {
|
||||||
|
SearchInput.value =
|
||||||
|
MutationEncyclopediaSearchQuery;
|
||||||
|
|
||||||
|
SearchInput.addEventListener(
|
||||||
|
"input",
|
||||||
|
() => {
|
||||||
|
MutationEncyclopediaSearchQuery =
|
||||||
|
SearchInput.value;
|
||||||
|
|
||||||
|
RenderMutationEncyclopedia();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (SortSelect !== null) {
|
||||||
|
SortSelect.value =
|
||||||
|
MutationEncyclopediaSortMode;
|
||||||
|
|
||||||
|
SortSelect.addEventListener(
|
||||||
|
"change",
|
||||||
|
() => {
|
||||||
|
MutationEncyclopediaSortMode =
|
||||||
|
SortSelect.value;
|
||||||
|
|
||||||
|
RenderMutationEncyclopedia();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function RenderMutationEncyclopedia() {
|
function RenderMutationEncyclopedia() {
|
||||||
const List =
|
const List =
|
||||||
document.getElementById(
|
document.getElementById(
|
||||||
@@ -69,10 +117,37 @@ function RenderMutationEncyclopedia() {
|
|||||||
)
|
)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
const SearchQuery =
|
||||||
|
MutationEncyclopediaSearchQuery
|
||||||
|
.trim()
|
||||||
|
.toLocaleLowerCase();
|
||||||
|
|
||||||
|
const VisibleHints =
|
||||||
|
AvailableHints.filter(
|
||||||
|
Mutation =>
|
||||||
|
DoesMutationHintMatchSearch(
|
||||||
|
Mutation,
|
||||||
|
SearchQuery
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const VisibleMutations =
|
||||||
|
DiscoveredMutations
|
||||||
|
.filter(
|
||||||
|
Mutation =>
|
||||||
|
DoesMutationEncyclopediaMatchSearch(
|
||||||
|
Mutation,
|
||||||
|
SearchQuery
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.sort(
|
||||||
|
CompareMutationEncyclopediaMutations
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
for (
|
for (
|
||||||
const Mutation
|
const Mutation
|
||||||
of AvailableHints
|
of VisibleHints
|
||||||
) {
|
) {
|
||||||
List.appendChild(
|
List.appendChild(
|
||||||
CreateMutationHintCard(
|
CreateMutationHintCard(
|
||||||
@@ -84,7 +159,7 @@ function RenderMutationEncyclopedia() {
|
|||||||
|
|
||||||
for (
|
for (
|
||||||
const Mutation
|
const Mutation
|
||||||
of DiscoveredMutations
|
of VisibleMutations
|
||||||
) {
|
) {
|
||||||
List.appendChild(
|
List.appendChild(
|
||||||
CreateMutationEncyclopediaCard(
|
CreateMutationEncyclopediaCard(
|
||||||
@@ -106,24 +181,60 @@ function RenderMutationEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
VisibleMutations.length === 0 &&
|
||||||
|
VisibleHints.length === 0
|
||||||
|
) {
|
||||||
|
SetMutationEncyclopediaMessage(
|
||||||
|
"No mutations or hints match your search."
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const MessageParts = [];
|
const MessageParts = [];
|
||||||
|
|
||||||
MessageParts.push(
|
if (SearchQuery.length > 0) {
|
||||||
DiscoveredMutations.length === 1
|
|
||||||
? "1 mutation discovered."
|
|
||||||
: DiscoveredMutations.length
|
|
||||||
.toLocaleString() +
|
|
||||||
" mutations discovered."
|
|
||||||
);
|
|
||||||
|
|
||||||
if (AvailableHints.length > 0) {
|
|
||||||
MessageParts.push(
|
MessageParts.push(
|
||||||
AvailableHints.length === 1
|
"Showing " +
|
||||||
? "1 hint available."
|
VisibleMutations.length
|
||||||
: AvailableHints.length
|
.toLocaleString() +
|
||||||
.toLocaleString() +
|
" of " +
|
||||||
" hints available."
|
DiscoveredMutations.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" discovered mutations."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (AvailableHints.length > 0) {
|
||||||
|
MessageParts.push(
|
||||||
|
"Showing " +
|
||||||
|
VisibleHints.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" of " +
|
||||||
|
AvailableHints.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" available hints."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MessageParts.push(
|
||||||
|
DiscoveredMutations.length === 1
|
||||||
|
? "1 mutation discovered."
|
||||||
|
: DiscoveredMutations.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" mutations discovered."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (AvailableHints.length > 0) {
|
||||||
|
MessageParts.push(
|
||||||
|
AvailableHints.length === 1
|
||||||
|
? "1 hint available."
|
||||||
|
: AvailableHints.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" hints available."
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetMutationEncyclopediaMessage(
|
SetMutationEncyclopediaMessage(
|
||||||
@@ -134,6 +245,183 @@ function RenderMutationEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function DoesMutationHintMatchSearch(
|
||||||
|
Mutation,
|
||||||
|
SearchQuery
|
||||||
|
) {
|
||||||
|
if (SearchQuery.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(
|
||||||
|
Mutation.Hint ?? ""
|
||||||
|
)
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
.includes(
|
||||||
|
SearchQuery
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function DoesMutationEncyclopediaMatchSearch(
|
||||||
|
Mutation,
|
||||||
|
SearchQuery
|
||||||
|
) {
|
||||||
|
if (SearchQuery.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchParts = [
|
||||||
|
Mutation.Id,
|
||||||
|
Mutation.Name,
|
||||||
|
Mutation.Description,
|
||||||
|
Mutation.Hint,
|
||||||
|
FormatMutationChance(
|
||||||
|
Mutation.Chance
|
||||||
|
),
|
||||||
|
FormatMutationEncyclopediaTime(
|
||||||
|
Mutation.Cooldown
|
||||||
|
),
|
||||||
|
Mutation.Rotation
|
||||||
|
];
|
||||||
|
|
||||||
|
const RelationPlantIds = [
|
||||||
|
...(Mutation.Relations
|
||||||
|
?.PlantsUsed ?? []),
|
||||||
|
...(Mutation.Relations
|
||||||
|
?.PlantsCreated ?? [])
|
||||||
|
];
|
||||||
|
|
||||||
|
for (
|
||||||
|
const PlantId
|
||||||
|
of RelationPlantIds
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!HasDiscoveredPlant(
|
||||||
|
MutationEncyclopediaSave,
|
||||||
|
PlantId
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Plant =
|
||||||
|
GetPlantById(
|
||||||
|
PlantId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Plant !== null) {
|
||||||
|
SearchParts.push(
|
||||||
|
Plant.Name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchParts
|
||||||
|
.filter(
|
||||||
|
Value =>
|
||||||
|
Value !== null &&
|
||||||
|
Value !== undefined
|
||||||
|
)
|
||||||
|
.join(" ")
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
.includes(
|
||||||
|
SearchQuery
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CompareMutationEncyclopediaMutations(
|
||||||
|
A,
|
||||||
|
B
|
||||||
|
) {
|
||||||
|
switch (MutationEncyclopediaSortMode) {
|
||||||
|
case "NameAsc":
|
||||||
|
return String(A.Name ?? "")
|
||||||
|
.localeCompare(
|
||||||
|
String(B.Name ?? ""),
|
||||||
|
undefined,
|
||||||
|
{sensitivity: "base"}
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "ChanceAsc":
|
||||||
|
return CompareMutationEncyclopediaNumbers(
|
||||||
|
A.Chance,
|
||||||
|
B.Chance,
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "ChanceDesc":
|
||||||
|
return CompareMutationEncyclopediaNumbers(
|
||||||
|
A.Chance,
|
||||||
|
B.Chance,
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "CooldownAsc":
|
||||||
|
return CompareMutationEncyclopediaNumbers(
|
||||||
|
A.Cooldown,
|
||||||
|
B.Cooldown,
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "CooldownDesc":
|
||||||
|
return CompareMutationEncyclopediaNumbers(
|
||||||
|
A.Cooldown,
|
||||||
|
B.Cooldown,
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "IdAsc":
|
||||||
|
default:
|
||||||
|
return A.Id - B.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CompareMutationEncyclopediaNumbers(
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
Direction
|
||||||
|
) {
|
||||||
|
const MissingA =
|
||||||
|
A === null ||
|
||||||
|
A === undefined ||
|
||||||
|
A === "";
|
||||||
|
|
||||||
|
const MissingB =
|
||||||
|
B === null ||
|
||||||
|
B === undefined ||
|
||||||
|
B === "";
|
||||||
|
|
||||||
|
const NumberA = Number(A);
|
||||||
|
const NumberB = Number(B);
|
||||||
|
|
||||||
|
const ValidA =
|
||||||
|
!MissingA &&
|
||||||
|
Number.isFinite(NumberA);
|
||||||
|
|
||||||
|
const ValidB =
|
||||||
|
!MissingB &&
|
||||||
|
Number.isFinite(NumberB);
|
||||||
|
|
||||||
|
if (!ValidA && !ValidB) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidA) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidB) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NumberA - NumberB) *
|
||||||
|
Direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function HasUsableMutationHint(
|
function HasUsableMutationHint(
|
||||||
Mutation
|
Mutation
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
let PlantEncyclopediaSave;
|
let PlantEncyclopediaSave;
|
||||||
|
let PlantEncyclopediaSearchQuery = "";
|
||||||
|
let PlantEncyclopediaSortMode = "IdAsc";
|
||||||
|
|
||||||
|
|
||||||
async function StartPlantEncyclopedia() {
|
async function StartPlantEncyclopedia() {
|
||||||
@@ -7,6 +9,7 @@ async function StartPlantEncyclopedia() {
|
|||||||
PlantEncyclopediaSave =
|
PlantEncyclopediaSave =
|
||||||
await LoadGame();
|
await LoadGame();
|
||||||
|
|
||||||
|
BindPlantEncyclopediaControls();
|
||||||
RenderPlantEncyclopedia();
|
RenderPlantEncyclopedia();
|
||||||
} catch (Error) {
|
} catch (Error) {
|
||||||
console.error(
|
console.error(
|
||||||
@@ -21,6 +24,51 @@ async function StartPlantEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function BindPlantEncyclopediaControls() {
|
||||||
|
const SearchInput =
|
||||||
|
document.getElementById(
|
||||||
|
"PlantEncyclopediaSearchInput"
|
||||||
|
);
|
||||||
|
|
||||||
|
const SortSelect =
|
||||||
|
document.getElementById(
|
||||||
|
"PlantEncyclopediaSortSelect"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (SearchInput !== null) {
|
||||||
|
SearchInput.value =
|
||||||
|
PlantEncyclopediaSearchQuery;
|
||||||
|
|
||||||
|
SearchInput.addEventListener(
|
||||||
|
"input",
|
||||||
|
() => {
|
||||||
|
PlantEncyclopediaSearchQuery =
|
||||||
|
SearchInput.value;
|
||||||
|
|
||||||
|
RenderPlantEncyclopedia();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (SortSelect !== null) {
|
||||||
|
SortSelect.value =
|
||||||
|
PlantEncyclopediaSortMode;
|
||||||
|
|
||||||
|
SortSelect.addEventListener(
|
||||||
|
"change",
|
||||||
|
() => {
|
||||||
|
PlantEncyclopediaSortMode =
|
||||||
|
SortSelect.value;
|
||||||
|
|
||||||
|
RenderPlantEncyclopedia();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function RenderPlantEncyclopedia() {
|
function RenderPlantEncyclopedia() {
|
||||||
const List =
|
const List =
|
||||||
document.getElementById(
|
document.getElementById(
|
||||||
@@ -38,16 +86,28 @@ function RenderPlantEncyclopedia() {
|
|||||||
PlantEncyclopediaSave,
|
PlantEncyclopediaSave,
|
||||||
Plant.Id
|
Plant.Id
|
||||||
)
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const SearchQuery =
|
||||||
|
PlantEncyclopediaSearchQuery
|
||||||
|
.trim()
|
||||||
|
.toLocaleLowerCase();
|
||||||
|
|
||||||
|
const VisiblePlants =
|
||||||
|
DiscoveredPlants
|
||||||
|
.filter(
|
||||||
|
Plant =>
|
||||||
|
DoesPlantEncyclopediaMatchSearch(
|
||||||
|
Plant,
|
||||||
|
SearchQuery
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.sort(
|
.sort(
|
||||||
(A, B) =>
|
ComparePlantEncyclopediaPlants
|
||||||
A.Id - B.Id
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if (
|
if (DiscoveredPlants.length === 0) {
|
||||||
DiscoveredPlants.length === 0
|
|
||||||
) {
|
|
||||||
SetPlantEncyclopediaMessage(
|
SetPlantEncyclopediaMessage(
|
||||||
"No plants discovered yet."
|
"No plants discovered yet."
|
||||||
);
|
);
|
||||||
@@ -56,9 +116,18 @@ function RenderPlantEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (VisiblePlants.length === 0) {
|
||||||
|
SetPlantEncyclopediaMessage(
|
||||||
|
"No discovered plants match your search."
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (
|
for (
|
||||||
const Plant
|
const Plant
|
||||||
of DiscoveredPlants
|
of VisiblePlants
|
||||||
) {
|
) {
|
||||||
List.appendChild(
|
List.appendChild(
|
||||||
CreatePlantEncyclopediaCard(
|
CreatePlantEncyclopediaCard(
|
||||||
@@ -68,6 +137,21 @@ function RenderPlantEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (SearchQuery.length > 0) {
|
||||||
|
SetPlantEncyclopediaMessage(
|
||||||
|
"Showing " +
|
||||||
|
VisiblePlants.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" of " +
|
||||||
|
DiscoveredPlants.length
|
||||||
|
.toLocaleString() +
|
||||||
|
" discovered plants."
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SetPlantEncyclopediaMessage(
|
SetPlantEncyclopediaMessage(
|
||||||
DiscoveredPlants.length === 1
|
DiscoveredPlants.length === 1
|
||||||
? "1 plant discovered."
|
? "1 plant discovered."
|
||||||
@@ -78,6 +162,190 @@ function RenderPlantEncyclopedia() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function DoesPlantEncyclopediaMatchSearch(
|
||||||
|
Plant,
|
||||||
|
SearchQuery
|
||||||
|
) {
|
||||||
|
if (SearchQuery.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchParts = [
|
||||||
|
Plant.Id,
|
||||||
|
Plant.Name,
|
||||||
|
Plant.Description,
|
||||||
|
...(Array.isArray(Plant.Tags)
|
||||||
|
? Plant.Tags
|
||||||
|
: [])
|
||||||
|
];
|
||||||
|
|
||||||
|
for (
|
||||||
|
const Mutation
|
||||||
|
of GetPlantRelatedMutations(
|
||||||
|
Plant.Id,
|
||||||
|
"PlantsCreated"
|
||||||
|
).concat(
|
||||||
|
GetPlantRelatedMutations(
|
||||||
|
Plant.Id,
|
||||||
|
"PlantsUsed"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
HasDiscoveredMutation(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
Mutation.Id
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
SearchParts.push(
|
||||||
|
Mutation.Name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchParts
|
||||||
|
.filter(
|
||||||
|
Value =>
|
||||||
|
Value !== null &&
|
||||||
|
Value !== undefined
|
||||||
|
)
|
||||||
|
.join(" ")
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
.includes(
|
||||||
|
SearchQuery
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ComparePlantEncyclopediaPlants(
|
||||||
|
A,
|
||||||
|
B
|
||||||
|
) {
|
||||||
|
switch (PlantEncyclopediaSortMode) {
|
||||||
|
case "NameAsc":
|
||||||
|
return String(A.Name ?? "")
|
||||||
|
.localeCompare(
|
||||||
|
String(B.Name ?? ""),
|
||||||
|
undefined,
|
||||||
|
{sensitivity: "base"}
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "GrowthAsc":
|
||||||
|
return ComparePlantEncyclopediaNumbers(
|
||||||
|
A.GrowthTime,
|
||||||
|
B.GrowthTime,
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "GrowthDesc":
|
||||||
|
return ComparePlantEncyclopediaNumbers(
|
||||||
|
A.GrowthTime,
|
||||||
|
B.GrowthTime,
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "RewardAsc":
|
||||||
|
return ComparePlantEncyclopediaNumbers(
|
||||||
|
GetPlantHarvestReward(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
A.Id
|
||||||
|
),
|
||||||
|
GetPlantHarvestReward(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
B.Id
|
||||||
|
),
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "RewardDesc":
|
||||||
|
return ComparePlantEncyclopediaNumbers(
|
||||||
|
GetPlantHarvestReward(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
A.Id
|
||||||
|
),
|
||||||
|
GetPlantHarvestReward(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
B.Id
|
||||||
|
),
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "DphAsc":
|
||||||
|
return ComparePlantEncyclopediaNumbers(
|
||||||
|
GetPlantDewPerHour(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
A.Id
|
||||||
|
),
|
||||||
|
GetPlantDewPerHour(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
B.Id
|
||||||
|
),
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "DphDesc":
|
||||||
|
return ComparePlantEncyclopediaNumbers(
|
||||||
|
GetPlantDewPerHour(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
A.Id
|
||||||
|
),
|
||||||
|
GetPlantDewPerHour(
|
||||||
|
PlantEncyclopediaSave,
|
||||||
|
B.Id
|
||||||
|
),
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "IdAsc":
|
||||||
|
default:
|
||||||
|
return A.Id - B.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ComparePlantEncyclopediaNumbers(
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
Direction
|
||||||
|
) {
|
||||||
|
const MissingA =
|
||||||
|
A === null ||
|
||||||
|
A === undefined ||
|
||||||
|
A === "";
|
||||||
|
|
||||||
|
const MissingB =
|
||||||
|
B === null ||
|
||||||
|
B === undefined ||
|
||||||
|
B === "";
|
||||||
|
|
||||||
|
const NumberA = Number(A);
|
||||||
|
const NumberB = Number(B);
|
||||||
|
|
||||||
|
const ValidA =
|
||||||
|
!MissingA &&
|
||||||
|
Number.isFinite(NumberA);
|
||||||
|
|
||||||
|
const ValidB =
|
||||||
|
!MissingB &&
|
||||||
|
Number.isFinite(NumberB);
|
||||||
|
|
||||||
|
if (!ValidA && !ValidB) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidA) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidB) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NumberA - NumberB) *
|
||||||
|
Direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function CreatePlantEncyclopediaCard(
|
function CreatePlantEncyclopediaCard(
|
||||||
Plant
|
Plant
|
||||||
) {
|
) {
|
||||||
|
|||||||
+272
-16
@@ -1,5 +1,7 @@
|
|||||||
let ShopSave;
|
let ShopSave;
|
||||||
let ShopPurchasePending = false;
|
let ShopPurchasePending = false;
|
||||||
|
let ShopSeedSearchQuery = "";
|
||||||
|
let ShopSeedSortMode = "IdAsc";
|
||||||
|
|
||||||
|
|
||||||
async function StartShop() {
|
async function StartShop() {
|
||||||
@@ -22,6 +24,7 @@ async function StartShop() {
|
|||||||
ShopSave = await LoadGame();
|
ShopSave = await LoadGame();
|
||||||
|
|
||||||
BindShopSectionToggles();
|
BindShopSectionToggles();
|
||||||
|
BindShopSeedControls();
|
||||||
RenderShop();
|
RenderShop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +87,51 @@ function BindShopSectionToggle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function BindShopSeedControls() {
|
||||||
|
const SearchInput =
|
||||||
|
document.getElementById(
|
||||||
|
"ShopSeedSearchInput"
|
||||||
|
);
|
||||||
|
|
||||||
|
const SortSelect =
|
||||||
|
document.getElementById(
|
||||||
|
"ShopSeedSortSelect"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (SearchInput !== null) {
|
||||||
|
SearchInput.value =
|
||||||
|
ShopSeedSearchQuery;
|
||||||
|
|
||||||
|
SearchInput.addEventListener(
|
||||||
|
"input",
|
||||||
|
() => {
|
||||||
|
ShopSeedSearchQuery =
|
||||||
|
SearchInput.value;
|
||||||
|
|
||||||
|
RenderShopSeeds();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (SortSelect !== null) {
|
||||||
|
SortSelect.value =
|
||||||
|
ShopSeedSortMode;
|
||||||
|
|
||||||
|
SortSelect.addEventListener(
|
||||||
|
"change",
|
||||||
|
() => {
|
||||||
|
ShopSeedSortMode =
|
||||||
|
SortSelect.value;
|
||||||
|
|
||||||
|
RenderShopSeeds();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function RenderShop() {
|
function RenderShop() {
|
||||||
RenderShopCurrency();
|
RenderShopCurrency();
|
||||||
RenderShopSeeds();
|
RenderShopSeeds();
|
||||||
@@ -124,29 +172,41 @@ function RenderShopSeeds() {
|
|||||||
ShopSave,
|
ShopSave,
|
||||||
Plant
|
Plant
|
||||||
)
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const SearchQuery =
|
||||||
|
ShopSeedSearchQuery
|
||||||
|
.trim()
|
||||||
|
.toLocaleLowerCase();
|
||||||
|
|
||||||
|
const VisiblePlants =
|
||||||
|
AvailablePlants
|
||||||
|
.filter(
|
||||||
|
Plant =>
|
||||||
|
DoesShopPlantMatchSearch(
|
||||||
|
Plant,
|
||||||
|
SearchQuery
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.sort(
|
.sort(
|
||||||
(A, B) =>
|
CompareShopPlants
|
||||||
A.Id - B.Id
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if (
|
if (AvailablePlants.length === 0) {
|
||||||
AvailablePlants.length === 0
|
AppendShopSeedEmptyMessage(
|
||||||
) {
|
SeedList,
|
||||||
const EmptyMessage =
|
"No seeds are available yet."
|
||||||
document.createElement(
|
);
|
||||||
"p"
|
|
||||||
);
|
|
||||||
|
|
||||||
EmptyMessage.className =
|
return;
|
||||||
"ShopEmpty";
|
}
|
||||||
|
|
||||||
EmptyMessage.textContent =
|
|
||||||
"No seeds are available yet.";
|
|
||||||
|
|
||||||
SeedList.appendChild(
|
if (VisiblePlants.length === 0) {
|
||||||
EmptyMessage
|
AppendShopSeedEmptyMessage(
|
||||||
|
SeedList,
|
||||||
|
"No seeds match your search."
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -155,7 +215,7 @@ function RenderShopSeeds() {
|
|||||||
|
|
||||||
for (
|
for (
|
||||||
const Plant
|
const Plant
|
||||||
of AvailablePlants
|
of VisiblePlants
|
||||||
) {
|
) {
|
||||||
SeedList.appendChild(
|
SeedList.appendChild(
|
||||||
CreateShopSeedCard(
|
CreateShopSeedCard(
|
||||||
@@ -166,6 +226,202 @@ function RenderShopSeeds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function AppendShopSeedEmptyMessage(
|
||||||
|
SeedList,
|
||||||
|
Message
|
||||||
|
) {
|
||||||
|
const EmptyMessage =
|
||||||
|
document.createElement(
|
||||||
|
"p"
|
||||||
|
);
|
||||||
|
|
||||||
|
EmptyMessage.className =
|
||||||
|
"ShopEmpty";
|
||||||
|
|
||||||
|
EmptyMessage.textContent =
|
||||||
|
Message;
|
||||||
|
|
||||||
|
SeedList.appendChild(
|
||||||
|
EmptyMessage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function DoesShopPlantMatchSearch(
|
||||||
|
Plant,
|
||||||
|
SearchQuery
|
||||||
|
) {
|
||||||
|
if (SearchQuery.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchParts = [
|
||||||
|
Plant.Id,
|
||||||
|
Plant.Name,
|
||||||
|
Plant.Description,
|
||||||
|
...(Array.isArray(Plant.Tags)
|
||||||
|
? Plant.Tags
|
||||||
|
: [])
|
||||||
|
];
|
||||||
|
|
||||||
|
return SearchParts
|
||||||
|
.filter(
|
||||||
|
Value =>
|
||||||
|
Value !== null &&
|
||||||
|
Value !== undefined
|
||||||
|
)
|
||||||
|
.join(" ")
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
.includes(
|
||||||
|
SearchQuery
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CompareShopPlants(
|
||||||
|
A,
|
||||||
|
B
|
||||||
|
) {
|
||||||
|
switch (ShopSeedSortMode) {
|
||||||
|
case "NameAsc":
|
||||||
|
return CompareShopText(
|
||||||
|
A.Name,
|
||||||
|
B.Name
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "PriceAsc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetPlantShopCost(ShopSave, A.Id),
|
||||||
|
GetPlantShopCost(ShopSave, B.Id),
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "PriceDesc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetPlantShopCost(ShopSave, A.Id),
|
||||||
|
GetPlantShopCost(ShopSave, B.Id),
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "GrowthAsc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
A.GrowthTime,
|
||||||
|
B.GrowthTime,
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "GrowthDesc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
A.GrowthTime,
|
||||||
|
B.GrowthTime,
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "RewardAsc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetPlantHarvestReward(ShopSave, A.Id),
|
||||||
|
GetPlantHarvestReward(ShopSave, B.Id),
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "RewardDesc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetPlantHarvestReward(ShopSave, A.Id),
|
||||||
|
GetPlantHarvestReward(ShopSave, B.Id),
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "DphAsc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetPlantDewPerHour(ShopSave, A.Id),
|
||||||
|
GetPlantDewPerHour(ShopSave, B.Id),
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "DphDesc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetPlantDewPerHour(ShopSave, A.Id),
|
||||||
|
GetPlantDewPerHour(ShopSave, B.Id),
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "InventoryAsc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetSeedCount(ShopSave, A.Id),
|
||||||
|
GetSeedCount(ShopSave, B.Id),
|
||||||
|
1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "InventoryDesc":
|
||||||
|
return CompareShopNumbers(
|
||||||
|
GetSeedCount(ShopSave, A.Id),
|
||||||
|
GetSeedCount(ShopSave, B.Id),
|
||||||
|
-1
|
||||||
|
) || A.Id - B.Id;
|
||||||
|
|
||||||
|
case "IdAsc":
|
||||||
|
default:
|
||||||
|
return A.Id - B.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CompareShopText(
|
||||||
|
A,
|
||||||
|
B
|
||||||
|
) {
|
||||||
|
return String(A ?? "")
|
||||||
|
.localeCompare(
|
||||||
|
String(B ?? ""),
|
||||||
|
undefined,
|
||||||
|
{sensitivity: "base"}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function CompareShopNumbers(
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
Direction
|
||||||
|
) {
|
||||||
|
const MissingA =
|
||||||
|
A === null ||
|
||||||
|
A === undefined ||
|
||||||
|
A === "";
|
||||||
|
|
||||||
|
const MissingB =
|
||||||
|
B === null ||
|
||||||
|
B === undefined ||
|
||||||
|
B === "";
|
||||||
|
|
||||||
|
const NumberA = Number(A);
|
||||||
|
const NumberB = Number(B);
|
||||||
|
|
||||||
|
const ValidA =
|
||||||
|
!MissingA &&
|
||||||
|
Number.isFinite(NumberA);
|
||||||
|
|
||||||
|
const ValidB =
|
||||||
|
!MissingB &&
|
||||||
|
Number.isFinite(NumberB);
|
||||||
|
|
||||||
|
if (!ValidA && !ValidB) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidA) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidB) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NumberA - NumberB) *
|
||||||
|
Direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function RenderGardenUpgrades() {
|
function RenderGardenUpgrades() {
|
||||||
const UpgradeList =
|
const UpgradeList =
|
||||||
document.getElementById(
|
document.getElementById(
|
||||||
|
|||||||
+46
-2
@@ -1210,6 +1210,50 @@ input, button, textarea, select {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.CatalogueControls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) minmax(0, 14rem);
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.CatalogueControls input, .CatalogueControls select {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0.65rem 0.75rem;
|
||||||
|
color: var(--Text);
|
||||||
|
background-color: var(--Mantle);
|
||||||
|
border: 3px solid var(--Surface2);
|
||||||
|
border-radius: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
box-shadow: 3px 3px 0 var(--Crust);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CatalogueControls input::placeholder {
|
||||||
|
color: var(--Overlay1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CatalogueControls input:hover, .CatalogueControls select:hover {
|
||||||
|
border-color: var(--Sky);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CatalogueControls input:focus, .CatalogueControls select:focus {
|
||||||
|
outline: 3px solid var(--Yellow);
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.CatalogueControls select {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 500px) {
|
||||||
|
.CatalogueControls {
|
||||||
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ShopSeedList {
|
.ShopSeedList {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat( auto-fit, minmax(15rem, 1fr) );
|
grid-template-columns: repeat( auto-fit, minmax(15rem, 1fr) );
|
||||||
@@ -1450,7 +1494,7 @@ input, button, textarea, select {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin-top: 1.5rem;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.PlantEncyclopediaCard {
|
.PlantEncyclopediaCard {
|
||||||
@@ -1594,7 +1638,7 @@ input, button, textarea, select {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin-top: 1.5rem;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MutationEncyclopediaCard {
|
.MutationEncyclopediaCard {
|
||||||
|
|||||||
Reference in new issue
Block a user