From f86a4022ea1d006b1cae0ea4e8209b3e13231a50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Mon, 29 Jul 2024 14:08:52 -0500
Subject: [PATCH] feat: armor toggle buttons
---
.../[id]/components/Model/HeroSection.tsx | 59 +++-
.../[id]/components/Model/TankSandbox.tsx | 9 +-
.../components/Model/components/Options.tsx | 22 +-
.../[id]/components/QuickInputs/index.tsx | 6 +-
.../[id]/components/Thicknesses.tsx | 130 +++++++++
.../SpacedArmorSceneComponent/index.tsx | 255 +++++++++---------
.../components/StaticArmorScene.tsx | 59 +---
src/components/StaticArmor/index.tsx | 24 +-
src/stores/tankopediaPersistent/index.ts | 4 +
9 files changed, 353 insertions(+), 215 deletions(-)
create mode 100644 src/app/tools/tankopedia/[id]/components/Thicknesses.tsx
diff --git a/src/app/tools/tankopedia/[id]/components/Model/HeroSection.tsx b/src/app/tools/tankopedia/[id]/components/Model/HeroSection.tsx
index 06799d6f9..931213969 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/HeroSection.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/HeroSection.tsx
@@ -1,8 +1,11 @@
import { ChevronLeftIcon, MixIcon } from '@radix-ui/react-icons';
import { Box, Button, Flex, Heading, Text } from '@radix-ui/themes';
import Link from 'next/link';
-import { Suspense, useEffect, useState } from 'react';
+import { Suspense, use, useEffect, useMemo, useState } from 'react';
import { classIcons } from '../../../../../../components/ClassIcon';
+import { ThicknessRange } from '../../../../../../components/StaticArmor/components/StaticArmorScene';
+import { modelDefinitions } from '../../../../../../core/blitzkit/modelDefinitions';
+import { tankDefinitions } from '../../../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../../../core/blitzkit/tankDefinitions/constants';
import { useFullScreen } from '../../../../../../hooks/useFullScreen';
import strings from '../../../../../../lang/en-US.json';
@@ -11,7 +14,11 @@ import { Options } from './components/Options';
import { TankSandbox } from './TankSandbox';
import { TankSandboxLoader } from './TankSandboxLoader';
-export function HeroSection({ id }: { id: number }) {
+interface HeroSectionProps {
+ id: number;
+}
+
+export function HeroSection({ id }: HeroSectionProps) {
const protagonist = Duel.use((state) => state.protagonist.tank);
const antagonist = Duel.use((state) => state.antagonist.tank);
const compareTanks =
@@ -27,6 +34,50 @@ export function HeroSection({ id }: { id: number }) {
: protagonist.treeType === 'premium'
? 'amber'
: undefined;
+ const awaitedTankDefinitions = use(tankDefinitions);
+ const awaitedModelDefinitions = use(modelDefinitions);
+ const tank = awaitedTankDefinitions[id];
+ const thicknessRange = useMemo(() => {
+ const thicknesses = Object.values(awaitedTankDefinitions)
+ .filter((thisTank) => thisTank.tier === tank.tier)
+ .map((tank) => ({
+ model: awaitedModelDefinitions[tank.id],
+ id: tank.id,
+ }))
+ .filter(Boolean)
+ .map(({ model, id }) => {
+ const tankThicknesses = Object.values(model.armor.thickness);
+ const turretThicknesses = Object.values(model.turrets)
+ .map((turret) => {
+ const turretThicknesses = Object.values(turret.armor.thickness);
+ const gunThicknesses = Object.values(turret.guns)
+ .map((gun) => Object.values(gun.armor.thickness))
+ .flat();
+
+ return [...turretThicknesses, ...gunThicknesses];
+ })
+ .flat();
+ const totalThicknesses = [...tankThicknesses, ...turretThicknesses];
+
+ return totalThicknesses;
+ })
+ .flat();
+
+ const sortedThicknesses = thicknesses.sort((a, b) => a - b);
+ const quartileIndex = (1 - 2 ** -6) * (sortedThicknesses.length + 1) - 1;
+ let quartile: number;
+
+ if (Number.isInteger(quartileIndex)) {
+ quartile = sortedThicknesses[quartileIndex];
+ } else {
+ quartile =
+ (sortedThicknesses[Math.floor(quartileIndex)] +
+ sortedThicknesses[Math.ceil(quartileIndex)]) /
+ 2;
+ }
+
+ return { quartile } satisfies ThicknessRange;
+ }, [tank.tier]);
useEffect(() => {
setDummyLoader(false);
@@ -129,11 +180,11 @@ export function HeroSection({ id }: { id: number }) {
/>
}
>
-
+
-
+
diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx
index ffd7a967b..dd66c984f 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx
@@ -4,6 +4,7 @@ import { Armor } from '../../../../../../components/Armor';
import { ArmorPlateDisplay } from '../../../../../../components/Armor/components/ArmorPlateDisplay';
import { ShotDisplay } from '../../../../../../components/Armor/components/ShotDisplay';
import { StaticArmor } from '../../../../../../components/StaticArmor';
+import { ThicknessRange } from '../../../../../../components/StaticArmor/components/StaticArmorScene';
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
import { modelDefinitions } from '../../../../../../core/blitzkit/modelDefinitions';
import { modelTransformEvent } from '../../../../../../core/blitzkit/modelTransform';
@@ -20,7 +21,11 @@ import { SceneProps } from '../SceneProps';
import { ModelLoader } from './components/ModelLoader';
import { TankModel } from './components/TankModel';
-export function TankSandbox() {
+interface TankSandboxProps {
+ thicknessRange: ThicknessRange;
+}
+
+export function TankSandbox({ thicknessRange }: TankSandboxProps) {
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const canvas = useRef(null);
const hasImprovedVerticalStabilizer = useEquipment(122);
@@ -165,7 +170,7 @@ export function TankSandbox() {
}>
{display === TankopediaDisplay.DynamicArmor && }
{display === TankopediaDisplay.StaticArmor && (
-
+
)}
diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx
index 46d1f6d53..61898b218 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx
@@ -22,6 +22,7 @@ import {
import { useEffect, useState } from 'react';
import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
import { SmallTankIcon } from '../../../../../../../components/SmallTankIcon';
+import { ThicknessRange } from '../../../../../../../components/StaticArmor/components/StaticArmorScene';
import { resolveNearPenetration } from '../../../../../../../core/blitz/resolveNearPenetration';
import { resolvePenetrationCoefficient } from '../../../../../../../core/blitz/resolvePenetrationCoefficient';
import { asset } from '../../../../../../../core/blitzkit/asset';
@@ -42,9 +43,14 @@ import * as TankopediaPersistent from '../../../../../../../stores/tankopediaPer
import { TankopediaDisplay } from '../../../../../../../stores/tankopediaPersistent/constants';
import { TankSearch } from '../../../../components/TankSearch';
import { ENVIRONMENTS } from '../../Lighting';
-import { RotationInputs } from '../../QuickInputs';
+import { QuickInputs } from '../../QuickInputs';
+import { Thicknesses } from '../../Thicknesses';
-export function Options() {
+interface OptionsProps {
+ thicknessRange: ThicknessRange;
+}
+
+export function Options({ thicknessRange }: OptionsProps) {
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
const displayRaw = TankopediaPersistent.use((state) => state.display);
@@ -113,7 +119,11 @@ export function Options() {
)}
-
+
+
+ {display === TankopediaDisplay.StaticArmor && (
+
+ )}
{display === TankopediaDisplay.DynamicArmor && (
-
+
-
+
-
+
diff --git a/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx b/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx
index 3c04fd8e7..4ee0350e9 100644
--- a/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx
+++ b/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx
@@ -9,12 +9,10 @@ import {
ModelTransformEventData,
} from '../../../../../../core/blitzkit/modelTransform';
import { useEquipment } from '../../../../../../hooks/useEquipment';
-import { useFullScreen } from '../../../../../../hooks/useFullScreen';
import * as Duel from '../../../../../../stores/duel';
-import * as TankopediaPersistent from '../../../../../../stores/tankopediaPersistent';
import * as styles from './index.css';
-export function RotationInputs() {
+export function QuickInputs() {
const mutateDuel = Duel.useMutation();
const protagonist = Duel.use((state) => state.protagonist);
const awaitedModelDefinitions = use(modelDefinitions);
@@ -26,8 +24,6 @@ export function RotationInputs() {
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
const initialGunPitch = tankModelDefinition.turretRotation?.pitch ?? 0;
const hasImprovedVerticalStabilizer = useEquipment(122);
- const isFullScreen = useFullScreen();
- const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
useEffect(() => {
yawInput.current!.value = radToDeg(protagonist.yaw).toFixed(1);
diff --git a/src/app/tools/tankopedia/[id]/components/Thicknesses.tsx b/src/app/tools/tankopedia/[id]/components/Thicknesses.tsx
new file mode 100644
index 000000000..33309ec08
--- /dev/null
+++ b/src/app/tools/tankopedia/[id]/components/Thicknesses.tsx
@@ -0,0 +1,130 @@
+import { EyeClosedIcon, EyeOpenIcon } from '@radix-ui/react-icons';
+import { Box, Flex, Text } from '@radix-ui/themes';
+import { ThicknessRange } from '../../../../../components/StaticArmor/components/StaticArmorScene';
+import * as TankopediaPersistent from '../../../../../stores/tankopediaPersistent';
+
+interface ThicknessesProps {
+ thicknessRange: ThicknessRange;
+}
+
+export function Thicknesses({ thicknessRange }: ThicknessesProps) {
+ const showExternalModules = TankopediaPersistent.use(
+ (state) => state.model.visual.showExternalModules,
+ );
+ const showSpacedArmor = TankopediaPersistent.use(
+ (state) => state.model.visual.showSpacedArmor,
+ );
+ const showCoreArmor = TankopediaPersistent.use(
+ (state) => state.model.visual.showCoreArmor,
+ );
+ const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
+
+ return (
+
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.showCoreArmor =
+ !draft.model.visual.showCoreArmor;
+ });
+ }}
+ >
+
+
+ {thicknessRange.quartile.toFixed(0)}
+
+
+ {showCoreArmor ? : }
+ Core
+
+
+ 0
+
+
+
+
+
+
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.showSpacedArmor =
+ !draft.model.visual.showSpacedArmor;
+ });
+ }}
+ >
+
+
+ {thicknessRange.quartile.toFixed(0)}
+
+
+ {showSpacedArmor ? : }
+ Spaced
+
+
+ 0
+
+
+
+
+
+
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.showExternalModules =
+ !draft.model.visual.showExternalModules;
+ });
+ }}
+ >
+
+
+ {showExternalModules ? : }
+ External
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx
index 6ee4ed792..b18e94545 100644
--- a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx
+++ b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx
@@ -36,7 +36,6 @@ function to255(value: number) {
type SpacedArmorSceneComponentProps = {
node: Object3D;
thickness: number;
- scene: Scene;
clip?: Plane;
} & (
| {
@@ -50,6 +49,7 @@ type SpacedArmorSceneComponentProps = {
(
| {
static?: false;
+ scene: Scene;
}
| {
static: true;
@@ -88,7 +88,6 @@ const externalModuleColor = new Color(0, 1 / 4, 1 / 2);
export function SpacedArmorSceneComponent({
node,
thickness,
- scene,
clip,
...props
}: SpacedArmorSceneComponentProps) {
@@ -97,6 +96,131 @@ export function SpacedArmorSceneComponent({
const camera = useThree((state) => state.camera);
const duelStore = Duel.useStore();
+ if (props.static) {
+ const x = clamp(thickness / props.thicknessRange.quartile, 0, 1);
+ const y = Math.sqrt(x);
+
+ let color: Color;
+ let opacity: number;
+ let renderOrder = 1;
+ let depthWrite = true;
+
+ switch (props.type) {
+ case ArmorType.Core:
+ color = new Color(-((1 - y) ** 2) + 1, -(y ** 2) + 1, 0);
+ opacity = 1;
+ break;
+
+ case ArmorType.Spaced:
+ color = new Color(1 - (7 / 8) * y, 0, 1 - (1 / 8) * y);
+ opacity = x + 1 / 2;
+ break;
+
+ case ArmorType.External:
+ color = externalModuleColor;
+ opacity = 1 / 8;
+ renderOrder = 0;
+ depthWrite = false;
+ break;
+ }
+
+ opacity = clamp(opacity, 0, 1);
+
+ const material = useMemo(
+ () =>
+ new MeshStandardMaterial({
+ color,
+ opacity,
+ transparent: true,
+ depthWrite,
+ ...(clip ? { clippingPlanes: [clip] } : {}),
+ }),
+ [],
+ );
+
+ /**
+ * hook inside an if statement?? don't panic! I assure you the static prop
+ * never mutates :)
+ */
+ useEffect(() => {
+ function handleHighlightArmor(selectedName?: string) {
+ if (!props.static) return;
+
+ if (selectedName === undefined) {
+ // nothing selected, go back to defaults
+ material.opacity = opacity;
+ material.transparent = opacity < 1;
+ material.color = color;
+ material.depthWrite = props.type !== ArmorType.External;
+ material.side = FrontSide;
+ } else if (
+ selectedName === props.name ||
+ (props.name.startsWith('chassis_') &&
+ selectedName.startsWith('chassis_')) ||
+ (props.name.startsWith('gun_') &&
+ selectedName.startsWith('gun_') &&
+ !props.name.includes('_armor_') &&
+ !selectedName.includes('_armor_'))
+ ) {
+ // this selected, stand out!
+ material.opacity = 1;
+ material.transparent = false;
+ material.color = color;
+ material.depthWrite = true;
+ material.side = DoubleSide;
+ } else {
+ // something else selected, become background
+ material.opacity = 1 / 4;
+ material.transparent = true;
+ material.color = unselectedColor;
+ material.depthWrite = props.type !== ArmorType.External;
+ material.side = FrontSide;
+ }
+ }
+
+ const unsubscribe = tankopediaEphemeralStore.subscribe(
+ (state) => state.highlightArmor?.name,
+ handleHighlightArmor,
+ );
+
+ return unsubscribe;
+ }, []);
+
+ return jsxTree(node, {
+ material,
+ renderOrder,
+ userData: {
+ type: props.type,
+ variant: props.type === ArmorType.External ? props.variant : 'gun',
+ thickness,
+ } satisfies ArmorUserData,
+
+ onClick(event) {
+ event.stopPropagation();
+
+ const { point } = event;
+ const cameraNormal = camera.position.clone().sub(point).normalize();
+ const surfaceNormal = event
+ .normal!.clone()
+ .applyQuaternion(event.object.getWorldQuaternion(new Quaternion()));
+ const angle = surfaceNormal.angleTo(cameraNormal);
+ const thicknessAngled = thickness / Math.sin(Math.PI / 2 - angle);
+
+ mutateTankopediaEphemeralStore((draft) => {
+ draft.highlightArmor = {
+ type: props.type,
+ name: props.name,
+ point,
+ thickness,
+ thicknessAngled,
+ angle,
+ color: `#${color.getHexString()}`,
+ };
+ });
+ },
+ });
+ }
+
const shoot = useCallback(
async (
point: Vector3,
@@ -345,7 +469,7 @@ export function SpacedArmorSceneComponent({
caster.set(lastLayer.point, ricochetNormal);
const ricochetIntersections = caster.intersectObjects(
- scene.children,
+ props.scene.children,
true,
);
const outShot = await shoot(
@@ -377,131 +501,6 @@ export function SpacedArmorSceneComponent({
[camera],
);
- if (props.static) {
- const x = clamp(thickness / props.thicknessRange.quartile, 0, 1);
- const y = Math.sqrt(x);
-
- let color: Color;
- let opacity: number;
- let renderOrder = 1;
- let depthWrite = true;
-
- switch (props.type) {
- case ArmorType.Core:
- color = new Color(-((1 - y) ** 2) + 1, -(y ** 2) + 1, 0);
- opacity = 1;
- break;
-
- case ArmorType.Spaced:
- color = new Color(1 - (7 / 8) * y, 0, 1 - (1 / 8) * y);
- opacity = x + 1 / 2;
- break;
-
- case ArmorType.External:
- color = externalModuleColor;
- opacity = 1 / 8;
- renderOrder = 0;
- depthWrite = false;
- break;
- }
-
- opacity = clamp(opacity, 0, 1);
-
- const material = useMemo(
- () =>
- new MeshStandardMaterial({
- color,
- opacity,
- transparent: true,
- depthWrite,
- ...(clip ? { clippingPlanes: [clip] } : {}),
- }),
- [],
- );
-
- /**
- * hook inside an if statement?? don't panic! I assure you the static prop
- * never mutates :)
- */
- useEffect(() => {
- function handleHighlightArmor(selectedName?: string) {
- if (!props.static) return;
-
- if (selectedName === undefined) {
- // nothing selected, go back to defaults
- material.opacity = opacity;
- material.transparent = opacity < 1;
- material.color = color;
- material.depthWrite = props.type !== ArmorType.External;
- material.side = FrontSide;
- } else if (
- selectedName === props.name ||
- (props.name.startsWith('chassis_') &&
- selectedName.startsWith('chassis_')) ||
- (props.name.startsWith('gun_') &&
- selectedName.startsWith('gun_') &&
- !props.name.includes('_armor_') &&
- !selectedName.includes('_armor_'))
- ) {
- // this selected, stand out!
- material.opacity = 1;
- material.transparent = false;
- material.color = color;
- material.depthWrite = true;
- material.side = DoubleSide;
- } else {
- // something else selected, become background
- material.opacity = 1 / 4;
- material.transparent = true;
- material.color = unselectedColor;
- material.depthWrite = props.type !== ArmorType.External;
- material.side = FrontSide;
- }
- }
-
- const unsubscribe = tankopediaEphemeralStore.subscribe(
- (state) => state.highlightArmor?.name,
- handleHighlightArmor,
- );
-
- return unsubscribe;
- }, []);
-
- return jsxTree(node, {
- material,
- renderOrder,
- userData: {
- type: props.type,
- variant: props.type === ArmorType.External ? props.variant : 'gun',
- thickness,
- } satisfies ArmorUserData,
-
- onClick(event) {
- event.stopPropagation();
-
- const { point } = event;
- const cameraNormal = camera.position.clone().sub(point).normalize();
- const surfaceNormal = event
- .normal!.clone()
- .applyQuaternion(event.object.getWorldQuaternion(new Quaternion()));
- const angle = surfaceNormal.angleTo(cameraNormal);
- const thicknessAngled = thickness / Math.sin(Math.PI / 2 - angle);
-
- mutateTankopediaEphemeralStore((draft) => {
- draft.highlightArmor = {
- type: props.type,
- name: props.name,
- point,
- thickness,
- thicknessAngled,
- angle,
- color: `#${color.getHexString()}`,
- };
- });
- },
- });
- }
-
return (
<>
{props.type === ArmorType.Core &&
diff --git a/src/components/StaticArmor/components/StaticArmorScene.tsx b/src/components/StaticArmor/components/StaticArmorScene.tsx
index 6e2c481f0..faace2aa8 100644
--- a/src/components/StaticArmor/components/StaticArmorScene.tsx
+++ b/src/components/StaticArmor/components/StaticArmorScene.tsx
@@ -1,9 +1,8 @@
-import { memo, useMemo, useRef } from 'react';
-import { Group, Plane, Scene, Vector3 } from 'three';
+import { memo, useRef } from 'react';
+import { Group, Plane, Vector3 } from 'three';
import { correctZYTuple } from '../../../core/blitz/correctZYTuple';
import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId';
import { resolveArmor } from '../../../core/blitzkit/resolveThickness';
-import { TankDefinitions } from '../../../core/blitzkit/tankDefinitions';
import { useArmor } from '../../../hooks/useArmor';
import { useModel } from '../../../hooks/useModel';
import { useModelDefinitions } from '../../../hooks/useModelDefinitions';
@@ -14,8 +13,7 @@ import { ArmorType } from '../../Armor/components/SpacedArmorScene';
import { SpacedArmorSceneComponent } from '../../Armor/components/SpacedArmorSceneComponent';
interface StaticArmorSceneProps {
- scene: Scene;
- awaitedTankDefinitions: TankDefinitions;
+ thicknessRange: ThicknessRange;
}
export interface ThicknessRange {
@@ -24,7 +22,7 @@ export interface ThicknessRange {
}
export const StaticArmorScene = memo(
- ({ scene, awaitedTankDefinitions }) => {
+ ({ thicknessRange }) => {
const wrapper = useRef(null);
const awaitedTankModelDefinitions = useModelDefinitions();
const turretContainer = useRef(null);
@@ -49,50 +47,6 @@ export const StaticArmorScene = memo(
gunModelDefinition.mask === undefined
? undefined
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
- let thisTankThicknesses: number[] = [];
- const thicknessRange = useMemo(() => {
- const thicknesses = Object.values(awaitedTankDefinitions)
- .filter((thisTank) => thisTank.tier === tank.tier)
- .map((tank) => ({
- model: awaitedTankModelDefinitions[tank.id],
- id: tank.id,
- }))
- .filter(Boolean)
- .map(({ model, id }) => {
- const tankThicknesses = Object.values(model.armor.thickness);
- const turretThicknesses = Object.values(model.turrets)
- .map((turret) => {
- const turretThicknesses = Object.values(turret.armor.thickness);
- const gunThicknesses = Object.values(turret.guns)
- .map((gun) => Object.values(gun.armor.thickness))
- .flat();
-
- return [...turretThicknesses, ...gunThicknesses];
- })
- .flat();
- const totalThicknesses = [...tankThicknesses, ...turretThicknesses];
-
- if (id === tank.id) thisTankThicknesses = totalThicknesses;
-
- return totalThicknesses;
- })
- .flat();
-
- const sortedThicknesses = thicknesses.sort((a, b) => a - b);
- const quartileIndex = (1 - 2 ** -6) * (sortedThicknesses.length + 1) - 1;
- let quartile: number;
-
- if (Number.isInteger(quartileIndex)) {
- quartile = sortedThicknesses[quartileIndex];
- } else {
- quartile =
- (sortedThicknesses[Math.floor(quartileIndex)] +
- sortedThicknesses[Math.ceil(quartileIndex)]) /
- 2;
- }
-
- return { quartile } satisfies ThicknessRange;
- }, [tank.tier]);
useTankTransform(protagonist, turretContainer, gunContainer);
@@ -115,7 +69,6 @@ export const StaticArmorScene = memo(
name={node.name}
thicknessRange={thicknessRange}
static
- scene={scene}
key={node.uuid}
type={spaced ? ArmorType.Spaced : ArmorType.Core}
thickness={thickness}
@@ -137,7 +90,6 @@ export const StaticArmorScene = memo(
name={node.name}
thicknessRange={thicknessRange}
static
- scene={scene}
key={node.uuid}
type={ArmorType.External}
thickness={trackModelDefinition.thickness}
@@ -168,7 +120,6 @@ export const StaticArmorScene = memo(
name={node.name}
thicknessRange={thicknessRange}
static
- scene={scene}
key={node.uuid}
type={spaced ? ArmorType.Spaced : ArmorType.Core}
thickness={thickness}
@@ -203,7 +154,6 @@ export const StaticArmorScene = memo(
name={node.name}
thicknessRange={thicknessRange}
static
- scene={scene}
type={spaced ? ArmorType.Spaced : ArmorType.Core}
thickness={thickness}
node={node}
@@ -227,7 +177,6 @@ export const StaticArmorScene = memo(
name={node.name}
thicknessRange={thicknessRange}
static
- scene={scene}
key={node.uuid}
type={ArmorType.External}
thickness={gunModelDefinition.thickness}
diff --git a/src/components/StaticArmor/index.tsx b/src/components/StaticArmor/index.tsx
index ebf5b65e8..fbb719bb6 100644
--- a/src/components/StaticArmor/index.tsx
+++ b/src/components/StaticArmor/index.tsx
@@ -1,18 +1,12 @@
-import { useThree } from '@react-three/fiber';
-import { TankDefinitions } from '../../core/blitzkit/tankDefinitions';
-import { StaticArmorScene } from './components/StaticArmorScene';
+import {
+ StaticArmorScene,
+ ThicknessRange,
+} from './components/StaticArmorScene';
-export function StaticArmor({
- awaitedTankDefinitions,
-}: {
- awaitedTankDefinitions: TankDefinitions;
-}) {
- const scene = useThree((state) => state.scene);
+interface StaticArmorProps {
+ thicknessRange: ThicknessRange;
+}
- return (
-
- );
+export function StaticArmor({ thicknessRange }: StaticArmorProps) {
+ return ;
}
diff --git a/src/stores/tankopediaPersistent/index.ts b/src/stores/tankopediaPersistent/index.ts
index 3c036d878..643e8a089 100644
--- a/src/stores/tankopediaPersistent/index.ts
+++ b/src/stores/tankopediaPersistent/index.ts
@@ -22,6 +22,8 @@ export interface TankopediaPersistent {
greenPenetration: boolean;
showEnvironment: boolean;
showSpacedArmor: boolean;
+ showExternalModules: boolean;
+ showCoreArmor: boolean;
};
};
sort: {
@@ -47,6 +49,8 @@ export const { Provider, use, useMutation, useStore } = createNextSafeStore(
model: {
visual: {
showSpacedArmor: true,
+ showExternalModules: true,
+ showCoreArmor: true,
wireframe: false,
opaque: false,
environment: ENVIRONMENTS[0],