diff --git a/src/app/game/berry-dash/leaderboards/page.tsx b/src/app/game/berry-dash/leaderboards/page.tsx index 78f071f..20f889c 100644 --- a/src/app/game/berry-dash/leaderboards/page.tsx +++ b/src/app/game/berry-dash/leaderboards/page.tsx @@ -8,7 +8,7 @@ import axios from 'axios' import { GetIconForUser } from '@/util/bd' import Image from 'next/image' -interface LeaderboardEntry { +interface BaseEntry { id: number username: string value: number @@ -19,29 +19,115 @@ interface LeaderboardEntry { customIcon: string | null } +interface Stats { + highScore: string + totalNormalBerries: string + totalPoisonBerries: string + totalSlowBerries: string + totalUltraBerries: string + totalSpeedyBerries: string + totalCoinBerries: string + totalRandomBerries: string + totalAntiBerries: string + totalGoldenBerries: string + coins: string +} + +interface LeaderboardEntry extends BaseEntry { + type: 'leaderboard' + value: number +} + +interface Account extends BaseEntry { + type: 'account' + stats: Stats + xp: bigint +} + +export function calculateXP ( + normalBerries: bigint, + poisonBerries: bigint, + slowBerries: bigint, + ultraBerries: bigint, + speedyBerries: bigint, + coinBerries: bigint, + randomBerries: bigint, + antiBerries: bigint, + goldenBerries: bigint +): bigint { + let totalXp = 0n + totalXp += normalBerries + totalXp -= poisonBerries + totalXp -= slowBerries + totalXp += ultraBerries * 5n + totalXp += speedyBerries * 10n + totalXp += coinBerries * 10n + totalXp += randomBerries + totalXp -= antiBerries + totalXp += goldenBerries * 4n + + if (totalXp < 0n) totalXp = 0n + return totalXp +} + +export function calculateLevel (xp: bigint): number { + const levelDivisor = 50.0 + + const xpNumber = Number(xp) + const discriminant = 95 * 95 + levelDivisor * 2 * xpNumber + const level = (-95 + Math.sqrt(discriminant)) / levelDivisor + return Math.floor(level) + 1 +} + export default function BerryDashLeaderboards () { const [selected, setSelected] = useState(-1) const [selectedBerryOption, setSelectedBerryOption] = useState(0) const [gettingEntries, setGettingEntries] = useState(false) - const [entries, setEntries] = useState([]) + const [entries, setEntries] = useState<(LeaderboardEntry | Account)[]>([]) const Refresh = useCallback(async () => { setGettingEntries(true) try { - const result = await axios.get( - '/api/berrydash/leaderboard/' + - (selected == 0 - ? 'score' - : selected == 1 - ? 'berry?berry=' + selectedBerryOption - : selected == 2 - ? 'coin' - : selected == 3 - ? 'legacy' - : 'total') - ) - if (result.data.success) { - setEntries(result.data.data) + if (selected == 3 || selected == 4) { + const result = await axios.get('/api/berrydash/account?username=') + if (result.data.success) { + let accounts = result.data.data as Account[] + + accounts = accounts.map(acc => { + const xp = calculateXP( + BigInt(acc.stats.totalNormalBerries), + BigInt(acc.stats.totalPoisonBerries), + BigInt(acc.stats.totalSlowBerries), + BigInt(acc.stats.totalUltraBerries), + BigInt(acc.stats.totalSpeedyBerries), + BigInt(acc.stats.totalCoinBerries), + BigInt(acc.stats.totalRandomBerries), + BigInt(acc.stats.totalAntiBerries), + BigInt(acc.stats.totalGoldenBerries) + ) + return { ...acc, xp } + }) + + accounts.sort((a, b) => (b.xp > a.xp ? 1 : b.xp < a.xp ? -1 : 0)) + + setEntries(accounts) + } + } else { + const result = await axios.get( + '/api/berrydash/leaderboard/' + + (selected == 0 + ? 'score' + : selected == 1 + ? 'berry?berry=' + selectedBerryOption + : selected == 2 + ? 'coin' + : selected == 5 + ? 'legacy' + : 'total') + ) + if (result.data.success) { + setEntries(result.data.data as LeaderboardEntry[]) + } } } catch { setEntries([]) @@ -82,14 +168,10 @@ export default function BerryDashLeaderboards () { - - + + - @@ -98,6 +180,9 @@ export default function BerryDashLeaderboards () { <>
{entries.map((item, index) => { + const isAccount = 'stats' in item + const isLeaderboard = 'value' in item && !isAccount + return (

{item.username} (#{index + 1})

-

- {selected == 1 || selected == 4 - ? 'Berries' - : selected == 2 - ? 'Coins' - : 'Score'} - : {item.value.toLocaleString('en-US')} -

+ + {isLeaderboard ? ( +

+ {selected === 1 || selected === 6 + ? 'Berries' + : selected === 2 + ? 'Coins' + : 'Score'} + : {item.value.toLocaleString('en-US')} +

+ ) : isAccount ? ( +

+ {selected === 3 ? 'Level' : 'XP'}:{' '} + {selected === 3 + ? calculateLevel(item.xp).toLocaleString('en-US') + : item.xp.toLocaleString('en-US')} +

+ ) : null}
) })} diff --git a/tsconfig.json b/tsconfig.json index cf9c65d..81fd489 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2017", + "target": "es2024", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true,