diff --git a/src/data/ability.ts b/src/data/ability.ts index 99d41fed1c9..33f700a0248 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -4867,9 +4867,10 @@ async function applyAbAttrsInternal( showAbilityInstant: boolean = false, simulated: boolean = false, messages: string[] = [], + considerPassive: boolean = true ) { for (const passive of [ false, true ]) { - if (!pokemon?.canApplyAbility(passive) || (passive && pokemon.getPassiveAbility().id === pokemon.getAbility().id)) { + if (!pokemon?.canApplyAbility(passive) || (passive && (pokemon.getPassiveAbility().id === pokemon.getAbility().id || !considerPassive))) { continue; } @@ -5295,6 +5296,21 @@ export function applyPostItemLostAbAttrs(attrType: Constructor(attrType, pokemon, (attr, passive) => attr.applyPostItemLost(pokemon, simulated, args), args); } +/** + * Applies abilities when they become active mid-turn (ability switch) + * + * Ignores passives as they don't change and shouldn't be reapplied when main abilities change + */ +export function applyMidTurnAbAttrs(pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise { + return applyAbAttrsInternal(PostSummonAbAttr, pokemon, (attr, passive) => attr.applyPostSummon(pokemon, passive, simulated, args), args, false, simulated, [], false); +} + +/** + * Clears primal weather during the turn if {@linkcode pokemon}'s ability corresponds to one + */ +export function applyMidTurnClearWeatherAbAttrs(pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise { + return applyAbAttrsInternal(PreSwitchOutClearWeatherAbAttr, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, simulated, args), args, true, simulated, [], false); +} function queueShowAbility(pokemon: Pokemon, passive: boolean): void { globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive)); globalScene.clearPhaseQueueSplice(); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 32db4f2b727..8c1083b424d 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, applyPostSummonAbAttrs, PostSummonAbAttr, PreSwitchOutAbAttr, applyPreSwitchOutAbAttrs } 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, applyMidTurnAbAttrs, applyMidTurnClearWeatherAbAttrs } from "#app/data/ability"; import type PokemonData from "#app/system/pokemon-data"; import { BattlerIndex } from "#app/battle"; import { Mode } from "#app/ui/ui"; @@ -1432,23 +1432,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Sets the {@linkcode Pokemon}'s ability and activates it if it normally activates on summon - * Clears + * + * Also clears primal weather if it is from the ability being changed * @param ability New Ability */ public setTempAbility(ability: Ability): void { - const legendaryWeather = [ Abilities.DESOLATE_LAND, Abilities.PRIMORDIAL_SEA, Abilities.DELTA_STREAM ]; - // If the ability to set is also a legendary weather, no need to clear old weather - if (legendaryWeather.includes(this.getAbility().id) && !legendaryWeather.includes(ability.id)) { - applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, this); - } + applyMidTurnClearWeatherAbAttrs(this); this.summonData.ability = ability.id; - - applyPostSummonAbAttrs(PostSummonAbAttr, this) - .then(() => { - const field = this.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField(); - field.forEach((p) => applyAbAttrs(CommanderAbAttr, p, null, false)); - }); - + applyMidTurnAbAttrs(this); } /**