Updated bedears stats
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { getBedwarsStar, getTextColor } from "@/lib/hypixel/bedwars"
|
||||
import { getBWLevelForExp } from "@/lib/hypixel/bedwarsLevel"
|
||||
import { bedwarsLevelColors } from "@/lib/hypixelFormatters"
|
||||
import Multicolored from "../../_components/Multicolored"
|
||||
|
||||
export function BedwarsLevel({ xp }: { xp: number }) {
|
||||
const level = getBWLevelForExp(xp)
|
||||
const color = bedwarsLevelColors(level)
|
||||
const star = getBedwarsStar(level)
|
||||
const val = `[${level}${star}]`
|
||||
|
||||
return <Multicolored val={val} color={color} />
|
||||
}
|
||||
|
||||
export function BedwarsProgress({ level, percent }: { level: number, percent: number }) {
|
||||
return (
|
||||
<div className="flex items-center mb-10">
|
||||
<div className={`mr-2 text-mc-${getTextColor(level)}`}>{level}</div>
|
||||
<div className={`h-5 bg-mc-${getTextColor(level)} rounded-l-md`} style={{ width: `${percent}%` }}></div>
|
||||
<div className="flex-1 h-5 rounded-r-md bg-background"></div>
|
||||
<div className={`ml-2 text-mc-${getTextColor(level)}`}>{level + 1}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
|
||||
import { getBedwarsStar } from "@/lib/hypixel/bedwars"
|
||||
import { getBWLevelForExp } from "@/lib/hypixel/bedwarsLevel"
|
||||
import { bedwarsLevelColors } from "@/lib/hypixelFormatters"
|
||||
import { getBedwarsStar, getPrestigeName, getTextColor } from "@/lib/hypixel/bedwars"
|
||||
import { getBWLevelForExp, getTotalExpForLevel } from "@/lib/hypixel/bedwarsLevel"
|
||||
import { getProgress } from "@/lib/hypixel/general"
|
||||
import { Player } from "@/lib/schema/player"
|
||||
import { Separator } from "@radix-ui/react-separator"
|
||||
import { ChevronDown, ChevronUp, Menu } from "lucide-react"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import CollapsedStats from "../CollapsedStats"
|
||||
import Multicolored from "../Multicolored"
|
||||
import CollapsedStats from "../../_components/CollapsedStats"
|
||||
import { BedwarsLevel, BedwarsProgress } from "./bedwars-components"
|
||||
|
||||
export default function BedwarsStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
@@ -42,6 +42,13 @@ export default function BedwarsStats({ stats }: { stats: Player["player"]["stats
|
||||
const fkd = (stats.final_kills_bedwars / stats.final_deaths_bedwars).toFixed(2)
|
||||
const wl = (stats.wins_bedwars / stats.losses_bedwars).toFixed(2)
|
||||
const bbl = (stats.beds_broken_bedwars / stats.beds_lost_bedwars).toFixed(2)
|
||||
const level = getBWLevelForExp(stats.Experience)
|
||||
|
||||
const percent = getProgress(
|
||||
getTotalExpForLevel(level),
|
||||
stats.Experience,
|
||||
getTotalExpForLevel(level + 1)
|
||||
)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -88,18 +95,32 @@ export default function BedwarsStats({ stats }: { stats: Player["player"]["stats
|
||||
</div>
|
||||
<CollapsibleContent>
|
||||
<Separator className="my-4" />
|
||||
<BedwarsProgress level={level} percent={percent} />
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<p>
|
||||
<span className="font-bold">{"Level: "}</span>
|
||||
<span>{`${level}.${percent.toFixed(0)}`}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-bold">{"Prestige: "}</span>
|
||||
<span className={`text-mc-${getTextColor(level)}`}>
|
||||
{`${getPrestigeName(level)} ${getBedwarsStar(level)}`}
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-bold">{"Tokens: "}</span>
|
||||
<span className="text-mc-dark-green">{}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
function BedwarsLevel({ xp }: { xp: number }) {
|
||||
const level = getBWLevelForExp(xp)
|
||||
const color = bedwarsLevelColors(level)
|
||||
const star = getBedwarsStar(level)
|
||||
const val = `[${level}${star}]`
|
||||
|
||||
return <Multicolored val={val} color={color} />
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { getUuid } from "@/lib/hypixel/api/mojang"
|
||||
import { getPlayer } from "@/lib/hypixel/api/player"
|
||||
import { getExactLevel } from "@/lib/hypixel/level"
|
||||
import Sidebar from "./_components/Sidebar"
|
||||
import BedwarsStats from "./_components/stats/bedewars"
|
||||
import BedwarsStats from "./_stats/bedwars/bedwars"
|
||||
|
||||
export default async function PlayerPage({
|
||||
params
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
--color-mc-dark-purple: #AA00AA;
|
||||
--color-mc-gold: #FFAA00;
|
||||
--color-mc-gray: #AAAAAA;
|
||||
--color-mc-light-gray: #C6C6C6;
|
||||
--color-mc-dark-gray: #555555;
|
||||
--color-mc-blue: #5555FF;
|
||||
--color-mc-green: #55FF55;
|
||||
|
||||
@@ -6,7 +6,7 @@ export function getColor(color?: string, type: "text" | "bg" = "text", defaultCo
|
||||
return type === "text" ? "text-mc-red" : "bg-mc-red"
|
||||
case "GOLD":
|
||||
return type === "text" ? "text-mc-gold" : "bg-mc-gold"
|
||||
case "LIME":
|
||||
case "GREEN":
|
||||
return type === "text" ? "text-mc-green" : "bg-mc-green"
|
||||
case "YELLOW":
|
||||
return type === "text" ? "text-mc-yellow" : "bg-mc-yellow"
|
||||
@@ -16,12 +16,12 @@ export function getColor(color?: string, type: "text" | "bg" = "text", defaultCo
|
||||
return type === "text" ? "text-mc-white" : "bg-mc-white"
|
||||
case "BLUE":
|
||||
return type === "text" ? "text-mc-blue" : "bg-mc-blue"
|
||||
case "GREEN":
|
||||
return type === "text" ? "text-mc-green" : "bg-mc-green"
|
||||
case "DARK_RED":
|
||||
return type === "text" ? "text-mc-dark-red" : "bg-mc-dark-red"
|
||||
case "DARK_GREEN":
|
||||
return type === "text" ? "text-mc-dark-green" : "bg-mc-dark-green"
|
||||
case "DARK_RED":
|
||||
return type === "text" ? "text-mc-dark-red" : "bg-mc-dark-red"
|
||||
case "DARK_AQUA":
|
||||
return type === "text" ? "text-mc-dark-aqua" : "bg-mc-dark-red"
|
||||
case "DARK_PURPLE":
|
||||
return type === "text" ? "text-mc-dark-purple" : "bg-mc-dark-purple"
|
||||
case "DARK_GRAY":
|
||||
@@ -30,6 +30,8 @@ export function getColor(color?: string, type: "text" | "bg" = "text", defaultCo
|
||||
return type === "text" ? "text-mc-black" : "bg-mc-black"
|
||||
case "DARK_BLUE":
|
||||
return type === "text" ? "text-mc-dark-blue" : "bg-mc-dark-blue"
|
||||
case "GRAY":
|
||||
return type === "text" ? "text-mc-gray" : "bg-mc-gray"
|
||||
default:
|
||||
return type === "text" ? `text-mc-${defaultColor}` : `bg-mc-${defaultColor}`
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ export const PRESTIGES = [
|
||||
{ level: 100, colormap: "f", color: "white", name: "Iron" },
|
||||
{ level: 200, colormap: "6", color: "gold", name: "Gold" },
|
||||
{ level: 300, colormap: "b", color: "aqua", name: "Diamond" },
|
||||
{ level: 400, colormap: "2", color: "darkgreen", name: "Emerald" },
|
||||
{ level: 500, colormap: "3", color: "darkaqua", name: "Sapphire" },
|
||||
{ level: 600, colormap: "4", color: "darkred", name: "Ruby" },
|
||||
{ level: 700, colormap: "d", color: "pink", name: "Crystal" },
|
||||
{ level: 400, colormap: "2", color: "dark-green", name: "Emerald" },
|
||||
{ level: 500, colormap: "3", color: "dark-aqua", name: "Sapphire" },
|
||||
{ level: 600, colormap: "4", color: "dark-red", name: "Ruby" },
|
||||
{ level: 700, colormap: "d", color: "light-purple", name: "Crystal" },
|
||||
{ level: 800, colormap: "9", color: "blue", name: "Opal" },
|
||||
{ level: 900, colormap: "5", color: "purple", name: "Amethyst" },
|
||||
{ level: 1000, colormap: "c6eabd5", color: "rainbow", name: "Rainbow" },
|
||||
@@ -15,9 +15,9 @@ export const PRESTIGES = [
|
||||
{ level: 1200, colormap: "7eeee67", color: "yellow", name: "Gold Prime" },
|
||||
{ level: 1300, colormap: "7bbbb37", color: "aqua", name: "Diamond Prime" },
|
||||
{ level: 1400, colormap: "7aaaa27", color: "green", name: "Emerald Prime" },
|
||||
{ level: 1500, colormap: "7333397", color: "darkaqua", name: "Sapphire Prime" },
|
||||
{ level: 1500, colormap: "7333397", color: "dark-aqua", name: "Sapphire Prime" },
|
||||
{ level: 1600, colormap: "7cccc47", color: "red", name: "Ruby Prime" },
|
||||
{ level: 1700, colormap: "7dddd57", color: "pink", name: "Crystal Prime" },
|
||||
{ level: 1700, colormap: "7dddd57", color: "light-purple", name: "Crystal Prime" },
|
||||
{ level: 1800, colormap: "7999917", color: "blue", name: "Opal Prime" },
|
||||
{ level: 1900, colormap: "7555587", color: "purple", name: "Amethyst Prime" },
|
||||
{ level: 2000, colormap: "87ff778", color: "white", name: "Mirror" },
|
||||
@@ -26,31 +26,31 @@ export const PRESTIGES = [
|
||||
{ level: 2300, colormap: "55dd6ee", color: "purple", name: "Dusk" },
|
||||
{ level: 2400, colormap: "bbff778", color: "white", name: "Air" },
|
||||
{ level: 2500, colormap: "ffaa222", color: "green", name: "Wind" },
|
||||
{ level: 2600, colormap: "44ccdd5", color: "darkred", name: "Nebula" },
|
||||
{ level: 2600, colormap: "44ccdd5", color: "dark-red", name: "Nebula" },
|
||||
{ level: 2700, colormap: "eeff777", color: "yellow", name: "Thunder" },
|
||||
{ level: 2800, colormap: "aa2266e", color: "darkgreen", name: "Earth" },
|
||||
{ level: 2800, colormap: "aa2266e", color: "dark-green", name: "Earth" },
|
||||
{ level: 2900, colormap: "bb33991", color: "blue", name: "Water" },
|
||||
{ level: 3000, colormap: "ee66cc4", color: "red", name: "Fire" },
|
||||
{ level: 3100, colormap: "993366e", color: "blue", name: "Sunshine" },
|
||||
{ level: 3200, colormap: "c4774cc", color: "darkred", name: "Eclipse" },
|
||||
{ level: 3200, colormap: "c4774cc", color: "dark-red", name: "Eclipse" },
|
||||
{ level: 3300, colormap: "999dcc4", color: "blue", name: "Gamma" },
|
||||
{ level: 3400, colormap: "2add552", color: "green", name: "Majestic" },
|
||||
{ level: 3500, colormap: "cc442aa", color: "red", name: "Andesine" },
|
||||
{ level: 3600, colormap: "aaab991", color: "green", name: "Marine" },
|
||||
{ level: 3700, colormap: "44ccb33", color: "darkred", name: "Element" },
|
||||
{ level: 3800, colormap: "11955d1", color: "darkblue", name: "Galaxy" },
|
||||
{ level: 3700, colormap: "44ccb33", color: "dark-red", name: "Element" },
|
||||
{ level: 3800, colormap: "11955d1", color: "dark-blue", name: "Galaxy" },
|
||||
{ level: 3900, colormap: "ccaa399", color: "red", name: "Atomic" },
|
||||
{ level: 4000, colormap: "55cc66e", color: "purple", name: "Sunset" },
|
||||
{ level: 4100, colormap: "ee6cdd5", color: "yellow", name: "Time" },
|
||||
{ level: 4200, colormap: "193bf77", color: "blue", name: "Winter" },
|
||||
{ level: 4300, colormap: "0588550", color: "purple", name: "Obsidian" },
|
||||
{ level: 4400, colormap: "22ae65d", color: "darkgreen", name: "Spring" },
|
||||
{ level: 4400, colormap: "22ae65d", color: "dark-green", name: "Spring" },
|
||||
{ level: 4500, colormap: "ffbb333", color: "white", name: "Ice" },
|
||||
{ level: 4600, colormap: "3bee6d5", color: "aqua", name: "Summer" },
|
||||
{ level: 4700, colormap: "f4cc919", color: "darkred", name: "Spinel" },
|
||||
{ level: 4700, colormap: "f4cc919", color: "dark-red", name: "Spinel" },
|
||||
{ level: 4800, colormap: "55c6eb3", color: "purple", name: "Autumn" },
|
||||
{ level: 4900, colormap: "2affaa2", color: "green", name: "Mystic" },
|
||||
{ level: 5000, colormap: "4459910", color: "darkred", name: "Eternal" }
|
||||
{ level: 5000, colormap: "4459910", color: "dark-red", name: "Eternal" }
|
||||
]
|
||||
export const PRESTIGE_ICONS = [
|
||||
{ level: 0, symbol: "✫" },
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
const numberFormatter = new Intl.NumberFormat(undefined, {
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 0,
|
||||
});
|
||||
minimumFractionDigits: 0
|
||||
})
|
||||
|
||||
const dateFormatter = new Intl.DateTimeFormat(undefined, {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
});
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false
|
||||
})
|
||||
|
||||
export function formatNumber(num: number): string {
|
||||
return numberFormatter.format(num);
|
||||
return numberFormatter.format(num)
|
||||
}
|
||||
export function formatDate(timestamp: number): string {
|
||||
return dateFormatter.format(new Date(timestamp));
|
||||
return dateFormatter.format(new Date(timestamp))
|
||||
}
|
||||
@@ -18,3 +18,4 @@ export async function getPlayer(uuid: string) {
|
||||
|
||||
return data.player
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { PRESTIGE_ICONS } from "@/data/hypixel/bedwars"
|
||||
import { PRESTIGE_ICONS, PRESTIGES } from "@/data/hypixel/bedwars"
|
||||
import { floorLevel } from "./formatters"
|
||||
|
||||
export function getBedwarsStar(level: number) {
|
||||
if (level < 1100) {
|
||||
@@ -15,3 +16,23 @@ export function getBedwarsStar(level: number) {
|
||||
|
||||
return PRESTIGE_ICONS[3].symbol
|
||||
}
|
||||
|
||||
export function getTextColor(level: number) {
|
||||
const floored = floorLevel(level, 100)
|
||||
|
||||
if (level > 5000) {
|
||||
return PRESTIGES[PRESTIGES.length - 1].color
|
||||
}
|
||||
|
||||
return PRESTIGES.find(l => l.level === floored)!.color
|
||||
}
|
||||
|
||||
export function getPrestigeName(level: number) {
|
||||
const floored = floorLevel(level, 100)
|
||||
|
||||
if (level > 5000) {
|
||||
return PRESTIGES[PRESTIGES.length - 1].name
|
||||
}
|
||||
|
||||
return PRESTIGES.find(p => p.level === floored)!.name
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ const XP_PER_PRESTIGE = 96 * 5000 + EASY_LEVELS_XP
|
||||
const LEVELS_PER_PRESTIGE = 100
|
||||
const HIGHEST_PRESTIGE = 10
|
||||
|
||||
export function getBWLevel(level: number) {
|
||||
function getBWLevel(level: number) {
|
||||
if (level > HIGHEST_PRESTIGE * LEVELS_PER_PRESTIGE) {
|
||||
return level - HIGHEST_PRESTIGE * LEVELS_PER_PRESTIGE
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export function getBWLevel(level: number) {
|
||||
return level % LEVELS_PER_PRESTIGE
|
||||
}
|
||||
|
||||
export function getBWExpForLevel(level: number) {
|
||||
function getBWExpForLevel(level: number) {
|
||||
if (level === 0) return 0
|
||||
|
||||
const respectedLevel = getBWLevel(level)
|
||||
@@ -53,3 +53,17 @@ export function getBWLevelForExp(exp: number) {
|
||||
}
|
||||
return level + Math.floor(expWithoutPrestiges / 5000)
|
||||
}
|
||||
|
||||
export function getTotalExpForLevel(level: number): number {
|
||||
if (level === 0) return 0
|
||||
|
||||
const prestiges = Math.floor(level / LEVELS_PER_PRESTIGE)
|
||||
let totalExp = prestiges * XP_PER_PRESTIGE
|
||||
const remainingLevels = level % LEVELS_PER_PRESTIGE
|
||||
|
||||
for (let i = 1; i <= remainingLevels; i += 1) {
|
||||
totalExp += getBWExpForLevel(i)
|
||||
}
|
||||
|
||||
return totalExp
|
||||
}
|
||||
|
||||
7
src/lib/hypixel/general.ts
Normal file
7
src/lib/hypixel/general.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export function getProgress(min: number, mid: number, max: number) {
|
||||
if (max === min) return 100
|
||||
const diff = max - min
|
||||
const progress = mid - min
|
||||
|
||||
return progress / diff * 100
|
||||
}
|
||||
@@ -2,18 +2,18 @@ import z from "zod"
|
||||
|
||||
export const playerSchema = z.looseObject({
|
||||
player: z.looseObject({
|
||||
displayname: z.string(),
|
||||
uuid: z.string(),
|
||||
newPackageRank: z.literal("VIP").or(z.literal("VIP_PLUS").or(z.literal("MVP")).or(z.literal("MVP_PLUS"))).optional(),
|
||||
displayname: z.string().optional(),
|
||||
uuid: z.string().optional(),
|
||||
newPackageRank: z.string().optional(),
|
||||
monthlyPackageRank: z.string().optional(),
|
||||
rankPlusColor: z.string().optional(),
|
||||
monthlyRankColor: z.literal("GOLD").or(z.literal("AQUA")).optional(),
|
||||
networkExp: z.number(),
|
||||
karma: z.number(),
|
||||
achievementPoints: z.number().optional(),
|
||||
monthlyRankColor: z.string().optional(),
|
||||
networkExp: z.number().default(0),
|
||||
karma: z.number().default(0),
|
||||
achievementPoints: z.number().default(0),
|
||||
stats: z.looseObject({
|
||||
Bedwars: z.looseObject({
|
||||
Experience: z.number(),
|
||||
Experience: z.number().default(0),
|
||||
winstreak: z.number().optional(),
|
||||
kills_bedwars: z.number().default(0),
|
||||
deaths_bedwars: z.number().default(0),
|
||||
@@ -33,11 +33,11 @@ export const playerSchema = z.looseObject({
|
||||
time: z.number()
|
||||
}).optional()
|
||||
).optional()
|
||||
})
|
||||
),
|
||||
}).optional()
|
||||
).optional(),
|
||||
challenges: z.looseObject({
|
||||
all_time: z.record(z.string(), z.number())
|
||||
}),
|
||||
}).optional(),
|
||||
lastClaimedReward: z.number().optional(),
|
||||
rewardHighScore: z.number().optional(),
|
||||
rewardStreak: z.number().optional(),
|
||||
@@ -55,8 +55,8 @@ export const playerSchema = z.looseObject({
|
||||
HYPIXEL: z.string().optional(),
|
||||
TWITTER: z.string().optional(),
|
||||
YOUTUBE: z.string().optional()
|
||||
})
|
||||
})
|
||||
}).optional()
|
||||
}).optional()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { type ClassValue, clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
|
||||
Reference in New Issue
Block a user