diff --git a/src/data/ability.ts b/src/data/ability.ts index d64e212da00..088c37e331d 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -4249,6 +4249,10 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr { } export class PostFaintAbAttr extends AbAttr { + willSucceedPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { + return true; + } + applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { return false; } @@ -4260,6 +4264,10 @@ export class PostFaintAbAttr extends AbAttr { * @extends PostFaintAbAttr */ export class PostFaintUnsuppressedWeatherFormChangeAbAttr extends PostFaintAbAttr { + willSucceedPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { + return getPokemonWithWeatherBasedForms().length > 0; + } + /** * Triggers {@linkcode Arena.triggerWeatherBasedFormChanges | triggerWeatherBasedFormChanges} * when the user of the ability faints @@ -4272,12 +4280,6 @@ export class PostFaintUnsuppressedWeatherFormChangeAbAttr extends PostFaintAbAtt * @returns whether the form change was triggered */ applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - const pokemonToTransform = getPokemonWithWeatherBasedForms(); - - if (pokemonToTransform.length < 1) { - return false; - } - if (!simulated) { globalScene.arena.triggerWeatherBasedFormChanges(); } @@ -4290,6 +4292,33 @@ export class PostFaintUnsuppressedWeatherFormChangeAbAttr extends PostFaintAbAtt * Clears Desolate Land/Primordial Sea/Delta Stream upon the Pokemon fainting */ export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr { + willSucceedPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { + 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.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.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.hasAbility(Abilities.DELTA_STREAM)).length === 0) { + return true; + } + break; + } + + return false; + } /** * @param pokemon The {@linkcode Pokemon} with the ability @@ -4301,41 +4330,11 @@ export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr { * @returns {boolean} Returns true if the weather clears, otherwise false. */ applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { - 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.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.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.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; } } @@ -4348,21 +4347,23 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { this.damageRatio = damageRatio; } - applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { - if (move !== undefined && attacker !== undefined && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { //If the mon didn't die to indirect damage - const cancelled = new Utils.BooleanHolder(false); - globalScene.getField(true).map(p => applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled, simulated)); - if (cancelled.value || attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { - return false; - } - if (!simulated) { - attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); - attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)); - } - return true; + willSucceedPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { + const diedToDirectDamage = move !== undefined && attacker !== undefined && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon); + const cancelled = new Utils.BooleanHolder(false); + globalScene.getField(true).map(p => applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled, simulated)); + if (!diedToDirectDamage || cancelled.value || attacker!.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { + return false; } - return false; + return true; + } + + applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { + if (!simulated) { + attacker!.damageAndUpdate(Utils.toDmgValue(attacker!.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker!.turnData.damageTaken += Utils.toDmgValue(attacker!.getMaxHp() * (1 / this.damageRatio)); + } + return true; } getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { @@ -5434,7 +5435,8 @@ export function applyPostBattleAbAttrs(attrType: Constructor, export function applyPostFaintAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker?: Pokemon, move?: Move, hitResult?: HitResult, simulated: boolean = false, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, simulated, attacker, move, hitResult, args), args, false, simulated); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, simulated, attacker, move, hitResult, args), + (attr, passive) => attr.willSucceedPostFaint(pokemon, passive, simulated, attacker, move, hitResult, args), args, false, simulated); } export function applyPostItemLostAbAttrs(attrType: Constructor,