From eb1696e93ea64014577ead87391da13007e89d48 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Tue, 24 Jun 2025 09:00:25 -0400 Subject: [PATCH] Fixed infiltrator bug --- src/field/pokemon.ts | 34 +++++++++++++----------- src/phases/obtain-status-effect-phase.ts | 2 +- test/abilities/infiltrator.test.ts | 12 ++++----- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 1b540d65ac7..29a1ad2ed67 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4670,18 +4670,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Check if a status effect can be applied to this {@linkcode Pokemon}. * - * @param effect - The {@linkcode StatusEffect} whose applicability is being checked. - * @param quiet - Whether to suppress in-battle messages for status checks; default `false`. - * @param overrideStatus - Whether to allow overriding the Pokemon's current status with a different one; default `false`. + * @param effect - The {@linkcode StatusEffect} whose applicability is being checked + * @param quiet - Whether to suppress in-battle messages for status checks; default `false` + * @param overrideStatus - Whether to allow overriding the Pokemon's current status with a different one; default `false` * @param sourcePokemon - The {@linkcode Pokemon} applying the status effect to the target, - * or `null` if the status is applied from a non-Pokemon source (hazards, etc.); default `null`. + * or `null` if the status is applied from a non-Pokemon source (hazards, etc.); default `null` * @param ignoreField - Whether to ignore field effects (weather, terrain, etc.) preventing status application; * default `false` * @returns Whether {@linkcode effect} can be applied to this Pokemon. */ // TODO: Review and verify the message order precedence in mainline if multiple status-blocking effects are present at once // TODO: Make argument order consistent with `trySetStatus` - canSetStatus( + public canSetStatus( effect: StatusEffect, quiet = false, overrideStatus = false, @@ -4791,28 +4791,29 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Attempt to set this Pokemon's status to the specified condition. * Enqueues a new `ObtainStatusEffectPhase` to trigger animations, etc. - * @param effect - The {@linkcode StatusEffect} to set. + * @param effect - The {@linkcode StatusEffect} to set * @param sourcePokemon - The {@linkcode Pokemon} applying the status effect to the target, - * or `null` if the status is applied from a non-Pokemon source (hazards, etc.); default `null`. + * or `null` if the status is applied from a non-Pokemon source (hazards, etc.); default `null` * @param sleepTurnsRemaining - The number of turns to set {@linkcode StatusEffect.SLEEP} for; - * defaults to a random number between 2 and 4 and is unused for non-Sleep statuses. - * @param sourceText - The text to show for the source of the status effect, if any; default `null`. - * @param overrideStatus - Whether to allow overriding the Pokemon's current status with a different one; default `false`. - * @param quiet - Whether to suppress in-battle messages for status checks; default `true`. - * @param overrideMessage - A string containing text to be displayed upon status setting; defaults to normal key for status + * defaults to a random number between 2 and 4 and is unused for non-Sleep statuses + * @param sourceText - The text to show for the source of the status effect, if any; default `null` + * @param overrideStatus - Whether to allow overriding the Pokemon's current status with a different one; default `false` + * @param quiet - Whether to suppress in-battle messages for status checks; default `true` + * @param overrideMessage - String containing text to be displayed upon status setting; defaults to normal key for status + * and is used exclusively for Rest. * @returns Whether the status effect phase was successfully created. * @see {@linkcode doSetStatus} - alternate function that sets status immediately (albeit without condition checks). */ - trySetStatus( + public trySetStatus( effect: StatusEffect, sourcePokemon: Pokemon | null = null, sleepTurnsRemaining?: number, sourceText: string | null = null, overrideStatus?: boolean, quiet = true, - overrideMessage?: string | undefined, + overrideMessage?: string, ): boolean { - // TODO: This needs to propagate failure status for non-status moves + // TODO: This needs to propagate failure status for status moves if (!effect) { return false; } @@ -4863,7 +4864,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * Set this Pokemon's {@linkcode status | status condition} to the specified effect. * Does **NOT** perform any feasibility checks whatsoever; must be checked by the caller. * @param effect - {@linkcode StatusEffect.SLEEP} - * @param sleepTurnsRemaining - The number of turns to inflict sleep for; defaults to a random number between 2 and 4. + * @param sleepTurnsRemaining - The number of turns to inflict sleep for; defaults to a random number between 2 and 4 */ doSetStatus(effect: StatusEffect.SLEEP, sleepTurnsRemaining?: number): void; /** @@ -4880,6 +4881,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param effect - The {@linkcode StatusEffect} to set * @param sleepTurnsRemaining - The number of turns to inflict sleep for; defaults to a random number between 2 and 4 * and is unused for all non-sleep Statuses. + * @todo Make this private and change tests to use a field-based helper or similar */ doSetStatus( effect: StatusEffect, diff --git a/src/phases/obtain-status-effect-phase.ts b/src/phases/obtain-status-effect-phase.ts index 4feb0bd4f0c..049eaea7a51 100644 --- a/src/phases/obtain-status-effect-phase.ts +++ b/src/phases/obtain-status-effect-phase.ts @@ -30,7 +30,7 @@ export class ObtainStatusEffectPhase extends PokemonPhase { battlerIndex: BattlerIndex, private statusEffect: StatusEffect, private sourcePokemon: Pokemon | null = null, - private sleepTurnsRemaining = 0, + private sleepTurnsRemaining?: number, sourceText: string | null = null, // TODO: This should take `undefined` instead of `null` private statusMessage = "", ) { diff --git a/test/abilities/infiltrator.test.ts b/test/abilities/infiltrator.test.ts index a5de035a136..4792dea0da0 100644 --- a/test/abilities/infiltrator.test.ts +++ b/test/abilities/infiltrator.test.ts @@ -58,8 +58,8 @@ describe("Abilities - Infiltrator", () => { ])("should bypass the target's $effectName", async ({ tagType, move }) => { await game.classicMode.startBattle([SpeciesId.MAGIKARP]); - const player = game.scene.getPlayerPokemon()!; - const enemy = game.scene.getEnemyPokemon()!; + const player = game.field.getPlayerPokemon(); + const enemy = game.field.getEnemyPokemon(); const preScreenDmg = enemy.getAttackDamage({ source: player, move: allMoves[move] }).damage; @@ -74,14 +74,14 @@ describe("Abilities - Infiltrator", () => { it("should bypass the target's Safeguard", async () => { await game.classicMode.startBattle([SpeciesId.MAGIKARP]); - const player = game.scene.getPlayerPokemon()!; - const enemy = game.scene.getEnemyPokemon()!; + const player = game.field.getPlayerPokemon(); + const enemy = game.field.getEnemyPokemon(); game.scene.arena.addTag(ArenaTagType.SAFEGUARD, 1, MoveId.NONE, enemy.id, ArenaTagSide.ENEMY, true); - game.move.select(MoveId.SPORE); + game.move.use(MoveId.SPORE); + await game.toEndOfTurn(); - await game.phaseInterceptor.to("BerryPhase", false); expect(enemy.status?.effect).toBe(StatusEffect.SLEEP); expect(player.waveData.abilitiesApplied).toContain(AbilityId.INFILTRATOR); });