Fix SelectModifierPhase tests

This commit is contained in:
NightKev 2024-11-13 21:52:25 -08:00
parent c01c623d3a
commit 810f472677
12 changed files with 98 additions and 117 deletions

View File

@ -75,7 +75,7 @@ describe("Abilities - Infiltrator", () => {
});
// TODO: fix this interaction to pass this test
it.skip("should bypass the target's Mist", async () => {
it.todo("should bypass the target's Mist", async () => {
await game.classicMode.startBattle([ Species.MAGIKARP ]);
const player = game.scene.getPlayerPokemon()!;

View File

@ -54,6 +54,7 @@ describe("Abilities - Libero", () => {
},
);
// Test for Gen9+ functionality, we are using previous funcionality
test.skip(
"ability applies only once per switch in",
async () => {

View File

@ -54,6 +54,7 @@ describe("Abilities - Protean", () => {
},
);
// Test for Gen9+ functionality, we are using previous funcionality
test.skip(
"ability applies only once per switch in",
async () => {

View File

@ -1,45 +0,0 @@
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Error Handling", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
const moveToUse = Moves.SPLASH;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.battleType("single")
.startingWave(3);
game.override.starterSpecies(Species.MEWTWO);
game.override.enemySpecies(Species.RATTATA);
game.override.enemyAbility(Abilities.HYDRATION);
game.override.ability(Abilities.ZEN_MODE);
game.override.startingLevel(2000);
game.override.moveset([ moveToUse ]);
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]);
});
it.skip("to next turn", async () => {
await game.startBattle();
const turn = game.scene.currentBattle.turn;
game.move.select(moveToUse);
await game.toNextTurn();
expect(game.scene.currentBattle.turn).toBeGreaterThan(turn);
}, 20000);
});

View File

@ -171,8 +171,8 @@ describe("BattlerTag - SubstituteTag", () => {
}
);
/** TODO: Figure out how to mock a MoveEffectPhase correctly for this test */
it.skip(
// TODO: Figure out how to mock a MoveEffectPhase correctly for this test
it.todo(
"HIT lapse triggers on-hit message",
async () => {
const subject = new SubstituteTag(Moves.SUBSTITUTE, mockPokemon.id);

View File

@ -82,7 +82,8 @@ describe("Moves - Burning Jealousy", () => {
expect(enemy.status?.effect).toBeUndefined();
});
it.skip("should ignore weakness policy", async () => { // TODO: Make this test if WP is implemented
// TODO: Make this test if WP is implemented
it.todo("should ignore weakness policy", async () => {
await game.classicMode.startBattle();
});

View File

@ -75,7 +75,7 @@ describe("Moves - Parting Shot", () => {
}
);
it.skip( // TODO: fix this bug to pass the test!
it.todo( // TODO: fix this bug to pass the test!
"Parting shot should fail if target is -6/-6 de-buffed",
async () => {
game.override.moveset([ Moves.PARTING_SHOT, Moves.MEMENTO, Moves.SPLASH ]);
@ -117,7 +117,7 @@ describe("Moves - Parting Shot", () => {
}
);
it.skip( // TODO: fix this bug to pass the test!
it.todo( // TODO: fix this bug to pass the test!
"Parting shot shouldn't allow switch out when mist is active",
async () => {
game.override
@ -138,7 +138,7 @@ describe("Moves - Parting Shot", () => {
}
);
it.skip( // TODO: fix this bug to pass the test!
it.todo( // TODO: fix this bug to pass the test!
"Parting shot shouldn't allow switch out against clear body ability",
async () => {
game.override
@ -158,7 +158,7 @@ describe("Moves - Parting Shot", () => {
}
);
it.skip( // TODO: fix this bug to pass the test!
it.todo( // TODO: fix this bug to pass the test!
"Parting shot should de-buff and not fail if no party available to switch - party size 1",
async () => {
await game.startBattle([ Species.MURKROW ]);
@ -175,7 +175,7 @@ describe("Moves - Parting Shot", () => {
}
);
it.skip( // TODO: fix this bug to pass the test!
it.todo( // TODO: fix this bug to pass the test!
"Parting shot regularly not fail if no party available to switch - party fainted",
async () => {
await game.startBattle([ Species.MURKROW, Species.MEOWTH ]);

View File

@ -87,7 +87,7 @@ describe("Moves - Tera Blast", () => {
});
// Currently abilities are bugged and can't see when a move's category is changed
it.skip("uses the higher stat of the user's Atk and SpAtk for damage calculation", async () => {
it.todo("uses the higher stat of the user's Atk and SpAtk for damage calculation", async () => {
game.override.enemyAbility(Abilities.TOXIC_DEBRIS);
await game.startBattle();

View File

@ -247,8 +247,7 @@ describe("Clowning Around - Mystery Encounter", () => {
});
});
// this is the test that's broken due to the event
it.skip("should randomize held items of the Pokemon with the most items, and not the held items of other pokemon", async () => {
it("should randomize held items of the Pokemon with the most items, and not the held items of other pokemon", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
// Set some moves on party for attack type booster generation

View File

@ -1,20 +1,22 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import Phaser from "phaser";
import GameManager from "#app/test/utils/gameManager";
import { initSceneWithoutEncounterPhase } from "#app/test/utils/gameManagerUtils";
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
import { ModifierTier } from "#app/modifier/modifier-tier";
import * as Utils from "#app/utils";
import { CustomModifierSettings, ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type";
import BattleScene from "#app/battle-scene";
import { Species } from "#enums/species";
import { Mode } from "#app/ui/ui";
import { PlayerPokemon } from "#app/field/pokemon";
import type BattleScene from "#app/battle-scene";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { PlayerPokemon } from "#app/field/pokemon";
import { ModifierTier } from "#app/modifier/modifier-tier";
import { CustomModifierSettings, ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
import { Mode } from "#app/ui/ui";
import { shiftCharCodes } from "#app/utils";
import { Abilities } from "#enums/abilities";
import { Button } from "#enums/buttons";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
// TODO: why are the `expect(modifierSelectHandler.options.length).toEqual(#)` checks unreliable/failing?
describe.skip("SelectModifierPhase", () => {
describe("SelectModifierPhase", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
let scene: BattleScene;
@ -29,7 +31,11 @@ describe.skip("SelectModifierPhase", () => {
game = new GameManager(phaserGame);
scene = game.scene;
initSceneWithoutEncounterPhase(scene, [ Species.ABRA, Species.VOLCARONA ]);
game.override
.moveset([ Moves.FISSURE, Moves.SPLASH ])
.ability(Abilities.NO_GUARD)
.startingLevel(200)
.enemySpecies(Species.MAGIKARP);
});
afterEach(() => {
@ -39,6 +45,7 @@ describe.skip("SelectModifierPhase", () => {
});
it("should start a select modifier phase", async () => {
initSceneWithoutEncounterPhase(scene, [ Species.ABRA, Species.VOLCARONA ]);
const selectModifierPhase = new SelectModifierPhase();
scene.pushPhase(selectModifierPhase);
await game.phaseInterceptor.run(SelectModifierPhase);
@ -47,10 +54,9 @@ describe.skip("SelectModifierPhase", () => {
});
it("should generate random modifiers", async () => {
const selectModifierPhase = new SelectModifierPhase();
scene.pushPhase(selectModifierPhase);
await game.phaseInterceptor.run(SelectModifierPhase);
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
game.move.select(Moves.FISSURE);
await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
@ -58,6 +64,7 @@ describe.skip("SelectModifierPhase", () => {
});
it("should modify reroll cost", async () => {
initSceneWithoutEncounterPhase(scene, [ Species.ABRA, Species.VOLCARONA ]);
const options = [
new ModifierTypeOption(modifierTypes.POTION(), 0, 100),
new ModifierTypeOption(modifierTypes.ETHER(), 0, 400),
@ -72,50 +79,48 @@ describe.skip("SelectModifierPhase", () => {
expect(cost2).toEqual(cost1 * 2);
});
it("should generate random modifiers from reroll", async () => {
let selectModifierPhase = new SelectModifierPhase();
scene.pushPhase(selectModifierPhase);
await game.phaseInterceptor.run(SelectModifierPhase);
it.todo("should generate random modifiers from reroll", async () => {
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
scene.money = 1000000;
scene.shopCursorTarget = 0;
game.move.select(Moves.FISSURE);
await game.phaseInterceptor.to("SelectModifierPhase");
// TODO: nagivate the ui to reroll somehow
//const smphase = scene.getCurrentPhase() as SelectModifierPhase;
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
expect(modifierSelectHandler.options.length).toEqual(3);
// Simulate selecting reroll
selectModifierPhase = new SelectModifierPhase(1, [ ModifierTier.COMMON, ModifierTier.COMMON, ModifierTier.COMMON ]);
scene.unshiftPhase(selectModifierPhase);
scene.ui.setMode(Mode.MESSAGE).then(() => game.endPhase());
await game.phaseInterceptor.run(SelectModifierPhase);
modifierSelectHandler.processInput(Button.ACTION);
expect(scene.money).toBe(1000000 - 250);
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
expect(modifierSelectHandler.options.length).toEqual(3);
});
it("should generate random modifiers of same tier for reroll with reroll lock", async () => {
it.todo("should generate random modifiers of same tier for reroll with reroll lock", async () => {
game.override.startingModifier([{ name: "LOCK_CAPSULE" }]);
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
scene.money = 1000000;
// Just use fully random seed for this test
vi.spyOn(scene, "resetSeed").mockImplementation(() => {
scene.waveSeed = Utils.shiftCharCodes(scene.seed, 5);
scene.waveSeed = shiftCharCodes(scene.seed, 5);
Phaser.Math.RND.sow([ scene.waveSeed ]);
console.log("Wave Seed:", scene.waveSeed, 5);
scene.rngCounter = 0;
});
let selectModifierPhase = new SelectModifierPhase();
scene.pushPhase(selectModifierPhase);
await game.phaseInterceptor.run(SelectModifierPhase);
game.move.select(Moves.FISSURE);
await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
expect(modifierSelectHandler.options.length).toEqual(3);
const firstRollTiers: ModifierTier[] = modifierSelectHandler.options.map(o => o.modifierTypeOption.type.tier);
// Simulate selecting reroll with lock
scene.lockModifierTiers = true;
scene.reroll = true;
selectModifierPhase = new SelectModifierPhase(1, firstRollTiers);
scene.unshiftPhase(selectModifierPhase);
scene.ui.setMode(Mode.MESSAGE).then(() => game.endPhase());
await game.phaseInterceptor.run(SelectModifierPhase);
// TODO: nagivate ui to reroll with lock capsule enabled
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
expect(modifierSelectHandler.options.length).toEqual(3);
@ -126,13 +131,15 @@ describe.skip("SelectModifierPhase", () => {
});
it("should generate custom modifiers", async () => {
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
scene.money = 1000000;
const customModifiers: CustomModifierSettings = {
guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_ULTRA, modifierTypes.LEFTOVERS, modifierTypes.AMULET_COIN, modifierTypes.GOLDEN_PUNCH ]
};
const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers);
scene.pushPhase(selectModifierPhase);
await game.phaseInterceptor.run(SelectModifierPhase);
scene.unshiftPhase(selectModifierPhase);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
@ -145,6 +152,8 @@ describe.skip("SelectModifierPhase", () => {
});
it("should generate custom modifier tiers that can upgrade from luck", async () => {
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
scene.money = 1000000;
const customModifiers: CustomModifierSettings = {
guaranteedModifierTiers: [ ModifierTier.COMMON, ModifierTier.GREAT, ModifierTier.ULTRA, ModifierTier.ROGUE, ModifierTier.MASTER ]
};
@ -157,9 +166,9 @@ describe.skip("SelectModifierPhase", () => {
scene.getPlayerParty().push(pokemon, pokemon, pokemon, pokemon, pokemon, pokemon);
const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers);
scene.pushPhase(selectModifierPhase);
await game.phaseInterceptor.run(SelectModifierPhase);
scene.unshiftPhase(selectModifierPhase);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
@ -172,12 +181,15 @@ describe.skip("SelectModifierPhase", () => {
});
it("should generate custom modifiers and modifier tiers together", async () => {
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
scene.money = 1000000;
const customModifiers: CustomModifierSettings = {
guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_COMMON ],
guaranteedModifierTiers: [ ModifierTier.MASTER, ModifierTier.MASTER ]
};
const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers);
scene.pushPhase(selectModifierPhase);
scene.unshiftPhase(selectModifierPhase);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.run(SelectModifierPhase);
@ -191,13 +203,16 @@ describe.skip("SelectModifierPhase", () => {
});
it("should fill remaining modifiers if fillRemaining is true with custom modifiers", async () => {
await game.classicMode.startBattle([ Species.ABRA, Species.VOLCARONA ]);
scene.money = 1000000;
const customModifiers: CustomModifierSettings = {
guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM ],
guaranteedModifierTiers: [ ModifierTier.MASTER ],
fillRemaining: true
};
const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers);
scene.pushPhase(selectModifierPhase);
scene.unshiftPhase(selectModifierPhase);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.run(SelectModifierPhase);

View File

@ -1,13 +1,14 @@
import BattleScene from "#app/battle-scene";
import Battle, { BattleType } from "#app/battle";
import type BattleScene from "#app/battle-scene";
import { getDailyRunStarters } from "#app/data/daily-run";
import { Gender } from "#app/data/gender";
import { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
import { Moves } from "#app/enums/moves";
import { PlayerPokemon } from "#app/field/pokemon";
import { GameModes, getGameMode } from "#app/game-mode";
import type { StarterMoveset } from "#app/system/game-data";
import { Starter } from "#app/ui/starter-select-ui-handler";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import Battle, { BattleType } from "#app/battle";
/** Function to convert Blob to string */
export function blobToString(blob) {
@ -31,7 +32,7 @@ export function holdOn(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function generateStarter(scene, species?: Species[]) {
export function generateStarter(scene: BattleScene, species?: Species[]): Starter[] {
const seed = "test";
const starters = getTestRunStarters(seed, species);
const startingLevel = scene.gameMode.getStartingLevel();
@ -42,12 +43,16 @@ export function generateStarter(scene, species?: Species[]) {
? !starterProps.female ? Gender.MALE : Gender.FEMALE
: Gender.GENDERLESS;
const starterPokemon = scene.addPlayerPokemon(starter.species, startingLevel, starter.abilityIndex, starterFormIndex, starterGender, starterProps.shiny, starterProps.variant, undefined, starter.nature);
starter.moveset = starterPokemon.moveset;
const moveset: Moves[] = [];
starterPokemon.moveset.forEach((move) => {
moveset.push(move!.getMove().id);
});
starter.moveset = moveset as StarterMoveset;
}
return starters;
}
function getTestRunStarters(seed, species) {
function getTestRunStarters(seed: string, species?: Species[]): Starter[] {
if (!species) {
return getDailyRunStarters(seed);
}
@ -71,7 +76,7 @@ function getTestRunStarters(seed, species) {
return starters;
}
export function waitUntil(truth) {
export function waitUntil(truth): Promise<unknown> {
return new Promise(resolve => {
const interval = setInterval(() => {
if (truth()) {
@ -83,7 +88,7 @@ export function waitUntil(truth) {
}
/** Get the index of `move` from the moveset of the pokemon on the player's field at location `pokemonIndex` */
export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves) {
export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves): number {
const playerPokemon = scene.getPlayerField()[pokemonIndex];
const moveSet = playerPokemon.getMoveset();
const index = moveSet.findIndex((m) => m?.moveId === move && m?.ppUsed < m?.getMovePp());
@ -93,10 +98,8 @@ export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: M
/**
* Useful for populating party, wave index, etc. without having to spin up and run through an entire EncounterPhase
* @param scene
* @param species
*/
export function initSceneWithoutEncounterPhase(scene: BattleScene, species?: Species[]) {
export function initSceneWithoutEncounterPhase(scene: BattleScene, species?: Species[]): void {
const starters = generateStarter(scene, species);
starters.forEach((starter) => {
const starterProps = scene.gameData.getSpeciesDexAttrProps(starter.species, starter.dexAttr);

View File

@ -510,7 +510,13 @@ export default class PhaseInterceptor {
const currentHandler = this.scene.ui.getHandler();
if (expireFn) {
this.prompts.shift();
} else if (currentMode === actionForNextPrompt.mode && currentPhase === actionForNextPrompt.phaseTarget && currentHandler.active && (!actionForNextPrompt.awaitingActionInput || (actionForNextPrompt.awaitingActionInput && currentHandler.awaitingActionInput))) {
} else if (
currentMode === actionForNextPrompt.mode
&& currentPhase === actionForNextPrompt.phaseTarget
&& currentHandler.active
&& (!actionForNextPrompt.awaitingActionInput
|| (actionForNextPrompt.awaitingActionInput && currentHandler.awaitingActionInput))
) {
const prompt = this.prompts.shift();
if (prompt?.callback) {
prompt.callback();