mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 11:39:50 +02:00
feat: /tankstats
This commit is contained in:
1 parent
d62ca080e9
commit
5b918d6e3e
16 files changed
+317
-33
No files matched your search
+3
-10
@@ -9,6 +9,7 @@ import addIGNOption from '../utilities/addIGNOption.js';
|
||||
import addServerChoices from '../utilities/addServerChoices.js';
|
||||
import { args } from '../utilities/args.js';
|
||||
import blitzLinks from '../utilities/blitzLinks.js';
|
||||
import cleanTable from '../utilities/cleanTable.js';
|
||||
import cmdName from '../utilities/cmdName.js';
|
||||
import getBlitzAccount from '../utilities/getBlitzAccount.js';
|
||||
import getBlitzStarsAccount from '../utilities/getBlitzStarsAccount.js';
|
||||
@@ -134,7 +135,7 @@ export default {
|
||||
period === 'today'
|
||||
? '**⚠ "Today" stats are in development. Some stats are not available/wrong.**\n\n'
|
||||
: ''
|
||||
}${[
|
||||
}${cleanTable([
|
||||
[
|
||||
'Winrate',
|
||||
`${(100 * (stats.all.wins / stats.all.battles)).toFixed(
|
||||
@@ -200,15 +201,7 @@ export default {
|
||||
(stats.all.battles - stats.all.survived_battles)
|
||||
).toFixed(2),
|
||||
],
|
||||
]
|
||||
.filter((array) => array[1] !== `${-Infinity}`)
|
||||
.map((array) =>
|
||||
array.length === 0 ? '' : `**${array[0]}**: ${array[1]}`,
|
||||
)
|
||||
.join('\n')}\n\n${blitzLinks(
|
||||
server,
|
||||
blitzAccount.nickname,
|
||||
)}`
|
||||
])}\n\n${blitzLinks(server, blitzAccount.nickname)}`
|
||||
: 'No battles played in this period.',
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { CommandRegistry } from '../behaviors/interactionCreate.js';
|
||||
import { BlitzServer } from '../constants/servers.js';
|
||||
import tanksAutocomplete from '../core/autocomplete/tanks.js';
|
||||
import getPeriodicStats, {
|
||||
Period,
|
||||
} from '../core/blitztankstats/getPeriodicStats.js';
|
||||
import errorEmbed from '../core/embeds/errorEmbed.js';
|
||||
import sklldEmbed from '../core/embeds/sklldEmbed.js';
|
||||
import addIGNOption from '../utilities/addIGNOption.js';
|
||||
import addServerChoices from '../utilities/addServerChoices.js';
|
||||
import addTankChoices from '../utilities/addTankChoices.js';
|
||||
import cleanTable from '../utilities/cleanTable.js';
|
||||
import cmdName from '../utilities/cmdName.js';
|
||||
import getBlitzAccount from '../utilities/getBlitzAccount.js';
|
||||
import { tankopedia } from '../utilities/tankopedia.js';
|
||||
|
||||
type Periods = '30' | '60' | '90';
|
||||
|
||||
export default {
|
||||
inProduction: true,
|
||||
inDevelopment: false,
|
||||
inPublic: true,
|
||||
|
||||
command: new SlashCommandBuilder()
|
||||
.setName(cmdName('tankstats'))
|
||||
.setDescription('Stats for a tank over a period')
|
||||
.addStringOption(addTankChoices)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName('period')
|
||||
.setDescription('The period to get stats for')
|
||||
.setChoices(
|
||||
{ name: '30 Days', value: '30' satisfies Periods },
|
||||
{ name: '60 Days', value: '60' satisfies Periods },
|
||||
{ name: '90 Days', value: '90' satisfies Periods },
|
||||
)
|
||||
.setRequired(true),
|
||||
)
|
||||
.addStringOption(addServerChoices)
|
||||
.addStringOption(addIGNOption),
|
||||
|
||||
async execute(interaction) {
|
||||
const server = interaction.options.getString('server') as BlitzServer;
|
||||
const name = interaction.options.getString('name')!;
|
||||
const tankId = interaction.options.getString('tank')!;
|
||||
const period = interaction.options.getString('period') as Periods;
|
||||
const blitzAccount = await getBlitzAccount(interaction, name, server);
|
||||
if (!blitzAccount) return;
|
||||
const tank = tankopedia.data[tankId as unknown as number];
|
||||
|
||||
if (tank) {
|
||||
const periodicStats = (
|
||||
await getPeriodicStats(blitzAccount.account_id, Number(period))
|
||||
).filter((stats) => stats.tank_id === tank.tank_id);
|
||||
|
||||
function sum(summer: (period: Period) => number) {
|
||||
return periodicStats.reduce(
|
||||
(accumulative, period) => accumulative + summer(period),
|
||||
0,
|
||||
);
|
||||
}
|
||||
function weighted(summer: (period: Period) => number) {
|
||||
return (
|
||||
periodicStats.reduce(
|
||||
(accumulative, period) =>
|
||||
accumulative + summer(period) * period.battles,
|
||||
0,
|
||||
) / sum((period) => period.battles)
|
||||
);
|
||||
}
|
||||
|
||||
interaction.editReply({
|
||||
embeds: [
|
||||
sklldEmbed(
|
||||
`${period} day stats for ${markdownEscape(
|
||||
blitzAccount.nickname,
|
||||
)}'s ${
|
||||
tank.name ? markdownEscape(tank.name) : `Unknown Tank ${tankId}`
|
||||
}`,
|
||||
periodicStats.length > 0
|
||||
? cleanTable([
|
||||
[
|
||||
'Winrate',
|
||||
`${(
|
||||
100 *
|
||||
(sum((a) => a.wins) / sum((a) => a.battles))
|
||||
).toFixed(2)}%`,
|
||||
],
|
||||
[
|
||||
'Survival',
|
||||
`${(
|
||||
100 *
|
||||
(sum((a) => a.survived_battles) / sum((a) => a.battles))
|
||||
).toFixed(2)}%`,
|
||||
],
|
||||
[
|
||||
'Accuracy',
|
||||
`${(
|
||||
100 *
|
||||
(sum((a) => a.hits) / sum((a) => a.shots))
|
||||
).toFixed(2)}%`,
|
||||
],
|
||||
['WN8', weighted((a) => a.wn8).toFixed(0)],
|
||||
[],
|
||||
['Battles', sum((a) => a.battles)],
|
||||
['Wins', sum((a) => a.wins)],
|
||||
['Losses', sum((a) => a.losses)],
|
||||
[],
|
||||
[
|
||||
'Shots per battle',
|
||||
(sum((a) => a.shots) / sum((a) => a.battles)).toFixed(2),
|
||||
],
|
||||
[
|
||||
'Hits per battle',
|
||||
(sum((a) => a.hits) / sum((a) => a.battles)).toFixed(2),
|
||||
],
|
||||
[
|
||||
'Damage per battle',
|
||||
(
|
||||
sum((a) => a.damage_dealt) / sum((a) => a.battles)
|
||||
).toFixed(0),
|
||||
],
|
||||
[
|
||||
'Kills per battle',
|
||||
(sum((a) => a.frags) / sum((a) => a.battles)).toFixed(2),
|
||||
],
|
||||
[
|
||||
'Spots per battle',
|
||||
(sum((a) => a.spotted) / sum((a) => a.battles)).toFixed(2),
|
||||
],
|
||||
[
|
||||
'XP per battle',
|
||||
(sum((a) => a.xp) / sum((a) => a.battles)).toFixed(0),
|
||||
],
|
||||
[],
|
||||
[
|
||||
'Damage ratio',
|
||||
(
|
||||
sum((a) => a.damage_dealt) / sum((a) => a.damage_received)
|
||||
).toFixed(2),
|
||||
],
|
||||
[
|
||||
'Kills to death ratio',
|
||||
(
|
||||
sum((a) => a.frags) /
|
||||
sum((a) => a.battles - a.survived_battles)
|
||||
).toFixed(2),
|
||||
],
|
||||
])
|
||||
: 'No battles were played or recorded during this period.',
|
||||
),
|
||||
],
|
||||
});
|
||||
} else {
|
||||
interaction.editReply({
|
||||
embeds: [
|
||||
errorEmbed(
|
||||
'Tank not found',
|
||||
`"${markdownEscape(tankId)}" does not exist in the game.`,
|
||||
),
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
autocomplete: tanksAutocomplete,
|
||||
} satisfies CommandRegistry;
|
||||
Reference in new issue
Block a user