Source: TurnEngine.js

Source: TurnEngine.js

var ActionEngine = require('./ActionEngine');
var ComponentGroup = require('./ComponentGroup');
var Turn = require('./Turn');
 
/**
 * Represents an turn based game engine.
 * It's like a normal ECS with Action and Turn.
 * @constructor
 * @extends ActionEngine
 * @param {Boolean} [isServer=false] - Whether if it's a server or not
 * @see Action
 * @see Turn
 */
function TurnEngine(isServer) {
  ActionEngine.call(this, isServer);
  /**
   * An array holding all the {@link Turn} used in the game.
   * @var {Array}
   * @see Turn
   */
  this.turns = [];
  /**
   * An arraying holding all the player {@link Entity} in the game.
   * @var {Array}
   * @see Entity
   */
  this.players = this.getEntitiesFor('player');
}

TurnEngine.prototype = Object.create(ActionEngine.prototype);
TurnEngine.prototype.constructor = TurnEngine;

/**
 * Returns current Turn object.
 * It'll call {@link TurnEngine#nextTurn} if the game hasn't started yet.
 * @returns {Turn} The current Turn
 */
TurnEngine.prototype.getTurn = function() {
  if(this.turns.length == 0) {
    return this.nextTurn();
  }
  return this.turns[this.turns.length-1];
}

/**
 * Finishes the current Turn and starts next Turn.
 * @returns {Turn} The current Turn
 * @throws If there are no players in the game
 * @fires TurnEngine#gameInit
 * @fires TurnEngine#sequenceNext
 * @fires TurnEngine#turnNext
 */
TurnEngine.prototype.nextTurn = function() {
  this.sortSystems();
  if(this.turns.length == 0) {
    if(this.players[0] == null) {
      throw new Error('There should be at least one player in the game');
    }
    var turn = new Turn(0, 0, 0, this.players[0]);
    this.turns.push(turn);
    /**
     * This event is fired when the game starts.
     *
     * @event TurnEngine#gameInit
     * @type {Turn}
     */
    this.emit('gameInit', turn, this);
    /**
     * This event is fired when the sequence changes.
     *
     * @event TurnEngine#sequenceNext
     * @type {Turn}
     */
    this.emit('sequenceNext', turn, this);
    /**
     * This event is fired when the turn changes.
     *
     * @event TurnEngine#turnNext
     * @type {Turn}
     */
    this.emit('turnNext', turn, this);
    this.systems.forEach(function(system) {
      if(system.init) {
        system.init(turn, this);
      }
    }, this);
    this.systems.forEach(function(system) {
      if(system.sequence) {
        system.sequence(turn, this);
      }
    }, this);
    this.systems.forEach(function(system) {
      if(system.turn) {
        system.turn(turn, this);
      }
    }, this);
    return turn;
  }
  // 원래 있던 턴 객체의 플레이어 인덱스 + 1
  var prevTurn = this.getTurn();
  var seqId = prevTurn.seqId;
  var id = prevTurn.id;
  var order = this.players.indexOf(prevTurn.player) + 1;
  if(order >= this.players.length) {
    seqId ++;
    order = 0;
  }
  var turn = new Turn(id + 1, order, seqId, this.players[order]);
  this.turns.push(turn);
  if(order == 0) {
    this.emit('sequenceNext', turn, this);
    this.systems.forEach(function(system) {
      if(system.sequence) {
        system.sequence(turn, this);
      }
    }, this);
  }
  this.emit('turnNext', turn, this);
  this.systems.forEach(function(system) {
    if(system.turn) {
      system.turn(turn, this);
    }
  }, this);
  return turn;
}

if(typeof module !== 'undefined') {
  module.exports = TurnEngine;
}