Finished uhc genereal stats
This commit is contained in:
33
src/app/(stats)/player/[ign]/_stats/uhc/stats.tsx
Normal file
33
src/app/(stats)/player/[ign]/_stats/uhc/stats.tsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { formatNumber } from "@/lib/formatters"
|
||||||
|
import { devide } from "@/lib/hypixel/general"
|
||||||
|
import { getUhcStar } from "@/lib/hypixel/uhc/level"
|
||||||
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { BasicStat } from "../../_components/Stats"
|
||||||
|
|
||||||
|
export default function UHCGeneralStats(
|
||||||
|
{ stats, kills, deaths, wins, heads }: { stats: NonNullable<NonNullStats["UHC"]>, kills: number, deaths: number, wins: number, heads: number }
|
||||||
|
) {
|
||||||
|
const rank = getUhcStar(stats.score)
|
||||||
|
const kd = formatNumber(devide(kills, deaths))
|
||||||
|
const kw = formatNumber(devide(kills, wins))
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Score: " value={formatNumber(stats.score)} />
|
||||||
|
<BasicStat title="Title: " value={rank.name} className={`font-bold text-mc-${rank.color}`} />
|
||||||
|
<BasicStat title="Coins: " value={formatNumber(stats.coins)} className="text-mc-gold" />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Kills: " value={formatNumber(kills)} />
|
||||||
|
<BasicStat title="Deaths: " value={formatNumber(deaths)} />
|
||||||
|
<BasicStat title="Kill/Death Ratio: " value={kd} />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Wins: " value={formatNumber(wins)} />
|
||||||
|
<BasicStat title="Kill/Win Ratio: " value={kw} />
|
||||||
|
<BasicStat title="Heads Eaten: " value={formatNumber(heads)} />
|
||||||
|
<BasicStat title="Ultimates Crafted: " value={formatNumber(stats.ultimates_crafted + stats.ultimates_crafted_solo)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,15 +3,18 @@ import { Card, CardContent } from "@/components/ui/card"
|
|||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import { formatNumber } from "@/lib/formatters"
|
import { formatNumber } from "@/lib/formatters"
|
||||||
import { devide } from "@/lib/hypixel/general"
|
import { devide } from "@/lib/hypixel/general"
|
||||||
|
import { getStatsCombined } from "@/lib/hypixel/uhc/general"
|
||||||
import { getUhcStarValue } from "@/lib/hypixel/uhc/level"
|
import { getUhcStarValue } from "@/lib/hypixel/uhc/level"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
import CollapsedStats from "../../_components/CollapsedStats"
|
import CollapsedStats from "../../_components/CollapsedStats"
|
||||||
import UHCProgress from "./progress"
|
import UHCProgress from "./progress"
|
||||||
|
import UHCGeneralStats from "./stats"
|
||||||
|
|
||||||
export default function UHCStats({ stats }: { stats: NonNullStats["UHC"] }) {
|
export default function UHCStats({ stats }: { stats: NonNullStats["UHC"] }) {
|
||||||
if (!stats) return null
|
if (!stats) return null
|
||||||
|
|
||||||
const kd = formatNumber(devide(stats.kills, stats.deaths))
|
const combined = getStatsCombined(stats)
|
||||||
|
const kd = formatNumber(devide(combined.kills, combined.deaths))
|
||||||
const star = getUhcStarValue(stats.score)
|
const star = getUhcStarValue(stats.score)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -33,7 +36,7 @@ export default function UHCStats({ stats }: { stats: NonNullStats["UHC"] }) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <p>Wins</p>,
|
title: <p>Wins</p>,
|
||||||
stat: <p className="text-muted-foreground">{formatNumber(stats.wins)}</p>
|
stat: <p className="text-muted-foreground">{formatNumber(combined.wins)}</p>
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
@@ -42,6 +45,8 @@ export default function UHCStats({ stats }: { stats: NonNullStats["UHC"] }) {
|
|||||||
<AccordionContent>
|
<AccordionContent>
|
||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
<UHCProgress score={stats.score} />
|
<UHCProgress score={stats.score} />
|
||||||
|
<Separator className="my-4" />
|
||||||
|
<UHCGeneralStats stats={stats} kills={combined.kills} deaths={combined.deaths} heads={combined.heads} wins={combined.wins} />
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
export const TITLE = "UHC" as const
|
export const TITLE = "UHC" as const
|
||||||
export const MODES = [
|
export const MODES = [
|
||||||
{ id: ["solo"], name: "Solo" },
|
{ id: "solo", name: "Solo" },
|
||||||
{ id: [""], name: "Teams" },
|
{ id: "", name: "Teams" },
|
||||||
{ id: ["red vs blue", "_red_vs_blue"], name: "Red vs. Blue" },
|
{ id: "red_vs_blue", name: "Red vs. Blue" },
|
||||||
{ id: ["no diamonds", "_no_diamonds"], name: "No Diamonds" },
|
{ id: "no_diamonds", name: "No Diamonds" },
|
||||||
{ id: ["vanilla doubles", "_vanilla_doubles"], name: "Vanilla Doubles" },
|
{ id: "vanilla_doubles", name: "Vanilla Doubles" },
|
||||||
{ id: ["brawl"], name: "Brawl" },
|
{ id: "brawl", name: "Brawl" },
|
||||||
{ id: ["solo brawl", "_solo_brawl"], name: "Solo Brawl" },
|
{ id: "solo_brawl", name: "Solo Brawl" },
|
||||||
{ id: ["duo brawl", "_duo_brawl"], name: "Duo Brawl" }
|
{ id: "duo_brawl", name: "Duo Brawl" }
|
||||||
] as const
|
] as const
|
||||||
export const STARS = [
|
export const STARS = [
|
||||||
{ value: 0, name: "Recruit", color: "gray" },
|
{ value: 0, name: "Recruit", color: "gray" },
|
||||||
|
|||||||
55
src/lib/hypixel/uhc/general.ts
Normal file
55
src/lib/hypixel/uhc/general.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { MODES } from "@/data/hypixel/uhc"
|
||||||
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
|
||||||
|
export function getStatsCombined(stats: NonNullable<NonNullStats["UHC"]>) {
|
||||||
|
return {
|
||||||
|
wins: getUHCWins(stats),
|
||||||
|
kills: getUHCKills(stats),
|
||||||
|
deaths: getUHCDeaths(stats),
|
||||||
|
heads: getUHCHeads(stats)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUHCWins(stats: NonNullable<NonNullStats["UHC"]>) {
|
||||||
|
let wins = 0
|
||||||
|
const ids = MODES.filter(m => m.id !== "").map(m => m.id)
|
||||||
|
|
||||||
|
for (const id of ids) {
|
||||||
|
wins = wins + stats[`wins_${id}`]
|
||||||
|
}
|
||||||
|
|
||||||
|
return wins + stats.wins
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUHCKills(stats: NonNullable<NonNullStats["UHC"]>) {
|
||||||
|
let kills = 0
|
||||||
|
const ids = MODES.filter(m => m.id !== "").map(m => m.id)
|
||||||
|
|
||||||
|
for (const id of ids) {
|
||||||
|
kills = kills + stats[`kills_${id}`]
|
||||||
|
}
|
||||||
|
|
||||||
|
return kills + stats.kills
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUHCDeaths(stats: NonNullable<NonNullStats["UHC"]>) {
|
||||||
|
let deaths = 0
|
||||||
|
const ids = MODES.filter(m => m.id !== "").map(m => m.id)
|
||||||
|
|
||||||
|
for (const id of ids) {
|
||||||
|
deaths = deaths + stats[`deaths_${id}`]
|
||||||
|
}
|
||||||
|
|
||||||
|
return deaths + stats.deaths
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUHCHeads(stats: NonNullable<NonNullStats["UHC"]>) {
|
||||||
|
let heads = 0
|
||||||
|
const ids = MODES.filter(m => m.id !== "").map(m => m.id)
|
||||||
|
|
||||||
|
for (const id of ids) {
|
||||||
|
heads = heads + stats[`heads_eaten_${id}`]
|
||||||
|
}
|
||||||
|
|
||||||
|
return heads + stats.heads_eaten
|
||||||
|
}
|
||||||
@@ -405,9 +405,43 @@ export const buildBattleStatsSchema = z.looseObject({
|
|||||||
wins_speed_builders_latest: z.number().default(0)
|
wins_speed_builders_latest: z.number().default(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function uhcModesStats() {
|
||||||
|
const ids = [
|
||||||
|
"solo",
|
||||||
|
"red_vs_blue",
|
||||||
|
"no_diamonds",
|
||||||
|
"vanilla_doubles",
|
||||||
|
"brawl",
|
||||||
|
"solo_brawl",
|
||||||
|
"duo_brawl"
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const stats = [
|
||||||
|
"wins",
|
||||||
|
"kills",
|
||||||
|
"deaths",
|
||||||
|
"heads_eaten"
|
||||||
|
] 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 uhcSchema = z.looseObject({
|
export const uhcSchema = z.looseObject({
|
||||||
kills: z.number().default(0),
|
kills: z.number().default(0),
|
||||||
deaths: z.number().default(0),
|
deaths: z.number().default(0),
|
||||||
wins: z.number().default(0),
|
wins: z.number().default(0),
|
||||||
score: z.number().default(0)
|
heads_eaten: z.number().default(0),
|
||||||
|
score: z.number().default(0),
|
||||||
|
coins: z.number().default(0),
|
||||||
|
ultimates_crafted: z.number().default(0),
|
||||||
|
ultimates_crafted_solo: z.number().default(0),
|
||||||
|
...uhcModesStats()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user