feat(skywars): add full mode stats rows and best mode detection

This commit is contained in:
2025-08-24 13:48:40 +02:00
parent 2b959a6c99
commit ba84f90221
2 changed files with 234 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { formatNumber } from "@/lib/formatters"
import { _SkywarsStats, getBestMode, getSkywarsModeStats } from "@/lib/hypixel/skywars"
import { NonNullStats } from "@/lib/schema/player"
import { cn } from "@/lib/utils"
export default function SkywarsStatTable({ stats }: { stats: NonNullStats["SkyWars"] }) {
return (
<Table>
<SkywarsTableHeader />
<TableBody>
<Normal stats={stats} />
<Insane stats={stats} />
<TeamsNormal stats={stats} />
<TeamsInsane stats={stats} />
<Mega stats={stats} />
<MegaDoubles stats={stats} />
<Ranked stats={stats} />
</TableBody>
</Table>
)
}
function SkywarsTableHeader() {
const headerElements = [
"Mode",
"Kills",
"Deaths",
"KD",
"Wins",
"Losses",
"WL"
]
return (
<TableHeader>
<TableRow>
{headerElements.map((v, i) => {
return <TableHead key={i} className="font-bold">{v}</TableHead>
})}
</TableRow>
</TableHeader>
)
}
function Normal({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("normal", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "normal"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Solo Normal</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Insane({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("insane", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "insane"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Solo Insane</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function TeamsNormal({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("teams_normal", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "teams_normal"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Teams Normal</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function TeamsInsane({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("teams_insane", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "teams_insane"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Teams Insane</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Mega({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("mega", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "mega"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Mega</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function MegaDoubles({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("mega_doubles", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "mega_doubles"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Mega Doubles</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Ranked({ stats }: { stats: NonNullStats["SkyWars"] }) {
const modeStats = getSkywarsModeStats("ranked", stats as _SkywarsStats)
const isBest = getBestMode(stats as _SkywarsStats) === "ranked"
return (
<TableRow className={cn(isBest ? "font-bold text-mc-light-purple" : undefined)}>
<TableCell>Ranked</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}

View File

@@ -1,5 +1,6 @@
import { ICONS, PRESTIGES } from "@/data/hypixel/skywars"
import { floorLevel } from "./formatters"
import { devide } from "./general"
export function getTextColor(level: number) {
const floored = floorLevel(level, 5)
@@ -36,3 +37,94 @@ export function getPrestigeName(level: number) {
return PRESTIGES.find(p => p.level === floored)!.name
}
export type _SkywarsStats = Record<string, number>
type Mode =
| "normal"
| "insane"
| "teams_normal"
| "teams_insane"
| "mega"
| "mega_doubles"
| "ranked"
export type SkywarsModeStats = {
kills: number
deaths: number
wins: number
losses: number
}
export function getBestMode(stats: _SkywarsStats): Mode | null {
const { wins: normal } = getSkywarsModeStats("normal", stats, true)
const { wins: insane } = getSkywarsModeStats("insane", stats, true)
const { wins: teams_normal } = getSkywarsModeStats("teams_normal", stats, true)
const { wins: teams_insane } = getSkywarsModeStats("teams_insane", stats, true)
const { wins: mega } = getSkywarsModeStats("mega", stats, true)
const { wins: mega_doubles } = getSkywarsModeStats("mega_doubles", stats, true)
const { wins: ranked } = getSkywarsModeStats("ranked", stats, true)
const max = Math.max(normal, insane, teams_normal, teams_insane, mega, mega_doubles, ranked)
switch (max) {
case normal:
return "normal"
case insane:
return "insane"
case teams_normal:
return "teams_normal"
case teams_insane:
return "teams_insane"
case mega:
return "mega"
case mega_doubles:
return "mega_doubles"
case ranked:
return "ranked"
default:
return null
}
}
export function getSkywarsModeStats(mode: Mode, stats: _SkywarsStats, raw: true): SkywarsModeStats
export function getSkywarsModeStats(mode: Mode, stats: _SkywarsStats, raw?: false): (string | number)[]
export function getSkywarsModeStats(mode: Mode, stats: _SkywarsStats, raw = false) {
switch (mode) {
case "normal":
return skywarsModeStats("solo_normal", stats, raw)
case "insane":
return skywarsModeStats("solo_insane", stats, raw)
case "teams_normal":
return skywarsModeStats("team_normal", stats, raw)
case "teams_insane":
return skywarsModeStats("team_insane", stats, raw)
case "mega":
return skywarsModeStats("mega_mega", stats, raw)
case "mega_doubles":
return skywarsModeStats("mega_doubles", stats, raw)
case "ranked":
return skywarsModeStats("ranked_normal", stats, raw)
default:
throw new Error(`${mode satisfies never} does not exist`)
}
}
function skywarsModeStats(suffix: string, stats: _SkywarsStats, raw = false) {
if (raw) {
return {
kills: stats[`kills_${suffix}`],
deaths: stats[`deaths_${suffix}`],
wins: stats[`wins_${suffix}`],
losses: stats[`losses_${suffix}`]
}
}
return [
stats[`kills_${suffix}`],
stats[`deaths_${suffix}`],
devide(stats[`kills_${suffix}`], stats[`deaths_${suffix}`]).toFixed(2),
stats[`wins_${suffix}`],
stats[`losses_${suffix}`],
devide(stats[`wins_${suffix}`], stats[`losses_${suffix}`]).toFixed(2)
]
}