Semi-Invulnerable Hit Checks Count as Miss (#904)

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
This commit is contained in:
Benjamin Odom 2024-05-16 02:05:36 -05:00 committed by GitHub
parent 77cfa58078
commit 8508ee7bc6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 10 deletions

View File

@ -2270,12 +2270,8 @@ export class MovePhase extends BattlePhase {
} }
const targets = this.scene.getField(true).filter(p => { const targets = this.scene.getField(true).filter(p => {
if (this.targets.indexOf(p.getBattlerIndex()) > -1) { 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;
return true; return true;
}
return false; return false;
}); });
@ -2316,10 +2312,17 @@ export class MovePhase extends BattlePhase {
if (this.move.moveId) if (this.move.moveId)
this.showMoveText(); this.showMoveText();
if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || (!targets.length && !this.move.getMove().getAttrs(SacrificialAttr).length)) { // This should only happen when there are no valid targets left on the field
moveQueue.shift(); if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) {
this.showFailedText();
this.cancel(); 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.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(); return this.end();
} }
@ -2590,13 +2593,14 @@ export class MoveEffectPhase extends PokemonPhase {
if (user.hasAbilityWithAttr(AlwaysHitAbAttr) || target.hasAbilityWithAttr(AlwaysHitAbAttr)) if (user.hasAbilityWithAttr(AlwaysHitAbAttr) || target.hasAbilityWithAttr(AlwaysHitAbAttr))
return true; 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); const hiddenTag = target.getTag(HiddenTag);
if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length) if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length)
return false; 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); const moveAccuracy = new Utils.NumberHolder(this.move.getMove().accuracy);
applyMoveAttrs(VariableAccuracyAttr, user, target, this.move.getMove(), moveAccuracy); applyMoveAttrs(VariableAccuracyAttr, user, target, this.move.getMove(), moveAccuracy);