Updated wool games stats

This commit is contained in:
2025-09-11 00:08:16 +02:00
parent e55a165986
commit c7ed674a34
4 changed files with 123 additions and 0 deletions

View File

@@ -1,11 +1,16 @@
import { Separator } from "@/components/ui/separator" import { Separator } from "@/components/ui/separator"
import { formatNumber } from "@/lib/formatters" import { formatNumber } from "@/lib/formatters"
import { getWoolGamesLevel, getWoolGamesPrestige, getWoolGamesPretigeIcon } from "@/lib/hypixel/woolgames/general"
import { NonNullStats } from "@/lib/schema/player" import { NonNullStats } from "@/lib/schema/player"
import Multicolored from "../../_components/Multicolored"
import GeneralStats from "../GeneralStats" import GeneralStats from "../GeneralStats"
export default function WoolGamesStats({ stats }: { stats: NonNullStats["WoolGames"] }) { export default function WoolGamesStats({ stats }: { stats: NonNullStats["WoolGames"] }) {
if (!stats) return null if (!stats) return null
const level = getWoolGamesLevel(stats.progression?.experience)
const icon = getWoolGamesPretigeIcon(stats.wool_wars_prestige_icon)
const pres = getWoolGamesPrestige(level)
const kills = (stats.capture_the_wool?.stats?.kills || 0) + (stats.sheep_wars?.stats?.kills || 0) + (stats.wool_wars?.stats?.kills || 0) const kills = (stats.capture_the_wool?.stats?.kills || 0) + (stats.sheep_wars?.stats?.kills || 0) + (stats.wool_wars?.stats?.kills || 0)
const wins = (stats.capture_the_wool?.stats?.participated_wins || 0) + (stats.sheep_wars?.stats?.wins || 0) + (stats.wool_wars?.stats?.wins || 0) const wins = (stats.capture_the_wool?.stats?.participated_wins || 0) + (stats.sheep_wars?.stats?.wins || 0) + (stats.wool_wars?.stats?.wins || 0)
@@ -14,6 +19,10 @@ export default function WoolGamesStats({ stats }: { stats: NonNullStats["WoolGam
id="woolgames" id="woolgames"
title="Wool Games" title="Wool Games"
collapsedStats={[ collapsedStats={[
{
title: <p>Level</p>,
stat: <Multicolored val={`[${Math.floor(level)}${icon}]`} color={pres.colormap} />
},
{ {
title: <p>Kills</p>, title: <p>Kills</p>,
stat: <p className="text-muted-foreground">{formatNumber(kills)}</p> stat: <p className="text-muted-foreground">{formatNumber(kills)}</p>

View File

@@ -0,0 +1,41 @@
export const EASY_XP = [5000, 1000, 2000, 3000, 4000] as const
export const NORMAL_XP = 5000 as const
export const PRESTIGES = [
{ level: 0, colormap: "7", color: "gray", name: "None" },
{ level: 100, colormap: "f", color: "white", name: "Sheep" },
{ level: 200, colormap: "c", color: "red", name: "First Arc" },
{ level: 300, colormap: "6", color: "gold", name: "Second Arc" },
{ level: 400, colormap: "e", color: "yellow", name: "Third Arc" },
{ level: 500, colormap: "a", color: "green", name: "Fourth Arc" },
{ level: 600, colormap: "3", color: "dark-aqua", name: "Fifth Arc" },
{ level: 700, colormap: "5", color: "dark-purple", name: "Sixth Arc" },
{ level: 800, colormap: "d", color: "light-purple", name: "Final Arc" },
{ level: 900, colormap: "c6eabd", color: "rainbow", name: "Full Rainbow" },
{ level: 1000, colormap: "0fffff0", color: "black", name: "Void Sheep" }
] as const
export const ICONS = {
HEART: "\u2764", // ❤
PLUS: "\u2719", // ✙
STAR: "\u2606", // ☆
PLANE: "\u2708", // ✈
CROSS: "\u2720", // ✠
CROWN: "\u2655", // ♕
LIGHTNING: "\u26a1", // ⚡
NUKE: "\u2622", // ☢
PENSUL: "\u270f", // ✏
YIN_YANG: "\u262f" // ☯
} as const
export const CLASSES = [
{ id: "tank", name: "Tank", difficulty: 1 },
{ id: "archer", name: "Archer", difficulty: 2 },
{ id: "swordsman", name: "Swordsman", difficulty: 1 },
{ id: "engineer", name: "Engineer", difficulty: 1 },
{ id: "golem", name: "Golem", difficulty: 2 },
{ id: "assault", name: "Assault", difficulty: 3 }
] as const
export const DIFFICULTIES = {
"1": "green",
"2": "yellow",
"3": "red",
"4": "dark-red"
} as const

View File

@@ -0,0 +1,69 @@
import { EASY_XP, ICONS, NORMAL_XP, PRESTIGES } from "@/data/hypixel/woolgames"
import { getColorFromCode } from "@/lib/colors"
import { floorLevel } from "../general"
export function getWoolGamesPrestige(level: number) {
const floored = floorLevel(Math.floor(level), 100)
if (level > 1000) {
const { name, color, colormap } = PRESTIGES.at(-1)!
return {
name,
color,
colormap: colormap.split("").map(v => {
return getColorFromCode(v)
})
}
}
if (floored === 900) {
const { name, color, colormap } = PRESTIGES.find(p => p.level === floored)!
return {
name,
color,
colormap: colormap.split("").map(v => {
return getColorFromCode(v)
})
}
}
const { name, color, colormap } = PRESTIGES.find(p => p.level === floored)!
return {
name,
color,
colormap: getColorFromCode(colormap)
}
}
export function getWoolGamesPretigeIcon(icon?: string) {
return Object.entries(ICONS).find(v => v[0] === icon)?.[1] || ICONS.HEART
}
function getExpReq(level: number) {
const progress = level % 100
if (level === 0) return 0
else if (progress < 5) return EASY_XP[progress]
else return NORMAL_XP
}
export function getWoolGamesLevel(xp = 0) {
let remainingXP = xp
let lvl = 1
let deltaXP = getExpReq(lvl)
while (remainingXP > 0) {
deltaXP = getExpReq(lvl)
remainingXP -= deltaXP
lvl++
}
return lvl + remainingXP / deltaXP
}
export function getWoolGamesXPForLevel(lvl: number) {
let xp = 0
for (let i = 0; i < lvl; i++) {
xp += getExpReq(i)
}
return xp
}

View File

@@ -725,6 +725,10 @@ export const copsAndCrimsStatsSchema = z.looseObject({
}) })
export const woolGamesStatsSchema = z.looseObject({ export const woolGamesStatsSchema = z.looseObject({
wool_wars_prestige_icon: z.string().optional(),
progression: z.looseObject({
experience: z.number().default(0)
}).optional(),
capture_the_wool: z.looseObject({ capture_the_wool: z.looseObject({
stats: z.looseObject({ stats: z.looseObject({
kills: z.number().default(0), kills: z.number().default(0),