Added mega walls card

This commit is contained in:
2025-09-07 11:36:19 +02:00
parent 4612222207
commit 33d02113da
6 changed files with 195 additions and 1 deletions

View File

@@ -0,0 +1,64 @@
import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
import { Card, CardContent } from "@/components/ui/card"
import { Separator } from "@/components/ui/separator"
import { formatNumber } from "@/lib/formatters"
import { devide } from "@/lib/hypixel/general"
import { getDifficultyColor, getMostPlayed } from "@/lib/hypixel/megawalls/general"
import { NonNullStats } from "@/lib/schema/player"
import { cn } from "@/lib/utils"
import CollapsedStats from "../../_components/CollapsedStats"
export default function MegaWallsStats({ stats }: { stats: NonNullStats["MegaWalls"] }) {
if (!stats) return null
const kd = formatNumber(devide(stats.kills, stats.deaths))
const fkd = formatNumber(devide(stats.final_kills, stats.final_deaths))
const wl = formatNumber(devide(stats.wins, stats.losses))
const mostPlayed = getMostPlayed(stats)
const difficultyColor = getDifficultyColor(mostPlayed !== null ? mostPlayed.difficulty : 1)
return (
<AccordionItem value="megawalls">
<Card className="py-0">
<CardContent>
<AccordionTrigger className="items-center py-2 hover:no-underline hover:cursor-pointer">
<h1 className="text-xl font-bold">Mega Walls</h1>
<div className="flex gap-4">
<CollapsedStats
stats={[
{
title: <p>Main</p>,
stat: (
<p className={cn("font-bold", mostPlayed && `text-mc-${difficultyColor}`)}>
{mostPlayed !== null ? mostPlayed.name : "Unknown"}
</p>
)
},
{
title: <p>KD</p>,
stat: <p>{kd}</p>
},
{
title: <p>FKD</p>,
stat: <p>{fkd}</p>
},
{
title: <p>Wins</p>,
stat: <p>{formatNumber(stats.wins)}</p>
},
{
title: <p>WL</p>,
stat: <p>{wl}</p>
}
]}
/>
</div>
</AccordionTrigger>
<AccordionContent>
<Separator className="my-4" />
</AccordionContent>
</CardContent>
</Card>
</AccordionItem>
)
}

View File

@@ -13,6 +13,7 @@ import Sidebar from "./_components/Sidebar"
import BedwarsStats from "./_stats/bedwars/bedwars"
import BuildBattleStats from "./_stats/build-battle/build-battle"
import DuelsStats from "./_stats/duels/duels"
import MegaWallsStats from "./_stats/megawalls/megawalls"
import MurderMysteryStats from "./_stats/murder-mystery/murder-mystery"
import PitStats from "./_stats/pit/pit"
import SkyWarsStats from "./_stats/skywars/skywars"
@@ -119,6 +120,7 @@ async function SuspendedPage({ ign: pign }: { ign: string }) {
<UHCStats stats={player.stats.UHC} />
<PitStats stats={player.stats.Pit} />
<TNTGamesStats stats={player.stats.TNTGames} />
<MegaWallsStats stats={player.stats.MegaWalls} />
</Accordion>
</div>
) :

View File

@@ -0,0 +1,40 @@
export const CLASSES = [
{ id: "angel", name: "Angel", difficulty: 3 },
{ id: "arcanist", name: "Arcanist", difficulty: 1 },
{ id: "assassin", name: "Assassin", difficulty: 2 },
{ id: "automaton", name: "Automaton", difficulty: 4 },
{ id: "blaze", name: "Blaze", difficulty: 2 },
{ id: "cow", name: "Cow", difficulty: 1 },
{ id: "creeper", name: "Creeper", difficulty: 3 },
{ id: "dragon", name: "Dragon", difficulty: 4 },
{ id: "dreadlord", name: "Dreadlord", difficulty: 1 },
{ id: "enderman", name: "Enderman", difficulty: 2 },
{ id: "golem", name: "Golem", difficulty: 1 },
{ id: "herobrine", name: "Herobrine", difficulty: 1 },
{ id: "hunter", name: "Hunter", difficulty: 2 },
{ id: "moleman", name: "Moleman", difficulty: 3 },
{ id: "phoenix", name: "Phoenix", difficulty: 3 },
{ id: "pigman", name: "Pigman", difficulty: 1 },
{ id: "pirate", name: "Pirate", difficulty: 3 },
{ id: "renegade", name: "Renegade", difficulty: 4 },
{ id: "shaman", name: "Shaman", difficulty: 2 },
{ id: "shark", name: "Shark", difficulty: 3 },
{ id: "sheep", name: "Sheep", difficulty: 3 },
{ id: "skeleton", name: "Skeleton", difficulty: 3 },
{ id: "snowman", name: "Snowman", difficulty: 4 },
{ id: "spider", name: "Spider", difficulty: 3 },
{ id: "squid", name: "Squid", difficulty: 2 },
{ id: "werewolf", name: "Werewolf", difficulty: 2 },
{ id: "zombie", name: "Zombie", difficulty: 1 }
] as const
export const DIFFICULTIES = {
1: "green",
2: "yellow",
3: "red",
4: "dark-red"
} as const
export const MODES = [
{ id: "standard", name: "Normal" },
{ id: "face_off", name: "Face Off" },
{ id: "gvg", name: "Casual Brawl" }
] as const

View File

@@ -0,0 +1,24 @@
import { CLASSES, DIFFICULTIES } from "@/data/hypixel/megawalls"
import { NonNullStats } from "@/lib/schema/player"
export function getMostPlayed(stats: NonNullable<NonNullStats["MegaWalls"]>) {
let mostPlayedClass: typeof CLASSES[number] | null = null
let maxPlays = 0
for (const classObj of CLASSES) {
const wins = stats[`${classObj.id}_wins`] || 0
const losses = stats[`${classObj.id}_losses`] || 0
const totalPlays = wins + losses
if (totalPlays > maxPlays) {
maxPlays = totalPlays
mostPlayedClass = classObj
}
}
return mostPlayedClass
}
export function getDifficultyColor(val: 1 | 2 | 3 | 4) {
return DIFFICULTIES[val]
}

View File

@@ -3,6 +3,7 @@ import {
bedwarsStatsSchema,
buildBattleStatsSchema,
duelsStatsSchema,
megawallsStats,
murderMysteryStatsSchema,
pitStats,
skywarsStatsSchema,
@@ -30,7 +31,13 @@ export const playerSchema = z.looseObject({
BuildBattle: buildBattleStatsSchema.optional(),
UHC: uhcSchema.optional(),
Pit: pitStats.optional(),
TNTGames: tntGamesStatsSchema.optional()
TNTGames: tntGamesStatsSchema.optional(),
Walls3: megawallsStats.optional()
}).transform(({ Walls3, ...rest }) => {
return {
MegaWalls: Walls3,
...rest
}
}).optional(),
quests: z.record(
z.string(),

View File

@@ -553,3 +553,60 @@ export const tntGamesStatsSchema = z.looseObject({
deaths_capture: z.number().default(0),
...tntGamesModeStats()
})
function megawallsModeStats() {
const ids = [
"angel",
"arcanist",
"assassin",
"automaton",
"blaze",
"cow",
"creeper",
"dragon",
"dreadlord",
"enderman",
"golem",
"herobrine",
"hunter",
"moleman",
"phoenix",
"pigman",
"pirate",
"renegade",
"shaman",
"shark",
"sheep",
"skeleton",
"snowman",
"spider",
"squid",
"werewolf",
"zombie"
] as const
const stats = [
"wins",
"losses"
] as const
const entries = new Map<string, z.ZodDefault<z.ZodNumber>>()
for (const id of ids) {
for (const stat of stats) {
entries.set(`${id}_${stat}`, z.number().default(0))
}
}
return Object.fromEntries(entries) as Record<`${typeof ids[number]}_${typeof stats[number]}`, z.ZodDefault<z.ZodNumber>>
}
export const megawallsStats = z.looseObject({
kills: z.number().default(0),
deaths: z.number().default(0),
wins: z.number().default(0),
losses: z.number().default(0),
final_kills: z.number().default(0),
final_deaths: z.number().default(0),
...megawallsModeStats()
})