diff --git a/packages/core/src/blitz/constants.ts b/packages/core/src/blitz/constants.ts index 0cc9ddbc9..f2ae72204 100644 --- a/packages/core/src/blitz/constants.ts +++ b/packages/core/src/blitz/constants.ts @@ -8,7 +8,6 @@ export const TANK_CLASSES = [ TankClass.MEDIUM, TankClass.HEAVY, TankClass.TANK_DESTROYER, - TankClass.UNRECOGNIZED, ] as const; export const emptyAllStats: BlitzStats = { diff --git a/packages/core/src/blitzkit/camouflageDefinitions.ts b/packages/core/src/blitzkit/camouflageDefinitions.ts index 1a65d3ac9..20315860c 100644 --- a/packages/core/src/blitzkit/camouflageDefinitions.ts +++ b/packages/core/src/blitzkit/camouflageDefinitions.ts @@ -3,5 +3,5 @@ import { CamouflageDefinitions } from '../protos'; import { asset } from './asset'; export function fetchCamouflageDefinitions() { - return fetchPB(asset('definitions/camoufles.pb'), CamouflageDefinitions); + return fetchPB(asset('definitions/camouflages.pb'), CamouflageDefinitions); } diff --git a/packages/core/src/blitzkit/tankDefinitions/constants.ts b/packages/core/src/blitzkit/tankDefinitions/constants.ts index b0141f139..731c37fec 100644 --- a/packages/core/src/blitzkit/tankDefinitions/constants.ts +++ b/packages/core/src/blitzkit/tankDefinitions/constants.ts @@ -12,7 +12,6 @@ export const SHELL_NAMES: Record = { [ShellType.APCR]: 'APCR', [ShellType.HEAT]: 'HEAT', [ShellType.HE]: 'HE', - [ShellType.UNRECOGNIZED]: 'unrecognized', }; export const CREW_MEMBER_NAMES: Record = { [CrewType.COMMANDER]: 'Commander', @@ -20,7 +19,6 @@ export const CREW_MEMBER_NAMES: Record = { [CrewType.GUNNER]: 'Gunner', [CrewType.LOADER]: 'Loader', [CrewType.RADIOMAN]: 'Radioman', - [CrewType.UNRECOGNIZED]: 'unrecognized', }; export const GUN_TYPE_NAMES: Record< Exclude['$case'], @@ -38,7 +36,6 @@ export const TANK_ICONS: Record = { [TankClass.LIGHT]: 'https://i.imgur.com/CSNha5V.png', [TankClass.MEDIUM]: 'https://i.imgur.com/wvf3ltm.png', [TankClass.HEAVY]: 'https://i.imgur.com/ECeqlZa.png', - [TankClass.UNRECOGNIZED]: 'https://i.imgur.com/6FBBzb9.png', // lmfao click on this }; /** * @deprecated use svg @@ -48,7 +45,6 @@ export const TANK_ICONS_PREMIUM: Record = { [TankClass.LIGHT]: 'https://i.imgur.com/zdkpTRb.png', [TankClass.MEDIUM]: 'https://i.imgur.com/3z7eHX6.png', [TankClass.HEAVY]: 'https://i.imgur.com/P3vbmyA.png', - [TankClass.UNRECOGNIZED]: 'https://i.imgur.com/6FBBzb9.png', }; /** * @deprecated use svg @@ -58,7 +54,6 @@ export const TANK_ICONS_COLLECTOR: Record = { [TankClass.LIGHT]: 'https://i.imgur.com/EwhtKkU.png', [TankClass.MEDIUM]: 'https://i.imgur.com/u8YDMBh.png', [TankClass.HEAVY]: 'https://i.imgur.com/8xRf3nc.png', - [TankClass.UNRECOGNIZED]: 'https://i.imgur.com/6FBBzb9.png', }; export const TIERS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as const; export const TIER_ROMAN_NUMERALS: Record = { @@ -72,7 +67,6 @@ export const TIER_ROMAN_NUMERALS: Record = { [Tier.VIII]: 'VIII', [Tier.IX]: 'IX', [Tier.X]: 'X', - [Tier.UNRECOGNIZED]: 'unrecognized', }; export const flags: Record = { @@ -90,11 +84,4 @@ export const TREE_TYPE_ICONS: Record> = { [TankType.RESEARCHABLE]: TANK_ICONS, [TankType.PREMIUM]: TANK_ICONS_PREMIUM, [TankType.COLLECTOR]: TANK_ICONS_COLLECTOR, - [TankType.UNRECOGNIZED]: { - '-1': 'https://i.imgur.com/6FBBzb9.png', - '0': 'https://i.imgur.com/6FBBzb9.png', - '1': 'https://i.imgur.com/6FBBzb9.png', - '2': 'https://i.imgur.com/6FBBzb9.png', - '3': 'https://i.imgur.com/6FBBzb9.png', - }, }; diff --git a/packages/core/src/blitzkit/tankNames.ts b/packages/core/src/blitzkit/tankNames.ts index 56a088cfe..0be345b26 100644 --- a/packages/core/src/blitzkit/tankNames.ts +++ b/packages/core/src/blitzkit/tankNames.ts @@ -10,17 +10,16 @@ export async function fetchTankNames() { const tankDefinitionsArray = Object.values(tankDefinitions.tanks); return await Promise.all( - tankDefinitionsArray.map(async (tank, index) => { - const { id } = tankDefinitionsArray[index]; - + tankDefinitionsArray.map(async (tank) => { return { - id, + id: tank.id, name: tank.name, nameFull: tank.nameFull, searchableName: tank.nameFull ?? tank.name, searchableNameDeburr: deburr(tank.nameFull ?? tank.name), camouflages: tank.camouflages - ?.map((id) => camouflageDefinitions.camouflages[id].name) + ?.map((id) => camouflageDefinitions.camouflages[id]?.name) + .filter(Boolean) .join(' '), treeType: tank.type, }; diff --git a/packages/scripts/src/buildAssets/definitions.ts b/packages/scripts/src/buildAssets/definitions.ts index fac35520f..c7285369a 100644 --- a/packages/scripts/src/buildAssets/definitions.ts +++ b/packages/scripts/src/buildAssets/definitions.ts @@ -147,9 +147,6 @@ const blitzkitCrewTypeToBlitz: Record = { [CrewType.GUNNER]: 'gunner', [CrewType.LOADER]: 'loader', [CrewType.RADIOMAN]: 'radioman', - - // this should never happen... i hope 😢 - [CrewType.UNRECOGNIZED]: 'radioman', }; interface VehicleDefinitions { invisibility: { diff --git a/packages/scripts/src/protos.ts b/packages/scripts/src/protos.ts index cbf0a4e45..322e235b1 100644 --- a/packages/scripts/src/protos.ts +++ b/packages/scripts/src/protos.ts @@ -30,6 +30,7 @@ const args = [ '--ts_proto_opt=esModuleInterop=true', '--ts_proto_opt=oneof=unions-value', '--ts_proto_opt=removeEnumPrefix=true', + '--ts_proto_opt=unrecognizedEnum=false', '--ts_proto_out=.', ...files.map((file) => `${ROOT}/${file}`), ]; diff --git a/packages/website-legacy/src/app/tools/compare/page.tsx b/packages/website-legacy/src/app/tools/compare/page.tsx index 6a4c868e1..ef040ba35 100644 --- a/packages/website-legacy/src/app/tools/compare/page.tsx +++ b/packages/website-legacy/src/app/tools/compare/page.tsx @@ -3,7 +3,6 @@ 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 * as CompareEphemeral from '../../../stores/compareEphemeral'; export default function Page() { const pathname = usePathname(); diff --git a/packages/website-legacy/src/app/tools/performance/components/Info.tsx b/packages/website-legacy/src/app/tools/performance/components/Info.tsx index c7b07ac08..e54e681bc 100644 --- a/packages/website-legacy/src/app/tools/performance/components/Info.tsx +++ b/packages/website-legacy/src/app/tools/performance/components/Info.tsx @@ -1,18 +1,18 @@ import { - averageDefinitions, - discoveredIdsDefinitions, + fetchAverageDefinitions, + fetchDiscoveredIdsDefinitions, formatCompact, } from '@blitzkit/core'; import { InfoCircledIcon } from '@radix-ui/react-icons'; import { Callout, Flex } from '@radix-ui/themes'; -import { use } from 'react'; + +const discoveredIdsDefinitions = await fetchDiscoveredIdsDefinitions(); +const averageDefinitions = await fetchAverageDefinitions(); export function Info() { - const awaitedDiscoveredIdsDefinitions = use(discoveredIdsDefinitions); - const awaitedAverageDefinitions = use(averageDefinitions); - const samples = awaitedDiscoveredIdsDefinitions.count; + const samples = discoveredIdsDefinitions.count; const minutesAgo = Math.floor( - (Date.now() - awaitedAverageDefinitions.time) / (1000 * 60), + (Date.now() - averageDefinitions.time) / (1000 * 60), ); const hoursAgo = Math.floor(minutesAgo / 60); diff --git a/packages/website-legacy/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx b/packages/website-legacy/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx index 43cb5d671..60ade1600 100644 --- a/packages/website-legacy/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx +++ b/packages/website-legacy/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx @@ -2,10 +2,10 @@ import { asset, coefficient, CREW_MEMBER_NAMES, - equipmentDefinitions, + fetchEquipmentDefinitions, + fetchProvisionDefinitions, GUN_TYPE_NAMES, isExplosive, - provisionDefinitions, resolvePenetrationCoefficient, } from '@blitzkit/core'; import { AccessibilityIcon, InfoCircledIcon } from '@radix-ui/react-icons'; @@ -24,15 +24,15 @@ import { Fragment, useEffect, useRef, useState } from 'react'; import { Ad, AdType } from '../../../../../../../../website/src/components/Ad'; import { InfoWithDelta } from '../../../../../../../../website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta'; import { applyPitchYawLimits } from '../../../../../../../../website/src/core/blitz/applyPitchYawLimits'; +import { tankCharacteristics } from '../../../../../../../../website/src/core/blitzkit/tankCharacteristics'; import { useAdExempt } from '../../../../../../../../website/src/hooks/useAdExempt'; import { useEquipment } from '../../../../../../../../website/src/hooks/useEquipment'; import { useTankModelDefinition } from '../../../../../../../../website/src/hooks/useTankModelDefinition'; import { Duel } from '../../../../../../../../website/src/stores/duel'; import { TankopediaEphemeral } from '../../../../../../../../website/src/stores/tankopediaEphemeral'; -import { Info } from '../../../../performance/components/Info'; -const awaitedEquipmentDefinitions = await equipmentDefinitions; -const awaitedProvisionDefinitions = await provisionDefinitions; +const equipmentDefinitions = await fetchEquipmentDefinitions(); +const provisionDefinitions = await fetchProvisionDefinitions(); export function Characteristics() { const mutateDuel = Duel.useMutation(); @@ -50,8 +50,8 @@ export function Characteristics() { const provisionCrewBonus = provisions.reduce( (total, provision) => - awaitedProvisionDefinitions[provision].crew - ? total + awaitedProvisionDefinitions[provision].crew! / 100 + provisionDefinitions.provisions[provision].crew + ? total + provisionDefinitions.provisions[provision].crew! / 100 : total, 0, ) + (hasImprovedVentilation ? 0.08 : 0); @@ -70,7 +70,8 @@ export function Characteristics() { const stockGun = stockTurret.guns[0]; const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = turretModelDefinition.guns[gun.id]; + const gunModelDefinition = + turretModelDefinition.guns[gun.gunType!.value.base.id]; const stats = tankCharacteristics( { tank, @@ -95,8 +96,8 @@ export function Characteristics() { }, { tankModelDefinition, - equipmentDefinitions: awaitedEquipmentDefinitions, - provisionDefinitions: awaitedProvisionDefinitions, + equipmentDefinitions: equipmentDefinitions, + provisionDefinitions: provisionDefinitions, }, ); @@ -143,7 +144,7 @@ export function Characteristics() { Firepower - {gun.shells.map((thisShell, shellIndex) => ( + {gun.gunType!.value.base.shells.map((thisShell, shellIndex) => ( { @@ -174,7 +179,7 @@ export function Characteristics() { ))} - {GUN_TYPE_NAMES[gun.type]} + {GUN_TYPE_NAMES[gun.gunType!.$case]} {stats.dpm} diff --git a/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx b/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx index 21fb08234..7c372e021 100644 --- a/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx +++ b/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx @@ -24,7 +24,8 @@ export const PrimaryArmorScene = memo(() => { const tankModelDefinition = useTankModelDefinition(); const trackModelDefinition = tankModelDefinition.tracks[track.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = turretModelDefinition.guns[gun.id]; + const gunModelDefinition = + turretModelDefinition.guns[gun.gunType!.value.base.id]; const hullOrigin = correctZYTuple(trackModelDefinition.origin); const turretOrigin = correctZYTuple(tankModelDefinition.turretOrigin); const gunOrigin = correctZYTuple(turretModelDefinition.gunOrigin); @@ -68,7 +69,7 @@ export const PrimaryArmorScene = memo(() => { {armorNodes.map((node) => { const isCurrentTurret = node.name.startsWith( - `turret_${turretModelDefinition.model.toString().padStart(2, '0')}`, + `turret_${turretModelDefinition.modelId.toString().padStart(2, '0')}`, ); const isVisible = isCurrentTurret; const armorId = nameToArmorId(node.name); @@ -102,7 +103,7 @@ export const PrimaryArmorScene = memo(() => { {armorNodes.map((node) => { const isCurrentGun = node.name.startsWith( - `gun_${gunModelDefinition.model.toString().padStart(2, '0')}`, + `gun_${gunModelDefinition.modelId.toString().padStart(2, '0')}`, ); const isVisible = isCurrentGun; const armorId = nameToArmorId(node.name); diff --git a/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx b/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx index a396c737f..f32404e89 100644 --- a/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx +++ b/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx @@ -2,7 +2,6 @@ import { type ShellDefinition, canSplash, isExplosive, - resolveNearPenetration, resolvePenetrationCoefficient, } from '@blitzkit/core'; import { useFrame } from '@react-three/fiber'; @@ -69,7 +68,7 @@ export function PrimaryArmorSceneComponent({ ); material.uniforms.isExplosive.value = isExplosive(shell.type); material.uniforms.canSplash.value = canSplash(shell.type); - material.uniforms.damage.value = shell.damage.armor; + material.uniforms.damage.value = shell.armorDamage; material.uniforms.explosionRadius.value = shell.explosionRadius; const duel = duelStore.getState(); @@ -91,7 +90,7 @@ export function PrimaryArmorSceneComponent({ const duel = duelStore.getState(); const hasEnhancedArmor = await hasEquipment( 110, - duel.protagonist.tank.equipment, + duel.protagonist.tank.equipmentPreset, equipment, ); material.uniforms.thickness.value = hasEnhancedArmor @@ -101,10 +100,10 @@ export function PrimaryArmorSceneComponent({ async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) { const duel = duelStore.getState(); const shell = duel.antagonist.shell; - const penetration = resolveNearPenetration(shell.penetration); + const penetration = shell.penetration.near; const hasCalibratedShells = await hasEquipment( 103, - duel.antagonist.tank.equipment, + duel.antagonist.tank.equipmentPreset, equipment, ); diff --git a/packages/website/src/components/Armor/components/SpacedArmorScene.tsx b/packages/website/src/components/Armor/components/SpacedArmorScene.tsx index ce2b3600f..0622d8f8c 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorScene.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorScene.tsx @@ -37,7 +37,8 @@ export const SpacedArmorScene = memo(({ scene }) => { const tankModelDefinition = useTankModelDefinition(); const trackModelDefinition = tankModelDefinition.tracks[track.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = turretModelDefinition.guns[gun.id]; + const gunModelDefinition = + turretModelDefinition.guns[gun.gunType!.value.base.id]; const hullOrigin = correctZYTuple(trackModelDefinition.origin); const turretOrigin = correctZYTuple(tankModelDefinition.turretOrigin); const gunOrigin = correctZYTuple(turretModelDefinition.gunOrigin); @@ -105,7 +106,7 @@ export const SpacedArmorScene = memo(({ scene }) => { {armorNodes.map((node) => { const isCurrentTurret = node.name.startsWith( - `turret_${turretModelDefinition.model.toString().padStart(2, '0')}`, + `turret_${turretModelDefinition.modelId.toString().padStart(2, '0')}`, ); const isVisible = isCurrentTurret; const armorId = nameToArmorId(node.name); @@ -140,7 +141,7 @@ export const SpacedArmorScene = memo(({ scene }) => { {armorNodes.map((node) => { const isCurrentGun = node.name.startsWith( - `gun_${gunModelDefinition.model.toString().padStart(2, '0')}`, + `gun_${gunModelDefinition.modelId.toString().padStart(2, '0')}`, ); const isVisible = isCurrentGun; const armorId = nameToArmorId(node.name); @@ -172,7 +173,7 @@ export const SpacedArmorScene = memo(({ scene }) => { })} {modelNodes.map((node) => { - const gunString = `gun_${gunModelDefinition.model + const gunString = `gun_${gunModelDefinition.modelId .toString() .padStart(2, '0')}`; const isCurrentGun = gunModelDefinition.mask diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx index c2123624d..270f8e761 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx @@ -1,6 +1,5 @@ import { isExplosive, - resolveNearPenetration, resolvePenetrationCoefficient, type ShellDefinition, } from '@blitzkit/core'; @@ -54,9 +53,7 @@ export function SpacedArmorSubSpaced({ useEffect(() => { function handleShellChange(shell: ShellDefinition) { - material.uniforms.penetration.value = resolveNearPenetration( - shell.penetration, - ); + material.uniforms.penetration.value = shell.penetration.near; material.uniforms.caliber.value = shell.caliber; material.uniforms.ricochet.value = degToRad( isExplosive(shell.type) ? 90 : shell.ricochet!, @@ -71,7 +68,7 @@ export function SpacedArmorSubSpaced({ const duel = duelStore.getState(); const hasEnhancedArmor = await hasEquipment( 110, - duel.protagonist.tank.equipment, + duel.protagonist.tank.equipmentPreset, equipment, ); material.uniforms.thickness.value = hasEnhancedArmor @@ -81,10 +78,10 @@ export function SpacedArmorSubSpaced({ async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) { const duel = duelStore.getState(); const shell = duelStore.getState().antagonist.shell; - const penetration = resolveNearPenetration(shell.penetration); + const penetration = shell.penetration.near; const hasCalibratedShells = await hasEquipment( 103, - duel.antagonist.tank.equipment, + duel.antagonist.tank.equipmentPreset, equipment, ); diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx index dbf378374..75c07f077 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx @@ -1,7 +1,6 @@ import { ShellType, isExplosive, - resolveNearPenetration, resolvePenetrationCoefficient, } from '@blitzkit/core'; import { useThree } from '@react-three/fiber'; @@ -104,16 +103,16 @@ export function SpacedArmorSceneComponent({ const hasCalibratedShells = await hasEquipment( 103, - antagonist.tank.equipment, + antagonist.tank.equipmentPreset, antagonist.equipmentMatrix, ); const hasEnhancedArmor = await hasEquipment( 110, - protagonist.tank.equipment, + protagonist.tank.equipmentPreset, protagonist.equipmentMatrix, ); const penetration = - resolveNearPenetration(shell.penetration) * + shell.penetration.near * resolvePenetrationCoefficient(hasCalibratedShells, shell.type); const thicknessCoefficient = hasEnhancedArmor ? 1.03 : 1; const filteredIntersections = intersections.filter( @@ -289,7 +288,7 @@ export function SpacedArmorSceneComponent({ const finalDamage = Math.max( 0, 0.5 * - shell.damage.armor * + shell.armorDamage * (1 - distanceFromSpacedArmor / shell.explosionRadius!) - 1.1 * (lastLayer.thicknessAngled + @@ -312,7 +311,7 @@ export function SpacedArmorSceneComponent({ shot.damage = finalDamage; } else { shot.in.status = 'penetration'; - shot.damage = shell.damage.armor; + shot.damage = shell.armorDamage; } } else { if (lastLayer.status === 'blocked') { @@ -320,7 +319,7 @@ export function SpacedArmorSceneComponent({ shot.damage = 0; } else if (lastLayer.status === 'penetration') { shot.in.status = 'penetration'; - shot.damage = shell.damage.armor; + shot.damage = shell.armorDamage; } else { const caster = new Raycaster(); // https://math.stackexchange.com/a/13263/1222875 diff --git a/packages/website/src/components/ClassIcon/index.ts b/packages/website/src/components/ClassIcon/index.ts index 430de4ec5..71cc58c3f 100644 --- a/packages/website/src/components/ClassIcon/index.ts +++ b/packages/website/src/components/ClassIcon/index.ts @@ -1,5 +1,6 @@ -import { type TankClass } from '@blitzkit/core'; +import { TankClass } from '@blitzkit/core'; import type { ComponentProps, ReactNode } from 'react'; +import { StupidCat } from '../StupidCat'; import { ClassHeavy } from './components/ClassHeavy'; import { ClassLight } from './components/ClassLight'; import { ClassMedium } from './components/ClassMedium'; @@ -9,8 +10,9 @@ export const classIcons: Record< TankClass, (props: ComponentProps<'svg'>) => ReactNode > = { - 'AT-SPG': ClassTankDestroyer, - heavyTank: ClassHeavy, - lightTank: ClassLight, - mediumTank: ClassMedium, + [TankClass.TANK_DESTROYER]: ClassTankDestroyer, + [TankClass.HEAVY]: ClassHeavy, + [TankClass.LIGHT]: ClassLight, + [TankClass.MEDIUM]: ClassMedium, + [TankClass.UNRECOGNIZED]: StupidCat, }; diff --git a/packages/website/src/components/CrewSkillManager.tsx b/packages/website/src/components/CrewSkillManager.tsx index d0dbcca52..a116dae4e 100644 --- a/packages/website/src/components/CrewSkillManager.tsx +++ b/packages/website/src/components/CrewSkillManager.tsx @@ -1,7 +1,7 @@ import { asset, + fetchSkillDefinitions, permanentSkills, - skillDefinitions, TIER_ROMAN_NUMERALS, type Tier, } from '@blitzkit/core'; @@ -13,7 +13,7 @@ interface CrewSkillManagerProps { onChange?: (skillLevels: Record) => void; } -const awaitedSkillDefinitions = await skillDefinitions; +const skillDefinitions = await fetchSkillDefinitions(); export function CrewSkillManager({ skillLevels, @@ -21,41 +21,39 @@ export function CrewSkillManager({ }: CrewSkillManagerProps) { return ( - {Object.entries(awaitedSkillDefinitions.classes).map( - ([tankClass, skills]) => ( - - {skills.map((skill) => { - const level = skillLevels[skill]; + {Object.entries(skillDefinitions.classes).map(([tankClass, skills]) => ( + + {skills.skills.map((skill) => { + const level = skillLevels[skill]; - return ( - 0} - discriminator={ - level === 0 ? undefined : TIER_ROMAN_NUMERALS[level as Tier] + return ( + 0} + discriminator={ + level === 0 ? undefined : TIER_ROMAN_NUMERALS[level as Tier] + } + icon={asset(`icons/skills/${skill}.webp`)} + onClick={(event) => { + if (!onChange) return; + + const draft = { ...skillLevels }; + + if (event.shiftKey) { + draft[skill] = draft[skill] === 0 ? 7 : 0; + } else { + draft[skill] = level - 1; + if (draft[skill] < 0) draft[skill] = 7; } - icon={asset(`icons/skills/${skill}.webp`)} - onClick={(event) => { - if (!onChange) return; - const draft = { ...skillLevels }; - - if (event.shiftKey) { - draft[skill] = draft[skill] === 0 ? 7 : 0; - } else { - draft[skill] = level - 1; - if (draft[skill] < 0) draft[skill] = 7; - } - - onChange(draft); - }} - /> - ); - })} - - ), - )} + onChange(draft); + }} + /> + ); + })} + + ))} ); } diff --git a/packages/website/src/components/Footer.astro b/packages/website/src/components/Footer.astro index c9067dfce..238e8cf17 100644 --- a/packages/website/src/components/Footer.astro +++ b/packages/website/src/components/Footer.astro @@ -1,9 +1,9 @@ --- -import { gameDefinitions } from '@blitzkit/core'; +import { fetchGameDefinitions } from '@blitzkit/core'; import { Code, Flex, Heading, Link, Text } from '@radix-ui/themes'; import packageJson from '../../../../package.json'; -const awaitedGameDefinitions = await gameDefinitions; +const gameDefinitions = await fetchGameDefinitions(); --- - {awaitedGameDefinitions.version} + {gameDefinitions.version} {import.meta.env.PUBLIC_ASSET_BRANCH} @@ -148,7 +148,7 @@ const awaitedGameDefinitions = await gameDefinitions; WoT Blitz - {awaitedGameDefinitions.version} + {gameDefinitions.version} CDN diff --git a/packages/website/src/components/ModuleButtons/ProvisionButton.tsx b/packages/website/src/components/ModuleButtons/ProvisionButton.tsx index 84514dd77..1ee05dac0 100644 --- a/packages/website/src/components/ModuleButtons/ProvisionButton.tsx +++ b/packages/website/src/components/ModuleButtons/ProvisionButton.tsx @@ -1,4 +1,4 @@ -import { asset, provisionDefinitions } from '@blitzkit/core'; +import { asset, fetchProvisionDefinitions } from '@blitzkit/core'; import { GenericTankComponentButton } from './GenericTankComponentButton'; import type { TankComponentButtonProps } from './TankComponentButton'; @@ -6,12 +6,12 @@ interface ProvisionButtonProps extends TankComponentButtonProps { provision: number; } -const awaitedProvisionDefinitions = await provisionDefinitions; +const provisionDefinitions = await fetchProvisionDefinitions(); export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) { return ( diff --git a/packages/website/src/components/StupidCat.tsx b/packages/website/src/components/StupidCat.tsx new file mode 100644 index 000000000..86c5be34d --- /dev/null +++ b/packages/website/src/components/StupidCat.tsx @@ -0,0 +1,3 @@ +export function StupidCat() { + return ; +} diff --git a/packages/website/src/components/TankSearch/components/FilterControl.tsx b/packages/website/src/components/TankSearch/components/FilterControl.tsx index 6db46de83..faa3f276e 100644 --- a/packages/website/src/components/TankSearch/components/FilterControl.tsx +++ b/packages/website/src/components/TankSearch/components/FilterControl.tsx @@ -2,6 +2,7 @@ import { asset, fetchGameDefinitions, TANK_CLASSES, + TankType, TIER_ROMAN_NUMERALS, type Tier, } from '@blitzkit/core'; @@ -35,7 +36,7 @@ export function FilterControl({ compact }: FilterControlProps) { > {times(5, (index) => { - const tier = (index + 1) as Tier; + const tier = index as Tier; const selected = tankFilters.tiers?.includes(tier); return ( @@ -46,29 +47,19 @@ export function FilterControl({ compact }: FilterControlProps) { radius="none" color={selected ? undefined : 'gray'} highContrast - onClick={() => - // mutateTankFilters((draft) => { - // if (draft.tiers?.includes(tier)) { - // draft.tiers = draft.tiers?.filter((t) => t !== tier); - // } else { - // draft.tiers = [...(draft.tiers ?? []), tier]; - // } - // }) - - { - if (tankFilters.tiers.includes(tier)) { - $tankFilters.setKey( - 'tiers', - tankFilters.tiers.filter((t) => t !== tier), - ); - } else { - $tankFilters.setKey('tiers', [ - ...tankFilters.tiers, - tier, - ]); - } + onClick={() => { + if (tankFilters.tiers.includes(tier)) { + $tankFilters.setKey( + 'tiers', + tankFilters.tiers.filter((t) => t !== tier), + ); + } else { + $tankFilters.setKey('tiers', [ + ...tankFilters.tiers, + tier, + ]); } - } + }} > {TIER_ROMAN_NUMERALS[tier]} @@ -78,7 +69,7 @@ export function FilterControl({ compact }: FilterControlProps) { {times(5, (index) => { - const tier = (index + 6) as Tier; + const tier = (index + 5) as Tier; const selected = tankFilters.tiers?.includes(tier); return ( @@ -89,28 +80,19 @@ export function FilterControl({ compact }: FilterControlProps) { radius="none" color={selected ? undefined : 'gray'} highContrast - onClick={() => - // mutateTankFilters((draft) => { - // if (draft.tiers?.includes(tier)) { - // draft.tiers = draft.tiers?.filter((t) => t !== tier); - // } else { - // draft.tiers = [...(draft.tiers ?? []), tier]; - // } - // }) - { - if (tankFilters.tiers.includes(tier)) { - $tankFilters.setKey( - 'tiers', - tankFilters.tiers.filter((t) => t !== tier), - ); - } else { - $tankFilters.setKey('tiers', [ - ...tankFilters.tiers, - tier, - ]); - } + onClick={() => { + if (tankFilters.tiers.includes(tier)) { + $tankFilters.setKey( + 'tiers', + tankFilters.tiers.filter((t) => t !== tier), + ); + } else { + $tankFilters.setKey('tiers', [ + ...tankFilters.tiers, + tier, + ]); } - } + }} > {TIER_ROMAN_NUMERALS[tier]} @@ -256,30 +238,19 @@ export function FilterControl({ compact }: FilterControlProps) { radius="none" color={selected ? undefined : 'gray'} highContrast - onClick={() => - // mutateTankFilters((draft) => { - // if (draft.classes?.includes(tankClass)) { - // draft.classes = draft.classes?.filter( - // (c) => c !== tankClass, - // ); - // } else { - // draft.classes = [...(draft.classes ?? []), tankClass]; - // } - // }) - { - if (tankFilters.classes.includes(tankClass)) { - $tankFilters.setKey( - 'classes', - tankFilters.classes.filter((c) => c !== tankClass), - ); - } else { - $tankFilters.setKey('classes', [ - ...tankFilters.classes, - tankClass, - ]); - } + onClick={() => { + if (tankFilters.classes.includes(tankClass)) { + $tankFilters.setKey( + 'classes', + tankFilters.classes.filter((c) => c !== tankClass), + ); + } else { + $tankFilters.setKey('classes', [ + ...tankFilters.classes, + tankClass, + ]); } - } + }} > @@ -296,73 +267,63 @@ export function FilterControl({ compact }: FilterControlProps) { - // mutateTankFilters((draft) => { - // if (draft.types?.includes('researchable')) { - // draft.types = draft.types?.filter( - // (t) => t !== 'researchable', - // ); - // } else { - // draft.types = [...(draft.types ?? []), 'researchable']; - // } - // }) - { - if (tankFilters.types.includes('researchable')) { - $tankFilters.setKey( - 'types', - tankFilters.types.filter((t) => t !== 'researchable'), - ); - } else { - $tankFilters.setKey('types', [ - ...tankFilters.types, - 'researchable', - ]); - } + onClick={() => { + if (tankFilters.types.includes(TankType.RESEARCHABLE)) { + $tankFilters.setKey( + 'types', + tankFilters.types.filter((t) => t !== TankType.RESEARCHABLE), + ); + } else { + $tankFilters.setKey('types', [ + ...tankFilters.types, + TankType.RESEARCHABLE, + ]); } - } + }} > - // mutateTankFilters((draft) => { - // if (draft.types?.includes('premium')) { - // draft.types = draft.types?.filter((t) => t !== 'premium'); - // } else { - // draft.types = [...(draft.types ?? []), 'premium']; - // } - // }) - { - if (tankFilters.types.includes('premium')) { - $tankFilters.setKey( - 'types', - tankFilters.types.filter((t) => t !== 'premium'), - ); - } else { - $tankFilters.setKey('types', [ - ...tankFilters.types, - 'premium', - ]); - } - } + variant={ + tankFilters.types?.includes(TankType.PREMIUM) ? 'solid' : 'soft' } + radius="none" + color={ + tankFilters.types?.includes(TankType.PREMIUM) ? 'amber' : 'gray' + } + highContrast + onClick={() => { + if (tankFilters.types.includes(TankType.PREMIUM)) { + $tankFilters.setKey( + 'types', + tankFilters.types.filter((t) => t !== TankType.PREMIUM), + ); + } else { + $tankFilters.setKey('types', [ + ...tankFilters.types, + TankType.PREMIUM, + ]); + } + }} > @@ -373,37 +334,32 @@ export function FilterControl({ compact }: FilterControlProps) { - // mutateTankFilters((draft) => { - // if (draft.types?.includes('collector')) { - // draft.types = draft.types?.filter((t) => t !== 'collector'); - // } else { - // draft.types = [...(draft.types ?? []), 'collector']; - // } - // }) - { - if (tankFilters.types.includes('collector')) { - $tankFilters.setKey( - 'types', - tankFilters.types.filter((t) => t !== 'collector'), - ); - } else { - $tankFilters.setKey('types', [ - ...tankFilters.types, - 'collector', - ]); - } - } + color={ + tankFilters.types?.includes(TankType.COLLECTOR) ? 'blue' : 'gray' } + highContrast + onClick={() => { + if (tankFilters.types.includes(TankType.COLLECTOR)) { + $tankFilters.setKey( + 'types', + tankFilters.types.filter((t) => t !== TankType.COLLECTOR), + ); + } else { + $tankFilters.setKey('types', [ + ...tankFilters.types, + TankType.COLLECTOR, + ]); + } + }} > @@ -424,14 +380,9 @@ export function FilterControl({ compact }: FilterControlProps) { radius="none" color={tankFilters.testing === 'include' ? undefined : 'gray'} highContrast - onClick={() => - // mutateTankFilters((draft) => { - // draft.testing = 'include'; - // }) - { - $tankFilters.setKey('testing', 'include'); - } - } + onClick={() => { + $tankFilters.setKey('testing', 'include'); + }} > { - // tankFiltersStore.setState(tankFiltersStore.getInitialState(), true); $tankFilters.set(initialTankFilters); }} > diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equipment.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equipment.tsx index 3148e356d..dc8864cc2 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equipment.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equipment.tsx @@ -1,16 +1,16 @@ -import { equipmentDefinitions } from '@blitzkit/core'; +import { fetchEquipmentDefinitions } from '@blitzkit/core'; import { Button, Flex, Heading } from '@radix-ui/themes'; import { Duel } from '../../../../stores/duel'; import { EquipmentManager } from '../../../EquipmentManager'; import { ConfigurationChildWrapper } from './ConfigurationChildWrapper'; -const awaitedEquipmentDefinitions = await equipmentDefinitions; +const equipmentDefinitions = await fetchEquipmentDefinitions(); export function Equipment() { const mutateDuel = Duel.useMutation(); const protagonist = Duel.use((state) => state.protagonist); const equipmentPreset = - awaitedEquipmentDefinitions.presets[protagonist.tank.equipment]; + equipmentDefinitions.presets[protagonist.tank.equipmentPreset]; const equipmentMatrix = Duel.use( (state) => state.protagonist.equipmentMatrix, ); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx index 72b334383..2200ef786 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx @@ -28,7 +28,8 @@ export const TankModel = memo(() => { const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[protagonist.turret.id]; - const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id]; + const gunModelDefinition = + turretModelDefinition.guns[protagonist.gun.gunType!.value.base.id]; const { gltf } = useModel(protagonist.tank.id); const nodes = Object.values(gltf.nodes); const isDynamicArmorActive = Duel.use((state) => @@ -135,7 +136,7 @@ export const TankModel = memo(() => { const isTurret = node.name.startsWith('turret_'); const isCurrentTurret = node.name === - `turret_${turretModelDefinition.model.toString().padStart(2, '0')}`; + `turret_${turretModelDefinition.modelId.toString().padStart(2, '0')}`; const isVisible = isCurrentTurret; const position = new Vector2(); const delta = new Vector2(); @@ -168,7 +169,7 @@ export const TankModel = memo(() => { const duel = duelStore.getState(); const hasImprovedVerticalStabilizer = await hasEquipment( 122, - duel.protagonist.tank.equipment, + duel.protagonist.tank.equipmentPreset, duel.protagonist.equipmentMatrix, ); const boundingRect = canvas.getBoundingClientRect(); @@ -231,12 +232,12 @@ export const TankModel = memo(() => { {nodes.map((node) => { const isCurrentMantlet = node.name === - `gun_${gunModelDefinition.model + `gun_${gunModelDefinition.modelId .toString() .padStart(2, '0')}_mask`; const isCurrentGun = node.name === - `gun_${gunModelDefinition.model.toString().padStart(2, '0')}`; + `gun_${gunModelDefinition.modelId.toString().padStart(2, '0')}`; const isVisible = isCurrentGun || isCurrentMantlet; const position = new Vector2(); const delta = new Vector2(); @@ -268,7 +269,7 @@ export const TankModel = memo(() => { const duel = duelStore.getState(); const hasImprovedVerticalStabilizer = await hasEquipment( 122, - duel.protagonist.tank.equipment, + duel.protagonist.tank.equipmentPreset, duel.protagonist.equipmentMatrix, ); const boundingRect = canvas.getBoundingClientRect(); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx index a536fcefb..91235188e 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx @@ -44,7 +44,8 @@ export const TankSandbox = forwardRef( const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[protagonist.turret.id]; - const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id]; + const gunModelDefinition = + turretModelDefinition.guns[protagonist.gun.gunType!.value.base.id]; const display = TankopediaPersistent.useDeferred( (state) => state.display, TankopediaDisplay.Model, @@ -185,7 +186,6 @@ export const TankSandbox = forwardRef( - {/* idk why the shot display doesn't work without suspense here lol */} }> {display === TankopediaDisplay.DynamicArmor && } {display === TankopediaDisplay.StaticArmor && ( diff --git a/packages/website/src/components/Tankopedia/HeroSection/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/index.tsx index f232fcb17..8762dfc62 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/index.tsx @@ -1,6 +1,6 @@ import { fetchTankDefinitions, TankType } from '@blitzkit/core'; import { Box, Flex, Heading, Text } from '@radix-ui/themes'; -import { Suspense, useEffect, useMemo, useRef } from 'react'; +import { Suspense, useMemo, useRef } from 'react'; import { NAVBAR_HEIGHT } from '../../../constants/navbar'; import { Var } from '../../../core/radix/var'; import { useFullScreen } from '../../../hooks/useFullScreen'; @@ -44,10 +44,6 @@ export function HeroSection() { return { value } satisfies ThicknessRange; }, [protagonist]); - useEffect(() => { - // setDummyLoader(false); - }, []); - return ( - {protagonist.xp && ( + {protagonist.researchCost && ( - {protagonist.xp.toLocaleString()} + {( + protagonist.researchCost.researchCostType!.value as number + ).toLocaleString()} xp + diff --git a/packages/website/src/pages/tools/tankopedia/[id]/index.astro b/packages/website/src/pages/tools/tankopedia/[id]/index.astro index 459882c61..5f6451d3e 100644 --- a/packages/website/src/pages/tools/tankopedia/[id]/index.astro +++ b/packages/website/src/pages/tools/tankopedia/[id]/index.astro @@ -7,7 +7,7 @@ import { Page } from './index'; export const getStaticPaths = (async () => { const tankDefinitions = await fetchTankDefinitions(); - return Object.values(tankDefinitions).map((tank) => ({ + return Object.values(tankDefinitions.tanks).map((tank) => ({ params: { id: tank.id }, })); }) satisfies GetStaticPaths; diff --git a/packages/website/src/pages/tools/tankopedia/[id]/index.tsx b/packages/website/src/pages/tools/tankopedia/[id]/index.tsx index a23718a5f..c74bcff71 100644 --- a/packages/website/src/pages/tools/tankopedia/[id]/index.tsx +++ b/packages/website/src/pages/tools/tankopedia/[id]/index.tsx @@ -43,13 +43,10 @@ export function Page({ id }: PageProps) { - {/* {!exempt && } */} - {/* {!exempt && } */} - {/* {!exempt && } */}