diff --git a/app/modules/analyzer/stats.ts b/app/modules/analyzer/stats.ts index 450b693bd..f3a29e2b2 100644 --- a/app/modules/analyzer/stats.ts +++ b/app/modules/analyzer/stats.ts @@ -87,6 +87,10 @@ export function buildStats({ subDefInkMineMarkedTimeInSeconds: subDefInkMineMarkedTimeInSeconds(input), subDefAngleShooterMarkedTimeInSeconds: subDefAngleShooterMarkedTimeInSeconds(input), + subDefToxicMistMovementReduction: subDefToxicMistMovementReduction(input), + subDefAngleShooterDamage: subDefAngleShooterDamage(input), + subDefSplashWallDamagePercentage: subDefSplashWallDamagePercentage(input), + subDefSprinklerDamagePercentage: subDefSprinklerDamagePercentage(input), ...subStats(input), }, }; @@ -276,6 +280,7 @@ const damageTypeToParamsKey: Record< MAX_CHARGE: "DamageParam_ValueMaxCharge", TAP_SHOT: "DamageParam_ValueMinCharge", BOMB_NORMAL: "DistanceDamage", + BOMB_DIRECT: "DirectDamage", }; function damages(args: StatFunctionInput): AnalyzedBuild["stats"]["damages"] { @@ -729,3 +734,89 @@ function subDefAngleShooterMarkedTimeInSeconds( value: framesToSeconds(markingTimeEffect * effect), }; } + +function subDefToxicMistMovementReduction( + args: StatFunctionInput +): AnalyzedBuild["stats"]["subDefToxicMistMovementReduction"] { + const SUB_DEF_TOXIC_MIST_MOVEMENT_REDUCTION_KEY = "SRU"; + const { baseEffect, effect } = abilityPointsToEffects({ + abilityPoints: apFromMap({ + abilityPoints: args.abilityPoints, + ability: SUB_DEF_TOXIC_MIST_MOVEMENT_REDUCTION_KEY, + }), + key: "MoveDownRt_PoisonMist", + weapon: args.mainWeaponParams, + }); + + return { + baseValue: roundToTwoDecimalPlaces(baseEffect * 100), + value: roundToTwoDecimalPlaces(effect * 100), + modifiedBy: SUB_DEF_TOXIC_MIST_MOVEMENT_REDUCTION_KEY, + }; +} + +function subDefAngleShooterDamage( + args: StatFunctionInput +): AnalyzedBuild["stats"]["subDefAngleShooterDamage"] { + const SUB_DEF_ANGLE_SHOOTER_DAMAGE_KEY = "SRU"; + const { baseEffect, effect } = abilityPointsToEffects({ + abilityPoints: apFromMap({ + abilityPoints: args.abilityPoints, + ability: SUB_DEF_ANGLE_SHOOTER_DAMAGE_KEY, + }), + key: "DamageRt_LineMarker", + weapon: args.mainWeaponParams, + }); + + const angleShooterDirectDamage = + weaponParams().subWeapons[ANGLE_SHOOTER_ID].DirectDamage; + invariant(angleShooterDirectDamage); + + return { + baseValue: roundToTwoDecimalPlaces( + (angleShooterDirectDamage * baseEffect) / 10 + ), + value: roundToTwoDecimalPlaces((angleShooterDirectDamage * effect) / 10), + modifiedBy: SUB_DEF_ANGLE_SHOOTER_DAMAGE_KEY, + }; +} + +function subDefSplashWallDamagePercentage( + args: StatFunctionInput +): AnalyzedBuild["stats"]["subDefSplashWallDamagePercentage"] { + const SUB_DEF_SPLASH_WALL_DAMAGE_PERCENTAGE_KEY = "SRU"; + const { baseEffect, effect } = abilityPointsToEffects({ + abilityPoints: apFromMap({ + abilityPoints: args.abilityPoints, + ability: SUB_DEF_SPLASH_WALL_DAMAGE_PERCENTAGE_KEY, + }), + key: "DamageRt_Shield", + weapon: args.mainWeaponParams, + }); + + return { + baseValue: roundToTwoDecimalPlaces(baseEffect * 100), + value: roundToTwoDecimalPlaces(effect * 100), + modifiedBy: SUB_DEF_SPLASH_WALL_DAMAGE_PERCENTAGE_KEY, + }; +} + +function subDefSprinklerDamagePercentage( + args: StatFunctionInput +): AnalyzedBuild["stats"]["subDefSprinklerDamagePercentage"] { + const SUB_DEF_SPRINKLER_DAMAGE_PERCENTAGE_KEY = "SRU"; + const { baseEffect, effect } = abilityPointsToEffects({ + abilityPoints: apFromMap({ + abilityPoints: args.abilityPoints, + ability: SUB_DEF_SPRINKLER_DAMAGE_PERCENTAGE_KEY, + }), + key: "DamageRt_Sprinkler", + weapon: args.mainWeaponParams, + }); + + return { + baseValue: roundToTwoDecimalPlaces(baseEffect * 100), + value: roundToTwoDecimalPlaces(effect * 100), + modifiedBy: SUB_DEF_SPRINKLER_DAMAGE_PERCENTAGE_KEY, + }; +} diff --git a/app/modules/analyzer/types.ts b/app/modules/analyzer/types.ts index a92d0950e..178fafee3 100644 --- a/app/modules/analyzer/types.ts +++ b/app/modules/analyzer/types.ts @@ -145,6 +145,7 @@ export const DAMAGE_TYPE = [ "TAP_SHOT", "DISTANCE", "BOMB_NORMAL", + "BOMB_DIRECT", ] as const; export type DamageType = typeof DAMAGE_TYPE[number]; @@ -189,6 +190,10 @@ export interface AnalyzedBuild { subDefPointSensorMarkedTimeInSeconds: Stat; subDefInkMineMarkedTimeInSeconds: Stat; subDefAngleShooterMarkedTimeInSeconds: Stat; + subDefToxicMistMovementReduction: Stat; + subDefAngleShooterDamage: Stat; + subDefSplashWallDamagePercentage: Stat; + subDefSprinklerDamagePercentage: Stat; // subDefBombDamageLight: Stat; // subDefBombDamageHeavy: Stat; // subDefAngleShooterDamage: Stat; diff --git a/app/routes/analyzer.tsx b/app/routes/analyzer.tsx index 54f5366ff..00d7041c9 100644 --- a/app/routes/analyzer.tsx +++ b/app/routes/analyzer.tsx @@ -20,6 +20,11 @@ import type { SpecialEffectType, } from "~/modules/analyzer/types"; import type { BuildAbilitiesTupleWithUnknown } from "~/modules/in-game-lists"; +import { + SPLASH_WALL_ID, + SPRINKLER_ID, + TOXIC_MIST_ID, +} from "~/modules/in-game-lists"; import { ANGLE_SHOOTER_ID } from "~/modules/in-game-lists"; import { INK_MINE_ID, POINT_SENSOR_ID } from "~/modules/in-game-lists"; import { @@ -210,6 +215,34 @@ export default function BuildAnalyzerPage() { /> + + + +