mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: composite stats
This commit is contained in:
1 parent
84893842e9
commit
64139e301b
27 files changed
+417
-82
No files matched your search
@@ -5,10 +5,20 @@ import {
|
|||||||
BreakdownEmbedWrapper,
|
BreakdownEmbedWrapper,
|
||||||
} from '../../../../components/TanksEmbed';
|
} from '../../../../components/TanksEmbed';
|
||||||
import { tankDefinitionsArray } from '../../../../core/blitzkit/tankDefinitions';
|
import { tankDefinitionsArray } from '../../../../core/blitzkit/tankDefinitions';
|
||||||
|
import {
|
||||||
|
CompositeStatsKey,
|
||||||
|
compositeStatsKeys,
|
||||||
|
} from '../../../../core/statistics/compositeStats/constants';
|
||||||
|
import strings from '../../../../lang/en-US.json';
|
||||||
import { EmbedConfig } from '../../../../stores/embedState';
|
import { EmbedConfig } from '../../../../stores/embedState';
|
||||||
import { EmbedItemType } from '../../../../stores/embedState/constants';
|
import { EmbedItemType } from '../../../../stores/embedState/constants';
|
||||||
import { useEmbedStateCurry } from '../../../../stores/embedState/utilities';
|
import { useEmbedStateCurry } from '../../../../stores/embedState/utilities';
|
||||||
|
|
||||||
|
const compositeStatsKeysOptions = compositeStatsKeys.map((value) => ({
|
||||||
|
label: strings.common.composite_stats[value],
|
||||||
|
value,
|
||||||
|
}));
|
||||||
|
|
||||||
export const breakdownConfig = {
|
export const breakdownConfig = {
|
||||||
showTotal: { type: EmbedItemType.Boolean, default: true, pad: true },
|
showTotal: { type: EmbedItemType.Boolean, default: true, pad: true },
|
||||||
|
|
||||||
@@ -60,14 +70,30 @@ export const breakdownConfig = {
|
|||||||
pad: true,
|
pad: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
column1Unit: { type: EmbedItemType.String, default: '' },
|
column1: {
|
||||||
column2Unit: { type: EmbedItemType.String, default: '%' },
|
type: EmbedItemType.Enum,
|
||||||
column3Unit: { type: EmbedItemType.String, default: '' },
|
default: 'cumulative_battles' satisfies CompositeStatsKey,
|
||||||
column4Unit: { type: EmbedItemType.String, default: '' },
|
options: compositeStatsKeysOptions,
|
||||||
column1Label: { type: EmbedItemType.String, default: 'Battles' },
|
},
|
||||||
column2Label: { type: EmbedItemType.String, default: 'Winrate' },
|
column2: {
|
||||||
column3Label: { type: EmbedItemType.String, default: 'WN8' },
|
type: EmbedItemType.Enum,
|
||||||
column4Label: { type: EmbedItemType.String, default: 'Damage' },
|
default: 'normalized_wins' satisfies CompositeStatsKey,
|
||||||
|
options: compositeStatsKeysOptions,
|
||||||
|
},
|
||||||
|
column3: {
|
||||||
|
type: EmbedItemType.Enum,
|
||||||
|
default: 'cumulative_wn8' satisfies CompositeStatsKey,
|
||||||
|
options: compositeStatsKeysOptions,
|
||||||
|
},
|
||||||
|
column4: {
|
||||||
|
type: EmbedItemType.Enum,
|
||||||
|
default: 'normalized_damage_dealt' satisfies CompositeStatsKey,
|
||||||
|
options: compositeStatsKeysOptions,
|
||||||
|
},
|
||||||
|
column1CustomLabel: { type: EmbedItemType.String, default: '' },
|
||||||
|
column2CustomLabel: { type: EmbedItemType.String, default: '' },
|
||||||
|
column3CustomLabel: { type: EmbedItemType.String, default: '' },
|
||||||
|
column4CustomLabel: { type: EmbedItemType.String, default: '' },
|
||||||
} satisfies EmbedConfig;
|
} satisfies EmbedConfig;
|
||||||
|
|
||||||
export function BreakdownPreview() {
|
export function BreakdownPreview() {
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Select } from '@radix-ui/themes';
|
||||||
|
import * as EmbedState from '../../../../../../stores/embedState';
|
||||||
|
import {
|
||||||
|
EmbedConfigItemType,
|
||||||
|
EmbedItemType,
|
||||||
|
} from '../../../../../../stores/embedState/constants';
|
||||||
|
import { EmbedPreviewControllerProps } from '../page';
|
||||||
|
|
||||||
|
export function Enum({
|
||||||
|
configKey,
|
||||||
|
config,
|
||||||
|
}: EmbedPreviewControllerProps & {
|
||||||
|
config: EmbedConfigItemType<EmbedItemType.Enum>;
|
||||||
|
}) {
|
||||||
|
const mutateEmbedState = EmbedState.useMutation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select.Root
|
||||||
|
value={EmbedState.use((state) => state[configKey] as string)}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateEmbedState((draft) => {
|
||||||
|
draft[configKey] = value;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
<Select.Content>
|
||||||
|
{config.options.map((option) => (
|
||||||
|
<Select.Item key={option.value} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -15,8 +15,6 @@ export function RichText({ configKey }: EmbedPreviewControllerProps) {
|
|||||||
] as EmbedConfigItemType<EmbedItemType.RichText>['default'],
|
] as EmbedConfigItemType<EmbedItemType.RichText>['default'],
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(state);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ColorControllerRaw
|
<ColorControllerRaw
|
||||||
value={state.color}
|
value={state.color}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { EmbedItemType } from '../../../../../stores/embedState/constants';
|
|||||||
import { configurations, previews } from '../../configurations';
|
import { configurations, previews } from '../../configurations';
|
||||||
import { Boolean } from './components/Boolean';
|
import { Boolean } from './components/Boolean';
|
||||||
import { Color } from './components/Color';
|
import { Color } from './components/Color';
|
||||||
|
import { Enum } from './components/Enum';
|
||||||
import { Radius } from './components/Radius';
|
import { Radius } from './components/Radius';
|
||||||
import { RichText } from './components/RichText';
|
import { RichText } from './components/RichText';
|
||||||
import { Size } from './components/Size';
|
import { Size } from './components/Size';
|
||||||
@@ -99,6 +100,12 @@ export default function Page({
|
|||||||
|
|
||||||
case EmbedItemType.RichText: {
|
case EmbedItemType.RichText: {
|
||||||
control = <RichText configKey={configKey} />;
|
control = <RichText configKey={configKey} />;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EmbedItemType.Enum: {
|
||||||
|
control = <Enum configKey={configKey} config={item} />;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { memo, use, useCallback } from 'react';
|
|||||||
import { StickyRowHeaderCell } from '../../../../components/StickyRowHeaderCell';
|
import { StickyRowHeaderCell } from '../../../../components/StickyRowHeaderCell';
|
||||||
import {
|
import {
|
||||||
averageDefinitions,
|
averageDefinitions,
|
||||||
AverageDefinitionsAllStats,
|
|
||||||
AverageDefinitionsEntryWithId,
|
AverageDefinitionsEntryWithId,
|
||||||
} from '../../../../core/blitzkit/averageDefinitions';
|
} from '../../../../core/blitzkit/averageDefinitions';
|
||||||
import { formatCompact } from '../../../../core/math/formatCompact';
|
import { formatCompact } from '../../../../core/math/formatCompact';
|
||||||
|
import { BlitzkitStats } from '../../../../core/statistics/compositeStats/constants';
|
||||||
import { useAveragesExclusionRatio } from '../../../../hooks/useAveragesExclusionRatio';
|
import { useAveragesExclusionRatio } from '../../../../hooks/useAveragesExclusionRatio';
|
||||||
import * as TankPerformancePersistent from '../../../../stores/tankPerformancePersistent';
|
import * as TankPerformancePersistent from '../../../../stores/tankPerformancePersistent';
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ export const Total = memo<TotalProps>(
|
|||||||
);
|
);
|
||||||
const ratio = useAveragesExclusionRatio();
|
const ratio = useAveragesExclusionRatio();
|
||||||
const sum = useCallback(
|
const sum = useCallback(
|
||||||
(slice: (tank: AverageDefinitionsAllStats) => number) => {
|
(slice: (tank: BlitzkitStats) => number) => {
|
||||||
return tanks.reduce(
|
return tanks.reduce(
|
||||||
(acc, tank) => acc + tank.samples.total * slice(tank.mu),
|
(acc, tank) => acc + tank.samples.total * slice(tank.mu),
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import * as Breakdown from '../../components/Breakdown';
|
|||||||
import CommandWrapper from '../../components/CommandWrapper';
|
import CommandWrapper from '../../components/CommandWrapper';
|
||||||
import NoData from '../../components/NoData';
|
import NoData from '../../components/NoData';
|
||||||
import TitleBar from '../../components/TitleBar';
|
import TitleBar from '../../components/TitleBar';
|
||||||
import { AllStats, getAccountInfo } from '../../core/blitz/getAccountInfo';
|
import { getAccountInfo } from '../../core/blitz/getAccountInfo';
|
||||||
import { getClanAccountInfo } from '../../core/blitz/getClanAccountInfo';
|
import { getClanAccountInfo } from '../../core/blitz/getClanAccountInfo';
|
||||||
import getTankStats from '../../core/blitz/getTankStats';
|
import getTankStats from '../../core/blitz/getTankStats';
|
||||||
import { filtersToDescription } from '../../core/blitzkit/filtersToDescription';
|
import { filtersToDescription } from '../../core/blitzkit/filtersToDescription';
|
||||||
@@ -18,6 +18,7 @@ import { ResolvedPeriod } from '../../core/discord/resolvePeriodFromCommand';
|
|||||||
import { ResolvedPlayer } from '../../core/discord/resolvePlayerFromCommand';
|
import { ResolvedPlayer } from '../../core/discord/resolvePlayerFromCommand';
|
||||||
import { translator } from '../../core/localization/translator';
|
import { translator } from '../../core/localization/translator';
|
||||||
import calculateWN8 from '../../core/statistics/calculateWN8';
|
import calculateWN8 from '../../core/statistics/calculateWN8';
|
||||||
|
import { BlitzStats } from '../../core/statistics/compositeStats/constants';
|
||||||
import { StatFilters, filterStats } from '../../core/statistics/filterStats';
|
import { StatFilters, filterStats } from '../../core/statistics/filterStats';
|
||||||
import getWN8Percentile from '../../core/statistics/getWN8Percentile';
|
import getWN8Percentile from '../../core/statistics/getWN8Percentile';
|
||||||
import { UserError } from '../../hooks/userError';
|
import { UserError } from '../../hooks/userError';
|
||||||
@@ -40,8 +41,8 @@ export async function renderBreakdown(
|
|||||||
const clanData = await getClanAccountInfo(region, id, ['clan']);
|
const clanData = await getClanAccountInfo(region, id, ['clan']);
|
||||||
const tankStats = await getTankStats(region, id);
|
const tankStats = await getTankStats(region, id);
|
||||||
const filterDescriptions = await filtersToDescription(filters, locale);
|
const filterDescriptions = await filtersToDescription(filters, locale);
|
||||||
const orderedCurrentStats: AllStats[] = [];
|
const orderedCurrentStats: BlitzStats[] = [];
|
||||||
const orderedCareerStats: AllStats[] = [];
|
const orderedCareerStats: BlitzStats[] = [];
|
||||||
const orderedCurrentWN8: (number | undefined)[] = [];
|
const orderedCurrentWN8: (number | undefined)[] = [];
|
||||||
const orderedCareerWN8: (number | undefined)[] = [];
|
const orderedCareerWN8: (number | undefined)[] = [];
|
||||||
const orderedCareerWN8Full: (number | undefined)[] = [];
|
const orderedCareerWN8Full: (number | undefined)[] = [];
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { AllStats, SupplementaryStats } from '../../core/blitz/getAccountInfo';
|
import { SupplementaryStats } from '../../core/blitz/getAccountInfo';
|
||||||
import { translator } from '../../core/localization/translator';
|
import { translator } from '../../core/localization/translator';
|
||||||
import isNumber from '../../core/math/isNumber';
|
import isNumber from '../../core/math/isNumber';
|
||||||
|
import { BlitzStats } from '../../core/statistics/compositeStats/constants';
|
||||||
import getWN8Percentile from '../../core/statistics/getWN8Percentile';
|
import getWN8Percentile from '../../core/statistics/getWN8Percentile';
|
||||||
import { Card } from './components/Card';
|
import { Card } from './components/Card';
|
||||||
import { Root } from './components/Root';
|
import { Root } from './components/Root';
|
||||||
import { Row } from './components/Row';
|
import { Row } from './components/Row';
|
||||||
|
|
||||||
interface GenericAllStatsProps {
|
interface GenericAllStatsProps {
|
||||||
stats: AllStats;
|
stats: BlitzStats;
|
||||||
supplementaryStats?: SupplementaryStats;
|
supplementaryStats?: SupplementaryStats;
|
||||||
locale: Locale;
|
locale: Locale;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import { ReactNode } from 'react';
|
|||||||
import { breakdownConfig } from '../app/tools/embed/configurations/breakdown';
|
import { breakdownConfig } from '../app/tools/embed/configurations/breakdown';
|
||||||
import { toRadiusVar } from '../app/tools/embed/utilities';
|
import { toRadiusVar } from '../app/tools/embed/utilities';
|
||||||
import { TankDefinition } from '../core/blitzkit/tankDefinitions';
|
import { TankDefinition } from '../core/blitzkit/tankDefinitions';
|
||||||
|
import { previewCompositeStat } from '../core/statistics/compositeStats';
|
||||||
|
import { CompositeStatsKey } from '../core/statistics/compositeStats/constants';
|
||||||
|
import strings from '../lang/en-US.json';
|
||||||
import { useEmbedStateCurry } from '../stores/embedState/utilities';
|
import { useEmbedStateCurry } from '../stores/embedState/utilities';
|
||||||
import { ClassHeavy } from './ClassIcon/components/ClassHeavy';
|
import { ClassHeavy } from './ClassIcon/components/ClassHeavy';
|
||||||
import { ClassLight } from './ClassIcon/components/ClassLight';
|
import { ClassLight } from './ClassIcon/components/ClassLight';
|
||||||
@@ -97,6 +100,8 @@ export function BreakdownEmbedCard({ tank }: BreakdownEmbedCardProps) {
|
|||||||
<Flex p={useState('cardBodyPadding')}>
|
<Flex p={useState('cardBodyPadding')}>
|
||||||
{times(4, (index) => {
|
{times(4, (index) => {
|
||||||
const column = (index + 1) as 1 | 2 | 3 | 4;
|
const column = (index + 1) as 1 | 2 | 3 | 4;
|
||||||
|
const columnState = useState(`column${column}`) as CompositeStatsKey;
|
||||||
|
const customLabel = useState(`column${column}CustomLabel`);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
@@ -106,10 +111,12 @@ export function BreakdownEmbedCard({ tank }: BreakdownEmbedCardProps) {
|
|||||||
flexGrow="1"
|
flexGrow="1"
|
||||||
>
|
>
|
||||||
<Text {...useRichText('columnValue')}>
|
<Text {...useRichText('columnValue')}>
|
||||||
70{useState(`column${column}Unit`)}
|
{previewCompositeStat(columnState)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text {...useRichText('columnLabel')}>
|
<Text {...useRichText('columnLabel')}>
|
||||||
{useState(`column${column}Label`)}
|
{customLabel.length === 0
|
||||||
|
? strings.common.composite_stats[columnState]
|
||||||
|
: customLabel}
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import calculateWN8 from '../statistics/calculateWN8';
|
import calculateWN8 from '../statistics/calculateWN8';
|
||||||
import { AllStats } from './getAccountInfo';
|
import { BlitzStats } from '../statistics/compositeStats/constants';
|
||||||
|
|
||||||
export type Stat = keyof ReturnType<typeof generateStats>;
|
export type Stat = keyof ReturnType<typeof generateStats>;
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ export const STAT_NAMES: Record<Stat, string> = {
|
|||||||
|
|
||||||
export const STAT_KEYS = Object.keys(STAT_NAMES) as Stat[];
|
export const STAT_KEYS = Object.keys(STAT_NAMES) as Stat[];
|
||||||
|
|
||||||
export function generateStats(s: AllStats, e?: AllStats) {
|
export function generateStats(s: BlitzStats, e?: BlitzStats) {
|
||||||
return {
|
return {
|
||||||
battles: s.battles,
|
battles: s.battles,
|
||||||
wins: s.wins,
|
wins: s.wins,
|
||||||
|
|||||||
@@ -1,27 +1,8 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
|
import { BlitzStats } from '../statistics/compositeStats/constants';
|
||||||
import fetchBlitz, { FetchBlitzParams } from './fetchBlitz';
|
import fetchBlitz, { FetchBlitzParams } from './fetchBlitz';
|
||||||
import { normalizeIds } from './normalizeIds';
|
import { normalizeIds } from './normalizeIds';
|
||||||
|
|
||||||
export interface AllStats {
|
|
||||||
spotted: number;
|
|
||||||
hits: number;
|
|
||||||
frags: number;
|
|
||||||
max_xp: number;
|
|
||||||
wins: number;
|
|
||||||
losses: number;
|
|
||||||
capture_points: number;
|
|
||||||
battles: number;
|
|
||||||
damage_dealt: number;
|
|
||||||
damage_received: number;
|
|
||||||
max_frags: number;
|
|
||||||
shots: number;
|
|
||||||
frags8p: number;
|
|
||||||
xp: number;
|
|
||||||
win_and_survived: number;
|
|
||||||
survived_battles: number;
|
|
||||||
dropped_capture_points: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SupplementaryStats {
|
export interface SupplementaryStats {
|
||||||
WN8?: number;
|
WN8?: number;
|
||||||
tier?: number;
|
tier?: number;
|
||||||
@@ -79,7 +60,7 @@ export interface IndividualAccountInfo {
|
|||||||
last_battle_time: number;
|
last_battle_time: number;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
statistics: {
|
statistics: {
|
||||||
all: AllStats;
|
all: BlitzStats;
|
||||||
clan: ClanStats;
|
clan: ClanStats;
|
||||||
rating?: RatingStats;
|
rating?: RatingStats;
|
||||||
frags: null | number;
|
frags: null | number;
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { AverageDefinitionsAllStats, Samples } from '.';
|
import { Samples } from '.';
|
||||||
import { emptyAllStats } from '../../blitzstars/getStatsInPeriod/constants';
|
import { emptyAllStats } from '../../blitzstars/getStatsInPeriod/constants';
|
||||||
|
import { BlitzkitStats } from '../../statistics/compositeStats/constants';
|
||||||
|
|
||||||
export const emptyAverageDefinitionsAllStats: AverageDefinitionsAllStats = {
|
export const emptyAverageDefinitionsAllStats: BlitzkitStats = {
|
||||||
...emptyAllStats,
|
...emptyAllStats,
|
||||||
battle_life_time: 0,
|
battle_life_time: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const averageDefinitionsAllStatsKeys = Object.keys(
|
export const averageDefinitionsAllStatsKeys = Object.keys(
|
||||||
emptyAverageDefinitionsAllStats,
|
emptyAverageDefinitionsAllStats,
|
||||||
) as (keyof AverageDefinitionsAllStats)[];
|
) as (keyof BlitzkitStats)[];
|
||||||
|
|
||||||
export const emptySamples: Samples = {
|
export const emptySamples: Samples = {
|
||||||
d_1: 0,
|
d_1: 0,
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
import { AllStats } from '../../blitz/getAccountInfo';
|
|
||||||
import { decode } from '../../protobuf/decode';
|
import { decode } from '../../protobuf/decode';
|
||||||
|
import { BlitzkitStats } from '../../statistics/compositeStats/constants';
|
||||||
import { asset } from '../asset';
|
import { asset } from '../asset';
|
||||||
|
|
||||||
export interface AverageDefinitionsAllStats extends AllStats {
|
|
||||||
battle_life_time: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AverageDefinitionsEntry {
|
export interface AverageDefinitionsEntry {
|
||||||
mu: AverageDefinitionsAllStats;
|
mu: BlitzkitStats;
|
||||||
sigma: AverageDefinitionsAllStats;
|
sigma: BlitzkitStats;
|
||||||
r: AverageDefinitionsAllStats;
|
r: BlitzkitStats;
|
||||||
samples: Samples;
|
samples: Samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AverageDefinitionsEntrySubPartial {
|
export interface AverageDefinitionsEntrySubPartial {
|
||||||
mu: Partial<AverageDefinitionsAllStats>;
|
mu: Partial<BlitzkitStats>;
|
||||||
sigma: Partial<AverageDefinitionsAllStats>;
|
sigma: Partial<BlitzkitStats>;
|
||||||
r: Partial<AverageDefinitionsAllStats>;
|
r: Partial<BlitzkitStats>;
|
||||||
samples: Samples;
|
samples: Samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { AllStats } from '../blitz/getAccountInfo';
|
import { BlitzStats } from '../statistics/compositeStats/constants';
|
||||||
|
|
||||||
interface IndividualPlayerStats {
|
interface IndividualPlayerStats {
|
||||||
clan: { clan_id: number; name: string; tag: string };
|
clan: { clan_id: number; name: string; tag: string };
|
||||||
statistics: {
|
statistics: {
|
||||||
all: AllStats;
|
all: BlitzStats;
|
||||||
wn8: number;
|
wn8: number;
|
||||||
wn7: number;
|
wn7: number;
|
||||||
average_tier: number;
|
average_tier: number;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AllStats } from '../../blitz/getAccountInfo';
|
import { BlitzStats } from '../../statistics/compositeStats/constants';
|
||||||
|
|
||||||
export const emptyAllStats: AllStats = {
|
export const emptyAllStats: BlitzStats = {
|
||||||
battles: 0,
|
battles: 0,
|
||||||
capture_points: 0,
|
capture_points: 0,
|
||||||
damage_dealt: 0,
|
damage_dealt: 0,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { Region } from '../../../constants/regions';
|
import { Region } from '../../../constants/regions';
|
||||||
import { AllStats } from '../../blitz/getAccountInfo';
|
|
||||||
import getTankHistories, {
|
import getTankHistories, {
|
||||||
TankHistories,
|
TankHistories,
|
||||||
TankHistoryRaw,
|
TankHistoryRaw,
|
||||||
} from '../../blitzkit/getTankHistories';
|
} from '../../blitzkit/getTankHistories';
|
||||||
|
import { BlitzStats } from '../../statistics/compositeStats/constants';
|
||||||
import { emptyAllStats } from './constants';
|
import { emptyAllStats } from './constants';
|
||||||
|
|
||||||
const emptyTankHistoryNode: TankHistoryRaw = {
|
const emptyTankHistoryNode: TankHistoryRaw = {
|
||||||
@@ -17,7 +17,7 @@ const emptyTankHistoryNode: TankHistoryRaw = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface DiffedTankStats {
|
export interface DiffedTankStats {
|
||||||
diff: Record<number, AllStats>;
|
diff: Record<number, BlitzStats>;
|
||||||
order: number[];
|
order: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ export default async function getStatsInPeriod(
|
|||||||
const playedTanks: number[] = [];
|
const playedTanks: number[] = [];
|
||||||
|
|
||||||
// fetch history node right before "start" and right before "end"
|
// fetch history node right before "start" and right before "end"
|
||||||
const diff: Record<number, AllStats> = {};
|
const diff: Record<number, BlitzStats> = {};
|
||||||
inRangeTanks.forEach((tankId) => {
|
inRangeTanks.forEach((tankId) => {
|
||||||
const sortedHistory = tankSortedHistory[tankId];
|
const sortedHistory = tankSortedHistory[tankId];
|
||||||
const previousIndex =
|
const previousIndex =
|
||||||
@@ -65,7 +65,7 @@ export default async function getStatsInPeriod(
|
|||||||
const latest =
|
const latest =
|
||||||
sortedHistory[latestIndex] ?? sortedHistory[sortedHistory.length - 1];
|
sortedHistory[latestIndex] ?? sortedHistory[sortedHistory.length - 1];
|
||||||
|
|
||||||
function d(get: (allStats: AllStats) => number) {
|
function d(get: (allStats: BlitzStats) => number) {
|
||||||
return get(latest.all) - get(previous.all);
|
return get(latest.all) - get(previous.all);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AllStats } from '../blitz/getAccountInfo';
|
|
||||||
import { context } from '../blitzkit/context';
|
import { context } from '../blitzkit/context';
|
||||||
import { tankDefinitions } from '../blitzkit/tankDefinitions';
|
import { tankDefinitions } from '../blitzkit/tankDefinitions';
|
||||||
|
import { BlitzStats } from '../statistics/compositeStats/constants';
|
||||||
|
|
||||||
interface SpecialStats {
|
interface SpecialStats {
|
||||||
winrate: number;
|
winrate: number;
|
||||||
@@ -71,7 +71,7 @@ export interface IndividualTankAverage {
|
|||||||
total_battle_life_time: number;
|
total_battle_life_time: number;
|
||||||
number_of_players: number;
|
number_of_players: number;
|
||||||
tank_id: number;
|
tank_id: number;
|
||||||
all: AllStats;
|
all: BlitzStats;
|
||||||
special: SpecialStats;
|
special: SpecialStats;
|
||||||
percentiles: SpecialPercentiles;
|
percentiles: SpecialPercentiles;
|
||||||
percentiles_player_count: number;
|
percentiles_player_count: number;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AllStats } from '../blitz/getAccountInfo';
|
import { BlitzStats } from './compositeStats/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formula from https://web.archive.org/web/20190105064817/http://wiki.wnefficiency.net/pages/WN8
|
* Formula from https://web.archive.org/web/20190105064817/http://wiki.wnefficiency.net/pages/WN8
|
||||||
@@ -7,7 +7,7 @@ import { AllStats } from '../blitz/getAccountInfo';
|
|||||||
* @param average what the player in question performs like
|
* @param average what the player in question performs like
|
||||||
*/
|
*/
|
||||||
export default function calculateWN8(
|
export default function calculateWN8(
|
||||||
expected: AllStats,
|
expected: BlitzStats,
|
||||||
average: {
|
average: {
|
||||||
damage_dealt: number;
|
damage_dealt: number;
|
||||||
battles: number;
|
battles: number;
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
export const blitzStatsKeys = [
|
||||||
|
'battles',
|
||||||
|
'capture_points',
|
||||||
|
'damage_dealt',
|
||||||
|
'damage_received',
|
||||||
|
'dropped_capture_points',
|
||||||
|
'frags',
|
||||||
|
'frags8p',
|
||||||
|
'hits',
|
||||||
|
'losses',
|
||||||
|
'max_frags',
|
||||||
|
'max_xp',
|
||||||
|
'shots',
|
||||||
|
'spotted',
|
||||||
|
'survived_battles',
|
||||||
|
'win_and_survived',
|
||||||
|
'wins',
|
||||||
|
'xp',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const blitzPlayerStatsKeys = [
|
||||||
|
...blitzStatsKeys,
|
||||||
|
'max_frags_tank_id',
|
||||||
|
'max_xp_tank_id',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const compositeStatsKeysBase = [
|
||||||
|
...blitzStatsKeys,
|
||||||
|
'damage_ratio',
|
||||||
|
'kills_to_death_ratio',
|
||||||
|
'accuracy',
|
||||||
|
'inaccuracy',
|
||||||
|
'misses',
|
||||||
|
'deaths',
|
||||||
|
'wn8',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const normalizedBlitzStatsKeys = [
|
||||||
|
// 'battles', will result in 1
|
||||||
|
// 'capture_points', not all battles are encounter mode
|
||||||
|
'damage_dealt',
|
||||||
|
'damage_received',
|
||||||
|
// 'dropped_capture_points', not all battles are encounter mode
|
||||||
|
'frags',
|
||||||
|
// 'frags8p', null on most tanks and not all battles have tier 8 and above tanks
|
||||||
|
'hits',
|
||||||
|
'losses',
|
||||||
|
// 'max_frags', counts the max; not cumulative
|
||||||
|
// 'max_xp', counts the max; not cumulative
|
||||||
|
'shots',
|
||||||
|
'spotted',
|
||||||
|
'survived_battles',
|
||||||
|
'win_and_survived',
|
||||||
|
'wins',
|
||||||
|
'xp',
|
||||||
|
] satisfies (typeof blitzStatsKeys)[number][];
|
||||||
|
|
||||||
|
const cumulativeBlitzStatsKeys = [
|
||||||
|
'battles',
|
||||||
|
'capture_points',
|
||||||
|
'damage_dealt',
|
||||||
|
'damage_received',
|
||||||
|
'dropped_capture_points',
|
||||||
|
'frags',
|
||||||
|
// 'frags8p', once again, just a painful metric
|
||||||
|
'hits',
|
||||||
|
'losses',
|
||||||
|
// 'max_frags', static, not cumulative
|
||||||
|
// 'max_xp', static, not cumulative
|
||||||
|
'shots',
|
||||||
|
'spotted',
|
||||||
|
'survived_battles',
|
||||||
|
'win_and_survived',
|
||||||
|
'wins',
|
||||||
|
'xp',
|
||||||
|
] satisfies (typeof blitzStatsKeys)[number][];
|
||||||
|
|
||||||
|
const normalizedCompositeStatsKeys = [
|
||||||
|
...normalizedBlitzStatsKeys,
|
||||||
|
// 'damage_ratio', is a dimensionless ratio
|
||||||
|
// 'kills_to_death_ratio', also a dimensionless ratio
|
||||||
|
// 'accuracy', dimensionless ratio
|
||||||
|
// 'inaccuracy', dimensionless ratio
|
||||||
|
'misses',
|
||||||
|
'deaths',
|
||||||
|
// 'wn8', is based on a sample of all battles so doesn't make sense to normalize
|
||||||
|
] satisfies (typeof compositeStatsKeysBase)[number][];
|
||||||
|
|
||||||
|
const cumulativeCompositeStatsKeys = [
|
||||||
|
...cumulativeBlitzStatsKeys,
|
||||||
|
'damage_ratio',
|
||||||
|
'kills_to_death_ratio',
|
||||||
|
'accuracy',
|
||||||
|
'inaccuracy',
|
||||||
|
'misses',
|
||||||
|
'deaths',
|
||||||
|
'wn8',
|
||||||
|
] satisfies (typeof compositeStatsKeysBase)[number][];
|
||||||
|
|
||||||
|
export const compositeStatsKeys = [
|
||||||
|
...normalizedCompositeStatsKeys.map((key) => `normalized_${key}`),
|
||||||
|
...cumulativeCompositeStatsKeys.map((key) => `cumulative_${key}`),
|
||||||
|
] as CompositeStatsKey[];
|
||||||
|
|
||||||
|
type BlitzStatsKey = (typeof blitzStatsKeys)[number];
|
||||||
|
export type BlitzStats = Record<BlitzStatsKey, number>;
|
||||||
|
|
||||||
|
type BlitzPlayerStatsKey = (typeof blitzPlayerStatsKeys)[number];
|
||||||
|
export type BlitzPlayerStats = Record<BlitzPlayerStatsKey, number>;
|
||||||
|
|
||||||
|
export type CompositeStatsKey =
|
||||||
|
| `normalized_${(typeof normalizedCompositeStatsKeys)[number]}`
|
||||||
|
| `cumulative_${(typeof cumulativeCompositeStatsKeys)[number]}`;
|
||||||
|
export type CompositeStats = Record<CompositeStatsKey, number>;
|
||||||
|
|
||||||
|
export const compositeStatsFormatting: {
|
||||||
|
[Key in CompositeStatsKey]: {
|
||||||
|
unit?: string;
|
||||||
|
fixed: number;
|
||||||
|
coefficient?: number;
|
||||||
|
preview: number;
|
||||||
|
localeFormat?: boolean;
|
||||||
|
};
|
||||||
|
} = {
|
||||||
|
normalized_damage_dealt: { fixed: 0, preview: 3246, localeFormat: true },
|
||||||
|
normalized_damage_received: { fixed: 0, preview: 966, localeFormat: true },
|
||||||
|
normalized_deaths: { fixed: 0, unit: '%', coefficient: 100, preview: 0.09 },
|
||||||
|
normalized_frags: { fixed: 2, preview: 2.1 },
|
||||||
|
normalized_hits: { fixed: 2, preview: 12.33 },
|
||||||
|
normalized_losses: { fixed: 0, unit: '%', coefficient: 100, preview: 0.3 },
|
||||||
|
normalized_misses: { fixed: 2, preview: 1.02 },
|
||||||
|
normalized_shots: { fixed: 2, preview: 14.54 },
|
||||||
|
normalized_spotted: { fixed: 2, preview: 2.02 },
|
||||||
|
normalized_survived_battles: {
|
||||||
|
fixed: 0,
|
||||||
|
unit: '%',
|
||||||
|
coefficient: 100,
|
||||||
|
preview: 0.65,
|
||||||
|
},
|
||||||
|
normalized_win_and_survived: {
|
||||||
|
fixed: 0,
|
||||||
|
unit: '%',
|
||||||
|
coefficient: 100,
|
||||||
|
preview: 0.59,
|
||||||
|
},
|
||||||
|
normalized_wins: { fixed: 0, unit: '%', coefficient: 100, preview: 0.72 },
|
||||||
|
normalized_xp: { fixed: 0, preview: 982, localeFormat: true },
|
||||||
|
|
||||||
|
cumulative_accuracy: { fixed: 0, unit: '%', coefficient: 100, preview: 0.91 },
|
||||||
|
cumulative_battles: { fixed: 0, preview: 12 },
|
||||||
|
cumulative_capture_points: { fixed: 2, preview: 0.12 },
|
||||||
|
cumulative_damage_dealt: { fixed: 0, preview: 45023, localeFormat: true },
|
||||||
|
cumulative_damage_ratio: { fixed: 2, preview: 2.83 },
|
||||||
|
cumulative_damage_received: { fixed: 0, preview: 10093, localeFormat: true },
|
||||||
|
cumulative_deaths: { fixed: 0, preview: 2 },
|
||||||
|
cumulative_dropped_capture_points: { fixed: 2, preview: 15 },
|
||||||
|
cumulative_frags: { fixed: 0, preview: 26 },
|
||||||
|
cumulative_hits: { fixed: 0, preview: 480 },
|
||||||
|
cumulative_inaccuracy: {
|
||||||
|
fixed: 0,
|
||||||
|
unit: '%',
|
||||||
|
coefficient: 100,
|
||||||
|
preview: 0.08,
|
||||||
|
},
|
||||||
|
cumulative_kills_to_death_ratio: { fixed: 2, preview: 2.3 },
|
||||||
|
cumulative_losses: { fixed: 0, preview: 3 },
|
||||||
|
cumulative_misses: { fixed: 0, preview: 13 },
|
||||||
|
cumulative_shots: { fixed: 0, preview: 309 },
|
||||||
|
cumulative_spotted: { fixed: 0, preview: 99 },
|
||||||
|
cumulative_survived_battles: { fixed: 0, preview: 10 },
|
||||||
|
cumulative_win_and_survived: { fixed: 0, preview: 9 },
|
||||||
|
cumulative_wins: { fixed: 0, preview: 8 },
|
||||||
|
cumulative_xp: { fixed: 0, preview: 19403, localeFormat: true },
|
||||||
|
cumulative_wn8: { fixed: 0, preview: 3103, localeFormat: true },
|
||||||
|
};
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import calculateWN8 from '../calculateWN8';
|
||||||
|
import {
|
||||||
|
BlitzStats,
|
||||||
|
CompositeStats,
|
||||||
|
compositeStatsFormatting,
|
||||||
|
CompositeStatsKey,
|
||||||
|
} from './constants';
|
||||||
|
|
||||||
|
export function compositeStats(stats: BlitzStats, average: BlitzStats) {
|
||||||
|
return {
|
||||||
|
normalized_damage_dealt: stats.damage_dealt / stats.battles,
|
||||||
|
normalized_damage_received: stats.damage_received / stats.battles,
|
||||||
|
normalized_deaths: (stats.battles - stats.survived_battles) / stats.battles,
|
||||||
|
normalized_frags: stats.frags / stats.battles,
|
||||||
|
normalized_hits: stats.hits / stats.battles,
|
||||||
|
normalized_losses: stats.losses / stats.battles,
|
||||||
|
normalized_misses: (stats.shots - stats.hits) / stats.battles,
|
||||||
|
normalized_shots: stats.shots / stats.battles,
|
||||||
|
normalized_spotted: stats.spotted / stats.battles,
|
||||||
|
normalized_survived_battles: stats.survived_battles / stats.battles,
|
||||||
|
normalized_win_and_survived: stats.win_and_survived / stats.battles,
|
||||||
|
normalized_wins: stats.wins / stats.battles,
|
||||||
|
normalized_xp: stats.xp / stats.battles,
|
||||||
|
|
||||||
|
cumulative_accuracy: stats.hits / stats.shots,
|
||||||
|
cumulative_battles: stats.battles,
|
||||||
|
cumulative_capture_points: stats.capture_points,
|
||||||
|
cumulative_damage_dealt: stats.damage_dealt,
|
||||||
|
cumulative_damage_ratio: stats.damage_dealt / stats.damage_received,
|
||||||
|
cumulative_damage_received: stats.damage_received,
|
||||||
|
cumulative_deaths: stats.battles - stats.survived_battles,
|
||||||
|
cumulative_dropped_capture_points: stats.dropped_capture_points,
|
||||||
|
cumulative_frags: stats.frags,
|
||||||
|
cumulative_hits: stats.hits,
|
||||||
|
cumulative_inaccuracy: (stats.shots - stats.hits) / stats.shots,
|
||||||
|
cumulative_kills_to_death_ratio:
|
||||||
|
stats.frags / (stats.battles - stats.survived_battles),
|
||||||
|
cumulative_losses: stats.losses,
|
||||||
|
cumulative_misses: stats.shots - stats.hits,
|
||||||
|
cumulative_shots: stats.shots,
|
||||||
|
cumulative_spotted: stats.spotted,
|
||||||
|
cumulative_survived_battles: stats.survived_battles,
|
||||||
|
cumulative_win_and_survived: stats.win_and_survived,
|
||||||
|
cumulative_wins: stats.wins,
|
||||||
|
cumulative_xp: stats.xp,
|
||||||
|
cumulative_wn8: calculateWN8(average, stats),
|
||||||
|
} satisfies CompositeStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatCompositeStat(value: number, key: CompositeStatsKey) {
|
||||||
|
const formatting = compositeStatsFormatting[key];
|
||||||
|
const resolvedValue = (formatting.coefficient ?? 1) * value;
|
||||||
|
return `${formatting.localeFormat ? resolvedValue.toLocaleString() : resolvedValue.toFixed(formatting.fixed)}${formatting.unit ?? ''}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function previewCompositeStat(key: CompositeStatsKey) {
|
||||||
|
const { preview } = compositeStatsFormatting[key];
|
||||||
|
return formatCompositeStat(preview, key);
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { TierWeightsRecord } from '../../components/TierWeights';
|
import { TierWeightsRecord } from '../../components/TierWeights';
|
||||||
import { AllStats } from '../blitz/getAccountInfo';
|
|
||||||
import { tankDefinitions } from '../blitzkit/tankDefinitions';
|
import { tankDefinitions } from '../blitzkit/tankDefinitions';
|
||||||
|
import { BlitzStats } from './compositeStats/constants';
|
||||||
|
|
||||||
export async function getTierWeights(
|
export async function getTierWeights(
|
||||||
stats: Record<number, AllStats>,
|
stats: Record<number, BlitzStats>,
|
||||||
order: number[] = Object.keys(stats).map(parseInt),
|
order: number[] = Object.keys(stats).map(parseInt),
|
||||||
) {
|
) {
|
||||||
const awaitedTankDefinitions = await tankDefinitions;
|
const awaitedTankDefinitions = await tankDefinitions;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { AllStats } from '../blitz/getAccountInfo';
|
|
||||||
import { emptyAllStats } from '../blitzstars/getStatsInPeriod/constants';
|
import { emptyAllStats } from '../blitzstars/getStatsInPeriod/constants';
|
||||||
|
import { BlitzStats } from './compositeStats/constants';
|
||||||
|
|
||||||
export default function sumStats(allStatsCollection: AllStats[]) {
|
export default function sumStats(allStatsCollection: BlitzStats[]) {
|
||||||
return allStatsCollection.reduce((accumulated, current) => {
|
return allStatsCollection.reduce((accumulated, current) => {
|
||||||
function sum(value: (allStats: AllStats) => number) {
|
function sum(value: (allStats: BlitzStats) => number) {
|
||||||
return value(accumulated) + value(current);
|
return value(accumulated) + value(current);
|
||||||
}
|
}
|
||||||
function max(value: (allStats: AllStats) => number) {
|
function max(value: (allStats: BlitzStats) => number) {
|
||||||
return Math.max(value(accumulated), value(current));
|
return Math.max(value(accumulated), value(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,6 +28,6 @@ export default function sumStats(allStatsCollection: AllStats[]) {
|
|||||||
survived_battles: sum((a) => a.survived_battles),
|
survived_battles: sum((a) => a.survived_battles),
|
||||||
win_and_survived: sum((a) => a.win_and_survived),
|
win_and_survived: sum((a) => a.win_and_survived),
|
||||||
xp: sum((a) => a.xp),
|
xp: sum((a) => a.xp),
|
||||||
} satisfies AllStats;
|
} satisfies BlitzStats;
|
||||||
}, emptyAllStats);
|
}, emptyAllStats);
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { times } from 'lodash';
|
import { times } from 'lodash';
|
||||||
import { IndividualTankStats } from '../../types/tanksStats';
|
import { IndividualTankStats } from '../../types/tanksStats';
|
||||||
import { AllStats } from '../blitz/getAccountInfo';
|
import { BlitzStats } from '../statistics/compositeStats/constants';
|
||||||
import { ReadStream, WriteStream } from './buffer';
|
import { ReadStream, WriteStream } from './buffer';
|
||||||
|
|
||||||
export interface BlitzkitTankStats extends AllStats {
|
export interface BlitzkitTankStats extends BlitzStats {
|
||||||
id: number;
|
id: number;
|
||||||
battle_life_time: number;
|
battle_life_time: number;
|
||||||
last_battle_time: number;
|
last_battle_time: number;
|
||||||
|
|||||||
+39
-1
@@ -83,6 +83,44 @@
|
|||||||
"gold": "Gold",
|
"gold": "Gold",
|
||||||
"silver": "Silver",
|
"silver": "Silver",
|
||||||
"bronze": "Bronze"
|
"bronze": "Bronze"
|
||||||
|
},
|
||||||
|
|
||||||
|
"composite_stats": {
|
||||||
|
"normalized_damage_dealt": "Damage",
|
||||||
|
"normalized_damage_received": "Damage received",
|
||||||
|
"normalized_deaths": "Deathrate",
|
||||||
|
"normalized_frags": "Kills",
|
||||||
|
"normalized_hits": "Hits",
|
||||||
|
"normalized_losses": "Lossrate",
|
||||||
|
"normalized_misses": "Misses",
|
||||||
|
"normalized_shots": "Shots",
|
||||||
|
"normalized_spotted": "Spots",
|
||||||
|
"normalized_survived_battles": "Survival rate",
|
||||||
|
"normalized_win_and_survived": "Winning and surviving rate",
|
||||||
|
"normalized_wins": "Winrate",
|
||||||
|
"normalized_xp": "XP",
|
||||||
|
|
||||||
|
"cumulative_accuracy": "Accuracy",
|
||||||
|
"cumulative_battles": "Battles",
|
||||||
|
"cumulative_capture_points": "Total encounter points",
|
||||||
|
"cumulative_damage_dealt": "Total damage",
|
||||||
|
"cumulative_damage_ratio": "Damage ratio",
|
||||||
|
"cumulative_damage_received": "Total damage received",
|
||||||
|
"cumulative_deaths": "Total deaths",
|
||||||
|
"cumulative_dropped_capture_points": "Total dropped encounter points",
|
||||||
|
"cumulative_frags": "Total kills",
|
||||||
|
"cumulative_hits": "Total hits",
|
||||||
|
"cumulative_inaccuracy": "Inaccuracy",
|
||||||
|
"cumulative_kills_to_death_ratio": "Kills to death ratio",
|
||||||
|
"cumulative_losses": "Losses",
|
||||||
|
"cumulative_misses": "Total misses",
|
||||||
|
"cumulative_shots": "Total shots",
|
||||||
|
"cumulative_spotted": "Total spots",
|
||||||
|
"cumulative_survived_battles": "Survived battles",
|
||||||
|
"cumulative_win_and_survived": "Won and survived battles",
|
||||||
|
"cumulative_wins": "Wins",
|
||||||
|
"cumulative_xp": "Total XP",
|
||||||
|
"cumulative_wn8": "WN8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -573,7 +611,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"rating": {
|
"rating": {
|
||||||
"$": "rating-session",
|
"$": "rating",
|
||||||
"description": "Rating player's statistics",
|
"description": "Rating player's statistics",
|
||||||
|
|
||||||
"subcommands": {
|
"subcommands": {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export enum EmbedItemType {
|
|||||||
RichText,
|
RichText,
|
||||||
Boolean,
|
Boolean,
|
||||||
Slider,
|
Slider,
|
||||||
|
Enum,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const radixGrays = [
|
export const radixGrays = [
|
||||||
|
|||||||
@@ -73,6 +73,14 @@ export type EmbedConfigItem = (
|
|||||||
weight: RadixTextWeight;
|
weight: RadixTextWeight;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: EmbedItemType.Enum;
|
||||||
|
default: string;
|
||||||
|
options: {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
) & {
|
) & {
|
||||||
pad?: boolean;
|
pad?: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// a cleaner simplification of Blitz Stars' histories because it's a mess there
|
// a cleaner simplification of Blitz Stars' histories because it's a mess there
|
||||||
|
|
||||||
import { AllStats } from '../core/blitz/getAccountInfo';
|
import { BlitzStats } from '../core/statistics/compositeStats/constants';
|
||||||
|
|
||||||
export interface History {
|
export interface History {
|
||||||
all: AllStats;
|
all: BlitzStats;
|
||||||
last_battle_time: number;
|
last_battle_time: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { AllStats } from '../core/blitz/getAccountInfo';
|
|
||||||
import { emptyAllStats } from '../core/blitzstars/getStatsInPeriod/constants';
|
import { emptyAllStats } from '../core/blitzstars/getStatsInPeriod/constants';
|
||||||
|
import { BlitzStats } from '../core/statistics/compositeStats/constants';
|
||||||
|
|
||||||
export interface IndividualTankStats {
|
export interface IndividualTankStats {
|
||||||
all: AllStats;
|
all: BlitzStats;
|
||||||
last_battle_time: number;
|
last_battle_time: number;
|
||||||
account_id: number;
|
account_id: number;
|
||||||
max_xp: number;
|
max_xp: number;
|
||||||
|
|||||||
Reference in new issue
Block a user