diff --git a/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx b/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx
deleted file mode 100644
index 61c9da069..000000000
--- a/src/app/tools/tankopedia/[id]/components/AntagonistBar.tsx
+++ /dev/null
@@ -1,251 +0,0 @@
-import { Cross1Icon, ShuffleIcon } from '@radix-ui/react-icons';
-import { Button, Card, Dialog, Flex, Heading, Tabs } from '@radix-ui/themes';
-import { useState } from 'react';
-import { ModuleButton } from '../../../../../components/ModuleButtons/ModuleButton';
-import { ShellButton } from '../../../../../components/ModuleButtons/ShellButton';
-import { SmallTankIcon } from '../../../../../components/SmallTankIcon';
-import { resolveNearPenetration } from '../../../../../core/blitz/resolveNearPenetration';
-import { pushTankopediaPath } from '../../../../../core/blitzkit/pushTankopediaPath';
-import {
- SHELL_NAMES,
- TIER_ROMAN_NUMERALS,
-} from '../../../../../core/blitzkit/tankDefinitions/constants';
-import { mutateDuel, useDuel } from '../../../../../stores/duel';
-import {
- mutateTankopediaTemporary,
- useTankopediaPersistent,
-} from '../../../../../stores/tankopedia';
-import { TankSearch } from '../../components/TankSearch';
-
-interface AntagonistBarProps {
- floating?: boolean;
-}
-
-export function AntagonistBar({ floating }: AntagonistBarProps) {
- const antagonist = useDuel((state) => state.antagonist!);
- const mode = useTankopediaPersistent((state) => state.mode);
- const [tab, setTab] = useState('search');
- const [antagonistSelectorOpen, setAntagonistSelectorVisible] =
- useState(false);
-
- if (mode !== 'armor') return null;
-
- return (
-
-
-
-
- {antagonist.gun.shells.map((shell, index) => {
- return (
- {
- mutateDuel((draft) => {
- draft.antagonist!.shell = shell;
- mutateTankopediaTemporary((draft) => {
- draft.shot = undefined;
- });
- });
- }}
- />
- );
- })}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Search
- Configure
-
-
-
-
- {
- mutateDuel((draft) => {
- draft.antagonist!.tank = tank;
- draft.antagonist!.engine = tank.engines.at(-1)!;
- draft.antagonist!.track = tank.tracks.at(-1)!;
- draft.antagonist!.turret = tank.turrets.at(-1)!;
- draft.antagonist!.gun =
- draft.antagonist!.turret.guns.at(-1)!;
- draft.antagonist!.shell =
- draft.antagonist!.gun.shells[0];
- });
- setAntagonistSelectorVisible(false);
- }}
- />
-
-
-
-
-
-
-
- {antagonist.tank.name} modules
-
-
-
-
- {antagonist.tank.turrets.map((turret, index) => (
- {
- mutateDuel((draft) => {
- draft.antagonist!.turret = turret;
- draft.antagonist!.gun =
- turret.guns.at(-1)!;
- draft.antagonist!.shell =
- draft.antagonist!.gun.shells[0];
- });
- mutateTankopediaTemporary((draft) => {
- draft.shot = undefined;
- });
- }}
- selected={antagonist.turret.id === turret.id}
- discriminator={
- TIER_ROMAN_NUMERALS[turret.tier]
- }
- module="turret"
- />
- ))}
-
-
- {antagonist.turret.guns.map((gun, index) => (
- {
- mutateDuel((draft) => {
- draft.antagonist!.gun = gun;
- draft.antagonist!.shell = gun.shells[0];
- });
- }}
- selected={antagonist.gun.id === gun.id}
- discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
- module="gun"
- />
- ))}
-
-
-
-
-
- Properties
-
-
- -
- Turret: {antagonist.turret.name}
-
- -
- Gun: {antagonist.gun.name}
-
- - Shells:
-
- {antagonist.gun.shells.map((shell) => (
- -
- {SHELL_NAMES[shell.type]}:{' '}
-
- {resolveNearPenetration(shell.penetration)}
- mm
-
- , {shell.damage.armor}HP
-
- ))}
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx
index 733d58738..bb837b48f 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx
@@ -1,12 +1,32 @@
import {
+ Cross1Icon,
EnterFullScreenIcon,
ExitFullScreenIcon,
EyeOpenIcon,
GearIcon,
} from '@radix-ui/react-icons';
-import { DropdownMenu, Flex, IconButton, Switch } from '@radix-ui/themes';
+import {
+ Button,
+ Dialog,
+ DropdownMenu,
+ Flex,
+ Heading,
+ IconButton,
+ Switch,
+ Tabs,
+ Text,
+} from '@radix-ui/themes';
+import { useState } from 'react';
+import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
+import { SmallTankIcon } from '../../../../../../../components/SmallTankIcon';
+import { resolveNearPenetration } from '../../../../../../../core/blitz/resolveNearPenetration';
import { asset } from '../../../../../../../core/blitzkit/asset';
import { Pose, poseEvent } from '../../../../../../../core/blitzkit/pose';
+import {
+ SHELL_NAMES,
+ TIER_ROMAN_NUMERALS,
+} from '../../../../../../../core/blitzkit/tankDefinitions/constants';
+import { useEquipment } from '../../../../../../../hooks/useEquipment';
import { useFullScreen } from '../../../../../../../hooks/useFullScreen';
import { useApp } from '../../../../../../../stores/app';
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
@@ -14,6 +34,7 @@ import mutateTankopediaPersistent, {
mutateTankopediaTemporary,
useTankopediaPersistent,
} from '../../../../../../../stores/tankopedia';
+import { TankSearch } from '../../../../components/TankSearch';
import { ENVIRONMENTS } from '../../Lighting';
export function Options() {
@@ -41,226 +62,448 @@ export function Options() {
(state) => state.model.visual.environment,
);
const developerMode = useApp((state) => state.developerMode);
- const gun = useDuel((state) => state.antagonist!.gun);
- const shell = useDuel((state) => state.antagonist!.shell);
+ const antagonistGun = useDuel((state) => state.antagonist!.gun);
+ const antagonistShell = useDuel((state) => state.antagonist!.shell);
+ const [antagonistSelectorOpen, setAntagonistSelectorOpen] = useState(false);
+ const antagonistTank = useDuel((state) => state.antagonist!.tank);
+ const antagonistTurret = useDuel((state) => state.antagonist!.turret);
+ const hasCalibratedShells = useEquipment(103, true);
+ const [tab, setTab] = useState('search');
+ const hasEnhancedArmor = useEquipment(110);
return (
<>
{mode === 'armor' && (
- {gun.shells.map((thisShell, shellIndex) => (
+
+ {antagonistGun.shells.map((thisShell, shellIndex) => (
+ {
+ mutateDuel((draft) => {
+ draft.antagonist!.shell = thisShell;
+ });
+ }}
+ >
+
+
+ ))}
+
+
+
{
mutateDuel((draft) => {
- draft.antagonist!.shell = thisShell;
+ draft.antagonist!.equipmentMatrix[0][0] = hasCalibratedShells
+ ? 0
+ : 1;
});
}}
>
- ))}
+ {
+ mutateDuel((draft) => {
+ draft.protagonist!.equipmentMatrix[1][1] = hasEnhancedArmor
+ ? 0
+ : -1;
+ });
+ }}
+ >
+
+
+
)}
- {
- mutateTankopediaPersistent((draft) => {
- draft.mode = draft.mode === 'armor' ? 'model' : 'armor';
- });
- }}
- mr="2"
- >
-
- Armor
-
+ {mode === 'armor' && (
+
+
+ Shooter:
+
+
+
+
+
-
-
-
-
-
-
-
-
- poseEvent.emit(Pose.HullDown)}>
- Hull down
-
-
- poseEvent.emit(Pose.FaceHug)}>
- Face hug
-
-
- poseEvent.emit(Pose.Default)}>
- Default
-
-
-
-
-
-
-
-
-
-
-
-
- {mode === 'armor' && (
- <>
- Armor
-
- {
- mutateTankopediaPersistent((draft) => {
- draft.model.visual.showSpacedArmor = checked;
- });
- mutateTankopediaTemporary((draft) => {
- draft.shot = undefined;
- });
- }}
+
+
- Spaced armor
-
+
+
+
- {
- mutateTankopediaPersistent((draft) => {
- draft.model.visual.greenPenetration = checked;
- });
- }}
- >
- Green penetration
-
+
+
+ Search
+ Configure
+
+
+
+
+ {
+ mutateDuel((draft) => {
+ draft.antagonist!.tank = tank;
+ draft.antagonist!.engine = tank.engines.at(-1)!;
+ draft.antagonist!.track = tank.tracks.at(-1)!;
+ draft.antagonist!.turret = tank.turrets.at(-1)!;
+ draft.antagonist!.gun =
+ draft.antagonist!.turret.guns.at(-1)!;
+ draft.antagonist!.shell =
+ draft.antagonist!.gun.shells[0];
+ });
+ setAntagonistSelectorOpen(false);
+ }}
+ />
+
+
+
+
+
+
+
+ {antagonistTank.name} modules
+
+
+
+
+ {antagonistTank.turrets.map((turret, index) => (
+ {
+ mutateDuel((draft) => {
+ draft.antagonist!.turret = turret;
+ draft.antagonist!.gun =
+ turret.guns.at(-1)!;
+ draft.antagonist!.shell =
+ draft.antagonist!.gun.shells[0];
+ });
+ mutateTankopediaTemporary((draft) => {
+ draft.shot = undefined;
+ });
+ }}
+ selected={antagonistTurret.id === turret.id}
+ discriminator={
+ TIER_ROMAN_NUMERALS[turret.tier]
+ }
+ module="turret"
+ />
+ ))}
+
+
+ {antagonistTurret.guns.map((gun, index) => (
+ {
+ mutateDuel((draft) => {
+ draft.antagonist!.gun = gun;
+ draft.antagonist!.shell = gun.shells[0];
+ });
+ }}
+ selected={antagonistGun.id === gun.id}
+ discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
+ module="gun"
+ />
+ ))}
+
+
+
+
+
+ Properties
+
+
+ -
+ Turret: {antagonistTurret.name}
+
+ -
+ Gun: {antagonistGun.name}
+
+ - Shells:
+
+ {antagonistGun.shells.map((shell) => (
+ -
+ {SHELL_NAMES[shell.type]}:{' '}
+
+ {resolveNearPenetration(shell.penetration)}
+ mm
+
+ , {shell.damage.armor}HP
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.mode = draft.mode === 'armor' ? 'model' : 'armor';
+ });
+ }}
+ mr="2"
+ >
+
+ Armor
+
+
+
+
+
+
+
+
+
+
+ poseEvent.emit(Pose.HullDown)}>
+ Hull down
+
+
+ poseEvent.emit(Pose.FaceHug)}>
+ Face hug
+
+
+ poseEvent.emit(Pose.Default)}>
+ Default
+
+
+
+
+
+
+
+
+
+
+
+
+ {mode === 'armor' && (
+ <>
+ Armor
- {developerMode && (
{
mutateTankopediaPersistent((draft) => {
- draft.model.visual.wireframe = checked;
+ draft.model.visual.showSpacedArmor = checked;
+ });
+ mutateTankopediaTemporary((draft) => {
+ draft.shot = undefined;
});
}}
>
- Wireframe
+ Spaced armor
- )}
- {
- mutateTankopediaPersistent((draft) => {
- draft.model.visual.opaque = checked;
- });
- }}
- >
- Opaque
-
- >
- )}
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.greenPenetration = checked;
+ });
+ }}
+ >
+ Green penetration
+
- Environment
-
- {
- mutateTankopediaPersistent((draft) => {
- draft.model.visual.showGrid = checked;
- });
- }}
- >
- Show grid
-
-
- {
- mutateTankopediaPersistent((draft) => {
- draft.model.visual.showEnvironment = checked;
- });
- }}
- >
- {/* TODO: consider removing this? */}
- View environment
-
-
-
- Lighting
-
-
-
- {ENVIRONMENTS.map((environment) => (
- {
+ {developerMode && (
+ {
mutateTankopediaPersistent((draft) => {
- draft.model.visual.environment = environment;
+ draft.model.visual.wireframe = checked;
});
}}
>
- {environment[0].toUpperCase() + environment.slice(1)}
-
- ))}
-
-
-
-
-
+ Wireframe
+
+ )}
- {fullScreenAvailable && (
- {
- if (isFullScreen) {
- document.exitFullscreen();
- } else document.body.requestFullscreen();
- }}
- >
- {isFullScreen ? : }
-
- )}
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.opaque = checked;
+ });
+ }}
+ >
+ Opaque
+
+ >
+ )}
+
+ Environment
+
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.showGrid = checked;
+ });
+ }}
+ >
+ Show grid
+
+
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.showEnvironment = checked;
+ });
+ }}
+ >
+ {/* TODO: consider removing this? */}
+ View environment
+
+
+
+ Lighting
+
+
+
+ {ENVIRONMENTS.map((environment) => (
+ {
+ mutateTankopediaPersistent((draft) => {
+ draft.model.visual.environment = environment;
+ });
+ }}
+ >
+ {environment[0].toUpperCase() + environment.slice(1)}
+
+ ))}
+
+
+
+
+
+
+ {fullScreenAvailable && (
+ {
+ if (isFullScreen) {
+ document.exitFullscreen();
+ } else document.body.requestFullscreen();
+ }}
+ >
+ {isFullScreen ? : }
+
+ )}
+
>
);