diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 5ff83cedaea..530b77fef14 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -6337,8 +6337,10 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr { /** * Applies the switch-out logic after the Pokémon takes damage. */ - public override apply({ pokemon }: PostDamageAbAttrParams): void { - // TODO: Consider respecting the `simulated` flag here + public override apply({ pokemon, simulated }: PostDamageAbAttrParams): void { + if (simulated) { + return; + } this.helper.doSwitch(pokemon); } } diff --git a/src/data/helpers/force-switch.ts b/src/data/helpers/force-switch.ts index bfd70ce0757..bfcc86afd7d 100644 --- a/src/data/helpers/force-switch.ts +++ b/src/data/helpers/force-switch.ts @@ -12,6 +12,7 @@ import i18next from "i18next"; export interface ForceSwitchOutHelperArgs { /** * Whether to switch out the user (`true`) or target (`false`). + * If `true`, will ignore certain effects that would otherwise block forced switches. * @defaultValue `false` */ selfSwitch?: boolean; @@ -21,7 +22,7 @@ export interface ForceSwitchOutHelperArgs { */ switchType?: NormalSwitchType; /** - * Whether to allow non-boss wild Pokemon to flee when using the move. + * Whether to allow non-boss wild Pokemon to flee from this effect's activation. * @defaultValue `false` */ allowFlee?: boolean; @@ -47,8 +48,6 @@ export class ForceSwitchOutHelper implements ForceSwitchOutHelperArgs { * @returns Whether {@linkcode switchOutTarget} can be switched out by the current effect. */ public canSwitchOut(switchOutTarget: Pokemon): boolean { - const isPlayer = switchOutTarget.isPlayer(); - if (switchOutTarget.isFainted()) { // Fainted Pokemon cannot be switched out by any means. // This is already checked in `MoveEffectAttr.canApply`, but better safe than sorry @@ -60,8 +59,9 @@ export class ForceSwitchOutHelper implements ForceSwitchOutHelperArgs { return false; } - // Wild enemies should not be allowed to flee with fleeing moves, nor by any means on X0 waves (don't want easy boss wins) + // Wild enemies should not be allowed to flee with ineligible fleeing moves, nor by any means on X0 waves (don't want easy boss wins) // TODO: Do we want to show a message for wave X0 failures? + const isPlayer = switchOutTarget.isPlayer(); if (!isPlayer && globalScene.currentBattle.battleType === BattleType.WILD) { return this.allowFlee && globalScene.currentBattle.waveIndex % 10 !== 0; } @@ -126,7 +126,7 @@ export class ForceSwitchOutHelper implements ForceSwitchOutHelperArgs { /** * Method to handle switching out a player Pokemon. - * @param switchOutTarget - The {@linkcode PlayerPokemon} to be switched out. + * @param switchOutTarget - The {@linkcode PlayerPokemon} to be switched out */ private trySwitchPlayerPokemon(switchOutTarget: PlayerPokemon): void { // If not forced to switch, add a SwitchPhase to allow picking the next switched in Pokemon. @@ -160,7 +160,7 @@ export class ForceSwitchOutHelper implements ForceSwitchOutHelperArgs { /** * Method to handle switching out an opposing trainer's Pokemon. - * @param switchOutTarget - The {@linkcode EnemyPokemon} to be switched out. + * @param switchOutTarget - The {@linkcode EnemyPokemon} to be switched out */ private trySwitchTrainerPokemon(switchOutTarget: EnemyPokemon): void { // fallback for no trainer @@ -189,7 +189,7 @@ export class ForceSwitchOutHelper implements ForceSwitchOutHelperArgs { /** * Method to handle fleeing a wild enemy Pokemon, redirecting incoming moves to its ally as applicable. - * @param switchOutTarget - The {@linkcode EnemyPokemon} fleeing the battle. + * @param switchOutTarget - The {@linkcode EnemyPokemon} fleeing the battle */ private tryFleeWildPokemon(switchOutTarget: EnemyPokemon): void { switchOutTarget.leaveField(true); diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index e5659082176..1a179c1cb51 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -6301,7 +6301,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { private readonly helper: ForceSwitchOutHelper; constructor(args: ForceSwitchOutHelperArgs) { - super(false, { lastHitOnly: true }); // procy to + super(false, { lastHitOnly: true }); this.helper = new ForceSwitchOutHelper(args); } @@ -6344,7 +6344,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { // upon an unsuccessful switch - they still succeed and perform secondary effects // (just without actually switching out). // TODO: Remove attr check once move attribute application is cleaned up - return (user, target, move) => (move.category !== MoveCategory.STATUS || move.attrs.length > 1 || this.canApply(user, target)); + return (user, target, move) => (move.category !== MoveCategory.STATUS || move.attrs.length > 1 || this.canApply(user, target, move, [])); } getFailedText(_user: Pokemon, target: Pokemon): string | undefined { diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index c6ef4e8ca0e..1a146bb92d8 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -36,7 +36,7 @@ export class SwitchSummonPhase extends SummonPhase { // -1 = "use trainer switch logic" this.slotIndex = slotIndex > -1 - ? this.slotIndex + ? slotIndex : globalScene.currentBattle.trainer!.getNextSummonIndex(this.getTrainerSlotFromFieldIndex()); this.doReturn = doReturn; } @@ -65,7 +65,7 @@ export class SwitchSummonPhase extends SummonPhase { // If the target is still on-field, remove it and/or hide its info container. // Effects are kept to be transferred to the new Pokemon later on. if (switchOutPokemon.isOnField()) { - switchOutPokemon.leaveField(false, switchOutPokemon.getBattleInfo()?.visible); + switchOutPokemon.leaveField(false, switchOutPokemon.getBattleInfo().visible); } if (this.player) { @@ -114,7 +114,7 @@ export class SwitchSummonPhase extends SummonPhase { scale: 0.5, onComplete: () => { globalScene.time.delayedCall(750, () => this.switchAndSummon()); - switchOutPokemon.leaveField(this.switchType === SwitchType.SWITCH, false); // TODO: do we have to do this right here right now + switchOutPokemon.leaveField(this.switchType === SwitchType.SWITCH, false); // TODO: this reset effects call is dubious }, }); } @@ -227,16 +227,14 @@ export class SwitchSummonPhase extends SummonPhase { // Baton Pass over any eligible effects or substitutes before resetting the last pokemon's temporary data. if (this.switchType === SwitchType.BATON_PASS) { activePokemon.transferSummon(this.lastPokemon); - this.lastPokemon.resetTurnData(); - this.lastPokemon.resetSummonData(); } else if (this.switchType === SwitchType.SHED_TAIL) { const subTag = this.lastPokemon.getTag(SubstituteTag); if (subTag) { activePokemon.summonData.tags.push(subTag); } - this.lastPokemon.resetTurnData(); - this.lastPokemon.resetSummonData(); } + this.lastPokemon.resetTurnData(); + this.lastPokemon.resetSummonData(); globalScene.triggerPokemonFormChange(activePokemon, SpeciesFormChangeActiveTrigger, true); // Reverts to weather-based forms when weather suppressors (Cloud Nine/Air Lock) are switched out