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(