Merge 9062925cf8
into 605ae9e1c3
This commit is contained in:
commit
2bc786503c
|
@ -1674,7 +1674,12 @@ export default class BattleScene extends SceneBase {
|
|||
this.scoreText.setVisible(this.gameMode.isDaily);
|
||||
}
|
||||
|
||||
updateAndShowText(duration: integer): void {
|
||||
/**
|
||||
* Displays the current luck value.
|
||||
* @param duration The time for this label to fade in, if it is not already visible.
|
||||
* @param isDaily If true, hides the label. (This is done because Luck does not apply in Daily Mode anymore)
|
||||
*/
|
||||
updateAndShowText(duration: number, isDaily?: boolean): void {
|
||||
const labels = [ this.luckLabelText, this.luckText ];
|
||||
labels.forEach(t => t.setAlpha(0));
|
||||
const luckValue = getPartyLuckValue(this.getParty());
|
||||
|
@ -1685,12 +1690,16 @@ export default class BattleScene extends SceneBase {
|
|||
this.luckText.setTint(0xffef5c, 0x47ff69, 0x6b6bff, 0xff6969);
|
||||
}
|
||||
this.luckLabelText.setX((this.game.canvas.width / 6) - 2 - (this.luckText.displayWidth + 2));
|
||||
if (isDaily) {
|
||||
// Hide luck label
|
||||
labels.forEach(t => t.setVisible(false));
|
||||
}
|
||||
this.tweens.add({
|
||||
targets: labels,
|
||||
duration: duration,
|
||||
alpha: 1,
|
||||
onComplete: () => {
|
||||
labels.forEach(t => t.setVisible(true));
|
||||
labels.forEach(t => t.setVisible(!isDaily));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1699,7 +1699,8 @@ const modifierPool: ModifierPool = {
|
|||
new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 50), 4) * 6, 24),
|
||||
new WeightedModifierType(modifierTypes.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
|
||||
new WeightedModifierType(modifierTypes.EVIOLITE, (party: Pokemon[]) => {
|
||||
if (!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.unlocks[Unlockables.EVIOLITE]) {
|
||||
const { gameMode, gameData } = party[0].scene;
|
||||
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
|
||||
return party.some(p => ((p.getSpeciesForm(true).speciesId in pokemonEvolutions) || (p.isFusion() && (p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions))) && !p.getHeldItems().some(i => i instanceof Modifiers.EvolutionStatBoosterModifier)) ? 10 : 0;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1777,7 +1778,7 @@ const modifierPool: ModifierPool = {
|
|||
new WeightedModifierType(modifierTypes.MULTI_LENS, 18),
|
||||
new WeightedModifierType(modifierTypes.VOUCHER_PREMIUM, (party: Pokemon[], rerollCount: integer) => !party[0].scene.gameMode.isDaily && !party[0].scene.gameMode.isEndless && !party[0].scene.gameMode.isSplicedOnly ? Math.max(5 - rerollCount * 2, 0) : 0, 5),
|
||||
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => !party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24),
|
||||
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => (!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE]) ? 1 : 0, 1),
|
||||
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => (party[0].scene.gameMode.isDaily || (!party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))) ? 1 : 0, 1),
|
||||
].map(m => {
|
||||
m.setTier(ModifierTier.MASTER); return m;
|
||||
})
|
||||
|
@ -1969,9 +1970,13 @@ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool
|
|||
}
|
||||
|
||||
const tierWeights = [ 768 / 1024, 195 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ];
|
||||
export const itemPoolChecks: Map<ModifierTypeKeys, boolean> = new Map();
|
||||
|
||||
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount: integer = 0) {
|
||||
const pool = getModifierPoolForType(poolType);
|
||||
itemPoolChecks.forEach((v, k) => {
|
||||
itemPoolChecks.set(k, false);
|
||||
});
|
||||
|
||||
const ignoredIndexes = {};
|
||||
const modifierTableData = {};
|
||||
|
@ -2008,6 +2013,9 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
|
|||
ignoredIndexes[t].push(i++);
|
||||
return total;
|
||||
}
|
||||
if (itemPoolChecks.has(modifierType.modifierType.id as ModifierTypeKeys)) {
|
||||
itemPoolChecks.set(modifierType.modifierType.id as ModifierTypeKeys, true);
|
||||
}
|
||||
thresholds.set(total, i++);
|
||||
return total;
|
||||
}, 0);
|
||||
|
@ -2410,8 +2418,16 @@ export class ModifierTypeOption {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the team's luck value.
|
||||
* @param party The player's party.
|
||||
* @returns A value between 0 and 14, or 0 if the player is in Daily Run mode.
|
||||
*/
|
||||
export function getPartyLuckValue(party: Pokemon[]): integer {
|
||||
const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() : 0)
|
||||
if (party[0].scene.gameMode.isDaily) {
|
||||
return 0;
|
||||
}
|
||||
const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? (p.scene.gameMode.isDaily ? 0 : p.getLuck()) : 0)
|
||||
.reduce((total: integer, value: integer) => total += value, 0), 0, 14);
|
||||
return luck || 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { type PokeballCounts } from "./battle-scene";
|
|||
import { Gender } from "./data/gender";
|
||||
import { Variant } from "./data/variant";
|
||||
import { type ModifierOverride } from "./modifier/modifier-type";
|
||||
import { Unlockables } from "./system/unlockables";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
||||
|
@ -70,8 +71,10 @@ class DefaultOverrides {
|
|||
[PokeballType.MASTER_BALL]: 0,
|
||||
},
|
||||
};
|
||||
/** Forces an item to be UNLOCKED */
|
||||
readonly ITEM_UNLOCK_OVERRIDE: Unlockables[] = [];
|
||||
/** Set to `true` to show all tutorials */
|
||||
readonly BYPASS_TUTORIAL_SKIP: boolean = false;
|
||||
readonly BYPASS_TUTORIAL_SKIP_OVERRIDE: boolean = false;
|
||||
|
||||
// ----------------
|
||||
// PLAYER OVERRIDES
|
||||
|
|
|
@ -76,7 +76,8 @@ export class TitlePhase extends Phase {
|
|||
this.scene.ui.clearText();
|
||||
this.end();
|
||||
};
|
||||
if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
|
||||
const { gameData } = this.scene;
|
||||
if (gameData.isUnlocked(Unlockables.ENDLESS_MODE)) {
|
||||
const options: OptionSelectItem[] = [
|
||||
{
|
||||
label: GameMode.getModeName(GameModes.CLASSIC),
|
||||
|
@ -100,7 +101,7 @@ export class TitlePhase extends Phase {
|
|||
}
|
||||
}
|
||||
];
|
||||
if (this.scene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) {
|
||||
if (gameData.isUnlocked(Unlockables.SPLICED_ENDLESS_MODE)) {
|
||||
options.push({
|
||||
label: GameMode.getModeName(GameModes.SPLICED_ENDLESS),
|
||||
handler: () => {
|
||||
|
@ -220,6 +221,7 @@ export class TitlePhase extends Phase {
|
|||
|
||||
const modifiers: Modifier[] = Array(3).fill(null).map(() => modifierTypes.EXP_SHARE().withIdFromFunc(modifierTypes.EXP_SHARE).newModifier())
|
||||
.concat(Array(3).fill(null).map(() => modifierTypes.GOLDEN_EXP_CHARM().withIdFromFunc(modifierTypes.GOLDEN_EXP_CHARM).newModifier()))
|
||||
.concat([modifierTypes.MAP().withIdFromFunc(modifierTypes.MAP).newModifier()])
|
||||
.concat(getDailyRunStarterModifiers(party))
|
||||
.filter((m) => m !== null);
|
||||
|
||||
|
|
|
@ -372,6 +372,18 @@ export class GameData {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an `Unlockable` has been unlocked.
|
||||
* @param unlockable The Unlockable to check
|
||||
* @returns `true` if the player has unlocked this `Unlockable` or an override has enabled it
|
||||
*/
|
||||
public isUnlocked(unlockable: Unlockables): boolean {
|
||||
if (Overrides.ITEM_UNLOCK_OVERRIDE.includes(unlockable)) {
|
||||
return true;
|
||||
}
|
||||
return this.unlocks[unlockable];
|
||||
}
|
||||
|
||||
public saveSystem(): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
this.scene.ui.savingIcon.show();
|
||||
|
|
|
@ -22,15 +22,25 @@ export function applySessionDataPatches(data: SessionSaveData) {
|
|||
} else if (m.className === "PokemonResetNegativeStatStageModifier") {
|
||||
m.className = "ResetNegativeStatStageModifier";
|
||||
} else if (m.className === "TempBattleStatBoosterModifier") {
|
||||
m.className = "TempStatStageBoosterModifier";
|
||||
m.typeId = "TEMP_STAT_STAGE_BOOSTER";
|
||||
// Dire Hit no longer a part of the TempBattleStatBoosterModifierTypeGenerator
|
||||
if (m.typeId !== "DIRE_HIT") {
|
||||
m.className = "TempStatStageBoosterModifier";
|
||||
m.typeId = "TEMP_STAT_STAGE_BOOSTER";
|
||||
|
||||
// Migration from TempBattleStat to Stat
|
||||
const newStat = m.typePregenArgs[0] + 1;
|
||||
m.typePregenArgs[0] = newStat;
|
||||
// Migration from TempBattleStat to Stat
|
||||
const newStat = m.typePregenArgs[0] + 1;
|
||||
m.typePregenArgs[0] = newStat;
|
||||
|
||||
// From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ]
|
||||
m.args = [ newStat, 5, m.args[1] ];
|
||||
} else {
|
||||
m.className = "TempCritBoosterModifier";
|
||||
m.typePregenArgs = [];
|
||||
|
||||
// From [ stat, battlesLeft ] to [ maxBattles, battleCount ]
|
||||
m.args = [ 5, m.args[1] ];
|
||||
}
|
||||
|
||||
// From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ]
|
||||
m.args = [ newStat, 5, m.args[1] ];
|
||||
} else if (m.className === "DoubleBattleChanceBoosterModifier" && m.args.length === 1) {
|
||||
let maxBattles: number;
|
||||
switch (m.typeId) {
|
||||
|
@ -73,7 +83,7 @@ export function applySystemDataPatches(data: SystemSaveData) {
|
|||
case "1.0.3":
|
||||
case "1.0.4":
|
||||
// --- LEGACY PATCHES ---
|
||||
if (data.starterData) {
|
||||
if (data.starterData && data.dexData) {
|
||||
// Migrate ability starter data if empty for caught species
|
||||
Object.keys(data.starterData).forEach(sd => {
|
||||
if (data.dexData[sd]?.caughtAttr && (data.starterData[sd] && !data.starterData[sd].abilityAttr)) {
|
||||
|
@ -104,12 +114,14 @@ export function applySystemDataPatches(data: SystemSaveData) {
|
|||
// --- PATCHES ---
|
||||
|
||||
// Fix Starter Data
|
||||
for (const starterId of defaultStarterSpecies) {
|
||||
if (data.starterData[starterId]?.abilityAttr) {
|
||||
data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1;
|
||||
}
|
||||
if (data.dexData[starterId]?.caughtAttr) {
|
||||
data.dexData[starterId].caughtAttr |= DexAttr.FEMALE;
|
||||
if (data.starterData && data.dexData) {
|
||||
for (const starterId of defaultStarterSpecies) {
|
||||
if (data.starterData[starterId]?.abilityAttr) {
|
||||
data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1;
|
||||
}
|
||||
if (data.dexData[starterId]?.caughtAttr) {
|
||||
data.dexData[starterId].caughtAttr |= DexAttr.FEMALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
import { MapModifier } from "#app/modifier/modifier";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import GameManager from "./utils/gameManager";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import { getPartyLuckValue, itemPoolChecks } from "#app/modifier/modifier-type";
|
||||
import { Biome } from "#app/enums/biome";
|
||||
import { BattleEndPhase } from "#app/phases/battle-end-phase";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
import Overrides from "#app/overrides";
|
||||
|
||||
//const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Daily Mode", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
|
@ -28,5 +38,97 @@ describe("Daily Mode", () => {
|
|||
expect(pkm.level).toBe(20);
|
||||
expect(pkm.moveset.length).toBeGreaterThan(0);
|
||||
});
|
||||
expect(game.scene.getModifiers(MapModifier).length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
//*
|
||||
// Need to figure out how to properly start a battle
|
||||
// Need to fix eviolite - test keeps insisting it is not in loot table, even though Mini Black Hole (which is using the exact same condition) is
|
||||
describe("Shop modifications", async () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
|
||||
game.override
|
||||
.startingWave(9)
|
||||
.startingBiome(Biome.ICE_CAVE) // Will lead to Snowy Forest with randomly generated weather
|
||||
.battleType("single")
|
||||
.shinyLevel(true)
|
||||
.startingLevel(100) // Avoid levelling up
|
||||
.enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents()
|
||||
.disableTrainerWaves()
|
||||
.moveset([Moves.KOWTOW_CLEAVE])
|
||||
.enemyMoveset(Moves.SPLASH);
|
||||
itemPoolChecks.set("EVIOLITE", false);
|
||||
itemPoolChecks.set("MINI_BLACK_HOLE", false);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
itemPoolChecks.clear();
|
||||
});
|
||||
|
||||
it("should not have Eviolite and Mini Black Hole available in Classic if not unlocked", async () => {
|
||||
await game.classicMode.runToSummon();
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeFalsy();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeFalsy();
|
||||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to(BattleEndPhase);
|
||||
game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
|
||||
expect(game.scene.ui.getHandler()).toBeInstanceOf(ModifierSelectUiHandler);
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeFalsy();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
it("should have Eviolite and Mini Black Hole available in Daily", async () => {
|
||||
await game.dailyMode.runToSummon();
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeFalsy();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeFalsy();
|
||||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to(BattleEndPhase);
|
||||
game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
|
||||
expect(game.scene.ui.getHandler()).toBeInstanceOf(ModifierSelectUiHandler);
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("EVIOLITE")).toBeTruthy();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeDefined();
|
||||
expect(itemPoolChecks.get("MINI_BLACK_HOLE")).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it("should apply luck in Classic Mode", async () => {
|
||||
await game.classicMode.runToSummon();
|
||||
const party = game.scene.getParty();
|
||||
expect(Overrides.SHINY_OVERRIDE).toBeTruthy();
|
||||
expect(party[0]).toBeDefined();
|
||||
expect(party[0].getLuck()).toBeGreaterThan(0);
|
||||
expect(getPartyLuckValue(party)).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should not apply luck in Daily Run", async () => {
|
||||
await game.dailyMode.runToSummon();
|
||||
const party = game.scene.getParty();
|
||||
expect(party[0]).toBeDefined();
|
||||
expect(party[0].getLuck()).toBeGreaterThan(0);
|
||||
expect(getPartyLuckValue(party)).toBe(0);
|
||||
});
|
||||
});
|
||||
//*/
|
||||
|
|
|
@ -2,6 +2,7 @@ import { GameMode, GameModes, getGameMode } from "#app/game-mode";
|
|||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as Utils from "../utils";
|
||||
import GameManager from "./utils/gameManager";
|
||||
|
||||
describe("game-mode", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
@ -12,6 +13,7 @@ describe("game-mode", () => {
|
|||
});
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
vi.clearAllMocks();
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import { Species } from "#app/enums/species";
|
||||
import { GameModes } from "#app/game-mode";
|
||||
import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import { Biome } from "#enums/biome";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { MockClock } from "#test/utils/mocks/mockClock";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import { Biome } from "#app/enums/biome";
|
||||
|
||||
describe("Reload", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
|
@ -50,6 +54,13 @@ describe("Reload", () => {
|
|||
game.move.select(Moves.KOWTOW_CLEAVE);
|
||||
await game.phaseInterceptor.to("DamagePhase");
|
||||
await game.doKillOpponents();
|
||||
game.onNextPrompt("SelectBiomePhase", Mode.OPTION_SELECT, () => {
|
||||
(game.scene.time as MockClock).overrideDelay = null;
|
||||
const optionSelectUiHandler = game.scene.ui.getHandler() as OptionSelectUiHandler;
|
||||
game.scene.time.delayedCall(1010, () => optionSelectUiHandler.processInput(Button.ACTION));
|
||||
game.endPhase();
|
||||
(game.scene.time as MockClock).overrideDelay = 1;
|
||||
});
|
||||
await game.toNextWave();
|
||||
expect(game.phaseInterceptor.log).toContain("NewBiomeEncounterPhase");
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { BerryType } from "#app/enums/berry-type";
|
|||
import { Button } from "#app/enums/buttons";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import { Species } from "#app/enums/species";
|
||||
import { itemPoolChecks } from "#app/modifier/modifier-type";
|
||||
import { BattleEndPhase } from "#app/phases/battle-end-phase";
|
||||
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
|
@ -94,3 +95,47 @@ describe("UI - Transfer Items", () => {
|
|||
await game.phaseInterceptor.to(SelectModifierPhase);
|
||||
}, 20000);
|
||||
});
|
||||
|
||||
describe.skip("Backup Test", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.battleType("single")
|
||||
.startingLevel(100)
|
||||
.startingWave(1)
|
||||
.startingHeldItems([
|
||||
{ name: "BERRY", count: 1, type: BerryType.SITRUS },
|
||||
{ name: "BERRY", count: 2, type: BerryType.APICOT },
|
||||
{ name: "BERRY", count: 2, type: BerryType.LUM },
|
||||
])
|
||||
.moveset([Moves.DRAGON_CLAW])
|
||||
.enemySpecies(Species.MAGIKARP)
|
||||
.enemyMoveset([Moves.SPLASH]);
|
||||
itemPoolChecks.set("EVIOLITE", false);
|
||||
itemPoolChecks.set("MINI_BLACK_HOLE", false);
|
||||
});
|
||||
it("should run", async () => {
|
||||
await game.classicMode.startBattle([Species.RAYQUAZA, Species.RAYQUAZA, Species.RAYQUAZA]);
|
||||
|
||||
game.move.select(Moves.DRAGON_CLAW);
|
||||
|
||||
game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
|
||||
expect(game.scene.ui.getHandler()).toBeInstanceOf(ModifierSelectUiHandler);
|
||||
});
|
||||
|
||||
await game.phaseInterceptor.to(BattleEndPhase);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,6 +10,8 @@ import { ModifierOverride } from "#app/modifier/modifier-type";
|
|||
import Overrides from "#app/overrides";
|
||||
import { vi } from "vitest";
|
||||
import { GameManagerHelper } from "./gameManagerHelper";
|
||||
import { Unlockables } from "#app/system/unlockables";
|
||||
import { Variant } from "#app/data/variant";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
||||
|
@ -300,6 +302,17 @@ export class OverridesHelper extends GameManagerHelper {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the player access to an Unlockable.
|
||||
* @param unlockable The Unlockable to enable.
|
||||
* @returns this
|
||||
*/
|
||||
enableUnlockable(unlockable: Unlockables[]) {
|
||||
vi.spyOn(Overrides, "ITEM_UNLOCK_OVERRIDE", "get").mockReturnValue(unlockable);
|
||||
this.log("Temporarily unlocked the following content: ", unlockable);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the items rolled at the end of a battle
|
||||
* @param items the items to be rolled
|
||||
|
@ -311,6 +324,25 @@ export class OverridesHelper extends GameManagerHelper {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override player shininess
|
||||
* @param shininess Whether the player's Pokemon should be shiny.
|
||||
*/
|
||||
shinyLevel(shininess: boolean): this {
|
||||
vi.spyOn(Overrides, "SHINY_OVERRIDE", "get").mockReturnValue(shininess);
|
||||
this.log(`Set player Pokemon as ${shininess ? "" : "not "}shiny!`);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Override player shiny variant
|
||||
* @param variant The player's shiny variant.
|
||||
*/
|
||||
variantLevel(variant: Variant): this {
|
||||
vi.spyOn(Overrides, "VARIANT_OVERRIDE", "get").mockReturnValue(variant);
|
||||
this.log(`Set player Pokemon's shiny variant to ${variant}!`);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the enemy (Pokemon) to have the given amount of health segments
|
||||
* @param healthSegments the number of segments to give
|
||||
|
|
|
@ -43,6 +43,7 @@ import { UnavailablePhase } from "#app/phases/unavailable-phase";
|
|||
import { VictoryPhase } from "#app/phases/victory-phase";
|
||||
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
||||
import UI, { Mode } from "#app/ui/ui";
|
||||
import { SelectBiomePhase } from "#app/phases/select-biome-phase";
|
||||
import {
|
||||
MysteryEncounterBattlePhase,
|
||||
MysteryEncounterOptionSelectedPhase,
|
||||
|
@ -122,6 +123,7 @@ export default class PhaseInterceptor {
|
|||
[EndEvolutionPhase, this.startPhase],
|
||||
[LevelCapPhase, this.startPhase],
|
||||
[AttemptRunPhase, this.startPhase],
|
||||
[SelectBiomePhase, this.startPhase],
|
||||
[MysteryEncounterPhase, this.startPhase],
|
||||
[MysteryEncounterOptionSelectedPhase, this.startPhase],
|
||||
[MysteryEncounterBattlePhase, this.startPhase],
|
||||
|
@ -346,7 +348,8 @@ export default class PhaseInterceptor {
|
|||
console.log("setMode", `${Mode[mode]} (=${mode})`, args);
|
||||
const ret = this.originalSetMode.apply(instance, [mode, ...args]);
|
||||
if (!this.phases[currentPhase.constructor.name]) {
|
||||
throw new Error(`missing ${currentPhase.constructor.name} in phaseInterceptor PHASES list`);
|
||||
throw new Error(`missing ${currentPhase.constructor.name} in phaseInterceptor PHASES list --- Add it to PHASES inside of /test/utils/phaseInterceptor.ts`);
|
||||
|
||||
}
|
||||
if (this.phases[currentPhase.constructor.name].endBySetMode) {
|
||||
this.inProgress?.callback();
|
||||
|
|
|
@ -74,11 +74,11 @@ const tutorialHandlers = {
|
|||
* @returns a promise with result `true` if the tutorial was run and finished, `false` otherwise
|
||||
*/
|
||||
export async function handleTutorial(scene: BattleScene, tutorial: Tutorial): Promise<boolean> {
|
||||
if (!scene.enableTutorials && !Overrides.BYPASS_TUTORIAL_SKIP) {
|
||||
if (!scene.enableTutorials && !Overrides.BYPASS_TUTORIAL_SKIP_OVERRIDE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scene.gameData.getTutorialFlags()[tutorial] && !Overrides.BYPASS_TUTORIAL_SKIP) {
|
||||
if (scene.gameData.getTutorialFlags()[tutorial] && !Overrides.BYPASS_TUTORIAL_SKIP_OVERRIDE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||
|
||||
/* Multiplies the appearance duration by the speed parameter so that it is always constant, and avoids "flashbangs" at game speed x5 */
|
||||
this.scene.showShopOverlay(750 * this.scene.gameSpeed);
|
||||
this.scene.updateAndShowText(750);
|
||||
this.scene.updateAndShowText(750, this.scene.gameMode.isDaily);
|
||||
this.scene.updateBiomeWaveText();
|
||||
this.scene.updateMoneyText();
|
||||
|
||||
|
|
Loading…
Reference in New Issue