mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: seperable buttons and remove antagonist configurer
This commit is contained in:
1 parent
f07aa9a2a7
commit
1132018d16
11 files changed
+36
-200
No files matched your search
+5
-4
@@ -1,15 +1,16 @@
|
||||
import { Flex } from '@radix-ui/themes';
|
||||
import { Flex, FlexProps } from '@radix-ui/themes';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
interface ConfigurationChildWrapperProps {
|
||||
type ConfigurationChildWrapperProps = FlexProps & {
|
||||
children: ReactNode;
|
||||
}
|
||||
};
|
||||
|
||||
export function ConfigurationChildWrapper({
|
||||
children,
|
||||
...props
|
||||
}: ConfigurationChildWrapperProps) {
|
||||
return (
|
||||
<Flex gap="2" direction="column">
|
||||
<Flex gap="2" direction="column" {...props}>
|
||||
{children}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -47,8 +47,6 @@ export function Miscellaneous() {
|
||||
left: '50%',
|
||||
transform: 'translate(calc(-50% + 4px), calc(-50% + 4px))',
|
||||
}}
|
||||
first
|
||||
last
|
||||
onClick={() => {
|
||||
mutateDuel((draft) => {
|
||||
draft.protagonist.camouflage = !camouflage;
|
||||
@@ -59,8 +57,6 @@ export function Miscellaneous() {
|
||||
<GenericTankComponentButton
|
||||
icon={asset('icons/boosters/equipment.webp')}
|
||||
selected={cooldownBooster > 0}
|
||||
first
|
||||
last
|
||||
banner={
|
||||
cooldownBooster === 0
|
||||
? undefined
|
||||
|
||||
@@ -36,7 +36,7 @@ export function CharacteristicsSection() {
|
||||
justify="center"
|
||||
direction={{ initial: 'column', sm: 'row' }}
|
||||
>
|
||||
<Flex direction="column" gap="4">
|
||||
<Flex direction="column" gap="4" maxWidth="21rem">
|
||||
<Heading>Configuration</Heading>
|
||||
<Modules />
|
||||
<Equipment />
|
||||
@@ -45,7 +45,6 @@ export function CharacteristicsSection() {
|
||||
<Skills />
|
||||
<Miscellaneous />
|
||||
</Flex>
|
||||
|
||||
<Flex
|
||||
flexGrow="1"
|
||||
maxWidth={{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
Cross1Icon,
|
||||
EnterFullScreenIcon,
|
||||
ExitFullScreenIcon,
|
||||
EyeOpenIcon,
|
||||
@@ -11,7 +10,6 @@ import {
|
||||
Dialog,
|
||||
DropdownMenu,
|
||||
Flex,
|
||||
Heading,
|
||||
IconButton,
|
||||
Popover,
|
||||
SegmentedControl,
|
||||
@@ -28,10 +26,7 @@ import { resolvePenetrationCoefficient } from '../../../../../../../core/blitz/r
|
||||
import { asset } from '../../../../../../../core/blitzkit/asset';
|
||||
import { imgur } from '../../../../../../../core/blitzkit/imgur';
|
||||
import { Pose, poseEvent } from '../../../../../../../core/blitzkit/pose';
|
||||
import {
|
||||
SHELL_NAMES,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
} from '../../../../../../../core/blitzkit/tankDefinitions/constants';
|
||||
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';
|
||||
@@ -181,12 +176,11 @@ export function Options({ thicknessRange }: OptionsProps) {
|
||||
</Popover.Trigger>
|
||||
|
||||
<Popover.Content side="left" align="center">
|
||||
<Flex>
|
||||
<Flex gap="2">
|
||||
{[...antagonistUniqueGuns]
|
||||
.reverse()
|
||||
.map(({ gun, turret }, index) => (
|
||||
<ModuleButton
|
||||
rowChild
|
||||
module="gun"
|
||||
key={gun.id}
|
||||
onClick={() =>
|
||||
@@ -196,8 +190,6 @@ export function Options({ thicknessRange }: OptionsProps) {
|
||||
draft.antagonist.shell = gun.shells[0];
|
||||
})
|
||||
}
|
||||
first={index === 0}
|
||||
last={index === antagonistUniqueGuns.length - 1}
|
||||
selected={gun.id === antagonistGun.id}
|
||||
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
||||
/>
|
||||
@@ -343,136 +335,21 @@ export function Options({ thicknessRange }: OptionsProps) {
|
||||
onValueChange={setTab}
|
||||
style={{ position: 'relative' }}
|
||||
>
|
||||
<Dialog.Close>
|
||||
<Button
|
||||
variant="ghost"
|
||||
style={{ position: 'absolute', right: 0, top: 8 }}
|
||||
>
|
||||
<Cross1Icon />
|
||||
</Button>
|
||||
</Dialog.Close>
|
||||
|
||||
<Flex gap="4" direction="column">
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value="search">Search</Tabs.Trigger>
|
||||
<Tabs.Trigger value="configure">Configure</Tabs.Trigger>
|
||||
</Tabs.List>
|
||||
|
||||
<Tabs.Content value="search">
|
||||
<Flex
|
||||
direction="column"
|
||||
gap="4"
|
||||
style={{ flex: 1 }}
|
||||
justify="center"
|
||||
>
|
||||
<TankSearch
|
||||
compact
|
||||
onSelect={(tank) => {
|
||||
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);
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content value="configure">
|
||||
<Flex direction="column" gap="4">
|
||||
<Flex direction="column" gap="2" style={{ flex: 1 }}>
|
||||
<Heading size="4">
|
||||
{antagonistTank.name} modules
|
||||
</Heading>
|
||||
|
||||
<Flex gap="2" wrap="wrap">
|
||||
<Flex>
|
||||
{antagonistTank.turrets.map((turret, index) => (
|
||||
<ModuleButton
|
||||
rowChild
|
||||
first={index === 0}
|
||||
last={
|
||||
index === antagonistTank.turrets.length - 1
|
||||
}
|
||||
key={turret.id}
|
||||
onClick={() => {
|
||||
mutateDuel((draft) => {
|
||||
draft.antagonist.turret = turret;
|
||||
draft.antagonist.gun =
|
||||
turret.guns.at(-1)!;
|
||||
draft.antagonist.shell =
|
||||
draft.antagonist.gun.shells[0];
|
||||
});
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
draft.shot = undefined;
|
||||
});
|
||||
}}
|
||||
selected={antagonistTurret.id === turret.id}
|
||||
discriminator={
|
||||
TIER_ROMAN_NUMERALS[turret.tier]
|
||||
}
|
||||
module="turret"
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
<Flex>
|
||||
{antagonistTurret.guns.map((gun, index) => (
|
||||
<ModuleButton
|
||||
key={gun.id}
|
||||
rowChild
|
||||
first={index === 0}
|
||||
last={
|
||||
index === antagonistTurret.guns.length - 1
|
||||
}
|
||||
onClick={() => {
|
||||
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"
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Flex direction="column" style={{ flex: 1 }}>
|
||||
<Heading size="4">Properties</Heading>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Turret: <b>{antagonistTurret.name}</b>
|
||||
</li>
|
||||
<li>
|
||||
Gun: <b>{antagonistGun.name}</b>
|
||||
</li>
|
||||
<li>Shells:</li>
|
||||
<ul>
|
||||
{antagonistGun.shells.map((shell) => (
|
||||
<li key={shell.id}>
|
||||
{SHELL_NAMES[shell.type]}:{' '}
|
||||
<b>
|
||||
{resolveNearPenetration(shell.penetration)}
|
||||
mm
|
||||
</b>
|
||||
, {shell.damage.armor}HP
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</ul>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Tabs.Content>
|
||||
</Flex>
|
||||
<TankSearch
|
||||
compact
|
||||
onSelect={(tank) => {
|
||||
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);
|
||||
}}
|
||||
/>
|
||||
</Tabs.Root>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
|
||||
@@ -24,14 +24,7 @@ export function ConsumablesManager({
|
||||
hasHighEndConsumables,
|
||||
}: ConsumablesManagerProps) {
|
||||
return (
|
||||
<Flex
|
||||
wrap="wrap"
|
||||
style={{
|
||||
maxWidth: 288,
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<Flex wrap="wrap" gap="2">
|
||||
{consumables.map((consumable, index) => {
|
||||
const isSelected = selected.some((id) => id === consumable.id);
|
||||
|
||||
@@ -53,9 +46,6 @@ export function ConsumablesManager({
|
||||
: undefined
|
||||
}
|
||||
key={consumable.id}
|
||||
first={index === 0}
|
||||
last={index === consumables.length - 1}
|
||||
rowChild
|
||||
disabled={disabled && !isSelected}
|
||||
consumable={consumable.id}
|
||||
selected={isSelected}
|
||||
|
||||
@@ -30,8 +30,6 @@ export function CrewSkillManager({
|
||||
<GenericTankComponentButton
|
||||
key={skill}
|
||||
special={!permanentSkills.includes(skill)}
|
||||
first
|
||||
last
|
||||
selected={level > 0}
|
||||
discriminator={
|
||||
level === 0 ? undefined : TIER_ROMAN_NUMERALS[level as Tier]
|
||||
|
||||
@@ -23,8 +23,10 @@ export function EquipmentManager({
|
||||
<Flex key={columnIndex}>
|
||||
<EquipmentButton
|
||||
equipment={equipment[0]}
|
||||
first
|
||||
rowChild
|
||||
style={{
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
}}
|
||||
selected={matrix[rowIndex][columnIndex] === -1}
|
||||
onClick={() => {
|
||||
const draft = cloneDeep(matrix);
|
||||
@@ -40,8 +42,10 @@ export function EquipmentManager({
|
||||
/>
|
||||
<EquipmentButton
|
||||
equipment={equipment[1]}
|
||||
last
|
||||
rowChild
|
||||
style={{
|
||||
borderTopLeftRadius: 0,
|
||||
borderBottomLeftRadius: 0,
|
||||
}}
|
||||
selected={matrix[rowIndex][columnIndex] === 1}
|
||||
onClick={() => {
|
||||
const draft = cloneDeep(matrix);
|
||||
|
||||
@@ -23,17 +23,13 @@ export function ConsumableButton({
|
||||
return (
|
||||
<GenericTankComponentButton
|
||||
icon={asset(`icons/consumables/${consumable}.webp`)}
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 'fit-content',
|
||||
borderRadius: 0,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{(cooldown || duration) && (
|
||||
<Flex direction="column" style={{ transform: 'translateX(-10px)' }}>
|
||||
<Flex direction="column" gap="1" ml="-2" mr="2">
|
||||
{duration && (
|
||||
<Text
|
||||
size="1"
|
||||
color={
|
||||
durationDelta > 0
|
||||
? 'green'
|
||||
@@ -50,6 +46,7 @@ export function ConsumableButton({
|
||||
)}
|
||||
{cooldown && (
|
||||
<Text
|
||||
size="1"
|
||||
color={
|
||||
cooldownDelta < 0
|
||||
? 'green'
|
||||
|
||||
@@ -4,9 +4,6 @@ import { ComponentProps, ReactNode } from 'react';
|
||||
export interface TankComponentButtonProps
|
||||
extends ComponentProps<typeof Button> {
|
||||
selected?: boolean;
|
||||
first?: boolean;
|
||||
last?: boolean;
|
||||
rowChild?: boolean;
|
||||
children?: ReactNode;
|
||||
discriminator?: ReactNode;
|
||||
disabled?: boolean;
|
||||
@@ -17,9 +14,6 @@ export interface TankComponentButtonProps
|
||||
export function TankComponentButton({
|
||||
variant,
|
||||
selected,
|
||||
first = false,
|
||||
last = false,
|
||||
rowChild,
|
||||
discriminator,
|
||||
special,
|
||||
children,
|
||||
@@ -38,11 +32,6 @@ export function TankComponentButton({
|
||||
minWidth: 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',
|
||||
overflow: 'hidden',
|
||||
cursor: 'unset',
|
||||
pointerEvents: variant === 'ghost' ? 'none' : undefined,
|
||||
|
||||
@@ -41,9 +41,6 @@ export function ModuleManager({
|
||||
<ModuleButton
|
||||
module="turret"
|
||||
discriminator={TIER_ROMAN_NUMERALS[modules.turret.tier]}
|
||||
first
|
||||
last
|
||||
rowChild
|
||||
onClick={() => setTurretMenuOpen(true)}
|
||||
/>
|
||||
|
||||
@@ -85,9 +82,6 @@ export function ModuleManager({
|
||||
<ModuleButton
|
||||
module="gun"
|
||||
discriminator={TIER_ROMAN_NUMERALS[modules.gun.tier]}
|
||||
first
|
||||
last
|
||||
rowChild
|
||||
onClick={() => setGunMenuOpen(true)}
|
||||
/>
|
||||
|
||||
@@ -128,9 +122,6 @@ export function ModuleManager({
|
||||
<ModuleButton
|
||||
module="engine"
|
||||
discriminator={TIER_ROMAN_NUMERALS[modules.engine.tier]}
|
||||
first
|
||||
last
|
||||
rowChild
|
||||
onClick={() => setEngineMenuOpen(true)}
|
||||
/>
|
||||
|
||||
@@ -170,9 +161,6 @@ export function ModuleManager({
|
||||
<ModuleButton
|
||||
module="chassis"
|
||||
discriminator={TIER_ROMAN_NUMERALS[modules.track.tier]}
|
||||
first
|
||||
last
|
||||
rowChild
|
||||
onClick={() => setTrackMenuOpen(true)}
|
||||
/>
|
||||
|
||||
|
||||
@@ -15,16 +15,13 @@ export function ProvisionsManager({
|
||||
disabled,
|
||||
}: ProvisionsManagerProps) {
|
||||
return (
|
||||
<Flex wrap="wrap">
|
||||
<Flex wrap="wrap" gap="2">
|
||||
{provisions.map((provision, index) => {
|
||||
const isSelected = selected.includes(provision);
|
||||
|
||||
return (
|
||||
<ProvisionButton
|
||||
key={provision}
|
||||
first={index === 0}
|
||||
last={index === provisions.length - 1}
|
||||
rowChild
|
||||
disabled={disabled && !isSelected}
|
||||
provision={provision}
|
||||
selected={isSelected}
|
||||
|
||||
Reference in new issue
Block a user