Index: binaries/data/mods/public/gui/summary/counters.js =================================================================== --- binaries/data/mods/public/gui/summary/counters.js +++ binaries/data/mods/public/gui/summary/counters.js @@ -24,10 +24,10 @@ return ret; } -function getPlayerValuesPerTeam(team, index, type, counters, headings) +function getPlayerValuesPerTeam(team, index, type, counters, headings, summarize) { let fn = counters[headings.map(heading => heading.identifier).indexOf(type) - 1].fn; - return g_Teams[team].map(player => fn(g_GameData.sim.playerStates[player], index, type)); + return g_Teams[team].map(player => fn(g_GameData.sim.playerStates[player], index, type, summarize)); } function updateCountersPlayer(playerState, allCounters, allHeadings, idGUI, index) @@ -38,7 +38,7 @@ { let fn = counters[n].fn; Engine.GetGUIObjectByName(idGUI + "[" + n + "]").caption = - formatSummaryValue(fn && fn(playerState, index, headings[+n + 1].identifier)); + formatSummaryValue(fn && fn(playerState, index, headings[+n + 1].identifier, true)); } } @@ -53,7 +53,7 @@ for (let n in counters) Engine.GetGUIObjectByName("valueDataTeam[" + team + "][" + n + "]").caption = - formatSummaryValue(teamFn(team, index, headings[+n + 1].identifier, counters, headings)); + formatSummaryValue(teamFn(team, index, headings[+n + 1].identifier, counters, headings, true)); } } @@ -88,6 +88,14 @@ }); } +function peakSummary(data, index) +{ + let m = -Infinity; + for(let i = 0; i < index && i < data.length; ++i) + m = Math.max(m, data[i]); + return m; +} + function calculateTeamCounterDataHelper() { for (let i = 0; i < g_PlayerCount; ++i) @@ -169,7 +177,7 @@ calculateExplorationScore(playerState, index); } -function calculateScoreTeam(team, index, type, counters, headings) +function calculateScoreTeam(team, index, type, counters, headings, summarize) { if (type == "explorationScore") return g_TeamHelperData[team].mapExploration[index] * 10; @@ -178,7 +186,7 @@ t => calculateScoreTeam(team, index, t, counters, headings)).reduce( (sum, value) => sum + value); - return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings)); + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); } function calculateBuildings(playerState, index, type) @@ -191,14 +199,19 @@ }; } -function calculateBuildingsTeam(team, index, type, counters, headings) +function calculateBuildingsTeam(team, index, type, counters, headings, summarize) { - return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings)); + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); } -function calculateUnitsTeam(team, index, type, counters, headings) +function calculateUnitsTeam(team, index, type, counters, headings, summarize) { - return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings)); + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); +} + +function calculatePopulationTeam(team, index, type, counters, headings, summarize) +{ + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); } function calculateUnitsWithCaptured(playerState, index, type) @@ -220,6 +233,16 @@ }; } +function calculatePopulation(playerState, index, type, summarize) +{ + let data = { + "population": playerState.sequences.population[type][index] + }; + if(summarize) + data.populationPeak = peakSummary(playerState.sequences.population[type], index); + return data; +} + function calculateResources(playerState, index, type) { return { @@ -268,9 +291,9 @@ return playerState.sequences.unitsTrained.Domestic[index]; } -function calculateResourcesTeam(team, index, type, counters, headings) +function calculateResourcesTeam(team, index, type, counters, headings, summarize) { - return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings)); + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); } function calculateResourceExchanged(playerState, index, type) @@ -300,12 +323,12 @@ return playerState.sequences.tradeIncome[index]; } -function calculateMarketTeam(team, index, type, counters, headings) +function calculateMarketTeam(team, index, type, counters, headings, summarize) { if (type == "barterEfficency") return calculatePercent(g_TeamHelperData[team].totalBought[index], g_TeamHelperData[team].totalSold[index]); - return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings)); + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); } function calculateVegetarianRatio(playerState, index) @@ -329,11 +352,6 @@ playerState.sequences.unitsLost.total[index]); } -function calculatePopulationCount(playerState, index) -{ - return { "population": playerState.sequences.populationCount[index] }; -} - function calculateMapExploration(playerState, index) { return { "percent": playerState.sequences.percentMapExplored[index] }; @@ -349,7 +367,7 @@ return { "percent": playerState.sequences.peakPercentMapControlled[index] }; } -function calculateMiscellaneousTeam(team, index, type, counters, headings) +function calculateMiscellaneousTeam(team, index, type, counters, headings, summarize) { if (type == "vegetarianRatio") return calculatePercent(g_TeamHelperData[team].vegetarianFood[index], g_TeamHelperData[team].food[index]); @@ -360,8 +378,8 @@ if (type == "killDeath") return calculateRatio(g_TeamHelperData[team].enemyUnitsKilled[index], g_TeamHelperData[team].unitsLost[index]); - if (type == "bribes" || type == "population") - return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings)); + if (type == "bribes") + return summaryArraySum(getPlayerValuesPerTeam(team, index, type, counters, headings, summarize)); return { "percent": g_TeamHelperData[team][type][index] }; } Index: binaries/data/mods/public/gui/summary/layout.js =================================================================== --- binaries/data/mods/public/gui/summary/layout.js +++ binaries/data/mods/public/gui/summary/layout.js @@ -105,6 +105,44 @@ ], "teamCounterFn": calculateUnitsTeam }, + { + "label": translate("Population"), + "headings": [ + { "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 }, + { "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 105 }, + { "identifier": "limit", "caption": translate("Limit"), "yStart": 34, "width": 85 }, + { "identifier": "FemaleCitizen", "caption": translate("Female Citizen"), "yStart": 34, "width": 85 }, + { "identifier": "Infantry", "caption": translate("Infantry"), "yStart": 34, "width": 85 }, + { "identifier": "Cavalry", "caption": translate("Cavalry"), "yStart": 34, "width": 85 }, + { "identifier": "Champion", "caption": translate("Champion"), "yStart": 34, "width": 85 }, + { "identifier": "Siege", "caption": translate("Siege"), "yStart": 34, "width": 85 }, + { "identifier": "Ship", "caption": translate("Navy"), "yStart": 34, "width": 85 }, + { "identifier": "Trader", "caption": translate("Traders"), "yStart": 34, "width": 85 } + ], + "titleHeadings": [ + { + "caption": sprintf(translate("(%(current)s / %(peak)s)"), + { + "current": getColoredTypeTranslation("population"), + "peak": getColoredTypeTranslation("populationPeak"), + }), + "yStart": 16, + "width": 85 * 8 + 105 + }, + ], + "counters": [ + { "width": 105, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 }, + { "width": 85, "fn": calculatePopulation, "verticalOffset": 3 } + ], + "teamCounterFn": calculatePopulationTeam + }, { "label": translate("Resources"), "headings": [ @@ -193,7 +231,6 @@ "headings": [ { "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 }, { "identifier": "killDeath", "caption": translate("Kill / Death ratio"), "yStart": 16, "width": 100, "format": "DECIMAL2" }, - { "identifier": "population", "caption": translate("Population"), "yStart": 16, "width": 100, "hideInSummary": true }, { "identifier": "mapControlPeak", "caption": translate("Map control (peak)"), "yStart": 16, "width": 100, "format": "PERCENTAGE" }, { "identifier": "mapControl", "caption": translate("Map control (finish)"), "yStart": 16, "width": 100, "format": "PERCENTAGE" }, { "identifier": "mapExploration", "caption": translate("Map exploration"), "yStart": 16, "width": 100, "format": "PERCENTAGE" }, @@ -214,7 +251,6 @@ "titleHeadings": [], "counters": [ { "width": 100, "fn": calculateKillDeathRatio, "verticalOffset": 12 }, - { "width": 100, "fn": calculatePopulationCount, "verticalOffset": 12, "hideInSummary": true }, { "width": 100, "fn": calculateMapPeakControl, "verticalOffset": 12 }, { "width": 100, "fn": calculateMapFinalControl, "verticalOffset": 12 }, { "width": 100, "fn": calculateMapExploration, "verticalOffset": 12 }, Index: binaries/data/mods/public/gui/summary/summary.js =================================================================== --- binaries/data/mods/public/gui/summary/summary.js +++ binaries/data/mods/public/gui/summary/summary.js @@ -95,8 +95,13 @@ "postfix": "" }, "population": { - "color": g_TypeColors.red, + "color": g_TypeColors.white, "caption": translate("Population"), + "postfix": " / " + }, + "populationPeak": { + "color": g_TypeColors.green, + "caption": translate("Population peak"), "postfix": "" }, "sold": { @@ -347,7 +352,7 @@ for (let index in g_GameData.sim.playerStates[1].sequences.time) { let value = g_ScorePanelsData[category].teamCounterFn(team, index, item, - g_ScorePanelsData[category].counters, g_ScorePanelsData[category].headings); + g_ScorePanelsData[category].counters, g_ScorePanelsData[category].headings, false); if (type) value = value[type]; data.push({ "x": g_GameData.sim.playerStates[1].sequences.time[index], "y": value }); @@ -361,7 +366,7 @@ let data = []; for (let index in playerState.sequences.time) { - let value = g_ScorePanelsData[category].counters[itemNumber].fn(playerState, index, item); + let value = g_ScorePanelsData[category].counters[itemNumber].fn(playerState, index, item, false); if (type) value = value[type]; data.push({ "x": playerState.sequences.time[index], "y": value }); Index: binaries/data/mods/public/simulation/components/StatisticsTracker.js =================================================================== --- binaries/data/mods/public/simulation/components/StatisticsTracker.js +++ binaries/data/mods/public/simulation/components/StatisticsTracker.js @@ -141,7 +141,7 @@ "tradeIncome": this.tradeIncome, "treasuresCollected": this.treasuresCollected, "lootCollected": this.lootCollected, - "populationCount": this.GetPopulationCount(), + "population": this.GetCurrentPopulation(), "percentMapExplored": this.GetPercentMapExplored(), "teamPercentMapExplored": this.GetTeamPercentMapExplored(), "percentMapControlled": this.GetPercentMapControlled(), @@ -416,10 +416,42 @@ this.tradeIncome += amount; }; -StatisticsTracker.prototype.GetPopulationCount = function() +StatisticsTracker.prototype.GetCurrentPopulation = function() { + let activeUnits = { + "total": 0, + "limit": 0 + }; + for (let unitClass of this.unitsClasses) + activeUnits[unitClass] = 0; + let cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); - return cmpPlayer ? cmpPlayer.GetPopulationCount() : 0; + if(!cmpPlayer) + return activeUnits; + + activeUnits.total = cmpPlayer.GetPopulationCount(); + activeUnits.limit = cmpPlayer.GetPopulationLimit(); + + let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + for(let entity of cmpRangeManager.GetEntitiesByPlayer(cmpPlayer.playerID)) + { + let entityIdentity = Engine.QueryInterface(entity, IID_Identity); + let classes = entityIdentity.GetClassesList(); + let popcost = -1; + + for (let unitClass of this.unitsClasses) + if(classes.indexOf(unitClass) != -1) + { + if(popcost == -1) + { + let entityCost = Engine.QueryInterface(entity, IID_Cost); + popcost = entityCost.GetPopCost(); + } + activeUnits[unitClass] += popcost; + } + } + + return activeUnits; }; StatisticsTracker.prototype.IncreaseSuccessfulBribesCounter = function()