From 24e07e092a41856fd5236953a20fffbc646aa61d Mon Sep 17 00:00:00 2001 From: Taken Date: Sat, 6 Sep 2025 20:46:00 +0200 Subject: [PATCH] Added tnt games stats --- .../[ign]/_components/GenericProgress.tsx | 27 ++++- .../player/[ign]/_stats/tnt-games/stats.tsx | 39 +++++++ .../[ign]/_stats/tnt-games/tnt-games.tsx | 37 +++++++ .../player/[ign]/_stats/tnt-games/wizards.tsx | 102 ++++++++++++++++++ src/app/(stats)/player/[ign]/page.tsx | 2 + src/data/hypixel/tnt-games.ts | 11 ++ src/lib/hypixel/tnt-games/general.ts | 18 ++++ src/lib/schema/player.ts | 4 +- src/lib/schema/stats.ts | 50 +++++++++ 9 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 src/app/(stats)/player/[ign]/_stats/tnt-games/stats.tsx create mode 100644 src/app/(stats)/player/[ign]/_stats/tnt-games/tnt-games.tsx create mode 100644 src/app/(stats)/player/[ign]/_stats/tnt-games/wizards.tsx create mode 100644 src/data/hypixel/tnt-games.ts create mode 100644 src/lib/hypixel/tnt-games/general.ts diff --git a/src/app/(stats)/player/[ign]/_components/GenericProgress.tsx b/src/app/(stats)/player/[ign]/_components/GenericProgress.tsx index 3f493e1..a8a9296 100644 --- a/src/app/(stats)/player/[ign]/_components/GenericProgress.tsx +++ b/src/app/(stats)/player/[ign]/_components/GenericProgress.tsx @@ -18,7 +18,32 @@ type GenericProgressProps = rainbow: true }) -export default function GenericProgress({ percent, tooltipId, tooltipContent, className, rainbow }: GenericProgressProps) { +type GenericProgressNoTooltipProps = { + text: string + percent: number + className?: string +} + +export function GenericProgressNoTooltip({ text, percent, className }: GenericProgressNoTooltipProps) { + return ( +
+
= 100 ? "rounded-r-md" : undefined, className)} + style={{ width: `${percent > 100 ? 100 : percent}%` }} + > + {text} +
+ {percent < 100 && ( +
+
+ )} +
+ ) +} + +export function GenericProgress({ percent, tooltipId, tooltipContent, className, rainbow }: GenericProgressProps) { const [pos, setPos] = useState({ x: 0, y: 0 }) useEffect(() => { diff --git a/src/app/(stats)/player/[ign]/_stats/tnt-games/stats.tsx b/src/app/(stats)/player/[ign]/_stats/tnt-games/stats.tsx new file mode 100644 index 0000000..79a1435 --- /dev/null +++ b/src/app/(stats)/player/[ign]/_stats/tnt-games/stats.tsx @@ -0,0 +1,39 @@ +import { formatNumber, formatSecondsToTime } from "@/lib/formatters" +import { devide } from "@/lib/hypixel/general" +import { NonNullStats } from "@/lib/schema/player" +import { BasicStat } from "../../_components/Stats" + +export default function TNTGamesGeneralStats({ stats }: { stats: NonNullable }) { + return ( +
+
+ + +
+
+
+

TNT Tag

+ + +
+
+

TNT Run

+ + +
+
+

PvP Run

+ + + +
+
+

Bow Spleef

+ + + +
+
+
+ ) +} diff --git a/src/app/(stats)/player/[ign]/_stats/tnt-games/tnt-games.tsx b/src/app/(stats)/player/[ign]/_stats/tnt-games/tnt-games.tsx new file mode 100644 index 0000000..4eca443 --- /dev/null +++ b/src/app/(stats)/player/[ign]/_stats/tnt-games/tnt-games.tsx @@ -0,0 +1,37 @@ +import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" +import { Card, CardContent } from "@/components/ui/card" +import { Separator } from "@/components/ui/separator" +import { NonNullStats } from "@/lib/schema/player" +import CollapsedStats from "../../_components/CollapsedStats" +import TNTGamesGeneralStats from "./stats" +import TNTWizardsStats from "./wizards" + +export default function TNTGamesStats({ stats }: { stats: NonNullStats["TNTGames"] }) { + if (!stats) return null + + return ( + + + + +

TNT Games

+
+ Wins

, + stat:

{stats.wins}

+ }]} + /> +
+
+ + + + + + +
+
+
+ ) +} diff --git a/src/app/(stats)/player/[ign]/_stats/tnt-games/wizards.tsx b/src/app/(stats)/player/[ign]/_stats/tnt-games/wizards.tsx new file mode 100644 index 0000000..52206ae --- /dev/null +++ b/src/app/(stats)/player/[ign]/_stats/tnt-games/wizards.tsx @@ -0,0 +1,102 @@ +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { formatNumber } from "@/lib/formatters" +import { devide, romanize } from "@/lib/hypixel/general" +import { getTNTGameMode, getTNTModeStats } from "@/lib/hypixel/tnt-games/general" +import { NonNullStats } from "@/lib/schema/player" +import { GenericProgressNoTooltip } from "../../_components/GenericProgress" +import { BasicStat } from "../../_components/Stats" + +export default function TNTWizardsStats({ stats }: { stats: NonNullable }) { + return ( +
+

TNT Wizards

+
+ + + + +
+ + + + + + + + + + + + + +
+
+ ) +} + +function TableStats({ id, stats }: { id: Parameters[0], stats: NonNullable }) { + const gm = getTNTGameMode(id) + const modeStats = getTNTModeStats(id, stats) + return ( + + {gm.name} + {modeStats.map((m, i) => { + if (i === modeStats.length - 2) { + if (m === 0) { + return ? + } + return ( + + { + + } + + ) + } + if (i === modeStats.length - 1) { + if (m === 0) { + return ? + } + return ( + + { + + } + + ) + } + return {formatNumber(m)} + })} + + ) +} + +function TNTWizardsTableHeader() { + const headerElements = [ + "Wizard", + "Kills", + "Deaths", + "Assists", + "KD", + "Power", + "Regen" + ] + + return ( + + + {headerElements.map((v, i) => { + return {v} + })} + + + ) +} diff --git a/src/app/(stats)/player/[ign]/page.tsx b/src/app/(stats)/player/[ign]/page.tsx index de836e7..f3e0e51 100644 --- a/src/app/(stats)/player/[ign]/page.tsx +++ b/src/app/(stats)/player/[ign]/page.tsx @@ -16,6 +16,7 @@ import DuelsStats from "./_stats/duels/duels" import MurderMysteryStats from "./_stats/murder-mystery/murder-mystery" import PitStats from "./_stats/pit/pit" import SkyWarsStats from "./_stats/skywars/skywars" +import TNTGamesStats from "./_stats/tnt-games/tnt-games" import UHCStats from "./_stats/uhc/uhc" export async function generateMetadata({ params }: { params: Promise<{ ign: string }> }): Promise { @@ -116,6 +117,7 @@ async function SuspendedPage({ ign: pign }: { ign: string }) { + ) : diff --git a/src/data/hypixel/tnt-games.ts b/src/data/hypixel/tnt-games.ts new file mode 100644 index 0000000..23c07b5 --- /dev/null +++ b/src/data/hypixel/tnt-games.ts @@ -0,0 +1,11 @@ +export const WIZARDS = [ + { id: "ancient", name: "Ancient", color: "gold" }, + { id: "blood", name: "Blood", color: "dark-red" }, + { id: "fire", name: "Fire", color: "red" }, + { id: "hydro", name: "Hydro", color: "dark-blue" }, + { id: "ice", name: "Ice", color: "blue" }, + { id: "kinetic", name: "Kinetic", color: "light-purple" }, + { id: "storm", name: "Storm", color: "yellow" }, + { id: "toxic", name: "Toxic", color: "green" }, + { id: "wither", name: "Wither", color: "black" } +] as const diff --git a/src/lib/hypixel/tnt-games/general.ts b/src/lib/hypixel/tnt-games/general.ts new file mode 100644 index 0000000..1f5c856 --- /dev/null +++ b/src/lib/hypixel/tnt-games/general.ts @@ -0,0 +1,18 @@ +import { WIZARDS } from "@/data/hypixel/tnt-games" +import { NonNullStats } from "@/lib/schema/player" +import { devide } from "../general" + +export function getTNTGameMode(id: typeof WIZARDS[number]["id"]) { + return WIZARDS.find(w => w.id === id)! +} + +export function getTNTModeStats(id: typeof WIZARDS[number]["id"], stats: NonNullable) { + return [ + stats[`new_${id}wizard_kills`], + stats[`new_${id}wizard_deaths`], + stats[`new_${id}wizard_assists`], + devide(stats[`new_${id}wizard_kills`], stats[`new_${id}wizard_deaths`]), + stats[`new_${id}wizard_explode`], + stats[`new_${id}wizard_regen`] + ] +} diff --git a/src/lib/schema/player.ts b/src/lib/schema/player.ts index 6209a61..f646f65 100644 --- a/src/lib/schema/player.ts +++ b/src/lib/schema/player.ts @@ -6,6 +6,7 @@ import { murderMysteryStatsSchema, pitStats, skywarsStatsSchema, + tntGamesStatsSchema, uhcSchema } from "./stats" @@ -28,7 +29,8 @@ export const playerSchema = z.looseObject({ MurderMystery: murderMysteryStatsSchema.optional(), BuildBattle: buildBattleStatsSchema.optional(), UHC: uhcSchema.optional(), - Pit: pitStats.optional() + Pit: pitStats.optional(), + TNTGames: tntGamesStatsSchema.optional() }).optional(), quests: z.record( z.string(), diff --git a/src/lib/schema/stats.ts b/src/lib/schema/stats.ts index 05a7d14..064b975 100644 --- a/src/lib/schema/stats.ts +++ b/src/lib/schema/stats.ts @@ -503,3 +503,53 @@ export const pitStats = z.looseObject({ ...pit_stats_ptl, ...rest })) + +function tntGamesModeStats() { + const ids = [ + "ancient", + "blood", + "fire", + "hydro", + "ice", + "kinetic", + "storm", + "toxic", + "wither" + ] as const + + const stats = [ + "kills", + "deaths", + "assists", + "explode", + "regen" + ] as const + + const entries = new Map>() + + for (const id of ids) { + for (const stat of stats) { + entries.set(`new_${id}wizard_${stat}`, z.number().default(0)) + } + } + + return Object.fromEntries(entries) as Record<`new_${typeof ids[number]}wizard_${typeof stats[number]}`, z.ZodDefault> +} + +export const tntGamesStatsSchema = z.looseObject({ + wins: z.number().default(0), + coins: z.number().default(0), + kills_tntag: z.number().default(0), + wins_tntag: z.number().default(0), + wins_tntrun: z.number().default(0), + record_tntrun: z.number().default(0), + kills_pvprun: z.number().default(0), + wins_pvprun: z.number().default(0), + record_pvprun: z.number().default(0), + wins_bowspleef: z.number().default(0), + deaths_bowspleef: z.number().default(0), + wins_capture: z.number().default(0), + kills_capture: z.number().default(0), + deaths_capture: z.number().default(0), + ...tntGamesModeStats() +})