[Bug] Properly handle suppression with Illusion (#5671)

* Remove extra attributes on neutralizing gas

* Add IllusionBreakAbAttr to applyOnLose

* Add test case
This commit is contained in:
Dean 2025-04-20 11:14:19 -07:00 committed by Sirz Benjie
parent e048627778
commit 193ac1402c
No known key found for this signature in database
GPG Key ID: 4A524B4D196C759E
2 changed files with 39 additions and 20 deletions

View File

@ -2219,18 +2219,6 @@ export class PostSummonMessageAbAttr extends PostSummonAbAttr {
} }
} }
/**
* Removes illusions when a Pokemon is summoned.
*/
export class PostSummonRemoveIllusionAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
for (const pokemon of globalScene.getField(true)) {
pokemon.breakIllusion();
}
return true;
}
}
export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr { export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr {
//Attr doesn't force pokemon name on the message //Attr doesn't force pokemon name on the message
private message: string; private message: string;
@ -5177,7 +5165,14 @@ export class IllusionPreSummonAbAttr extends PreSummonAbAttr {
} }
} }
export class IllusionBreakAbAttr extends PostDefendAbAttr { export class IllusionBreakAbAttr extends AbAttr {
override apply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: BooleanHolder | null, _args: any[]): void {
pokemon.breakIllusion();
pokemon.summonData.illusionBroken = true;
}
}
export class PostDefendIllusionBreakAbAttr extends PostDefendAbAttr {
/** /**
* Destroy the illusion upon taking damage * Destroy the illusion upon taking damage
* *
@ -6269,7 +6264,7 @@ export function applyOnGainAbAttrs(
} }
/** /**
* Clears primal weather/neutralizing gas during the turn if {@linkcode pokemon}'s ability corresponds to one * Applies ability attributes which activate when the ability is lost or suppressed (i.e. primal weather)
*/ */
export function applyOnLoseAbAttrs(pokemon: Pokemon, passive = false, simulated = false, ...args: any[]): void { export function applyOnLoseAbAttrs(pokemon: Pokemon, passive = false, simulated = false, ...args: any[]): void {
applySingleAbAttrs<PreLeaveFieldAbAttr>( applySingleAbAttrs<PreLeaveFieldAbAttr>(
@ -6281,6 +6276,17 @@ export function applyOnLoseAbAttrs(pokemon: Pokemon, passive = false, simulated
args, args,
true, true,
simulated); simulated);
applySingleAbAttrs<IllusionBreakAbAttr>(
pokemon,
passive,
IllusionBreakAbAttr,
(attr, passive) => attr.apply(pokemon, passive, simulated, null, args),
(attr, passive) => attr.canApply(pokemon, passive, simulated, args),
args,
true,
simulated
)
} }
/** /**
@ -6780,10 +6786,11 @@ export function initAbilities() {
return isNullOrUndefined(movePhase); return isNullOrUndefined(movePhase);
}, 1.3), }, 1.3),
new Ability(Abilities.ILLUSION, 5) new Ability(Abilities.ILLUSION, 5)
//The pokemon generate an illusion if it's available // The Pokemon generate an illusion if it's available
.attr(IllusionPreSummonAbAttr, false) .attr(IllusionPreSummonAbAttr, false)
//The pokemon loses his illusion when he is damaged by a move .attr(IllusionBreakAbAttr)
.attr(IllusionBreakAbAttr, true) // The Pokemon loses its illusion when damaged by a move
.attr(PostDefendIllusionBreakAbAttr, true)
// Illusion is available again after a battle // Illusion is available again after a battle
.conditionalAttr((pokemon) => pokemon.isAllowedInBattle(), IllusionPostBattleAbAttr, false) .conditionalAttr((pokemon) => pokemon.isAllowedInBattle(), IllusionPostBattleAbAttr, false)
.uncopiable() .uncopiable()
@ -7198,8 +7205,6 @@ export function initAbilities() {
.attr(PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr) .attr(PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr)
.uncopiable() .uncopiable()
.attr(NoTransformAbilityAbAttr) .attr(NoTransformAbilityAbAttr)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonNeutralizingGas", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
.attr(PostSummonRemoveIllusionAbAttr)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.PASTEL_VEIL, 8) new Ability(Abilities.PASTEL_VEIL, 8)
.attr(PostSummonUserFieldRemoveStatusEffectAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .attr(PostSummonUserFieldRemoveStatusEffectAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)

View File

@ -142,4 +142,18 @@ describe("Abilities - Illusion", () => {
expect(zoroark.isShiny(true)).equals(true); expect(zoroark.isShiny(true)).equals(true);
expect(zoroark.getPokeball(true)).equals(PokeballType.GREAT_BALL); expect(zoroark.getPokeball(true)).equals(PokeballType.GREAT_BALL);
}); });
it("breaks when suppressed", async () => {
game.override.moveset(Moves.GASTRO_ACID);
await game.classicMode.startBattle([Species.MAGIKARP]);
const zorua = game.scene.getEnemyPokemon()!;
expect(!!zorua.summonData?.illusion).toBe(true);
game.move.select(Moves.GASTRO_ACID);
await game.phaseInterceptor.to(BerryPhase);
expect(zorua.isFullHp()).toBe(true);
expect(!!zorua.summonData?.illusion).toBe(false);
});
}); });