feat: added trees

This commit is contained in:
TrèsAbhi committed 2024-03-13 23:23:06 -05:00
1 parent 025cec3687
commit 5372068830
3 files changed
+113 -40

No files matched your search

+93 -40
View File
@@ -1,4 +1,4 @@
import { readdir } from 'fs/promises'; import { readdir, writeFile } from 'fs/promises';
import { parse as parsePath } from 'path'; import { parse as parsePath } from 'path';
import { Vector3Tuple } from 'three'; import { Vector3Tuple } from 'three';
import { parse as parseYaml } from 'yaml'; import { parse as parseYaml } from 'yaml';
@@ -79,6 +79,16 @@ type VehicleDefinitionArmor = Record<
string, string,
number | { vehicleDamageFactor: 0; '#text': number } number | { vehicleDamageFactor: 0; '#text': number }
>; >;
interface UnlocksInner {
cost: number;
'#text': number;
}
type Unlocks = {
[key in 'vehicle' | 'engine' | 'chassis' | 'turret' | 'gun']:
| UnlocksInner
| UnlocksInner[];
};
type UnlocksListing = Unlocks | undefined;
interface VehicleDefinitions { interface VehicleDefinitions {
invisibility: { invisibility: {
moving: number; moving: number;
@@ -102,6 +112,7 @@ interface VehicleDefinitions {
}; };
chassis: { chassis: {
[key: string]: { [key: string]: {
unlocks: UnlocksListing;
weight: number; weight: number;
terrainResistance: string; terrainResistance: string;
rotationSpeed: number; rotationSpeed: number;
@@ -130,10 +141,13 @@ interface VehicleDefinitions {
}; };
}; };
engines: { engines: {
[key: string]: unknown; [key: string]: {
unlocks: UnlocksListing;
};
}; };
turrets0: { turrets0: {
[key: string]: { [key: string]: {
unlocks: UnlocksListing;
rotationSpeed: number; rotationSpeed: number;
weight: number; weight: number;
circularVisionRadius: number; circularVisionRadius: number;
@@ -149,6 +163,7 @@ interface VehicleDefinitions {
}; };
guns: { guns: {
[key: string]: { [key: string]: {
unlocks: UnlocksListing;
armor: VehicleDefinitionArmor & { armor: VehicleDefinitionArmor & {
gun?: gun?:
| number | number
@@ -427,6 +442,7 @@ export async function definitions(production: boolean) {
}); });
const crew: Crew[] = []; const crew: Crew[] = [];
const fixedCamouflage = tankTags.includes('eventCamouflage_user'); const fixedCamouflage = tankTags.includes('eventCamouflage_user');
const totalUnlocks: UnlocksListing[] = [];
Object.entries(tankDefinition.root.crew).forEach(([key, value]) => { Object.entries(tankDefinition.root.crew).forEach(([key, value]) => {
let entry: Crew; let entry: Crew;
@@ -532,6 +548,7 @@ export async function definitions(production: boolean) {
.split(' ') .split(' ')
.map(Number) as Vector3Tuple; .map(Number) as Vector3Tuple;
totalUnlocks.push(track.unlocks);
tankDefinitions[tankId].tracks.push({ tankDefinitions[tankId].tracks.push({
id: trackId, id: trackId,
weight: track.weight, weight: track.weight,
@@ -558,16 +575,18 @@ export async function definitions(production: boolean) {
}); });
Object.keys(tankDefinition.root.engines).forEach((engineKey) => { Object.keys(tankDefinition.root.engines).forEach((engineKey) => {
const engine = enginesList.root.shared[engineKey]; const engine = tankDefinition.root.engines[engineKey];
const engineListEntry = enginesList.root.shared[engineKey];
const engineId = toUniqueId(nation, enginesList.root.ids[engineKey]); const engineId = toUniqueId(nation, enginesList.root.ids[engineKey]);
totalUnlocks.push(engine.unlocks);
tankDefinitions[tankId].engines.push({ tankDefinitions[tankId].engines.push({
id: engineId, id: engineId,
name: strings[engine.userString], name: strings[engineListEntry.userString],
fireChance: engine.fireStartingChance, fireChance: engineListEntry.fireStartingChance,
tier: engine.level as Tier, tier: engineListEntry.level as Tier,
weight: engine.weight, weight: engineListEntry.weight,
power: engine.power, power: engineListEntry.power,
}); });
}); });
@@ -594,6 +613,7 @@ export async function definitions(production: boolean) {
.map(Number) as Vector3Tuple; .map(Number) as Vector3Tuple;
const turretArmor: ModelArmor = { thickness: {} }; const turretArmor: ModelArmor = { thickness: {} };
totalUnlocks.push(turret.unlocks);
Object.keys(turret.armor) Object.keys(turret.armor)
.filter((name) => name.startsWith('armor_')) .filter((name) => name.startsWith('armor_'))
.forEach((name) => { .forEach((name) => {
@@ -646,11 +666,11 @@ export async function definitions(production: boolean) {
}; };
Object.keys(turret.guns).forEach((gunKey, gunIndex) => { Object.keys(turret.guns).forEach((gunKey, gunIndex) => {
const turretGunEntry = turret.guns[gunKey]; const gun = turret.guns[gunKey];
const gunId = toUniqueId(nation, gunList.root.ids[gunKey]); const gunId = toUniqueId(nation, gunList.root.ids[gunKey]);
const gunListEntry = gunList.root.shared[gunKey]; const gunListEntry = gunList.root.shared[gunKey];
const pitchLimitsRaw = const pitchLimitsRaw =
turretGunEntry.pitchLimits ?? gunListEntry.pitchLimits; gun.pitchLimits ?? gunListEntry.pitchLimits;
const gunPitch = ( const gunPitch = (
typeof pitchLimitsRaw === 'string' typeof pitchLimitsRaw === 'string'
? pitchLimitsRaw ? pitchLimitsRaw
@@ -659,43 +679,41 @@ export async function definitions(production: boolean) {
.split(' ') .split(' ')
.map(Number) as [number, number]; .map(Number) as [number, number];
const gunModel = Number( const gunModel = Number(
parsePath(turretGunEntry.models.undamaged).name.split('_')[1], parsePath(gun.models.undamaged).name.split('_')[1],
); );
const gunName = const gunName =
strings[gunListEntry.userString] ?? gunKey.replaceAll('_', ' '); strings[gunListEntry.userString] ?? gunKey.replaceAll('_', ' ');
const gunType = const gunType =
'clip' in turretGunEntry 'clip' in gun
? turretGunEntry.pumpGunMode ? gun.pumpGunMode
? 'autoReloader' ? 'autoReloader'
: 'autoLoader' : 'autoLoader'
: 'regular'; : 'regular';
const gunReload = const gunReload =
gunType === 'autoReloader' gunType === 'autoReloader'
? turretGunEntry.pumpGunReloadTimes!.split(' ').map(Number) ? gun.pumpGunReloadTimes!.split(' ').map(Number)
: turretGunEntry.reloadTime; : gun.reloadTime;
const gunClipCount = const gunClipCount =
gunType === 'regular' ? undefined : turretGunEntry.clip!.count; gunType === 'regular' ? undefined : gun.clip!.count;
const gunIntraClip = const gunIntraClip =
gunType === 'regular' gunType === 'regular' ? undefined : 60 / gun.clip!.rate;
? undefined const front = gun.extraPitchLimits?.front
: 60 / turretGunEntry.clip!.rate; ? gun.extraPitchLimits.front.split(' ').map(Number)
const front = turretGunEntry.extraPitchLimits?.front
? turretGunEntry.extraPitchLimits.front.split(' ').map(Number)
: undefined; : undefined;
const back = turretGunEntry.extraPitchLimits?.back const back = gun.extraPitchLimits?.back
? turretGunEntry.extraPitchLimits.back.split(' ').map(Number) ? gun.extraPitchLimits.back.split(' ').map(Number)
: undefined; : undefined;
const transition = turretGunEntry.extraPitchLimits?.transition const transition = gun.extraPitchLimits?.transition
? typeof turretGunEntry.extraPitchLimits.transition === 'number' ? typeof gun.extraPitchLimits.transition === 'number'
? turretGunEntry.extraPitchLimits.transition ? gun.extraPitchLimits.transition
: turretGunEntry.extraPitchLimits.transition.at(-1)! : gun.extraPitchLimits.transition.at(-1)!
: undefined; : undefined;
const gunArmor: ModelArmor = { thickness: {} }; const gunArmor: ModelArmor = { thickness: {} };
const shotDispersionFactors = const shotDispersionFactors =
turretGunEntry.shotDispersionFactors ?? gun.shotDispersionFactors ?? gunListEntry.shotDispersionFactors;
gunListEntry.shotDispersionFactors;
Object.keys(turretGunEntry.armor) totalUnlocks.push(gun.unlocks);
Object.keys(gun.armor)
.filter((name) => name.startsWith('armor_')) .filter((name) => name.startsWith('armor_'))
.forEach((name) => { .forEach((name) => {
const armorIdString = name.match(/armor_(\d+)/)?.[1]; const armorIdString = name.match(/armor_(\d+)/)?.[1];
@@ -703,7 +721,7 @@ export async function definitions(production: boolean) {
throw new SyntaxError(`Invalid armor id: ${name}`); throw new SyntaxError(`Invalid armor id: ${name}`);
} }
const armorId = parseInt(armorIdString); const armorId = parseInt(armorIdString);
const armorRaw = turretGunEntry.armor[name]; const armorRaw = gun.armor[name];
if (typeof armorRaw === 'number') { if (typeof armorRaw === 'number') {
gunArmor.thickness[armorId] = armorRaw; gunArmor.thickness[armorId] = armorRaw;
} else { } else {
@@ -725,13 +743,13 @@ export async function definitions(production: boolean) {
count: gunClipCount, count: gunClipCount,
intraClip: gunIntraClip, intraClip: gunIntraClip,
camouflageLoss: camouflageLoss:
typeof turretGunEntry.invisibilityFactorAtShot === 'number' typeof gun.invisibilityFactorAtShot === 'number'
? turretGunEntry.invisibilityFactorAtShot ? gun.invisibilityFactorAtShot
: turretGunEntry.invisibilityFactorAtShot.at(-1)!, : gun.invisibilityFactorAtShot.at(-1)!,
aimTime: turretGunEntry.aimingTime ?? gunListEntry.aimingTime, aimTime: gun.aimingTime ?? gunListEntry.aimingTime,
dispersion: { dispersion: {
base: base:
turretGunEntry.shotDispersionRadius ?? gun.shotDispersionRadius ??
gunListEntry.shotDispersionRadius, gunListEntry.shotDispersionRadius,
damaged: shotDispersionFactors.whileGunDamaged, damaged: shotDispersionFactors.whileGunDamaged,
shot: shotDispersionFactors.afterShot, shot: shotDispersionFactors.afterShot,
@@ -743,11 +761,11 @@ export async function definitions(production: boolean) {
armor: gunArmor, armor: gunArmor,
model: gunModel, model: gunModel,
thickness: thickness:
turretGunEntry.armor.gun === undefined gun.armor.gun === undefined
? 0 ? 0
: typeof turretGunEntry.armor.gun === 'number' : typeof gun.armor.gun === 'number'
? turretGunEntry.armor.gun ? gun.armor.gun
: turretGunEntry.armor.gun['#text'], : gun.armor.gun['#text'],
pitch: { pitch: {
min: gunPitch[0], min: gunPitch[0],
max: gunPitch[1], max: gunPitch[1],
@@ -809,10 +827,42 @@ export async function definitions(production: boolean) {
}); });
}, },
); );
totalUnlocks.forEach((unlocks) => {
if (unlocks === undefined) return;
Object.entries(unlocks).forEach(([key, value]) => {
if ((key as keyof Unlocks) !== 'vehicle') return;
(Array.isArray(value) ? value : [value]).forEach((vehicle) => {
const tankListEntry = tankList.root[vehicle['#text']];
const successorId = toUniqueId(nation, tankListEntry.id);
if (tankDefinitions[tankId].successors === undefined) {
tankDefinitions[tankId].successors = [];
}
if (!tankDefinitions[tankId].successors!.includes(successorId)) {
tankDefinitions[tankId].successors!.push(successorId);
}
});
});
});
} }
}), }),
); );
Object.values(tankDefinitions).forEach((tank) => {
tank.successors?.forEach((predecessorId) => {
if (tankDefinitions[predecessorId].ancestors === undefined) {
tankDefinitions[predecessorId].ancestors = [];
}
if (!tankDefinitions[predecessorId].ancestors?.includes(tank.id)) {
tankDefinitions[predecessorId].ancestors?.push(tank.id);
}
});
});
Object.entries(optionalDevices.root).forEach( Object.entries(optionalDevices.root).forEach(
([optionalDeviceKey, optionalDeviceEntry]) => { ([optionalDeviceKey, optionalDeviceEntry]) => {
if (optionalDeviceKey === 'nextAvailableId') return; if (optionalDeviceKey === 'nextAvailableId') return;
@@ -970,6 +1020,9 @@ export async function definitions(production: boolean) {
} }
}); });
writeFile('test.json', JSON.stringify(tankDefinitions, null, 2));
return;
await commitAssets( await commitAssets(
'definitions', 'definitions',
[ [
+18
View File
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"resolveJsonModule": true,
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"incremental": true,
"isolatedModules": true
}
}
@@ -22,6 +22,8 @@ export interface Crew {
export interface TankDefinition { export interface TankDefinition {
id: number; id: number;
fixedCamouflage?: boolean; fixedCamouflage?: boolean;
ancestors?: number[];
successors?: number[];
crew: Crew[]; crew: Crew[];
health: number; health: number;
nation: string; nation: string;