pokerogue/src/phases/battle-end-phase.ts
Dean 87e6095a00
[Misc/Feature] Add dynamic turn order (#6036)
* Add new priority queues

* Add dynamic queue manager

* Add timing modifier and fix post speed ordering

* Make `phaseQueue` private

* Fix `gameManager.setTurnOrder`

* Update `findPhase` to also check dynamic queues

* Modify existing phase manager methods to check dynamic queues

* Fix move order persisting through tests

* Fix magic coat/bounce

* Use append for magic coat/bounce

* Remove `getSpeedOrder` from `TurnStartPhase`, fix references to `getCommandOrder` in tests

* Fix round queuing last instead of next

* Add quick draw application

* Add quick claw activation

* Fix turn order tracking

* Add move header queue to fix ordering

* Fix abilities activating immediately on summon

* Fix `postsummonphases` being shuffled (need to handle speed ties differently here)

* Update speed order function

* Add `StaticSwitchSummonPhase`

* Fix magic coat/bounce error from conflict resolution

* Remove conditional queue

* Fix dancer and baton pass tests

* Automatically queue consecutive Pokémon phases as dynamic

* Move turn end phases queuing back to `TurnStartPhase`

* Fix `LearnMovePhase`

* Remove `PrependSplice`

* Move DQM to phase manager

* Fix various phases being pushed instead of unshifted

* Remove `StaticSwitchSummonPhase`

* Ensure the top queue is always at length - 1

* Fix encounter `PostSummonPhase`s and Revival Blessing

* Fix move headers

* Remove implicit ordering from DQM

* Fix `PostSummonPhase`s in encounters running too early

* Fix `tryRemovePhase` usages

* Add `MovePhase` after `MoveEndPhase` automatically

* Implement an `inSpeedOrder` function

* Merge fixes

* Fix encounter rewards

* Defer `FaintPhase`s where splice was used previously

* Separate speed order utils to avoid circular imports

* Temporarily disable lunar dance test

* Simplify deferral

* Remove move priority modifier

* Fix TS errors in code files

* Fix ts errors in tests

* Fix more test files

* Fix postsummon + checkswitch ability activations

* Fix `removeAll`

* Reposition `positionalTagPhase`

* Re-add `startCurrentPhase`

* Avoid overwriting `currentPhase` after `turnStart`

* Delete `switchSummonPhasePriorityQueue`

* Update `phase-manager.ts`

* Remove uses of `isNullOrUndefined`

* Rename deferral methods

* Update docs and use `getPlayerField(true)` in turn start phase

* Use `.getEnemyField(true)`

* Update docs for post summon phase priority queue (psppq)

* Update speed order utils

* Remove null from `nextPhase`

* Update move phase timing modifier docs

* Remove mention of phases from base priority queue class

* Remove and replace `applyInSpeedOrder`

* Don't sort weather effect phases

* Order priority queues before removing

- Add some `readonly` and `public` modifiers

- Remove unused `queuedPhases` field from `MoveEffectPhase`

* Fix linting in `phase-manager.ts`

* Remove unnecessary turn order modification in Rage Fist test

---------

Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com>
Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-09-20 17:49:40 -05:00

83 lines
2.6 KiB
TypeScript

import { applyAbAttrs } from "#abilities/apply-ab-attrs";
import { globalScene } from "#app/global-scene";
import { LapsingPersistentModifier, LapsingPokemonHeldItemModifier } from "#modifiers/modifier";
import { BattlePhase } from "#phases/battle-phase";
export class BattleEndPhase extends BattlePhase {
public readonly phaseName = "BattleEndPhase";
/** If true, will increment battles won */
isVictory: boolean;
constructor(isVictory: boolean) {
super();
this.isVictory = isVictory;
}
start() {
super.start();
// cull any extra `BattleEnd` phases from the queue.
this.isVictory ||= globalScene.phaseManager.hasPhaseOfType(
"BattleEndPhase",
(phase: BattleEndPhase) => phase.isVictory,
);
globalScene.phaseManager.removeAllPhasesOfType("BattleEndPhase");
globalScene.gameData.gameStats.battles++;
if (
globalScene.gameMode.isEndless
&& globalScene.currentBattle.waveIndex + 1 > globalScene.gameData.gameStats.highestEndlessWave
) {
globalScene.gameData.gameStats.highestEndlessWave = globalScene.currentBattle.waveIndex + 1;
}
if (this.isVictory) {
globalScene.currentBattle.addBattleScore();
if (globalScene.currentBattle.trainer) {
globalScene.gameData.gameStats.trainersDefeated++;
}
}
// Endless graceful end
if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex >= 5850) {
globalScene.phaseManager.clearPhaseQueue();
globalScene.phaseManager.unshiftNew("GameOverPhase", true);
}
for (const pokemon of globalScene.getPokemonAllowedInBattle()) {
applyAbAttrs("PostBattleAbAttr", { pokemon, victory: this.isVictory });
}
if (globalScene.currentBattle.moneyScattered) {
globalScene.currentBattle.pickUpScatteredMoney();
}
globalScene.clearEnemyHeldItemModifiers();
for (const p of globalScene.getEnemyParty()) {
try {
p.destroy();
} catch {
console.warn("Unable to destroy stale pokemon object in BattleEndPhase:", p);
}
}
const lapsingModifiers = globalScene.findModifiers(
m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier,
) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[];
for (const m of lapsingModifiers) {
const args: any[] = [];
if (m instanceof LapsingPokemonHeldItemModifier) {
args.push(globalScene.getPokemonById(m.pokemonId));
}
if (!m.lapse(...args)) {
globalScene.removeModifier(m);
}
}
globalScene.updateModifiers();
this.end();
}
}