From b922e94d0b1d6fa56253dbed11049170fc8c5a97 Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Sun, 26 Jan 2025 01:34:12 +0100 Subject: [PATCH] Added new AbAttr that triggers whenever a pokemon leaves the field --- src/data/ability.ts | 121 ++++++++++++++++++++++++------------------- src/field/pokemon.ts | 3 +- 2 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 0e8b3c2392d..f16e05e3abc 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -2643,55 +2643,6 @@ export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr { } } -/** - * Clears Desolate Land/Primordial Sea/Delta Stream upon the Pokemon switching out. - */ -export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr { - - /** - * @param pokemon The {@linkcode Pokemon} with the ability - * @param passive N/A - * @param args N/A - * @returns {boolean} Returns true if the weather clears, otherwise false. - */ - applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { - const weatherType = globalScene.arena.weather?.weatherType; - let turnOffWeather = false; - - // Clear weather only if user's ability matches the weather and no other pokemon has the ability. - switch (weatherType) { - case (WeatherType.HARSH_SUN): - if (pokemon.hasAbility(Abilities.DESOLATE_LAND) - && globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) { - turnOffWeather = true; - } - break; - case (WeatherType.HEAVY_RAIN): - if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA) - && globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) { - turnOffWeather = true; - } - break; - case (WeatherType.STRONG_WINDS): - if (pokemon.hasAbility(Abilities.DELTA_STREAM) - && globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) { - turnOffWeather = true; - } - break; - } - - if (simulated) { - return turnOffWeather; - } - - if (turnOffWeather) { - globalScene.arena.trySetWeather(WeatherType.NONE, false); - return true; - } - - return false; - } -} export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr { applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { @@ -2744,6 +2695,67 @@ export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr { } +export class PreLeaveFieldAbAttr extends AbAttr { + constructor() { + super(true); + } + + applyPreLeaveField(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + return false; + } +} + + +/** + * Clears Desolate Land/Primordial Sea/Delta Stream upon the Pokemon switching out. + */ +export class PreLeaveFieldClearWeatherAbAttr extends PreLeaveFieldAbAttr { + + /** + * @param pokemon The {@linkcode Pokemon} with the ability + * @param passive N/A + * @param args N/A + * @returns {boolean} Returns true if the weather clears, otherwise false. + */ + applyPreLeaveField(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + const weatherType = globalScene.arena.weather?.weatherType; + let turnOffWeather = false; + + // Clear weather only if user's ability matches the weather and no other pokemon has the ability. + switch (weatherType) { + case (WeatherType.HARSH_SUN): + if (pokemon.hasAbility(Abilities.DESOLATE_LAND) + && globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) { + turnOffWeather = true; + } + break; + case (WeatherType.HEAVY_RAIN): + if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA) + && globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) { + turnOffWeather = true; + } + break; + case (WeatherType.STRONG_WINDS): + if (pokemon.hasAbility(Abilities.DELTA_STREAM) + && globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) { + turnOffWeather = true; + } + break; + } + + if (simulated) { + return turnOffWeather; + } + + if (turnOffWeather) { + globalScene.arena.trySetWeather(WeatherType.NONE, false); + return true; + } + + return false; + } +} + export class PreStatStageChangeAbAttr extends AbAttr { applyPreStatStageChange(pokemon: Pokemon | null, passive: boolean, simulated: boolean, stat: BattleStat, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise { return false; @@ -5229,6 +5241,11 @@ export function applyPreSwitchOutAbAttrs(attrType: Constructor(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, simulated, args), args, true, simulated); } +export function applyPreLeaveFieldAbAttrs(attrType: Constructor, + pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise { + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreLeaveField(pokemon, passive, simulated, args), args, true, simulated); +} + export function applyPreStatStageChangeAbAttrs(attrType: Constructor, pokemon: Pokemon | null, stat: BattleStat, cancelled: Utils.BooleanHolder, simulated: boolean = false, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreStatStageChange(pokemon, passive, simulated, stat, cancelled, args), args, false, simulated); @@ -5912,19 +5929,19 @@ export function initAbilities() { new Ability(Abilities.PRIMORDIAL_SEA, 6) .attr(PostSummonWeatherChangeAbAttr, WeatherType.HEAVY_RAIN) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN) - .attr(PreSwitchOutClearWeatherAbAttr) + .attr(PreLeaveFieldClearWeatherAbAttr) .attr(PostFaintClearWeatherAbAttr) .bypassFaint(), new Ability(Abilities.DESOLATE_LAND, 6) .attr(PostSummonWeatherChangeAbAttr, WeatherType.HARSH_SUN) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HARSH_SUN) - .attr(PreSwitchOutClearWeatherAbAttr) + .attr(PreLeaveFieldClearWeatherAbAttr) .attr(PostFaintClearWeatherAbAttr) .bypassFaint(), new Ability(Abilities.DELTA_STREAM, 6) .attr(PostSummonWeatherChangeAbAttr, WeatherType.STRONG_WINDS) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.STRONG_WINDS) - .attr(PreSwitchOutClearWeatherAbAttr) + .attr(PreLeaveFieldClearWeatherAbAttr) .attr(PostFaintClearWeatherAbAttr) .bypassFaint(), new Ability(Abilities.STAMINA, 7) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 432f0a92fec..fa6b33764d3 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -32,7 +32,7 @@ import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoo import { WeatherType } from "#enums/weather-type"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag"; import type { Ability, AbAttr } from "#app/data/ability"; -import { StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, CommanderAbAttr, applyPostItemLostAbAttrs, PostItemLostAbAttr } from "#app/data/ability"; +import { StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, CommanderAbAttr, applyPostItemLostAbAttrs, PostItemLostAbAttr, PreLeaveFieldAbAttr, applyPreLeaveFieldAbAttrs } from "#app/data/ability"; import type PokemonData from "#app/system/pokemon-data"; import { BattlerIndex } from "#app/battle"; import { Mode } from "#app/ui/ui"; @@ -4128,6 +4128,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (hideInfo) { this.hideInfo(); } + applyPreLeaveFieldAbAttrs(PreLeaveFieldAbAttr, this); globalScene.field.remove(this); this.setSwitchOutStatus(true); globalScene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);