diff --git a/src/app/(stats)/player/[ign]/_stats/speeduhc/speeduhc.tsx b/src/app/(stats)/player/[ign]/_stats/speeduhc/speeduhc.tsx
index 4a28057..7e769d7 100644
--- a/src/app/(stats)/player/[ign]/_stats/speeduhc/speeduhc.tsx
+++ b/src/app/(stats)/player/[ign]/_stats/speeduhc/speeduhc.tsx
@@ -6,7 +6,7 @@ import { NonNullStats } from "@/lib/schema/player"
import GeneralStats from "../GeneralStats"
import SpeedUHCProgress from "./progress"
import SpeedUHCGeneralStats from "./stats"
-import { SpeedUHCModeStatsTable } from "./table"
+import { SpeedUHCMasteryStatsTable, SpeedUHCModeStatsTable } from "./table"
export default function SpeedUHCStats({ stats, uhcCoins }: { stats: NonNullStats["SpeedUHC"], uhcCoins: number | undefined }) {
if (!stats) return null
@@ -45,6 +45,8 @@ export default function SpeedUHCStats({ stats, uhcCoins }: { stats: NonNullStats
+
+
)
}
diff --git a/src/app/(stats)/player/[ign]/_stats/speeduhc/table.tsx b/src/app/(stats)/player/[ign]/_stats/speeduhc/table.tsx
index a81c414..2630881 100644
--- a/src/app/(stats)/player/[ign]/_stats/speeduhc/table.tsx
+++ b/src/app/(stats)/player/[ign]/_stats/speeduhc/table.tsx
@@ -1,9 +1,74 @@
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { formatNumber } from "@/lib/formatters"
-import { getSpeedUHCBestMode, getSpeedUHCModeName, getSpeedUHCModeStats } from "@/lib/hypixel/speeduhc/general"
+import {
+ getSpeedUHCBestMastery,
+ getSpeedUHCBestMode,
+ getSpeedUHCMasteryName,
+ getSpeedUHCMasteryStats,
+ getSpeedUHCModeName,
+ getSpeedUHCModeStats
+} from "@/lib/hypixel/speeduhc/general"
import { NonNullStats } from "@/lib/schema/player"
import { cn } from "@/lib/utils"
+export function SpeedUHCMasteryStatsTable({ stats }: { stats: NonNullable }) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function SpeedUHCMasteryStatRow(
+ { id, stats }: { id: Parameters[0], stats: NonNullable }
+) {
+ const modeStats = getSpeedUHCMasteryStats(id, stats)
+ const modeName = getSpeedUHCMasteryName(id)
+ const isBest = getSpeedUHCBestMastery(stats) === id
+
+ return (
+
+ {modeName}
+ {modeStats.map((v, i) => {
+ return {formatNumber(v)}
+ })}
+
+ )
+}
+
+function SpeedUHCMasteryStatsTableHeader() {
+ const headerElements = [
+ "Mastery",
+ "Kills",
+ "Deaths",
+ "KD",
+ "Wins",
+ "Losses",
+ "WL"
+ ]
+
+ return (
+
+
+ {headerElements.map((v, i) => {
+ return {v}
+ })}
+
+
+ )
+}
+
export function SpeedUHCModeStatsTable({ stats }: { stats: NonNullable }) {
return (
diff --git a/src/lib/hypixel/speeduhc/general.ts b/src/lib/hypixel/speeduhc/general.ts
index 3fb620c..c46a90d 100644
--- a/src/lib/hypixel/speeduhc/general.ts
+++ b/src/lib/hypixel/speeduhc/general.ts
@@ -1,7 +1,57 @@
-import { MODES, TITLES } from "@/data/hypixel/speeduhc"
+import { MASTERIES, MODES, TITLES } from "@/data/hypixel/speeduhc"
import { NonNullStats } from "@/lib/schema/player"
import { devide } from "../general"
+export function getSpeedUHCMasteryName(modeId: Exclude | "all") {
+ if (modeId === "all") {
+ return MASTERIES.find(m => m.id === "")!.name
+ }
+
+ return MASTERIES.find(m => m.id === modeId)!.name
+}
+
+export function getSpeedUHCBestMastery(stats: NonNullable) {
+ let bestMastery: typeof MASTERIES[number]["id"] | null = null
+ let maxGames = 0
+
+ for (const mode of MASTERIES) {
+ if (mode.id === "") continue
+
+ const wins = stats[`wins_${mode.id}`]
+ const losses = stats[`losses_${mode.id}`]
+ const totalGames = wins + losses
+
+ if (totalGames > maxGames) {
+ maxGames = totalGames
+ bestMastery = mode.id
+ }
+ }
+
+ return bestMastery
+}
+
+export function getSpeedUHCMasteryStats(id: Exclude | "all", stats: NonNullable) {
+ if (id === "all") {
+ return [
+ stats.kills,
+ stats.deaths,
+ devide(stats.kills, stats.deaths),
+ stats.wins,
+ stats.losses,
+ devide(stats.wins, stats.losses)
+ ]
+ }
+
+ return [
+ stats[`kills_${id}`],
+ stats[`deaths_${id}`],
+ devide(stats[`kills_${id}`], stats[`deaths_${id}`]),
+ stats[`wins_${id}`],
+ stats[`losses_${id}`],
+ devide(stats[`wins_${id}`], stats[`losses_${id}`])
+ ]
+}
+
export function getSpeedUHCModeName(modeId: Exclude | "all_modes") {
if (modeId === "all_modes") {
return MODES.find(m => m.id === "")!.name
@@ -32,25 +82,13 @@ export function getSpeedUHCBestMode(stats: NonNullable
export function getSpeedUHCModeStats(modeId: Exclude | "all_modes", stats: NonNullable) {
if (modeId === "all_modes") {
- const bestMode = getSpeedUHCBestMode(stats)
- if (!bestMode) {
- return [
- stats.kills,
- stats.deaths,
- devide(stats.kills, stats.deaths),
- stats.wins,
- stats.losses,
- devide(stats.wins, stats.losses)
- ]
- }
-
return [
- stats[`kills_${bestMode}`],
- stats[`deaths_${bestMode}`],
- devide(stats[`kills_${bestMode}`], stats[`deaths_${bestMode}`]),
- stats[`wins_${bestMode}`],
- stats[`losses_${bestMode}`],
- devide(stats[`wins_${bestMode}`], stats[`losses_${bestMode}`])
+ stats.kills,
+ stats.deaths,
+ devide(stats.kills, stats.deaths),
+ stats.wins,
+ stats.losses,
+ devide(stats.wins, stats.losses)
]
}
diff --git a/src/lib/schema/stats.ts b/src/lib/schema/stats.ts
index 34eee1c..4eefe2f 100644
--- a/src/lib/schema/stats.ts
+++ b/src/lib/schema/stats.ts
@@ -1048,6 +1048,40 @@ export const arcadeStatsSchema = z.object({
...arcadeZombiesTypeStats()
})
+function speedUhcModeModeMasteryStats() {
+ const ids = [
+ "mastery_wild_specialist",
+ "mastery_sniper",
+ "mastery_berserk",
+ "mastery_fortune",
+ "mastery_master_baker",
+ "mastery_invigorate",
+ "mastery_huntsman",
+ "mastery_vampirism",
+ "mastery_guardian",
+ "solo_normal",
+ "solo_insane",
+ "team_normal",
+ "team_insane"
+ ] as const
+
+ const stats = [
+ "kills",
+ "deaths",
+ "wins",
+ "losses"
+ ] as const
+
+ const entries = new Map>()
+ 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>
+}
+
export const speedUhcStatsSchema = z.object({
kills: z.number().default(0),
deaths: z.number().default(0),
@@ -1055,20 +1089,5 @@ export const speedUhcStatsSchema = z.object({
losses: z.number().default(0),
score: z.number().default(0),
coins: z.number().default(0),
- kills_solo_normal: z.number().default(0),
- deaths_solo_normal: z.number().default(0),
- wins_solo_normal: z.number().default(0),
- losses_solo_normal: z.number().default(0),
- kills_solo_insane: z.number().default(0),
- deaths_solo_insane: z.number().default(0),
- wins_solo_insane: z.number().default(0),
- losses_solo_insane: z.number().default(0),
- kills_team_normal: z.number().default(0),
- deaths_team_normal: z.number().default(0),
- wins_team_normal: z.number().default(0),
- losses_team_normal: z.number().default(0),
- kills_team_insane: z.number().default(0),
- deaths_team_insane: z.number().default(0),
- wins_team_insane: z.number().default(0),
- losses_team_insane: z.number().default(0)
+ ...speedUhcModeModeMasteryStats()
})