attachments

This commit is contained in:
tresabhi committed 2026-10-31 13:48:15 -05:00
1 parent b3064cdd3a
commit 11088ee3dc
6 files changed
+76 -51

No files matched your search

@@ -1,6 +1,5 @@
import { useModel } from "../hooks/useModel"; import { useModel } from "../hooks/useModel";
import { Guess, GuessState } from "../stores/guess"; import { Guess, GuessState } from "../stores/guess";
import { Controls } from "./CanvasControl";
import { Lighting } from "./Lighting"; import { Lighting } from "./Lighting";
import { SmartCanvas } from "./SmartCanvas"; import { SmartCanvas } from "./SmartCanvas";
import { TankModel } from "./TankModel"; import { TankModel } from "./TankModel";
@@ -103,7 +103,10 @@ export function TankModel() {
} }
function onPointerDown(event: ThreeEvent<PointerEvent>) { function onPointerDown(event: ThreeEvent<PointerEvent>) {
if (isTrack && Tankopedia.state.display === TankopediaDisplay.Model) { if (
isTrack &&
Tankopedia.state.loaders.display.loaded === TankopediaDisplay.Model
) {
position.set(event.clientX, event.clientY); position.set(event.clientX, event.clientY);
event.stopPropagation(); event.stopPropagation();
@@ -49,7 +49,7 @@ export function TankopediaSandbox({
const model = Tankopedia.use((state) => state.protagonist.model); const model = Tankopedia.use((state) => state.protagonist.model);
const turretModelDefinition = model.turrets[turret.id]; const turretModelDefinition = model.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id]; const gunModelDefinition = turretModelDefinition.guns[gun.id];
const display = Tankopedia.use((state) => state.display); const display = Tankopedia.use((state) => state.loaders.display.loaded);
function handlePointerDown() { function handlePointerDown() {
window.addEventListener("pointermove", handlePointerMove); window.addEventListener("pointermove", handlePointerMove);
@@ -185,7 +185,7 @@ export function TankopediaSandbox({
} }
function Content({ thicknessRange }: { thicknessRange: ThicknessRange }) { function Content({ thicknessRange }: { thicknessRange: ThicknessRange }) {
const display = Tankopedia.use((state) => state.display); const display = Tankopedia.use((state) => state.loaders.display.loaded);
const tank = useDuel("protagonist", DuelModule.Tank); const tank = useDuel("protagonist", DuelModule.Tank);
const { hasPbr } = useModel(tank.id); const { hasPbr } = useModel(tank.id);
@@ -12,10 +12,17 @@
transform: translate(calc(100% + var(--space-4)), -50%); transform: translate(calc(100% + var(--space-4)), -50%);
gap: var(--space-3);
&[data-visible="true"] { &[data-visible="true"] {
transform: translate(0, -50%); transform: translate(0, -50%);
} }
.group {
display: flex;
flex-direction: column;
}
.camouflage-icon { .camouflage-icon {
border-radius: 50%; border-radius: 50%;
} }
@@ -32,45 +32,57 @@ export function TankopediaSkinSwitcher() {
if (skins.length === 0) return null; if (skins.length === 0) return null;
const groups = [
skins.filter((camouflage) => !camouflage.attachment),
skins.filter((camouflage) => camouflage.attachment),
].filter((group) => group.length > 0);
return ( return (
<div <div
className={styles["skin-switcher"]} className={styles["skin-switcher"]}
data-visible={revealed && requestedDisplay === TankopediaDisplay.Model} data-visible={revealed && requestedDisplay === TankopediaDisplay.Model}
> >
{skins.map((camouflage) => { {groups.map((group, index) => (
const name = unwrap(camouflage.name!).replace( <div className={styles.group} key={index}>
"%(camo_num)", {group.map((camouflage) => {
SKIN_NUMBER, const name = unwrap(camouflage.name!).replace(
); "%(camo_num)",
SKIN_NUMBER,
);
const selected = skin === camouflage.id; const selected = skin === camouflage.id;
return ( return (
<Tooltip key={camouflage.id} tooltip={name} side="left"> <Tooltip key={camouflage.id} tooltip={name} side="left">
<IconButton <IconButton
parentListChild="vertical" parentListChild="vertical"
color={selected ? undefined : "gray"} color={selected ? undefined : "gray"}
variant={selected ? "solid" : "soft"} variant={selected ? "solid" : "soft"}
highContrast={selected} highContrast={selected}
size="major" size="major"
onClick={() => { onClick={() => {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
draft.loaders.skin.requested = draft.loaders.skin.requested =
draft.loaders.skin.requested === camouflage.id draft.loaders.skin.requested === camouflage.id
? undefined ? undefined
: camouflage.id; : camouflage.id;
}); });
}} }}
> >
<img <img
className={styles["camouflage-icon"]} className={styles["camouflage-icon"]}
alt={name} alt={name}
src={alias("api", `/icons/camouflages/${camouflage.id}.webp`)} src={alias(
/> "api",
</IconButton> `/icons/camouflages/${camouflage.id}.webp`,
</Tooltip> )}
); />
})} </IconButton>
</Tooltip>
);
})}
</div>
))}
</div> </div>
); );
} }
+19 -15
View File
@@ -81,6 +81,21 @@ interface LoaderState<Type> {
loaded: Type; loaded: Type;
} }
type HighlightArmor = {
editingPlate: boolean;
name: string;
point: Vector3;
thickness: number;
color: string;
} & (
| {
type: ArmorType.Primary | ArmorType.Spaced;
thicknessAngled: number;
angle: number;
}
| { type: ArmorType.External }
);
interface Tankopedia { interface Tankopedia {
disturbed: boolean; disturbed: boolean;
revealed: boolean; revealed: boolean;
@@ -98,22 +113,11 @@ interface Tankopedia {
attachment: LoaderState<number | undefined>; attachment: LoaderState<number | undefined>;
}; };
// shot?: Shot; shot?: Shot;
highlightArmor?: HighlightArmor;
// editStatic: boolean; // editStatic: boolean;
// highlightArmor?: {
// editingPlate: boolean;
// name: string;
// point: Vector3;
// thickness: number;
// color: string;
// } & (
// | {
// type: ArmorType.Primary | ArmorType.Spaced;
// thicknessAngled: number;
// angle: number;
// }
// | { type: ArmorType.External }
// );
// xpMultiplier: (typeof XP_MULTIPLIERS)[number]; // xpMultiplier: (typeof XP_MULTIPLIERS)[number];
// customShell?: ShellDefinition; // customShell?: ShellDefinition;
// statSearch?: string; // statSearch?: string;