mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 07:22:19 +02:00
Merge branch 'beta' into force-switch-locales
This commit is contained in:
commit
126713fa35
@ -145,6 +145,5 @@
|
||||
</div>
|
||||
<script type="module" src="./src/main.ts"></script>
|
||||
<script src="./src/touch-controls.ts" type="module"></script>
|
||||
<script src="./src/debug.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
* Dex entry for a single Pokemon Species
|
||||
*/
|
||||
export interface DexData {
|
||||
[key: number]: DexEntry;
|
||||
}
|
||||
|
||||
export interface DexEntry {
|
||||
seenAttr: bigint;
|
||||
caughtAttr: bigint;
|
||||
@ -10,7 +11,3 @@ export interface DexEntry {
|
||||
hatchedCount: number;
|
||||
ivs: number[];
|
||||
}
|
||||
|
||||
export interface DexData {
|
||||
[key: number]: DexEntry;
|
||||
}
|
@ -2,9 +2,6 @@ export interface Localizable {
|
||||
localize(): void;
|
||||
}
|
||||
|
||||
export interface TranslationEntries {
|
||||
[key: string]: string | { [key: string]: string };
|
||||
}
|
||||
export interface SimpleTranslationEntries {
|
||||
[key: string]: string;
|
||||
}
|
@ -2,8 +2,8 @@ import type { EnemyPokemon } from "#app/field/pokemon";
|
||||
import type { PersistentModifier } from "#app/modifier/modifier";
|
||||
import type { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
import type { TrainerConfig } from "./trainer-config";
|
||||
import type { TrainerPartyTemplate } from "./TrainerPartyTemplate";
|
||||
import type { TrainerConfig } from "../data/trainers/trainer-config";
|
||||
import type { TrainerPartyTemplate } from "../data/trainers/TrainerPartyTemplate";
|
||||
|
||||
export type PartyTemplateFunc = () => TrainerPartyTemplate;
|
||||
export type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon;
|
@ -120,7 +120,7 @@ import { SceneBase } from "#app/scene-base";
|
||||
import CandyBar from "#app/ui/candy-bar";
|
||||
import type { Variant } from "#app/sprites/variant";
|
||||
import { variantData, clearVariantData } from "#app/sprites/variant";
|
||||
import type { Localizable } from "#app/interfaces/locales";
|
||||
import type { Localizable } from "#app/@types/locales";
|
||||
import Overrides from "#app/overrides";
|
||||
import { InputsController } from "#app/inputs-controller";
|
||||
import { UiInputs } from "#app/ui-inputs";
|
||||
@ -144,7 +144,6 @@ import { battleSpecDialogue } from "#app/data/dialogue";
|
||||
import { LoadingScene } from "#app/loading-scene";
|
||||
import { LevelCapPhase } from "#app/phases/level-cap-phase";
|
||||
import { LoginPhase } from "#app/phases/login-phase";
|
||||
import { MessagePhase } from "#app/phases/message-phase";
|
||||
import type { MovePhase } from "#app/phases/move-phase";
|
||||
import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase";
|
||||
import { NextEncounterPhase } from "#app/phases/next-encounter-phase";
|
||||
@ -155,7 +154,6 @@ import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
|
||||
import { SummonPhase } from "#app/phases/summon-phase";
|
||||
import { TitlePhase } from "#app/phases/title-phase";
|
||||
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
|
||||
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
|
||||
import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import {
|
||||
@ -169,7 +167,7 @@ import {
|
||||
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import { ExpPhase } from "#app/phases/exp-phase";
|
||||
import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
@ -178,13 +176,12 @@ import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#app/data/balance/starters";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { initGlobalScene } from "#app/global-scene";
|
||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
|
||||
import { expSpriteKeys } from "./sprites/sprite-keys";
|
||||
import { hasExpSprite } from "./sprites/sprite-utils";
|
||||
import { timedEventManager } from "./global-event-manager";
|
||||
import { starterColors } from "./global-vars/starter-colors";
|
||||
import { startingWave } from "./starting-wave";
|
||||
import { PhaseManager } from "./phase-manager";
|
||||
|
||||
const DEBUG_RNG = false;
|
||||
|
||||
@ -297,18 +294,8 @@ export default class BattleScene extends SceneBase {
|
||||
public gameData: GameData;
|
||||
public sessionSlotId: number;
|
||||
|
||||
/** PhaseQueue: dequeue/remove the first element to get the next phase */
|
||||
public phaseQueue: Phase[];
|
||||
public conditionalQueue: Array<[() => boolean, Phase]>;
|
||||
/** PhaseQueuePrepend: is a temp storage of what will be added to PhaseQueue */
|
||||
private phaseQueuePrepend: Phase[];
|
||||
|
||||
/** overrides default of inserting phases to end of phaseQueuePrepend array, useful or inserting Phases "out of order" */
|
||||
private phaseQueuePrependSpliceIndex: number;
|
||||
private nextCommandPhaseQueue: Phase[];
|
||||
|
||||
private currentPhase: Phase | null;
|
||||
private standbyPhase: Phase | null;
|
||||
/** Manager for the phases active in the battle scene */
|
||||
public readonly phaseManager: PhaseManager;
|
||||
public field: Phaser.GameObjects.Container;
|
||||
public fieldUI: Phaser.GameObjects.Container;
|
||||
public charSprite: CharSprite;
|
||||
@ -396,11 +383,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
constructor() {
|
||||
super("battle");
|
||||
this.phaseQueue = [];
|
||||
this.phaseQueuePrepend = [];
|
||||
this.conditionalQueue = [];
|
||||
this.phaseQueuePrependSpliceIndex = -1;
|
||||
this.nextCommandPhaseQueue = [];
|
||||
this.phaseManager = new PhaseManager();
|
||||
this.eventManager = new TimedEventManager();
|
||||
this.updateGameInfo();
|
||||
initGlobalScene(this);
|
||||
@ -716,10 +699,10 @@ export default class BattleScene extends SceneBase {
|
||||
).then(() => loadMoveAnimAssets(defaultMoves, true)),
|
||||
this.initStarterColors(),
|
||||
]).then(() => {
|
||||
this.pushPhase(new LoginPhase());
|
||||
this.pushPhase(new TitlePhase());
|
||||
this.phaseManager.pushPhase(new LoginPhase());
|
||||
this.phaseManager.pushPhase(new TitlePhase());
|
||||
|
||||
this.shiftPhase();
|
||||
this.phaseManager.shiftPhase();
|
||||
});
|
||||
}
|
||||
|
||||
@ -811,6 +794,7 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add a `getPartyOnSide` function for getting the party of a pokemon
|
||||
public getPlayerParty(): PlayerPokemon[] {
|
||||
return this.party;
|
||||
}
|
||||
@ -898,7 +882,7 @@ export default class BattleScene extends SceneBase {
|
||||
if (allyPokemon?.isActive(true)) {
|
||||
let targetingMovePhase: MovePhase;
|
||||
do {
|
||||
targetingMovePhase = this.findPhase(
|
||||
targetingMovePhase = this.phaseManager.findPhase(
|
||||
mp =>
|
||||
mp.is("MovePhase") &&
|
||||
mp.targets.length === 1 &&
|
||||
@ -1276,7 +1260,7 @@ export default class BattleScene extends SceneBase {
|
||||
duration: 250,
|
||||
ease: "Sine.easeInOut",
|
||||
onComplete: () => {
|
||||
this.clearPhaseQueue();
|
||||
this.phaseManager.clearPhaseQueue();
|
||||
|
||||
this.ui.freeUIData();
|
||||
this.uiContainer.remove(this.ui, true);
|
||||
@ -1449,7 +1433,7 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
|
||||
if (lastBattle?.double && !newDouble) {
|
||||
this.tryRemovePhase((p: Phase) => p.is("SwitchPhase"));
|
||||
this.phaseManager.tryRemovePhase((p: Phase) => p.is("SwitchPhase"));
|
||||
for (const p of this.getPlayerField()) {
|
||||
p.lapseTag(BattlerTagType.COMMANDED);
|
||||
}
|
||||
@ -1491,7 +1475,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
playerField.forEach((pokemon, p) => {
|
||||
if (pokemon.isOnField()) {
|
||||
this.pushPhase(new ReturnPhase(p));
|
||||
this.phaseManager.pushPhase(new ReturnPhase(p));
|
||||
}
|
||||
});
|
||||
|
||||
@ -1508,7 +1492,7 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
|
||||
if (!this.trainer.visible) {
|
||||
this.pushPhase(new ShowTrainerPhase());
|
||||
this.phaseManager.pushPhase(new ShowTrainerPhase());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1517,13 +1501,13 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
|
||||
if (!this.gameMode.hasRandomBiomes && !isNewBiome) {
|
||||
this.pushPhase(new NextEncounterPhase());
|
||||
this.phaseManager.pushPhase(new NextEncounterPhase());
|
||||
} else {
|
||||
this.pushPhase(new NewBiomeEncounterPhase());
|
||||
this.phaseManager.pushPhase(new NewBiomeEncounterPhase());
|
||||
|
||||
const newMaxExpLevel = this.getMaxExpLevel();
|
||||
if (newMaxExpLevel > maxExpLevel) {
|
||||
this.pushPhase(new LevelCapPhase());
|
||||
this.phaseManager.pushPhase(new LevelCapPhase());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1587,7 +1571,9 @@ export default class BattleScene extends SceneBase {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const isEggPhase: boolean = ["EggLapsePhase", "EggHatchPhase"].includes(this.getCurrentPhase()?.phaseName ?? "");
|
||||
const isEggPhase: boolean = ["EggLapsePhase", "EggHatchPhase"].includes(
|
||||
this.phaseManager.getCurrentPhase()?.phaseName ?? "",
|
||||
);
|
||||
|
||||
if (
|
||||
// Give trainers with specialty types an appropriately-typed form for Wormadam, Rotom, Arceus, Oricorio, Silvally, or Paldean Tauros.
|
||||
@ -2614,286 +2600,6 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
}
|
||||
|
||||
/* Phase Functions */
|
||||
getCurrentPhase(): Phase | null {
|
||||
return this.currentPhase;
|
||||
}
|
||||
|
||||
getStandbyPhase(): Phase | null {
|
||||
return this.standbyPhase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a phase to the conditional queue and ensures it is executed only when the specified condition is met.
|
||||
*
|
||||
* This method allows deferring the execution of a phase until certain conditions are met, which is useful for handling
|
||||
* situations like abilities and entry hazards that depend on specific game states.
|
||||
*
|
||||
* @param {Phase} phase - The phase to be added to the conditional queue.
|
||||
* @param {() => boolean} condition - A function that returns a boolean indicating whether the phase should be executed.
|
||||
*
|
||||
*/
|
||||
pushConditionalPhase(phase: Phase, condition: () => boolean): void {
|
||||
this.conditionalQueue.push([condition, phase]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a phase to nextCommandPhaseQueue, as long as boolean passed in is false
|
||||
* @param phase {@linkcode Phase} the phase to add
|
||||
* @param defer boolean on which queue to add to, defaults to false, and adds to phaseQueue
|
||||
*/
|
||||
pushPhase(phase: Phase, defer = false): void {
|
||||
(!defer ? this.phaseQueue : this.nextCommandPhaseQueue).push(phase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Phase(s) to the end of phaseQueuePrepend, or at phaseQueuePrependSpliceIndex
|
||||
* @param phases {@linkcode Phase} the phase(s) to add
|
||||
*/
|
||||
unshiftPhase(...phases: Phase[]): void {
|
||||
if (this.phaseQueuePrependSpliceIndex === -1) {
|
||||
this.phaseQueuePrepend.push(...phases);
|
||||
} else {
|
||||
this.phaseQueuePrepend.splice(this.phaseQueuePrependSpliceIndex, 0, ...phases);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the phaseQueue
|
||||
*/
|
||||
clearPhaseQueue(): void {
|
||||
this.phaseQueue.splice(0, this.phaseQueue.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all phase-related stuff, including all phase queues, the current and standby phases, and a splice index
|
||||
*/
|
||||
clearAllPhases(): void {
|
||||
for (const queue of [this.phaseQueue, this.phaseQueuePrepend, this.conditionalQueue, this.nextCommandPhaseQueue]) {
|
||||
queue.splice(0, queue.length);
|
||||
}
|
||||
this.currentPhase = null;
|
||||
this.standbyPhase = null;
|
||||
this.clearPhaseQueueSplice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by function unshiftPhase(), sets index to start inserting at current length instead of the end of the array, useful if phaseQueuePrepend gets longer with Phases
|
||||
*/
|
||||
setPhaseQueueSplice(): void {
|
||||
this.phaseQueuePrependSpliceIndex = this.phaseQueuePrepend.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets phaseQueuePrependSpliceIndex to -1, implies that calls to unshiftPhase will insert at end of phaseQueuePrepend
|
||||
*/
|
||||
clearPhaseQueueSplice(): void {
|
||||
this.phaseQueuePrependSpliceIndex = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called by each Phase implementations "end()" by default
|
||||
* We dump everything from phaseQueuePrepend to the start of of phaseQueue
|
||||
* then removes first Phase and starts it
|
||||
*/
|
||||
shiftPhase(): void {
|
||||
if (this.standbyPhase) {
|
||||
this.currentPhase = this.standbyPhase;
|
||||
this.standbyPhase = null;
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this.phaseQueue.length) {
|
||||
this.populatePhaseQueue();
|
||||
// Clear the conditionalQueue if there are no phases left in the phaseQueue
|
||||
this.conditionalQueue = [];
|
||||
}
|
||||
|
||||
this.currentPhase = this.phaseQueue.shift() ?? null;
|
||||
|
||||
// Check if there are any conditional phases queued
|
||||
if (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
|
||||
this.conditionalQueue.unshift(conditionalPhase);
|
||||
} else {
|
||||
console.warn("condition phase is undefined/null!", conditionalPhase);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.currentPhase) {
|
||||
console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;");
|
||||
this.currentPhase.start();
|
||||
}
|
||||
}
|
||||
|
||||
overridePhase(phase: Phase): boolean {
|
||||
if (this.standbyPhase) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.standbyPhase = this.currentPhase;
|
||||
this.currentPhase = phase;
|
||||
console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;");
|
||||
phase.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific {@linkcode Phase} in the phase queue.
|
||||
*
|
||||
* @param phaseFilter filter function to use to find the wanted phase
|
||||
* @returns the found phase or undefined if none found
|
||||
*/
|
||||
findPhase<P extends Phase = Phase>(phaseFilter: (phase: P) => boolean): P | undefined {
|
||||
return this.phaseQueue.find(phaseFilter) as P;
|
||||
}
|
||||
|
||||
tryReplacePhase(phaseFilter: (phase: Phase) => boolean, phase: Phase): boolean {
|
||||
const phaseIndex = this.phaseQueue.findIndex(phaseFilter);
|
||||
if (phaseIndex > -1) {
|
||||
this.phaseQueue[phaseIndex] = phase;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
tryRemovePhase(phaseFilter: (phase: Phase) => boolean): boolean {
|
||||
const phaseIndex = this.phaseQueue.findIndex(phaseFilter);
|
||||
if (phaseIndex > -1) {
|
||||
this.phaseQueue.splice(phaseIndex, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will search for a specific phase in {@linkcode phaseQueuePrepend} via filter, and remove the first result if a match is found.
|
||||
* @param phaseFilter filter function
|
||||
*/
|
||||
tryRemoveUnshiftedPhase(phaseFilter: (phase: Phase) => boolean): boolean {
|
||||
const phaseIndex = this.phaseQueuePrepend.findIndex(phaseFilter);
|
||||
if (phaseIndex > -1) {
|
||||
this.phaseQueuePrepend.splice(phaseIndex, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to add the input phase to index before target phase in the phaseQueue, else simply calls unshiftPhase()
|
||||
* @param phase {@linkcode Phase} the phase to be added
|
||||
* @param targetPhase {@linkcode Phase} the type of phase to search for in phaseQueue
|
||||
* @returns boolean if a targetPhase was found and added
|
||||
*/
|
||||
prependToPhase(phase: Phase | Phase[], targetPhase: Constructor<Phase>): boolean {
|
||||
if (!Array.isArray(phase)) {
|
||||
phase = [phase];
|
||||
}
|
||||
const targetIndex = this.phaseQueue.findIndex(ph => ph instanceof targetPhase);
|
||||
|
||||
if (targetIndex !== -1) {
|
||||
this.phaseQueue.splice(targetIndex, 0, ...phase);
|
||||
return true;
|
||||
}
|
||||
this.unshiftPhase(...phase);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to add the input phase(s) to index after target phase in the {@linkcode phaseQueue}, else simply calls {@linkcode unshiftPhase()}
|
||||
* @param phase {@linkcode Phase} the phase(s) to be added
|
||||
* @param targetPhase {@linkcode Phase} the type of phase to search for in {@linkcode phaseQueue}
|
||||
* @returns `true` if a `targetPhase` was found to append to
|
||||
*/
|
||||
appendToPhase(phase: Phase | Phase[], targetPhase: Constructor<Phase>): boolean {
|
||||
if (!Array.isArray(phase)) {
|
||||
phase = [phase];
|
||||
}
|
||||
const targetIndex = this.phaseQueue.findIndex(ph => ph instanceof targetPhase);
|
||||
|
||||
if (targetIndex !== -1 && this.phaseQueue.length > targetIndex) {
|
||||
this.phaseQueue.splice(targetIndex + 1, 0, ...phase);
|
||||
return true;
|
||||
}
|
||||
this.unshiftPhase(...phase);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a MessagePhase, either to PhaseQueuePrepend or nextCommandPhaseQueue
|
||||
* @param message string for MessagePhase
|
||||
* @param callbackDelay optional param for MessagePhase constructor
|
||||
* @param prompt optional param for MessagePhase constructor
|
||||
* @param promptDelay optional param for MessagePhase constructor
|
||||
* @param defer boolean for which queue to add it to, false -> add to PhaseQueuePrepend, true -> nextCommandPhaseQueue
|
||||
*/
|
||||
queueMessage(
|
||||
message: string,
|
||||
callbackDelay?: number | null,
|
||||
prompt?: boolean | null,
|
||||
promptDelay?: number | null,
|
||||
defer?: boolean | null,
|
||||
) {
|
||||
const phase = new MessagePhase(message, callbackDelay, prompt, promptDelay);
|
||||
if (!defer) {
|
||||
// adds to the end of PhaseQueuePrepend
|
||||
this.unshiftPhase(phase);
|
||||
} else {
|
||||
//remember that pushPhase adds it to nextCommandPhaseQueue
|
||||
this.pushPhase(phase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues an ability bar flyout phase
|
||||
* @param pokemon The pokemon who has the ability
|
||||
* @param passive Whether the ability is a passive
|
||||
* @param show Whether to show or hide the bar
|
||||
*/
|
||||
public queueAbilityDisplay(pokemon: Pokemon, passive: boolean, show: boolean): void {
|
||||
this.unshiftPhase(show ? new ShowAbilityPhase(pokemon.getBattlerIndex(), passive) : new HideAbilityPhase());
|
||||
this.clearPhaseQueueSplice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the ability bar if it is currently visible
|
||||
*/
|
||||
public hideAbilityBar(): void {
|
||||
if (this.abilityBar.isVisible()) {
|
||||
this.unshiftPhase(new HideAbilityPhase());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves everything from nextCommandPhaseQueue to phaseQueue (keeping order)
|
||||
*/
|
||||
populatePhaseQueue(): void {
|
||||
if (this.nextCommandPhaseQueue.length) {
|
||||
this.phaseQueue.push(...this.nextCommandPhaseQueue);
|
||||
this.nextCommandPhaseQueue.splice(0, this.nextCommandPhaseQueue.length);
|
||||
}
|
||||
this.phaseQueue.push(new TurnInitPhase());
|
||||
}
|
||||
|
||||
addMoney(amount: number): void {
|
||||
this.money = Math.min(this.money + amount, Number.MAX_SAFE_INTEGER);
|
||||
this.updateMoneyText();
|
||||
@ -2941,7 +2647,7 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
} else if (!virtual) {
|
||||
const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier);
|
||||
this.queueMessage(
|
||||
this.phaseManager.queueMessage(
|
||||
i18next.t("battle:itemStackFull", {
|
||||
fullItemName: modifier.type.name,
|
||||
itemName: defaultModifierType.name,
|
||||
@ -3086,9 +2792,9 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
const removeOld = itemModifier.stackCount === 0;
|
||||
|
||||
if (!removeOld || !source || this.removeModifier(itemModifier, !source.isPlayer())) {
|
||||
if (!removeOld || !source || this.removeModifier(itemModifier, source.isEnemy())) {
|
||||
const addModifier = () => {
|
||||
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
||||
if (!matchingModifier || this.removeModifier(matchingModifier, target.isEnemy())) {
|
||||
if (target.isPlayer()) {
|
||||
this.addModifier(newItemModifier, ignoreUpdate, playSound, false, instant);
|
||||
if (source && itemLost) {
|
||||
@ -3492,17 +3198,17 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
if (matchingFormChange) {
|
||||
let phase: Phase;
|
||||
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet) {
|
||||
if (pokemon.isPlayer() && !matchingFormChange.quiet) {
|
||||
phase = new FormChangePhase(pokemon, matchingFormChange, modal);
|
||||
} else {
|
||||
phase = new QuietFormChangePhase(pokemon, matchingFormChange);
|
||||
}
|
||||
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet && modal) {
|
||||
this.overridePhase(phase);
|
||||
if (pokemon.isPlayer() && !matchingFormChange.quiet && modal) {
|
||||
this.phaseManager.overridePhase(phase);
|
||||
} else if (delayed) {
|
||||
this.pushPhase(phase);
|
||||
this.phaseManager.pushPhase(phase);
|
||||
} else {
|
||||
this.unshiftPhase(phase);
|
||||
this.phaseManager.unshiftPhase(phase);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3519,9 +3225,9 @@ export default class BattleScene extends SceneBase {
|
||||
): boolean {
|
||||
const phase: Phase = new PokemonAnimPhase(battleAnimType, pokemon, fieldAssets);
|
||||
if (delayed) {
|
||||
this.pushPhase(phase);
|
||||
this.phaseManager.pushPhase(phase);
|
||||
} else {
|
||||
this.unshiftPhase(phase);
|
||||
this.phaseManager.unshiftPhase(phase);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3595,7 +3301,7 @@ export default class BattleScene extends SceneBase {
|
||||
activePokemon = activePokemon.concat(this.getEnemyParty());
|
||||
for (const p of activePokemon) {
|
||||
keys.push(p.getSpriteKey(true));
|
||||
if (p instanceof PlayerPokemon) {
|
||||
if (p.isPlayer()) {
|
||||
keys.push(p.getBattleSpriteKey(true, true));
|
||||
}
|
||||
keys.push(p.species.getCryKey(p.formIndex));
|
||||
@ -3611,7 +3317,7 @@ export default class BattleScene extends SceneBase {
|
||||
* @param pokemon The (enemy) pokemon
|
||||
*/
|
||||
initFinalBossPhaseTwo(pokemon: Pokemon): void {
|
||||
if (pokemon instanceof EnemyPokemon && pokemon.isBoss() && !pokemon.formIndex && pokemon.bossSegmentIndex < 1) {
|
||||
if (pokemon.isEnemy() && pokemon.isBoss() && !pokemon.formIndex && pokemon.bossSegmentIndex < 1) {
|
||||
this.fadeOutBgm(fixedInt(2000), false);
|
||||
this.ui.showDialogue(
|
||||
battleSpecDialogue[BattleSpec.FINAL_BOSS].firstStageWin,
|
||||
@ -3629,19 +3335,19 @@ export default class BattleScene extends SceneBase {
|
||||
this.currentBattle.double = true;
|
||||
const availablePartyMembers = this.getPlayerParty().filter(p => p.isAllowedInBattle());
|
||||
if (availablePartyMembers.length > 1) {
|
||||
this.pushPhase(new ToggleDoublePositionPhase(true));
|
||||
this.phaseManager.pushPhase(new ToggleDoublePositionPhase(true));
|
||||
if (!availablePartyMembers[1].isOnField()) {
|
||||
this.pushPhase(new SummonPhase(1));
|
||||
this.phaseManager.pushPhase(new SummonPhase(1));
|
||||
}
|
||||
}
|
||||
|
||||
this.shiftPhase();
|
||||
this.phaseManager.shiftPhase();
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.shiftPhase();
|
||||
this.phaseManager.shiftPhase();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3753,7 +3459,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
if (exp) {
|
||||
const partyMemberIndex = party.indexOf(expPartyMembers[pm]);
|
||||
this.unshiftPhase(
|
||||
this.phaseManager.unshiftPhase(
|
||||
expPartyMembers[pm].isOnField()
|
||||
? new ExpPhase(partyMemberIndex, exp)
|
||||
: new ShowPartyExpBarPhase(partyMemberIndex, exp),
|
||||
|
@ -205,7 +205,7 @@ export default class Battle {
|
||||
const message = i18next.t("battle:moneyPickedUp", {
|
||||
moneyAmount: formattedMoneyAmount,
|
||||
});
|
||||
globalScene.queueMessage(message, undefined, true);
|
||||
globalScene.phaseManager.queueMessage(message, undefined, true);
|
||||
|
||||
globalScene.currentBattle.moneyScattered = 0;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { AbilityId } from "#enums/ability-id";
|
||||
import type { AbAttrCondition } from "#app/@types/ability-types";
|
||||
import type { AbAttr } from "#app/data/abilities/ab-attrs/ab-attr";
|
||||
import i18next from "i18next";
|
||||
import type { Localizable } from "#app/interfaces/locales";
|
||||
import type { Localizable } from "#app/@types/locales";
|
||||
import type { Constructor } from "#app/utils/common";
|
||||
|
||||
export class Ability implements Localizable {
|
||||
|
@ -159,7 +159,7 @@ export class PostTeraFormChangeStatChangeAbAttr extends AbAttr {
|
||||
statStageChangePhases.push(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
||||
|
||||
for (const statStageChangePhase of statStageChangePhases) {
|
||||
globalScene.unshiftPhase(statStageChangePhase);
|
||||
globalScene.phaseManager.unshiftPhase(statStageChangePhase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -410,7 +410,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
|
||||
super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
|
||||
if (!pokemon.isFullHp() && !simulated) {
|
||||
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 4), i18next.t("abilityTriggers:typeImmunityHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
}
|
||||
@ -436,7 +436,7 @@ class TypeImmunityStatStageChangeAbAttr extends TypeImmunityAbAttr {
|
||||
super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -648,7 +648,7 @@ export class MoveImmunityStatStageChangeAbAttr extends MoveImmunityAbAttr {
|
||||
|
||||
override applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: BooleanHolder, args: any[]): void {
|
||||
super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -675,7 +675,7 @@ export class ReverseDrainAbAttr extends PostDefendAbAttr {
|
||||
*/
|
||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -710,10 +710,10 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr {
|
||||
const ally = pokemon.getAlly();
|
||||
const otherPokemon = !isNullOrUndefined(ally) ? pokemon.getOpponents().concat([ ally ]) : pokemon.getOpponents();
|
||||
for (const other of otherPokemon) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase((other).getBattlerIndex(), false, [ this.stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase((other).getBattlerIndex(), false, [ this.stat ], this.stages));
|
||||
}
|
||||
} else {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), this.selfTarget, [ this.stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), this.selfTarget, [ this.stat ], this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -744,7 +744,7 @@ export class PostDefendHpGatedStatStageChangeAbAttr extends PostDefendAbAttr {
|
||||
|
||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -790,7 +790,7 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
|
||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void {
|
||||
if (!pokemon.getTag(this.tagType) && !simulated) {
|
||||
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -915,7 +915,7 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr {
|
||||
|
||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1099,7 +1099,7 @@ export class PostStatStageChangeStatStageChangeAbAttr extends PostStatStageChang
|
||||
|
||||
override applyPostStatStageChange(pokemon: Pokemon, simulated: boolean, statStagesChanged: BattleStat[], stagesChanged: number, selfTarget: boolean, args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase((pokemon).getBattlerIndex(), true, this.statsToChange, this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase((pokemon).getBattlerIndex(), true, this.statsToChange, this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1765,7 +1765,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
||||
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
||||
}
|
||||
if (globalScene.tryTransferHeldItemModifier(this.stolenItem, pokemon, false)) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:postAttackStealHeldItem", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
defenderName: defender.name,
|
||||
@ -1892,7 +1892,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
||||
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
||||
}
|
||||
if (globalScene.tryTransferHeldItemModifier(this.stolenItem, pokemon, false)) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:postDefendStealHeldItem", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
attackerName: attacker.name,
|
||||
@ -1999,7 +1999,7 @@ class PostVictoryStatStageChangeAbAttr extends PostVictoryAbAttr {
|
||||
override applyPostVictory(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
const stat = typeof this.stat === "function" ? this.stat(pokemon) : this.stat;
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2047,7 +2047,7 @@ export class PostKnockOutStatStageChangeAbAttr extends PostKnockOutAbAttr {
|
||||
override applyPostKnockOut(pokemon: Pokemon, passive: boolean, simulated: boolean, knockedOut: Pokemon, args: any[]): void {
|
||||
const stat = typeof this.stat === "function" ? this.stat(pokemon) : this.stat;
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2064,7 +2064,7 @@ export class CopyFaintedAllyAbilityAbAttr extends PostKnockOutAbAttr {
|
||||
override applyPostKnockOut(pokemon: Pokemon, passive: boolean, simulated: boolean, knockedOut: Pokemon, args: any[]): void {
|
||||
if (!simulated) {
|
||||
pokemon.setTempAbility(knockedOut.getAbility());
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:copyFaintedAllyAbility", { pokemonNameWithAffix: getPokemonNameWithAffix(knockedOut), abilityName: allAbilities[knockedOut.getAbility().id].name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:copyFaintedAllyAbility", { pokemonNameWithAffix: getPokemonNameWithAffix(knockedOut), abilityName: allAbilities[knockedOut.getAbility().id].name }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2130,7 +2130,7 @@ export class PostIntimidateStatStageChangeAbAttr extends AbAttr {
|
||||
|
||||
override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: BooleanHolder, args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.pushPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, this.stages));
|
||||
globalScene.phaseManager.pushPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, this.stages));
|
||||
}
|
||||
cancelled.value = this.overwrites;
|
||||
}
|
||||
@ -2240,7 +2240,7 @@ export class PostSummonMessageAbAttr extends PostSummonAbAttr {
|
||||
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(this.messageFunc(pokemon));
|
||||
globalScene.phaseManager.queueMessage(this.messageFunc(pokemon));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2257,7 +2257,7 @@ export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr {
|
||||
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(this.message);
|
||||
globalScene.phaseManager.queueMessage(this.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2332,7 +2332,7 @@ export class PostSummonStatStageChangeAbAttr extends PostSummonAbAttr {
|
||||
if (this.selfTarget) {
|
||||
// we unshift the StatStageChangePhase to put it right after the showAbility and not at the end of the
|
||||
// phase list (which could be after CommandPhase for example)
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
||||
} else {
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
const cancelled = new BooleanHolder(false);
|
||||
@ -2345,7 +2345,7 @@ export class PostSummonStatStageChangeAbAttr extends PostSummonAbAttr {
|
||||
}
|
||||
}
|
||||
if (!cancelled.value) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(opponent.getBattlerIndex(), false, this.stats, this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(opponent.getBattlerIndex(), false, this.stats, this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2370,7 +2370,7 @@ export class PostSummonAllyHealAbAttr extends PostSummonAbAttr {
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
const target = pokemon.getAlly();
|
||||
if (!simulated && !isNullOrUndefined(target)) {
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / this.healRatio), i18next.t("abilityTriggers:postSummonAllyHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(target), pokemonName: pokemon.name }), true, !this.showAnim));
|
||||
}
|
||||
}
|
||||
@ -2400,7 +2400,7 @@ export class PostSummonClearAllyStatStagesAbAttr extends PostSummonAbAttr {
|
||||
target.setStatStage(s, 0);
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:postSummonClearAllyStats", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:postSummonClearAllyStats", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2448,7 +2448,7 @@ export class DownloadAbAttr extends PostSummonAbAttr {
|
||||
}
|
||||
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, 1));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2617,7 +2617,7 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
|
||||
}
|
||||
|
||||
override canApplyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||
const party = pokemon instanceof PlayerPokemon ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
const party = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
return party.filter(p => p.isAllowedInBattle()).length > 0;
|
||||
}
|
||||
|
||||
@ -2629,13 +2629,13 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
|
||||
* @param args - n/a
|
||||
*/
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
const party = pokemon instanceof PlayerPokemon ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
const party = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
const allowedParty = party.filter(p => p.isAllowedInBattle());
|
||||
|
||||
if (!simulated) {
|
||||
for (const pokemon of allowedParty) {
|
||||
if (pokemon.status && this.statusEffect.includes(pokemon.status.effect)) {
|
||||
globalScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
|
||||
globalScene.phaseManager.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
|
||||
pokemon.resetStatus(false);
|
||||
pokemon.updateInfo();
|
||||
}
|
||||
@ -2725,7 +2725,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
||||
override applyPostSummon(pokemon: Pokemon, _passive: boolean, simulated: boolean, _args: any[]): void {
|
||||
const target = this.getTarget(pokemon.getOpponents());
|
||||
|
||||
globalScene.unshiftPhase(new PokemonTransformPhase(pokemon.getBattlerIndex(), target.getBattlerIndex(), true));
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonTransformPhase(pokemon.getBattlerIndex(), target.getBattlerIndex(), true));
|
||||
|
||||
}
|
||||
}
|
||||
@ -2820,7 +2820,7 @@ export class CommanderAbAttr extends AbAttr {
|
||||
// Apply boosts from this effect to the ally Dondozo
|
||||
pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, MoveId.NONE, pokemon.id);
|
||||
// Cancel the source Pokemon's next move (if a move is queued)
|
||||
globalScene.tryRemovePhase((phase) => phase.is("MovePhase") && phase.pokemon === pokemon);
|
||||
globalScene.phaseManager.tryRemovePhase((phase) => phase.is("MovePhase") && phase.pokemon === pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3076,7 +3076,7 @@ export class ReflectStatStageChangeAbAttr extends PreStatStageChangeAbAttr {
|
||||
const stages = args[1];
|
||||
this.reflectedStat = stat;
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [ stat ], stages, true, false, true, null, true));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [ stat ], stages, true, false, true, null, true));
|
||||
}
|
||||
cancelled.value = true;
|
||||
}
|
||||
@ -3768,7 +3768,7 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
|
||||
}
|
||||
}
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:forewarn", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: maxMove }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:forewarn", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: maxMove }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3781,7 +3781,7 @@ export class FriskAbAttr extends PostSummonAbAttr {
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated) {
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:frisk", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), opponentName: opponent.name, opponentAbilityName: opponent.getAbility().name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:frisk", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), opponentName: opponent.name, opponentAbilityName: opponent.getAbility().name }));
|
||||
setAbilityRevealed(opponent);
|
||||
}
|
||||
}
|
||||
@ -3913,7 +3913,7 @@ export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr {
|
||||
override applyPostWeatherLapse(pokemon: Pokemon, passive: boolean, simulated: boolean, weather: Weather, args: any[]): void {
|
||||
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / (16 / this.healFactor)), i18next.t("abilityTriggers:postWeatherLapseHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
|
||||
}
|
||||
}
|
||||
@ -3935,7 +3935,7 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr {
|
||||
override applyPostWeatherLapse(pokemon: Pokemon, passive: boolean, simulated: boolean, weather: Weather, args: any[]): void {
|
||||
if (!simulated) {
|
||||
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }));
|
||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / (16 / this.damageFactor)), { result: HitResult.INDIRECT });
|
||||
}
|
||||
}
|
||||
@ -4015,7 +4015,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
|
||||
override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated) {
|
||||
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 8), i18next.t("abilityTriggers:poisonHeal", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName }), true));
|
||||
}
|
||||
}
|
||||
@ -4047,7 +4047,7 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
|
||||
|
||||
override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated && this.target?.status) {
|
||||
globalScene.queueMessage(getStatusEffectHealText(this.target.status?.effect, getPokemonNameWithAffix(this.target)));
|
||||
globalScene.phaseManager.queueMessage(getStatusEffectHealText(this.target.status?.effect, getPokemonNameWithAffix(this.target)));
|
||||
this.target.resetStatus(false);
|
||||
this.target.updateInfo();
|
||||
}
|
||||
@ -4132,7 +4132,7 @@ export class PostTurnRestoreBerryAbAttr extends PostTurnAbAttr {
|
||||
}
|
||||
|
||||
globalScene.updateModifiers(pokemon.isPlayer());
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: chosenBerry.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: chosenBerry.name }));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -4162,7 +4162,7 @@ export class RepeatBerryNextTurnAbAttr extends PostTurnAbAttr {
|
||||
* @param _args - N/A
|
||||
*/
|
||||
override apply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: BooleanHolder | null, _args: any[]): void {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM),
|
||||
);
|
||||
|
||||
@ -4226,11 +4226,11 @@ export class MoodyAbAttr extends PostTurnAbAttr {
|
||||
if (canRaise.length > 0) {
|
||||
const raisedStat = canRaise[pokemon.randBattleSeedInt(canRaise.length)];
|
||||
canLower = canRaise.filter(s => s !== raisedStat);
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ raisedStat ], 2));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ raisedStat ], 2));
|
||||
}
|
||||
if (canLower.length > 0) {
|
||||
const loweredStat = canLower[pokemon.randBattleSeedInt(canLower.length)];
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ loweredStat ], -1));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ loweredStat ], -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4247,7 +4247,7 @@ export class SpeedBoostAbAttr extends PostTurnAbAttr {
|
||||
}
|
||||
|
||||
override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPD ], 1));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPD ], 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4259,7 +4259,7 @@ export class PostTurnHealAbAttr extends PostTurnAbAttr {
|
||||
override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated) {
|
||||
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 16), i18next.t("abilityTriggers:postTurnHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
|
||||
}
|
||||
}
|
||||
@ -4305,7 +4305,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
|
||||
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(AbilityId.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !opp.switchOutStatus) {
|
||||
if (!simulated) {
|
||||
opp.damageAndUpdate(toDmgValue(opp.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4336,7 +4336,7 @@ export class FetchBallAbAttr extends PostTurnAbAttr {
|
||||
const lastUsed = globalScene.currentBattle.lastUsedPokeball;
|
||||
globalScene.pokeballCounts[lastUsed!]++;
|
||||
globalScene.currentBattle.lastUsedPokeball = null;
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:fetchBall", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), pokeballName: getPokeballName(lastUsed!) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:fetchBall", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), pokeballName: getPokeballName(lastUsed!) }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4442,10 +4442,10 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
|
||||
// If the move is an AttackMove or a StatusMove the Dancer must replicate the move on the source of the Dance
|
||||
if (move.getMove() instanceof AttackMove || move.getMove() instanceof StatusMove) {
|
||||
const target = this.getTarget(dancer, source, targets);
|
||||
globalScene.unshiftPhase(new MovePhase(dancer, target, move, true, true));
|
||||
globalScene.phaseManager.unshiftPhase(new MovePhase(dancer, target, move, true, true));
|
||||
} else if (move.getMove() instanceof SelfStatusMove) {
|
||||
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
|
||||
globalScene.unshiftPhase(new MovePhase(dancer, [ dancer.getBattlerIndex() ], move, true, true));
|
||||
globalScene.phaseManager.unshiftPhase(new MovePhase(dancer, [ dancer.getBattlerIndex() ], move, true, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4525,7 +4525,7 @@ export class StatStageChangeCopyAbAttr extends AbAttr {
|
||||
args: any[],
|
||||
): void {
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, (args[0] as BattleStat[]), (args[1] as number), true, false, false));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, (args[0] as BattleStat[]), (args[1] as number), true, false, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4606,7 +4606,7 @@ export class HealFromBerryUseAbAttr extends AbAttr {
|
||||
}
|
||||
|
||||
const { name: abilityName } = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() * this.healPercent),
|
||||
@ -4739,7 +4739,7 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr {
|
||||
|
||||
if (globalScene.tryTransferHeldItemModifier(this.randItem, pokemon, true, 1, true, undefined, false)) {
|
||||
postBattleLoot.splice(postBattleLoot.indexOf(this.randItem), 1);
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:postBattleLoot", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), itemName: this.randItem.type.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:postBattleLoot", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), itemName: this.randItem.type.name }));
|
||||
}
|
||||
this.randItem = undefined;
|
||||
}
|
||||
@ -4927,7 +4927,7 @@ export class FlinchStatStageChangeAbAttr extends FlinchEffectAbAttr {
|
||||
|
||||
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: BooleanHolder, args: any[]): void {
|
||||
if (!simulated) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5495,16 +5495,16 @@ function applySingleAbAttrs<TAttr extends AbAttr>(
|
||||
continue;
|
||||
}
|
||||
|
||||
globalScene.setPhaseQueueSplice();
|
||||
globalScene.phaseManager.setPhaseQueueSplice();
|
||||
|
||||
if (attr.showAbility && !simulated) {
|
||||
globalScene.queueAbilityDisplay(pokemon, passive, true);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, passive, true);
|
||||
abShown = true;
|
||||
}
|
||||
const message = attr.getTriggerMessage(pokemon, ability.name, args);
|
||||
if (message) {
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(message);
|
||||
globalScene.phaseManager.queueMessage(message);
|
||||
}
|
||||
messages.push(message);
|
||||
}
|
||||
@ -5512,14 +5512,14 @@ function applySingleAbAttrs<TAttr extends AbAttr>(
|
||||
applyFunc(attr, passive);
|
||||
|
||||
if (abShown) {
|
||||
globalScene.queueAbilityDisplay(pokemon, passive, false);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, passive, false);
|
||||
}
|
||||
|
||||
if (!simulated) {
|
||||
pokemon.waveData.abilitiesApplied.add(ability.id);
|
||||
}
|
||||
|
||||
globalScene.clearPhaseQueueSplice();
|
||||
globalScene.phaseManager.clearPhaseQueueSplice();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5539,14 +5539,14 @@ class ForceSwitchOutHelper {
|
||||
* - Whether there are available party members to switch in.
|
||||
* - If the Pokémon is still alive (hp > 0), and if so, it leaves the field and a new SwitchPhase is initiated.
|
||||
*/
|
||||
if (switchOutTarget instanceof PlayerPokemon) {
|
||||
if (switchOutTarget.isPlayer()) {
|
||||
if (globalScene.getPlayerParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
globalScene.prependToPhase(new SwitchPhase(this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase);
|
||||
globalScene.phaseManager.prependToPhase(new SwitchPhase(this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
@ -5560,7 +5560,7 @@ class ForceSwitchOutHelper {
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
const summonIndex = (globalScene.currentBattle.trainer ? globalScene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0);
|
||||
globalScene.prependToPhase(new SwitchSummonPhase(this.switchType, switchOutTarget.getFieldIndex(), summonIndex, false, false), MoveEndPhase);
|
||||
globalScene.phaseManager.prependToPhase(new SwitchSummonPhase(this.switchType, switchOutTarget.getFieldIndex(), summonIndex, false, false), MoveEndPhase);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
@ -5576,7 +5576,7 @@ class ForceSwitchOutHelper {
|
||||
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(false);
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) {
|
||||
globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon);
|
||||
}
|
||||
@ -5586,13 +5586,13 @@ class ForceSwitchOutHelper {
|
||||
globalScene.clearEnemyHeldItemModifiers();
|
||||
|
||||
if (switchOutTarget.hp) {
|
||||
globalScene.pushPhase(new BattleEndPhase(false));
|
||||
globalScene.phaseManager.pushPhase(new BattleEndPhase(false));
|
||||
|
||||
if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
||||
globalScene.pushPhase(new SelectBiomePhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectBiomePhase());
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new NewBattlePhase());
|
||||
globalScene.phaseManager.pushPhase(new NewBattlePhase());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5608,7 +5608,7 @@ class ForceSwitchOutHelper {
|
||||
*/
|
||||
public getSwitchOutCondition(pokemon: Pokemon, opponent: Pokemon): boolean {
|
||||
const switchOutTarget = pokemon;
|
||||
const player = switchOutTarget instanceof PlayerPokemon;
|
||||
const player = switchOutTarget.isPlayer();
|
||||
|
||||
if (player) {
|
||||
const blockedByAbility = new BooleanHolder(false);
|
||||
@ -5792,7 +5792,7 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(
|
||||
for (const passive of [ false, true ]) {
|
||||
if (pokemon) {
|
||||
applySingleAbAttrs(pokemon, passive, attrType, applyFunc, successFunc, args, gainedMidTurn, simulated, messages);
|
||||
globalScene.clearPhaseQueueSplice();
|
||||
globalScene.phaseManager.clearPhaseQueueSplice();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6870,7 +6870,7 @@ export function initAbilities() {
|
||||
.ignorable(),
|
||||
new Ability(AbilityId.ANALYTIC, 5)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => {
|
||||
const movePhase = globalScene.findPhase((phase) => phase.is("MovePhase") && phase.pokemon.id !== user?.id);
|
||||
const movePhase = globalScene.phaseManager.findPhase((phase) => phase.is("MovePhase") && phase.pokemon.id !== user?.id);
|
||||
return isNullOrUndefined(movePhase);
|
||||
}, 1.3),
|
||||
new Ability(AbilityId.ILLUSION, 5)
|
||||
|
@ -54,7 +54,7 @@ export abstract class ArenaTag {
|
||||
|
||||
onRemove(_arena: Arena, quiet = false): void {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:arenaOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
{ moveName: this.getMoveName() },
|
||||
@ -126,7 +126,7 @@ export class MistTag extends ArenaTag {
|
||||
const source = globalScene.getPokemonById(this.sourceId);
|
||||
|
||||
if (!quiet && source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:mistOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(source),
|
||||
}),
|
||||
@ -161,7 +161,7 @@ export class MistTag extends ArenaTag {
|
||||
cancelled.value = true;
|
||||
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:mistApply"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:mistApply"));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -239,7 +239,7 @@ class ReflectTag extends WeakenMoveScreenTag {
|
||||
|
||||
onAdd(_arena: Arena, quiet = false): void {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:reflectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -259,7 +259,7 @@ class LightScreenTag extends WeakenMoveScreenTag {
|
||||
|
||||
onAdd(_arena: Arena, quiet = false): void {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:lightScreenOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -282,7 +282,7 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
|
||||
|
||||
onAdd(_arena: Arena, quiet = false): void {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:auroraVeilOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -318,7 +318,7 @@ export class ConditionalProtectTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:conditionalProtectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
{ moveName: super.getMoveName() },
|
||||
@ -355,7 +355,7 @@ export class ConditionalProtectTag extends ArenaTag {
|
||||
isProtected.value = true;
|
||||
if (!simulated) {
|
||||
new CommonBattleAnim(CommonAnim.PROTECT, defender).play();
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:conditionalProtectApply", {
|
||||
moveName: super.getMoveName(),
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(defender),
|
||||
@ -381,7 +381,7 @@ export class ConditionalProtectTag extends ArenaTag {
|
||||
*/
|
||||
const QuickGuardConditionFunc: ProtectConditionFunc = (_arena, moveId) => {
|
||||
const move = allMoves[moveId];
|
||||
const effectPhase = globalScene.getCurrentPhase();
|
||||
const effectPhase = globalScene.phaseManager.getCurrentPhase();
|
||||
|
||||
if (effectPhase?.is("MoveEffectPhase")) {
|
||||
const attacker = effectPhase.getUserPokemon();
|
||||
@ -458,7 +458,7 @@ class MatBlockTag extends ConditionalProtectTag {
|
||||
if (this.sourceId) {
|
||||
const source = globalScene.getPokemonById(this.sourceId);
|
||||
if (source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:matBlockOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(source),
|
||||
}),
|
||||
@ -517,7 +517,7 @@ export class NoCritTag extends ArenaTag {
|
||||
|
||||
/** Queues a message upon adding this effect to the field */
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(`arenaTag:noCritOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : "Enemy"}`, {
|
||||
moveName: this.getMoveName(),
|
||||
}),
|
||||
@ -527,7 +527,7 @@ export class NoCritTag extends ArenaTag {
|
||||
/** Queues a message upon removing this effect from the field */
|
||||
onRemove(_arena: Arena): void {
|
||||
const source = globalScene.getPokemonById(this.sourceId!); // TODO: is this bang correct?
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:noCritOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(source ?? undefined),
|
||||
moveName: this.getMoveName(),
|
||||
@ -567,8 +567,10 @@ class WishTag extends ArenaTag {
|
||||
onRemove(_arena: Arena): void {
|
||||
const target = globalScene.getField()[this.battlerIndex];
|
||||
if (target?.isActive(true)) {
|
||||
globalScene.queueMessage(this.triggerMessage);
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(), this.healHp, null, true, false));
|
||||
globalScene.phaseManager.queueMessage(this.triggerMessage);
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(target.getBattlerIndex(), this.healHp, null, true, false),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -621,11 +623,11 @@ class MudSportTag extends WeakenMoveTypeTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:mudSportOnAdd"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:mudSportOnAdd"));
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:mudSportOnRemove"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:mudSportOnRemove"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,11 +641,11 @@ class WaterSportTag extends WeakenMoveTypeTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:waterSportOnAdd"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:waterSportOnAdd"));
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:waterSportOnRemove"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:waterSportOnRemove"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -659,7 +661,7 @@ export class IonDelugeTag extends ArenaTag {
|
||||
|
||||
/** Queues an on-add message */
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {} // Removes default on-remove message
|
||||
@ -758,7 +760,7 @@ class SpikesTag extends ArenaTrapTag {
|
||||
|
||||
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
|
||||
if (!quiet && source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:spikesOnAdd", {
|
||||
moveName: this.getMoveName(),
|
||||
opponentDesc: source.getOpponentDescriptor(),
|
||||
@ -781,7 +783,7 @@ class SpikesTag extends ArenaTrapTag {
|
||||
const damageHpRatio = 1 / (10 - 2 * this.layers);
|
||||
const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:spikesActivateTrap", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -811,7 +813,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
|
||||
|
||||
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
|
||||
if (!quiet && source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:toxicSpikesOnAdd", {
|
||||
moveName: this.getMoveName(),
|
||||
opponentDesc: source.getOpponentDescriptor(),
|
||||
@ -834,7 +836,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
|
||||
if (pokemon.isOfType(PokemonType.POISON)) {
|
||||
this.neutralized = true;
|
||||
if (globalScene.arena.removeTag(this.tagType)) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:toxicSpikesActivateTrapPoison", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: this.getMoveName(),
|
||||
@ -891,7 +893,7 @@ export class DelayedAttackTag extends ArenaTag {
|
||||
const ret = super.lapse(arena);
|
||||
|
||||
if (!ret) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new MoveEffectPhase(this.sourceId!, [this.targetIndex], allMoves[this.sourceMove!], false, true),
|
||||
); // TODO: are those bangs correct?
|
||||
}
|
||||
@ -917,7 +919,7 @@ class StealthRockTag extends ArenaTrapTag {
|
||||
|
||||
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
|
||||
if (!quiet && source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:stealthRockOnAdd", {
|
||||
opponentDesc: source.getOpponentDescriptor(),
|
||||
}),
|
||||
@ -971,7 +973,7 @@ class StealthRockTag extends ArenaTrapTag {
|
||||
}
|
||||
|
||||
const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:stealthRockActivateTrap", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1001,7 +1003,7 @@ class StickyWebTag extends ArenaTrapTag {
|
||||
super.onAdd(arena);
|
||||
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
|
||||
if (!quiet && source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:stickyWebOnAdd", {
|
||||
moveName: this.getMoveName(),
|
||||
opponentDesc: source.getOpponentDescriptor(),
|
||||
@ -1020,13 +1022,13 @@ class StickyWebTag extends ArenaTrapTag {
|
||||
}
|
||||
|
||||
if (!cancelled.value) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:stickyWebActivateTrap", {
|
||||
pokemonName: pokemon.getNameToRender(),
|
||||
}),
|
||||
);
|
||||
const stages = new NumberHolder(-1);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
false,
|
||||
@ -1074,7 +1076,7 @@ export class TrickRoomTag extends ArenaTag {
|
||||
onAdd(_arena: Arena): void {
|
||||
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
|
||||
if (source) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:trickRoomOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(source),
|
||||
}),
|
||||
@ -1083,7 +1085,7 @@ export class TrickRoomTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:trickRoomOnRemove"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:trickRoomOnRemove"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1098,7 +1100,7 @@ export class GravityTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
|
||||
globalScene.getField(true).forEach(pokemon => {
|
||||
if (pokemon !== null) {
|
||||
pokemon.removeTag(BattlerTagType.FLOATING);
|
||||
@ -1111,7 +1113,7 @@ export class GravityTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:gravityOnRemove"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:gravityOnRemove"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1127,7 +1129,7 @@ class TailwindTag extends ArenaTag {
|
||||
|
||||
onAdd(_arena: Arena, quiet = false): void {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:tailwindOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1141,7 +1143,7 @@ class TailwindTag extends ArenaTag {
|
||||
// Apply the CHARGED tag to party members with the WIND_POWER ability
|
||||
if (pokemon.hasAbility(AbilityId.WIND_POWER) && !pokemon.getTag(BattlerTagType.CHARGED)) {
|
||||
pokemon.addTag(BattlerTagType.CHARGED);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:windPowerCharged", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
moveName: this.getMoveName(),
|
||||
@ -1151,16 +1153,18 @@ class TailwindTag extends ArenaTag {
|
||||
// Raise attack by one stage if party member has WIND_RIDER ability
|
||||
// TODO: Ability displays should be handled by the ability
|
||||
if (pokemon.hasAbility(AbilityId.WIND_RIDER)) {
|
||||
globalScene.queueAbilityDisplay(pokemon, false, true);
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.ATK], 1, true));
|
||||
globalScene.queueAbilityDisplay(pokemon, false, false);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, false, true);
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.ATK], 1, true),
|
||||
);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena, quiet = false): void {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:tailwindOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1179,11 +1183,11 @@ class HappyHourTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:happyHourOnAdd"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:happyHourOnAdd"));
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:happyHourOnRemove"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:happyHourOnRemove"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1193,7 +1197,7 @@ class SafeguardTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:safeguardOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1201,7 +1205,7 @@ class SafeguardTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onRemove(_arena: Arena): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:safeguardOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1237,7 +1241,7 @@ class ImprisonTag extends ArenaTrapTag {
|
||||
p.addTag(BattlerTagType.IMPRISON, 1, MoveId.IMPRISON, this.sourceId);
|
||||
}
|
||||
});
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:imprisonOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(source),
|
||||
}),
|
||||
@ -1294,7 +1298,7 @@ class FireGrassPledgeTag extends ArenaTag {
|
||||
|
||||
override onAdd(_arena: Arena): void {
|
||||
// "A sea of fire enveloped your/the opposing team!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:fireGrassPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1309,13 +1313,13 @@ class FireGrassPledgeTag extends ArenaTag {
|
||||
.filter(pokemon => !pokemon.isOfType(PokemonType.FIRE) && !pokemon.switchOutStatus)
|
||||
.forEach(pokemon => {
|
||||
// "{pokemonNameWithAffix} was hurt by the sea of fire!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:fireGrassPledgeLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
// TODO: Replace this with a proper animation
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM),
|
||||
);
|
||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
||||
@ -1339,7 +1343,7 @@ class WaterFirePledgeTag extends ArenaTag {
|
||||
|
||||
override onAdd(_arena: Arena): void {
|
||||
// "A rainbow appeared in the sky on your/the opposing team's side!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:waterFirePledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1373,7 +1377,7 @@ class GrassWaterPledgeTag extends ArenaTag {
|
||||
|
||||
override onAdd(_arena: Arena): void {
|
||||
// "A swamp enveloped your/the opposing team!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(
|
||||
`arenaTag:grassWaterPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`,
|
||||
),
|
||||
@ -1394,7 +1398,7 @@ export class FairyLockTag extends ArenaTag {
|
||||
}
|
||||
|
||||
onAdd(_arena: Arena): void {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:fairyLockOnAdd"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:fairyLockOnAdd"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1451,7 +1455,7 @@ export class SuppressAbilitiesTag extends ArenaTag {
|
||||
public override onRemove(_arena: Arena, quiet = false) {
|
||||
this.beingRemoved = true;
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(i18next.t("arenaTag:neutralizingGasOnRemove"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("arenaTag:neutralizingGasOnRemove"));
|
||||
}
|
||||
|
||||
for (const pokemon of globalScene.getField(true)) {
|
||||
@ -1472,7 +1476,7 @@ export class SuppressAbilitiesTag extends ArenaTag {
|
||||
|
||||
private playActivationMessage(pokemon: Pokemon | null) {
|
||||
if (pokemon) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:neutralizingGasOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
|
@ -164,12 +164,12 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag {
|
||||
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
|
||||
// Cancel the affected pokemon's selected move
|
||||
const phase = globalScene.getCurrentPhase() as MovePhase;
|
||||
const phase = globalScene.phaseManager.getCurrentPhase() as MovePhase;
|
||||
const move = phase.move;
|
||||
|
||||
if (this.isMoveRestricted(move.moveId, pokemon)) {
|
||||
if (this.interruptedText(pokemon, move.moveId)) {
|
||||
globalScene.queueMessage(this.interruptedText(pokemon, move.moveId));
|
||||
globalScene.phaseManager.queueMessage(this.interruptedText(pokemon, move.moveId));
|
||||
}
|
||||
phase.cancel();
|
||||
}
|
||||
@ -315,7 +315,7 @@ export class DisabledTag extends MoveRestrictionBattlerTag {
|
||||
|
||||
this.moveId = move.move;
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:disabledOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: allMoves[this.moveId].name,
|
||||
@ -327,7 +327,7 @@ export class DisabledTag extends MoveRestrictionBattlerTag {
|
||||
override onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:disabledLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: allMoves[this.moveId].name,
|
||||
@ -456,12 +456,12 @@ export class RechargingTag extends BattlerTag {
|
||||
/** Cancels the source's move this turn and queues a "__ must recharge!" message */
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:rechargingLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
(globalScene.getCurrentPhase() as MovePhase).cancel();
|
||||
(globalScene.phaseManager.getCurrentPhase() as MovePhase).cancel();
|
||||
pokemon.getMoveQueue().shift();
|
||||
}
|
||||
return super.lapse(pokemon, lapseType);
|
||||
@ -488,7 +488,7 @@ export class BeakBlastChargingTag extends BattlerTag {
|
||||
new MoveChargeAnim(ChargeAnim.BEAK_BLAST_CHARGING, this.sourceMove, pokemon).play();
|
||||
|
||||
// Queue Beak Blast's header message
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("moveTriggers:startedHeatingUpBeak", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -533,7 +533,7 @@ export class ShellTrapTag extends BattlerTag {
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("moveTriggers:setUpShellTrap", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -552,15 +552,15 @@ export class ShellTrapTag extends BattlerTag {
|
||||
|
||||
// Trap should only be triggered by opponent's Physical moves
|
||||
if (phaseData?.move.category === MoveCategory.PHYSICAL && pokemon.isOpponent(phaseData.attacker)) {
|
||||
const shellTrapPhaseIndex = globalScene.phaseQueue.findIndex(
|
||||
const shellTrapPhaseIndex = globalScene.phaseManager.phaseQueue.findIndex(
|
||||
phase => phase.is("MovePhase") && phase.pokemon === pokemon,
|
||||
);
|
||||
const firstMovePhaseIndex = globalScene.phaseQueue.findIndex(phase => phase.is("MovePhase"));
|
||||
const firstMovePhaseIndex = globalScene.phaseManager.phaseQueue.findIndex(phase => phase.is("MovePhase"));
|
||||
|
||||
// Only shift MovePhase timing if it's not already next up
|
||||
if (shellTrapPhaseIndex !== -1 && shellTrapPhaseIndex !== firstMovePhaseIndex) {
|
||||
const shellTrapMovePhase = globalScene.phaseQueue.splice(shellTrapPhaseIndex, 1)[0];
|
||||
globalScene.prependToPhase(shellTrapMovePhase, MovePhase);
|
||||
const shellTrapMovePhase = globalScene.phaseManager.phaseQueue.splice(shellTrapPhaseIndex, 1)[0];
|
||||
globalScene.phaseManager.prependToPhase(shellTrapMovePhase, MovePhase);
|
||||
}
|
||||
|
||||
this.activated = true;
|
||||
@ -598,13 +598,13 @@ export class TrappedTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(this.getTrapMessage(pokemon));
|
||||
globalScene.phaseManager.queueMessage(this.getTrapMessage(pokemon));
|
||||
}
|
||||
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:trappedOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: this.getMoveName(),
|
||||
@ -660,8 +660,8 @@ export class FlinchedTag extends BattlerTag {
|
||||
*/
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
|
||||
(globalScene.getCurrentPhase() as MovePhase).cancel();
|
||||
globalScene.queueMessage(
|
||||
(globalScene.phaseManager.getCurrentPhase() as MovePhase).cancel();
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:flinchedLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -699,7 +699,7 @@ export class InterruptedTag extends BattlerTag {
|
||||
}
|
||||
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
(globalScene.getCurrentPhase() as MovePhase).cancel();
|
||||
(globalScene.phaseManager.getCurrentPhase() as MovePhase).cancel();
|
||||
return super.lapse(pokemon, lapseType);
|
||||
}
|
||||
}
|
||||
@ -719,8 +719,10 @@ export class ConfusedTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION),
|
||||
);
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:confusedOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -730,7 +732,7 @@ export class ConfusedTag extends BattlerTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:confusedOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -740,7 +742,7 @@ export class ConfusedTag extends BattlerTag {
|
||||
onOverlap(pokemon: Pokemon): void {
|
||||
super.onOverlap(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:confusedOnOverlap", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -754,12 +756,14 @@ export class ConfusedTag extends BattlerTag {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:confusedLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION),
|
||||
);
|
||||
|
||||
// 1/3 chance of hitting self with a 40 base power move
|
||||
if (pokemon.randBattleSeedInt(3) === 0 || Overrides.CONFUSION_ACTIVATION_OVERRIDE === true) {
|
||||
@ -769,9 +773,9 @@ export class ConfusedTag extends BattlerTag {
|
||||
((((2 * pokemon.level) / 5 + 2) * 40 * atk) / def / 50 + 2) * (pokemon.randBattleSeedIntRange(85, 100) / 100),
|
||||
);
|
||||
// Intentionally don't increment rage fist's hitCount
|
||||
globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
|
||||
pokemon.damageAndUpdate(damage, { result: HitResult.CONFUSION });
|
||||
(globalScene.getCurrentPhase() as MovePhase).cancel();
|
||||
(globalScene.phaseManager.getCurrentPhase() as MovePhase).cancel();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -815,7 +819,7 @@ export class DestinyBondTag extends BattlerTag {
|
||||
}
|
||||
|
||||
if (pokemon.isBossImmune()) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:destinyBondLapseIsBoss", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -823,7 +827,7 @@ export class DestinyBondTag extends BattlerTag {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:destinyBondLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(source),
|
||||
pokemonNameWithAffix2: getPokemonNameWithAffix(pokemon),
|
||||
@ -856,7 +860,7 @@ export class InfatuatedTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:infatuatedOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
|
||||
@ -867,7 +871,7 @@ export class InfatuatedTag extends BattlerTag {
|
||||
onOverlap(pokemon: Pokemon): void {
|
||||
super.onOverlap(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:infatuatedOnOverlap", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -878,21 +882,23 @@ export class InfatuatedTag extends BattlerTag {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:infatuatedLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
|
||||
}),
|
||||
);
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT),
|
||||
);
|
||||
|
||||
if (pokemon.randBattleSeedInt(2)) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:infatuatedLapseImmobilize", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
(globalScene.getCurrentPhase() as MovePhase).cancel();
|
||||
(globalScene.phaseManager.getCurrentPhase() as MovePhase).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,7 +908,7 @@ export class InfatuatedTag extends BattlerTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:infatuatedOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -941,7 +947,7 @@ export class SeedTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:seededOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -959,13 +965,13 @@ export class SeedTag extends BattlerTag {
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
||||
|
||||
if (!cancelled.value) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED),
|
||||
);
|
||||
|
||||
const damage = pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
||||
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr, false);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
source.getBattlerIndex(),
|
||||
!reverseDrain ? damage : damage * -1,
|
||||
@ -1006,7 +1012,7 @@ export class PowderTag extends BattlerTag {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
// "{Pokemon} is covered in powder!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:powderOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1022,7 +1028,7 @@ export class PowderTag extends BattlerTag {
|
||||
*/
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
|
||||
const movePhase = globalScene.getCurrentPhase();
|
||||
const movePhase = globalScene.phaseManager.getCurrentPhase();
|
||||
if (movePhase?.is("MovePhase")) {
|
||||
const move = movePhase.move.getMove();
|
||||
const weather = globalScene.arena.weather;
|
||||
@ -1033,7 +1039,7 @@ export class PowderTag extends BattlerTag {
|
||||
movePhase.fail();
|
||||
movePhase.showMoveText();
|
||||
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.POWDER),
|
||||
);
|
||||
|
||||
@ -1044,7 +1050,7 @@ export class PowderTag extends BattlerTag {
|
||||
}
|
||||
|
||||
// "When the flame touched the powder\non the Pokémon, it exploded!"
|
||||
globalScene.queueMessage(i18next.t("battlerTags:powderLapse", { moveName: move.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battlerTags:powderLapse", { moveName: move.name }));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -1061,7 +1067,7 @@ export class NightmareTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:nightmareOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1071,7 +1077,7 @@ export class NightmareTag extends BattlerTag {
|
||||
onOverlap(pokemon: Pokemon): void {
|
||||
super.onOverlap(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:nightmareOnOverlap", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1082,12 +1088,14 @@ export class NightmareTag extends BattlerTag {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:nightmareLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE),
|
||||
); // TODO: Update animation type
|
||||
|
||||
const cancelled = new BooleanHolder(false);
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
||||
@ -1173,18 +1181,18 @@ export class EncoreTag extends MoveRestrictionBattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:encoreOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
|
||||
const movePhase = globalScene.findPhase(m => m.is("MovePhase") && m.pokemon === pokemon);
|
||||
const movePhase = globalScene.phaseManager.findPhase(m => m.is("MovePhase") && m.pokemon === pokemon);
|
||||
if (movePhase) {
|
||||
const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId);
|
||||
if (movesetMove) {
|
||||
const lastMove = pokemon.getLastXMoves(1)[0];
|
||||
globalScene.tryReplacePhase(
|
||||
globalScene.phaseManager.tryReplacePhase(
|
||||
m => m.is("MovePhase") && m.pokemon === pokemon,
|
||||
new MovePhase(pokemon, lastMove.targets ?? [], movesetMove),
|
||||
);
|
||||
@ -1221,7 +1229,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:encoreOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1235,7 +1243,7 @@ export class HelpingHandTag extends BattlerTag {
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:helpingHandOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
@ -1268,7 +1276,7 @@ export class IngrainTag extends TrappedTag {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 16),
|
||||
@ -1307,7 +1315,9 @@ export class OctolockTag extends TrappedTag {
|
||||
const shouldLapse = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (shouldLapse) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, [Stat.DEF, Stat.SPDEF], -1));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), false, [Stat.DEF, Stat.SPDEF], -1),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1323,7 +1333,7 @@ export class AquaRingTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:aquaRingOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1334,7 +1344,7 @@ export class AquaRingTag extends BattlerTag {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 16),
|
||||
@ -1382,7 +1392,7 @@ export class DrowsyTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:drowsyOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1435,13 +1445,13 @@ export abstract class DamagingTrapTag extends TrappedTag {
|
||||
const ret = super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:damagingTrapLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: this.getMoveName(),
|
||||
}),
|
||||
);
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, this.commonAnim));
|
||||
globalScene.phaseManager.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, this.commonAnim));
|
||||
|
||||
const cancelled = new BooleanHolder(false);
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
||||
@ -1596,7 +1606,7 @@ export class ProtectedTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:protectedOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1606,14 +1616,14 @@ export class ProtectedTag extends BattlerTag {
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||
new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play();
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:protectedLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
|
||||
// Stop multi-hit moves early
|
||||
const effectPhase = globalScene.getCurrentPhase();
|
||||
const effectPhase = globalScene.phaseManager.getCurrentPhase();
|
||||
if (effectPhase?.is("MoveEffectPhase")) {
|
||||
effectPhase.stopMultiHit(pokemon);
|
||||
}
|
||||
@ -1754,7 +1764,9 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
|
||||
* @param user - The pokemon that is being attacked and has the tag
|
||||
*/
|
||||
override onContact(attacker: Pokemon, _user: Pokemon): void {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [this.stat], this.levels));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(attacker.getBattlerIndex(), false, [this.stat], this.levels),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1771,7 +1783,7 @@ export class EnduringTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:enduringOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1780,7 +1792,7 @@ export class EnduringTag extends BattlerTag {
|
||||
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:enduringLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1799,7 +1811,7 @@ export class SturdyTag extends BattlerTag {
|
||||
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:sturdyLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1824,7 +1836,7 @@ export class PerishSongTag extends BattlerTag {
|
||||
const ret = super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:perishSongLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
turnCount: this.turnCount,
|
||||
@ -1861,7 +1873,7 @@ export class CenterOfAttentionTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:centerOfAttentionOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1918,15 +1930,15 @@ export class TruantTag extends AbilityBattlerTag {
|
||||
const lastMove = pokemon.getLastXMoves().find(() => true);
|
||||
|
||||
if (lastMove && lastMove.move !== MoveId.NONE) {
|
||||
(globalScene.getCurrentPhase() as MovePhase).cancel();
|
||||
(globalScene.phaseManager.getCurrentPhase() as MovePhase).cancel();
|
||||
// TODO: Ability displays should be handled by the ability
|
||||
globalScene.queueAbilityDisplay(pokemon, passive, true);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, passive, true);
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:truantLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
globalScene.queueAbilityDisplay(pokemon, passive, false);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, passive, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1941,7 +1953,7 @@ export class SlowStartTag extends AbilityBattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:slowStartOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -1959,7 +1971,7 @@ export class SlowStartTag extends AbilityBattlerTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:slowStartOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2006,7 +2018,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
|
||||
this.stat = highestStat;
|
||||
|
||||
this.multiplier = this.stat === Stat.SPD ? 1.5 : 1.3;
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:highestStatBoostOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
statName: i18next.t(getStatKey(highestStat)),
|
||||
@ -2021,7 +2033,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:highestStatBoostOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
abilityName: allAbilities[this.ability].name,
|
||||
@ -2119,7 +2131,7 @@ export class FloatingTag extends TypeImmuneTag {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
if (this.sourceMove === MoveId.MAGNET_RISE) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:magnetRisenOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2130,7 +2142,7 @@ export class FloatingTag extends TypeImmuneTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
if (this.sourceMove === MoveId.MAGNET_RISE) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:magnetRisenOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2174,7 +2186,7 @@ export class TypeBoostTag extends BattlerTag {
|
||||
}
|
||||
|
||||
override onAdd(pokemon: Pokemon): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:typeImmunityPowerBoost", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.boostedType]}`),
|
||||
@ -2183,7 +2195,7 @@ export class TypeBoostTag extends BattlerTag {
|
||||
}
|
||||
|
||||
override onOverlap(pokemon: Pokemon): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:moveImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }),
|
||||
);
|
||||
}
|
||||
@ -2197,7 +2209,7 @@ export class CritBoostTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:critBoostOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2211,7 +2223,7 @@ export class CritBoostTag extends BattlerTag {
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:critBoostOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2257,7 +2269,7 @@ export class SaltCuredTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:saltCuredOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2269,7 +2281,7 @@ export class SaltCuredTag extends BattlerTag {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE),
|
||||
);
|
||||
|
||||
@ -2282,7 +2294,7 @@ export class SaltCuredTag extends BattlerTag {
|
||||
result: HitResult.INDIRECT,
|
||||
});
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:saltCuredLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: this.getMoveName(),
|
||||
@ -2320,7 +2332,7 @@ export class CursedTag extends BattlerTag {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE),
|
||||
);
|
||||
|
||||
@ -2329,7 +2341,7 @@ export class CursedTag extends BattlerTag {
|
||||
|
||||
if (!cancelled.value) {
|
||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT });
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:cursedLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2497,7 +2509,7 @@ export class CommandedTag extends BattlerTag {
|
||||
/** Caches the Tatsugiri's form key and sharply boosts the tagged Pokemon's stats */
|
||||
override onAdd(pokemon: Pokemon): void {
|
||||
this._tatsugiriFormKey = this.getSourcePokemon()?.getFormKey() ?? "curly";
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
true,
|
||||
@ -2572,7 +2584,7 @@ export class StockpilingTag extends BattlerTag {
|
||||
if (this.stockpiledCount < 3) {
|
||||
this.stockpiledCount++;
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:stockpilingOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
stockpiledCount: this.stockpiledCount,
|
||||
@ -2580,7 +2592,7 @@ export class StockpilingTag extends BattlerTag {
|
||||
);
|
||||
|
||||
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
true,
|
||||
@ -2608,13 +2620,13 @@ export class StockpilingTag extends BattlerTag {
|
||||
const spDefChange = this.statChangeCounts[Stat.SPDEF];
|
||||
|
||||
if (defChange) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.DEF], -defChange, true, false, true),
|
||||
);
|
||||
}
|
||||
|
||||
if (spDefChange) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.SPDEF], -spDefChange, true, false, true),
|
||||
);
|
||||
}
|
||||
@ -2635,7 +2647,7 @@ export class GulpMissileTag extends BattlerTag {
|
||||
return true;
|
||||
}
|
||||
|
||||
const moveEffectPhase = globalScene.getCurrentPhase();
|
||||
const moveEffectPhase = globalScene.phaseManager.getCurrentPhase();
|
||||
if (moveEffectPhase?.is("MoveEffectPhase")) {
|
||||
const attacker = moveEffectPhase.getUserPokemon();
|
||||
|
||||
@ -2655,7 +2667,9 @@ export class GulpMissileTag extends BattlerTag {
|
||||
}
|
||||
|
||||
if (this.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [Stat.DEF], -1));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(attacker.getBattlerIndex(), false, [Stat.DEF], -1),
|
||||
);
|
||||
} else {
|
||||
attacker.trySetStatus(StatusEffect.PARALYSIS, true, pokemon);
|
||||
}
|
||||
@ -2803,7 +2817,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
|
||||
override onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battle:battlerTagsHealBlockOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2833,7 +2847,7 @@ export class TarShotTag extends BattlerTag {
|
||||
}
|
||||
|
||||
override onAdd(pokemon: Pokemon): void {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:tarShotOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2852,7 +2866,7 @@ export class ElectrifiedTag extends BattlerTag {
|
||||
|
||||
override onAdd(pokemon: Pokemon): void {
|
||||
// "{pokemonNameWithAffix}'s moves have been electrified!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:electrifiedOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2878,7 +2892,7 @@ export class AutotomizedTag extends BattlerTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
const minWeight = 0.1;
|
||||
if (pokemon.getWeight() > minWeight) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:autotomizeOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2924,14 +2938,14 @@ export class SubstituteTag extends BattlerTag {
|
||||
// Queue battle animation and message
|
||||
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_ADD);
|
||||
if (this.sourceMove === MoveId.SHED_TAIL) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:shedTailOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
1500,
|
||||
);
|
||||
} else {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:substituteOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2951,7 +2965,7 @@ export class SubstituteTag extends BattlerTag {
|
||||
} else {
|
||||
this.sprite.destroy();
|
||||
}
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:substituteOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -2987,7 +3001,7 @@ export class SubstituteTag extends BattlerTag {
|
||||
|
||||
/** If the Substitute redirects damage, queue a message to indicate it. */
|
||||
onHit(pokemon: Pokemon): void {
|
||||
const moveEffectPhase = globalScene.getCurrentPhase();
|
||||
const moveEffectPhase = globalScene.phaseManager.getCurrentPhase();
|
||||
if (moveEffectPhase?.is("MoveEffectPhase")) {
|
||||
const attacker = moveEffectPhase.getUserPokemon();
|
||||
if (!attacker) {
|
||||
@ -2997,7 +3011,7 @@ export class SubstituteTag extends BattlerTag {
|
||||
const firstHit = attacker.turnData.hitCount === attacker.turnData.hitsLeft;
|
||||
|
||||
if (firstHit && move.hitsSubstitute(attacker, pokemon)) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:substituteOnHit", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3074,7 +3088,7 @@ export class TormentTag extends MoveRestrictionBattlerTag {
|
||||
*/
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
super.onAdd(pokemon);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:tormentOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3132,7 +3146,7 @@ export class TauntTag extends MoveRestrictionBattlerTag {
|
||||
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
super.onAdd(pokemon);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:tauntOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3143,7 +3157,7 @@ export class TauntTag extends MoveRestrictionBattlerTag {
|
||||
public override onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:tauntOnRemove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3253,7 +3267,7 @@ export class SyrupBombTag extends BattlerTag {
|
||||
*/
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
super.onAdd(pokemon);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:syrupBombOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3271,12 +3285,12 @@ export class SyrupBombTag extends BattlerTag {
|
||||
return false;
|
||||
}
|
||||
// Custom message in lieu of an animation in mainline
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:syrupBombLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.SPD], -1, true, false, true),
|
||||
);
|
||||
return --this.turnCount > 0;
|
||||
@ -3302,7 +3316,7 @@ export class TelekinesisTag extends BattlerTag {
|
||||
}
|
||||
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:telekinesisOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3321,7 +3335,7 @@ export class PowerTrickTag extends BattlerTag {
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
this.swapStat(pokemon);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:powerTrickActive", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3330,7 +3344,7 @@ export class PowerTrickTag extends BattlerTag {
|
||||
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
this.swapStat(pokemon);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:powerTrickActive", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3368,7 +3382,7 @@ export class GrudgeTag extends BattlerTag {
|
||||
|
||||
onAdd(pokemon: Pokemon) {
|
||||
super.onAdd(pokemon);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:grudgeOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3389,7 +3403,7 @@ export class GrudgeTag extends BattlerTag {
|
||||
const lastMoveData = sourcePokemon.getMoveset().find(m => m.moveId === lastMove.move);
|
||||
if (lastMoveData && lastMove.move !== MoveId.STRUGGLE) {
|
||||
lastMoveData.ppUsed = lastMoveData.getMovePp();
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:grudgeLapse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: lastMoveData.getName(),
|
||||
@ -3417,7 +3431,9 @@ export class PsychoShiftTag extends BattlerTag {
|
||||
*/
|
||||
override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean {
|
||||
if (pokemon.status && pokemon.isActive(true)) {
|
||||
globalScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)),
|
||||
);
|
||||
pokemon.resetStatus();
|
||||
pokemon.updateInfo();
|
||||
}
|
||||
@ -3439,7 +3455,7 @@ export class MagicCoatTag extends BattlerTag {
|
||||
*/
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
// "{pokemonNameWithAffix} shrouded itself with Magic Coat!"
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:magicCoatOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -3673,7 +3689,7 @@ export function loadBattlerTag(source: BattlerTag | any): BattlerTag {
|
||||
* corresponding {@linkcode Move} and user {@linkcode Pokemon}
|
||||
*/
|
||||
function getMoveEffectPhaseData(_pokemon: Pokemon): { phase: MoveEffectPhase; attacker: Pokemon; move: Move } | null {
|
||||
const phase = globalScene.getCurrentPhase();
|
||||
const phase = globalScene.phaseManager.getCurrentPhase();
|
||||
if (phase?.is("MoveEffectPhase")) {
|
||||
return {
|
||||
phase: phase,
|
||||
|
@ -3,11 +3,7 @@ import type Pokemon from "../field/pokemon";
|
||||
import { HitResult } from "../field/pokemon";
|
||||
import { getStatusEffectHealText } from "./status-effect";
|
||||
import { NumberHolder, toDmgValue, randSeedInt } from "#app/utils/common";
|
||||
import {
|
||||
DoubleBerryEffectAbAttr,
|
||||
ReduceBerryUseThresholdAbAttr,
|
||||
applyAbAttrs,
|
||||
} from "./abilities/ability";
|
||||
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./abilities/ability";
|
||||
import i18next from "i18next";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { BerryType } from "#enums/berry-type";
|
||||
@ -79,7 +75,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
||||
{
|
||||
const hpHealed = new NumberHolder(toDmgValue(consumer.getMaxHp() / 4));
|
||||
applyAbAttrs(DoubleBerryEffectAbAttr, consumer, null, false, hpHealed);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
consumer.getBattlerIndex(),
|
||||
hpHealed.value,
|
||||
@ -95,7 +91,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
||||
case BerryType.LUM:
|
||||
{
|
||||
if (consumer.status) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(consumer.status.effect, getPokemonNameWithAffix(consumer)),
|
||||
);
|
||||
}
|
||||
@ -113,7 +109,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
||||
const stat: BattleStat = berryType - BerryType.ENIGMA;
|
||||
const statStages = new NumberHolder(1);
|
||||
applyAbAttrs(DoubleBerryEffectAbAttr, consumer, null, false, statStages);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(consumer.getBattlerIndex(), true, [stat], statStages.value),
|
||||
);
|
||||
}
|
||||
@ -130,7 +126,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
||||
const randStat = randSeedInt(Stat.SPD, Stat.ATK);
|
||||
const stages = new NumberHolder(2);
|
||||
applyAbAttrs(DoubleBerryEffectAbAttr, consumer, null, false, stages);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(consumer.getBattlerIndex(), true, [randStat], stages.value),
|
||||
);
|
||||
}
|
||||
@ -144,7 +140,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
||||
consumer.getMoveset().find(m => m.ppUsed < m.getMovePp());
|
||||
if (ppRestoreMove) {
|
||||
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0);
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battle:ppHealBerry", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(consumer),
|
||||
moveName: ppRestoreMove.getName(),
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||
import type { DexEntry, StarterDataEntry } from "#app/system/game-data";
|
||||
import type { StarterDataEntry } from "#app/system/game-data";
|
||||
import type { DexEntry } from "#app/@types/dex-data";
|
||||
|
||||
/**
|
||||
* Stores data associated with a specific egg and the hatched pokemon
|
||||
|
@ -81,7 +81,7 @@ import { TerrainType } from "../terrain";
|
||||
import { ModifierPoolType } from "#app/modifier/modifier-type";
|
||||
import { Command } from "../../ui/command-ui-handler";
|
||||
import i18next from "i18next";
|
||||
import type { Localizable } from "#app/interfaces/locales";
|
||||
import type { Localizable } from "#app/@types/locales";
|
||||
import { getBerryEffectFunc } from "../berry";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
@ -837,7 +837,7 @@ export default class Move implements Localizable {
|
||||
aura.applyPreAttack(source, null, simulated, target, this, [ power ]);
|
||||
}
|
||||
|
||||
const alliedField: Pokemon[] = source instanceof PlayerPokemon ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
const alliedField: Pokemon[] = source.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
alliedField.forEach(p => applyPreAttackAbAttrs(UserFieldMoveTypePowerBoostAbAttr, p, target, this, simulated, power));
|
||||
|
||||
power.value *= typeChangeMovePowerMultiplier.value;
|
||||
@ -1048,7 +1048,7 @@ function ChargeMove<TBase extends SubMove>(Base: TBase) {
|
||||
* @param target the {@linkcode Pokemon} targeted by this move (optional)
|
||||
*/
|
||||
showChargeText(user: Pokemon, target?: Pokemon): void {
|
||||
globalScene.queueMessage(this._chargeText
|
||||
globalScene.phaseManager.queueMessage(this._chargeText
|
||||
.replace("{USER}", getPokemonNameWithAffix(user))
|
||||
.replace("{TARGET}", getPokemonNameWithAffix(target))
|
||||
);
|
||||
@ -1310,7 +1310,7 @@ export class MessageHeaderAttr extends MoveHeaderAttr {
|
||||
: this.message(user, move);
|
||||
|
||||
if (message) {
|
||||
globalScene.queueMessage(message);
|
||||
globalScene.phaseManager.queueMessage(message);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1363,7 +1363,7 @@ export class PreMoveMessageAttr extends MoveAttr {
|
||||
? this.message as string
|
||||
: this.message(user, target, move);
|
||||
if (message) {
|
||||
globalScene.queueMessage(message, 500);
|
||||
globalScene.phaseManager.queueMessage(message, 500);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1620,14 +1620,14 @@ export class SurviveDamageAttr extends ModifiedDamageAttr {
|
||||
|
||||
export class SplashAttr extends MoveEffectAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:splash"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:splash"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class CelebrateAttr extends MoveEffectAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:celebrate", { playerName: loggedInUser?.username }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:celebrate", { playerName: loggedInUser?.username }));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1677,7 +1677,7 @@ export class RecoilAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
user.damageAndUpdate(recoilDamage, { result: HitResult.INDIRECT, ignoreSegments: true });
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:hitWithRecoil", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:hitWithRecoil", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
user.turnData.damageTaken += recoilDamage;
|
||||
|
||||
return true;
|
||||
@ -1789,7 +1789,7 @@ export class HalfSacrificialAttr extends MoveEffectAttr {
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled);
|
||||
if (!cancelled.value) {
|
||||
user.damageAndUpdate(toDmgValue(user.getMaxHp() / 2), { result: HitResult.INDIRECT, ignoreSegments: true });
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", { pokemonName: getPokemonNameWithAffix(user) })); // Queue recoil message
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", { pokemonName: getPokemonNameWithAffix(user) })); // Queue recoil message
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1890,7 +1890,7 @@ export class HealAttr extends MoveEffectAttr {
|
||||
* This heals the target and shows the appropriate message.
|
||||
*/
|
||||
addHealPhase(target: Pokemon, healRatio: number) {
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
toDmgValue(target.getMaxHp() * healRatio), i18next.t("moveTriggers:healHp", { pokemonName: getPokemonNameWithAffix(target) }), true, !this.showAnim));
|
||||
}
|
||||
|
||||
@ -1934,7 +1934,7 @@ export class PartyStatusCureAttr extends MoveEffectAttr {
|
||||
partyPokemon.forEach(p => this.cureStatus(p, user.id));
|
||||
|
||||
if (this.message) {
|
||||
globalScene.queueMessage(this.message);
|
||||
globalScene.phaseManager.queueMessage(this.message);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1954,8 +1954,8 @@ export class PartyStatusCureAttr extends MoveEffectAttr {
|
||||
pokemon.updateInfo();
|
||||
} else {
|
||||
// TODO: Ability displays should be handled by the ability
|
||||
globalScene.queueAbilityDisplay(pokemon, pokemon.getPassiveAbility()?.id === this.abilityCondition, true);
|
||||
globalScene.queueAbilityDisplay(pokemon, pokemon.getPassiveAbility()?.id === this.abilityCondition, false);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, pokemon.getPassiveAbility()?.id === this.abilityCondition, true);
|
||||
globalScene.phaseManager.queueAbilityDisplay(pokemon, pokemon.getPassiveAbility()?.id === this.abilityCondition, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2021,7 +2021,7 @@ export class SacrificialFullRestoreAttr extends SacrificialAttr {
|
||||
const party = user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty();
|
||||
const maxPartyMemberHp = party.map(p => p.getMaxHp()).reduce((maxHp: number, hp: number) => Math.max(hp, maxHp), 0);
|
||||
|
||||
globalScene.pushPhase(
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new PokemonHealPhase(
|
||||
user.getBattlerIndex(),
|
||||
maxPartyMemberHp,
|
||||
@ -2233,7 +2233,7 @@ export class HitHealAttr extends MoveEffectAttr {
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(user.getBattlerIndex(), healAmount, message, false, true));
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(user.getBattlerIndex(), healAmount, message, false, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2565,7 +2565,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name }));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2643,9 +2643,9 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
||||
globalScene.updateModifiers(target.isPlayer());
|
||||
|
||||
if (this.berriesOnly) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
|
||||
} else {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2777,7 +2777,7 @@ export class StealEatBerryAttr extends EatBerryAttr {
|
||||
this.chosenBerry = heldBerries[user.randBattleSeedInt(heldBerries.length)];
|
||||
applyPostItemLostAbAttrs(PostItemLostAbAttr, target, false);
|
||||
const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name });
|
||||
globalScene.queueMessage(message);
|
||||
globalScene.phaseManager.queueMessage(message);
|
||||
this.reduceBerryModifier(target);
|
||||
this.eatBerry(user, target);
|
||||
|
||||
@ -2822,7 +2822,7 @@ export class HealStatusEffectAttr extends MoveEffectAttr {
|
||||
|
||||
const pokemon = this.selfTarget ? user : target;
|
||||
if (pokemon.status && this.effects.includes(pokemon.status.effect)) {
|
||||
globalScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
|
||||
globalScene.phaseManager.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
|
||||
pokemon.resetStatus();
|
||||
pokemon.updateInfo();
|
||||
|
||||
@ -3067,13 +3067,13 @@ export class DelayedAttackAttr extends OverrideMoveEffectAttr {
|
||||
|
||||
if (!virtual) {
|
||||
overridden.value = true;
|
||||
globalScene.unshiftPhase(new MoveAnimPhase(new MoveChargeAnim(this.chargeAnim, move.id, user)));
|
||||
globalScene.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user)));
|
||||
globalScene.phaseManager.unshiftPhase(new MoveAnimPhase(new MoveChargeAnim(this.chargeAnim, move.id, user)));
|
||||
globalScene.phaseManager.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user)));
|
||||
user.pushMoveHistory({ move: move.id, targets: [ target.getBattlerIndex() ], result: MoveResult.OTHER });
|
||||
const side = target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||
globalScene.arena.addTag(this.tagType, 3, move.id, user.id, side, false, target.getBattlerIndex());
|
||||
} else {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:tookMoveAttack", { pokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(target.id) ?? undefined), moveName: move.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:tookMoveAttack", { pokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(target.id) ?? undefined), moveName: move.name }));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -3103,29 +3103,29 @@ export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr {
|
||||
override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (user.turnData.combiningPledge) {
|
||||
// "The two moves have become one!\nIt's a combined move!"
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:combiningPledge"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:combiningPledge"));
|
||||
return false;
|
||||
}
|
||||
|
||||
const overridden = args[0] as BooleanHolder;
|
||||
|
||||
const allyMovePhase = globalScene.findPhase<MovePhase>((phase) => phase.is("MovePhase") && phase.pokemon.isPlayer() === user.isPlayer());
|
||||
const allyMovePhase = globalScene.phaseManager.findPhase<MovePhase>((phase) => phase.is("MovePhase") && phase.pokemon.isPlayer() === user.isPlayer());
|
||||
if (allyMovePhase) {
|
||||
const allyMove = allyMovePhase.move.getMove();
|
||||
if (allyMove !== move && allyMove.hasAttr(AwaitCombinedPledgeAttr)) {
|
||||
[ user, allyMovePhase.pokemon ].forEach((p) => p.turnData.combiningPledge = move.id);
|
||||
|
||||
// "{userPokemonName} is waiting for {allyPokemonName}'s move..."
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:awaitingPledge", {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:awaitingPledge", {
|
||||
userPokemonName: getPokemonNameWithAffix(user),
|
||||
allyPokemonName: getPokemonNameWithAffix(allyMovePhase.pokemon)
|
||||
}));
|
||||
|
||||
// Move the ally's MovePhase (if needed) so that the ally moves next
|
||||
const allyMovePhaseIndex = globalScene.phaseQueue.indexOf(allyMovePhase);
|
||||
const firstMovePhaseIndex = globalScene.phaseQueue.findIndex((phase) => phase.is("MovePhase"));
|
||||
const allyMovePhaseIndex = globalScene.phaseManager.phaseQueue.indexOf(allyMovePhase);
|
||||
const firstMovePhaseIndex = globalScene.phaseManager.phaseQueue.findIndex((phase) => phase.is("MovePhase"));
|
||||
if (allyMovePhaseIndex !== firstMovePhaseIndex) {
|
||||
globalScene.prependToPhase(globalScene.phaseQueue.splice(allyMovePhaseIndex, 1)[0], MovePhase);
|
||||
globalScene.phaseManager.prependToPhase(globalScene.phaseManager.phaseQueue.splice(allyMovePhaseIndex, 1)[0], MovePhase);
|
||||
}
|
||||
|
||||
overridden.value = true;
|
||||
@ -3207,7 +3207,7 @@ export class StatStageChangeAttr extends MoveEffectAttr {
|
||||
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
|
||||
if (moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) {
|
||||
const stages = this.getLevels(user);
|
||||
globalScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, stages, this.showMessage));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase((this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, stages, this.showMessage));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3432,7 +3432,7 @@ export class AcupressureStatStageChangeAttr extends MoveEffectAttr {
|
||||
const randStats = BATTLE_STATS.filter((s) => target.getStatStage(s) < 6);
|
||||
if (randStats.length > 0) {
|
||||
const boostStat = [ randStats[user.randBattleSeedInt(randStats.length)] ];
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(target.getBattlerIndex(), this.selfTarget, boostStat, 2));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(target.getBattlerIndex(), this.selfTarget, boostStat, 2));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3510,7 +3510,7 @@ export class OrderUpStatBoostAttr extends MoveEffectAttr {
|
||||
break;
|
||||
}
|
||||
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), this.selfTarget, [ increasedStat ], 1));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), this.selfTarget, [ increasedStat ], 1));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -3533,7 +3533,7 @@ export class CopyStatsAttr extends MoveEffectAttr {
|
||||
}
|
||||
target.updateInfo();
|
||||
user.updateInfo();
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copiedStatChanges", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:copiedStatChanges", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3552,7 +3552,7 @@ export class InvertStatsAttr extends MoveEffectAttr {
|
||||
target.updateInfo();
|
||||
user.updateInfo();
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:invertStats", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:invertStats", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3570,10 +3570,10 @@ export class ResetStatsAttr extends MoveEffectAttr {
|
||||
// Target all pokemon on the field when Freezy Frost or Haze are used
|
||||
const activePokemon = globalScene.getField(true);
|
||||
activePokemon.forEach((p) => this.resetStats(p));
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:statEliminated"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:statEliminated"));
|
||||
} else { // Affects only the single target when Clear Smog is used
|
||||
this.resetStats(target);
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:resetStats", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:resetStats", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3623,9 +3623,9 @@ export class SwapStatStagesAttr extends MoveEffectAttr {
|
||||
user.updateInfo();
|
||||
|
||||
if (this.stats.length === 7) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:switchedStatChanges", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:switchedStatChanges", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
} else if (this.stats.length === 2) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:switchedTwoStatChanges", {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:switchedTwoStatChanges", {
|
||||
pokemonName: getPokemonNameWithAffix(user),
|
||||
firstStat: i18next.t(getStatKey(this.stats[0])),
|
||||
secondStat: i18next.t(getStatKey(this.stats[1]))
|
||||
@ -4125,7 +4125,7 @@ export class FriendshipPowerAttr extends VariablePowerAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const power = args[0] as NumberHolder;
|
||||
|
||||
const friendshipPower = Math.floor(Math.min(user instanceof PlayerPokemon ? user.friendship : user.species.baseFriendship, 255) / 2.5);
|
||||
const friendshipPower = Math.floor(Math.min(user.isPlayer() ? user.friendship : user.species.baseFriendship, 255) / 2.5);
|
||||
power.value = Math.max(!this.invert ? friendshipPower : 102 - friendshipPower, 1);
|
||||
|
||||
return true;
|
||||
@ -4227,7 +4227,7 @@ export class PresentPowerAttr extends VariablePowerAttr {
|
||||
// If this move is multi-hit, disable all other hits
|
||||
user.turnData.hitCount = 1;
|
||||
user.turnData.hitsLeft = 1;
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
toDmgValue(target.getMaxHp() / 4), i18next.t("moveTriggers:regainedHealth", { pokemonName: getPokemonNameWithAffix(target) }), true));
|
||||
}
|
||||
|
||||
@ -4476,7 +4476,7 @@ export class CueNextRoundAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
override apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean {
|
||||
const nextRoundPhase = globalScene.findPhase<MovePhase>(phase =>
|
||||
const nextRoundPhase = globalScene.phaseManager.findPhase<MovePhase>(phase =>
|
||||
phase.is("MovePhase") && phase.move.moveId === MoveId.ROUND
|
||||
);
|
||||
|
||||
@ -4485,10 +4485,10 @@ export class CueNextRoundAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
// Update the phase queue so that the next Pokemon using Round moves next
|
||||
const nextRoundIndex = globalScene.phaseQueue.indexOf(nextRoundPhase);
|
||||
const nextMoveIndex = globalScene.phaseQueue.findIndex(phase => phase.is("MovePhase"));
|
||||
const nextRoundIndex = globalScene.phaseManager.phaseQueue.indexOf(nextRoundPhase);
|
||||
const nextMoveIndex = globalScene.phaseManager.phaseQueue.findIndex(phase => phase.is("MovePhase"));
|
||||
if (nextRoundIndex !== nextMoveIndex) {
|
||||
globalScene.prependToPhase(globalScene.phaseQueue.splice(nextRoundIndex, 1)[0], MovePhase);
|
||||
globalScene.phaseManager.prependToPhase(globalScene.phaseManager.phaseQueue.splice(nextRoundIndex, 1)[0], MovePhase);
|
||||
}
|
||||
|
||||
// Mark the corresponding Pokemon as having "joined the Round" (for doubling power later)
|
||||
@ -4546,14 +4546,14 @@ export class SpectralThiefAttr extends StatChangeBeforeDmgCalcAttr {
|
||||
*/
|
||||
const availableToSteal = Math.min(statStageValueTarget, 6 - statStageValueUser);
|
||||
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), this.selfTarget, [ s ], availableToSteal));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), this.selfTarget, [ s ], availableToSteal));
|
||||
target.setStatStage(s, statStageValueTarget - availableToSteal);
|
||||
}
|
||||
}
|
||||
|
||||
target.updateInfo();
|
||||
user.updateInfo();
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:stealPositiveStats", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:stealPositiveStats", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -5368,7 +5368,7 @@ const crashDamageFunc = (user: Pokemon, move: Move) => {
|
||||
}
|
||||
|
||||
user.damageAndUpdate(toDmgValue(user.getMaxHp() / 2), { result: HitResult.INDIRECT });
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
user.turnData.damageTaken += toDmgValue(user.getMaxHp() / 2);
|
||||
|
||||
return true;
|
||||
@ -5581,7 +5581,7 @@ export class FallDownAttr extends AddBattlerTagAttr {
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (!target.isGrounded()) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:fallDown", { targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:fallDown", { targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
}
|
||||
return super.apply(user, target, move, args);
|
||||
}
|
||||
@ -5665,12 +5665,12 @@ export class CurseAttr extends MoveEffectAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move:Move, args: any[]): boolean {
|
||||
if (user.getTypes(true).includes(PokemonType.GHOST)) {
|
||||
if (target.getTag(BattlerTagType.CURSED)) {
|
||||
globalScene.queueMessage(i18next.t("battle:attackFailed"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:attackFailed"));
|
||||
return false;
|
||||
}
|
||||
const curseRecoilDamage = Math.max(1, Math.floor(user.getMaxHp() / 2));
|
||||
user.damageAndUpdate(curseRecoilDamage, { result: HitResult.INDIRECT, ignoreSegments: true });
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:cursedOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(user),
|
||||
pokemonName: getPokemonNameWithAffix(target)
|
||||
@ -5680,8 +5680,8 @@ export class CurseAttr extends MoveEffectAttr {
|
||||
target.addTag(BattlerTagType.CURSED, 0, move.id, user.id);
|
||||
return true;
|
||||
} else {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF ], 1));
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), true, [ Stat.SPD ], -1));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF ], 1));
|
||||
globalScene.phaseManager.unshiftPhase(new StatStageChangePhase(user.getBattlerIndex(), true, [ Stat.SPD ], -1));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -5745,7 +5745,7 @@ export class ConfuseAttr extends AddBattlerTagAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (!this.selfTarget && target.isSafeguarded(user)) {
|
||||
if (move.category === MoveCategory.STATUS) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target) }));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -5802,7 +5802,7 @@ export class IgnoreAccuracyAttr extends AddBattlerTagAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:tookAimAtTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:tookAimAtTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -5818,7 +5818,7 @@ export class FaintCountdownAttr extends AddBattlerTagAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:faintCountdown", { pokemonName: getPokemonNameWithAffix(target), turnCount: this.turnCountMin - 1 }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:faintCountdown", { pokemonName: getPokemonNameWithAffix(target), turnCount: this.turnCountMin - 1 }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6102,7 +6102,7 @@ export class SwapArenaTagsAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:swapArenaTags", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:swapArenaTags", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -6149,14 +6149,14 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
|
||||
* @param target {@linkcode Pokemon} target of this move
|
||||
* @param move {@linkcode Move} being used
|
||||
* @param args N/A
|
||||
* @returns Promise, true if function succeeds.
|
||||
* @returns `true` if function succeeds.
|
||||
*/
|
||||
override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
// If user is player, checks if the user has fainted pokemon
|
||||
if (user instanceof PlayerPokemon) {
|
||||
globalScene.unshiftPhase(new RevivalBlessingPhase(user));
|
||||
if (user.isPlayer()) {
|
||||
globalScene.phaseManager.unshiftPhase(new RevivalBlessingPhase(user));
|
||||
return true;
|
||||
} else if (user instanceof EnemyPokemon && user.hasTrainer() && globalScene.getEnemyParty().findIndex((p) => p.isFainted() && !p.isBoss()) > -1) {
|
||||
} else if (user.isEnemy() && user.hasTrainer() && globalScene.getEnemyParty().findIndex((p) => p.isFainted() && !p.isBoss()) > -1) {
|
||||
// If used by an enemy trainer with at least one fainted non-boss Pokemon, this
|
||||
// revives one of said Pokemon selected at random.
|
||||
const faintedPokemon = globalScene.getEnemyParty().filter((p) => p.isFainted() && !p.isBoss());
|
||||
@ -6164,20 +6164,20 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
|
||||
const slotIndex = globalScene.getEnemyParty().findIndex((p) => pokemon.id === p.id);
|
||||
pokemon.resetStatus(true, false, false, true);
|
||||
pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true);
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true);
|
||||
const allyPokemon = user.getAlly();
|
||||
if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1 && !isNullOrUndefined(allyPokemon)) {
|
||||
// Handle cases where revived pokemon needs to get switched in on same turn
|
||||
if (allyPokemon.isFainted() || allyPokemon === pokemon) {
|
||||
// Enemy switch phase should be removed and replaced with the revived pkmn switching in
|
||||
globalScene.tryRemovePhase((phase: SwitchSummonPhase) => phase.is("SwitchSummonPhase") && phase.getPokemon() === pokemon);
|
||||
globalScene.phaseManager.tryRemovePhase((phase: SwitchSummonPhase) => phase.is("SwitchSummonPhase") && phase.getPokemon() === pokemon);
|
||||
// If the pokemon being revived was alive earlier in the turn, cancel its move
|
||||
// (revived pokemon can't move in the turn they're brought back)
|
||||
globalScene.findPhase((phase: MovePhase) => phase.pokemon === pokemon)?.cancel();
|
||||
globalScene.phaseManager.findPhase((phase: MovePhase) => phase.pokemon === pokemon)?.cancel();
|
||||
if (user.fieldPosition === FieldPosition.CENTER) {
|
||||
user.setFieldPosition(FieldPosition.LEFT);
|
||||
}
|
||||
globalScene.unshiftPhase(new SwitchSummonPhase(SwitchType.SWITCH, allyPokemon.getFieldIndex(), slotIndex, false, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SwitchSummonPhase(SwitchType.SWITCH, allyPokemon.getFieldIndex(), slotIndex, false, false));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -6187,10 +6187,8 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
|
||||
|
||||
getCondition(): MoveConditionFunc {
|
||||
return (user, target, move) =>
|
||||
(user instanceof PlayerPokemon && globalScene.getPlayerParty().some((p) => p.isFainted())) ||
|
||||
(user instanceof EnemyPokemon &&
|
||||
user.hasTrainer() &&
|
||||
globalScene.getEnemyParty().some((p) => p.isFainted() && !p.isBoss()));
|
||||
(user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).some((p: Pokemon) => p.isFainted() && !p.isBoss());
|
||||
}
|
||||
|
||||
override getUserBenefitScore(user: Pokemon, _target: Pokemon, _move: Move): number {
|
||||
@ -6228,7 +6226,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
// (e.g. when it uses Flip Turn), make it spit out the Tatsugiri before switching out.
|
||||
switchOutTarget.lapseTag(BattlerTagType.COMMANDED);
|
||||
|
||||
if (switchOutTarget instanceof PlayerPokemon) {
|
||||
if (switchOutTarget.isPlayer()) {
|
||||
/**
|
||||
* Check if Wimp Out/Emergency Exit activates due to being hit by U-turn or Volt Switch
|
||||
* If it did, the user of U-turn or Volt Switch will not be switched out.
|
||||
@ -6257,7 +6255,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
if (this.switchType === SwitchType.FORCE_SWITCH) {
|
||||
switchOutTarget.leaveField(true);
|
||||
const slotIndex = eligibleNewIndices[user.randBattleSeedInt(eligibleNewIndices.length)];
|
||||
globalScene.prependToPhase(
|
||||
globalScene.phaseManager.prependToPhase(
|
||||
new SwitchSummonPhase(
|
||||
this.switchType,
|
||||
switchOutTarget.getFieldIndex(),
|
||||
@ -6269,7 +6267,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
);
|
||||
} else {
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
globalScene.prependToPhase(
|
||||
globalScene.phaseManager.prependToPhase(
|
||||
new SwitchPhase(
|
||||
this.switchType,
|
||||
switchOutTarget.getFieldIndex(),
|
||||
@ -6300,7 +6298,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
if (this.switchType === SwitchType.FORCE_SWITCH) {
|
||||
switchOutTarget.leaveField(true);
|
||||
const slotIndex = eligibleNewIndices[user.randBattleSeedInt(eligibleNewIndices.length)];
|
||||
globalScene.prependToPhase(
|
||||
globalScene.phaseManager.prependToPhase(
|
||||
new SwitchSummonPhase(
|
||||
this.switchType,
|
||||
switchOutTarget.getFieldIndex(),
|
||||
@ -6312,7 +6310,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
);
|
||||
} else {
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
globalScene.prependToPhase(
|
||||
globalScene.phaseManager.prependToPhase(
|
||||
new SwitchSummonPhase(
|
||||
this.switchType,
|
||||
switchOutTarget.getFieldIndex(),
|
||||
@ -6341,7 +6339,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(false);
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
|
||||
// in double battles redirect potential moves off fled pokemon
|
||||
if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) {
|
||||
@ -6353,13 +6351,13 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
globalScene.clearEnemyHeldItemModifiers(switchOutTarget);
|
||||
|
||||
if (!allyPokemon?.isActive(true) && switchOutTarget.hp) {
|
||||
globalScene.pushPhase(new BattleEndPhase(false));
|
||||
globalScene.phaseManager.pushPhase(new BattleEndPhase(false));
|
||||
|
||||
if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
||||
globalScene.pushPhase(new SelectBiomePhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectBiomePhase());
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new NewBattlePhase());
|
||||
globalScene.phaseManager.pushPhase(new NewBattlePhase());
|
||||
}
|
||||
}
|
||||
|
||||
@ -6382,7 +6380,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
getSwitchOutCondition(): MoveConditionFunc {
|
||||
return (user, target, move) => {
|
||||
const switchOutTarget = (this.selfSwitch ? user : target);
|
||||
const player = switchOutTarget instanceof PlayerPokemon;
|
||||
const player = switchOutTarget.isPlayer();
|
||||
const forceSwitchAttr = move.getAttrs(ForceSwitchOutAttr).find(attr => attr.switchType === SwitchType.FORCE_SWITCH);
|
||||
|
||||
if (!this.selfSwitch) {
|
||||
@ -6527,7 +6525,7 @@ export class CopyTypeAttr extends MoveEffectAttr {
|
||||
user.summonData.types = targetTypes;
|
||||
user.updateInfo();
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copyType", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:copyType", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6558,7 +6556,7 @@ export class CopyBiomeTypeAttr extends MoveEffectAttr {
|
||||
user.summonData.types = [ typeChange ];
|
||||
user.updateInfo();
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), typeName: i18next.t(`pokemonInfo:Type.${PokemonType[typeChange]}`) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), typeName: i18next.t(`pokemonInfo:Type.${PokemonType[typeChange]}`) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6663,7 +6661,7 @@ export class ChangeTypeAttr extends MoveEffectAttr {
|
||||
target.summonData.types = [ this.type ];
|
||||
target.updateInfo();
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:transformedIntoType", { pokemonName: getPokemonNameWithAffix(target), typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:transformedIntoType", { pokemonName: getPokemonNameWithAffix(target), typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6686,7 +6684,7 @@ export class AddTypeAttr extends MoveEffectAttr {
|
||||
target.summonData.addedType = this.type;
|
||||
target.updateInfo();
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:addType", { typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`), pokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:addType", { typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`), pokemonName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6708,7 +6706,7 @@ export class FirstMoveTypeAttr extends MoveEffectAttr {
|
||||
|
||||
const firstMoveType = target.getMoveset()[0].getMove().type;
|
||||
user.summonData.types = [ firstMoveType ];
|
||||
globalScene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${PokemonType[firstMoveType]}`) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${PokemonType[firstMoveType]}`) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6727,7 +6725,7 @@ class CallMoveAttr extends OverrideMoveEffectAttr {
|
||||
const replaceMoveTarget = move.moveTarget === MoveTarget.NEAR_OTHER ? MoveTarget.NEAR_ENEMY : undefined;
|
||||
const moveTargets = getMoveTargets(user, move.id, replaceMoveTarget);
|
||||
if (moveTargets.targets.length === 0) {
|
||||
globalScene.queueMessage(i18next.t("battle:attackFailed"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:attackFailed"));
|
||||
console.log("CallMoveAttr failed due to no targets.");
|
||||
return false;
|
||||
}
|
||||
@ -6735,8 +6733,8 @@ class CallMoveAttr extends OverrideMoveEffectAttr {
|
||||
? moveTargets.targets
|
||||
: [ this.hasTarget ? target.getBattlerIndex() : moveTargets.targets[user.randBattleSeedInt(moveTargets.targets.length)] ]; // account for Mirror Move having a target already
|
||||
user.getMoveQueue().push({ move: move.id, targets: targets, virtual: true, ignorePP: true });
|
||||
globalScene.unshiftPhase(new LoadMoveAnimPhase(move.id));
|
||||
globalScene.unshiftPhase(new MovePhase(user, targets, new PokemonMove(move.id, 0, 0, true), true, true));
|
||||
globalScene.phaseManager.unshiftPhase(new LoadMoveAnimPhase(move.id));
|
||||
globalScene.phaseManager.unshiftPhase(new MovePhase(user, targets, new PokemonMove(move.id, 0, 0, true), true, true));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -6964,8 +6962,8 @@ export class NaturePowerAttr extends OverrideMoveEffectAttr {
|
||||
}
|
||||
|
||||
user.getMoveQueue().push({ move: moveId, targets: [ target.getBattlerIndex() ], ignorePP: true });
|
||||
globalScene.unshiftPhase(new LoadMoveAnimPhase(moveId));
|
||||
globalScene.unshiftPhase(new MovePhase(user, [ target.getBattlerIndex() ], new PokemonMove(moveId, 0, 0, true), true));
|
||||
globalScene.phaseManager.unshiftPhase(new LoadMoveAnimPhase(moveId));
|
||||
globalScene.phaseManager.unshiftPhase(new MovePhase(user, [ target.getBattlerIndex() ], new PokemonMove(moveId, 0, 0, true), true));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -7046,13 +7044,13 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
||||
}
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:instructingMove", {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:instructingMove", {
|
||||
userPokemonName: getPokemonNameWithAffix(user),
|
||||
targetPokemonName: getPokemonNameWithAffix(target)
|
||||
}));
|
||||
target.getMoveQueue().unshift({ move: lastMove.move, targets: moveTargets, ignorePP: false });
|
||||
target.turnData.extraTurns++;
|
||||
globalScene.appendToPhase(new MovePhase(target, moveTargets, movesetMove), MoveEndPhase);
|
||||
globalScene.phaseManager.appendToPhase(new MovePhase(target, moveTargets, movesetMove), MoveEndPhase);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7167,7 +7165,7 @@ export class ReducePpMoveAttr extends MoveEffectAttr {
|
||||
|
||||
const message = i18next.t("battle:ppReduced", { targetName: getPokemonNameWithAffix(target), moveName: movesetMove.getName(), reduction: (movesetMove.ppUsed) - lastPpUsed });
|
||||
globalScene.eventTarget.dispatchEvent(new MoveUsedEvent(target.id, movesetMove.getMove(), movesetMove.ppUsed));
|
||||
globalScene.queueMessage(message);
|
||||
globalScene.phaseManager.queueMessage(message);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -7278,7 +7276,7 @@ export class MovesetCopyMoveAttr extends OverrideMoveEffectAttr {
|
||||
user.summonData.moveset = user.getMoveset().slice(0);
|
||||
user.summonData.moveset[thisMoveIndex] = new PokemonMove(copiedMove.id, 0, 0);
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copiedMove", { pokemonName: getPokemonNameWithAffix(user), moveName: copiedMove.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:copiedMove", { pokemonName: getPokemonNameWithAffix(user), moveName: copiedMove.name }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -7328,7 +7326,7 @@ export class SketchAttr extends MoveEffectAttr {
|
||||
|
||||
user.setMove(sketchIndex, sketchedMove.id);
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:sketchedMove", { pokemonName: getPokemonNameWithAffix(user), moveName: sketchedMove.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:sketchedMove", { pokemonName: getPokemonNameWithAffix(user), moveName: sketchedMove.name }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -7383,9 +7381,9 @@ export class AbilityChangeAttr extends MoveEffectAttr {
|
||||
|
||||
globalScene.triggerPokemonFormChange(moveTarget, SpeciesFormChangeRevertWeatherFormTrigger);
|
||||
if (moveTarget.breakIllusion()) {
|
||||
globalScene.queueMessage(i18next.t("abilityTriggers:illusionBreak", { pokemonName: getPokemonNameWithAffix(moveTarget) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("abilityTriggers:illusionBreak", { pokemonName: getPokemonNameWithAffix(moveTarget) }));
|
||||
}
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:acquiredAbility", { pokemonName: getPokemonNameWithAffix(moveTarget), abilityName: allAbilities[this.ability].name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:acquiredAbility", { pokemonName: getPokemonNameWithAffix(moveTarget), abilityName: allAbilities[this.ability].name }));
|
||||
moveTarget.setTempAbility(allAbilities[this.ability]);
|
||||
globalScene.triggerPokemonFormChange(moveTarget, SpeciesFormChangeRevertWeatherFormTrigger);
|
||||
return true;
|
||||
@ -7410,13 +7408,13 @@ export class AbilityCopyAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
|
||||
user.setTempAbility(target.getAbility());
|
||||
const ally = user.getAlly();
|
||||
|
||||
if (this.copyToPartner && globalScene.currentBattle?.double && !isNullOrUndefined(ally) && ally.hp) { // TODO is this the best way to check that the ally is active?
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(ally), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(ally), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
ally.setTempAbility(target.getAbility());
|
||||
}
|
||||
|
||||
@ -7449,7 +7447,7 @@ export class AbilityGiveAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:acquiredAbility", { pokemonName: getPokemonNameWithAffix(target), abilityName: allAbilities[user.getAbility().id].name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:acquiredAbility", { pokemonName: getPokemonNameWithAffix(target), abilityName: allAbilities[user.getAbility().id].name }));
|
||||
|
||||
target.setTempAbility(user.getAbility());
|
||||
|
||||
@ -7469,7 +7467,7 @@ export class SwitchAbilitiesAttr extends MoveEffectAttr {
|
||||
|
||||
const tempAbility = user.getAbility();
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:swappedAbilitiesWithTarget", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:swappedAbilitiesWithTarget", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
|
||||
user.setTempAbility(target.getAbility());
|
||||
target.setTempAbility(tempAbility);
|
||||
@ -7499,7 +7497,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:suppressAbilities", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:suppressAbilities", { pokemonName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
target.suppressAbility();
|
||||
|
||||
@ -7552,9 +7550,9 @@ export class TransformAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.unshiftPhase(new PokemonTransformPhase(user.getBattlerIndex(), target.getBattlerIndex()));
|
||||
globalScene.phaseManager.unshiftPhase(new PokemonTransformPhase(user.getBattlerIndex(), target.getBattlerIndex()));
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -7591,7 +7589,7 @@ export class SwapStatAttr extends MoveEffectAttr {
|
||||
user.setStat(this.stat, target.getStat(this.stat, false), false);
|
||||
target.setStat(this.stat, temp, false);
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:switchedStat", {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:switchedStat", {
|
||||
pokemonName: getPokemonNameWithAffix(user),
|
||||
stat: i18next.t(getStatKey(this.stat)),
|
||||
}));
|
||||
@ -7637,7 +7635,7 @@ export class ShiftStatAttr extends MoveEffectAttr {
|
||||
user.setStat(this.statToSwitch, secondStat, false);
|
||||
user.setStat(this.statToSwitchWith, firstStat, false);
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:shiftedStats", {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:shiftedStats", {
|
||||
pokemonName: getPokemonNameWithAffix(user),
|
||||
statToSwitch: i18next.t(getStatKey(this.statToSwitch)),
|
||||
statToSwitchWith: i18next.t(getStatKey(this.statToSwitchWith))
|
||||
@ -7696,7 +7694,7 @@ export class AverageStatsAttr extends MoveEffectAttr {
|
||||
target.setStat(s, avg, false);
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t(this.msgKey, { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t(this.msgKey, { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -7711,7 +7709,7 @@ export class MoneyAttr extends MoveEffectAttr {
|
||||
|
||||
apply(user: Pokemon, target: Pokemon, move: Move): boolean {
|
||||
globalScene.currentBattle.moneyScattered += globalScene.getWaveMoneyAmount(0.2);
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:coinsScatteredEverywhere"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:coinsScatteredEverywhere"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -7735,7 +7733,7 @@ export class DestinyBondAttr extends MoveEffectAttr {
|
||||
* @returns true
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
globalScene.queueMessage(`${i18next.t("moveTriggers:tryingToTakeFoeDown", { pokemonName: getPokemonNameWithAffix(user) })}`);
|
||||
globalScene.phaseManager.queueMessage(`${i18next.t("moveTriggers:tryingToTakeFoeDown", { pokemonName: getPokemonNameWithAffix(user) })}`);
|
||||
user.addTag(BattlerTagType.DESTINY_BOND, undefined, move.id, user.id);
|
||||
return true;
|
||||
}
|
||||
@ -7849,12 +7847,12 @@ export class AfterYouAttr extends MoveEffectAttr {
|
||||
* @returns true
|
||||
*/
|
||||
override apply(user: Pokemon, target: Pokemon, _move: Move, _args: any[]): boolean {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:afterYou", { targetName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:afterYou", { targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
//Will find next acting phase of the targeted pokémon, delete it and queue it next on successful delete.
|
||||
const nextAttackPhase = globalScene.findPhase<MovePhase>((phase) => phase.pokemon === target);
|
||||
if (nextAttackPhase && globalScene.tryRemovePhase((phase: MovePhase) => phase.pokemon === target)) {
|
||||
globalScene.prependToPhase(new MovePhase(target, [ ...nextAttackPhase.targets ], nextAttackPhase.move), MovePhase);
|
||||
const nextAttackPhase = globalScene.phaseManager.findPhase<MovePhase>((phase) => phase.pokemon === target);
|
||||
if (nextAttackPhase && globalScene.phaseManager.tryRemovePhase((phase: MovePhase) => phase.pokemon === target)) {
|
||||
globalScene.phaseManager.prependToPhase(new MovePhase(target, [ ...nextAttackPhase.targets ], nextAttackPhase.move), MovePhase);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -7877,19 +7875,19 @@ export class ForceLastAttr extends MoveEffectAttr {
|
||||
* @returns true
|
||||
*/
|
||||
override apply(user: Pokemon, target: Pokemon, _move: Move, _args: any[]): boolean {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:forceLast", { targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:forceLast", { targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
const targetMovePhase = globalScene.findPhase<MovePhase>((phase) => phase.pokemon === target);
|
||||
if (targetMovePhase && !targetMovePhase.isForcedLast() && globalScene.tryRemovePhase((phase: MovePhase) => phase.pokemon === target)) {
|
||||
const targetMovePhase = globalScene.phaseManager.findPhase<MovePhase>((phase) => phase.pokemon === target);
|
||||
if (targetMovePhase && !targetMovePhase.isForcedLast() && globalScene.phaseManager.tryRemovePhase((phase: MovePhase) => phase.pokemon === target)) {
|
||||
// Finding the phase to insert the move in front of -
|
||||
// Either the end of the turn or in front of another, slower move which has also been forced last
|
||||
const prependPhase = globalScene.findPhase((phase) =>
|
||||
const prependPhase = globalScene.phaseManager.findPhase((phase) =>
|
||||
[ MovePhase, MoveEndPhase ].every(cls => !(phase instanceof cls))
|
||||
|| (phase.is("MovePhase")) && phaseForcedSlower(phase, target, !!globalScene.arena.getTag(ArenaTagType.TRICK_ROOM))
|
||||
);
|
||||
if (prependPhase) {
|
||||
globalScene.phaseQueue.splice(
|
||||
globalScene.phaseQueue.indexOf(prependPhase),
|
||||
globalScene.phaseManager.phaseQueue.splice(
|
||||
globalScene.phaseManager.phaseQueue.indexOf(prependPhase),
|
||||
0,
|
||||
new MovePhase(target, [ ...targetMovePhase.targets ], targetMovePhase.move, false, false, false, true)
|
||||
);
|
||||
@ -7922,7 +7920,7 @@ const failIfDampCondition: MoveConditionFunc = (user, target, move) => {
|
||||
globalScene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled));
|
||||
// Queue a message if an ability prevented usage of the move
|
||||
if (cancelled.value) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:cannotUseMove", { pokemonName: getPokemonNameWithAffix(user), moveName: move.name }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:cannotUseMove", { pokemonName: getPokemonNameWithAffix(user), moveName: move.name }));
|
||||
}
|
||||
return !cancelled.value;
|
||||
};
|
||||
@ -7931,7 +7929,7 @@ const userSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target:
|
||||
|
||||
const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(AbilityId.COMATOSE);
|
||||
|
||||
const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => globalScene.phaseQueue.find(phase => phase.is("MovePhase")) !== undefined;
|
||||
const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => globalScene.phaseManager.phaseQueue.find(phase => phase.is("MovePhase")) !== undefined;
|
||||
|
||||
const failIfLastInPartyCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => {
|
||||
const party: Pokemon[] = user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty();
|
||||
@ -8109,7 +8107,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr {
|
||||
}
|
||||
const type = validTypes[user.randBattleSeedInt(validTypes.length)];
|
||||
user.summonData.types = [ type ];
|
||||
globalScene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: toReadableString(PokemonType[type]) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: toReadableString(PokemonType[type]) }));
|
||||
user.updateInfo();
|
||||
|
||||
return true;
|
||||
@ -8168,7 +8166,7 @@ export class ExposedMoveAttr extends AddBattlerTagAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:exposedMove", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:exposedMove", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -8804,7 +8802,7 @@ export function initMoves() {
|
||||
.reflectable(),
|
||||
new SelfStatusMove(MoveId.BELLY_DRUM, PokemonType.NORMAL, -1, 10, -1, 0, 2)
|
||||
.attr(CutHpStatStageBoostAttr, [ Stat.ATK ], 12, 2, (user) => {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:cutOwnHpAndMaximizedStat", { pokemonName: getPokemonNameWithAffix(user), statName: i18next.t(getStatKey(Stat.ATK)) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:cutOwnHpAndMaximizedStat", { pokemonName: getPokemonNameWithAffix(user), statName: i18next.t(getStatKey(Stat.ATK)) }));
|
||||
}),
|
||||
new AttackMove(MoveId.SLUDGE_BOMB, PokemonType.POISON, MoveCategory.SPECIAL, 90, 100, 10, 30, 0, 2)
|
||||
.attr(StatusEffectAttr, StatusEffect.POISON)
|
||||
@ -9857,7 +9855,7 @@ export function initMoves() {
|
||||
const lastEnemyFaint = globalScene.currentBattle.enemyFaintsHistory[globalScene.currentBattle.enemyFaintsHistory.length - 1];
|
||||
return (
|
||||
(lastPlayerFaint !== undefined && turn - lastPlayerFaint.turn === 1 && user.isPlayer()) ||
|
||||
(lastEnemyFaint !== undefined && turn - lastEnemyFaint.turn === 1 && !user.isPlayer())
|
||||
(lastEnemyFaint !== undefined && turn - lastEnemyFaint.turn === 1 && user.isEnemy())
|
||||
) ? 2 : 1;
|
||||
}),
|
||||
new AttackMove(MoveId.FINAL_GAMBIT, PokemonType.FIGHTING, MoveCategory.SPECIAL, -1, 100, 5, -1, 0, 5)
|
||||
@ -10372,7 +10370,7 @@ export function initMoves() {
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false)
|
||||
.attr(RemoveTypeAttr, PokemonType.FIRE, (user) => {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:burnedItselfOut", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:burnedItselfOut", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
}),
|
||||
new StatusMove(MoveId.SPEED_SWAP, PokemonType.PSYCHIC, -1, 10, -1, 0, 7)
|
||||
.attr(SwapStatAttr, Stat.SPD)
|
||||
@ -11156,7 +11154,7 @@ export function initMoves() {
|
||||
})
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.DOUBLE_SHOCKED, true, false)
|
||||
.attr(RemoveTypeAttr, PokemonType.ELECTRIC, (user) => {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
}),
|
||||
new AttackMove(MoveId.GIGATON_HAMMER, PokemonType.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, -1, 0, 9)
|
||||
.makesContact(false)
|
||||
|
@ -182,7 +182,7 @@ export const ATrainersTestEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
async () => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
// Full heal party
|
||||
globalScene.unshiftPhase(new PartyHealPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new PartyHealPhase(true));
|
||||
|
||||
const eggOptions: IEggOptions = {
|
||||
pulled: false,
|
||||
|
@ -33,7 +33,7 @@ import {
|
||||
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import type { BerryType } from "#enums/berry-type";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { Stat } from "#enums/stat";
|
||||
@ -237,7 +237,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1),
|
||||
);
|
||||
},
|
||||
|
@ -137,7 +137,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = MysteryEncounterB
|
||||
})
|
||||
.withOptionPhase(async () => {
|
||||
// Give the player a Shiny Charm
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.SHINY_CHARM));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.SHINY_CHARM));
|
||||
leaveEncounterWithoutBattle(true);
|
||||
})
|
||||
.build(),
|
||||
|
@ -237,7 +237,7 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
config.pokemonConfigs![0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON];
|
||||
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.2.boss_enraged`);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1),
|
||||
);
|
||||
};
|
||||
|
@ -766,7 +766,7 @@ function doBugTypeMoveTutor(): Promise<void> {
|
||||
|
||||
// Option select complete, handle if they are learning a move
|
||||
if (result && result.selectedOptionIndex < moveOptions.length) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new LearnMovePhase(result.selectedPokemonIndex, moveOptions[result.selectedOptionIndex].moveId),
|
||||
);
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
true,
|
||||
@ -245,7 +245,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
|
||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new LearnMovePhase(globalScene.getPlayerParty().indexOf(pokemon), MoveId.REVELATION_DANCE),
|
||||
);
|
||||
|
||||
|
@ -165,7 +165,7 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE
|
||||
.withOptionPhase(async () => {
|
||||
// Give the player 5 Rogue Balls
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.ROGUE_BALL));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.ROGUE_BALL));
|
||||
|
||||
// Start encounter with random legendary (7-10 starter strength) that has level additive
|
||||
// If this is a mono-type challenge, always ensure the required type is filtered for
|
||||
|
@ -65,10 +65,10 @@ const doEventReward = () => {
|
||||
return !(existingCharm && existingCharm.getStackCount() >= existingCharm.getMaxStackCount());
|
||||
});
|
||||
if (candidates.length > 0) {
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes[randSeedItem(candidates)]));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes[randSeedItem(candidates)]));
|
||||
} else {
|
||||
// At max stacks, give a Voucher instead
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.VOUCHER));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.VOUCHER));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -181,7 +181,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
);
|
||||
doEventReward();
|
||||
} else {
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.AMULET_COIN));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.AMULET_COIN));
|
||||
doEventReward();
|
||||
}
|
||||
|
||||
@ -266,7 +266,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
);
|
||||
doEventReward();
|
||||
} else {
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.CANDY_JAR));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.CANDY_JAR));
|
||||
doEventReward();
|
||||
}
|
||||
} else {
|
||||
@ -288,7 +288,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
);
|
||||
doEventReward();
|
||||
} else {
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.BERRY_POUCH));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.BERRY_POUCH));
|
||||
doEventReward();
|
||||
}
|
||||
}
|
||||
@ -372,7 +372,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
);
|
||||
doEventReward();
|
||||
} else {
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.HEALING_CHARM));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierTypes.HEALING_CHARM));
|
||||
doEventReward();
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
|
||||
gender: Gender.MALE,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.SPDEF, Stat.SPD], 1),
|
||||
);
|
||||
},
|
||||
@ -103,7 +103,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
|
||||
gender: Gender.FEMALE,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.SPDEF, Stat.SPD], 1),
|
||||
);
|
||||
},
|
||||
|
@ -76,7 +76,9 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
queueEncounterMessage(`${namespace}:option.1.stat_boost`);
|
||||
// Randomly boost 1 stat 2 stages
|
||||
// Cannot boost Spd, Acc, or Evasion
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [randSeedInt(4, 1)], 2));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [randSeedInt(4, 1)], 2),
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -411,13 +411,13 @@ function summonPlayerPokemonAnimation(pokemon: PlayerPokemon): Promise<void> {
|
||||
pokemon.resetSummonData();
|
||||
globalScene.time.delayedCall(1000, () => {
|
||||
if (pokemon.isShiny()) {
|
||||
globalScene.unshiftPhase(new ShinySparklePhase(pokemon.getBattlerIndex()));
|
||||
globalScene.phaseManager.unshiftPhase(new ShinySparklePhase(pokemon.getBattlerIndex()));
|
||||
}
|
||||
|
||||
pokemon.resetTurnData();
|
||||
|
||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
|
||||
globalScene.pushPhase(new PostSummonPhase(pokemon.getBattlerIndex()));
|
||||
globalScene.phaseManager.pushPhase(new PostSummonPhase(pokemon.getBattlerIndex()));
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
|
@ -189,8 +189,8 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
const allowedPokemon = globalScene.getPokemonAllowedInBattle();
|
||||
if (allowedPokemon.length === 0) {
|
||||
// If there are no longer any legal pokemon in the party, game over.
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
} else {
|
||||
// Show which Pokemon was KOed, then start battle against Gimmighoul
|
||||
await transitionMysteryEncounterIntroVisuals(true, true, 500);
|
||||
|
@ -276,7 +276,7 @@ async function summonSafariPokemon() {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
// Message pokemon remaining
|
||||
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
|
||||
globalScene.queueMessage(getEncounterText(`${namespace}:safari.remaining_count`) ?? "", null, true);
|
||||
globalScene.phaseManager.queueMessage(getEncounterText(`${namespace}:safari.remaining_count`) ?? "", null, true);
|
||||
|
||||
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
||||
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
||||
@ -325,7 +325,7 @@ async function summonSafariPokemon() {
|
||||
encounter.misc.pokemon = pokemon;
|
||||
encounter.misc.safariPokemonRemaining -= 1;
|
||||
|
||||
globalScene.unshiftPhase(new SummonPhase(0, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(0, false));
|
||||
|
||||
encounter.setDialogueToken("pokemonName", getPokemonNameWithAffix(pokemon));
|
||||
|
||||
@ -336,7 +336,7 @@ async function summonSafariPokemon() {
|
||||
|
||||
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
|
||||
if (ivScannerModifier) {
|
||||
globalScene.pushPhase(new ScanIvsPhase(pokemon.getBattlerIndex()));
|
||||
globalScene.phaseManager.pushPhase(new ScanIvsPhase(pokemon.getBattlerIndex()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,7 +559,7 @@ async function doEndTurn(cursorIndex: number) {
|
||||
leaveEncounterWithoutBattle(true);
|
||||
}
|
||||
} else {
|
||||
globalScene.queueMessage(getEncounterText(`${namespace}:safari.watching`) ?? "", 0, null, 1000);
|
||||
globalScene.phaseManager.queueMessage(getEncounterText(`${namespace}:safari.watching`) ?? "", 0, null, 1000);
|
||||
initSubsequentOptionSelect({
|
||||
overrideOptions: safariZoneGameOptions,
|
||||
startingCursorIndex: cursorIndex,
|
||||
|
@ -155,7 +155,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
async () => {
|
||||
// Fall asleep waiting for Snorlax
|
||||
// Full heal party
|
||||
globalScene.unshiftPhase(new PartyHealPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new PartyHealPhase(true));
|
||||
queueEncounterMessage(`${namespace}:option.2.rest_result`);
|
||||
leaveEncounterWithoutBattle();
|
||||
},
|
||||
|
@ -227,7 +227,9 @@ async function doBiomeTransitionDialogueAndBattleInit() {
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:boss_enraged`);
|
||||
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1),
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -658,8 +658,8 @@ function onGameOver() {
|
||||
globalScene.playBgm(globalScene.arena.bgm);
|
||||
|
||||
// Clear any leftover battle phases
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.clearPhaseQueueSplice();
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueueSplice();
|
||||
|
||||
// Return enemy Pokemon
|
||||
const pokemon = globalScene.getEnemyPokemon();
|
||||
|
@ -116,7 +116,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.2.stat_boost`);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.DEF, Stat.SPDEF], 1),
|
||||
);
|
||||
},
|
||||
|
@ -143,7 +143,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = MysteryEncounter
|
||||
},
|
||||
async () => {
|
||||
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
|
||||
globalScene.unshiftPhase(new PartyHealPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new PartyHealPhase(true));
|
||||
setEncounterRewards({
|
||||
guaranteedModifierTypeFuncs: [modifierTypes.RARER_CANDY],
|
||||
fillRemaining: false,
|
||||
@ -209,7 +209,7 @@ function endTrainerBattleAndShowDialogue(): Promise<void> {
|
||||
for (const pokemon of playerField) {
|
||||
pokemon.lapseTag(BattlerTagType.COMMANDED);
|
||||
}
|
||||
playerField.forEach((_, p) => globalScene.unshiftPhase(new ReturnPhase(p)));
|
||||
playerField.forEach((_, p) => globalScene.phaseManager.unshiftPhase(new ReturnPhase(p)));
|
||||
|
||||
for (const pokemon of globalScene.getPlayerParty()) {
|
||||
// Only trigger form change when Eiscue is in Noice form
|
||||
@ -227,7 +227,7 @@ function endTrainerBattleAndShowDialogue(): Promise<void> {
|
||||
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon);
|
||||
}
|
||||
|
||||
globalScene.unshiftPhase(new ShowTrainerPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new ShowTrainerPhase());
|
||||
// Hide the trainer and init next battle
|
||||
const trainer = globalScene.currentBattle.trainer;
|
||||
// Unassign previous trainer from battle so it isn't destroyed before animation completes
|
||||
|
@ -25,7 +25,7 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
|
||||
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import i18next from "i18next";
|
||||
import { getStatKey } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||
|
@ -103,7 +103,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.stat_boost`);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1),
|
||||
);
|
||||
},
|
||||
|
@ -39,7 +39,7 @@ import { PlayerGender } from "#enums/player-gender";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { Nature } from "#enums/nature";
|
||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
|
@ -51,7 +51,7 @@ function getTextWithDialogueTokens(keyOrString: string): string | null {
|
||||
*/
|
||||
export function queueEncounterMessage(contentKey: string): void {
|
||||
const text: string | null = getEncounterText(contentKey);
|
||||
globalScene.queueMessage(text ?? "", null, true);
|
||||
globalScene.phaseManager.queueMessage(text ?? "", null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,7 @@ import type PokemonSpecies from "#app/data/pokemon-species";
|
||||
import type { IEggOptions } from "#app/data/egg";
|
||||
import { Egg } from "#app/data/egg";
|
||||
import type { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import { MovePhase } from "#app/phases/move-phase";
|
||||
import { EggLapsePhase } from "#app/phases/egg-lapse-phase";
|
||||
import { TrainerVictoryPhase } from "#app/phases/trainer-victory-phase";
|
||||
@ -428,7 +428,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
|
||||
console.log("Moveset:", moveset);
|
||||
});
|
||||
|
||||
globalScene.pushPhase(new MysteryEncounterBattlePhase(partyConfig.disableSwitch));
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterBattlePhase(partyConfig.disableSwitch));
|
||||
|
||||
await Promise.all(loadEnemyAssets);
|
||||
battle.enemyParty.forEach((enemyPokemon_2, e_1) => {
|
||||
@ -480,7 +480,7 @@ export function updatePlayerMoney(changeValue: number, playSound = true, showMes
|
||||
}
|
||||
if (showMessage) {
|
||||
if (changeValue < 0) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("mysteryEncounterMessages:paid_money", {
|
||||
amount: -changeValue,
|
||||
}),
|
||||
@ -488,7 +488,7 @@ export function updatePlayerMoney(changeValue: number, playSound = true, showMes
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("mysteryEncounterMessages:receive_money", {
|
||||
amount: changeValue,
|
||||
}),
|
||||
@ -767,9 +767,9 @@ export function setEncounterRewards(
|
||||
}
|
||||
|
||||
if (customShopRewards) {
|
||||
globalScene.unshiftPhase(new SelectModifierPhase(0, undefined, customShopRewards));
|
||||
globalScene.phaseManager.unshiftPhase(new SelectModifierPhase(0, undefined, customShopRewards));
|
||||
} else {
|
||||
globalScene.tryRemovePhase(p => p.is("MysteryEncounterRewardsPhase"));
|
||||
globalScene.phaseManager.tryRemovePhase(p => p.is("MysteryEncounterRewardsPhase"));
|
||||
}
|
||||
|
||||
if (eggRewards) {
|
||||
@ -807,7 +807,7 @@ export function setEncounterExp(participantId: number | number[], baseExpValue:
|
||||
const participantIds = Array.isArray(participantId) ? participantId : [participantId];
|
||||
|
||||
globalScene.currentBattle.mysteryEncounter!.doEncounterExp = () => {
|
||||
globalScene.unshiftPhase(new PartyExpPhase(baseExpValue, useWaveIndex, new Set(participantIds)));
|
||||
globalScene.phaseManager.unshiftPhase(new PartyExpPhase(baseExpValue, useWaveIndex, new Set(participantIds)));
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -829,7 +829,7 @@ export class OptionSelectSettings {
|
||||
* @param optionSelectSettings
|
||||
*/
|
||||
export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSettings) {
|
||||
globalScene.pushPhase(new MysteryEncounterPhase(optionSelectSettings));
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterPhase(optionSelectSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -843,8 +843,8 @@ export function leaveEncounterWithoutBattle(
|
||||
encounterMode: MysteryEncounterMode = MysteryEncounterMode.NO_BATTLE,
|
||||
) {
|
||||
globalScene.currentBattle.mysteryEncounter!.encounterMode = encounterMode;
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.clearPhaseQueueSplice();
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueueSplice();
|
||||
handleMysteryEncounterVictory(addHealPhase);
|
||||
}
|
||||
|
||||
@ -857,8 +857,8 @@ export function handleMysteryEncounterVictory(addHealPhase = false, doNotContinu
|
||||
const allowedPkm = globalScene.getPlayerParty().filter(pkm => pkm.isAllowedInBattle());
|
||||
|
||||
if (allowedPkm.length === 0) {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -869,8 +869,8 @@ export function handleMysteryEncounterVictory(addHealPhase = false, doNotContinu
|
||||
return;
|
||||
}
|
||||
if (encounter.encounterMode === MysteryEncounterMode.NO_BATTLE) {
|
||||
globalScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
|
||||
globalScene.pushPhase(new EggLapsePhase());
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
|
||||
globalScene.phaseManager.pushPhase(new EggLapsePhase());
|
||||
} else if (
|
||||
!globalScene
|
||||
.getEnemyParty()
|
||||
@ -878,15 +878,15 @@ export function handleMysteryEncounterVictory(addHealPhase = false, doNotContinu
|
||||
encounter.encounterMode !== MysteryEncounterMode.TRAINER_BATTLE ? p.isOnField() : !p?.isFainted(true),
|
||||
)
|
||||
) {
|
||||
globalScene.pushPhase(new BattleEndPhase(true));
|
||||
globalScene.phaseManager.pushPhase(new BattleEndPhase(true));
|
||||
if (encounter.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||
globalScene.pushPhase(new TrainerVictoryPhase());
|
||||
globalScene.phaseManager.pushPhase(new TrainerVictoryPhase());
|
||||
}
|
||||
if (globalScene.gameMode.isEndless || !globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) {
|
||||
globalScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
|
||||
if (!encounter.doContinueEncounter) {
|
||||
// Only lapse eggs once for multi-battle encounters
|
||||
globalScene.pushPhase(new EggLapsePhase());
|
||||
globalScene.phaseManager.pushPhase(new EggLapsePhase());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -900,8 +900,8 @@ export function handleMysteryEncounterBattleFailed(addHealPhase = false, doNotCo
|
||||
const allowedPkm = globalScene.getPlayerParty().filter(pkm => pkm.isAllowedInBattle());
|
||||
|
||||
if (allowedPkm.length === 0) {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -912,14 +912,14 @@ export function handleMysteryEncounterBattleFailed(addHealPhase = false, doNotCo
|
||||
return;
|
||||
}
|
||||
if (encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE) {
|
||||
globalScene.pushPhase(new BattleEndPhase(false));
|
||||
globalScene.phaseManager.pushPhase(new BattleEndPhase(false));
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
|
||||
|
||||
if (!encounter.doContinueEncounter) {
|
||||
// Only lapse eggs once for multi-battle encounters
|
||||
globalScene.pushPhase(new EggLapsePhase());
|
||||
globalScene.phaseManager.pushPhase(new EggLapsePhase());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1004,12 +1004,14 @@ export function handleMysteryEncounterBattleStartEffects() {
|
||||
} else {
|
||||
source = globalScene.getEnemyField()[0];
|
||||
}
|
||||
globalScene.phaseManager.pushPhase(
|
||||
// @ts-ignore: source cannot be undefined
|
||||
globalScene.pushPhase(new MovePhase(source, effect.targets, effect.move, effect.followUp, effect.ignorePp));
|
||||
new MovePhase(source, effect.targets, effect.move, effect.followUp, effect.ignorePp),
|
||||
);
|
||||
});
|
||||
|
||||
// Pseudo turn end phase to reset flinch states, Endure, etc.
|
||||
globalScene.pushPhase(new MysteryEncounterBattleStartCleanupPhase());
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterBattleStartCleanupPhase());
|
||||
|
||||
encounter.startOfBattleEffectsComplete = true;
|
||||
}
|
||||
|
@ -675,7 +675,7 @@ export async function catchPokemon(
|
||||
if (!globalScene.getEnemyParty().some(p => p.id === pokemon.id)) {
|
||||
globalScene.getEnemyParty().push(pokemon);
|
||||
}
|
||||
globalScene.unshiftPhase(new VictoryPhase(pokemon.id, true));
|
||||
globalScene.phaseManager.unshiftPhase(new VictoryPhase(pokemon.id, true));
|
||||
globalScene.pokemonInfoContainer.hide();
|
||||
if (pokeball) {
|
||||
removePb(pokeball);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Localizable } from "#app/interfaces/locales";
|
||||
import type { Localizable } from "#app/@types/locales";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
@ -2022,9 +2022,9 @@ export function initSpecies() {
|
||||
new PokemonForm("Normal", "", PokemonType.GROUND, null, 3.5, 950, AbilityId.DROUGHT, AbilityId.NONE, AbilityId.NONE, 670, 100, 150, 140, 100, 90, 90, 3, 0, 335, false, null, true),
|
||||
new PokemonForm("Primal", "primal", PokemonType.GROUND, PokemonType.FIRE, 5, 999.7, AbilityId.DESOLATE_LAND, AbilityId.NONE, AbilityId.NONE, 770, 100, 180, 160, 150, 90, 90, 3, 0, 335),
|
||||
),
|
||||
new PokemonSpecies(SpeciesId.RAYQUAZA, 3, false, true, false, "Sky High Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 45, 0, 340, GrowthRate.SLOW, null, false, true,
|
||||
new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 45, 0, 340, false, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FLYING, 10.8, 392, AbilityId.DELTA_STREAM, AbilityId.NONE, AbilityId.NONE, 780, 105, 180, 100, 180, 100, 115, 45, 0, 340),
|
||||
new PokemonSpecies(SpeciesId.RAYQUAZA, 3, false, true, false, "Sky High Pokémon", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 3, 0, 340, GrowthRate.SLOW, null, false, true,
|
||||
new PokemonForm("Normal", "", PokemonType.DRAGON, PokemonType.FLYING, 7, 206.5, AbilityId.AIR_LOCK, AbilityId.NONE, AbilityId.NONE, 680, 105, 150, 90, 150, 90, 95, 3, 0, 340, false, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.DRAGON, PokemonType.FLYING, 10.8, 392, AbilityId.DELTA_STREAM, AbilityId.NONE, AbilityId.NONE, 780, 105, 180, 100, 180, 100, 115, 3, 0, 340),
|
||||
),
|
||||
new PokemonSpecies(SpeciesId.JIRACHI, 3, false, false, true, "Wish Pokémon", PokemonType.STEEL, PokemonType.PSYCHIC, 0.3, 1.1, AbilityId.SERENE_GRACE, AbilityId.NONE, AbilityId.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.DEOXYS, 3, false, false, true, "DNA Pokémon", PokemonType.PSYCHIC, null, 1.7, 60.8, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 600, 50, 150, 50, 150, 50, 150, 3, 0, 300, GrowthRate.SLOW, null, false, true,
|
||||
@ -2270,10 +2270,10 @@ export function initSpecies() {
|
||||
new PokemonSpecies(SpeciesId.WHIMSICOTT, 5, false, false, false, "Windveiled Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 0.7, 6.6, AbilityId.PRANKSTER, AbilityId.INFILTRATOR, AbilityId.CHLOROPHYLL, 480, 60, 67, 85, 77, 75, 116, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.PETILIL, 5, false, false, false, "Bulb Pokémon", PokemonType.GRASS, null, 0.5, 6.6, AbilityId.CHLOROPHYLL, AbilityId.OWN_TEMPO, AbilityId.LEAF_GUARD, 280, 45, 35, 50, 70, 50, 30, 190, 50, 56, GrowthRate.MEDIUM_FAST, 0, false),
|
||||
new PokemonSpecies(SpeciesId.LILLIGANT, 5, false, false, false, "Flowering Pokémon", PokemonType.GRASS, null, 1.1, 16.3, AbilityId.CHLOROPHYLL, AbilityId.OWN_TEMPO, AbilityId.LEAF_GUARD, 480, 70, 60, 75, 110, 75, 90, 75, 50, 168, GrowthRate.MEDIUM_FAST, 0, false),
|
||||
new PokemonSpecies(SpeciesId.BASCULIN, 5, false, false, false, "Hostile Pokémon", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 25, 50, 161, GrowthRate.MEDIUM_FAST, 50, false, false,
|
||||
new PokemonForm("Red-Striped Form", "red-striped", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 25, 50, 161, false, null, true),
|
||||
new PokemonForm("Blue-Striped Form", "blue-striped", PokemonType.WATER, null, 1, 18, AbilityId.ROCK_HEAD, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 25, 50, 161, false, null, true),
|
||||
new PokemonForm("White-Striped Form", "white-striped", PokemonType.WATER, null, 1, 18, AbilityId.RATTLED, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 25, 50, 161, false, null, true),
|
||||
new PokemonSpecies(SpeciesId.BASCULIN, 5, false, false, false, "Hostile Pokémon", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, GrowthRate.MEDIUM_FAST, 50, false, false,
|
||||
new PokemonForm("Red-Striped Form", "red-striped", PokemonType.WATER, null, 1, 18, AbilityId.RECKLESS, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true),
|
||||
new PokemonForm("Blue-Striped Form", "blue-striped", PokemonType.WATER, null, 1, 18, AbilityId.ROCK_HEAD, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true),
|
||||
new PokemonForm("White-Striped Form", "white-striped", PokemonType.WATER, null, 1, 18, AbilityId.RATTLED, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 460, 70, 92, 65, 80, 55, 98, 190, 50, 161, false, null, true),
|
||||
),
|
||||
new PokemonSpecies(SpeciesId.SANDILE, 5, false, false, false, "Desert Croc Pokémon", PokemonType.GROUND, PokemonType.DARK, 0.7, 15.2, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 292, 50, 72, 35, 35, 35, 65, 180, 50, 58, GrowthRate.MEDIUM_SLOW, 50, false),
|
||||
new PokemonSpecies(SpeciesId.KROKOROK, 5, false, false, false, "Desert Croc Pokémon", PokemonType.GROUND, PokemonType.DARK, 1, 33.4, AbilityId.INTIMIDATE, AbilityId.MOXIE, AbilityId.ANGER_POINT, 351, 60, 82, 45, 45, 45, 74, 90, 50, 123, GrowthRate.MEDIUM_SLOW, 50, false),
|
||||
@ -2740,10 +2740,10 @@ export function initSpecies() {
|
||||
new PokemonSpecies(SpeciesId.TAPU_LELE, 7, true, false, false, "Land Spirit Pokémon", PokemonType.PSYCHIC, PokemonType.FAIRY, 1.2, 18.6, AbilityId.PSYCHIC_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 85, 75, 130, 115, 95, 3, 50, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.TAPU_BULU, 7, true, false, false, "Land Spirit Pokémon", PokemonType.GRASS, PokemonType.FAIRY, 1.9, 45.5, AbilityId.GRASSY_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 130, 115, 85, 95, 75, 3, 50, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.TAPU_FINI, 7, true, false, false, "Land Spirit Pokémon", PokemonType.WATER, PokemonType.FAIRY, 1.3, 21.2, AbilityId.MISTY_SURGE, AbilityId.NONE, AbilityId.TELEPATHY, 570, 70, 75, 115, 95, 130, 85, 3, 50, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.COSMOG, 7, true, false, false, "Nebula Pokémon", PokemonType.PSYCHIC, null, 0.2, 0.1, AbilityId.UNAWARE, AbilityId.NONE, AbilityId.NONE, 200, 43, 29, 31, 29, 31, 37, 45, 0, 40, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.COSMOEM, 7, true, false, false, "Protostar Pokémon", PokemonType.PSYCHIC, null, 0.1, 999.9, AbilityId.STURDY, AbilityId.NONE, AbilityId.NONE, 400, 43, 29, 131, 29, 131, 37, 45, 0, 140, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.SOLGALEO, 7, false, true, false, "Sunne Pokémon", PokemonType.PSYCHIC, PokemonType.STEEL, 3.4, 230, AbilityId.FULL_METAL_BODY, AbilityId.NONE, AbilityId.NONE, 680, 137, 137, 107, 113, 89, 97, 45, 0, 340, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.LUNALA, 7, false, true, false, "Moone Pokémon", PokemonType.PSYCHIC, PokemonType.GHOST, 4, 120, AbilityId.SHADOW_SHIELD, AbilityId.NONE, AbilityId.NONE, 680, 137, 113, 89, 137, 107, 97, 45, 0, 340, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.COSMOG, 7, true, false, false, "Nebula Pokémon", PokemonType.PSYCHIC, null, 0.2, 0.1, AbilityId.UNAWARE, AbilityId.NONE, AbilityId.NONE, 200, 43, 29, 31, 29, 31, 37, 3, 0, 40, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.COSMOEM, 7, true, false, false, "Protostar Pokémon", PokemonType.PSYCHIC, null, 0.1, 999.9, AbilityId.STURDY, AbilityId.NONE, AbilityId.NONE, 400, 43, 29, 131, 29, 131, 37, 3, 0, 140, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.SOLGALEO, 7, false, true, false, "Sunne Pokémon", PokemonType.PSYCHIC, PokemonType.STEEL, 3.4, 230, AbilityId.FULL_METAL_BODY, AbilityId.NONE, AbilityId.NONE, 680, 137, 137, 107, 113, 89, 97, 3, 0, 340, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.LUNALA, 7, false, true, false, "Moone Pokémon", PokemonType.PSYCHIC, PokemonType.GHOST, 4, 120, AbilityId.SHADOW_SHIELD, AbilityId.NONE, AbilityId.NONE, 680, 137, 113, 89, 137, 107, 97, 3, 0, 340, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.NIHILEGO, 7, true, false, false, "Parasite Pokémon", PokemonType.ROCK, PokemonType.POISON, 1.2, 55.5, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 109, 53, 47, 127, 131, 103, 45, 0, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.BUZZWOLE, 7, true, false, false, "Swollen Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 2.4, 333.6, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 107, 139, 139, 53, 53, 79, 45, 0, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.PHEROMOSA, 7, true, false, false, "Lissome Pokémon", PokemonType.BUG, PokemonType.FIGHTING, 1.8, 25, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 71, 137, 37, 137, 37, 151, 45, 0, 285, GrowthRate.SLOW, null, false),
|
||||
@ -2751,11 +2751,11 @@ export function initSpecies() {
|
||||
new PokemonSpecies(SpeciesId.CELESTEELA, 7, true, false, false, "Launch Pokémon", PokemonType.STEEL, PokemonType.FLYING, 9.2, 999.9, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 97, 101, 103, 107, 101, 61, 45, 0, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.KARTANA, 7, true, false, false, "Drawn Sword Pokémon", PokemonType.GRASS, PokemonType.STEEL, 0.3, 0.1, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 59, 181, 131, 59, 31, 109, 45, 0, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.GUZZLORD, 7, true, false, false, "Junkivore Pokémon", PokemonType.DARK, PokemonType.DRAGON, 5.5, 888, AbilityId.BEAST_BOOST, AbilityId.NONE, AbilityId.NONE, 570, 223, 101, 53, 97, 53, 43, 45, 0, 285, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(SpeciesId.NECROZMA, 7, false, true, false, "Prism Pokémon", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 255, 0, 300, GrowthRate.SLOW, null, false, false,
|
||||
new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 255, 0, 300, false, null, true),
|
||||
new PokemonForm("Dusk Mane", "dusk-mane", PokemonType.PSYCHIC, PokemonType.STEEL, 3.8, 460, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 157, 127, 113, 109, 77, 255, 0, 340),
|
||||
new PokemonForm("Dawn Wings", "dawn-wings", PokemonType.PSYCHIC, PokemonType.GHOST, 4.2, 350, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 113, 109, 157, 127, 77, 255, 0, 340),
|
||||
new PokemonForm("Ultra", "ultra", PokemonType.PSYCHIC, PokemonType.DRAGON, 7.5, 230, AbilityId.NEUROFORCE, AbilityId.NONE, AbilityId.NONE, 754, 97, 167, 97, 167, 97, 129, 255, 0, 377),
|
||||
new PokemonSpecies(SpeciesId.NECROZMA, 7, false, true, false, "Prism Pokémon", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 3, 0, 300, GrowthRate.SLOW, null, false, false,
|
||||
new PokemonForm("Normal", "", PokemonType.PSYCHIC, null, 2.4, 230, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 600, 97, 107, 101, 127, 89, 79, 3, 0, 300, false, null, true),
|
||||
new PokemonForm("Dusk Mane", "dusk-mane", PokemonType.PSYCHIC, PokemonType.STEEL, 3.8, 460, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 157, 127, 113, 109, 77, 3, 0, 340),
|
||||
new PokemonForm("Dawn Wings", "dawn-wings", PokemonType.PSYCHIC, PokemonType.GHOST, 4.2, 350, AbilityId.PRISM_ARMOR, AbilityId.NONE, AbilityId.NONE, 680, 97, 113, 109, 157, 127, 77, 3, 0, 340),
|
||||
new PokemonForm("Ultra", "ultra", PokemonType.PSYCHIC, PokemonType.DRAGON, 7.5, 230, AbilityId.NEUROFORCE, AbilityId.NONE, AbilityId.NONE, 754, 97, 167, 97, 167, 97, 129, 3, 0, 377),
|
||||
),
|
||||
new PokemonSpecies(SpeciesId.MAGEARNA, 7, false, false, true, "Artificial Pokémon", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, GrowthRate.SLOW, null, false, false,
|
||||
new PokemonForm("Normal", "", PokemonType.STEEL, PokemonType.FAIRY, 1, 80.5, AbilityId.SOUL_HEART, AbilityId.NONE, AbilityId.NONE, 600, 80, 95, 115, 130, 115, 65, 3, 0, 300, false, null, true),
|
||||
@ -2964,15 +2964,15 @@ export function initSpecies() {
|
||||
new PokemonForm("Ice", "ice", PokemonType.PSYCHIC, PokemonType.ICE, 2.4, 809.1, AbilityId.AS_ONE_GLASTRIER, AbilityId.NONE, AbilityId.NONE, 680, 100, 165, 150, 85, 130, 50, 3, 100, 340),
|
||||
new PokemonForm("Shadow", "shadow", PokemonType.PSYCHIC, PokemonType.GHOST, 2.4, 53.6, AbilityId.AS_ONE_SPECTRIER, AbilityId.NONE, AbilityId.NONE, 680, 100, 85, 80, 165, 100, 150, 3, 100, 340),
|
||||
),
|
||||
new PokemonSpecies(SpeciesId.WYRDEER, 8, false, false, false, "Big Horn Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.8, 95.1, AbilityId.INTIMIDATE, AbilityId.FRISK, AbilityId.SAP_SIPPER, 525, 103, 105, 72, 105, 75, 65, 135, 50, 263, GrowthRate.SLOW, 50, false),
|
||||
new PokemonSpecies(SpeciesId.KLEAVOR, 8, false, false, false, "Axe Pokémon", PokemonType.BUG, PokemonType.ROCK, 1.8, 89, AbilityId.SWARM, AbilityId.SHEER_FORCE, AbilityId.SHARPNESS, 500, 70, 135, 95, 45, 70, 85, 115, 50, 175, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.URSALUNA, 8, false, false, false, "Peat Pokémon", PokemonType.GROUND, PokemonType.NORMAL, 2.4, 290, AbilityId.GUTS, AbilityId.BULLETPROOF, AbilityId.UNNERVE, 550, 130, 140, 105, 45, 80, 50, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.BASCULEGION, 8, false, false, false, "Big Fish Pokémon", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 135, 50, 265, GrowthRate.MEDIUM_FAST, 50, false, false,
|
||||
new PokemonForm("Male", "male", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 135, 50, 265, false, "", true),
|
||||
new PokemonForm("Female", "female", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 92, 65, 100, 75, 78, 135, 50, 265, false, null, true),
|
||||
new PokemonSpecies(SpeciesId.WYRDEER, 8, false, false, false, "Big Horn Pokémon", PokemonType.NORMAL, PokemonType.PSYCHIC, 1.8, 95.1, AbilityId.INTIMIDATE, AbilityId.FRISK, AbilityId.SAP_SIPPER, 525, 103, 105, 72, 105, 75, 65, 45, 50, 263, GrowthRate.SLOW, 50, false),
|
||||
new PokemonSpecies(SpeciesId.KLEAVOR, 8, false, false, false, "Axe Pokémon", PokemonType.BUG, PokemonType.ROCK, 1.8, 89, AbilityId.SWARM, AbilityId.SHEER_FORCE, AbilityId.SHARPNESS, 500, 70, 135, 95, 45, 70, 85, 15, 50, 175, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.URSALUNA, 8, false, false, false, "Peat Pokémon", PokemonType.GROUND, PokemonType.NORMAL, 2.4, 290, AbilityId.GUTS, AbilityId.BULLETPROOF, AbilityId.UNNERVE, 550, 130, 140, 105, 45, 80, 50, 20, 50, 275, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.BASCULEGION, 8, false, false, false, "Big Fish Pokémon", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 45, 50, 265, GrowthRate.MEDIUM_FAST, 50, false, false,
|
||||
new PokemonForm("Male", "male", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 112, 65, 80, 75, 78, 45, 50, 265, false, "", true),
|
||||
new PokemonForm("Female", "female", PokemonType.WATER, PokemonType.GHOST, 3, 110, AbilityId.SWIFT_SWIM, AbilityId.ADAPTABILITY, AbilityId.MOLD_BREAKER, 530, 120, 92, 65, 100, 75, 78, 45, 50, 265, false, null, true),
|
||||
),
|
||||
new PokemonSpecies(SpeciesId.SNEASLER, 8, false, false, false, "Free Climb Pokémon", PokemonType.FIGHTING, PokemonType.POISON, 1.3, 43, AbilityId.PRESSURE, AbilityId.UNBURDEN, AbilityId.POISON_TOUCH, 510, 80, 130, 60, 40, 80, 120, 135, 50, 102, GrowthRate.MEDIUM_SLOW, 50, false),
|
||||
new PokemonSpecies(SpeciesId.OVERQWIL, 8, false, false, false, "Pin Cluster Pokémon", PokemonType.DARK, PokemonType.POISON, 2.5, 60.5, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 510, 85, 115, 95, 65, 65, 85, 135, 50, 179, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.SNEASLER, 8, false, false, false, "Free Climb Pokémon", PokemonType.FIGHTING, PokemonType.POISON, 1.3, 43, AbilityId.PRESSURE, AbilityId.UNBURDEN, AbilityId.POISON_TOUCH, 510, 80, 130, 60, 40, 80, 120, 20, 50, 102, GrowthRate.MEDIUM_SLOW, 50, false),
|
||||
new PokemonSpecies(SpeciesId.OVERQWIL, 8, false, false, false, "Pin Cluster Pokémon", PokemonType.DARK, PokemonType.POISON, 2.5, 60.5, AbilityId.POISON_POINT, AbilityId.SWIFT_SWIM, AbilityId.INTIMIDATE, 510, 85, 115, 95, 65, 65, 85, 45, 50, 179, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(SpeciesId.ENAMORUS, 8, true, false, false, "Love-Hate Pokémon", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.CONTRARY, 580, 74, 115, 70, 135, 80, 106, 3, 50, 116, GrowthRate.SLOW, 0, false, true,
|
||||
new PokemonForm("Incarnate Forme", "incarnate", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.CUTE_CHARM, AbilityId.NONE, AbilityId.CONTRARY, 580, 74, 115, 70, 135, 80, 106, 3, 50, 116, false, null, true),
|
||||
new PokemonForm("Therian Forme", "therian", PokemonType.FAIRY, PokemonType.FLYING, 1.6, 48, AbilityId.OVERCOAT, AbilityId.NONE, AbilityId.OVERCOAT, 580, 74, 115, 110, 135, 100, 46, 3, 50, 116),
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { TrainerTierPools } from "#app/data/trainers/typedefs";
|
||||
import type { TrainerTierPools } from "#app/@types/trainer-funcs";
|
||||
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
|
||||
|
@ -48,7 +48,7 @@ import type {
|
||||
TrainerTierPools,
|
||||
TrainerConfigs,
|
||||
PartyMemberFuncs,
|
||||
} from "./typedefs";
|
||||
} from "../../@types/trainer-funcs";
|
||||
|
||||
/** Minimum BST for Pokemon generated onto the Elite Four's teams */
|
||||
const ELITE_FOUR_MINIMUM_BST = 460;
|
||||
|
17
src/debug.js
17
src/debug.js
@ -1,17 +0,0 @@
|
||||
export function getData() {
|
||||
const dataStr = localStorage.getItem("data");
|
||||
if (!dataStr) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(atob(dataStr), (k, v) =>
|
||||
k.endsWith("Attr") && !["natureAttr", "abilityAttr", "passiveAttr"].includes(k) ? BigInt(v) : v,
|
||||
);
|
||||
}
|
||||
|
||||
export function getSession() {
|
||||
const sessionStr = localStorage.getItem("sessionData");
|
||||
if (!sessionStr) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(atob(sessionStr));
|
||||
}
|
@ -297,8 +297,8 @@ export class Arena {
|
||||
*/
|
||||
trySetWeatherOverride(weather: WeatherType): boolean {
|
||||
this.weather = new Weather(weather, 0);
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
|
||||
globalScene.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
|
||||
globalScene.phaseManager.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
|
||||
globalScene.phaseManager.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -328,10 +328,10 @@ export class Arena {
|
||||
this.weather?.isImmutable() &&
|
||||
![WeatherType.HARSH_SUN, WeatherType.HEAVY_RAIN, WeatherType.STRONG_WINDS, WeatherType.NONE].includes(weather)
|
||||
) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (oldWeatherType - 1), true),
|
||||
);
|
||||
globalScene.queueMessage(getLegendaryWeatherContinuesMessage(oldWeatherType)!);
|
||||
globalScene.phaseManager.queueMessage(getLegendaryWeatherContinuesMessage(oldWeatherType)!);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -348,10 +348,12 @@ export class Arena {
|
||||
); // TODO: is this bang correct?
|
||||
|
||||
if (this.weather) {
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1), true));
|
||||
globalScene.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1), true),
|
||||
);
|
||||
globalScene.phaseManager.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
|
||||
} else {
|
||||
globalScene.queueMessage(getWeatherClearMessage(oldWeatherType)!); // TODO: is this bang correct?
|
||||
globalScene.phaseManager.queueMessage(getWeatherClearMessage(oldWeatherType)!); // TODO: is this bang correct?
|
||||
}
|
||||
|
||||
globalScene
|
||||
@ -431,11 +433,13 @@ export class Arena {
|
||||
|
||||
if (this.terrain) {
|
||||
if (!ignoreAnim) {
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)),
|
||||
);
|
||||
}
|
||||
globalScene.queueMessage(getTerrainStartMessage(terrain)!); // TODO: is this bang correct?
|
||||
globalScene.phaseManager.queueMessage(getTerrainStartMessage(terrain)!); // TODO: is this bang correct?
|
||||
} else {
|
||||
globalScene.queueMessage(getTerrainClearMessage(oldTerrainType)!); // TODO: is this bang correct?
|
||||
globalScene.phaseManager.queueMessage(getTerrainClearMessage(oldTerrainType)!); // TODO: is this bang correct?
|
||||
}
|
||||
|
||||
globalScene
|
||||
|
@ -503,7 +503,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
if (level > 1) {
|
||||
const fused = new BooleanHolder(globalScene.gameMode.isSplicedOnly);
|
||||
if (!fused.value && !this.isPlayer() && !this.hasTrainer()) {
|
||||
if (!fused.value && this.isEnemy() && !this.hasTrainer()) {
|
||||
globalScene.applyModifier(EnemyFusionChanceModifier, false, fused);
|
||||
}
|
||||
|
||||
@ -788,7 +788,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract isPlayer(): boolean;
|
||||
abstract isPlayer(): this is PlayerPokemon;
|
||||
|
||||
abstract isEnemy(): this is EnemyPokemon;
|
||||
|
||||
abstract hasTrainer(): boolean;
|
||||
|
||||
@ -1296,7 +1298,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return false;
|
||||
}
|
||||
// During the Pokemon's MoveEffect phase, the offset is removed to put the Pokemon "in focus"
|
||||
const currentPhase = globalScene.getCurrentPhase();
|
||||
const currentPhase = globalScene.phaseManager.getCurrentPhase();
|
||||
return !(currentPhase?.is("MoveEffectPhase") && currentPhase.getPokemon() === this);
|
||||
}
|
||||
|
||||
@ -2050,7 +2052,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (Overrides.ABILITY_OVERRIDE && this.isPlayer()) {
|
||||
return allAbilities[Overrides.ABILITY_OVERRIDE];
|
||||
}
|
||||
if (Overrides.OPP_ABILITY_OVERRIDE && !this.isPlayer()) {
|
||||
if (Overrides.OPP_ABILITY_OVERRIDE && this.isEnemy()) {
|
||||
return allAbilities[Overrides.OPP_ABILITY_OVERRIDE];
|
||||
}
|
||||
if (this.isFusion()) {
|
||||
@ -2080,7 +2082,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (Overrides.PASSIVE_ABILITY_OVERRIDE && this.isPlayer()) {
|
||||
return allAbilities[Overrides.PASSIVE_ABILITY_OVERRIDE];
|
||||
}
|
||||
if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer()) {
|
||||
if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && this.isEnemy()) {
|
||||
return allAbilities[Overrides.OPP_PASSIVE_ABILITY_OVERRIDE];
|
||||
}
|
||||
if (!isNullOrUndefined(this.customPokemonData.passive) && this.customPokemonData.passive !== -1) {
|
||||
@ -2152,7 +2154,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
// returns override if valid for current case
|
||||
if (
|
||||
(Overrides.HAS_PASSIVE_ABILITY_OVERRIDE === false && this.isPlayer()) ||
|
||||
(Overrides.OPP_HAS_PASSIVE_ABILITY_OVERRIDE === false && !this.isPlayer())
|
||||
(Overrides.OPP_HAS_PASSIVE_ABILITY_OVERRIDE === false && this.isEnemy())
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -2160,7 +2162,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
((Overrides.PASSIVE_ABILITY_OVERRIDE !== AbilityId.NONE || Overrides.HAS_PASSIVE_ABILITY_OVERRIDE) &&
|
||||
this.isPlayer()) ||
|
||||
((Overrides.OPP_PASSIVE_ABILITY_OVERRIDE !== AbilityId.NONE || Overrides.OPP_HAS_PASSIVE_ABILITY_OVERRIDE) &&
|
||||
!this.isPlayer())
|
||||
this.isEnemy())
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -2169,7 +2171,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const { currentBattle, gameMode } = globalScene;
|
||||
const waveIndex = currentBattle?.waveIndex;
|
||||
if (
|
||||
this instanceof EnemyPokemon &&
|
||||
this.isEnemy() &&
|
||||
(currentBattle?.battleSpec === BattleSpec.FINAL_BOSS ||
|
||||
gameMode.isEndlessMinorBoss(waveIndex) ||
|
||||
gameMode.isEndlessMajorBoss(waveIndex))
|
||||
@ -2535,7 +2537,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
) {
|
||||
multiplier /= 2;
|
||||
if (!simulated) {
|
||||
globalScene.queueMessage(i18next.t("weather:strongWindsEffectMessage"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("weather:strongWindsEffectMessage"));
|
||||
}
|
||||
}
|
||||
return multiplier as TypeDamageMultiplier;
|
||||
@ -2979,9 +2981,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
let fusionOverride: PokemonSpecies | undefined = undefined;
|
||||
|
||||
if (forStarter && this instanceof PlayerPokemon && Overrides.STARTER_FUSION_SPECIES_OVERRIDE) {
|
||||
if (forStarter && this.isPlayer() && Overrides.STARTER_FUSION_SPECIES_OVERRIDE) {
|
||||
fusionOverride = getPokemonSpecies(Overrides.STARTER_FUSION_SPECIES_OVERRIDE);
|
||||
} else if (this instanceof EnemyPokemon && Overrides.OPP_FUSION_SPECIES_OVERRIDE) {
|
||||
} else if (this.isEnemy() && Overrides.OPP_FUSION_SPECIES_OVERRIDE) {
|
||||
fusionOverride = getPokemonSpecies(Overrides.OPP_FUSION_SPECIES_OVERRIDE);
|
||||
}
|
||||
|
||||
@ -3292,7 +3294,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.battleInfo.setX(this.battleInfo.x + (this.isPlayer() ? 150 : !this.isBoss() ? -150 : -198));
|
||||
this.battleInfo.setVisible(true);
|
||||
if (this.isPlayer()) {
|
||||
this.battleInfo.expMaskRect.x += 150;
|
||||
// TODO: How do you get this to not require a private property access?
|
||||
this["battleInfo"].expMaskRect.x += 150;
|
||||
}
|
||||
globalScene.tweens.add({
|
||||
targets: [this.battleInfo, this.battleInfo.expMaskRect],
|
||||
@ -3313,7 +3316,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
ease: "Cubic.easeIn",
|
||||
onComplete: () => {
|
||||
if (this.isPlayer()) {
|
||||
this.battleInfo.expMaskRect.x -= 150;
|
||||
// TODO: How do you get this to not require a private property access?
|
||||
this["battleInfo"].expMaskRect.x -= 150;
|
||||
}
|
||||
this.battleInfo.setVisible(false);
|
||||
this.battleInfo.setX(this.battleInfo.x - (this.isPlayer() ? 150 : !this.isBoss() ? -150 : -198));
|
||||
@ -3408,7 +3412,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @returns An array of Pokémon on the allied field.
|
||||
*/
|
||||
getAlliedField(): Pokemon[] {
|
||||
return this instanceof PlayerPokemon ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
return this.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4007,8 +4011,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
*
|
||||
* Once the MoveEffectPhase is over (and calls it's .end() function, shiftPhase() will reset the PhaseQueueSplice via clearPhaseQueueSplice() )
|
||||
*/
|
||||
globalScene.setPhaseQueueSplice();
|
||||
globalScene.unshiftPhase(new FaintPhase(this.getBattlerIndex(), preventEndure));
|
||||
globalScene.phaseManager.setPhaseQueueSplice();
|
||||
globalScene.phaseManager.unshiftPhase(new FaintPhase(this.getBattlerIndex(), preventEndure));
|
||||
this.destroySubstitute();
|
||||
this.lapseTag(BattlerTagType.COMMANDED);
|
||||
}
|
||||
@ -4045,7 +4049,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
): number {
|
||||
const isIndirectDamage = [HitResult.INDIRECT, HitResult.INDIRECT_KO].includes(result);
|
||||
const damagePhase = new DamageAnimPhase(this.getBattlerIndex(), damage, result as DamageResult, isCritical);
|
||||
globalScene.unshiftPhase(damagePhase);
|
||||
globalScene.phaseManager.unshiftPhase(damagePhase);
|
||||
if (this.switchOutStatus && source) {
|
||||
damage = 0;
|
||||
}
|
||||
@ -4260,7 +4264,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
// Copy all stat stages
|
||||
for (const s of BATTLE_STATS) {
|
||||
const sourceStage = source.getStatStage(s);
|
||||
if (this instanceof PlayerPokemon && sourceStage === 6) {
|
||||
if (this.isPlayer() && sourceStage === 6) {
|
||||
globalScene.validateAchv(achvs.TRANSFER_MAX_STAT_STAGE);
|
||||
}
|
||||
this.setStatStage(s, sourceStage);
|
||||
@ -4611,7 +4615,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
: i18next.t("abilityTriggers:moveImmunity", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(this),
|
||||
});
|
||||
globalScene.queueMessage(message);
|
||||
globalScene.phaseManager.queueMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4731,7 +4735,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
if (sourcePokemon && sourcePokemon !== this && this.isSafeguarded(sourcePokemon)) {
|
||||
if (!quiet) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(this) }));
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(this) }),
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -4760,7 +4766,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* cancel the attack's subsequent hits.
|
||||
*/
|
||||
if (effect === StatusEffect.SLEEP || effect === StatusEffect.FREEZE) {
|
||||
const currentPhase = globalScene.getCurrentPhase();
|
||||
const currentPhase = globalScene.phaseManager.getCurrentPhase();
|
||||
if (currentPhase?.is("MoveEffectPhase") && currentPhase.getUserPokemon() === this) {
|
||||
this.turnData.hitCount = 1;
|
||||
this.turnData.hitsLeft = 1;
|
||||
@ -4771,7 +4777,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (overrideStatus) {
|
||||
this.resetStatus(false);
|
||||
}
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new ObtainStatusEffectPhase(this.getBattlerIndex(), effect, turnsRemaining, sourceText, sourcePokemon),
|
||||
);
|
||||
return true;
|
||||
@ -4821,7 +4827,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
if (asPhase) {
|
||||
globalScene.unshiftPhase(new ResetStatusPhase(this, confusion, reloadAssets));
|
||||
globalScene.phaseManager.unshiftPhase(new ResetStatusPhase(this, confusion, reloadAssets));
|
||||
} else {
|
||||
this.clearStatus(confusion, reloadAssets);
|
||||
}
|
||||
@ -5468,7 +5474,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
heldItem.stackCount--;
|
||||
if (heldItem.stackCount <= 0) {
|
||||
globalScene.removeModifier(heldItem, !this.isPlayer());
|
||||
globalScene.removeModifier(heldItem, this.isEnemy());
|
||||
}
|
||||
if (forBattle) {
|
||||
applyPostItemLostAbAttrs(PostItemLostAbAttr, this, false);
|
||||
@ -5541,15 +5547,19 @@ export class PlayerPokemon extends Pokemon {
|
||||
this.battleInfo.initInfo(this);
|
||||
}
|
||||
|
||||
isPlayer(): boolean {
|
||||
override isPlayer(): this is PlayerPokemon {
|
||||
return true;
|
||||
}
|
||||
|
||||
hasTrainer(): boolean {
|
||||
override isEnemy(): this is EnemyPokemon {
|
||||
return false;
|
||||
}
|
||||
|
||||
override hasTrainer(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
isBoss(): boolean {
|
||||
override isBoss(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5624,7 +5634,7 @@ export class PlayerPokemon extends Pokemon {
|
||||
this.getFieldIndex(),
|
||||
(slotIndex: number, _option: PartyOption) => {
|
||||
if (slotIndex >= globalScene.currentBattle.getBattlerCount() && slotIndex < 6) {
|
||||
globalScene.prependToPhase(
|
||||
globalScene.phaseManager.prependToPhase(
|
||||
new SwitchSummonPhase(switchType, this.getFieldIndex(), slotIndex, false),
|
||||
MoveEndPhase,
|
||||
);
|
||||
@ -5989,7 +5999,9 @@ export class PlayerPokemon extends Pokemon {
|
||||
const newPartyMemberIndex = globalScene.getPlayerParty().indexOf(this);
|
||||
pokemon
|
||||
.getMoveset(true)
|
||||
.map((m: PokemonMove) => globalScene.unshiftPhase(new LearnMovePhase(newPartyMemberIndex, m.getMove().id)));
|
||||
.map((m: PokemonMove) =>
|
||||
globalScene.phaseManager.unshiftPhase(new LearnMovePhase(newPartyMemberIndex, m.getMove().id)),
|
||||
);
|
||||
pokemon.destroy();
|
||||
this.updateFusionPalette();
|
||||
}
|
||||
@ -6494,15 +6506,19 @@ export class EnemyPokemon extends Pokemon {
|
||||
return [sortedBenefitScores[targetIndex][0]];
|
||||
}
|
||||
|
||||
isPlayer() {
|
||||
override isPlayer(): this is PlayerPokemon {
|
||||
return false;
|
||||
}
|
||||
|
||||
hasTrainer(): boolean {
|
||||
override isEnemy(): this is EnemyPokemon {
|
||||
return true;
|
||||
}
|
||||
|
||||
override hasTrainer(): boolean {
|
||||
return !!this.trainerSlot;
|
||||
}
|
||||
|
||||
isBoss(): boolean {
|
||||
override isBoss(): boolean {
|
||||
return !!this.bossSegments;
|
||||
}
|
||||
|
||||
@ -6627,7 +6643,7 @@ export class EnemyPokemon extends Pokemon {
|
||||
stages++;
|
||||
}
|
||||
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(this.getBattlerIndex(), true, [boostedStat!], stages, true, true),
|
||||
);
|
||||
this.bossSegmentIndex--;
|
||||
|
@ -1,4 +1,3 @@
|
||||
export const starterColors: StarterColors = {};
|
||||
interface StarterColors {
|
||||
export const starterColors: {
|
||||
[key: string]: [string, string];
|
||||
}
|
||||
} = {};
|
||||
|
@ -16,7 +16,7 @@ export function getPokemonNameWithAffix(pokemon: Pokemon | undefined, useIllusio
|
||||
|
||||
switch (globalScene.currentBattle.battleSpec) {
|
||||
case BattleSpec.DEFAULT:
|
||||
return !pokemon.isPlayer()
|
||||
return pokemon.isEnemy()
|
||||
? pokemon.hasTrainer()
|
||||
? i18next.t("battle:foePokemonWithAffix", {
|
||||
pokemonName: pokemon.getNameToRender(useIllusion),
|
||||
@ -26,7 +26,7 @@ export function getPokemonNameWithAffix(pokemon: Pokemon | undefined, useIllusio
|
||||
})
|
||||
: pokemon.getNameToRender(useIllusion);
|
||||
case BattleSpec.FINAL_BOSS:
|
||||
return !pokemon.isPlayer()
|
||||
return pokemon.isEnemy()
|
||||
? i18next.t("battle:foePokemonWithAffix", { pokemonName: pokemon.getNameToRender(useIllusion) })
|
||||
: pokemon.getNameToRender(useIllusion);
|
||||
default:
|
||||
|
@ -1548,7 +1548,7 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier {
|
||||
if (!surviveDamage.value && pokemon.randBattleSeedInt(10) < this.getStackCount()) {
|
||||
surviveDamage.value = true;
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("modifier:surviveDamageApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
typeName: this.type.name,
|
||||
@ -1598,7 +1598,7 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
|
||||
const hasQuickClaw = this.type instanceof PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW";
|
||||
|
||||
if (isCommandFight && hasQuickClaw) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("modifier:bypassSpeedChanceApply", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
itemName: i18next.t("modifierType:ModifierType.QUICK_CLAW.name"),
|
||||
@ -1684,7 +1684,7 @@ export class TurnHealModifier extends PokemonHeldItemModifier {
|
||||
*/
|
||||
override apply(pokemon: Pokemon): boolean {
|
||||
if (!pokemon.isFullHp()) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 16) * this.stackCount,
|
||||
@ -1782,7 +1782,7 @@ export class HitHealModifier extends PokemonHeldItemModifier {
|
||||
override apply(pokemon: Pokemon): boolean {
|
||||
if (pokemon.turnData.totalDamageDealt && !pokemon.isFullHp()) {
|
||||
// TODO: this shouldn't be undefined AFAIK
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.turnData.totalDamageDealt / 8) * this.stackCount,
|
||||
@ -1950,7 +1950,7 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
|
||||
*/
|
||||
override apply(pokemon: Pokemon): boolean {
|
||||
// Restore the Pokemon to half HP
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 2),
|
||||
@ -2012,7 +2012,7 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier {
|
||||
}
|
||||
|
||||
if (statRestored) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("modifier:resetNegativeStatStageApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
typeName: this.type.name,
|
||||
@ -2323,7 +2323,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
|
||||
|
||||
playerPokemon.addFriendship(FRIENDSHIP_GAIN_FROM_RARE_CANDY);
|
||||
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new LevelUpPhase(
|
||||
globalScene.getPlayerParty().indexOf(playerPokemon),
|
||||
playerPokemon.level - levelCount.value,
|
||||
@ -2344,7 +2344,7 @@ export class TmModifier extends ConsumablePokemonModifier {
|
||||
* @returns always `true`
|
||||
*/
|
||||
override apply(playerPokemon: PlayerPokemon): boolean {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new LearnMovePhase(globalScene.getPlayerParty().indexOf(playerPokemon), this.type.moveId, LearnMoveType.TM),
|
||||
);
|
||||
|
||||
@ -2367,7 +2367,7 @@ export class RememberMoveModifier extends ConsumablePokemonModifier {
|
||||
* @returns always `true`
|
||||
*/
|
||||
override apply(playerPokemon: PlayerPokemon, cost?: number): boolean {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new LearnMovePhase(
|
||||
globalScene.getPlayerParty().indexOf(playerPokemon),
|
||||
playerPokemon.getLearnableLevelMoves()[this.levelMoveIndex],
|
||||
@ -2410,7 +2410,9 @@ export class EvolutionItemModifier extends ConsumablePokemonModifier {
|
||||
}
|
||||
|
||||
if (matchingEvolution) {
|
||||
globalScene.unshiftPhase(new EvolutionPhase(playerPokemon, matchingEvolution, playerPokemon.level - 1));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new EvolutionPhase(playerPokemon, matchingEvolution, playerPokemon.level - 1),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3008,7 +3010,7 @@ export class MoneyInterestModifier extends PersistentModifier {
|
||||
moneyAmount: formattedMoneyAmount,
|
||||
typeName: this.type.name,
|
||||
});
|
||||
globalScene.queueMessage(message, undefined, true);
|
||||
globalScene.phaseManager.queueMessage(message, undefined, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3262,7 +3264,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
||||
}
|
||||
|
||||
for (const mt of transferredModifierTypes) {
|
||||
globalScene.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
|
||||
globalScene.phaseManager.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
|
||||
}
|
||||
|
||||
return !!transferredModifierTypes.length;
|
||||
@ -3572,7 +3574,7 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
|
||||
*/
|
||||
override apply(enemyPokemon: Pokemon): boolean {
|
||||
if (!enemyPokemon.isFullHp()) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
enemyPokemon.getBattlerIndex(),
|
||||
Math.max(Math.floor(enemyPokemon.getMaxHp() / (100 / this.healPercent)) * this.stackCount, 1),
|
||||
@ -3668,7 +3670,7 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier
|
||||
*/
|
||||
override apply(enemyPokemon: Pokemon): boolean {
|
||||
if (enemyPokemon.status && Phaser.Math.RND.realInRange(0, 1) < this.chance * this.getStackCount()) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(enemyPokemon.status.effect, getPokemonNameWithAffix(enemyPokemon)),
|
||||
);
|
||||
enemyPokemon.resetStatus();
|
||||
|
311
src/phase-manager.ts
Normal file
311
src/phase-manager.ts
Normal file
@ -0,0 +1,311 @@
|
||||
import { HideAbilityPhase } from "./phases/hide-ability-phase";
|
||||
import { ShowAbilityPhase } from "./phases/show-ability-phase";
|
||||
import { TurnInitPhase } from "./phases/turn-init-phase";
|
||||
import type { Phase } from "#app/phase";
|
||||
import type { default as Pokemon } from "#app/field/pokemon";
|
||||
import type { Constructor } from "#app/utils/common";
|
||||
import { MessagePhase } from "./phases/message-phase";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
|
||||
/**
|
||||
* Manager for phases used by battle scene.
|
||||
*
|
||||
* *This file must not be imported or used directly. The manager is exclusively used by the battle scene and is not intended for external use.*
|
||||
*/
|
||||
|
||||
export class PhaseManager {
|
||||
/** PhaseQueue: dequeue/remove the first element to get the next phase */
|
||||
public phaseQueue: Phase[] = [];
|
||||
public conditionalQueue: Array<[() => boolean, Phase]> = [];
|
||||
/** PhaseQueuePrepend: is a temp storage of what will be added to PhaseQueue */
|
||||
private phaseQueuePrepend: Phase[] = [];
|
||||
|
||||
/** overrides default of inserting phases to end of phaseQueuePrepend array. Useful for inserting Phases "out of order" */
|
||||
private phaseQueuePrependSpliceIndex = -1;
|
||||
private nextCommandPhaseQueue: Phase[] = [];
|
||||
|
||||
private currentPhase: Phase | null = null;
|
||||
private standbyPhase: Phase | null = null;
|
||||
|
||||
/* Phase Functions */
|
||||
getCurrentPhase(): Phase | null {
|
||||
return this.currentPhase;
|
||||
}
|
||||
|
||||
getStandbyPhase(): Phase | null {
|
||||
return this.standbyPhase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a phase to the conditional queue and ensures it is executed only when the specified condition is met.
|
||||
*
|
||||
* This method allows deferring the execution of a phase until certain conditions are met, which is useful for handling
|
||||
* situations like abilities and entry hazards that depend on specific game states.
|
||||
*
|
||||
* @param phase - The phase to be added to the conditional queue.
|
||||
* @param condition - A function that returns a boolean indicating whether the phase should be executed.
|
||||
*
|
||||
*/
|
||||
pushConditionalPhase(phase: Phase, condition: () => boolean): void {
|
||||
this.conditionalQueue.push([condition, phase]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a phase to nextCommandPhaseQueue, as long as boolean passed in is false
|
||||
* @param phase {@linkcode Phase} the phase to add
|
||||
* @param defer boolean on which queue to add to, defaults to false, and adds to phaseQueue
|
||||
*/
|
||||
pushPhase(phase: Phase, defer = false): void {
|
||||
(!defer ? this.phaseQueue : this.nextCommandPhaseQueue).push(phase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Phase(s) to the end of phaseQueuePrepend, or at phaseQueuePrependSpliceIndex
|
||||
* @param phases {@linkcode Phase} the phase(s) to add
|
||||
*/
|
||||
unshiftPhase(...phases: Phase[]): void {
|
||||
if (this.phaseQueuePrependSpliceIndex === -1) {
|
||||
this.phaseQueuePrepend.push(...phases);
|
||||
} else {
|
||||
this.phaseQueuePrepend.splice(this.phaseQueuePrependSpliceIndex, 0, ...phases);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the phaseQueue
|
||||
*/
|
||||
clearPhaseQueue(): void {
|
||||
this.phaseQueue.splice(0, this.phaseQueue.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all phase-related stuff, including all phase queues, the current and standby phases, and a splice index
|
||||
*/
|
||||
clearAllPhases(): void {
|
||||
for (const queue of [this.phaseQueue, this.phaseQueuePrepend, this.conditionalQueue, this.nextCommandPhaseQueue]) {
|
||||
queue.splice(0, queue.length);
|
||||
}
|
||||
this.currentPhase = null;
|
||||
this.standbyPhase = null;
|
||||
this.clearPhaseQueueSplice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by function unshiftPhase(), sets index to start inserting at current length instead of the end of the array, useful if phaseQueuePrepend gets longer with Phases
|
||||
*/
|
||||
setPhaseQueueSplice(): void {
|
||||
this.phaseQueuePrependSpliceIndex = this.phaseQueuePrepend.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets phaseQueuePrependSpliceIndex to -1, implies that calls to unshiftPhase will insert at end of phaseQueuePrepend
|
||||
*/
|
||||
clearPhaseQueueSplice(): void {
|
||||
this.phaseQueuePrependSpliceIndex = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called by each Phase implementations "end()" by default
|
||||
* We dump everything from phaseQueuePrepend to the start of of phaseQueue
|
||||
* then removes first Phase and starts it
|
||||
*/
|
||||
shiftPhase(): void {
|
||||
if (this.standbyPhase) {
|
||||
this.currentPhase = this.standbyPhase;
|
||||
this.standbyPhase = null;
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this.phaseQueue.length) {
|
||||
this.populatePhaseQueue();
|
||||
// Clear the conditionalQueue if there are no phases left in the phaseQueue
|
||||
this.conditionalQueue = [];
|
||||
}
|
||||
|
||||
this.currentPhase = this.phaseQueue.shift() ?? null;
|
||||
|
||||
// Check if there are any conditional phases queued
|
||||
if (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
|
||||
this.conditionalQueue.unshift(conditionalPhase);
|
||||
} else {
|
||||
console.warn("condition phase is undefined/null!", conditionalPhase);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.currentPhase) {
|
||||
console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;");
|
||||
this.currentPhase.start();
|
||||
}
|
||||
}
|
||||
|
||||
overridePhase(phase: Phase): boolean {
|
||||
if (this.standbyPhase) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.standbyPhase = this.currentPhase;
|
||||
this.currentPhase = phase;
|
||||
console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;");
|
||||
phase.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific {@linkcode Phase} in the phase queue.
|
||||
*
|
||||
* @param phaseFilter filter function to use to find the wanted phase
|
||||
* @returns the found phase or undefined if none found
|
||||
*/
|
||||
findPhase<P extends Phase = Phase>(phaseFilter: (phase: P) => boolean): P | undefined {
|
||||
return this.phaseQueue.find(phaseFilter) as P;
|
||||
}
|
||||
|
||||
tryReplacePhase(phaseFilter: (phase: Phase) => boolean, phase: Phase): boolean {
|
||||
const phaseIndex = this.phaseQueue.findIndex(phaseFilter);
|
||||
if (phaseIndex > -1) {
|
||||
this.phaseQueue[phaseIndex] = phase;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
tryRemovePhase(phaseFilter: (phase: Phase) => boolean): boolean {
|
||||
const phaseIndex = this.phaseQueue.findIndex(phaseFilter);
|
||||
if (phaseIndex > -1) {
|
||||
this.phaseQueue.splice(phaseIndex, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will search for a specific phase in {@linkcode phaseQueuePrepend} via filter, and remove the first result if a match is found.
|
||||
* @param phaseFilter filter function
|
||||
*/
|
||||
tryRemoveUnshiftedPhase(phaseFilter: (phase: Phase) => boolean): boolean {
|
||||
const phaseIndex = this.phaseQueuePrepend.findIndex(phaseFilter);
|
||||
if (phaseIndex > -1) {
|
||||
this.phaseQueuePrepend.splice(phaseIndex, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to add the input phase to index before target phase in the phaseQueue, else simply calls unshiftPhase()
|
||||
* @param phase {@linkcode Phase} the phase to be added
|
||||
* @param targetPhase {@linkcode Phase} the type of phase to search for in phaseQueue
|
||||
* @returns boolean if a targetPhase was found and added
|
||||
*/
|
||||
prependToPhase(phase: Phase | Phase[], targetPhase: Constructor<Phase>): boolean {
|
||||
if (!Array.isArray(phase)) {
|
||||
phase = [phase];
|
||||
}
|
||||
const targetIndex = this.phaseQueue.findIndex(ph => ph instanceof targetPhase);
|
||||
|
||||
if (targetIndex !== -1) {
|
||||
this.phaseQueue.splice(targetIndex, 0, ...phase);
|
||||
return true;
|
||||
}
|
||||
this.unshiftPhase(...phase);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to add the input phase(s) to index after target phase in the {@linkcode phaseQueue}, else simply calls {@linkcode unshiftPhase()}
|
||||
* @param phase - The phase(s) to be added
|
||||
* @param targetPhase - The type of phase to search for in {@linkcode phaseQueue}
|
||||
* @returns `true` if a `targetPhase` was found to append to
|
||||
*/
|
||||
appendToPhase(phase: Phase | Phase[], targetPhase: Constructor<Phase>): boolean {
|
||||
if (!Array.isArray(phase)) {
|
||||
phase = [phase];
|
||||
}
|
||||
const targetIndex = this.phaseQueue.findIndex(ph => ph instanceof targetPhase);
|
||||
|
||||
if (targetIndex !== -1 && this.phaseQueue.length > targetIndex) {
|
||||
this.phaseQueue.splice(targetIndex + 1, 0, ...phase);
|
||||
return true;
|
||||
}
|
||||
this.unshiftPhase(...phase);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a MessagePhase, either to PhaseQueuePrepend or nextCommandPhaseQueue
|
||||
* @param message - string for MessagePhase
|
||||
* @param callbackDelay - optional param for MessagePhase constructor
|
||||
* @param prompt - optional param for MessagePhase constructor
|
||||
* @param promptDelay - optional param for MessagePhase constructor
|
||||
* @param defer - Whether to allow the phase to be deferred
|
||||
*
|
||||
* @see {@linkcode MessagePhase} for more details on the parameters
|
||||
*/
|
||||
queueMessage(
|
||||
message: string,
|
||||
callbackDelay?: number | null,
|
||||
prompt?: boolean | null,
|
||||
promptDelay?: number | null,
|
||||
defer?: boolean | null,
|
||||
) {
|
||||
const phase = new MessagePhase(message, callbackDelay, prompt, promptDelay);
|
||||
if (!defer) {
|
||||
// adds to the end of PhaseQueuePrepend
|
||||
this.unshiftPhase(phase);
|
||||
} else {
|
||||
//remember that pushPhase adds it to nextCommandPhaseQueue
|
||||
this.pushPhase(phase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues an ability bar flyout phase
|
||||
* @param pokemon The pokemon who has the ability
|
||||
* @param passive Whether the ability is a passive
|
||||
* @param show Whether to show or hide the bar
|
||||
*/
|
||||
public queueAbilityDisplay(pokemon: Pokemon, passive: boolean, show: boolean): void {
|
||||
this.unshiftPhase(show ? new ShowAbilityPhase(pokemon.getBattlerIndex(), passive) : new HideAbilityPhase());
|
||||
this.clearPhaseQueueSplice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the ability bar if it is currently visible
|
||||
*/
|
||||
public hideAbilityBar(): void {
|
||||
if (globalScene.abilityBar.isVisible()) {
|
||||
this.unshiftPhase(new HideAbilityPhase());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves everything from nextCommandPhaseQueue to phaseQueue (keeping order)
|
||||
*/
|
||||
private populatePhaseQueue(): void {
|
||||
if (this.nextCommandPhaseQueue.length) {
|
||||
this.phaseQueue.push(...this.nextCommandPhaseQueue);
|
||||
this.nextCommandPhaseQueue.splice(0, this.nextCommandPhaseQueue.length);
|
||||
}
|
||||
this.phaseQueue.push(new TurnInitPhase());
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ export abstract class Phase {
|
||||
start() {}
|
||||
|
||||
end() {
|
||||
globalScene.shiftPhase();
|
||||
globalScene.phaseManager.shiftPhase();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +257,7 @@ export class AttemptCapturePhase extends PokemonPhase {
|
||||
null,
|
||||
() => {
|
||||
const end = () => {
|
||||
globalScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
|
||||
globalScene.phaseManager.unshiftPhase(new VictoryPhase(this.battlerIndex));
|
||||
globalScene.pokemonInfoContainer.hide();
|
||||
this.removePb();
|
||||
this.end();
|
||||
|
@ -39,7 +39,7 @@ export class AttemptRunPhase extends PokemonPhase {
|
||||
enemyField.forEach(enemyPokemon => applyPreLeaveFieldAbAttrs(PreLeaveFieldAbAttr, enemyPokemon));
|
||||
|
||||
globalScene.playSound("se/flee");
|
||||
globalScene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
|
||||
|
||||
globalScene.tweens.add({
|
||||
targets: [globalScene.arenaEnemy, enemyField].flat(),
|
||||
@ -60,16 +60,16 @@ export class AttemptRunPhase extends PokemonPhase {
|
||||
enemyPokemon.trySetStatus(StatusEffect.FAINT);
|
||||
});
|
||||
|
||||
globalScene.pushPhase(new BattleEndPhase(false));
|
||||
globalScene.phaseManager.pushPhase(new BattleEndPhase(false));
|
||||
|
||||
if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
||||
globalScene.pushPhase(new SelectBiomePhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectBiomePhase());
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new NewBattlePhase());
|
||||
globalScene.phaseManager.pushPhase(new NewBattlePhase());
|
||||
} else {
|
||||
playerPokemon.turnData.failedRunAway = true;
|
||||
globalScene.queueMessage(i18next.t("battle:runAwayCannotEscape"), null, true, 500);
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:runAwayCannotEscape"), null, true, 500);
|
||||
}
|
||||
|
||||
this.end();
|
||||
|
@ -19,7 +19,7 @@ export class BattleEndPhase extends BattlePhase {
|
||||
super.start();
|
||||
|
||||
// cull any extra `BattleEnd` phases from the queue.
|
||||
globalScene.phaseQueue = globalScene.phaseQueue.filter(phase => {
|
||||
globalScene.phaseManager.phaseQueue = globalScene.phaseManager.phaseQueue.filter(phase => {
|
||||
if (phase.is("BattleEndPhase")) {
|
||||
this.isVictory ||= phase.isVictory;
|
||||
return false;
|
||||
@ -28,7 +28,7 @@ export class BattleEndPhase extends BattlePhase {
|
||||
});
|
||||
// `phaseQueuePrepend` is private, so we have to use this inefficient loop.
|
||||
while (
|
||||
globalScene.tryRemoveUnshiftedPhase(phase => {
|
||||
globalScene.phaseManager.tryRemoveUnshiftedPhase(phase => {
|
||||
if (phase.is("BattleEndPhase")) {
|
||||
this.isVictory ||= phase.isVictory;
|
||||
return true;
|
||||
@ -55,8 +55,8 @@ export class BattleEndPhase extends BattlePhase {
|
||||
|
||||
// Endless graceful end
|
||||
if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex >= 5850) {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new GameOverPhase(true));
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase(true));
|
||||
}
|
||||
|
||||
for (const pokemon of globalScene.getField()) {
|
||||
|
@ -50,7 +50,7 @@ export class BerryPhase extends FieldPhase {
|
||||
const cancelled = new BooleanHolder(false);
|
||||
pokemon.getOpponents().forEach(opp => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled));
|
||||
if (cancelled.value) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:preventBerryUse", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -58,7 +58,7 @@ export class BerryPhase extends FieldPhase {
|
||||
return;
|
||||
}
|
||||
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM),
|
||||
);
|
||||
|
||||
|
@ -15,7 +15,7 @@ export class CheckStatusEffectPhase extends Phase {
|
||||
const field = globalScene.getField();
|
||||
for (const o of this.order) {
|
||||
if (field[o].status?.isPostTurn()) {
|
||||
globalScene.unshiftPhase(new PostTurnStatusEffectPhase(o));
|
||||
globalScene.phaseManager.unshiftPhase(new PostTurnStatusEffectPhase(o));
|
||||
}
|
||||
}
|
||||
this.end();
|
||||
|
@ -35,7 +35,7 @@ export class CheckSwitchPhase extends BattlePhase {
|
||||
|
||||
// ...if the checked Pokemon is somehow not on the field
|
||||
if (globalScene.field.getAll().indexOf(pokemon) === -1) {
|
||||
globalScene.unshiftPhase(new SummonMissingPhase(this.fieldIndex));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonMissingPhase(this.fieldIndex));
|
||||
return super.end();
|
||||
}
|
||||
|
||||
@ -68,7 +68,9 @@ export class CheckSwitchPhase extends BattlePhase {
|
||||
UiMode.CONFIRM,
|
||||
() => {
|
||||
globalScene.ui.setMode(UiMode.MESSAGE);
|
||||
globalScene.unshiftPhase(new SwitchPhase(SwitchType.INITIAL_SWITCH, this.fieldIndex, false, true));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SwitchPhase(SwitchType.INITIAL_SWITCH, this.fieldIndex, false, true),
|
||||
);
|
||||
this.end();
|
||||
},
|
||||
() => {
|
||||
|
@ -192,7 +192,7 @@ export class CommandPhase extends FieldPhase {
|
||||
}
|
||||
console.log(moveTargets, getPokemonNameWithAffix(playerPokemon));
|
||||
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
|
||||
globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
|
||||
globalScene.phaseManager.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
|
||||
}
|
||||
if (turnCommand.move && (moveTargets.targets.length <= 1 || moveTargets.multiple)) {
|
||||
turnCommand.move.targets = moveTargets.targets;
|
||||
@ -203,7 +203,7 @@ export class CommandPhase extends FieldPhase {
|
||||
) {
|
||||
turnCommand.move.targets = playerPokemon.getMoveQueue()[0].targets;
|
||||
} else {
|
||||
globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
|
||||
globalScene.phaseManager.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
|
||||
}
|
||||
globalScene.currentBattle.preTurnCommands[this.fieldIndex] = preTurnCommand;
|
||||
globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
|
||||
@ -457,8 +457,8 @@ export class CommandPhase extends FieldPhase {
|
||||
|
||||
cancel() {
|
||||
if (this.fieldIndex) {
|
||||
globalScene.unshiftPhase(new CommandPhase(0));
|
||||
globalScene.unshiftPhase(new CommandPhase(1));
|
||||
globalScene.phaseManager.unshiftPhase(new CommandPhase(0));
|
||||
globalScene.phaseManager.unshiftPhase(new CommandPhase(1));
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ export class EggHatchPhase extends Phase {
|
||||
}
|
||||
|
||||
end() {
|
||||
if (globalScene.findPhase(p => p.is("EggHatchPhase"))) {
|
||||
if (globalScene.phaseManager.findPhase(p => p.is("EggHatchPhase"))) {
|
||||
this.eggHatchHandler.clear();
|
||||
} else {
|
||||
globalScene.time.delayedCall(250, () => globalScene.setModifiersVisible(true));
|
||||
|
@ -62,12 +62,12 @@ export class EggLapsePhase extends Phase {
|
||||
true,
|
||||
);
|
||||
} else if (eggsToHatchCount >= this.minEggsToSkip && globalScene.eggSkipPreference === 2) {
|
||||
globalScene.queueMessage(i18next.t("battle:eggHatching"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:eggHatching"));
|
||||
this.hatchEggsSkipped(eggsToHatch);
|
||||
this.showSummary();
|
||||
} else {
|
||||
// regular hatches, no summary
|
||||
globalScene.queueMessage(i18next.t("battle:eggHatching"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:eggHatching"));
|
||||
this.hatchEggsRegular(eggsToHatch);
|
||||
this.end();
|
||||
}
|
||||
@ -83,7 +83,7 @@ export class EggLapsePhase extends Phase {
|
||||
hatchEggsRegular(eggsToHatch: Egg[]) {
|
||||
let eggsToHatchCount: number = eggsToHatch.length;
|
||||
for (const egg of eggsToHatch) {
|
||||
globalScene.unshiftPhase(new EggHatchPhase(this, egg, eggsToHatchCount));
|
||||
globalScene.phaseManager.unshiftPhase(new EggHatchPhase(this, egg, eggsToHatchCount));
|
||||
eggsToHatchCount--;
|
||||
}
|
||||
}
|
||||
@ -99,7 +99,7 @@ export class EggLapsePhase extends Phase {
|
||||
}
|
||||
|
||||
showSummary() {
|
||||
globalScene.unshiftPhase(new EggSummaryPhase(this.eggHatchData));
|
||||
globalScene.phaseManager.unshiftPhase(new EggSummaryPhase(this.eggHatchData));
|
||||
this.end();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
|
||||
// Failsafe if players somehow skip floor 200 in classic mode
|
||||
if (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex > 200) {
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
}
|
||||
|
||||
const loadEnemyAssets: Promise<void>[] = [];
|
||||
@ -438,9 +438,9 @@ export class EncounterPhase extends BattlePhase {
|
||||
const doTrainerSummon = () => {
|
||||
this.hideEnemyTrainer();
|
||||
const availablePartyMembers = globalScene.getEnemyParty().filter(p => !p.isFainted()).length;
|
||||
globalScene.unshiftPhase(new SummonPhase(0, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(0, false));
|
||||
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
|
||||
globalScene.unshiftPhase(new SummonPhase(1, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(1, false));
|
||||
}
|
||||
this.end();
|
||||
};
|
||||
@ -496,7 +496,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
globalScene.ui.clearText();
|
||||
globalScene.ui.getMessageHandler().hideNameText();
|
||||
|
||||
globalScene.unshiftPhase(new MysteryEncounterPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new MysteryEncounterPhase());
|
||||
this.end();
|
||||
};
|
||||
|
||||
@ -554,7 +554,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
|
||||
enemyField.forEach((enemyPokemon, e) => {
|
||||
if (enemyPokemon.isShiny(true)) {
|
||||
globalScene.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e));
|
||||
globalScene.phaseManager.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e));
|
||||
}
|
||||
/** This sets Eternatus' held item to be untransferrable, preventing it from being stolen */
|
||||
if (
|
||||
@ -576,7 +576,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
|
||||
if (![BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(globalScene.currentBattle.battleType)) {
|
||||
enemyField.map(p =>
|
||||
globalScene.pushConditionalPhase(new PostSummonPhase(p.getBattlerIndex()), () => {
|
||||
globalScene.phaseManager.pushConditionalPhase(new PostSummonPhase(p.getBattlerIndex()), () => {
|
||||
// if there is not a player party, we can't continue
|
||||
if (!globalScene.getPlayerParty().length) {
|
||||
return false;
|
||||
@ -594,7 +594,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
);
|
||||
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
|
||||
if (ivScannerModifier) {
|
||||
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex())));
|
||||
enemyField.map(p => globalScene.phaseManager.pushPhase(new ScanIvsPhase(p.getBattlerIndex())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,21 +602,21 @@ export class EncounterPhase extends BattlePhase {
|
||||
const availablePartyMembers = globalScene.getPokemonAllowedInBattle();
|
||||
|
||||
if (!availablePartyMembers[0].isOnField()) {
|
||||
globalScene.pushPhase(new SummonPhase(0));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(0));
|
||||
}
|
||||
|
||||
if (globalScene.currentBattle.double) {
|
||||
if (availablePartyMembers.length > 1) {
|
||||
globalScene.pushPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.pushPhase(new ToggleDoublePositionPhase(true));
|
||||
if (!availablePartyMembers[1].isOnField()) {
|
||||
globalScene.pushPhase(new SummonPhase(1));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) {
|
||||
globalScene.pushPhase(new ReturnPhase(1));
|
||||
globalScene.phaseManager.pushPhase(new ReturnPhase(1));
|
||||
}
|
||||
globalScene.pushPhase(new ToggleDoublePositionPhase(false));
|
||||
globalScene.phaseManager.pushPhase(new ToggleDoublePositionPhase(false));
|
||||
}
|
||||
|
||||
if (
|
||||
@ -625,9 +625,9 @@ export class EncounterPhase extends BattlePhase {
|
||||
) {
|
||||
const minPartySize = globalScene.currentBattle.double ? 2 : 1;
|
||||
if (availablePartyMembers.length > minPartySize) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
if (globalScene.currentBattle.double) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ export class EvolutionPhase extends Phase {
|
||||
|
||||
SoundFade.fadeOut(globalScene, this.evolutionBgm, 100);
|
||||
|
||||
globalScene.unshiftPhase(new EndEvolutionPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new EndEvolutionPhase());
|
||||
|
||||
globalScene.ui.showText(
|
||||
i18next.t("menu:stoppedEvolving", {
|
||||
@ -355,9 +355,11 @@ export class EvolutionPhase extends Phase {
|
||||
.getLevelMoves(this.lastLevel + 1, true, false, false, learnSituation)
|
||||
.filter(lm => lm[0] === EVOLVE_MOVE);
|
||||
for (const lm of levelMoves) {
|
||||
globalScene.unshiftPhase(new LearnMovePhase(globalScene.getPlayerParty().indexOf(this.pokemon), lm[1]));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new LearnMovePhase(globalScene.getPlayerParty().indexOf(this.pokemon), lm[1]),
|
||||
);
|
||||
}
|
||||
globalScene.unshiftPhase(new EndEvolutionPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new EndEvolutionPhase());
|
||||
|
||||
globalScene.playSound("se/shine");
|
||||
this.doSpray();
|
||||
|
@ -34,7 +34,7 @@ export class ExpPhase extends PlayerPartyMemberPokemonPhase {
|
||||
pokemon.addExp(exp.value);
|
||||
const newLevel = pokemon.level;
|
||||
if (newLevel > lastLevel) {
|
||||
globalScene.unshiftPhase(new LevelUpPhase(this.partyMemberIndex, lastLevel, newLevel));
|
||||
globalScene.phaseManager.unshiftPhase(new LevelUpPhase(this.partyMemberIndex, lastLevel, newLevel));
|
||||
}
|
||||
pokemon.updateInfo().then(() => this.end());
|
||||
},
|
||||
|
@ -18,7 +18,8 @@ import { BattleSpec } from "#app/enums/battle-spec";
|
||||
import { StatusEffect } from "#app/enums/status-effect";
|
||||
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { HitResult, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||
import { HitResult, PokemonMove } from "#app/field/pokemon";
|
||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { PokemonInstantReviveModifier } from "#app/modifier/modifier";
|
||||
import { SwitchType } from "#enums/switch-type";
|
||||
@ -114,7 +115,7 @@ export class FaintPhase extends PokemonPhase {
|
||||
});
|
||||
}
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battle:fainted", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
@ -165,7 +166,7 @@ export class FaintPhase extends PokemonPhase {
|
||||
const legalPlayerPartyPokemon = legalPlayerPokemon.filter(p => !p.isActive(true));
|
||||
if (!legalPlayerPokemon.length) {
|
||||
/** If the player doesn't have any legal Pokemon, end the game */
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
} else if (
|
||||
globalScene.currentBattle.double &&
|
||||
legalPlayerPokemon.length === 1 &&
|
||||
@ -175,23 +176,25 @@ export class FaintPhase extends PokemonPhase {
|
||||
* If the player has exactly one Pokemon in total at this point in a double battle, and that Pokemon
|
||||
* is already on the field, unshift a phase that moves that Pokemon to center position.
|
||||
*/
|
||||
globalScene.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
} else if (legalPlayerPartyPokemon.length > 0) {
|
||||
/**
|
||||
* If previous conditions weren't met, and the player has at least 1 legal Pokemon off the field,
|
||||
* push a phase that prompts the player to summon a Pokemon from their party.
|
||||
*/
|
||||
globalScene.pushPhase(new SwitchPhase(SwitchType.SWITCH, this.fieldIndex, true, false));
|
||||
globalScene.phaseManager.pushPhase(new SwitchPhase(SwitchType.SWITCH, this.fieldIndex, true, false));
|
||||
}
|
||||
} else {
|
||||
globalScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
|
||||
globalScene.phaseManager.unshiftPhase(new VictoryPhase(this.battlerIndex));
|
||||
if ([BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(globalScene.currentBattle.battleType)) {
|
||||
const hasReservePartyMember = !!globalScene
|
||||
.getEnemyParty()
|
||||
.filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot)
|
||||
.length;
|
||||
if (hasReservePartyMember) {
|
||||
globalScene.pushPhase(new SwitchSummonPhase(SwitchType.SWITCH, this.fieldIndex, -1, false, false));
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new SwitchSummonPhase(SwitchType.SWITCH, this.fieldIndex, -1, false, false),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,7 +206,7 @@ export class FaintPhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
pokemon.faintCry(() => {
|
||||
if (pokemon instanceof PlayerPokemon) {
|
||||
if (pokemon.isPlayer()) {
|
||||
pokemon.addFriendship(-FRIENDSHIP_LOSS_FROM_FAINT);
|
||||
}
|
||||
pokemon.hideInfo();
|
||||
@ -246,7 +249,7 @@ export class FaintPhase extends PokemonPhase {
|
||||
} else {
|
||||
// Final boss' HP threshold has been bypassed; cancel faint and force check for 2nd phase
|
||||
enemy.hp++;
|
||||
globalScene.unshiftPhase(new DamageAnimPhase(enemy.getBattlerIndex(), 0, HitResult.INDIRECT));
|
||||
globalScene.phaseManager.unshiftPhase(new DamageAnimPhase(enemy.getBattlerIndex(), 0, HitResult.INDIRECT));
|
||||
this.end();
|
||||
}
|
||||
return true;
|
||||
|
@ -100,7 +100,7 @@ export class FormChangePhase extends EvolutionPhase {
|
||||
globalScene.time.delayedCall(900, () => {
|
||||
this.pokemon.changeForm(this.formChange).then(() => {
|
||||
if (!this.modal) {
|
||||
globalScene.unshiftPhase(new EndEvolutionPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new EndEvolutionPhase());
|
||||
}
|
||||
|
||||
globalScene.playSound("se/shine");
|
||||
|
@ -47,7 +47,7 @@ export class GameOverPhase extends BattlePhase {
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
globalScene.hideAbilityBar();
|
||||
globalScene.phaseManager.hideAbilityBar();
|
||||
|
||||
// Failsafe if players somehow skip floor 200 in classic mode
|
||||
if (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex > 200) {
|
||||
@ -84,23 +84,23 @@ export class GameOverPhase extends BattlePhase {
|
||||
() => {
|
||||
globalScene.ui.fadeOut(1250).then(() => {
|
||||
globalScene.reset();
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.gameData.loadSession(globalScene.sessionSlotId).then(() => {
|
||||
globalScene.pushPhase(new EncounterPhase(true));
|
||||
globalScene.phaseManager.pushPhase(new EncounterPhase(true));
|
||||
|
||||
const availablePartyMembers = globalScene.getPokemonAllowedInBattle().length;
|
||||
|
||||
globalScene.pushPhase(new SummonPhase(0));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(0));
|
||||
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
|
||||
globalScene.pushPhase(new SummonPhase(1));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(1));
|
||||
}
|
||||
if (
|
||||
globalScene.currentBattle.waveIndex > 1 &&
|
||||
globalScene.currentBattle.battleType !== BattleType.TRAINER
|
||||
) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ export class GameOverPhase extends BattlePhase {
|
||||
globalScene.ui.fadeOut(fadeDuration).then(() => {
|
||||
activeBattlers.map(a => a.setVisible(false));
|
||||
globalScene.setFieldScale(1, true);
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.ui.clearText();
|
||||
|
||||
if (this.isVictory && globalScene.gameMode.isChallenge) {
|
||||
@ -160,15 +160,17 @@ export class GameOverPhase extends BattlePhase {
|
||||
this.handleUnlocks();
|
||||
|
||||
for (const species of this.firstRibbons) {
|
||||
globalScene.unshiftPhase(new RibbonModifierRewardPhase(modifierTypes.VOUCHER_PLUS, species));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new RibbonModifierRewardPhase(modifierTypes.VOUCHER_PLUS, species),
|
||||
);
|
||||
}
|
||||
if (!firstClear) {
|
||||
globalScene.unshiftPhase(new GameOverModifierRewardPhase(modifierTypes.VOUCHER_PREMIUM));
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverModifierRewardPhase(modifierTypes.VOUCHER_PREMIUM));
|
||||
}
|
||||
}
|
||||
this.getRunHistoryEntry().then(runHistoryEntry => {
|
||||
globalScene.gameData.saveRunHistory(runHistoryEntry, this.isVictory);
|
||||
globalScene.pushPhase(new PostGameOverPhase(endCardPhase));
|
||||
globalScene.phaseManager.pushPhase(new PostGameOverPhase(endCardPhase));
|
||||
this.end();
|
||||
});
|
||||
};
|
||||
@ -198,7 +200,7 @@ export class GameOverPhase extends BattlePhase {
|
||||
globalScene.ui.fadeOut(500).then(() => {
|
||||
globalScene.charSprite.hide().then(() => {
|
||||
const endCardPhase = new EndCardPhase();
|
||||
globalScene.unshiftPhase(endCardPhase);
|
||||
globalScene.phaseManager.unshiftPhase(endCardPhase);
|
||||
clear(endCardPhase);
|
||||
});
|
||||
});
|
||||
@ -208,7 +210,7 @@ export class GameOverPhase extends BattlePhase {
|
||||
});
|
||||
} else {
|
||||
const endCardPhase = new EndCardPhase();
|
||||
globalScene.unshiftPhase(endCardPhase);
|
||||
globalScene.phaseManager.unshiftPhase(endCardPhase);
|
||||
clear(endCardPhase);
|
||||
}
|
||||
} else {
|
||||
@ -230,9 +232,9 @@ export class GameOverPhase extends BattlePhase {
|
||||
})
|
||||
.then(success => doGameOver(!globalScene.gameMode.isDaily || !!success))
|
||||
.catch(_err => {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.clearPhaseQueueSplice();
|
||||
globalScene.unshiftPhase(new MessagePhase(i18next.t("menu:serverCommunicationFailed"), 2500));
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueueSplice();
|
||||
globalScene.phaseManager.unshiftPhase(new MessagePhase(i18next.t("menu:serverCommunicationFailed"), 2500));
|
||||
// force the game to reload after 2 seconds.
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
@ -251,22 +253,22 @@ export class GameOverPhase extends BattlePhase {
|
||||
handleUnlocks(): void {
|
||||
if (this.isVictory && globalScene.gameMode.isClassic) {
|
||||
if (!globalScene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
|
||||
globalScene.unshiftPhase(new UnlockPhase(Unlockables.ENDLESS_MODE));
|
||||
globalScene.phaseManager.unshiftPhase(new UnlockPhase(Unlockables.ENDLESS_MODE));
|
||||
}
|
||||
if (
|
||||
globalScene.getPlayerParty().filter(p => p.fusionSpecies).length &&
|
||||
!globalScene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]
|
||||
) {
|
||||
globalScene.unshiftPhase(new UnlockPhase(Unlockables.SPLICED_ENDLESS_MODE));
|
||||
globalScene.phaseManager.unshiftPhase(new UnlockPhase(Unlockables.SPLICED_ENDLESS_MODE));
|
||||
}
|
||||
if (!globalScene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE]) {
|
||||
globalScene.unshiftPhase(new UnlockPhase(Unlockables.MINI_BLACK_HOLE));
|
||||
globalScene.phaseManager.unshiftPhase(new UnlockPhase(Unlockables.MINI_BLACK_HOLE));
|
||||
}
|
||||
if (
|
||||
!globalScene.gameData.unlocks[Unlockables.EVIOLITE] &&
|
||||
globalScene.getPlayerParty().some(p => p.getSpeciesForm(true).speciesId in pokemonEvolutions)
|
||||
) {
|
||||
globalScene.unshiftPhase(new UnlockPhase(Unlockables.EVIOLITE));
|
||||
globalScene.phaseManager.unshiftPhase(new UnlockPhase(Unlockables.EVIOLITE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
||||
pokemon.usedTMs = [];
|
||||
}
|
||||
pokemon.usedTMs.push(this.moveId);
|
||||
globalScene.tryRemovePhase(phase => phase.is("SelectModifierPhase"));
|
||||
globalScene.phaseManager.tryRemovePhase(phase => phase.is("SelectModifierPhase"));
|
||||
} else if (this.learnMoveType === LearnMoveType.MEMORY) {
|
||||
if (this.cost !== -1) {
|
||||
if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) {
|
||||
@ -205,7 +205,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
||||
}
|
||||
globalScene.playSound("se/buy");
|
||||
} else {
|
||||
globalScene.tryRemovePhase(phase => phase.is("SelectModifierPhase"));
|
||||
globalScene.phaseManager.tryRemovePhase(phase => phase.is("SelectModifierPhase"));
|
||||
}
|
||||
}
|
||||
pokemon.setMove(index, this.moveId);
|
||||
|
@ -66,14 +66,14 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
|
||||
// this feels like an unnecessary optimization
|
||||
const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1);
|
||||
for (const lm of levelMoves) {
|
||||
globalScene.unshiftPhase(new LearnMovePhase(this.partyMemberIndex, lm[1]));
|
||||
globalScene.phaseManager.unshiftPhase(new LearnMovePhase(this.partyMemberIndex, lm[1]));
|
||||
}
|
||||
}
|
||||
if (!this.pokemon.pauseEvolutions) {
|
||||
const evolution = this.pokemon.getEvolution();
|
||||
if (evolution) {
|
||||
this.pokemon.breakIllusion();
|
||||
globalScene.unshiftPhase(new EvolutionPhase(this.pokemon, evolution, this.lastLevel));
|
||||
globalScene.phaseManager.unshiftPhase(new EvolutionPhase(this.pokemon, evolution, this.lastLevel));
|
||||
}
|
||||
}
|
||||
return super.end();
|
||||
|
@ -70,7 +70,7 @@ export class LoginPhase extends Phase {
|
||||
});
|
||||
},
|
||||
() => {
|
||||
globalScene.unshiftPhase(new LoginPhase(false));
|
||||
globalScene.phaseManager.unshiftPhase(new LoginPhase(false));
|
||||
this.end();
|
||||
},
|
||||
],
|
||||
@ -94,7 +94,7 @@ export class LoginPhase extends Phase {
|
||||
removeCookie(sessionIdKey);
|
||||
globalScene.reset(true, true);
|
||||
} else {
|
||||
globalScene.unshiftPhase(new UnavailablePhase());
|
||||
globalScene.phaseManager.unshiftPhase(new UnavailablePhase());
|
||||
super.end();
|
||||
}
|
||||
return null;
|
||||
@ -114,7 +114,7 @@ export class LoginPhase extends Phase {
|
||||
globalScene.ui.setMode(UiMode.MESSAGE);
|
||||
|
||||
if (!globalScene.gameData.gender) {
|
||||
globalScene.unshiftPhase(new SelectGenderPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new SelectGenderPhase());
|
||||
}
|
||||
|
||||
handleTutorial(Tutorial.Intro).then(() => super.end());
|
||||
|
@ -44,7 +44,7 @@ export class MessagePhase extends Phase {
|
||||
page0 = page0.split(repname[p]).join(pokename[p]);
|
||||
page1 = page1.split(repname[p]).join(pokename[p]);
|
||||
}
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new MessagePhase(page1, this.callbackDelay, this.prompt, this.promptDelay, this.speaker),
|
||||
);
|
||||
this.text = page0.trim();
|
||||
|
@ -62,9 +62,9 @@ export class MoveChargePhase extends PokemonPhase {
|
||||
|
||||
if (instantCharge.value) {
|
||||
// this MoveEndPhase will be duplicated by the queued MovePhase if not removed
|
||||
globalScene.tryRemovePhase(phase => phase.is("MoveEndPhase") && phase.getPokemon() === user);
|
||||
globalScene.phaseManager.tryRemovePhase(phase => phase.is("MoveEndPhase") && phase.getPokemon() === user);
|
||||
// queue a new MovePhase for this move's attack phase
|
||||
globalScene.unshiftPhase(new MovePhase(user, [this.targetIndex], this.move, false));
|
||||
globalScene.phaseManager.unshiftPhase(new MovePhase(user, [this.targetIndex], this.move, false));
|
||||
} else {
|
||||
user.getMoveQueue().push({ move: move.id, targets: [this.targetIndex] });
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
break;
|
||||
// biome-ignore lint/suspicious/noFallthroughSwitchClause: The fallthrough is intentional
|
||||
case HitCheckResult.NO_EFFECT:
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(this.move.id === MoveId.SHEER_COLD ? "battle:hitResultImmune" : "battle:hitResultNoEffect", {
|
||||
pokemonName: getPokemonNameWithAffix(target),
|
||||
}),
|
||||
@ -232,7 +232,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
applyMoveAttrs(NoEffectAttr, user, target, this.move);
|
||||
break;
|
||||
case HitCheckResult.MISS:
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }),
|
||||
);
|
||||
applyMoveAttrs(MissEffectAttr, user, target, this.move);
|
||||
@ -384,7 +384,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
if (this.queuedPhases.length) {
|
||||
globalScene.appendToPhase(this.queuedPhases, MoveEndPhase);
|
||||
globalScene.phaseManager.appendToPhase(this.queuedPhases, MoveEndPhase);
|
||||
}
|
||||
const moveType = user.getMoveType(this.move, true);
|
||||
if (this.move.category !== MoveCategory.STATUS && !user.stellarTypesBoosted.includes(moveType)) {
|
||||
@ -410,14 +410,14 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
*/
|
||||
if (user) {
|
||||
if (user.turnData.hitsLeft && --user.turnData.hitsLeft >= 1 && this.getFirstTarget()?.isActive()) {
|
||||
globalScene.unshiftPhase(this.getNewHitPhase());
|
||||
globalScene.phaseManager.unshiftPhase(this.getNewHitPhase());
|
||||
} else {
|
||||
// Queue message for number of hits made by multi-move
|
||||
// If multi-hit attack only hits once, still want to render a message
|
||||
const hitsTotal = user.turnData.hitCount - Math.max(user.turnData.hitsLeft, 0);
|
||||
if (hitsTotal > 1 || (user.turnData.hitsLeft && user.turnData.hitsLeft > 0)) {
|
||||
// If there are multiple hits, or if there are hits of the multi-hit move left
|
||||
globalScene.queueMessage(i18next.t("battle:attackHitsCount", { count: hitsTotal }));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:attackHitsCount", { count: hitsTotal }));
|
||||
}
|
||||
globalScene.applyModifiers(HitHealModifier, this.player, user);
|
||||
this.getTargets().forEach(target => (target.turnData.moveEffectiveness = null));
|
||||
@ -858,7 +858,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
});
|
||||
|
||||
if (isCritical) {
|
||||
globalScene.queueMessage(i18next.t("battle:hitResultCriticalHit"));
|
||||
globalScene.phaseManager.queueMessage(i18next.t("battle:hitResultCriticalHit"));
|
||||
}
|
||||
|
||||
if (damage <= 0) {
|
||||
@ -887,7 +887,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
sourceBattlerIndex: user.getBattlerIndex(),
|
||||
});
|
||||
|
||||
if (user.isPlayer() && !target.isPlayer()) {
|
||||
if (user.isPlayer() && target.isEnemy()) {
|
||||
globalScene.applyModifiers(DamageMoneyRewardModifier, true, user, new NumberHolder(damage));
|
||||
}
|
||||
|
||||
@ -901,9 +901,9 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
*/
|
||||
protected onFaintTarget(user: Pokemon, target: Pokemon): void {
|
||||
// set splice index here, so future scene queues happen before FaintedPhase
|
||||
globalScene.setPhaseQueueSplice();
|
||||
globalScene.phaseManager.setPhaseQueueSplice();
|
||||
|
||||
globalScene.unshiftPhase(new FaintPhase(target.getBattlerIndex(), false, user));
|
||||
globalScene.phaseManager.unshiftPhase(new FaintPhase(target.getBattlerIndex(), false, user));
|
||||
|
||||
target.destroySubstitute();
|
||||
target.lapseTag(BattlerTagType.COMMANDED);
|
||||
@ -936,7 +936,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
break;
|
||||
}
|
||||
if (msg) {
|
||||
globalScene.queueMessage(msg);
|
||||
globalScene.phaseManager.queueMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,10 +268,10 @@ export class MovePhase extends BattlePhase {
|
||||
|
||||
if (activated) {
|
||||
this.cancel();
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectActivationText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)),
|
||||
);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new CommonAnimPhase(
|
||||
this.pokemon.getBattlerIndex(),
|
||||
undefined,
|
||||
@ -279,7 +279,7 @@ export class MovePhase extends BattlePhase {
|
||||
),
|
||||
);
|
||||
} else if (healed) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)),
|
||||
);
|
||||
this.pokemon.resetStatus();
|
||||
@ -407,7 +407,7 @@ export class MovePhase extends BattlePhase {
|
||||
if (success) {
|
||||
const move = this.move.getMove();
|
||||
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, move);
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new MoveEffectPhase(this.pokemon.getBattlerIndex(), this.targets, move, this.reflected, this.move.virtual),
|
||||
);
|
||||
} else {
|
||||
@ -457,7 +457,9 @@ export class MovePhase extends BattlePhase {
|
||||
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
||||
|
||||
this.showMoveText();
|
||||
globalScene.unshiftPhase(new MoveChargePhase(this.pokemon.getBattlerIndex(), this.targets[0], this.move));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new MoveChargePhase(this.pokemon.getBattlerIndex(), this.targets[0], this.move),
|
||||
);
|
||||
} else {
|
||||
this.pokemon.pushMoveHistory({
|
||||
move: this.move.moveId,
|
||||
@ -479,7 +481,7 @@ export class MovePhase extends BattlePhase {
|
||||
* Queues a {@linkcode MoveEndPhase} and then ends the phase
|
||||
*/
|
||||
public end(): void {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new MoveEndPhase(this.pokemon.getBattlerIndex(), this.getActiveTargetPokemon(), this.followUp),
|
||||
);
|
||||
|
||||
@ -545,12 +547,12 @@ export class MovePhase extends BattlePhase {
|
||||
if (this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr)) {
|
||||
redirectTarget.value = currentTarget;
|
||||
// TODO: Ability displays should be handled by the ability
|
||||
globalScene.queueAbilityDisplay(
|
||||
globalScene.phaseManager.queueAbilityDisplay(
|
||||
this.pokemon,
|
||||
this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr),
|
||||
true,
|
||||
);
|
||||
globalScene.queueAbilityDisplay(
|
||||
globalScene.phaseManager.queueAbilityDisplay(
|
||||
this.pokemon,
|
||||
this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr),
|
||||
false,
|
||||
@ -649,7 +651,7 @@ export class MovePhase extends BattlePhase {
|
||||
return;
|
||||
}
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t(this.reflected ? "battle:magicCoatActivated" : "battle:useMove", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
|
||||
moveName: this.move.getName(),
|
||||
@ -660,6 +662,6 @@ export class MovePhase extends BattlePhase {
|
||||
}
|
||||
|
||||
public showFailedText(failedText: string = i18next.t("battle:attackFailed")): void {
|
||||
globalScene.queueMessage(failedText);
|
||||
globalScene.phaseManager.queueMessage(failedText);
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ export class MysteryEncounterPhase extends Phase {
|
||||
super.start();
|
||||
|
||||
// Clears out queued phases that are part of standard battle
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.clearPhaseQueueSplice();
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueueSplice();
|
||||
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
encounter.updateSeedOffset();
|
||||
@ -124,7 +124,7 @@ export class MysteryEncounterPhase extends Phase {
|
||||
*/
|
||||
continueEncounter() {
|
||||
const endDialogueAndContinueEncounter = () => {
|
||||
globalScene.pushPhase(new MysteryEncounterOptionSelectedPhase());
|
||||
globalScene.phaseManager.pushPhase(new MysteryEncounterOptionSelectedPhase());
|
||||
this.end();
|
||||
};
|
||||
|
||||
@ -247,8 +247,8 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
});
|
||||
|
||||
// Remove any status tick phases
|
||||
while (globalScene.findPhase(p => p.is("PostTurnStatusEffectPhase"))) {
|
||||
globalScene.tryRemovePhase(p => p.is("PostTurnStatusEffectPhase"));
|
||||
while (globalScene.phaseManager.findPhase(p => p.is("PostTurnStatusEffectPhase"))) {
|
||||
globalScene.phaseManager.tryRemovePhase(p => p.is("PostTurnStatusEffectPhase"));
|
||||
}
|
||||
|
||||
// The total number of Pokemon in the player's party that can legally fight
|
||||
@ -256,7 +256,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
// The total number of legal player Pokemon that aren't currently on the field
|
||||
const legalPlayerPartyPokemon = legalPlayerPokemon.filter(p => !p.isActive(true));
|
||||
if (!legalPlayerPokemon.length) {
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
return this.end();
|
||||
}
|
||||
|
||||
@ -265,13 +265,13 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
const playerField = globalScene.getPlayerField();
|
||||
playerField.forEach((pokemon, i) => {
|
||||
if (!pokemon.isAllowedInBattle() && legalPlayerPartyPokemon.length > i) {
|
||||
globalScene.unshiftPhase(new SwitchPhase(SwitchType.SWITCH, i, true, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SwitchPhase(SwitchType.SWITCH, i, true, false));
|
||||
}
|
||||
});
|
||||
|
||||
// THEN, if is a double battle, and player only has 1 summoned pokemon, center pokemon on field
|
||||
if (globalScene.currentBattle.double && legalPlayerPokemon.length === 1 && legalPlayerPartyPokemon.length === 0) {
|
||||
globalScene.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
}
|
||||
|
||||
this.end();
|
||||
@ -348,9 +348,9 @@ export class MysteryEncounterBattlePhase extends Phase {
|
||||
globalScene.playBgm();
|
||||
}
|
||||
const availablePartyMembers = globalScene.getEnemyParty().filter(p => !p.isFainted()).length;
|
||||
globalScene.unshiftPhase(new SummonPhase(0, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(0, false));
|
||||
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
|
||||
globalScene.unshiftPhase(new SummonPhase(1, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(1, false));
|
||||
}
|
||||
|
||||
if (!globalScene.currentBattle.mysteryEncounter?.hideBattleIntroMessage) {
|
||||
@ -368,9 +368,9 @@ export class MysteryEncounterBattlePhase extends Phase {
|
||||
const doTrainerSummon = () => {
|
||||
this.hideEnemyTrainer();
|
||||
const availablePartyMembers = globalScene.getEnemyParty().filter(p => !p.isFainted()).length;
|
||||
globalScene.unshiftPhase(new SummonPhase(0, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(0, false));
|
||||
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
|
||||
globalScene.unshiftPhase(new SummonPhase(1, false));
|
||||
globalScene.phaseManager.unshiftPhase(new SummonPhase(1, false));
|
||||
}
|
||||
this.endBattleSetup();
|
||||
};
|
||||
@ -426,37 +426,37 @@ export class MysteryEncounterBattlePhase extends Phase {
|
||||
if (encounterMode !== MysteryEncounterMode.TRAINER_BATTLE) {
|
||||
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
|
||||
if (ivScannerModifier) {
|
||||
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex())));
|
||||
enemyField.map(p => globalScene.phaseManager.pushPhase(new ScanIvsPhase(p.getBattlerIndex())));
|
||||
}
|
||||
}
|
||||
|
||||
const availablePartyMembers = globalScene.getPlayerParty().filter(p => p.isAllowedInBattle());
|
||||
|
||||
if (!availablePartyMembers[0].isOnField()) {
|
||||
globalScene.pushPhase(new SummonPhase(0));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(0));
|
||||
}
|
||||
|
||||
if (globalScene.currentBattle.double) {
|
||||
if (availablePartyMembers.length > 1) {
|
||||
globalScene.pushPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.pushPhase(new ToggleDoublePositionPhase(true));
|
||||
if (!availablePartyMembers[1].isOnField()) {
|
||||
globalScene.pushPhase(new SummonPhase(1));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) {
|
||||
globalScene.getPlayerField().forEach(pokemon => pokemon.lapseTag(BattlerTagType.COMMANDED));
|
||||
globalScene.pushPhase(new ReturnPhase(1));
|
||||
globalScene.phaseManager.pushPhase(new ReturnPhase(1));
|
||||
}
|
||||
globalScene.pushPhase(new ToggleDoublePositionPhase(false));
|
||||
globalScene.phaseManager.pushPhase(new ToggleDoublePositionPhase(false));
|
||||
}
|
||||
|
||||
if (encounterMode !== MysteryEncounterMode.TRAINER_BATTLE && !this.disableSwitch) {
|
||||
const minPartySize = globalScene.currentBattle.double ? 2 : 1;
|
||||
if (availablePartyMembers.length > minPartySize) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
if (globalScene.currentBattle.double) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -562,8 +562,8 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
||||
if (encounter.doEncounterRewards) {
|
||||
encounter.doEncounterRewards();
|
||||
} else if (this.addHealPhase) {
|
||||
globalScene.tryRemovePhase(p => p.is("SelectModifierPhase"));
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.tryRemovePhase(p => p.is("SelectModifierPhase"));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SelectModifierPhase(0, undefined, {
|
||||
fillRemaining: false,
|
||||
rerollMultiplier: -1,
|
||||
@ -571,7 +571,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
||||
);
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new PostMysteryEncounterPhase());
|
||||
globalScene.phaseManager.pushPhase(new PostMysteryEncounterPhase());
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
@ -618,10 +618,10 @@ export class PostMysteryEncounterPhase extends Phase {
|
||||
continueEncounter() {
|
||||
const endPhase = () => {
|
||||
if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
||||
globalScene.pushPhase(new SelectBiomePhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectBiomePhase());
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new NewBattlePhase());
|
||||
globalScene.phaseManager.pushPhase(new NewBattlePhase());
|
||||
this.end();
|
||||
};
|
||||
|
||||
|
@ -7,9 +7,11 @@ export class NewBattlePhase extends BattlePhase {
|
||||
super.start();
|
||||
|
||||
// cull any extra `NewBattle` phases from the queue.
|
||||
globalScene.phaseQueue = globalScene.phaseQueue.filter(phase => !phase.is("NewBattlePhase"));
|
||||
globalScene.phaseManager.phaseQueue = globalScene.phaseManager.phaseQueue.filter(
|
||||
phase => !phase.is("NewBattlePhase"),
|
||||
);
|
||||
// `phaseQueuePrepend` is private, so we have to use this inefficient loop.
|
||||
while (globalScene.tryRemoveUnshiftedPhase(phase => phase.is("NewBattlePhase"))) {}
|
||||
while (globalScene.phaseManager.tryRemoveUnshiftedPhase(phase => phase.is("NewBattlePhase"))) {}
|
||||
|
||||
globalScene.newBattle();
|
||||
|
||||
|
@ -41,7 +41,7 @@ export class ObtainStatusEffectPhase extends PokemonPhase {
|
||||
}
|
||||
pokemon.updateInfo(true);
|
||||
new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(false, () => {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectObtainText(
|
||||
this.statusEffect,
|
||||
getPokemonNameWithAffix(pokemon),
|
||||
@ -59,7 +59,7 @@ export class ObtainStatusEffectPhase extends PokemonPhase {
|
||||
return;
|
||||
}
|
||||
} else if (pokemon.status?.effect === this.statusEffect) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectOverlapText(this.statusEffect ?? StatusEffect.NONE, getPokemonNameWithAffix(pokemon)),
|
||||
);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
||||
let lastStatusEffect = StatusEffect.NONE;
|
||||
|
||||
if (healBlock && this.hpHealed > 0) {
|
||||
globalScene.queueMessage(healBlock.onActivation(pokemon));
|
||||
globalScene.phaseManager.queueMessage(healBlock.onActivation(pokemon));
|
||||
this.message = null;
|
||||
return super.end();
|
||||
}
|
||||
@ -119,11 +119,13 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
||||
}
|
||||
|
||||
if (this.message) {
|
||||
globalScene.queueMessage(this.message);
|
||||
globalScene.phaseManager.queueMessage(this.message);
|
||||
}
|
||||
|
||||
if (this.healStatus && lastStatusEffect && !hasMessage) {
|
||||
globalScene.queueMessage(getStatusEffectHealText(lastStatusEffect, getPokemonNameWithAffix(pokemon)));
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(lastStatusEffect, getPokemonNameWithAffix(pokemon)),
|
||||
);
|
||||
}
|
||||
|
||||
if (!healOrDamage && !lastStatusEffect) {
|
||||
|
@ -65,7 +65,7 @@ export class PokemonTransformPhase extends PokemonPhase {
|
||||
globalScene.playSound("battle_anims/PRSFX- Transform");
|
||||
}
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:postSummonTransform", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(user),
|
||||
targetName: target.name,
|
||||
|
@ -28,7 +28,7 @@ export class PostGameOverPhase extends Phase {
|
||||
return globalScene.reset(true);
|
||||
}
|
||||
globalScene.reset();
|
||||
globalScene.unshiftPhase(new TitlePhase());
|
||||
globalScene.phaseManager.unshiftPhase(new TitlePhase());
|
||||
this.end();
|
||||
});
|
||||
});
|
||||
|
@ -32,7 +32,7 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
||||
applyAbAttrs(BlockStatusDamageAbAttr, pokemon, cancelled);
|
||||
|
||||
if (!cancelled.value) {
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectActivationText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)),
|
||||
);
|
||||
const damage = new NumberHolder(0);
|
||||
|
@ -6,7 +6,6 @@ import { getTypeRgb } from "#app/data/type";
|
||||
import { BattleSpec } from "#app/enums/battle-spec";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { EnemyPokemon } from "#app/field/pokemon";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { BattlePhase } from "./battle-phase";
|
||||
import type { MovePhase } from "./move-phase";
|
||||
@ -158,9 +157,9 @@ export class QuietFormChangePhase extends BattlePhase {
|
||||
|
||||
end(): void {
|
||||
this.pokemon.findAndRemoveTags(t => t.tagType === BattlerTagType.AUTOTOMIZED);
|
||||
if (globalScene?.currentBattle.battleSpec === BattleSpec.FINAL_BOSS && this.pokemon instanceof EnemyPokemon) {
|
||||
if (globalScene?.currentBattle.battleSpec === BattleSpec.FINAL_BOSS && this.pokemon.isEnemy()) {
|
||||
globalScene.playBgm();
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(this.pokemon.getBattlerIndex(), this.pokemon.getMaxHp(), null, false, false, false, true),
|
||||
);
|
||||
this.pokemon.findAndRemoveTags(() => true);
|
||||
@ -169,7 +168,9 @@ export class QuietFormChangePhase extends BattlePhase {
|
||||
this.pokemon.initBattleInfo();
|
||||
this.pokemon.cry();
|
||||
|
||||
const movePhase = globalScene.findPhase(p => p.is("MovePhase") && p.pokemon === this.pokemon) as MovePhase;
|
||||
const movePhase = globalScene.phaseManager.findPhase(
|
||||
p => p.is("MovePhase") && p.pokemon === this.pokemon,
|
||||
) as MovePhase;
|
||||
if (movePhase) {
|
||||
movePhase.cancel();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export class RevivalBlessingPhase extends BattlePhase {
|
||||
pokemon.resetTurnData();
|
||||
pokemon.resetStatus(true, false, false, false);
|
||||
pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("moveTriggers:revivalBlessing", {
|
||||
pokemonName: pokemon.name,
|
||||
}),
|
||||
@ -51,16 +51,16 @@ export class RevivalBlessingPhase extends BattlePhase {
|
||||
) {
|
||||
if (slotIndex <= 1) {
|
||||
// Revived ally pokemon
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SwitchSummonPhase(SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, true),
|
||||
);
|
||||
globalScene.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
} else if (allyPokemon.isFainted()) {
|
||||
// Revived party pokemon, and ally pokemon is fainted
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SwitchSummonPhase(SwitchType.SWITCH, allyPokemon.getFieldIndex(), slotIndex, false, true),
|
||||
);
|
||||
globalScene.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ export class SelectBiomePhase extends BattlePhase {
|
||||
const setNextBiome = (nextBiome: BiomeId) => {
|
||||
if (nextWaveIndex % 10 === 1) {
|
||||
globalScene.applyModifiers(MoneyInterestModifier, true);
|
||||
globalScene.unshiftPhase(new PartyHealPhase(false));
|
||||
globalScene.phaseManager.unshiftPhase(new PartyHealPhase(false));
|
||||
}
|
||||
globalScene.unshiftPhase(new SwitchBiomePhase(nextBiome));
|
||||
globalScene.phaseManager.unshiftPhase(new SwitchBiomePhase(nextBiome));
|
||||
this.end();
|
||||
};
|
||||
|
||||
|
@ -123,7 +123,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
return false;
|
||||
}
|
||||
globalScene.reroll = true;
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SelectModifierPhase(
|
||||
this.rerollCount + 1,
|
||||
this.typeOptions.map(o => o.type?.tier).filter(t => t !== undefined) as ModifierTier[],
|
||||
@ -247,7 +247,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
// If the player selects either of these, then escapes out of consuming them,
|
||||
// they are returned to a shop in the same state.
|
||||
if (modifier.type instanceof RememberMoveModifierType || modifier.type instanceof TmModifierType) {
|
||||
globalScene.unshiftPhase(this.copy());
|
||||
globalScene.phaseManager.unshiftPhase(this.copy());
|
||||
}
|
||||
|
||||
if (cost && !(modifier.type instanceof RememberMoveModifierType)) {
|
||||
|
@ -25,8 +25,8 @@ export class SelectStarterPhase extends Phase {
|
||||
globalScene.ui.clearText();
|
||||
globalScene.ui.setMode(UiMode.SAVE_SLOT, SaveSlotUiMode.SAVE, (slotId: number) => {
|
||||
if (slotId === -1) {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.pushPhase(new TitlePhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.pushPhase(new TitlePhase());
|
||||
return this.end();
|
||||
}
|
||||
globalScene.sessionSlotId = slotId;
|
||||
|
@ -28,12 +28,12 @@ export class SelectTargetPhase extends PokemonPhase {
|
||||
const errorMessage = user
|
||||
.getRestrictingTag(move!, user, fieldSide[targets[0]])!
|
||||
.selectionDeniedText(user, moveObject.id);
|
||||
globalScene.queueMessage(i18next.t(errorMessage, { moveName: moveObject.name }), 0, true);
|
||||
globalScene.phaseManager.queueMessage(i18next.t(errorMessage, { moveName: moveObject.name }), 0, true);
|
||||
targets = [];
|
||||
}
|
||||
if (targets.length < 1) {
|
||||
globalScene.currentBattle.turnCommands[this.fieldIndex] = null;
|
||||
globalScene.unshiftPhase(new CommandPhase(this.fieldIndex));
|
||||
globalScene.phaseManager.unshiftPhase(new CommandPhase(this.fieldIndex));
|
||||
} else {
|
||||
turnCommand!.targets = targets; //TODO: is the bang correct here?
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ export class ShowAbilityPhase extends PokemonPhase {
|
||||
|
||||
// If the bar is already out, hide it before showing the new one
|
||||
if (globalScene.abilityBar.isVisible()) {
|
||||
globalScene.unshiftPhase(new HideAbilityPhase());
|
||||
globalScene.unshiftPhase(new ShowAbilityPhase(this.battlerIndex, this.passive));
|
||||
globalScene.phaseManager.unshiftPhase(new HideAbilityPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new ShowAbilityPhase(this.battlerIndex, this.passive));
|
||||
return this.end();
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,9 @@ export class ShowPartyExpBarPhase extends PlayerPartyMemberPokemonPhase {
|
||||
pokemon.addExp(exp.value);
|
||||
const newLevel = pokemon.level;
|
||||
if (newLevel > lastLevel) {
|
||||
globalScene.unshiftPhase(new LevelUpPhase(this.partyMemberIndex, lastLevel, newLevel));
|
||||
globalScene.phaseManager.unshiftPhase(new LevelUpPhase(this.partyMemberIndex, lastLevel, newLevel));
|
||||
}
|
||||
globalScene.unshiftPhase(new HidePartyExpBarPhase());
|
||||
globalScene.phaseManager.unshiftPhase(new HidePartyExpBarPhase());
|
||||
pokemon.updateInfo();
|
||||
|
||||
if (globalScene.expParty === ExpNotification.SKIP) {
|
||||
|
@ -72,7 +72,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
if (this.stats.length > 1) {
|
||||
for (let i = 0; i < this.stats.length; i++) {
|
||||
const stat = [this.stats[i]];
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new StatStageChangePhase(
|
||||
this.battlerIndex,
|
||||
this.selfTarget,
|
||||
@ -212,7 +212,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
if (this.showMessage) {
|
||||
const messages = this.getStatStageChangeMessages(filteredStats, stages.value, relLevels);
|
||||
for (const message of messages) {
|
||||
globalScene.queueMessage(message);
|
||||
globalScene.phaseManager.queueMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
applyPostStatStageChangeAbAttrs(PostStatStageChangeAbAttr, pokemon, filteredStats, this.stages, this.selfTarget);
|
||||
|
||||
// Look for any other stat change phases; if this is the last one, do White Herb check
|
||||
const existingPhase = globalScene.findPhase(
|
||||
const existingPhase = globalScene.phaseManager.findPhase(
|
||||
p => p.is("StatStageChangePhase") && p.battlerIndex === this.battlerIndex,
|
||||
);
|
||||
if (!existingPhase?.is("StatStageChangePhase")) {
|
||||
@ -315,7 +315,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
let existingPhase: StatStageChangePhase;
|
||||
if (this.stats.length === 1) {
|
||||
while (
|
||||
(existingPhase = globalScene.findPhase(
|
||||
(existingPhase = globalScene.phaseManager.findPhase(
|
||||
p =>
|
||||
p.is("StatStageChangePhase") &&
|
||||
p.battlerIndex === this.battlerIndex &&
|
||||
@ -328,13 +328,13 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
) {
|
||||
this.stages += existingPhase.stages;
|
||||
|
||||
if (!globalScene.tryRemovePhase(p => p === existingPhase)) {
|
||||
if (!globalScene.phaseManager.tryRemovePhase(p => p === existingPhase)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (
|
||||
(existingPhase = globalScene.findPhase(
|
||||
(existingPhase = globalScene.phaseManager.findPhase(
|
||||
p =>
|
||||
p.is("StatStageChangePhase") &&
|
||||
p.battlerIndex === this.battlerIndex &&
|
||||
@ -346,7 +346,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
) as StatStageChangePhase)
|
||||
) {
|
||||
this.stats.push(...existingPhase.stats);
|
||||
if (!globalScene.tryRemovePhase(p => p === existingPhase)) {
|
||||
if (!globalScene.phaseManager.tryRemovePhase(p => p === existingPhase)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ export class SummonPhase extends PartyMemberPokemonPhase {
|
||||
if (legalIndex === -1) {
|
||||
console.error("Party Details:\n", party);
|
||||
console.error("All available Pokemon were fainted or illegal!");
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
this.end();
|
||||
return;
|
||||
}
|
||||
@ -275,7 +275,7 @@ export class SummonPhase extends PartyMemberPokemonPhase {
|
||||
const pokemon = this.getPokemon();
|
||||
|
||||
if (pokemon.isShiny(true)) {
|
||||
globalScene.unshiftPhase(new ShinySparklePhase(pokemon.getBattlerIndex()));
|
||||
globalScene.phaseManager.unshiftPhase(new ShinySparklePhase(pokemon.getBattlerIndex()));
|
||||
}
|
||||
|
||||
pokemon.resetTurnData();
|
||||
@ -291,7 +291,7 @@ export class SummonPhase extends PartyMemberPokemonPhase {
|
||||
}
|
||||
|
||||
queuePostSummon(): void {
|
||||
globalScene.pushPhase(new PostSummonPhase(this.getPokemon().getBattlerIndex()));
|
||||
globalScene.phaseManager.pushPhase(new PostSummonPhase(this.getPokemon().getBattlerIndex()));
|
||||
}
|
||||
|
||||
end() {
|
||||
|
@ -76,9 +76,13 @@ export class SwitchPhase extends BattlePhase {
|
||||
if (slotIndex >= globalScene.currentBattle.getBattlerCount() && slotIndex < 6) {
|
||||
// Remove any pre-existing PostSummonPhase under the same field index.
|
||||
// Pre-existing PostSummonPhases may occur when this phase is invoked during a prompt to switch at the start of a wave.
|
||||
globalScene.tryRemovePhase(p => p.is("PostSummonPhase") && p.player && p.fieldIndex === this.fieldIndex);
|
||||
globalScene.phaseManager.tryRemovePhase(
|
||||
p => p.is("PostSummonPhase") && p.player && p.fieldIndex === this.fieldIndex,
|
||||
);
|
||||
const switchType = option === PartyOption.PASS_BATON ? SwitchType.BATON_PASS : this.switchType;
|
||||
globalScene.unshiftPhase(new SwitchSummonPhase(switchType, fieldIndex, slotIndex, this.doReturn));
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SwitchSummonPhase(switchType, fieldIndex, slotIndex, this.doReturn),
|
||||
);
|
||||
}
|
||||
globalScene.ui.setMode(UiMode.MESSAGE).then(() => super.end());
|
||||
},
|
||||
|
@ -253,7 +253,7 @@ export class SwitchSummonPhase extends SummonPhase {
|
||||
}
|
||||
|
||||
queuePostSummon(): void {
|
||||
globalScene.unshiftPhase(new PostSummonPhase(this.getPokemon().getBattlerIndex()));
|
||||
globalScene.phaseManager.unshiftPhase(new PostSummonPhase(this.getPokemon().getBattlerIndex()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@ export class TeraPhase extends BattlePhase {
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
globalScene.queueMessage(
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battle:pokemonTerastallized", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
|
||||
type: i18next.t(`pokemonInfo:Type.${PokemonType[this.pokemon.getTeraType()]}`),
|
||||
|
@ -124,8 +124,8 @@ export class TitlePhase extends Phase {
|
||||
options.push({
|
||||
label: i18next.t("menu:cancel"),
|
||||
handler: () => {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.pushPhase(new TitlePhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.pushPhase(new TitlePhase());
|
||||
super.end();
|
||||
return true;
|
||||
},
|
||||
@ -198,9 +198,9 @@ export class TitlePhase extends Phase {
|
||||
initDailyRun(): void {
|
||||
globalScene.ui.clearText();
|
||||
globalScene.ui.setMode(UiMode.SAVE_SLOT, SaveSlotUiMode.SAVE, (slotId: number) => {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
if (slotId === -1) {
|
||||
globalScene.pushPhase(new TitlePhase());
|
||||
globalScene.phaseManager.pushPhase(new TitlePhase());
|
||||
return super.end();
|
||||
}
|
||||
globalScene.sessionSlotId = slotId;
|
||||
@ -304,23 +304,23 @@ export class TitlePhase extends Phase {
|
||||
globalScene.arena.preloadBgm();
|
||||
globalScene.gameMode = getGameMode(this.gameMode);
|
||||
if (this.gameMode === GameModes.CHALLENGE) {
|
||||
globalScene.pushPhase(new SelectChallengePhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectChallengePhase());
|
||||
} else {
|
||||
globalScene.pushPhase(new SelectStarterPhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectStarterPhase());
|
||||
}
|
||||
globalScene.newArena(globalScene.gameMode.getStartingBiome());
|
||||
} else {
|
||||
globalScene.playBgm();
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new EncounterPhase(this.loaded));
|
||||
globalScene.phaseManager.pushPhase(new EncounterPhase(this.loaded));
|
||||
|
||||
if (this.loaded) {
|
||||
const availablePartyMembers = globalScene.getPokemonAllowedInBattle().length;
|
||||
|
||||
globalScene.pushPhase(new SummonPhase(0, true, true));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(0, true, true));
|
||||
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
|
||||
globalScene.pushPhase(new SummonPhase(1, true, true));
|
||||
globalScene.phaseManager.pushPhase(new SummonPhase(1, true, true));
|
||||
}
|
||||
|
||||
if (
|
||||
@ -329,9 +329,9 @@ export class TitlePhase extends Phase {
|
||||
) {
|
||||
const minPartySize = globalScene.currentBattle.double ? 2 : 1;
|
||||
if (availablePartyMembers > minPartySize) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
|
||||
if (globalScene.currentBattle.double) {
|
||||
globalScene.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
globalScene.phaseManager.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,13 @@ export class TrainerVictoryPhase extends BattlePhase {
|
||||
|
||||
globalScene.playBgm(globalScene.currentBattle.trainer?.config.victoryBgm);
|
||||
|
||||
globalScene.unshiftPhase(new MoneyRewardPhase(globalScene.currentBattle.trainer?.config.moneyMultiplier!)); // TODO: is this bang correct?
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new MoneyRewardPhase(globalScene.currentBattle.trainer?.config.moneyMultiplier!),
|
||||
); // TODO: is this bang correct?
|
||||
|
||||
const modifierRewardFuncs = globalScene.currentBattle.trainer?.config.modifierRewardFuncs!; // TODO: is this bang correct?
|
||||
for (const modifierRewardFunc of modifierRewardFuncs) {
|
||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierRewardFunc));
|
||||
globalScene.phaseManager.unshiftPhase(new ModifierRewardPhase(modifierRewardFunc));
|
||||
}
|
||||
|
||||
const trainerType = globalScene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct?
|
||||
@ -35,7 +37,7 @@ export class TrainerVictoryPhase extends BattlePhase {
|
||||
globalScene.currentBattle.trainer?.config.isBoss
|
||||
) {
|
||||
if (timedEventManager.getUpgradeUnlockedVouchers()) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new ModifierRewardPhase(
|
||||
[
|
||||
modifierTypes.VOUCHER_PLUS,
|
||||
@ -46,7 +48,7 @@ export class TrainerVictoryPhase extends BattlePhase {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new ModifierRewardPhase(
|
||||
[modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM][
|
||||
vouchers[TrainerType[trainerType]].voucherType
|
||||
|
@ -25,7 +25,7 @@ export class TurnEndPhase extends FieldPhase {
|
||||
globalScene.currentBattle.incrementTurn();
|
||||
globalScene.eventTarget.dispatchEvent(new TurnEndEvent(globalScene.currentBattle.turn));
|
||||
|
||||
globalScene.hideAbilityBar();
|
||||
globalScene.phaseManager.hideAbilityBar();
|
||||
|
||||
const handlePokemon = (pokemon: Pokemon) => {
|
||||
if (!pokemon.switchOutStatus) {
|
||||
@ -34,7 +34,7 @@ export class TurnEndPhase extends FieldPhase {
|
||||
globalScene.applyModifiers(TurnHealModifier, pokemon.isPlayer(), pokemon);
|
||||
|
||||
if (globalScene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) {
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
Math.max(pokemon.getMaxHp() >> 4, 1),
|
||||
|
@ -22,14 +22,18 @@ export class TurnInitPhase extends FieldPhase {
|
||||
globalScene.getPlayerField().forEach(p => {
|
||||
// If this pokemon is in play and evolved into something illegal under the current challenge, force a switch
|
||||
if (p.isOnField() && !p.isAllowedInBattle()) {
|
||||
globalScene.queueMessage(i18next.t("challenges:illegalEvolution", { pokemon: p.name }), null, true);
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("challenges:illegalEvolution", { pokemon: p.name }),
|
||||
null,
|
||||
true,
|
||||
);
|
||||
|
||||
const allowedPokemon = globalScene.getPokemonAllowedInBattle();
|
||||
|
||||
if (!allowedPokemon.length) {
|
||||
// If there are no longer any legal pokemon in the party, game over.
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new GameOverPhase());
|
||||
globalScene.phaseManager.clearPhaseQueue();
|
||||
globalScene.phaseManager.unshiftPhase(new GameOverPhase());
|
||||
} else if (
|
||||
allowedPokemon.length >= globalScene.currentBattle.getBattlerCount() ||
|
||||
(globalScene.currentBattle.double && !allowedPokemon[0].isActive(true))
|
||||
@ -42,7 +46,7 @@ export class TurnInitPhase extends FieldPhase {
|
||||
p.leaveField();
|
||||
}
|
||||
if (allowedPokemon.length === 1 && globalScene.currentBattle.double) {
|
||||
globalScene.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new ToggleDoublePositionPhase(true));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -65,11 +69,13 @@ export class TurnInitPhase extends FieldPhase {
|
||||
|
||||
pokemon.resetTurnData();
|
||||
|
||||
globalScene.pushPhase(pokemon.isPlayer() ? new CommandPhase(i) : new EnemyCommandPhase(i - BattlerIndex.ENEMY));
|
||||
globalScene.phaseManager.pushPhase(
|
||||
pokemon.isPlayer() ? new CommandPhase(i) : new EnemyCommandPhase(i - BattlerIndex.ENEMY),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
globalScene.pushPhase(new TurnStartPhase());
|
||||
globalScene.phaseManager.pushPhase(new TurnStartPhase());
|
||||
|
||||
this.end();
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ export class TurnStartPhase extends FieldPhase {
|
||||
|
||||
switch (preTurnCommand?.command) {
|
||||
case Command.TERA:
|
||||
globalScene.pushPhase(new TeraPhase(pokemon));
|
||||
globalScene.phaseManager.pushPhase(new TeraPhase(pokemon));
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,11 +176,13 @@ export class TurnStartPhase extends FieldPhase {
|
||||
pokemon.getMoveset().find(m => m.moveId === queuedMove.move && m.ppUsed < m.getMovePp()) ||
|
||||
new PokemonMove(queuedMove.move);
|
||||
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
||||
globalScene.unshiftPhase(new MoveHeaderPhase(pokemon, move));
|
||||
globalScene.phaseManager.unshiftPhase(new MoveHeaderPhase(pokemon, move));
|
||||
}
|
||||
if (pokemon.isPlayer()) {
|
||||
if (turnCommand.cursor === -1) {
|
||||
globalScene.pushPhase(new MovePhase(pokemon, turnCommand.targets || turnCommand.move!.targets, move)); //TODO: is the bang correct here?
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new MovePhase(pokemon, turnCommand.targets || turnCommand.move!.targets, move),
|
||||
); //TODO: is the bang correct here?
|
||||
} else {
|
||||
const playerPhase = new MovePhase(
|
||||
pokemon,
|
||||
@ -189,10 +191,10 @@ export class TurnStartPhase extends FieldPhase {
|
||||
false,
|
||||
queuedMove.ignorePP,
|
||||
); //TODO: is the bang correct here?
|
||||
globalScene.pushPhase(playerPhase);
|
||||
globalScene.phaseManager.pushPhase(playerPhase);
|
||||
}
|
||||
} else {
|
||||
globalScene.pushPhase(
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new MovePhase(
|
||||
pokemon,
|
||||
turnCommand.targets || turnCommand.move!.targets,
|
||||
@ -204,11 +206,13 @@ export class TurnStartPhase extends FieldPhase {
|
||||
}
|
||||
break;
|
||||
case Command.BALL:
|
||||
globalScene.unshiftPhase(new AttemptCapturePhase(turnCommand.targets![0] % 2, turnCommand.cursor!)); //TODO: is the bang correct here?
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new AttemptCapturePhase(turnCommand.targets![0] % 2, turnCommand.cursor!),
|
||||
); //TODO: is the bang correct here?
|
||||
break;
|
||||
case Command.POKEMON:
|
||||
const switchType = turnCommand.args?.[0] ? SwitchType.BATON_PASS : SwitchType.SWITCH;
|
||||
globalScene.unshiftPhase(
|
||||
globalScene.phaseManager.unshiftPhase(
|
||||
new SwitchSummonPhase(switchType, pokemon.getFieldIndex(), turnCommand.cursor!, true, pokemon.isPlayer()),
|
||||
);
|
||||
break;
|
||||
@ -233,18 +237,18 @@ export class TurnStartPhase extends FieldPhase {
|
||||
runningPokemon = hasRunAway !== undefined ? hasRunAway : fasterPokemon;
|
||||
}
|
||||
}
|
||||
globalScene.unshiftPhase(new AttemptRunPhase(runningPokemon.getFieldIndex()));
|
||||
globalScene.phaseManager.unshiftPhase(new AttemptRunPhase(runningPokemon.getFieldIndex()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new WeatherEffectPhase());
|
||||
globalScene.pushPhase(new BerryPhase());
|
||||
globalScene.phaseManager.pushPhase(new WeatherEffectPhase());
|
||||
globalScene.phaseManager.pushPhase(new BerryPhase());
|
||||
|
||||
/** Add a new phase to check who should be taking status damage */
|
||||
globalScene.pushPhase(new CheckStatusEffectPhase(moveOrder));
|
||||
globalScene.phaseManager.pushPhase(new CheckStatusEffectPhase(moveOrder));
|
||||
|
||||
globalScene.pushPhase(new TurnEndPhase());
|
||||
globalScene.phaseManager.pushPhase(new TurnEndPhase());
|
||||
|
||||
/**
|
||||
* this.end() will call shiftPhase(), which dumps everything from PrependQueue (aka everything that is unshifted()) to the front
|
||||
|
@ -7,7 +7,7 @@ export class UnavailablePhase extends Phase {
|
||||
public readonly phaseName = "UnavailablePhase";
|
||||
start(): void {
|
||||
globalScene.ui.setMode(UiMode.UNAVAILABLE, () => {
|
||||
globalScene.unshiftPhase(new LoginPhase(true));
|
||||
globalScene.phaseManager.unshiftPhase(new LoginPhase(true));
|
||||
this.end();
|
||||
});
|
||||
}
|
||||
|
@ -51,12 +51,12 @@ export class VictoryPhase extends PokemonPhase {
|
||||
.getEnemyParty()
|
||||
.find(p => (globalScene.currentBattle.battleType === BattleType.WILD ? p.isOnField() : !p?.isFainted(true)))
|
||||
) {
|
||||
globalScene.pushPhase(new BattleEndPhase(true));
|
||||
globalScene.phaseManager.pushPhase(new BattleEndPhase(true));
|
||||
if (globalScene.currentBattle.battleType === BattleType.TRAINER) {
|
||||
globalScene.pushPhase(new TrainerVictoryPhase());
|
||||
globalScene.phaseManager.pushPhase(new TrainerVictoryPhase());
|
||||
}
|
||||
if (globalScene.gameMode.isEndless || !globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) {
|
||||
globalScene.pushPhase(new EggLapsePhase());
|
||||
globalScene.phaseManager.pushPhase(new EggLapsePhase());
|
||||
if (globalScene.gameMode.isClassic) {
|
||||
switch (globalScene.currentBattle.waveIndex) {
|
||||
case ClassicFixedBossWaves.RIVAL_1:
|
||||
@ -64,34 +64,36 @@ export class VictoryPhase extends PokemonPhase {
|
||||
// Get event modifiers for this wave
|
||||
timedEventManager
|
||||
.getFixedBattleEventRewards(globalScene.currentBattle.waveIndex)
|
||||
.map(r => globalScene.pushPhase(new ModifierRewardPhase(modifierTypes[r])));
|
||||
.map(r => globalScene.phaseManager.pushPhase(new ModifierRewardPhase(modifierTypes[r])));
|
||||
break;
|
||||
case ClassicFixedBossWaves.EVIL_BOSS_2:
|
||||
// Should get Lock Capsule on 165 before shop phase so it can be used in the rewards shop
|
||||
globalScene.pushPhase(new ModifierRewardPhase(modifierTypes.LOCK_CAPSULE));
|
||||
globalScene.phaseManager.pushPhase(new ModifierRewardPhase(modifierTypes.LOCK_CAPSULE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (globalScene.currentBattle.waveIndex % 10) {
|
||||
globalScene.pushPhase(new SelectModifierPhase(undefined, undefined, this.getFixedBattleCustomModifiers()));
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new SelectModifierPhase(undefined, undefined, this.getFixedBattleCustomModifiers()),
|
||||
);
|
||||
} else if (globalScene.gameMode.isDaily) {
|
||||
globalScene.pushPhase(new ModifierRewardPhase(modifierTypes.EXP_CHARM));
|
||||
globalScene.phaseManager.pushPhase(new ModifierRewardPhase(modifierTypes.EXP_CHARM));
|
||||
if (
|
||||
globalScene.currentBattle.waveIndex > 10 &&
|
||||
!globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)
|
||||
) {
|
||||
globalScene.pushPhase(new ModifierRewardPhase(modifierTypes.GOLDEN_POKEBALL));
|
||||
globalScene.phaseManager.pushPhase(new ModifierRewardPhase(modifierTypes.GOLDEN_POKEBALL));
|
||||
}
|
||||
} else {
|
||||
const superExpWave = !globalScene.gameMode.isEndless ? (globalScene.offsetGym ? 0 : 20) : 10;
|
||||
if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex === 10) {
|
||||
globalScene.pushPhase(new ModifierRewardPhase(modifierTypes.EXP_SHARE));
|
||||
globalScene.phaseManager.pushPhase(new ModifierRewardPhase(modifierTypes.EXP_SHARE));
|
||||
}
|
||||
if (
|
||||
globalScene.currentBattle.waveIndex <= 750 &&
|
||||
(globalScene.currentBattle.waveIndex <= 500 || globalScene.currentBattle.waveIndex % 30 === superExpWave)
|
||||
) {
|
||||
globalScene.pushPhase(
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new ModifierRewardPhase(
|
||||
globalScene.currentBattle.waveIndex % 30 !== superExpWave || globalScene.currentBattle.waveIndex > 250
|
||||
? modifierTypes.EXP_CHARM
|
||||
@ -100,30 +102,30 @@ export class VictoryPhase extends PokemonPhase {
|
||||
);
|
||||
}
|
||||
if (globalScene.currentBattle.waveIndex <= 150 && !(globalScene.currentBattle.waveIndex % 50)) {
|
||||
globalScene.pushPhase(new ModifierRewardPhase(modifierTypes.GOLDEN_POKEBALL));
|
||||
globalScene.phaseManager.pushPhase(new ModifierRewardPhase(modifierTypes.GOLDEN_POKEBALL));
|
||||
}
|
||||
if (globalScene.gameMode.isEndless && !(globalScene.currentBattle.waveIndex % 50)) {
|
||||
globalScene.pushPhase(
|
||||
globalScene.phaseManager.pushPhase(
|
||||
new ModifierRewardPhase(
|
||||
!(globalScene.currentBattle.waveIndex % 250)
|
||||
? modifierTypes.VOUCHER_PREMIUM
|
||||
: modifierTypes.VOUCHER_PLUS,
|
||||
),
|
||||
);
|
||||
globalScene.pushPhase(new AddEnemyBuffModifierPhase());
|
||||
globalScene.phaseManager.pushPhase(new AddEnemyBuffModifierPhase());
|
||||
}
|
||||
}
|
||||
|
||||
if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
||||
globalScene.pushPhase(new SelectBiomePhase());
|
||||
globalScene.phaseManager.pushPhase(new SelectBiomePhase());
|
||||
}
|
||||
|
||||
globalScene.pushPhase(new NewBattlePhase());
|
||||
globalScene.phaseManager.pushPhase(new NewBattlePhase());
|
||||
} else {
|
||||
globalScene.currentBattle.battleType = BattleType.CLEAR;
|
||||
globalScene.score += globalScene.gameMode.getClearScoreBonus();
|
||||
globalScene.updateScoreText();
|
||||
globalScene.pushPhase(new GameOverPhase(true));
|
||||
globalScene.phaseManager.pushPhase(new GameOverPhase(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ export class WeatherEffectPhase extends CommonAnimPhase {
|
||||
|
||||
const damage = toDmgValue(pokemon.getMaxHp() / 16);
|
||||
|
||||
globalScene.queueMessage(getWeatherDamageMessage(this.weather!.weatherType, pokemon) ?? "");
|
||||
globalScene.phaseManager.queueMessage(getWeatherDamageMessage(this.weather!.weatherType, pokemon) ?? "");
|
||||
pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT, ignoreSegments: true });
|
||||
};
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
export const starterColors: StarterColors = {};
|
||||
interface StarterColors {
|
||||
[key: string]: [string, string];
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user