From f63c1d50aecd8a4b68f9e44b21548e5a6f36b9a4 Mon Sep 17 00:00:00 2001
From: Kalle <38327916+Sendouc@users.noreply.github.com>
Date: Sat, 11 Nov 2023 15:00:24 +0200
Subject: [PATCH] Build Analyzer: fix Dread Wringer damage
---
.../build-analyzer/analyzer-constants.ts | 4 +++
app/features/build-analyzer/analyzer-types.ts | 3 ++
app/features/build-analyzer/core/stats.ts | 2 ++
.../build-analyzer/core/weapon-params.json | 2 ++
.../build-analyzer/routes/analyzer.tsx | 29 +++++++++++++++++--
.../calculator-hooks.ts | 2 ++
.../core/objectDamage.ts | 28 ++++++++++++++++--
.../routes/object-damage-calculator.tsx | 4 +--
scripts/create-analyzer-json.ts | 16 ++++++++++
9 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/app/features/build-analyzer/analyzer-constants.ts b/app/features/build-analyzer/analyzer-constants.ts
index 3ddddfa2f..58de91835 100644
--- a/app/features/build-analyzer/analyzer-constants.ts
+++ b/app/features/build-analyzer/analyzer-constants.ts
@@ -12,6 +12,8 @@ export const DAMAGE_TYPE = [
"DIRECT",
"DIRECT_MIN",
"DIRECT_MAX",
+ "DIRECT_SECONDARY_MIN",
+ "DIRECT_SECONDARY_MAX",
"FULL_CHARGE",
"MAX_CHARGE",
"TAP_SHOT",
@@ -60,6 +62,8 @@ export const damageTypeToWeaponType: Record<
DIRECT: "MAIN",
DIRECT_MIN: "MAIN",
DIRECT_MAX: "MAIN",
+ DIRECT_SECONDARY_MAX: "MAIN",
+ DIRECT_SECONDARY_MIN: "MAIN",
FULL_CHARGE: "MAIN",
MAX_CHARGE: "MAIN",
TAP_SHOT: "MAIN",
diff --git a/app/features/build-analyzer/analyzer-types.ts b/app/features/build-analyzer/analyzer-types.ts
index 864bd8e09..81f302b86 100644
--- a/app/features/build-analyzer/analyzer-types.ts
+++ b/app/features/build-analyzer/analyzer-types.ts
@@ -39,6 +39,9 @@ export interface MainWeaponParams {
DamageParam_ValueDirect?: number;
DamageParam_ValueDirectMax?: number;
DamageParam_ValueDirectMin?: number;
+ // Dread Wringer
+ DamageParam_Secondary_ValueDirectMax?: number;
+ DamageParam_Secondary_ValueDirectMin?: number;
DamageParam_SplatanaVerticalDirect?: number;
DamageParam_SplatanaVertical?: number;
DamageParam_SplatanaHorizontalDirect?: number;
diff --git a/app/features/build-analyzer/core/stats.ts b/app/features/build-analyzer/core/stats.ts
index c1e0a6543..ce958e2a6 100644
--- a/app/features/build-analyzer/core/stats.ts
+++ b/app/features/build-analyzer/core/stats.ts
@@ -414,6 +414,8 @@ const damageTypeToParamsKey: Record<
DIRECT: "DamageParam_ValueDirect",
DIRECT_MIN: "DamageParam_ValueDirectMin",
DIRECT_MAX: "DamageParam_ValueDirectMax",
+ DIRECT_SECONDARY_MIN: "DamageParam_Secondary_ValueDirectMin",
+ DIRECT_SECONDARY_MAX: "DamageParam_Secondary_ValueDirectMax",
DISTANCE: ["BlastParam_DistanceDamage", "DistanceDamage_BlastParamArray"],
SPLASH: ["BlastParam_SplashDamage", "DistanceDamage_SplashBlastParam"],
SPLASH_MIN: "SwingUnitGroupParam_DamageParam_DamageMinValue",
diff --git a/app/features/build-analyzer/core/weapon-params.json b/app/features/build-analyzer/core/weapon-params.json
index 981b8c3bf..6a65681c2 100644
--- a/app/features/build-analyzer/core/weapon-params.json
+++ b/app/features/build-analyzer/core/weapon-params.json
@@ -1063,6 +1063,8 @@
"MoveSpeed": 0.04,
"DamageParam_ValueDirectMax": 480,
"DamageParam_ValueDirectMin": 350,
+ "DamageParam_Secondary_ValueDirectMax": 420,
+ "DamageParam_Secondary_ValueDirectMin": 350,
"InkRecoverStop": 50,
"InkConsumeSlosher": 0.1
},
diff --git a/app/features/build-analyzer/routes/analyzer.tsx b/app/features/build-analyzer/routes/analyzer.tsx
index bea67c9de..1ee028959 100644
--- a/app/features/build-analyzer/routes/analyzer.tsx
+++ b/app/features/build-analyzer/routes/analyzer.tsx
@@ -54,6 +54,7 @@ import type {
AbilityPoints,
AnalyzedBuild,
Damage,
+ DamageType,
SpecialEffectType,
Stat,
SubWeaponDamage,
@@ -75,6 +76,7 @@ import {
isStackableAbility,
} from "../core/utils";
import { PerInkTankGrid } from "../components/PerInkTankGrid";
+import invariant from "tiny-invariant";
export const CURRENT_PATCH = "5.1";
@@ -1497,6 +1499,27 @@ function DamageTable({
return true;
};
+ const multiShotValues = (
+ damage: AnalyzedBuild["stats"]["damages"][number],
+ ) => {
+ // initially only Dread Wringer
+ const isAsymmetric = values.some(
+ (value) => value.type === "DIRECT_SECONDARY_MIN",
+ );
+
+ if (!isAsymmetric) return new Array(multiShots).fill(damage.value);
+
+ const otherKey: DamageType =
+ damage.type === "DIRECT_MAX"
+ ? "DIRECT_SECONDARY_MAX"
+ : "DIRECT_SECONDARY_MIN";
+
+ const secondaryDamage = values.find((value) => value.type === otherKey);
+ invariant(secondaryDamage, "secondary damage not found");
+
+ return [damage.value, secondaryDamage.value];
+ };
+
return (
<>
@@ -1519,9 +1542,11 @@ function DamageTable({
{values.map((val, i) => {
+ if (val.type.includes("SECONDARY")) return null;
+
const damage = (val: AnalyzedBuild["stats"]["damages"][number]) =>
multiShots && damageTypeToWeaponType[val.type] === "MAIN"
- ? new Array(multiShots).fill(val.value).join(" + ")
+ ? multiShotValues(val).join(" + ")
: val.value;
const typeRowName = damageIsSubWeaponDamage(val)
@@ -1543,7 +1568,7 @@ function DamageTable({
height={12}
/>
) : null}{" "}
- {t(typeRowName)}{" "}
+ {t(typeRowName as any)}{" "}
{damageIsSubWeaponDamage(val) && val.type === "SPLASH" ? (
<>({t("analyzer:damage.SPLASH")})>
) : null}
diff --git a/app/features/object-damage-calculator/calculator-hooks.ts b/app/features/object-damage-calculator/calculator-hooks.ts
index 6ca630084..13bdd3726 100644
--- a/app/features/object-damage-calculator/calculator-hooks.ts
+++ b/app/features/object-damage-calculator/calculator-hooks.ts
@@ -103,6 +103,8 @@ export const damageTypePriorityList = [
"TURRET_MAX",
"TURRET_MIN",
"DIRECT_MAX",
+ "DIRECT_SECONDARY_MAX",
+ "DIRECT_SECONDARY_MIN",
"DIRECT",
"DIRECT_MIN",
"FULL_CHARGE",
diff --git a/app/features/object-damage-calculator/core/objectDamage.ts b/app/features/object-damage-calculator/core/objectDamage.ts
index ca45ba6c4..0c9a24e59 100644
--- a/app/features/object-damage-calculator/core/objectDamage.ts
+++ b/app/features/object-damage-calculator/core/objectDamage.ts
@@ -20,6 +20,7 @@ import {
} from "../calculator-constants";
import type { CombineWith, DamageReceiver } from "../calculator-types";
import { removeDuplicates } from "~/utils/arrays";
+import type { Damage } from "~/features/build-analyzer/analyzer-types";
export function damageTypeToMultipliers({
type,
@@ -127,7 +128,9 @@ export function resolveAllUniqueDamageTypes({
? analyzed.stats.specialWeaponDamages.map((d) => d.type)
: analyzed.stats.damages.map((d) => d.type);
- return removeDuplicates(damageTypes);
+ return removeDuplicates(damageTypes).filter(
+ (dmg) => !dmg.includes("SECONDARY"),
+ );
}
function resolveFilteredDamages({
@@ -149,6 +152,27 @@ function resolveFilteredDamages({
);
}
+ const damageWithMultishots = (dmg: Damage, multiShots: number) => {
+ // initially only Dread Wringer
+ const isAsymmetric = analyzed.stats.damages.some(
+ (dmg) => dmg.type === "DIRECT_SECONDARY_MIN",
+ );
+
+ if (!isAsymmetric) return dmg.value * multiShots;
+
+ const otherKey: DamageType =
+ dmg.type === "DIRECT_MAX"
+ ? "DIRECT_SECONDARY_MAX"
+ : "DIRECT_SECONDARY_MIN";
+
+ const secondaryDamage = analyzed.stats.damages.find(
+ (dmg) => dmg.type === otherKey,
+ );
+ invariant(secondaryDamage, "secondary damage not found");
+
+ return dmg.value + secondaryDamage.value;
+ };
+
const damages =
anyWeapon.type === "SPECIAL"
? analyzed.stats.specialWeaponDamages
@@ -161,7 +185,7 @@ function resolveFilteredDamages({
return {
...damage,
- value: damage.value * damage.multiShots,
+ value: damageWithMultishots(damage, damage.multiShots),
};
});
}
diff --git a/app/features/object-damage-calculator/routes/object-damage-calculator.tsx b/app/features/object-damage-calculator/routes/object-damage-calculator.tsx
index 589c8632b..d3a807221 100644
--- a/app/features/object-damage-calculator/routes/object-damage-calculator.tsx
+++ b/app/features/object-damage-calculator/routes/object-damage-calculator.tsx
@@ -185,7 +185,7 @@ function DamageTypesSelect({
{t(
damageTypeTranslationString({
damageType,
- }),
+ }) as any,
)}
);
@@ -307,7 +307,7 @@ function DamageReceiversGrid({
{t(
damageTypeTranslationString({
damageType: damage.type,
- }),
+ }) as any,
)}
{damage.objectShredder && }
diff --git a/scripts/create-analyzer-json.ts b/scripts/create-analyzer-json.ts
index a2910b7ed..38c6b6d93 100644
--- a/scripts/create-analyzer-json.ts
+++ b/scripts/create-analyzer-json.ts
@@ -191,6 +191,21 @@ function parametersToMainWeaponResult(
};
};
+ const slosherDirectDamageSecondary = () => {
+ const isDreadWringer = weapon.Id === 3050 || weapon.Id === 3051;
+ if (!isDreadWringer) return;
+
+ const DamageParam_Secondary_ValueDirectMax =
+ params["UnitGroupParam"]?.["Unit"]?.[1]?.["DamageParam"]?.["ValueMax"];
+ const DamageParam_Secondary_ValueDirectMin =
+ params["UnitGroupParam"]?.["Unit"]?.[1]?.["DamageParam"]?.["ValueMin"];
+
+ return {
+ DamageParam_Secondary_ValueDirectMax,
+ DamageParam_Secondary_ValueDirectMin,
+ };
+ };
+
const KeepChargeFullFrame =
params["WeaponKeepChargeParam"]?.["KeepChargeFullFrame"] ??
params["spl__WeaponStringerParam"]?.["ChargeKeepParam"]?.[
@@ -258,6 +273,7 @@ function parametersToMainWeaponResult(
: undefined,
DamageParam_ValueDirect,
...slosherDirectDamage(),
+ ...slosherDirectDamageSecondary(),
// Glooga turret mode damage
DamageLapOverParam_ValueMax: params["DamageLapOverParam"]?.["ValueMax"],
DamageLapOverParam_ValueMin: params["DamageLapOverParam"]?.["ValueMin"],