2010-10-01 22:51:21 +02:00
|
|
|
// Repetition interval (msecs) for checking end game conditions
|
|
|
|
var g_ProgressInterval = 1000;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* System component which regularly checks victory/defeat conditions
|
|
|
|
* and if they are satisfied then it marks the player as victorious/defeated.
|
|
|
|
*/
|
|
|
|
function EndGameManager() {}
|
|
|
|
|
|
|
|
EndGameManager.prototype.Schema =
|
|
|
|
"<a:component type='system'/><empty/>";
|
|
|
|
|
|
|
|
EndGameManager.prototype.Init = function()
|
|
|
|
{
|
|
|
|
// Game type, initialised from the map settings.
|
|
|
|
// One of: "conquest" (default) and "endless"
|
|
|
|
this.gameType = "conquest";
|
2010-11-21 01:35:08 +01:00
|
|
|
|
|
|
|
// Allied victory means allied players can win if victory conditions are met for each of them
|
|
|
|
// Would be false for a "last man standing" game (when diplomacy is fully implemented)
|
|
|
|
this.alliedVictory = true;
|
2010-10-01 22:51:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
EndGameManager.prototype.SetGameType = function(newGameType)
|
|
|
|
{
|
|
|
|
this.gameType = newGameType;
|
2013-12-28 14:40:39 +01:00
|
|
|
Engine.BroadcastMessage(MT_GameTypeChanged, {});
|
|
|
|
};
|
|
|
|
|
|
|
|
EndGameManager.prototype.CheckGameType = function(type)
|
|
|
|
{
|
|
|
|
return this.gameType == type;
|
|
|
|
};
|
|
|
|
|
2013-12-29 11:01:39 +01:00
|
|
|
EndGameManager.prototype.MarkPlayerAsWon = function(playerID)
|
2013-12-28 14:40:39 +01:00
|
|
|
{
|
|
|
|
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
|
|
|
var numPlayers = cmpPlayerManager.GetNumPlayers();
|
|
|
|
for (var i = 1; i < numPlayers; i++)
|
|
|
|
{
|
|
|
|
var playerEntityId = cmpPlayerManager.GetPlayerByID(i);
|
|
|
|
var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
|
|
|
|
if (cmpPlayer.GetState() != "active")
|
|
|
|
continue;
|
2013-12-29 11:01:39 +01:00
|
|
|
if (playerID == cmpPlayer.GetPlayerID() || this.alliedVictory && cmpPlayer.IsMutualAlly(playerID))
|
2013-12-28 14:40:39 +01:00
|
|
|
cmpPlayer.SetState("won")
|
|
|
|
else
|
|
|
|
Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { "playerId": i } );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reveal the map to all players
|
|
|
|
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
2013-12-31 22:30:48 +01:00
|
|
|
cmpRangeManager.SetLosRevealAll(-1, true);
|
2010-10-01 22:51:21 +02:00
|
|
|
};
|
|
|
|
|
2010-11-21 01:35:08 +01:00
|
|
|
EndGameManager.prototype.SetAlliedVictory = function(flag)
|
|
|
|
{
|
|
|
|
this.alliedVictory = flag;
|
|
|
|
};
|
|
|
|
|
2013-11-09 11:09:28 +01:00
|
|
|
/*
|
|
|
|
* Check players the next turn. Avoids problems in Atlas, with promoting entities etc
|
|
|
|
*/
|
2013-12-29 11:01:39 +01:00
|
|
|
EndGameManager.prototype.CheckConquestCriticalEntities = function()
|
2013-11-09 11:09:28 +01:00
|
|
|
{
|
|
|
|
if (this.timeout)
|
|
|
|
return;
|
|
|
|
// wait a turn for actually checking the players
|
|
|
|
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
2013-12-29 11:01:39 +01:00
|
|
|
this.timeout = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "CheckConquestCriticalEntitiesNow", 100, null);
|
2013-11-09 11:09:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check players immediately. Might cause problems with converting/promoting entities.
|
|
|
|
*/
|
2013-12-29 11:01:39 +01:00
|
|
|
EndGameManager.prototype.CheckConquestCriticalEntitiesNow = function()
|
2010-10-01 22:51:21 +02:00
|
|
|
{
|
2013-11-09 11:09:28 +01:00
|
|
|
if (this.timeout)
|
|
|
|
this.timeout = null;
|
2013-11-05 20:40:50 +01:00
|
|
|
if (this.gameType == "endless")
|
|
|
|
return;
|
2010-10-01 22:51:21 +02:00
|
|
|
|
2013-11-05 20:40:50 +01:00
|
|
|
// for all other game types, defeat that player
|
2010-10-01 22:51:21 +02:00
|
|
|
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
2013-11-05 20:40:50 +01:00
|
|
|
|
|
|
|
// Ignore gaia
|
|
|
|
var numPlayers = cmpPlayerManager.GetNumPlayers();
|
|
|
|
var cmpPlayers = [];
|
|
|
|
|
|
|
|
var allies = [];
|
|
|
|
var onlyAlliesLeft = true;
|
|
|
|
// If the player is currently active but needs to be defeated,
|
|
|
|
// mark that player as defeated
|
|
|
|
// cache the cmpPlayer instances of the other players and search the allies
|
|
|
|
for (var i = 1; i < numPlayers; i++)
|
2010-10-01 22:51:21 +02:00
|
|
|
{
|
2013-11-05 20:40:50 +01:00
|
|
|
// cmpPlayer should always exist for the player ids from 1 to numplayers
|
|
|
|
// so no tests on the existance of cmpPlayer are needed
|
|
|
|
var playerEntityId = cmpPlayerManager.GetPlayerByID(i);
|
|
|
|
cmpPlayers[i] = Engine.QueryInterface(playerEntityId, IID_Player);
|
|
|
|
if (cmpPlayers[i].GetState() != "active")
|
|
|
|
continue;
|
2013-11-09 11:09:28 +01:00
|
|
|
if (cmpPlayers[i].GetConquestCriticalEntitiesCount() == 0)
|
2013-11-05 20:40:50 +01:00
|
|
|
Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { "playerId": i } );
|
|
|
|
else
|
2010-10-01 22:51:21 +02:00
|
|
|
{
|
2013-11-05 20:40:50 +01:00
|
|
|
if (!allies.length || cmpPlayers[allies[0]].IsMutualAlly(i))
|
|
|
|
allies.push(i);
|
|
|
|
else
|
|
|
|
onlyAlliesLeft = false;
|
2010-10-01 22:51:21 +02:00
|
|
|
}
|
2013-11-05 20:40:50 +01:00
|
|
|
}
|
2010-10-01 22:51:21 +02:00
|
|
|
|
2013-11-05 20:40:50 +01:00
|
|
|
// check if there are winners, or the game needs to continue
|
|
|
|
if (!allies.length || !onlyAlliesLeft || !(this.alliedVictory || allies.length == 1))
|
|
|
|
return;
|
2010-10-01 22:51:21 +02:00
|
|
|
|
2013-11-05 20:40:50 +01:00
|
|
|
for each (var p in allies)
|
|
|
|
cmpPlayers[p].SetState("won");
|
2010-10-01 22:51:21 +02:00
|
|
|
|
2013-11-05 20:40:50 +01:00
|
|
|
// Reveal the map to all players
|
|
|
|
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
|
|
|
cmpRangeManager.SetLosRevealAll(-1, true);
|
2010-10-01 22:51:21 +02:00
|
|
|
};
|
|
|
|
|
2014-05-18 15:44:08 +02:00
|
|
|
Engine.RegisterSystemComponentType(IID_EndGameManager, "EndGameManager", EndGameManager);
|