From f65ab5c4f6aaa288a774789cb26e5355128d57dd Mon Sep 17 00:00:00 2001 From: geeil-han Date: Tue, 12 Nov 2024 02:19:43 +0100 Subject: [PATCH] cleaned up code making it more general --- src/data/move.ts | 48 +++++++++++++++----------- src/test/moves/freeze_dry.test.ts | 57 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 19 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 0b01058bfc0..03fb0b6e8b9 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4934,31 +4934,41 @@ export class NeutralDamageAgainstFlyingTypeMultiplierAttr extends VariableMoveTy } } +/** + * This class forces Freeze-Dry to be super effective against Water Type. + * It considers if target is Mono or Dual Type and calculates the new Multiplier accordingly + */ export class FreezeDryAttr extends VariableMoveTypeMultiplierAttr { + /** + * If the target is Mono Type (Water only) then a 2x Multiplier is always forced. + * If target is Dual Type (containing Water) then only a 2x Multiplier is forced for the Water Type + * + * Additionally Freeze-Dry's effectiveness against water is always forced during {@linkcode InverseBattleChallenge}. + * The multiplier is recalculated for the non-Water Type in case of Dual Type targets containing Water Type. + * + * @param user The {@linkcode Pokemon} applying the move + * @param target The {@linkcode Pokemon} targeted by the move + * @param move The move used by the user + * @param args `[0]` a {@linkcode Utils.NumberHolder | NumberHolder} containing a type effectiveness multiplier + * @returns `true` if super effectiveness on water type is forced; `false` otherwise + */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const multiplier = args[0] as Utils.NumberHolder; - if (target.isOfType(Type.WATER)) { - const effectivenessAgainstWater = new Utils.NumberHolder(getTypeDamageMultiplier(move.type, Type.WATER)); - applyChallenges(user.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, effectivenessAgainstWater); - if (effectivenessAgainstWater.value !== 0) { - /** - * During Normalize the given multiplier value against water Pkm is 1x but should be 2x. - * - * For more information about special interactions visit [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Freeze-Dry_(move)) - */ - if (user.hasAbility(Abilities.NORMALIZE)) { - multiplier.value *= 2; - return true; - } + if (target.isOfType(Type.WATER) && multiplier.value !== 0) { + const multipleTypes = new Utils.BooleanHolder(target.getTypes().length > 1); - /** - * If move is of type electric it already has super effectiveness against water types and multiplier does not need to recalculate its value. - */ - if (user.getMoveType(move) !== Type.ELECTRIC) { - multiplier.value *= 2 / effectivenessAgainstWater.value; - } + if (multipleTypes) { + const effectivenessAgainstTarget = new Utils.NumberHolder(getTypeDamageMultiplier(move.type, target.getTypes().filter(types => types !== Type.WATER)[0])); + + applyChallenges(user.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, effectivenessAgainstTarget); + + multiplier.value = effectivenessAgainstTarget.value; + multiplier.value *= 2; return true; } + + multiplier.value = 2; + return true; } return false; diff --git a/src/test/moves/freeze_dry.test.ts b/src/test/moves/freeze_dry.test.ts index 3a3760dd3f4..00400a71e16 100644 --- a/src/test/moves/freeze_dry.test.ts +++ b/src/test/moves/freeze_dry.test.ts @@ -192,4 +192,61 @@ describe("Moves - Freeze-Dry", () => { expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); }); + + it("should deal 2x damage to Water type during inverse battle under Normalize", async () => { + game.override + .moveset([ Moves.FREEZE_DRY ]) + .ability(Abilities.NORMALIZE) + .enemySpecies(Species.MAGIKARP); + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); + }); + + it("should deal 2x damage to Water type during inverse battle under Electrify", async () => { + game.override + .moveset([ Moves.FREEZE_DRY ]) + .enemySpecies(Species.MAGIKARP) + .enemyMoveset([ Moves.ELECTRIFY ]); + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); + }); + + it("should deal 1x damage to water/flying type during inverse battle under Electrify", async () => { + game.override + .enemyMoveset([ Moves.ELECTRIFY ]) + .enemySpecies(Species.GYARADOS); + + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(1); + }); });