Finished duels stats

This commit is contained in:
2025-09-02 13:57:52 +02:00
parent 83031f6526
commit 2b262025df
4 changed files with 82 additions and 30 deletions

View File

@@ -1,6 +1,7 @@
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { formatNumber } from "@/lib/formatters" import { formatNumber } from "@/lib/formatters"
import { getBestDuelsMode, getDuelsModeStats, getModeTitle } from "@/lib/hypixel/duels/duels" import { getBestDuelsMode, getDevision, getDuelsModeStats, getMode } from "@/lib/hypixel/duels/duels"
import { romanize } from "@/lib/hypixel/general"
import { NonNullStats } from "@/lib/schema/player" import { NonNullStats } from "@/lib/schema/player"
export default function DuelsStatTable({ stats }: { stats: NonNullStats["Duels"] }) { export default function DuelsStatTable({ stats }: { stats: NonNullStats["Duels"] }) {
@@ -72,20 +73,18 @@ function DuelsTableHeader() {
) )
} }
function DuelsStat( function DuelsStat({ modeId, stats }: { modeId: Parameters<typeof getMode>[0], stats: NonNullStats["Duels"] }) {
{ modeId, stats }: { modeId: Parameters<typeof getModeTitle>[0], stats: NonNullStats["Duels"] }
) {
if (!stats) return null if (!stats) return null
const modeStats = getDuelsModeStats(modeId, stats) const modeStats = getDuelsModeStats(modeId, stats)
const title = getModeTitle(modeId) const mode = getMode(modeId)
const bestMode = getBestDuelsMode(stats) === modeId const bestMode = getBestDuelsMode(stats) === modeId
const divisionLabel = "I" const div = getDevision(mode.divId, stats)
return ( return (
<TableRow> <TableRow>
<TableCell className={bestMode ? "font-bold text-mc-light-purple" : undefined}>{title}</TableCell> <TableCell className={bestMode ? "font-bold text-mc-light-purple" : undefined}>{mode.name}</TableCell>
<TableCell>{divisionLabel}</TableCell> <TableCell className={div === null ? undefined : `text-mc-${div.color}`}>{div === null ? "?" : romanize(div.level)}</TableCell>
{modeStats.map((v, i) => ( {modeStats.map((v, i) => (
<TableCell className={bestMode ? "font-bold text-mc-light-purple" : undefined} key={i}> <TableCell className={bestMode ? "font-bold text-mc-light-purple" : undefined} key={i}>
{typeof v === "number" ? formatNumber(v) : v} {typeof v === "number" ? formatNumber(v) : v}

View File

@@ -27,7 +27,7 @@ export const MODES = [
{ id: "mw_doubles", divisionId: "mega_walls", name: "MegaWalls Doubles" }, { id: "mw_doubles", divisionId: "mega_walls", name: "MegaWalls Doubles" },
{ id: "sumo_duel", divisionId: "sumo", name: "Sumo 1v1" }, { id: "sumo_duel", divisionId: "sumo", name: "Sumo 1v1" },
{ id: "bowspleef_duel", divisionId: "tnt_games", name: "Bow Spleef 1v1" }, { id: "bowspleef_duel", divisionId: "tnt_games", name: "Bow Spleef 1v1" },
{ id: "spleef_duel", divisionId: "", name: "Spleef 1v1" }, { id: "spleef_duel", divisionId: null, name: "Spleef 1v1" },
{ id: "parkour_eight", divisionId: "parkour", name: "Parkour FFA" }, { id: "parkour_eight", divisionId: "parkour", name: "Parkour FFA" },
{ id: "boxing_duel", divisionId: "boxing", name: "Boxing 1v1" }, { id: "boxing_duel", divisionId: "boxing", name: "Boxing 1v1" },
{ id: "classic_duel", divisionId: "classic", name: "Classic 1v1" }, { id: "classic_duel", divisionId: "classic", name: "Classic 1v1" },
@@ -40,8 +40,8 @@ export const MODES = [
{ id: "bridge_four", divisionId: "bridge", name: "Bridge 4v4" }, { id: "bridge_four", divisionId: "bridge", name: "Bridge 4v4" },
{ id: "bridge_2v2v2v2", divisionId: "bridge", name: "Bridge 2v2v2v2" }, { id: "bridge_2v2v2v2", divisionId: "bridge", name: "Bridge 2v2v2v2" },
{ id: "bridge_3v3v3v3", divisionId: "bridge", name: "Bridge 3v3v3v3" }, { id: "bridge_3v3v3v3", divisionId: "bridge", name: "Bridge 3v3v3v3" },
{ id: "duel_arena", divisionId: "", name: "Duel Arena" }, { id: "duel_arena", divisionId: null, name: "Duel Arena" },
{ id: "quake_duel", divisionId: "quake", name: "Quakecraft 1v1" }, { id: "quake_duel", divisionId: null, name: "Quakecraft 1v1" },
{ id: "bedwars_two_one_duels", divisionId: "bedwars", name: "Bedwars 1v1" }, { id: "bedwars_two_one_duels", divisionId: null, name: "Bedwars 1v1" },
{ id: "bedwars_two_one_duels_rush", divisionId: "bedwars", name: "Bedwars Rush 1v1" } { id: "bedwars_two_one_duels_rush", divisionId: null, name: "Bedwars Rush 1v1" }
] as const ] as const

View File

@@ -8,11 +8,33 @@ export type Div = {
level: number level: number
color: typeof DIVISIONS[number]["color"] color: typeof DIVISIONS[number]["color"]
} }
type Mode = typeof MODES[number]["id"]
type Devisions = typeof MODES[number]["divisionId"]
export function getModeTitle(id: typeof MODES[number]["id"]) { export function getMode(id: typeof MODES[number]["id"]) {
const div = MODES.find(d => d.id === id) const div = MODES.find(d => d.id === id)
return div!.name return {
name: div!.name,
divId: div!.divisionId
}
}
export function getDevision(devison: Devisions, stats: NonNullable<NonNullStats["Duels"]>) {
if (!devison) return null
for (const div of DIVISIONS.slice().reverse()) {
const index = `${devison}_${div.id}_title_prestige` as const
const val = stats[index]
if (val > 0) {
return {
level: val,
color: div.color
}
}
}
return null
} }
export function getAllDivisions(stats: NonNullable<NonNullStats["Duels"]>) { export function getAllDivisions(stats: NonNullable<NonNullStats["Duels"]>) {
@@ -44,8 +66,6 @@ export function getMostPlayed(stats: NonNullable<NonNullStats["Duels"]>) {
return mostPlayed return mostPlayed
} }
type Mode = typeof MODES[number]["id"]
export function getBestDuelsMode(stats: NonNullable<NonNullStats["Duels"]>) { export function getBestDuelsMode(stats: NonNullable<NonNullStats["Duels"]>) {
let best: typeof MODES[number] | null = null let best: typeof MODES[number] | null = null
let mostPlays = 0 let mostPlays = 0

View File

@@ -1,4 +1,5 @@
import z from "zod" import { title } from "process"
import z, { object } from "zod"
function bedwarsModeStats() { function bedwarsModeStats() {
const ids = [ const ids = [
@@ -269,6 +270,49 @@ function duelsModeStats() {
} }
} }
function devisionTitles() {
const devisions = [
"all_modes",
"uhc",
"op",
"skywars",
"bow",
"blitz",
"mega_walls",
"sumo",
"tnt_games",
"parkour",
"boxing",
"classic",
"no_debuff",
"combo",
"bridge"
] as const
const titles = [
"rookie",
"iron",
"gold",
"diamond",
"master",
"legend",
"grandmaster",
"godlike",
"celestial",
"divine",
"ascended"
] as const
const entries = new Map<string, z.ZodDefault<z.ZodNumber>>()
for (const div of devisions) {
for (const title of titles) {
entries.set(`${div}_${title}_title_prestige`, z.number().default(-1))
}
}
return Object.fromEntries(entries) as Record<`${typeof devisions[number]}_${typeof titles[number]}_title_prestige`, z.ZodDefault<z.ZodNumber>>
}
export const duelsStatsSchema = z.looseObject({ export const duelsStatsSchema = z.looseObject({
wins: z.number().default(0), wins: z.number().default(0),
losses: z.number().default(0), losses: z.number().default(0),
@@ -281,18 +325,7 @@ export const duelsStatsSchema = z.looseObject({
bow_hits: z.number().default(0), bow_hits: z.number().default(0),
current_winstreak: z.number().optional(), current_winstreak: z.number().optional(),
best_overall_winstreak: z.number().optional(), best_overall_winstreak: z.number().optional(),
// ...devisionTitles(),
all_modes_rookie_title_prestige: z.number().default(-1),
all_modes_iron_title_prestige: z.number().default(-1),
all_modes_gold_title_prestige: z.number().default(-1),
all_modes_diamond_title_prestige: z.number().default(-1),
all_modes_master_title_prestige: z.number().default(-1),
all_modes_legend_title_prestige: z.number().default(-1),
all_modes_grandmaster_title_prestige: z.number().default(-1),
all_modes_godlike_title_prestige: z.number().default(-1),
all_modes_celestial_title_prestige: z.number().default(-1),
all_modes_divine_title_prestige: z.number().default(-1),
all_modes_ascended_title_prestige: z.number().default(-1),
...duelsModeStats().all, ...duelsModeStats().all,
...duelsModeStats().ws, ...duelsModeStats().ws,
...duelsModeStats().bestWs, ...duelsModeStats().bestWs,