diff --git a/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-table.tsx b/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-table.tsx index 8095b13..99596b4 100644 --- a/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-table.tsx @@ -1,4 +1,5 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { formatNumber } from "@/lib/formatters" import { _BedwarsStats, getBedwarsModeStats } from "@/lib/hypixel/bedwars" import { Player } from "@/lib/schema/player" @@ -11,6 +12,21 @@ export default function BedwarsStatTable({ stats }: { stats: Player["player"]["s + + + + + + + + + + + + + + + ) @@ -38,12 +54,12 @@ function BedwarsTableHeader() { - Normal - Finals + Normal + Finals {headerElements.map((v, i) => { - return {v} + return {v} })} @@ -59,7 +75,7 @@ function SoloStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { Solo {modeStats.map((v, i) => { - return {v} + return {typeof v === "number" ? formatNumber(v) : v} })} ) @@ -74,7 +90,7 @@ function DoublesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] } Doubles {modeStats.map((v, i) => { - return {v} + return {typeof v === "number" ? formatNumber(v) : v} })} ) @@ -89,7 +105,7 @@ function ThreesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) 3v3v3v3 {modeStats.map((v, i) => { - return {v} + return {typeof v === "number" ? formatNumber(v) : v} })} ) @@ -104,7 +120,245 @@ function FoursStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) 4v4v4v4 {modeStats.map((v, i) => { - return {v} + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function CoreModeStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const soloStats = getBedwarsModeStats("solo", stats as _BedwarsStats, true) + const doublesStats = getBedwarsModeStats("doubles", stats as _BedwarsStats, true) + const threesStats = getBedwarsModeStats("3s", stats as _BedwarsStats, true) + const foursStats = getBedwarsModeStats("4s", stats as _BedwarsStats, true) + + const fraction = [2, 5, 8] + + const combinedStats = soloStats.map((v, i) => { + if (v < 0) return "?" + + if (fraction.includes(i) || i === soloStats.length - 1) { + return ((v + doublesStats[i] + threesStats[i] + foursStats[i]) / 4).toFixed(2) + } + + return v + doublesStats[i] + threesStats[i] + foursStats[i] + }) + + return ( + + Core Modes + {combinedStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function FourVFourStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("4v4", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + 4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function RushDoublesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("rush_2s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Rush Doubles + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Rush4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("rush_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Rush 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function UltimateDoublesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("ultimate_2s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Ultimate Doubles + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Ultimate4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("ultimate_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Ultimate 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function LuckyDoublesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("lucky_2s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Lucky Doubles + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Lucky4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("lucky_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Lucky 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function VoidlessDoublesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("voidless_2s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Voidless Doubles + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Voidless4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("voidless_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Voidless 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function ArmedDoublesStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("armed_2s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Armed Doubles + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Armed4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("armed_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Armed 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Swap4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("swap_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Swap 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function Underworld4sStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("underworld_4s", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Underworld 4v4v4v4 + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} + +function CastleStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { + const modeStats = getBedwarsModeStats("castle", stats as _BedwarsStats) + + if (!modeStats) return null + + return ( + + Castle + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} })} ) diff --git a/src/lib/hypixel/bedwars.ts b/src/lib/hypixel/bedwars.ts index 8e31242..b0003f6 100644 --- a/src/lib/hypixel/bedwars.ts +++ b/src/lib/hypixel/bedwars.ts @@ -62,21 +62,90 @@ export function getLatestRoom(rooms?: Record) { } export type _BedwarsStats = Record & { [key: `${string}_winstreak`]: number | undefined } +type Mode = + | "solo" + | "doubles" + | "3s" + | "4s" + | "4v4" + | "rush_2s" + | "rush_4s" + | "ultimate_2s" + | "ultimate_4s" + | "lucky_2s" + | "lucky_4s" + | "voidless_2s" + | "voidless_4s" + | "armed_2s" + | "armed_4s" + | "swap_4s" + | "underworld_4s" + | "castle" -export function getBedwarsModeStats(mode: "solo" | "doubles" | "3s" | "4s", stats: _BedwarsStats) { +export function getBedwarsModeStats(mode: Mode, stats: _BedwarsStats, raw: true): number[] +export function getBedwarsModeStats(mode: Mode, stats: _BedwarsStats, raw?: false): (string | number)[] +export function getBedwarsModeStats(mode: Mode, stats: _BedwarsStats, raw = false) { switch (mode) { case "solo": - return bedwarsModeStats("eight_one", stats) + return bedwarsModeStats("eight_one", stats, raw) case "doubles": - return bedwarsModeStats("eight_two", stats) + return bedwarsModeStats("eight_two", stats, raw) case "3s": - return bedwarsModeStats("four_three", stats) + return bedwarsModeStats("four_three", stats, raw) case "4s": - return bedwarsModeStats("four_four", stats) + return bedwarsModeStats("four_four", stats, raw) + case "4v4": + return bedwarsModeStats("two_four", stats, raw) + case "rush_2s": + return bedwarsModeStats("eight_two_rush", stats, raw) + case "rush_4s": + return bedwarsModeStats("four_four_rush", stats, raw) + case "ultimate_2s": + return bedwarsModeStats("eight_two_ultimate", stats, raw) + case "ultimate_4s": + return bedwarsModeStats("four_four_ultimate", stats, raw) + case "lucky_2s": + return bedwarsModeStats("eight_two_lucky", stats, raw) + case "lucky_4s": + return bedwarsModeStats("four_four_lucky", stats, raw) + case "voidless_2s": + return bedwarsModeStats("eight_two_voidless", stats, raw) + case "voidless_4s": + return bedwarsModeStats("four_four_voidless", stats, raw) + case "armed_2s": + return bedwarsModeStats("eight_two_armed", stats, raw) + case "armed_4s": + return bedwarsModeStats("four_four_armed", stats, raw) + case "swap_4s": + return bedwarsModeStats("four_four_swap", stats, raw) + case "underworld_4s": + return bedwarsModeStats("four_four_underworld", stats, raw) + case "castle": + return bedwarsModeStats("castle", stats, raw) + default: + throw new Error(`${mode satisfies never} does not exist`) } } -function bedwarsModeStats(prefix: string, stats: _BedwarsStats) { +function bedwarsModeStats(prefix: string, stats: _BedwarsStats, raw = false) { + if (raw) { + return [ + stats[`${prefix}_kills_bedwars`], + stats[`${prefix}_deaths_bedwars`], + stats[`${prefix}_kills_bedwars`] / stats[`${prefix}_deaths_bedwars`], + stats[`${prefix}_final_kills_bedwars`], + stats[`${prefix}_final_deaths_bedwars`], + stats[`${prefix}_final_kills_bedwars`] / stats[`${prefix}_final_deaths_bedwars`], + stats[`${prefix}_wins_bedwars`], + stats[`${prefix}_losses_bedwars`], + stats[`${prefix}_wins_bedwars`] / stats[`${prefix}_losses_bedwars`], + stats[`${prefix}_winstreak`] ?? -1, + stats[`${prefix}_beds_broken_bedwars`], + stats[`${prefix}_beds_lost_bedwars`], + stats[`${prefix}_beds_broken_bedwars`] / stats[`${prefix}_beds_lost_bedwars`] + ] + } + return [ stats[`${prefix}_kills_bedwars`], stats[`${prefix}_deaths_bedwars`], diff --git a/src/lib/schema/player.ts b/src/lib/schema/player.ts index 25fa969..02ad2c3 100644 --- a/src/lib/schema/player.ts +++ b/src/lib/schema/player.ts @@ -36,43 +36,7 @@ export const playerSchema = z.looseObject({ total_tickets_earned: z.number(), doublers: z.number(), room: z.record(z.string(), z.boolean()) - }).optional(), - eight_one_winstreak: z.number().optional(), - eight_one_kills_bedwars: z.number().default(0), - eight_one_deaths_bedwars: z.number().default(0), - eight_one_final_kills_bedwars: z.number().default(0), - eight_one_final_deaths_bedwars: z.number().default(0), - eight_one_wins_bedwars: z.number().default(0), - eight_one_losses_bedwars: z.number().default(0), - eight_one_beds_broken_bedwars: z.number().default(0), - eight_one_beds_lost_bedwars: z.number().default(0), - eight_two_winstreak: z.number().optional(), - eight_two_kills_bedwars: z.number().default(0), - eight_two_deaths_bedwars: z.number().default(0), - eight_two_final_kills_bedwars: z.number().default(0), - eight_two_final_deaths_bedwars: z.number().default(0), - eight_two_wins_bedwars: z.number().default(0), - eight_two_losses_bedwars: z.number().default(0), - eight_two_beds_broken_bedwars: z.number().default(0), - eight_two_beds_lost_bedwars: z.number().default(0), - four_three_winstreak: z.number().optional(), - four_three_kills_bedwars: z.number().default(0), - four_three_deaths_bedwars: z.number().default(0), - four_three_final_kills_bedwars: z.number().default(0), - four_three_final_deaths_bedwars: z.number().default(0), - four_three_wins_bedwars: z.number().default(0), - four_three_losses_bedwars: z.number().default(0), - four_three_beds_broken_bedwars: z.number().default(0), - four_three_beds_lost_bedwars: z.number().default(0), - four_four_winstreak: z.number().optional(), - four_four_kills_bedwars: z.number().default(0), - four_four_deaths_bedwars: z.number().default(0), - four_four_final_kills_bedwars: z.number().default(0), - four_four_final_deaths_bedwars: z.number().default(0), - four_four_wins_bedwars: z.number().default(0), - four_four_losses_bedwars: z.number().default(0), - four_four_beds_broken_bedwars: z.number().default(0), - four_four_beds_lost_bedwars: z.number().default(0) + }).optional() }).optional() }), quests: z.record(