Updated pixel party stats
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
|
import { formatNumber } from "@/lib/formatters"
|
||||||
import { getArcadeTotalWins } from "@/lib/hypixel/arcade/general"
|
import { getArcadeTotalWins } from "@/lib/hypixel/arcade/general"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { BasicStat } from "../../_components/Stats"
|
||||||
import GeneralStats from "../GeneralStats"
|
import GeneralStats from "../GeneralStats"
|
||||||
|
import { ArcadeMiniWallsStats, ArcadePixelPartyStats } from "./stats"
|
||||||
|
|
||||||
export default function ArcadeStats({ stats }: { stats: NonNullStats["Arcade"] }) {
|
export default function ArcadeStats({ stats }: { stats: NonNullStats["Arcade"] }) {
|
||||||
if (!stats) return null
|
if (!stats) return null
|
||||||
@@ -18,6 +21,14 @@ export default function ArcadeStats({ stats }: { stats: NonNullStats["Arcade"] }
|
|||||||
}]}
|
}]}
|
||||||
>
|
>
|
||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
|
<div>
|
||||||
|
<BasicStat title="Arcade Coins: " value={formatNumber(stats.coins)} className="text-mc-gold" />
|
||||||
|
</div>
|
||||||
|
<Separator className="my-4" />
|
||||||
|
<ArcadeMiniWallsStats stats={stats} />
|
||||||
|
<Separator className="my-4" />
|
||||||
|
<ArcadePixelPartyStats stats={stats} />
|
||||||
|
<Separator className="my-4" />
|
||||||
</GeneralStats>
|
</GeneralStats>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/app/(stats)/player/[ign]/_stats/arcade/stats.tsx
Normal file
65
src/app/(stats)/player/[ign]/_stats/arcade/stats.tsx
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { formatNumber } from "@/lib/formatters"
|
||||||
|
import { devide } from "@/lib/hypixel/general"
|
||||||
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { capitalizeFirstLetter } from "@/lib/utils"
|
||||||
|
import { BasicStat } from "../../_components/Stats"
|
||||||
|
import { PixelPartyStatsTable } from "./table"
|
||||||
|
|
||||||
|
export function ArcadePixelPartyStats({ stats }: { stats: NonNullable<NonNullStats["Arcade"]> }) {
|
||||||
|
const losses = (stats.pixel_party?.games_played || 0) - (stats.pixel_party?.wins || 0)
|
||||||
|
const wl = formatNumber(devide(stats.pixel_party?.wins || 0, losses))
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2 className="pb-5 text-xl font-bold">Pixel Party</h2>
|
||||||
|
<div className="flex pb-5">
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Wins: " value={formatNumber(stats.pixel_party?.wins || 0)} />
|
||||||
|
<BasicStat title="Losses: " value={formatNumber(losses)} />
|
||||||
|
<BasicStat title="Win/Loss Ratio: " value={wl} />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Games Played: " value={formatNumber(stats.pixel_party?.games_played || 0)} />
|
||||||
|
<BasicStat title="Rounds Completed: " value={formatNumber(stats.pixel_party?.rounds_completed || 0)} />
|
||||||
|
<BasicStat title="Highest Round: " value={formatNumber(stats.pixel_party?.highest_round || 0)} />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Power-ups Collected: " value={formatNumber(stats.pixel_party?.power_ups_collected || 0)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<PixelPartyStatsTable stats={stats.pixel_party} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ArcadeMiniWallsStats({ stats }: { stats: NonNullable<NonNullStats["Arcade"]> }) {
|
||||||
|
const kd = formatNumber(devide(stats.kills_mini_walls + stats.final_kills_mini_walls, stats.deaths_mini_walls))
|
||||||
|
const ac = formatNumber(devide(stats.arrows_hit_mini_walls, stats.arrows_shot_mini_walls))
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2 className="pb-5 text-xl font-bold">Mini Walls</h2>
|
||||||
|
<div className="flex">
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Wins: " value={stats.wins_mini_walls} />
|
||||||
|
<BasicStat
|
||||||
|
title="Kit Seleted: "
|
||||||
|
value={stats.miniwalls_activeKit !== undefined
|
||||||
|
? capitalizeFirstLetter(stats.miniwalls_activeKit)
|
||||||
|
: "Unknown"}
|
||||||
|
/>
|
||||||
|
<BasicStat title="Withers Killed: " value={stats.wither_kills_mini_walls} />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Kills: " value={stats.kills_mini_walls} />
|
||||||
|
<BasicStat title="Final Kills: " value={stats.final_kills_mini_walls} />
|
||||||
|
<BasicStat title="Deaths: " value={stats.deaths_mini_walls} />
|
||||||
|
<BasicStat title="Kill/Death Ratio: " value={kd} />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<BasicStat title="Arrows Hit: " value={stats.arrows_hit_mini_walls} />
|
||||||
|
<BasicStat title="Arrows Shot: " value={stats.arrows_shot_mini_walls} />
|
||||||
|
<BasicStat title="Arrow Hit Accuracy: " value={ac} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
56
src/app/(stats)/player/[ign]/_stats/arcade/table.tsx
Normal file
56
src/app/(stats)/player/[ign]/_stats/arcade/table.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||||
|
import { formatNumber } from "@/lib/formatters"
|
||||||
|
import { getArcadeMostPlayedPixelPartyMode, getArcadePixelPartyModeName, getArcadePixelPartyModeStats } from "@/lib/hypixel/arcade/general"
|
||||||
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export function PixelPartyStatsTable({ stats }: { stats: NonNullable<NonNullStats["Arcade"]>["pixel_party"] }) {
|
||||||
|
return (
|
||||||
|
<Table>
|
||||||
|
<PixelPartyStatsTableHeader />
|
||||||
|
<TableBody>
|
||||||
|
<PixelPartyTableStat modeId="normal" stats={stats} />
|
||||||
|
<PixelPartyTableStat modeId="hyper" stats={stats} />
|
||||||
|
<PixelPartyTableStat modeId="all_modes" stats={stats} />
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function PixelPartyTableStat(
|
||||||
|
{ modeId, stats }: { modeId: Parameters<typeof getArcadePixelPartyModeStats>[0], stats: NonNullable<NonNullStats["Arcade"]>["pixel_party"] }
|
||||||
|
) {
|
||||||
|
const modeName = getArcadePixelPartyModeName(modeId)
|
||||||
|
const modeStats = getArcadePixelPartyModeStats(modeId, stats)
|
||||||
|
const mostPlayed = getArcadeMostPlayedPixelPartyMode(stats) === modeId
|
||||||
|
const isMostPlayed = modeId !== "all_modes" && mostPlayed
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow className={cn(modeName === "Overall" && "font-bold", isMostPlayed && "text-mc-light-purple")}>
|
||||||
|
<TableCell>{modeName}</TableCell>
|
||||||
|
{modeStats.map((v, i) => {
|
||||||
|
return <TableCell key={i}>{formatNumber(v)}</TableCell>
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function PixelPartyStatsTableHeader() {
|
||||||
|
const headerElements = [
|
||||||
|
"Mode",
|
||||||
|
"Wins",
|
||||||
|
"Losses",
|
||||||
|
"WL",
|
||||||
|
"Games Played",
|
||||||
|
"Rounds Completed",
|
||||||
|
"Power-Ups Collected"
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
{headerElements.map((v, i) => <TableHead key={i} className="font-bold">{v}</TableHead>)}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@
|
|||||||
import { formatNumber } from "@/lib/formatters"
|
import { formatNumber } from "@/lib/formatters"
|
||||||
import { getUHCModeName, getUHCModeStats } from "@/lib/hypixel/uhc/general"
|
import { getUHCModeName, getUHCModeStats } from "@/lib/hypixel/uhc/general"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
export default function UHCStatTable({ stats }: { stats: NonNullable<NonNullStats["UHC"]> }) {
|
export default function UHCStatTable({ stats }: { stats: NonNullable<NonNullStats["UHC"]> }) {
|
||||||
return (
|
return (
|
||||||
@@ -50,8 +51,8 @@ function TableStat(
|
|||||||
const modeName = getUHCModeName(modeId === "teams" || modeId === "all_modes" ? "" : modeId)
|
const modeName = getUHCModeName(modeId === "teams" || modeId === "all_modes" ? "" : modeId)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<TableRow className={cn(modeId === "all_modes" && "font-bold")}>
|
||||||
<TableCell className={modeId === "all_modes" ? "font-bold" : undefined}>{modeId === "all_modes" ? "Overall" : modeName}</TableCell>
|
<TableCell>{modeId === "all_modes" ? "Overall" : modeName}</TableCell>
|
||||||
{modeStats.map((v, i) => {
|
{modeStats.map((v, i) => {
|
||||||
return (
|
return (
|
||||||
<TableCell key={i}>
|
<TableCell key={i}>
|
||||||
|
|||||||
@@ -22,3 +22,37 @@ export const WINS = [
|
|||||||
"wins_mini_walls",
|
"wins_mini_walls",
|
||||||
"wins_zombies"
|
"wins_zombies"
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
|
export const ZOMBIESMODES = [
|
||||||
|
{ id: "deadend", name: "Dead End", color: "gold" },
|
||||||
|
{ id: "badblood", name: "Bad Blood", color: "red" },
|
||||||
|
{ id: "alienarcadium", name: "Alien Arcadium", color: "pink" }
|
||||||
|
] as const
|
||||||
|
export const ZOMBIESTYPES = [
|
||||||
|
{ id: "basic", name: "Basic" },
|
||||||
|
{ id: "blaze", name: "Blaze" },
|
||||||
|
{ id: "empowered", name: "Empowered" },
|
||||||
|
{ id: "ender", name: "Ender" },
|
||||||
|
{ id: "endermite", name: "Endermite" },
|
||||||
|
{ id: "fire", name: "Fire" },
|
||||||
|
{ id: "guardian", name: "Guardian" },
|
||||||
|
{ id: "magma", name: "Magma" },
|
||||||
|
{ id: "magma_cube", name: "Magma Cube" },
|
||||||
|
{ id: "pig_zombie", name: "Pig Zombie" },
|
||||||
|
{ id: "skelefish", name: "Skelefish" },
|
||||||
|
{ id: "tnt_baby", name: "TNT Baby" },
|
||||||
|
{ id: "tnt", name: "Bombie", color: "gold" },
|
||||||
|
{ id: "inferno", name: "Inferno", color: "gold" },
|
||||||
|
{ id: "broodmother", name: "Broodmother", color: "gold" },
|
||||||
|
{ id: "king_slime", name: "King Slime", color: "red" },
|
||||||
|
{ id: "wither", name: "Wither", color: "red" },
|
||||||
|
{ id: "herobrine", name: "Herobrine", color: "red" },
|
||||||
|
{ id: "mega_blob", name: "Mega Blob", color: "pink" },
|
||||||
|
{ id: "mega_magma", name: "Mega Magma", color: "pink" },
|
||||||
|
{ id: "world_ender", name: "World Ender", color: "pink" }
|
||||||
|
] as const
|
||||||
|
export const PIXELPARTYMODES = [
|
||||||
|
{ id: "normal", name: "Normal" },
|
||||||
|
{ id: "hyper", name: "Hyper" },
|
||||||
|
{ id: "", name: "Overall" }
|
||||||
|
] as const
|
||||||
|
|||||||
@@ -1,5 +1,50 @@
|
|||||||
import { WINS } from "@/data/hypixel/arcade"
|
import { PIXELPARTYMODES, WINS } from "@/data/hypixel/arcade"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { devide } from "../general"
|
||||||
|
|
||||||
|
export function getArcadeMostPlayedPixelPartyMode(stats: NonNullable<NonNullStats["Arcade"]>["pixel_party"]) {
|
||||||
|
if (!stats) return null
|
||||||
|
const played = [
|
||||||
|
{ games: stats.games_played_normal, modeId: "normal" as const },
|
||||||
|
{ games: stats.games_played_hyper, modeId: "hyper" as const }
|
||||||
|
]
|
||||||
|
|
||||||
|
const mostPlayed = played.reduce((max, current) => current.games > max.games ? current : max)
|
||||||
|
|
||||||
|
return mostPlayed.modeId
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getArcadePixelPartyModeName(modeId: Exclude<typeof PIXELPARTYMODES[number]["id"], ""> | "all_modes") {
|
||||||
|
if (modeId === "all_modes") return PIXELPARTYMODES.find(m => m.id === "")!.name
|
||||||
|
return PIXELPARTYMODES.find(m => m.id === modeId)!.name
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getArcadePixelPartyModeStats(
|
||||||
|
modeId: Exclude<typeof PIXELPARTYMODES[number]["id"], ""> | "all_modes",
|
||||||
|
stats: NonNullable<NonNullStats["Arcade"]>["pixel_party"]
|
||||||
|
) {
|
||||||
|
if (!stats) return [0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
if (modeId === "all_modes") {
|
||||||
|
return [
|
||||||
|
stats["wins"],
|
||||||
|
stats["games_played"] - stats["wins"],
|
||||||
|
devide(stats["wins"], stats["games_played"] - stats["wins"]),
|
||||||
|
stats["games_played"],
|
||||||
|
stats["rounds_completed"],
|
||||||
|
stats["power_ups_collected"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
stats[`wins_${modeId}`],
|
||||||
|
stats[`games_played_${modeId}`] - stats[`wins_${modeId}`],
|
||||||
|
devide(stats[`wins_${modeId}`], stats[`games_played_${modeId}`] - stats[`wins_${modeId}`]),
|
||||||
|
stats[`games_played_${modeId}`],
|
||||||
|
stats[`rounds_completed_${modeId}`],
|
||||||
|
stats[`power_ups_collected_${modeId}`]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
export function getArcadeTotalWins(stats: NonNullable<NonNullStats["Arcade"]>) {
|
export function getArcadeTotalWins(stats: NonNullable<NonNullStats["Arcade"]>) {
|
||||||
let wins = 0
|
let wins = 0
|
||||||
|
|||||||
@@ -913,9 +913,28 @@ function arcadeModeWins() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const arcadeStatsSchema = z.object({
|
export const arcadeStatsSchema = z.object({
|
||||||
|
miniwalls_activeKit: z.string().optional(),
|
||||||
|
wither_kills_mini_walls: z.number().default(0),
|
||||||
|
kills_mini_walls: z.number().default(0),
|
||||||
|
final_kills_mini_walls: z.number().default(0),
|
||||||
|
deaths_mini_walls: z.number().default(0),
|
||||||
|
arrows_hit_mini_walls: z.number().default(0),
|
||||||
|
arrows_shot_mini_walls: z.number().default(0),
|
||||||
coins: z.number().default(0),
|
coins: z.number().default(0),
|
||||||
pixel_party: z.object({
|
pixel_party: z.object({
|
||||||
wins: z.number().default(0)
|
wins: z.number().default(0),
|
||||||
|
games_played: z.number().default(0),
|
||||||
|
rounds_completed: z.number().default(0),
|
||||||
|
highest_round: z.number().default(0),
|
||||||
|
power_ups_collected: z.number().default(0),
|
||||||
|
wins_normal: z.number().default(0),
|
||||||
|
games_played_normal: z.number().default(0),
|
||||||
|
rounds_completed_normal: z.number().default(0),
|
||||||
|
power_ups_collected_normal: z.number().default(0),
|
||||||
|
wins_hyper: z.number().default(0),
|
||||||
|
games_played_hyper: z.number().default(0),
|
||||||
|
rounds_completed_hyper: z.number().default(0),
|
||||||
|
power_ups_collected_hyper: z.number().default(0)
|
||||||
}).optional(),
|
}).optional(),
|
||||||
dropper: z.object({
|
dropper: z.object({
|
||||||
wins: z.number().default(0)
|
wins: z.number().default(0)
|
||||||
|
|||||||
@@ -4,3 +4,7 @@ import { twMerge } from "tailwind-merge"
|
|||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs))
|
return twMerge(clsx(inputs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function capitalizeFirstLetter(str: string) {
|
||||||
|
return str[0].toUpperCase() + str.slice(1, str.length)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user