Ticket #2130: endgame.diff

File endgame.diff, 5.6 KB (added by sanderd17, 11 years ago)
  • binaries/data/mods/public/simulation/components/EndGameManager.js

     
    1919    // Allied victory means allied players can win if victory conditions are met for each of them
    2020    // Would be false for a "last man standing" game (when diplomacy is fully implemented)
    2121    this.alliedVictory = true;
     22    this.activePlayers = [];
    2223};
    2324
    2425EndGameManager.prototype.SetGameType = function(newGameType)
     
    3132    this.alliedVictory = flag;
    3233};
    3334
    34 /**
    35  * Begin checking the end-game conditions.
    36  * Must be called once, after calling SetGameType.
    37  */
    38 EndGameManager.prototype.Start = function()
     35EndGameManager.prototype.OnUpdate = function()
    3936{
    40     if (this.gameType != "endless")
     37    if (this.gameType == "endless")
     38        return;
     39    // initialise the activePlayers array on the start of the game
     40    if (!this.activePlayers.length)
    4141    {
    42         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    43         this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, {});
     42        this.UpdatePlayerStates();
     43        return;
    4444    }
    45 };
    4645
    47 EndGameManager.prototype.OnDestroy = function()
    48 {
    49     if (this.timer)
    50     {
    51         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    52         cmpTimer.CancelTimer(this.timer);
    53     }
    54 };
     46    if (!this.activePlayers.every(function(v){return v.GetConquestCriticalEntitiesCount()}))
     47        this.UpdatePlayerStates();
     48}
    5549
    56 EndGameManager.prototype.ProgressTimeout = function(data)
     50EndGameManager.prototype.UpdatePlayerStates = function()
    5751{
    58     this.UpdatePlayerStates();
    59    
    60     // Repeat the timer
    61     var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    62     this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, data);
    63 };
     52    if (this.gameType == "endless")
     53        return;
    6454
    65 EndGameManager.prototype.UpdatePlayerStates = function()
    66 {
    6755    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    68     switch (this.gameType)
     56    var numPlayers = cmpPlayerManager.GetNumPlayers();
     57    this.activePlayers = [];
     58
     59    // get all the active players (or won). Defeat players without the needed entities
     60    for (var i = 1; i < numPlayers; ++i)
    6961    {
    70     case "conquest":
     62        var playerEntity = cmpPlayerManager.GetPlayerByID(i);
     63        var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player);
     64        if (cmpPlayer.GetState() == "defeated")
     65            continue;
     66        if (cmpPlayer.GetConquestCriticalEntitiesCount())
     67            this.activePlayers.push(cmpPlayer);
     68        else
     69            Engine.PostMessage(playerEntity, MT_PlayerDefeated);
     70    }
    7171
    72         // Ignore gaia
    73         var numPlayers = cmpPlayerManager.GetNumPlayers() - 1;
    74         var cmpPlayers = new Array(numPlayers);
    75        
    76         // If a player is currently active but has no suitable units left,
    77         // mark that player as defeated
    78         for (var i = 0; i < numPlayers; i++)
    79         {
    80             var playerEntityId = cmpPlayerManager.GetPlayerByID(i+1);
    81             cmpPlayers[i] = Engine.QueryInterface(playerEntityId, IID_Player);
    82             if (cmpPlayers[i].GetState() == "active")
    83             {
    84                 if (cmpPlayers[i].GetConquestCriticalEntitiesCount() == 0)
    85                 {   // Defeated - notify AIs by sending playerId
    86                     Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { "playerId": i } );
    87                 }
    88             }
    89         }
     72    if (!this.alliedVictory && this.activePlayers.length > 1)
     73        return;
    9074
    91         var onlyAlliesLeft = true;
    92         var allies = [];
    93         for (var i = 0; i < numPlayers && onlyAlliesLeft; i++)
    94         {
    95             if (cmpPlayers[i].GetState() == "active")
    96             {   //Active player
    97                 for (var j = 0; j < numPlayers && onlyAlliesLeft; j++)
    98                 {
    99                     if (cmpPlayers[j].GetState() == "active"
    100                         && (cmpPlayers[i].IsEnemy(j+1) || cmpPlayers[j].IsEnemy(i+1)
    101                             || cmpPlayers[i].IsNeutral(j+1) || cmpPlayers[j].IsNeutral(i+1)))
    102                     {   // Only need to find an active non-allied player
    103                         onlyAlliesLeft = false;
    104                     }
    105                 }
    106                
    107                 if (onlyAlliesLeft)
    108                     allies.push(i);
    109             }
    110         }
     75    for each (var cmpPlayer in this.activePlayers)
     76    {
     77        if (!this.activePlayers.every(function(v){return cmpPlayer == v || cmpPlayer.IsMutualAlly(v.GetPlayerID())}))
     78            return;
     79    }
    11180
    112         // If only allies left and allied victory set (or only one player left)
    113         if (onlyAlliesLeft && (this.alliedVictory || allies.length == 1))
    114         {
    115             for each (var p in allies)
    116             {
    117                 cmpPlayers[p].SetState("won");
    118             }
    119 
    120             // Reveal the map to all players
    121             var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    122             cmpRangeManager.SetLosRevealAll(-1, true);
    123         }
    124 
    125         break;
    126 
    127     default:
    128         error("Invalid game type "+this.gameType);
    129         break;
    130     }
     81    var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     82    cmpRangeManager.SetLosRevealAll(-1, true);
     83    for each (var cmpPlayer in this.activePlayers)
     84        cmpPlayer.SetState("won");
    13185};
    13286
    13387Engine.RegisterComponentType(IID_EndGameManager, "EndGameManager", EndGameManager);
  • binaries/data/mods/public/simulation/helpers/Setup.js

     
    4141    {
    4242        cmpEndGameManager.SetGameType(settings.GameType);
    4343    }
    44     cmpEndGameManager.Start();
    4544}
    4645
    4746Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);