Ensure force switches cannot pull pokemon from the wrong trainer

This commit is contained in:
Sirz Benjie 2025-04-10 10:43:22 -05:00
parent b07f9f1d2a
commit 6501d17f1e
No known key found for this signature in database
GPG Key ID: 4A524B4D196C759E
2 changed files with 25 additions and 27 deletions

View File

@ -77,7 +77,7 @@ import {
PreserveBerryModifier,
} from "../../modifier/modifier";
import type { BattlerIndex } from "../../battle";
import { BattleType } from "../../battle";
import { BattleType } from "#enums/battle-type";
import { TerrainType } from "../terrain";
import { ModifierPoolType } from "#app/modifier/modifier-type";
import { Command } from "../../ui/command-ui-handler";
@ -123,6 +123,7 @@ import { MoveFlags } from "#enums/MoveFlags";
import { MoveEffectTrigger } from "#enums/MoveEffectTrigger";
import { MultiHitType } from "#enums/MultiHitType";
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves";
import { TrainerVariant } from "#app/field/trainer";
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
@ -6232,8 +6233,10 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
// Check if the move category is not STATUS or if the switch out condition is not met
if (!this.getSwitchOutCondition()(user, target, move)) {
console.log("=========== Switch out condition was false!===========");
return false;
}
console.log("=========== Switch out condition was true!===========");
/** The {@linkcode Pokemon} to be switched out with this effect */
const switchOutTarget = this.selfSwitch ? user : target;
@ -6298,9 +6301,10 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
return false;
} else if (globalScene.currentBattle.battleType !== BattleType.WILD) { // Switch out logic for enemy trainers
// Find indices of off-field Pokemon that are eligible to be switched into
const isPartnerTrainer = globalScene.currentBattle.trainer?.isPartner();
const eligibleNewIndices: number[] = [];
globalScene.getEnemyParty().forEach((pokemon, index) => {
if (pokemon.isAllowedInBattle() && !pokemon.isOnField() && (pokemon as EnemyPokemon).trainerSlot === (switchOutTarget as EnemyPokemon).trainerSlot) {
if (pokemon.isAllowedInBattle() && !pokemon.isOnField() && (!isPartnerTrainer || pokemon.trainerSlot === (switchOutTarget as EnemyPokemon).trainerSlot)) {
eligibleNewIndices.push(index);
}
});
@ -6350,15 +6354,6 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
}
}
if (globalScene.currentBattle.waveIndex % 10 === 0) {
return false;
}
// Don't allow wild mons to flee with U-turn et al.
if (this.selfSwitch && !user.isPlayer() && move.category !== MoveCategory.STATUS) {
return false;
}
const allyPokemon = switchOutTarget.getAlly();
if (switchOutTarget.hp > 0) {
@ -6371,13 +6366,12 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
}
}
if (!allyPokemon?.isActive(true)) {
globalScene.clearEnemyHeldItemModifiers();
// clear out enemy held item modifiers of the switch out target
globalScene.clearEnemyHeldItemModifiers(switchOutTarget);
if (switchOutTarget.hp) {
if (!allyPokemon?.isActive(true) && switchOutTarget.hp) {
globalScene.pushPhase(new BattleEndPhase(false));
globalScene.pushPhase(new NewBattlePhase());
}
}
}
@ -6419,23 +6413,27 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
const blockedByAbility = new Utils.BooleanHolder(false);
applyAbAttrs(ForceSwitchOutImmunityAbAttr, target, blockedByAbility);
return !blockedByAbility.value;
if (blockedByAbility.value) {
return false;
}
}
if (!player && globalScene.currentBattle.battleType === BattleType.WILD) {
if (this.isBatonPass()) {
return false;
}
// Don't allow wild opponents to flee on the boss stage since it can ruin a run early on
if (globalScene.currentBattle.waveIndex % 10 === 0) {
return false;
}
// Prevent wild pokemon fr
return !(this.isBatonPass()
// Don't allow boss waves of wild pokemon to flee
&& globalScene.currentBattle.waveIndex % 10 === 0
// Don't allow wild mons to flee with U-turn et al.
&& this.selfSwitch && move.category !== MoveCategory.STATUS)
}
const party = player ? globalScene.getPlayerParty() : globalScene.getEnemyParty();
return (!player && !globalScene.currentBattle.battleType)
|| party.filter(p => p.isAllowedInBattle()
&& (player || (p as EnemyPokemon).trainerSlot === (switchOutTarget as EnemyPokemon).trainerSlot)).length > globalScene.currentBattle.getBattlerCount();
// Determine if this is a
const currentBattle = globalScene.currentBattle;
// If the trainer battle is a partner, then they can switch out as long as they have at least one pokemon in the back
const MIN_BATTLE_COUNT = (!player && currentBattle.trainer?.variant === TrainerVariant.DOUBLE) ? 1 : currentBattle.getBattlerCount();
return party.filter(p => p.isAllowedInBattle()
&& (player || (p as EnemyPokemon).trainerSlot === (switchOutTarget as EnemyPokemon).trainerSlot)).length > MIN_BATTLE_COUNT;
};
}

View File

@ -15,7 +15,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PokeballType } from "#enums/pokeball";
import { PokemonType } from "#enums/pokemon-type";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import { BATTLE_STATS, Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect";
import { TimeOfDay } from "#enums/time-of-day";
import { VariantTier } from "#enums/variant-tier";