Updated tkr stats
This commit is contained in:
@@ -3,6 +3,7 @@ import { formatNumber } from "@/lib/formatters"
|
||||
import { NonNullStats } from "@/lib/schema/player"
|
||||
import { EmptyStats, GeneralStats } from "../stats-components"
|
||||
import { TkrGeneralStats } from "./stats"
|
||||
import TkrKart from "./tkrkart"
|
||||
|
||||
export default function TkrStats({ stats }: { stats: NonNullStats["TurboKartRacers"] }) {
|
||||
if (!stats) return <EmptyStats title="Turbo Kart Racers" />
|
||||
@@ -29,6 +30,8 @@ export default function TkrStats({ stats }: { stats: NonNullStats["TurboKartRace
|
||||
<Separator className="my-4" />
|
||||
<TkrGeneralStats stats={stats} />
|
||||
<Separator className="my-4" />
|
||||
<TkrKart stats={stats} />
|
||||
<Separator className="my-4" />
|
||||
</GeneralStats>
|
||||
)
|
||||
}
|
||||
|
||||
64
src/app/(stats)/player/[ign]/_stats/classic/tkrkart.tsx
Normal file
64
src/app/(stats)/player/[ign]/_stats/classic/tkrkart.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { getTkrKart } from "@/lib/hypixel/classic/general"
|
||||
import { NonNullStats } from "@/lib/schema/player"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export default function TkrKart({ stats }: { stats: NonNullable<NonNullStats["TurboKartRacers"]> }) {
|
||||
const { engine, frame, turbocharger } = getTkrKart(stats.engine_active, stats.frame_active, stats.booster_active)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="text-xl font-bold">Current Kart</h2>
|
||||
<div className="flex gap-4 mt-4">
|
||||
{engine !== null ?
|
||||
(
|
||||
<div className="flex-1">
|
||||
<p className={cn("mb-2 font-bold", `text-mc-${engine.color}`)}>{`${engine.name} ${engine.rarity} Engine`}</p>
|
||||
{engine.attributes.map((e, i) => {
|
||||
return (
|
||||
<div key={i} className="flex justify-between">
|
||||
<p>{e.name}</p>
|
||||
<p className="text-mc-green">
|
||||
{e.level}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) :
|
||||
<p>Error while getting engine</p>}
|
||||
{frame !== null ?
|
||||
(
|
||||
<div className="flex-1">
|
||||
<p className={cn("mb-2 font-bold", `text-mc-${frame.color}`)}>{`${frame.name} ${frame.rarity} Frame`}</p>
|
||||
{frame.attributes.map((e, i) => {
|
||||
return (
|
||||
<div key={i} className="flex justify-between">
|
||||
<p>{e.name}</p>
|
||||
<p className="text-mc-green">{e.level}</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) :
|
||||
<p>Error while getting frame</p>}
|
||||
{turbocharger !== null ?
|
||||
(
|
||||
<div className="flex-1">
|
||||
<p className={cn("mb-2 font-bold", `text-mc-${turbocharger.color}`)}>
|
||||
{`${turbocharger.name} ${turbocharger.rarity} Turbocharger`}
|
||||
</p>
|
||||
{turbocharger.attributes.map((e, i) => {
|
||||
return (
|
||||
<div key={i} className="flex justify-between">
|
||||
<p>{e.name}</p>
|
||||
<p className="text-mc-green">{e.level}</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) :
|
||||
<p>Error while getting turbocharger</p>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -7,3 +7,36 @@ export const QUAKECRAFTMODES = [
|
||||
{ id: "", name: "Solo" },
|
||||
{ id: "teams", name: "Teams" }
|
||||
] as const
|
||||
export const TKRATTRIBUTES = [
|
||||
{ id: "ACCELERATION", name: "Acceleration" },
|
||||
{ id: "BOOSTER_SPEED", name: "Booster Speed" },
|
||||
{ id: "BRAKES", name: "Brakes" },
|
||||
{ id: "DRIFTING_EFFICIENCY", name: "Drifting Efficiency" },
|
||||
{ id: "HANDLING", name: "Handling" },
|
||||
{ id: "RECOVERY", name: "Recovery" },
|
||||
{ id: "START_POSITION", name: "Start Position" },
|
||||
{ id: "TOP_SPEED", name: "Top Speed" },
|
||||
{ id: "TRACTION", name: "Traction" }
|
||||
] as const
|
||||
export const TKRQUALITY = [
|
||||
{ name: "Starter", color: "gray" },
|
||||
{ name: "Mini", color: "gray" },
|
||||
{ name: "Auxiliary", color: "green" },
|
||||
{ name: "Standard", color: "green" },
|
||||
{ name: "Primary", color: "green" },
|
||||
{ name: "Experimental", color: "green" },
|
||||
{ name: "Dynamic", color: "blue" },
|
||||
{ name: "Stellar", color: "blue" },
|
||||
{ name: "Kinetic", color: "blue" },
|
||||
{ name: "Multi-phase", color: "blue" },
|
||||
{ name: "Turbocharged", color: "light-purple" },
|
||||
{ name: "Quantum", color: "light-purple" },
|
||||
{ name: "Superluminal", color: "light-purple" },
|
||||
{ name: "Psi", color: "light-purple" },
|
||||
{ name: "Eternal", color: "dark-purple" }
|
||||
] as const
|
||||
export const TKRRARITY = [
|
||||
{ id: "BASIC", name: "Basic" },
|
||||
{ id: "SUPER", name: "Super" },
|
||||
{ id: "AWESOME", name: "Awesome" }
|
||||
] as const
|
||||
|
||||
@@ -1,6 +1,71 @@
|
||||
import { ARENABRAWLMODES, QUAKECRAFTMODES } from "@/data/hypixel/classic"
|
||||
import { ARENABRAWLMODES, QUAKECRAFTMODES, TKRATTRIBUTES, TKRQUALITY, TKRRARITY } from "@/data/hypixel/classic"
|
||||
import { NonNullStats } from "@/lib/schema/player"
|
||||
import { devide } from "../general"
|
||||
import z from "zod"
|
||||
import { addQuotes, devide } from "../general"
|
||||
|
||||
const tkrSchema = z.object({
|
||||
GingerbreadPart: z.object({
|
||||
PartRarity: z.string().optional(),
|
||||
Attributes: z.array(z.object({
|
||||
KartAttributeType: z.string().optional(),
|
||||
Level: z.coerce.number().default(0)
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
export function getTkrKart(engine?: string, frame?: string, turbocharger?: string) {
|
||||
return {
|
||||
engine: getTkrPart(engine),
|
||||
frame: getTkrPart(frame),
|
||||
turbocharger: getTkrPart(turbocharger)
|
||||
}
|
||||
}
|
||||
|
||||
function getTkrPart(val?: string) {
|
||||
const unknown = JSON.parse(addQuotes(val))
|
||||
const { data, success } = tkrSchema.safeParse(unknown)
|
||||
if (!success) return null
|
||||
|
||||
let quality = 0
|
||||
const rarity = getTkrRarity(data.GingerbreadPart.PartRarity)
|
||||
|
||||
const attributes: { name: typeof TKRATTRIBUTES[number]["name"], level: number }[] = []
|
||||
for (const attr of data.GingerbreadPart.Attributes) {
|
||||
const val = getTkrAttribute(attr)
|
||||
if (!val) continue
|
||||
quality += val.level
|
||||
attributes.push({ name: val.name, level: val.level })
|
||||
}
|
||||
const { color, name } = getTkrQuality(quality)
|
||||
|
||||
return { rarity, attributes, color, name }
|
||||
}
|
||||
|
||||
function getTkrRarity(rarity?: string) {
|
||||
const val = TKRRARITY.find(r => r.id === rarity)
|
||||
return val?.name || TKRRARITY.find(r => r.id === "BASIC")!.name
|
||||
}
|
||||
|
||||
function getTkrAttribute(attr: z.infer<typeof tkrSchema>["GingerbreadPart"]["Attributes"][number]) {
|
||||
const val = TKRATTRIBUTES.find(a => a.id === attr.KartAttributeType)?.name
|
||||
|
||||
if (!val) return null
|
||||
|
||||
return { name: val, level: attr.Level }
|
||||
}
|
||||
|
||||
function getTkrQuality(quality: number) {
|
||||
if (quality < 1) {
|
||||
const { color, name } = TKRQUALITY.at(0)!
|
||||
return { name, color }
|
||||
}
|
||||
if (quality > TKRQUALITY.length) {
|
||||
const { color, name } = TKRQUALITY.at(-1)!
|
||||
return { name, color }
|
||||
}
|
||||
const { color, name } = TKRQUALITY.at(quality - 1)!
|
||||
return { name, color }
|
||||
}
|
||||
|
||||
export function getQuakecraftModeName(modeId: Exclude<typeof QUAKECRAFTMODES[number]["id"], ""> | "solo") {
|
||||
if (modeId === "solo") return QUAKECRAFTMODES.find(m => m.id === "")!.name
|
||||
|
||||
@@ -82,3 +82,19 @@ export function romanize(num: number) {
|
||||
export function head(val: string, size: number) {
|
||||
return `https://vzge.me/face/${size}/${val}?no-shadow,cape,ears,overlay`
|
||||
}
|
||||
|
||||
export function addQuotes(str?: string) {
|
||||
if (!str) return "{}"
|
||||
const bank = ["{", "}", "[", "]", ",", ":"]
|
||||
let newStr = str.charAt(0)
|
||||
for (let i = 1; i < str.length; i++) {
|
||||
if (
|
||||
(bank.includes(str[i - 1]) && !bank.includes(str[i])) ||
|
||||
(!bank.includes(str[i - 1]) && bank.includes(str[i]))
|
||||
) {
|
||||
newStr += "\""
|
||||
}
|
||||
newStr += str[i]
|
||||
}
|
||||
return newStr
|
||||
}
|
||||
|
||||
@@ -82,5 +82,8 @@ export const turboKartRacersStatsSchema = z.object({
|
||||
laps_completed: z.number().default(0),
|
||||
blue_torpedo_hit: z.number().default(0),
|
||||
banana_hits_sent: z.number().default(0),
|
||||
banana_hits_received: z.number().default(0)
|
||||
banana_hits_received: z.number().default(0),
|
||||
engine_active: z.string().optional(),
|
||||
frame_active: z.string().optional(),
|
||||
booster_active: z.string().optional()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user