mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
(3) some implementation
This commit is contained in:
1 parent
f7180f0e1a
commit
bd7c952478
2 files changed
+61
-242
No files matched your search
@@ -47,6 +47,7 @@ import {
|
|||||||
TurretDefinitionsList,
|
TurretDefinitionsList,
|
||||||
Unlock,
|
Unlock,
|
||||||
UnlocksListing,
|
UnlocksListing,
|
||||||
|
Vector3,
|
||||||
VehicleDefinitionArmor,
|
VehicleDefinitionArmor,
|
||||||
VehicleDefinitionList,
|
VehicleDefinitionList,
|
||||||
VehicleDefinitions,
|
VehicleDefinitions,
|
||||||
@@ -54,6 +55,7 @@ import {
|
|||||||
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
import { parse as parsePath } from "path";
|
import { parse as parsePath } from "path";
|
||||||
|
import { Vector3Tuple } from "three";
|
||||||
import { parse as parseYaml } from "yaml";
|
import { parse as parseYaml } from "yaml";
|
||||||
import { BlitzKitAPI } from "./base";
|
import { BlitzKitAPI } from "./base";
|
||||||
|
|
||||||
@@ -105,6 +107,7 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
HIGH_EXPLOSIVE: ShellType.SHELL_TYPE_HE,
|
HIGH_EXPLOSIVE: ShellType.SHELL_TYPE_HE,
|
||||||
HOLLOW_CHARGE: ShellType.SHELL_TYPE_HEAT,
|
HOLLOW_CHARGE: ShellType.SHELL_TYPE_HEAT,
|
||||||
};
|
};
|
||||||
|
private botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
|
||||||
|
|
||||||
private stringsI18n: Record<string, Record<string, string>> = {};
|
private stringsI18n: Record<string, Record<string, string>> = {};
|
||||||
private nationsDir?: string[];
|
private nationsDir?: string[];
|
||||||
@@ -240,22 +243,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
return { locales: collection } satisfies I18nString;
|
return { locales: collection } satisfies I18nString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private assignArmor(
|
|
||||||
raw: VehicleDefinitionArmor[string],
|
|
||||||
id: number,
|
|
||||||
armor: Armor,
|
|
||||||
) {
|
|
||||||
if (typeof raw === "number") {
|
|
||||||
armor.thickness[id] = raw;
|
|
||||||
} else if (Array.isArray(raw)) {
|
|
||||||
armor.thickness[id] = raw.at(-1)!;
|
|
||||||
} else {
|
|
||||||
if (!armor.spaced) armor.spaced = [];
|
|
||||||
armor.thickness[id] = raw["#text"];
|
|
||||||
armor.spaced.push(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseResearchCost(raw: number | string) {
|
private parseResearchCost(raw: number | string) {
|
||||||
if (typeof raw === "number") {
|
if (typeof raw === "number") {
|
||||||
return {
|
return {
|
||||||
@@ -300,7 +287,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
|
|
||||||
const slugRequesters = new Map<string, { id: number; key: string }[]>();
|
const slugRequesters = new Map<string, { id: number; key: string }[]>();
|
||||||
const idToNation: Record<number, string> = {};
|
const idToNation: Record<number, string> = {};
|
||||||
|
|
||||||
@@ -310,7 +296,7 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (const tankKey in tankList.root) {
|
for (const tankKey in tankList.root) {
|
||||||
if (botPattern.test(tankKey)) continue;
|
if (this.botPattern.test(tankKey)) continue;
|
||||||
|
|
||||||
const tank = tankList.root[tankKey];
|
const tank = tankList.root[tankKey];
|
||||||
const tankId = toUniqueId(nation, tank.id);
|
const tankId = toUniqueId(nation, tank.id);
|
||||||
@@ -451,7 +437,7 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const tankKey in tankList.root) {
|
for (const tankKey in tankList.root) {
|
||||||
if (botPattern.test(tankKey)) continue;
|
if (this.botPattern.test(tankKey)) continue;
|
||||||
|
|
||||||
const gunXps = new Map<number, ResearchCost>();
|
const gunXps = new Map<number, ResearchCost>();
|
||||||
const turretXps = new Map<number, ResearchCost>();
|
const turretXps = new Map<number, ResearchCost>();
|
||||||
@@ -468,9 +454,10 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
const tankId = toUniqueId(nation, tank.id);
|
const tankId = toUniqueId(nation, tank.id);
|
||||||
|
|
||||||
const tankTags = tank.tags.split(" ");
|
const tankTags = tank.tags.split(" ");
|
||||||
const hullArmor: Armor = { spaced: [], thickness: {} };
|
|
||||||
const equipment = tankDefinition.root.optDevicePreset;
|
const equipment = tankDefinition.root.optDevicePreset;
|
||||||
|
|
||||||
this.tankStringIdMap[`${nation}:${tankKey}`] = tankId;
|
this.tankStringIdMap[`${nation}:${tankKey}`] = tankId;
|
||||||
|
|
||||||
const slug = slugs.get(tankId);
|
const slug = slugs.get(tankId);
|
||||||
|
|
||||||
if (slug === undefined) {
|
if (slug === undefined) {
|
||||||
@@ -496,20 +483,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(tankDefinition.root.hull.armor)
|
|
||||||
.filter((name) => name.startsWith("armor_"))
|
|
||||||
.forEach((name) => {
|
|
||||||
const armorIdString = name.match(/armor_(\d+)/)?.[1];
|
|
||||||
|
|
||||||
if (armorIdString === undefined) {
|
|
||||||
throw new SyntaxError(`Invalid armor id: ${name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const armorId = parseInt(armorIdString);
|
|
||||||
const armorRaw = tankDefinition.root.hull.armor[name];
|
|
||||||
|
|
||||||
this.assignArmor(armorRaw, armorId, hullArmor);
|
|
||||||
});
|
|
||||||
const crew: Crew[] = [];
|
const crew: Crew[] = [];
|
||||||
const fixedCamouflage = tankTags.includes("eventCamouflage_user");
|
const fixedCamouflage = tankTags.includes("eventCamouflage_user");
|
||||||
const totalUnlocks: UnlocksListing[] = [];
|
const totalUnlocks: UnlocksListing[] = [];
|
||||||
@@ -699,25 +672,7 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
const turret = tankDefinition.root.turrets0[turretKey];
|
const turret = tankDefinition.root.turrets0[turretKey];
|
||||||
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
||||||
|
|
||||||
const turretArmor: Armor = { thickness: {}, spaced: [] };
|
|
||||||
|
|
||||||
totalUnlocks.push(turret.unlocks);
|
totalUnlocks.push(turret.unlocks);
|
||||||
Object.keys(turret.armor)
|
|
||||||
.filter((name) => name.startsWith("armor_"))
|
|
||||||
.forEach((name) => {
|
|
||||||
const armorIdString = name.match(/armor_(\d+)/)?.[1];
|
|
||||||
|
|
||||||
if (armorIdString === undefined) {
|
|
||||||
throw new SyntaxError(`Invalid armor id: ${name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const armorId = parseInt(armorIdString);
|
|
||||||
const armorRaw = turret.armor[name];
|
|
||||||
|
|
||||||
this.assignArmor(armorRaw, armorId, turretArmor);
|
|
||||||
});
|
|
||||||
|
|
||||||
turret.userString;
|
|
||||||
|
|
||||||
tankDefinitions.tanks[tankId].turrets.push({
|
tankDefinitions.tanks[tankId].turrets.push({
|
||||||
id: turretId,
|
id: turretId,
|
||||||
@@ -804,18 +759,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
totalUnlocks.push(gun.unlocks);
|
totalUnlocks.push(gun.unlocks);
|
||||||
Object.keys(gun.armor)
|
|
||||||
.filter((name) => name.startsWith("armor_"))
|
|
||||||
.forEach((name) => {
|
|
||||||
const armorIdString = name.match(/armor_(\d+)/)?.[1];
|
|
||||||
if (armorIdString === undefined) {
|
|
||||||
throw new SyntaxError(`Invalid armor id: ${name}`);
|
|
||||||
}
|
|
||||||
const armorId = parseInt(armorIdString);
|
|
||||||
const armorRaw = gun.armor[name];
|
|
||||||
|
|
||||||
this.assignArmor(armorRaw, armorId, gunArmor);
|
|
||||||
});
|
|
||||||
|
|
||||||
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
||||||
id: gunId,
|
id: gunId,
|
||||||
@@ -1038,41 +981,58 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
return camouflageDefinitions;
|
return camouflageDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
||||||
|
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
|
||||||
|
}
|
||||||
|
|
||||||
|
private assignArmor(
|
||||||
|
raw: VehicleDefinitionArmor[string],
|
||||||
|
id: number,
|
||||||
|
armor: Armor,
|
||||||
|
) {
|
||||||
|
if (typeof raw === "number") {
|
||||||
|
armor.thickness[id] = raw;
|
||||||
|
} else if (Array.isArray(raw)) {
|
||||||
|
armor.thickness[id] = raw.at(-1)!;
|
||||||
|
} else {
|
||||||
|
if (!armor.spaced) armor.spaced = [];
|
||||||
|
armor.thickness[id] = raw["#text"];
|
||||||
|
armor.spaced.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async modelDefinitions() {
|
async modelDefinitions() {
|
||||||
const modelDefinitions = ModelDefinitions.create();
|
const modelDefinitions = ModelDefinitions.create();
|
||||||
|
|
||||||
for (const nation of this.nationsDir!) {
|
for (const nation of this.nationsDir!) {
|
||||||
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
const tankList = await this.vfs.xml<{ root: VehicleDefinitionList }>(
|
||||||
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
|
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
|
||||||
);
|
);
|
||||||
const turretList = await vfs.xml<{
|
const turretList = await this.vfs.xml<{
|
||||||
root: TurretDefinitionsList;
|
root: TurretDefinitionsList;
|
||||||
}>(`Data/XML/item_defs/vehicles/${nation}/components/turrets.xml`);
|
}>(`Data/XML/item_defs/vehicles/${nation}/components/turrets.xml`);
|
||||||
const gunList = await vfs.xml<{
|
const gunList = await this.vfs.xml<{
|
||||||
root: GunDefinitionsList;
|
root: GunDefinitionsList;
|
||||||
}>(`Data/XML/item_defs/vehicles/${nation}/components/guns.xml`);
|
}>(`Data/XML/item_defs/vehicles/${nation}/components/guns.xml`);
|
||||||
const shellList = await vfs.xml<{
|
const enginesList = await this.vfs.xml<{
|
||||||
root: ShellDefinitionsList;
|
|
||||||
}>(`Data/XML/item_defs/vehicles/${nation}/components/shells.xml`);
|
|
||||||
const enginesList = await vfs.xml<{
|
|
||||||
root: EngineDefinitionsList;
|
root: EngineDefinitionsList;
|
||||||
}>(`Data/XML/item_defs/vehicles/${nation}/components/engines.xml`);
|
}>(`Data/XML/item_defs/vehicles/${nation}/components/engines.xml`);
|
||||||
const chassisList = await vfs.xml<{
|
const chassisList = await this.vfs.xml<{
|
||||||
root: ChassisDefinitionsList;
|
root: ChassisDefinitionsList;
|
||||||
}>(`Data/XML/item_defs/vehicles/${nation}/components/chassis.xml`);
|
}>(`Data/XML/item_defs/vehicles/${nation}/components/chassis.xml`);
|
||||||
|
|
||||||
for (const tankKey in tankList.root) {
|
for (const tankKey in tankList.root) {
|
||||||
if (botPattern.test(tankKey)) continue;
|
if (this.botPattern.test(tankKey)) continue;
|
||||||
|
|
||||||
const gunXps = new Map<number, ResearchCost>();
|
const gunXps = new Map<number, ResearchCost>();
|
||||||
const turretXps = new Map<number, ResearchCost>();
|
const turretXps = new Map<number, ResearchCost>();
|
||||||
const engineXps = new Map<number, ResearchCost>();
|
const engineXps = new Map<number, ResearchCost>();
|
||||||
const trackXps = new Map<number, ResearchCost>();
|
const trackXps = new Map<number, ResearchCost>();
|
||||||
const tank = tankList.root[tankKey];
|
const tank = tankList.root[tankKey];
|
||||||
const tankDefinition = await vfs.xml<{ root: VehicleDefinitions }>(
|
const tankDefinition = await this.vfs.xml<{ root: VehicleDefinitions }>(
|
||||||
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
|
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
|
||||||
);
|
);
|
||||||
const tankParameters = await vfs.yaml<TankParameters>(
|
const tankParameters = await this.vfs.yaml<TankParameters>(
|
||||||
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
||||||
);
|
);
|
||||||
const turretOrigin = tankDefinition.root.hull.turretPositions.turret
|
const turretOrigin = tankDefinition.root.hull.turretPositions.turret
|
||||||
@@ -1080,33 +1040,8 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
.map(Number) as Vector3Tuple;
|
.map(Number) as Vector3Tuple;
|
||||||
const tankId = toUniqueId(nation, tank.id);
|
const tankId = toUniqueId(nation, tank.id);
|
||||||
|
|
||||||
const tankTags = tank.tags.split(" ");
|
|
||||||
const hullArmor: Armor = { spaced: [], thickness: {} };
|
const hullArmor: Armor = { spaced: [], thickness: {} };
|
||||||
tankStringIdMap[`${nation}:${tankKey}`] = tankId;
|
this.tankStringIdMap[`${nation}:${tankKey}`] = tankId;
|
||||||
const slug = slugs.get(tankId);
|
|
||||||
|
|
||||||
if (slug === undefined) {
|
|
||||||
throw new Error(
|
|
||||||
`Could not find slug for ${nation}/${tankKey} (${tankId})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tank.sellPrice) {
|
|
||||||
tankPrice = {
|
|
||||||
type: TankPriceType.TANK_PRICE_TYPE_GOLD,
|
|
||||||
value: tank.sellPrice["#text"] * 2,
|
|
||||||
};
|
|
||||||
} else if (typeof tank.price === "number") {
|
|
||||||
tankPrice = {
|
|
||||||
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
|
|
||||||
value: tank.price,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
tankPrice = {
|
|
||||||
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
|
|
||||||
value: tank.price["#text"] * 400,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(tankDefinition.root.hull.armor)
|
Object.keys(tankDefinition.root.hull.armor)
|
||||||
.filter((name) => name.startsWith("armor_"))
|
.filter((name) => name.startsWith("armor_"))
|
||||||
@@ -1120,20 +1055,22 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
const armorId = parseInt(armorIdString);
|
const armorId = parseInt(armorIdString);
|
||||||
const armorRaw = tankDefinition.root.hull.armor[name];
|
const armorRaw = tankDefinition.root.hull.armor[name];
|
||||||
|
|
||||||
assignArmor(armorRaw, armorId, hullArmor);
|
this.assignArmor(armorRaw, armorId, hullArmor);
|
||||||
});
|
});
|
||||||
const crew: Crew[] = [];
|
const crew: Crew[] = [];
|
||||||
const totalUnlocks: UnlocksListing[] = [];
|
|
||||||
|
|
||||||
Object.entries(tankDefinition.root.crew).forEach(([crewKey, value]) => {
|
for (const crewKey in tankDefinition.root.crew) {
|
||||||
|
const value = tankDefinition.root.crew[crewKey as BlitzCrewType];
|
||||||
|
|
||||||
|
{
|
||||||
let entry: Crew;
|
let entry: Crew;
|
||||||
const index = crew.findIndex(
|
const index = crew.findIndex(
|
||||||
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey,
|
({ type }) => this.blitzkitCrewTypeToBlitz[type] === crewKey,
|
||||||
);
|
);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
if (crewKey === "#text") return;
|
if (crewKey === "#text") return;
|
||||||
entry = {
|
entry = {
|
||||||
type: blitzCrewTypeToBlitzkit[crewKey as BlitzCrewType],
|
type: this.blitzCrewTypeToBlitzkit[crewKey as BlitzCrewType],
|
||||||
count: 0,
|
count: 0,
|
||||||
substitute: [],
|
substitute: [],
|
||||||
};
|
};
|
||||||
@@ -1147,7 +1084,9 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
|
|
||||||
if (value !== "") {
|
if (value !== "") {
|
||||||
entry.substitute = value.split(/\n| /).map((member) => {
|
entry.substitute = value.split(/\n| /).map((member) => {
|
||||||
return blitzCrewTypeToBlitzkit[member.trim() as BlitzCrewType];
|
return this.blitzCrewTypeToBlitzkit[
|
||||||
|
member.trim() as BlitzCrewType
|
||||||
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1157,35 +1096,12 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
entry.count += value.length;
|
entry.count += value.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
let equalizerEntry = tierEqualizer.find(
|
|
||||||
(line) => line[0] === `${nation}:${tankKey}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (equalizerEntry) {
|
|
||||||
const [health, penetration, module_health, damage, armor] =
|
|
||||||
equalizerEntry?.slice(1).map(Number);
|
|
||||||
equalizer = { health, penetration, module_health, damage, armor };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tank.combatRole) {
|
|
||||||
Object.entries(tank.combatRole).forEach(([gameMode, role]) => {
|
|
||||||
const id = Object.entries(gameModeNativeNames).find(
|
|
||||||
([key]) => key.toLowerCase() === gameMode.toLowerCase(),
|
|
||||||
)?.[1];
|
|
||||||
|
|
||||||
if (id === undefined) {
|
|
||||||
throw new Error(
|
|
||||||
`Unknown game mode in tank ${tankKey}: ${gameMode}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modelDefinitions.models[tankId] = {
|
modelDefinitions.models[tankId] = {
|
||||||
armor: hullArmor,
|
armor: hullArmor,
|
||||||
turret_origin: vector3TupleToBlitzkit(turretOrigin),
|
turret_origin: this.vector3TupleToBlitzkit(turretOrigin),
|
||||||
initial_turret_rotation: tankDefinition.root.hull
|
initial_turret_rotation: tankDefinition.root.hull
|
||||||
.turretInitialRotation
|
.turretInitialRotation
|
||||||
? {
|
? {
|
||||||
@@ -1195,14 +1111,18 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
bounding_box: {
|
bounding_box: {
|
||||||
min: vector3TupleToBlitzkit(tankParameters.collision.hull.bbox.min),
|
min: this.vector3TupleToBlitzkit(
|
||||||
max: vector3TupleToBlitzkit(tankParameters.collision.hull.bbox.max),
|
tankParameters.collision.hull.bbox.min,
|
||||||
|
),
|
||||||
|
max: this.vector3TupleToBlitzkit(
|
||||||
|
tankParameters.collision.hull.bbox.max,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
turrets: {},
|
turrets: {},
|
||||||
tracks: {},
|
tracks: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(tankDefinition.root.chassis).forEach((key) => {
|
for (const key in tankDefinition.root.chassis) {
|
||||||
const track = tankDefinition.root.chassis[key];
|
const track = tankDefinition.root.chassis[key];
|
||||||
const trackId = toUniqueId(nation, chassisList.root.ids[key]);
|
const trackId = toUniqueId(nation, chassisList.root.ids[key]);
|
||||||
const trackArmorRaw = track.armor.leftTrack;
|
const trackArmorRaw = track.armor.leftTrack;
|
||||||
@@ -1210,22 +1130,14 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
.split(" ")
|
.split(" ")
|
||||||
.map(Number) as Vector3Tuple;
|
.map(Number) as Vector3Tuple;
|
||||||
|
|
||||||
totalUnlocks.push(track.unlocks);
|
|
||||||
|
|
||||||
modelDefinitions.models[tankId].tracks[trackId] = {
|
modelDefinitions.models[tankId].tracks[trackId] = {
|
||||||
thickness:
|
thickness:
|
||||||
typeof trackArmorRaw === "number"
|
typeof trackArmorRaw === "number"
|
||||||
? trackArmorRaw
|
? trackArmorRaw
|
||||||
: trackArmorRaw["#text"],
|
: trackArmorRaw["#text"],
|
||||||
origin: vector3TupleToBlitzkit(hullOrigin),
|
origin: this.vector3TupleToBlitzkit(hullOrigin),
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
|
||||||
Object.keys(tankDefinition.root.engines).forEach((engineKey) => {
|
|
||||||
const engine = tankDefinition.root.engines[engineKey];
|
|
||||||
|
|
||||||
totalUnlocks.push(engine.unlocks);
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(tankDefinition.root.turrets0).forEach((turretKey) => {
|
Object.keys(tankDefinition.root.turrets0).forEach((turretKey) => {
|
||||||
const turret = tankDefinition.root.turrets0[turretKey];
|
const turret = tankDefinition.root.turrets0[turretKey];
|
||||||
@@ -1249,7 +1161,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
.map(Number) as Vector3Tuple;
|
.map(Number) as Vector3Tuple;
|
||||||
const turretArmor: Armor = { thickness: {}, spaced: [] };
|
const turretArmor: Armor = { thickness: {}, spaced: [] };
|
||||||
|
|
||||||
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) => {
|
||||||
@@ -1262,14 +1173,14 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
const armorId = parseInt(armorIdString);
|
const armorId = parseInt(armorIdString);
|
||||||
const armorRaw = turret.armor[name];
|
const armorRaw = turret.armor[name];
|
||||||
|
|
||||||
assignArmor(armorRaw, armorId, turretArmor);
|
this.assignArmor(armorRaw, armorId, turretArmor);
|
||||||
});
|
});
|
||||||
|
|
||||||
turret.userString;
|
turret.userString;
|
||||||
|
|
||||||
modelDefinitions.models[tankId].turrets[turretId] = {
|
modelDefinitions.models[tankId].turrets[turretId] = {
|
||||||
armor: turretArmor,
|
armor: turretArmor,
|
||||||
gun_origin: vector3TupleToBlitzkit(gunOrigin),
|
gun_origin: this.vector3TupleToBlitzkit(gunOrigin),
|
||||||
model_id: turretModel,
|
model_id: turretModel,
|
||||||
yaw:
|
yaw:
|
||||||
-turretYaw[0] + turretYaw[1] === 360
|
-turretYaw[0] + turretYaw[1] === 360
|
||||||
@@ -1277,12 +1188,12 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
: { min: turretYaw[0], max: turretYaw[1] },
|
: { min: turretYaw[0], max: turretYaw[1] },
|
||||||
guns: {},
|
guns: {},
|
||||||
bounding_box: {
|
bounding_box: {
|
||||||
min: vector3TupleToBlitzkit(
|
min: this.vector3TupleToBlitzkit(
|
||||||
tankParameters.collision[
|
tankParameters.collision[
|
||||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
||||||
].bbox.min,
|
].bbox.min,
|
||||||
),
|
),
|
||||||
max: vector3TupleToBlitzkit(
|
max: this.vector3TupleToBlitzkit(
|
||||||
tankParameters.collision[
|
tankParameters.collision[
|
||||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
||||||
].bbox.max,
|
].bbox.max,
|
||||||
@@ -1305,8 +1216,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
const gunModel = Number(
|
const gunModel = Number(
|
||||||
parsePath(gun.models.undamaged).name.split("_")[1],
|
parsePath(gun.models.undamaged).name.split("_")[1],
|
||||||
);
|
);
|
||||||
// const gunReload = gun.reloadTime;
|
|
||||||
// const shellReloads =
|
|
||||||
const front = gun.extraPitchLimits?.front
|
const front = gun.extraPitchLimits?.front
|
||||||
? gun.extraPitchLimits.front.split(" ").map(Number)
|
? gun.extraPitchLimits.front.split(" ").map(Number)
|
||||||
: undefined;
|
: undefined;
|
||||||
@@ -1324,35 +1233,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
tankParameters.maskSlice?.[maskName]?.enabled ?? false;
|
tankParameters.maskSlice?.[maskName]?.enabled ?? false;
|
||||||
let mask: number | undefined;
|
let mask: number | undefined;
|
||||||
|
|
||||||
if (gun.extras?.trayShell) {
|
|
||||||
const types = gun.extras.trayShell.kinds
|
|
||||||
.split(" ")
|
|
||||||
.map((string) => {
|
|
||||||
const trimmed = string.trim();
|
|
||||||
|
|
||||||
if (trimmed in blitzShellKindToBlitzkit) {
|
|
||||||
return blitzShellKindToBlitzkit[trimmed as ShellKind];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new SyntaxError(`Invalid shell kind: ${trimmed}`);
|
|
||||||
});
|
|
||||||
const sectorNames = Object.keys(gun.extras.trayShell.sectors);
|
|
||||||
|
|
||||||
if (sectorNames.length !== 1 || sectorNames[0] !== "sector") {
|
|
||||||
throw new SyntaxError("Invalid tray shell sector");
|
|
||||||
}
|
|
||||||
|
|
||||||
const sector = gun.extras.trayShell.sectors.sector;
|
|
||||||
|
|
||||||
assault_ranges = {
|
|
||||||
types,
|
|
||||||
ranges: sector.map((value) => ({
|
|
||||||
factor: value.factor,
|
|
||||||
distance: value.distance,
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maskEnabled) {
|
if (maskEnabled) {
|
||||||
const maskRaw = tankParameters.maskSlice![maskName]!;
|
const maskRaw = tankParameters.maskSlice![maskName]!;
|
||||||
mask = maskRaw.planePosition[1];
|
mask = maskRaw.planePosition[1];
|
||||||
@@ -1360,7 +1240,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
mask = undefined;
|
mask = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalUnlocks.push(gun.unlocks);
|
|
||||||
Object.keys(gun.armor)
|
Object.keys(gun.armor)
|
||||||
.filter((name) => name.startsWith("armor_"))
|
.filter((name) => name.startsWith("armor_"))
|
||||||
.forEach((name) => {
|
.forEach((name) => {
|
||||||
@@ -1371,7 +1250,7 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
const armorId = parseInt(armorIdString);
|
const armorId = parseInt(armorIdString);
|
||||||
const armorRaw = gun.armor[name];
|
const armorRaw = gun.armor[name];
|
||||||
|
|
||||||
assignArmor(armorRaw, armorId, gunArmor);
|
this.assignArmor(armorRaw, armorId, gunArmor);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
|
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
|
||||||
@@ -1407,63 +1286,6 @@ export class ServerBlitzKitAPI extends BlitzKitAPI {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
totalUnlocks.forEach((unlocks) => {
|
|
||||||
if (unlocks === undefined) return;
|
|
||||||
|
|
||||||
Object.entries(unlocks).forEach(([key, value]) => {
|
|
||||||
(Array.isArray(value) ? value : [value]).forEach((vehicle) => {
|
|
||||||
switch (key as keyof BlitzModuleType) {
|
|
||||||
case "vehicle": {
|
|
||||||
const tankListEntry = tankList.root[vehicle["#text"]];
|
|
||||||
const successorId = toUniqueId(nation, tankListEntry.id);
|
|
||||||
|
|
||||||
tankXps.set(successorId, parseResearchCost(vehicle.cost));
|
|
||||||
|
|
||||||
if (currentTank.successors === undefined) {
|
|
||||||
currentTank.successors = [];
|
|
||||||
}
|
|
||||||
if (!currentTank.successors!.includes(successorId)) {
|
|
||||||
currentTank.successors!.push(successorId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "gun": {
|
|
||||||
gunXps.set(
|
|
||||||
toUniqueId(nation, gunList.root.ids[vehicle["#text"]]),
|
|
||||||
parseResearchCost(vehicle.cost),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "turret": {
|
|
||||||
turretXps.set(
|
|
||||||
toUniqueId(nation, turretList.root.ids[vehicle["#text"]]),
|
|
||||||
parseResearchCost(vehicle.cost),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "engine": {
|
|
||||||
engineXps.set(
|
|
||||||
toUniqueId(nation, enginesList.root.ids[vehicle["#text"]]),
|
|
||||||
parseResearchCost(vehicle.cost),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "chassis": {
|
|
||||||
trackXps.set(
|
|
||||||
toUniqueId(nation, chassisList.root.ids[vehicle["#text"]]),
|
|
||||||
parseResearchCost(vehicle.cost),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ const blitzTankFilterDefinitionCategoryToBlitzkit: Record<
|
|||||||
> = {
|
> = {
|
||||||
clip: ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP,
|
clip: ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP,
|
||||||
};
|
};
|
||||||
function vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
|
||||||
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BlitzStrings {
|
export interface BlitzStrings {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
|
|||||||
Reference in new issue
Block a user