Added smash heros hero stat table
This commit is contained in:
@@ -5,7 +5,7 @@ import { getSmashHerosDifficultyColor, getSmashHerosMostPlayedHero } from "@/lib
|
|||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
import GeneralStats from "../GeneralStats"
|
import GeneralStats from "../GeneralStats"
|
||||||
import SmashHerosGeneralStats from "./stats"
|
import SmashHerosGeneralStats from "./stats"
|
||||||
import { SmashHerosModeTable } from "./table"
|
import { SmashHerosHeroTable, SmashHerosModeTable } from "./table"
|
||||||
|
|
||||||
export default function SmashHerosStats({ stats }: { stats: NonNullStats["SmashHeros"] }) {
|
export default function SmashHerosStats({ stats }: { stats: NonNullStats["SmashHeros"] }) {
|
||||||
if (!stats) return null
|
if (!stats) return null
|
||||||
@@ -52,6 +52,8 @@ export default function SmashHerosStats({ stats }: { stats: NonNullStats["SmashH
|
|||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
<SmashHerosModeTable stats={stats} />
|
<SmashHerosModeTable stats={stats} />
|
||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
|
<SmashHerosHeroTable stats={stats} />
|
||||||
|
<Separator className="my-4" />
|
||||||
</GeneralStats>
|
</GeneralStats>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,83 @@
|
|||||||
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 { getSmashHerosModeName, getSmashHerosModeStats, getSmashHerosMostPlayedMode } from "@/lib/hypixel/smashhero/general"
|
import {
|
||||||
|
getSmashHerosAllHerosStats,
|
||||||
|
getSmashHerosDifficultyColor,
|
||||||
|
getSmashHerosHero,
|
||||||
|
getSmashHerosHeroLvlPres,
|
||||||
|
getSmashHerosHeroPrestigeColor,
|
||||||
|
getSmashHerosModeName,
|
||||||
|
getSmashHerosModeStats,
|
||||||
|
getSmashHerosMostPlayedHero,
|
||||||
|
getSmashHerosMostPlayedMode
|
||||||
|
} from "@/lib/hypixel/smashhero/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 SmashHerosHeroTable({ stats }: { stats: NonNullable<NonNullStats["SmashHeros"]> }) {
|
||||||
|
return (
|
||||||
|
<Table>
|
||||||
|
<SmashHerosHeroTableHeader />
|
||||||
|
<SmashHerosHeroTableStats stats={stats} />
|
||||||
|
</Table>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function SmashHerosHeroTableStats({ stats }: { stats: NonNullable<NonNullStats["SmashHeros"]> }) {
|
||||||
|
const heroStats = getSmashHerosAllHerosStats(stats)
|
||||||
|
return (
|
||||||
|
<TableBody>
|
||||||
|
{heroStats.map((v, i) => {
|
||||||
|
const { id, nums } = v
|
||||||
|
const hero = getSmashHerosHero(id)
|
||||||
|
const difficultyColor = getSmashHerosDifficultyColor(hero.difficulty)
|
||||||
|
const mostPlayed = getSmashHerosMostPlayedHero(stats)?.id === id
|
||||||
|
const { lvl, pg: pres } = getSmashHerosHeroLvlPres(id, stats)
|
||||||
|
const presColor = getSmashHerosHeroPrestigeColor(pres)
|
||||||
|
return (
|
||||||
|
<TableRow key={i} className={cn(mostPlayed && "text-mc-light-purple")}>
|
||||||
|
<TableCell>
|
||||||
|
<span className={`text-mc-${difficultyColor}`}>{hero.name}</span>
|
||||||
|
<span className="text-mc-gray">{" Lv"}</span>
|
||||||
|
<span className="text-mc-aqua">{lvl}</span>
|
||||||
|
{pres > 0 && (
|
||||||
|
<span className={`text-mc-${presColor}`}>
|
||||||
|
{` 【${pres}】`}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
{nums.map((n, j) => {
|
||||||
|
return <TableCell key={j}>{formatNumber(n)}</TableCell>
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function SmashHerosHeroTableHeader() {
|
||||||
|
const headerElements = [
|
||||||
|
"Hero",
|
||||||
|
"Kills",
|
||||||
|
"Deaths",
|
||||||
|
"KD",
|
||||||
|
"Wins",
|
||||||
|
"Losses",
|
||||||
|
"WL"
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
{headerElements.map((v, i) => {
|
||||||
|
return <TableHead key={i} className="font-bold">{v}</TableHead>
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function SmashHerosModeTable({ stats }: { stats: NonNullable<NonNullStats["SmashHeros"]> }) {
|
export function SmashHerosModeTable({ stats }: { stats: NonNullable<NonNullStats["SmashHeros"]> }) {
|
||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
export const MODES = [
|
export const MODES = [
|
||||||
{ id: "normal", name: "1v1v1v1" },
|
{ id: "normal", name: "1v1v1v1" },
|
||||||
{ id: "2v2", name: "2v2" },
|
{ id: "teams", name: "2v2v2v2" },
|
||||||
{ id: "teams", name: "2v2v2" },
|
{ id: "teams", name: "2v2v2" },
|
||||||
|
{ id: "2v2", name: "2v2" },
|
||||||
{ id: "", name: "Overall" }
|
{ id: "", name: "Overall" }
|
||||||
] as const
|
] as const
|
||||||
export const HEROES = [
|
export const HEROES = [
|
||||||
|
|||||||
@@ -1,7 +1,50 @@
|
|||||||
import { DIFFICULTY, HEROES, MODES } from "@/data/hypixel/smashheros"
|
import { DIFFICULTY, HEROES, MODES, PRESTIGECOLORS } from "@/data/hypixel/smashheros"
|
||||||
import { NonNullStats } from "@/lib/schema/player"
|
import { NonNullStats } from "@/lib/schema/player"
|
||||||
import { devide } from "../general"
|
import { devide } from "../general"
|
||||||
|
|
||||||
|
export function getSmashHerosHeroPrestigeColor(pres: number) {
|
||||||
|
if (pres < 1) return PRESTIGECOLORS.at(0)!
|
||||||
|
if (pres > PRESTIGECOLORS.length) return PRESTIGECOLORS.at(0)!
|
||||||
|
|
||||||
|
return PRESTIGECOLORS.at(pres - 1)!
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSmashHerosHeroLvlPres(heroId: typeof HEROES[number]["id"], stats: NonNullable<NonNullStats["SmashHeros"]>) {
|
||||||
|
return {
|
||||||
|
lvl: stats[`lastLevel_${heroId}`],
|
||||||
|
pg: stats[`pg_${heroId}`]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSmashHerosHero(heroId: typeof HEROES[number]["id"]) {
|
||||||
|
return HEROES.find(h => h.id === heroId)!
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSmashHerosAllHerosStats(stats: NonNullable<NonNullStats["SmashHeros"]>) {
|
||||||
|
const vals: { id: typeof HEROES[number]["id"], nums: number[] }[] = []
|
||||||
|
|
||||||
|
for (const hero of HEROES) {
|
||||||
|
vals.push({ id: hero.id, nums: getSmashHerosHeroStats(hero.id, stats) })
|
||||||
|
}
|
||||||
|
|
||||||
|
return vals
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSmashHerosHeroStats(heroId: typeof HEROES[number]["id"], stats: NonNullable<NonNullStats["SmashHeros"]>) {
|
||||||
|
if (!stats.class_stats) return [0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
const cStats = stats.class_stats[heroId]
|
||||||
|
|
||||||
|
return [
|
||||||
|
cStats?.kills || 0,
|
||||||
|
cStats?.deaths || 0,
|
||||||
|
devide(cStats?.kills || 0, cStats?.deaths || 0),
|
||||||
|
cStats?.wins || 0,
|
||||||
|
cStats?.losses || 0,
|
||||||
|
devide(cStats?.wins || 0, cStats?.losses || 0)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
export function getSmashHerosModeName(modeId: Exclude<typeof MODES[number]["id"], ""> | "all") {
|
export function getSmashHerosModeName(modeId: Exclude<typeof MODES[number]["id"], ""> | "all") {
|
||||||
if (modeId === "all") return MODES.find(m => m.id === "")!.name
|
if (modeId === "all") return MODES.find(m => m.id === "")!.name
|
||||||
return MODES.find(m => m.id === modeId)!.name
|
return MODES.find(m => m.id === modeId)!.name
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import z from "zod"
|
import z from "zod"
|
||||||
|
|
||||||
const classStats = z.object({
|
const classStats = z.object({
|
||||||
games: z.number().default(0)
|
games: z.number().default(0),
|
||||||
|
kills: z.number().default(0),
|
||||||
|
deaths: z.number().default(0),
|
||||||
|
wins: z.number().default(0),
|
||||||
|
losses: z.number().default(0)
|
||||||
}).optional()
|
}).optional()
|
||||||
|
|
||||||
export const smashHerosStats = z.object({
|
export const smashHerosStats = z.object({
|
||||||
@@ -30,6 +34,38 @@ export const smashHerosStats = z.object({
|
|||||||
TINMAN: classStats,
|
TINMAN: classStats,
|
||||||
DUSK_CRAWLER: classStats
|
DUSK_CRAWLER: classStats
|
||||||
}).optional(),
|
}).optional(),
|
||||||
|
lastLevel_BOTMUN: z.number().default(0),
|
||||||
|
lastLevel_THE_BULK: z.number().default(0),
|
||||||
|
lastLevel_CAKE_MONSTER: z.number().default(0),
|
||||||
|
lastLevel_FROSTY: z.number().default(0),
|
||||||
|
lastLevel_GENERAL_CLUCK: z.number().default(0),
|
||||||
|
lastLevel_GREEN_HOOD: z.number().default(0),
|
||||||
|
lastLevel_GOKU: z.number().default(0),
|
||||||
|
lastLevel_MARAUDER: z.number().default(0),
|
||||||
|
lastLevel_PUG: z.number().default(0),
|
||||||
|
lastLevel_SANIC: z.number().default(0),
|
||||||
|
lastLevel_SERGEANT_SHIELD: z.number().default(0),
|
||||||
|
lastLevel_SHOOP_DA_WHOOP: z.number().default(0),
|
||||||
|
lastLevel_SKULLFIRE: z.number().default(0),
|
||||||
|
lastLevel_SPODERMAN: z.number().default(0),
|
||||||
|
lastLevel_TINMAN: z.number().default(0),
|
||||||
|
lastLevel_DUSK_CRAWLER: z.number().default(0),
|
||||||
|
pg_BOTMUN: z.number().default(0),
|
||||||
|
pg_THE_BULK: z.number().default(0),
|
||||||
|
pg_CAKE_MONSTER: z.number().default(0),
|
||||||
|
pg_FROSTY: z.number().default(0),
|
||||||
|
pg_GENERAL_CLUCK: z.number().default(0),
|
||||||
|
pg_GREEN_HOOD: z.number().default(0),
|
||||||
|
pg_GOKU: z.number().default(0),
|
||||||
|
pg_MARAUDER: z.number().default(0),
|
||||||
|
pg_PUG: z.number().default(0),
|
||||||
|
pg_SANIC: z.number().default(0),
|
||||||
|
pg_SERGEANT_SHIELD: z.number().default(0),
|
||||||
|
pg_SHOOP_DA_WHOOP: z.number().default(0),
|
||||||
|
pg_SKULLFIRE: z.number().default(0),
|
||||||
|
pg_SPODERMAN: z.number().default(0),
|
||||||
|
pg_TINMAN: z.number().default(0),
|
||||||
|
pg_DUSK_CRAWLER: z.number().default(0),
|
||||||
kills_normal: z.number().default(0),
|
kills_normal: z.number().default(0),
|
||||||
deaths_normal: z.number().default(0),
|
deaths_normal: z.number().default(0),
|
||||||
wins_normal: z.number().default(0),
|
wins_normal: z.number().default(0),
|
||||||
|
|||||||
Reference in New Issue
Block a user