mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
fix: use code
This commit is contained in:
1 parent
93632a7073
commit
99c95a4c15
1 file changed
+154
-144
@@ -1,13 +1,20 @@
|
|||||||
import { ReloadIcon } from "@radix-ui/react-icons";
|
import { ReloadIcon } from "@radix-ui/react-icons";
|
||||||
import { Card, Flex, IconButton, Text, TextField } from "@radix-ui/themes";
|
import {
|
||||||
|
Card,
|
||||||
|
Code,
|
||||||
|
Flex,
|
||||||
|
IconButton,
|
||||||
|
Text,
|
||||||
|
TextField,
|
||||||
|
} from "@radix-ui/themes";
|
||||||
import { Html } from "@react-three/drei";
|
import { Html } from "@react-three/drei";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { radToDeg } from "three/src/math/MathUtils.js";
|
import { radToDeg } from "three/src/math/MathUtils.js";
|
||||||
import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex";
|
import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex";
|
||||||
|
import { LocaleProvider, useLocale } from "../../../hooks/useLocale";
|
||||||
import { App } from "../../../stores/app";
|
import { App } from "../../../stores/app";
|
||||||
import { Duel } from "../../../stores/duel";
|
import { Duel } from "../../../stores/duel";
|
||||||
import { Tankopedia } from "../../../stores/tankopedia";
|
import { Tankopedia } from "../../../stores/tankopedia";
|
||||||
import { CopyableCode } from "../../CopyableCode";
|
|
||||||
import { layerTypeNames } from "./ShotDisplayCard";
|
import { layerTypeNames } from "./ShotDisplayCard";
|
||||||
import { ArmorType } from "./SpacedArmorScene";
|
import { ArmorType } from "./SpacedArmorScene";
|
||||||
|
|
||||||
@@ -15,6 +22,7 @@ export function ArmorPlateDisplay() {
|
|||||||
const highlightArmor = Tankopedia.use((state) => state.highlightArmor);
|
const highlightArmor = Tankopedia.use((state) => state.highlightArmor);
|
||||||
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
||||||
const input = useRef<HTMLInputElement>(null);
|
const input = useRef<HTMLInputElement>(null);
|
||||||
|
const { locale } = useLocale();
|
||||||
|
|
||||||
if (highlightArmor === undefined) return null;
|
if (highlightArmor === undefined) return null;
|
||||||
|
|
||||||
@@ -24,162 +32,164 @@ export function ArmorPlateDisplay() {
|
|||||||
center
|
center
|
||||||
style={{ pointerEvents: highlightArmor.editingPlate ? "auto" : "none" }}
|
style={{ pointerEvents: highlightArmor.editingPlate ? "auto" : "none" }}
|
||||||
>
|
>
|
||||||
<Card
|
<LocaleProvider locale={locale}>
|
||||||
variant="classic"
|
<Card
|
||||||
mb="4"
|
variant="classic"
|
||||||
style={{
|
mb="4"
|
||||||
whiteSpace: "nowrap",
|
style={{
|
||||||
color: highlightArmor.color,
|
whiteSpace: "nowrap",
|
||||||
transform: "translateY(-50%)",
|
color: highlightArmor.color,
|
||||||
}}
|
transform: "translateY(-50%)",
|
||||||
>
|
}}
|
||||||
<Flex direction="column">
|
>
|
||||||
<Text weight="bold">
|
<Flex direction="column">
|
||||||
{layerTypeNames[highlightArmor.type]}{" "}
|
<Text weight="bold">
|
||||||
{highlightArmor.thickness.toFixed(0)}
|
{layerTypeNames[highlightArmor.type]}{" "}
|
||||||
<Text size="1" weight="regular">
|
{highlightArmor.thickness.toFixed(0)}
|
||||||
mm
|
<Text size="1" weight="regular">
|
||||||
</Text>
|
mm
|
||||||
</Text>
|
|
||||||
|
|
||||||
{highlightArmor.type !== ArmorType.External && (
|
|
||||||
<Text size="2" color="gray">
|
|
||||||
{highlightArmor.thicknessAngled.toFixed(0)}
|
|
||||||
<Text size="1">
|
|
||||||
mm {radToDeg(highlightArmor.angle).toFixed(0)}°
|
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
|
||||||
|
|
||||||
{developerMode && (
|
{highlightArmor.type !== ArmorType.External && (
|
||||||
<>
|
<Text size="2" color="gray">
|
||||||
<Text mt="2" color="gray" size="2">
|
{highlightArmor.thicknessAngled.toFixed(0)}
|
||||||
<b>DEV:</b>{" "}
|
<Text size="1">
|
||||||
<CopyableCode
|
mm {radToDeg(highlightArmor.angle).toFixed(0)}°
|
||||||
copy={highlightArmor.name}
|
</Text>
|
||||||
variant="soft"
|
|
||||||
highContrast
|
|
||||||
color="gray"
|
|
||||||
>
|
|
||||||
{highlightArmor.name}
|
|
||||||
</CopyableCode>
|
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{highlightArmor.editingPlate && (
|
{developerMode && (
|
||||||
<Flex gap="2" align="center">
|
<>
|
||||||
<TextField.Root
|
<Text mt="2" color="gray" size="2">
|
||||||
variant="classic"
|
<b>DEV:</b>{" "}
|
||||||
style={{ width: 96 }}
|
<Code variant="soft" highContrast color="gray">
|
||||||
mt="2"
|
{highlightArmor.name}
|
||||||
ref={input}
|
</Code>
|
||||||
key={highlightArmor.name}
|
</Text>
|
||||||
type="number"
|
</>
|
||||||
autoFocus
|
)}
|
||||||
onFocus={(event) => event.target.select()}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (!highlightArmor.editingPlate) return;
|
|
||||||
|
|
||||||
const index = resolveArmorIndex(highlightArmor.name);
|
{highlightArmor.editingPlate && (
|
||||||
|
<Flex gap="2" align="center">
|
||||||
if (index === undefined) return;
|
<TextField.Root
|
||||||
|
variant="classic"
|
||||||
const thickness = event.currentTarget.valueAsNumber;
|
style={{ width: 96 }}
|
||||||
|
mt="2"
|
||||||
if (isNaN(thickness) || thickness < 0) return;
|
ref={input}
|
||||||
|
key={highlightArmor.name}
|
||||||
if (event.key === "Enter") {
|
type="number"
|
||||||
input.current?.blur();
|
autoFocus
|
||||||
|
onFocus={(event) => event.target.select()}
|
||||||
Tankopedia.mutate((draft) => {
|
onKeyDown={(event) => {
|
||||||
draft.highlightArmor = undefined;
|
|
||||||
const { protagonist } = Duel.state;
|
|
||||||
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];
|
|
||||||
|
|
||||||
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();
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
draft.highlightArmor = undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onClick={(event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
}}
|
|
||||||
defaultValue={highlightArmor.thickness.toFixed(0)}
|
|
||||||
>
|
|
||||||
<TextField.Slot side="right">mm</TextField.Slot>
|
|
||||||
</TextField.Root>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
mt="2"
|
|
||||||
color="red"
|
|
||||||
onClick={() => {
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
if (!highlightArmor.editingPlate) return;
|
if (!highlightArmor.editingPlate) return;
|
||||||
|
|
||||||
const index = resolveArmorIndex(highlightArmor.name);
|
const index = resolveArmorIndex(highlightArmor.name);
|
||||||
|
|
||||||
if (index === undefined) return;
|
if (index === undefined) return;
|
||||||
|
|
||||||
draft.highlightArmor = undefined;
|
const thickness = event.currentTarget.valueAsNumber;
|
||||||
const initialState = Tankopedia.initial;
|
|
||||||
const { protagonist } = Duel.state;
|
|
||||||
const tank = draft.model;
|
|
||||||
const initialTank = initialState.model;
|
|
||||||
const turret = tank.turrets[protagonist.turret.id];
|
|
||||||
const initialTurret =
|
|
||||||
initialTank.turrets[protagonist.turret.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];
|
|
||||||
|
|
||||||
if (highlightArmor.name.startsWith("hull_")) {
|
if (isNaN(thickness) || thickness < 0) return;
|
||||||
tank.armor!.thickness[index] =
|
|
||||||
initialTank.armor!.thickness[index];
|
if (event.key === "Enter") {
|
||||||
} else if (highlightArmor.name.startsWith("turret_")) {
|
input.current?.blur();
|
||||||
turret.armor!.thickness[index] =
|
|
||||||
initialTurret.armor!.thickness[index];
|
Tankopedia.mutate((draft) => {
|
||||||
} else if (highlightArmor.name.startsWith("gun_")) {
|
draft.highlightArmor = undefined;
|
||||||
if (highlightArmor.name.includes("_armor_")) {
|
const { protagonist } = Duel.state;
|
||||||
gun.armor!.thickness[index] =
|
const tank = draft.model;
|
||||||
initialGun.armor!.thickness[index];
|
const turret = tank.turrets[protagonist.turret.id];
|
||||||
} else {
|
const gun = turret.guns[protagonist.gun.id];
|
||||||
gun.thickness = initialGun.thickness;
|
const track = tank.tracks[protagonist.track.id];
|
||||||
}
|
|
||||||
} else if (highlightArmor.name.startsWith("chassis_")) {
|
if (highlightArmor.name.startsWith("hull_")) {
|
||||||
track.thickness = initialTrack.thickness;
|
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();
|
||||||
|
Tankopedia.mutate((draft) => {
|
||||||
|
draft.highlightArmor = undefined;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
}}
|
||||||
}}
|
onClick={(event) => {
|
||||||
>
|
event.stopPropagation();
|
||||||
<ReloadIcon />
|
event.preventDefault();
|
||||||
</IconButton>
|
}}
|
||||||
</Flex>
|
defaultValue={highlightArmor.thickness.toFixed(0)}
|
||||||
)}
|
>
|
||||||
</Flex>
|
<TextField.Slot side="right">mm</TextField.Slot>
|
||||||
</Card>
|
</TextField.Root>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
mt="2"
|
||||||
|
color="red"
|
||||||
|
onClick={() => {
|
||||||
|
Tankopedia.mutate((draft) => {
|
||||||
|
if (!highlightArmor.editingPlate) return;
|
||||||
|
|
||||||
|
const index = resolveArmorIndex(highlightArmor.name);
|
||||||
|
|
||||||
|
if (index === undefined) return;
|
||||||
|
|
||||||
|
draft.highlightArmor = undefined;
|
||||||
|
const initialState = Tankopedia.initial;
|
||||||
|
const { protagonist } = Duel.state;
|
||||||
|
const tank = draft.model;
|
||||||
|
const initialTank = initialState.model;
|
||||||
|
const turret = tank.turrets[protagonist.turret.id];
|
||||||
|
const initialTurret =
|
||||||
|
initialTank.turrets[protagonist.turret.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];
|
||||||
|
|
||||||
|
if (highlightArmor.name.startsWith("hull_")) {
|
||||||
|
tank.armor!.thickness[index] =
|
||||||
|
initialTank.armor!.thickness[index];
|
||||||
|
} else if (highlightArmor.name.startsWith("turret_")) {
|
||||||
|
turret.armor!.thickness[index] =
|
||||||
|
initialTurret.armor!.thickness[index];
|
||||||
|
} else if (highlightArmor.name.startsWith("gun_")) {
|
||||||
|
if (highlightArmor.name.includes("_armor_")) {
|
||||||
|
gun.armor!.thickness[index] =
|
||||||
|
initialGun.armor!.thickness[index];
|
||||||
|
} else {
|
||||||
|
gun.thickness = initialGun.thickness;
|
||||||
|
}
|
||||||
|
} else if (highlightArmor.name.startsWith("chassis_")) {
|
||||||
|
track.thickness = initialTrack.thickness;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ReloadIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</LocaleProvider>
|
||||||
</Html>
|
</Html>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user