diff --git a/src/app/(stats)/player/[ign]/_client.tsx b/src/app/(stats)/player/[ign]/_client.tsx index 8334240..4979beb 100644 --- a/src/app/(stats)/player/[ign]/_client.tsx +++ b/src/app/(stats)/player/[ign]/_client.tsx @@ -26,6 +26,7 @@ import SmashHerosStats from "./_stats/smashheros/smashheros" import SpeedUHCStats from "./_stats/speeduhc/speeduhc" import TNTGamesStats from "./_stats/tnt-games/tnt-games" import UHCStats from "./_stats/uhc/uhc" +import WarlordsStats from "./_stats/warlords/warlords" import WoolGamesStats from "./_stats/woolgames/woolgames" export function PlayerPageLoadText() { @@ -96,7 +97,8 @@ export function PlayerStats( "blitz": , "arcade": , "speeduhc": , - "smashheros": + "smashheros": , + "warlords": } as const const defaultOrder = Object.keys(statsComponents) diff --git a/src/app/(stats)/player/[ign]/_stats/warlords/stats.tsx b/src/app/(stats)/player/[ign]/_stats/warlords/stats.tsx new file mode 100644 index 0000000..c5055a4 --- /dev/null +++ b/src/app/(stats)/player/[ign]/_stats/warlords/stats.tsx @@ -0,0 +1,39 @@ +import { formatNumber } from "@/lib/formatters" +import { devide } from "@/lib/hypixel/general" +import { getWarlordsLosses } from "@/lib/hypixel/warlords/general" +import { NonNullStats } from "@/lib/schema/player" +import { BasicStat } from "../../_components/Stats" + +export default function WarlordsGeneralStats({ stats }: { stats: NonNullable }) { + const losses = getWarlordsLosses(stats) + const wl = formatNumber(devide(stats.wins, losses)) + const kd = formatNumber(devide(stats.kills, stats.deaths)) + const ak = formatNumber(devide(stats.assists, stats.kills)) + return ( +
+
+ + + +

+
+

+ + + +
+
+ + + + + +

+
+

+ + +
+
+ ) +} diff --git a/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx b/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx new file mode 100644 index 0000000..74579fc --- /dev/null +++ b/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx @@ -0,0 +1,44 @@ +import { Separator } from "@/components/ui/separator" +import { formatNumber } from "@/lib/formatters" +import { devide } from "@/lib/hypixel/general" +import { getWarlordsLosses, getWarlordsMostPlayedClass } from "@/lib/hypixel/warlords/general" +import { NonNullStats } from "@/lib/schema/player" +import GeneralStats from "../GeneralStats" +import WarlordsGeneralStats from "./stats" + +export default function WarlordsStats({ stats }: { stats: NonNullStats["Warlords"] }) { + if (!stats) return null + + const losses = getWarlordsLosses(stats) + const kd = formatNumber(devide(stats.kills, stats.deaths)) + const wl = formatNumber(devide(stats.wins, losses)) + const mostPlayed = getWarlordsMostPlayedClass(stats) + + return ( + Main

, + stat:

{mostPlayed !== null ? mostPlayed.name : "Unknown"}

+ }, + { + title:

KD

, + stat:

{kd}

+ }, + { + title:

Wins

, + stat:

{formatNumber(stats.wins)}

+ }, + { + title:

WL

, + stat:

{wl}

+ } + ]} + > + + +
+ ) +} diff --git a/src/data/hypixel/warlords.ts b/src/data/hypixel/warlords.ts new file mode 100644 index 0000000..d30eec9 --- /dev/null +++ b/src/data/hypixel/warlords.ts @@ -0,0 +1,114 @@ +export const CLASSES = [ + { id: "mage", name: "Mage" }, + { id: "paladin", name: "Paladin" }, + { id: "shaman", name: "Shaman" }, + { id: "warrior", name: "Warrior" }, + { id: "", name: "Overall" } +] as const +export const MODES = [ + { id: "capturetheflag", name: "Capture the Flag" }, + { id: "domination", name: "Domination" }, + { id: "teamdeathmatch", name: "Team Deathmatch" }, + { id: "", name: "Overall" } +] as const +export const RARITIES = [ + { id: "common", name: "Common", color: "green" }, + { id: "rare", name: "Rare", color: "blue" }, + { id: "epic", name: "Epic", color: "purple" }, + { id: "legendary", name: "Legendary", color: "gold" } +] as const +export const UPGRADES = [ + { id: "cooldown", name: "Cooldown" }, + { id: "critchance", name: "Crit Chance" }, + { id: "critmultiplier", name: "Crit Multiplier" }, + { id: "energy", name: "Energy" }, + { id: "health", name: "Health" }, + { id: "skill1", name: "First Skill" }, + { id: "skill2", name: "Second Skill" }, + { id: "skill3", name: "Third Skill" }, + { id: "skill4", name: "Fourth Skill" }, + { id: "skill5", name: "Ultimate SKill" } +] as const +export const MATERIALS = { + "WOOD_AXE": "Steel Sword", + "STONE_AXE": "Training Sword", + "IRON_AXE": "Demonblade", + "GOLD_AXE": "Venomstrike", + "DIAMOND_AXE": "Diamondspark", + "WOOD_HOE": "Zweireaper", + "STONE_HOE": "Runeblade", + "IRON_HOE": "Elven Greatsword", + "GOLD_HOE": "Hatchet", + "DIAMOND_HOE": "Gem Axe", + "WOOD_SPADE": "Nomegusta", + "STONE_SPADE": "Drakefang", + "IRON_SPADE": "Hammer", + "GOLD_SPADE": "Stone Mallet", + "DIAMOND_SPADE": "Gemcrusher", + "WOOD_PICKAXE": "Abbadon", + "STONE_PICKAXE": "Walking Stick", + "IRON_PICKAXE": "World Tree Branch", + "GOLD_PICKAXE": "Flameweaver", + "DIAMOND_PICKAXE": "Void Twig", + "SALMON": "Scimitar", + "PUFFERFISH": "Golden Gladius", + "CLOWNFISH": "Magmasword", + "COD": "Frostbite", + "ROTTEN_FLESH": "Pike", + "POTATO": "Halberd", + "MELON": "Divine Reach", + "POISONOUS_POTATO": "Ruby Thorn", + "STRING": "Hammer of Light", + "RAW_CHICKEN": "Nethersteel Katana", + "MUTTON": "Claws", + "PORK": "Mandibles", + "RAW_BEEF": "Katar", + "APPLE": "Enderfist", + "PUMPKIN_PIE": "Orc Axe", + "COOKED_COD": "Doubleaxe", + "BREAD": "Runic Axe", + "MUSHROOM_STEW": "Lunar Relic", + "RABBIT_STEW": "Bludgeon", + "COOKED_RABBIT": "Cudgel", + "COOKED_CHICKEN": "Tenderizer", + "BAKED_POTATO": "Broccomace", + "COOKED_SALMON": "Felflame Blade", + "COOKED_MUTTON": "Amaranth", + "COOKED_BEEF": "Armblade", + "GRILLED_PORK": "Gemini", + "COOKED_PORKCHOP": "Gemini", + "GOLDEN_CARROT": "Void Edge" +} as const +export const PLAYERCLASSES = { + mage: ["Pyromancer", "Cryomancer", "Aquamancer"], + warrior: ["Berserker", "Defender", "Revenant"], + paladin: ["Avenger", "Crusader", "Protector"], + shaman: ["Thunderlord", "Earthwarden", "Spiritguard"] +} as const +export const SCORES = { + COMMON: [ + { score: 276, prefix: "Crumbly" }, + { score: 302, prefix: "Flimsy" }, + { score: 327, prefix: "Rough" }, + { score: 352, prefix: "Honed" }, + { score: 378, prefix: "Refined" }, + { score: 403, prefix: "Balanced" } + ], + RARE: [ + { score: 359, prefix: "Savage" }, + { score: 400, prefix: "Vicious" }, + { score: 440, prefix: "Deadly" }, + { score: 481, prefix: "Perfect" } + ], + EPIC: [ + { score: 450, prefix: "Fierce" }, + { score: 489, prefix: "Mighty" }, + { score: 527, prefix: "Brutal" }, + { score: 566, prefix: "Gladiator's" } + ], + LEGENDARY: [ + { score: 595, prefix: "Vanquisher's" }, + { score: 665, prefix: "Champion's" }, + { score: 735, prefix: "Warlord's" } + ] +} as const diff --git a/src/lib/hypixel/warlords/general.ts b/src/lib/hypixel/warlords/general.ts new file mode 100644 index 0000000..8fd39fe --- /dev/null +++ b/src/lib/hypixel/warlords/general.ts @@ -0,0 +1,24 @@ +import { CLASSES } from "@/data/hypixel/warlords" +import { NonNullStats } from "@/lib/schema/player" + +export function getWarlordsLosses(stats: NonNullable) { + return stats.mage_plays + stats.paladin_plays + stats.shaman_plays + stats.warrior_plays - stats.wins +} + +export function getWarlordsMostPlayedClass(stats: NonNullable) { + let mostPlayedClass: typeof CLASSES[number] | null = null + let maxPlays = 0 + + for (const classObj of CLASSES) { + if (classObj.id === "") continue + + const plays = stats[`${classObj.id}_plays`] + + if (plays > maxPlays) { + maxPlays = plays + mostPlayedClass = classObj + } + } + + return mostPlayedClass +} diff --git a/src/lib/schema/player.ts b/src/lib/schema/player.ts index 5a78654..6092b31 100644 --- a/src/lib/schema/player.ts +++ b/src/lib/schema/player.ts @@ -13,6 +13,7 @@ import { smashHerosStats } from "./stats/smashheros" import { speedUhcStatsSchema } from "./stats/speeduhc" import { tntGamesStatsSchema } from "./stats/tnt-games" import { uhcSchema } from "./stats/uhc" +import { warlordsStatsSchema } from "./stats/warlords" import { woolGamesStatsSchema } from "./stats/woolgames" export const playerSchema = z.looseObject({ @@ -42,13 +43,15 @@ export const playerSchema = z.looseObject({ HungerGames: blitzStatsSchema.optional(), Arcade: arcadeStatsSchema.optional(), SpeedUHC: speedUhcStatsSchema.optional(), - SuperSmash: smashHerosStats.optional() - }).transform(({ Walls3, MCGO, HungerGames, SuperSmash, ...rest }) => { + SuperSmash: smashHerosStats.optional(), + Battleground: warlordsStatsSchema.optional() + }).transform(({ Walls3, MCGO, HungerGames, SuperSmash, Battleground, ...rest }) => { return { MegaWalls: Walls3, CopsAndCrims: MCGO, Blitz: HungerGames, SmashHeros: SuperSmash, + Warlords: Battleground, ...rest } }).optional(), diff --git a/src/lib/schema/stats/warlords.ts b/src/lib/schema/stats/warlords.ts new file mode 100644 index 0000000..4dc3b3a --- /dev/null +++ b/src/lib/schema/stats/warlords.ts @@ -0,0 +1,25 @@ +import z from "zod" + +export const warlordsStatsSchema = z.object({ + kills: z.number().default(0), + assists: z.number().default(0), + deaths: z.number().default(0), + wins: z.number().default(0), + coins: z.number().default(0), + magic_dust: z.number().default(0), + void_shards: z.number().default(0), + flag_conquer_self: z.number().default(0), + flag_returns: z.number().default(0), + mage_plays: z.number().default(0), + paladin_plays: z.number().default(0), + shaman_plays: z.number().default(0), + warrior_plays: z.number().default(0), + mage_wins: z.number().default(0), + paladin_wins: z.number().default(0), + shaman_wins: z.number().default(0), + warrior_wins: z.number().default(0), + mage_losses: z.number().default(0), + paladin_losses: z.number().default(0), + shaman_losses: z.number().default(0), + warrior_losses: z.number().default(0) +})