Skip to content

Commit

Permalink
Fix magic bounce semi-invulnerable interaction
Browse files Browse the repository at this point in the history
This was based on smogon's incorrect handling of this situation
  • Loading branch information
SirzBenjie committed Feb 2, 2025
1 parent 70b2bd3 commit 6e1230f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 7 deletions.
8 changes: 1 addition & 7 deletions src/phases/move-effect-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,6 @@ export class MoveEffectPhase extends PokemonPhase {
* - An ability like {@linkcode Abilities.NO_GUARD | No Guard}
* - A poison type using {@linkcode Moves.TOXIC | Toxic}
* - A move like {@linkcode Moves.LOCK_ON | Lock-On} or {@linkcode Moves.MIND_READER | Mind Reader}.
* - A move like {@linkcode Moves.SPIEKS | Spikes} or {@linkcode Moves.SANDSTORM | Sandstorm} that targets the field
*
* Does *not* check against effects {@linkcode Moves.GLAIVE_RUSH | Glaive Rush} status (which
* should not bypass semi-invulnerability), or interactions like Earthquake hitting against Dig,
Expand All @@ -687,9 +686,6 @@ export class MoveEffectPhase extends PokemonPhase {
if (!user) {
return false;
}
if ([ MoveTarget.USER, MoveTarget.ENEMY_SIDE, MoveTarget.USER_SIDE, MoveTarget.BOTH_SIDES ].includes(this.move.getMove().moveTarget)) {
return true;
}
if (user.hasAbilityWithAttr(AlwaysHitAbAttr) || target.hasAbilityWithAttr(AlwaysHitAbAttr)) {
return true;
}
Expand All @@ -712,9 +708,7 @@ export class MoveEffectPhase extends PokemonPhase {
return false;
}
const move = this.move.getMove();
/** Does the move target the field instead of the target itself? */
const isIndirectTarget = move.moveTarget in [ MoveTarget.USER, MoveTarget.ENEMY_SIDE, MoveTarget.USER_SIDE, MoveTarget.BOTH_SIDES ];
return isIndirectTarget || move.getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType);
return move.getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType);
}

/** @returns The {@linkcode Pokemon} using this phase's invoked move */
Expand Down
11 changes: 11 additions & 0 deletions src/test/abilities/magic_bounce.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,17 @@ describe("Abilities - Magic Bounce", () => {
expect(game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.PLAYER)!["layers"]).toBe(1);
});

it("should not bounce spikes when the target is in the semi-invulnerable state", async () => {
game.override.moveset([ Moves.SPIKES ]);
game.override.enemyMoveset([ Moves.FLY ]);
await game.classicMode.startBattle([ Species.MAGIKARP ]);

game.move.select(Moves.SPIKES);
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY)!["layers"]).toBe(1);
});

it("should not bounce back curse", async() => {
game.override.starterSpecies(Species.GASTLY);
await game.classicMode.startBattle([ Species.GASTLY ]);
Expand Down

0 comments on commit 6e1230f

Please sign in to comment.