Added mega walls card
This commit is contained in:
64
src/app/(stats)/player/[ign]/_stats/megawalls/megawalls.tsx
Normal file
64
src/app/(stats)/player/[ign]/_stats/megawalls/megawalls.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import Sidebar from "./_components/Sidebar"
|
|||||||
import BedwarsStats from "./_stats/bedwars/bedwars"
|
import BedwarsStats from "./_stats/bedwars/bedwars"
|
||||||
import BuildBattleStats from "./_stats/build-battle/build-battle"
|
import BuildBattleStats from "./_stats/build-battle/build-battle"
|
||||||
import DuelsStats from "./_stats/duels/duels"
|
import DuelsStats from "./_stats/duels/duels"
|
||||||
|
import MegaWallsStats from "./_stats/megawalls/megawalls"
|
||||||
import MurderMysteryStats from "./_stats/murder-mystery/murder-mystery"
|
import MurderMysteryStats from "./_stats/murder-mystery/murder-mystery"
|
||||||
import PitStats from "./_stats/pit/pit"
|
import PitStats from "./_stats/pit/pit"
|
||||||
import SkyWarsStats from "./_stats/skywars/skywars"
|
import SkyWarsStats from "./_stats/skywars/skywars"
|
||||||
@@ -119,6 +120,7 @@ async function SuspendedPage({ ign: pign }: { ign: string }) {
|
|||||||
<UHCStats stats={player.stats.UHC} />
|
<UHCStats stats={player.stats.UHC} />
|
||||||
<PitStats stats={player.stats.Pit} />
|
<PitStats stats={player.stats.Pit} />
|
||||||
<TNTGamesStats stats={player.stats.TNTGames} />
|
<TNTGamesStats stats={player.stats.TNTGames} />
|
||||||
|
<MegaWallsStats stats={player.stats.MegaWalls} />
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
</div>
|
||||||
) :
|
) :
|
||||||
|
|||||||
40
src/data/hypixel/megawalls.ts
Normal file
40
src/data/hypixel/megawalls.ts
Normal 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
|
||||||
24
src/lib/hypixel/megawalls/general.ts
Normal file
24
src/lib/hypixel/megawalls/general.ts
Normal 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]
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
bedwarsStatsSchema,
|
bedwarsStatsSchema,
|
||||||
buildBattleStatsSchema,
|
buildBattleStatsSchema,
|
||||||
duelsStatsSchema,
|
duelsStatsSchema,
|
||||||
|
megawallsStats,
|
||||||
murderMysteryStatsSchema,
|
murderMysteryStatsSchema,
|
||||||
pitStats,
|
pitStats,
|
||||||
skywarsStatsSchema,
|
skywarsStatsSchema,
|
||||||
@@ -30,7 +31,13 @@ export const playerSchema = z.looseObject({
|
|||||||
BuildBattle: buildBattleStatsSchema.optional(),
|
BuildBattle: buildBattleStatsSchema.optional(),
|
||||||
UHC: uhcSchema.optional(),
|
UHC: uhcSchema.optional(),
|
||||||
Pit: pitStats.optional(),
|
Pit: pitStats.optional(),
|
||||||
TNTGames: tntGamesStatsSchema.optional()
|
TNTGames: tntGamesStatsSchema.optional(),
|
||||||
|
Walls3: megawallsStats.optional()
|
||||||
|
}).transform(({ Walls3, ...rest }) => {
|
||||||
|
return {
|
||||||
|
MegaWalls: Walls3,
|
||||||
|
...rest
|
||||||
|
}
|
||||||
}).optional(),
|
}).optional(),
|
||||||
quests: z.record(
|
quests: z.record(
|
||||||
z.string(),
|
z.string(),
|
||||||
|
|||||||
@@ -553,3 +553,60 @@ export const tntGamesStatsSchema = z.looseObject({
|
|||||||
deaths_capture: z.number().default(0),
|
deaths_capture: z.number().default(0),
|
||||||
...tntGamesModeStats()
|
...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()
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user