mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
fix: some linting for new proto 5
This commit is contained in:
1 parent
53a9c5f2de
commit
96310a9d63
40 files changed
+378
-336
No files matched your search
@@ -188,7 +188,7 @@ export async function renderBreakdown(
|
||||
key={id}
|
||||
displayType="tank"
|
||||
class={tankDefinition?.class}
|
||||
displayType={tankDefinition?.type}
|
||||
type={tankDefinition?.type}
|
||||
title={
|
||||
tankDefinition?.name ??
|
||||
translate('bot.commands.breakdown.body.unknown_tank', [`${id}`])
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import {
|
||||
blitzStarsTankAverages,
|
||||
calculateWN8,
|
||||
emblemURL,
|
||||
getClanAccountInfo,
|
||||
idToRegion,
|
||||
mapDefinitions,
|
||||
tankDefinitions,
|
||||
tankIcon,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
} from '@blitzkit/core';
|
||||
@@ -13,7 +10,12 @@ import { clamp } from 'lodash-es';
|
||||
import { CommandWrapper } from '../components/CommandWrapper';
|
||||
import { TitleBar } from '../components/TitleBar';
|
||||
import { iconPng } from '../core/blitzkit/iconPng';
|
||||
import {
|
||||
mapDefinitions,
|
||||
tankDefinitions,
|
||||
} from '../core/blitzkit/nonBlockingPromises';
|
||||
import { RenderConfiguration } from '../core/blitzkit/renderConfiguration';
|
||||
import { blitzStarsTankAverages } from '../core/blitzstars/tankAverages';
|
||||
import { buttonLink } from '../core/discord/buttonLink';
|
||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
@@ -223,7 +225,7 @@ async function playerListing(
|
||||
) {
|
||||
const awaitedTankAverages = await blitzStarsTankAverages;
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const tank = awaitedTankDefinitions[player.vehicle_descr];
|
||||
const tank = awaitedTankDefinitions.tanks[player.vehicle_descr];
|
||||
const blockAccent = recordingPlayer ? '_amber' : '';
|
||||
const healthAccent = protagonistTeam
|
||||
? recordingPlayer
|
||||
@@ -502,7 +504,7 @@ export const replayCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
replayData.protagonist_team === replayData.winner_team
|
||||
? 'Victory'
|
||||
: 'Defeat'
|
||||
} • ${awaitedMapDefinitions[replayData.map_id].name}`}
|
||||
} • ${awaitedMapDefinitions.maps[replayData.map_id].name}`}
|
||||
/>
|
||||
|
||||
<div
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
getClanAccountInfo,
|
||||
getTankStats,
|
||||
TANK_ICONS,
|
||||
tankDefinitions,
|
||||
TankType,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
} from '@blitzkit/core';
|
||||
import { escapeMarkdown, Locale } from 'discord.js';
|
||||
@@ -15,6 +15,7 @@ import { TitleBar } from '../components/TitleBar';
|
||||
import { resolveTankId } from '../core/blitz/resolveTankId';
|
||||
import { buildTechTreeLine } from '../core/blitzkit/buildTechTreeLine';
|
||||
import { iconPng } from '../core/blitzkit/iconPng';
|
||||
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
|
||||
import { resolveAncestry } from '../core/blitzkit/resolveAncestry';
|
||||
import { tankIconPng } from '../core/blitzkit/tankIconPng';
|
||||
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
|
||||
@@ -76,7 +77,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
true,
|
||||
);
|
||||
const startingTankRaw = interaction.options.getString('starting-tank');
|
||||
const targetTank = awaitedTankDefinitions[targetTankId];
|
||||
const targetTank = awaitedTankDefinitions.tanks[targetTankId];
|
||||
const { id, region } = await resolvePlayerFromCommand(interaction);
|
||||
let startingTankId: number;
|
||||
const targetTankAncestry = await resolveAncestry(targetTankId);
|
||||
@@ -94,7 +95,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
]);
|
||||
}
|
||||
|
||||
const startingTank = awaitedTankDefinitions[startingTankId];
|
||||
const startingTank = awaitedTankDefinitions.tanks[startingTankId];
|
||||
|
||||
if (startingTank.tier > targetTank.tier) {
|
||||
return translate('bot.commands.research.errors.unordered', [
|
||||
@@ -111,7 +112,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if (targetTank.treeType !== 'researchable') {
|
||||
if (targetTank.type !== TankType.RESEARCHABLE) {
|
||||
return translate('bot.commands.research.errors.non_tech_tree', [
|
||||
escapeMarkdown(targetTank.name),
|
||||
]);
|
||||
@@ -137,7 +138,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
|
||||
const foundAncestor = targetTankAncestry.find(
|
||||
(id) =>
|
||||
awaitedTankDefinitions[id].tier === 1 ||
|
||||
awaitedTankDefinitions.tanks[id].tier === 1 ||
|
||||
tankStats.some(({ tank_id }) => tank_id === id),
|
||||
);
|
||||
|
||||
@@ -159,7 +160,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
||||
const costs = await Promise.all(
|
||||
line.map(async (id) => {
|
||||
const tank = awaitedTankDefinitions[id];
|
||||
const tank = awaitedTankDefinitions.tanks[id];
|
||||
const turretXps = new Map<number, number>();
|
||||
const gunXps = new Map<number, number>();
|
||||
const engineXps = new Map<number, number>();
|
||||
@@ -171,8 +172,11 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
}
|
||||
|
||||
turret.guns.forEach((gun) => {
|
||||
if (gun.xp !== undefined) {
|
||||
gunXps.set(gun.id, gun.xp);
|
||||
if (gun.gunType!.value.base.xp !== undefined) {
|
||||
gunXps.set(
|
||||
gun.gunType!.value.base.id,
|
||||
gun.gunType!.value.base.xp,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -353,7 +357,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
|
||||
{await Promise.all(
|
||||
line.map(async (id, index) => {
|
||||
const tank = awaitedTankDefinitions[id];
|
||||
const tank = awaitedTankDefinitions.tanks[id];
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { tankDefinitions, tankNames } from '@blitzkit/core';
|
||||
import { Locale } from 'discord.js';
|
||||
import { go } from 'fuzzysort';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { tankNames } from '../blitzkit/nonBlockingPromises';
|
||||
import { UserError } from '../blitzkit/userError';
|
||||
import { tankNamesTechTreeOnly } from '../discord/autocompleteTanks';
|
||||
import { translator } from '../localization/translator';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { tankDefinitions } from '@blitzkit/core';
|
||||
import { fetchTankDefinitions } from '@blitzkit/core';
|
||||
import { resolveAncestry } from './resolveAncestry';
|
||||
|
||||
export async function buildTechTreeLine(start: number, end: number) {
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const endTank = awaitedTankDefinitions[end];
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const endTank = tankDefinitions.tanks[end];
|
||||
if (!endTank.ancestors) throw new Error('End tank has no ancestors');
|
||||
const line = [end];
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import {
|
||||
StatFilters,
|
||||
tankDefinitions,
|
||||
fetchTankDefinitions,
|
||||
Tier,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
} from '@blitzkit/core';
|
||||
import { Locale } from 'discord.js';
|
||||
import { StatFilters } from '../blitzstars/filterStats';
|
||||
import { translator } from '../localization/translator';
|
||||
|
||||
export async function filtersToDescription(
|
||||
{ nation, tier, tankType, treeType, tank }: StatFilters,
|
||||
{ nation, tier, type, class: tankClass, tank }: StatFilters,
|
||||
locale: Locale,
|
||||
) {
|
||||
const { translate } = translator(locale);
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const awaitedTankDefinitions = await fetchTankDefinitions();
|
||||
const info: string[] = [];
|
||||
|
||||
// TODO: somehow localize tank names?
|
||||
if (tank) return awaitedTankDefinitions[tank].name;
|
||||
if (tank) return awaitedTankDefinitions.tanks[tank].name;
|
||||
if (nation) info.push(translate(`common.nations.${nation}`));
|
||||
if (tier) {
|
||||
info.push(
|
||||
translate('bot.common.filters.tier', [TIER_ROMAN_NUMERALS[tier as Tier]]),
|
||||
);
|
||||
}
|
||||
if (tankType) info.push(translate(`common.tank_class_short.${tankType}`));
|
||||
if (treeType) info.push(translate(`common.tree_type.${treeType}`));
|
||||
if (tankClass) info.push(translate(`common.tank_class_short.${tankClass}`));
|
||||
if (type) info.push(translate(`common.tree_type.${type}`));
|
||||
|
||||
return info.length === 0
|
||||
? translate('bot.common.filters.none')
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { fetchGameDefinitions, fetchTankDefinitions } from '@blitzkit/core';
|
||||
import {
|
||||
fetchGameDefinitions,
|
||||
fetchMapDefinitions,
|
||||
fetchTankDefinitions,
|
||||
fetchTankNames,
|
||||
} from '@blitzkit/core';
|
||||
|
||||
export const tankDefinitions = fetchTankDefinitions();
|
||||
export const gameDefinitions = fetchGameDefinitions();
|
||||
export const tankNames = fetchTankNames();
|
||||
export const mapDefinitions = fetchMapDefinitions();
|
||||
@@ -1,8 +1,8 @@
|
||||
import { tankDefinitions } from '@blitzkit/core';
|
||||
import { fetchTankDefinitions } from '@blitzkit/core';
|
||||
|
||||
export async function resolveAncestry(id: number) {
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const tank = awaitedTankDefinitions[id];
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const tank = tankDefinitions.tanks[id];
|
||||
const ancestors: number[] = [];
|
||||
|
||||
if (tank.ancestors) {
|
||||
@@ -20,6 +20,6 @@ export async function resolveAncestry(id: number) {
|
||||
}
|
||||
|
||||
return ancestors.sort(
|
||||
(a, b) => awaitedTankDefinitions[b].tier - awaitedTankDefinitions[a].tier,
|
||||
(a, b) => tankDefinitions.tanks[b].tier - tankDefinitions.tanks[a].tier,
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { tankNames } from '@blitzkit/core';
|
||||
import { fetchTankNames, TankType } from '@blitzkit/core';
|
||||
import {
|
||||
ApplicationCommandOptionChoiceData,
|
||||
AutocompleteInteraction,
|
||||
@@ -9,9 +9,10 @@ import {
|
||||
DISCORD_CHOICES_MAX_NAME_SIZE,
|
||||
OVERFLOW_SUFFIX,
|
||||
} from './autocompleteClan/constants';
|
||||
import { tankNames } from '../blitzkit/nonBlockingPromises';
|
||||
|
||||
export const tankNamesTechTreeOnly = tankNames.then((names) =>
|
||||
names.filter((tank) => tank.treeType === 'researchable'),
|
||||
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
|
||||
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE),
|
||||
);
|
||||
|
||||
export async function autocompleteTanks(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type ShellDefinition, ShellType } from '@blitzkit/core';
|
||||
|
||||
export function canSplash(type: ShellDefinition['type']): type is ShellType.HE {
|
||||
return type === ShellType.SHELL_TYPE_HE;
|
||||
return type === ShellType.HE;
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Vector3Tuple } from 'three';
|
||||
import { Tier } from '../blitzkit';
|
||||
import { Tier } from '../protos';
|
||||
|
||||
export const equipmentPriceMatrix: Record<Tier, Vector3Tuple> = {
|
||||
1: [100, 200, 300],
|
||||
2: [200, 300, 400],
|
||||
3: [400, 500, 600],
|
||||
4: [4000, 5000, 6000],
|
||||
5: [40_000, 50_000, 60_000],
|
||||
6: [100_000, 120_000, 140_000],
|
||||
7: [150_000, 170_000, 190_000],
|
||||
8: [200_000, 225_000, 250_000],
|
||||
9: [250_000, 275_000, 300_000],
|
||||
10: [300_000, 350_000, 400_000],
|
||||
[Tier.I]: [100, 200, 300],
|
||||
[Tier.II]: [200, 300, 400],
|
||||
[Tier.III]: [400, 500, 600],
|
||||
[Tier.IV]: [4000, 5000, 6000],
|
||||
[Tier.V]: [40_000, 50_000, 60_000],
|
||||
[Tier.VI]: [100_000, 120_000, 140_000],
|
||||
[Tier.VII]: [150_000, 170_000, 190_000],
|
||||
[Tier.VIII]: [200_000, 225_000, 250_000],
|
||||
[Tier.IX]: [250_000, 275_000, 300_000],
|
||||
[Tier.X]: [300_000, 350_000, 400_000],
|
||||
[Tier.UNRECOGNIZED]: [0, 0, 0],
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
import { ProvisionDefinitions } from '@blitzkit/core';
|
||||
import {
|
||||
GunDefinition,
|
||||
ProvisionDefinitions,
|
||||
TankDefinition,
|
||||
} from '@blitzkit/core';
|
||||
import { checkConsumableProvisionInclusivity } from './checkConsumableProvisionInclusivity';
|
||||
import { GunDefinition, TankDefinition } from './tankDefinitions';
|
||||
|
||||
export function availableProvisions(
|
||||
tank: TankDefinition,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Samples } from '.';
|
||||
import { emptyAllStats } from '../../blitz/constants';
|
||||
import { Samples } from '../../protos';
|
||||
import { BlitzkitStats } from '../../statistics';
|
||||
|
||||
export const emptyAverageDefinitionsAllStats: BlitzkitStats = {
|
||||
@@ -12,11 +12,11 @@ export const averageDefinitionsAllStatsKeys = Object.keys(
|
||||
) as (keyof BlitzkitStats)[];
|
||||
|
||||
export const emptySamples: Samples = {
|
||||
d_1: 0,
|
||||
d_7: 0,
|
||||
d_30: 0,
|
||||
d_60: 0,
|
||||
d_90: 0,
|
||||
d_120: 0,
|
||||
d1: 0,
|
||||
d7: 0,
|
||||
d30: 0,
|
||||
d60: 0,
|
||||
d90: 0,
|
||||
d120: 0,
|
||||
total: 0,
|
||||
};
|
||||
@@ -1,53 +1,64 @@
|
||||
import { ConsumableEntry, ProvisionEntry } from '@blitzkit/core';
|
||||
import { GunDefinition, TankDefinition } from './tankDefinitions';
|
||||
import {
|
||||
Consumable,
|
||||
ConsumableTankCategoryFilterCategory,
|
||||
GunDefinition,
|
||||
Provision,
|
||||
TankDefinition,
|
||||
} from '../protos';
|
||||
|
||||
export function checkConsumableProvisionInclusivity(
|
||||
consumableProvision: ConsumableEntry | ProvisionEntry,
|
||||
consumableProvision: Consumable | Provision,
|
||||
tank: TankDefinition,
|
||||
gun: GunDefinition,
|
||||
) {
|
||||
const included =
|
||||
!consumableProvision.gameMode &&
|
||||
!consumableProvision.gameModeExclusive &&
|
||||
consumableProvision.include?.every((rule) => {
|
||||
switch (rule.type) {
|
||||
case 'tier':
|
||||
return rule.min <= tank.tier && tank.tier <= rule.max;
|
||||
switch (rule.filterType!.$case) {
|
||||
case 'tiers':
|
||||
return (
|
||||
rule.filterType!.value.min <= tank.tier &&
|
||||
tank.tier <= rule.filterType!.value.max
|
||||
);
|
||||
|
||||
case 'ids':
|
||||
return rule.ids.includes(tank.id);
|
||||
return rule.filterType!.value.ids.includes(tank.id);
|
||||
|
||||
case 'nation':
|
||||
return rule.nations.includes(tank.nation);
|
||||
case 'nations':
|
||||
return rule.filterType!.value.nations.includes(tank.nation);
|
||||
|
||||
case 'category':
|
||||
case 'categories':
|
||||
throw new SyntaxError('Category filtering found in include rule');
|
||||
}
|
||||
});
|
||||
const excluded =
|
||||
consumableProvision.gameMode ||
|
||||
consumableProvision.gameModeExclusive ||
|
||||
consumableProvision.exclude?.some((rule) => {
|
||||
switch (rule.type) {
|
||||
case 'tier':
|
||||
return rule.min <= tank.tier && tank.tier <= rule.max;
|
||||
switch (rule.filterType!.$case) {
|
||||
case 'tiers':
|
||||
return (
|
||||
rule.filterType!.value.min <= tank.tier &&
|
||||
tank.tier <= rule.filterType!.value.max
|
||||
);
|
||||
|
||||
case 'ids':
|
||||
return rule.ids.includes(tank.id);
|
||||
return rule.filterType!.value.ids.includes(tank.id);
|
||||
|
||||
case 'nation':
|
||||
return rule.nations.includes(tank.nation);
|
||||
case 'nations':
|
||||
return rule.filterType!.value.nations.includes(tank.nation);
|
||||
|
||||
case 'category':
|
||||
return rule.categories.some((category) => {
|
||||
case 'categories':
|
||||
return rule.filterType!.value.categories.some((category) => {
|
||||
switch (category) {
|
||||
case 'clip':
|
||||
return gun.type !== 'regular';
|
||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
||||
return gun.gunType!.$case !== 'regular';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
!consumableProvision.gameMode &&
|
||||
!consumableProvision.gameModeExclusive &&
|
||||
consumableProvision.include?.length > 0 &&
|
||||
included &&
|
||||
!excluded
|
||||
|
||||
@@ -5,7 +5,7 @@ export function createDefaultSkills(skillDefinitions: SkillDefinitions) {
|
||||
const skills: Record<string, number> = {};
|
||||
|
||||
Object.values(skillDefinitions.classes).forEach((tankSkills) => {
|
||||
tankSkills.forEach((skill) => {
|
||||
tankSkills.skills.forEach((skill) => {
|
||||
skills[skill] = permanentSkills.includes(skill) ? 7 : 0;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import { RatingInfo, Region, asset, superDecompress } from '@blitzkit/core';
|
||||
// import { RatingInfo, Region, asset } from '@blitzkit/core';
|
||||
|
||||
const cache: Record<
|
||||
Region,
|
||||
Record<
|
||||
number,
|
||||
RatingInfo & {
|
||||
detail: undefined;
|
||||
}
|
||||
>
|
||||
> = {
|
||||
com: {},
|
||||
eu: {},
|
||||
asia: {},
|
||||
};
|
||||
// const cache: Record<
|
||||
// Region,
|
||||
// Record<
|
||||
// number,
|
||||
// RatingInfo & {
|
||||
// detail: undefined;
|
||||
// }
|
||||
// >
|
||||
// > = {
|
||||
// com: {},
|
||||
// eu: {},
|
||||
// asia: {},
|
||||
// };
|
||||
|
||||
export async function getArchivedRatingInfo(region: Region, season: number) {
|
||||
if (!cache[region][season]) {
|
||||
const info = await fetch(
|
||||
asset(`regions/${region}/rating/${season}/info.cdon.lz4`),
|
||||
)
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((buffer) =>
|
||||
superDecompress<RatingInfo & { detail: undefined }>(buffer),
|
||||
);
|
||||
cache[region][season] = info;
|
||||
}
|
||||
// export async function getArchivedRatingInfo(region: Region, season: number) {
|
||||
// if (!cache[region][season]) {
|
||||
// const info = await fetch(
|
||||
// asset(`regions/${region}/rating/${season}/info.cdon.lz4`),
|
||||
// )
|
||||
// .then((response) => response.arrayBuffer())
|
||||
// .then((buffer) =>
|
||||
// superDecompress<RatingInfo & { detail: undefined }>(buffer),
|
||||
// );
|
||||
// cache[region][season] = info;
|
||||
// }
|
||||
|
||||
return cache[region][season];
|
||||
}
|
||||
// return cache[region][season];
|
||||
// }
|
||||
@@ -10,10 +10,9 @@ export * from './consumableDefinitions';
|
||||
export * from './createDefaultSkills';
|
||||
export * from './degressiveStat';
|
||||
export * from './discoveredIdDefinitions';
|
||||
// export * from './emblemURL';
|
||||
export * from './emblemURL';
|
||||
export * from './equipmentDefinitions';
|
||||
export * from './eventManager';
|
||||
export * from './resolveGun';
|
||||
// export * from './flagUserActivity';
|
||||
export * from './gameDefinitions';
|
||||
// export * from './getArchivedLatestSeasonNumber';
|
||||
@@ -23,7 +22,7 @@ export * from './gameDefinitions';
|
||||
// export * from './getTimeDaysAgo';
|
||||
export * from './isExplosive';
|
||||
// export * from './linkBlitzAndDiscord';
|
||||
// export * from './mapDefinitions';
|
||||
export * from './mapDefinitions';
|
||||
export * from './modelDefinitions';
|
||||
export * from './normalizeBoundingBox';
|
||||
// export * from './parseBkni';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { BoundingBox } from '@blitzkit/core';
|
||||
import { Vector3Tuple } from 'three';
|
||||
import { BoundingBox, Vector3 } from '@blitzkit/core';
|
||||
|
||||
export function normalizeBoundingBox(boundingBox: BoundingBox) {
|
||||
return boundingBox.max.map(
|
||||
(max, index) => max - boundingBox.min[index],
|
||||
) as Vector3Tuple;
|
||||
return {
|
||||
x: boundingBox.max.x - boundingBox.min.x,
|
||||
y: boundingBox.max.y - boundingBox.min.y,
|
||||
z: boundingBox.max.z - boundingBox.min.z,
|
||||
} satisfies Vector3;
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
import { GunDefinition, ShellDefinition } from './tankDefinitions';
|
||||
import {
|
||||
GunDefinition,
|
||||
GunDefinitionAutoReloaderProperties,
|
||||
ShellDefinition,
|
||||
} from '../protos';
|
||||
|
||||
export function resolveDpm(
|
||||
gun: GunDefinition,
|
||||
@@ -7,24 +11,32 @@ export function resolveDpm(
|
||||
reloadCoefficient = 1,
|
||||
intraClipCoefficient = 1,
|
||||
) {
|
||||
const alpha = shell.damage.armor * damageCoefficient;
|
||||
const alpha = shell.armorDamage * damageCoefficient;
|
||||
let dps: number;
|
||||
|
||||
if (gun.type === 'regular') {
|
||||
dps = alpha / (reloadCoefficient * gun.reload);
|
||||
} else if (gun.type === 'autoLoader') {
|
||||
if (gun.gunType!.$case === 'regular') {
|
||||
dps = alpha / (reloadCoefficient * gun.gunType!.value.extension.reload);
|
||||
} else if (gun.gunType!.$case === 'autoLoader') {
|
||||
dps =
|
||||
(alpha * gun.count) /
|
||||
(gun.reload * reloadCoefficient +
|
||||
(gun.count - 1) * gun.intraClip * intraClipCoefficient);
|
||||
(alpha * gun.gunType!.value.extension.shellCount) /
|
||||
(gun.gunType!.value.extension.clipReload * reloadCoefficient +
|
||||
(gun.gunType!.value.extension.shellCount - 1) *
|
||||
gun.gunType!.value.extension.intraClip *
|
||||
intraClipCoefficient);
|
||||
} else {
|
||||
const mostOptimalShell = gun.reload.reduce<null | {
|
||||
const mostOptimalShell =
|
||||
gun.gunType!.value.extension.shellReloads.reduce<null | {
|
||||
index: number;
|
||||
reload: number;
|
||||
}>((current, reloadRaw, index) => {
|
||||
const reload =
|
||||
reloadRaw * reloadCoefficient +
|
||||
(index > 0 ? gun.intraClip * intraClipCoefficient : 0);
|
||||
(index > 0
|
||||
? (
|
||||
gun.gunType!.value
|
||||
.extension as GunDefinitionAutoReloaderProperties
|
||||
).intraClip * intraClipCoefficient
|
||||
: 0);
|
||||
|
||||
if (current === null || reload < current.reload) {
|
||||
return { index, reload };
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import { GunDefinition } from '../protos';
|
||||
|
||||
export function resolveGun(gun: GunDefinition) {
|
||||
if (gun.regular) return gun.regular;
|
||||
else if (gun.autoLoader) return gun.autoLoader;
|
||||
else if (gun.autoReloader) return gun.autoReloader;
|
||||
|
||||
throw new Error('Could not resolve gun');
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ShellType } from '../blitzkit/tankDefinitions';
|
||||
import { ShellType } from '../protos';
|
||||
|
||||
export function resolvePenetrationCoefficient(
|
||||
calibratedShells: boolean,
|
||||
@@ -6,11 +6,11 @@ export function resolvePenetrationCoefficient(
|
||||
) {
|
||||
if (!calibratedShells) return 1;
|
||||
|
||||
return type === 'ap'
|
||||
return type === ShellType.AP
|
||||
? 1.08
|
||||
: type === 'ap_cr'
|
||||
: type === ShellType.APCR
|
||||
? 1.05
|
||||
: type === 'hc'
|
||||
: type === ShellType.HEAT
|
||||
? 1.13
|
||||
: 1.08;
|
||||
}
|
||||
@@ -9,3 +9,4 @@ export * from './protos';
|
||||
export * from './statistics';
|
||||
export * from './streams';
|
||||
export * from './types';
|
||||
|
||||
@@ -12,7 +12,7 @@ message Consumable {
|
||||
required uint32 id = 1;
|
||||
required string name = 2;
|
||||
required uint32 cooldown = 3;
|
||||
optional uint32 duration = 4;
|
||||
optional float duration = 4;
|
||||
required bool game_mode_exclusive = 5;
|
||||
repeated ConsumableTankFilter include = 6;
|
||||
repeated ConsumableTankFilter exclude = 7;
|
||||
|
||||
@@ -16,7 +16,7 @@ message ModelDefinition {
|
||||
}
|
||||
|
||||
message Armor {
|
||||
map<uint32, uint32> thickness = 1;
|
||||
map<uint32, float> thickness = 1;
|
||||
repeated uint32 spaced = 2;
|
||||
}
|
||||
|
||||
@@ -52,13 +52,13 @@ message BoundingBox {
|
||||
}
|
||||
|
||||
message TrackModelDefinition {
|
||||
required uint32 thickness = 1;
|
||||
required float thickness = 1;
|
||||
required Vector3 origin = 2;
|
||||
}
|
||||
|
||||
message GunModelDefinition {
|
||||
required Armor armor = 1;
|
||||
required uint32 thickness = 2;
|
||||
required float thickness = 2;
|
||||
required uint32 model_id = 3;
|
||||
required PitchLimits pitch = 4;
|
||||
optional float mask = 5;
|
||||
|
||||
@@ -30,7 +30,7 @@ message TankDefinition {
|
||||
repeated EngineDefinition engines = 21;
|
||||
repeated TrackDefinition tracks = 22;
|
||||
required TankPrice price = 23;
|
||||
optional uint32 xp = 24;
|
||||
optional ResearchCost research_cost = 24;
|
||||
required float speed_forwards = 25;
|
||||
required float speed_backwards = 26;
|
||||
required float camouflage_still = 27;
|
||||
@@ -40,6 +40,18 @@ message TankDefinition {
|
||||
required uint32 weight = 31;
|
||||
}
|
||||
|
||||
message ResearchCost {
|
||||
oneof research_cost_type {
|
||||
uint32 xp = 1;
|
||||
ResearchCostSeasonalTokens seasonal_tokens = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ResearchCostSeasonalTokens {
|
||||
required uint32 season = 1;
|
||||
required uint32 tokens = 2;
|
||||
}
|
||||
|
||||
enum TankPriceType {
|
||||
TANK_PRICE_TYPE_CREDITS = 0;
|
||||
TANK_PRICE_TYPE_GOLD = 1;
|
||||
@@ -56,7 +68,7 @@ message TrackDefinition {
|
||||
required string name = 3;
|
||||
required uint32 weight = 4;
|
||||
required float traverse_speed = 5;
|
||||
optional uint32 xp = 6;
|
||||
optional ResearchCost research_cost = 6;
|
||||
required float dispersion_move = 7;
|
||||
required float dispersion_traverse = 8;
|
||||
required float resistance_hard = 9;
|
||||
@@ -68,7 +80,7 @@ message TrackDefinition {
|
||||
message EngineDefinition {
|
||||
required uint32 id = 1;
|
||||
required string name = 2;
|
||||
optional uint32 xp = 3;
|
||||
optional ResearchCost research_cost = 3;
|
||||
required Tier tier = 4;
|
||||
required float fire_chance = 5;
|
||||
required uint32 power = 6;
|
||||
@@ -81,7 +93,7 @@ message TurretDefinition {
|
||||
required uint32 health = 2;
|
||||
required uint32 view_range = 3;
|
||||
required float traverse_speed = 4;
|
||||
optional uint32 xp = 5;
|
||||
optional ResearchCost research_cost = 5;
|
||||
required string name = 6;
|
||||
required Tier tier = 7;
|
||||
required uint32 weight = 8;
|
||||
@@ -131,7 +143,7 @@ message GunDefinitionAutoReloaderProperties {
|
||||
message GunDefinitionBase {
|
||||
required uint32 id = 1;
|
||||
required float rotation_speed = 2;
|
||||
optional uint32 xp = 3;
|
||||
optional ResearchCost research_cost = 3;
|
||||
required uint32 weight = 4;
|
||||
required string name = 5;
|
||||
required Tier tier = 6;
|
||||
@@ -151,13 +163,13 @@ message ShellDefinition {
|
||||
required uint32 velocity = 3;
|
||||
required uint32 armor_damage = 4;
|
||||
required uint32 module_damage = 5;
|
||||
required uint32 caliber = 6;
|
||||
required float caliber = 6;
|
||||
required string icon = 7;
|
||||
required ShellPenetration penetration = 8;
|
||||
required ShellType type = 9;
|
||||
required uint32 normalization = 10;
|
||||
required uint32 ricochet = 11;
|
||||
required uint32 explosion_radius = 12;
|
||||
optional float normalization = 10;
|
||||
optional float ricochet = 11;
|
||||
optional float explosion_radius = 12;
|
||||
}
|
||||
|
||||
enum ShellType {
|
||||
@@ -168,8 +180,8 @@ enum ShellType {
|
||||
}
|
||||
|
||||
message ShellPenetration {
|
||||
required uint32 near = 1;
|
||||
required uint32 far = 2;
|
||||
required float near = 1;
|
||||
required float far = 2;
|
||||
}
|
||||
|
||||
message Unlock {
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { tankDefinitions, Tier } from '../blitzkit/tankDefinitions';
|
||||
import { fetchTankDefinitions } from '../blitzkit';
|
||||
import { Tier } from '../protos';
|
||||
import { BlitzStats } from './compositeStats/constants';
|
||||
|
||||
export async function getTierWeights(
|
||||
stats: Record<number, BlitzStats>,
|
||||
order: number[] = Object.keys(stats).map(parseInt),
|
||||
) {
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const tierWeights: TierWeightsRecord = {};
|
||||
|
||||
order.forEach((id) => {
|
||||
const entry = awaitedTankDefinitions[id];
|
||||
const entry = tankDefinitions.tanks[id];
|
||||
|
||||
if (!entry) return;
|
||||
if (!tierWeights[entry.tier]) tierWeights[entry.tier] = 0;
|
||||
|
||||
@@ -12,11 +12,13 @@ import {
|
||||
EquipmentSlot,
|
||||
GameDefinitions,
|
||||
GunDefinition,
|
||||
GunDefinitionBase,
|
||||
MapDefinitions,
|
||||
ModelDefinitions,
|
||||
ModuleType,
|
||||
Provision,
|
||||
ProvisionDefinitions,
|
||||
ResearchCost,
|
||||
ShellType,
|
||||
SkillDefinitions,
|
||||
TankClass,
|
||||
@@ -41,6 +43,24 @@ import { DATA } from './constants';
|
||||
import { Avatar } from './skillIcons';
|
||||
import { TankParameters } from './tankIcons';
|
||||
|
||||
function parseResearchCost(raw: number | string) {
|
||||
if (typeof raw === 'number') {
|
||||
return {
|
||||
researchCostType: { $case: 'xp', value: raw },
|
||||
} satisfies ResearchCost;
|
||||
} else {
|
||||
return {
|
||||
researchCostType: {
|
||||
$case: 'seasonalTokens',
|
||||
value: {
|
||||
season: Number(/prx_season_(\d+):\d+/.exec(raw)![1]),
|
||||
tokens: Number(/prx_season_\d+:(\d+)/.exec(raw)![1]),
|
||||
},
|
||||
},
|
||||
} satisfies ResearchCost;
|
||||
}
|
||||
}
|
||||
|
||||
type BlitzTankFilterDefinitionCategory = 'clip';
|
||||
const blitzTankFilterDefinitionCategoryToBlitzkit: Record<
|
||||
BlitzTankFilterDefinitionCategory,
|
||||
@@ -75,8 +95,8 @@ type ShellDefinitionsList = Record<
|
||||
kind: ShellKind;
|
||||
caliber: number;
|
||||
damage: { armor: number; devices: number };
|
||||
normalizationAngle: number;
|
||||
ricochetAngle: number;
|
||||
normalizationAngle?: number;
|
||||
ricochetAngle?: number;
|
||||
explosionRadius?: number;
|
||||
}
|
||||
> & {
|
||||
@@ -593,7 +613,7 @@ export async function definitions() {
|
||||
`${DATA}/XML/item_defs/tankmen/avatar.xml.dvpl`,
|
||||
);
|
||||
const maps = await readYAMLDVPL<Maps>(`${DATA}/maps.yaml.dvpl`);
|
||||
const tankXps = new Map<number, number>();
|
||||
const tankXps = new Map<number, ResearchCost>();
|
||||
const camouflagesXml = await readXMLDVPL<{ root: CamouflagesXML }>(
|
||||
`${DATA}/XML/item_defs/vehicles/common/camouflages.xml.dvpl`,
|
||||
);
|
||||
@@ -726,10 +746,10 @@ export async function definitions() {
|
||||
for (const tankKey in tankList.root) {
|
||||
if (botPattern.test(tankKey)) continue;
|
||||
|
||||
const gunXps = new Map<number, number>();
|
||||
const turretXps = new Map<number, number>();
|
||||
const engineXps = new Map<number, number>();
|
||||
const trackXps = new Map<number, number>();
|
||||
const gunXps = new Map<number, ResearchCost>();
|
||||
const turretXps = new Map<number, ResearchCost>();
|
||||
const engineXps = new Map<number, ResearchCost>();
|
||||
const trackXps = new Map<number, ResearchCost>();
|
||||
const tank = tankList.root[tankKey];
|
||||
let tankPrice: TankPrice;
|
||||
const tankDefinition = await readXMLDVPL<{ root: VehicleDefinitions }>(
|
||||
@@ -794,6 +814,7 @@ export async function definitions() {
|
||||
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey,
|
||||
);
|
||||
if (index === -1) {
|
||||
if (crewKey === '#text') return;
|
||||
entry = {
|
||||
type: blitzCrewTypeToBlitzkit[crewKey as BlitzCrewType],
|
||||
count: 1,
|
||||
@@ -808,12 +829,9 @@ export async function definitions() {
|
||||
entry.count++;
|
||||
|
||||
if (value !== '') {
|
||||
entry.substitute = value
|
||||
.split('\n')
|
||||
.map(
|
||||
(member) =>
|
||||
blitzCrewTypeToBlitzkit[member.trim() as BlitzCrewType],
|
||||
);
|
||||
entry.substitute = value.split(/\n| /).map((member) => {
|
||||
return blitzCrewTypeToBlitzkit[member.trim() as BlitzCrewType];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (entry.count === undefined) {
|
||||
@@ -1091,14 +1109,9 @@ export async function definitions() {
|
||||
? 'autoReloader'
|
||||
: 'autoLoader'
|
||||
: 'regular';
|
||||
const gunReload =
|
||||
gunType === 'autoReloader'
|
||||
? gun.pumpGunReloadTimes!.split(' ').map(Number)
|
||||
: gun.reloadTime;
|
||||
const gunClipCount =
|
||||
gunType === 'regular' ? undefined : gun.clip!.count;
|
||||
const gunIntraClip =
|
||||
gunType === 'regular' ? undefined : 60 / gun.clip!.rate;
|
||||
// const gunReload = gun.reloadTime;
|
||||
// const shellReloads =
|
||||
const gunClipCount = gunType === 'regular' ? 1 : gun.clip!.count;
|
||||
const front = gun.extraPitchLimits?.front
|
||||
? gun.extraPitchLimits.front.split(' ').map(Number)
|
||||
: undefined;
|
||||
@@ -1144,32 +1157,62 @@ export async function definitions() {
|
||||
}
|
||||
});
|
||||
|
||||
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
||||
const base = {
|
||||
id: gunId,
|
||||
weight: gunListEntry.weight,
|
||||
rotationSpeed: gunListEntry.rotationSpeed,
|
||||
name: gunName,
|
||||
tier: gunListEntry.level as Tier,
|
||||
shells: [],
|
||||
type: gunType,
|
||||
reload: gunReload,
|
||||
count: gunClipCount,
|
||||
intraClip: gunIntraClip,
|
||||
camouflageLoss:
|
||||
typeof gun.invisibilityFactorAtShot === 'number'
|
||||
? gun.invisibilityFactorAtShot
|
||||
: gun.invisibilityFactorAtShot.at(-1)!,
|
||||
aimTime: gun.aimingTime ?? gunListEntry.aimingTime,
|
||||
dispersion: {
|
||||
base:
|
||||
gun.shotDispersionRadius ??
|
||||
gunListEntry.shotDispersionRadius,
|
||||
damaged: shotDispersionFactors.whileGunDamaged,
|
||||
shot: shotDispersionFactors.afterShot,
|
||||
traverse: shotDispersionFactors.turretRotation,
|
||||
},
|
||||
dispersionBase:
|
||||
gun.shotDispersionRadius ?? gunListEntry.shotDispersionRadius,
|
||||
dispersionDamaged: shotDispersionFactors.whileGunDamaged,
|
||||
dispersionShot: shotDispersionFactors.afterShot,
|
||||
dispersionTraverse: shotDispersionFactors.turretRotation,
|
||||
unlocks: resolveUnlocks(gun.unlocks),
|
||||
} as GunDefinition);
|
||||
} satisfies GunDefinitionBase;
|
||||
|
||||
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
||||
gunType:
|
||||
gunType === 'regular'
|
||||
? {
|
||||
$case: 'regular',
|
||||
value: {
|
||||
base,
|
||||
extension: { reload: gun.reloadTime },
|
||||
},
|
||||
}
|
||||
: gunType === 'autoReloader'
|
||||
? {
|
||||
$case: 'autoReloader',
|
||||
value: {
|
||||
base,
|
||||
extension: {
|
||||
intraClip: 60 / gun.clip!.rate,
|
||||
shellCount: gunClipCount,
|
||||
shellReloads: gun
|
||||
.pumpGunReloadTimes!.split(' ')
|
||||
.map(Number),
|
||||
},
|
||||
},
|
||||
}
|
||||
: {
|
||||
$case: 'autoLoader',
|
||||
value: {
|
||||
base,
|
||||
extension: {
|
||||
intraClip: 60 / gun.clip!.rate,
|
||||
clipReload: gun.reloadTime,
|
||||
shellCount: gunClipCount,
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies GunDefinition);
|
||||
|
||||
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
|
||||
armor: gunArmor,
|
||||
@@ -1214,19 +1257,14 @@ export async function definitions() {
|
||||
.filter((penetrationString) => penetrationString !== '')
|
||||
.map(Number);
|
||||
|
||||
Object.values(
|
||||
tankDefinitions.tanks[tankId].turrets[turretIndex].guns[
|
||||
gunIndex
|
||||
],
|
||||
).forEach((gun) => {
|
||||
gun.shells.push({
|
||||
].gunType!.value.base.shells.push({
|
||||
id: shellId,
|
||||
name: shellName,
|
||||
speed: gunShellEntry.speed,
|
||||
damage: {
|
||||
armor: shell.damage.armor,
|
||||
module: shell.damage.devices,
|
||||
},
|
||||
velocity: gunShellEntry.speed,
|
||||
armorDamage: shell.damage.armor,
|
||||
moduleDamage: shell.damage.devices,
|
||||
caliber: shell.caliber,
|
||||
normalization: shell.normalizationAngle,
|
||||
ricochet: shell.ricochetAngle,
|
||||
@@ -1236,11 +1274,10 @@ export async function definitions() {
|
||||
? (shell.explosionRadius ?? 0)
|
||||
: undefined,
|
||||
icon: shell.icon,
|
||||
penetration:
|
||||
penetrationRaw[0] === penetrationRaw[1]
|
||||
? penetrationRaw[0]
|
||||
: [penetrationRaw[0], penetrationRaw[1]],
|
||||
});
|
||||
penetration: {
|
||||
near: penetrationRaw[0],
|
||||
far: penetrationRaw[1],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1258,7 +1295,7 @@ export async function definitions() {
|
||||
const currentTank = tankDefinitions.tanks[tankId];
|
||||
const successorId = toUniqueId(nation, tankListEntry.id);
|
||||
|
||||
tankXps.set(successorId, vehicle.cost as number);
|
||||
tankXps.set(successorId, parseResearchCost(vehicle.cost));
|
||||
|
||||
if (currentTank.successors === undefined) {
|
||||
currentTank.successors = [];
|
||||
@@ -1272,7 +1309,7 @@ export async function definitions() {
|
||||
case 'gun': {
|
||||
gunXps.set(
|
||||
toUniqueId(nation, gunList.root.ids[vehicle['#text']]),
|
||||
vehicle.cost as number,
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1280,7 +1317,7 @@ export async function definitions() {
|
||||
case 'turret': {
|
||||
turretXps.set(
|
||||
toUniqueId(nation, turretList.root.ids[vehicle['#text']]),
|
||||
vehicle.cost as number,
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1288,7 +1325,7 @@ export async function definitions() {
|
||||
case 'engine': {
|
||||
engineXps.set(
|
||||
toUniqueId(nation, enginesList.root.ids[vehicle['#text']]),
|
||||
vehicle.cost as number,
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1296,7 +1333,7 @@ export async function definitions() {
|
||||
case 'chassis': {
|
||||
trackXps.set(
|
||||
toUniqueId(nation, chassisList.root.ids[vehicle['#text']]),
|
||||
vehicle.cost as number,
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1307,31 +1344,31 @@ export async function definitions() {
|
||||
|
||||
Object.values(tankDefinitions.tanks[tankId].turrets).forEach(
|
||||
(turret) => {
|
||||
turret.xp = turretXps.get(turret.id);
|
||||
turret.researchCost = turretXps.get(turret.id);
|
||||
|
||||
Object.values(turret.guns).forEach((gunRaw) => {
|
||||
Object.values(gunRaw).forEach((gun) => {
|
||||
gun.xp = gunXps.get(gun.id);
|
||||
});
|
||||
gunRaw.gunType!.value.base.researchCost = gunXps.get(
|
||||
gunRaw.gunType!.value.base.id,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
Object.values(tankDefinitions.tanks[tankId].engines).forEach(
|
||||
(engine) => {
|
||||
engine.xp = engineXps.get(engine.id);
|
||||
engine.researchCost = engineXps.get(engine.id);
|
||||
},
|
||||
);
|
||||
|
||||
Object.values(tankDefinitions.tanks[tankId].tracks).forEach((track) => {
|
||||
track.xp = trackXps.get(track.id);
|
||||
track.researchCost = trackXps.get(track.id);
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
Object.values(tankDefinitions.tanks).forEach((tank) => {
|
||||
tank.xp = tankXps.get(tank.id);
|
||||
tank.researchCost = tankXps.get(tank.id);
|
||||
});
|
||||
|
||||
Object.values(tankDefinitions.tanks).forEach((tank) => {
|
||||
@@ -1357,9 +1394,8 @@ export async function definitions() {
|
||||
([optionalDeviceSlotKey, optionalDeviceSlotEntry]) => {
|
||||
if (optionalDeviceSlotKey === 'emptyPreset') return;
|
||||
|
||||
equipmentDefinitions.presets[optionalDeviceSlotKey].slots = Object.values(
|
||||
optionalDeviceSlotEntry,
|
||||
)
|
||||
equipmentDefinitions.presets[optionalDeviceSlotKey] = {
|
||||
slots: Object.values(optionalDeviceSlotEntry)
|
||||
.map((level) => {
|
||||
return Object.values(level).map((options) => {
|
||||
return {
|
||||
@@ -1368,7 +1404,8 @@ export async function definitions() {
|
||||
} satisfies EquipmentSlot;
|
||||
});
|
||||
})
|
||||
.flat();
|
||||
.flat(),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1400,17 +1437,17 @@ export async function definitions() {
|
||||
entry.include.push({
|
||||
filterType: {
|
||||
$case: 'tiers',
|
||||
tiers: { min: includeRaw.minLevel, max: includeRaw.maxLevel },
|
||||
value: { min: includeRaw.minLevel, max: includeRaw.maxLevel },
|
||||
},
|
||||
});
|
||||
} else if ('name' in includeRaw) {
|
||||
entry.include.push({
|
||||
filterType: {
|
||||
$case: 'ids',
|
||||
ids: {
|
||||
ids: includeRaw.name
|
||||
.split(' ')
|
||||
.map((key) => tankStringIdMap[key]),
|
||||
value: {
|
||||
ids: includeRaw.name.split(/ +/).map((key) => {
|
||||
return tankStringIdMap[key];
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1420,7 +1457,7 @@ export async function definitions() {
|
||||
entry.include.push({
|
||||
filterType: {
|
||||
$case: 'nations',
|
||||
nations: {
|
||||
value: {
|
||||
nations: consumable.vehicleFilter.include.nations.split(' '),
|
||||
},
|
||||
},
|
||||
@@ -1435,10 +1472,10 @@ export async function definitions() {
|
||||
entry.exclude!.push({
|
||||
filterType: {
|
||||
$case: 'ids',
|
||||
ids: {
|
||||
ids: excludeRaw.name
|
||||
.split(' ')
|
||||
.map((key) => tankStringIdMap[key]),
|
||||
value: {
|
||||
ids: excludeRaw.name.split(/ +/).map((key) => {
|
||||
return tankStringIdMap[key];
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1446,7 +1483,7 @@ export async function definitions() {
|
||||
entry.exclude!.push({
|
||||
filterType: {
|
||||
$case: 'categories',
|
||||
categories: {
|
||||
value: {
|
||||
categories: excludeRaw.extendedTags
|
||||
.split(' ')
|
||||
.map(
|
||||
@@ -1464,7 +1501,7 @@ export async function definitions() {
|
||||
entry.exclude!.push({
|
||||
filterType: {
|
||||
$case: 'nations',
|
||||
nations: {
|
||||
value: {
|
||||
nations: consumable.vehicleFilter.exclude.nations.split(' '),
|
||||
},
|
||||
},
|
||||
@@ -1500,7 +1537,7 @@ export async function definitions() {
|
||||
entry.include.push({
|
||||
filterType: {
|
||||
$case: 'tiers',
|
||||
tiers: {
|
||||
value: {
|
||||
min: includeRaw.minLevel,
|
||||
max: includeRaw.maxLevel,
|
||||
},
|
||||
@@ -1510,10 +1547,10 @@ export async function definitions() {
|
||||
entry.include.push({
|
||||
filterType: {
|
||||
$case: 'ids',
|
||||
ids: {
|
||||
ids: includeRaw.name
|
||||
.split(' ')
|
||||
.map((key) => tankStringIdMap[key]),
|
||||
value: {
|
||||
ids: includeRaw.name.split(/ +/).map((key) => {
|
||||
return tankStringIdMap[key];
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1523,7 +1560,7 @@ export async function definitions() {
|
||||
entry.include.push({
|
||||
filterType: {
|
||||
$case: 'nations',
|
||||
nations: {
|
||||
value: {
|
||||
nations: provision.vehicleFilter.include.nations.split(' '),
|
||||
},
|
||||
},
|
||||
@@ -1538,9 +1575,9 @@ export async function definitions() {
|
||||
entry.exclude!.push({
|
||||
filterType: {
|
||||
$case: 'ids',
|
||||
ids: {
|
||||
value: {
|
||||
ids: excludeRaw.name
|
||||
.split(' ')
|
||||
.split(/ +/)
|
||||
.map((key) => tankStringIdMap[key]),
|
||||
},
|
||||
},
|
||||
@@ -1549,7 +1586,7 @@ export async function definitions() {
|
||||
entry.exclude!.push({
|
||||
filterType: {
|
||||
$case: 'categories',
|
||||
categories: {
|
||||
value: {
|
||||
categories: excludeRaw.extendedTags
|
||||
.split(' ')
|
||||
.map(
|
||||
@@ -1567,7 +1604,7 @@ export async function definitions() {
|
||||
entry.exclude!.push({
|
||||
filterType: {
|
||||
$case: 'nations',
|
||||
nations: {
|
||||
value: {
|
||||
nations: provision.vehicleFilter.exclude.nations.split(' '),
|
||||
},
|
||||
},
|
||||
@@ -1617,47 +1654,47 @@ export async function definitions() {
|
||||
{
|
||||
content: encodePB64(GameDefinitions, gameDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/game.cdon.lz4',
|
||||
path: 'definitions/game.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(TankDefinitions, tankDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/tanks.cdon.lz4',
|
||||
path: 'definitions/tanks.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(ModelDefinitions, modelDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/models.cdon.lz4',
|
||||
path: 'definitions/models.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(EquipmentDefinitions, equipmentDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/equipment.cdon.lz4',
|
||||
path: 'definitions/equipment.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(ConsumableDefinitions, consumableDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/consumables.cdon.lz4',
|
||||
path: 'definitions/consumables.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(ProvisionDefinitions, provisionDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/provisions.cdon.lz4',
|
||||
path: 'definitions/provisions.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(SkillDefinitions, skillDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/skills.cdon.lz4',
|
||||
path: 'definitions/skills.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(MapDefinitions, mapDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/maps.cdon.lz4',
|
||||
path: 'definitions/maps.pb',
|
||||
},
|
||||
{
|
||||
content: encodePB64(CamouflageDefinitions, camouflageDefinitions),
|
||||
encoding: 'base64',
|
||||
path: 'definitions/camouflages.cdon.lz4',
|
||||
path: 'definitions/camouflages.pb',
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -48,7 +48,8 @@ for (const method of methods) {
|
||||
try {
|
||||
await method();
|
||||
} catch (error) {
|
||||
console.warn(`Failed method ${method.name}; skipping...`, error);
|
||||
console.warn(`Failed method ${method.name}; skipping...`);
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,7 @@ export async function moduleIcons() {
|
||||
console.log('Building module icons...');
|
||||
|
||||
const changes = await Promise.all(
|
||||
(
|
||||
await readdir(`${DATA}/Gfx/UI/ModulesTechTree`)
|
||||
)
|
||||
(await readdir(`${DATA}/Gfx/UI/ModulesTechTree`))
|
||||
.filter(
|
||||
(file) =>
|
||||
!file.endsWith('@2x.packed.webp.dvpl') && file.startsWith('vehicle'),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { tankDefinitions } from '@blitzkit/core';
|
||||
import { fetchTankDefinitions } from '@blitzkit/core';
|
||||
|
||||
// random vercel bug forces require import
|
||||
const { writeFileSync } = require('fs');
|
||||
|
||||
console.log('Building sitemap...');
|
||||
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const values = Object.values(awaitedTankDefinitions);
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const values = Object.values(tankDefinitions);
|
||||
const txt = values
|
||||
.map((tank) => `https://blitzkit.app/tools/tankopedia/${tank.id}/`)
|
||||
.join('\n');
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
import {
|
||||
createDefaultSkills,
|
||||
equipmentDefinitions,
|
||||
modelDefinitions,
|
||||
provisionDefinitions,
|
||||
skillDefinitions,
|
||||
tankDefinitions,
|
||||
} from '@blitzkit/core';
|
||||
import { createDefaultSkills } from '@blitzkit/core';
|
||||
import { PlusIcon } from '@radix-ui/react-icons';
|
||||
import { Box, Flex, Heading, IconButton, Text } from '@radix-ui/themes';
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
||||
import { use, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { CompareControls } from '../../../../../website/src/components/Controls';
|
||||
import { DamageWarning } from '../../../../../website/src/components/DamageWarning';
|
||||
import { PageWrapper } from '../../../components/PageWrapper';
|
||||
import { tankCharacteristics } from '../../../core/blitzkit/tankCharacteristics';
|
||||
import { tankToCompareMember } from '../../../core/blitzkit/tankToCompareMember';
|
||||
import * as CompareEphemeral from '../../../stores/compareEphemeral';
|
||||
import { CompareTable } from '../../../../../website/src/components/Compare/CompareTable';
|
||||
|
||||
export default function Page() {
|
||||
const pathname = usePathname();
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { averageDefinitionsArray, tankDefinitions } from '@blitzkit/core';
|
||||
import { Table } from '@radix-ui/themes';
|
||||
import { times } from 'lodash-es';
|
||||
import { Suspense, use, useEffect, useMemo, useState } from 'react';
|
||||
import { filterTank } from '../../../../core/blitzkit/filterTank';
|
||||
import * as TankFilters from '../../../../stores/tankFilters';
|
||||
import * as TankPerformancePersistent from '../../../../stores/tankPerformancePersistent';
|
||||
import * as TankPerformanceSort from '../../../../stores/tankPerformanceSort';
|
||||
import { RowLoader } from './RowLoader';
|
||||
import { TankRow } from './TankRow';
|
||||
import { Total } from './Total';
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import {
|
||||
averageDefinitionsArray,
|
||||
formatCompact,
|
||||
TANK_CLASSES,
|
||||
TankClass,
|
||||
tankDefinitions,
|
||||
Tier,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
} from '@blitzkit/core';
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
STAT_NAMES,
|
||||
Stat,
|
||||
UNLOCALIZED_REGION_NAMES_SHORT,
|
||||
blitzStarsTankAverages,
|
||||
deltaTankStats,
|
||||
fetchTankDefinitions,
|
||||
generateStats,
|
||||
getAccountInfo,
|
||||
getTankStats,
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
prettifyStats,
|
||||
searchPlayersAcrossRegions,
|
||||
sumBlitzStarsStats,
|
||||
tankDefinitions,
|
||||
} from '@blitzkit/core';
|
||||
import {
|
||||
ArrowDownIcon,
|
||||
@@ -37,9 +36,8 @@ import {
|
||||
} from '@radix-ui/themes';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { use, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { PageWrapper } from '../../../components/PageWrapper';
|
||||
import { TankRowHeaderCell } from '../../../components/TankRowHeaderCell';
|
||||
import * as Session from '../../../stores/session';
|
||||
|
||||
const awaitedTankDefinitions = await fetchTankDefinitions();
|
||||
|
||||
export default function Page({
|
||||
searchParams,
|
||||
@@ -47,8 +45,6 @@ export default function Page({
|
||||
searchParams: { id?: string };
|
||||
}) {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const awaitedTankDefinitions = use(tankDefinitions);
|
||||
const awaitedTankAvearges = use(blitzStarsTankAverages);
|
||||
const [showSearch, setShowSearch] = useState(false);
|
||||
const [searching, setSearching] = useState(false);
|
||||
const [searchResults, setSearchResults] = useState<AccountListWithServer>([]);
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import {
|
||||
modelDefinitions,
|
||||
provisionDefinitions,
|
||||
tankDefinitions,
|
||||
tankDefinitionsArray,
|
||||
fetchModelDefinitions,
|
||||
fetchTankDefinitions,
|
||||
tankIcon,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
} from '@blitzkit/core';
|
||||
import strings from '@blitzkit/core/lang/en-US.json';
|
||||
import { ReactNode } from 'react';
|
||||
import * as Duel from '../../../../stores/duel';
|
||||
import * as TankopediaEphemeral from '../../../../stores/tankopediaEphemeral';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const tanks = await tankDefinitionsArray;
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const tanks = Object.values(tankDefinitions.tanks);
|
||||
return tanks.map((tank) => ({ id: `${tank.id}` }));
|
||||
}
|
||||
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const definitions = await fetchModelDefinitions();
|
||||
|
||||
export default async function Layout({
|
||||
children,
|
||||
params,
|
||||
@@ -24,11 +24,9 @@ export default async function Layout({
|
||||
params: { id: string };
|
||||
}) {
|
||||
const id = Number(params.id);
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const awaitedModelDefinitions = await modelDefinitions;
|
||||
const tankModelDefinition = awaitedModelDefinitions[id];
|
||||
const tankModelDefinition = definitions[id];
|
||||
const awaitedProvisionDefinitions = await provisionDefinitions;
|
||||
const tank = awaitedTankDefinitions[id];
|
||||
const tank = tankDefinitions[id];
|
||||
const title = `${tank.name} - Tier ${TIER_ROMAN_NUMERALS[tank.tier]} ${
|
||||
(strings.common.nations_adjectives as Record<string, string>)[tank.nation]
|
||||
} ${strings.common.tank_class_short[tank.class]}`;
|
||||
@@ -38,7 +36,7 @@ export default async function Layout({
|
||||
<TankopediaEphemeral.Provider data={tankModelDefinition}>
|
||||
<Duel.Provider
|
||||
data={{
|
||||
tank: awaitedTankDefinitions[id],
|
||||
tank: tankDefinitions[id],
|
||||
provisionDefinitions: awaitedProvisionDefinitions,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -7,16 +7,5 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
".next/types/**/*.ts",
|
||||
"../website/src/components/TankSearch/components/FilterControl.tsx",
|
||||
"../website/src/components/Tankopedia/HeroSection/index.tsx",
|
||||
"../website/src/components/Tankopedia/GameModeSection.tsx",
|
||||
"../website/src/components/Tankopedia/CharacteristicsSection.tsx",
|
||||
"../website/src/components/Tankopedia/MetaSection",
|
||||
"../website/src/components/Tankopedia/HistorySection.tsx",
|
||||
"../website/src/components/Tankopedia/CalloutsSection.tsx",
|
||||
"../website/src/components/Tankopedia/ShotDisplaySection.tsx"
|
||||
, "../website/src/components/Tankopedia/CharacteristicsSection/components/ConfigurationChildWrapper.tsx", "../website/src/components/Tankopedia/VideoSection.tsx", "../website/src/components/DamageWarning.tsx", "../website/src/components/Controls.tsx", "../website/src/components/Compare/CompareTable.tsx" ]
|
||||
"include": ["src/**/*", ".next/types/**/*.ts"]
|
||||
}
|
||||
+8
-9
@@ -1,20 +1,19 @@
|
||||
import { compositeStatsKeys, tankDefinitionsArray } from '@blitzkit/core';
|
||||
import { compositeStatsKeys, fetchTankDefinitions } from '@blitzkit/core';
|
||||
import strings from '@blitzkit/core/lang/en-US.json';
|
||||
import { use } from 'react';
|
||||
import {
|
||||
BreakdownEmbedCard,
|
||||
BreakdownEmbedWrapper,
|
||||
} from '../../../../components/TanksEmbed';
|
||||
import { breakdownConfig } from '../../../../../../website/src/constants/embeds';
|
||||
import { useEmbedStateCurry } from '../../../../stores/embedState/utilities';
|
||||
import { breakdownConfig } from '../../constants/embeds';
|
||||
import { useEmbedStateCurry } from '../../stores/embedState/utilities';
|
||||
import { BreakdownEmbedCard, BreakdownEmbedWrapper } from '../TanksEmbed';
|
||||
|
||||
export const compositeStatsKeysOptions = compositeStatsKeys.map((value) => ({
|
||||
label: strings.common.composite_stats[value],
|
||||
value,
|
||||
}));
|
||||
|
||||
const tanks = await fetchTankDefinitions().then((tanks) =>
|
||||
Object.values(tanks.tanks),
|
||||
);
|
||||
|
||||
export function BreakdownPreview() {
|
||||
const tanks = use(tankDefinitionsArray);
|
||||
const { useState } = useEmbedStateCurry<typeof breakdownConfig>();
|
||||
|
||||
return (
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
fetchTankNames,
|
||||
normalizeBoundingBox,
|
||||
resolveDpm,
|
||||
resolveGun,
|
||||
unionBoundingBox,
|
||||
type TankDefinition,
|
||||
} from '@blitzkit/core';
|
||||
@@ -115,10 +114,10 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.camouflageStill *
|
||||
resolveGun(a.turrets.at(-1)!.guns.at(-1)!).gun!
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gunType!.value.base
|
||||
.camouflageLoss -
|
||||
b.camouflageStill *
|
||||
resolveGun(b.turrets.at(-1)!.guns.at(-1)!).gun!
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gunType!.value.base
|
||||
.camouflageLoss,
|
||||
);
|
||||
break;
|
||||
@@ -143,8 +142,8 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
bTurretModelDefinition.boundingBox,
|
||||
),
|
||||
);
|
||||
const aVolume = aSize[0] * aSize[1] * aSize[2];
|
||||
const bVolume = bSize[0] * bSize[1] * bSize[2];
|
||||
const aVolume = aSize.x * aSize.y * aSize.z;
|
||||
const bVolume = bSize.x * bSize.y * bSize.z;
|
||||
|
||||
return aVolume - bVolume;
|
||||
});
|
||||
@@ -170,8 +169,8 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
bTurretModelDefinition.boundingBox,
|
||||
),
|
||||
);
|
||||
const aLength = Math.max(aSize[0], aSize[1], aSize[2]);
|
||||
const bLength = Math.max(bSize[0], bSize[1], bSize[2]);
|
||||
const aLength = Math.max(aSize.x, aSize.y, aSize.z);
|
||||
const bLength = Math.max(bSize.x, bSize.y, bSize.z);
|
||||
|
||||
return aLength - bLength;
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveNearPenetration, tankDefinitions } from '@blitzkit/core';
|
||||
import { fetchTankDefinitions, TankType } from '@blitzkit/core';
|
||||
import { Box, Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import { Suspense, useEffect, useMemo, useRef } from 'react';
|
||||
import { NAVBAR_HEIGHT } from '../../../constants/navbar';
|
||||
@@ -11,7 +11,7 @@ import { Options } from './components/Options';
|
||||
import { TankSandbox } from './components/TankSandbox';
|
||||
import { TankSandboxLoader } from './components/TankSandboxLoader';
|
||||
|
||||
const awaitedTankDefinitions = await tankDefinitions;
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
|
||||
export function HeroSection() {
|
||||
const canvas = useRef<HTMLCanvasElement>(null);
|
||||
@@ -20,13 +20,13 @@ export function HeroSection() {
|
||||
const Icon = classIcons[protagonist.class];
|
||||
// const [dummyLoader, setDummyLoader] = useState(true);
|
||||
const treeColor =
|
||||
protagonist.treeType === 'collector'
|
||||
protagonist.type === TankType.COLLECTOR
|
||||
? 'blue'
|
||||
: protagonist.treeType === 'premium'
|
||||
: protagonist.type === TankType.PREMIUM
|
||||
? 'amber'
|
||||
: undefined;
|
||||
const thicknessRange = useMemo(() => {
|
||||
const entries = Object.values(awaitedTankDefinitions);
|
||||
const entries = Object.values(tankDefinitions.tanks);
|
||||
const filtered = entries.filter(
|
||||
(thisTank) => thisTank.tier === protagonist.tier,
|
||||
);
|
||||
@@ -34,9 +34,8 @@ export function HeroSection() {
|
||||
(filtered.reduce((accumulator, thisTank) => {
|
||||
return (
|
||||
accumulator +
|
||||
resolveNearPenetration(
|
||||
thisTank.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration,
|
||||
)
|
||||
thisTank.turrets.at(-1)!.guns.at(-1)!.gunType!.value.base.shells[0]
|
||||
.penetration.near
|
||||
);
|
||||
}, 0) /
|
||||
filtered.length) *
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { CompositeStatsKey } from '@blitzkit/core';
|
||||
import { type CompositeStatsKey } from '@blitzkit/core';
|
||||
import { grayA, grayDark, grayDarkA } from '@radix-ui/colors';
|
||||
import type { ReactNode } from 'react';
|
||||
import {
|
||||
BreakdownPreview,
|
||||
compositeStatsKeysOptions,
|
||||
} from '../../../website-legacy/src/app/tools/embed/configurations/breakdown';
|
||||
} from '../components/Embeds/breakdown';
|
||||
import type {
|
||||
EmbedConfig,
|
||||
ExtractEmbedConfigTypes,
|
||||
|
||||
Reference in new issue
Block a user