[P1][Beta] Fix softlock when losing a run on local build (#4846)
This commit is contained in:
parent
cebedd220b
commit
4802f512ff
|
@ -125,10 +125,9 @@ export class GameOverPhase extends BattlePhase {
|
||||||
}
|
}
|
||||||
|
|
||||||
const clear = (endCardPhase?: EndCardPhase) => {
|
const clear = (endCardPhase?: EndCardPhase) => {
|
||||||
if (newClear) {
|
|
||||||
this.handleUnlocks();
|
|
||||||
}
|
|
||||||
if (this.isVictory && newClear) {
|
if (this.isVictory && newClear) {
|
||||||
|
this.handleUnlocks();
|
||||||
|
|
||||||
for (const species of this.firstRibbons) {
|
for (const species of this.firstRibbons) {
|
||||||
this.scene.unshiftPhase(new RibbonModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PLUS, species));
|
this.scene.unshiftPhase(new RibbonModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PLUS, species));
|
||||||
}
|
}
|
||||||
|
@ -183,6 +182,8 @@ export class GameOverPhase extends BattlePhase {
|
||||||
this.scene.gameData.offlineNewClear(this.scene).then(result => {
|
this.scene.gameData.offlineNewClear(this.scene).then(result => {
|
||||||
doGameOver(result);
|
doGameOver(result);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
doGameOver(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import { Biome } from "#enums/biome";
|
||||||
|
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, vi } from "vitest";
|
||||||
|
import { achvs } from "#app/system/achv";
|
||||||
|
import { Unlockables } from "#app/system/unlockables";
|
||||||
|
|
||||||
|
describe("Game Over Phase", () => {
|
||||||
|
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
|
||||||
|
.moveset([ Moves.MEMENTO, Moves.ICE_BEAM, Moves.SPLASH ])
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
|
.battleType("single")
|
||||||
|
.disableCrits()
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyMoveset(Moves.SPLASH)
|
||||||
|
.startingWave(200)
|
||||||
|
.startingBiome(Biome.END)
|
||||||
|
.startingLevel(10000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("winning a run should give rewards", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
vi.spyOn(game.scene, "validateAchv");
|
||||||
|
|
||||||
|
// Note: `game.doKillOpponents()` does not properly handle final boss
|
||||||
|
// Final boss phase 1
|
||||||
|
game.move.select(Moves.ICE_BEAM);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Final boss phase 2
|
||||||
|
game.move.select(Moves.ICE_BEAM);
|
||||||
|
await game.phaseInterceptor.to("PostGameOverPhase", false);
|
||||||
|
|
||||||
|
// The game refused to actually give the vouchers during tests,
|
||||||
|
// so the best we can do is to check that their reward phases occurred.
|
||||||
|
expect(game.phaseInterceptor.log.includes("GameOverPhase")).toBe(true);
|
||||||
|
expect(game.phaseInterceptor.log.includes("UnlockPhase")).toBe(true);
|
||||||
|
expect(game.phaseInterceptor.log.includes("RibbonModifierRewardPhase")).toBe(true);
|
||||||
|
expect(game.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]).toBe(true);
|
||||||
|
expect(game.scene.validateAchv).toHaveBeenCalledWith(achvs.CLASSIC_VICTORY);
|
||||||
|
expect(game.scene.gameData.achvUnlocks[achvs.CLASSIC_VICTORY.id]).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("losing a run should not give rewards", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
vi.spyOn(game.scene, "validateAchv");
|
||||||
|
|
||||||
|
game.move.select(Moves.MEMENTO);
|
||||||
|
await game.phaseInterceptor.to("PostGameOverPhase", false);
|
||||||
|
|
||||||
|
expect(game.phaseInterceptor.log.includes("GameOverPhase")).toBe(true);
|
||||||
|
expect(game.phaseInterceptor.log.includes("UnlockPhase")).toBe(false);
|
||||||
|
expect(game.phaseInterceptor.log.includes("RibbonModifierRewardPhase")).toBe(false);
|
||||||
|
expect(game.phaseInterceptor.log.includes("GameOverModifierRewardPhase")).toBe(false);
|
||||||
|
expect(game.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]).toBe(false);
|
||||||
|
expect(game.scene.validateAchv).not.toHaveBeenCalledWith(achvs.CLASSIC_VICTORY);
|
||||||
|
expect(game.scene.gameData.achvUnlocks[achvs.CLASSIC_VICTORY.id]).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -55,6 +55,11 @@ import {
|
||||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
import { PartyExpPhase } from "#app/phases/party-exp-phase";
|
import { PartyExpPhase } from "#app/phases/party-exp-phase";
|
||||||
import { ExpPhase } from "#app/phases/exp-phase";
|
import { ExpPhase } from "#app/phases/exp-phase";
|
||||||
|
import { GameOverPhase } from "#app/phases/game-over-phase";
|
||||||
|
import { RibbonModifierRewardPhase } from "#app/phases/ribbon-modifier-reward-phase";
|
||||||
|
import { GameOverModifierRewardPhase } from "#app/phases/game-over-modifier-reward-phase";
|
||||||
|
import { UnlockPhase } from "#app/phases/unlock-phase";
|
||||||
|
import { PostGameOverPhase } from "#app/phases/post-game-over-phase";
|
||||||
|
|
||||||
export interface PromptHandler {
|
export interface PromptHandler {
|
||||||
phaseTarget?: string;
|
phaseTarget?: string;
|
||||||
|
@ -113,10 +118,15 @@ type PhaseClass =
|
||||||
| typeof MysteryEncounterBattlePhase
|
| typeof MysteryEncounterBattlePhase
|
||||||
| typeof MysteryEncounterRewardsPhase
|
| typeof MysteryEncounterRewardsPhase
|
||||||
| typeof PostMysteryEncounterPhase
|
| typeof PostMysteryEncounterPhase
|
||||||
|
| typeof RibbonModifierRewardPhase
|
||||||
|
| typeof GameOverModifierRewardPhase
|
||||||
| typeof ModifierRewardPhase
|
| typeof ModifierRewardPhase
|
||||||
| typeof PartyExpPhase
|
| typeof PartyExpPhase
|
||||||
| typeof ExpPhase
|
| typeof ExpPhase
|
||||||
| typeof EncounterPhase;
|
| typeof EncounterPhase
|
||||||
|
| typeof GameOverPhase
|
||||||
|
| typeof UnlockPhase
|
||||||
|
| typeof PostGameOverPhase;
|
||||||
|
|
||||||
type PhaseString =
|
type PhaseString =
|
||||||
| "LoginPhase"
|
| "LoginPhase"
|
||||||
|
@ -167,10 +177,15 @@ type PhaseString =
|
||||||
| "MysteryEncounterBattlePhase"
|
| "MysteryEncounterBattlePhase"
|
||||||
| "MysteryEncounterRewardsPhase"
|
| "MysteryEncounterRewardsPhase"
|
||||||
| "PostMysteryEncounterPhase"
|
| "PostMysteryEncounterPhase"
|
||||||
|
| "RibbonModifierRewardPhase"
|
||||||
|
| "GameOverModifierRewardPhase"
|
||||||
| "ModifierRewardPhase"
|
| "ModifierRewardPhase"
|
||||||
| "PartyExpPhase"
|
| "PartyExpPhase"
|
||||||
| "ExpPhase"
|
| "ExpPhase"
|
||||||
| "EncounterPhase";
|
| "EncounterPhase"
|
||||||
|
| "GameOverPhase"
|
||||||
|
| "UnlockPhase"
|
||||||
|
| "PostGameOverPhase";
|
||||||
|
|
||||||
type PhaseInterceptorPhase = PhaseClass | PhaseString;
|
type PhaseInterceptorPhase = PhaseClass | PhaseString;
|
||||||
|
|
||||||
|
@ -245,10 +260,15 @@ export default class PhaseInterceptor {
|
||||||
[ MysteryEncounterBattlePhase, this.startPhase ],
|
[ MysteryEncounterBattlePhase, this.startPhase ],
|
||||||
[ MysteryEncounterRewardsPhase, this.startPhase ],
|
[ MysteryEncounterRewardsPhase, this.startPhase ],
|
||||||
[ PostMysteryEncounterPhase, this.startPhase ],
|
[ PostMysteryEncounterPhase, this.startPhase ],
|
||||||
|
[ RibbonModifierRewardPhase, this.startPhase ],
|
||||||
|
[ GameOverModifierRewardPhase, this.startPhase ],
|
||||||
[ ModifierRewardPhase, this.startPhase ],
|
[ ModifierRewardPhase, this.startPhase ],
|
||||||
[ PartyExpPhase, this.startPhase ],
|
[ PartyExpPhase, this.startPhase ],
|
||||||
[ ExpPhase, this.startPhase ],
|
[ ExpPhase, this.startPhase ],
|
||||||
[ EncounterPhase, this.startPhase ],
|
[ EncounterPhase, this.startPhase ],
|
||||||
|
[ GameOverPhase, this.startPhase ],
|
||||||
|
[ UnlockPhase, this.startPhase ],
|
||||||
|
[ PostGameOverPhase, this.startPhase ],
|
||||||
];
|
];
|
||||||
|
|
||||||
private endBySetMode = [
|
private endBySetMode = [
|
||||||
|
|
Loading…
Reference in New Issue