feat: fire chance

This commit is contained in:
TrèsAbhi committed 2024-01-28 19:06:38 -06:00
1 parent eea2024549
commit c34edbd3ac
8 files changed
+94 -32

No files matched your search

+40 -7
View File
@@ -55,6 +55,17 @@ type ShellDefinitionsList = Record<
> & {
icons: Record<string, string>;
};
interface EngineDefinitionsList {
nextAvailableId: number;
ids: Record<string, number>;
shared: {
[key: string]: {
userString: string;
level: number;
fireStartingChance: number;
};
};
}
type VehicleDefinitionArmor = Record<
string,
number | { vehicleDamageFactor: 0; '#text': number }
@@ -91,6 +102,9 @@ interface VehicleDefinitions {
};
};
};
engines: {
[key: string]: unknown;
};
turrets0: {
[key: string]: {
maxHealth: number;
@@ -260,7 +274,7 @@ export async function definitions(production: boolean) {
(nations) => nations.filter((nation) => nation !== 'common'),
);
const tankStringIdMap: Record<string, number> = {};
const strings = await readYAMLDVPL<Strings>(
const stringsPreInstalled = await readYAMLDVPL<Strings>(
`${DATA}/${POI.strings}/en.yaml.dvpl`,
);
const stringsCache = await fetch(POI.cachedStrings)
@@ -269,6 +283,10 @@ export async function definitions(production: boolean) {
const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>(
`${DATA}/${POI.optionalDevices}.dvpl`,
);
const strings = {
...stringsPreInstalled,
...stringsCache,
};
const optionalDeviceSlots = await readXMLDVPL<{
root: OptionalDeviceSlots;
}>(`${DATA}/${POI.optionalDeviceSlots}.dvpl`);
@@ -299,6 +317,11 @@ export async function definitions(production: boolean) {
}>(
`${DATA}/${POI.vehicleDefinitions}/${nation}/components/shells.xml.dvpl`,
);
const enginesList = await readXMLDVPL<{
root: EngineDefinitionsList;
}>(
`${DATA}/${POI.vehicleDefinitions}/${nation}/components/engines.xml.dvpl`,
);
for (const tankKey in tankList.root) {
const tank = tankList.root[tankKey];
@@ -354,12 +377,9 @@ export async function definitions(production: boolean) {
provisions: tankDefinition.root.provisionSlots,
name:
(tank.shortUserString
? strings[tank.shortUserString] ??
stringsCache[tank.shortUserString]
: undefined) ??
strings[tank.userString] ??
stringsCache[tank.userString],
name_full: strings[tank.userString] ?? stringsCache[tank.userString],
? strings[tank.shortUserString]
: undefined) ?? strings[tank.userString],
name_full: strings[tank.userString],
nation,
tree_type: tankTags.includes('collectible')
? 'collector'
@@ -376,6 +396,7 @@ export async function definitions(production: boolean) {
firing: tankDefinition.root.invisibility.firePenalty,
},
turrets: [],
engines: [],
};
if (
@@ -402,6 +423,18 @@ export async function definitions(production: boolean) {
turrets: {},
};
Object.keys(tankDefinition.root.engines).forEach((engineKey) => {
const engine = enginesList.root.shared[engineKey];
const engineId = toUniqueId(nation, enginesList.root.ids[engineKey]);
tankDefinitions[tankId].engines.push({
id: engineId,
name: strings[engine.userString],
fire_chance: engine.fireStartingChance,
tier: engine.level as Tier,
});
});
Object.keys(tankDefinition.root.turrets0).forEach(
(turretKey, turretIndex) => {
const turret = tankDefinition.root.turrets0[turretKey];
@@ -104,6 +104,7 @@ export function AntagonistBar() {
onSelect={(tank) => {
mutateDuel((draft) => {
draft.antagonist!.tank = tank;
draft.antagonist!.engine = tank.engines.at(-1)!;
draft.antagonist!.turret = tank.turrets.at(-1)!;
draft.antagonist!.gun =
draft.antagonist!.turret.guns.at(-1)!;
@@ -11,25 +11,24 @@ export function Modules() {
<ConfigurationChildWrapper>
<Heading size="4">Modules</Heading>
<Flex gap="2">
<Flex gap="2" wrap="wrap">
<Flex>
{protagonist.tank.turrets.map((thisTurret, index) => {
{protagonist.tank.turrets.map((turret, index) => {
return (
<ModuleButton
key={thisTurret.id}
selected={protagonist.turret.id === thisTurret.id}
key={turret.id}
selected={protagonist.turret.id === turret.id}
type="module"
module="turret"
discriminator={TIER_ROMAN_NUMERALS[thisTurret.tier]}
discriminator={TIER_ROMAN_NUMERALS[turret.tier]}
first={index === 0}
last={index === protagonist.tank.turrets.length - 1}
rowChild
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.turret = thisTurret;
draft.protagonist!.gun = thisTurret.guns.at(-1)!;
draft.protagonist!.shell =
thisTurret.guns.at(-1)!.shells[0];
draft.protagonist!.turret = turret;
draft.protagonist!.gun = turret.guns.at(-1)!;
draft.protagonist!.shell = turret.guns.at(-1)!.shells[0];
});
}}
/>
@@ -38,21 +37,43 @@ export function Modules() {
</Flex>
<Flex>
{protagonist.turret.guns.map((thisGun, index) => {
{protagonist.turret.guns.map((gun, index) => {
return (
<ModuleButton
key={thisGun.id}
key={gun.id}
type="module"
module="gun"
discriminator={TIER_ROMAN_NUMERALS[thisGun.tier]}
selected={protagonist.gun.id === thisGun.id}
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
selected={protagonist.gun.id === gun.id}
first={index === 0}
last={index === protagonist.turret.guns.length - 1}
rowChild
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.gun = thisGun;
draft.protagonist!.shell = thisGun.shells[0];
draft.protagonist!.gun = gun;
draft.protagonist!.shell = gun.shells[0];
});
}}
/>
);
})}
</Flex>
<Flex>
{protagonist.tank.engines.map((engine, index) => {
return (
<ModuleButton
key={engine.id}
type="module"
module="engine"
discriminator={TIER_ROMAN_NUMERALS[engine.tier]}
selected={protagonist.engine.id === engine.id}
first={index === 0}
last={index === protagonist.tank.engines.length - 1}
rowChild
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.engine = engine;
});
}}
/>
@@ -14,7 +14,9 @@ import { Provisions } from './components/Provisions';
export function Characteristics() {
const awaitedModelDefinitions = use(modelDefinitions);
const { tank, turret, gun, shell } = useDuel((state) => state.protagonist!);
const { tank, turret, gun, shell, engine } = useDuel(
(state) => state.protagonist!,
);
const tankModelDefinition = awaitedModelDefinitions[tank.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
@@ -52,7 +54,7 @@ export function Characteristics() {
{tank.health + turret.health}
</Info>
<Info name="Fire chance" unit="%">
TODO
{Math.round(engine.fire_chance * 100)}
</Info>
<Info name="View range" unit="m">
TODO
@@ -1,9 +1,9 @@
import { UpdateIcon } from '@radix-ui/react-icons';
import { Button, Dialog, Flex, Heading } from '@radix-ui/themes';
import { useState } from 'react';
import { TREE_TYPE_ICONS } from '../../../../../components/Tanks';
import { mutateDuel, useDuel } from '../../../../../stores/duel';
import { TankSearch } from '../../components/TankSearch';
import { useState } from 'react';
export function Title() {
const protagonist = useDuel((state) => state.protagonist!);
@@ -61,6 +61,7 @@ export function Title() {
onSelect={(tank) => {
mutateDuel((draft) => {
draft.protagonist!.tank = tank;
draft.protagonist!.engine = tank.engines.at(-1)!;
draft.protagonist!.turret = tank.turrets.at(-1)!;
draft.protagonist!.gun =
draft.protagonist!.turret.guns.at(-1)!;
+2 -7
View File
@@ -22,18 +22,13 @@ export default function Page({ params }: { params: { id: string } }) {
draft.assigned = true;
draft.protagonist = {
tank: awaitedTankDefinitions[id],
engine: awaitedTankDefinitions[id].engines.at(-1)!,
turret: awaitedTankDefinitions[id].turrets.at(-1)!,
gun: awaitedTankDefinitions[id].turrets.at(-1)!.guns.at(-1)!,
shell: awaitedTankDefinitions[id].turrets.at(-1)!.guns.at(-1)!
.shells[0],
};
draft.antagonist = {
tank: awaitedTankDefinitions[id],
turret: awaitedTankDefinitions[id].turrets.at(-1)!,
gun: awaitedTankDefinitions[id].turrets.at(-1)!.guns.at(-1)!,
shell: awaitedTankDefinitions[id].turrets.at(-1)!.guns.at(-1)!
.shells[0],
};
draft.antagonist = { ...draft.protagonist };
});
mutateTankopediaTemporary((draft) => {
+7
View File
@@ -26,10 +26,17 @@ export interface TankDefinition {
type: TankType;
testing?: boolean;
turrets: TurretDefinition[];
engines: EngineDefinition[];
price: TankDefinitionPrice;
camouflage: { still: number; moving: number; firing: number };
equipment: string;
}
export interface EngineDefinition {
id: number;
name: string;
tier: Tier;
fire_chance: number;
}
export type TankDefinitionPrice =
| { type: 'credits'; value: number }
| { type: 'gold'; value: number };
+2
View File
@@ -3,6 +3,7 @@ import { create } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware';
import { TankType, TreeType } from '../components/Tanks';
import {
EngineDefinition,
GunDefinition,
ShellDefinition,
TankDefinition,
@@ -16,6 +17,7 @@ export type TankopediaTestTankDisplay = 'include' | 'exclude' | 'only';
export type TankopediaMode = 'model' | 'armor';
export interface DuelMember {
tank: TankDefinition;
engine: EngineDefinition;
turret: TurretDefinition;
gun: GunDefinition;
shell: ShellDefinition;