status buttons

This commit is contained in:
tresabhi committed 2026-05-30 14:29:17 -05:00
1 parent b297babde5
commit 477b9a9630
3 files changed
+54 -97

No files matched your search

@@ -11,7 +11,6 @@ import {
CornerBottomLeftIcon, CornerBottomLeftIcon,
DoubleArrowLeftIcon, DoubleArrowLeftIcon,
DoubleArrowRightIcon, DoubleArrowRightIcon,
ExclamationTriangleIcon,
ResetIcon, ResetIcon,
TrashIcon, TrashIcon,
} from "@radix-ui/react-icons"; } from "@radix-ui/react-icons";
@@ -34,6 +33,7 @@ import { useTierPrices } from "../../hooks/useTierPrices";
import { useUpgradePreset } from "../../hooks/useUpgradePreset"; import { useUpgradePreset } from "../../hooks/useUpgradePreset";
import { Tankopedia } from "../../stores/tankopedia"; import { Tankopedia } from "../../stores/tankopedia";
import type { ComputedCharacteristics } from "../../tankopedia/computeCharacteristics"; import type { ComputedCharacteristics } from "../../tankopedia/computeCharacteristics";
import { vehicleStatusKeys } from "../../tankopedia/tankState";
import { Button } from "../Button"; import { Button } from "../Button";
import { Heading } from "../Heading"; import { Heading } from "../Heading";
import { IconButton } from "../IconButton"; import { IconButton } from "../IconButton";
@@ -65,19 +65,7 @@ export function TankopediaLoadout({ characteristics }: TankopediaLoadoutProps) {
function State() { function State() {
const strings = useStrings(); const strings = useStrings();
const isShooting = Tankopedia.use((state) => state.protagonist.isShooting); const status = Tankopedia.use((state) => state.protagonist.status);
const isGunDamaged = Tankopedia.use(
(state) => state.protagonist.isGunDamaged,
);
const isTurretTraversing = Tankopedia.use(
(state) => state.protagonist.isTurretTraversing,
);
const isHullTraversing = Tankopedia.use(
(state) => state.protagonist.isHullTraversing,
);
const isCaughtOnFire = Tankopedia.use(
(state) => state.protagonist.isCaughtOnFire,
);
return ( return (
<div className={styles.section}> <div className={styles.section}>
@@ -97,78 +85,22 @@ function State() {
</div> </div>
<div className={styles.state}> <div className={styles.state}>
<IconButton {vehicleStatusKeys.map((key) => (
radius="1" <IconButton
className={styles.toggle} key={key}
color={isShooting ? undefined : "gray"} radius="1"
variant={isShooting ? "surface" : "soft"} className={styles.toggle}
onClick={() => { color={status[key] ? undefined : "gray"}
Tankopedia.mutate((draft) => { variant={status[key] ? "surface" : "soft"}
draft.protagonist.isShooting = !draft.protagonist.isShooting; onClick={() => {
}); Tankopedia.mutate((draft) => {
}} draft.protagonist.status[key] = !draft.protagonist.status[key];
> });
<ExclamationTriangleIcon /> }}
</IconButton> >
<img src={`/media/status/${key}.svg`} />
<IconButton </IconButton>
radius="1" ))}
className={styles.toggle}
color={isGunDamaged ? undefined : "gray"}
variant={isGunDamaged ? "surface" : "soft"}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.isGunDamaged = !draft.protagonist.isGunDamaged;
});
}}
>
<ExclamationTriangleIcon />
</IconButton>
<IconButton
radius="1"
className={styles.toggle}
color={isTurretTraversing ? undefined : "gray"}
variant={isTurretTraversing ? "surface" : "soft"}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.isTurretTraversing =
!draft.protagonist.isTurretTraversing;
});
}}
>
<ExclamationTriangleIcon />
</IconButton>
<IconButton
radius="1"
className={styles.toggle}
color={isHullTraversing ? undefined : "gray"}
variant={isHullTraversing ? "surface" : "soft"}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.isHullTraversing =
!draft.protagonist.isHullTraversing;
});
}}
>
<ExclamationTriangleIcon />
</IconButton>
<IconButton
radius="1"
className={styles.toggle}
color={isCaughtOnFire ? undefined : "gray"}
variant={isCaughtOnFire ? "surface" : "soft"}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.isCaughtOnFire =
!draft.protagonist.isCaughtOnFire;
});
}}
>
<ExclamationTriangleIcon />
</IconButton>
</div> </div>
</div> </div>
); );
@@ -1,6 +1,11 @@
import type { Tank } from "@protos/tank"; import type { Tank } from "@protos/tank";
import { alternativeLines } from "../config/modules"; import { alternativeLines } from "../config/modules";
import { TerrainHardness, type TankState } from "./tankState"; import {
TerrainHardness,
vehicleStatusKeys,
type TankState,
type VehicleStatusKey,
} from "./tankState";
export function createTankState({ tank, id }: Tank) { export function createTankState({ tank, id }: Tank) {
const upgrades: Record<string, number> = {}; const upgrades: Record<string, number> = {};
@@ -19,6 +24,12 @@ export function createTankState({ tank, id }: Tank) {
} }
} }
const status: Partial<Record<VehicleStatusKey, boolean>> = {};
for (const key of vehicleStatusKeys) {
status[key] = false;
}
return { return {
id, id,
@@ -32,10 +43,6 @@ export function createTankState({ tank, id }: Tank) {
speed: 0, speed: 0,
terrainHardness: TerrainHardness.Hard, terrainHardness: TerrainHardness.Hard,
isShooting: false, status: status as Record<VehicleStatusKey, boolean>,
isGunDamaged: false,
isTurretTraversing: false,
isHullTraversing: false,
isCaughtOnFire: false,
} satisfies TankState; } satisfies TankState;
} }
@@ -17,9 +17,27 @@ export interface TankState {
speed: number; speed: number;
terrainHardness: TerrainHardness; terrainHardness: TerrainHardness;
isShooting: boolean; status: Record<VehicleStatusKey, boolean>;
isGunDamaged: boolean;
isTurretTraversing: boolean;
isHullTraversing: boolean;
isCaughtOnFire: boolean;
} }
export const vehicleStatusKeys = [
"commander_dead",
"gunner_dead",
"driver_dead",
"loader_dead",
"fuel_tank_damaged",
"engine_damaged",
"chassis_damaged",
"viewport_damaged",
"ammo_bay_damaged",
"gun_damaged",
"turret_damaged",
"caught_on_fire",
"shooting",
"turret_traversing",
"hull_traversing",
] as const;
export type VehicleStatusKey = (typeof vehicleStatusKeys)[number];