mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-22 07:19:28 +02:00
[Balance][Challenge] Block master ball catching final boss in challenges (#6273)
* Block catching bosses in nuzlockes * Changes to conditions to restrict master ball use * Implemented new can't catch messages * Fixed some bugs which prevented correct usage of balls * Special casing full fresh start * fix text Update command-phase.ts * Added tests for failing catches * Using `mockI18next` * Shorten a couple of variable declarations * Fixed bug that allowed catching trainer pokemon in end; showing double battle failure only if other failure messages do not apply * Fixed order of error messages * Changed description of tests with "in end biome" instead of "paradox mon(s)" * Not override nature after selection * Update test/field/catching.test.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: damocleas <damocleas25@gmail.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com>
This commit is contained in:
parent
93cdffccc4
commit
14a0a23abc
@ -10,7 +10,6 @@ import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
|||||||
import { ModifierTier } from "#enums/modifier-tier";
|
import { ModifierTier } from "#enums/modifier-tier";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import type { MoveSourceType } from "#enums/move-source-type";
|
import type { MoveSourceType } from "#enums/move-source-type";
|
||||||
import { Nature } from "#enums/nature";
|
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
@ -800,7 +799,6 @@ export class FreshStartChallenge extends Challenge {
|
|||||||
applyStarterModify(pokemon: Pokemon): boolean {
|
applyStarterModify(pokemon: Pokemon): boolean {
|
||||||
pokemon.abilityIndex = pokemon.abilityIndex % 2; // Always base ability, if you set it to hidden it wraps to first ability
|
pokemon.abilityIndex = pokemon.abilityIndex % 2; // Always base ability, if you set it to hidden it wraps to first ability
|
||||||
pokemon.passive = false; // Passive isn't unlocked
|
pokemon.passive = false; // Passive isn't unlocked
|
||||||
pokemon.nature = Nature.HARDY; // Neutral nature
|
|
||||||
let validMoves = pokemon.species
|
let validMoves = pokemon.species
|
||||||
.getLevelMoves()
|
.getLevelMoves()
|
||||||
.filter(m => isBetween(m[0], 1, 5))
|
.filter(m => isBetween(m[0], 1, 5))
|
||||||
|
@ -82,6 +82,14 @@ export class GameMode implements GameModeConfig {
|
|||||||
return this.challenges.some(c => c.id === challenge && c.value !== 0);
|
return this.challenges.some(c => c.id === challenge && c.value !== 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to see if a GameMode has any challenges, needed in tests
|
||||||
|
* @returns true if the game mode has at least one challenge
|
||||||
|
*/
|
||||||
|
hasAnyChallenges(): boolean {
|
||||||
|
return this.challenges.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to see if the game mode is using fresh start
|
* Helper function to see if the game mode is using fresh start
|
||||||
* @returns true if a fresh start challenge is being applied
|
* @returns true if a fresh start challenge is being applied
|
||||||
@ -90,6 +98,19 @@ export class GameMode implements GameModeConfig {
|
|||||||
return this.hasChallenge(Challenges.FRESH_START);
|
return this.hasChallenge(Challenges.FRESH_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to see if the game mode is using fresh start
|
||||||
|
* @returns true if a fresh start challenge is being applied
|
||||||
|
*/
|
||||||
|
isFullFreshStartChallenge(): boolean {
|
||||||
|
for (const challenge of this.challenges) {
|
||||||
|
if (challenge.id === Challenges.FRESH_START && challenge.value === 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to get starting level for game mode.
|
* Helper function to get starting level for game mode.
|
||||||
* @returns either:
|
* @returns either:
|
||||||
|
@ -376,7 +376,6 @@ export class CommandPhase extends FieldPhase {
|
|||||||
* - It is a trainer battle
|
* - It is a trainer battle
|
||||||
* - The player is in the {@linkcode BiomeId.END | End} biome and
|
* - The player is in the {@linkcode BiomeId.END | End} biome and
|
||||||
* - it is not classic mode; or
|
* - it is not classic mode; or
|
||||||
* - the fresh start challenge is active; or
|
|
||||||
* - the player has not caught the target before and the player is still missing more than one starter
|
* - the player has not caught the target before and the player is still missing more than one starter
|
||||||
* - The player is in a mystery encounter that disallows catching the pokemon
|
* - The player is in a mystery encounter that disallows catching the pokemon
|
||||||
* @returns Whether a pokeball can be thrown
|
* @returns Whether a pokeball can be thrown
|
||||||
@ -385,19 +384,37 @@ export class CommandPhase extends FieldPhase {
|
|||||||
const { arena, currentBattle, gameData, gameMode } = globalScene;
|
const { arena, currentBattle, gameData, gameMode } = globalScene;
|
||||||
const { battleType } = currentBattle;
|
const { battleType } = currentBattle;
|
||||||
const { biomeType } = arena;
|
const { biomeType } = arena;
|
||||||
const { isClassic } = gameMode;
|
const { isClassic, isEndless, isDaily } = gameMode;
|
||||||
const { dexData } = gameData;
|
const { dexData } = gameData;
|
||||||
|
|
||||||
|
const isClassicFinalBoss = gameMode.isBattleClassicFinalBoss(globalScene.currentBattle.waveIndex);
|
||||||
|
const isEndlessMinorBoss = gameMode.isEndlessMinorBoss(globalScene.currentBattle.waveIndex);
|
||||||
|
const isFullFreshStart = gameMode.isFullFreshStartChallenge();
|
||||||
const someUncaughtSpeciesOnField = globalScene
|
const someUncaughtSpeciesOnField = globalScene
|
||||||
.getEnemyField()
|
.getEnemyField()
|
||||||
.some(p => p.isActive() && !dexData[p.species.speciesId].caughtAttr);
|
.some(p => p.isActive() && !dexData[p.species.speciesId].caughtAttr);
|
||||||
const missingMultipleStarters =
|
const missingMultipleStarters =
|
||||||
gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1;
|
gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1;
|
||||||
|
|
||||||
|
if (biomeType === BiomeId.END && battleType === BattleType.WILD) {
|
||||||
if (
|
if (
|
||||||
biomeType === BiomeId.END &&
|
(isClassic && !isClassicFinalBoss && someUncaughtSpeciesOnField) ||
|
||||||
(!isClassic || gameMode.isFreshStartChallenge() || (someUncaughtSpeciesOnField && missingMultipleStarters))
|
(isFullFreshStart && !isClassicFinalBoss) ||
|
||||||
|
(isEndless && !isEndlessMinorBoss)
|
||||||
) {
|
) {
|
||||||
|
// Uncatchable paradox mons in classic and endless
|
||||||
this.queueShowText("battle:noPokeballForce");
|
this.queueShowText("battle:noPokeballForce");
|
||||||
|
} else if (
|
||||||
|
(isClassic && isClassicFinalBoss && missingMultipleStarters) ||
|
||||||
|
(isFullFreshStart && isClassicFinalBoss) ||
|
||||||
|
(isEndless && isEndlessMinorBoss) ||
|
||||||
|
isDaily
|
||||||
|
) {
|
||||||
|
// Uncatchable final boss in classic, endless and daily
|
||||||
|
this.queueShowText("battle:noPokeballForceFinalBoss");
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else if (battleType === BattleType.TRAINER) {
|
} else if (battleType === BattleType.TRAINER) {
|
||||||
this.queueShowText("battle:noPokeballTrainer");
|
this.queueShowText("battle:noPokeballTrainer");
|
||||||
} else if (currentBattle.isBattleMysteryEncounter() && !currentBattle.mysteryEncounter!.catchAllowed) {
|
} else if (currentBattle.isBattleMysteryEncounter() && !currentBattle.mysteryEncounter!.catchAllowed) {
|
||||||
@ -420,14 +437,18 @@ export class CommandPhase extends FieldPhase {
|
|||||||
.getEnemyField()
|
.getEnemyField()
|
||||||
.filter(p => p.isActive(true))
|
.filter(p => p.isActive(true))
|
||||||
.map(p => p.getBattlerIndex());
|
.map(p => p.getBattlerIndex());
|
||||||
|
|
||||||
|
if (!this.checkCanUseBall()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (targets.length > 1) {
|
if (targets.length > 1) {
|
||||||
this.queueShowText("battle:noPokeballMulti");
|
this.queueShowText("battle:noPokeballMulti");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.checkCanUseBall()) {
|
const isChallengeActive = globalScene.gameMode.hasAnyChallenges();
|
||||||
return false;
|
const isFinalBoss = globalScene.gameMode.isBattleClassicFinalBoss(globalScene.currentBattle.waveIndex);
|
||||||
}
|
|
||||||
|
|
||||||
const numBallTypes = 5;
|
const numBallTypes = 5;
|
||||||
if (cursor < numBallTypes) {
|
if (cursor < numBallTypes) {
|
||||||
@ -436,12 +457,23 @@ export class CommandPhase extends FieldPhase {
|
|||||||
targetPokemon?.isBoss() &&
|
targetPokemon?.isBoss() &&
|
||||||
targetPokemon?.bossSegmentIndex >= 1 &&
|
targetPokemon?.bossSegmentIndex >= 1 &&
|
||||||
// TODO: Decouple this hardcoded exception for wonder guard and just check the target...
|
// TODO: Decouple this hardcoded exception for wonder guard and just check the target...
|
||||||
!targetPokemon?.hasAbility(AbilityId.WONDER_GUARD, false, true) &&
|
!targetPokemon?.hasAbility(AbilityId.WONDER_GUARD, false, true)
|
||||||
cursor < PokeballType.MASTER_BALL
|
|
||||||
) {
|
) {
|
||||||
|
// When facing the final boss, it must be weakened unless a Master Ball is used AND no challenges are active.
|
||||||
|
// The message is customized for the final boss.
|
||||||
|
if (
|
||||||
|
isFinalBoss &&
|
||||||
|
(cursor < PokeballType.MASTER_BALL || (cursor === PokeballType.MASTER_BALL && isChallengeActive))
|
||||||
|
) {
|
||||||
|
this.queueShowText("battle:noPokeballForceFinalBossCatchable");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// When facing any other boss, Master Ball can always be used, and we use the standard message.
|
||||||
|
if (cursor < PokeballType.MASTER_BALL) {
|
||||||
this.queueShowText("battle:noPokeballStrong");
|
this.queueShowText("battle:noPokeballStrong");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
globalScene.currentBattle.turnCommands[this.fieldIndex] = {
|
globalScene.currentBattle.turnCommands[this.fieldIndex] = {
|
||||||
command: Command.BALL,
|
command: Command.BALL,
|
||||||
|
299
test/field/catching.test.ts
Normal file
299
test/field/catching.test.ts
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
import { pokerogueApi } from "#api/pokerogue-api";
|
||||||
|
import { BattleType } from "#enums/battle-type";
|
||||||
|
import { BiomeId } from "#enums/biome-id";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
import { GameModes } from "#enums/game-modes";
|
||||||
|
import { MoveId } from "#enums/move-id";
|
||||||
|
import { PokeballType } from "#enums/pokeball";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { GameManager } from "#test/test-utils/game-manager";
|
||||||
|
import { mockI18next } from "#test/test-utils/test-utils";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to run tests on cactching mons
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - Starts a run on the desired game mode, then attempts to throw a ball
|
||||||
|
* - If still in the command phase (meaning the ball did not catch) uses a move to proceed
|
||||||
|
* - If expecting success, checks that party length has increased by 1
|
||||||
|
* - Otherwise, checks that {@link i18next} has been called on the requested error key
|
||||||
|
*
|
||||||
|
* @param game - The {@link GameManager} instance
|
||||||
|
* @param ball - The {@link PokeballType} to be used for the catch attempt
|
||||||
|
* @param expectedResult - Either "success" if the enemy should be caught, or the expected locales error key
|
||||||
|
* @param mode - One of "classic", "daily", or "challenge"; defaults to "classic".
|
||||||
|
*/
|
||||||
|
async function runPokeballTest(
|
||||||
|
game: GameManager,
|
||||||
|
ball: PokeballType,
|
||||||
|
expectedResult: string,
|
||||||
|
mode: "classic" | "daily" | "challenge" = "classic",
|
||||||
|
) {
|
||||||
|
if (mode === "classic") {
|
||||||
|
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||||
|
} else if (mode === "daily") {
|
||||||
|
// Have to do it this way because daily run is weird...
|
||||||
|
await game.runToFinalBossEncounter([SpeciesId.MAGIKARP], GameModes.DAILY);
|
||||||
|
} else if (mode === "challenge") {
|
||||||
|
await game.challengeMode.startBattle([SpeciesId.MAGIKARP]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const partyLength = game.scene.getPlayerParty().length;
|
||||||
|
|
||||||
|
game.scene.pokeballCounts[ball] = 1;
|
||||||
|
|
||||||
|
const tSpy = mockI18next();
|
||||||
|
|
||||||
|
game.doThrowPokeball(ball);
|
||||||
|
|
||||||
|
// If still in the command phase due to ball failing, use a move to go on
|
||||||
|
if (game.isCurrentPhase("CommandPhase")) {
|
||||||
|
game.move.select(MoveId.SPLASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
await game.toEndOfTurn();
|
||||||
|
if (expectedResult === "success") {
|
||||||
|
// Check that a mon has been caught by noticing that party length has increased
|
||||||
|
expect(game.scene.getPlayerParty()).toHaveLength(partyLength + 1);
|
||||||
|
} else {
|
||||||
|
expect(tSpy).toHaveBeenCalledWith(expectedResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Throwing balls in classic", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.override
|
||||||
|
.startingWave(199)
|
||||||
|
.startingBiome(BiomeId.END)
|
||||||
|
.battleStyle("single")
|
||||||
|
.moveset([MoveId.SPLASH])
|
||||||
|
.enemyMoveset([MoveId.SPLASH])
|
||||||
|
.startingLevel(9999);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at two mons", async () => {
|
||||||
|
game.override.startingWave(21).startingBiome(BiomeId.TOWN);
|
||||||
|
game.override.battleStyle("double");
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballMulti");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball in end biome", async () => {
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForce");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at two mons in end biome", async () => {
|
||||||
|
game.override.battleStyle("double");
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForce");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at two previously caught mon in end biome", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "success");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at two mons in end biome", async () => {
|
||||||
|
game.override.battleStyle("double");
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballMulti");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at final boss", async () => {
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForceFinalBoss");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing rogue ball at final boss with full dex", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.ROGUE_BALL, "battle:noPokeballForceFinalBossCatchable");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing master ball at final boss with full dex", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "success");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Throwing balls in fresh start challenge", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.challengeMode.addChallenge(Challenges.FRESH_START, 2, 1);
|
||||||
|
game.override
|
||||||
|
.startingWave(199)
|
||||||
|
.startingBiome(BiomeId.END)
|
||||||
|
.battleStyle("single")
|
||||||
|
.moveset([MoveId.SPLASH])
|
||||||
|
.enemyMoveset([MoveId.SPLASH])
|
||||||
|
.startingLevel(9999);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tests should give the same result as a normal classic run, except for the last one
|
||||||
|
it("throwing ball in end biome", async () => {
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForce", "challenge");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at previously caught mon in end biome", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "success", "challenge");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at final boss", async () => {
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForceFinalBoss", "challenge");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing rogue ball at final boss with full dex", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.ROGUE_BALL, "battle:noPokeballForceFinalBossCatchable", "challenge");
|
||||||
|
});
|
||||||
|
|
||||||
|
// If a challenge is active, even if the dex is complete we still need to weaken the final boss to master ball it
|
||||||
|
it("throwing ball at final boss with full dex", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForceFinalBossCatchable", "challenge");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Throwing balls in full fresh start challenge", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.challengeMode.addChallenge(Challenges.FRESH_START, 1, 1);
|
||||||
|
game.override
|
||||||
|
.startingWave(199)
|
||||||
|
.startingBiome(BiomeId.END)
|
||||||
|
.battleStyle("single")
|
||||||
|
.moveset([MoveId.SPLASH])
|
||||||
|
.enemyMoveset([MoveId.SPLASH])
|
||||||
|
.startingLevel(9999);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Paradox mons and final boss can NEVER be caught in the full fresh start challenge
|
||||||
|
it("throwing ball at previously caught mon in end biome", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForce", "challenge");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at final boss with full dex", async () => {
|
||||||
|
await game.importData("./test/test-utils/saves/everything.prsv");
|
||||||
|
game.override.startingWave(200);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForceFinalBoss", "challenge");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Throwing balls in daily run", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("test-seed");
|
||||||
|
game.override
|
||||||
|
.startingWave(50)
|
||||||
|
.startingBiome(BiomeId.END)
|
||||||
|
.battleStyle("single")
|
||||||
|
.moveset([MoveId.SPLASH])
|
||||||
|
.enemyMoveset([MoveId.SPLASH])
|
||||||
|
.startingLevel(9999);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at daily run boss", async () => {
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballForceFinalBoss", "daily");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Throwing balls at trainers", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.override
|
||||||
|
.battleType(BattleType.TRAINER)
|
||||||
|
.randomTrainer({ trainerType: TrainerType.ACE_TRAINER })
|
||||||
|
.moveset([MoveId.SPLASH])
|
||||||
|
.enemyMoveset([MoveId.SPLASH])
|
||||||
|
.startingLevel(9999);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at a trainer", async () => {
|
||||||
|
game.override.startingWave(21);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballTrainer");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at a trainer in a double battle", async () => {
|
||||||
|
game.override.startingWave(21).randomTrainer({ trainerType: TrainerType.TWINS });
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballTrainer");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throwing ball at a trainer in the end biome", async () => {
|
||||||
|
game.override.startingWave(195).startingBiome(BiomeId.END);
|
||||||
|
await runPokeballTest(game, PokeballType.MASTER_BALL, "battle:noPokeballTrainer");
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user