diff --git a/binaries/data/mods/public/gui/summary/summary.js b/binaries/data/mods/public/gui/summary/summary.js index 0ae2d0046c..8cf9a59f7f 100644 --- a/binaries/data/mods/public/gui/summary/summary.js +++ b/binaries/data/mods/public/gui/summary/summary.js @@ -787,8 +787,7 @@ function init(data) sumVegetarianRatio(); sumFeminisation(); sumKillDeathRatio(); - // TODO: probably change from simple sum to union from range manager - panels.miscelanous.counters.mapExploration.teamsScores[playerState.team] += playerState.statistics.percentMapExplored; + panels.miscelanous.counters.mapExploration.teamsScores[playerState.team] = playerState.statistics.teamPercentMapExplored; panels.miscelanous.counters.mapExploration.teamsScoresCaption[playerState.team] = panels.miscelanous.counters.mapExploration.teamsScores[playerState.team] + "%"; } diff --git a/binaries/data/mods/public/simulation/components/AIInterface.js b/binaries/data/mods/public/simulation/components/AIInterface.js index c6c1621ccb..3e06e585cd 100644 --- a/binaries/data/mods/public/simulation/components/AIInterface.js +++ b/binaries/data/mods/public/simulation/components/AIInterface.js @@ -40,7 +40,7 @@ AIInterface.prototype.GetNonEntityRepresentation = function() var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); // Return the same game state as the GUI uses - var state = cmpGuiInterface.GetExtendedSimulationState(-1); + var state = cmpGuiInterface.GetSimulationState(-1); // Add some extra AI-specific data // add custom events and reset them for the next turn diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js index 6ce4c39ecb..6a70d26772 100644 --- a/binaries/data/mods/public/simulation/components/GuiInterface.js +++ b/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -119,13 +119,23 @@ GuiInterface.prototype.GetSimulationState = function(player) var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); ret.timeElapsed = cmpTimer.GetTime(); - // and the game type + // Add the game type var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); ret.gameType = cmpEndGameManager.GetGameType(); + // Add bartering prices + var cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); + ret.barterPrices = cmpBarter.GetPrices(); + return ret; }; +/** + * Returns global information about the current game state, plus statistics. + * This is used by the GUI at the end of a game, in the summary screen. + * Note: Amongst statistics, the team exploration map percentage is computed from + * scratch, so the extended simulation state should not be requested too often. + */ GuiInterface.prototype.GetExtendedSimulationState = function(player) { // Get basic simulation info @@ -141,10 +151,6 @@ GuiInterface.prototype.GetExtendedSimulationState = function(player) ret.players[i].statistics = cmpPlayerStatisticsTracker.GetStatistics(); } - // Add bartering prices - var cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); - ret.barterPrices = cmpBarter.GetPrices(); - return ret; }; diff --git a/binaries/data/mods/public/simulation/components/StatisticsTracker.js b/binaries/data/mods/public/simulation/components/StatisticsTracker.js index 7a7e62b24b..41d351996e 100644 --- a/binaries/data/mods/public/simulation/components/StatisticsTracker.js +++ b/binaries/data/mods/public/simulation/components/StatisticsTracker.js @@ -142,7 +142,8 @@ StatisticsTracker.prototype.GetStatistics = function() "tributesReceived": this.tributesReceived, "tradeIncome": this.tradeIncome, "treasuresCollected": this.treasuresCollected, - "percentMapExplored": this.GetPercentMapExplored() + "percentMapExplored": this.GetPercentMapExplored(), + "teamPercentMapExplored": this.GetTeamPercentMapExplored() }; }; @@ -336,4 +337,33 @@ StatisticsTracker.prototype.GetPercentMapExplored = function() return cmpRangeManager.GetPercentMapExplored(cmpPlayer.GetPlayerID()); }; +/** + * Note: cmpRangeManager.GetUnionPercentMapExplored computes statistics from scratch! + * As a consequence, this function should not be called too often. + */ +StatisticsTracker.prototype.GetTeamPercentMapExplored = function() +{ + var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + + var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); + var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); + if (!cmpPlayer) + return 0; + + var team = cmpPlayer.GetTeam(); + // If teams are not locked, this statistic won't be displayed, so don't bother computing + if (team == -1 || !cmpPlayer.GetLockTeams()) + return cmpRangeManager.GetPercentMapExplored(cmpPlayer.GetPlayerID()); + + var teamPlayers = []; + for (var i = 1; i < cmpPlayerManager.GetNumPlayers(); ++i) + { + let cmpOtherPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player); + if (cmpOtherPlayer && cmpOtherPlayer.GetTeam() == team) + teamPlayers.push(i); + } + + return cmpRangeManager.GetUnionPercentMapExplored(teamPlayers); +}; + Engine.RegisterComponentType(IID_StatisticsTracker, "StatisticsTracker", StatisticsTracker); diff --git a/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js b/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js index 6dc379098f..4c9a36b295 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js +++ b/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js @@ -117,6 +117,7 @@ AddMock(100, IID_StatisticsTracker, { }, "treasuresCollected": 0, "percentMapExplored": 10, + "teamPercentMapExplored": 10 }; }, IncreaseTrainedUnitsCounter: function() { return 1; }, @@ -180,6 +181,7 @@ AddMock(101, IID_StatisticsTracker, { }, "treasuresCollected": 0, "percentMapExplored": 10, + "teamPercentMapExplored": 10 }; }, IncreaseTrainedUnitsCounter: function() { return 1; }, @@ -254,6 +256,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), { circularMap: false, timeElapsed: 0, gameType: "conquest", + barterPrices: {buy: {food: 150}, sell: {food: 25}} }); TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), { @@ -301,6 +304,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), { }, treasuresCollected: 0, percentMapExplored: 10, + teamPercentMapExplored: 10 }, }, { @@ -346,6 +350,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), { }, treasuresCollected: 0, percentMapExplored: 10, + teamPercentMapExplored: 10 }, } ], diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp index df0a8ab3a9..b4988b9c3e 100644 --- a/source/simulation2/components/CCmpRangeManager.cpp +++ b/source/simulation2/components/CCmpRangeManager.cpp @@ -2048,6 +2048,32 @@ public: { return m_ExploredVertices.at((u8)player) * 100 / m_TotalInworldVertices; } + + virtual u8 GetUnionPercentMapExplored(std::vector players) + { + u32 exploredVertices = 0; + std::vector::iterator playerIt; + + for (i32 j = 0; j < m_TerrainVerticesPerSide; j++) + { + for (i32 i = 0; i < m_TerrainVerticesPerSide; i++) + { + if (LosIsOffWorld(i, j)) + continue; + + for (playerIt = players.begin(); playerIt != players.end(); ++playerIt) + { + if (m_LosState[j*m_TerrainVerticesPerSide + i] & (LOS_EXPLORED << (2*((*playerIt)-1)))) + { + exploredVertices += 1; + break; + } + } + } + } + + return exploredVertices * 100 / m_TotalInworldVertices; + } }; REGISTER_COMPONENT_TYPE(RangeManager) diff --git a/source/simulation2/components/ICmpRangeManager.cpp b/source/simulation2/components/ICmpRangeManager.cpp index 99edb7e0f7..8f34c0b39d 100644 --- a/source/simulation2/components/ICmpRangeManager.cpp +++ b/source/simulation2/components/ICmpRangeManager.cpp @@ -56,4 +56,5 @@ DEFINE_INTERFACE_METHOD_1("SetLosCircular", void, ICmpRangeManager, SetLosCircul DEFINE_INTERFACE_METHOD_0("GetLosCircular", bool, ICmpRangeManager, GetLosCircular) DEFINE_INTERFACE_METHOD_2("SetSharedLos", void, ICmpRangeManager, SetSharedLos, player_id_t, std::vector) DEFINE_INTERFACE_METHOD_1("GetPercentMapExplored", u8, ICmpRangeManager, GetPercentMapExplored, player_id_t) +DEFINE_INTERFACE_METHOD_1("GetUnionPercentMapExplored", u8, ICmpRangeManager, GetUnionPercentMapExplored, std::vector) END_INTERFACE_WRAPPER(RangeManager) diff --git a/source/simulation2/components/ICmpRangeManager.h b/source/simulation2/components/ICmpRangeManager.h index 4f4545899f..437734f12a 100644 --- a/source/simulation2/components/ICmpRangeManager.h +++ b/source/simulation2/components/ICmpRangeManager.h @@ -380,6 +380,12 @@ public: */ virtual u8 GetPercentMapExplored(player_id_t player) = 0; + /** + * Get percent map explored statistics for specified set of players. + * Note: this function computes statistics from scratch and should not be called too often. + */ + virtual u8 GetUnionPercentMapExplored(std::vector players) = 0; + /** * Perform some internal consistency checks for testing/debugging.