From e7c35324050364210af450b87c4874d4e8c914ab Mon Sep 17 00:00:00 2001 From: Benjamin Odom Date: Wed, 15 May 2024 07:18:12 -0500 Subject: [PATCH] Semi-Invulnerable Hit Checks Count as Miss Fixed an issue where targeting the user of a Semi-Invulnerable move caused the move to cancel. These moves now miss instead. No Guard and other accuracy locking moves still function as they were already duplicating their check in hitCheck. Fixed an issue where IGNORE_ACCURACY was checking against the current move for targets instead of Lock-On's target --- src/phases.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/phases.ts b/src/phases.ts index a802582cb..831e1abee 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -2259,12 +2259,8 @@ export class MovePhase extends BattlePhase { } const targets = this.scene.getField(true).filter(p => { - if (this.targets.indexOf(p.getBattlerIndex()) > -1) { - const hiddenTag = p.getTag(HiddenTag); - if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length && !p.hasAbilityWithAttr(AlwaysHitAbAttr) && !this.pokemon.hasAbilityWithAttr(AlwaysHitAbAttr)) - return false; + if (this.targets.indexOf(p.getBattlerIndex()) > -1) return true; - } return false; }); @@ -2305,10 +2301,17 @@ export class MovePhase extends BattlePhase { if (this.move.moveId) this.showMoveText(); - if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || (!targets.length && !this.move.getMove().getAttrs(SacrificialAttr).length)) { - moveQueue.shift(); + // This should only happen when there are no valid targets left on the field + if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) { + this.showFailedText(); this.cancel(); + + // Record a failed move so Abilities like Truant don't trigger next turn and soft-lock this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL }); + + this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc. + + moveQueue.shift(); return this.end(); } @@ -2579,13 +2582,14 @@ export class MoveEffectPhase extends PokemonPhase { if (user.hasAbilityWithAttr(AlwaysHitAbAttr) || target.hasAbilityWithAttr(AlwaysHitAbAttr)) return true; + // If the user should ignore accuracy on a target, check who the user targeted last turn and see if they match + if (user.getTag(BattlerTagType.IGNORE_ACCURACY) && (user.getLastXMoves().slice(1).find(() => true)?.targets || []).indexOf(target.getBattlerIndex()) !== -1) + return true; + const hiddenTag = target.getTag(HiddenTag); if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length) return false; - if (user.getTag(BattlerTagType.IGNORE_ACCURACY) && (user.getLastXMoves().find(() => true)?.targets || []).indexOf(target.getBattlerIndex()) > -1) - return true; - const moveAccuracy = new Utils.NumberHolder(this.move.getMove().accuracy); applyMoveAttrs(VariableAccuracyAttr, user, target, this.move.getMove(), moveAccuracy);