mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: ability defs
This commit is contained in:
1 parent
4811668832
commit
d9c2f53c6a
4 files changed
+190
-104
No files matched your search
@@ -12,6 +12,7 @@ import { CamouflageDefinitions } from '../../src/core/blitzkit/camouflageDefinit
|
|||||||
import { commitAssets } from '../../src/core/blitzkit/commitAssets';
|
import { commitAssets } from '../../src/core/blitzkit/commitAssets';
|
||||||
import {
|
import {
|
||||||
ConsumableDefinitions,
|
ConsumableDefinitions,
|
||||||
|
ConsumableEntry,
|
||||||
TankFilterDefinitionCategory,
|
TankFilterDefinitionCategory,
|
||||||
} from '../../src/core/blitzkit/consumableDefinitions';
|
} from '../../src/core/blitzkit/consumableDefinitions';
|
||||||
import {
|
import {
|
||||||
@@ -25,7 +26,10 @@ import {
|
|||||||
ModelArmor,
|
ModelArmor,
|
||||||
ModelDefinitions,
|
ModelDefinitions,
|
||||||
} from '../../src/core/blitzkit/modelDefinitions';
|
} from '../../src/core/blitzkit/modelDefinitions';
|
||||||
import { ProvisionDefinitions } from '../../src/core/blitzkit/provisionDefinitions';
|
import {
|
||||||
|
ProvisionDefinitions,
|
||||||
|
ProvisionEntry,
|
||||||
|
} from '../../src/core/blitzkit/provisionDefinitions';
|
||||||
import { SkillDefinitions } from '../../src/core/blitzkit/skillDefinitions';
|
import { SkillDefinitions } from '../../src/core/blitzkit/skillDefinitions';
|
||||||
import { superCompress } from '../../src/core/blitzkit/superCompress';
|
import { superCompress } from '../../src/core/blitzkit/superCompress';
|
||||||
import {
|
import {
|
||||||
@@ -450,6 +454,7 @@ export async function definitions(production: boolean) {
|
|||||||
)
|
)
|
||||||
).available_nations,
|
).available_nations,
|
||||||
gameModes: {},
|
gameModes: {},
|
||||||
|
roles: {},
|
||||||
};
|
};
|
||||||
const tankDefinitions: TankDefinitions = {};
|
const tankDefinitions: TankDefinitions = {};
|
||||||
const camouflageDefinitions: CamouflageDefinitions = {};
|
const camouflageDefinitions: CamouflageDefinitions = {};
|
||||||
@@ -486,12 +491,43 @@ export async function definitions(production: boolean) {
|
|||||||
const optionalDeviceSlots = await readXMLDVPL<{
|
const optionalDeviceSlots = await readXMLDVPL<{
|
||||||
root: OptionalDeviceSlots;
|
root: OptionalDeviceSlots;
|
||||||
}>(`${DATA}/XML/item_defs/vehicles/common/optional_device_slots.xml.dvpl`);
|
}>(`${DATA}/XML/item_defs/vehicles/common/optional_device_slots.xml.dvpl`);
|
||||||
const consumables = await readXMLDVPL<{ root: ConsumablesCommon }>(
|
const consumables: ConsumablesCommon = {};
|
||||||
`${DATA}/XML/item_defs/vehicles/common/consumables/common.xml.dvpl`,
|
const provisions: ProvisionsCommon = {};
|
||||||
);
|
|
||||||
const provisions = await readXMLDVPL<{ root: ProvisionsCommon }>(
|
for (const match of (
|
||||||
`${DATA}/XML/item_defs/vehicles/common/provisions/common.xml.dvpl`,
|
await readStringDVPL(
|
||||||
);
|
`${DATA}/XML/item_defs/vehicles/common/consumables/list.xml.dvpl`,
|
||||||
|
)
|
||||||
|
).matchAll(/<items path="(.+)\.xml"\/>/g)) {
|
||||||
|
if (match[1] === 'prototypes') continue;
|
||||||
|
|
||||||
|
Object.assign(
|
||||||
|
consumables,
|
||||||
|
(
|
||||||
|
await readXMLDVPL<{ root: ConsumablesCommon }>(
|
||||||
|
`${DATA}/XML/item_defs/vehicles/common/consumables/${match[1]}.xml.dvpl`,
|
||||||
|
)
|
||||||
|
).root,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const match of (
|
||||||
|
await readStringDVPL(
|
||||||
|
`${DATA}/XML/item_defs/vehicles/common/provisions/list.xml.dvpl`,
|
||||||
|
)
|
||||||
|
).matchAll(/<items path="(.+)\.xml"\/>/g)) {
|
||||||
|
if (match[1] === 'prototypes') continue;
|
||||||
|
|
||||||
|
Object.assign(
|
||||||
|
provisions,
|
||||||
|
(
|
||||||
|
await readXMLDVPL<{ root: ConsumablesCommon }>(
|
||||||
|
`${DATA}/XML/item_defs/vehicles/common/provisions/${match[1]}.xml.dvpl`,
|
||||||
|
)
|
||||||
|
).root,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const avatar = await readXMLDVPL<{ root: Avatar }>(
|
const avatar = await readXMLDVPL<{ root: Avatar }>(
|
||||||
`${DATA}/XML/item_defs/tankmen/avatar.xml.dvpl`,
|
`${DATA}/XML/item_defs/tankmen/avatar.xml.dvpl`,
|
||||||
);
|
);
|
||||||
@@ -514,6 +550,8 @@ export async function definitions(production: boolean) {
|
|||||||
const combatRoles = await readYAMLDVPL<CombatRolesYaml>(
|
const combatRoles = await readYAMLDVPL<CombatRolesYaml>(
|
||||||
`${DATA}/XML/item_defs/vehicles/common/combat_roles.yaml.dvpl`,
|
`${DATA}/XML/item_defs/vehicles/common/combat_roles.yaml.dvpl`,
|
||||||
);
|
);
|
||||||
|
const consumableNativeNames: Record<string, number> = {};
|
||||||
|
const provisionNativeNames: Record<string, number> = {};
|
||||||
|
|
||||||
for (const match of squadBattleTypeStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
for (const match of squadBattleTypeStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
||||||
/"(\d+)" -> "(battleType\/([a-zA-Z]+))"/g,
|
/"(\d+)" -> "(battleType\/([a-zA-Z]+))"/g,
|
||||||
@@ -785,8 +823,6 @@ export async function definitions(production: boolean) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(combatRoles[role].id);
|
|
||||||
|
|
||||||
tankDefinitions[tankId].roles[id] = combatRoles[role].id;
|
tankDefinitions[tankId].roles[id] = combatRoles[role].id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1240,126 +1276,140 @@ export async function definitions(production: boolean) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.values(consumables.root).forEach((consumable) => {
|
Object.entries(consumables).forEach(([key, consumable]) => {
|
||||||
consumableDefinitions[consumable.id] = {
|
consumableNativeNames[key] = consumable.id;
|
||||||
|
|
||||||
|
const entry = {
|
||||||
id: consumable.id,
|
id: consumable.id,
|
||||||
|
gameMode: 'gameModeFilter' in consumable,
|
||||||
cooldown: consumable.script.cooldown,
|
cooldown: consumable.script.cooldown,
|
||||||
duration: consumable.script.duration,
|
duration: consumable.script.duration,
|
||||||
name:
|
name:
|
||||||
strings[consumable.userString] ??
|
strings[consumable.userString] ??
|
||||||
missingStrings[consumable.userString] ??
|
missingStrings[consumable.userString] ??
|
||||||
`Unknown ${consumable.id}`,
|
`Unknown ${consumable.id}`,
|
||||||
include: [],
|
} as ConsumableEntry;
|
||||||
};
|
consumableDefinitions[consumable.id] = entry;
|
||||||
|
|
||||||
const includeRaw = consumable.vehicleFilter?.include.vehicle;
|
const includeRaw = consumable.vehicleFilter?.include.vehicle;
|
||||||
const excludeRaw = consumable.vehicleFilter?.exclude?.vehicle;
|
const excludeRaw = consumable.vehicleFilter?.exclude?.vehicle;
|
||||||
|
|
||||||
if (includeRaw) {
|
if (!entry.gameMode) {
|
||||||
if ('minLevel' in includeRaw) {
|
if (includeRaw) {
|
||||||
consumableDefinitions[consumable.id].include.push({
|
entry.include = [];
|
||||||
type: 'tier',
|
|
||||||
min: includeRaw.minLevel,
|
|
||||||
max: includeRaw.maxLevel,
|
|
||||||
});
|
|
||||||
} else if ('name' in includeRaw) {
|
|
||||||
consumableDefinitions[consumable.id].include.push({
|
|
||||||
type: 'ids',
|
|
||||||
ids: includeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
|
||||||
});
|
|
||||||
} else throw new SyntaxError('Unhandled include type');
|
|
||||||
|
|
||||||
if (consumable.vehicleFilter?.include.nations) {
|
if ('minLevel' in includeRaw) {
|
||||||
consumableDefinitions[consumable.id].include.push({
|
entry.include.push({
|
||||||
type: 'nation',
|
type: 'tier',
|
||||||
nations: consumable.vehicleFilter.include.nations.split(' '),
|
min: includeRaw.minLevel,
|
||||||
});
|
max: includeRaw.maxLevel,
|
||||||
|
});
|
||||||
|
} else if ('name' in includeRaw) {
|
||||||
|
entry.include.push({
|
||||||
|
type: 'ids',
|
||||||
|
ids: includeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
||||||
|
});
|
||||||
|
} else throw new SyntaxError('Unhandled include type');
|
||||||
|
|
||||||
|
if (consumable.vehicleFilter?.include.nations) {
|
||||||
|
entry.include.push({
|
||||||
|
type: 'nation',
|
||||||
|
nations: consumable.vehicleFilter.include.nations.split(' '),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (excludeRaw) {
|
if (excludeRaw) {
|
||||||
consumableDefinitions[consumable.id].exclude = [];
|
entry.exclude = [];
|
||||||
|
|
||||||
if ('name' in excludeRaw) {
|
if ('name' in excludeRaw) {
|
||||||
consumableDefinitions[consumable.id].exclude!.push({
|
entry.exclude!.push({
|
||||||
type: 'ids',
|
type: 'ids',
|
||||||
ids: excludeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
ids: excludeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
||||||
});
|
});
|
||||||
} else if ('extendedTags' in excludeRaw) {
|
} else if ('extendedTags' in excludeRaw) {
|
||||||
consumableDefinitions[consumable.id].exclude!.push({
|
entry.exclude!.push({
|
||||||
type: 'category',
|
type: 'category',
|
||||||
categories: excludeRaw.extendedTags.split(
|
categories: excludeRaw.extendedTags.split(
|
||||||
' ',
|
' ',
|
||||||
) as TankFilterDefinitionCategory[],
|
) as TankFilterDefinitionCategory[],
|
||||||
});
|
});
|
||||||
} else throw new SyntaxError('Unhandled exclude type');
|
} else throw new SyntaxError('Unhandled exclude type');
|
||||||
|
|
||||||
if (consumable.vehicleFilter?.exclude?.nations) {
|
if (consumable.vehicleFilter?.exclude?.nations) {
|
||||||
consumableDefinitions[consumable.id].exclude!.push({
|
entry.exclude!.push({
|
||||||
type: 'nation',
|
type: 'nation',
|
||||||
nations: consumable.vehicleFilter.exclude.nations.split(' '),
|
nations: consumable.vehicleFilter.exclude.nations.split(' '),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.values(provisions.root).forEach((provision) => {
|
Object.entries(provisions).forEach(([key, provision]) => {
|
||||||
provisionDefinitions[provision.id] = {
|
provisionNativeNames[key] = provision.id;
|
||||||
|
|
||||||
|
const entry = {
|
||||||
id: provision.id,
|
id: provision.id,
|
||||||
|
gameMode: 'gameModeFilter' in provision,
|
||||||
name:
|
name:
|
||||||
strings[provision.userString] ??
|
strings[provision.userString] ??
|
||||||
missingStrings[provision.userString] ??
|
missingStrings[provision.userString] ??
|
||||||
`Unknown ${provision.id}`,
|
`Unknown ${provision.id}`,
|
||||||
include: [],
|
} as ProvisionEntry;
|
||||||
};
|
provisionDefinitions[provision.id] = entry;
|
||||||
|
|
||||||
const includeRaw = provision.vehicleFilter?.include.vehicle;
|
const includeRaw = provision.vehicleFilter?.include.vehicle;
|
||||||
const excludeRaw = provision.vehicleFilter?.exclude?.vehicle;
|
const excludeRaw = provision.vehicleFilter?.exclude?.vehicle;
|
||||||
|
|
||||||
if (includeRaw) {
|
if (!entry.gameMode) {
|
||||||
if ('minLevel' in includeRaw) {
|
if (includeRaw) {
|
||||||
provisionDefinitions[provision.id].include.push({
|
entry.include = [];
|
||||||
type: 'tier',
|
|
||||||
min: includeRaw.minLevel,
|
|
||||||
max: includeRaw.maxLevel,
|
|
||||||
});
|
|
||||||
} else if ('name' in includeRaw) {
|
|
||||||
provisionDefinitions[provision.id].include.push({
|
|
||||||
type: 'ids',
|
|
||||||
ids: includeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
|
||||||
});
|
|
||||||
} else throw new SyntaxError('Unhandled include type');
|
|
||||||
|
|
||||||
if (provision.vehicleFilter?.include.nations) {
|
if ('minLevel' in includeRaw) {
|
||||||
provisionDefinitions[provision.id].include.push({
|
entry.include.push({
|
||||||
type: 'nation',
|
type: 'tier',
|
||||||
nations: provision.vehicleFilter.include.nations.split(' '),
|
min: includeRaw.minLevel,
|
||||||
});
|
max: includeRaw.maxLevel,
|
||||||
|
});
|
||||||
|
} else if ('name' in includeRaw) {
|
||||||
|
entry.include.push({
|
||||||
|
type: 'ids',
|
||||||
|
ids: includeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
||||||
|
});
|
||||||
|
} else throw new SyntaxError('Unhandled include type');
|
||||||
|
|
||||||
|
if (provision.vehicleFilter?.include.nations) {
|
||||||
|
entry.include.push({
|
||||||
|
type: 'nation',
|
||||||
|
nations: provision.vehicleFilter.include.nations.split(' '),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (excludeRaw) {
|
if (excludeRaw) {
|
||||||
provisionDefinitions[provision.id].exclude = [];
|
entry.exclude = [];
|
||||||
|
|
||||||
if ('name' in excludeRaw) {
|
if ('name' in excludeRaw) {
|
||||||
provisionDefinitions[provision.id].exclude!.push({
|
entry.exclude!.push({
|
||||||
type: 'ids',
|
type: 'ids',
|
||||||
ids: excludeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
ids: excludeRaw.name.split(' ').map((key) => tankStringIdMap[key]),
|
||||||
});
|
});
|
||||||
} else if ('extendedTags' in excludeRaw) {
|
} else if ('extendedTags' in excludeRaw) {
|
||||||
provisionDefinitions[provision.id].exclude!.push({
|
entry.exclude!.push({
|
||||||
type: 'category',
|
type: 'category',
|
||||||
categories: excludeRaw.extendedTags.split(
|
categories: excludeRaw.extendedTags.split(
|
||||||
' ',
|
' ',
|
||||||
) as TankFilterDefinitionCategory[],
|
) as TankFilterDefinitionCategory[],
|
||||||
});
|
});
|
||||||
} else throw new SyntaxError('Unhandled exclude type');
|
} else throw new SyntaxError('Unhandled exclude type');
|
||||||
|
|
||||||
if (provision.vehicleFilter?.exclude?.nations) {
|
if (provision.vehicleFilter?.exclude?.nations) {
|
||||||
provisionDefinitions[provision.id].exclude!.push({
|
entry.exclude!.push({
|
||||||
type: 'nation',
|
type: 'nation',
|
||||||
nations: provision.vehicleFilter.exclude.nations.split(' '),
|
nations: provision.vehicleFilter.exclude.nations.split(' '),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1369,6 +1419,22 @@ export async function definitions(production: boolean) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Object.entries(combatRoles).forEach(([, value]) => {
|
||||||
|
gameDefinitions.roles[value.id] = { provisions: [], consumables: [] };
|
||||||
|
|
||||||
|
value.default_abilities.forEach((ability) => {
|
||||||
|
if (ability in consumableNativeNames) {
|
||||||
|
gameDefinitions.roles[value.id].consumables.push(
|
||||||
|
consumableNativeNames[ability],
|
||||||
|
);
|
||||||
|
} else if (ability in provisionNativeNames) {
|
||||||
|
gameDefinitions.roles[value.id].provisions.push(
|
||||||
|
provisionNativeNames[ability],
|
||||||
|
);
|
||||||
|
} else throw new Error(`Unknown ability ${ability}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Object.entries(avatar.root.skillsByClasses).forEach(([tankClass, skills]) => {
|
Object.entries(avatar.root.skillsByClasses).forEach(([tankClass, skills]) => {
|
||||||
skillDefinitions.classes[tankClass as TankClass] = skills.split(' ');
|
skillDefinitions.classes[tankClass as TankClass] = skills.split(' ');
|
||||||
});
|
});
|
||||||
@@ -1380,7 +1446,6 @@ export async function definitions(production: boolean) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
|
||||||
await commitAssets(
|
await commitAssets(
|
||||||
'definitions',
|
'definitions',
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -22,14 +22,21 @@ export type TankFilterDefinition =
|
|||||||
nations: string[];
|
nations: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ConsumableEntry {
|
export type ConsumableEntry = {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
cooldown: number;
|
cooldown: number;
|
||||||
duration?: number;
|
duration?: number;
|
||||||
include: TankFilterDefinition[];
|
} & (
|
||||||
exclude?: TankFilterDefinition[];
|
| {
|
||||||
}
|
gameMode: false;
|
||||||
|
include: TankFilterDefinition[];
|
||||||
|
exclude?: TankFilterDefinition[];
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
gameMode: true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export interface ConsumableDefinitions {
|
export interface ConsumableDefinitions {
|
||||||
[key: string]: ConsumableEntry;
|
[key: string]: ConsumableEntry;
|
||||||
|
|||||||
@@ -9,6 +9,13 @@ export interface GameDefinitions {
|
|||||||
version: string;
|
version: string;
|
||||||
nations: string[];
|
nations: string[];
|
||||||
gameModes: Record<number, GameMode>;
|
gameModes: Record<number, GameMode>;
|
||||||
|
roles: Record<
|
||||||
|
number,
|
||||||
|
{
|
||||||
|
provisions: number[];
|
||||||
|
consumables: number[];
|
||||||
|
}
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const gameDefinitions = fetchCdonLz4<GameDefinitions>(
|
export const gameDefinitions = fetchCdonLz4<GameDefinitions>(
|
||||||
|
|||||||
@@ -2,13 +2,20 @@ import { asset } from './asset';
|
|||||||
import { TankFilterDefinition } from './consumableDefinitions';
|
import { TankFilterDefinition } from './consumableDefinitions';
|
||||||
import { fetchCdonLz4 } from './fetchCdonLz4';
|
import { fetchCdonLz4 } from './fetchCdonLz4';
|
||||||
|
|
||||||
export interface ProvisionEntry {
|
export type ProvisionEntry = {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
include: TankFilterDefinition[];
|
|
||||||
exclude?: TankFilterDefinition[];
|
|
||||||
crew?: number;
|
crew?: number;
|
||||||
}
|
} & (
|
||||||
|
| {
|
||||||
|
gameMode: false;
|
||||||
|
include: TankFilterDefinition[];
|
||||||
|
exclude?: TankFilterDefinition[];
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
gameMode: true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export interface ProvisionDefinitions {
|
export interface ProvisionDefinitions {
|
||||||
[key: string]: ProvisionEntry;
|
[key: string]: ProvisionEntry;
|
||||||
|
|||||||
Reference in new issue
Block a user