Files
blitzkit/packages/website/src/components/PrimaryArmorScene.tsx
T

137 lines
4.7 KiB
TypeScript
Raw Normal View History

2025-09-27 16:07:45 -05:00
import { memo, useRef } from "react";
import { Group } from "three";
2026-09-27 16:46:22 -05:00
import { correctZYTuple } from "../core/blitz/correctZYTuple";
import { nameToArmorId } from "../core/blitzkit/nameToArmorId";
import { resolveArmor } from "../core/blitzkit/resolveThickness";
import { useArmor } from "../hooks/useArmor";
import { DuelModule, useDuel } from "../hooks/useDuel";
2025-09-27 16:07:45 -05:00
import { ModelTankWrapper } from "./ModelTankWrapper";
import { PrimaryArmorSceneComponent } from "./PrimaryArmorSceneComponent";
2024-01-15 21:55:09 -06:00
2024-07-29 20:46:57 -05:00
export const PrimaryArmorScene = memo(() => {
2024-02-28 17:41:59 -06:00
const wrapper = useRef<Group>(null);
2025-09-27 16:07:45 -05:00
const turretContainer = useRef<Group>(null!);
const gunContainer = useRef<Group>(null!);
2026-09-23 17:37:52 -05:00
const tank = useDuel("protagonist", DuelModule.Tank);
const track = useDuel("protagonist", DuelModule.Track);
const turret = useDuel("protagonist", DuelModule.Turret);
const gun = useDuel("protagonist", DuelModule.Gun);
const armorGltf = useArmor(tank.id).gltf;
2024-07-26 13:24:18 -05:00
const armorNodes = Object.values(armorGltf.nodes);
2024-07-30 13:24:55 -05:00
const tankModelDefinition = useTankModelDefinition();
2024-07-26 13:24:18 -05:00
const trackModelDefinition = tankModelDefinition.tracks[track.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
2025-08-18 12:06:14 -05:00
const gunModelDefinition = turretModelDefinition.guns[gun.id];
2026-03-31 14:11:45 -05:00
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
const isDynamicArmorActive = Duel.use((state) =>
2026-03-31 14:11:45 -05:00
state.protagonist.consumables.includes(73),
2024-08-28 21:16:25 -05:00
);
2024-07-30 13:24:55 -05:00
useTankTransform(track, turret, turretContainer, gunContainer);
2024-02-28 17:41:59 -06:00
return (
2024-07-28 13:32:52 -05:00
<ModelTankWrapper ref={wrapper}>
2024-07-13 19:49:00 -05:00
<group position={hullOrigin}>
{armorNodes.map((node) => {
2025-09-27 16:07:45 -05:00
const isHull = node.name.startsWith("hull_");
2024-07-13 19:49:00 -05:00
const isVisible = isHull;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
2026-03-31 14:11:45 -05:00
tankModelDefinition.armor!,
armorId,
2024-07-13 19:49:00 -05:00
);
2024-02-28 17:41:59 -06:00
2024-08-28 21:16:25 -05:00
if (
!isVisible ||
spaced ||
thickness === undefined ||
2025-09-27 16:07:45 -05:00
(isDynamicArmorActive && node.name.includes("state_01")) ||
(!isDynamicArmorActive && node.name.includes("state_00"))
2024-08-28 21:16:25 -05:00
)
return null;
2024-07-13 19:49:00 -05:00
return (
2024-07-29 20:46:57 -05:00
<PrimaryArmorSceneComponent
2024-07-13 19:49:00 -05:00
key={node.uuid}
thickness={thickness}
node={node}
/>
);
})}
</group>
<group ref={turretContainer}>
2024-07-24 20:46:42 -05:00
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
2025-11-27 13:42:37 -06:00
`turret_${turretModelDefinition.model_id
.toString()
2026-03-31 14:11:45 -05:00
.padStart(2, "0")}`,
2024-07-24 20:46:42 -05:00
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
2026-03-31 14:11:45 -05:00
turretModelDefinition.armor!,
armorId,
2024-07-24 20:46:42 -05:00
);
2024-08-28 21:16:25 -05:00
if (
!isVisible ||
spaced ||
thickness === undefined ||
2025-09-27 16:07:45 -05:00
(isDynamicArmorActive && node.name.includes("state_01")) ||
(!isDynamicArmorActive && node.name.includes("state_00"))
2024-08-28 21:16:25 -05:00
)
return null;
2024-07-24 20:46:42 -05:00
return (
2024-09-22 21:27:46 -05:00
<group position={hullOrigin} key={node.uuid}>
<group position={turretOrigin}>
2024-07-29 20:46:57 -05:00
<PrimaryArmorSceneComponent
2024-07-27 13:46:36 -05:00
key={node.uuid}
thickness={thickness}
node={node}
/>
</group>
2024-07-24 20:46:42 -05:00
</group>
);
})}
<group ref={gunContainer}>
2024-01-15 21:55:09 -06:00
{armorNodes.map((node) => {
2024-07-24 20:46:42 -05:00
const isCurrentGun = node.name.startsWith(
2026-03-31 14:11:45 -05:00
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`,
2024-07-13 19:49:00 -05:00
);
2024-07-24 20:46:42 -05:00
const isVisible = isCurrentGun;
2024-01-15 21:55:09 -06:00
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
2026-03-31 14:11:45 -05:00
gunModelDefinition.armor!,
armorId,
2024-01-15 21:55:09 -06:00
);
2024-08-28 21:16:25 -05:00
if (
!isVisible ||
spaced ||
thickness === undefined ||
2025-09-27 16:07:45 -05:00
(isDynamicArmorActive && node.name.includes("state_01")) ||
(!isDynamicArmorActive && node.name.includes("state_00"))
2024-08-28 21:16:25 -05:00
)
return null;
2024-01-15 21:55:09 -06:00
return (
2024-09-22 21:27:46 -05:00
<group position={hullOrigin} key={node.uuid}>
<group position={turretOrigin.clone().add(gunOrigin)}>
2024-07-29 20:46:57 -05:00
<PrimaryArmorSceneComponent
thickness={thickness}
node={node}
/>
2024-07-27 13:46:36 -05:00
</group>
2024-07-13 19:49:00 -05:00
</group>
2024-01-15 21:55:09 -06:00
);
})}
2024-01-22 16:54:07 -06:00
</group>
2024-01-15 21:55:09 -06:00
</group>
2024-07-24 20:46:42 -05:00
</ModelTankWrapper>
2024-02-28 17:41:59 -06:00
);
});