mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: burst data
This commit is contained in:
1 parent
79c450798c
commit
c20f8c5040
37 files changed
+973
-1378
No files matched your search
@@ -100,8 +100,7 @@ export function ArmorPlateDisplay() {
|
||||
const { protagonist } = duelStore.getState();
|
||||
const tank = draft.model;
|
||||
const turret = tank.turrets[protagonist.turret.id];
|
||||
const gun =
|
||||
turret.guns[protagonist.gun.gun_type!.value.base.id];
|
||||
const gun = turret.guns[protagonist.gun.id];
|
||||
const track = tank.tracks[protagonist.track.id];
|
||||
|
||||
if (highlightArmor.name.startsWith('hull_')) {
|
||||
@@ -154,12 +153,8 @@ export function ArmorPlateDisplay() {
|
||||
const turret = tank.turrets[protagonist.turret.id];
|
||||
const initialTurret =
|
||||
initialTank.turrets[protagonist.turret.id];
|
||||
const gun =
|
||||
turret.guns[protagonist.gun.gun_type!.value.base.id];
|
||||
const initialGun =
|
||||
initialTurret.guns[
|
||||
protagonist.gun.gun_type!.value.base.id
|
||||
];
|
||||
const gun = turret.guns[protagonist.gun.id];
|
||||
const initialGun = initialTurret.guns[protagonist.gun.id];
|
||||
const track = tank.tracks[protagonist.track.id];
|
||||
const initialTrack =
|
||||
initialTank.tracks[protagonist.track.id];
|
||||
|
||||
@@ -24,8 +24,7 @@ export const PrimaryArmorScene = memo(() => {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
||||
|
||||
@@ -36,8 +36,7 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
||||
|
||||
@@ -42,8 +42,7 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
||||
|
||||
@@ -33,43 +33,35 @@ export function Body({ stats }: BodyProps) {
|
||||
<StickyColumnHeaderCell key={key} top={137}>
|
||||
<Flex justify="center">
|
||||
<Flex>
|
||||
{gun.gun_type!.value.base.shells.map(
|
||||
(thisShell, shellIndex) => (
|
||||
<IconButton
|
||||
color={thisShell.id === shell.id ? undefined : 'gray'}
|
||||
variant="soft"
|
||||
key={thisShell.id}
|
||||
style={{
|
||||
borderTopLeftRadius: shellIndex === 0 ? undefined : 0,
|
||||
borderBottomLeftRadius:
|
||||
shellIndex === 0 ? undefined : 0,
|
||||
borderTopRightRadius:
|
||||
shellIndex ===
|
||||
gun.gun_type!.value.base.shells.length - 1
|
||||
? undefined
|
||||
: 0,
|
||||
borderBottomRightRadius:
|
||||
shellIndex ===
|
||||
gun.gun_type!.value.base.shells.length - 1
|
||||
? undefined
|
||||
: 0,
|
||||
marginLeft: shellIndex === 0 ? 0 : -1,
|
||||
}}
|
||||
onClick={() => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].shell = thisShell;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt={unwrap(thisShell.name)}
|
||||
width={16}
|
||||
height={16}
|
||||
src={asset(`icons/shells/${thisShell.icon}.webp`)}
|
||||
/>
|
||||
</IconButton>
|
||||
),
|
||||
)}
|
||||
{gun.shells.map((thisShell, shellIndex) => (
|
||||
<IconButton
|
||||
color={thisShell.id === shell.id ? undefined : 'gray'}
|
||||
variant="soft"
|
||||
key={thisShell.id}
|
||||
style={{
|
||||
borderTopLeftRadius: shellIndex === 0 ? undefined : 0,
|
||||
borderBottomLeftRadius:
|
||||
shellIndex === 0 ? undefined : 0,
|
||||
borderTopRightRadius:
|
||||
shellIndex === gun.shells.length - 1 ? undefined : 0,
|
||||
borderBottomRightRadius:
|
||||
shellIndex === gun.shells.length - 1 ? undefined : 0,
|
||||
marginLeft: shellIndex === 0 ? 0 : -1,
|
||||
}}
|
||||
onClick={() => {
|
||||
mutateCompareEphemeral((draft) => {
|
||||
draft.members[index].shell = thisShell;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt={unwrap(thisShell.name)}
|
||||
width={16}
|
||||
height={16}
|
||||
src={asset(`icons/shells/${thisShell.icon}.webp`)}
|
||||
/>
|
||||
</IconButton>
|
||||
))}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</StickyColumnHeaderCell>
|
||||
|
||||
@@ -250,8 +250,7 @@ export function CompareTable({ stats }: CompareTableProps) {
|
||||
|
||||
member.turret = member.tank.turrets[0];
|
||||
member.gun = member.turret.guns[0];
|
||||
member.shell =
|
||||
member.gun.gun_type!.value.base.shells[0];
|
||||
member.shell = member.gun.shells[0];
|
||||
member.engine = member.tank.engines[0];
|
||||
member.track = member.tank.tracks[0];
|
||||
});
|
||||
@@ -267,8 +266,7 @@ export function CompareTable({ stats }: CompareTableProps) {
|
||||
|
||||
member.turret = member.tank.turrets.at(-1)!;
|
||||
member.gun = member.turret.guns.at(-1)!;
|
||||
member.shell =
|
||||
member.gun.gun_type!.value.base.shells[0];
|
||||
member.shell = member.gun.shells[0];
|
||||
member.engine = member.tank.engines.at(-1)!;
|
||||
member.track = member.tank.tracks.at(-1)!;
|
||||
});
|
||||
|
||||
@@ -62,7 +62,7 @@ export function ModuleManager({
|
||||
const draft = { ...modules };
|
||||
draft.turret = turret;
|
||||
draft.gun = draft.turret.guns.at(-1)!;
|
||||
draft.shell = draft.gun.gun_type!.value.base.shells[0];
|
||||
draft.shell = draft.gun.shells[0];
|
||||
|
||||
onChange?.(draft);
|
||||
setTurretMenuOpen(false);
|
||||
@@ -83,9 +83,7 @@ export function ModuleManager({
|
||||
|
||||
<ModuleButton
|
||||
module="gun"
|
||||
discriminator={
|
||||
TIER_ROMAN_NUMERALS[modules.gun.gun_type!.value.base.tier]
|
||||
}
|
||||
discriminator={TIER_ROMAN_NUMERALS[modules.gun.tier]}
|
||||
onClick={() => setGunMenuOpen(true)}
|
||||
/>
|
||||
|
||||
@@ -95,18 +93,16 @@ export function ModuleManager({
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Content>
|
||||
<DropdownMenu.RadioGroup
|
||||
value={`${modules.gun.gun_type!.value.base.id}`}
|
||||
>
|
||||
<DropdownMenu.RadioGroup value={`${modules.gun.id}`}>
|
||||
{[...modules.turret.guns].reverse().map((gun) => {
|
||||
return (
|
||||
<DropdownMenu.RadioItem
|
||||
key={gun.gun_type!.value.base.id}
|
||||
value={`${gun.gun_type!.value.base.id}`}
|
||||
key={gun.id}
|
||||
value={`${gun.id}`}
|
||||
onClick={() => {
|
||||
const draft = { ...modules };
|
||||
draft.gun = gun;
|
||||
draft.shell = draft.gun.gun_type!.value.base.shells[0];
|
||||
draft.shell = draft.gun.shells[0];
|
||||
|
||||
onChange?.(draft);
|
||||
setGunMenuOpen(false);
|
||||
@@ -115,11 +111,9 @@ export function ModuleManager({
|
||||
<ModuleButton
|
||||
variant="ghost"
|
||||
module="gun"
|
||||
discriminator={
|
||||
TIER_ROMAN_NUMERALS[gun.gun_type!.value.base.tier]
|
||||
}
|
||||
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
||||
/>{' '}
|
||||
{unwrap(gun.gun_type!.value.base.name)}
|
||||
{unwrap(gun.name)}
|
||||
</DropdownMenu.RadioItem>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -25,19 +25,18 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
|
||||
const turret = tank.turrets.at(-1)!;
|
||||
const gun = turret.guns.at(-1)!;
|
||||
const shell0 = gun.gun_type!.value.base.shells[0];
|
||||
const shell1 = gun.gun_type!.value.base.shells[1];
|
||||
const shell2 = gun.gun_type!.value.base.shells[2];
|
||||
const shell0 = gun.shells[0];
|
||||
const shell1 = gun.shells[1];
|
||||
const shell2 = gun.shells[2];
|
||||
const tracks = tank.tracks.at(-1)!;
|
||||
const engine = tank.engines.at(-1)!;
|
||||
const tankModelDefinition = modelDefinitions.models[tank.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
|
||||
switch (tankopediaSort.by) {
|
||||
case 'fire.aimTime':
|
||||
return gun.gun_type!.value.base.aim_time.toFixed(2);
|
||||
return gun.aim_time.toFixed(2);
|
||||
case 'fire.caliber':
|
||||
return shell0.caliber.toFixed(0);
|
||||
case 'fire.damage':
|
||||
@@ -47,7 +46,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
case 'fire.dispersionMoving':
|
||||
return tracks.dispersion_move.toFixed(3);
|
||||
case 'fire.dispersionStill':
|
||||
return gun.gun_type!.value.base.dispersion_base.toFixed(3);
|
||||
return gun.dispersion_base.toFixed(3);
|
||||
case 'fire.dpm':
|
||||
return resolveDpm(gun, shell0).toFixed(0);
|
||||
case 'fire.dpmPremium':
|
||||
@@ -63,7 +62,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
case 'fire.shellVelocity':
|
||||
return shell0.velocity.toFixed(0);
|
||||
case 'fire.shellCapacity':
|
||||
return gun.gun_type!.value.base.shell_capacity.toFixed(0);
|
||||
return gun.shell_capacity.toFixed(0);
|
||||
case 'fire.shellRange':
|
||||
return shell0.range.toFixed(0);
|
||||
case 'fire.gunDepression':
|
||||
@@ -89,7 +88,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
engine.weight +
|
||||
tracks.weight +
|
||||
turret.weight +
|
||||
gun.gun_type!.value.base.weight)
|
||||
gun.weight)
|
||||
).toFixed(1);
|
||||
case 'maneuverability.weight':
|
||||
return (
|
||||
@@ -97,7 +96,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
engine.weight +
|
||||
tracks.weight +
|
||||
turret.weight +
|
||||
gun.gun_type!.value.base.weight) /
|
||||
gun.weight) /
|
||||
1000
|
||||
).toFixed(1);
|
||||
case 'maneuverability.traverseSpeed':
|
||||
@@ -111,11 +110,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
case 'survivability.camouflageMoving':
|
||||
return (tank.camouflage_moving * 100).toFixed(0);
|
||||
case 'survivability.camouflageShooting':
|
||||
return (
|
||||
tank.camouflage_still *
|
||||
gun.gun_type!.value.base.camouflage_loss *
|
||||
100
|
||||
).toFixed(0);
|
||||
return (tank.camouflage_still * gun.camouflage_loss * 100).toFixed(0);
|
||||
case 'survivability.volume': {
|
||||
const dimensions = normalizeBoundingBox(
|
||||
unionBoundingBox(
|
||||
|
||||
@@ -104,11 +104,9 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.camouflage_still *
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.camouflage_loss -
|
||||
a.turrets.at(-1)!.guns.at(-1)!.camouflage_loss -
|
||||
b.camouflage_still *
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.camouflage_loss,
|
||||
b.turrets.at(-1)!.guns.at(-1)!.camouflage_loss,
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -171,11 +169,11 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
(a, b) =>
|
||||
resolveDpm(
|
||||
a.turrets.at(-1)!.guns.at(-1)!,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0],
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0],
|
||||
) -
|
||||
resolveDpm(
|
||||
b.turrets.at(-1)!.guns.at(-1)!,
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0],
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0],
|
||||
),
|
||||
);
|
||||
break;
|
||||
@@ -183,18 +181,16 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
case 'fire.dpmPremium':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
(a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1]
|
||||
(a.turrets.at(-1)!.guns.at(-1)!.shells[1]
|
||||
? resolveDpm(
|
||||
a.turrets.at(-1)!.guns.at(-1)!,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.shells[1],
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[1],
|
||||
)
|
||||
: 0) -
|
||||
(b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1]
|
||||
(b.turrets.at(-1)!.guns.at(-1)!.shells[1]
|
||||
? resolveDpm(
|
||||
b.turrets.at(-1)!.guns.at(-1)!,
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.shells[1],
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[1],
|
||||
)
|
||||
: 0),
|
||||
);
|
||||
@@ -211,108 +207,92 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
case 'fire.caliber':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.caliber -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.caliber,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0].caliber -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0].caliber,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.standardPenetration':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.penetration.near -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.penetration.near,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration.near -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration.near,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.premiumPenetration':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
(a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1]
|
||||
?.penetration.near ?? 0) -
|
||||
(b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1]
|
||||
?.penetration.near ?? 0),
|
||||
(a.turrets.at(-1)!.guns.at(-1)!.shells[1]?.penetration.near ??
|
||||
0) -
|
||||
(b.turrets.at(-1)!.guns.at(-1)!.shells[1]?.penetration.near ??
|
||||
0),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.tertiaryPenetration':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
(a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[2]
|
||||
?.penetration.near ?? 0) -
|
||||
(b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[2]
|
||||
?.penetration.near ?? 0),
|
||||
(a.turrets.at(-1)!.guns.at(-1)!.shells[2]?.penetration.near ??
|
||||
0) -
|
||||
(b.turrets.at(-1)!.guns.at(-1)!.shells[2]?.penetration.near ??
|
||||
0),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.damage':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.armor_damage -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.armor_damage,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0].armor_damage -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0].armor_damage,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.moduleDamage':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.module_damage -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.module_damage,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0].module_damage -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0].module_damage,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.shellVelocity':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.velocity -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.velocity,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0].velocity -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0].velocity,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.shellRange':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.range -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.range,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shells[0].range -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shells[0].range,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.shellCapacity':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.shell_capacity -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.shell_capacity,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.shell_capacity -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.shell_capacity,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.aimTime':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.aim_time -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.aim_time,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.aim_time -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.aim_time,
|
||||
);
|
||||
break;
|
||||
|
||||
case 'fire.dispersionStill':
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.dispersion_base -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.dispersion_base,
|
||||
a.turrets.at(-1)!.guns.at(-1)!.dispersion_base -
|
||||
b.turrets.at(-1)!.guns.at(-1)!.dispersion_base,
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -328,13 +308,11 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
modelDefinitions.models[a.id].turrets[a.turrets.at(-1)!.id]
|
||||
.guns[a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id]
|
||||
.pitch.max +
|
||||
.guns[a.turrets.at(-1)!.guns.at(-1)!.id].pitch.max +
|
||||
(modelDefinitions.models[a.id].initial_turret_rotation?.pitch ??
|
||||
0) -
|
||||
modelDefinitions.models[b.id].turrets[b.turrets.at(-1)!.id]
|
||||
.guns[b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id]
|
||||
.pitch.max -
|
||||
.guns[b.turrets.at(-1)!.guns.at(-1)!.id].pitch.max -
|
||||
(modelDefinitions.models[b.id].initial_turret_rotation?.pitch ??
|
||||
0),
|
||||
);
|
||||
@@ -344,13 +322,11 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
sorted = filtered.sort(
|
||||
(a, b) =>
|
||||
modelDefinitions.models[b.id].turrets[b.turrets.at(-1)!.id]
|
||||
.guns[b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id]
|
||||
.pitch.min +
|
||||
.guns[b.turrets.at(-1)!.guns.at(-1)!.id].pitch.min +
|
||||
(modelDefinitions.models[b.id].initial_turret_rotation?.pitch ??
|
||||
0) -
|
||||
modelDefinitions.models[a.id].turrets[a.turrets.at(-1)!.id]
|
||||
.guns[a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id]
|
||||
.pitch.min -
|
||||
.guns[a.turrets.at(-1)!.guns.at(-1)!.id].pitch.min -
|
||||
(modelDefinitions.models[a.id].initial_turret_rotation?.pitch ??
|
||||
0),
|
||||
);
|
||||
@@ -382,14 +358,13 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
a.engines.at(-1)!.weight +
|
||||
a.tracks.at(-1)!.weight +
|
||||
a.turrets.at(-1)!.weight +
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base
|
||||
.weight) -
|
||||
a.turrets.at(-1)!.guns.at(-1)!.weight) -
|
||||
b.engines.at(-1)!.power /
|
||||
(b.weight +
|
||||
b.engines.at(-1)!.weight +
|
||||
b.tracks.at(-1)!.weight +
|
||||
b.turrets.at(-1)!.weight +
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.weight),
|
||||
b.turrets.at(-1)!.guns.at(-1)!.weight),
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -400,12 +375,12 @@ export const TankSearch = memo<TankSearchProps>(
|
||||
a.engines.at(-1)!.weight +
|
||||
a.tracks.at(-1)!.weight +
|
||||
a.turrets.at(-1)!.weight +
|
||||
a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.weight -
|
||||
a.turrets.at(-1)!.guns.at(-1)!.weight -
|
||||
(b.weight +
|
||||
b.engines.at(-1)!.weight +
|
||||
b.tracks.at(-1)!.weight +
|
||||
b.turrets.at(-1)!.weight +
|
||||
b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.weight),
|
||||
b.turrets.at(-1)!.guns.at(-1)!.weight),
|
||||
);
|
||||
break;
|
||||
|
||||
|
||||
+8
-15
@@ -26,6 +26,7 @@ import { AssaultRangesVisualizer } from './AssaultRangesVisualizer';
|
||||
import { GunFlexibilityVisualizer } from './GunFlexibilityVisualizer';
|
||||
import { Info } from './Info';
|
||||
import { InfoWithDelta } from './InfoWithDelta';
|
||||
import { ReloadVisualizer } from './ReloadVisualizer';
|
||||
import { RicochetVisualizer } from './RicochetVisualizer';
|
||||
import { StatsTableWrapper } from './StatsTableWrapper';
|
||||
import type { StatsAcceptorProps } from './TraverseVisualizer';
|
||||
@@ -54,8 +55,7 @@ export function Firepower({
|
||||
]);
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
|
||||
useEffect(() => {
|
||||
if (penetrationDistanceInput.current) {
|
||||
@@ -71,7 +71,7 @@ export function Firepower({
|
||||
</Heading>
|
||||
|
||||
<Flex>
|
||||
{gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => {
|
||||
{gun.shells.map((thisShell, shellIndex) => {
|
||||
const selected = thisShell.id === shell.id;
|
||||
|
||||
return (
|
||||
@@ -84,13 +84,9 @@ export function Firepower({
|
||||
borderTopLeftRadius: shellIndex === 0 ? undefined : 0,
|
||||
borderBottomLeftRadius: shellIndex === 0 ? undefined : 0,
|
||||
borderTopRightRadius:
|
||||
shellIndex === gun.gun_type!.value.base.shells.length - 1
|
||||
? undefined
|
||||
: 0,
|
||||
shellIndex === gun.shells.length - 1 ? undefined : 0,
|
||||
borderBottomRightRadius:
|
||||
shellIndex === gun.gun_type!.value.base.shells.length - 1
|
||||
? undefined
|
||||
: 0,
|
||||
shellIndex === gun.shells.length - 1 ? undefined : 0,
|
||||
marginLeft: shellIndex === 0 ? 0 : -1,
|
||||
}}
|
||||
onClick={() => {
|
||||
@@ -125,11 +121,8 @@ export function Firepower({
|
||||
<InfoWithDelta stats={stats} decimals={0} value="moduleDamage" />
|
||||
<InfoWithDelta stats={stats} decimals={0} value="penetration" />
|
||||
|
||||
{gun.gun_type!.value.base.assault_ranges?.types.includes(shell.type) && (
|
||||
<AssaultRangesVisualizer
|
||||
stats={stats}
|
||||
ranges={gun.gun_type!.value.base.assault_ranges}
|
||||
/>
|
||||
{gun.assault_ranges?.types.includes(shell.type) && (
|
||||
<AssaultRangesVisualizer stats={stats} ranges={gun.assault_ranges} />
|
||||
)}
|
||||
|
||||
{gun.gun_type!.$case === 'auto_reloader' && (
|
||||
@@ -190,7 +183,7 @@ export function Firepower({
|
||||
value="intraClip"
|
||||
/>
|
||||
)}
|
||||
{/* <ReloadVisualizer stats={stats} /> */}
|
||||
<ReloadVisualizer stats={stats} />
|
||||
|
||||
{typeof shell.penetration !== 'number' && (
|
||||
<>
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ export function ModelChunk({ only }: Props) {
|
||||
|
||||
const tankModel = modelDefinitions.models[tank.id];
|
||||
const turretModel = tankModel.turrets[turret.id];
|
||||
const gunModel = turretModel.guns[gun.gun_type!.value.base.id];
|
||||
const gunModel = turretModel.guns[gun.id];
|
||||
|
||||
const originZ = tankModel.turret_origin.z + turretModel.gun_origin.z;
|
||||
const originY = tankModel.turret_origin.y + turretModel.gun_origin.y;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ export function GunFlexibilityVisualizer({
|
||||
|
||||
const tankModel = modelDefinition.models[tank.id];
|
||||
const turretModel = tankModel.turrets[turret.id];
|
||||
const gunModel = turretModel.guns[gun.gun_type!.value.base.id];
|
||||
const gunModel = turretModel.guns[gun.id];
|
||||
|
||||
const [yaw, setYaw] = useState(0);
|
||||
const [pitch, setPitch] = useState(0);
|
||||
|
||||
+3
-7
@@ -61,9 +61,7 @@ export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
||||
const delta = useDelta(uhWhatDoICallThisVariable);
|
||||
const protagonistTank = Duel.use((state) => state.protagonist.tank);
|
||||
const shellIndex = Duel.use((state) =>
|
||||
state.protagonist.gun.gun_type!.value.base.shells.indexOf(
|
||||
state.protagonist.shell,
|
||||
),
|
||||
state.protagonist.gun.shells.indexOf(state.protagonist.shell),
|
||||
);
|
||||
const equipmentMatrix = Duel.use(
|
||||
(state) => state.protagonist.equipmentMatrix,
|
||||
@@ -89,9 +87,7 @@ export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
||||
provisionDefinitions,
|
||||
);
|
||||
|
||||
if (
|
||||
member.gun.gun_type!.value.base.shells[shellIndex] === undefined
|
||||
) {
|
||||
if (member.gun.shells[shellIndex] === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -107,7 +103,7 @@ export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
||||
engine: member.engine,
|
||||
gun: member.gun,
|
||||
equipmentMatrix: equipmentMatrix,
|
||||
shell: member.gun.gun_type!.value.base.shells[shellIndex],
|
||||
shell: member.gun.shells[shellIndex],
|
||||
stockEngine: tank.engines[0],
|
||||
stockGun: tank.turrets[0].guns[0],
|
||||
stockTrack: tank.tracks[0],
|
||||
|
||||
+2
-4
@@ -11,7 +11,7 @@ export function ShellSwitcher() {
|
||||
|
||||
return (
|
||||
<Flex>
|
||||
{gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => {
|
||||
{gun.shells.map((thisShell, shellIndex) => {
|
||||
const selected = thisShell.id === shell.id;
|
||||
|
||||
return (
|
||||
@@ -26,9 +26,7 @@ export function ShellSwitcher() {
|
||||
borderBottomLeftRadius: shellIndex === 0 ? '50%' : 0,
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius:
|
||||
shellIndex === gun.gun_type!.value.base.shells.length - 1
|
||||
? '50%'
|
||||
: 0,
|
||||
shellIndex === gun.shells.length - 1 ? '50%' : 0,
|
||||
marginLeft: shellIndex === 0 ? 0 : -1,
|
||||
}}
|
||||
onClick={() => {
|
||||
|
||||
+1
-2
@@ -41,8 +41,7 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) {
|
||||
const stockGun = stockTurret.guns[0];
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const stats = tankCharacteristics(
|
||||
{
|
||||
tank,
|
||||
|
||||
+15
-26
@@ -33,7 +33,7 @@ type ModuleDefinition =
|
||||
|
||||
function extractModule(raw: ModuleDefinition | TankDefinition) {
|
||||
if ('gun_type' in raw) {
|
||||
return raw.gun_type!.value.base;
|
||||
return raw;
|
||||
} else
|
||||
return raw as Exclude<ModuleDefinition | TankDefinition, GunDefinition>;
|
||||
}
|
||||
@@ -179,37 +179,31 @@ export function Modules() {
|
||||
|
||||
if (
|
||||
!draft.protagonist.turret.guns.some(
|
||||
(gun) =>
|
||||
gun.gun_type!.value.base.id ===
|
||||
draft.protagonist.gun.gun_type!.value.base.id,
|
||||
(gun) => gun.id === draft.protagonist.gun.id,
|
||||
)
|
||||
) {
|
||||
draft.protagonist.gun = draft.protagonist.turret.guns.at(-1)!;
|
||||
draft.protagonist.shell =
|
||||
draft.protagonist.gun.gun_type!.value.base.shells[0];
|
||||
draft.protagonist.shell = draft.protagonist.gun.shells[0];
|
||||
}
|
||||
} else if (unlock.type === ModuleType.GUN) {
|
||||
const gunInTurret = draft.protagonist.turret.guns.find(
|
||||
(gun) => gun.gun_type!.value.base.id === unlock.id,
|
||||
(gun) => gun.id === unlock.id,
|
||||
);
|
||||
if (gunInTurret) {
|
||||
draft.protagonist.gun = gunInTurret;
|
||||
draft.protagonist.shell = gunInTurret.gun_type!.value.base.shells[0];
|
||||
draft.protagonist.shell = gunInTurret.shells[0];
|
||||
} else {
|
||||
// TODO: warn somehow?
|
||||
const suitableTurret = draft.protagonist.tank.turrets.find((turret) =>
|
||||
turret.guns.some(
|
||||
(gun) => gun.gun_type!.value.base.id === unlock.id,
|
||||
),
|
||||
turret.guns.some((gun) => gun.id === unlock.id),
|
||||
)!;
|
||||
const gunInSuitableTurret = suitableTurret.guns.find(
|
||||
(gun) => gun.gun_type!.value.base.id === unlock.id,
|
||||
(gun) => gun.id === unlock.id,
|
||||
)!;
|
||||
|
||||
draft.protagonist.turret = suitableTurret;
|
||||
draft.protagonist.gun = gunInSuitableTurret;
|
||||
draft.protagonist.shell =
|
||||
gunInSuitableTurret.gun_type!.value.base.shells[0];
|
||||
draft.protagonist.shell = gunInSuitableTurret.shells[0];
|
||||
}
|
||||
} else if (unlock.type === ModuleType.ENGINE) {
|
||||
draft.protagonist.engine = draft.protagonist.tank.engines.find(
|
||||
@@ -241,11 +235,9 @@ export function Modules() {
|
||||
} else if (unlock.type === ModuleType.GUN) {
|
||||
module = tank.turrets
|
||||
.find((turret) =>
|
||||
turret.guns.some(
|
||||
(gun) => gun.gun_type!.value.base.id === unlock.id,
|
||||
),
|
||||
turret.guns.some((gun) => gun.id === unlock.id),
|
||||
)!
|
||||
.guns.find((gun) => gun.gun_type!.value.base.id === unlock.id)!;
|
||||
.guns.find((gun) => gun.id === unlock.id)!;
|
||||
} else if (unlock.type === ModuleType.VEHICLE) {
|
||||
module = tankDefinitions.tanks[unlock.id];
|
||||
}
|
||||
@@ -308,7 +300,7 @@ export function Modules() {
|
||||
(unlock.type === ModuleType.TURRET
|
||||
? turret.id
|
||||
: unlock.type === ModuleType.GUN
|
||||
? gun.gun_type!.value.base.id
|
||||
? gun.id
|
||||
: unlock.type === ModuleType.ENGINE
|
||||
? engine.id
|
||||
: unlock.type === ModuleType.TRACKS
|
||||
@@ -319,8 +311,7 @@ export function Modules() {
|
||||
unlock.type === ModuleType.TURRET
|
||||
? extractModule(module).id == topTurret.id
|
||||
: unlock.type === ModuleType.GUN
|
||||
? extractModule(module).id ===
|
||||
topGun.gun_type!.value.base.id
|
||||
? extractModule(module).id === topGun.id
|
||||
: unlock.type === ModuleType.ENGINE
|
||||
? extractModule(module).id === topEngine.id
|
||||
: unlock.type === ModuleType.TRACKS
|
||||
@@ -371,8 +362,7 @@ export function Modules() {
|
||||
mutateDuel((draft) => {
|
||||
draft.protagonist.turret = draft.protagonist.tank.turrets[0];
|
||||
draft.protagonist.gun = draft.protagonist.turret.guns[0];
|
||||
draft.protagonist.shell =
|
||||
draft.protagonist.gun.gun_type!.value.base.shells[0];
|
||||
draft.protagonist.shell = draft.protagonist.gun.shells[0];
|
||||
draft.protagonist.engine = draft.protagonist.tank.engines[0];
|
||||
draft.protagonist.track = draft.protagonist.tank.tracks[0];
|
||||
});
|
||||
@@ -387,8 +377,7 @@ export function Modules() {
|
||||
draft.protagonist.turret =
|
||||
draft.protagonist.tank.turrets.at(-1)!;
|
||||
draft.protagonist.gun = draft.protagonist.turret.guns.at(-1)!;
|
||||
draft.protagonist.shell =
|
||||
draft.protagonist.gun.gun_type!.value.base.shells[0];
|
||||
draft.protagonist.shell = draft.protagonist.gun.shells[0];
|
||||
draft.protagonist.engine =
|
||||
draft.protagonist.tank.engines.at(-1)!;
|
||||
draft.protagonist.track =
|
||||
@@ -427,7 +416,7 @@ export function Modules() {
|
||||
{tree(ModuleType.GUN, [
|
||||
{
|
||||
cost: { type: 'xp', value: 0 },
|
||||
id: gun0.gun_type!.value.base.id,
|
||||
id: gun0.id,
|
||||
type: ModuleType.GUN,
|
||||
},
|
||||
])}
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ export function CustomShellButton() {
|
||||
modified.normalization = undefined;
|
||||
modified.ricochet = undefined;
|
||||
modified.explosion_radius =
|
||||
gun.gun_type!.value.base.shells.find(
|
||||
gun.shells.find(
|
||||
(shell) => shell.type === ShellType.HE,
|
||||
)?.explosion_radius ?? 1;
|
||||
break;
|
||||
|
||||
+1
-2
@@ -21,8 +21,7 @@ export function QuickInputs() {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
|
||||
const initialGunPitch =
|
||||
tankModelDefinition.initial_turret_rotation?.pitch ?? 0;
|
||||
const hasImprovedVerticalStabilizer = useEquipment(122);
|
||||
|
||||
+8
-15
@@ -141,7 +141,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
mr="2"
|
||||
mb="1"
|
||||
>
|
||||
{TIER_ROMAN_NUMERALS[antagonistGun.gun_type!.value.base.tier]}
|
||||
{TIER_ROMAN_NUMERALS[antagonistGun.tier]}
|
||||
</Text>
|
||||
|
||||
<img
|
||||
@@ -161,26 +161,20 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
{[...antagonistUniqueGuns].reverse().map(({ gun, turret }) => (
|
||||
<ModuleButton
|
||||
module="gun"
|
||||
key={gun.gun_type!.value.base.id}
|
||||
key={gun.id}
|
||||
onClick={() =>
|
||||
mutateDuel((draft) => {
|
||||
draft.antagonist.turret = turret;
|
||||
draft.antagonist.gun = gun;
|
||||
draft.antagonist.shell =
|
||||
gun.gun_type!.value.base.shells[0];
|
||||
draft.antagonist.shell = gun.shells[0];
|
||||
})
|
||||
}
|
||||
selected={
|
||||
gun.gun_type!.value.base.id ===
|
||||
antagonistGun.gun_type!.value.base.id
|
||||
}
|
||||
discriminator={
|
||||
TIER_ROMAN_NUMERALS[gun.gun_type!.value.base.tier]
|
||||
}
|
||||
selected={gun.id === antagonistGun.id}
|
||||
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
||||
secondaryDiscriminator={
|
||||
<Text style={{ fontSize: '0.75em' }}>
|
||||
{literals(strings.common.units.mm, [
|
||||
gun.gun_type!.value.base.shells[0].caliber.toFixed(0),
|
||||
gun.shells[0].caliber.toFixed(0),
|
||||
])}
|
||||
</Text>
|
||||
}
|
||||
@@ -198,7 +192,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
}}
|
||||
overflow="hidden"
|
||||
>
|
||||
{antagonistGun.gun_type!.value.base.shells.map((thisShell) => (
|
||||
{antagonistGun.shells.map((thisShell) => (
|
||||
<IconButton
|
||||
color={
|
||||
thisShell.id === antagonistShell.id && !hasCustomShell
|
||||
@@ -367,8 +361,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
draft.antagonist.turret = tank.turrets.at(-1)!;
|
||||
draft.antagonist.gun =
|
||||
draft.antagonist.turret.guns.at(-1)!;
|
||||
draft.antagonist.shell =
|
||||
draft.antagonist.gun.gun_type!.value.base.shells[0];
|
||||
draft.antagonist.shell = draft.antagonist.gun.shells[0];
|
||||
});
|
||||
setAntagonistSelectorOpen(false);
|
||||
}}
|
||||
|
||||
+1
-3
@@ -56,9 +56,7 @@ export function Controls({
|
||||
const antagonistTurretModelDefinition =
|
||||
antagonistModelDefinition.turrets[antagonistTurret.id];
|
||||
const protagonistGunModelDefinition =
|
||||
protagonistTurretModelDefinition.guns[
|
||||
protagonistGun.gun_type!.value.base.id
|
||||
];
|
||||
protagonistTurretModelDefinition.guns[protagonistGun.id];
|
||||
const protagonistHullOrigin = new Vector3(
|
||||
protagonistTrackModelDefinition.origin.x,
|
||||
protagonistTrackModelDefinition.origin.y,
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ export function InitialAligner() {
|
||||
|
||||
const tankModel = modelDefinitions.models[tank.id];
|
||||
const turretModel = tankModel.turrets[turret.id];
|
||||
const gunModel = turretModel.guns[gun.gun_type!.value.base.id];
|
||||
const gunModel = turretModel.guns[gun.id];
|
||||
|
||||
useEffect(() => {
|
||||
const [pitch, yaw] = applyPitchYawLimits(
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ export function SceneProps() {
|
||||
const trackModelDefinition =
|
||||
modelDefinitions.models[tank.id].tracks[track.id];
|
||||
const gunModelDefinition =
|
||||
tankModelDefinition.turrets[turret.id].guns[gun.gun_type!.value.base.id];
|
||||
tankModelDefinition.turrets[turret.id].guns[gun.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const hullOrigin = new Vector3(
|
||||
trackModelDefinition.origin.x,
|
||||
|
||||
+1
-2
@@ -28,8 +28,7 @@ export function TankModel() {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
|
||||
const { gltf } = useModel(protagonist.tank.id);
|
||||
const nodes = Object.values(gltf.nodes);
|
||||
|
||||
|
||||
+1
-2
@@ -31,8 +31,7 @@ export function TransitionSkeleton() {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
|
||||
const { gltf } = useModel(protagonist.tank.id);
|
||||
const nodes = Object.values(gltf.nodes);
|
||||
const revealed = tankopediaEphemeralStore((state) => state.revealed);
|
||||
|
||||
+1
-2
@@ -59,8 +59,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonistTurret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonistGun.id];
|
||||
const rawDisplay = TankopediaEphemeral.use((state) => state.display);
|
||||
const [display, setDisplay] = useState(rawDisplay);
|
||||
const hideTankModelUnderArmor = TankopediaPersistent.use(
|
||||
|
||||
@@ -29,8 +29,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
||||
(filtered.reduce((accumulator, thisTank) => {
|
||||
return (
|
||||
accumulator +
|
||||
thisTank.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0]
|
||||
.penetration.near
|
||||
thisTank.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration.near
|
||||
);
|
||||
}, 0) /
|
||||
filtered.length) *
|
||||
@@ -51,8 +50,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
||||
|
||||
useEffect(() => {
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
const { shells } =
|
||||
duelStore.getState().antagonist.gun.gun_type!.value.base;
|
||||
const { shells } = duelStore.getState().antagonist.gun;
|
||||
|
||||
times(3, (index) => {
|
||||
if (event.key === `${index + 1}` && shells.length > index) {
|
||||
|
||||
Reference in new issue
Block a user