Updated murder mystery stats

This commit is contained in:
2025-09-02 23:27:16 +02:00
parent e536054d2d
commit 23652bd412
5 changed files with 174 additions and 7 deletions

View File

@@ -1,4 +1,6 @@
import { KNIFESKINS } from "@/data/hypixel/murder-mystery"
import { KNIFESKINS, MODES } from "@/data/hypixel/murder-mystery"
import { NonNullStats } from "@/lib/schema/player"
import { devide } from "../general"
export function getKnifeName(name?: string) {
if (!name) return KNIFESKINS.undefined
@@ -9,3 +11,60 @@ export function getKnifeName(name?: string) {
return skin
}
export function getModeTitle(mode: Exclude<typeof MODES[number]["id"], ""> | "all_modes") {
if (mode === "all_modes") return MODES.find(m => m.id === "")!.name
return MODES.find(m => m.id === mode)!.name
}
export function getBestMurderMysteryMode(stats: NonNullable<NonNullStats["MurderMystery"]>) {
let best: typeof MODES[number] | null = null
let mostPlays = 0
for (const mode of MODES.filter(m => m.id !== "")) {
const [, , , wins, losses] = getMurderMysteryModeStats(mode.id, stats)
const plays = (wins as number || 0) + (losses as number || 0)
if (plays > mostPlays) {
mostPlays = plays
best = mode
}
}
return best === null ? null : best.id
}
export function getMurderMysteryModeStats(
index: Exclude<typeof MODES[number]["id"], ""> | "all_modes",
stats: NonNullable<NonNullStats["MurderMystery"]>
) {
return murderMysteryModeStats(index, stats)
}
function murderMysteryModeStats(index: Exclude<typeof MODES[number]["id"], ""> | "all_modes", stats: NonNullable<NonNullStats["MurderMystery"]>) {
if (index === "all_modes") {
const losses = stats["games"] - stats["wins"]
return [
stats["kills"],
stats["bow_kills"],
stats["knife_kills"],
stats["thrown_knife_kills"],
stats["wins"],
losses,
devide(stats["wins"], losses),
stats["coins_pickedup"]
]
}
const losses = stats[`games_${index}`] - stats[`wins_${index}`]
return [
stats[`kills_${index}`],
stats[`bow_kills_${index}`],
stats[`knife_kills_${index}`],
stats[`thrown_knife_kills_${index}`],
stats[`wins_${index}`],
losses,
devide(stats[`wins_${index}`], losses),
stats[`coins_pickedup_${index}`]
]
}

View File

@@ -331,15 +331,50 @@ export const duelsStatsSchema = z.looseObject({
...duelsModeStats().bridge
})
function murderMysteryModeStats() {
const ids = [
"MURDER_CLASSIC",
"MURDER_ASSASSINS",
"MURDER_DOUBLE_UP",
"MURDER_HARDCORE",
"MURDER_SHOWDOWN"
] as const
const stats = [
"kills",
"bow_kills",
"knife_kills",
"thrown_knife_kills",
"wins",
"games",
"coins_pickedup"
] as const
const entries = new Map<string, z.ZodDefault<z.ZodNumber>>()
for (const id of ids) {
for (const stat of stats) {
entries.set(`${stat}_${id}`, z.number().default(0))
}
}
return Object.fromEntries(entries) as Record<`${typeof stats[number]}_${typeof ids[number]}`, z.ZodDefault<z.ZodNumber>>
}
export const murderMysteryStatsSchema = z.looseObject({
kills: z.number().default(0),
deaths: z.number().default(0),
wins: z.number().default(0),
losses: z.number().default(0),
coins: z.number().default(0),
games: z.number().default(0),
bow_kills: z.number().default(0),
knife_kills: z.number().default(0),
coins_pickedup: z.number().default(0),
kills_as_murderer: z.number().default(0),
thrown_knife_kills: z.number().default(0),
active_knife_skin: z.string().optional(),
quickest_detective_win_time_seconds: z.number().default(0),
quickest_murderer_win_time_seconds: z.number().default(0)
quickest_murderer_win_time_seconds: z.number().default(0),
...murderMysteryModeStats()
})