diff --git a/src/data/ability.ts b/src/data/ability.ts index 1e8ac98c1ac..922d994375a 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -2667,23 +2667,27 @@ export class PreSwitchOutAbAttr extends AbAttr { super(true); } + willSucceedPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + return true; + } + applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { return false; } } export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr { - applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { - if (pokemon.status) { - if (!simulated) { - pokemon.resetStatus(); - pokemon.updateInfo(); - } + willSucceedPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + return !Utils.isNullOrUndefined(pokemon.status); + } - return true; + applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + if (!simulated) { + pokemon.resetStatus(); + pokemon.updateInfo(); } - return false; + return true; } } @@ -2691,6 +2695,37 @@ export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr { * Clears Desolate Land/Primordial Sea/Delta Stream upon the Pokemon switching out. */ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr { + private turnOffWeather: boolean; + + willSucceedPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + this.turnOffWeather = false; + + const weatherType = globalScene.arena.weather?.weatherType; + + // 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) { + return 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) { + return 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) { + return true; + } + break; + } + + return false; + } /** * @param pokemon The {@linkcode Pokemon} with the ability @@ -2699,57 +2734,26 @@ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr { * @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) { + if (!simulated) { globalScene.arena.trySetWeather(WeatherType.NONE, false); - return true; } - - return false; + return true; } } export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr { - applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { - if (!pokemon.isFullHp()) { - if (!simulated) { - const healAmount = Utils.toDmgValue(pokemon.getMaxHp() * 0.33); - pokemon.heal(healAmount); - pokemon.updateInfo(); - } + willSucceedPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + return !pokemon.isFullHp(); + } - return true; + applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + if (!simulated) { + const healAmount = Utils.toDmgValue(pokemon.getMaxHp() * 0.33); + pokemon.heal(healAmount); + pokemon.updateInfo(); } - return false; + return true; } } @@ -2767,6 +2771,10 @@ export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr { this.formFunc = formFunc; } + willSucceedPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + return this.formFunc(pokemon) !== pokemon.formIndex; + } + /** * On switch out, trigger the form change to the one defined in the ability * @param pokemon The pokemon switching out and changing form {@linkcode Pokemon} @@ -2775,15 +2783,10 @@ export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr { * @returns true if the form change was successful */ applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { - const formIndex = this.formFunc(pokemon); - if (formIndex !== pokemon.formIndex) { - if (!simulated) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); - } - return true; + if (!simulated) { + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); } - - return false; + return true; } } @@ -5313,7 +5316,8 @@ export function applyPostSummonAbAttrs(attrType: Constructor, export function applyPreSwitchOutAbAttrs(attrType: Constructor, pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, simulated, args), args, true, simulated); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, simulated, args), + (attr, passive) => attr.willSucceedPreSwitchOut(pokemon, passive, simulated, args), args, true, simulated); } export function applyPreStatStageChangeAbAttrs(attrType: Constructor,