From 0d7c79a31033202df814f7eeb80d05c7176bd814 Mon Sep 17 00:00:00 2001 From: Taken Date: Sun, 14 Sep 2025 21:05:12 +0200 Subject: [PATCH] Added best mode stats --- .../[ign]/_stats/copsandcrims/table.tsx | 9 +++-- .../player/[ign]/_stats/megawalls/table.tsx | 11 ++++-- .../(stats)/player/[ign]/_stats/uhc/table.tsx | 5 ++- .../player/[ign]/_stats/woolgames/table.tsx | 10 ++++- src/lib/hypixel/copsandcrims/general.ts | 12 ++++++ src/lib/hypixel/megawalls/general.ts | 39 +++++++++++++++++++ src/lib/hypixel/uhc/general.ts | 18 +++++++++ src/lib/hypixel/woolgames/general.ts | 19 +++++++++ 8 files changed, 113 insertions(+), 10 deletions(-) diff --git a/src/app/(stats)/player/[ign]/_stats/copsandcrims/table.tsx b/src/app/(stats)/player/[ign]/_stats/copsandcrims/table.tsx index a91a71a..1621a4c 100644 --- a/src/app/(stats)/player/[ign]/_stats/copsandcrims/table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/copsandcrims/table.tsx @@ -1,7 +1,8 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { formatNumber } from "@/lib/formatters" -import { getCopsAndCrimsModeName, getCopsAndCrimsModeStats } from "@/lib/hypixel/copsandcrims/general" +import { getCopsAndCrimsBestMode, getCopsAndCrimsModeName, getCopsAndCrimsModeStats } from "@/lib/hypixel/copsandcrims/general" import { NonNullStats } from "@/lib/schema/player" +import { cn } from "@/lib/utils" export default function CopsAndCrimsStatTable({ stats }: { stats: NonNullable }) { return ( @@ -44,10 +45,12 @@ function CopsAndCrimsTableStat( stats: NonNullable } ) { - const modeStats = getCopsAndCrimsModeStats(modeId === "regular" ? "" : modeId, stats) const name = getCopsAndCrimsModeName(modeId === "regular" ? "" : modeId) + const modeStats = getCopsAndCrimsModeStats(modeId === "regular" ? "" : modeId, stats) + const isBest = getCopsAndCrimsBestMode(stats) === modeId + return ( - + {name} {modeStats.map((v, i) => { return {formatNumber(v)} diff --git a/src/app/(stats)/player/[ign]/_stats/megawalls/table.tsx b/src/app/(stats)/player/[ign]/_stats/megawalls/table.tsx index a4023a2..fa1a7d0 100644 --- a/src/app/(stats)/player/[ign]/_stats/megawalls/table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/megawalls/table.tsx @@ -6,9 +6,12 @@ import { getMegaWallsClass, getMegaWallsDifficultyColor, getMegaWallsModeName, - getMegaWallsModeStats + getMegaWallsModeStats, + getMegaWallsMostPlayedClass, + getMegaWallsMostPlayedMode } from "@/lib/hypixel/megawalls/general" import { NonNullStats } from "@/lib/schema/player" +import { cn } from "@/lib/utils" export function MegaWallsModesTable({ stats }: { stats: NonNullable }) { return ( @@ -90,8 +93,9 @@ function MegaWallsClassStats({ stats }: { stats: NonNullable + {klass.name} {val.map((v, j) => { if (j === val.length - 2) { @@ -111,9 +115,10 @@ function MegaWallsModeStat( ) { const modeName = getMegaWallsModeName(modeId) const modeStat = getMegaWallsModeStats(modeId, stats) + const mostPlayed = getMegaWallsMostPlayedMode(stats) === modeId return ( - + {modeName} {modeStat.map((s, i) => { return {formatNumber(s)} diff --git a/src/app/(stats)/player/[ign]/_stats/uhc/table.tsx b/src/app/(stats)/player/[ign]/_stats/uhc/table.tsx index edf801b..e556d94 100644 --- a/src/app/(stats)/player/[ign]/_stats/uhc/table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/uhc/table.tsx @@ -1,6 +1,6 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { formatNumber } from "@/lib/formatters" -import { getUHCModeName, getUHCModeStats } from "@/lib/hypixel/uhc/general" +import { getUHCBestMode, getUHCModeName, getUHCModeStats } from "@/lib/hypixel/uhc/general" import { NonNullStats } from "@/lib/schema/player" import { cn } from "@/lib/utils" @@ -49,9 +49,10 @@ function TableStat( ) { const modeStats = getUHCModeStats(modeId === "teams" ? "" : modeId, stats) const modeName = getUHCModeName(modeId === "teams" || modeId === "all_modes" ? "" : modeId) + const isBest = getUHCBestMode(stats) === modeId return ( - + {modeId === "all_modes" ? "Overall" : modeName} {modeStats.map((v, i) => { return ( diff --git a/src/app/(stats)/player/[ign]/_stats/woolgames/table.tsx b/src/app/(stats)/player/[ign]/_stats/woolgames/table.tsx index 05e8675..d03500d 100644 --- a/src/app/(stats)/player/[ign]/_stats/woolgames/table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/woolgames/table.tsx @@ -1,6 +1,11 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { formatNumber } from "@/lib/formatters" -import { getWoolGamesWoolWarsClass, getWoolGamesWoolWarsClassColor, getWoolGamesWoolWarsClassStats } from "@/lib/hypixel/woolgames/general" +import { + getWoolGamesWoolWarsClass, + getWoolGamesWoolWarsClassColor, + getWoolGamesWoolWarsClassStats, + getWoolGamesWoolWarsMostPlayedClass +} from "@/lib/hypixel/woolgames/general" import { NonNullStats } from "@/lib/schema/player" import { cn } from "@/lib/utils" @@ -52,9 +57,10 @@ function StatRow( const classStats = getWoolGamesWoolWarsClassStats(classId, stats) const klass = getWoolGamesWoolWarsClass(classId) const classColor = getWoolGamesWoolWarsClassColor(klass?.difficulty) + const isMostPlayed = getWoolGamesWoolWarsMostPlayedClass(stats)?.id === classId return ( - + {klass !== null ? klass.name : "Unknown"} {classStats.map((v, i) => { return {formatNumber(v)} diff --git a/src/lib/hypixel/copsandcrims/general.ts b/src/lib/hypixel/copsandcrims/general.ts index 48d13f9..e351770 100644 --- a/src/lib/hypixel/copsandcrims/general.ts +++ b/src/lib/hypixel/copsandcrims/general.ts @@ -46,6 +46,18 @@ export function getCopsAndCrimsScoreColor(score: number) { return SCORE.at(0)!.color } +export function getCopsAndCrimsBestMode(stats: NonNullable) { + const modeWins = MODES.map(mode => ({ + mode: mode.id, + name: mode.name, + wins: mode.id === "" ? stats["game_wins"] : stats[`game_wins_${mode.id}`] || 0 + })) + + const best = modeWins.reduce((best, current) => current.wins > best.wins ? current : best).mode + + return best === "" ? "regular" : best +} + export function getCopsAndCrimsModeStats(modeId: typeof MODES[number]["id"], stats: NonNullable) { if (modeId === "") { return [ diff --git a/src/lib/hypixel/megawalls/general.ts b/src/lib/hypixel/megawalls/general.ts index 8b039a7..3ab3d38 100644 --- a/src/lib/hypixel/megawalls/general.ts +++ b/src/lib/hypixel/megawalls/general.ts @@ -32,6 +32,24 @@ export function getMegaWallsClass(classId: typeof CLASSES[number]["id"]) { return CLASSES.find(c => c.id === classId)! } +export function getMegaWallsMostPlayedClass(stats: NonNullable) { + let mostPlayedClass: typeof CLASSES[number] | null = null + let maxPlays = 0 + + for (const classObj of CLASSES) { + const wins = stats[`${classObj.id}_wins`] || 0 + const losses = stats[`${classObj.id}_losses`] || 0 + const totalPlays = wins + losses + + if (totalPlays > maxPlays) { + maxPlays = totalPlays + mostPlayedClass = classObj + } + } + + return mostPlayedClass +} + export function getAllMegawallsClassStats(stats: NonNullable) { const statsArr: { id: typeof CLASSES[number]["id"], val: number[] }[] = [] @@ -58,6 +76,27 @@ export function getMegaWallsClassStats(classId: typeof CLASSES[number]["id"], st ] } +export function getMegaWallsMostPlayedMode(stats: NonNullable) { + const modes = [ + { + id: "standard" as const, + games: (stats.wins_standard || 0) + (stats.losses_standard || 0) + }, + { + id: "face_off" as const, + games: (stats.wins_face_off || 0) + (stats.losses_face_off || 0) + }, + { + id: "gvg" as const, + games: (stats.wins_gvg || 0) + (stats.losses_gvg || 0) + } + ] + + const mostPlayed = modes.reduce((max, current) => current.games > max.games ? current : max) + + return mostPlayed.id +} + export function getMegaWallsModeStats(modeId: typeof MODES[number]["id"], stats: NonNullable) { return [ stats[`kills_${modeId}`], diff --git a/src/lib/hypixel/uhc/general.ts b/src/lib/hypixel/uhc/general.ts index d4b5443..b507684 100644 --- a/src/lib/hypixel/uhc/general.ts +++ b/src/lib/hypixel/uhc/general.ts @@ -11,6 +11,24 @@ export function getUHCStatsCombined(stats: NonNullable) { } } +export function getUHCBestMode(stats: NonNullable) { + let bestMode = MODES[0] as typeof MODES[number] + let maxScore = 0 + + for (const mode of MODES) { + const modeWins = mode.id === "" ? stats.wins : stats[`wins_${mode.id}`] ?? 0 + const modeDeaths = mode.id === "" ? stats.deaths : stats[`deaths_${mode.id}`] ?? 0 + const combinedScore = modeWins + modeDeaths + + if (combinedScore > maxScore) { + maxScore = combinedScore + bestMode = mode + } + } + + return bestMode.id === "" ? "teams" : bestMode.id +} + export function getUHCModeName(modeId: typeof MODES[number]["id"]) { return MODES.find(m => m.id === modeId)!.name } diff --git a/src/lib/hypixel/woolgames/general.ts b/src/lib/hypixel/woolgames/general.ts index b27f4c6..552c221 100644 --- a/src/lib/hypixel/woolgames/general.ts +++ b/src/lib/hypixel/woolgames/general.ts @@ -3,6 +3,25 @@ import { getColorFromCode } from "@/lib/colors" import { NonNullStats } from "@/lib/schema/player" import { devide, floorLevel } from "../general" +export function getWoolGamesWoolWarsMostPlayedClass(stats: NonNullable["wool_wars"]) { + if (!stats?.stats?.classes) return null + + let mostPlayedClass = null + let maxKills = 0 + + for (const classData of CLASSES) { + const classStats = stats.stats.classes[classData.id] + const kills = classStats?.kills || 0 + + if (kills > maxKills) { + maxKills = kills + mostPlayedClass = classData + } + } + + return mostPlayedClass +} + export function getWoolGamesWoolWarsClassStats( classId: typeof CLASSES[number]["id"], stats: NonNullable["wool_wars"]