mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
add basic xi compatibility
This commit is contained in:
1 parent
05648ea040
commit
b9388cc544
9 files changed
+73
-27
No files matched your search
@@ -246,6 +246,27 @@ export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getTankFilterIds(
|
||||||
|
name: string,
|
||||||
|
definitionKey: string,
|
||||||
|
filter: "include" | "exclude",
|
||||||
|
) {
|
||||||
|
const keys = name.trim().split(/\s+/).filter(Boolean);
|
||||||
|
|
||||||
|
return keys.flatMap((key) => {
|
||||||
|
const id = this.tankStringIdMap[key];
|
||||||
|
|
||||||
|
if (id === undefined) {
|
||||||
|
console.warn(
|
||||||
|
`Skipping unavailable tank "${key}" in ${filter} vehicle filter for "${definitionKey}"`,
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [id];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected getString(name: string) {
|
protected getString(name: string) {
|
||||||
const collection: Record<string, string> = {
|
const collection: Record<string, string> = {
|
||||||
[locales.default]: this.stringsI18n[locales.default][name],
|
[locales.default]: this.stringsI18n[locales.default][name],
|
||||||
|
|||||||
@@ -595,9 +595,25 @@ export abstract class ServerBlitzKitAPI1 extends ServerBlitzKitAPI0 {
|
|||||||
for (const shellKey in gunListEntry.shots) {
|
for (const shellKey in gunListEntry.shots) {
|
||||||
const gunShellEntry = gunListEntry.shots[shellKey];
|
const gunShellEntry = gunListEntry.shots[shellKey];
|
||||||
const shell = shellList.root[shellKey];
|
const shell = shellList.root[shellKey];
|
||||||
|
|
||||||
|
// Newer client data stores shot properties on the shell rather
|
||||||
|
// than repeating them under every gun's <shots> entry.
|
||||||
|
const speed =
|
||||||
|
typeof gunShellEntry === "string"
|
||||||
|
? shell.speed
|
||||||
|
: gunShellEntry.speed;
|
||||||
|
const maxDistance =
|
||||||
|
typeof gunShellEntry === "string"
|
||||||
|
? shell.maxDistance
|
||||||
|
: gunShellEntry.maxDistance;
|
||||||
|
const piercingPower =
|
||||||
|
typeof gunShellEntry === "string"
|
||||||
|
? shell.piercingPower
|
||||||
|
: gunShellEntry.piercingPower;
|
||||||
|
|
||||||
const shellId = toUniqueId(nation, shell.id);
|
const shellId = toUniqueId(nation, shell.id);
|
||||||
const shellName = this.getString(shell.userString);
|
const shellName = this.getString(shell.userString);
|
||||||
const penetrationRaw = gunShellEntry.piercingPower
|
const penetrationRaw = piercingPower
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.filter((penetrationString) => penetrationString !== "")
|
.filter((penetrationString) => penetrationString !== "")
|
||||||
.map(Number);
|
.map(Number);
|
||||||
@@ -607,7 +623,7 @@ export abstract class ServerBlitzKitAPI1 extends ServerBlitzKitAPI0 {
|
|||||||
].shells.push({
|
].shells.push({
|
||||||
id: shellId,
|
id: shellId,
|
||||||
name: shellName,
|
name: shellName,
|
||||||
velocity: gunShellEntry.speed,
|
velocity: speed,
|
||||||
armor_damage: shell.damage.armor,
|
armor_damage: shell.damage.armor,
|
||||||
module_damage: shell.damage.devices,
|
module_damage: shell.damage.devices,
|
||||||
caliber: shell.caliber,
|
caliber: shell.caliber,
|
||||||
@@ -623,7 +639,7 @@ export abstract class ServerBlitzKitAPI1 extends ServerBlitzKitAPI0 {
|
|||||||
near: penetrationRaw[0],
|
near: penetrationRaw[0],
|
||||||
far: penetrationRaw[1],
|
far: penetrationRaw[1],
|
||||||
},
|
},
|
||||||
range: gunShellEntry.maxDistance,
|
range: maxDistance,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export abstract class ServerBlitzKitAPI2 extends ServerBlitzKitAPI1 {
|
|||||||
for (const camoKey in this.camouflagesXml!.root.camouflages) {
|
for (const camoKey in this.camouflagesXml!.root.camouflages) {
|
||||||
const camo = this.camouflagesXml!.root.camouflages[camoKey];
|
const camo = this.camouflagesXml!.root.camouflages[camoKey];
|
||||||
|
|
||||||
|
if (!(camoKey in this.camouflagesYaml!)) continue;
|
||||||
|
|
||||||
const yamlEntry = this.camouflagesYaml![camoKey];
|
const yamlEntry = this.camouflagesYaml![camoKey];
|
||||||
const fullName = yamlEntry.userString
|
const fullName = yamlEntry.userString
|
||||||
? this.getString(yamlEntry.userString)
|
? this.getString(yamlEntry.userString)
|
||||||
|
|||||||
@@ -44,9 +44,7 @@ export abstract class ServerBlitzKitAPI6 extends ServerBlitzKitAPI5 {
|
|||||||
filter_type: {
|
filter_type: {
|
||||||
$case: "ids",
|
$case: "ids",
|
||||||
value: {
|
value: {
|
||||||
ids: includeRaw.name.split(/ +/).map((key) => {
|
ids: this.getTankFilterIds(includeRaw.name, key, "include"),
|
||||||
return this.tankStringIdMap[key];
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -72,9 +70,7 @@ export abstract class ServerBlitzKitAPI6 extends ServerBlitzKitAPI5 {
|
|||||||
filter_type: {
|
filter_type: {
|
||||||
$case: "ids",
|
$case: "ids",
|
||||||
value: {
|
value: {
|
||||||
ids: excludeRaw.name.split(/ +/).map((key) => {
|
ids: this.getTankFilterIds(excludeRaw.name, key, "exclude"),
|
||||||
return this.tankStringIdMap[key];
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
|
|||||||
async provisionDefinitions() {
|
async provisionDefinitions() {
|
||||||
const provisionDefinitions = ProvisionDefinitions.create();
|
const provisionDefinitions = ProvisionDefinitions.create();
|
||||||
|
|
||||||
Object.entries(this.provisionsCommon).forEach(([, provision]) => {
|
Object.entries(this.provisionsCommon).forEach(([key, provision]) => {
|
||||||
const entry: Provision = {
|
const entry: Provision = {
|
||||||
id: provision.id,
|
id: provision.id,
|
||||||
exclude: [],
|
exclude: [],
|
||||||
@@ -42,9 +42,7 @@ export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
|
|||||||
filter_type: {
|
filter_type: {
|
||||||
$case: "ids",
|
$case: "ids",
|
||||||
value: {
|
value: {
|
||||||
ids: includeRaw.name.split(/ +/).map((key) => {
|
ids: this.getTankFilterIds(includeRaw.name, key, "include"),
|
||||||
return this.tankStringIdMap[key];
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -70,9 +68,7 @@ export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
|
|||||||
filter_type: {
|
filter_type: {
|
||||||
$case: "ids",
|
$case: "ids",
|
||||||
value: {
|
value: {
|
||||||
ids: excludeRaw.name
|
ids: this.getTankFilterIds(excludeRaw.name, key, "exclude"),
|
||||||
.split(/ +/)
|
|
||||||
.map((key) => this.tankStringIdMap[key]),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ export interface GunDefinitionsList {
|
|||||||
burst?: { count: number; rate: number };
|
burst?: { count: number; rate: number };
|
||||||
clip?: { count: number; rate: number };
|
clip?: { count: number; rate: number };
|
||||||
shots: {
|
shots: {
|
||||||
[key: string]: {
|
[key: string]:
|
||||||
speed: number;
|
| ""
|
||||||
piercingPower: string;
|
| {
|
||||||
maxDistance: number;
|
speed: number;
|
||||||
};
|
piercingPower: string;
|
||||||
|
maxDistance: number;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ export type ShellDefinitionsList = Record<
|
|||||||
normalizationAngle?: number;
|
normalizationAngle?: number;
|
||||||
ricochetAngle?: number;
|
ricochetAngle?: number;
|
||||||
explosionRadius?: number;
|
explosionRadius?: number;
|
||||||
|
speed: number;
|
||||||
|
maxDistance?: number;
|
||||||
|
piercingPower: string;
|
||||||
}
|
}
|
||||||
> & {
|
> & {
|
||||||
icons: Record<string, string>;
|
icons: Record<string, string>;
|
||||||
|
|||||||
@@ -7,12 +7,23 @@ import {
|
|||||||
import type { DuelMember } from "../../stores/duel";
|
import type { DuelMember } from "../../stores/duel";
|
||||||
import { genericDefaultEquipmentMatrix } from "../../stores/duel/constants";
|
import { genericDefaultEquipmentMatrix } from "../../stores/duel/constants";
|
||||||
|
|
||||||
|
export function defaultTankWeapon(tank: TankDefinition) {
|
||||||
|
for (const turret of [...tank.turrets].reverse()) {
|
||||||
|
for (const gun of [...turret.guns].reverse()) {
|
||||||
|
const shell = gun.shells[0];
|
||||||
|
|
||||||
|
if (shell) return { turret, gun, shell };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Tank ${tank.id} has no gun with shells`);
|
||||||
|
}
|
||||||
|
|
||||||
export function tankToDuelMember(
|
export function tankToDuelMember(
|
||||||
tank: TankDefinition,
|
tank: TankDefinition,
|
||||||
provisionDefinitions: ProvisionDefinitions,
|
provisionDefinitions: ProvisionDefinitions,
|
||||||
) {
|
) {
|
||||||
const turret = tank.turrets.at(-1)!;
|
const { turret, gun, shell } = defaultTankWeapon(tank);
|
||||||
const gun = turret.guns.at(-1)!;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
camouflage: true,
|
camouflage: true,
|
||||||
@@ -22,7 +33,7 @@ export function tankToDuelMember(
|
|||||||
provisions: createDefaultProvisions(tank, gun, provisionDefinitions),
|
provisions: createDefaultProvisions(tank, gun, provisionDefinitions),
|
||||||
engine: tank.engines.at(-1)!,
|
engine: tank.engines.at(-1)!,
|
||||||
gun,
|
gun,
|
||||||
shell: tank.turrets.at(-1)!.guns.at(-1)!.shells[0],
|
shell,
|
||||||
tank,
|
tank,
|
||||||
track: tank.tracks.at(-1)!,
|
track: tank.tracks.at(-1)!,
|
||||||
turret,
|
turret,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { load } from "cheerio";
|
|||||||
import { api } from "../../../../../core/blitzkit/api";
|
import { api } from "../../../../../core/blitzkit/api";
|
||||||
import { mixStaticPaths } from "../../../../../core/blitzkit/mixStaticPaths";
|
import { mixStaticPaths } from "../../../../../core/blitzkit/mixStaticPaths";
|
||||||
import { tankCharacteristics } from "../../../../../core/blitzkit/tankCharacteristics";
|
import { tankCharacteristics } from "../../../../../core/blitzkit/tankCharacteristics";
|
||||||
|
import { defaultTankWeapon } from "../../../../../core/blitzkit/tankToDuelMember";
|
||||||
import { getStrings } from "../../../../../core/i18n/getStrings";
|
import { getStrings } from "../../../../../core/i18n/getStrings";
|
||||||
import BaseLayout from "../../../../../layouts/BaseLayout.astro";
|
import BaseLayout from "../../../../../layouts/BaseLayout.astro";
|
||||||
import { genericDefaultEquipmentMatrix } from "../../../../../stores/duel/constants";
|
import { genericDefaultEquipmentMatrix } from "../../../../../stores/duel/constants";
|
||||||
@@ -53,9 +54,7 @@ const title = literals(strings.website.tools.tankopedia.tank_seo_title, {
|
|||||||
const url = import.meta.env.SITE + Astro.url.pathname;
|
const url = import.meta.env.SITE + Astro.url.pathname;
|
||||||
|
|
||||||
const icon = alias("api", `/tanks/${id}/icons/big.webp`);
|
const icon = alias("api", `/tanks/${id}/icons/big.webp`);
|
||||||
const turret = tank.turrets.at(-1)!;
|
const { turret, gun, shell } = defaultTankWeapon(tank);
|
||||||
const gun = turret.guns.at(-1)!;
|
|
||||||
const shell = gun.shells[0];
|
|
||||||
const characteristics = tankCharacteristics(
|
const characteristics = tankCharacteristics(
|
||||||
{
|
{
|
||||||
tank,
|
tank,
|
||||||
|
|||||||
Reference in new issue
Block a user