diff --git a/src/data/ability.ts b/src/data/ability.ts index eec1240e1..23c725666 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -2190,13 +2190,13 @@ export class CheckTrappedAbAttr extends AbAttr { super(false); } - applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, args: any[]): boolean | Promise { + applyCheckTrapped(pokemon: Pokemon, target: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, args: any[]): boolean | Promise { return false; } } export class ArenaTrapAbAttr extends CheckTrappedAbAttr { - applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, args: any[]): boolean { + applyCheckTrapped(pokemon: Pokemon, target: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, args: any[]): boolean { trapped.value = true; return true; } @@ -2206,6 +2206,23 @@ export class ArenaTrapAbAttr extends CheckTrappedAbAttr { } } +export class ConditionalArenaTrapAbAttr extends ArenaTrapAbAttr { + private condition: (opponent: Pokemon) => boolean; + + constructor(condition: (opponent: Pokemon) => boolean) { + super(); + this.condition = condition; + } + + applyCheckTrapped(pokemon: Pokemon, opponent: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, args: any[]): boolean { + if (this.condition(opponent)) { + trapped.value = true; + return true; + } + return false; + } +} + export class MaxMultiHitAbAttr extends AbAttr { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { (args[0] as Utils.IntegerHolder).value = 0; @@ -2638,8 +2655,8 @@ export function applyPostTerrainChangeAbAttrs(attrType: { new(...args: any[]): P } export function applyCheckTrappedAbAttrs(attrType: { new(...args: any[]): CheckTrappedAbAttr }, - pokemon: Pokemon, trapped: Utils.BooleanHolder, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, passive, trapped, args), args, true); + pokemon: Pokemon, target: Pokemon, trapped: Utils.BooleanHolder, ...args: any[]): Promise { + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, target, passive, trapped, args), args, true); } export function applyPostBattleAbAttrs(attrType: { new(...args: any[]): PostBattleAbAttr }, @@ -2733,7 +2750,7 @@ export function initAbilities() { new Ability(Abilities.INTIMIDATE, 3) .attr(PostSummonStatChangeAbAttr, BattleStat.ATK, -1, false, true), new Ability(Abilities.SHADOW_TAG, 3) - .attr(ArenaTrapAbAttr), + .attr(ConditionalArenaTrapAbAttr, (opponent: Pokemon) => !opponent.isOfType(Type.GHOST)), new Ability(Abilities.ROUGH_SKIN, 3) .attr(PostDefendContactDamageAbAttr, 8) .bypassFaint(), @@ -2790,9 +2807,7 @@ export function initAbilities() { .attr(StatusEffectImmunityAbAttr, StatusEffect.BURN) .ignorable(), new Ability(Abilities.MAGNET_PULL, 3) - /*.attr(ArenaTrapAbAttr) - .condition((pokemon: Pokemon) => pokemon.getOpponent()?.isOfType(Type.STEEL))*/ - .unimplemented(), + .attr(ConditionalArenaTrapAbAttr, (opponent: Pokemon) => opponent.isOfType(Type.STEEL)), new Ability(Abilities.SOUNDPROOF, 3) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.getMove().hasFlag(MoveFlags.SOUND_BASED)) .ignorable(), @@ -2866,7 +2881,7 @@ export function initAbilities() { .attr(PostSummonWeatherChangeAbAttr, WeatherType.SUNNY) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SUNNY), new Ability(Abilities.ARENA_TRAP, 3) - .attr(ArenaTrapAbAttr) + .attr(ConditionalArenaTrapAbAttr, (opponent: Pokemon) => opponent.isGrounded()) .attr(DoubleBattleChanceAbAttr), new Ability(Abilities.VITAL_SPIRIT, 3) .attr(StatusEffectImmunityAbAttr, StatusEffect.SLEEP) diff --git a/src/phases.ts b/src/phases.ts index fc6af354a..fb2367c2c 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1779,7 +1779,7 @@ export class CommandPhase extends FieldPhase { const trapped = new Utils.BooleanHolder(false); const batonPass = isSwitch && args[0] as boolean; if (!batonPass) - enemyField.forEach(enemyPokemon => applyCheckTrappedAbAttrs(CheckTrappedAbAttr, enemyPokemon, trapped)); + enemyField.forEach(enemyPokemon => applyCheckTrappedAbAttrs(CheckTrappedAbAttr, enemyPokemon, playerPokemon, trapped)); if (batonPass || (!trapTag && !trapped.value)) { this.scene.currentBattle.turnCommands[this.fieldIndex] = isSwitch ? { command: Command.POKEMON, cursor: cursor, args: args } @@ -1877,7 +1877,7 @@ export class EnemyCommandPhase extends FieldPhase { const trapTag = enemyPokemon.findTag(t => t instanceof TrappedTag) as TrappedTag; const trapped = new Utils.BooleanHolder(false); - opponents.forEach(playerPokemon => applyCheckTrappedAbAttrs(CheckTrappedAbAttr, playerPokemon, trapped)); + opponents.forEach(playerPokemon => applyCheckTrappedAbAttrs(CheckTrappedAbAttr, playerPokemon, enemyPokemon, trapped)); if (!trapTag && !trapped.value) { const partyMemberScores = trainer.getPartyMemberMatchupScores(enemyPokemon.trainerSlot, true);