diff --git a/src/app/(stats)/player/[ign]/_stats/woolgames/woolgames.tsx b/src/app/(stats)/player/[ign]/_stats/woolgames/woolgames.tsx index 454fdca..a39a672 100644 --- a/src/app/(stats)/player/[ign]/_stats/woolgames/woolgames.tsx +++ b/src/app/(stats)/player/[ign]/_stats/woolgames/woolgames.tsx @@ -1,11 +1,16 @@ import { Separator } from "@/components/ui/separator" import { formatNumber } from "@/lib/formatters" +import { getWoolGamesLevel, getWoolGamesPrestige, getWoolGamesPretigeIcon } from "@/lib/hypixel/woolgames/general" import { NonNullStats } from "@/lib/schema/player" +import Multicolored from "../../_components/Multicolored" import GeneralStats from "../GeneralStats" export default function WoolGamesStats({ stats }: { stats: NonNullStats["WoolGames"] }) { 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 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" title="Wool Games" collapsedStats={[ + { + title:
Level
, + stat:Kills
, stat:{formatNumber(kills)}
diff --git a/src/data/hypixel/woolgames.ts b/src/data/hypixel/woolgames.ts new file mode 100644 index 0000000..8924b03 --- /dev/null +++ b/src/data/hypixel/woolgames.ts @@ -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 diff --git a/src/lib/hypixel/woolgames/general.ts b/src/lib/hypixel/woolgames/general.ts new file mode 100644 index 0000000..db6c0f1 --- /dev/null +++ b/src/lib/hypixel/woolgames/general.ts @@ -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 +} diff --git a/src/lib/schema/stats.ts b/src/lib/schema/stats.ts index 90d7901..8925e82 100644 --- a/src/lib/schema/stats.ts +++ b/src/lib/schema/stats.ts @@ -725,6 +725,10 @@ export const copsAndCrimsStatsSchema = 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({ stats: z.looseObject({ kills: z.number().default(0),