nit updates and cleanup

This commit is contained in:
ImperialSympathizer 2024-07-19 19:21:46 -04:00
parent 670013a107
commit 186a1af7b8
9 changed files with 89 additions and 51 deletions

View File

@ -2650,8 +2650,8 @@ export default class BattleScene extends SceneBase {
return encounter;
}
// Common / Great / Ultra / Rogue
const tierWeights = [64, 40, 21, 3];
// See Enum values for base tier weights
const tierWeights = [MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE];
// Adjust tier weights by previously encountered events to lower odds of only common/uncommons in run
this.mysteryEncounterData.encounteredEvents.forEach(val => {

View File

@ -206,7 +206,7 @@ export default class Battle {
getBgmOverride(scene: BattleScene): string {
const battlers = this.enemyParty.slice(0, this.getBattlerCount());
if (this.battleType === BattleType.TRAINER || this.mysteryEncounter?.encounterVariant === MysteryEncounterVariant.TRAINER_BATTLE) {
if (!this.started && this.trainer?.config?.encounterBgm && this.trainer?.getEncounterMessages()?.length) {
if (!this.started && this.trainer.config.encounterBgm && this.trainer.getEncounterMessages().length) {
return `encounter_${this.trainer.getEncounterBgm()}`;
}
if (scene.musicPreference === 0) {

View File

@ -27,15 +27,19 @@ export enum MysteryEncounterVariant {
WILD_BATTLE,
BOSS_BATTLE,
NO_BATTLE,
/** For spawning new encounter queries instead of continuing to next wave */
REPEATED_ENCOUNTER
}
/**
* Enum values are base spawn weights of each tier
*/
export enum MysteryEncounterTier {
COMMON,
GREAT,
ULTRA,
ROGUE,
MASTER // Not currently used
COMMON = 64,
GREAT = 40,
ULTRA = 21,
ROGUE = 3,
MASTER = 0 // Not currently used
}
export interface StartOfBattleEffect {
@ -438,7 +442,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @param callback - {@linkcode OptionPhaseCallback}
* @returns
*/
withSimpleOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback) {
withSimpleOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this {
return this.withOption(new MysteryEncounterOptionBuilder().withOptionMode(EncounterOptionMode.DEFAULT).withDialogue(dialogue).withOptionPhase(callback).build());
}

View File

@ -18,6 +18,7 @@ import BattleScene from "#app/battle-scene";
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
import { Type } from "#app/data/type";
import { Status, StatusEffect } from "#app/data/status-effect";
import { MysteryEncounterTier } from "#app/data/mystery-encounters/mystery-encounter";
const namespace = "mysteryEncounter:fieryFallout";
/** Arcanine and Ninetails for 2 Fire types. Lapras, Gengar, Abra for burnable mon. */
@ -38,9 +39,10 @@ describe("Fiery Fallout - Mystery Encounter", () => {
game = new GameManager(phaserGame);
scene = game.scene;
game.override.mysteryEncounterChance(100);
game.override.mysteryEncounterTier(MysteryEncounterTier.COMMON);
game.override.startingWave(defaultWave);
game.override.startingBiome(defaultBiome);
game.override.trainerWave(false);
game.override.disableTrainerWave(true);
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
new Map<Biome, MysteryEncounterType[]>([
@ -55,9 +57,11 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
it("should have the correct properties", async () => {
await game.runToMysteryEncounter(defaultParty);
game.override.mysteryEncounter(MysteryEncounterType.FIERY_FALLOUT);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
expect(FieryFalloutEncounter.encounterType).toBe(MysteryEncounterType.FIERY_FALLOUT);
expect(FieryFalloutEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
expect(FieryFalloutEncounter.dialogue).toBeDefined();
expect(FieryFalloutEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]);
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`);
@ -126,6 +130,10 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
describe("Option 1 - Fight 2 Volcarona", () => {
beforeEach(async () => {
game.override.mysteryEncounter(MysteryEncounterType.FIERY_FALLOUT);
});
it("should have the correct properties", () => {
const option1 = FieryFalloutEncounter.options[0];
expect(option1.optionMode).toBe(EncounterOptionMode.DEFAULT);
@ -144,7 +152,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
it("should start battle against 2 Volcarona", async () => {
const phaseSpy = vi.spyOn(scene, "pushPhase");
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
await runSelectMysteryEncounterOption(game, 1, true);
const enemyField = scene.getEnemyField();
@ -161,7 +169,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
it("should give charcoal to lead pokemon", async () => {
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
await runSelectMysteryEncounterOption(game, 1, true);
await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false);
@ -176,6 +184,10 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
describe("Option 2 - Suffer the weather", () => {
beforeEach(async () => {
game.override.mysteryEncounter(MysteryEncounterType.FIERY_FALLOUT);
});
it("should have the correct properties", () => {
const option1 = FieryFalloutEncounter.options[1];
expect(option1.optionMode).toBe(EncounterOptionMode.DEFAULT);
@ -192,7 +204,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
it("should damage all non-fire party PKM by 20% and randomly burn 1", async () => {
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
const party = scene.getParty();
const lapras = party.find((pkm) => pkm.species.speciesId === Species.LAPRAS);
@ -215,7 +227,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
it("should leave encounter without battle", async () => {
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
await runSelectMysteryEncounterOption(game, 2);
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
@ -223,6 +235,10 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
describe("Option 3 - use FIRE types", () => {
beforeEach(async () => {
game.override.mysteryEncounter(MysteryEncounterType.FIERY_FALLOUT);
});
it("should have the correct properties", () => {
const option1 = FieryFalloutEncounter.options[2];
expect(option1.optionMode).toBe(EncounterOptionMode.DISABLED_OR_SPECIAL);
@ -240,7 +256,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
});
it("should give charcoal to lead pokemon", async () => {
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
await runSelectMysteryEncounterOption(game, 3);
// await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false);
@ -256,7 +272,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
it("should leave encounter without battle", async () => {
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
await runSelectMysteryEncounterOption(game, 3);
expect(leaveEncounterWithoutBattleSpy).toBeCalled();

View File

@ -11,6 +11,7 @@ import { Species } from "#app/enums/species";
import GameManager from "#app/test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { runSelectMysteryEncounterOption } from "../encounterTestUtils";
import { MysteryEncounterTier } from "#app/data/mystery-encounters/mystery-encounter";
const namespace = "mysteryEncounter:lostAtSea";
/** Blastoise for surf. Pidgeot for fly. Abra for none. */
@ -31,7 +32,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
game.override.mysteryEncounterChance(100);
game.override.startingWave(defaultWave);
game.override.startingBiome(defaultBiome);
game.override.trainerWave(false);
game.override.disableTrainerWave(true);
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
new Map<Biome, MysteryEncounterType[]>([
@ -46,9 +47,11 @@ describe("Lost at Sea - Mystery Encounter", () => {
});
it("should have the correct properties", async () => {
await game.runToMysteryEncounter(defaultParty);
game.override.mysteryEncounter(MysteryEncounterType.LOST_AT_SEA);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
expect(LostAtSeaEncounter.encounterType).toBe(MysteryEncounterType.LOST_AT_SEA);
expect(LostAtSeaEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
expect(LostAtSeaEncounter.dialogue).toBeDefined();
expect(LostAtSeaEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]);
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`);
@ -96,6 +99,10 @@ describe("Lost at Sea - Mystery Encounter", () => {
});
describe("Option 1 - Surf", () => {
beforeEach(async () => {
game.override.mysteryEncounter(MysteryEncounterType.LOST_AT_SEA);
});
it("should have the correct properties", () => {
const option1 = LostAtSeaEncounter.options[0];
expect(option1.optionMode).toBe(EncounterOptionMode.DISABLED_OR_DEFAULT);
@ -116,7 +123,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
it("should award exp to surfable PKM (Blastoise)", async () => {
const laprasSpecies = getPokemonSpecies(Species.LAPRAS);
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
const party = game.scene.getParty();
const blastoise = party.find((pkm) => pkm.species.speciesId === Species.PIDGEOT);
const expBefore = blastoise.exp;
@ -130,7 +137,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
game.override.startingWave(33);
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
await runSelectMysteryEncounterOption(game, 1);
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
@ -142,6 +149,10 @@ describe("Lost at Sea - Mystery Encounter", () => {
});
describe("Option 2 - Fly", () => {
beforeEach(async () => {
game.override.mysteryEncounter(MysteryEncounterType.LOST_AT_SEA);
});
it("should have the correct properties", () => {
const option2 = LostAtSeaEncounter.options[1];
@ -165,7 +176,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
const wave = 33;
game.override.startingWave(wave);
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
const party = game.scene.getParty();
const pidgeot = party.find((pkm) => pkm.species.speciesId === Species.PIDGEOT);
const expBefore = pidgeot.exp;
@ -179,7 +190,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
game.override.startingWave(33);
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
await runSelectMysteryEncounterOption(game, 2);
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
@ -191,6 +202,10 @@ describe("Lost at Sea - Mystery Encounter", () => {
});
describe("Option 3 - Wander aimlessy", () => {
beforeEach(async () => {
game.override.mysteryEncounter(MysteryEncounterType.LOST_AT_SEA);
});
it("should have the correct properties", () => {
const option3 = LostAtSeaEncounter.options[2];
@ -210,7 +225,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
it("should damage all (allowed in battle) party PKM by 25%", async () => {
game.override.startingWave(33);
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
const party = game.scene.getParty();
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA);
@ -231,7 +246,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
game.override.startingWave(33);
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(defaultParty);
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
await runSelectMysteryEncounterOption(game, 3);
expect(leaveEncounterWithoutBattleSpy).toBeCalled();

View File

@ -24,24 +24,18 @@ describe("Mystery Encounters", () => {
game.override.startingWave(11);
game.override.mysteryEncounterChance(100);
game.override.mysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS);
game.override.trainerWave(false);
game.override.disableTrainerWave(true);
});
it("Spawns a mystery encounter", async () => {
await game.runToMysteryEncounter([
Species.CHARIZARD,
Species.VOLCARONA
]);
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
});
it("", async () => {
await game.runToMysteryEncounter([
Species.CHARIZARD,
Species.VOLCARONA
]);
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);

View File

@ -35,20 +35,14 @@ describe("Mystery Encounter Phases", () => {
describe("MysteryEncounterPhase", () => {
it("Runs to MysteryEncounterPhase", async() => {
await game.runToMysteryEncounter([
Species.CHARIZARD,
Species.VOLCARONA
]);
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
});
it("Runs MysteryEncounterPhase", async() => {
await game.runToMysteryEncounter([
Species.CHARIZARD,
Species.VOLCARONA
]);
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
game.onNextPrompt("MysteryEncounterPhase", Mode.MYSTERY_ENCOUNTER, () => {
// End phase early for test
@ -65,10 +59,7 @@ describe("Mystery Encounter Phases", () => {
it("Selects an option for MysteryEncounterPhase", async() => {
const dialogueSpy = vi.spyOn(game.scene.ui, "showDialogue");
const messageSpy = vi.spyOn(game.scene.ui, "showText");
await game.runToMysteryEncounter([
Species.CHARIZARD,
Species.VOLCARONA
]);
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
game.onNextPrompt("MysteryEncounterPhase", Mode.MESSAGE, () => {
const handler = game.scene.ui.getHandler() as MessageUiHandler;

View File

@ -36,6 +36,8 @@ import TargetSelectUiHandler from "#app/ui/target-select-ui-handler.js";
import BattleMessageUiHandler from "#app/ui/battle-message-ui-handler";
import {MysteryEncounterPhase} from "#app/phases/mystery-encounter-phases";
import { OverridesHelper } from "./overridesHelper";
import { expect } from "vitest";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
/**
* Class to manage the game state and transitions between phases.
@ -144,10 +146,11 @@ export default class GameManager {
/**
* Runs the game to a mystery encounter phase.
* @param encounterType - if specified, will expect encounter to have been spawned
* @param species - Optional array of species for party.
* @returns A promise that resolves when the EncounterPhase ends.
*/
async runToMysteryEncounter(species?: Species[]) {
async runToMysteryEncounter(encounterType?: MysteryEncounterType, species?: Species[]) {
await this.runToTitle();
this.onNextPrompt("TitlePhase", Mode.TITLE, () => {
@ -164,6 +167,9 @@ export default class GameManager {
}, () => this.isCurrentPhase(MysteryEncounterPhase), true);
await this.phaseInterceptor.run(EncounterPhase);
if (encounterType) {
expect(this.scene.currentBattle?.mysteryEncounter?.encounterType).toBe(encounterType);
}
}
/**

View File

@ -5,6 +5,7 @@ import { MockInstance, vi } from "vitest";
import GameManager from "#test/utils/gameManager";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import * as overrides from "#app/overrides";
import { MysteryEncounterTier } from "#app/data/mystery-encounters/mystery-encounter";
/**
* Helper to handle overrides in tests
@ -28,6 +29,17 @@ export class OverridesHelper {
return spy;
}
/**
* Override the encounter chance for a mystery encounter.
* @returns spy instance
* @param tier
*/
mysteryEncounterTier(tier: MysteryEncounterTier): MockInstance {
const spy = vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_TIER_OVERRIDE", "get").mockReturnValue(tier);
this.log(`Mystery encounter tier set to ${tier}!`);
return spy;
}
/**
* Override the encounter that spawns for the scene
* @param encounterType
@ -63,11 +75,11 @@ export class OverridesHelper {
/**
* Override each wave to have or not have standard trainer battles
* @returns spy instance
* @param isTrainer
* @param disable - true
*/
trainerWave(isTrainer: boolean): MockInstance {
const spy = vi.spyOn(this.game.scene.gameMode, "isWaveTrainer").mockReturnValue(isTrainer);
this.log(`${isTrainer? "forcing" : "ignoring"} trainer waves!`);
disableTrainerWave(disable: boolean): MockInstance {
const spy = vi.spyOn(this.game.scene.gameMode, "isWaveTrainer").mockReturnValue(!disable);
this.log(`Standard trainer waves are ${disable? "disabled" : "enabled"}!`);
return spy;
}