mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: provisions
This commit is contained in:
1 parent
561b59d235
commit
5bbe93bcec
14 files changed
+233
-53
No files matched your search
@@ -1,8 +1,8 @@
|
||||
import { Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import { use } from 'react';
|
||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
||||
import { checkConsumableInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableInclusivity';
|
||||
import { consumableDefinitions } from '../../../../../../../core/blitzkrieg/consumablesDefinitions';
|
||||
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableInclusivity';
|
||||
import { consumableDefinitions } from '../../../../../../../core/blitzkrieg/consumableDefinitions';
|
||||
import { useDuel } from '../../../../../../../stores/duel';
|
||||
import {
|
||||
mutateTankopediaTemporary,
|
||||
@@ -15,7 +15,11 @@ export function Consumables() {
|
||||
const consumables = useTankopediaTemporary((state) => state.consumables);
|
||||
const consumablesList = Object.values(awaitedConsumableDefinitions).filter(
|
||||
(consumable) =>
|
||||
checkConsumableInclusivity(consumable, protagonist.tank, protagonist.gun),
|
||||
checkConsumableProvisionInclusivity(
|
||||
consumable,
|
||||
protagonist.tank,
|
||||
protagonist.gun,
|
||||
),
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import { use } from 'react';
|
||||
import { ModuleButton } from '../../../../../../../components/ModuleButton';
|
||||
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableInclusivity';
|
||||
import { provisionDefinitions } from '../../../../../../../core/blitzkrieg/provisionDefinitions';
|
||||
import { useDuel } from '../../../../../../../stores/duel';
|
||||
import {
|
||||
mutateTankopediaTemporary,
|
||||
useTankopediaTemporary,
|
||||
} from '../../../../../../../stores/tankopedia';
|
||||
|
||||
export function Provisions() {
|
||||
const protagonist = useDuel((state) => state.protagonist!);
|
||||
const awaitedProvisionDefinitions = use(provisionDefinitions);
|
||||
const provisions = useTankopediaTemporary((state) => state.provisions);
|
||||
const provisionsList = Object.values(awaitedProvisionDefinitions).filter(
|
||||
(provision) =>
|
||||
checkConsumableProvisionInclusivity(
|
||||
provision,
|
||||
protagonist.tank,
|
||||
protagonist.gun,
|
||||
),
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex gap="2" direction="column">
|
||||
<Heading size="4">
|
||||
Provisions <Text color="gray">(max {protagonist.tank.provisions})</Text>
|
||||
</Heading>
|
||||
|
||||
<Flex>
|
||||
{provisionsList.map((provision, index) => {
|
||||
const selected = provisions.includes(provision.id);
|
||||
|
||||
return (
|
||||
<ModuleButton
|
||||
first={index === 0}
|
||||
last={index === provisionsList.length - 1}
|
||||
rowChild
|
||||
type="provision"
|
||||
disabled={
|
||||
protagonist.tank.provisions === provisions.length && !selected
|
||||
}
|
||||
provision={provision.id}
|
||||
selected={selected}
|
||||
onClick={() => {
|
||||
mutateTankopediaTemporary((draft) => {
|
||||
if (selected) {
|
||||
draft.provisions = draft.provisions.filter(
|
||||
(id) => id !== provision.id,
|
||||
);
|
||||
} else {
|
||||
draft.provisions.push(provision.id);
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { Camouflage } from './components/Camouflage';
|
||||
import { Consumables } from './components/Consumables';
|
||||
import { Equipments } from './components/Equipments';
|
||||
import { Modules } from './components/Modules';
|
||||
import { Provisions } from './components/Provisions';
|
||||
|
||||
export function Configure() {
|
||||
return (
|
||||
@@ -14,13 +15,10 @@ export function Configure() {
|
||||
<Equipments />
|
||||
<Consumables />
|
||||
<Camouflage />
|
||||
<Provisions />
|
||||
</Flex>
|
||||
|
||||
{/*
|
||||
<Flex gap="4" direction="column">
|
||||
<Heading size="5">Camouflage</Heading>
|
||||
</Flex>
|
||||
|
||||
<Flex gap="4" direction="column">
|
||||
<Heading size="5">Provisions</Heading>
|
||||
</Flex> */}
|
||||
|
||||
@@ -25,6 +25,10 @@ type ModuleButtonProps = Omit<ComponentProps<typeof Button>, 'type'> & {
|
||||
type: 'consumable';
|
||||
consumable: number;
|
||||
}
|
||||
| {
|
||||
type: 'provision';
|
||||
provision: number;
|
||||
}
|
||||
| {
|
||||
type: 'camouflage';
|
||||
}
|
||||
@@ -89,7 +93,9 @@ export function ModuleButton({
|
||||
? `icons/consumables/${props.consumable}.webp`
|
||||
: props.type === 'camouflage'
|
||||
? `icons/camo.webp`
|
||||
: `icons/equipment/${props.equipment}.webp`,
|
||||
: props.type === 'provision'
|
||||
? `icons/provisions/${props.provision}.webp`
|
||||
: `icons/equipment/${props.equipment}.webp`,
|
||||
)}
|
||||
style={imageStyles}
|
||||
/>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { ConsumableEntry } from './consumablesDefinitions';
|
||||
import { ConsumableEntry } from './consumableDefinitions';
|
||||
import { ProvisionEntry } from './provisionDefinitions';
|
||||
import { GunDefinition, TankDefinition } from './tankDefinitions';
|
||||
|
||||
export function checkConsumableInclusivity(
|
||||
consumable: ConsumableEntry,
|
||||
export function checkConsumableProvisionInclusivity(
|
||||
consumableProvision: ConsumableEntry | ProvisionEntry,
|
||||
tank: TankDefinition,
|
||||
gun: GunDefinition,
|
||||
) {
|
||||
const included = consumable.include.every((rule) => {
|
||||
const included = consumableProvision.include.every((rule) => {
|
||||
switch (rule.type) {
|
||||
case 'tier':
|
||||
return rule.min <= tank.tier && tank.tier <= rule.max;
|
||||
@@ -18,7 +19,7 @@ export function checkConsumableInclusivity(
|
||||
throw new SyntaxError('Category filtering found in include rule');
|
||||
}
|
||||
});
|
||||
const excluded = consumable.exclude?.some((rule) => {
|
||||
const excluded = consumableProvision.exclude?.some((rule) => {
|
||||
switch (rule.type) {
|
||||
case 'tier':
|
||||
return rule.min <= tank.tier && tank.tier <= rule.max;
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
import { asset } from './asset';
|
||||
|
||||
export type ConsumableDefinitionFilterCategory = 'clip';
|
||||
export type TankFilterDefinitionCategory = 'clip';
|
||||
|
||||
type ConsumableDefinitionFilter =
|
||||
export type TankFilterDefinition =
|
||||
| {
|
||||
type: 'tier';
|
||||
min: number;
|
||||
@@ -14,15 +14,15 @@ type ConsumableDefinitionFilter =
|
||||
}
|
||||
| {
|
||||
type: 'category';
|
||||
categories: ConsumableDefinitionFilterCategory[];
|
||||
categories: TankFilterDefinitionCategory[];
|
||||
};
|
||||
|
||||
export interface ConsumableEntry {
|
||||
id: number;
|
||||
name: string;
|
||||
effects?: Record<string, number>;
|
||||
include: ConsumableDefinitionFilter[];
|
||||
exclude?: ConsumableDefinitionFilter[];
|
||||
include: TankFilterDefinition[];
|
||||
exclude?: TankFilterDefinition[];
|
||||
}
|
||||
|
||||
export interface ConsumableDefinitions {
|
||||
@@ -0,0 +1,21 @@
|
||||
import { asset } from './asset';
|
||||
import { TankFilterDefinition } from './consumableDefinitions';
|
||||
|
||||
export interface ProvisionEntry {
|
||||
id: number;
|
||||
name: string;
|
||||
effects?: Record<string, number>;
|
||||
include: TankFilterDefinition[];
|
||||
exclude?: TankFilterDefinition[];
|
||||
}
|
||||
|
||||
export interface ProvisionDefinitions {
|
||||
[key: string]: ProvisionEntry;
|
||||
}
|
||||
|
||||
export const provisionDefinitions = fetch(
|
||||
asset('definitions/provisions.json'),
|
||||
{
|
||||
cache: 'no-cache',
|
||||
},
|
||||
).then(async (response) => response.json() as Promise<ProvisionDefinitions>);
|
||||
@@ -20,6 +20,7 @@ export interface TankDefinition {
|
||||
name_full?: string;
|
||||
tree_type: TreeTypeString;
|
||||
consumables: number;
|
||||
provisions: number;
|
||||
tier: Tier;
|
||||
type: TankType;
|
||||
testing?: boolean;
|
||||
|
||||
@@ -58,6 +58,7 @@ interface TankopediaTemporary {
|
||||
equipmentMatrix: EquipmentMatrix;
|
||||
mode: TankopediaMode;
|
||||
consumables: number[];
|
||||
provisions: number[];
|
||||
camouflage: boolean;
|
||||
}
|
||||
|
||||
@@ -107,6 +108,7 @@ export const useTankopediaTemporary = create<TankopediaTemporary>()(
|
||||
],
|
||||
mode: 'model',
|
||||
consumables: [],
|
||||
provisions: [],
|
||||
camouflage: false,
|
||||
})),
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user