adding immunity check

This commit is contained in:
PrabbyDD 2024-09-19 13:39:40 -07:00
parent 0567d4b5e2
commit 60dd2a254f
2 changed files with 17 additions and 5 deletions

View File

@ -353,6 +353,10 @@ export class TypeImmunityAbAttr extends PreDefendAbAttr {
return false; return false;
} }
getImmuneType(): Type | null {
return this.immuneType;
}
override getCondition(): AbAttrCondition | null { override getCondition(): AbAttrCondition | null {
return this.condition; return this.condition;
} }

View File

@ -1,6 +1,6 @@
import BattleScene from "#app/battle-scene"; import BattleScene from "#app/battle-scene";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, applyPostDefendAbAttrs, PostDefendAbAttr, applyPostAttackAbAttrs, PostAttackAbAttr, MaxMultiHitAbAttr, AlwaysHitAbAttr } from "#app/data/ability"; import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, applyPostDefendAbAttrs, PostDefendAbAttr, applyPostAttackAbAttrs, PostAttackAbAttr, MaxMultiHitAbAttr, AlwaysHitAbAttr, TypeImmunityAbAttr } from "#app/data/ability";
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag"; import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
import { MoveAnim } from "#app/data/battle-anims"; import { MoveAnim } from "#app/data/battle-anims";
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags"; import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags";
@ -97,12 +97,17 @@ export class MoveEffectPhase extends PokemonPhase {
*/ */
const targetHitChecks = Object.fromEntries(targets.map(p => [p.getBattlerIndex(), this.hitCheck(p)])); const targetHitChecks = Object.fromEntries(targets.map(p => [p.getBattlerIndex(), this.hitCheck(p)]));
const hasActiveTargets = targets.some(t => t.isActive(true)); const hasActiveTargets = targets.some(t => t.isActive(true));
/** Check if the target is immune via ability */
const isImmune = targets[0].hasAbilityWithAttr(TypeImmunityAbAttr) && targets[0].getAbility().getAttrs(TypeImmunityAbAttr)[0].getImmuneType() === user.getMoveType(move);
/** /**
* If no targets are left for the move to hit (FAIL), or the invoked move is single-target * If no targets are left for the move to hit (FAIL), or the invoked move is single-target
* (and not random target) and failed the hit check against its target (MISS), log the move * (and not random target) and failed the hit check against its target (MISS), log the move
* as FAILed or MISSed (depending on the conditions above) and end this phase. * as FAILed or MISSed (depending on the conditions above) and end this phase.
*/ */
if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag))) {
if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag) && !isImmune)) {
this.stopMultiHit(); this.stopMultiHit();
if (hasActiveTargets) { if (hasActiveTargets) {
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget()? getPokemonNameWithAffix(this.getTarget()!) : "" })); this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget()? getPokemonNameWithAffix(this.getTarget()!) : "" }));
@ -132,7 +137,7 @@ export class MoveEffectPhase extends PokemonPhase {
const hasConditionalProtectApplied = new Utils.BooleanHolder(false); const hasConditionalProtectApplied = new Utils.BooleanHolder(false);
/** Does the applied conditional protection bypass Protect-ignoring effects? */ /** Does the applied conditional protection bypass Protect-ignoring effects? */
const bypassIgnoreProtect = new Utils.BooleanHolder(false); const bypassIgnoreProtect = new Utils.BooleanHolder(false);
// If the move is not targeting a Pokemon on the user's side, try to apply conditional protection effects /** If the move is not targeting a Pokemon on the user's side, try to apply conditional protection effects */
if (!this.move.getMove().isAllyTarget()) { if (!this.move.getMove().isAllyTarget()) {
this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect); this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect);
} }
@ -142,11 +147,14 @@ export class MoveEffectPhase extends PokemonPhase {
&& (hasConditionalProtectApplied.value || (!target.findTags(t => t instanceof DamageProtectedTag).length && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType))) && (hasConditionalProtectApplied.value || (!target.findTags(t => t instanceof DamageProtectedTag).length && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType)))
|| (this.move.getMove().category !== MoveCategory.STATUS && target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType)))); || (this.move.getMove().category !== MoveCategory.STATUS && target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType))));
/** Is the pokemon immune due to an ablility? */
const isImmune = target.hasAbilityWithAttr(TypeImmunityAbAttr) && target.getAbility().getAttrs(TypeImmunityAbAttr)[0].getImmuneType() === user.getMoveType(move);
/** /**
* If the move missed a target, stop all future hits against that target * If the move missed a target, stop all future hits against that target
* and move on to the next target (if there is one). * and move on to the next target (if there is one).
*/ */
if (!isProtected && !targetHitChecks[target.getBattlerIndex()]) { if (!isImmune && !isProtected && !targetHitChecks[target.getBattlerIndex()]) {
this.stopMultiHit(target); this.stopMultiHit(target);
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) })); this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
if (moveHistoryEntry.result === MoveResult.PENDING) { if (moveHistoryEntry.result === MoveResult.PENDING) {
@ -407,7 +415,7 @@ export class MoveEffectPhase extends PokemonPhase {
const accuracyMultiplier = user.getAccuracyMultiplier(target, this.move.getMove()); const accuracyMultiplier = user.getAccuracyMultiplier(target, this.move.getMove());
const rand = user.randSeedInt(100); const rand = user.randSeedInt(100);
return rand < (moveAccuracy * accuracyMultiplier); return rand < accuracyMultiplier * moveAccuracy;
} }
/** Returns the {@linkcode Pokemon} using this phase's invoked move */ /** Returns the {@linkcode Pokemon} using this phase's invoked move */