feat: shell swapping

This commit is contained in:
TrèsAbhi committed 2024-01-10 17:57:41 -06:00
1 parent 32ee10445d
commit 371dcad568
4 files changed
+107 -73

No files matched your search

@@ -5,6 +5,7 @@ import { GLTFLoader } from 'three-stdlib';
import { ArmorMesh } from '../../../../../../../components/ArmorMesh';
import { HeadsUpDisplay } from '../../../../../../../components/HeadsUpDisplay';
import { X_AXIS } from '../../../../../../../constants/axis';
import { numericPenetration } from '../../../../../../../core/blitz/numericPenetration';
import { asset } from '../../../../../../../core/blitzkrieg/asset';
import {
ModelDefinitions,
@@ -97,7 +98,7 @@ export function TankArmor(props: TankArmorProps) {
key={node.uuid}
geometry={(node as Mesh).geometry}
thickness={thickness}
penetration={252}
penetration={numericPenetration(antagonist.shell.penetration)}
ricochet={antagonist.shell.ricochet}
caliber={antagonist.shell.caliber}
normalization={antagonist.shell.normalization}
@@ -123,7 +124,7 @@ export function TankArmor(props: TankArmorProps) {
position={turretOrigin}
geometry={(node as Mesh).geometry}
thickness={thickness}
penetration={252}
penetration={numericPenetration(antagonist.shell.penetration)}
ricochet={antagonist.shell.ricochet}
caliber={antagonist.shell.caliber}
normalization={antagonist.shell.normalization}
@@ -155,7 +156,7 @@ export function TankArmor(props: TankArmorProps) {
position={turretOrigin.clone().add(gunOrigin)}
geometry={(node as Mesh).geometry}
thickness={thickness}
penetration={252}
penetration={numericPenetration(antagonist.shell.penetration)}
ricochet={antagonist.shell.ricochet}
caliber={antagonist.shell.caliber}
normalization={antagonist.shell.normalization}
@@ -18,8 +18,7 @@ import {
import { go } from 'fuzzysort';
import { debounce } from 'lodash';
import { use, useRef, useState } from 'react';
import { ModuleButtons } from '../../../../../components/ModuleButton';
import { asset } from '../../../../../core/blitzkrieg/asset';
import { ModuleButton } from '../../../../../components/ModuleButton';
import {
SHELL_NAMES,
tankDefinitions,
@@ -169,7 +168,12 @@ export function VersusBar() {
<Flex>
{antagonist.tank.turrets.map((turret, index) => (
<Tooltip content={turret.name} key={turret.id}>
<ModuleButtons
<ModuleButton
rowChild
first={index === 0}
last={
index === antagonist.tank.turrets.length - 1
}
key={turret.id}
onClick={() => {
mutateTankopedia((draft) => {
@@ -184,24 +188,8 @@ export function VersusBar() {
}}
selected={antagonist.turret.id === turret.id}
tier={turret.tier}
type="turret"
style={{
margin: -0.5,
borderTopLeftRadius:
index === 0 ? undefined : 0,
borderBottomLeftRadius:
index === 0 ? undefined : 0,
borderTopRightRadius:
index ===
antagonist.tank.turrets.length - 1
? undefined
: 0,
borderBottomRightRadius:
index ===
antagonist.tank.turrets.length - 1
? undefined
: 0,
}}
type="module"
module="turret"
/>
</Tooltip>
))}
@@ -209,7 +197,12 @@ export function VersusBar() {
<Flex>
{antagonist.turret.guns.map((gun, index) => (
<Tooltip content={gun.name} key={gun.id}>
<ModuleButtons
<ModuleButton
rowChild
first={index === 0}
last={
index === antagonist.turret.guns.length - 1
}
onClick={() => {
mutateTankopedia((draft) => {
if (!draft.areTanksAssigned) return;
@@ -219,24 +212,8 @@ export function VersusBar() {
}}
selected={antagonist.gun.id === gun.id}
tier={gun.tier}
type="gun"
style={{
margin: -0.5,
borderTopLeftRadius:
index === 0 ? undefined : 0,
borderBottomLeftRadius:
index === 0 ? undefined : 0,
borderTopRightRadius:
index ===
antagonist.turret.guns.length - 1
? undefined
: 0,
borderBottomRightRadius:
index ===
antagonist.turret.guns.length - 1
? undefined
: 0,
}}
type="module"
module="gun"
/>
</Tooltip>
))}
@@ -278,8 +255,27 @@ export function VersusBar() {
<Text>Calibrated</Text>
</Flex>
<Flex gap="1">
<Button variant="solid" radius="small">
<Flex>
{antagonist.gun.shells.map((shell, index) => {
return (
<ModuleButton
selected={antagonist.shell.id === shell.id}
type="shell"
shell={shell.type}
rowChild
first={index === 0}
key={shell.id}
last={index === antagonist.gun.shells.length - 1}
onClick={() => {
mutateTankopedia((draft) => {
if (!draft.areTanksAssigned) return;
draft.antagonist.shell = shell;
});
}}
/>
);
})}
{/* <Button variant="solid" radius="small">
<img src={asset('icons/shells/ap.webp')} width={24} height={24} />
</Button>
<Button variant="soft" radius="small" color="gray">
@@ -291,7 +287,7 @@ export function VersusBar() {
</Button>
<Button variant="soft" radius="small" color="gray">
<img src={asset('icons/shells/he.webp')} width={24} height={24} />
</Button>
</Button> */}
</Flex>
</Flex>
</Card>
+59 -27
View File
@@ -1,20 +1,35 @@
import { Button, Text } from '@radix-ui/themes';
import { ComponentProps } from 'react';
import { asset } from '../core/blitzkrieg/asset';
import { TIER_ROMAN_NUMERALS, Tier } from '../core/blitzkrieg/tankDefinitions';
import {
ShellType,
TIER_ROMAN_NUMERALS,
Tier,
} from '../core/blitzkrieg/tankDefinitions';
interface ModuleButtonProps
extends Omit<ComponentProps<typeof Button>, 'type'> {
type: string;
tier: Tier;
type ModuleButtonProps = Omit<ComponentProps<typeof Button>, 'type'> & {
selected?: boolean;
}
first?: boolean;
last?: boolean;
rowChild?: boolean;
} & (
| {
type: 'module';
module: string;
tier: Tier;
}
| {
type: 'shell';
shell: ShellType;
}
);
export function ModuleButtons({
type,
tier,
export function ModuleButton({
selected,
style,
first = true,
last = true,
rowChild,
...props
}: ModuleButtonProps) {
return (
@@ -27,34 +42,51 @@ export function ModuleButtons({
width: 48,
height: 40,
position: 'relative',
borderTopLeftRadius: first ? undefined : 0,
borderTopRightRadius: last ? undefined : 0,
borderBottomLeftRadius: first ? undefined : 0,
borderBottomRightRadius: last ? undefined : 0,
margin: rowChild ? -0.5 : 'unset',
...style,
}}
{...props}
{...(props as unknown as ComponentProps<typeof Button>)}
>
<img
src={asset(`icons/modules/${type}.webp`)}
src={asset(
props.type === 'module'
? `icons/modules/${props.module}.webp`
: `icons/shells/${props.shell}.webp`,
)}
style={{
width: 32,
height: 32,
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(calc(-50% + 2px), calc(-50% + 2px))',
...(props.type === 'module'
? {
top: '50%',
left: '50%',
transform: 'translate(calc(-50% + 2px), calc(-50% + 2px))',
}
: {
transform: 'scale(0.75)',
}),
}}
/>
<Text
size="1"
weight="bold"
style={{
zIndex: 1,
position: 'absolute',
top: '50%',
right: 8,
textAlign: 'right',
}}
>
{TIER_ROMAN_NUMERALS[tier]}
</Text>
{props.type === 'module' && (
<Text
size="1"
weight="bold"
style={{
zIndex: 1,
position: 'absolute',
top: '50%',
right: 8,
textAlign: 'right',
}}
>
{TIER_ROMAN_NUMERALS[props.tier]}
</Text>
)}
</Button>
);
}
+5
View File
@@ -0,0 +1,5 @@
import { Vector2Tuple } from 'three';
export function numericPenetration(penetration: number | Vector2Tuple) {
return typeof penetration === 'number' ? penetration : penetration[0];
}