[Bug] Fixed OHKO moves being affected by accuracy and evasion battle stats (#3117)

* Fixed OHKO moves being affected by accuracy and evasion battle stats

* Added related tests for Fissure, unskipped related test for Hustle

* Tweaked fissure accuracy and evasion tests to use spyOn() for getAccuracyMultiplier() as per feedback

* Fixed accuracy test for Fissure
This commit is contained in:
Corrade 2024-07-25 12:34:02 +12:00 committed by GitHub
parent 45d9c65a3e
commit 928a3ae977
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 8 deletions

View File

@ -3,7 +3,7 @@ import BattleScene, { AnySound } from "../battle-scene";
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
import { variantData } from "#app/data/variant";
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, StatusMoveTypeImmunityAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, MoveFlags, NeutralDamageAgainstFlyingTypeMultiplierAttr } from "../data/move";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, StatusMoveTypeImmunityAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, MoveFlags, NeutralDamageAgainstFlyingTypeMultiplierAttr, OneHitKOAccuracyAttr } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
import { Constructor } from "#app/utils";
import * as Utils from "../utils";
@ -1792,6 +1792,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns The calculated accuracy multiplier.
*/
getAccuracyMultiplier(target: Pokemon, sourceMove: Move): number {
const isOhko = sourceMove.hasAttr(OneHitKOAccuracyAttr);
if (isOhko) {
return 1;
}
const userAccuracyLevel = new Utils.IntegerHolder(this.summonData.battleStats[BattleStat.ACC]);
const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]);

View File

@ -78,13 +78,13 @@ describe("Abilities - Hustle", () => {
expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(1);
});
// Skip until OHKO moves are fixed - it should not be affected by accuracy and evasion stats
it("does not affect OHKO moves", async () => {
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100);
vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(30);
await game.startBattle([Species.PIKACHU]);
const pikachu = game.scene.getPlayerPokemon();
const enemyPokemon = game.scene.getEnemyPokemon();
vi.spyOn(pikachu, "getAccuracyMultiplier");
vi.spyOn(allMoves[Moves.FISSURE], "calculateBattleAccuracy");
@ -92,8 +92,8 @@ describe("Abilities - Hustle", () => {
game.doAttack(getMovePosition(game.scene, 0, Moves.FISSURE));
await game.phaseInterceptor.to(DamagePhase);
expect(game.scene.getEnemyPokemon().turnData.damageTaken).toBe(game.scene.getEnemyPokemon().hp);
expect(enemyPokemon.turnData.damageTaken).toBe(enemyPokemon.getMaxHp());
expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(1);
expect(allMoves[Moves.FISSURE].calculateBattleAccuracy).toHaveReturnedWith(100);
}, { skip: true });
});
});

View File

@ -2,17 +2,18 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
import Phaser from "phaser";
import GameManager from "#app/test/utils/gameManager";
import Overrides from "#app/overrides";
import { DamagePhase } from "#app/phases";
import { DamagePhase, TurnEndPhase } from "#app/phases";
import { Moves } from "#enums/moves";
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
import { Abilities } from "#enums/abilities";
import { Species } from "#app/enums/species.js";
import { EnemyPokemon } from "#app/field/pokemon";
import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
import { BattleStat } from "#app/data/battle-stat";
describe("Moves - Fissure", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
//let partyPokemon: PlayerPokemon;
let partyPokemon: PlayerPokemon;
let enemyPokemon: EnemyPokemon;
beforeAll(() => {
@ -43,7 +44,7 @@ describe("Moves - Fissure", () => {
await game.startBattle();
//partyPokemon = game.scene.getParty()[0];
partyPokemon = game.scene.getParty()[0];
enemyPokemon = game.scene.getEnemyPokemon();
// remove berries
@ -60,4 +61,30 @@ describe("Moves - Fissure", () => {
expect(enemyPokemon.isFainted()).toBe(true);
});
it("ignores accuracy stat", async () => {
vi.spyOn(partyPokemon, "getAccuracyMultiplier");
enemyPokemon.summonData.battleStats[BattleStat.ACC] = -6;
game.doAttack(getMovePosition(game.scene, 0, Moves.FISSURE));
// wait for TurnEndPhase instead of DamagePhase as fissure might not actually inflict damage
await game.phaseInterceptor.to(TurnEndPhase);
expect(partyPokemon.getAccuracyMultiplier).toHaveReturnedWith(1);
});
it("ignores evasion stat", async () => {
vi.spyOn(partyPokemon, "getAccuracyMultiplier");
enemyPokemon.summonData.battleStats[BattleStat.EVA] = 6;
game.doAttack(getMovePosition(game.scene, 0, Moves.FISSURE));
// wait for TurnEndPhase instead of DamagePhase as fissure might not actually inflict damage
await game.phaseInterceptor.to(TurnEndPhase);
expect(partyPokemon.getAccuracyMultiplier).toHaveReturnedWith(1);
});
});