mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2024-11-29 18:26:09 +00:00
Substitute now blocks all target-facing secondary effects
This commit is contained in:
parent
f421b5d5a6
commit
1e8cbc9d3c
@ -683,7 +683,7 @@ export class ReverseDrainAbAttr extends PostDefendAbAttr {
|
|||||||
* @returns true if healing should be reversed on a healing move, false otherwise.
|
* @returns true if healing should be reversed on a healing move, false otherwise.
|
||||||
*/
|
*/
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.hasAttr(HitHealAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (move.hasAttr(HitHealAttr)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
|
||||||
}
|
}
|
||||||
@ -711,7 +711,7 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (this.condition(pokemon, attacker, move)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -753,7 +753,7 @@ export class PostDefendHpGatedStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1];
|
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1];
|
||||||
const damageReceived = lastAttackReceived?.damage || 0;
|
const damageReceived = lastAttackReceived?.damage || 0;
|
||||||
|
|
||||||
if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
|
||||||
}
|
}
|
||||||
@ -776,7 +776,7 @@ export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (this.condition(pokemon, attacker, move)) {
|
||||||
const tag = pokemon.scene.arena.getTag(this.tagType) as ArenaTrapTag;
|
const tag = pokemon.scene.arena.getTag(this.tagType) as ArenaTrapTag;
|
||||||
if (!pokemon.scene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) {
|
if (!pokemon.scene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
@ -800,7 +800,7 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (this.condition(pokemon, attacker, move)) {
|
||||||
if (!pokemon.getTag(this.tagType) && !simulated) {
|
if (!pokemon.getTag(this.tagType) && !simulated) {
|
||||||
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
||||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
|
||||||
@ -813,7 +813,7 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
|
export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) {
|
if (hitResult < HitResult.NO_EFFECT) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -847,7 +847,7 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) {
|
if (hitResult < HitResult.NO_EFFECT) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return pokemon.scene.arena.terrain?.terrainType !== (this.terrainType || undefined);
|
return pokemon.scene.arena.terrain?.terrainType !== (this.terrainType || undefined);
|
||||||
} else {
|
} else {
|
||||||
@ -872,7 +872,7 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status
|
||||||
&& (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !move.hitsSubstitute(attacker, pokemon)) {
|
&& (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) {
|
||||||
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return attacker.canSetStatus(effect, true, false, pokemon);
|
return attacker.canSetStatus(effect, true, false, pokemon);
|
||||||
@ -912,7 +912,7 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance && !move.hitsSubstitute(attacker, pokemon)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return attacker.canAddTag(this.tagType);
|
return attacker.canAddTag(this.tagType);
|
||||||
} else {
|
} else {
|
||||||
@ -936,10 +936,6 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.hitsSubstitute(attacker, pokemon)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||||
}
|
}
|
||||||
@ -962,8 +958,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)
|
if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
||||||
&& !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
|
||||||
attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
|
attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
|
||||||
attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio));
|
attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio));
|
||||||
return true;
|
return true;
|
||||||
@ -996,7 +991,7 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
|
||||||
if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) {
|
if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -1027,7 +1022,7 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition && !this.condition(pokemon, attacker, move) || move.hitsSubstitute(attacker, pokemon)) {
|
if (this.condition && !this.condition(pokemon, attacker, move)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!pokemon.scene.arena.weather?.isImmutable()) {
|
if (!pokemon.scene.arena.weather?.isImmutable()) {
|
||||||
@ -1048,7 +1043,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)
|
||||||
&& !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
&& !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
const tempAbilityId = attacker.getAbility().id;
|
const tempAbilityId = attacker.getAbility().id;
|
||||||
attacker.summonData.ability = pokemon.getAbility().id;
|
attacker.summonData.ability = pokemon.getAbility().id;
|
||||||
@ -1075,7 +1070,7 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr)
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr)
|
||||||
&& !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
&& !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
attacker.summonData.ability = this.ability;
|
attacker.summonData.ability = this.ability;
|
||||||
}
|
}
|
||||||
@ -1106,7 +1101,7 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (attacker.getTag(BattlerTagType.DISABLED) === null && !move.hitsSubstitute(attacker, pokemon)) {
|
if (attacker.getTag(BattlerTagType.DISABLED) === null) {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return true;
|
return true;
|
||||||
@ -1694,7 +1689,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||||
if (pokemon !== attacker && move.hitsSubstitute(attacker, pokemon)) {
|
if (pokemon !== attacker) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1750,7 +1745,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): Promise<boolean> {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move)) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) {
|
||||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
||||||
if (heldItems.length) {
|
if (heldItems.length) {
|
||||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||||
@ -4668,7 +4663,7 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
|||||||
* @returns `true` if the immunity was applied.
|
* @returns `true` if the immunity was applied.
|
||||||
*/
|
*/
|
||||||
override applyPreDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
override applyPreDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
if (this.condition(pokemon, attacker, move)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
(args[0] as Utils.NumberHolder).value = this.multiplier;
|
(args[0] as Utils.NumberHolder).value = this.multiplier;
|
||||||
pokemon.removeTag(this.tagType);
|
pokemon.removeTag(this.tagType);
|
||||||
|
@ -2259,10 +2259,6 @@ export class StatusEffectAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
if (!this.selfTarget && move.hitsSubstitute(user, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
|
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
|
||||||
const statusCheck = moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance;
|
const statusCheck = moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance;
|
||||||
if (statusCheck) {
|
if (statusCheck) {
|
||||||
@ -2369,9 +2365,6 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
if (move.hitsSubstitute(user, target)) {
|
|
||||||
return resolve(false);
|
|
||||||
}
|
|
||||||
const rand = Phaser.Math.RND.realInRange(0, 1);
|
const rand = Phaser.Math.RND.realInRange(0, 1);
|
||||||
if (rand >= this.chance) {
|
if (rand >= this.chance) {
|
||||||
return resolve(false);
|
return resolve(false);
|
||||||
@ -2441,10 +2434,6 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (move.hitsSubstitute(user, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // Check for abilities that block item theft
|
applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // Check for abilities that block item theft
|
||||||
|
|
||||||
@ -2565,9 +2554,6 @@ export class StealEatBerryAttr extends EatBerryAttr {
|
|||||||
* @returns {boolean} true if the function succeeds
|
* @returns {boolean} true if the function succeeds
|
||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
if (move.hitsSubstitute(user, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // check for abilities that block item theft
|
applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // check for abilities that block item theft
|
||||||
if (cancelled.value === true) {
|
if (cancelled.value === true) {
|
||||||
@ -2618,10 +2604,6 @@ export class HealStatusEffectAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.selfTarget && move.hitsSubstitute(user, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special edge case for shield dust blocking Sparkling Aria curing burn
|
// Special edge case for shield dust blocking Sparkling Aria curing burn
|
||||||
const moveTargets = getMoveTargets(user, move.id);
|
const moveTargets = getMoveTargets(user, move.id);
|
||||||
if (target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && move.id === Moves.SPARKLING_ARIA && moveTargets.targets.length === 1) {
|
if (target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && move.id === Moves.SPARKLING_ARIA && moveTargets.targets.length === 1) {
|
||||||
@ -3013,10 +2995,6 @@ export class StatStageChangeAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.selfTarget && move.hitsSubstitute(user, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
|
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
|
||||||
if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) {
|
if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) {
|
||||||
const stages = this.getLevels(user);
|
const stages = this.getLevels(user);
|
||||||
@ -3388,10 +3366,8 @@ export class ResetStatsAttr extends MoveEffectAttr {
|
|||||||
activePokemon.forEach(p => promises.push(this.resetStats(p)));
|
activePokemon.forEach(p => promises.push(this.resetStats(p)));
|
||||||
target.scene.queueMessage(i18next.t("moveTriggers:statEliminated"));
|
target.scene.queueMessage(i18next.t("moveTriggers:statEliminated"));
|
||||||
} else { // Affects only the single target when Clear Smog is used
|
} else { // Affects only the single target when Clear Smog is used
|
||||||
if (!move.hitsSubstitute(user, target)) {
|
promises.push(this.resetStats(target));
|
||||||
promises.push(this.resetStats(target));
|
target.scene.queueMessage(i18next.t("moveTriggers:resetStats", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||||
target.scene.queueMessage(i18next.t("moveTriggers:resetStats", { pokemonName: getPokemonNameWithAffix(target) }));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
@ -5305,19 +5281,6 @@ export class LeechSeedAttr extends AddBattlerTagAttr {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super(BattlerTagType.SEEDED);
|
super(BattlerTagType.SEEDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a Seeding effect to the target if the target does not have an active Substitute.
|
|
||||||
* @param user the {@linkcode Pokemon} using the move
|
|
||||||
* @param target the {@linkcode Pokemon} targeted by the move
|
|
||||||
* @param move the {@linkcode Move} invoking this effect
|
|
||||||
* @param args n/a
|
|
||||||
* @returns `true` if the effect successfully applies; `false` otherwise
|
|
||||||
*/
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
|
||||||
return !move.hitsSubstitute(user, target)
|
|
||||||
&& super.apply(user, target, move, args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5470,9 +5433,6 @@ export class FlinchAttr extends AddBattlerTagAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
if (!move.hitsSubstitute(user, target)) {
|
|
||||||
return super.apply(user, target, move, args);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5490,9 +5450,6 @@ export class ConfuseAttr extends AddBattlerTagAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!move.hitsSubstitute(user, target)) {
|
|
||||||
return super.apply(user, target, move, args);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5882,7 +5839,7 @@ export class AddPledgeEffectAttr extends AddArenaTagAttr {
|
|||||||
* @see {@linkcode apply}
|
* @see {@linkcode apply}
|
||||||
*/
|
*/
|
||||||
export class RevivalBlessingAttr extends MoveEffectAttr {
|
export class RevivalBlessingAttr extends MoveEffectAttr {
|
||||||
constructor(user?: boolean) {
|
constructor() {
|
||||||
super(true);
|
super(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6063,10 +6020,6 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
const player = switchOutTarget instanceof PlayerPokemon;
|
const player = switchOutTarget instanceof PlayerPokemon;
|
||||||
|
|
||||||
if (!this.selfSwitch) {
|
if (!this.selfSwitch) {
|
||||||
if (move.hitsSubstitute(user, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dondozo with an allied Tatsugiri in its mouth cannot be forced out
|
// Dondozo with an allied Tatsugiri in its mouth cannot be forced out
|
||||||
const commandedTag = switchOutTarget.getTag(BattlerTagType.COMMANDED);
|
const commandedTag = switchOutTarget.getTag(BattlerTagType.COMMANDED);
|
||||||
if (commandedTag?.getSourcePokemon(switchOutTarget.scene)?.isActive(true)) {
|
if (commandedTag?.getSourcePokemon(switchOutTarget.scene)?.isActive(true)) {
|
||||||
|
@ -257,23 +257,10 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
return this.triggerMoveEffects(MoveEffectTrigger.PRE_APPLY, user, target).then(() => {
|
return this.triggerMoveEffects(MoveEffectTrigger.PRE_APPLY, user, target).then(() => {
|
||||||
const hitResult = this.applyMove(target, effectiveness);
|
const hitResult = this.applyMove(target, effectiveness);
|
||||||
|
|
||||||
/** Does {@linkcode hitResult} indicate that damage was dealt to the target? */
|
return this.triggerMoveEffects(MoveEffectTrigger.POST_APPLY, user, target, firstTarget, true)
|
||||||
const dealsDamage = [
|
.then(() => executeIf(!move.hitsSubstitute(user, target),
|
||||||
HitResult.EFFECTIVE,
|
() => this.applyOnTargetEffects(user, target, hitResult, firstTarget)))
|
||||||
HitResult.SUPER_EFFECTIVE,
|
|
||||||
HitResult.NOT_VERY_EFFECTIVE,
|
|
||||||
HitResult.ONE_HIT_KO
|
|
||||||
].includes(hitResult);
|
|
||||||
|
|
||||||
return this.triggerMoveEffects(MoveEffectTrigger.POST_APPLY, user, target, firstTarget)
|
|
||||||
.then(() => this.applyHeldItemFlinchCheck(user, target, dealsDamage))
|
|
||||||
.then(() => this.applyOnGetHitAbEffects(user, target, hitResult))
|
|
||||||
.then(() => applyPostAttackAbAttrs(PostAttackAbAttr, user, target, move, hitResult))
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (move instanceof AttackMove) {
|
|
||||||
this.scene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.lastHit) {
|
if (this.lastHit) {
|
||||||
this.scene.triggerPokemonFormChange(user, SpeciesFormChangePostMoveTrigger);
|
this.scene.triggerPokemonFormChange(user, SpeciesFormChangePostMoveTrigger);
|
||||||
}
|
}
|
||||||
@ -442,6 +429,28 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected applyOnTargetEffects(user: Pokemon, target: Pokemon, hitResult: HitResult, firstTarget: boolean): Promise<void | null> {
|
||||||
|
const move = this.move.getMove();
|
||||||
|
|
||||||
|
/** Does {@linkcode hitResult} indicate that damage was dealt to the target? */
|
||||||
|
const dealsDamage = [
|
||||||
|
HitResult.EFFECTIVE,
|
||||||
|
HitResult.SUPER_EFFECTIVE,
|
||||||
|
HitResult.NOT_VERY_EFFECTIVE,
|
||||||
|
HitResult.ONE_HIT_KO
|
||||||
|
].includes(hitResult);
|
||||||
|
|
||||||
|
return this.triggerMoveEffects(MoveEffectTrigger.POST_APPLY, user, target, firstTarget, false)
|
||||||
|
.then(() => this.applyHeldItemFlinchCheck(user, target, dealsDamage))
|
||||||
|
.then(() => this.applyOnGetHitAbEffects(user, target, hitResult))
|
||||||
|
.then(() => applyPostAttackAbAttrs(PostAttackAbAttr, user, target, move, hitResult))
|
||||||
|
.then(() => {
|
||||||
|
if (move instanceof AttackMove) {
|
||||||
|
this.scene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies reactive effects that occur when a Pokémon is hit.
|
* Applies reactive effects that occur when a Pokémon is hit.
|
||||||
@ -455,15 +464,11 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
return executeIf(!target.isFainted() || target.canApplyAbility(), () =>
|
return executeIf(!target.isFainted() || target.canApplyAbility(), () =>
|
||||||
applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult)
|
applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) {
|
||||||
if (!this.move.getMove().hitsSubstitute(user, target)) {
|
user.scene.applyShuffledModifiers(this.scene, EnemyAttackStatusEffectChanceModifier, false, target);
|
||||||
if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) {
|
|
||||||
user.scene.applyShuffledModifiers(this.scene, EnemyAttackStatusEffectChanceModifier, false, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
target.lapseTags(BattlerTagLapseType.AFTER_HIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target.lapseTags(BattlerTagLapseType.AFTER_HIT);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user