mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: code split module buttons
This commit is contained in:
1 parent
9d7c60e92d
commit
574b1eec92
17 files changed
+230
-153
No files matched your search
@@ -63,9 +63,10 @@ export async function consumableProvisionIcons(production: boolean) {
|
|||||||
.replace('.txt', '');
|
.replace('.txt', '');
|
||||||
|
|
||||||
if (configPath.startsWith('Gfx/Shared')) {
|
if (configPath.startsWith('Gfx/Shared')) {
|
||||||
const content = (
|
const image = sharp(
|
||||||
await readDVPLFile(`${DATA}/${configPath}.packed.webp.dvpl`)
|
await readDVPLFile(`${DATA}/${configPath}.packed.webp.dvpl`),
|
||||||
).toString('base64');
|
);
|
||||||
|
const content = (await image.trim().toBuffer()).toString('base64');
|
||||||
|
|
||||||
changes.push({
|
changes.push({
|
||||||
path: `icons/consumables/${consumable.id}.webp`,
|
path: `icons/consumables/${consumable.id}.webp`,
|
||||||
@@ -119,9 +120,10 @@ export async function consumableProvisionIcons(production: boolean) {
|
|||||||
.replace('.txt', '');
|
.replace('.txt', '');
|
||||||
|
|
||||||
if (configPath.startsWith('Gfx/Shared')) {
|
if (configPath.startsWith('Gfx/Shared')) {
|
||||||
const content = (
|
const image = sharp(
|
||||||
await readDVPLFile(`${DATA}/${configPath}.packed.webp.dvpl`)
|
await readDVPLFile(`${DATA}/${configPath}.packed.webp.dvpl`),
|
||||||
).toString('base64');
|
);
|
||||||
|
const content = (await image.trim().toBuffer()).toString('base64');
|
||||||
|
|
||||||
changes.push({
|
changes.push({
|
||||||
path: `icons/provisions/${provision.id}.webp`,
|
path: `icons/provisions/${provision.id}.webp`,
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ModuleButton } from '../../../../../../components/ModuleButton';
|
import { ModuleButton } from '../../../../../../components/ModuleButtons/ModuleButton';
|
||||||
|
import { ShellButton } from '../../../../../../components/ModuleButtons/ShellButton';
|
||||||
import { SmallTankIcon } from '../../../../../../components/SmallTankIcon';
|
import { SmallTankIcon } from '../../../../../../components/SmallTankIcon';
|
||||||
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
|
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
|
||||||
import {
|
import {
|
||||||
@@ -39,9 +40,8 @@ export function AntagonistBar() {
|
|||||||
<Flex>
|
<Flex>
|
||||||
{antagonist.gun.shells.map((shell, index) => {
|
{antagonist.gun.shells.map((shell, index) => {
|
||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ShellButton
|
||||||
selected={antagonist.shell.id === shell.id}
|
selected={antagonist.shell.id === shell.id}
|
||||||
type="shell"
|
|
||||||
shell={shell.icon}
|
shell={shell.icon}
|
||||||
rowChild
|
rowChild
|
||||||
first={index === 0}
|
first={index === 0}
|
||||||
@@ -155,7 +155,6 @@ export function AntagonistBar() {
|
|||||||
discriminator={
|
discriminator={
|
||||||
TIER_ROMAN_NUMERALS[turret.tier]
|
TIER_ROMAN_NUMERALS[turret.tier]
|
||||||
}
|
}
|
||||||
type="module"
|
|
||||||
module="turret"
|
module="turret"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -178,7 +177,6 @@ export function AntagonistBar() {
|
|||||||
}}
|
}}
|
||||||
selected={antagonist.gun.id === gun.id}
|
selected={antagonist.gun.id === gun.id}
|
||||||
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
||||||
type="module"
|
|
||||||
module="gun"
|
module="gun"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Heading } from '@radix-ui/themes';
|
import { Heading } from '@radix-ui/themes';
|
||||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
import { CamouflageButton } from '../../../../../../../components/ModuleButtons/CamouflageButton';
|
||||||
import {
|
import {
|
||||||
mutateTankopediaTemporary,
|
mutateTankopediaTemporary,
|
||||||
useTankopediaTemporary,
|
useTankopediaTemporary,
|
||||||
@@ -13,11 +13,10 @@ export function Camouflage() {
|
|||||||
<ConfigurationChildWrapper>
|
<ConfigurationChildWrapper>
|
||||||
<Heading size="4">Camouflage</Heading>
|
<Heading size="4">Camouflage</Heading>
|
||||||
|
|
||||||
<ModuleButton
|
<CamouflageButton
|
||||||
selected={camouflage}
|
selected={camouflage}
|
||||||
first
|
first
|
||||||
last
|
last
|
||||||
type="camouflage"
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
mutateTankopediaTemporary((draft) => {
|
mutateTankopediaTemporary((draft) => {
|
||||||
draft.camouflage = !camouflage;
|
draft.camouflage = !camouflage;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Flex, Heading } from '@radix-ui/themes';
|
import { Flex, Heading } from '@radix-ui/themes';
|
||||||
import { use } from 'react';
|
import { use } from 'react';
|
||||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
import { ConsumableButton } from '../../../../../../../components/ModuleButtons/ConsumableButton';
|
||||||
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity';
|
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity';
|
||||||
import { consumableDefinitions } from '../../../../../../../core/blitzkrieg/consumableDefinitions';
|
import { consumableDefinitions } from '../../../../../../../core/blitzkrieg/consumableDefinitions';
|
||||||
import { useDuel } from '../../../../../../../stores/duel';
|
import { useDuel } from '../../../../../../../stores/duel';
|
||||||
@@ -32,12 +32,11 @@ export function Consumables() {
|
|||||||
const selected = consumables.includes(consumable.id);
|
const selected = consumables.includes(consumable.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ConsumableButton
|
||||||
key={consumable.id}
|
key={consumable.id}
|
||||||
first={index === 0}
|
first={index === 0}
|
||||||
last={index === consumablesList.length - 1}
|
last={index === consumablesList.length - 1}
|
||||||
rowChild
|
rowChild
|
||||||
type="consumable"
|
|
||||||
disabled={
|
disabled={
|
||||||
protagonist.tank.consumables === consumables.length && !selected
|
protagonist.tank.consumables === consumables.length && !selected
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Flex, Heading } from '@radix-ui/themes';
|
import { Flex, Heading } from '@radix-ui/themes';
|
||||||
import { use } from 'react';
|
import { use } from 'react';
|
||||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
import { EquipmentButton } from '../../../../../../../components/ModuleButtons/EquipmentButton';
|
||||||
import { equipmentDefinitions } from '../../../../../../../core/blitzkrieg/equipmentDefinitions';
|
import { equipmentDefinitions } from '../../../../../../../core/blitzkrieg/equipmentDefinitions';
|
||||||
import { useDuel } from '../../../../../../../stores/duel';
|
import { useDuel } from '../../../../../../../stores/duel';
|
||||||
import {
|
import {
|
||||||
@@ -27,8 +27,7 @@ export function Equipments() {
|
|||||||
<Flex gap="2" key={rowIndex}>
|
<Flex gap="2" key={rowIndex}>
|
||||||
{equipmentRow.map((equipment, columnIndex) => (
|
{equipmentRow.map((equipment, columnIndex) => (
|
||||||
<Flex key={columnIndex}>
|
<Flex key={columnIndex}>
|
||||||
<ModuleButton
|
<EquipmentButton
|
||||||
type="equipment"
|
|
||||||
equipment={equipment[0]}
|
equipment={equipment[0]}
|
||||||
first
|
first
|
||||||
rowChild
|
rowChild
|
||||||
@@ -43,8 +42,7 @@ export function Equipments() {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ModuleButton
|
<EquipmentButton
|
||||||
type="equipment"
|
|
||||||
equipment={equipment[1]}
|
equipment={equipment[1]}
|
||||||
last
|
last
|
||||||
rowChild
|
rowChild
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { Flex, Heading } from '@radix-ui/themes';
|
import { Flex, Heading } from '@radix-ui/themes';
|
||||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
|
||||||
import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkrieg/tankDefinitions';
|
import { ShellButton } from '../../../../../../../components/ModuleButtons/ShellButton';
|
||||||
|
import {
|
||||||
|
SHELL_NAMES,
|
||||||
|
TIER_ROMAN_NUMERALS,
|
||||||
|
} from '../../../../../../../core/blitzkrieg/tankDefinitions';
|
||||||
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
|
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
|
||||||
import { ConfigurationChildWrapper } from './ConfigurationChildWrapper';
|
import { ConfigurationChildWrapper } from './ConfigurationChildWrapper';
|
||||||
|
|
||||||
@@ -18,7 +22,6 @@ export function Modules() {
|
|||||||
<ModuleButton
|
<ModuleButton
|
||||||
key={turret.id}
|
key={turret.id}
|
||||||
selected={protagonist.turret.id === turret.id}
|
selected={protagonist.turret.id === turret.id}
|
||||||
type="module"
|
|
||||||
module="turret"
|
module="turret"
|
||||||
discriminator={TIER_ROMAN_NUMERALS[turret.tier]}
|
discriminator={TIER_ROMAN_NUMERALS[turret.tier]}
|
||||||
first={index === 0}
|
first={index === 0}
|
||||||
@@ -41,7 +44,6 @@ export function Modules() {
|
|||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ModuleButton
|
||||||
key={gun.id}
|
key={gun.id}
|
||||||
type="module"
|
|
||||||
module="gun"
|
module="gun"
|
||||||
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
|
||||||
selected={protagonist.gun.id === gun.id}
|
selected={protagonist.gun.id === gun.id}
|
||||||
@@ -64,7 +66,6 @@ export function Modules() {
|
|||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ModuleButton
|
||||||
key={engine.id}
|
key={engine.id}
|
||||||
type="module"
|
|
||||||
module="engine"
|
module="engine"
|
||||||
discriminator={TIER_ROMAN_NUMERALS[engine.tier]}
|
discriminator={TIER_ROMAN_NUMERALS[engine.tier]}
|
||||||
selected={protagonist.engine.id === engine.id}
|
selected={protagonist.engine.id === engine.id}
|
||||||
@@ -86,7 +87,6 @@ export function Modules() {
|
|||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ModuleButton
|
||||||
key={track.id}
|
key={track.id}
|
||||||
type="module"
|
|
||||||
module="chassis"
|
module="chassis"
|
||||||
discriminator={TIER_ROMAN_NUMERALS[track.tier]}
|
discriminator={TIER_ROMAN_NUMERALS[track.tier]}
|
||||||
selected={protagonist.track.id === track.id}
|
selected={protagonist.track.id === track.id}
|
||||||
@@ -106,10 +106,10 @@ export function Modules() {
|
|||||||
<Flex>
|
<Flex>
|
||||||
{protagonist.gun.shells.map((shell, index) => {
|
{protagonist.gun.shells.map((shell, index) => {
|
||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ShellButton
|
||||||
key={shell.id}
|
key={shell.id}
|
||||||
type="shell"
|
|
||||||
shell={shell.icon}
|
shell={shell.icon}
|
||||||
|
discriminator={SHELL_NAMES[shell.type]}
|
||||||
selected={protagonist.shell.id === shell.id}
|
selected={protagonist.shell.id === shell.id}
|
||||||
first={index === 0}
|
first={index === 0}
|
||||||
last={index === protagonist.gun.shells.length - 1}
|
last={index === protagonist.gun.shells.length - 1}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Flex, Heading } from '@radix-ui/themes';
|
import { Flex, Heading } from '@radix-ui/themes';
|
||||||
import { use } from 'react';
|
import { use } from 'react';
|
||||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
import { ProvisionButton } from '../../../../../../../components/ModuleButtons/ProvisionButton';
|
||||||
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity';
|
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity';
|
||||||
import { provisionDefinitions } from '../../../../../../../core/blitzkrieg/provisionDefinitions';
|
import { provisionDefinitions } from '../../../../../../../core/blitzkrieg/provisionDefinitions';
|
||||||
import { useDuel } from '../../../../../../../stores/duel';
|
import { useDuel } from '../../../../../../../stores/duel';
|
||||||
@@ -32,12 +32,11 @@ export function Provisions() {
|
|||||||
const selected = provisions.includes(provision.id);
|
const selected = provisions.includes(provision.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModuleButton
|
<ProvisionButton
|
||||||
key={provision.id}
|
key={provision.id}
|
||||||
first={index === 0}
|
first={index === 0}
|
||||||
last={index === provisionsList.length - 1}
|
last={index === provisionsList.length - 1}
|
||||||
rowChild
|
rowChild
|
||||||
type="provision"
|
|
||||||
disabled={
|
disabled={
|
||||||
protagonist.tank.provisions === provisions.length && !selected
|
protagonist.tank.provisions === provisions.length && !selected
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
import { Button, Text } from '@radix-ui/themes';
|
|
||||||
import { CSSProperties, ComponentProps } from 'react';
|
|
||||||
import { asset } from '../core/blitzkrieg/asset';
|
|
||||||
|
|
||||||
type ModuleButtonProps = Omit<ComponentProps<typeof Button>, 'type'> & {
|
|
||||||
selected?: boolean;
|
|
||||||
first?: boolean;
|
|
||||||
last?: boolean;
|
|
||||||
rowChild?: boolean;
|
|
||||||
discriminator?: string;
|
|
||||||
} & (
|
|
||||||
| {
|
|
||||||
type: 'module';
|
|
||||||
module: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'shell';
|
|
||||||
shell: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'equipment';
|
|
||||||
equipment: number;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'consumable';
|
|
||||||
consumable: number;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'provision';
|
|
||||||
provision: number;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'camouflage';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export function ModuleButton({
|
|
||||||
selected,
|
|
||||||
style,
|
|
||||||
first = false,
|
|
||||||
last = false,
|
|
||||||
rowChild,
|
|
||||||
discriminator,
|
|
||||||
disabled,
|
|
||||||
...props
|
|
||||||
}: ModuleButtonProps) {
|
|
||||||
const imageStyles: CSSProperties = {
|
|
||||||
width: 32,
|
|
||||||
height: 32,
|
|
||||||
position: 'absolute',
|
|
||||||
opacity: disabled ? 0.5 : 1,
|
|
||||||
transform: 'scale(0.75)',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (props.type === 'module') {
|
|
||||||
imageStyles.top = '50%';
|
|
||||||
imageStyles.left = '50%';
|
|
||||||
imageStyles.transform = 'translate(calc(-50% + 2px), calc(-50% + 2px))';
|
|
||||||
} else if (props.type === 'camouflage') {
|
|
||||||
imageStyles.top = '50%';
|
|
||||||
imageStyles.left = '50%';
|
|
||||||
imageStyles.transform = 'translate(calc(-50% + 4px), calc(-50% + 4px))';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
disabled={disabled}
|
|
||||||
radius="medium"
|
|
||||||
color={selected ? undefined : 'gray'}
|
|
||||||
variant={selected ? 'surface' : 'soft'}
|
|
||||||
style={{
|
|
||||||
padding: 0,
|
|
||||||
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 as unknown as ComponentProps<typeof Button>)}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
draggable={false}
|
|
||||||
src={asset(
|
|
||||||
props.type === 'module'
|
|
||||||
? `icons/modules/${props.module}.webp`
|
|
||||||
: props.type === 'shell'
|
|
||||||
? `icons/shells/${props.shell}.webp`
|
|
||||||
: props.type === 'consumable'
|
|
||||||
? `icons/consumables/${props.consumable}.webp`
|
|
||||||
: props.type === 'camouflage'
|
|
||||||
? `icons/camo.webp`
|
|
||||||
: props.type === 'provision'
|
|
||||||
? `icons/provisions/${props.provision}.webp`
|
|
||||||
: `icons/equipment/${props.equipment}.webp`,
|
|
||||||
)}
|
|
||||||
style={imageStyles}
|
|
||||||
/>
|
|
||||||
{discriminator !== undefined && (
|
|
||||||
<Text
|
|
||||||
size="1"
|
|
||||||
style={{
|
|
||||||
zIndex: 1,
|
|
||||||
position: 'absolute',
|
|
||||||
top: '50%',
|
|
||||||
right: 8,
|
|
||||||
textAlign: 'right',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{discriminator}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { asset } from '../../core/blitzkrieg/asset';
|
||||||
|
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||||
|
import { TankComponentButtonProps } from './TankComponentButton';
|
||||||
|
|
||||||
|
export function CamouflageButton(props: TankComponentButtonProps) {
|
||||||
|
return (
|
||||||
|
<GenericTankComponentButton
|
||||||
|
icon={asset('icons/camo.webp')}
|
||||||
|
iconStyles={{
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(calc(-50% + 4px), calc(-50% + 4px))',
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { asset } from '../../core/blitzkrieg/asset';
|
||||||
|
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||||
|
import { TankComponentButtonProps } from './TankComponentButton';
|
||||||
|
|
||||||
|
interface ConsumableButtonProps extends TankComponentButtonProps {
|
||||||
|
consumable: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ConsumableButton({
|
||||||
|
consumable,
|
||||||
|
...props
|
||||||
|
}: ConsumableButtonProps) {
|
||||||
|
return (
|
||||||
|
<GenericTankComponentButton
|
||||||
|
icon={asset(`icons/consumables/${consumable}.webp`)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { asset } from '../../core/blitzkrieg/asset';
|
||||||
|
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||||
|
import { TankComponentButtonProps } from './TankComponentButton';
|
||||||
|
|
||||||
|
interface EquipmentButtonProps extends TankComponentButtonProps {
|
||||||
|
equipment: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
|
||||||
|
return (
|
||||||
|
<GenericTankComponentButton
|
||||||
|
icon={asset(`icons/equipment/${equipment}.webp`)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { HTMLAttributes } from 'react';
|
||||||
|
import {
|
||||||
|
TankComponentButton,
|
||||||
|
TankComponentButtonProps,
|
||||||
|
} from './TankComponentButton';
|
||||||
|
|
||||||
|
interface GenericTankComponentButtonProps extends TankComponentButtonProps {
|
||||||
|
icon: string;
|
||||||
|
iconStyles?: HTMLAttributes<HTMLImageElement>['style'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GenericTankComponentButton({
|
||||||
|
icon,
|
||||||
|
iconStyles,
|
||||||
|
...props
|
||||||
|
}: GenericTankComponentButtonProps) {
|
||||||
|
return (
|
||||||
|
<TankComponentButton disabled={props.disabled} {...props}>
|
||||||
|
<img
|
||||||
|
draggable={false}
|
||||||
|
src={icon}
|
||||||
|
style={{
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
position: 'absolute',
|
||||||
|
opacity: props.disabled ? 0.5 : 1,
|
||||||
|
transform: 'scale(0.75)',
|
||||||
|
...iconStyles,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TankComponentButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { asset } from '../../core/blitzkrieg/asset';
|
||||||
|
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||||
|
import { TankComponentButtonProps } from './TankComponentButton';
|
||||||
|
|
||||||
|
interface ModuleProps extends TankComponentButtonProps {
|
||||||
|
module: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ModuleButton({ module, ...props }: ModuleProps) {
|
||||||
|
return (
|
||||||
|
<GenericTankComponentButton
|
||||||
|
icon={asset(`icons/modules/${module}.webp`)}
|
||||||
|
iconStyles={{
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(calc(-50% + 2px), calc(-50% + 2px))',
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { asset } from '../../core/blitzkrieg/asset';
|
||||||
|
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||||
|
import { TankComponentButtonProps } from './TankComponentButton';
|
||||||
|
|
||||||
|
interface ProvisionButtonProps extends TankComponentButtonProps {
|
||||||
|
provision: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
|
||||||
|
return (
|
||||||
|
<GenericTankComponentButton
|
||||||
|
icon={asset(`icons/provisions/${provision}.webp`)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { asset } from '../../core/blitzkrieg/asset';
|
||||||
|
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||||
|
import { TankComponentButtonProps } from './TankComponentButton';
|
||||||
|
|
||||||
|
interface ShellButtonProps extends TankComponentButtonProps {
|
||||||
|
shell: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShellButton({ shell, ...props }: ShellButtonProps) {
|
||||||
|
return (
|
||||||
|
<GenericTankComponentButton
|
||||||
|
icon={asset(`icons/shells/${shell}.webp`)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import { Button, Text } from '@radix-ui/themes';
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TankComponentButton({
|
||||||
|
selected,
|
||||||
|
first = false,
|
||||||
|
last = false,
|
||||||
|
rowChild,
|
||||||
|
discriminator,
|
||||||
|
disabled,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: TankComponentButtonProps) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
disabled={disabled}
|
||||||
|
radius="medium"
|
||||||
|
color={selected ? undefined : 'gray'}
|
||||||
|
variant={selected ? 'surface' : 'soft'}
|
||||||
|
style={{
|
||||||
|
padding: 0,
|
||||||
|
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',
|
||||||
|
}}
|
||||||
|
{...(props as unknown as ComponentProps<typeof Button>)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
|
||||||
|
{discriminator !== undefined && (
|
||||||
|
<Text
|
||||||
|
size="1"
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textShadow: '0 0 4px black',
|
||||||
|
zIndex: 1,
|
||||||
|
position: 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
right: 8,
|
||||||
|
textAlign: 'right',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{discriminator}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -36,5 +36,3 @@ export interface ConsumableDefinitions {
|
|||||||
export const consumableDefinitions = fetchCdonLz4<ConsumableDefinitions>(
|
export const consumableDefinitions = fetchCdonLz4<ConsumableDefinitions>(
|
||||||
asset('definitions/consumables.cdon.lz4'),
|
asset('definitions/consumables.cdon.lz4'),
|
||||||
);
|
);
|
||||||
|
|
||||||
consumableDefinitions.then(console.log);
|
|
||||||
Reference in new issue
Block a user