fix: deterministic and correct boolean dynamic armor

This commit is contained in:
TrèsAbhi committed 2024-09-04 21:15:57 -05:00
1 parent 319c865ef0
commit 952523d3f9
8 files changed
+127 -177

No files matched your search

@@ -0,0 +1,53 @@
import { IconButton } from '@radix-ui/themes';
import { invalidate } from '@react-three/fiber';
import { asset } from '../../../../../../../../../core/blitzkit/asset';
import { useArmor } from '../../../../../../../../../hooks/useArmor';
import * as Duel from '../../../../../../../../../stores/duel';
import * as TankopediaEphemeral from '../../../../../../../../../stores/tankopediaEphemeral';
export function DynamicArmorSwitcher() {
const tank = Duel.use((state) => state.protagonist.tank);
const mutateDuel = Duel.useMutation();
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const isDynamicArmorActive = Duel.use((state) =>
state.protagonist.consumables.includes(73),
);
const { hasDynamicArmor } = useArmor(tank.id);
if (!hasDynamicArmor) return null;
return (
<IconButton
color={isDynamicArmorActive ? undefined : 'gray'}
variant="soft"
size={{ initial: '2', sm: '3' }}
onClick={() => {
invalidate();
mutateDuel((draft) => {
if (draft.protagonist.consumables.includes(73)) {
draft.protagonist.consumables =
draft.protagonist.consumables.filter((id) => id !== 73);
} else {
if (draft.protagonist.consumables.length === tank.consumables) {
draft.protagonist.consumables[tank.consumables - 1] = 73;
} else {
draft.protagonist.consumables.push(73);
}
}
});
mutateTankopediaEphemeral((draft) => {
draft.shot = undefined;
});
}}
>
<img
alt="Dynamic Armor"
src={asset('icons/consumables/73.webp')}
style={{
width: '50%',
height: '50%',
}}
/>
</IconButton>
);
}
@@ -20,31 +20,31 @@ import {
Tooltip,
} from '@radix-ui/themes';
import { invalidate } from '@react-three/fiber';
import { RefObject, use, useEffect, useState } from 'react';
import { ThicknessRange } from '../../../../../../../components/Armor/components/StaticArmor';
import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
import { SmallTankIcon } from '../../../../../../../components/SmallTankIcon';
import { resolveNearPenetration } from '../../../../../../../core/blitz/resolveNearPenetration';
import { resolvePenetrationCoefficient } from '../../../../../../../core/blitz/resolvePenetrationCoefficient';
import { asset } from '../../../../../../../core/blitzkit/asset';
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkit/checkConsumableProvisionInclusivity';
import { consumableDefinitions } from '../../../../../../../core/blitzkit/consumableDefinitions';
import { imgur } from '../../../../../../../core/blitzkit/imgur';
import { Pose, poseEvent } from '../../../../../../../core/blitzkit/pose';
import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkit/tankDefinitions/constants';
import { uniqueGuns } from '../../../../../../../core/blitzkit/uniqueGuns';
import { useEquipment } from '../../../../../../../hooks/useEquipment';
import { useFullScreen } from '../../../../../../../hooks/useFullScreen';
import { useFullscreenAvailability } from '../../../../../../../hooks/useFullscreenAvailability';
import * as App from '../../../../../../../stores/app';
import * as Duel from '../../../../../../../stores/duel';
import * as TankopediaEphemeral from '../../../../../../../stores/tankopediaEphemeral';
import * as TankopediaPersistent from '../../../../../../../stores/tankopediaPersistent';
import { TankopediaDisplay } from '../../../../../../../stores/tankopediaPersistent/constants';
import { TankSearch } from '../../../../components/TankSearch';
import { ENVIRONMENTS } from '../../Lighting';
import { QuickInputs } from '../../QuickInputs';
import { Thicknesses } from '../../Thicknesses';
import { RefObject, useEffect, useState } from 'react';
import { ThicknessRange } from '../../../../../../../../components/Armor/components/StaticArmor';
import { ModuleButton } from '../../../../../../../../components/ModuleButtons/ModuleButton';
import { SmallTankIcon } from '../../../../../../../../components/SmallTankIcon';
import { resolveNearPenetration } from '../../../../../../../../core/blitz/resolveNearPenetration';
import { resolvePenetrationCoefficient } from '../../../../../../../../core/blitz/resolvePenetrationCoefficient';
import { asset } from '../../../../../../../../core/blitzkit/asset';
import { imgur } from '../../../../../../../../core/blitzkit/imgur';
import { Pose, poseEvent } from '../../../../../../../../core/blitzkit/pose';
import { TIER_ROMAN_NUMERALS } from '../../../../../../../../core/blitzkit/tankDefinitions/constants';
import { uniqueGuns } from '../../../../../../../../core/blitzkit/uniqueGuns';
import { useArmor } from '../../../../../../../../hooks/useArmor';
import { useEquipment } from '../../../../../../../../hooks/useEquipment';
import { useFullScreen } from '../../../../../../../../hooks/useFullScreen';
import { useFullscreenAvailability } from '../../../../../../../../hooks/useFullscreenAvailability';
import * as App from '../../../../../../../../stores/app';
import * as Duel from '../../../../../../../../stores/duel';
import * as TankopediaEphemeral from '../../../../../../../../stores/tankopediaEphemeral';
import * as TankopediaPersistent from '../../../../../../../../stores/tankopediaPersistent';
import { TankopediaDisplay } from '../../../../../../../../stores/tankopediaPersistent/constants';
import { TankSearch } from '../../../../../components/TankSearch';
import { ENVIRONMENTS } from '../../../Lighting';
import { QuickInputs } from '../../../QuickInputs';
import { Thicknesses } from '../../../Thicknesses';
import { DynamicArmorSwitcher } from './components/DynamicArmorSwitcher';
interface OptionsProps {
thicknessRange: ThicknessRange;
@@ -78,28 +78,14 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
);
const developerMode = App.useDeferred(false, (state) => state.developerMode);
const protagonistTank = Duel.use((state) => state.protagonist.tank);
const protagonistGun = Duel.use((state) => state.protagonist.gun);
const protagonistConsumables = Duel.use(
(state) => state.protagonist.consumables,
);
const antagonistGun = Duel.use((state) => state.antagonist.gun);
const antagonistShell = Duel.use((state) => state.antagonist.shell);
const [antagonistSelectorOpen, setAntagonistSelectorOpen] = useState(false);
const antagonistTank = Duel.use((state) => state.antagonist.tank);
const hasCalibratedShells = useEquipment(103, true);
const hasDynamicArmor = protagonistConsumables.includes(73);
const [tab, setTab] = useState('search');
const mutateDuel = Duel.useMutation();
const hasEnhancedArmor = useEquipment(110);
const awaitedConsumableDefinitions = use(consumableDefinitions);
const consumablesList = Object.values(awaitedConsumableDefinitions).filter(
(consumable) =>
checkConsumableProvisionInclusivity(
consumable,
protagonistTank,
protagonistGun,
),
);
const antagonistUniqueGuns = uniqueGuns(antagonistTank.turrets);
useEffect(() => setDisplay(displayRaw), [displayRaw]);
@@ -291,45 +277,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
</IconButton>
</Flex>
{consumablesList.some((consumable) => consumable.id === 73) && (
<IconButton
color={hasDynamicArmor ? undefined : 'gray'}
variant="soft"
size={{ initial: '2', sm: '3' }}
onClick={() => {
invalidate();
mutateDuel((draft) => {
if (draft.protagonist.consumables.includes(73)) {
draft.protagonist.consumables =
draft.protagonist.consumables.filter((id) => id !== 73);
} else {
if (
draft.protagonist.consumables.length ===
protagonistTank.consumables
) {
draft.protagonist.consumables[
protagonistTank.consumables - 1
] = 73;
} else {
draft.protagonist.consumables.push(73);
}
}
});
mutateTankopediaEphemeral((draft) => {
draft.shot = undefined;
});
}}
>
<img
alt="Calibrated Shells"
src={asset('icons/consumables/73.webp')}
style={{
width: '50%',
height: '50%',
}}
/>
</IconButton>
)}
<DynamicArmorSwitcher />
</Flex>
)}
@@ -1,21 +1,11 @@
import { EyeClosedIcon, EyeOpenIcon, ReloadIcon } from '@radix-ui/react-icons';
import {
Box,
Button,
Checkbox,
Flex,
IconButton,
Text,
} from '@radix-ui/themes';
import { invalidate } from '@react-three/fiber';
import { use } from 'react';
import { Box, Button, Checkbox, Flex, Text } from '@radix-ui/themes';
import { ThicknessRange } from '../../../../../components/Armor/components/StaticArmor';
import { asset } from '../../../../../core/blitzkit/asset';
import { checkConsumableProvisionInclusivity } from '../../../../../core/blitzkit/checkConsumableProvisionInclusivity';
import { consumableDefinitions } from '../../../../../core/blitzkit/consumableDefinitions';
import { useArmor } from '../../../../../hooks/useArmor';
import * as Duel from '../../../../../stores/duel';
import * as TankopediaEphemeral from '../../../../../stores/tankopediaEphemeral';
import * as TankopediaPersistent from '../../../../../stores/tankopediaPersistent';
import { DynamicArmorSwitcher } from './Model/components/Options/components/DynamicArmorSwitcher';
interface ThicknessesProps {
thicknessRange: ThicknessRange;
@@ -36,21 +26,8 @@ export function Thicknesses({ thicknessRange }: ThicknessesProps) {
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const editStatic = TankopediaEphemeral.use((state) => state.editStatic);
const protagonistTank = Duel.use((state) => state.protagonist.tank);
const protagonistGun = Duel.use((state) => state.protagonist.gun);
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const awaitedConsumableDefinitions = use(consumableDefinitions);
const protagonistConsumables = Duel.use(
(state) => state.protagonist.consumables,
);
const hasDynamicArmor = protagonistConsumables.includes(73);
const consumablesList = Object.values(awaitedConsumableDefinitions).filter(
(consumable) =>
checkConsumableProvisionInclusivity(
consumable,
protagonistTank,
protagonistGun,
),
);
const { hasDynamicArmor } = useArmor(protagonistTank.id);
return (
<Flex
@@ -199,45 +176,7 @@ export function Thicknesses({ thicknessRange }: ThicknessesProps) {
</Flex>
</Flex>
{consumablesList.some((consumable) => consumable.id === 73) && (
<IconButton
color={hasDynamicArmor ? undefined : 'gray'}
variant="soft"
size={{ initial: '2', sm: '3' }}
onClick={() => {
invalidate();
mutateDuel((draft) => {
if (draft.protagonist.consumables.includes(73)) {
draft.protagonist.consumables =
draft.protagonist.consumables.filter((id) => id !== 73);
} else {
if (
draft.protagonist.consumables.length ===
protagonistTank.consumables
) {
draft.protagonist.consumables[
protagonistTank.consumables - 1
] = 73;
} else {
draft.protagonist.consumables.push(73);
}
}
});
mutateTankopediaEphemeral((draft) => {
draft.shot = undefined;
});
}}
>
<img
alt="Calibrated Shells"
src={asset('icons/consumables/73.webp')}
style={{
width: '50%',
height: '50%',
}}
/>
</IconButton>
)}
<DynamicArmorSwitcher />
</Flex>
);
}