diff --git a/app/(wiki)/perks/[item]/page.tsx b/app/(wiki)/perks/[item]/page.tsx
index e69de29b..da1bc2b5 100644
--- a/app/(wiki)/perks/[item]/page.tsx
+++ b/app/(wiki)/perks/[item]/page.tsx
@@ -0,0 +1,13 @@
+import GenericArticlePage from "@/components/generics/GenericArticlePage";
+import PerkSidebar from "@/components/sidebars/PerkSidebar";
+import { Perks } from "@/vendor/suroi/common/src/definitions/perks";
+
+const toExport = GenericArticlePage({
+ items: Perks.definitions,
+ path: "perks",
+ Sidebar: PerkSidebar,
+ combinedArticles: []
+});
+
+export const { generateMetadata, generateStaticParams } = toExport;
+export default toExport.default;
diff --git a/app/(wiki)/perks/page.tsx b/app/(wiki)/perks/page.tsx
index e69de29b..d5467c23 100644
--- a/app/(wiki)/perks/page.tsx
+++ b/app/(wiki)/perks/page.tsx
@@ -0,0 +1,18 @@
+import GenericListingPageFactory from "@/components/layouts/GenericListingPageFactory";
+import { PerkCategories, PerkQualities, Perks } from "@/vendor/suroi/common/src/definitions/perks";
+
+const perkDefs = Perks.definitions;
+const normalPerks = perkDefs.filter(perk => perk.categories[0] === PerkCategories.Normal);
+const halloweenPerks = perkDefs.filter(perk => perk.categories[0] === PerkCategories.Halloween);
+const halloweenPerkCountOfType = (type: PerkQualities): number => halloweenPerks.filter(perk => perk.type === type).length;
+
+export default GenericListingPageFactory(
+ perkDefs,
+ "Perks",
+ "/perks",
+ `There are currently ${perkDefs.length} perks in the game.
+ ${normalPerks.length} of these are normal perks, and ${halloweenPerks.length} are Halloween perks.
+ All normal perks are positive.
+ Of the Halloween perks, ${halloweenPerkCountOfType(PerkQualities.Positive)} are positive, ${halloweenPerkCountOfType(PerkQualities.Neutral)} are neutral, and ${halloweenPerkCountOfType(PerkQualities.Negative)} are negative.
+ `
+);
diff --git a/app/page.tsx b/app/page.tsx
index e47c64c2..ba58df0a 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -73,7 +73,7 @@ export default async function Home() {
Wiki Pages
- {wikiPages.map(page => (
+ {wikiPages.filter(page => page.name !== "Home").map(page => (
+ Basic Info
+
+ {category}
+ {type}
+
+
+ {item.noDrop ? "No" : "Yes"}
+ {item.noSwap ? "No" : "Yes"}
+
+
+ {modifiers.some(([prop]) => prop in item) && (
+ <>
+ Stats & Modifiers
+
+ {modifiers.map(([prop, name]) => prop in item && {Math.round(item[prop as keyof PerkDefinition] as number * 100) / 100}{prop === "updateInterval" || prop === "speedBoostDuration" ? "ms" : ""})}
+
+ >
+ )}
+
+ Advanced Stats
+
+
+ {item.idString}
+
+
+
+ );
+}
diff --git a/lib/util/search.ts b/lib/util/search.ts
index 48e2c29b..dc4b335d 100644
--- a/lib/util/search.ts
+++ b/lib/util/search.ts
@@ -1,13 +1,14 @@
+import { Armors, Backpacks, Buildings, HealingItems } from "@/vendor/suroi/common/src/definitions";
import { Guns } from "@/vendor/suroi/common/src/definitions/guns";
import { Melees } from "@/vendor/suroi/common/src/definitions/melees";
import { Obstacles } from "@/vendor/suroi/common/src/definitions/obstacles";
+import { Perks } from "@/vendor/suroi/common/src/definitions/perks";
import {
ObjectDefinition,
ObjectDefinitions
} from "@/vendor/suroi/common/src/utils/objectDefinitions";
import {
- LootTables,
- LootTiers
+ LootTables
} from "@/vendor/suroi/server/src/data/lootTables";
import {
IMAGE_BASE_URL,
@@ -73,6 +74,12 @@ export const wikiPages: SearchItem[] = [
description: "List of buildings",
image: getSuroiImageLink(getSuroiBuilding("red_house"))
},
+ {
+ name: "Perks",
+ url: "/perks",
+ description: "List of perks",
+ image: getSuroiImageLink(getSuroiItem("advanced_athletics"))
+ },
{
name: "Skins",
url: "/skins",
@@ -113,7 +120,12 @@ export const SearchItems: SearchItem[] = [
...wikiPages,
...generateItemsFromDefinitions(Guns, "/weapons/guns/"),
...generateItemsFromDefinitions(Melees, "/weapons/melee/"),
+ ...generateItemsFromDefinitions(HealingItems, "/healing/"),
+ ...generateItemsFromDefinitions(Armors, "/equipment/armor/"),
+ ...generateItemsFromDefinitions(Backpacks, "/equipment/backpacks/"),
...generateItemsFromDefinitions(Obstacles, "/obstacles/"),
+ ...generateItemsFromDefinitions(Buildings, "/buildings/"),
+ ...generateItemsFromDefinitions(Perks, "/perks/"),
...Object.entries(LootTables).map(([k]) => ({
name: `Loot Table ${k}`,
url: `/loot#${k}`
diff --git a/lib/util/suroi.ts b/lib/util/suroi.ts
index d265f3ab..b28bb598 100644
--- a/lib/util/suroi.ts
+++ b/lib/util/suroi.ts
@@ -50,6 +50,7 @@ export const IMAGE_BASE_URLS = {
Scope: "game/loot",
Skin: "game/skins",
ThrowableProjectile: "game/projectiles/throwables",
+ Perk: "game/perks",
// Objects
Player: "",
diff --git a/vendor/suroi b/vendor/suroi
index 9dec3b7f..0f07dde2 160000
--- a/vendor/suroi
+++ b/vendor/suroi
@@ -1 +1 @@
-Subproject commit 9dec3b7fa7999f67621682a74d9aedcd231f66c5
+Subproject commit 0f07dde26a638f4804d716cb7ec1d32cd49b925a