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.
|
||||
</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
|
||||
id="MutationEncyclopediaList"
|
||||
class="MutationEncyclopediaList"
|
||||
|
||||
@@ -23,6 +23,33 @@ $PageSection = "Plants";
|
||||
them in your Garden.
|
||||
</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
|
||||
id="PlantEncyclopediaList"
|
||||
class="PlantEncyclopediaList"
|
||||
|
||||
@@ -95,6 +95,37 @@ $PageSection = "Shop";
|
||||
id="SeedsContent"
|
||||
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
|
||||
id="ShopSeedList"
|
||||
class="ShopSeedList"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
let MutationEncyclopediaSave;
|
||||
let MutationEncyclopediaSearchQuery = "";
|
||||
let MutationEncyclopediaSortMode = "IdAsc";
|
||||
|
||||
|
||||
async function StartMutationEncyclopedia() {
|
||||
@@ -8,6 +10,7 @@ async function StartMutationEncyclopedia() {
|
||||
MutationEncyclopediaSave =
|
||||
await LoadGame();
|
||||
|
||||
BindMutationEncyclopediaControls();
|
||||
RenderMutationEncyclopedia();
|
||||
} catch (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() {
|
||||
const List =
|
||||
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 (
|
||||
const Mutation
|
||||
of AvailableHints
|
||||
of VisibleHints
|
||||
) {
|
||||
List.appendChild(
|
||||
CreateMutationHintCard(
|
||||
@@ -84,7 +159,7 @@ function RenderMutationEncyclopedia() {
|
||||
|
||||
for (
|
||||
const Mutation
|
||||
of DiscoveredMutations
|
||||
of VisibleMutations
|
||||
) {
|
||||
List.appendChild(
|
||||
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 = [];
|
||||
|
||||
MessageParts.push(
|
||||
DiscoveredMutations.length === 1
|
||||
? "1 mutation discovered."
|
||||
: DiscoveredMutations.length
|
||||
.toLocaleString() +
|
||||
" mutations discovered."
|
||||
);
|
||||
|
||||
if (AvailableHints.length > 0) {
|
||||
if (SearchQuery.length > 0) {
|
||||
MessageParts.push(
|
||||
AvailableHints.length === 1
|
||||
? "1 hint available."
|
||||
: AvailableHints.length
|
||||
.toLocaleString() +
|
||||
" hints available."
|
||||
"Showing " +
|
||||
VisibleMutations.length
|
||||
.toLocaleString() +
|
||||
" of " +
|
||||
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(
|
||||
@@ -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(
|
||||
Mutation
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
let PlantEncyclopediaSave;
|
||||
let PlantEncyclopediaSearchQuery = "";
|
||||
let PlantEncyclopediaSortMode = "IdAsc";
|
||||
|
||||
|
||||
async function StartPlantEncyclopedia() {
|
||||
@@ -7,6 +9,7 @@ async function StartPlantEncyclopedia() {
|
||||
PlantEncyclopediaSave =
|
||||
await LoadGame();
|
||||
|
||||
BindPlantEncyclopediaControls();
|
||||
RenderPlantEncyclopedia();
|
||||
} catch (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() {
|
||||
const List =
|
||||
document.getElementById(
|
||||
@@ -38,16 +86,28 @@ function RenderPlantEncyclopedia() {
|
||||
PlantEncyclopediaSave,
|
||||
Plant.Id
|
||||
)
|
||||
);
|
||||
|
||||
const SearchQuery =
|
||||
PlantEncyclopediaSearchQuery
|
||||
.trim()
|
||||
.toLocaleLowerCase();
|
||||
|
||||
const VisiblePlants =
|
||||
DiscoveredPlants
|
||||
.filter(
|
||||
Plant =>
|
||||
DoesPlantEncyclopediaMatchSearch(
|
||||
Plant,
|
||||
SearchQuery
|
||||
)
|
||||
)
|
||||
.sort(
|
||||
(A, B) =>
|
||||
A.Id - B.Id
|
||||
ComparePlantEncyclopediaPlants
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
DiscoveredPlants.length === 0
|
||||
) {
|
||||
if (DiscoveredPlants.length === 0) {
|
||||
SetPlantEncyclopediaMessage(
|
||||
"No plants discovered yet."
|
||||
);
|
||||
@@ -56,9 +116,18 @@ function RenderPlantEncyclopedia() {
|
||||
}
|
||||
|
||||
|
||||
if (VisiblePlants.length === 0) {
|
||||
SetPlantEncyclopediaMessage(
|
||||
"No discovered plants match your search."
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (
|
||||
const Plant
|
||||
of DiscoveredPlants
|
||||
of VisiblePlants
|
||||
) {
|
||||
List.appendChild(
|
||||
CreatePlantEncyclopediaCard(
|
||||
@@ -68,6 +137,21 @@ function RenderPlantEncyclopedia() {
|
||||
}
|
||||
|
||||
|
||||
if (SearchQuery.length > 0) {
|
||||
SetPlantEncyclopediaMessage(
|
||||
"Showing " +
|
||||
VisiblePlants.length
|
||||
.toLocaleString() +
|
||||
" of " +
|
||||
DiscoveredPlants.length
|
||||
.toLocaleString() +
|
||||
" discovered plants."
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetPlantEncyclopediaMessage(
|
||||
DiscoveredPlants.length === 1
|
||||
? "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(
|
||||
Plant
|
||||
) {
|
||||
|
||||
+272
-16
@@ -1,5 +1,7 @@
|
||||
let ShopSave;
|
||||
let ShopPurchasePending = false;
|
||||
let ShopSeedSearchQuery = "";
|
||||
let ShopSeedSortMode = "IdAsc";
|
||||
|
||||
|
||||
async function StartShop() {
|
||||
@@ -22,6 +24,7 @@ async function StartShop() {
|
||||
ShopSave = await LoadGame();
|
||||
|
||||
BindShopSectionToggles();
|
||||
BindShopSeedControls();
|
||||
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() {
|
||||
RenderShopCurrency();
|
||||
RenderShopSeeds();
|
||||
@@ -124,29 +172,41 @@ function RenderShopSeeds() {
|
||||
ShopSave,
|
||||
Plant
|
||||
)
|
||||
);
|
||||
|
||||
const SearchQuery =
|
||||
ShopSeedSearchQuery
|
||||
.trim()
|
||||
.toLocaleLowerCase();
|
||||
|
||||
const VisiblePlants =
|
||||
AvailablePlants
|
||||
.filter(
|
||||
Plant =>
|
||||
DoesShopPlantMatchSearch(
|
||||
Plant,
|
||||
SearchQuery
|
||||
)
|
||||
)
|
||||
.sort(
|
||||
(A, B) =>
|
||||
A.Id - B.Id
|
||||
CompareShopPlants
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
AvailablePlants.length === 0
|
||||
) {
|
||||
const EmptyMessage =
|
||||
document.createElement(
|
||||
"p"
|
||||
);
|
||||
if (AvailablePlants.length === 0) {
|
||||
AppendShopSeedEmptyMessage(
|
||||
SeedList,
|
||||
"No seeds are available yet."
|
||||
);
|
||||
|
||||
EmptyMessage.className =
|
||||
"ShopEmpty";
|
||||
return;
|
||||
}
|
||||
|
||||
EmptyMessage.textContent =
|
||||
"No seeds are available yet.";
|
||||
|
||||
SeedList.appendChild(
|
||||
EmptyMessage
|
||||
if (VisiblePlants.length === 0) {
|
||||
AppendShopSeedEmptyMessage(
|
||||
SeedList,
|
||||
"No seeds match your search."
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -155,7 +215,7 @@ function RenderShopSeeds() {
|
||||
|
||||
for (
|
||||
const Plant
|
||||
of AvailablePlants
|
||||
of VisiblePlants
|
||||
) {
|
||||
SeedList.appendChild(
|
||||
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() {
|
||||
const UpgradeList =
|
||||
document.getElementById(
|
||||
|
||||
+46
-2
@@ -1210,6 +1210,50 @@ input, button, textarea, select {
|
||||
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 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat( auto-fit, minmax(15rem, 1fr) );
|
||||
@@ -1450,7 +1494,7 @@ input, button, textarea, select {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.PlantEncyclopediaCard {
|
||||
@@ -1594,7 +1638,7 @@ input, button, textarea, select {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.MutationEncyclopediaCard {
|
||||
|
||||
Reference in new issue
Block a user