From ca3a1fbe3f92d437069647ce2ad4c361d9c51c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:40:01 -0500 Subject: [PATCH] feat: ratings stats --- src/commands/link.tsx | 2 +- src/commands/ratingStats.tsx | 31 +++---------- .../components/Glow.tsx | 13 +++--- .../components/HeroStat/constants.ts | 9 ++++ .../{WN8Display => HeroStat}/index.tsx | 33 +++++++++++--- src/components/AllStatsOverview/index.tsx | 45 +++++++++++-------- src/components/GenericAllStats/index.tsx | 6 +++ src/constants/leagues.ts | 10 ++--- src/core/blitz/getAccountInfo.ts | 13 +++++- src/core/blitz/getLeagueFromScore.ts | 5 +++ src/core/statistics/filterStats.ts | 4 +- src/lang/en-US.json | 24 +++++----- 12 files changed, 117 insertions(+), 78 deletions(-) rename src/components/AllStatsOverview/components/{WN8Display => HeroStat}/components/Glow.tsx (67%) create mode 100644 src/components/AllStatsOverview/components/HeroStat/constants.ts rename src/components/AllStatsOverview/components/{WN8Display => HeroStat}/index.tsx (60%) create mode 100644 src/core/blitz/getLeagueFromScore.ts diff --git a/src/commands/link.tsx b/src/commands/link.tsx index 55c2cc463..f56686286 100644 --- a/src/commands/link.tsx +++ b/src/commands/link.tsx @@ -2,7 +2,7 @@ import { teal } from '@radix-ui/colors'; import { GuildMemberRoleManager } from 'discord.js'; import markdownEscape from 'markdown-escape'; import discord from '../../discord.json' assert { type: 'json' }; -import { Glow } from '../components/AllStatsOverview/components/WN8Display/components/Glow'; +import { Glow } from '../components/AllStatsOverview/components/HeroStat/components/Glow'; import CommandWrapper from '../components/CommandWrapper'; import { getAccountInfo } from '../core/blitz/getAccountInfo'; import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo'; diff --git a/src/commands/ratingStats.tsx b/src/commands/ratingStats.tsx index 8a12bdc83..d50917e56 100644 --- a/src/commands/ratingStats.tsx +++ b/src/commands/ratingStats.tsx @@ -52,7 +52,6 @@ export const ratingStatsCommand = new Promise((resolve) => { } const delta = deltaBkrlBlitzStats(statsA, accountInfo.statistics.rating!); - const scoreDiff = statsB2.score - statsA.score; return ( @@ -78,35 +77,15 @@ export const ratingStatsCommand = new Promise((resolve) => { survived_battles: delta.survived, wins: delta.wins, }} - supplementaryStats={{ WN8: 3000, tier: 10 }} + supplementaryStats={{ + type: 'rating', + score: statsB2.score, + delta: statsB2.score - statsA.score, + }} /> )} ); - - // return `# ${markdownEscape(accountInfo.nickname)}\n\n${markdownTable([ - // [ - // 'score', - // `${statsB2.score}${scoreDiff === 0 ? '' : ` (${scoreDiff > 0 ? '+' : ''}${scoreDiff})`}`, - // ], - // ['winrate', `${(100 * (delta.wins / delta.battles)).toFixed(0)}%`], - // ['battles', delta.battles], - // ['wins / losses', `${delta.wins} / ${delta.battles - delta.wins}`], - // ['wn8', 'impossible'], - // ['survival', `${(100 * (delta.survived / delta.battles)).toFixed(0)}%`], - // ['accuracy', `${(100 * (delta.hits / delta.shots)).toFixed(0)}%`], - // ['average damage', (delta.damageDealt / delta.battles).toFixed(0)], - // ['damager per tier', 'impossible'], - // ['damage ratio', (delta.damageDealt / delta.damageReceived).toFixed(2)], - // ['average kills', (delta.kills / delta.battles).toFixed(2)], - // ['average tier', 'impossible'], - // ['average spots', 'possible'], - // ['average xp', 'possible'], - // [ - // 'kills to death ratio', - // (delta.kills / (delta.wins - delta.survived)).toFixed(2), - // ], - // ])}`; }, }); }); diff --git a/src/components/AllStatsOverview/components/WN8Display/components/Glow.tsx b/src/components/AllStatsOverview/components/HeroStat/components/Glow.tsx similarity index 67% rename from src/components/AllStatsOverview/components/WN8Display/components/Glow.tsx rename to src/components/AllStatsOverview/components/HeroStat/components/Glow.tsx index b5a524067..94933b00f 100644 --- a/src/components/AllStatsOverview/components/WN8Display/components/Glow.tsx +++ b/src/components/AllStatsOverview/components/HeroStat/components/Glow.tsx @@ -4,6 +4,8 @@ export interface GlowProps { rotation?: number; } +const width = 16; + export function Glow({ color, direction = 'default', @@ -11,7 +13,6 @@ export function Glow({ }: GlowProps) { const color1 = color; const color2 = `${color}00`; - const background = `linear-gradient(${ direction === 'default' ? 0 : 180 }deg, ${color1} 0%, ${color2} 100%)`; @@ -25,11 +26,11 @@ export function Glow({ transform: `rotate(${rotation}deg)`, }} > -
-
-
-
-
+
+
+
+
+
); } diff --git a/src/components/AllStatsOverview/components/HeroStat/constants.ts b/src/components/AllStatsOverview/components/HeroStat/constants.ts new file mode 100644 index 000000000..8e1de6207 --- /dev/null +++ b/src/components/AllStatsOverview/components/HeroStat/constants.ts @@ -0,0 +1,9 @@ +import { amber, brown, purple, sandDark, slate } from '@radix-ui/colors'; + +export const LEAGUE_COLORS = [ + purple.purple9, + sandDark.sand11, + amber.amber10, + slate.slate9, + brown.brown9, +]; diff --git a/src/components/AllStatsOverview/components/WN8Display/index.tsx b/src/components/AllStatsOverview/components/HeroStat/index.tsx similarity index 60% rename from src/components/AllStatsOverview/components/WN8Display/index.tsx rename to src/components/AllStatsOverview/components/HeroStat/index.tsx index 9248a9456..ecfdb34e8 100644 --- a/src/components/AllStatsOverview/components/WN8Display/index.tsx +++ b/src/components/AllStatsOverview/components/HeroStat/index.tsx @@ -1,21 +1,40 @@ import { Locale } from 'discord.js'; import { Percentile } from '../../../../constants/percentiles'; +import { SupplementaryStats } from '../../../../core/blitz/getAccountInfo'; +import { getLeagueFromScore } from '../../../../core/blitz/getLeagueFromScore'; import { translator } from '../../../../core/localization/translator'; import getWN8Percentile from '../../../../core/statistics/getWN8Percentile'; import { theme } from '../../../../stitches.config'; import { PERCENTILE_COLORS } from '../../../PercentileIndicator/constants'; import { Glow } from './components/Glow'; +import { LEAGUE_COLORS } from './constants'; export interface WN8DisplayProps { - wn8?: number; + stats: SupplementaryStats; locale: Locale; } -export function WN8Display({ wn8, locale }: WN8DisplayProps) { - const percentile = - wn8 === undefined ? Percentile.VeryBad : getWN8Percentile(wn8); - const color = PERCENTILE_COLORS[percentile]; +export function HeroStat({ stats, locale }: WN8DisplayProps) { const { translate } = translator(locale); + let color: string; + let heroStat: string | number; + let subtitle: string | number | undefined; + let subtitleImage: string | undefined; + + if (stats.type === 'random') { + const percentile = + stats.WN8 === undefined + ? Percentile.VeryBad + : getWN8Percentile(stats.WN8); + color = PERCENTILE_COLORS[percentile]; + heroStat = stats.WN8 === undefined ? '--' : stats.WN8.toFixed(0); + subtitle = translate(`common.wn8_percentile.${percentile}`); + } else { + heroStat = stats.score; + const league = getLeagueFromScore(stats.score); + color = LEAGUE_COLORS[league.index]; + subtitle = translate(`common.leagues.${league.name}`); + } return (
- {wn8 === undefined ? '--' : wn8.toFixed(0)} + {heroStat} - {translate(`common.wn8_percentile.${percentile}`)} + {subtitle}
diff --git a/src/components/AllStatsOverview/index.tsx b/src/components/AllStatsOverview/index.tsx index 6834b1121..f78af5bc6 100644 --- a/src/components/AllStatsOverview/index.tsx +++ b/src/components/AllStatsOverview/index.tsx @@ -1,7 +1,7 @@ import { Locale } from 'discord.js'; import { SupplementaryStats } from '../../core/blitz/getAccountInfo'; import { translator } from '../../core/localization/translator'; -import { WN8Display } from './components/WN8Display'; +import { HeroStat } from './components/HeroStat'; import { WN8SurroundingStat, WN8SurroundingStatAlign, @@ -47,18 +47,18 @@ export default function AllStatsOverview({ }} >
- +
+ {supplementaryStats.type === 'random' && ( + + )} + {supplementaryStats.type === 'rating' && ( + + )} -
diff --git a/src/components/GenericAllStats/index.tsx b/src/components/GenericAllStats/index.tsx index 2e2ff3bb5..f3ff45bb5 100644 --- a/src/components/GenericAllStats/index.tsx +++ b/src/components/GenericAllStats/index.tsx @@ -23,6 +23,12 @@ export default function GenericAllStats({ const killsToDeathRatio = stats.frags / (stats.battles - stats.survived_battles); + if (supplementaryStats && supplementaryStats.type !== 'random') { + throw new Error( + 'Generic all stats does not support random supplementary stats', + ); + } + return ( diff --git a/src/constants/leagues.ts b/src/constants/leagues.ts index ee77accb4..8013e16ec 100644 --- a/src/constants/leagues.ts +++ b/src/constants/leagues.ts @@ -1,7 +1,7 @@ export const LEAGUES = [ - { name: 'diamond', minScore: 5000 }, - { name: 'platinum', minScore: 4000 }, - { name: 'gold', minScore: 3000 }, - { name: 'silver', minScore: 2000 }, - { name: 'bronze', minScore: 0 }, + { name: 'diamond', minScore: 5000, index: 0 }, + { name: 'platinum', minScore: 4000, index: 1 }, + { name: 'gold', minScore: 3000, index: 2 }, + { name: 'silver', minScore: 2000, index: 3 }, + { name: 'bronze', minScore: -Infinity, index: 4 }, ]; diff --git a/src/core/blitz/getAccountInfo.ts b/src/core/blitz/getAccountInfo.ts index e9cab4285..f8549b9e5 100644 --- a/src/core/blitz/getAccountInfo.ts +++ b/src/core/blitz/getAccountInfo.ts @@ -23,11 +23,22 @@ export interface AllStats { dropped_capture_points: number; } -export interface SupplementaryStats { +export interface SupplementaryStatsRandom { + type: 'random'; WN8?: number; tier?: number; } +export interface SupplementaryStatsRating { + type: 'rating'; + score: number; + delta: number; +} + +export type SupplementaryStats = + | SupplementaryStatsRandom + | SupplementaryStatsRating; + export interface ClanStats { spotted: number; max_frags_tank_id: number; diff --git a/src/core/blitz/getLeagueFromScore.ts b/src/core/blitz/getLeagueFromScore.ts new file mode 100644 index 000000000..d0f881be2 --- /dev/null +++ b/src/core/blitz/getLeagueFromScore.ts @@ -0,0 +1,5 @@ +import { LEAGUES } from '../../constants/leagues'; + +export function getLeagueFromScore(score: number) { + return LEAGUES.find(({ minScore }) => score >= minScore)!; +} diff --git a/src/core/statistics/filterStats.ts b/src/core/statistics/filterStats.ts index 42a60015e..4da925a2c 100644 --- a/src/core/statistics/filterStats.ts +++ b/src/core/statistics/filterStats.ts @@ -1,4 +1,5 @@ import { TreeType } from '../../components/Tanks'; +import { SupplementaryStatsRandom } from '../blitz/getAccountInfo'; import { tankDefinitions } from '../blitzkrieg/tankDefinitions'; import { DiffedTankStats } from '../blitzstars/getStatsInPeriod'; import { tankAverages } from '../blitzstars/tankAverages'; @@ -50,6 +51,7 @@ export async function filterStats( 0, ); const supplementary = { + type: 'random', WN8: filteredOrder.reduce( (accumulator, id) => @@ -68,7 +70,7 @@ export async function filterStats( : accumulator, 0, ) / battlesOfTanksWithTankDefinition, - }; + } satisfies SupplementaryStatsRandom; return { stats, supplementary, filteredOrder }; } diff --git a/src/lang/en-US.json b/src/lang/en-US.json index f3bca9607..977063329 100644 --- a/src/lang/en-US.json +++ b/src/lang/en-US.json @@ -193,6 +193,17 @@ "get_help": "Help Discord server", "uncaught_error": "# Blitzkrieg ran into an error!\nWe're so sorry about this. Feel free to [join the official Discord server](https://discord.gg/nDt7AjGJQH) to get help.", "preview": "# This command is in preview\n\nYou can only access this command in [the official Discord server](https://discord.gg/nDt7AjGJQH). The command will be generally available soon." + }, + + "hero_stats": { + "battles": "Battles", + "winrate": "Winrate", + "damage": "Damage", + "damage_ratio": "Damage ratio", + "tier": "Tier", + "survival": "Survival", + "accuracy": "Accuracy", + "kills": "Kills" } }, @@ -469,18 +480,7 @@ "stats": { "$": "stats", - "description": "Quick statistics for a period", - - "body": { - "battles": "Battles", - "winrate": "Winrate", - "damage": "Damage", - "damage_ratio": "Damage ratio", - "tier": "Tier", - "survival": "Survival", - "accuracy": "Accuracy", - "kill_ratio": "Kill ratio" - } + "description": "Quick statistics for a period" }, "owned_tanks": {