mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: swap core and _core
This commit is contained in:
1 parent
07e3660388
commit
b827f7f730
113 files changed
+254
-247
No files matched your search
@@ -0,0 +1,48 @@
|
||||
import { AllStats } from '../blitz/getAccountInfo';
|
||||
|
||||
/**
|
||||
* Formula from https://web.archive.org/web/20190105064817/http://wiki.wnefficiency.net/pages/WN8
|
||||
*
|
||||
* @param expected what all players on average perform like
|
||||
* @param average what the player in question performs like
|
||||
*/
|
||||
export default function calculateWN8(expected: AllStats, average: AllStats) {
|
||||
const avgDmg = average.damage_dealt / average.battles;
|
||||
const avgSpot = average.spotted / average.battles;
|
||||
const avgFrag = average.frags / average.battles;
|
||||
const avgDef = average.dropped_capture_points / average.battles;
|
||||
const avgWinRate = average.wins / average.battles;
|
||||
|
||||
const expDmg = expected.damage_dealt / expected.battles;
|
||||
const expSpot = expected.spotted / expected.battles;
|
||||
const expFrag = expected.frags / expected.battles;
|
||||
const expDef = expected.dropped_capture_points / expected.battles;
|
||||
const expWinRate = expected.wins / expected.battles;
|
||||
|
||||
const rDAMAGE = avgDmg / expDmg;
|
||||
const rSPOT = avgSpot / expSpot;
|
||||
const rFRAG = avgFrag / expFrag;
|
||||
const rDEF = avgDef / expDef;
|
||||
const rWIN = avgWinRate / expWinRate;
|
||||
|
||||
const rWINc = Math.max(0, (rWIN - 0.71) / (1 - 0.71));
|
||||
const rDAMAGEc = Math.max(0, (rDAMAGE - 0.22) / (1 - 0.22));
|
||||
const rFRAGc = Math.max(
|
||||
0,
|
||||
Math.min(rDAMAGEc + 0.2, (rFRAG - 0.12) / (1 - 0.12)),
|
||||
);
|
||||
const rSPOTc = Math.max(
|
||||
0,
|
||||
Math.min(rDAMAGEc + 0.1, (rSPOT - 0.38) / (1 - 0.38)),
|
||||
);
|
||||
const rDEFc = Math.max(0, Math.min(rDAMAGEc + 0.1, (rDEF - 0.1) / (1 - 0.1)));
|
||||
|
||||
const WN8 =
|
||||
980 * rDAMAGEc +
|
||||
210 * rDAMAGEc * rFRAGc +
|
||||
155 * rFRAGc * rSPOTc +
|
||||
75 * rDEFc * rFRAGc +
|
||||
145 * Math.min(1.8, rWINc);
|
||||
|
||||
return WN8;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import {
|
||||
IndividualTankStats,
|
||||
NormalizedTankStats,
|
||||
emptyIndividualTankStats,
|
||||
} from '../../types/tanksStats';
|
||||
|
||||
export function deltaTankStats(a: NormalizedTankStats, b: NormalizedTankStats) {
|
||||
const bTanks = Object.keys(b);
|
||||
const changedTanks = bTanks.filter((id) => {
|
||||
return (
|
||||
a[id as unknown as number]?.all.battles !==
|
||||
b[id as unknown as number].all.battles
|
||||
);
|
||||
});
|
||||
const diff = changedTanks.map((id) => {
|
||||
const aTank = a[id as unknown as number] ?? emptyIndividualTankStats;
|
||||
const bTank = b[id as unknown as number];
|
||||
|
||||
const tankDiff = {
|
||||
account_id: bTank.account_id,
|
||||
battle_life_time: bTank.battle_life_time,
|
||||
frags: (bTank.frags ?? aTank.frags ?? 0) - (aTank.frags ?? 0),
|
||||
max_frags: Math.max(aTank.max_frags, bTank.max_frags),
|
||||
in_garage: bTank.in_garage,
|
||||
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
|
||||
in_garage_updated: bTank.in_garage_updated,
|
||||
last_battle_time: bTank.last_battle_time - aTank.last_battle_time,
|
||||
mark_of_mastery: bTank.mark_of_mastery,
|
||||
tank_id: bTank.tank_id,
|
||||
|
||||
all: {
|
||||
battles: bTank.all.battles - aTank.all.battles,
|
||||
wins: bTank.all.wins - aTank.all.wins,
|
||||
capture_points: bTank.all.capture_points - aTank.all.capture_points,
|
||||
damage_dealt: bTank.all.damage_dealt - aTank.all.damage_dealt,
|
||||
damage_received: bTank.all.damage_received - aTank.all.damage_received,
|
||||
dropped_capture_points:
|
||||
bTank.all.dropped_capture_points - aTank.all.dropped_capture_points,
|
||||
frags: bTank.all.frags - aTank.all.frags,
|
||||
frags8p: bTank.all.frags8p - aTank.all.frags8p,
|
||||
hits: bTank.all.hits - aTank.all.hits,
|
||||
losses: bTank.all.losses - aTank.all.losses,
|
||||
max_frags: Math.max(aTank.max_frags, bTank.max_frags),
|
||||
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
|
||||
shots: bTank.all.shots - aTank.all.shots,
|
||||
spotted: bTank.all.spotted - aTank.all.spotted,
|
||||
survived_battles:
|
||||
bTank.all.survived_battles - aTank.all.survived_battles,
|
||||
win_and_survived:
|
||||
bTank.all.win_and_survived - aTank.all.win_and_survived,
|
||||
xp: bTank.all.xp - aTank.all.xp,
|
||||
},
|
||||
} satisfies IndividualTankStats;
|
||||
|
||||
return tankDiff;
|
||||
});
|
||||
const normalized = diff.reduce<NormalizedTankStats>(
|
||||
(accumulator, diff) => ({ ...accumulator, [diff.tank_id]: diff }),
|
||||
{},
|
||||
);
|
||||
|
||||
return normalized;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { TreeTypeString } from '../../components/Tanks';
|
||||
import sumStats from '../../LEGACY_core/blitz/sumStats';
|
||||
import { tankopedia } from '../../LEGACY_core/blitz/tankopedia';
|
||||
import { DiffedTankStats } from '../../LEGACY_core/blitzstars/getDiffedTankStats';
|
||||
import { tankAverages } from '../../LEGACY_core/blitzstars/tankAverages';
|
||||
import calculateWN8 from './calculateWN8';
|
||||
|
||||
export interface StatFilters {
|
||||
nation?: string;
|
||||
tier?: number;
|
||||
tankType?: string;
|
||||
treeType?: TreeTypeString;
|
||||
tank?: number;
|
||||
}
|
||||
|
||||
export async function filterStats(
|
||||
{ diff, order }: DiffedTankStats,
|
||||
filters: StatFilters,
|
||||
) {
|
||||
// tank, if provided, takes priority over all other filters
|
||||
if (filters.tank) filters = { tank: filters.tank };
|
||||
|
||||
const awaitedTankopedia = await tankopedia;
|
||||
const awaitedTankAverages = await tankAverages;
|
||||
const filteredOrder = order.filter((id) => {
|
||||
const entry = awaitedTankopedia[id];
|
||||
|
||||
return (
|
||||
entry &&
|
||||
(filters.nation === undefined || entry.nation === filters.nation) &&
|
||||
(filters.tier === undefined || entry.tier === filters.tier) &&
|
||||
(filters.tankType === undefined || entry.type === filters.tankType) &&
|
||||
(filters.treeType === undefined ||
|
||||
(filters.treeType === 'collector' && entry.is_collectible) ||
|
||||
(filters.treeType === 'premium' &&
|
||||
entry.is_premium &&
|
||||
!entry.is_collectible) ||
|
||||
(filters.treeType === 'tech-tree' &&
|
||||
!entry.is_collectible &&
|
||||
!entry.is_premium)) &&
|
||||
(filters.tank === undefined || entry.tank_id === filters.tank)
|
||||
);
|
||||
});
|
||||
const stats = sumStats(filteredOrder.map((id) => diff[id]));
|
||||
const battlesOfTanksWithAverages = filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankAverages[id] ? accumulator + diff[id].battles : accumulator,
|
||||
0,
|
||||
);
|
||||
const battlesOfTanksWithTankopediaEntry = filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankopedia[id] ? accumulator + diff[id].battles : accumulator,
|
||||
0,
|
||||
);
|
||||
const supplementary = {
|
||||
WN8:
|
||||
filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankAverages[id]
|
||||
? accumulator +
|
||||
calculateWN8(awaitedTankAverages[id].all, diff[id]) *
|
||||
diff[id].battles
|
||||
: accumulator,
|
||||
0,
|
||||
) / battlesOfTanksWithAverages,
|
||||
tier:
|
||||
filteredOrder.reduce<number>(
|
||||
(accumulator, id) =>
|
||||
awaitedTankopedia[id]
|
||||
? accumulator + awaitedTankopedia[id]!.tier * diff[id].battles
|
||||
: accumulator,
|
||||
0,
|
||||
) / battlesOfTanksWithTankopediaEntry,
|
||||
};
|
||||
|
||||
return { stats, supplementary, filteredOrder };
|
||||
}
|
||||
Reference in new issue
Block a user