diff --git a/src/battle-scene-events.ts b/src/battle-scene-events.ts new file mode 100644 index 00000000000..be3b79ff609 --- /dev/null +++ b/src/battle-scene-events.ts @@ -0,0 +1,25 @@ +import Move from "./data/move"; + +export enum BattleSceneEventType { + MOVE_USED = "onMoveUsed" +} + +/** + * Container class for `onMoveUsed` events + * @extends Event +*/ +export class MoveUsedEvent extends Event { + /** The ID of the {@linkcode Pokemon} that used the {@linkcode Move} */ + public userId: number; + /** The {@linkcode Move} used */ + public move: Move; + /** The amount of PP used on the {@linkcode Move} this turn */ + public ppUsed: number; + constructor(userId: number, move: Move, ppUsed: number) { + super(BattleSceneEventType.MOVE_USED); + + this.userId = userId; + this.move = move; + this.ppUsed = ppUsed; + } +} diff --git a/src/battle-scene.ts b/src/battle-scene.ts index b4435ec5b26..2d403dad5ce 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -184,6 +184,14 @@ export default class BattleScene extends SceneBase { public rngSeedOverride: string = ""; public rngOffset: integer = 0; + /** + * Allows subscribers to listen for events + * + * Current Events: + * - {@linkcode BattleSceneEventType.MOVE_USED} {@linkcode MoveUsedEvent} + */ + public readonly eventTarget: EventTarget = new EventTarget(); + constructor() { super("battle"); this.phaseQueue = []; diff --git a/src/phases.ts b/src/phases.ts index 3189e670ebf..e132c3a911b 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -61,6 +61,7 @@ import { Abilities } from "./data/enums/abilities"; import * as Overrides from "./overrides"; import { TextStyle, addTextObject } from "./ui/text"; import { Type } from "./data/type"; +import { MoveUsedEvent } from "./battle-scene-events"; export class LoginPhase extends Phase { @@ -2466,8 +2467,9 @@ export class MovePhase extends BattlePhase { const moveQueue = this.pokemon.getMoveQueue(); if (this.cancelled || this.failed) { if (this.failed) { - this.move.usePp(ppUsed); - } // Only use PP if the move failed + this.move.usePp(ppUsed); // Only use PP if the move failed + this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed)); + } // Record a failed move so Abilities like Truant don't trigger next turn and soft-lock this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL }); @@ -2497,8 +2499,9 @@ export class MovePhase extends BattlePhase { return this.end(); } - if (!moveQueue.length || !moveQueue.shift().ignorePP) {// using .shift here clears out two turn moves once they've been used + if (!moveQueue.length || !moveQueue.shift().ignorePP) { // using .shift here clears out two turn moves once they've been used this.move.usePp(ppUsed); + this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed)); } if (!allMoves[this.move.moveId].getAttrs(CopyMoveAttr).length) {