diff --git a/.github/workflows/cd-assets.yml b/.github/workflows/cd-assets.yml
index 250cd6706..3b7757240 100644
--- a/.github/workflows/cd-assets.yml
+++ b/.github/workflows/cd-assets.yml
@@ -2,7 +2,6 @@ name: CD Build Assets
on:
push:
- branches: [dev, main]
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
@@ -18,6 +17,9 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ token: ${{ secrets.GH_TOKEN }}
- name: Use node
uses: actions/setup-node@v4
@@ -46,6 +48,14 @@ jobs:
- name: Run DepotDownloader
run: ./temp/depotDownloader/DepotDownloader.exe -app 444200 -username ${{ secrets.DEPOT_DOWNLOADER_USERNAME }} -password "${{ secrets.DEPOT_DOWNLOADER_PASSWORD }}"
+ - name: Apply patches
+ run: |
+ $env:GH_TOKEN = "${{ secrets.GH_TOKEN }}"
+ $env:DISCORD_TOKEN = "${{ secrets.DISCORD_TOKEN }}"
+ $env:DISCORD_BLITZ_DB = "${{ secrets.DISCORD_BLITZ_DB }}"
+ $env:WOTB_DLC_CDN = "${{ secrets.WOTB_DLC_CDN }}"
+ yarn setup:patches --depot
+
- name: Build assets
run: |
$env:GH_TOKEN = "${{ secrets.GH_TOKEN }}"
diff --git a/.github/workflows/cd-host.yml b/.github/workflows/cd-host.yml
index 435540fb6..b75d31c4a 100644
--- a/.github/workflows/cd-host.yml
+++ b/.github/workflows/cd-host.yml
@@ -6,6 +6,8 @@ on:
schedule:
- cron: '0 */5 * * *'
workflow_dispatch:
+ release:
+ types: [created, published, released, edited]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
diff --git a/.gitignore b/.gitignore
index 3464b9cc4..7dc3942e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,5 @@ tsconfig.tsbuildinfo
temp/
/.yarn
/.VSCodeCounter
-/.yarn
\ No newline at end of file
+/.yarn
+depots
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index b72b99f10..8c41337cf 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -7,6 +7,7 @@
"alphatest",
"APAC",
"apcr",
+ "applypatches",
"artefacts",
"atgm",
"AYUV",
@@ -21,6 +22,7 @@
"CDON",
"classname",
"cleandist",
+ "closedkrieg",
"cockroackdb",
"Coef",
"cooldown",
diff --git a/docs/changelogs/1.16.4.md b/docs/changelogs/1.16.4.md
new file mode 100644
index 000000000..ec81946b8
--- /dev/null
+++ b/docs/changelogs/1.16.4.md
@@ -0,0 +1,19 @@
+# Blitzkrieg 1.16.4
+
+A few issues here and there addressed for good measure.
+
+## Changes
+
+- Armor layer penetration indices are now much more compact.
+
+## Fixes
+
+- Reverted splash mechanics changes from `1.16.1` as it made them less accurate.
+- Auto-reloaders now report their DPM stats correctly with crew training.
+
+## Technical Changes
+
+- All files in the project were reviewed and constant exports were isolated.
+- The downloaded game in the workflow now also includes the latest patches.
+- Asset building now uses sharp under the hood which should in theory be faster.
+- Fetching CDON LZ4 files now uses `no-store` instead of `no-cache`
diff --git a/package.json b/package.json
index b4f9ff3f3..3546cc0e0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "blitzkrieg",
- "version": "1.16.2",
+ "version": "1.16.4",
"description": "🎉 Tools for everything World of Tanks Blitz",
"main": "src/server.ts",
"type": "module",
@@ -19,6 +19,7 @@
"start:website": "next start",
"host:docs": "vitepress preview docs",
"publish:ratingsleaderboard": "vite-node --script scripts/buildRatingsLeaderboard --publish",
+ "setup:patches": "vite-node --script scripts/applyPatches",
"lint": "npx tsc",
"lint:website": "next lint",
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
diff --git a/scripts/applyPatches.ts b/scripts/applyPatches.ts
new file mode 100644
index 000000000..7c2b51fe1
--- /dev/null
+++ b/scripts/applyPatches.ts
@@ -0,0 +1,48 @@
+import { mkdir, writeFile } from 'fs/promises';
+import { parse as parsePath } from 'path';
+import { parse as parseYaml } from 'yaml';
+import { readStringDVPL } from '../src/core/blitz/readStringDVPL';
+import { writeDVPL } from '../src/core/blitz/writeDVPL';
+import { secrets } from '../src/core/blitzkrieg/secrets';
+import { dvp } from '../submodules/closedkrieg/src/dvp';
+import { DATA } from './buildAssets/constants';
+
+const versionTextFile = await readStringDVPL(`${DATA}/version.txt.dvpl`);
+const currentVersion = versionTextFile
+ .split(' ')[0]
+ .split('.')
+ .slice(0, 3)
+ .join('.');
+
+console.log(`Installing patches for ${currentVersion}...`);
+
+let patchIndex = 1;
+while (true) {
+ const response = await fetch(
+ `${secrets.WOTB_DLC_CDN}/dlc/s${currentVersion}_${patchIndex}.yaml`,
+ );
+
+ if (response.status === 200) {
+ console.log(`Applying patch ${patchIndex}...`);
+
+ const data = parseYaml(await response.text());
+ const dvpm = await fetch(`${secrets.WOTB_DLC_CDN}/dlc/${data.dx11}`).then(
+ (response) => response.arrayBuffer(),
+ );
+ const dvpd = await fetch(
+ `${secrets.WOTB_DLC_CDN}/dlc/${data.dx11.replace('.dvpm', '.dvpd')}`,
+ ).then((response) => response.arrayBuffer());
+ const files = await dvp(dvpm, dvpd);
+
+ await Promise.all(
+ files.map(async ({ path, data }) => {
+ const { dir } = parsePath(path);
+
+ await mkdir(`${DATA}/${dir}`, { recursive: true });
+ await writeFile(`${DATA}/${path}.dvpl`, writeDVPL(Buffer.from(data)));
+ }),
+ );
+
+ patchIndex++;
+ } else break;
+}
diff --git a/scripts/buildAssets/constants.ts b/scripts/buildAssets/constants.ts
index 75907fa3a..d7649d279 100644
--- a/scripts/buildAssets/constants.ts
+++ b/scripts/buildAssets/constants.ts
@@ -24,7 +24,7 @@ export const POI = {
collisionMeshes: '3d/Tanks/CollisionMeshes',
optionalDevices: 'XML/item_defs/vehicles/common/optional_devices.xml',
optionalDeviceSlots:
- 'XML/item_defs/vehicles/common/optional_device_slots.xml',
+ 'XML/item_defs/vehicles/common/optional_device_slots.xml',
optionalDeviceImageMappings:
'UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml',
optionalDevicesImage:
diff --git a/scripts/buildAssets/tankModels.ts b/scripts/buildAssets/tankModels.ts
index edf276fe9..f639dac88 100644
--- a/scripts/buildAssets/tankModels.ts
+++ b/scripts/buildAssets/tankModels.ts
@@ -1,21 +1,15 @@
import { NodeIO } from '@gltf-transform/core';
import { readdir } from 'fs/promises';
-import { Vector3Tuple } from 'three';
import { extractModel } from '../../src/core/blitz/extractModel';
import { readXMLDVPL } from '../../src/core/blitz/readXMLDVPL';
import { readYAMLDVPL } from '../../src/core/blitz/readYAMLDVPL';
import { toUniqueId } from '../../src/core/blitz/toUniqueId';
-// import { AssetCommit } from '../../src/core/github/assetCommit';
import { commitAssets } from '../../src/core/blitzkrieg/commitAssets';
import { FileChange } from '../../src/core/blitzkrieg/commitMultipleFiles';
import { DATA, POI } from './constants';
import { VehicleDefinitionList } from './definitions';
import { TankParameters } from './tankIcons';
-interface VehicleCustomization {
- armorColor: string;
-}
-
export async function tankModels(production: boolean) {
console.log('Building tank models...');
@@ -27,18 +21,9 @@ export async function tankModels(production: boolean) {
for (const nationIndex in nations) {
const nation = nations[nationIndex];
const changes: FileChange[] = [];
- // const assetCommit = new AssetCommit(`tank models ${nation}`, production);
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/${POI.vehicleDefinitions}/${nation}/list.xml.dvpl`,
);
- const customization = await readXMLDVPL<{ root: VehicleCustomization }>(
- `${DATA}/${POI.vehicleDefinitions}/${nation}/customization.xml.dvpl`,
- );
- const baseColor = customization.root.armorColor
- .split(' ')
- .slice(0, 3)
- .map(Number)
- .map((channel) => channel / 255) as Vector3Tuple;
console.log(`Building models for ${nation}`);
@@ -56,11 +41,8 @@ export async function tankModels(production: boolean) {
const model = await extractModel(
DATA,
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, ''),
- baseColor,
);
- // writeFile(`test.${tankKey}.glb`, await nodeIO.writeBinary(model));
-
changes.push({
path: `3d/tanks/models/${id}.glb`,
content: Buffer.from(await nodeIO.writeBinary(model)).toString(
@@ -71,7 +53,6 @@ export async function tankModels(production: boolean) {
}),
);
- // assetCommit.push();
await commitAssets(`tank models ${nation}`, changes, production);
}
}
diff --git a/src/app/embeds/session/page.tsx b/src/app/embeds/session/page.tsx
index 85b766b22..0d724f360 100644
--- a/src/app/embeds/session/page.tsx
+++ b/src/app/embeds/session/page.tsx
@@ -5,6 +5,7 @@ import { useEffect, useState } from 'react';
import * as Breakdown from '../../../components/Breakdown';
import { WARGAMING_APPLICATION_ID } from '../../../constants/wargamingApplicationID';
import fetchBlitz from '../../../core/blitz/fetchBlitz';
+import { resetSession } from '../../../core/blitzkrieg/resetSession';
import {
TankDefinition,
tankDefinitions,
@@ -13,10 +14,7 @@ import { tankAverages } from '../../../core/blitzstars/tankAverages';
import calculateWN8 from '../../../core/statistics/calculateWN8';
import { deltaTankStats } from '../../../core/statistics/deltaTankStats';
import getWN8Percentile from '../../../core/statistics/getWN8Percentile';
-import mutateSession, {
- resetSession,
- useSession,
-} from '../../../stores/session';
+import mutateSession, { useSession } from '../../../stores/session';
import { IndividualTankStats, TanksStats } from '../../../types/tanksStats';
import { CustomColumnDisplay } from '../../tools/session/components/CustomColumn';
import { Menu } from '../../tools/session/components/Menu';
diff --git a/src/app/tools/session/page.tsx b/src/app/tools/session/page.tsx
index a092b4f8a..10123cb34 100644
--- a/src/app/tools/session/page.tsx
+++ b/src/app/tools/session/page.tsx
@@ -22,7 +22,9 @@ import { UNLOCALIZED_REGION_NAMES } from '../../../constants/regions';
import searchPlayersAcrossRegions, {
AccountListWithServer,
} from '../../../core/blitz/searchPlayersAcrossRegions';
-import { resetSession, setSession, useSession } from '../../../stores/session';
+import { resetSession } from '../../../core/blitzkrieg/resetSession';
+import { setSession } from '../../../core/blitzkrieg/setSession';
+import { useSession } from '../../../stores/session';
import SessionPage from '../../embeds/session/page';
import { Menu } from './components/Menu';
import * as styles from './page.css';
diff --git a/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx b/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx
index ffe8033f1..9ed4b869b 100644
--- a/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx
+++ b/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx
@@ -19,7 +19,7 @@ import { pushTankopediaPath } from '../../../../../core/blitzkrieg/pushTankopedi
import {
SHELL_NAMES,
TIER_ROMAN_NUMERALS,
-} from '../../../../../core/blitzkrieg/tankDefinitions';
+} from '../../../../../core/blitzkrieg/tankDefinitions/constants';
import { mutateDuel, useDuel } from '../../../../../stores/duel';
import {
mutateTankopediaTemporary,
diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/components/Modules.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/components/Modules.tsx
index fc258968c..3f3f113ce 100644
--- a/src/app/tools/tankopedia/[id]/components/Characteristics/components/Modules.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Characteristics/components/Modules.tsx
@@ -1,6 +1,6 @@
import { Flex, Heading } from '@radix-ui/themes';
import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
-import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkrieg/tankDefinitions';
+import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkrieg/tankDefinitions/constants';
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
import { mutateTankopediaTemporary } from '../../../../../../../stores/tankopedia';
import { ConfigurationChildWrapper } from './ConfigurationChildWrapper';
diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx
index 48efd9cc0..f0f77649c 100644
--- a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx
@@ -18,7 +18,7 @@ import {
CREW_MEMBER_NAMES,
GUN_TYPE_NAMES,
SHELL_NAMES,
-} from '../../../../../../core/blitzkrieg/tankDefinitions';
+} from '../../../../../../core/blitzkrieg/tankDefinitions/constants';
import { unionBoundingBox } from '../../../../../../core/blitzkrieg/unionBoundingBox';
import { useConsumable } from '../../../../../../hooks/useConsumable';
import { useEquipment } from '../../../../../../hooks/useEquipment';
@@ -268,9 +268,13 @@ export function Characteristics() {
<>
{gun.reload.at(-1)! < gun.reload.at(-2)!
- ? (shell.damage.armor / (gun.reload.at(-1)! + gun.intraClip)) *
+ ? ((damageCoefficient * shell.damage.armor) /
+ (gun.reload.at(-1)! * reloadCoefficient +
+ gun.intraClip * intraClipCoefficient)) *
60
- : (shell.damage.armor / gun.reload[0]) * 60}
+ : ((damageCoefficient * shell.damage.armor) /
+ (gun.reload[0] * reloadCoefficient)) *
+ 60}
{gun.reload.at(-1)! < gun.reload.at(-2)!
- ? (shell.damage.armor / (gun.reload.at(-1)! + gun.intraClip)) *
+ ? ((damageCoefficient * shell.damage.armor) /
+ (gun.reload.at(-1)! * reloadCoefficient +
+ gun.intraClip * intraClipCoefficient)) *
(60 -
- (gun.reload.slice(0, -1).length - 1) * gun.intraClip) +
- shell.damage.armor * gun.reload.slice(0, -1).length
- : (shell.damage.armor / (gun.reload[0] + gun.intraClip)) *
- (60 - (gun.reload.slice(1).length - 1) * gun.intraClip) +
- shell.damage.armor * gun.reload.slice(1).length}
+ (gun.reload.slice(0, -1).length - 1) *
+ gun.intraClip *
+ intraClipCoefficient) +
+ damageCoefficient *
+ shell.damage.armor *
+ gun.reload.slice(0, -1).length
+ : ((damageCoefficient * shell.damage.armor) /
+ (gun.reload[0] * reloadCoefficient +
+ gun.intraClip * intraClipCoefficient)) *
+ (60 -
+ (gun.reload.slice(1).length - 1) *
+ gun.intraClip *
+ intraClipCoefficient) +
+ damageCoefficient *
+ shell.damage.armor *
+ gun.reload.slice(1).length}
(
+ async (resolve) => {
+ resolve({
+ inProduction: true,
+ inPublic: true,
+
+ command: await addPeriodicFilterOptions(
+ createLocalizedCommand('breakdown'),
+ (option) => option.addStringOption(addUsernameChoices),
+ ),
+
+ async handler(interaction) {
+ const player = await resolvePlayerFromCommand(interaction);
+ const period = resolvePeriodFromCommand(player.region, interaction);
+ const filters = await getFiltersFromCommand(interaction);
+ const path = commandToURL(interaction, {
+ ...player,
+ ...getCustomPeriodParams(interaction),
+ ...filters,
+ });
+
+ return [
+ ...(await renderBreakdown(
+ player,
+ period,
+ filters,
+ interaction.locale,
+ )),
+ buttonRefresh(interaction, path),
+ await getBlitzStarsLinkButton(player.region, player.id),
+ ];
+ },
+
+ autocomplete: (interaction) => {
+ autocompleteUsername(interaction);
+ autocompleteTanks(interaction);
+ },
+
+ async button(interaction) {
+ const player = await resolvePlayerFromButton(interaction);
+ const period = resolvePeriodFromButton(player.region, interaction);
+ const filters = getFiltersFromButton(interaction);
+
+ return await renderBreakdown(
+ player,
+ period,
+ filters,
+ interaction.locale,
+ );
+ },
+ });
+ },
+);
diff --git a/src/commands/breakdown.tsx b/src/commands/breakdown/render.tsx
similarity index 69%
rename from src/commands/breakdown.tsx
rename to src/commands/breakdown/render.tsx
index a231eda2d..ff7b087ca 100644
--- a/src/commands/breakdown.tsx
+++ b/src/commands/breakdown/render.tsx
@@ -1,43 +1,25 @@
import { Locale } from 'discord.js';
import { chunk } from 'lodash';
-import * as Breakdown from '../components/Breakdown';
-import CommandWrapper from '../components/CommandWrapper';
-import NoData from '../components/NoData';
-import TitleBar from '../components/TitleBar';
-import { AllStats, getAccountInfo } from '../core/blitz/getAccountInfo';
-import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo';
-import getTankStats from '../core/blitz/getTankStats';
-import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
+import * as Breakdown from '../../components/Breakdown';
+import CommandWrapper from '../../components/CommandWrapper';
+import NoData from '../../components/NoData';
+import TitleBar from '../../components/TitleBar';
+import { AllStats, getAccountInfo } from '../../core/blitz/getAccountInfo';
+import { getClanAccountInfo } from '../../core/blitz/getClanAccountInfo';
+import getTankStats from '../../core/blitz/getTankStats';
+import { filtersToDescription } from '../../core/blitzkrieg/filtersToDescription';
import {
TankDefinition,
tankDefinitions,
-} from '../core/blitzkrieg/tankDefinitions';
-import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
-import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
-import { tankAverages } from '../core/blitzstars/tankAverages';
-import addPeriodicFilterOptions from '../core/discord/addPeriodicFilterOptions';
-import addUsernameChoices from '../core/discord/addUsernameChoices';
-import autocompleteTanks from '../core/discord/autocompleteTanks';
-import autocompleteUsername from '../core/discord/autocompleteUsername';
-import { buttonRefresh } from '../core/discord/buttonRefresh';
-import commandToURL from '../core/discord/commandToURL';
-import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
-import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
-import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
-import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
-import resolvePeriodFromButton from '../core/discord/resolvePeriodFromButton';
-import resolvePeriodFromCommand, {
- ResolvedPeriod,
-} from '../core/discord/resolvePeriodFromCommand';
-import resolvePlayerFromButton from '../core/discord/resolvePlayerFromButton';
-import resolvePlayerFromCommand, {
- ResolvedPlayer,
-} from '../core/discord/resolvePlayerFromCommand';
-import { translator } from '../core/localization/translator';
-import calculateWN8 from '../core/statistics/calculateWN8';
-import { StatFilters, filterStats } from '../core/statistics/filterStats';
-import getWN8Percentile from '../core/statistics/getWN8Percentile';
-import { CommandRegistry } from '../events/interactionCreate';
+} from '../../core/blitzkrieg/tankDefinitions';
+import getStatsInPeriod from '../../core/blitzstars/getStatsInPeriod';
+import { tankAverages } from '../../core/blitzstars/tankAverages';
+import { ResolvedPeriod } from '../../core/discord/resolvePeriodFromCommand';
+import { ResolvedPlayer } from '../../core/discord/resolvePlayerFromCommand';
+import { translator } from '../../core/localization/translator';
+import calculateWN8 from '../../core/statistics/calculateWN8';
+import { StatFilters, filterStats } from '../../core/statistics/filterStats';
+import getWN8Percentile from '../../core/statistics/getWN8Percentile';
const ROWS_PER_PAGE = 8;
const MAX_PAGES = 9;
@@ -296,57 +278,3 @@ export async function renderBreakdown(
];
}
}
-
-export const breakdownCommand = new Promise(
- async (resolve) => {
- resolve({
- inProduction: true,
- inPublic: true,
-
- command: await addPeriodicFilterOptions(
- createLocalizedCommand('breakdown'),
- (option) => option.addStringOption(addUsernameChoices),
- ),
-
- async handler(interaction) {
- const player = await resolvePlayerFromCommand(interaction);
- const period = resolvePeriodFromCommand(player.region, interaction);
- const filters = await getFiltersFromCommand(interaction);
- const path = commandToURL(interaction, {
- ...player,
- ...getCustomPeriodParams(interaction),
- ...filters,
- });
-
- return [
- ...(await renderBreakdown(
- player,
- period,
- filters,
- interaction.locale,
- )),
- buttonRefresh(interaction, path),
- await getBlitzStarsLinkButton(player.region, player.id),
- ];
- },
-
- autocomplete: (interaction) => {
- autocompleteUsername(interaction);
- autocompleteTanks(interaction);
- },
-
- async button(interaction) {
- const player = await resolvePlayerFromButton(interaction);
- const period = resolvePeriodFromButton(player.region, interaction);
- const filters = getFiltersFromButton(interaction);
-
- return await renderBreakdown(
- player,
- period,
- filters,
- interaction.locale,
- );
- },
- });
- },
-);
diff --git a/src/commands/evolution.tsx b/src/commands/evolution.tsx
index 52dd4c4d4..75233426f 100644
--- a/src/commands/evolution.tsx
+++ b/src/commands/evolution.tsx
@@ -1,6 +1,7 @@
import { Locale, SlashCommandSubcommandGroupBuilder } from 'discord.js';
import CommandWrapper from '../components/CommandWrapper';
import * as Graph from '../components/Graph';
+import { LineColor } from '../components/Graph/components/Line/constants';
import NoData from '../components/NoData';
import TitleBar from '../components/TitleBar';
import { getAccountInfo } from '../core/blitz/getAccountInfo';
@@ -93,7 +94,7 @@ async function render(
xMaxLabel={new Date(maxTime * 1000).toLocaleDateString(locale)}
>
{Graph.Line({
- color: Graph.LineColor.Red,
+ color: LineColor.Red,
plot: plot,
minY,
maxY,
diff --git a/src/commands/ownedTanks.tsx b/src/commands/ownedTanks.tsx
index 88037733d..c5faee701 100644
--- a/src/commands/ownedTanks.tsx
+++ b/src/commands/ownedTanks.tsx
@@ -7,12 +7,11 @@ import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo';
import getTankStats from '../core/blitz/getTankStats';
import { emblemIdToURL } from '../core/blitzkrieg/emblemIdToURL';
import {
- TIER_ROMAN_NUMERALS,
TankDefinition,
Tier,
tankDefinitions,
} from '../core/blitzkrieg/tankDefinitions';
-import { tankIcon } from '../core/blitzkrieg/tankIcon';
+import { TIER_ROMAN_NUMERALS } from '../core/blitzkrieg/tankDefinitions/constants';
import addTierChoices from '../core/discord/addTierChoices';
import addUsernameChoices from '../core/discord/addUsernameChoices';
import autocompleteUsername from '../core/discord/autocompleteUsername';
@@ -100,7 +99,6 @@ export const ownedTanksCommand = new Promise((resolve) => {
key={tank.id}
name={tank.name}
tankType={tank.class}
- image={tankIcon(tank.id)}
treeType={tank.treeType}
/>
)),
@@ -113,7 +111,6 @@ export const ownedTanksCommand = new Promise((resolve) => {
key={tank.id}
name={tank.name}
tankType={tank.class}
- image={tankIcon(tank.id)}
treeType={tank.treeType}
/>
)),
diff --git a/src/commands/searchPlayers.ts b/src/commands/searchPlayers.ts
index 6ca66ff17..ed816c1f2 100644
--- a/src/commands/searchPlayers.ts
+++ b/src/commands/searchPlayers.ts
@@ -3,10 +3,8 @@ import markdownEscape from 'markdown-escape';
import { Region } from '../constants/regions';
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
import fetchBlitz from '../core/blitz/fetchBlitz';
-import {
- AccountList,
- usernamePattern,
-} from '../core/blitz/searchPlayersAcrossRegions';
+import { AccountList } from '../core/blitz/searchPlayersAcrossRegions';
+import { usernamePattern } from '../core/blitz/searchPlayersAcrossRegions/constants';
import addRegionChoices from '../core/discord/addRegionChoices';
import addUsernameChoices from '../core/discord/addUsernameChoices';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
diff --git a/src/commands/today.ts b/src/commands/today.ts
index 1e2bc06e7..cc0fc5c06 100644
--- a/src/commands/today.ts
+++ b/src/commands/today.ts
@@ -15,7 +15,7 @@ import resolvePeriodFromCommand from '../core/discord/resolvePeriodFromCommand';
import resolvePlayerFromButton from '../core/discord/resolvePlayerFromButton';
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../events/interactionCreate';
-import { renderBreakdown } from './breakdown';
+import { renderBreakdown } from './breakdown/render';
export const todayCommand = new Promise(async (resolve) => {
const nations = await NATIONS;
diff --git a/src/components/AllStatsOverview/components/WN8Display/index.tsx b/src/components/AllStatsOverview/components/WN8Display/index.tsx
index 8be77a70f..9248a9456 100644
--- a/src/components/AllStatsOverview/components/WN8Display/index.tsx
+++ b/src/components/AllStatsOverview/components/WN8Display/index.tsx
@@ -3,7 +3,7 @@ import { Percentile } from '../../../../constants/percentiles';
import { translator } from '../../../../core/localization/translator';
import getWN8Percentile from '../../../../core/statistics/getWN8Percentile';
import { theme } from '../../../../stitches.config';
-import { PERCENTILE_COLORS } from '../../../PercentileIndicator';
+import { PERCENTILE_COLORS } from '../../../PercentileIndicator/constants';
import { Glow } from './components/Glow';
export interface WN8DisplayProps {
diff --git a/src/components/Armor/components/CoreArmorSceneComponent/index.tsx b/src/components/Armor/components/CoreArmorSceneComponent/index.tsx
index c646ee157..3a3d5955b 100644
--- a/src/components/Armor/components/CoreArmorSceneComponent/index.tsx
+++ b/src/components/Armor/components/CoreArmorSceneComponent/index.tsx
@@ -1,12 +1,6 @@
import { useFrame } from '@react-three/fiber';
import { useEffect } from 'react';
-import {
- MeshBasicMaterial,
- Object3D,
- ShaderMaterial,
- Vector2,
- WebGLRenderTarget,
-} from 'three';
+import { MeshBasicMaterial, Object3D, ShaderMaterial, Vector2 } from 'three';
import { degToRad } from 'three/src/math/MathUtils';
import { canSplash } from '../../../../core/blitz/canSplash';
import { isExplosive } from '../../../../core/blitz/isExplosive';
@@ -21,8 +15,7 @@ import {
} from '../../../../stores/tankopedia';
import fragmentShader from './shaders/fragment.glsl';
import vertexShader from './shaders/vertex.glsl';
-
-export const spacedArmorRenderTarget = new WebGLRenderTarget();
+import { spacedArmorRenderTarget } from './target';
interface CoreArmorSceneComponentProps {
thickness: number;
diff --git a/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl b/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl
index e03696067..7975e2c20 100644
--- a/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl
+++ b/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl
@@ -53,7 +53,7 @@ void main() {
float spacedArmorThickness = spacedArmorBufferFragment.r * penetration;
remainingPenetration -= spacedArmorThickness;
- if (isExplosive && !canSplash && remainingPenetration > 0.0) {
+ if (isExplosive && remainingPenetration > 0.0) {
// there is a 50% penetration loss per meter for HEAT shells
remainingPenetration -= 0.5 * remainingPenetration * distanceFromSpacedArmor;
}
diff --git a/src/components/Armor/components/CoreArmorSceneComponent/target.tsx b/src/components/Armor/components/CoreArmorSceneComponent/target.tsx
new file mode 100644
index 000000000..b61b76f7e
--- /dev/null
+++ b/src/components/Armor/components/CoreArmorSceneComponent/target.tsx
@@ -0,0 +1,3 @@
+import { WebGLRenderTarget } from 'three';
+
+export const spacedArmorRenderTarget = new WebGLRenderTarget();
diff --git a/src/components/Armor/components/ShotDisplay.tsx b/src/components/Armor/components/ShotDisplay.tsx
index 6b470feb4..512815160 100644
--- a/src/components/Armor/components/ShotDisplay.tsx
+++ b/src/components/Armor/components/ShotDisplay.tsx
@@ -1,4 +1,4 @@
-import { Card, Flex, Inset, Text } from '@radix-ui/themes';
+import { Card, Flex, Text } from '@radix-ui/themes';
import { Html } from '@react-three/drei';
import { useFrame } from '@react-three/fiber';
import { useEffect, useRef } from 'react';
@@ -182,33 +182,38 @@ export function ShotDisplay() {
pointerEvents: 'none',
}}
>
-
-
- {hasMultipleLayers && (
-
- {layer.index + 1}
-
- )}
-
-
+ {hasMultipleLayers && (
+
+ {layer.index + 1}
+
+ )}
+