Compare commits

...
3 Commits
Author SHA1 Message Date
TrèsAbhi d01b7cf707 feat: shells 2025-12-14 22:00:45 -06:00
TrèsAbhi 8921f84c38 feat: verbose 2025-12-14 21:41:26 -06:00
TrèsAbhi 6830df01fa penetration_groups_upgrades 2025-12-14 21:38:18 -06:00
2 changed files with 102 additions and 16 deletions

No files matched your search

@@ -1,4 +1,9 @@
import { StandardSinglePrice } from "@protos/blitz_static_standard_single_price";
import { PenetrationGroup } from "@protos/blitz_static_tank_penetration_group";
import {
PenetrationGroupUpgrade,
ShellUpgrade,
ShellUpgrageSingleChange,
StageParameters,
TankAttributeChange_AttributeName,
TankAttributeChange_Modifier,
@@ -6,54 +11,134 @@ import {
import { times } from "lodash-es";
function patch(change: StageParameters, base: StageParameters) {
if (change.stage_number !== base.stage_number + 1) {
if (change.stage_number !== ++base.stage_number) {
throw new Error("Change stage number must be 1 greater than base");
}
for (const attribute of change.attributes) {
const oldValue = base.attributes[attribute.attribute_name].value;
for (const changedAttribute of change.attributes) {
let newValue: number;
switch (attribute.modifier) {
switch (changedAttribute.modifier) {
case TankAttributeChange_Modifier.MODIFIER_OVERRIDE:
newValue = attribute.value;
newValue = changedAttribute.value;
break;
case TankAttributeChange_Modifier.MODIFIER_MULTIPLY:
case TankAttributeChange_Modifier.MODIFIER_ADD: {
if (!(attribute.attribute_name in base)) {
case TankAttributeChange_Modifier.MODIFIER_ADD:
if (!(changedAttribute.attribute_name in base)) {
throw new Error(
`Missing attribute ${
TankAttributeChange_AttributeName[attribute.attribute_name]
TankAttributeChange_AttributeName[changedAttribute.attribute_name]
} to modify`
);
}
}
const oldValue =
base.attributes[changedAttribute.attribute_name]!.value;
case TankAttributeChange_Modifier.MODIFIER_MULTIPLY: {
newValue = oldValue * attribute.value;
newValue = oldValue! * changedAttribute.value;
break;
}
case TankAttributeChange_Modifier.MODIFIER_ADD: {
newValue = oldValue + attribute.value;
newValue = oldValue! + changedAttribute.value;
break;
}
default:
throw new Error(
`Unhandled modified ${
TankAttributeChange_Modifier[attribute.modifier]
TankAttributeChange_Modifier[changedAttribute.modifier]
}`
);
}
base.attributes[attribute.attribute_name] = {
base.attributes[changedAttribute.attribute_name] = {
modifier: TankAttributeChange_Modifier.MODIFIER_OVERRIDE,
attribute_name: attribute.attribute_name,
attribute_name: changedAttribute.attribute_name,
value: newValue,
};
}
for (const changedPenetrationGroupUpgrades of change.penetration_groups_upgrades) {
if (changedPenetrationGroupUpgrades.primary_armor.length > 0) {
throw new Error("Primary armor is not empty; implement this");
}
let basePenetrationGroupUpgrades = base.penetration_groups_upgrades.find(
(group) => group.tank_part === changedPenetrationGroupUpgrades.tank_part
);
if (!basePenetrationGroupUpgrades) {
basePenetrationGroupUpgrades = PenetrationGroupUpgrade.create({
tank_part: changedPenetrationGroupUpgrades.tank_part,
});
base.penetration_groups_upgrades.push(basePenetrationGroupUpgrades);
}
for (const changedPenetrationGroup of changedPenetrationGroupUpgrades.penetration_groups) {
const basePenetrationGroup =
basePenetrationGroupUpgrades.penetration_groups.find(
(baseGroup) =>
baseGroup.group_name === changedPenetrationGroup.group_name
);
if (basePenetrationGroup) {
if (
basePenetrationGroup.common_data !==
changedPenetrationGroup.common_data
) {
throw new Error("Common data is not the same");
}
basePenetrationGroup.armor = changedPenetrationGroup.armor;
} else {
basePenetrationGroupUpgrades.penetration_groups.push(
PenetrationGroup.create(changedPenetrationGroup)
);
}
}
}
if (change.modules_upgrades.length > 0) {
throw new Error("Modules upgrades not implemented");
}
for (const changedShellUpgrades of change.shells_upgrades) {
let baseShellUpgrades = base.shells_upgrades.find(
(baseShell) => baseShell.shell_id === changedShellUpgrades.shell_id
);
if (!baseShellUpgrades) {
baseShellUpgrades = ShellUpgrade.create({
shell_id: changedShellUpgrades.shell_id,
});
}
baseShellUpgrades.shell_type = changedShellUpgrades.shell_type;
for (const changedShellUpgrade of changedShellUpgrades.changes) {
const baseShellUpgrade = baseShellUpgrades.changes.find(
(baseShellUpgrade) =>
baseShellUpgrade.attribute_name === changedShellUpgrade.attribute_name
);
if (baseShellUpgrade) {
baseShellUpgrade.value = changedShellUpgrade.value;
} else {
baseShellUpgrades.changes.push(
ShellUpgrageSingleChange.create(changedShellUpgrade)
);
}
}
baseShellUpgrades.silver_price =
changedShellUpgrades.silver_price === undefined
? undefined
: StandardSinglePrice.create(changedShellUpgrades.silver_price);
}
}
export function aggregateStages(
@@ -68,7 +153,8 @@ export function aggregateStages(
/**
* Bug in Reforged: base stats are stage 1, so is the first upgrade. Manually
* setting it to stage 0 below and if the bug's been fixed, throw an error
* in dev mode to allow clean up in the future.
* in dev mode to allow clean up in the future. Also, update the initial
* stage number to -1.
*/
if (attributes.stage_number === 0 && import.meta.env.DEV) {
@@ -18,7 +18,7 @@ function Content({ id }: { id: string }) {
const stage = Tankopedia.use((state) => state.stage);
const attributes = useMemo(
const aggregatedStages = useMemo(
() => aggregateStages(tank.base_stats!, tank.upgrade_stages, stage),
[stage]
);