mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: consumable max
This commit is contained in:
1 parent
ad1ad80026
commit
cbe7b42fb8
7 files changed
+65
-44
No files matched your search
@@ -4,8 +4,7 @@ export const DATA =
|
|||||||
export const POI = {
|
export const POI = {
|
||||||
vehicleDefinitions: 'XML/item_defs/vehicles',
|
vehicleDefinitions: 'XML/item_defs/vehicles',
|
||||||
strings: 'Strings',
|
strings: 'Strings',
|
||||||
cachedStrings:
|
cachedStrings: 'https://stufficons.wgcdn.co/localizations/en.yaml',
|
||||||
'C:/Users/coola/Documents/DAVAProject/cache/localizations/en.yaml',
|
|
||||||
tankParameters: '3d/Tanks/Parameters',
|
tankParameters: '3d/Tanks/Parameters',
|
||||||
smallIcons: 'Gfx/UI/BattleScreenHUD/SmallTankIcons',
|
smallIcons: 'Gfx/UI/BattleScreenHUD/SmallTankIcons',
|
||||||
bigIcons: 'Gfx/UI/BigTankIcons',
|
bigIcons: 'Gfx/UI/BigTankIcons',
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { readdir } from 'fs/promises';
|
import { readdir } from 'fs/promises';
|
||||||
import { parse } from 'path';
|
import { parse as parsePath } from 'path';
|
||||||
import { Vector3Tuple } from 'three';
|
import { Vector3Tuple } from 'three';
|
||||||
|
import { parse as parseYaml } from 'yaml';
|
||||||
import { TankType } from '../../src/components/Tanks';
|
import { TankType } from '../../src/components/Tanks';
|
||||||
import { readXMLDVPL } from '../../src/core/blitz/readXMLDVPL';
|
import { readXMLDVPL } from '../../src/core/blitz/readXMLDVPL';
|
||||||
import { readYAML } from '../../src/core/blitz/readYAML';
|
|
||||||
import { readYAMLDVPL } from '../../src/core/blitz/readYAMLDVPL';
|
import { readYAMLDVPL } from '../../src/core/blitz/readYAMLDVPL';
|
||||||
import { toUniqueId } from '../../src/core/blitz/toUniqueId';
|
import { toUniqueId } from '../../src/core/blitz/toUniqueId';
|
||||||
import { commitAssets } from '../../src/core/blitzkrieg/commitAssets';
|
import { commitAssets } from '../../src/core/blitzkrieg/commitAssets';
|
||||||
@@ -60,6 +60,7 @@ type VehicleDefinitionArmor = Record<
|
|||||||
>;
|
>;
|
||||||
interface VehicleDefinitions {
|
interface VehicleDefinitions {
|
||||||
invisibility: { moving: number; still: number; firePenalty: number };
|
invisibility: { moving: number; still: number; firePenalty: number };
|
||||||
|
consumableSlots: number;
|
||||||
optDevicePreset: string;
|
optDevicePreset: string;
|
||||||
hull: {
|
hull: {
|
||||||
armor: VehicleDefinitionArmor;
|
armor: VehicleDefinitionArmor;
|
||||||
@@ -257,7 +258,9 @@ export async function buildDefinitions(production: boolean) {
|
|||||||
const strings = await readYAMLDVPL<Strings>(
|
const strings = await readYAMLDVPL<Strings>(
|
||||||
`${DATA}/${POI.strings}/en.yaml.dvpl`,
|
`${DATA}/${POI.strings}/en.yaml.dvpl`,
|
||||||
);
|
);
|
||||||
const stringsCache = await readYAML<Strings>(POI.cachedStrings);
|
const stringsCache = await fetch(POI.cachedStrings)
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((string) => parseYaml(string) as Strings);
|
||||||
const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>(
|
const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>(
|
||||||
`${DATA}/${POI.optionalDevices}.dvpl`,
|
`${DATA}/${POI.optionalDevices}.dvpl`,
|
||||||
);
|
);
|
||||||
@@ -338,6 +341,7 @@ export async function buildDefinitions(production: boolean) {
|
|||||||
tankDefinitions[tankId] = {
|
tankDefinitions[tankId] = {
|
||||||
id: tankId,
|
id: tankId,
|
||||||
equipment,
|
equipment,
|
||||||
|
consumables: tankDefinition.root.consumableSlots,
|
||||||
name:
|
name:
|
||||||
(tank.shortUserString
|
(tank.shortUserString
|
||||||
? strings[tank.shortUserString] ??
|
? strings[tank.shortUserString] ??
|
||||||
@@ -392,7 +396,7 @@ export async function buildDefinitions(production: boolean) {
|
|||||||
(turretKey, turretIndex) => {
|
(turretKey, turretIndex) => {
|
||||||
const turret = tankDefinition.root.turrets0[turretKey];
|
const turret = tankDefinition.root.turrets0[turretKey];
|
||||||
const turretModel = Number(
|
const turretModel = Number(
|
||||||
parse(turret.models.undamaged).name.split('_')[1],
|
parsePath(turret.models.undamaged).name.split('_')[1],
|
||||||
);
|
);
|
||||||
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
||||||
const turretYaw = (
|
const turretYaw = (
|
||||||
@@ -468,7 +472,7 @@ export async function buildDefinitions(production: boolean) {
|
|||||||
.split(' ')
|
.split(' ')
|
||||||
.map(Number) as [number, number];
|
.map(Number) as [number, number];
|
||||||
const gunModel = Number(
|
const gunModel = Number(
|
||||||
parse(turretGunEntry.models.undamaged).name.split('_')[1],
|
parsePath(turretGunEntry.models.undamaged).name.split('_')[1],
|
||||||
);
|
);
|
||||||
const gunName =
|
const gunName =
|
||||||
strings[gunListEntry.userString] ?? gunKey.replaceAll('_', ' ');
|
strings[gunListEntry.userString] ?? gunKey.replaceAll('_', ' ');
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ export function Configure() {
|
|||||||
(state) => state.equipmentMatrix,
|
(state) => state.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const consumables = useTankopediaTemporary((state) => state.consumables);
|
const consumables = useTankopediaTemporary((state) => state.consumables);
|
||||||
|
const consumablesList = Object.values(awaitedConsumableDefinitions).filter(
|
||||||
|
(consumable) =>
|
||||||
|
checkConsumableInclusivity(consumable, protagonist.tank, protagonist.gun),
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex gap="4" direction="column">
|
<Flex gap="4" direction="column">
|
||||||
@@ -94,10 +98,14 @@ export function Configure() {
|
|||||||
equipment={equipment[0]}
|
equipment={equipment[0]}
|
||||||
first
|
first
|
||||||
rowChild
|
rowChild
|
||||||
selected={equipmentMatrix[rowIndex][columnIndex] === 0}
|
selected={equipmentMatrix[rowIndex][columnIndex] === -1}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
mutateTankopediaTemporary((draft) => {
|
mutateTankopediaTemporary((draft) => {
|
||||||
draft.equipmentMatrix[rowIndex][columnIndex] = 0;
|
if (equipmentMatrix[rowIndex][columnIndex] === -1) {
|
||||||
|
draft.equipmentMatrix[rowIndex][columnIndex] = 0;
|
||||||
|
} else {
|
||||||
|
draft.equipmentMatrix[rowIndex][columnIndex] = -1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -109,7 +117,11 @@ export function Configure() {
|
|||||||
selected={equipmentMatrix[rowIndex][columnIndex] === 1}
|
selected={equipmentMatrix[rowIndex][columnIndex] === 1}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
mutateTankopediaTemporary((draft) => {
|
mutateTankopediaTemporary((draft) => {
|
||||||
draft.equipmentMatrix[rowIndex][columnIndex] = 1;
|
if (equipmentMatrix[rowIndex][columnIndex] === 1) {
|
||||||
|
draft.equipmentMatrix[rowIndex][columnIndex] = 0;
|
||||||
|
} else {
|
||||||
|
draft.equipmentMatrix[rowIndex][columnIndex] = 1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -121,36 +133,41 @@ export function Configure() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap="2" direction="column">
|
<Flex gap="2" direction="column">
|
||||||
<Heading size="4">Consumables</Heading>
|
<Heading size="4">
|
||||||
|
Consumables (max {protagonist.tank.consumables})
|
||||||
|
</Heading>
|
||||||
|
|
||||||
{Object.values(awaitedConsumableDefinitions)
|
<Flex>
|
||||||
.filter((consumable) =>
|
{consumablesList.map((consumable, index) => {
|
||||||
checkConsumableInclusivity(
|
const selected = consumables.includes(consumable.id);
|
||||||
consumable,
|
|
||||||
protagonist.tank,
|
return (
|
||||||
protagonist.gun,
|
<ModuleButton
|
||||||
),
|
first={index === 0}
|
||||||
)
|
last={index === consumablesList.length - 1}
|
||||||
.map((consumable) => (
|
rowChild
|
||||||
<ModuleButton
|
type="consumable"
|
||||||
first
|
disabled={
|
||||||
last
|
protagonist.tank.consumables === consumables.length &&
|
||||||
type="consumable"
|
!selected
|
||||||
consumable={consumable.id}
|
}
|
||||||
selected={consumables.includes(consumable.id)}
|
consumable={consumable.id}
|
||||||
onClick={() => {
|
selected={selected}
|
||||||
mutateTankopediaTemporary((draft) => {
|
onClick={() => {
|
||||||
if (draft.consumables.includes(consumable.id)) {
|
mutateTankopediaTemporary((draft) => {
|
||||||
draft.consumables = draft.consumables.filter(
|
if (selected) {
|
||||||
(id) => id !== consumable.id,
|
draft.consumables = draft.consumables.filter(
|
||||||
);
|
(id) => id !== consumable.id,
|
||||||
} else {
|
);
|
||||||
draft.consumables.push(consumable.id);
|
} else {
|
||||||
}
|
draft.consumables.push(consumable.id);
|
||||||
});
|
}
|
||||||
}}
|
});
|
||||||
/>
|
}}
|
||||||
))}
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ export function ModuleButton({
|
|||||||
{...(props as unknown as ComponentProps<typeof Button>)}
|
{...(props as unknown as ComponentProps<typeof Button>)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
draggable={false}
|
||||||
src={asset(
|
src={asset(
|
||||||
props.type === 'module'
|
props.type === 'module'
|
||||||
? `icons/modules/${props.module}.webp`
|
? `icons/modules/${props.module}.webp`
|
||||||
|
|||||||
@@ -3,6 +3,5 @@ import { parse } from 'yaml';
|
|||||||
|
|
||||||
export async function readYAML<Type>(file: string) {
|
export async function readYAML<Type>(file: string) {
|
||||||
const yaml = (await readFile(file)).toString();
|
const yaml = (await readFile(file)).toString();
|
||||||
|
|
||||||
return parse(yaml) as Type;
|
return parse(yaml) as Type;
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ export interface TankDefinition {
|
|||||||
name: string;
|
name: string;
|
||||||
name_full?: string;
|
name_full?: string;
|
||||||
tree_type: TreeTypeString;
|
tree_type: TreeTypeString;
|
||||||
|
consumables: number;
|
||||||
tier: Tier;
|
tier: Tier;
|
||||||
type: TankType;
|
type: TankType;
|
||||||
testing?: boolean;
|
testing?: boolean;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ interface TankopediaPersistent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EquipmentMatrix = (0 | 1)[][];
|
export type EquipmentMatrix = (-1 | 0 | 1)[][];
|
||||||
|
|
||||||
interface TankopediaTemporary {
|
interface TankopediaTemporary {
|
||||||
model: {
|
model: {
|
||||||
@@ -100,9 +100,9 @@ export const useTankopediaTemporary = create<TankopediaTemporary>()(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
equipmentMatrix: [
|
equipmentMatrix: [
|
||||||
[1, 0, 0],
|
[0, 0, 0],
|
||||||
[0, 1, 1],
|
[0, 0, 0],
|
||||||
[0, 1, 0],
|
[0, 0, 0],
|
||||||
],
|
],
|
||||||
mode: 'model',
|
mode: 'model',
|
||||||
consumables: [],
|
consumables: [],
|
||||||
|
|||||||
Reference in new issue
Block a user