Compare commits

...

8 Commits

Author SHA1 Message Date
Bertie690
11a25bac56
Merge c1c66a473b into f42237d415 2025-08-14 13:28:36 -04:00
Bertie690
f42237d415
[Refactor] Removed map(x => x) (#6256)
* Enforced a few usages of `toCamelCase`

* Removed `map(x => x)`

* Removed more maps and sufff

* Update test/mystery-encounter/encounters/weird-dream-encounter.test.ts

* Update game-data.ts types to work
2025-08-14 10:25:44 -07:00
fabske0
b44f0a4176
[Refactor] Remove bgm param from arena constructor (#6254) 2025-08-14 16:52:56 +00:00
Bertie690
c1c66a473b
Update src/data/phase-priority-queue.ts
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-08-11 10:41:55 -04:00
Bertie690
d576da72d2
Update src/data/phase-priority-queue.ts
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-08-11 10:41:44 -04:00
Bertie690
018a0091f3 Fixed intimidate bugs fr fr 2025-08-10 23:09:11 -04:00
Bertie690
2d6267b668 Fixed comment 2025-08-04 17:08:28 -04:00
Bertie690
8b65f9afab Added TODO test case + documentation for failing intim test 2025-08-04 16:27:47 -04:00
17 changed files with 211 additions and 98 deletions

View File

@ -104,6 +104,7 @@ import {
getLuckString,
getLuckTextTint,
getPartyLuckValue,
type ModifierType,
PokemonHeldItemModifierType,
} from "#modifiers/modifier-type";
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
@ -1203,7 +1204,9 @@ export class BattleScene extends SceneBase {
this.updateScoreText();
this.scoreText.setVisible(false);
[this.luckLabelText, this.luckText].map(t => t.setVisible(false));
[this.luckLabelText, this.luckText].forEach(t => {
t.setVisible(false);
});
this.newArena(Overrides.STARTING_BIOME_OVERRIDE || BiomeId.TOWN);
@ -1237,8 +1240,7 @@ export class BattleScene extends SceneBase {
Object.values(mp)
.flat()
.map(mt => mt.modifierType)
.filter(mt => "localize" in mt)
.map(lpb => lpb as unknown as Localizable),
.filter((mt): mt is ModifierType & Localizable => "localize" in mt && typeof mt.localize === "function"),
),
];
for (const item of localizable) {
@ -1513,8 +1515,8 @@ export class BattleScene extends SceneBase {
return this.currentBattle;
}
newArena(biome: BiomeId, playerFaints?: number): Arena {
this.arena = new Arena(biome, BiomeId[biome].toLowerCase(), playerFaints);
newArena(biome: BiomeId, playerFaints = 0): Arena {
this.arena = new Arena(biome, playerFaints);
this.eventTarget.dispatchEvent(new NewArenaEvent());
this.arenaBg.pipelineData = {
@ -2711,7 +2713,9 @@ export class BattleScene extends SceneBase {
}
}
this.party.map(p => p.updateInfo(instant));
this.party.forEach(p => {
p.updateInfo(instant);
});
} else {
const args = [this];
if (modifier.shouldApply(...args)) {

View File

@ -74,6 +74,7 @@ import {
randSeedItem,
toDmgValue,
} from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next";
export class Ability implements Localizable {
@ -109,13 +110,9 @@ export class Ability implements Localizable {
}
localize(): void {
const i18nKey = AbilityId[this.id]
.split("_")
.filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("") as string;
const i18nKey = toCamelCase(AbilityId[this.id]);
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : "";
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`)}${this.nameAppend}` : "";
this.description = this.id ? (i18next.t(`ability:${i18nKey}.description`) as string) : "";
}

View File

@ -1866,17 +1866,16 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {};
export function initPokemonPrevolutions(): void {
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
const prevolutionKeys = Object.keys(pokemonEvolutions);
prevolutionKeys.forEach(pk => {
const evolutions = pokemonEvolutions[pk];
// TODO: Why do we have empty strings in our array?
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ];
for (const [pk, evolutions] of Object.entries(pokemonEvolutions)) {
for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue;
}
pokemonPrevolutions[ev.speciesId] = Number.parseInt(pk) as SpeciesId;
}
});
}
}

View File

@ -90,7 +90,7 @@ import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindS
import type { TurnMove } from "#types/turn-move";
import { BooleanHolder, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
import { getEnumValues } from "#utils/enums";
import { toTitleCase } from "#utils/strings";
import { toCamelCase, toTitleCase } from "#utils/strings";
import i18next from "i18next";
import { applyChallenges } from "#utils/challenge-utils";
@ -162,10 +162,16 @@ export abstract class Move implements Localizable {
}
localize(): void {
const i18nKey = MoveId[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string;
const i18nKey = toCamelCase(MoveId[this.id])
this.name = this.id ? `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}` : "";
this.effect = this.id ? `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}` : "";
if (this.id === MoveId.NONE) {
this.name = "";
this.effect = ""
return;
}
this.name = `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}`;
this.effect = `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}`;
}
/**
@ -5926,8 +5932,8 @@ export class ProtectAttr extends AddBattlerTagAttr {
for (const turnMove of user.getLastXMoves(-1).slice()) {
if (
// Quick & Wide guard increment the Protect counter without using it for fail chance
!(allMoves[turnMove.move].hasAttr("ProtectAttr") ||
[MoveId.QUICK_GUARD, MoveId.WIDE_GUARD].includes(turnMove.move)) ||
!(allMoves[turnMove.move].hasAttr("ProtectAttr") ||
[MoveId.QUICK_GUARD, MoveId.WIDE_GUARD].includes(turnMove.move)) ||
turnMove.result !== MoveResult.SUCCESS
) {
break;

View File

@ -44,6 +44,33 @@ export abstract class PhasePriorityQueue {
public clear(): void {
this.queue.splice(0, this.queue.length);
}
/**
* Attempt to remove one or more Phases from the current queue.
* @param phaseFilter - The function to select phases for removal
* @param removeCount - The maximum number of phases to remove, or `all` to remove all matching phases;
* default `1`
* @returns The number of successfully removed phases
* @todo Remove this eventually once the patchwork bug this is used for is fixed
*/
public tryRemovePhase(phaseFilter: (phase: Phase) => boolean, removeCount: number | "all" = 1): number {
if (removeCount === "all") {
removeCount = Number.MAX_SAFE_INTEGER;
} else if (removeCount < 1) {
return 0;
}
let numRemoved = 0;
let phaseIndex = this.queue.findIndex(phaseFilter);
if (phaseIndex === -1) {
return 0;
}
while (numRemoved < removeCount && phaseIndex !== -1) {
this.queue.splice(phaseIndex, 1);
numRemoved++;
phaseIndex = this.queue.findIndex(phaseFilter);
}
return numRemoved;
}
}
/**
@ -79,6 +106,7 @@ export class PostSummonPhasePriorityQueue extends PhasePriorityQueue {
private queueAbilityPhase(phase: PostSummonPhase): void {
const phasePokemon = phase.getPokemon();
console.log(phasePokemon.getNameToRender());
phasePokemon.getAbilityPriorities().forEach((priority, idx) => {
this.queue.push(new PostSummonActivateAbilityPhase(phasePokemon.getBattlerIndex(), priority, !!idx));
globalScene.phaseManager.appendToPhase(

View File

@ -12,6 +12,7 @@ import { WeatherType } from "#enums/weather-type";
import type { Pokemon } from "#field/pokemon";
import type { PokemonFormChangeItemModifier } from "#modifiers/modifier";
import { type Constructor, coerceArray } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next";
export abstract class SpeciesFormChangeTrigger {
@ -143,11 +144,7 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
super();
this.move = move;
this.known = known;
const moveKey = MoveId[this.move]
.split("_")
.filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("") as unknown as string;
const moveKey = toCamelCase(MoveId[this.move]);
this.description = known
? i18next.t("pokemonEvolutions:Forms.moveLearned", {
move: i18next.t(`move:${moveKey}.name`),

View File

@ -54,7 +54,7 @@ export class Arena {
public bgm: string;
public ignoreAbilities: boolean;
public ignoringEffectSource: BattlerIndex | null;
public playerTerasUsed: number;
public playerTerasUsed = 0;
/**
* Saves the number of times a party pokemon faints during a arena encounter.
* {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave).
@ -68,12 +68,11 @@ export class Arena {
public readonly eventTarget: EventTarget = new EventTarget();
constructor(biome: BiomeId, bgm: string, playerFaints = 0) {
constructor(biome: BiomeId, playerFaints = 0) {
this.biomeType = biome;
this.bgm = bgm;
this.bgm = BiomeId[biome].toLowerCase();
this.trainerPool = biomeTrainerPools[biome];
this.updatePoolsForTimeOfDay();
this.playerTerasUsed = 0;
this.playerFaints = playerFaints;
}

View File

@ -447,7 +447,9 @@ export class LoadingScene extends SceneBase {
);
if (!mobile) {
loadingGraphics.map(g => g.setVisible(false));
loadingGraphics.forEach(g => {
g.setVisible(false);
});
}
const intro = this.add.video(0, 0);

View File

@ -121,8 +121,8 @@ export class ModifierBar extends Phaser.GameObjects.Container {
}
updateModifierOverflowVisibility(ignoreLimit: boolean) {
const modifierIcons = this.getAll().reverse();
for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) {
const modifierIcons = this.getAll().reverse() as Phaser.GameObjects.Container[];
for (const modifier of modifierIcons.slice(iconOverflowIndex)) {
modifier.setVisible(ignoreLimit);
}
}

View File

@ -355,14 +355,23 @@ export class PhaseManager {
if (this.phaseQueuePrependSpliceIndex > -1) {
this.clearPhaseQueueSplice();
}
if (this.phaseQueuePrepend.length) {
while (this.phaseQueuePrepend.length) {
const poppedPhase = this.phaseQueuePrepend.pop();
if (poppedPhase) {
this.phaseQueue.unshift(poppedPhase);
}
this.phaseQueue.unshift(...this.phaseQueuePrepend);
this.phaseQueuePrepend.splice(0);
const unactivatedConditionalPhases: [() => boolean, Phase][] = [];
// Check if there are any conditional phases queued
for (const [condition, phase] of this.conditionalQueue) {
// Evaluate the condition associated with the phase
if (condition()) {
// If the condition is met, add the phase to the phase queue
this.pushPhase(phase);
} else {
// If the condition is not met, re-add the phase back to the end of the conditional queue
unactivatedConditionalPhases.push([condition, phase]);
}
}
this.conditionalQueue = unactivatedConditionalPhases;
if (!this.phaseQueue.length) {
this.populatePhaseQueue();
// Clear the conditionalQueue if there are no phases left in the phaseQueue
@ -371,24 +380,6 @@ export class PhaseManager {
this.currentPhase = this.phaseQueue.shift() ?? null;
const unactivatedConditionalPhases: [() => boolean, Phase][] = [];
// Check if there are any conditional phases queued
while (this.conditionalQueue?.length) {
// Retrieve the first conditional phase from the queue
const conditionalPhase = this.conditionalQueue.shift();
// Evaluate the condition associated with the phase
if (conditionalPhase?.[0]()) {
// If the condition is met, add the phase to the phase queue
this.pushPhase(conditionalPhase[1]);
} else if (conditionalPhase) {
// If the condition is not met, re-add the phase back to the front of the conditional queue
unactivatedConditionalPhases.push(conditionalPhase);
} else {
console.warn("condition phase is undefined/null!", conditionalPhase);
}
}
this.conditionalQueue.push(...unactivatedConditionalPhases);
if (this.currentPhase) {
console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;");
this.currentPhase.start();
@ -520,6 +511,25 @@ export class PhaseManager {
this.dynamicPhaseQueues[type].push(phase);
}
/**
* Attempt to remove one or more Phases from the given DynamicPhaseQueue, removing the equivalent amount of {@linkcode ActivatePriorityQueuePhase}s from the queue.
* @param type - The {@linkcode DynamicPhaseType} to check
* @param phaseFilter - The function to select phases for removal
* @param removeCount - The maximum number of phases to remove, or `all` to remove all matching phases;
* default `1`
* @todo Remove this eventually once the patchwork bug this is used for is fixed
*/
public tryRemoveDynamicPhase(
type: DynamicPhaseType,
phaseFilter: (phase: Phase) => boolean,
removeCount: number | "all" = 1,
): void {
const numRemoved = this.dynamicPhaseQueues[type].tryRemovePhase(phaseFilter, removeCount);
for (let x = 0; x < numRemoved; x++) {
this.tryRemovePhase(p => p.is("ActivatePriorityQueuePhase"));
}
}
/**
* Unshifts the top phase from the corresponding dynamic queue onto {@linkcode phaseQueue}
* @param type {@linkcode DynamicPhaseType} The type of dynamic phase to start

View File

@ -2,6 +2,7 @@ import { globalScene } from "#app/global-scene";
import { getPokemonNameWithAffix } from "#app/messages";
import { BattleStyle } from "#enums/battle-style";
import { BattlerTagType } from "#enums/battler-tag-type";
import { DynamicPhaseType } from "#enums/dynamic-phase-type";
import { SwitchType } from "#enums/switch-type";
import { UiMode } from "#enums/ui-mode";
import { BattlePhase } from "#phases/battle-phase";
@ -66,6 +67,17 @@ export class CheckSwitchPhase extends BattlePhase {
UiMode.CONFIRM,
() => {
globalScene.ui.setMode(UiMode.MESSAGE);
/*
Remove any pending `ActivatePriorityQueuePhase`s for the currently leaving Pokemon produced by the prior `SwitchSummonPhase`.
This is required to avoid triggering on-switch abilities twice on initial entrance.
TODO: Separate the animations from `SwitchSummonPhase` to another phase and call that on initial switch - this is a band-aid fix
TODO: Confirm with @emdeann what the maximum number of these things that gets unshifted can be
*/
globalScene.phaseManager.tryRemoveDynamicPhase(
DynamicPhaseType.POST_SUMMON,
p => p.is("PostSummonPhase") && p.getPokemon() === pokemon,
4,
);
globalScene.phaseManager.unshiftNew("SwitchPhase", SwitchType.INITIAL_SWITCH, this.fieldIndex, false, true);
this.end();
},

View File

@ -207,10 +207,12 @@ export interface StarterData {
[key: number]: StarterDataEntry;
}
export interface TutorialFlags {
[key: string]: boolean;
}
// TODO: Rework into a bitmask
export type TutorialFlags = {
[key in Tutorial]: boolean;
};
// TODO: Rework into a bitmask
export interface SeenDialogues {
[key: string]: boolean;
}
@ -823,52 +825,51 @@ export class GameData {
return true; // TODO: is `true` the correct return value?
}
private loadGamepadSettings(): boolean {
Object.values(SettingGamepad)
.map(setting => setting as SettingGamepad)
.forEach(setting => setSettingGamepad(setting, settingGamepadDefaults[setting]));
private loadGamepadSettings(): void {
Object.values(SettingGamepad).forEach(setting => {
setSettingGamepad(setting, settingGamepadDefaults[setting]);
});
if (!localStorage.hasOwnProperty("settingsGamepad")) {
return false;
return;
}
const settingsGamepad = JSON.parse(localStorage.getItem("settingsGamepad")!); // TODO: is this bang correct?
for (const setting of Object.keys(settingsGamepad)) {
setSettingGamepad(setting as SettingGamepad, settingsGamepad[setting]);
}
return true; // TODO: is `true` the correct return value?
}
public saveTutorialFlag(tutorial: Tutorial, flag: boolean): boolean {
const key = getDataTypeKey(GameDataType.TUTORIALS);
let tutorials: object = {};
if (localStorage.hasOwnProperty(key)) {
tutorials = JSON.parse(localStorage.getItem(key)!); // TODO: is this bang correct?
/**
* Save the specified tutorial as having the specified completion status.
* @param tutorial - The {@linkcode Tutorial} whose completion status is being saved
* @param status - The completion status to set
*/
public saveTutorialFlag(tutorial: Tutorial, status: boolean): void {
// Grab the prior save data tutorial
const saveDataKey = getDataTypeKey(GameDataType.TUTORIALS);
const tutorials: TutorialFlags = localStorage.hasOwnProperty(saveDataKey)
? JSON.parse(localStorage.getItem(saveDataKey)!)
: {};
// TODO: We shouldn't be storing this like that
for (const key of Object.values(Tutorial)) {
if (key === tutorial) {
tutorials[key] = status;
} else {
tutorials[key] ??= false;
}
}
Object.keys(Tutorial)
.map(t => t as Tutorial)
.forEach(t => {
const key = Tutorial[t];
if (key === tutorial) {
tutorials[key] = flag;
} else {
tutorials[key] ??= false;
}
});
localStorage.setItem(key, JSON.stringify(tutorials));
return true;
localStorage.setItem(saveDataKey, JSON.stringify(tutorials));
}
public getTutorialFlags(): TutorialFlags {
const key = getDataTypeKey(GameDataType.TUTORIALS);
const ret: TutorialFlags = {};
Object.values(Tutorial)
.map(tutorial => tutorial as Tutorial)
.forEach(tutorial => (ret[Tutorial[tutorial]] = false));
const ret: TutorialFlags = Object.values(Tutorial).reduce((acc, tutorial) => {
acc[Tutorial[tutorial]] = false;
return acc;
}, {} as TutorialFlags);
if (!localStorage.hasOwnProperty(key)) {
return ret;

View File

@ -26,6 +26,7 @@ import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text";
import { UiHandler } from "#ui/ui-handler";
import { addWindow } from "#ui/ui-theme";
import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next";
import RoundRectangle from "phaser3-rex-plugins/plugins/roundrectangle";
@ -706,10 +707,7 @@ export class RunInfoUiHandler extends UiHandler {
rules.push(i18next.t("challenges:inverseBattle.shortName"));
break;
default: {
const localizationKey = Challenges[this.runInfo.challenges[i].id]
.split("_")
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("");
const localizationKey = toCamelCase(Challenges[this.runInfo.challenges[i].id]);
rules.push(i18next.t(`challenges:${localizationKey}.name`));
break;
}

View File

@ -31,7 +31,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler {
// we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key
// Return in the format expected by i18next
return middleKey ? `${topKey}:${middleKey.map(m => m).join(".")}.${t}` : `${topKey}:${t}`;
return middleKey ? `${topKey}:${middleKey.join(".")}.${t}` : `${topKey}:${t}`;
}
})
.filter(t => t);

View File

@ -35,13 +35,43 @@ describe("Abilities - Intimidate", () => {
it("should lower all opponents' ATK by 1 stage on entry and switch", async () => {
await game.classicMode.startBattle([SpeciesId.MIGHTYENA, SpeciesId.POOCHYENA]);
const [mightyena, poochyena] = game.scene.getPlayerParty();
const enemy = game.field.getEnemyPokemon();
expect(enemy.getStatStage(Stat.ATK)).toBe(-1);
expect(mightyena).toHaveAbilityApplied(AbilityId.INTIMIDATE);
game.doSwitchPokemon(1);
await game.toNextTurn();
expect(poochyena.isActive()).toBe(true);
expect(enemy.getStatStage(Stat.ATK)).toBe(-2);
expect(poochyena).toHaveAbilityApplied(AbilityId.INTIMIDATE);
});
it("should trigger once on initial switch prompt without cancelling opposing abilities", async () => {
await game.classicMode.runToSummon([SpeciesId.MIGHTYENA, SpeciesId.POOCHYENA]);
await game.classicMode.startBattleWithSwitch(1);
const [poochyena, mightyena] = game.scene.getPlayerParty();
expect(poochyena.species.speciesId).toBe(SpeciesId.POOCHYENA);
const enemy = game.field.getEnemyPokemon();
expect(enemy).toHaveStatStage(Stat.ATK, -1);
expect(poochyena).toHaveStatStage(Stat.ATK, -1);
expect(poochyena).toHaveAbilityApplied(AbilityId.INTIMIDATE);
expect(mightyena).not.toHaveAbilityApplied(AbilityId.INTIMIDATE);
});
it("should activate on reload with single party", async () => {
await game.classicMode.startBattle([SpeciesId.MIGHTYENA]);
expect(game.field.getEnemyPokemon()).toHaveStatStage(Stat.ATK, -1);
await game.reload.reloadSession();
expect(game.field.getEnemyPokemon()).toHaveStatStage(Stat.ATK, -1);
});
it("should lower ATK of all opponents in a double battle", async () => {

View File

@ -112,7 +112,7 @@ describe("Weird Dream - Mystery Encounter", () => {
it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
const pokemonPrior = scene.getPlayerParty().map(pokemon => pokemon);
const pokemonPrior = scene.getPlayerParty().slice();
const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal());
await runMysteryEncounterToEnd(game, 1);

View File

@ -1,6 +1,7 @@
import { getGameMode } from "#app/game-mode";
import overrides from "#app/overrides";
import { BattleStyle } from "#enums/battle-style";
import { Button } from "#enums/buttons";
import { GameModes } from "#enums/game-modes";
import { Nature } from "#enums/nature";
import type { SpeciesId } from "#enums/species-id";
@ -100,4 +101,33 @@ export class ClassicModeHelper extends GameManagerHelper {
await this.game.phaseInterceptor.to(CommandPhase);
console.log("==================[New Turn]==================");
}
/**
* Queue inputs to switch at the start of the next battle, and then start it.
* @param pokemonIndex - The 0-indexed position of the party pokemon to switch to.
* Should never be called with 0 as that will select the currently active pokemon and freeze
* @returns A Promise that resolves once the battle has been started and the switch prompt resolved
* @todo Make this work for double battles
* @example
* ```ts
* await game.classicMode.runToSummon([SpeciesId.MIGHTYENA, SpeciesId.POOCHYENA])
* await game.startBattleWithSwitch(1);
* ```
*/
public async startBattleWithSwitch(pokemonIndex: number): Promise<void> {
this.game.scene.battleStyle = BattleStyle.SWITCH;
this.game.onNextPrompt(
"CheckSwitchPhase",
UiMode.CONFIRM,
() => {
this.game.scene.ui.getHandler().setCursor(0);
this.game.scene.ui.getHandler().processInput(Button.ACTION);
},
() => this.game.isCurrentPhase("CommandPhase") || this.game.isCurrentPhase("TurnInitPhase"),
);
this.game.doSelectPartyPokemon(pokemonIndex);
await this.game.phaseInterceptor.to("CommandPhase");
console.log("==================[New Battle (Initial Switch)]==================");
}
}