core/event.js

/**
 * A cancellable game event passed to piece callbacks.
 * Carries a reference to the current player and board so callbacks can
 * read game state and fire messages without needing to import Game.
 */
export class GameEvent {
  /** @param {Player} player @param {Board} board */
  constructor(player, board) {
    this.player = player;
    this.board = board;
    this._cancelled = false;
    this._cancelMessage = null;
    this._cancelCell = null;
    this._kills = null;
  }

  /**
   * Record that an agent has been killed (changeHealth returned 0).
   * Callers are responsible for removing the agent from the board after
   * processing all callbacks.
   * @param {Cell} cell
   * @param {object} agent
   */
  kill(cell, agent) {
    if (!this._kills) this._kills = [];
    this._kills.push({ cell, agent });
  }

  /** @returns {Array<{cell: Cell, agent: object}>|null} */
  get kills() {
    return this._kills;
  }

  /** Cancel this event (prevents the default action). */
  cancel() {
    this._cancelled = true;
  }

  /**
   * Cancel and queue a message to display to the player.
   * @param {string|Cell} cellOrMessage
   * @param {string} [message]
   */
  cancelWithMessage(cellOrMessage, message) {
    this._cancelled = true;
    if (message !== undefined) {
      // Called as cancel(cell, message)
      this._cancelCell = cellOrMessage;
      this._cancelMessage = message;
    } else {
      // Called as cancel(message)
      this._cancelMessage = cellOrMessage;
    }
  }

  /** True if the event has been cancelled. */
  get isCancelled() {
    return this._cancelled;
  }

  /** Allow a cancelled event to proceed (used by Game controller). */
  suppressCancel() {
    this._cancelled = false;
    this._cancelMessage = null;
  }
}