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"],