diff --git a/src/app/(stats)/player/[ign]/_client.tsx b/src/app/(stats)/player/[ign]/_client.tsx index 4979beb..1cb32ef 100644 --- a/src/app/(stats)/player/[ign]/_client.tsx +++ b/src/app/(stats)/player/[ign]/_client.tsx @@ -10,7 +10,7 @@ import { CSS } from "@dnd-kit/utilities" import Cookies from "js-cookie" import { GripVertical } from "lucide-react" import { usePathname } from "next/navigation" -import { useEffect, useMemo, useState } from "react" +import { useEffect, useRef, useState } from "react" import ArcadeStats from "./_stats/arcade/arcade" import BedwarsStats from "./_stats/bedwars/bedwars" @@ -114,17 +114,14 @@ export function PlayerStats( }) ) - const cookieOpts = useMemo(() => { - const cookieOpts: Parameters[2] = { - secure: process.env.NODE_ENV === "production", - sameSite: "lax", - expires: 365 - } - return cookieOpts - }, []) + const cookieOpts = useRef[2]>({ + secure: process.env.NODE_ENV === "production", + sameSite: "lax", + expires: 365 + }) function updateStatsOrder(arr: string[]) { - Cookies.set(COOKIE_VALUES.statsOrder, JSON.stringify(arr), cookieOpts) + Cookies.set(COOKIE_VALUES.statsOrder, JSON.stringify(arr), cookieOpts.current) } function handleDragEnd(event: DragEndEvent) { @@ -147,7 +144,7 @@ export function PlayerStats( } const cookie = Cookies.get(COOKIE_VALUES.statsOrder) if (cookie) { - Cookies.set(COOKIE_VALUES.statsOrder, cookie, cookieOpts) + Cookies.set(COOKIE_VALUES.statsOrder, cookie, cookieOpts.current) } }, [layout, cookieOpts]) diff --git a/src/app/(stats)/player/[ign]/_stats/warlords/table.tsx b/src/app/(stats)/player/[ign]/_stats/warlords/table.tsx index f051cc9..0e3b7c8 100644 --- a/src/app/(stats)/player/[ign]/_stats/warlords/table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/warlords/table.tsx @@ -1,9 +1,82 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { formatNumber } from "@/lib/formatters" -import { getWarlordsModeName, getWarlordsModeStats, getWarlordsMostPlayedMode } from "@/lib/hypixel/warlords/general" +import { + getWarlordsClassLevel, + getWarlordsClassName, + getWarlordsClassStats, + getWarlordsModeName, + getWarlordsModeStats, + getWarlordsMostPlayedClass, + getWarlordsMostPlayedMode +} from "@/lib/hypixel/warlords/general" import { NonNullStats } from "@/lib/schema/player" import { cn } from "@/lib/utils" +export function WarlordsClassStatsTable({ stats }: { stats: NonNullable }) { + return ( + + + + + + + + + +
+ ) +} + +function WarlordsClassStatsTableStat( + { classId, stats }: { classId: Parameters[0], stats: NonNullable } +) { + const classStats = getWarlordsClassStats(classId, stats) + const klassName = getWarlordsClassName(classId) + const mostPlayed = getWarlordsMostPlayedClass(stats)?.id === classId + + return ( + + {classId === "all" ? + ( + + {klassName} + + ) + : ( + + {`Lv ${getWarlordsClassLevel(classId, stats)} `} + {klassName} + + )} + {classStats.map((v, i) => { + return {formatNumber(v)} + })} + + ) +} + +function WarlordsClassStatsTableHeader() { + const headerElements = [ + "Class", + "Damage", + "Damage Prevented", + "Healing", + "Wins", + "Losses", + "WL" + ] + + return ( + + + {headerElements.map((v, i) => { + return {v} + })} + + + ) +} + export function WarlordsModeStatsTable({ stats }: { stats: NonNullable }) { return ( diff --git a/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx b/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx index b4a301e..3da0f81 100644 --- a/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx +++ b/src/app/(stats)/player/[ign]/_stats/warlords/warlords.tsx @@ -6,7 +6,7 @@ import { NonNullStats } from "@/lib/schema/player" import GeneralStats from "../GeneralStats" import { WarlordsWeaponsBar } from "./client" import WarlordsGeneralStats from "./stats" -import { WarlordsModeStatsTable } from "./table" +import { WarlordsClassStatsTable, WarlordsModeStatsTable } from "./table" export default function WarlordsStats({ stats }: { stats: NonNullStats["Warlords"] }) { if (!stats) return null @@ -44,6 +44,8 @@ export default function WarlordsStats({ stats }: { stats: NonNullStats["Warlords + + diff --git a/src/lib/hypixel/warlords/general.ts b/src/lib/hypixel/warlords/general.ts index 633777f..6b73b47 100644 --- a/src/lib/hypixel/warlords/general.ts +++ b/src/lib/hypixel/warlords/general.ts @@ -1,5 +1,45 @@ -import { CLASSES, MODES, RARITIES } from "@/data/hypixel/warlords" +import { CLASSES, MODES, RARITIES, UPGRADES } from "@/data/hypixel/warlords" import { NonNullStats } from "@/lib/schema/player" +import { devide } from "../general" + +export function getWarlordsClassLevel(classId: Exclude, stats: NonNullable) { + let level = 0 + + for (const upgrade of UPGRADES) { + level += stats[`${classId}_${upgrade.id}`] + } + + return level +} + +export function getWarlordsClassName(classId: Exclude | "all") { + if (classId === "all") return CLASSES.find(c => c.id === "")!.name + return CLASSES.find(c => c.id === classId)!.name +} + +export function getWarlordsClassStats(classId: Exclude | "all", stats: NonNullable) { + const losses = getWarlordsLosses(stats) + + if (classId === "all") { + return [ + stats.damage, + stats.damage_prevented, + stats.heal, + stats.wins, + losses, + devide(stats.wins, losses) + ] + } + + return [ + stats[`damage_${classId}`], + stats[`damage_prevented_${classId}`], + stats[`heal_${classId}`], + stats[`wins_${classId}`], + stats[`${classId}_plays`] - stats[`wins_${classId}`], + devide(stats[`${classId}_plays`] - stats[`wins_${classId}`], stats[`wins_${classId}`]) + ] +} export function getWarlordsModeName(modeId: Exclude | "all") { if (modeId === "all") { diff --git a/src/lib/schema/stats/warlords.ts b/src/lib/schema/stats/warlords.ts index 8c9e270..79c3c36 100644 --- a/src/lib/schema/stats/warlords.ts +++ b/src/lib/schema/stats/warlords.ts @@ -1,27 +1,65 @@ import z from "zod" +function warlordsClassStats() { + const ids = [ + "mage", + "paladin", + "shaman", + "warrior" + ] as const + const stats = [ + "cooldown", + "critchance", + "critmultiplier", + "energy", + "health", + "skill1", + "skill2", + "skill3", + "skill4", + "skill5", + "wins", + "losses", + "plays" + ] as const + const stats2 = [ + "damage", + "damage_prevented", + "heal", + "wins" + ] as const + + const entries = new Map>() + const entries2 = new Map>() + + for (const id of ids) { + for (const stat of stats) { + entries.set(`${id}_${stat}`, z.number().default(0)) + } + for (const stat of stats2) { + entries2.set(`${stat}_${id}`, z.number().default(0)) + } + } + + return { + left_right: Object.fromEntries(entries) as Record<`${typeof ids[number]}_${typeof stats[number]}`, z.ZodDefault>, + right_left: Object.fromEntries(entries2) as Record<`${typeof stats2[number]}_${typeof ids[number]}`, z.ZodDefault> + } +} + 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), + damage: z.number().default(0), + damage_prevented: z.number().default(0), + heal: 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), repaired: z.number().default(0), repaired_common: z.number().default(0), repaired_rare: z.number().default(0), @@ -32,5 +70,7 @@ export const warlordsStatsSchema = z.object({ wins_teamdeathmatch: z.number().default(0), kills_capturetheflag: z.number().default(0), kills_domination: z.number().default(0), - kills_teamdeathmatch: z.number().default(0) + kills_teamdeathmatch: z.number().default(0), + ...warlordsClassStats().left_right, + ...warlordsClassStats().right_left })