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;
}