diff --git a/src/app/tools/tankopedia/[id]/components/Prompts.tsx b/src/app/tools/tankopedia/[id]/components/Prompts.tsx deleted file mode 100644 index 60226948d..000000000 --- a/src/app/tools/tankopedia/[id]/components/Prompts.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Button, Dialog, Flex, Text, TextField } from '@radix-ui/themes'; -import { useRef } from 'react'; -import { ModelArmor } from '../../../../../core/blitzkit/modelDefinitions'; -import { resolveArmorIndex } from '../../../../../core/blitzkit/resolveArmorIndex'; -import * as Duel from '../../../../../stores/duel'; -import * as TankopediaEphemeral from '../../../../../stores/tankopediaEphemeral'; - -export function Prompts() { - const input = useRef(null); - const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); - const editingPlate = TankopediaEphemeral.use((state) => state.editingPlate); - const duelStore = Duel.useStore(); - - return ( - { - mutateTankopediaEphemeral((draft) => { - draft.editingPlate = undefined; - }); - }} - > - - - Edit thickness - - { - input.current?.select(); - }} - onKeyDown={(event) => { - if (!editingPlate) return; - - if (event.key === 'Enter') { - input.current?.blur(); - mutateTankopediaEphemeral((draft) => { - draft.editingPlate = undefined; - draft.highlightArmor = undefined; - const { protagonist } = duelStore.getState(); - let armor: ModelArmor; - - if (editingPlate.name.startsWith('hull_')) { - armor = draft.model.armor; - } else if (editingPlate.name.startsWith('turret_')) { - armor = draft.model.turrets[protagonist.turret.id].armor; - } else if (editingPlate.name.startsWith('gun_')) { - armor = - draft.model.turrets[protagonist.turret.id].guns[ - protagonist.gun.id - ].armor; - } else return; - - const index = resolveArmorIndex(editingPlate.name); - - if (index === undefined) return; - - const input = event.currentTarget.valueAsNumber; - - if (isNaN(input) || input < 0) return; - - armor.thickness[index] = input; - }); - } else if (event.key === 'Escape') { - input.current?.blur(); - mutateTankopediaEphemeral((draft) => { - draft.highlightArmor = undefined; - }); - } - }} - onClick={(event) => { - event.stopPropagation(); - event.preventDefault(); - }} - defaultValue={editingPlate?.default.toFixed(0)} - > - mm - - - - - - - - - - - - - - ); -} diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index 54f16dffc..56033181f 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -10,7 +10,6 @@ import { HistorySection } from './components/HistorySection'; import { CharacteristicsSection } from './components/Model/CharacteristicsSection'; import { HeroSection } from './components/Model/HeroSection'; import { TechTreeSection } from './components/Model/TechTreeSection'; -import { Prompts } from './components/Prompts'; import { ShotDisplaySection } from './components/ShotDisplaySection'; import { VideoSection } from './components/VideoSection'; @@ -75,8 +74,6 @@ export default function Page({ params }: { params: { id: string } }) { return ( - - {!exempt && } diff --git a/src/components/Armor/components/ArmorPlateDisplay.tsx b/src/components/Armor/components/ArmorPlateDisplay.tsx index 53f35989c..1f1274ca9 100644 --- a/src/components/Armor/components/ArmorPlateDisplay.tsx +++ b/src/components/Armor/components/ArmorPlateDisplay.tsx @@ -1,7 +1,8 @@ -import { Card, Code, Flex, Text } from '@radix-ui/themes'; +import { Card, Code, Flex, Text, TextField } from '@radix-ui/themes'; import { Html } from '@react-three/drei'; import { useRef } from 'react'; import { radToDeg } from 'three/src/math/MathUtils'; +import { resolveArmorIndex } from '../../../core/blitzkit/resolveArmorIndex'; import * as App from '../../../stores/app'; import * as Duel from '../../../stores/duel'; import * as TankopediaEphemeral from '../../../stores/tankopediaEphemeral'; @@ -16,12 +17,16 @@ export function ArmorPlateDisplay() { const developerMode = App.use((state) => state.developerMode); const devThicknessInput = useRef(null); const duelStore = Duel.useStore(); + const input = useRef(null); if (highlightArmor === undefined) return null; return ( - + + {highlightArmor.type !== ArmorType.External && ( {highlightArmor.thicknessAngled.toFixed(0)} @@ -54,6 +60,67 @@ export function ArmorPlateDisplay() { )} + + {highlightArmor.editingPlate && ( + event.target.select()} + onKeyDown={(event) => { + if (!highlightArmor.editingPlate) return; + + const index = resolveArmorIndex(highlightArmor.name); + + if (index === undefined) return; + + const thickness = event.currentTarget.valueAsNumber; + + if (isNaN(thickness) || thickness < 0) return; + + if (event.key === 'Enter') { + input.current?.blur(); + + mutateTankopediaEphemeral((draft) => { + draft.highlightArmor = undefined; + const { protagonist } = duelStore.getState(); + const tank = draft.model; + const turret = tank.turrets[protagonist.turret.id]; + const gun = turret.guns[protagonist.gun.id]; + const track = tank.tracks[protagonist.track.id]; + + console.log(highlightArmor.name); + if (highlightArmor.name.startsWith('hull_')) { + tank.armor.thickness[index] = thickness; + } else if (highlightArmor.name.startsWith('turret_')) { + turret.armor.thickness[index] = thickness; + } else if (highlightArmor.name.startsWith('gun_')) { + if (highlightArmor.name.includes('_armor_')) { + gun.armor.thickness[index] = thickness; + } else { + gun.thickness = thickness; + } + } else if (highlightArmor.name.startsWith('chassis_')) { + track.thickness = thickness; + } + }); + } else if (event.key === 'Escape') { + input.current?.blur(); + mutateTankopediaEphemeral((draft) => { + draft.highlightArmor = undefined; + }); + } + }} + onClick={(event) => { + event.stopPropagation(); + event.preventDefault(); + }} + defaultValue={highlightArmor.thickness.toFixed(0)} + > + mm + + )} diff --git a/src/components/Armor/components/StaticArmorSceneComponent.tsx b/src/components/Armor/components/StaticArmorSceneComponent.tsx index 52fc81afb..14d3fad7e 100644 --- a/src/components/Armor/components/StaticArmorSceneComponent.tsx +++ b/src/components/Armor/components/StaticArmorSceneComponent.tsx @@ -173,41 +173,31 @@ export function StaticArmorSceneComponent({ const { editStatic } = tankopediaEphemeralStore.getState(); - if (editStatic) { - mutateTankopediaEphemeralStore((draft) => { - draft.editingPlate = { - name: name, - default: thickness, - }; - }); - } else { - const bounds = new Box3().setFromObject(event.object); - const point = bounds.min - .clone() - .add(bounds.max) - .divideScalar(2) - .setY(bounds.max.y); - 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, - point, - thickness, - thicknessAngled, - angle, - color: `#${color.getHexString()}`, - }; - }); - } + const bounds = new Box3().setFromObject(event.object); + const point = bounds.min + .clone() + .add(bounds.max) + .divideScalar(2) + .setY(bounds.max.y); + 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); + console.log(name); + mutateTankopediaEphemeralStore((draft) => { + draft.highlightArmor = { + type: props.type, + name, + point, + thickness, + thicknessAngled, + angle, + color: `#${color.getHexString()}`, + editingPlate: editStatic, + }; + }); }, })} diff --git a/src/stores/tankopediaEphemeral.ts b/src/stores/tankopediaEphemeral.ts index 708021b93..f91d435c2 100644 --- a/src/stores/tankopediaEphemeral.ts +++ b/src/stores/tankopediaEphemeral.ts @@ -14,8 +14,8 @@ interface TankopediaEphemeral { controlsEnabled: boolean; model: ModelDefinition; editStatic: boolean; - editingPlate?: { name: string; default: number }; highlightArmor?: { + editingPlate: boolean; name: string; point: Vector3; thickness: number;