feat: upgrade tankopediaEphemeral

This commit is contained in:
TrèsAbhi committed 2025-09-01 18:51:04 -05:00
1 parent b6c3fdc4e9
commit ac29d1ead0
28 files changed
+165 -168

No files matched your search

@@ -21,11 +21,9 @@ export function ArmorPlateDisplay() {
const highlightArmor = TankopediaEphemeral.use(
(state) => state.highlightArmor,
);
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const developerMode = App.useDeferred((state) => state.developerMode, false);
const duelStore = Duel.useStore();
const input = useRef<HTMLInputElement>(null);
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
if (highlightArmor === undefined) return null;
@@ -95,7 +93,7 @@ export function ArmorPlateDisplay() {
if (event.key === 'Enter') {
input.current?.blur();
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.highlightArmor = undefined;
const { protagonist } = duelStore.getState();
const tank = draft.model;
@@ -119,7 +117,7 @@ export function ArmorPlateDisplay() {
});
} else if (event.key === 'Escape') {
input.current?.blur();
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.highlightArmor = undefined;
});
}
@@ -137,7 +135,7 @@ export function ArmorPlateDisplay() {
mt="2"
color="red"
onClick={() => {
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
if (!highlightArmor.editingPlate) return;
const index = resolveArmorIndex(highlightArmor.name);
@@ -145,8 +143,7 @@ export function ArmorPlateDisplay() {
if (index === undefined) return;
draft.highlightArmor = undefined;
const initialState =
tankopediaEphemeralStore.getInitialState();
const initialState = TankopediaEphemeral.initial;
const { protagonist } = duelStore.getState();
const tank = draft.model;
const initialTank = initialState.model;
@@ -43,7 +43,6 @@ export function PrimaryArmorSceneComponent({
}: PrimaryArmorSceneComponentProps) {
const tankopediaPersistentStore = TankopediaPersistent.useStore();
const duelStore = Duel.useStore();
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const material = new ShaderMaterial({
fragmentShader,
vertexShader,
@@ -82,7 +81,7 @@ export function PrimaryArmorSceneComponent({
useEffect(() => {
function handleShellChange() {
const duel = duelStore.getState();
const tankopediaEphemeral = tankopediaEphemeralStore.getState();
const tankopediaEphemeral = TankopediaEphemeral.state;
const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
material.uniforms.caliber.value = shell.caliber;
@@ -136,7 +135,7 @@ export function PrimaryArmorSceneComponent({
noInvalidate = false,
) {
const duel = duelStore.getState();
const tankopediaEphemeral = tankopediaEphemeralStore.getState();
const tankopediaEphemeral = TankopediaEphemeral.state;
const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
const penetration = shell.penetration.near;
const hasCalibratedShells = hasEquipment(
@@ -168,10 +167,7 @@ export function PrimaryArmorSceneComponent({
const unsubscribes = [
duelStore.subscribe((state) => state.antagonist.shell, handleShellChange),
tankopediaEphemeralStore.subscribe(
(state) => state.customShell,
handleShellChange,
),
TankopediaEphemeral.on((state) => state.customShell, handleShellChange),
tankopediaPersistentStore.subscribe(
(state) => state.greenPenetration,
handleGreenPenetrationChange,
@@ -29,7 +29,6 @@ export function SpacedArmorSubExternal({
variant,
clip,
}: SpacedArmorSubExternalProps) {
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const duelStore = Duel.useStore();
const material = new ShaderMaterial({
fragmentShader,
@@ -50,7 +49,7 @@ export function SpacedArmorSubExternal({
useEffect(() => {
function handleShellChange() {
const duel = duelStore.getState();
const tankopediaEphemeral = tankopediaEphemeralStore.getState();
const tankopediaEphemeral = TankopediaEphemeral.state;
const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
material.uniforms.penetration.value = shell.penetration.near;
}
@@ -67,7 +66,7 @@ export function SpacedArmorSubExternal({
}
function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
const duel = duelStore.getState();
const tankopediaEphemeral = tankopediaEphemeralStore.getState();
const tankopediaEphemeral = TankopediaEphemeral.state;
const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
const penetration = shell.penetration.near;
const hasCalibratedShells = hasEquipment(
@@ -91,10 +90,7 @@ export function SpacedArmorSubExternal({
const unsubscribes = [
duelStore.subscribe((state) => state.antagonist.shell, handleShellChange),
tankopediaEphemeralStore.subscribe(
(state) => state.customShell,
handleShellChange,
),
TankopediaEphemeral.on((state) => state.customShell, handleShellChange),
duelStore.subscribe(
(state) => state.protagonist.equipmentMatrix,
handleProtagonistEquipmentChange,
@@ -30,7 +30,6 @@ export function SpacedArmorSubSpaced({
node,
thickness,
}: SpacedArmorSubSpacedProps) {
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const duelStore = Duel.useStore();
const material = new ShaderMaterial({
fragmentShader,
@@ -52,7 +51,7 @@ export function SpacedArmorSubSpaced({
useEffect(() => {
function handleShellChange() {
const duel = duelStore.getState();
const tankopediaEphemeral = tankopediaEphemeralStore.getState();
const tankopediaEphemeral = TankopediaEphemeral.state;
const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
material.uniforms.penetration.value = shell.penetration.near;
@@ -77,7 +76,7 @@ export function SpacedArmorSubSpaced({
}
function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
const duel = duelStore.getState();
const tankopediaEphemeral = tankopediaEphemeralStore.getState();
const tankopediaEphemeral = TankopediaEphemeral.state;
const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
const penetration = shell.penetration.near;
const hasCalibratedShells = hasEquipment(
@@ -101,10 +100,7 @@ export function SpacedArmorSubSpaced({
const unsubscribes = [
duelStore.subscribe((state) => state.antagonist.shell, handleShellChange),
tankopediaEphemeralStore.subscribe(
(state) => state.customShell,
handleShellChange,
),
TankopediaEphemeral.on((state) => state.customShell, handleShellChange),
duelStore.subscribe(
(state) => state.protagonist.equipmentMatrix,
handleProtagonistEquipmentChange,
@@ -76,7 +76,6 @@ export function SpacedArmorSceneComponent({
clip,
...props
}: SpacedArmorSceneComponentProps) {
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const duelStore = Duel.useStore();
const camera = useThree((state) => state.camera);
@@ -88,7 +87,7 @@ export function SpacedArmorSceneComponent({
remainingPenetrationInput?: number,
) => {
const { antagonist, protagonist } = duelStore.getState();
const { customShell } = tankopediaEphemeralStore.getState();
const { customShell } = TankopediaEphemeral.state;
const shell = customShell ?? antagonist.shell;
const cameraNormal = camera.position.clone().sub(point).normalize();
const shot: Shot = {
@@ -391,7 +390,9 @@ export function SpacedArmorSceneComponent({
const shot = shoot(event.point, event.intersections, true)!;
tankopediaEphemeralStore.setState({ shot });
TankopediaEphemeral.mutate((draft) => {
draft.shot = shot;
});
}}
/>
);
@@ -46,7 +46,6 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
const canvas = useThree((state) => state.gl.domElement);
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const duelStore = Duel.useStore();
const maskOrigin =
gunModelDefinition.mask === undefined
@@ -155,10 +154,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
position.set(event.clientX, event.clientY);
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.controlsEnabled = false;
});
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.shot = undefined;
draft.highlightArmor = undefined;
});
@@ -194,7 +193,7 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
modelTransformEvent.dispatch({ pitch, yaw });
}
function handlePointerUp() {
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.controlsEnabled = true;
});
window.removeEventListener('pointermove', handlePointerMove);
@@ -245,10 +244,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
function onPointerDown(event: ThreeEvent<PointerEvent>) {
event.stopPropagation();
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.controlsEnabled = false;
});
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.shot = undefined;
draft.highlightArmor = undefined;
});
@@ -287,7 +286,7 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
modelTransformEvent.dispatch({ pitch, yaw });
}
function handlePointerUp() {
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.controlsEnabled = true;
});
window.removeEventListener('pointermove', handlePointerMove);
@@ -327,10 +326,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
function onPointerDown(event: ThreeEvent<PointerEvent>) {
event.stopPropagation();
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.controlsEnabled = false;
});
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.shot = undefined;
draft.highlightArmor = undefined;
});
@@ -368,7 +367,7 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
modelTransformEvent.dispatch({ pitch, yaw });
}
function handlePointerUp() {
mutateTankopediaEphemeral((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.controlsEnabled = true;
});
@@ -69,8 +69,6 @@ export function StaticArmorSceneComponent({
onPointerDown,
...props
}: StaticArmorSceneComponentProps) {
const mutateTankopediaEphemeralStore = TankopediaEphemeral.useMutation();
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const camera = useThree((state) => state.camera);
const x = thickness / thicknessRange.value;
const xClamped = clamp(x, 0, 1);
@@ -166,7 +164,7 @@ export function StaticArmorSceneComponent({
}
const unsubscribes = [
tankopediaEphemeralStore.subscribe(
TankopediaEphemeral.on(
(state) => state.highlightArmor?.name,
handleHighlightArmor,
),
@@ -238,7 +236,7 @@ export function StaticArmorSceneComponent({
event.stopPropagation();
const { editStatic } = tankopediaEphemeralStore.getState();
const { editStatic } = TankopediaEphemeral.state;
const bounds = new Box3().setFromObject(event.object);
const point = bounds.min
@@ -259,7 +257,7 @@ export function StaticArmorSceneComponent({
const thicknessAngled =
thickness / Math.sin(Math.PI / 2 - angle);
mutateTankopediaEphemeralStore((draft) => {
TankopediaEphemeral.mutate((draft) => {
draft.highlightArmor = {
type: props.type,
name,