Compare commits

...
2 Commits
Author SHA1 Message Date
tresabhi 3c01056f4e implement rest 2026-09-16 09:56:13 -05:00
tresabhi 66f9c9d106 start of data driven provisions 2026-09-16 09:42:20 -05:00
6 changed files with 241 additions and 147 deletions

No files matched your search

+4 -1
View File
@@ -254,5 +254,8 @@
"youtubers",
"zoomable"
],
"typescript.tsdk": "node_modules\\typescript\\lib"
"typescript.tsdk": "node_modules\\typescript\\lib",
"cSpell.enabledFileTypes": {
"proto": true
}
}
+1
View File
@@ -1,6 +1,7 @@
{
"words": [
"gamemodes",
"Passability",
"Recoverkit",
"Repairkit",
"Tankopedia"
@@ -12,13 +12,13 @@ export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
const provisionDefinitions = ProvisionDefinitions.create();
Object.entries(this.provisionsCommon).forEach(([, provision]) => {
const entry: Provision = {
const entry = Provision.create({
id: provision.id,
exclude: [],
include: [],
game_mode_exclusive: "gameModeFilter" in provision,
name: this.getString(provision.userString),
};
});
provisionDefinitions.provisions[provision.id] = entry;
const includeRaw = provision.vehicleFilter?.include.vehicle;
@@ -106,9 +106,222 @@ export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
}
}
if (provision.script.bonusValues?.crewLevelIncrease !== undefined) {
provisionDefinitions.provisions[provision.id].crew =
provision.script.bonusValues?.crewLevelIncrease;
function applyCanonicalBonuses(map: Record<string, string>) {
for (const key in map) {
entry.bonuses[key] = provision.script.bonusValues![map[key]];
}
}
function applyRootBonuses(map: Record<string, string>) {
for (const key in map) {
entry.bonuses[key] = provision.script[map[key]];
}
}
function applyAttributeBonuses(map: Record<string, string>) {
for (const key in map) {
if (!(map[key] in provision.script.attributes!)) continue;
entry.bonuses[key] = provision.script.attributes![map[key]];
}
}
switch (provision.script["#text"]) {
case "Stimulator":
applyCanonicalBonuses({ crew_level_increase: "crewLevelIncrease" });
break;
case "AntiHighExplosive":
applyCanonicalBonuses({ anti_high_explosive_factor: "factor" });
break;
case "Fuel":
applyCanonicalBonuses({
engine_power_increase: "enginePowerIncrease",
turret_rotation_speed_increase: "turretRotationSpeedIncrease",
});
break;
case "SafetySet":
applyCanonicalBonuses({
crew_chance_to_hit_factor: "crewChanceToHitFactor",
repair_speed_increase: "repairSpeedIncrease",
fire_protection_increase: "fireProtectionIncrease",
});
break;
case "SmallHPStock":
applyRootBonuses({ hp_stock_percent: "hpStockPercent" });
break;
case "GearOil":
applyCanonicalBonuses({
forward_speed_limit_bias: "fwdSpeedLimitBias",
backward_speed_limit_bias: "bkwdSpeedLimitBias",
engine_power_increase: "enginePowerIncrease",
});
break;
case "GunPowder":
applyCanonicalBonuses({
projectile_speed_factor: "projectileSpeedFactor",
});
break;
case "AttributesModifier":
applyAttributeBonuses({
firm_ground_passability_increase: "firmGroundPassabilityIncrease",
medium_ground_passability_increase:
"mediumGroundPassabilityIncrease",
repair_speed_factor: "repairSpeedFactor",
common_damage_factor: "commonDamageFactor",
gun_reload_factor: "gunReloadFactor",
pump_gun_reload_factor: "pumpGunReloadFactor",
gun_aiming_factor: "gunAimingFactor",
engine_power_factor: "enginePowerFactor",
speed_limits_factor: "speedLimitsFactor",
chassis_health_factor: "chassisHealthFactor",
});
break;
case "LifestealHeal":
applyCanonicalBonuses({
life_steal_factor: "lifestealFactor",
life_steal_random_factor: "lifestealRandomFactor",
kill_heal_factor: "killHealFactor",
heal_factor: "healFactor",
heal_random_factor: "healRandomFactor",
});
break;
case "RammingDamage":
applyCanonicalBonuses({
ramming_damage_factor: "rammingDamageFactor",
dealing_ramming_damage_factor: "dealingRammingDamageFactor",
});
break;
case "AllyBuff":
applyCanonicalBonuses({
gun_reloading_bonus: "gunReloadingBonus",
gun_aiming_time_bonus: "gunAimingTimeBonus",
vision_radius_bonus: "visionRadiusBonus",
});
applyRootBonuses({
range: "range",
max_bonus_sources: "maxBonusSources",
});
break;
case "Stealth":
applyRootBonuses({
sixth_sense_delay: "sixthSenseDelay",
stop_observing_delay_factor: "stopObservingDelayFactor",
});
break;
case "Revenge":
applyRootBonuses({
revenge_damage_percentage: "revengeDamagePercentage",
effect_duration: "effectDuration",
});
break;
case "ComeBackKit":
applyRootBonuses({
time_for_come_back: "timeForComeBack",
simple_mode: "simpleMode",
});
break;
case "EngineAndSpeedBoost":
applyCanonicalBonuses({
engine_power_ability_factor: "enginePowerAbilityFactor",
speed_limit_ability_bonus: "speedLimitAbilityBonus",
});
break;
case "EnemyReloadTime":
break;
case "Duplet":
applyCanonicalBonuses({
shot_dispersion_angle_factor: "shotDispersionAngleFactor",
aiming_time_factor: "aimingTimeFactor",
time_between_shots: "timeBetweenShots",
});
break;
case "Fortune":
applyCanonicalBonuses({
increased_damage_chance: "increasedDamageChance",
increase_damage_factor: "increaseDamageFactor",
});
break;
case "VampiricCurse":
applyRootBonuses({
curse_strength: "curseStrength",
curse_reduction: "curseReduction",
curse_heal: "curseHeal",
});
break;
case "VampiricDeath":
applyRootBonuses({
explode_damage_percent: "explodeDamagePercent",
range: "range",
});
break;
case "PermanentDamageShield":
applyRootBonuses({
damage_reduction_percent: "damageReductionPercent",
});
break;
case "EngineAndSpeedBoost":
applyCanonicalBonuses({
engine_power_ability_factor: "enginePowerAbilityFactor",
speed_limit_ability_bonus: "speedLimitAbilityBonus",
});
break;
case "BigBoss":
applyCanonicalBonuses({
gun_reload_factor: "gunReloadFactor",
common_damage_factor: "commonDamageFactor",
engine_power_factor: "enginePowerFactor",
speed_limits_factor: "speedLimitsFactor",
max_health_percent_bonus: "maxHealthPercentBonus",
max_statics_damage_percent: "maxStaticsDamagePercent",
});
// These are nested structures and need their own handling
// rather than a simple key -> key mapping.
break;
case "VampiricBoost":
// Nested `respawns` structure; needs dedicated handling.
break;
case "ZombieMark":
applyAttributeBonuses({
dealing_ramming_damage_factor: "dealingRammingDamageFactor",
ramming_damage_factor: "rammingDamageFactor",
engine_power_factor: "enginePowerFactor",
speed_limits_factor: "speedLimitsFactor",
common_damage_factor: "commonDamageFactor",
});
// Nested respawnBoost structure.
break;
default:
console.warn(`Unhandled script type ${provision.script["#text"]}`);
console.dir(provision.script, { depth: null, colors: true });
}
});
@@ -1,140 +1,10 @@
export type ProvisionConsumableScript =
| {
"#text": "Extinguisher";
cooldown: number;
automatic: boolean;
}
| {
"#text": "Repairkit";
cooldown: number;
}
| {
"#text": "Afterburning";
cooldown: number;
duration: number;
bonusValues: {
enginePowerIncrease: number;
};
}
| {
"#text": "Berserk";
cooldown: number;
duration: number;
bonusValues: {
gunReloadSpeedIncrease: number;
};
}
| {
"#text": "Recoverkit";
cooldown: number;
}
| {
"#text": "ImprovedAfterburning";
cooldown: number;
duration: number;
enginePowerIncrease: number;
rotationSpeedFactor: number;
fwdSpeedLimitBias: number;
bkwdSpeedLimitBias: number;
}
| {
"#text": "FireControlSystem";
cooldown: number;
duration: number;
shotDispersionAngleFactor: number;
aimingTimeFactor: number;
}
| {
"#text": "NewAutoloader";
cooldown: number;
duration: number;
clipReloadTimeFactor: number;
gunReloadTimeFactor: number;
}
| {
"#text": "ShieldKit";
cooldown: number;
duration: number;
shieldCoef: number;
}
| {
"#text": "TungstenTip";
cooldown: number;
duration: number;
minDamageFactor: number;
maxDamageFactor: number;
shotEffect: "dangerousTracer";
}
| {
"#text": "ArmorMover";
cooldown: number;
duration: number;
deactivateStates: number;
activateStates: number;
bonusValues: {
damageReductionPercent: number;
};
}
| {
"#text": "ImprovedAfterburning";
cooldown: number;
duration: number;
enginePowerIncrease: number;
rotationSpeedFactor: number;
fwdSpeedLimitBias: number;
bkwdSpeedLimitBias: number;
}
| {
"#text": "Stimulator";
bonusValues: {
crewLevelIncrease: number;
};
}
| {
"#text": "AntiHighExplosive";
bonusValues: {
factor: number;
};
}
| {
"#text": "Fuel";
bonusValues: {
enginePowerIncrease: number;
turretRotationSpeedIncrease: number;
};
}
| {
"#text": "SafetySet";
bonusValues: {
crewChanceToHitFactor: number;
repairSpeedIncrease: number;
fireProtectionIncrease: number;
explosivesHealthIncrease: number;
};
}
| {
"#text": "SmallHPStock";
hpStockPercent: number;
}
| {
"#text": "GearOil";
bonusValues: {
fwdSpeedLimitBias: number;
bkwdSpeedLimitBias: number;
enginePowerIncrease: number;
};
}
| {
"#text": "GunPowder";
bonusValues: {
projectileSpeedFactor: number;
};
}
| {
"#text": "AttributesModifier";
attributes: {
firmGroundPassabilityIncrease: number;
mediumGroundPassabilityIncrease: number;
repairSpeedFactor: number;
};
};
export type ProvisionConsumableScript = {
"#text": string;
cooldown?: number;
automatic?: boolean;
bonusValues?: Record<string, number>;
attributes?: Record<string, number>;
shotEffect?: string;
} & Record<string, number>;
@@ -10,10 +10,14 @@ message ProvisionDefinitions {
}
message Provision {
reserved 3; // crew
required uint32 id = 1;
required I18nString name = 2;
optional float crew = 3;
required bool game_mode_exclusive = 5;
repeated ConsumableTankFilter include = 6;
repeated ConsumableTankFilter exclude = 7;
map<string, float> bonuses = 8;
map<string, string> effects = 9;
}
@@ -5,6 +5,9 @@ export { getStaticPaths } from "../_index";
export async function GET() {
const definitions = await api.provisions();
return Response.json(definitions);
const bytes = ProvisionDefinitions.encode(definitions).finish();
return new Response(bytes);