mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 17:12:44 +02:00
Made game.phaseInterceptor
fail if move not in moveset
also added a few assorted doc fixes
This commit is contained in:
parent
6ff258fb37
commit
9c9e7fbbb9
@ -3,7 +3,6 @@ import Phaser from "phaser";
|
|||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import { UiMode } from "#enums/ui-mode";
|
import { UiMode } from "#enums/ui-mode";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { getMovePosition } from "#test/testUtils/gameManagerUtils";
|
|
||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
@ -114,7 +113,7 @@ describe("Abilities - Intimidate", () => {
|
|||||||
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
|
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
|
||||||
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
|
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
|
||||||
|
|
||||||
game.move.select(getMovePosition(game.scene, 0, MoveId.SPLASH));
|
game.move.select(MoveId.SPLASH);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
enemyPokemon = game.scene.getEnemyPokemon()!;
|
enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||||
|
@ -65,8 +65,7 @@ describe("Abilities - Moxie", () => {
|
|||||||
|
|
||||||
secondPokemon.hp = 1;
|
secondPokemon.hp = 1;
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
game.move.select(moveToUse, BattlerIndex.PLAYER_2);
|
||||||
game.selectTarget(BattlerIndex.PLAYER_2);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.to(TurnEndPhase);
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
@ -201,9 +201,8 @@ export default class GameManager {
|
|||||||
/**
|
/**
|
||||||
* Helper function to run to the final boss encounter as it's a bit tricky due to extra dialogue
|
* Helper function to run to the final boss encounter as it's a bit tricky due to extra dialogue
|
||||||
* Also handles Major/Minor bosses from endless modes
|
* Also handles Major/Minor bosses from endless modes
|
||||||
* @param game - The game manager
|
* @param species - Array of {@linkcode SpeciesId}s to start the final battle with.
|
||||||
* @param species
|
* @param mode - The {@linkcode GameModes} to spawn the final boss encounter in.
|
||||||
* @param mode
|
|
||||||
*/
|
*/
|
||||||
async runToFinalBossEncounter(species: SpeciesId[], mode: GameModes) {
|
async runToFinalBossEncounter(species: SpeciesId[], mode: GameModes) {
|
||||||
console.log("===to final boss encounter===");
|
console.log("===to final boss encounter===");
|
||||||
@ -230,9 +229,9 @@ export default class GameManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the game to a mystery encounter phase.
|
* Runs the game to a mystery encounter phase.
|
||||||
* @param encounterType if specified, will expect encounter to have been spawned
|
* @param encounterType - If specified, will expect encounter to be the given type.
|
||||||
* @param species Optional array of species for party.
|
* @param species - Optional array of species for party to start with.
|
||||||
* @returns A promise that resolves when the EncounterPhase ends.
|
* @returns A Promise that resolves when the EncounterPhase ends.
|
||||||
*/
|
*/
|
||||||
async runToMysteryEncounter(encounterType?: MysteryEncounterType, species?: SpeciesId[]) {
|
async runToMysteryEncounter(encounterType?: MysteryEncounterType, species?: SpeciesId[]) {
|
||||||
if (!isNullOrUndefined(encounterType)) {
|
if (!isNullOrUndefined(encounterType)) {
|
||||||
@ -277,6 +276,7 @@ export default class GameManager {
|
|||||||
* Will trigger during the next {@linkcode SelectTargetPhase}
|
* Will trigger during the next {@linkcode SelectTargetPhase}
|
||||||
* @param targetIndex - The {@linkcode BattlerIndex} of the attack target, or `undefined` for multi-target attacks
|
* @param targetIndex - The {@linkcode BattlerIndex} of the attack target, or `undefined` for multi-target attacks
|
||||||
* @param movePosition - The 0-indexed position of the move in the pokemon's moveset array
|
* @param movePosition - The 0-indexed position of the move in the pokemon's moveset array
|
||||||
|
* @throws Immediately fails tests
|
||||||
*/
|
*/
|
||||||
selectTarget(movePosition: number, targetIndex?: BattlerIndex) {
|
selectTarget(movePosition: number, targetIndex?: BattlerIndex) {
|
||||||
this.onNextPrompt(
|
this.onNextPrompt(
|
||||||
@ -292,7 +292,7 @@ export default class GameManager {
|
|||||||
handler.setCursor(targetIndex !== undefined ? targetIndex : BattlerIndex.ENEMY);
|
handler.setCursor(targetIndex !== undefined ? targetIndex : BattlerIndex.ENEMY);
|
||||||
}
|
}
|
||||||
if (move.isMultiTarget() && targetIndex !== undefined) {
|
if (move.isMultiTarget() && targetIndex !== undefined) {
|
||||||
throw new Error(`targetIndex was passed to selectMove() but move ("${move.name}") is not targetted`);
|
expect.fail(`targetIndex was passed to selectMove() but move ("${move.name}") is not targetted`);
|
||||||
}
|
}
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
},
|
},
|
||||||
|
@ -10,7 +10,7 @@ import { getGameMode } from "#app/game-mode";
|
|||||||
import { GameModes } from "#enums/game-modes";
|
import { GameModes } from "#enums/game-modes";
|
||||||
import type { StarterMoveset } from "#app/system/game-data";
|
import type { StarterMoveset } from "#app/system/game-data";
|
||||||
import type { Starter } from "#app/ui/starter-select-ui-handler";
|
import type { Starter } from "#app/ui/starter-select-ui-handler";
|
||||||
import { MoveId } from "#enums/move-id";
|
import type { MoveId } from "#enums/move-id";
|
||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
|
|
||||||
/** Function to convert Blob to string */
|
/** Function to convert Blob to string */
|
||||||
@ -98,15 +98,6 @@ export function waitUntil(truth): Promise<unknown> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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: MoveId): number {
|
|
||||||
const playerPokemon = scene.getPlayerField()[pokemonIndex];
|
|
||||||
const moveSet = playerPokemon.getMoveset();
|
|
||||||
const index = moveSet.findIndex(m => m.moveId === move && m.ppUsed < m.getMovePp());
|
|
||||||
console.log(`Move position for ${MoveId[move]} (=${move}):`, index);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useful for populating party, wave index, etc. without having to spin up and run through an entire EncounterPhase
|
* Useful for populating party, wave index, etc. without having to spin up and run through an entire EncounterPhase
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { BattlerIndex } from "#enums/battler-index";
|
import { BattlerIndex } from "#enums/battler-index";
|
||||||
import { getMoveTargets } from "#app/data/moves/move-utils";
|
import { getMoveTargets } from "#app/data/moves/move-utils";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { PokemonMove } from "#app/data/moves/pokemon-move";
|
import { PokemonMove } from "#app/data/moves/pokemon-move";
|
||||||
@ -9,14 +9,13 @@ import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
|||||||
import { Command } from "#enums/command";
|
import { Command } from "#enums/command";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { UiMode } from "#enums/ui-mode";
|
import { UiMode } from "#enums/ui-mode";
|
||||||
import { getMovePosition } from "#test/testUtils/gameManagerUtils";
|
|
||||||
import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper";
|
import { GameManagerHelper } from "#test/testUtils/helpers/gameManagerHelper";
|
||||||
import { vi } from "vitest";
|
import { expect, vi } from "vitest";
|
||||||
import { coerceArray } from "#app/utils/common";
|
import { coerceArray, toReadableString } from "#app/utils/common";
|
||||||
import { MoveUseMode } from "#enums/move-use-mode";
|
import { MoveUseMode } from "#enums/move-use-mode";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to handle a Pokemon's move
|
* Helper to handle using a Pokemon's moves.
|
||||||
*/
|
*/
|
||||||
export class MoveHelper extends GameManagerHelper {
|
export class MoveHelper extends GameManagerHelper {
|
||||||
/**
|
/**
|
||||||
@ -49,13 +48,25 @@ export class MoveHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select the move to be used by the given Pokemon(-index). Triggers during the next {@linkcode CommandPhase}
|
* Select a move _already in the player's moveset_ to be used during the next {@linkcode CommandPhase}.
|
||||||
* @param move - the move to use
|
* @param move - The {@linkcode MoveId} to use.
|
||||||
* @param pkmIndex - the pokemon index. Relevant for double-battles only (defaults to 0)
|
* @param pkmIndex - The {@linkcode BattlerIndex} of the player Pokemon using the move. Relevant for double battles only and defaults to {@linkcode BattlerIndex.PLAYER} if not specified.
|
||||||
* @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves, or `null` if a manual call to `selectTarget()` is required
|
* @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves; should be omitted for multi-target moves.
|
||||||
|
* If set to `null`, will forgo normal target selection entirely (useful for UI tests).
|
||||||
|
* @remarks
|
||||||
|
* Will fail the current test if the move being selected is not in the user's moveset.
|
||||||
*/
|
*/
|
||||||
public select(move: MoveId, pkmIndex: 0 | 1 = 0, targetIndex?: BattlerIndex | null) {
|
public select(
|
||||||
const movePosition = getMovePosition(this.game.scene, pkmIndex, move);
|
move: MoveId,
|
||||||
|
pkmIndex: BattlerIndex.PLAYER | BattlerIndex.PLAYER_2 = BattlerIndex.PLAYER,
|
||||||
|
targetIndex?: BattlerIndex | null,
|
||||||
|
) {
|
||||||
|
const movePosition = this.getMovePosition(pkmIndex, move);
|
||||||
|
if (movePosition === -1) {
|
||||||
|
expect.fail(
|
||||||
|
`MoveHelper.select called with move ${toReadableString(MoveId[move])} not in moveset; Battler Index: ${BattlerIndex[pkmIndex]}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.game.onNextPrompt("CommandPhase", UiMode.COMMAND, () => {
|
this.game.onNextPrompt("CommandPhase", UiMode.COMMAND, () => {
|
||||||
this.game.scene.ui.setMode(
|
this.game.scene.ui.setMode(
|
||||||
@ -77,14 +88,24 @@ export class MoveHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select the move to be used by the given Pokemon(-index), **which will also terastallize on this turn**.
|
* Select a move _already in the player's moveset_ to be used during the next {@linkcode CommandPhase}, **which will also terastallize on this turn**.
|
||||||
* Triggers during the next {@linkcode CommandPhase}
|
* @param move - The {@linkcode MoveId} to use.
|
||||||
* @param move - the move to use
|
* @param pkmIndex - The {@linkcode BattlerIndex} of the player Pokemon using the move. Relevant for double battles only and defaults to {@linkcode BattlerIndex.PLAYER} if not specified.
|
||||||
* @param pkmIndex - the pokemon index. Relevant for double-battles only (defaults to 0)
|
* @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves; should be omitted for multi-target moves.
|
||||||
* @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves, or `null` if a manual call to `selectTarget()` is required
|
* If set to `null`, will forgo normal target selection entirely (useful for UI tests)
|
||||||
*/
|
*/
|
||||||
public selectWithTera(move: MoveId, pkmIndex: 0 | 1 = 0, targetIndex?: BattlerIndex | null) {
|
public selectWithTera(
|
||||||
const movePosition = getMovePosition(this.game.scene, pkmIndex, move);
|
move: MoveId,
|
||||||
|
pkmIndex: BattlerIndex.PLAYER | BattlerIndex.PLAYER_2 = BattlerIndex.PLAYER,
|
||||||
|
targetIndex?: BattlerIndex | null,
|
||||||
|
) {
|
||||||
|
const movePosition = this.getMovePosition(pkmIndex, move);
|
||||||
|
if (movePosition === -1) {
|
||||||
|
expect.fail(
|
||||||
|
`MoveHelper.selectWithTera called with move ${toReadableString(MoveId[move])} not in moveset;\nBattler Index: ${BattlerIndex[pkmIndex]};\nMoveset: ${this.game.scene.getField()[pkmIndex].getMoveset()}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.game.scene.getPlayerParty()[pkmIndex].isTerastallized = false;
|
this.game.scene.getPlayerParty()[pkmIndex].isTerastallized = false;
|
||||||
|
|
||||||
this.game.onNextPrompt("CommandPhase", UiMode.COMMAND, () => {
|
this.game.onNextPrompt("CommandPhase", UiMode.COMMAND, () => {
|
||||||
@ -107,6 +128,15 @@ export class MoveHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper function to get the index of the selected move in the selected part member's moveset. */
|
||||||
|
private getMovePosition(pokemonIndex: BattlerIndex.PLAYER | BattlerIndex.PLAYER_2, move: MoveId): number {
|
||||||
|
const playerPokemon = this.game.scene.getPlayerField()[pokemonIndex];
|
||||||
|
const moveset = playerPokemon.getMoveset();
|
||||||
|
const index = moveset.findIndex(m => m.moveId === move && m.ppUsed < m.getMovePp());
|
||||||
|
console.log(`Move position for ${MoveId[move]} (=${move}):`, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies a player pokemon's moveset to contain only the selected move and then
|
* Modifies a player pokemon's moveset to contain only the selected move and then
|
||||||
* selects it to be used during the next {@linkcode CommandPhase}.
|
* selects it to be used during the next {@linkcode CommandPhase}.
|
||||||
@ -116,14 +146,19 @@ export class MoveHelper extends GameManagerHelper {
|
|||||||
* Note: If you need to check for changes in the player's moveset as part of the test, it may be
|
* Note: If you need to check for changes in the player's moveset as part of the test, it may be
|
||||||
* best to use {@linkcode changeMoveset} and {@linkcode select} instead.
|
* best to use {@linkcode changeMoveset} and {@linkcode select} instead.
|
||||||
* @param moveId - the move to use
|
* @param moveId - the move to use
|
||||||
* @param pkmIndex - the pokemon index. Relevant for double-battles only (defaults to 0)
|
* @param pkmIndex - The {@linkcode BattlerIndex} of the player Pokemon using the move. Relevant for double battles only and defaults to {@linkcode BattlerIndex.PLAYER} if not specified.
|
||||||
* @param targetIndex - (optional) The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves, or `null` if a manual call to `selectTarget()` is required
|
* @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves; should be omitted for multi-target moves.
|
||||||
* @param useTera - If `true`, the Pokemon also chooses to Terastallize. This does not require a Tera Orb. Default: `false`.
|
* @param useTera - If `true`, the Pokemon will attempt to Terastallize even without a Tera Orb; default `false`.
|
||||||
*/
|
*/
|
||||||
public use(moveId: MoveId, pkmIndex: 0 | 1 = 0, targetIndex?: BattlerIndex | null, useTera = false): void {
|
public use(
|
||||||
|
moveId: MoveId,
|
||||||
|
pkmIndex: BattlerIndex.PLAYER | BattlerIndex.PLAYER_2 = BattlerIndex.PLAYER,
|
||||||
|
targetIndex?: BattlerIndex,
|
||||||
|
useTera = false,
|
||||||
|
): void {
|
||||||
if ([Overrides.MOVESET_OVERRIDE].flat().length > 0) {
|
if ([Overrides.MOVESET_OVERRIDE].flat().length > 0) {
|
||||||
vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]);
|
vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]);
|
||||||
console.warn("Warning: `use` overwrites the Pokemon's moveset and disables the player moveset override!");
|
console.warn("Warning: `MoveHelper.use` overwriting player pokemon moveset and disabling moveset override!");
|
||||||
}
|
}
|
||||||
|
|
||||||
const pokemon = this.game.scene.getPlayerField()[pkmIndex];
|
const pokemon = this.game.scene.getPlayerField()[pkmIndex];
|
||||||
|
Loading…
Reference in New Issue
Block a user