mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-17 22:02:18 +02:00
Obstruct et al no longer protect against status moves
This commit is contained in:
parent
7288350d45
commit
6da40f3e4a
@ -1180,6 +1180,8 @@ export class ProtectedTag extends BattlerTag {
|
||||
}
|
||||
}
|
||||
|
||||
export class DamageProtectedTag extends ProtectedTag {}
|
||||
|
||||
export class ContactDamageProtectedTag extends ProtectedTag {
|
||||
private damageRatio: number;
|
||||
|
||||
@ -1215,7 +1217,7 @@ export class ContactDamageProtectedTag extends ProtectedTag {
|
||||
}
|
||||
}
|
||||
|
||||
export class ContactStatStageChangeProtectedTag extends ProtectedTag {
|
||||
export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
|
||||
private stat: BattleStat;
|
||||
private levels: number;
|
||||
|
||||
@ -1271,7 +1273,7 @@ export class ContactPoisonProtectedTag extends ProtectedTag {
|
||||
}
|
||||
}
|
||||
|
||||
export class ContactBurnProtectedTag extends ProtectedTag {
|
||||
export class ContactBurnProtectedTag extends DamageProtectedTag {
|
||||
constructor(sourceMove: Moves) {
|
||||
super(sourceMove, BattlerTagType.BURNING_BULWARK);
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { BattlerIndex } from "#app/battle.js";
|
||||
import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, applyPostDefendAbAttrs, PostDefendAbAttr, applyPostAttackAbAttrs, PostAttackAbAttr, MaxMultiHitAbAttr, AlwaysHitAbAttr } from "#app/data/ability.js";
|
||||
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag.js";
|
||||
import { MoveAnim } from "#app/data/battle-anims.js";
|
||||
import { BattlerTagLapseType, ProtectedTag, SemiInvulnerableTag } from "#app/data/battler-tags.js";
|
||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr } from "#app/data/move.js";
|
||||
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms.js";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type.js";
|
||||
import { Moves } from "#app/enums/moves.js";
|
||||
import Pokemon, { PokemonMove, MoveResult, HitResult } from "#app/field/pokemon.js";
|
||||
import { getPokemonNameWithAffix } from "#app/messages.js";
|
||||
import { PokemonMultiHitModifier, FlinchChanceModifier, EnemyAttackStatusEffectChanceModifier, ContactHeldItemTransferChanceModifier, HitHealModifier } from "#app/modifier/modifier.js";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, applyPostDefendAbAttrs, PostDefendAbAttr, applyPostAttackAbAttrs, PostAttackAbAttr, MaxMultiHitAbAttr, AlwaysHitAbAttr } from "#app/data/ability";
|
||||
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
||||
import { MoveAnim } from "#app/data/battle-anims";
|
||||
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag } from "#app/data/battler-tags";
|
||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr } from "#app/data/move";
|
||||
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import Pokemon, { PokemonMove, MoveResult, HitResult } from "#app/field/pokemon";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { PokemonMultiHitModifier, FlinchChanceModifier, EnemyAttackStatusEffectChanceModifier, ContactHeldItemTransferChanceModifier, HitHealModifier } from "#app/modifier/modifier";
|
||||
import i18next from "i18next";
|
||||
import * as Utils from "#app/utils.js";
|
||||
import * as Utils from "#app/utils";
|
||||
import { PokemonPhase } from "./pokemon-phase";
|
||||
|
||||
export class MoveEffectPhase extends PokemonPhase {
|
||||
@ -152,7 +152,8 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
|
||||
/** Is the target protected by Protect, etc. or a relevant conditional protection effect? */
|
||||
const isProtected = (bypassIgnoreProtect.value || !this.move.getMove().checkFlag(MoveFlags.IGNORE_PROTECT, user, target))
|
||||
&& (hasConditionalProtectApplied.value || 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))));
|
||||
|
||||
/** Does this phase represent the invoked move's first strike? */
|
||||
const firstHit = (user.turnData.hitsLeft === user.turnData.hitCount);
|
||||
|
71
src/test/moves/obstruct.test.ts
Normal file
71
src/test/moves/obstruct.test.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import { Stat } from "#app/enums/stat.js";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Moves - Obstruct", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.battleType("single")
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.ability(Abilities.BALL_FETCH)
|
||||
.moveset([Moves.OBSTRUCT]);
|
||||
});
|
||||
|
||||
it("protects from contact damaging moves and lowers the opponent's defense by 2 stages", async () => {
|
||||
game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH));
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.OBSTRUCT);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
||||
expect(player.isFullHp()).toBe(true);
|
||||
expect(enemy.getStatStage(Stat.DEF)).toBe(-2);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => {
|
||||
game.override.enemyMoveset(Array(4).fill(Moves.WATER_GUN));
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.OBSTRUCT);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
||||
expect(player.isFullHp()).toBe(true);
|
||||
expect(enemy.getStatStage(Stat.DEF)).toBe(0);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("doesn't protect from status moves", async () => {
|
||||
game.override.enemyMoveset(Array(4).fill(Moves.GROWL));
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.OBSTRUCT);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
|
||||
expect(player.getStatStage(Stat.ATK)).toBe(-1);
|
||||
}, TIMEOUT);
|
||||
});
|
Loading…
Reference in New Issue
Block a user