mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 14:02:18 +02:00
[Bug] Fix critical hits not bypassing screens (#5470)
This commit is contained in:
parent
ba617ad91b
commit
7a9b1e5033
@ -2886,7 +2886,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
/** Reduces damage if this Pokemon has a relevant screen (e.g. Light Screen for special attacks) */
|
/** Reduces damage if this Pokemon has a relevant screen (e.g. Light Screen for special attacks) */
|
||||||
const screenMultiplier = new Utils.NumberHolder(1);
|
const screenMultiplier = new Utils.NumberHolder(1);
|
||||||
globalScene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, simulated, source, moveCategory, screenMultiplier);
|
|
||||||
|
// Critical hits should bypass screens
|
||||||
|
if (!isCritical) {
|
||||||
|
globalScene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, simulated, source, moveCategory, screenMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For each {@linkcode HitsTagAttr} the move has, doubles the damage of the move if:
|
* For each {@linkcode HitsTagAttr} the move has, doubles the damage of the move if:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type BattleScene from "#app/battle-scene";
|
import type BattleScene from "#app/battle-scene";
|
||||||
import { ArenaTagSide } from "#app/data/arena-tag";
|
import { ArenaTagSide } from "#app/data/arena-tag";
|
||||||
import type Move from "#app/data/move";
|
import type Move from "#app/data/move";
|
||||||
import { allMoves } from "#app/data/move";
|
import { allMoves, CritOnlyAttr } from "#app/data/move";
|
||||||
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
||||||
@ -12,7 +12,7 @@ import { Species } from "#enums/species";
|
|||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
let globalScene: BattleScene;
|
let globalScene: BattleScene;
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ describe("Moves - Aurora Veil", () => {
|
|||||||
|
|
||||||
it("reduces damage of physical attacks by half in a single battle", async () => {
|
it("reduces damage of physical attacks by half in a single battle", async () => {
|
||||||
const moveToUse = Moves.TACKLE;
|
const moveToUse = Moves.TACKLE;
|
||||||
await game.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ describe("Moves - Aurora Veil", () => {
|
|||||||
game.override.battleType("double");
|
game.override.battleType("double");
|
||||||
|
|
||||||
const moveToUse = Moves.ROCK_SLIDE;
|
const moveToUse = Moves.ROCK_SLIDE;
|
||||||
await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
game.move.select(moveToUse, 1);
|
game.move.select(moveToUse, 1);
|
||||||
@ -74,7 +74,7 @@ describe("Moves - Aurora Veil", () => {
|
|||||||
|
|
||||||
it("reduces damage of special attacks by half in a single battle", async () => {
|
it("reduces damage of special attacks by half in a single battle", async () => {
|
||||||
const moveToUse = Moves.ABSORB;
|
const moveToUse = Moves.ABSORB;
|
||||||
await game.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ describe("Moves - Aurora Veil", () => {
|
|||||||
game.override.battleType("double");
|
game.override.battleType("double");
|
||||||
|
|
||||||
const moveToUse = Moves.DAZZLING_GLEAM;
|
const moveToUse = Moves.DAZZLING_GLEAM;
|
||||||
await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
game.move.select(moveToUse, 1);
|
game.move.select(moveToUse, 1);
|
||||||
@ -99,6 +99,31 @@ describe("Moves - Aurora Veil", () => {
|
|||||||
|
|
||||||
expect(mockedDmg).toBe(allMoves[moveToUse].power * doubleBattleMultiplier);
|
expect(mockedDmg).toBe(allMoves[moveToUse].power * doubleBattleMultiplier);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not affect physical critical hits", async () => {
|
||||||
|
game.override.moveset([ Moves.WICKED_BLOW ]);
|
||||||
|
const moveToUse = Moves.WICKED_BLOW;
|
||||||
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
|
game.move.select(moveToUse);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||||
|
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not affect critical hits", async () => {
|
||||||
|
game.override.moveset([ Moves.FROST_BREATH ]);
|
||||||
|
const moveToUse = Moves.FROST_BREATH;
|
||||||
|
vi.spyOn(allMoves[Moves.FROST_BREATH], "accuracy", "get").mockReturnValue(100);
|
||||||
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
|
game.move.select(moveToUse);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||||
|
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,7 +140,9 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
|||||||
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
|
|
||||||
if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) {
|
if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) {
|
||||||
globalScene.arena.applyTagsForSide(ArenaTagType.AURORA_VEIL, side, false, attacker, move.category, multiplierHolder);
|
if (move.getAttrs(CritOnlyAttr).length === 0) {
|
||||||
|
globalScene.arena.applyTagsForSide(ArenaTagType.AURORA_VEIL, side, false, attacker, move.category, multiplierHolder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return move.power * multiplierHolder.value;
|
return move.power * multiplierHolder.value;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type BattleScene from "#app/battle-scene";
|
import type BattleScene from "#app/battle-scene";
|
||||||
import { ArenaTagSide } from "#app/data/arena-tag";
|
import { ArenaTagSide } from "#app/data/arena-tag";
|
||||||
import type Move from "#app/data/move";
|
import type Move from "#app/data/move";
|
||||||
import { allMoves } from "#app/data/move";
|
import { allMoves, CritOnlyAttr } from "#app/data/move";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
@ -11,7 +11,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
let globalScene: BattleScene;
|
let globalScene: BattleScene;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ describe("Moves - Light Screen", () => {
|
|||||||
|
|
||||||
it("reduces damage of special attacks by half in a single battle", async () => {
|
it("reduces damage of special attacks by half in a single battle", async () => {
|
||||||
const moveToUse = Moves.ABSORB;
|
const moveToUse = Moves.ABSORB;
|
||||||
await game.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ describe("Moves - Light Screen", () => {
|
|||||||
game.override.battleType("double");
|
game.override.battleType("double");
|
||||||
|
|
||||||
const moveToUse = Moves.DAZZLING_GLEAM;
|
const moveToUse = Moves.DAZZLING_GLEAM;
|
||||||
await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
game.move.select(moveToUse, 1);
|
game.move.select(moveToUse, 1);
|
||||||
@ -73,7 +73,7 @@ describe("Moves - Light Screen", () => {
|
|||||||
|
|
||||||
it("does not affect physical attacks", async () => {
|
it("does not affect physical attacks", async () => {
|
||||||
const moveToUse = Moves.TACKLE;
|
const moveToUse = Moves.TACKLE;
|
||||||
await game.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
|
|
||||||
@ -82,6 +82,19 @@ describe("Moves - Light Screen", () => {
|
|||||||
|
|
||||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not affect critical hits", async () => {
|
||||||
|
game.override.moveset([ Moves.FROST_BREATH ]);
|
||||||
|
const moveToUse = Moves.FROST_BREATH;
|
||||||
|
vi.spyOn(allMoves[Moves.FROST_BREATH], "accuracy", "get").mockReturnValue(100);
|
||||||
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
|
game.move.select(moveToUse);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||||
|
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,7 +111,9 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
|||||||
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
|
|
||||||
if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) {
|
if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) {
|
||||||
globalScene.arena.applyTagsForSide(ArenaTagType.LIGHT_SCREEN, side, false, attacker, move.category, multiplierHolder);
|
if (move.getAttrs(CritOnlyAttr).length === 0) {
|
||||||
|
globalScene.arena.applyTagsForSide(ArenaTagType.LIGHT_SCREEN, side, false, attacker, move.category, multiplierHolder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return move.power * multiplierHolder.value;
|
return move.power * multiplierHolder.value;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type BattleScene from "#app/battle-scene";
|
import type BattleScene from "#app/battle-scene";
|
||||||
import { ArenaTagSide } from "#app/data/arena-tag";
|
import { ArenaTagSide } from "#app/data/arena-tag";
|
||||||
import type Move from "#app/data/move";
|
import type Move from "#app/data/move";
|
||||||
import { allMoves } from "#app/data/move";
|
import { allMoves, CritOnlyAttr } from "#app/data/move";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
import { ArenaTagType } from "#app/enums/arena-tag-type";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
@ -45,7 +45,7 @@ describe("Moves - Reflect", () => {
|
|||||||
|
|
||||||
it("reduces damage of physical attacks by half in a single battle", async () => {
|
it("reduces damage of physical attacks by half in a single battle", async () => {
|
||||||
const moveToUse = Moves.TACKLE;
|
const moveToUse = Moves.TACKLE;
|
||||||
await game.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ describe("Moves - Reflect", () => {
|
|||||||
game.override.battleType("double");
|
game.override.battleType("double");
|
||||||
|
|
||||||
const moveToUse = Moves.ROCK_SLIDE;
|
const moveToUse = Moves.ROCK_SLIDE;
|
||||||
await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
game.move.select(moveToUse, 1);
|
game.move.select(moveToUse, 1);
|
||||||
@ -72,7 +72,7 @@ describe("Moves - Reflect", () => {
|
|||||||
|
|
||||||
it("does not affect special attacks", async () => {
|
it("does not affect special attacks", async () => {
|
||||||
const moveToUse = Moves.ABSORB;
|
const moveToUse = Moves.ABSORB;
|
||||||
await game.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse);
|
||||||
|
|
||||||
@ -82,6 +82,18 @@ describe("Moves - Reflect", () => {
|
|||||||
|
|
||||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not affect critical hits", async () => {
|
||||||
|
game.override.moveset([ Moves.WICKED_BLOW ]);
|
||||||
|
const moveToUse = Moves.WICKED_BLOW;
|
||||||
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
|
game.move.select(moveToUse);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||||
|
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,7 +110,9 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
|||||||
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
|
|
||||||
if (globalScene.arena.getTagOnSide(ArenaTagType.REFLECT, side)) {
|
if (globalScene.arena.getTagOnSide(ArenaTagType.REFLECT, side)) {
|
||||||
globalScene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder);
|
if (move.getAttrs(CritOnlyAttr).length === 0) {
|
||||||
|
globalScene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return move.power * multiplierHolder.value;
|
return move.power * multiplierHolder.value;
|
||||||
|
Loading…
Reference in New Issue
Block a user