mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 17:12:44 +02:00
Update abattr callsites in battler-tags
Also removed stat drop ability application from cancelling ME stat boost effects
This commit is contained in:
parent
1deb74e926
commit
f432f8cbf6
@ -1402,6 +1402,12 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
export class PostStatStageChangeAbAttr extends AbAttr {
|
export class PostStatStageChangeAbAttr extends AbAttr {
|
||||||
private declare readonly _: never;
|
private declare readonly _: never;
|
||||||
|
|
||||||
|
override canApply(_params: Closed<PostStatStageChangeAbAttrParams>) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override apply(_params: Closed<PostStatStageChangeAbAttrParams>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PostStatStageChangeAbAttrParams extends AbAttrBaseParams {
|
export interface PostStatStageChangeAbAttrParams extends AbAttrBaseParams {
|
||||||
@ -3415,9 +3421,12 @@ export interface PreStatStageChangeAbAttrParams extends AbAttrBaseParams {
|
|||||||
stat: BattleStat;
|
stat: BattleStat;
|
||||||
/** The amount of stages to change by (negative if the stat is being decreased) */
|
/** The amount of stages to change by (negative if the stat is being decreased) */
|
||||||
stages: number;
|
stages: number;
|
||||||
/** The source of the stat stage drop */
|
/** The source of the stat stage drop. May be omitted if the source of the stat drop is the user itself.
|
||||||
source: Pokemon;
|
*
|
||||||
// Note: `cancelled` already exists in `AbAttrBaseParams`, though we redefine it here to change its tsdoc
|
* @remarks
|
||||||
|
* Currently, only used by {@linkcode ReflectStatStageChangeAbAttr} in order to reflect the stat stage change
|
||||||
|
*/
|
||||||
|
source?: Pokemon;
|
||||||
/** Holder that will be set to true if the stat stage change should be cancelled due to the ability */
|
/** Holder that will be set to true if the stat stage change should be cancelled due to the ability */
|
||||||
cancelled: BooleanHolder;
|
cancelled: BooleanHolder;
|
||||||
}
|
}
|
||||||
@ -3440,10 +3449,17 @@ export class ReflectStatStageChangeAbAttr extends PreStatStageChangeAbAttr {
|
|||||||
/** {@linkcode BattleStat} to reflect */
|
/** {@linkcode BattleStat} to reflect */
|
||||||
private reflectedStat?: BattleStat;
|
private reflectedStat?: BattleStat;
|
||||||
|
|
||||||
|
override canApply({ source, cancelled }: PreStatStageChangeAbAttrParams): boolean {
|
||||||
|
return !!source && !cancelled.value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the {@linkcode ReflectStatStageChangeAbAttr} to an interaction
|
* Apply the {@linkcode ReflectStatStageChangeAbAttr} to an interaction
|
||||||
*/
|
*/
|
||||||
override apply({ source, cancelled, stat, simulated, stages }: PreStatStageChangeAbAttrParams): void {
|
override apply({ source, cancelled, stat, simulated, stages }: PreStatStageChangeAbAttrParams): void {
|
||||||
|
if (!source) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.reflectedStat = stat;
|
this.reflectedStat = stat;
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.phaseManager.unshiftNew(
|
globalScene.phaseManager.unshiftNew(
|
||||||
|
@ -946,7 +946,7 @@ class StealthRockTag extends ArenaTrapTag {
|
|||||||
|
|
||||||
override activateTrap(pokemon: Pokemon, simulated: boolean): boolean {
|
override activateTrap(pokemon: Pokemon, simulated: boolean): boolean {
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
if (cancelled.value) {
|
if (cancelled.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1003,7 +1003,12 @@ class StickyWebTag extends ArenaTrapTag {
|
|||||||
override activateTrap(pokemon: Pokemon, simulated: boolean): boolean {
|
override activateTrap(pokemon: Pokemon, simulated: boolean): boolean {
|
||||||
if (pokemon.isGrounded()) {
|
if (pokemon.isGrounded()) {
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("ProtectStatAbAttr", pokemon, cancelled);
|
applyAbAttrs("ProtectStatAbAttr", {
|
||||||
|
pokemon,
|
||||||
|
cancelled,
|
||||||
|
stat: Stat.SPD,
|
||||||
|
stages: -1,
|
||||||
|
});
|
||||||
|
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return !cancelled.value;
|
return !cancelled.value;
|
||||||
@ -1416,7 +1421,9 @@ export class SuppressAbilitiesTag extends ArenaTag {
|
|||||||
|
|
||||||
for (const fieldPokemon of globalScene.getField(true)) {
|
for (const fieldPokemon of globalScene.getField(true)) {
|
||||||
if (fieldPokemon && fieldPokemon.id !== pokemon.id) {
|
if (fieldPokemon && fieldPokemon.id !== pokemon.id) {
|
||||||
[true, false].forEach(passive => applyOnLoseAbAttrs(fieldPokemon, passive));
|
// TODO: investigate whether we can just remove the foreach and call `applyAbAttrs` directly, providing
|
||||||
|
// the appropriate attributes (preLEaveField and IllusionBreak)
|
||||||
|
[true, false].forEach(passive => applyOnLoseAbAttrs({ pokemon: fieldPokemon, passive }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,7 +621,7 @@ export class FlinchedTag extends BattlerTag {
|
|||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
applyAbAttrs("FlinchEffectAbAttr", pokemon, null);
|
applyAbAttrs("FlinchEffectAbAttr", { pokemon });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,7 +916,7 @@ export class SeedTag extends BattlerTag {
|
|||||||
const source = pokemon.getOpponents().find(o => o.getBattlerIndex() === this.sourceIndex);
|
const source = pokemon.getOpponents().find(o => o.getBattlerIndex() === this.sourceIndex);
|
||||||
if (source) {
|
if (source) {
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
globalScene.phaseManager.unshiftNew(
|
globalScene.phaseManager.unshiftNew(
|
||||||
@ -1006,7 +1006,7 @@ export class PowderTag extends BattlerTag {
|
|||||||
globalScene.phaseManager.unshiftNew("CommonAnimPhase", idx, idx, CommonAnim.POWDER);
|
globalScene.phaseManager.unshiftNew("CommonAnimPhase", idx, idx, CommonAnim.POWDER);
|
||||||
|
|
||||||
const cancelDamage = new BooleanHolder(false);
|
const cancelDamage = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelDamage);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled: cancelDamage });
|
||||||
if (!cancelDamage.value) {
|
if (!cancelDamage.value) {
|
||||||
pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
||||||
}
|
}
|
||||||
@ -1056,7 +1056,7 @@ export class NightmareTag extends BattlerTag {
|
|||||||
phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE); // TODO: Update animation type
|
phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE); // TODO: Update animation type
|
||||||
|
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
||||||
@ -1409,7 +1409,7 @@ export abstract class DamagingTrapTag extends TrappedTag {
|
|||||||
phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, this.commonAnim);
|
phaseManager.unshiftNew("CommonAnimPhase", pokemon.getBattlerIndex(), undefined, this.commonAnim);
|
||||||
|
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
||||||
@ -1642,7 +1642,7 @@ export class ContactDamageProtectedTag extends ContactProtectedTag {
|
|||||||
*/
|
*/
|
||||||
override onContact(attacker: Pokemon, user: Pokemon): void {
|
override onContact(attacker: Pokemon, user: Pokemon): void {
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", user, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon: user, cancelled });
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), {
|
attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), {
|
||||||
result: HitResult.INDIRECT,
|
result: HitResult.INDIRECT,
|
||||||
@ -2243,7 +2243,7 @@ export class SaltCuredTag extends BattlerTag {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
const pokemonSteelOrWater = pokemon.isOfType(PokemonType.STEEL) || pokemon.isOfType(PokemonType.WATER);
|
const pokemonSteelOrWater = pokemon.isOfType(PokemonType.STEEL) || pokemon.isOfType(PokemonType.WATER);
|
||||||
@ -2297,7 +2297,7 @@ export class CursedTag extends BattlerTag {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
||||||
@ -2632,7 +2632,7 @@ export class GulpMissileTag extends BattlerTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", attacker, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon: attacker, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), { result: HitResult.INDIRECT });
|
attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), { result: HitResult.INDIRECT });
|
||||||
@ -3021,14 +3021,7 @@ export class MysteryEncounterPostSummonTag extends BattlerTag {
|
|||||||
const ret = super.lapse(pokemon, lapseType);
|
const ret = super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||||
const cancelled = new BooleanHolder(false);
|
pokemon.mysteryEncounterBattleEffects?.(pokemon);
|
||||||
applyAbAttrs("ProtectStatAbAttr", pokemon, cancelled);
|
|
||||||
applyAbAttrs("ConditionalUserFieldProtectStatAbAttr", pokemon, cancelled, false, pokemon);
|
|
||||||
if (!cancelled.value) {
|
|
||||||
if (pokemon.mysteryEncounterBattleEffects) {
|
|
||||||
pokemon.mysteryEncounterBattleEffects(pokemon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -14,7 +14,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase {
|
|||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
pokemon.resetBattleAndWaveData();
|
pokemon.resetBattleAndWaveData();
|
||||||
if (pokemon.isOnField()) {
|
if (pokemon.isOnField()) {
|
||||||
applyAbAttrs("PostBiomeChangeAbAttr", pokemon, null);
|
applyAbAttrs("PostBiomeChangeAbAttr", { pokemon });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import type Pokemon from "#app/field/pokemon";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
import { PokemonPhase } from "./pokemon-phase";
|
||||||
import { SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms/form-change-triggers";
|
import { SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms/form-change-triggers";
|
||||||
import { applyPostSetStatusAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
import { applyAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
||||||
import { isNullOrUndefined } from "#app/utils/common";
|
import { isNullOrUndefined } from "#app/utils/common";
|
||||||
|
|
||||||
export class ObtainStatusEffectPhase extends PokemonPhase {
|
export class ObtainStatusEffectPhase extends PokemonPhase {
|
||||||
@ -53,7 +53,11 @@ export class ObtainStatusEffectPhase extends PokemonPhase {
|
|||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeStatusEffectTrigger, true);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeStatusEffectTrigger, true);
|
||||||
// If mold breaker etc was used to set this status, it shouldn't apply to abilities activated afterwards
|
// If mold breaker etc was used to set this status, it shouldn't apply to abilities activated afterwards
|
||||||
globalScene.arena.setIgnoreAbilities(false);
|
globalScene.arena.setIgnoreAbilities(false);
|
||||||
applyPostSetStatusAbAttrs("PostSetStatusAbAttr", pokemon, this.statusEffect, this.sourcePokemon);
|
applyAbAttrs("PostSetStatusAbAttr", {
|
||||||
|
pokemon,
|
||||||
|
effect: this.statusEffect,
|
||||||
|
sourcePokemon: this.sourcePokemon ?? undefined,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.end();
|
this.end();
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { applyPostSummonAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
import { applyAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
||||||
import { PostSummonPhase } from "#app/phases/post-summon-phase";
|
import { PostSummonPhase } from "#app/phases/post-summon-phase";
|
||||||
import type { BattlerIndex } from "#enums/battler-index";
|
import type { BattlerIndex } from "#enums/battler-index";
|
||||||
|
|
||||||
@ -16,7 +16,8 @@ export class PostSummonActivateAbilityPhase extends PostSummonPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
applyPostSummonAbAttrs("PostSummonAbAttr", this.getPokemon(), this.passive, false);
|
// TODO: Check with Dean on whether or not passive must be provided to `this.passive`
|
||||||
|
applyAbAttrs("PostSummonAbAttr", { pokemon: this.getPokemon(), passive: this.passive });
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export class PostSummonPhase extends PokemonPhase {
|
|||||||
|
|
||||||
const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||||
for (const p of field) {
|
for (const p of field) {
|
||||||
applyAbAttrs("CommanderAbAttr", p, null, false);
|
applyAbAttrs("CommanderAbAttr", { pokemon: p });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { BattlerIndex } from "#enums/battler-index";
|
import type { BattlerIndex } from "#enums/battler-index";
|
||||||
import { applyAbAttrs, applyPostDamageAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
import { applyAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
||||||
import { CommonBattleAnim } from "#app/data/battle-anims";
|
import { CommonBattleAnim } from "#app/data/battle-anims";
|
||||||
import { CommonAnim } from "#enums/move-anims-common";
|
import { CommonAnim } from "#enums/move-anims-common";
|
||||||
import { getStatusEffectActivationText } from "#app/data/status-effect";
|
import { getStatusEffectActivationText } from "#app/data/status-effect";
|
||||||
@ -22,8 +22,8 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
|||||||
if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn() && !pokemon.switchOutStatus) {
|
if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn() && !pokemon.switchOutStatus) {
|
||||||
pokemon.status.incrementTurn();
|
pokemon.status.incrementTurn();
|
||||||
const cancelled = new BooleanHolder(false);
|
const cancelled = new BooleanHolder(false);
|
||||||
applyAbAttrs("BlockNonDirectDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockNonDirectDamageAbAttr", { pokemon, cancelled });
|
||||||
applyAbAttrs("BlockStatusDamageAbAttr", pokemon, cancelled);
|
applyAbAttrs("BlockStatusDamageAbAttr", { pokemon, cancelled });
|
||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
globalScene.phaseManager.queueMessage(
|
globalScene.phaseManager.queueMessage(
|
||||||
@ -39,14 +39,14 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
|||||||
break;
|
break;
|
||||||
case StatusEffect.BURN:
|
case StatusEffect.BURN:
|
||||||
damage.value = Math.max(pokemon.getMaxHp() >> 4, 1);
|
damage.value = Math.max(pokemon.getMaxHp() >> 4, 1);
|
||||||
applyAbAttrs("ReduceBurnDamageAbAttr", pokemon, null, false, damage);
|
applyAbAttrs("ReduceBurnDamageAbAttr", { pokemon, burnDamage: damage });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (damage.value) {
|
if (damage.value) {
|
||||||
// Set preventEndure flag to avoid pokemon surviving thanks to focus band, sturdy, endure ...
|
// Set preventEndure flag to avoid pokemon surviving thanks to focus band, sturdy, endure ...
|
||||||
globalScene.damageNumberHandler.add(this.getPokemon(), pokemon.damage(damage.value, false, true));
|
globalScene.damageNumberHandler.add(this.getPokemon(), pokemon.damage(damage.value, false, true));
|
||||||
pokemon.updateInfo();
|
pokemon.updateInfo();
|
||||||
applyPostDamageAbAttrs("PostDamageAbAttr", pokemon, damage.value, pokemon.hasPassive(), false, []);
|
applyAbAttrs("PostDamageAbAttr", { pokemon, damage: damage.value });
|
||||||
}
|
}
|
||||||
new CommonBattleAnim(CommonAnim.POISON + (pokemon.status.effect - 1), pokemon).play(false, () => this.end());
|
new CommonBattleAnim(CommonAnim.POISON + (pokemon.status.effect - 1), pokemon).play(false, () => this.end());
|
||||||
} else {
|
} else {
|
||||||
|
@ -181,9 +181,10 @@ export class QuietFormChangePhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.formChange.trigger instanceof SpeciesFormChangeTeraTrigger) {
|
if (this.formChange.trigger instanceof SpeciesFormChangeTeraTrigger) {
|
||||||
applyAbAttrs("PostTeraFormChangeStatChangeAbAttr", this.pokemon, null);
|
const params = { pokemon: this.pokemon };
|
||||||
applyAbAttrs("ClearWeatherAbAttr", this.pokemon, null);
|
applyAbAttrs("PostTeraFormChangeStatChangeAbAttr", params);
|
||||||
applyAbAttrs("ClearTerrainAbAttr", this.pokemon, null);
|
applyAbAttrs("ClearWeatherAbAttr", params);
|
||||||
|
applyAbAttrs("ClearTerrainAbAttr", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.end();
|
super.end();
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { BattlerIndex } from "#enums/battler-index";
|
import type { BattlerIndex } from "#enums/battler-index";
|
||||||
import {
|
import { applyAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
||||||
applyAbAttrs,
|
|
||||||
applyPostStatStageChangeAbAttrs,
|
|
||||||
applyPreStatStageChangeAbAttrs,
|
|
||||||
} from "#app/data/abilities/apply-ab-attrs";
|
|
||||||
import { MistTag } from "#app/data/arena-tag";
|
import { MistTag } from "#app/data/arena-tag";
|
||||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||||
import type { ArenaTag } from "#app/data/arena-tag";
|
import type { ArenaTag } from "#app/data/arena-tag";
|
||||||
@ -18,6 +14,10 @@ import { PokemonPhase } from "./pokemon-phase";
|
|||||||
import { Stat, type BattleStat, getStatKey, getStatStageChangeDescriptionKey } from "#enums/stat";
|
import { Stat, type BattleStat, getStatKey, getStatStageChangeDescriptionKey } from "#enums/stat";
|
||||||
import { OctolockTag } from "#app/data/battler-tags";
|
import { OctolockTag } from "#app/data/battler-tags";
|
||||||
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
||||||
|
import type {
|
||||||
|
ConditionalUserFieldProtectStatAbAttrParams,
|
||||||
|
PreStatStageChangeAbAttrParams,
|
||||||
|
} from "#app/@types/ability-types";
|
||||||
|
|
||||||
export type StatStageChangeCallback = (
|
export type StatStageChangeCallback = (
|
||||||
target: Pokemon | null,
|
target: Pokemon | null,
|
||||||
@ -126,7 +126,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
|||||||
const stages = new NumberHolder(this.stages);
|
const stages = new NumberHolder(this.stages);
|
||||||
|
|
||||||
if (!this.ignoreAbilities) {
|
if (!this.ignoreAbilities) {
|
||||||
applyAbAttrs("StatStageChangeMultiplierAbAttr", pokemon, null, false, stages);
|
applyAbAttrs("StatStageChangeMultiplierAbAttr", { pokemon, numStages: stages });
|
||||||
}
|
}
|
||||||
|
|
||||||
let simulate = false;
|
let simulate = false;
|
||||||
@ -146,42 +146,38 @@ export class StatStageChangePhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!cancelled.value && !this.selfTarget && stages.value < 0) {
|
if (!cancelled.value && !this.selfTarget && stages.value < 0) {
|
||||||
applyPreStatStageChangeAbAttrs("ProtectStatAbAttr", pokemon, stat, cancelled, simulate);
|
const abAttrParams: PreStatStageChangeAbAttrParams & ConditionalUserFieldProtectStatAbAttrParams = {
|
||||||
applyPreStatStageChangeAbAttrs(
|
|
||||||
"ConditionalUserFieldProtectStatAbAttr",
|
|
||||||
pokemon,
|
pokemon,
|
||||||
stat,
|
stat,
|
||||||
cancelled,
|
cancelled,
|
||||||
simulate,
|
simulated: simulate,
|
||||||
pokemon,
|
target: pokemon,
|
||||||
);
|
stages: this.stages,
|
||||||
|
};
|
||||||
|
applyAbAttrs("ProtectStatAbAttr", abAttrParams);
|
||||||
|
applyAbAttrs("ConditionalUserFieldProtectStatAbAttr", abAttrParams);
|
||||||
|
// TODO: Consider skipping this call if `cancelled` is false.
|
||||||
const ally = pokemon.getAlly();
|
const ally = pokemon.getAlly();
|
||||||
if (!isNullOrUndefined(ally)) {
|
if (!isNullOrUndefined(ally)) {
|
||||||
applyPreStatStageChangeAbAttrs(
|
applyAbAttrs("ConditionalUserFieldProtectStatAbAttr", { ...abAttrParams, pokemon: ally });
|
||||||
"ConditionalUserFieldProtectStatAbAttr",
|
|
||||||
ally,
|
|
||||||
stat,
|
|
||||||
cancelled,
|
|
||||||
simulate,
|
|
||||||
pokemon,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Potential stat reflection due to Mirror Armor, does not apply to Octolock end of turn effect */
|
/** Potential stat reflection due to Mirror Armor, does not apply to Octolock end of turn effect */
|
||||||
if (
|
if (
|
||||||
opponentPokemon !== undefined &&
|
opponentPokemon !== undefined &&
|
||||||
|
// TODO: investigate whether this is stoping mirror armor from applying to non-octolock
|
||||||
|
// reasons for stat drops if the user has the Octolock tag
|
||||||
!pokemon.findTag(t => t instanceof OctolockTag) &&
|
!pokemon.findTag(t => t instanceof OctolockTag) &&
|
||||||
!this.comingFromMirrorArmorUser
|
!this.comingFromMirrorArmorUser
|
||||||
) {
|
) {
|
||||||
applyPreStatStageChangeAbAttrs(
|
applyAbAttrs("ReflectStatStageChangeAbAttr", {
|
||||||
"ReflectStatStageChangeAbAttr",
|
|
||||||
pokemon,
|
pokemon,
|
||||||
stat,
|
stat,
|
||||||
cancelled,
|
cancelled,
|
||||||
simulate,
|
simulated: simulate,
|
||||||
opponentPokemon,
|
source: opponentPokemon,
|
||||||
this.stages,
|
stages: this.stages,
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,17 +218,16 @@ export class StatStageChangePhase extends PokemonPhase {
|
|||||||
|
|
||||||
if (stages.value > 0 && this.canBeCopied) {
|
if (stages.value > 0 && this.canBeCopied) {
|
||||||
for (const opponent of pokemon.getOpponents()) {
|
for (const opponent of pokemon.getOpponents()) {
|
||||||
applyAbAttrs("StatStageChangeCopyAbAttr", opponent, null, false, this.stats, stages.value);
|
applyAbAttrs("StatStageChangeCopyAbAttr", { pokemon: opponent, stats: this.stats, numStages: stages.value });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostStatStageChangeAbAttrs(
|
applyAbAttrs("PostStatStageChangeAbAttr", {
|
||||||
"PostStatStageChangeAbAttr",
|
|
||||||
pokemon,
|
pokemon,
|
||||||
filteredStats,
|
stats: filteredStats,
|
||||||
this.stages,
|
stages: this.stages,
|
||||||
this.selfTarget,
|
selfTarget: this.selfTarget,
|
||||||
);
|
});
|
||||||
|
|
||||||
// Look for any other stat change phases; if this is the last one, do White Herb check
|
// Look for any other stat change phases; if this is the last one, do White Herb check
|
||||||
const existingPhase = globalScene.phaseManager.findPhase(
|
const existingPhase = globalScene.phaseManager.findPhase(
|
||||||
|
Loading…
Reference in New Issue
Block a user