Added warlords class stats table
This commit is contained in:
@@ -10,7 +10,7 @@ import { CSS } from "@dnd-kit/utilities"
|
|||||||
import Cookies from "js-cookie"
|
import Cookies from "js-cookie"
|
||||||
import { GripVertical } from "lucide-react"
|
import { GripVertical } from "lucide-react"
|
||||||
import { usePathname } from "next/navigation"
|
import { usePathname } from "next/navigation"
|
||||||
import { useEffect, useMemo, useState } from "react"
|
import { useEffect, useRef, useState } from "react"
|
||||||
|
|
||||||
import ArcadeStats from "./_stats/arcade/arcade"
|
import ArcadeStats from "./_stats/arcade/arcade"
|
||||||
import BedwarsStats from "./_stats/bedwars/bedwars"
|
import BedwarsStats from "./_stats/bedwars/bedwars"
|
||||||
@@ -114,17 +114,14 @@ export function PlayerStats(
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const cookieOpts = useMemo(() => {
|
const cookieOpts = useRef<Parameters<typeof Cookies.set>[2]>({
|
||||||
const cookieOpts: Parameters<typeof Cookies.set>[2] = {
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
secure: process.env.NODE_ENV === "production",
|
||||||
sameSite: "lax",
|
sameSite: "lax",
|
||||||
expires: 365
|
expires: 365
|
||||||
}
|
})
|
||||||
return cookieOpts
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
function updateStatsOrder(arr: string[]) {
|
function updateStatsOrder(arr: string[]) {
|
||||||
Cookies.set(COOKIE_VALUES.statsOrder, JSON.stringify(arr), cookieOpts)
|
Cookies.set(COOKIE_VALUES.statsOrder, JSON.stringify(arr), cookieOpts.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDragEnd(event: DragEndEvent) {
|
function handleDragEnd(event: DragEndEvent) {
|
||||||
@@ -147,7 +144,7 @@ export function PlayerStats(
|
|||||||
}
|
}
|
||||||
const cookie = Cookies.get(COOKIE_VALUES.statsOrder)
|
const cookie = Cookies.get(COOKIE_VALUES.statsOrder)
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
Cookies.set(COOKIE_VALUES.statsOrder, cookie, cookieOpts)
|
Cookies.set(COOKIE_VALUES.statsOrder, cookie, cookieOpts.current)
|
||||||
}
|
}
|
||||||
}, [layout, cookieOpts])
|
}, [layout, cookieOpts])
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,82 @@
|
|||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||||
import { formatNumber } from "@/lib/formatters"
|
import { formatNumber } from "@/lib/formatters"
|
||||||
import { getWarlordsModeName, getWarlordsModeStats, getWarlordsMostPlayedMode } from "@/lib/hypixel/warlords/general"
|
import {
|
||||||
|
getWarlordsClassLevel,
|
||||||
|
getWarlordsClassName,
|
||||||
|
getWarlordsClassStats,
|
||||||
|
getWarlordsModeName,
|
||||||
|
getWarlordsModeStats,
|
||||||
|
getWarlordsMostPlayedClass,
|
||||||
|
getWarlordsMostPlayedMode
|
||||||
|
} from "@/lib/hypixel/warlords/general"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export function WarlordsClassStatsTable({ stats }: { stats: NonNullable<NonNullStats["Warlords"]> }) {
|
||||||
|
return (
|
||||||
|
<Table>
|
||||||
|
<WarlordsClassStatsTableHeader />
|
||||||
|
<TableBody>
|
||||||
|
<WarlordsClassStatsTableStat classId="mage" stats={stats} />
|
||||||
|
<WarlordsClassStatsTableStat classId="paladin" stats={stats} />
|
||||||
|
<WarlordsClassStatsTableStat classId="shaman" stats={stats} />
|
||||||
|
<WarlordsClassStatsTableStat classId="warrior" stats={stats} />
|
||||||
|
<WarlordsClassStatsTableStat classId="all" stats={stats} />
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function WarlordsClassStatsTableStat(
|
||||||
|
{ classId, stats }: { classId: Parameters<typeof getWarlordsClassStats>[0], stats: NonNullable<NonNullStats["Warlords"]> }
|
||||||
|
) {
|
||||||
|
const classStats = getWarlordsClassStats(classId, stats)
|
||||||
|
const klassName = getWarlordsClassName(classId)
|
||||||
|
const mostPlayed = getWarlordsMostPlayedClass(stats)?.id === classId
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow className={cn(mostPlayed && "text-mc-light-purple")}>
|
||||||
|
{classId === "all" ?
|
||||||
|
(
|
||||||
|
<TableCell>
|
||||||
|
{klassName}
|
||||||
|
</TableCell>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<TableCell>
|
||||||
|
<span className="text-mc-gray">{`Lv ${getWarlordsClassLevel(classId, stats)} `}</span>
|
||||||
|
<span className="text-mc-gold">{klassName}</span>
|
||||||
|
</TableCell>
|
||||||
|
)}
|
||||||
|
{classStats.map((v, i) => {
|
||||||
|
return <TableCell key={i}>{formatNumber(v)}</TableCell>
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function WarlordsClassStatsTableHeader() {
|
||||||
|
const headerElements = [
|
||||||
|
"Class",
|
||||||
|
"Damage",
|
||||||
|
"Damage Prevented",
|
||||||
|
"Healing",
|
||||||
|
"Wins",
|
||||||
|
"Losses",
|
||||||
|
"WL"
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
{headerElements.map((v, i) => {
|
||||||
|
return <TableHead key={i} className="font-bold">{v}</TableHead>
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function WarlordsModeStatsTable({ stats }: { stats: NonNullable<NonNullStats["Warlords"]> }) {
|
export function WarlordsModeStatsTable({ stats }: { stats: NonNullable<NonNullStats["Warlords"]> }) {
|
||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { NonNullStats } from "@/lib/schema/player"
|
|||||||
import GeneralStats from "../GeneralStats"
|
import GeneralStats from "../GeneralStats"
|
||||||
import { WarlordsWeaponsBar } from "./client"
|
import { WarlordsWeaponsBar } from "./client"
|
||||||
import WarlordsGeneralStats from "./stats"
|
import WarlordsGeneralStats from "./stats"
|
||||||
import { WarlordsModeStatsTable } from "./table"
|
import { WarlordsClassStatsTable, WarlordsModeStatsTable } from "./table"
|
||||||
|
|
||||||
export default function WarlordsStats({ stats }: { stats: NonNullStats["Warlords"] }) {
|
export default function WarlordsStats({ stats }: { stats: NonNullStats["Warlords"] }) {
|
||||||
if (!stats) return null
|
if (!stats) return null
|
||||||
@@ -44,6 +44,8 @@ export default function WarlordsStats({ stats }: { stats: NonNullStats["Warlords
|
|||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
<WarlordsWeaponsBar stats={stats} />
|
<WarlordsWeaponsBar stats={stats} />
|
||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
|
<WarlordsClassStatsTable stats={stats} />
|
||||||
|
<Separator className="my-4" />
|
||||||
<WarlordsModeStatsTable stats={stats} />
|
<WarlordsModeStatsTable stats={stats} />
|
||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
</GeneralStats>
|
</GeneralStats>
|
||||||
|
|||||||
@@ -1,5 +1,45 @@
|
|||||||
import { CLASSES, MODES, RARITIES } from "@/data/hypixel/warlords"
|
import { CLASSES, MODES, RARITIES, UPGRADES } from "@/data/hypixel/warlords"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
|
import { devide } from "../general"
|
||||||
|
|
||||||
|
export function getWarlordsClassLevel(classId: Exclude<typeof CLASSES[number]["id"], "">, stats: NonNullable<NonNullStats["Warlords"]>) {
|
||||||
|
let level = 0
|
||||||
|
|
||||||
|
for (const upgrade of UPGRADES) {
|
||||||
|
level += stats[`${classId}_${upgrade.id}`]
|
||||||
|
}
|
||||||
|
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWarlordsClassName(classId: Exclude<typeof CLASSES[number]["id"], ""> | "all") {
|
||||||
|
if (classId === "all") return CLASSES.find(c => c.id === "")!.name
|
||||||
|
return CLASSES.find(c => c.id === classId)!.name
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWarlordsClassStats(classId: Exclude<typeof CLASSES[number]["id"], ""> | "all", stats: NonNullable<NonNullStats["Warlords"]>) {
|
||||||
|
const losses = getWarlordsLosses(stats)
|
||||||
|
|
||||||
|
if (classId === "all") {
|
||||||
|
return [
|
||||||
|
stats.damage,
|
||||||
|
stats.damage_prevented,
|
||||||
|
stats.heal,
|
||||||
|
stats.wins,
|
||||||
|
losses,
|
||||||
|
devide(stats.wins, losses)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
stats[`damage_${classId}`],
|
||||||
|
stats[`damage_prevented_${classId}`],
|
||||||
|
stats[`heal_${classId}`],
|
||||||
|
stats[`wins_${classId}`],
|
||||||
|
stats[`${classId}_plays`] - stats[`wins_${classId}`],
|
||||||
|
devide(stats[`${classId}_plays`] - stats[`wins_${classId}`], stats[`wins_${classId}`])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
export function getWarlordsModeName(modeId: Exclude<typeof MODES[number]["id"], ""> | "all") {
|
export function getWarlordsModeName(modeId: Exclude<typeof MODES[number]["id"], ""> | "all") {
|
||||||
if (modeId === "all") {
|
if (modeId === "all") {
|
||||||
|
|||||||
@@ -1,27 +1,65 @@
|
|||||||
import z from "zod"
|
import z from "zod"
|
||||||
|
|
||||||
|
function warlordsClassStats() {
|
||||||
|
const ids = [
|
||||||
|
"mage",
|
||||||
|
"paladin",
|
||||||
|
"shaman",
|
||||||
|
"warrior"
|
||||||
|
] as const
|
||||||
|
const stats = [
|
||||||
|
"cooldown",
|
||||||
|
"critchance",
|
||||||
|
"critmultiplier",
|
||||||
|
"energy",
|
||||||
|
"health",
|
||||||
|
"skill1",
|
||||||
|
"skill2",
|
||||||
|
"skill3",
|
||||||
|
"skill4",
|
||||||
|
"skill5",
|
||||||
|
"wins",
|
||||||
|
"losses",
|
||||||
|
"plays"
|
||||||
|
] as const
|
||||||
|
const stats2 = [
|
||||||
|
"damage",
|
||||||
|
"damage_prevented",
|
||||||
|
"heal",
|
||||||
|
"wins"
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const entries = new Map<string, z.ZodDefault<z.ZodNumber>>()
|
||||||
|
const entries2 = 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))
|
||||||
|
}
|
||||||
|
for (const stat of stats2) {
|
||||||
|
entries2.set(`${stat}_${id}`, z.number().default(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
left_right: Object.fromEntries(entries) as Record<`${typeof ids[number]}_${typeof stats[number]}`, z.ZodDefault<z.ZodNumber>>,
|
||||||
|
right_left: Object.fromEntries(entries2) as Record<`${typeof stats2[number]}_${typeof ids[number]}`, z.ZodDefault<z.ZodNumber>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const warlordsStatsSchema = z.object({
|
export const warlordsStatsSchema = z.object({
|
||||||
kills: z.number().default(0),
|
kills: z.number().default(0),
|
||||||
assists: z.number().default(0),
|
assists: z.number().default(0),
|
||||||
deaths: z.number().default(0),
|
deaths: z.number().default(0),
|
||||||
wins: z.number().default(0),
|
wins: z.number().default(0),
|
||||||
coins: z.number().default(0),
|
coins: z.number().default(0),
|
||||||
|
damage: z.number().default(0),
|
||||||
|
damage_prevented: z.number().default(0),
|
||||||
|
heal: z.number().default(0),
|
||||||
magic_dust: z.number().default(0),
|
magic_dust: z.number().default(0),
|
||||||
void_shards: z.number().default(0),
|
void_shards: z.number().default(0),
|
||||||
flag_conquer_self: z.number().default(0),
|
flag_conquer_self: z.number().default(0),
|
||||||
flag_returns: z.number().default(0),
|
flag_returns: z.number().default(0),
|
||||||
mage_plays: z.number().default(0),
|
|
||||||
paladin_plays: z.number().default(0),
|
|
||||||
shaman_plays: z.number().default(0),
|
|
||||||
warrior_plays: z.number().default(0),
|
|
||||||
mage_wins: z.number().default(0),
|
|
||||||
paladin_wins: z.number().default(0),
|
|
||||||
shaman_wins: z.number().default(0),
|
|
||||||
warrior_wins: z.number().default(0),
|
|
||||||
mage_losses: z.number().default(0),
|
|
||||||
paladin_losses: z.number().default(0),
|
|
||||||
shaman_losses: z.number().default(0),
|
|
||||||
warrior_losses: z.number().default(0),
|
|
||||||
repaired: z.number().default(0),
|
repaired: z.number().default(0),
|
||||||
repaired_common: z.number().default(0),
|
repaired_common: z.number().default(0),
|
||||||
repaired_rare: z.number().default(0),
|
repaired_rare: z.number().default(0),
|
||||||
@@ -32,5 +70,7 @@ export const warlordsStatsSchema = z.object({
|
|||||||
wins_teamdeathmatch: z.number().default(0),
|
wins_teamdeathmatch: z.number().default(0),
|
||||||
kills_capturetheflag: z.number().default(0),
|
kills_capturetheflag: z.number().default(0),
|
||||||
kills_domination: z.number().default(0),
|
kills_domination: z.number().default(0),
|
||||||
kills_teamdeathmatch: z.number().default(0)
|
kills_teamdeathmatch: z.number().default(0),
|
||||||
|
...warlordsClassStats().left_right,
|
||||||
|
...warlordsClassStats().right_left
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user