Feature: Finish Magnet Pull and clauses for Arena Trap (#1193)

* Implements Magnet Pull and lets Levitate/Flying Pokemon ignore Arena Trap

* using isGrounded() instead of checking for Flying/Levitate

* MR feedback to use condtions for trapping instead of having it in the class

* Making Shadow Tag Pokemon immune to Shadow Tag

* Updated to make sure Tera Stellar Pokemon are checked against their original type as well
This commit is contained in:
td76099 2024-05-29 14:47:16 -04:00 committed by GitHub
parent 8d3c334e50
commit 55423dd39d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

48
src/data/ability.ts Normal file → Executable file
View File

@ -2756,14 +2756,20 @@ export class RunSuccessAbAttr extends AbAttr {
} }
} }
type ArenaTrapCondition = (user: Pokemon, target: Pokemon) => boolean;
/** /**
* Base class for checking if a Pokemon is trapped by arena trap * Base class for checking if a Pokemon is trapped by arena trap
* @extends AbAttr * @extends AbAttr
* @field {@linkcode arenaTrapCondition} Conditional for trapping abilities.
* For example, Magnet Pull will only activate if opponent is Steel type.
* @see {@linkcode applyCheckTrapped} * @see {@linkcode applyCheckTrapped}
*/ */
export class CheckTrappedAbAttr extends AbAttr { export class CheckTrappedAbAttr extends AbAttr {
constructor() { protected arenaTrapCondition: ArenaTrapCondition;
constructor(condition: ArenaTrapCondition) {
super(false); super(false);
this.arenaTrapCondition = condition;
} }
applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, args: any[]): boolean | Promise<boolean> { applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, args: any[]): boolean | Promise<boolean> {
@ -2780,6 +2786,9 @@ export class CheckTrappedAbAttr extends AbAttr {
export class ArenaTrapAbAttr extends CheckTrappedAbAttr { export class ArenaTrapAbAttr extends CheckTrappedAbAttr {
/** /**
* Checks if enemy Pokemon is trapped by an Arena Trap-esque ability * Checks if enemy Pokemon is trapped by an Arena Trap-esque ability
* If the enemy is a Ghost type, it is not trapped
* If the user has Magnet Pull and the enemy is not a Steel type, it is not trapped.
* If the user has Arena Trap and the enemy is not grounded, it is not trapped.
* @param pokemon The {@link Pokemon} with this {@link AbAttr} * @param pokemon The {@link Pokemon} with this {@link AbAttr}
* @param passive N/A * @param passive N/A
* @param trapped {@link Utils.BooleanHolder} indicating whether the other Pokemon is trapped or not * @param trapped {@link Utils.BooleanHolder} indicating whether the other Pokemon is trapped or not
@ -2788,12 +2797,16 @@ export class ArenaTrapAbAttr extends CheckTrappedAbAttr {
* @returns if enemy Pokemon is trapped or not * @returns if enemy Pokemon is trapped or not
*/ */
applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, args: any[]): boolean { applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, args: any[]): boolean {
if (otherPokemon.getTypes().includes(Type.GHOST)) { if (this.arenaTrapCondition(pokemon, otherPokemon)) {
trapped.value = false; if (otherPokemon.getTypes(true).includes(Type.GHOST) || (otherPokemon.getTypes(true).includes(Type.STELLAR) && otherPokemon.getTypes().includes(Type.GHOST))) {
return false; trapped.value = false;
return false;
}
trapped.value = true;
return true;
} }
trapped.value = true; trapped.value = false;
return true; return false;
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
@ -3433,7 +3446,12 @@ export function initAbilities() {
new Ability(Abilities.INTIMIDATE, 3) new Ability(Abilities.INTIMIDATE, 3)
.attr(PostSummonStatChangeAbAttr, BattleStat.ATK, -1, false, true), .attr(PostSummonStatChangeAbAttr, BattleStat.ATK, -1, false, true),
new Ability(Abilities.SHADOW_TAG, 3) new Ability(Abilities.SHADOW_TAG, 3)
.attr(ArenaTrapAbAttr), .attr(ArenaTrapAbAttr, (user, target) => {
if (target.hasAbility(Abilities.SHADOW_TAG)) {
return false;
}
return true;
}),
new Ability(Abilities.ROUGH_SKIN, 3) new Ability(Abilities.ROUGH_SKIN, 3)
.attr(PostDefendContactDamageAbAttr, 8) .attr(PostDefendContactDamageAbAttr, 8)
.bypassFaint(), .bypassFaint(),
@ -3490,9 +3508,12 @@ export function initAbilities() {
.attr(StatusEffectImmunityAbAttr, StatusEffect.BURN) .attr(StatusEffectImmunityAbAttr, StatusEffect.BURN)
.ignorable(), .ignorable(),
new Ability(Abilities.MAGNET_PULL, 3) new Ability(Abilities.MAGNET_PULL, 3)
/*.attr(ArenaTrapAbAttr) .attr(ArenaTrapAbAttr, (user, target) => {
.condition((pokemon: Pokemon) => pokemon.getOpponent()?.isOfType(Type.STEEL))*/ if (target.getTypes(true).includes(Type.STEEL) || (target.getTypes(true).includes(Type.STELLAR) && target.getTypes().includes(Type.STEEL))) {
.unimplemented(), return true;
}
return false;
}),
new Ability(Abilities.SOUNDPROOF, 3) new Ability(Abilities.SOUNDPROOF, 3)
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.getMove().hasFlag(MoveFlags.SOUND_BASED)) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.getMove().hasFlag(MoveFlags.SOUND_BASED))
.ignorable(), .ignorable(),
@ -3569,7 +3590,12 @@ export function initAbilities() {
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SUNNY) .attr(PostSummonWeatherChangeAbAttr, WeatherType.SUNNY)
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SUNNY), .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SUNNY),
new Ability(Abilities.ARENA_TRAP, 3) new Ability(Abilities.ARENA_TRAP, 3)
.attr(ArenaTrapAbAttr) .attr(ArenaTrapAbAttr, (user, target) => {
if (target.isGrounded()) {
return true;
}
return false;
})
.attr(DoubleBattleChanceAbAttr), .attr(DoubleBattleChanceAbAttr),
new Ability(Abilities.VITAL_SPIRIT, 3) new Ability(Abilities.VITAL_SPIRIT, 3)
.attr(StatusEffectImmunityAbAttr, StatusEffect.SLEEP) .attr(StatusEffectImmunityAbAttr, StatusEffect.SLEEP)