diff --git a/scripts/buildAssets.ts b/scripts/buildAssets.ts index 28698f753..3589a7a63 100644 --- a/scripts/buildAssets.ts +++ b/scripts/buildAssets.ts @@ -1,5 +1,5 @@ import { config } from 'dotenv'; -import { existsSync } from 'fs'; +import { existsSync, writeFileSync } from 'fs'; import { mkdir, readdir, rm } from 'fs/promises'; import { argv } from 'process'; import sharp from 'sharp'; @@ -15,16 +15,14 @@ import { toUniqueId } from '../src/core/blitz/toUniqueId'; import commitMultipleFiles, { FileChange, } from '../src/core/blitzkrieg/commitMultipleFiles'; -import { BlitzkriegGunDefinitions } from '../src/core/blitzkrieg/definitions/guns'; import { - BlitzkriegShellDefinitions, + GunDefinition, + ShellDefinition, ShellType, -} from '../src/core/blitzkrieg/definitions/shells'; -import { - BlitzkriegTankDefinitions, + TankDefinitions, Tier, -} from '../src/core/blitzkrieg/definitions/tanks'; -import { BlitzkriegTurretDefinitions } from '../src/core/blitzkrieg/definitions/turrets'; + TurretDefinition, +} from '../src/core/blitzkrieg/tankDefinitions'; config(); @@ -98,8 +96,12 @@ interface VehicleDefinitions { yawLimits: string | string[]; guns: { [key: string]: { + reloadTime: number; maxAmmo: number; pitchLimits?: string | string[]; + pumpGunMode?: boolean; + pumpGunReloadTimes?: string; + clip?: { count: number; rate: number }; }; }; }; @@ -141,6 +143,7 @@ const DOI = { flags: 'Gfx/Lobby/flags', '3d': '3d', bigShellIcons: 'Gfx/Shared/tank-supply/ammunition/big', + moduleIcons: 'Gfx/UI/ModulesTechTree', }; const allTargets = argv.includes('--all-targets'); @@ -154,10 +157,7 @@ if (!targets && !allTargets) throw new Error('No target(s) specified'); if (allTargets || targets?.includes('definitions')) { console.log('Building tank definitions...'); - const tankDefinitions: BlitzkriegTankDefinitions = {}; - const turretDefinitions: BlitzkriegTurretDefinitions = {}; - const gunDefinitions: BlitzkriegGunDefinitions = {}; - const shellDefinitions: BlitzkriegShellDefinitions = {}; + const definitions: TankDefinitions = {}; const nations = await readdir(`${DATA}/${DOI.vehicleDefinitions}`).then( (nations) => nations.filter((nation) => nation !== 'common'), ); @@ -203,15 +203,41 @@ if (allTargets || targets?.includes('definitions')) { const gun = gunList.root.shared[gunKey]; const pitchLimitsRaw = turretGunEntry.pitchLimits ?? gun.pitchLimits; + const gunPitch = ( + typeof pitchLimitsRaw === 'string' + ? pitchLimitsRaw + : pitchLimitsRaw.at(-1)! + ) + .split(' ') + .map(Number) as [number, number]; + const gunName = + strings[gun.userString] ?? gunKey.replaceAll('_', ' '); + const gunType = + 'clip' in turretGunEntry + ? turretGunEntry.pumpGunMode + ? 'auto_reloader' + : 'auto_loader' + : 'regular'; + const gunReload = + gunType === 'auto_reloader' + ? turretGunEntry.pumpGunReloadTimes!.split(' ').map(Number) + : turretGunEntry.reloadTime; + const gunClipCount = + gunType === 'regular' ? undefined : turretGunEntry.clip!.count; + const gunInterClip = + gunType === 'regular' + ? undefined + : 60 / turretGunEntry.clip!.rate; const gunShells = Object.keys(gun.shots).map((shellKey) => { const turretShellEntry = gun.shots[shellKey]; const shell = shellList.root[shellKey]; const shellId = toUniqueId(nation, shell.id); + const shellName = + strings[shell.userString] ?? shellKey.replaceAll('_', ' '); - shellDefinitions[shellId] = { + return { id: shellId, - name: - strings[shell.userString] ?? shellKey.replaceAll('_', ' '), + name: shellName, speed: turretShellEntry.speed, damage: { armor: shell.damage.armor, @@ -222,28 +248,23 @@ if (allTargets || targets?.includes('definitions')) { ricochet: shell.ricochetAngle, type: blitzShellKindToBLitzkrieg[shell.kind], icon: shell.icon, - }; - - return shellId; + } satisfies ShellDefinition; }); - gunDefinitions[gunId] = { + return { id: gunId, - pitch: (typeof pitchLimitsRaw === 'string' - ? pitchLimitsRaw - : pitchLimitsRaw.at(-1)! - ) - .split(' ') - .map(Number) as [number, number], - name: strings[gun.userString] ?? gunKey.replaceAll('_', ' '), + pitch: gunPitch, + name: gunName, tier: gun.level as Tier, shells: gunShells, - }; - - return gunId; + type: gunType, + reload: gunReload, + count: gunClipCount, + interClip: gunInterClip, + } as GunDefinition; }); - turretDefinitions[turretId] = { + return { id: turretId, name: strings[turret.userString] ?? @@ -258,13 +279,11 @@ if (allTargets || targets?.includes('definitions')) { .split(' ') .map(Number) as [number, number], guns: turretGuns, - }; - - return turretId; + } satisfies TurretDefinition; }, ); - tankDefinitions[tankId] = { + definitions[tankId] = { id: tankId, name: (tank.shortUserString @@ -288,36 +307,37 @@ if (allTargets || targets?.includes('definitions')) { ); console.log('Committing tank definitions...'); - await commitMultipleFiles( - 'tresabhi', - 'blitzkrieg-assets', - 'main', - 'definitions', - [ - { - content: JSON.stringify(tankDefinitions), - encoding: 'utf-8', - path: 'definitions/tanks.json', - }, - { - content: JSON.stringify(turretDefinitions), - encoding: 'utf-8', - path: 'definitions/turrets.json', - }, - { - content: JSON.stringify(gunDefinitions), - encoding: 'utf-8', - path: 'definitions/guns.json', - }, - { - content: JSON.stringify(shellDefinitions), - encoding: 'utf-8', - path: 'definitions/shells.json', - }, - ], + writeFileSync('test.json', JSON.stringify(definitions, null, 2)); + // await commitMultipleFiles( + // 'tresabhi', + // 'blitzkrieg-assets', + // 'main', + // 'definitions', + // [ + // { + // content: JSON.stringify(tankDefinitions), + // encoding: 'utf-8', + // path: 'definitions/tanks.json', + // }, + // { + // content: JSON.stringify(turretDefinitions), + // encoding: 'utf-8', + // path: 'definitions/turrets.json', + // }, + // { + // content: JSON.stringify(gunDefinitions), + // encoding: 'utf-8', + // path: 'definitions/guns.json', + // }, + // { + // content: JSON.stringify(shellDefinitions), + // encoding: 'utf-8', + // path: 'definitions/shells.json', + // }, + // ], - true, - ); + // true, + // ); } if ( @@ -356,14 +376,14 @@ if ( changes.push({ content: await readBase64DVPL(big), encoding: 'base64', - path: `icons/big/${id}.webp`, + path: `icons/tank/big/${id}.webp`, }); } if (allTargets || targets?.includes('smallTankIcons')) { changes.push({ content: await readBase64DVPL(small), encoding: 'base64', - path: `icons/small/${id}.webp`, + path: `icons/tank/small/${id}.webp`, }); } } @@ -527,7 +547,7 @@ if (allTargets || targets?.includes('shellIcons')) { .toBuffer() ).toString('base64'), encoding: 'base64', - path: `shells/${name}.webp`, + path: `icons/shells/${name}.webp`, } satisfies FileChange; }), ); @@ -542,3 +562,38 @@ if (allTargets || targets?.includes('shellIcons')) { true, ); } + +if (allTargets || targets?.includes('moduleIcons')) { + console.log('Building module icons...'); + + const changes = await Promise.all( + (await readdir(`${DATA}/${DOI.moduleIcons}`)) + .filter( + (file) => + !file.endsWith('@2x.packed.webp.dvpl') && file.startsWith('vehicle'), + ) + .map(async (file) => { + const nameRaw = file.match(/vehicle(.+)\.packed\.webp\.dvpl/)![1]; + const name = nameRaw[0].toLowerCase() + nameRaw.slice(1); + const content = await readBase64DVPL( + `${DATA}/${DOI.moduleIcons}/${file}`, + ); + + return { + content, + path: `icons/modules/${name}.webp`, + encoding: 'base64', + } satisfies FileChange; + }), + ); + + console.log('Committing module icons...'); + commitMultipleFiles( + 'tresabhi', + 'blitzkrieg-assets', + 'main', + 'module icons', + changes, + true, + ); +} diff --git a/src/app/embeds/session/page.tsx b/src/app/embeds/session/page.tsx index 2f65393f7..1c51c0610 100644 --- a/src/app/embeds/session/page.tsx +++ b/src/app/embeds/session/page.tsx @@ -7,9 +7,9 @@ import { TreeTypeEnum } from '../../../components/Tanks'; import { WARGAMING_APPLICATION_ID } from '../../../constants/wargamingApplicationID'; import fetchBlitz from '../../../core/blitz/fetchBlitz'; import { - BlitzkriegTankDefinition, + TankDefinition, tankDefinitions, -} from '../../../core/blitzkrieg/definitions/tanks'; +} from '../../../core/blitzkrieg/tankDefinitions'; import { tankAverages } from '../../../core/blitzstars/tankAverages'; import calculateWN8 from '../../../core/statistics/calculateWN8'; import { deltaTankStats } from '../../../core/statistics/deltaTankStats'; @@ -30,7 +30,7 @@ export default function SessionPage() { list: { stats: IndividualTankStats; - tankDefinitions?: BlitzkriegTankDefinition; + tankDefinitions?: TankDefinition; career: IndividualTankStats; currentWN8?: number; careerWN8?: number; diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index ab9ce029b..68c0cab7b 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -12,7 +12,6 @@ import { Dialog, Flex, Heading, - Separator, Slider, Tabs, Text, @@ -27,52 +26,64 @@ import { debounce } from 'lodash'; import Link from 'next/link'; import { use, useEffect, useRef, useState } from 'react'; import { Flag } from '../../../../components/Flag'; +import { ModuleButtons } from '../../../../components/ModuleButton'; import PageWrapper from '../../../../components/PageWrapper'; import { asset } from '../../../../core/blitzkrieg/asset'; import { gunDefinitions } from '../../../../core/blitzkrieg/definitions/guns'; import { shellDefinitions } from '../../../../core/blitzkrieg/definitions/shells'; +import { turretDefinitions } from '../../../../core/blitzkrieg/definitions/turrets'; import { TIER_ROMAN_NUMERALS, tankDefinitions, tankNamesDiacritics, - tanksDefinitionsArray, -} from '../../../../core/blitzkrieg/definitions/tanks'; -import { turretDefinitions } from '../../../../core/blitzkrieg/definitions/turrets'; +} from '../../../../core/blitzkrieg/tankDefinitions'; import * as styles from '../page.css'; -type Mode = 'model' | 'armor'; - export default function Page({ params }: { params: { id: string } }) { const id = parseInt(params.id); const awaitedTankDefinitions = use(tankDefinitions); - const awaitedTanksDefinitionsArray = use(tanksDefinitionsArray); const awaitedTurretDefinitions = use(turretDefinitions); const awaitedGunDefinitions = use(gunDefinitions); const awaitedShellDefinitions = use(shellDefinitions); const awaitedTankNamesDiacritics = use(tankNamesDiacritics); const tank = awaitedTankDefinitions[id]; const [turret, setTurret] = useState( - awaitedTurretDefinitions[tank.turrets[0]], + awaitedTurretDefinitions[tank.turrets.at(-1)!], ); - const [gun, setGun] = useState(awaitedGunDefinitions[turret.guns[0]]); + const [gun, setGun] = useState(awaitedGunDefinitions[turret.guns.at(-1)!]); const [crew, setCrew] = useState(100); - const [versusTankId, setVersusTankId] = useState( - awaitedTanksDefinitionsArray[0].id, - ); - const [mode, setMode] = useState('model'); + const [mode, setMode] = useState('model'); const versusTankSearchInput = useRef(null); const [versusTankSearchResults, setVersusTankSearchResults] = useState< number[] >([]); - const [versusTankTurretId, setVersusTankTurretId] = useState( - awaitedTurretDefinitions[tank.turrets[0]].id, + const [versusTank, setVersusTank] = useState(tank); + const [versusTurret, setVersusTurret] = useState( + awaitedTurretDefinitions[versusTank.turrets.at(-1)!], ); - const versusTank = awaitedTankDefinitions[versusTankId]; + const [versusGun, setVersusGun] = useState( + awaitedGunDefinitions[versusTurret.guns.at(-1)!], + ); + const [versusTankTab, setVersusTankTab] = useState('search'); - useEffect(() => setGun(awaitedGunDefinitions[turret.guns[0]]), [turret]); + useEffect(() => { + if (!turret.guns.includes(gun.id)) { + setGun(awaitedGunDefinitions[turret.guns.at(-1)!]); + } + }, [turret]); + useEffect(() => { + if (!versusTank.turrets.includes(versusTurret.id)) { + setVersusTurret(awaitedTurretDefinitions[versusTank.turrets.at(-1)!]); + } + }, [versusTank]); + useEffect(() => { + if (!versusTurret.guns.includes(versusGun.id)) { + setVersusGun(awaitedGunDefinitions[versusTurret.guns.at(-1)!]); + } + }, [versusTurret]); return ( - + @@ -94,10 +105,7 @@ export default function Page({ params }: { params: { id: string } }) { - setMode(value as Mode)} - > + Model Armor @@ -136,86 +144,191 @@ export default function Page({ params }: { params: { id: string } }) { - - - Search tank + + + + Search + + Configure + + - - - - - { - setVersusTankSearchResults( - go( - versusTankSearchInput.current!.value, - awaitedTankNamesDiacritics, - { key: 'combined', limit: 8 }, - ).map((item) => item.obj.id), - ); - }, 500)} - /> - - + + + + + + + { + setVersusTankSearchResults( + go( + versusTankSearchInput.current!.value, + awaitedTankNamesDiacritics, + { key: 'combined', limit: 8 }, + ).map((item) => item.obj.id), + ); + }, 500)} + /> + - {(versusTankSearchResults.length > 0 || - versusTankSearchInput.current?.value) && ( - - {versusTankSearchResults.map((id) => ( - + ))} + + {versusTankSearchResults.length === 0 && + (versusTankSearchInput.current + ? versusTankSearchInput.current.value + .length > 0 + : false) && ( + + )} + + )} + + + + + + + - {awaitedTankDefinitions[id].name} - - ))} + Configuration - {versusTankSearchResults.length === 0 && - (versusTankSearchInput.current - ? versusTankSearchInput.current.value.length > 0 - : false) && ( - - )} - - )} + + + {versusTank.turrets.map((id, index) => ( + + + setVersusTurret( + awaitedTurretDefinitions[id], + ) + } + selected={versusTurret.id === id} + tier={ + awaitedTurretDefinitions[id].tier + } + type="turret" + style={{ + margin: -0.5, + borderTopLeftRadius: + index === 0 ? undefined : 0, + borderBottomLeftRadius: + index === 0 ? undefined : 0, + borderTopRightRadius: + index === + versusTank.turrets.length - 1 + ? undefined + : 0, + borderBottomRightRadius: + index === + versusTank.turrets.length - 1 + ? undefined + : 0, + }} + /> + + ))} + + + {versusTurret.guns.map((id, index) => ( + + + setVersusGun( + awaitedGunDefinitions[id], + ) + } + selected={versusGun.id === id} + tier={awaitedGunDefinitions[id].tier} + type="gun" + style={{ + margin: -0.5, + borderTopLeftRadius: + index === 0 ? undefined : 0, + borderBottomLeftRadius: + index === 0 ? undefined : 0, + borderTopRightRadius: + index === + versusTurret.guns.length - 1 + ? undefined + : 0, + borderBottomRightRadius: + index === + versusTurret.guns.length - 1 + ? undefined + : 0, + }} + /> + + ))} + + + - - - - - {awaitedTankDefinitions[versusTankId].name} - - - - {versusTank.turrets.map((id) => ( - - ))} - + Properties + +
    +
  • Penetration
  • +
+
+
+
-
+
@@ -227,17 +340,25 @@ export default function Page({ params }: { params: { id: string } }) { - +
diff --git a/src/app/tools/tankopedia/components/Options/index.tsx b/src/app/tools/tankopedia/components/Options/index.tsx index c67417100..e63d4167e 100644 --- a/src/app/tools/tankopedia/components/Options/index.tsx +++ b/src/app/tools/tankopedia/components/Options/index.tsx @@ -15,7 +15,7 @@ import { NATIONS, TIERS, TIER_ROMAN_NUMERALS, -} from '../../../../../core/blitzkrieg/definitions/tanks'; +} from '../../../../../core/blitzkrieg/tankDefinitions'; import mutateTankopedia, { TankopediaTestTankDisplay, useTankopedia, diff --git a/src/app/tools/tankopedia/components/PageTurner.tsx b/src/app/tools/tankopedia/components/PageTurner.tsx index 231a6c690..3b649d4fd 100644 --- a/src/app/tools/tankopedia/components/PageTurner.tsx +++ b/src/app/tools/tankopedia/components/PageTurner.tsx @@ -1,12 +1,12 @@ import { CaretLeftIcon, CaretRightIcon } from '@radix-ui/react-icons'; import { Button, Flex, TextField } from '@radix-ui/themes'; import { useEffect, useRef } from 'react'; -import { BlitzkriegTankDefinition } from '../../../../core/blitzkrieg/definitions/tanks'; +import { TankDefinition } from '../../../../core/blitzkrieg/tankDefinitions'; interface PageTurnerProps { page: number; setPage: (page: number) => void; - searchedList: BlitzkriegTankDefinition[]; + searchedList: TankDefinition[]; tanksPerPage: number; } diff --git a/src/app/tools/tankopedia/page.tsx b/src/app/tools/tankopedia/page.tsx index e99ec392b..a41a99c00 100644 --- a/src/app/tools/tankopedia/page.tsx +++ b/src/app/tools/tankopedia/page.tsx @@ -20,13 +20,13 @@ import { Suspense, use, useEffect, useMemo, useRef, useState } from 'react'; import PageWrapper from '../../../components/PageWrapper'; import { asset } from '../../../core/blitzkrieg/asset'; import { - BlitzkriegTankDefinition, TANK_ICONS, TANK_ICONS_COLLECTOR, TANK_ICONS_PREMIUM, TIER_ROMAN_NUMERALS, + TankDefinition, tanksDefinitionsArray, -} from '../../../core/blitzkrieg/definitions/tanks'; +} from '../../../core/blitzkrieg/tankDefinitions'; import { tankIcon } from '../../../core/blitzkrieg/tankIcon'; import { theme } from '../../../stitches.config'; import mutateTankopedia, { @@ -117,10 +117,7 @@ export default function Page() { } else { setSearchedList( go(event.target.value, searchableTanks, { - keys: [ - 'name', - 'id', - ] satisfies (keyof BlitzkriegTankDefinition)[], + keys: ['name', 'id'] satisfies (keyof TankDefinition)[], }).map(({ obj }) => obj), ); } diff --git a/src/commands/breakdown.tsx b/src/commands/breakdown.tsx index fe05523db..725ea64c7 100644 --- a/src/commands/breakdown.tsx +++ b/src/commands/breakdown.tsx @@ -8,8 +8,8 @@ import { AllStats, getAccountInfo } from '../core/blitz/getAccountInfo'; import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo'; import getTankStats from '../core/blitz/getTankStats'; import getTreeType from '../core/blitz/getTreeType'; -import { tankDefinitions } from '../core/blitzkrieg/definitions/tanks'; import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription'; +import { tankDefinitions } from '../core/blitzkrieg/tankDefinitions'; import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton'; import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod'; import { tankAverages } from '../core/blitzstars/tankAverages'; diff --git a/src/commands/eligible.ts b/src/commands/eligible.ts index 1158b6910..8225885e6 100644 --- a/src/commands/eligible.ts +++ b/src/commands/eligible.ts @@ -1,8 +1,8 @@ import { SlashCommandBuilder } from 'discord.js'; import { getAccountInfo } from '../core/blitz/getAccountInfo'; -import { tankDefinitions } from '../core/blitzkrieg/definitions/tanks'; import getPeriodNow from '../core/blitzkrieg/getPeriodNow'; import getTimeDaysAgo from '../core/blitzkrieg/getTimeDaysAgo'; +import { tankDefinitions } from '../core/blitzkrieg/tankDefinitions'; import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod'; import { tankAverages } from '../core/blitzstars/tankAverages'; import addUsernameChoices from '../core/discord/addUsernameChoices'; diff --git a/src/commands/ownedTanks.tsx b/src/commands/ownedTanks.tsx index e92e628bf..4a93fdfb1 100644 --- a/src/commands/ownedTanks.tsx +++ b/src/commands/ownedTanks.tsx @@ -8,13 +8,13 @@ import { getAccountInfo } from '../core/blitz/getAccountInfo'; import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo'; import getTankStats from '../core/blitz/getTankStats'; import getTreeType from '../core/blitz/getTreeType'; +import { emblemIdToURL } from '../core/blitzkrieg/emblemIdToURL'; import { - BlitzkriegTankDefinition, TIER_ROMAN_NUMERALS, + TankDefinition, Tier, tankDefinitions, -} from '../core/blitzkrieg/definitions/tanks'; -import { emblemIdToURL } from '../core/blitzkrieg/emblemIdToURL'; +} from '../core/blitzkrieg/tankDefinitions'; import { tankIcon } from '../core/blitzkrieg/tankIcon'; import addTierChoices from '../core/discord/addTierChoices'; import addUsernameChoices from '../core/discord/addUsernameChoices'; @@ -47,7 +47,7 @@ export const ownedTanksCommand: CommandRegistry = { ) ).filter((tank) => tank.tankDefinitions?.tier === tier); const clanAccountInfo = await getClanAccountInfo(server, id, ['clan']); - const groupedTanks: Record = {}; + const groupedTanks: Record = {}; const nations: string[] = []; filteredTanks.forEach((tank) => { diff --git a/src/commands/searchTanks.ts b/src/commands/searchTanks.ts index cb2f1e089..b24ab7a4f 100644 --- a/src/commands/searchTanks.ts +++ b/src/commands/searchTanks.ts @@ -1,7 +1,7 @@ import { SlashCommandBuilder } from 'discord.js'; import { go } from 'fuzzysort'; import markdownEscape from 'markdown-escape'; -import { tankNamesDiacritics } from '../core/blitzkrieg/definitions/tanks'; +import { tankNamesDiacritics } from '../core/blitzkrieg/tankDefinitions'; import addTankChoices from '../core/discord/addTankChoices'; import embedInfo from '../core/discord/embedInfo'; import { CommandRegistry } from '../events/interactionCreate'; diff --git a/src/components/ModuleButton.tsx b/src/components/ModuleButton.tsx new file mode 100644 index 000000000..2f66cb107 --- /dev/null +++ b/src/components/ModuleButton.tsx @@ -0,0 +1,60 @@ +import { Button, Text } from '@radix-ui/themes'; +import { ComponentProps } from 'react'; +import { asset } from '../core/blitzkrieg/asset'; +import { TIER_ROMAN_NUMERALS, Tier } from '../core/blitzkrieg/tankDefinitions'; + +interface ModuleButtonProps + extends Omit, 'type'> { + type: string; + tier: Tier; + selected?: boolean; +} + +export function ModuleButtons({ + type, + tier, + selected, + style, + ...props +}: ModuleButtonProps) { + return ( + + ); +} diff --git a/src/components/Tanks/components/Item.tsx b/src/components/Tanks/components/Item.tsx index 4363e0a80..67193f81a 100644 --- a/src/components/Tanks/components/Item.tsx +++ b/src/components/Tanks/components/Item.tsx @@ -2,7 +2,7 @@ import { TANK_ICONS, TANK_ICONS_COLLECTOR, TANK_ICONS_PREMIUM, -} from '../../../core/blitzkrieg/definitions/tanks'; +} from '../../../core/blitzkrieg/tankDefinitions'; import { theme } from '../../../stitches.config'; export enum TreeTypeEnum { diff --git a/src/components/TierWeights.tsx b/src/components/TierWeights.tsx index 3fe2149b6..f95dbabd2 100644 --- a/src/components/TierWeights.tsx +++ b/src/components/TierWeights.tsx @@ -1,4 +1,4 @@ -import { Tier } from '../core/blitzkrieg/definitions/tanks'; +import { Tier } from '../core/blitzkrieg/tankDefinitions'; import { theme } from '../stitches.config'; export type TierWeightsRecord = Partial>; diff --git a/src/core/blitz/getTreeType.ts b/src/core/blitz/getTreeType.ts index b8aedd82d..cdc6c5bd9 100644 --- a/src/core/blitz/getTreeType.ts +++ b/src/core/blitz/getTreeType.ts @@ -1,5 +1,5 @@ import { TreeTypeEnum } from '../../components/Tanks'; -import { tankDefinitions } from '../blitzkrieg/definitions/tanks'; +import { tankDefinitions } from '../blitzkrieg/tankDefinitions'; export default async function getTreeType(id: number) { const entry = (await tankDefinitions)[id]; diff --git a/src/core/blitz/resolveTankId.ts b/src/core/blitz/resolveTankId.ts index c110ee3a2..a57f9b608 100644 --- a/src/core/blitz/resolveTankId.ts +++ b/src/core/blitz/resolveTankId.ts @@ -2,7 +2,7 @@ import { go } from 'fuzzysort'; import { tankDefinitions, tanksDefinitionsArray, -} from '../blitzkrieg/definitions/tanks'; +} from '../blitzkrieg/tankDefinitions'; import { UserError } from '../blitzkrieg/userError'; export default async function resolveTankId(tank: string | number) { diff --git a/src/core/blitzkrieg/definitions/guns.ts b/src/core/blitzkrieg/definitions/guns.ts deleted file mode 100644 index 4de669219..000000000 --- a/src/core/blitzkrieg/definitions/guns.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { asset } from '../asset'; -import { Tier } from './tanks'; - -export interface BlitzkriegGunDefinition { - id: number; - name: string; - tier: Tier; - pitch: [number, number]; - shells: number[]; -} - -export type BlitzkriegGunDefinitions = Record; - -export const gunDefinitions = fetch(asset('definitions/guns.json'), { - cache: 'no-cache', -}).then( - async (response) => response.json() as Promise, -); diff --git a/src/core/blitzkrieg/definitions/shells.ts b/src/core/blitzkrieg/definitions/shells.ts deleted file mode 100644 index 77f008855..000000000 --- a/src/core/blitzkrieg/definitions/shells.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { asset } from '../asset'; - -export type ShellType = 'ap' | 'ap_cr' | 'hc' | 'he'; - -export interface BlitzkriegShellDefinition { - id: number; - name: string; - speed: number; - damage: { armor: number; devices: number }; - caliber: number; - normalization: number; - ricochet: number; - type: ShellType; - icon: string; -} - -export type BlitzkriegShellDefinitions = Record< - number, - BlitzkriegShellDefinition ->; - -export const shellDefinitions = fetch(asset('definitions/shells.json'), { - cache: 'no-cache', -}).then( - async (response) => response.json() as Promise, -); diff --git a/src/core/blitzkrieg/definitions/turrets.ts b/src/core/blitzkrieg/definitions/turrets.ts deleted file mode 100644 index 7399a09c3..000000000 --- a/src/core/blitzkrieg/definitions/turrets.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { asset } from '../asset'; -import { Tier } from './tanks'; - -export interface BlitzkriegTurretDefinition { - id: number; - name: string; - tier: Tier; - yaw: [number, number]; - guns: number[]; -} - -export type BlitzkriegTurretDefinitions = Record< - number, - BlitzkriegTurretDefinition ->; - -export const turretDefinitions = fetch(asset('definitions/turrets.json'), { - cache: 'no-cache', -}).then( - async (response) => response.json() as Promise, -); diff --git a/src/core/blitzkrieg/filtersToDescription.ts b/src/core/blitzkrieg/filtersToDescription.ts index c7963b5e4..ce5b5a8b0 100644 --- a/src/core/blitzkrieg/filtersToDescription.ts +++ b/src/core/blitzkrieg/filtersToDescription.ts @@ -1,11 +1,7 @@ import { TREE_TYPE_NAMES } from '../../components/Tanks'; import { encyclopediaInfo } from '../blitz/encyclopediaInfo'; import { StatFilters } from '../statistics/filterStats'; -import { - TIER_ROMAN_NUMERALS, - Tier, - tankDefinitions, -} from './definitions/tanks'; +import { TIER_ROMAN_NUMERALS, Tier, tankDefinitions } from './tankDefinitions'; export async function filtersToDescription({ nation, diff --git a/src/core/blitzkrieg/definitions/tanks.ts b/src/core/blitzkrieg/tankDefinitions.ts similarity index 63% rename from src/core/blitzkrieg/definitions/tanks.ts rename to src/core/blitzkrieg/tankDefinitions.ts index c9ca0f57c..b29a7fe0b 100644 --- a/src/core/blitzkrieg/definitions/tanks.ts +++ b/src/core/blitzkrieg/tankDefinitions.ts @@ -1,8 +1,51 @@ import { deburr } from 'lodash'; -import { TankType, TreeTypeString } from '../../../components/Tanks'; -import { asset } from '../asset'; +import { TankType, TreeTypeString } from '../../components/Tanks'; +import { asset } from './asset'; -export interface BlitzkriegTankDefinition { +export type ShellType = 'ap' | 'ap_cr' | 'hc' | 'he'; +export interface ShellDefinition { + id: number; + name: string; + speed: number; + damage: { armor: number; devices: number }; + caliber: number; + normalization: number; + ricochet: number; + type: ShellType; + icon: string; +} +export type GunDefinition = { + id: number; + name: string; + tier: Tier; + pitch: [number, number]; + shells: ShellDefinition[]; +} & ( + | { + type: 'regular'; + reload: number; + } + | { + type: 'auto_loader'; + reload: number; + interClip: number; + count: number; + } + | { + type: 'auto_reloader'; + reload: number[]; + interClip: number; + count: number; + } +); +export interface TurretDefinition { + id: number; + name: string; + tier: Tier; + yaw: [number, number]; + guns: GunDefinition[]; +} +export interface TankDefinition { id: number; nation: string; name: string; @@ -10,23 +53,18 @@ export interface BlitzkriegTankDefinition { tier: Tier; type: TankType; testing?: boolean; - turrets: number[]; + turrets: TurretDefinition[]; } -export type BlitzkriegTankDefinitions = Record< - number, - BlitzkriegTankDefinition ->; +export type TankDefinitions = Record; export const tankDefinitions = fetch(asset('definitions/tanks.json'), { cache: 'no-cache', -}).then( - async (response) => response.json() as Promise, -); +}).then(async (response) => response.json() as Promise); -const entries = new Promise(async (resolve) => { +const entries = new Promise(async (resolve) => { resolve(Object.entries(await tankDefinitions).map(([, entry]) => entry)); }); -export const tanksDefinitionsArray = new Promise( +export const tanksDefinitionsArray = new Promise( async (resolve) => { resolve((await entries).map((entry) => entry)); }, diff --git a/src/core/blitzkrieg/tankIcon.ts b/src/core/blitzkrieg/tankIcon.ts index 8ca97d74f..1ebe0aef3 100644 --- a/src/core/blitzkrieg/tankIcon.ts +++ b/src/core/blitzkrieg/tankIcon.ts @@ -1,5 +1,5 @@ import { asset } from './asset'; export function tankIcon(id: number, size: 'big' | 'small' = 'big') { - return asset(`icons/${size}/${id}.webp`); + return asset(`icons/tanks/${size}/${id}.webp`); } diff --git a/src/core/blitzstars/tankAverages.ts b/src/core/blitzstars/tankAverages.ts index 1ed7d87a3..7ce28099f 100644 --- a/src/core/blitzstars/tankAverages.ts +++ b/src/core/blitzstars/tankAverages.ts @@ -1,6 +1,6 @@ import { AllStats } from '../blitz/getAccountInfo'; import { context } from '../blitzkrieg/context'; -import { tankDefinitions } from '../blitzkrieg/definitions/tanks'; +import { tankDefinitions } from '../blitzkrieg/tankDefinitions'; export interface SpecialStats { winrate: number; diff --git a/src/core/discord/autocompleteTanks.ts b/src/core/discord/autocompleteTanks.ts index 78f1b17ab..26c8c9c6f 100644 --- a/src/core/discord/autocompleteTanks.ts +++ b/src/core/discord/autocompleteTanks.ts @@ -4,7 +4,7 @@ import { CacheType, } from 'discord.js'; import { go } from 'fuzzysort'; -import { tankNamesDiacritics } from '../blitzkrieg/definitions/tanks'; +import { tankNamesDiacritics } from '../blitzkrieg/tankDefinitions'; import { DISCORD_CHOICES_MAX_NAME_SIZE, OVERFLOW_SUFFIX, diff --git a/src/core/statistics/filterStats.ts b/src/core/statistics/filterStats.ts index c48ce83c5..e56da6af4 100644 --- a/src/core/statistics/filterStats.ts +++ b/src/core/statistics/filterStats.ts @@ -1,5 +1,5 @@ import { TreeTypeString } from '../../components/Tanks'; -import { tankDefinitions } from '../blitzkrieg/definitions/tanks'; +import { tankDefinitions } from '../blitzkrieg/tankDefinitions'; import { DiffedTankStats } from '../blitzstars/getStatsInPeriod'; import { tankAverages } from '../blitzstars/tankAverages'; import calculateWN8 from './calculateWN8'; diff --git a/src/core/statistics/getTierWeights.ts b/src/core/statistics/getTierWeights.ts index 933bd30ee..532b65911 100644 --- a/src/core/statistics/getTierWeights.ts +++ b/src/core/statistics/getTierWeights.ts @@ -1,6 +1,6 @@ import { TierWeightsRecord } from '../../components/TierWeights'; import { AllStats } from '../blitz/getAccountInfo'; -import { tankDefinitions } from '../blitzkrieg/definitions/tanks'; +import { tankDefinitions } from '../blitzkrieg/tankDefinitions'; export async function getTierWeights( stats: Record, diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index 447edf4bd..3ec510c30 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -1,7 +1,7 @@ import { produce } from 'immer'; import { create } from 'zustand'; import { TankType, TreeTypeString } from '../components/Tanks'; -import { Tier } from '../core/blitzkrieg/definitions/tanks'; +import { Tier } from '../core/blitzkrieg/tankDefinitions'; export type TankopediaSortBy = 'tier' | 'name'; export type TankopediaSortDirection = 'ascending' | 'descending';