mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Show all summary values as a graph
Reviewed by: bb Differential Revision: https://code.wildfiregames.com/D144 This was SVN commit r19517.
This commit is contained in:
parent
2f67b2da61
commit
4a0673e44e
8 changed files with 795 additions and 483 deletions
|
|
@ -1467,6 +1467,15 @@ function reportGame()
|
|||
"resourcesBought"
|
||||
];
|
||||
|
||||
let misc = [
|
||||
"tradeIncome",
|
||||
"tributesSent",
|
||||
"tributesReceived",
|
||||
"treasuresCollected",
|
||||
"lootCollected",
|
||||
"percentMapExplored"
|
||||
];
|
||||
|
||||
let playerStatistics = {};
|
||||
|
||||
// Unit Stats
|
||||
|
|
@ -1501,19 +1510,13 @@ function reportGame()
|
|||
}
|
||||
playerStatistics.resourcesGathered.vegetarianFood = "";
|
||||
|
||||
playerStatistics.tradeIncome = "";
|
||||
// Tribute
|
||||
playerStatistics.tributesSent = "";
|
||||
playerStatistics.tributesReceived = "";
|
||||
for (let type of misc)
|
||||
playerStatistics[type] = "";
|
||||
|
||||
// Total
|
||||
playerStatistics.economyScore = "";
|
||||
playerStatistics.militaryScore = "";
|
||||
playerStatistics.totalScore = "";
|
||||
// Various
|
||||
playerStatistics.treasuresCollected = "";
|
||||
playerStatistics.lootCollected = "";
|
||||
playerStatistics.feminisation = "";
|
||||
playerStatistics.percentMapExplored = "";
|
||||
|
||||
let mapName = g_GameAttributes.settings.Name;
|
||||
let playerStates = "";
|
||||
|
|
@ -1526,6 +1529,7 @@ function reportGame()
|
|||
for (let i = 1; i < extendedSimState.players.length; ++i)
|
||||
{
|
||||
let player = extendedSimState.players[i];
|
||||
let maxIndex = player.sequences.time.length - 1;
|
||||
|
||||
playerStates += player.state + ",";
|
||||
playerCivs += player.civ + ",";
|
||||
|
|
@ -1533,31 +1537,28 @@ function reportGame()
|
|||
teamsLocked = teamsLocked && player.teamsLocked;
|
||||
for (let resourcesCounterType of resourcesCounterTypes)
|
||||
for (let resourcesType of resourcesTypes)
|
||||
playerStatistics[resourcesCounterType][resourcesType] += player.statistics[resourcesCounterType][resourcesType] + ",";
|
||||
playerStatistics.resourcesGathered.vegetarianFood += player.statistics.resourcesGathered.vegetarianFood + ",";
|
||||
playerStatistics[resourcesCounterType][resourcesType] += player.sequences[resourcesCounterType][resourcesType][maxIndex] + ",";
|
||||
playerStatistics.resourcesGathered.vegetarianFood += player.sequences.resourcesGathered.vegetarianFood[maxIndex] + ",";
|
||||
|
||||
for (let unitCounterType of unitsCountersTypes)
|
||||
for (let unitsClass of unitsClasses)
|
||||
playerStatistics[unitCounterType][unitsClass] += player.statistics[unitCounterType][unitsClass] + ",";
|
||||
playerStatistics[unitCounterType][unitsClass] += player.sequences[unitCounterType][unitsClass][maxIndex] + ",";
|
||||
|
||||
for (let buildingCounterType of buildingsCountersTypes)
|
||||
for (let buildingsClass of buildingsClasses)
|
||||
playerStatistics[buildingCounterType][buildingsClass] += player.statistics[buildingCounterType][buildingsClass] + ",";
|
||||
playerStatistics[buildingCounterType][buildingsClass] += player.sequences[buildingCounterType][buildingsClass][maxIndex] + ",";
|
||||
let total = 0;
|
||||
for (let type in player.statistics.resourcesGathered)
|
||||
total += player.statistics.resourcesGathered[type];
|
||||
for (let type in player.sequences.resourcesGathered)
|
||||
total += player.sequences.resourcesGathered[type][maxIndex];
|
||||
|
||||
playerStatistics.economyScore += total + ",";
|
||||
playerStatistics.militaryScore += Math.round((player.statistics.enemyUnitsKilledValue +
|
||||
player.statistics.enemyBuildingsDestroyedValue) / 10) + ",";
|
||||
playerStatistics.totalScore += (total + Math.round((player.statistics.enemyUnitsKilledValue +
|
||||
player.statistics.enemyBuildingsDestroyedValue) / 10)) + ",";
|
||||
playerStatistics.tradeIncome += player.statistics.tradeIncome + ",";
|
||||
playerStatistics.tributesSent += player.statistics.tributesSent + ",";
|
||||
playerStatistics.tributesReceived += player.statistics.tributesReceived + ",";
|
||||
playerStatistics.percentMapExplored += player.statistics.percentMapExplored + ",";
|
||||
playerStatistics.treasuresCollected += player.statistics.treasuresCollected + ",";
|
||||
playerStatistics.lootCollected += player.statistics.lootCollected + ",";
|
||||
playerStatistics.militaryScore += Math.round((player.sequences.enemyUnitsKilledValue[maxIndex] +
|
||||
player.sequences.enemyBuildingsDestroyedValue[maxIndex]) / 10) + ",";
|
||||
playerStatistics.totalScore += (total + Math.round((player.sequences.enemyUnitsKilledValue[maxIndex] +
|
||||
player.sequences.enemyBuildingsDestroyedValue[maxIndex]) / 10)) + ",";
|
||||
|
||||
for (let type of misc)
|
||||
playerStatistics[type] += player.sequences[type][maxIndex] + ",";
|
||||
}
|
||||
|
||||
// Send the report with serialized data
|
||||
|
|
@ -1595,12 +1596,8 @@ function reportGame()
|
|||
reportObject[(type.substr(0,1)).toLowerCase()+type.substr(1)+"BuildingsLost"] = playerStatistics.buildingsLost[type];
|
||||
reportObject["enemy"+type+"BuildingsDestroyed"] = playerStatistics.enemyBuildingsDestroyed[type];
|
||||
}
|
||||
reportObject.tributesSent = playerStatistics.tributesSent;
|
||||
reportObject.tributesReceived = playerStatistics.tributesReceived;
|
||||
reportObject.percentMapExplored = playerStatistics.percentMapExplored;
|
||||
reportObject.treasuresCollected = playerStatistics.treasuresCollected;
|
||||
reportObject.lootCollected = playerStatistics.lootCollected;
|
||||
reportObject.tradeIncome = playerStatistics.tradeIncome;
|
||||
for (let type of misc)
|
||||
reportObject[type] = playerStatistics[type];
|
||||
|
||||
Engine.SendGameReport(reportObject);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,44 +5,27 @@ function resetDataHelpers()
|
|||
g_TeamHelperData = [];
|
||||
}
|
||||
|
||||
function formatTrained(trained, killed, lost)
|
||||
function calculatePercent(divident, divisor)
|
||||
{
|
||||
return g_TrainedColor + trained + '[/color] / ' +
|
||||
g_KilledColor + killed + '[/color] / ' +
|
||||
g_LostColor + lost + '[/color]';
|
||||
return { "percent": divisor ? Math.floor(100 * divident / divisor) : 0 };
|
||||
}
|
||||
|
||||
function formatCaptured(constructed, destroyed, captured, lost)
|
||||
function calculateRatio(divident, divisor)
|
||||
{
|
||||
return g_TrainedColor + constructed + '[/color] / ' +
|
||||
g_KilledColor + destroyed + '[/color]\n' +
|
||||
g_CapturedColor + captured + '[/color] / ' +
|
||||
g_LostColor + lost + '[/color]\n';
|
||||
return divident ? +((divident / divisor).toFixed(2)) : 0;
|
||||
}
|
||||
|
||||
function formatIncome(income, outcome)
|
||||
function formatSummaryValue(values)
|
||||
{
|
||||
return g_IncomeColor + income + '[/color] / ' +
|
||||
g_OutcomeColor + outcome + '[/color]';
|
||||
}
|
||||
if (typeof values != "object")
|
||||
return values === Infinity ? g_InfinitySymbol : values;
|
||||
|
||||
function formatPercent(divident, divisor)
|
||||
{
|
||||
if (!divisor)
|
||||
return "0%";
|
||||
|
||||
return Math.floor(100 * divident / divisor) + "%";
|
||||
}
|
||||
|
||||
function formatRatio(divident, divisor)
|
||||
{
|
||||
if (!divident)
|
||||
return "0.00";
|
||||
|
||||
if (!divisor)
|
||||
return g_InfiniteSymbol;
|
||||
|
||||
return Math.round(divident / divisor * 100) / 100;
|
||||
let ret = "";
|
||||
for (let type in values)
|
||||
ret += (g_SummaryTypes[type].color ?
|
||||
'[color="' + g_SummaryTypes[type].color + '"]' + values[type] + '[/color]' :
|
||||
values[type]) + g_SummaryTypes[type].postfix;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,83 +42,90 @@ function cleanGUICaption(team, player, counter, removeLineFeed = true)
|
|||
return caption.replace(/\[([\w\' \\\"\/\=]*)\]|[\t\r \f]/g, "");
|
||||
}
|
||||
|
||||
function updateCountersPlayer(playerState, counters, idGUI)
|
||||
function updateCountersPlayer(playerState, counters, headings, idGUI)
|
||||
{
|
||||
let index = playerState.sequences.time.length - 1;
|
||||
for (let w in counters)
|
||||
{
|
||||
let fn = counters[w].fn;
|
||||
Engine.GetGUIObjectByName(idGUI + "[" + w + "]").caption = fn && fn(playerState, w);
|
||||
Engine.GetGUIObjectByName(idGUI + "[" + w + "]").caption = formatSummaryValue(fn && fn(playerState, index, headings[+w+1].identifier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two arrays element-wise. So addArray([1, 2], [7, 42]) will result in [8, 44].
|
||||
*
|
||||
* @param {Array} array1 - first summand array.
|
||||
* @param {Array} array2 - second summand array.
|
||||
* @returns {Array} the element-wise sum of array1 and array2.
|
||||
*/
|
||||
function addArray(array1, array2)
|
||||
{
|
||||
array1 = array1.map((value, index) => value + array2[index]);
|
||||
}
|
||||
|
||||
// Updates g_TeamHelperData by appending some data from playerState
|
||||
function calculateTeamCounters(playerState)
|
||||
{
|
||||
if (!g_TeamHelperData[playerState.team])
|
||||
g_TeamHelperData[playerState.team] = {
|
||||
"food": 0,
|
||||
"vegetarianFood": 0,
|
||||
"femaleCitizen": 0,
|
||||
"worker": 0,
|
||||
"enemyUnitsKilled": 0,
|
||||
"unitsLost": 0,
|
||||
"percentMapControlled": 0,
|
||||
"peakPercentMapControlled": 0,
|
||||
"percentMapExplored": 0,
|
||||
"totalBought": 0,
|
||||
"totalSold": 0
|
||||
};
|
||||
{
|
||||
g_TeamHelperData[playerState.team] = {};
|
||||
for (let value of ["food", "vegetarianFood", "femaleCitizen", "worker", "enemyUnitsKilled",
|
||||
"unitsLost", "percentMapControlled", "peakPercentMapControlled",
|
||||
"percentMapExplored", "totalBought", "totalSold"])
|
||||
g_TeamHelperData[playerState.team][value] = new Array(playerState.sequences.time.length).fill(0);
|
||||
}
|
||||
|
||||
g_TeamHelperData[playerState.team].food += playerState.statistics.resourcesGathered.food;
|
||||
g_TeamHelperData[playerState.team].vegetarianFood += playerState.statistics.resourcesGathered.vegetarianFood;
|
||||
addArray(g_TeamHelperData[playerState.team].food, playerState.sequences.resourcesGathered.food);
|
||||
addArray(g_TeamHelperData[playerState.team].vegetarianFood, playerState.sequences.resourcesGathered.vegetarianFood);
|
||||
|
||||
g_TeamHelperData[playerState.team].femaleCitizen += playerState.statistics.unitsTrained.FemaleCitizen;
|
||||
g_TeamHelperData[playerState.team].worker += playerState.statistics.unitsTrained.Worker;
|
||||
addArray(g_TeamHelperData[playerState.team].femaleCitizen, playerState.sequences.unitsTrained.FemaleCitizen);
|
||||
addArray(g_TeamHelperData[playerState.team].worker, playerState.sequences.unitsTrained.Worker);
|
||||
|
||||
g_TeamHelperData[playerState.team].enemyUnitsKilled += playerState.statistics.enemyUnitsKilled.total;
|
||||
g_TeamHelperData[playerState.team].unitsLost += playerState.statistics.unitsLost.total;
|
||||
addArray(g_TeamHelperData[playerState.team].enemyUnitsKilled, playerState.sequences.enemyUnitsKilled.total);
|
||||
addArray(g_TeamHelperData[playerState.team].unitsLost, playerState.sequences.unitsLost.total);
|
||||
|
||||
g_TeamHelperData[playerState.team].percentMapControlled = playerState.statistics.teamPercentMapControlled;
|
||||
g_TeamHelperData[playerState.team].peakPercentMapControlled = playerState.statistics.teamPeakPercentMapControlled;
|
||||
g_TeamHelperData[playerState.team].percentMapControlled = playerState.sequences.teamPercentMapControlled;
|
||||
g_TeamHelperData[playerState.team].peakPercentMapControlled = playerState.sequences.teamPeakPercentMapControlled;
|
||||
|
||||
g_TeamHelperData[playerState.team].percentMapExplored = playerState.statistics.teamPercentMapExplored;
|
||||
g_TeamHelperData[playerState.team].percentMapExplored = playerState.sequences.teamPercentMapExplored;
|
||||
|
||||
for (let type in playerState.statistics.resourcesBought)
|
||||
g_TeamHelperData[playerState.team].totalBought += playerState.statistics.resourcesBought[type];
|
||||
for (let type in playerState.sequences.resourcesBought)
|
||||
addArray(g_TeamHelperData[playerState.team].totalBought, playerState.sequences.resourcesBought[type]);
|
||||
|
||||
for (let type in playerState.statistics.resourcesSold)
|
||||
g_TeamHelperData[playerState.team].totalSold += playerState.statistics.resourcesSold[type];
|
||||
for (let type in playerState.sequences.resourcesSold)
|
||||
addArray(g_TeamHelperData[playerState.team].totalSold, playerState.sequences.resourcesSold[type]);
|
||||
}
|
||||
|
||||
function calculateEconomyScore(playerState)
|
||||
function calculateEconomyScore(playerState, index)
|
||||
{
|
||||
let total = 0;
|
||||
for (let type in playerState.statistics.resourcesGathered)
|
||||
total += playerState.statistics.resourcesGathered[type];
|
||||
for (let type in playerState.sequences.resourcesGathered)
|
||||
total += playerState.sequences.resourcesGathered[type][index];
|
||||
|
||||
return Math.round(total / 10);
|
||||
}
|
||||
|
||||
function calculateMilitaryScore(playerState)
|
||||
function calculateMilitaryScore(playerState, index)
|
||||
{
|
||||
return Math.round((playerState.statistics.enemyUnitsKilledValue +
|
||||
playerState.statistics.enemyBuildingsDestroyedValue +
|
||||
playerState.statistics.buildingsCapturedValue) / 10);
|
||||
return Math.round((playerState.sequences.enemyUnitsKilledValue[index] +
|
||||
playerState.sequences.enemyBuildingsDestroyedValue[index] +
|
||||
playerState.sequences.buildingsCapturedValue[index]) / 10);
|
||||
}
|
||||
|
||||
function calculateExplorationScore(playerState)
|
||||
function calculateExplorationScore(playerState, index)
|
||||
{
|
||||
return playerState.statistics.percentMapExplored * 10;
|
||||
return playerState.sequences.percentMapExplored[index] * 10;
|
||||
}
|
||||
|
||||
function calculateScoreTotal(playerState)
|
||||
function calculateScoreTotal(playerState, index)
|
||||
{
|
||||
return calculateEconomyScore(playerState) +
|
||||
calculateMilitaryScore(playerState) +
|
||||
calculateExplorationScore(playerState);
|
||||
return calculateEconomyScore(playerState, index) +
|
||||
calculateMilitaryScore(playerState, index) +
|
||||
calculateExplorationScore(playerState, index);
|
||||
}
|
||||
|
||||
function calculateScoreTeam(counters)
|
||||
function calculateScoreTeam(counters, index)
|
||||
{
|
||||
for (let t in g_Teams)
|
||||
{
|
||||
|
|
@ -148,7 +138,7 @@ function calculateScoreTeam(counters)
|
|||
let total = 0;
|
||||
|
||||
if (w == 2) // Team exploration score (not additive)
|
||||
total = g_TeamHelperData[t].percentMapExplored * 10;
|
||||
total = g_TeamHelperData[t].percentMapExplored[index] * 10;
|
||||
else
|
||||
for (let p = 0; p < g_Teams[t]; ++p)
|
||||
total += +Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + p + "][" + w + "]").caption;
|
||||
|
|
@ -164,17 +154,17 @@ function calculateScoreTeam(counters)
|
|||
}
|
||||
}
|
||||
|
||||
function calculateBuildings(playerState, position)
|
||||
function calculateBuildings(playerState, index, type)
|
||||
{
|
||||
let type = g_BuildingsTypes[position];
|
||||
return formatCaptured(
|
||||
playerState.statistics.buildingsConstructed[type],
|
||||
playerState.statistics.enemyBuildingsDestroyed[type],
|
||||
playerState.statistics.buildingsCaptured[type],
|
||||
playerState.statistics.buildingsLost[type]);
|
||||
return {
|
||||
"constructed": playerState.sequences.buildingsConstructed[type][index],
|
||||
"destroyed": playerState.sequences.enemyBuildingsDestroyed[type][index],
|
||||
"captured": playerState.sequences.buildingsCaptured[type][index],
|
||||
"lost": playerState.sequences.buildingsLost[type][index]
|
||||
};
|
||||
}
|
||||
|
||||
function calculateBuildingsTeam(counters)
|
||||
function calculateBuildingsTeam(counters, index)
|
||||
{
|
||||
for (let t in g_Teams)
|
||||
{
|
||||
|
|
@ -203,12 +193,12 @@ function calculateBuildingsTeam(counters)
|
|||
}
|
||||
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption =
|
||||
formatCaptured(total.constructed, total.destroyed, total.captured, total.lost);
|
||||
formatSummaryValue(total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateUnitsTeam(counters)
|
||||
function calculateUnitsTeam(counters, index)
|
||||
{
|
||||
for (let t in g_Teams)
|
||||
{
|
||||
|
|
@ -227,100 +217,89 @@ function calculateUnitsTeam(counters)
|
|||
|
||||
for (let p = 0; p < g_Teams[t]; ++p)
|
||||
{
|
||||
let splitCaption = cleanGUICaption(t, p, w, false).split("\n");
|
||||
let first = splitCaption[0].split("/");
|
||||
total.trained += +first[0];
|
||||
total.killed += +first[1];
|
||||
|
||||
if (w == 0 || w == 6)
|
||||
{
|
||||
let splitCaption = cleanGUICaption(t, p, w, false).split("\n");
|
||||
let first = splitCaption[0].split("/");
|
||||
let second = splitCaption[1].split("/");
|
||||
|
||||
total.trained += +first[0];
|
||||
total.killed += +first[1];
|
||||
total.captured += +second[0];
|
||||
total.lost += +second[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
let splitCaption = cleanGUICaption(t, p, w).split("/");
|
||||
total.trained += +splitCaption[0];
|
||||
total.killed += +splitCaption[1];
|
||||
total.lost += +splitCaption[2];
|
||||
}
|
||||
total.lost += +splitCaption[1];
|
||||
}
|
||||
|
||||
let formattedCaption = "";
|
||||
if (w != 0 && w != 6)
|
||||
delete total.captured;
|
||||
|
||||
if (w == 0 || w == 6)
|
||||
formattedCaption = formatCaptured(total.trained, total.killed, total.captured, total.lost);
|
||||
else
|
||||
formattedCaption = formatTrained(total.trained, total.killed, total.lost);
|
||||
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = formattedCaption;
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = formatSummaryValue(total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateUnitsWithCaptured(playerState, position)
|
||||
function calculateUnitsWithCaptured(playerState, index, type)
|
||||
{
|
||||
let type = g_UnitsTypes[position];
|
||||
|
||||
return formatCaptured(
|
||||
playerState.statistics.unitsTrained[type],
|
||||
playerState.statistics.enemyUnitsKilled[type],
|
||||
playerState.statistics.unitsCaptured[type],
|
||||
playerState.statistics.unitsLost[type]);
|
||||
return {
|
||||
"trained": playerState.sequences.unitsTrained[type][index],
|
||||
"killed": playerState.sequences.enemyUnitsKilled[type][index],
|
||||
"captured": playerState.sequences.unitsCaptured[type][index],
|
||||
"lost": playerState.sequences.unitsLost[type][index]
|
||||
};
|
||||
}
|
||||
|
||||
function calculateUnits(playerState, position)
|
||||
function calculateUnits(playerState, index, type)
|
||||
{
|
||||
let type = g_UnitsTypes[position];
|
||||
|
||||
return formatTrained(
|
||||
playerState.statistics.unitsTrained[type],
|
||||
playerState.statistics.enemyUnitsKilled[type],
|
||||
playerState.statistics.unitsLost[type]);
|
||||
return {
|
||||
"trained": playerState.sequences.unitsTrained[type][index],
|
||||
"killed": playerState.sequences.enemyUnitsKilled[type][index],
|
||||
"lost": playerState.sequences.unitsLost[type][index]
|
||||
};
|
||||
}
|
||||
|
||||
function calculateResources(playerState, position)
|
||||
function calculateResources(playerState, index, type)
|
||||
{
|
||||
let type = g_ResourceData.GetCodes()[position];
|
||||
|
||||
return formatIncome(
|
||||
playerState.statistics.resourcesGathered[type],
|
||||
playerState.statistics.resourcesUsed[type] - playerState.statistics.resourcesSold[type]);
|
||||
return {
|
||||
"gathered": playerState.sequences.resourcesGathered[type][index],
|
||||
"used": playerState.sequences.resourcesUsed[type][index] - playerState.sequences.resourcesSold[type][index]
|
||||
};
|
||||
}
|
||||
|
||||
function calculateTotalResources(playerState)
|
||||
function calculateTotalResources(playerState, index)
|
||||
{
|
||||
let totalGathered = 0;
|
||||
let totalUsed = 0;
|
||||
|
||||
for (let type of g_ResourceData.GetCodes())
|
||||
{
|
||||
totalGathered += playerState.statistics.resourcesGathered[type];
|
||||
totalUsed += playerState.statistics.resourcesUsed[type] - playerState.statistics.resourcesSold[type];
|
||||
totalGathered += playerState.sequences.resourcesGathered[type][index];
|
||||
totalUsed += playerState.sequences.resourcesUsed[type][index] - playerState.sequences.resourcesSold[type][index];
|
||||
}
|
||||
|
||||
return formatIncome(totalGathered, totalUsed);
|
||||
return { "gathered": totalGathered, "used": totalUsed };
|
||||
}
|
||||
|
||||
function calculateTreasureCollected(playerState)
|
||||
function calculateTreasureCollected(playerState, index)
|
||||
{
|
||||
return playerState.statistics.treasuresCollected;
|
||||
return playerState.sequences.treasuresCollected[index];
|
||||
}
|
||||
|
||||
function calculateLootCollected(playerState)
|
||||
function calculateLootCollected(playerState, index)
|
||||
{
|
||||
return playerState.statistics.lootCollected;
|
||||
return playerState.sequences.lootCollected[index];
|
||||
}
|
||||
|
||||
function calculateTributeSent(playerState)
|
||||
function calculateTributeSent(playerState, index)
|
||||
{
|
||||
return formatIncome(
|
||||
playerState.statistics.tributesSent,
|
||||
playerState.statistics.tributesReceived);
|
||||
return {
|
||||
"sent": playerState.sequences.tributesSent[index],
|
||||
"received": playerState.sequences.tributesReceived[index]
|
||||
};
|
||||
}
|
||||
|
||||
function calculateResourcesTeam(counters)
|
||||
function calculateResourcesTeam(counters, index)
|
||||
{
|
||||
for (let t in g_Teams)
|
||||
{
|
||||
|
|
@ -352,43 +331,44 @@ function calculateResourcesTeam(counters)
|
|||
let teamTotal;
|
||||
if (w >= 6)
|
||||
teamTotal = total.income;
|
||||
else if (w == 5)
|
||||
teamTotal = { "sent": total.income, "received": total.outcome };
|
||||
else
|
||||
teamTotal = formatIncome(total.income, total.outcome);
|
||||
teamTotal = { "gathered": total.income, "used": total.outcome };
|
||||
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = teamTotal;
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = formatSummaryValue(teamTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateResourceExchanged(playerState, position)
|
||||
function calculateResourceExchanged(playerState, index, type)
|
||||
{
|
||||
let type = g_ResourceData.GetCodes()[position];
|
||||
|
||||
return formatIncome(
|
||||
playerState.statistics.resourcesBought[type],
|
||||
playerState.statistics.resourcesSold[type]);
|
||||
return {
|
||||
"bought": playerState.sequences.resourcesBought[type][index],
|
||||
"sold": playerState.sequences.resourcesSold[type][index]
|
||||
};
|
||||
}
|
||||
|
||||
function calculateBarterEfficiency(playerState)
|
||||
function calculateBarterEfficiency(playerState, index)
|
||||
{
|
||||
let totalBought = 0;
|
||||
let totalSold = 0;
|
||||
|
||||
for (let type in playerState.statistics.resourcesBought)
|
||||
totalBought += playerState.statistics.resourcesBought[type];
|
||||
for (let type in playerState.sequences.resourcesBought)
|
||||
totalBought += playerState.sequences.resourcesBought[type][index];
|
||||
|
||||
for (let type in playerState.statistics.resourcesSold)
|
||||
totalSold += playerState.statistics.resourcesSold[type];
|
||||
for (let type in playerState.sequences.resourcesSold)
|
||||
totalSold += playerState.sequences.resourcesSold[type][index];
|
||||
|
||||
return formatPercent(totalBought, totalSold);
|
||||
return calculatePercent(totalBought, totalSold);
|
||||
}
|
||||
|
||||
function calculateTradeIncome(playerState)
|
||||
function calculateTradeIncome(playerState, index)
|
||||
{
|
||||
return playerState.statistics.tradeIncome;
|
||||
return playerState.sequences.tradeIncome[index];
|
||||
}
|
||||
|
||||
function calculateMarketTeam(counters)
|
||||
function calculateMarketTeam(counters, index)
|
||||
{
|
||||
for (let t in g_Teams)
|
||||
{
|
||||
|
|
@ -418,54 +398,54 @@ function calculateMarketTeam(counters)
|
|||
|
||||
let teamTotal;
|
||||
if (w == 4)
|
||||
teamTotal = formatPercent(g_TeamHelperData[t].totalBought, g_TeamHelperData[t].totalSold);
|
||||
teamTotal = calculatePercent(g_TeamHelperData[t].totalBought[index], g_TeamHelperData[t].totalSold[index]);
|
||||
else if (w > 4)
|
||||
teamTotal = total.income;
|
||||
else
|
||||
teamTotal = formatIncome(total.income, total.outcome);
|
||||
teamTotal = total;
|
||||
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = teamTotal;
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = formatSummaryValue(teamTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateVegetarianRatio(playerState)
|
||||
function calculateVegetarianRatio(playerState, index)
|
||||
{
|
||||
return formatPercent(
|
||||
playerState.statistics.resourcesGathered.vegetarianFood,
|
||||
playerState.statistics.resourcesGathered.food);
|
||||
return calculatePercent(
|
||||
playerState.sequences.resourcesGathered.vegetarianFood[index],
|
||||
playerState.sequences.resourcesGathered.food[index]);
|
||||
}
|
||||
|
||||
function calculateFeminization(playerState)
|
||||
function calculateFeminization(playerState, index)
|
||||
{
|
||||
return formatPercent(
|
||||
playerState.statistics.unitsTrained.FemaleCitizen,
|
||||
playerState.statistics.unitsTrained.Worker);
|
||||
return calculatePercent(
|
||||
playerState.sequences.unitsTrained.FemaleCitizen[index],
|
||||
playerState.sequences.unitsTrained.Worker[index]);
|
||||
}
|
||||
|
||||
function calculateKillDeathRatio(playerState)
|
||||
function calculateKillDeathRatio(playerState, index)
|
||||
{
|
||||
return formatRatio(
|
||||
playerState.statistics.enemyUnitsKilled.total,
|
||||
playerState.statistics.unitsLost.total);
|
||||
return calculateRatio(
|
||||
playerState.sequences.enemyUnitsKilled.total[index],
|
||||
playerState.sequences.unitsLost.total[index]);
|
||||
}
|
||||
|
||||
function calculateMapExploration(playerState)
|
||||
function calculateMapExploration(playerState, index)
|
||||
{
|
||||
return playerState.statistics.percentMapExplored + "%";
|
||||
return { "percent": playerState.sequences.percentMapExplored[index] };
|
||||
}
|
||||
|
||||
function calculateMapFinalControl(playerState)
|
||||
function calculateMapFinalControl(playerState, index)
|
||||
{
|
||||
return playerState.statistics.percentMapControlled + "%";
|
||||
return { "percent": playerState.sequences.percentMapControlled[index] };
|
||||
}
|
||||
|
||||
function calculateMapPeakControl(playerState)
|
||||
function calculateMapPeakControl(playerState, index)
|
||||
{
|
||||
return playerState.statistics.peakPercentMapControlled + "%";
|
||||
return { "percent": playerState.sequences.peakPercentMapControlled[index] };
|
||||
}
|
||||
|
||||
function calculateMiscellaneous(counters)
|
||||
function calculateMiscellaneousTeam(counters, index)
|
||||
{
|
||||
for (let t in g_Teams)
|
||||
{
|
||||
|
|
@ -477,19 +457,19 @@ function calculateMiscellaneous(counters)
|
|||
let teamTotal;
|
||||
|
||||
if (w == 0)
|
||||
teamTotal = formatPercent(g_TeamHelperData[t].vegetarianFood, g_TeamHelperData[t].food);
|
||||
teamTotal = calculatePercent(g_TeamHelperData[t].vegetarianFood[index], g_TeamHelperData[t].food[index]);
|
||||
else if (w == 1)
|
||||
teamTotal = formatPercent(g_TeamHelperData[t].femaleCitizen, g_TeamHelperData[t].worker);
|
||||
teamTotal = calculatePercent(g_TeamHelperData[t].femaleCitizen[index], g_TeamHelperData[t].worker[index]);
|
||||
else if (w == 2)
|
||||
teamTotal = formatRatio(g_TeamHelperData[t].enemyUnitsKilled, g_TeamHelperData[t].unitsLost);
|
||||
teamTotal = calculateRatio(g_TeamHelperData[t].enemyUnitsKilled[index], g_TeamHelperData[t].unitsLost[index]);
|
||||
else if (w == 3)
|
||||
teamTotal = g_TeamHelperData[t].percentMapExplored + "%";
|
||||
teamTotal = { "percent": g_TeamHelperData[t].percentMapExplored[index] };
|
||||
else if (w == 4)
|
||||
teamTotal = g_TeamHelperData[t].peakPercentMapControlled + "%";
|
||||
teamTotal = { "percent": g_TeamHelperData[t].peakPercentMapControlled[index] };
|
||||
else if (w == 5)
|
||||
teamTotal = g_TeamHelperData[t].percentMapControlled + "%";
|
||||
teamTotal = { "percent": g_TeamHelperData[t].percentMapControlled[index] };
|
||||
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = teamTotal;
|
||||
Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + w + "]").caption = formatSummaryValue(teamTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
var g_ScorePanelsData = {
|
||||
"score": {
|
||||
"caption": translate("Score"),
|
||||
"headings": [
|
||||
{ "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "caption": translate("Economy score"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Military score"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Exploration score"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Total score"), "yStart": 16, "width": 100 }
|
||||
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "identifier": "economyScore", "caption": translate("Economy score"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "militaryScore", "caption": translate("Military score"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "explorationScore", "caption": translate("Exploration score"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "totalScore", "caption": translate("Total score"), "yStart": 16, "width": 100 }
|
||||
],
|
||||
"titleHeadings": [],
|
||||
"counters": [
|
||||
|
|
@ -17,28 +18,29 @@ var g_ScorePanelsData = {
|
|||
"teamCounterFn": calculateScoreTeam
|
||||
},
|
||||
"buildings": {
|
||||
"caption": translate("Buildings"),
|
||||
"headings": [
|
||||
{ "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "caption": translate("Total"), "yStart": 34, "width": 105 },
|
||||
{ "caption": translate("Houses"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Economic"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Outposts"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Military"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Fortresses"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Civ centers"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Wonders"), "yStart": 34, "width": 85 }
|
||||
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 105 },
|
||||
{ "identifier": "House", "caption": translate("Houses"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Economic", "caption": translate("Economic"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Outpost", "caption": translate("Outposts"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Military", "caption": translate("Military"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Fortress", "caption": translate("Fortresses"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "CivCentre", "caption": translate("Civ centers"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Wonder", "caption": translate("Wonders"), "yStart": 34, "width": 85 }
|
||||
],
|
||||
"titleHeadings": [
|
||||
{
|
||||
"caption": sprintf(translate("Buildings Statistics (%(constructed)s / %(destroyed)s / %(captured)s / %(lost)s)"),
|
||||
{
|
||||
"constructed": g_TrainedColor + translate("Constructed") + '[/color]',
|
||||
"destroyed": g_KilledColor + translate("Destroyed") + '[/color]',
|
||||
"captured": g_CapturedColor + translate("Captured") + '[/color]',
|
||||
"lost": g_LostColor + translate("Lost") + '[/color]'
|
||||
"constructed": getColoredTypeTranslation("constructed"),
|
||||
"destroyed": getColoredTypeTranslation("destroyed"),
|
||||
"captured": getColoredTypeTranslation("captured"),
|
||||
"lost": getColoredTypeTranslation("lost")
|
||||
}),
|
||||
"yStart": 16,
|
||||
"width": (85 * 7 + 105)
|
||||
"width": 85 * 7 + 105
|
||||
}, // width = 700
|
||||
],
|
||||
"counters": [
|
||||
|
|
@ -54,71 +56,75 @@ var g_ScorePanelsData = {
|
|||
"teamCounterFn": calculateBuildingsTeam
|
||||
},
|
||||
"units": {
|
||||
"caption": translate("Units"),
|
||||
"headings": [
|
||||
{ "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "caption": translate("Total"), "yStart": 34, "width": 105 },
|
||||
{ "caption": translate("Infantry"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Worker"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Cavalry"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Champion"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Heroes"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Siege"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Navy"), "yStart": 34, "width": 85 },
|
||||
{ "caption": translate("Traders"), "yStart": 34, "width": 85 }
|
||||
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 105 },
|
||||
{ "identifier": "Infantry", "caption": translate("Infantry"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Worker", "caption": translate("Worker"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Cavalry", "caption": translate("Cavalry"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Champion", "caption": translate("Champion"), "yStart": 34, "width": 85 },
|
||||
{ "identifier": "Hero", "caption": translate("Heroes"), "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("Units Statistics (%(trained)s / %(killed)s / %(captured)s / %(lost)s)"),
|
||||
{
|
||||
"trained": g_TrainedColor + translate("Trained") + '[/color]',
|
||||
"killed": g_KilledColor + translate("Killed") + '[/color]',
|
||||
"captured": g_CapturedColor + translate("Captured") + '[/color]',
|
||||
"lost": g_LostColor + translate("Lost") + '[/color]'
|
||||
"trained": getColoredTypeTranslation("trained"),
|
||||
"killed": getColoredTypeTranslation("killed"),
|
||||
"captured": getColoredTypeTranslation("captured"),
|
||||
"lost": getColoredTypeTranslation("lost")
|
||||
}),
|
||||
"yStart": 16,
|
||||
"width": (100 * 7 + 120)
|
||||
}, // width = 820
|
||||
"width": 85 * 8 + 105
|
||||
}, // width = 785
|
||||
],
|
||||
"counters": [
|
||||
{ "width": 105, "fn": calculateUnitsWithCaptured, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 },
|
||||
{ "width": 105, "fn": calculateUnitsWithCaptured, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 12 }
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnitsWithCaptured, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 },
|
||||
{ "width": 85, "fn": calculateUnits, "verticalOffset": 3 }
|
||||
],
|
||||
"teamCounterFn": calculateUnitsTeam
|
||||
},
|
||||
"resources": {
|
||||
"caption": translate("Resources"),
|
||||
"headings": [
|
||||
{ "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
...g_ResourceData.GetResources().map(res => ({
|
||||
"identifier": res.code,
|
||||
"caption": translateWithContext("firstWord", res.name),
|
||||
"yStart": 34,
|
||||
"width": 100
|
||||
})),
|
||||
{ "caption": translate("Total"), "yStart": 34, "width": 110 },
|
||||
{ "identifier": "total", "caption": translate("Total"), "yStart": 34, "width": 110 },
|
||||
{
|
||||
"identifier": "tributes",
|
||||
"caption": sprintf(translate("Tributes \n(%(sent)s / %(received)s)"),
|
||||
{
|
||||
"sent": g_IncomeColor + translate("Sent") + '[/color]',
|
||||
"received": g_OutcomeColor + translate("Received") + '[/color]'
|
||||
"sent": getColoredTypeTranslation("sent"),
|
||||
"received": getColoredTypeTranslation("received")
|
||||
}),
|
||||
"yStart": 16,
|
||||
"width": 121
|
||||
},
|
||||
{ "caption": translate("Treasures collected"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Loot"), "yStart": 16, "width": 100 }
|
||||
{ "identifier": "treasuresCollected", "caption": translate("Treasures collected"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "loot", "caption": translate("Loot"), "yStart": 16, "width": 100 }
|
||||
],
|
||||
"titleHeadings": [
|
||||
{
|
||||
"caption": sprintf(translate("Resource Statistics (%(gathered)s / %(used)s)"),
|
||||
{
|
||||
"gathered": g_IncomeColor + translate("Gathered") + '[/color]',
|
||||
"used": g_OutcomeColor + translate("Used") + '[/color]'
|
||||
"gathered": getColoredTypeTranslation("gathered"),
|
||||
"used": getColoredTypeTranslation("used")
|
||||
}),
|
||||
"yStart": 16,
|
||||
"width": 100 * g_ResourceData.GetCodes().length + 110
|
||||
|
|
@ -138,10 +144,12 @@ var g_ScorePanelsData = {
|
|||
"teamCounterFn": calculateResourcesTeam
|
||||
},
|
||||
"market": {
|
||||
"caption": translate("Market"),
|
||||
"headings": [
|
||||
{ "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
...g_ResourceData.GetResources().map(res => {
|
||||
return {
|
||||
"identifier": res.code,
|
||||
"caption":
|
||||
// Translation: use %(resourceWithinSentence)s if needed
|
||||
sprintf(translate("%(resourceFirstWord)s exchanged"), {
|
||||
|
|
@ -152,8 +160,8 @@ var g_ScorePanelsData = {
|
|||
"width": 100
|
||||
};
|
||||
}),
|
||||
{ "caption": translate("Barter efficiency"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Trade income"), "yStart": 16, "width": 100 }
|
||||
{ "identifier": "barterEfficency", "caption": translate("Barter efficiency"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "tradeIncome", "caption": translate("Trade income"), "yStart": 16, "width": 100 }
|
||||
],
|
||||
"titleHeadings": [],
|
||||
"counters": [
|
||||
|
|
@ -168,18 +176,17 @@ var g_ScorePanelsData = {
|
|||
"teamCounterFn": calculateMarketTeam
|
||||
},
|
||||
"misc": {
|
||||
"caption": translate("Miscellaneous"),
|
||||
"headings": [
|
||||
{ "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "caption": translate("Vegetarian\nratio"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Feminization"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Kill / Death\nratio"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("Map\nexploration"), "yStart": 16, "width": 100 },
|
||||
{ "caption": translate("At peak"), "yStart": 34, "width": 100 },
|
||||
{ "caption": translate("At finish"), "yStart": 34, "width": 100 }
|
||||
],
|
||||
"titleHeadings": [
|
||||
{ "caption": translate("Map control"), "xOffset": 400, "yStart": 16, "width": 200 }
|
||||
{ "identifier": "playername", "caption": translate("Player name"), "yStart": 26, "width": 200 },
|
||||
{ "identifier": "vegetarianRatio", "caption": translate("Vegetarian ratio"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "feminization", "caption": translate("Feminization"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "killDeath", "caption": translate("Kill / Death ratio"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "mapExploration", "caption": translate("Map exploration"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "mapControlPeak", "caption": translate("Map control (peak)"), "yStart": 16, "width": 100 },
|
||||
{ "identifier": "mapControlFinish", "caption": translate("Map control (finish)"), "yStart": 16, "width": 100 }
|
||||
],
|
||||
"titleHeadings": [],
|
||||
"counters": [
|
||||
{ "width": 100, "fn": calculateVegetarianRatio, "verticalOffset": 12 },
|
||||
{ "width": 100, "fn": calculateFeminization, "verticalOffset": 12 },
|
||||
|
|
@ -188,10 +195,15 @@ var g_ScorePanelsData = {
|
|||
{ "width": 100, "fn": calculateMapPeakControl, "verticalOffset": 12 },
|
||||
{ "width": 100, "fn": calculateMapFinalControl, "verticalOffset": 12 }
|
||||
],
|
||||
"teamCounterFn": calculateMiscellaneous
|
||||
"teamCounterFn": calculateMiscellaneousTeam
|
||||
}
|
||||
};
|
||||
|
||||
function getColoredTypeTranslation(type)
|
||||
{
|
||||
return g_SummaryTypes[type].color ? '[color="' + g_SummaryTypes[type].color + '"]' + g_SummaryTypes[type].caption + '[/color]' : g_SummaryTypes[type].caption;
|
||||
}
|
||||
|
||||
function resetGeneralPanel()
|
||||
{
|
||||
for (let h = 0; h < g_MaxHeadingTitle; ++h)
|
||||
|
|
|
|||
|
|
@ -9,20 +9,95 @@ const g_PlayerBoxAlpha = " 50";
|
|||
const g_PlayerColorBoxAlpha = " 255";
|
||||
const g_TeamsBoxYStart = 40;
|
||||
|
||||
// Colors used for units and buildings
|
||||
const g_TrainedColor = '[color="201 255 200"]';
|
||||
const g_LostColor = '[color="255 213 213"]';
|
||||
const g_KilledColor = '[color="196 198 255"]';
|
||||
const g_CapturedColor = '[color="255 255 157"]';
|
||||
const g_TypeColors = {
|
||||
"blue": "196 198 255",
|
||||
"green": "201 255 200",
|
||||
"red": "255 213 213",
|
||||
"yellow": "255 255 157"
|
||||
}
|
||||
|
||||
const g_BuildingsTypes = [ "total", "House", "Economic", "Outpost", "Military", "Fortress", "CivCentre", "Wonder" ];
|
||||
const g_UnitsTypes = [ "total", "Infantry", "Worker", "Cavalry", "Champion", "Hero", "Siege", "Ship", "Trader" ];
|
||||
/**
|
||||
* Colors, captions and format used for units, buildings, etc. types
|
||||
*/
|
||||
var g_SummaryTypes = {
|
||||
"percent": {
|
||||
"color": "",
|
||||
"caption": "%",
|
||||
"postfix": "%"
|
||||
},
|
||||
"trained": {
|
||||
"color": g_TypeColors.green,
|
||||
"caption": translate("Trained"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"constructed": {
|
||||
"color": g_TypeColors.green,
|
||||
"caption": translate("Constructed"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"gathered": {
|
||||
"color": g_TypeColors.green,
|
||||
"caption": translate("Gathered"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"sent": {
|
||||
"color": g_TypeColors.green,
|
||||
"caption": translate("Sent"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"bought": {
|
||||
"color": g_TypeColors.green,
|
||||
"caption": translate("Bought"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"income": {
|
||||
"color": g_TypeColors.green,
|
||||
"caption": translate("Income"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"captured": {
|
||||
"color": g_TypeColors.yellow,
|
||||
"caption": translate("Captured"),
|
||||
"postfix": " / "
|
||||
},
|
||||
"destroyed": {
|
||||
"color": g_TypeColors.blue,
|
||||
"caption": translate("Destroyed"),
|
||||
"postfix": "\n"
|
||||
},
|
||||
"killed": {
|
||||
"color": g_TypeColors.blue,
|
||||
"caption": translate("Killed"),
|
||||
"postfix": "\n"
|
||||
},
|
||||
"lost": {
|
||||
"color": g_TypeColors.red,
|
||||
"caption": translate("Lost"),
|
||||
"postfix": "\n"
|
||||
},
|
||||
"used": {
|
||||
"color": g_TypeColors.red,
|
||||
"caption": translate("Used"),
|
||||
"postfix": "\n"
|
||||
},
|
||||
"received": {
|
||||
"color": g_TypeColors.red,
|
||||
"caption": translate("Recieved"),
|
||||
"postfix": "\n"
|
||||
},
|
||||
"sold": {
|
||||
"color": g_TypeColors.red,
|
||||
"caption": translate("Sold"),
|
||||
"postfix": "\n"
|
||||
},
|
||||
"outcome": {
|
||||
"color": g_TypeColors.red,
|
||||
"caption": translate("Outcome"),
|
||||
"postfix": "\n"
|
||||
}
|
||||
};
|
||||
|
||||
// Colors used for gathered and traded resources
|
||||
const g_IncomeColor = '[color="201 255 200"]';
|
||||
const g_OutcomeColor = '[color="255 213 213"]';
|
||||
|
||||
const g_InfiniteSymbol = "\u221E";
|
||||
const g_InfinitySymbol = "\u221E";
|
||||
|
||||
var g_CivData = loadCivData();
|
||||
var g_Teams = [];
|
||||
|
|
@ -47,7 +122,132 @@ function selectPanel(panel)
|
|||
|
||||
adjustTabDividers(panel.size);
|
||||
|
||||
updatePanelData(g_ScorePanelsData[panel.name.substr(0, panel.name.length - "PanelButton".length)]);
|
||||
let generalPanel = Engine.GetGUIObjectByName("generalPanel");
|
||||
let chartsPanel = Engine.GetGUIObjectByName("chartsPanel");
|
||||
let chartsHidden = panel.name != "chartsPanelButton";
|
||||
generalPanel.hidden = !chartsHidden;
|
||||
chartsPanel.hidden = chartsHidden;
|
||||
if (chartsHidden)
|
||||
updatePanelData(g_ScorePanelsData[panel.name.substr(0, panel.name.length - "PanelButton".length)]);
|
||||
else
|
||||
[0, 1].forEach(updateCategoryDropdown);
|
||||
}
|
||||
|
||||
function initCharts()
|
||||
{
|
||||
let player_colors = [];
|
||||
for (let i = 1; i <= g_PlayerCount; ++i)
|
||||
{
|
||||
let playerState = g_GameData.sim.playerStates[i];
|
||||
player_colors.push(
|
||||
Math.floor(playerState.color.r * 255) + " " +
|
||||
Math.floor(playerState.color.g * 255) + " " +
|
||||
Math.floor(playerState.color.b * 255)
|
||||
);
|
||||
}
|
||||
|
||||
[0, 1].forEach(i => Engine.GetGUIObjectByName("chart[" + i + "]").series_color = player_colors);
|
||||
|
||||
let chartLegend = Engine.GetGUIObjectByName("chartLegend");
|
||||
chartLegend.caption = g_GameData.sim.playerStates.slice(1).map(
|
||||
(state, index) => '[color="' + player_colors[index] + '"]■[/color] ' + state.name
|
||||
).join(" ");
|
||||
|
||||
let chart1Part = Engine.GetGUIObjectByName("chart[1]Part");
|
||||
let chart1PartSize = chart1Part.size;
|
||||
chart1PartSize.rright += 50;
|
||||
chart1PartSize.rleft += 50;
|
||||
chart1PartSize.right -= 5;
|
||||
chart1PartSize.left -= 5;
|
||||
chart1Part.size = chart1PartSize;
|
||||
}
|
||||
|
||||
function resizeDropdown(dropdown)
|
||||
{
|
||||
let size = dropdown.size;
|
||||
size.bottom = dropdown.size.top +
|
||||
(Engine.GetTextWidth(dropdown.font, dropdown.list[dropdown.selected]) >
|
||||
dropdown.size.right - dropdown.size.left - 32 ? 42 : 27);
|
||||
dropdown.size = size;
|
||||
}
|
||||
|
||||
function updateCategoryDropdown(number)
|
||||
{
|
||||
let chartCategory = Engine.GetGUIObjectByName("chart[" + number + "]CategorySelection");
|
||||
chartCategory.list_data = Object.keys(g_ScorePanelsData);
|
||||
chartCategory.list = Object.keys(g_ScorePanelsData).map(panel => g_ScorePanelsData[panel].caption);
|
||||
chartCategory.onSelectionChange = function() {
|
||||
if (!this.list_data[this.selected])
|
||||
return;
|
||||
resizeDropdown(this);
|
||||
updateValueDropdown(number, this.list_data[this.selected]);
|
||||
};
|
||||
chartCategory.selected = 0;
|
||||
}
|
||||
|
||||
function updateValueDropdown(number, category)
|
||||
{
|
||||
let chartValue = Engine.GetGUIObjectByName("chart[" + number + "]ValueSelection");
|
||||
let list = g_ScorePanelsData[category].headings.map(heading => heading.caption);
|
||||
list.shift();
|
||||
chartValue.list = list;
|
||||
let list_data = g_ScorePanelsData[category].headings.map(heading => heading.identifier);
|
||||
list_data.shift();
|
||||
chartValue.list_data = list_data;
|
||||
chartValue.onSelectionChange = function() {
|
||||
if (!this.list_data[this.selected])
|
||||
return;
|
||||
resizeDropdown(this);
|
||||
updateTypeDropdown(number, category, this.list_data[this.selected], this.selected);
|
||||
};
|
||||
chartValue.selected = 0;
|
||||
}
|
||||
|
||||
function updateTypeDropdown(number, category, item, itemNumber)
|
||||
{
|
||||
let testValue = g_ScorePanelsData[category].counters[itemNumber].fn(g_GameData.sim.playerStates[1], 0, item);
|
||||
let hide = !g_ScorePanelsData[category].counters[itemNumber].fn ||
|
||||
typeof testValue != "object" || Object.keys(testValue).length < 2;
|
||||
Engine.GetGUIObjectByName("chart[" + number + "]TypeLabel").hidden = hide;
|
||||
let chartType = Engine.GetGUIObjectByName("chart[" + number + "]TypeSelection");
|
||||
chartType.hidden = hide;
|
||||
if (hide)
|
||||
{
|
||||
updateChart(number, category, item, itemNumber, Object.keys(testValue)[0] || undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
chartType.list = Object.keys(testValue).map(type => g_SummaryTypes[type].caption);
|
||||
chartType.list_data = Object.keys(testValue);
|
||||
chartType.onSelectionChange = function() {
|
||||
if (!this.list_data[this.selected])
|
||||
return;
|
||||
resizeDropdown(this);
|
||||
updateChart(number, category, item, itemNumber, this.list_data[this.selected]);
|
||||
};
|
||||
chartType.selected = 0;
|
||||
}
|
||||
|
||||
function updateChart(number, category, item, itemNumber, type)
|
||||
{
|
||||
if (!g_ScorePanelsData[category].counters[itemNumber].fn)
|
||||
return;
|
||||
let chart = Engine.GetGUIObjectByName("chart[" + number + "]");
|
||||
let series = [];
|
||||
for (let j = 1; j <= g_PlayerCount; ++j)
|
||||
{
|
||||
let playerState = g_GameData.sim.playerStates[j];
|
||||
let data = [];
|
||||
for (let index in playerState.sequences.time)
|
||||
{
|
||||
let value = g_ScorePanelsData[category].counters[itemNumber].fn(playerState, index, item);
|
||||
if (type)
|
||||
value = value[type];
|
||||
data.push([playerState.sequences.time[index], value]);
|
||||
}
|
||||
series.push(data);
|
||||
}
|
||||
chart.series = series;
|
||||
}
|
||||
|
||||
function adjustTabDividers(tabSize)
|
||||
|
|
@ -126,14 +326,14 @@ function updatePanelData(panelInfo)
|
|||
civIcon.sprite = "stretched:" + g_CivData[playerState.civ].Emblem;
|
||||
civIcon.tooltip = g_CivData[playerState.civ].Name;
|
||||
|
||||
updateCountersPlayer(playerState, panelInfo.counters, playerCounterValue);
|
||||
updateCountersPlayer(playerState, panelInfo.counters, panelInfo.headings, playerCounterValue);
|
||||
|
||||
calculateTeamCounters(playerState);
|
||||
}
|
||||
|
||||
let teamCounterFn = panelInfo.teamCounterFn;
|
||||
if (g_Teams && teamCounterFn)
|
||||
teamCounterFn(panelInfo.counters);
|
||||
teamCounterFn(panelInfo.counters, g_GameData.sim.playerStates[1].sequences.time.length - 1);
|
||||
}
|
||||
|
||||
function confirmStartReplay()
|
||||
|
|
@ -256,5 +456,6 @@ function init(data)
|
|||
g_WithoutTeam -= g_Teams[i] ? g_Teams[i] : 0;
|
||||
}
|
||||
|
||||
initCharts();
|
||||
selectPanel(Engine.GetGUIObjectByName("scorePanelButton"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,13 @@
|
|||
</object>
|
||||
</object>
|
||||
|
||||
<object name="chartsPanelButton" type="button" sprite="BackgroundTab" style="TabButton" size="762 92 880 120">
|
||||
<action on="Press">selectPanel(this);</action>
|
||||
<object type="text" style="ModernLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Charts</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="generalPanel" type="image" sprite="ForegroundBody" size="20 120 100%-20 100%-54">
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerNameHeading" type="text" style="ModernLeftTabLabelText">
|
||||
|
|
@ -152,6 +159,48 @@
|
|||
</repeat>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="chartsPanel" type="image" sprite="ForegroundBody" size="20 120 100%-20 100%-54">
|
||||
<repeat count="2" var="k">
|
||||
<object name="chart[k]Part" size="15 0 50%-10 100%-35">
|
||||
<object type="text" style="ModernLeftLabelText" size="1 6 145 26">
|
||||
<translatableAttribute id="caption" context="summary chart">Category:</translatableAttribute>
|
||||
</object>
|
||||
<object name="chart[k]CategorySelection"
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="5 28 145 52">
|
||||
<translatableAttribute id="tooltip" context="summary chart">Category</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="text" style="ModernLeftLabelText" size="151 6 295 26">
|
||||
<translatableAttribute id="caption" context="summary chart">Value:</translatableAttribute>
|
||||
</object>
|
||||
<object name="chart[k]ValueSelection"
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="155 28 295 52">
|
||||
<translatableAttribute id="tooltip" context="summary chart">Value</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="chart[k]TypeLabel" type="text" style="ModernLeftLabelText" size="301 6 445 26">
|
||||
<translatableAttribute id="caption" context="summary chart">Type:</translatableAttribute>
|
||||
</object>
|
||||
<object name="chart[k]TypeSelection"
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
hidden="true"
|
||||
size="305 28 445 52">
|
||||
<translatableAttribute id="tooltip" context="summary chart">Type</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="image" sprite="color: 255 255 255 20" size="0 75 100% 100%"/>
|
||||
<object name="chart[k]" type="chart" size="5 80 100%-5 100%-5"/>
|
||||
</object>
|
||||
</repeat>
|
||||
|
||||
<object name="chartLegend" type="text" style="ModernLabelText" size="15 100%-35 100%-15 100%-5"/>
|
||||
</object>
|
||||
|
||||
<object type="button" name="replayButton" style="ModernButtonRed" size="100%-310 100%-48 100%-170 100%-20">
|
||||
<translatableAttribute id="caption">Replay</translatableAttribute>
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ GuiInterface.prototype.GetExtendedSimulationState = function()
|
|||
let playerEnt = cmpPlayerManager.GetPlayerByID(i);
|
||||
let cmpPlayerStatisticsTracker = Engine.QueryInterface(playerEnt, IID_StatisticsTracker);
|
||||
if (cmpPlayerStatisticsTracker)
|
||||
ret.players[i].statistics = cmpPlayerStatisticsTracker.GetStatistics();
|
||||
ret.players[i].sequences = cmpPlayerStatisticsTracker.GetSequences();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
function StatisticsTracker() {}
|
||||
|
||||
const g_UpdateSequenceInterval = 30 * 1000;
|
||||
|
||||
StatisticsTracker.prototype.Schema =
|
||||
"<empty/>";
|
||||
|
||||
|
|
@ -142,6 +144,10 @@ StatisticsTracker.prototype.Init = function()
|
|||
this.lootCollected = 0;
|
||||
this.peakPercentMapControlled = 0;
|
||||
this.teamPeakPercentMapControlled = 0;
|
||||
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
this.updateTimer = cmpTimer.SetInterval(
|
||||
this.entity, IID_StatisticsTracker, "updateSequences", 0, g_UpdateSequenceInterval);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -195,11 +201,21 @@ StatisticsTracker.prototype.GetStatistics = function()
|
|||
};
|
||||
};
|
||||
|
||||
StatisticsTracker.prototype.GetSequences = function()
|
||||
{
|
||||
let ret = clone(this.sequences);
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
|
||||
ret.time.push(cmpTimer.GetTime() / 1000);
|
||||
this.PushValue(this.GetStatistics(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments counter associated with certain entity/counter and type of given entity.
|
||||
* @param cmpIdentity The entity identity component
|
||||
* @param counter The name of the counter to increment (e.g. "unitsTrained")
|
||||
* @param type The type of the counter (e.g. "workers")
|
||||
* @param cmpIdentity - the entity identity component.
|
||||
* @param counter - the name of the counter to increment (e.g. "unitsTrained").
|
||||
* @param type - the type of the counter (e.g. "workers").
|
||||
*/
|
||||
StatisticsTracker.prototype.CounterIncrement = function(cmpIdentity, counter, type)
|
||||
{
|
||||
|
|
@ -356,9 +372,9 @@ StatisticsTracker.prototype.CapturedEntity = function(capturedEntity)
|
|||
};
|
||||
|
||||
/**
|
||||
* @param type Generic type of resource (string)
|
||||
* @param amount Amount of resource, whick should be added (integer)
|
||||
* @param specificType Specific type of resource (string, optional)
|
||||
* @param {string} type - generic type of resource.
|
||||
* @param {number} amount - amount of resource, whick should be added.
|
||||
* @param {string} specificType - specific type of resource.
|
||||
*/
|
||||
StatisticsTracker.prototype.IncreaseResourceGatheredCounter = function(type, amount, specificType)
|
||||
{
|
||||
|
|
@ -369,8 +385,8 @@ StatisticsTracker.prototype.IncreaseResourceGatheredCounter = function(type, amo
|
|||
};
|
||||
|
||||
/**
|
||||
* @param type Generic type of resource (string)
|
||||
* @param amount Amount of resource, which should be added (integer)
|
||||
* @param {string} type - generic type of resource.
|
||||
* @param {number} amount - amount of resource, which should be added.
|
||||
*/
|
||||
StatisticsTracker.prototype.IncreaseResourceUsedCounter = function(type, amount)
|
||||
{
|
||||
|
|
@ -493,4 +509,41 @@ StatisticsTracker.prototype.OnTerritoriesChanged = function(msg)
|
|||
this.teamPeakPercentMapControlled = newPercent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the values of fromData to the end of the arrays of toData.
|
||||
* If toData misses the needed array, one will be created.
|
||||
*
|
||||
* @param fromData - an object of values or a value.
|
||||
* @param toData - an object of arrays or an array.
|
||||
**/
|
||||
StatisticsTracker.prototype.PushValue = function(fromData, toData)
|
||||
{
|
||||
if (typeof fromData == "object")
|
||||
for (let prop in fromData)
|
||||
{
|
||||
if (typeof toData[prop] != "object")
|
||||
toData[prop] = [fromData[prop]];
|
||||
else
|
||||
this.PushValue(fromData[prop], toData[prop]);
|
||||
}
|
||||
else
|
||||
toData.push(fromData);
|
||||
};
|
||||
|
||||
StatisticsTracker.prototype.updateSequences = function()
|
||||
{
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
|
||||
// Don't do this on Init, because GetStatistics doesn't work in this state of the game
|
||||
// This is probably, because the simulation hasn't totally started/initialized and we query some simulation values
|
||||
if (!this.sequences)
|
||||
{
|
||||
this.sequences = clone(this.GetStatistics());
|
||||
this.sequences.time = [];
|
||||
}
|
||||
|
||||
this.sequences.time.push(cmpTimer.GetTime() / 1000);
|
||||
this.PushValue(this.GetStatistics(), this.sequences);
|
||||
}
|
||||
|
||||
Engine.RegisterComponentType(IID_StatisticsTracker, "StatisticsTracker", StatisticsTracker);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ Resources = {
|
|||
"aiAnalysisInfluenceGroup":
|
||||
resource == "food" ? "ignore" :
|
||||
resource == "wood" ? "abundant" : "sparse"
|
||||
}),
|
||||
})
|
||||
};
|
||||
|
||||
var cmp = ConstructComponent(SYSTEM_ENTITY, "GuiInterface");
|
||||
|
|
@ -70,22 +70,22 @@ AddMock(SYSTEM_ENTITY, IID_EndGameManager, {
|
|||
|
||||
AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
|
||||
GetNumPlayers: function() { return 2; },
|
||||
GetPlayerByID: function(id) { TS_ASSERT(id === 0 || id === 1); return 100+id; },
|
||||
GetPlayerByID: function(id) { TS_ASSERT(id === 0 || id === 1); return 100+id; }
|
||||
});
|
||||
|
||||
AddMock(SYSTEM_ENTITY, IID_RangeManager, {
|
||||
GetLosVisibility: function(ent, player) { return "visible"; },
|
||||
GetLosCircular: function() { return false; },
|
||||
GetLosCircular: function() { return false; }
|
||||
});
|
||||
|
||||
AddMock(SYSTEM_ENTITY, IID_TemplateManager, {
|
||||
GetCurrentTemplateName: function(ent) { return "example"; },
|
||||
GetTemplate: function(name) { return ""; },
|
||||
GetTemplate: function(name) { return ""; }
|
||||
});
|
||||
|
||||
AddMock(SYSTEM_ENTITY, IID_Timer, {
|
||||
GetTime: function() { return 0; },
|
||||
SetTimeout: function(ent, iid, funcname, time, data) { return 0; },
|
||||
SetTimeout: function(ent, iid, funcname, time, data) { return 0; }
|
||||
});
|
||||
|
||||
AddMock(100, IID_Player, {
|
||||
|
|
@ -112,7 +112,7 @@ AddMock(100, IID_Player, {
|
|||
GetDisabledTechnologies: function() { return {}; },
|
||||
GetSpyCostMultiplier: function() { return 1; },
|
||||
HasSharedDropsites: function() { return false; },
|
||||
HasSharedLos: function() { return false; },
|
||||
HasSharedLos: function() { return false; }
|
||||
});
|
||||
|
||||
AddMock(100, IID_EntityLimits, {
|
||||
|
|
@ -128,7 +128,7 @@ AddMock(100, IID_TechnologyManager, {
|
|||
GetResearchedTechs: function() { return {}; },
|
||||
GetClassCounts: function() { return {}; },
|
||||
GetTypeCountsByClass: function() { return {}; },
|
||||
GetTechModifications: function() { return {}; },
|
||||
GetTechModifications: function() { return {}; }
|
||||
});
|
||||
|
||||
AddMock(100, IID_StatisticsTracker, {
|
||||
|
|
@ -139,39 +139,39 @@ AddMock(100, IID_StatisticsTracker, {
|
|||
"wood": 0,
|
||||
"metal": 0,
|
||||
"stone": 0,
|
||||
"vegetarianFood": 0,
|
||||
"vegetarianFood": 0
|
||||
},
|
||||
"percentMapExplored": 10
|
||||
};
|
||||
},
|
||||
GetStatistics: function() {
|
||||
GetSequences: function() {
|
||||
return {
|
||||
"unitsTrained": 10,
|
||||
"unitsLost": 9,
|
||||
"buildingsConstructed": 5,
|
||||
"buildingsCaptured": 7,
|
||||
"buildingsLost": 4,
|
||||
"civCentresBuilt": 1,
|
||||
"unitsTrained": [0, 10],
|
||||
"unitsLost": [0, 42],
|
||||
"buildingsConstructed": [1, 3],
|
||||
"buildingsCaptured": [3, 7],
|
||||
"buildingsLost": [3, 10],
|
||||
"civCentresBuilt": [4, 10],
|
||||
"resourcesGathered": {
|
||||
"food": 100,
|
||||
"wood": 0,
|
||||
"metal": 0,
|
||||
"stone": 0,
|
||||
"vegetarianFood": 0,
|
||||
"food": [5, 100],
|
||||
"wood": [0, 0],
|
||||
"metal": [0, 0],
|
||||
"stone": [0, 0],
|
||||
"vegetarianFood": [0, 0]
|
||||
},
|
||||
"treasuresCollected": 0,
|
||||
"lootCollected": 0,
|
||||
"percentMapExplored": 10,
|
||||
"teamPercentMapExplored": 10,
|
||||
"percentMapControlled": 10,
|
||||
"teamPercentMapControlled": 10,
|
||||
"peakPercentOfMapControlled": 10,
|
||||
"teamPeakPercentOfMapControlled": 10
|
||||
"treasuresCollected": [1, 20],
|
||||
"lootCollected": [0, 2],
|
||||
"percentMapExplored": [0, 10],
|
||||
"teamPercentMapExplored": [0, 10],
|
||||
"percentMapControlled": [0, 10],
|
||||
"teamPercentMapControlled": [0, 10],
|
||||
"peakPercentOfMapControlled": [0, 10],
|
||||
"teamPeakPercentOfMapControlled": [0, 10]
|
||||
};
|
||||
},
|
||||
IncreaseTrainedUnitsCounter: function() { return 1; },
|
||||
IncreaseConstructedBuildingsCounter: function() { return 1; },
|
||||
IncreaseBuiltCivCentresCounter: function() { return 1; },
|
||||
IncreaseBuiltCivCentresCounter: function() { return 1; }
|
||||
});
|
||||
|
||||
AddMock(101, IID_Player, {
|
||||
|
|
@ -198,7 +198,7 @@ AddMock(101, IID_Player, {
|
|||
GetDisabledTechnologies: function() { return {}; },
|
||||
GetSpyCostMultiplier: function() { return 1; },
|
||||
HasSharedDropsites: function() { return false; },
|
||||
HasSharedLos: function() { return false; },
|
||||
HasSharedLos: function() { return false; }
|
||||
});
|
||||
|
||||
AddMock(101, IID_EntityLimits, {
|
||||
|
|
@ -214,7 +214,7 @@ AddMock(101, IID_TechnologyManager, {
|
|||
GetResearchedTechs: function() { return {}; },
|
||||
GetClassCounts: function() { return {}; },
|
||||
GetTypeCountsByClass: function() { return {}; },
|
||||
GetTechModifications: function() { return {}; },
|
||||
GetTechModifications: function() { return {}; }
|
||||
});
|
||||
|
||||
AddMock(101, IID_StatisticsTracker, {
|
||||
|
|
@ -225,39 +225,39 @@ AddMock(101, IID_StatisticsTracker, {
|
|||
"wood": 0,
|
||||
"metal": 0,
|
||||
"stone": 0,
|
||||
"vegetarianFood": 0,
|
||||
"vegetarianFood": 0
|
||||
},
|
||||
"percentMapExplored": 10
|
||||
};
|
||||
},
|
||||
GetStatistics: function() {
|
||||
GetSequences: function() {
|
||||
return {
|
||||
"unitsTrained": 10,
|
||||
"unitsLost": 9,
|
||||
"buildingsConstructed": 5,
|
||||
"buildingsCaptured": 7,
|
||||
"buildingsLost": 4,
|
||||
"civCentresBuilt": 1,
|
||||
"unitsTrained": [0, 10],
|
||||
"unitsLost": [0, 9],
|
||||
"buildingsConstructed": [0, 5],
|
||||
"buildingsCaptured": [0, 7],
|
||||
"buildingsLost": [0, 4],
|
||||
"civCentresBuilt": [0, 1],
|
||||
"resourcesGathered": {
|
||||
"food": 100,
|
||||
"wood": 0,
|
||||
"metal": 0,
|
||||
"stone": 0,
|
||||
"vegetarianFood": 0,
|
||||
"food": [0, 100],
|
||||
"wood": [0, 0],
|
||||
"metal": [0, 0],
|
||||
"stone": [0, 0],
|
||||
"vegetarianFood": [0, 0]
|
||||
},
|
||||
"treasuresCollected": 0,
|
||||
"lootCollected": 0,
|
||||
"percentMapExplored": 10,
|
||||
"teamPercentMapExplored": 10,
|
||||
"percentMapControlled": 10,
|
||||
"teamPercentMapControlled": 10,
|
||||
"peakPercentOfMapControlled": 10,
|
||||
"teamPeakPercentOfMapControlled": 10
|
||||
"treasuresCollected": [0, 0],
|
||||
"lootCollected": [0, 0],
|
||||
"percentMapExplored": [0, 10],
|
||||
"teamPercentMapExplored": [0, 10],
|
||||
"percentMapControlled": [0, 10],
|
||||
"teamPercentMapControlled": [0, 10],
|
||||
"peakPercentOfMapControlled": [0, 10],
|
||||
"teamPeakPercentOfMapControlled": [0, 10]
|
||||
};
|
||||
},
|
||||
IncreaseTrainedUnitsCounter: function() { return 1; },
|
||||
IncreaseConstructedBuildingsCounter: function() { return 1; },
|
||||
IncreaseBuiltCivCentresCounter: function() { return 1; },
|
||||
IncreaseBuiltCivCentresCounter: function() { return 1; }
|
||||
});
|
||||
|
||||
// Note: property order matters when using TS_ASSERT_UNEVAL_EQUALS,
|
||||
|
|
@ -305,10 +305,10 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
|||
wood: 0,
|
||||
metal: 0,
|
||||
stone: 0,
|
||||
vegetarianFood: 0,
|
||||
vegetarianFood: 0
|
||||
},
|
||||
percentMapExplored: 10
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Player 2",
|
||||
|
|
@ -350,10 +350,10 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
|||
wood: 0,
|
||||
metal: 0,
|
||||
stone: 0,
|
||||
vegetarianFood: 0,
|
||||
vegetarianFood: 0
|
||||
},
|
||||
percentMapExplored: 10
|
||||
},
|
||||
}
|
||||
}
|
||||
],
|
||||
circularMap: false,
|
||||
|
|
@ -370,140 +370,160 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
|||
"food": "Food",
|
||||
"metal": "Metal",
|
||||
"stone": "Stone",
|
||||
"wood": "Wood",
|
||||
"wood": "Wood"
|
||||
},
|
||||
"aiInfluenceGroups": {
|
||||
"food": "ignore",
|
||||
"metal": "sparse",
|
||||
"stone": "sparse",
|
||||
"wood": "abundant",
|
||||
"wood": "abundant"
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
|
||||
players: [
|
||||
"players": [
|
||||
{
|
||||
name: "Player 1",
|
||||
civ: "gaia",
|
||||
color: { r:1, g:1, b:1, a:1 },
|
||||
controlsAll: false,
|
||||
popCount: 10,
|
||||
popLimit: 20,
|
||||
popMax: 200,
|
||||
panelEntities: [],
|
||||
resourceCounts: { food: 100 },
|
||||
trainingBlocked: false,
|
||||
state: "active",
|
||||
team: -1,
|
||||
teamsLocked: false,
|
||||
cheatsEnabled: false,
|
||||
disabledTemplates: {},
|
||||
disabledTechnologies: {},
|
||||
hasSharedDropsites: false,
|
||||
hasSharedLos: false,
|
||||
spyCostMultiplier: 1,
|
||||
phase: "village",
|
||||
isAlly: [false, false],
|
||||
isMutualAlly: [false, false],
|
||||
isNeutral: [false, false],
|
||||
isEnemy: [true, true],
|
||||
entityLimits: {"Foo": 10},
|
||||
entityCounts: {"Foo": 5},
|
||||
entityLimitChangers: {"Foo": {}},
|
||||
researchQueued: {},
|
||||
researchStarted: {},
|
||||
researchedTechs: {},
|
||||
classCounts: {},
|
||||
typeCountsByClass: {},
|
||||
canBarter: false,
|
||||
statistics: {
|
||||
unitsTrained: 10,
|
||||
unitsLost: 9,
|
||||
buildingsConstructed: 5,
|
||||
buildingsCaptured: 7,
|
||||
buildingsLost: 4,
|
||||
civCentresBuilt: 1,
|
||||
resourcesGathered: {
|
||||
food: 100,
|
||||
wood: 0,
|
||||
metal: 0,
|
||||
stone: 0,
|
||||
vegetarianFood: 0,
|
||||
"name": "Player 1",
|
||||
"civ": "gaia",
|
||||
"color": { "r":1, "g":1, "b":1, "a":1 },
|
||||
"controlsAll": false,
|
||||
"popCount": 10,
|
||||
"popLimit": 20,
|
||||
"popMax": 200,
|
||||
"panelEntities": [],
|
||||
"resourceCounts": { "food": 100 },
|
||||
"trainingBlocked": false,
|
||||
"state": "active",
|
||||
"team": -1,
|
||||
"teamsLocked": false,
|
||||
"cheatsEnabled": false,
|
||||
"disabledTemplates": {},
|
||||
"disabledTechnologies": {},
|
||||
"hasSharedDropsites": false,
|
||||
"hasSharedLos": false,
|
||||
"spyCostMultiplier": 1,
|
||||
"phase": "village",
|
||||
"isAlly": [false, false],
|
||||
"isMutualAlly": [false, false],
|
||||
"isNeutral": [false, false],
|
||||
"isEnemy": [true, true],
|
||||
"entityLimits": {"Foo": 10},
|
||||
"entityCounts": {"Foo": 5},
|
||||
"entityLimitChangers": {"Foo": {}},
|
||||
"researchQueued": {},
|
||||
"researchStarted": {},
|
||||
"researchedTechs": {},
|
||||
"classCounts": {},
|
||||
"typeCountsByClass": {},
|
||||
"canBarter": false,
|
||||
"statistics": {
|
||||
"resourcesGathered": {
|
||||
"food": 100,
|
||||
"wood": 0,
|
||||
"metal": 0,
|
||||
"stone": 0,
|
||||
"vegetarianFood": 0
|
||||
},
|
||||
treasuresCollected: 0,
|
||||
lootCollected: 0,
|
||||
percentMapExplored: 10,
|
||||
teamPercentMapExplored: 10,
|
||||
percentMapControlled: 10,
|
||||
teamPercentMapControlled: 10,
|
||||
peakPercentOfMapControlled: 10,
|
||||
teamPeakPercentOfMapControlled: 10
|
||||
"percentMapExplored": 10
|
||||
},
|
||||
"sequences": {
|
||||
"unitsTrained": [0, 10],
|
||||
"unitsLost": [0, 42],
|
||||
"buildingsConstructed": [1, 3],
|
||||
"buildingsCaptured": [3, 7],
|
||||
"buildingsLost": [3, 10],
|
||||
"civCentresBuilt": [4, 10],
|
||||
"resourcesGathered": {
|
||||
"food": [5, 100],
|
||||
"wood": [0, 0],
|
||||
"metal": [0, 0],
|
||||
"stone": [0, 0],
|
||||
"vegetarianFood": [0, 0]
|
||||
},
|
||||
"treasuresCollected": [1, 20],
|
||||
"lootCollected": [0, 2],
|
||||
"percentMapExplored": [0, 10],
|
||||
"teamPercentMapExplored": [0, 10],
|
||||
"percentMapControlled": [0, 10],
|
||||
"teamPercentMapControlled": [0, 10],
|
||||
"peakPercentOfMapControlled": [0, 10],
|
||||
"teamPeakPercentOfMapControlled": [0, 10]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Player 2",
|
||||
civ: "mace",
|
||||
color: { r:1, g:0, b:0, a:1 },
|
||||
controlsAll: true,
|
||||
popCount: 40,
|
||||
popLimit: 30,
|
||||
popMax: 300,
|
||||
panelEntities: [],
|
||||
resourceCounts: { food: 200 },
|
||||
trainingBlocked: false,
|
||||
state: "active",
|
||||
team: -1,
|
||||
teamsLocked: false,
|
||||
cheatsEnabled: false,
|
||||
disabledTemplates: {},
|
||||
disabledTechnologies: {},
|
||||
hasSharedDropsites: false,
|
||||
hasSharedLos: false,
|
||||
spyCostMultiplier: 1,
|
||||
phase: "village",
|
||||
isAlly: [true, true],
|
||||
isMutualAlly: [false, false],
|
||||
isNeutral: [false, false],
|
||||
isEnemy: [false, false],
|
||||
entityLimits: {"Bar": 20},
|
||||
entityCounts: {"Bar": 0},
|
||||
entityLimitChangers: {"Bar": {}},
|
||||
researchQueued: {},
|
||||
researchStarted: {},
|
||||
researchedTechs: {},
|
||||
classCounts: {},
|
||||
typeCountsByClass: {},
|
||||
canBarter: false,
|
||||
statistics: {
|
||||
unitsTrained: 10,
|
||||
unitsLost: 9,
|
||||
buildingsConstructed: 5,
|
||||
buildingsCaptured: 7,
|
||||
buildingsLost: 4,
|
||||
civCentresBuilt: 1,
|
||||
resourcesGathered: {
|
||||
food: 100,
|
||||
wood: 0,
|
||||
metal: 0,
|
||||
stone: 0,
|
||||
vegetarianFood: 0,
|
||||
"name": "Player 2",
|
||||
"civ": "mace",
|
||||
"color": { "r":1, "g":0, "b":0, "a":1 },
|
||||
"controlsAll": true,
|
||||
"popCount": 40,
|
||||
"popLimit": 30,
|
||||
"popMax": 300,
|
||||
"panelEntities": [],
|
||||
"resourceCounts": { "food": 200 },
|
||||
"trainingBlocked": false,
|
||||
"state": "active",
|
||||
"team": -1,
|
||||
"teamsLocked": false,
|
||||
"cheatsEnabled": false,
|
||||
"disabledTemplates": {},
|
||||
"disabledTechnologies": {},
|
||||
"hasSharedDropsites": false,
|
||||
"hasSharedLos": false,
|
||||
"spyCostMultiplier": 1,
|
||||
"phase": "village",
|
||||
"isAlly": [true, true],
|
||||
"isMutualAlly": [false, false],
|
||||
"isNeutral": [false, false],
|
||||
"isEnemy": [false, false],
|
||||
"entityLimits": {"Bar": 20},
|
||||
"entityCounts": {"Bar": 0},
|
||||
"entityLimitChangers": {"Bar": {}},
|
||||
"researchQueued": {},
|
||||
"researchStarted": {},
|
||||
"researchedTechs": {},
|
||||
"classCounts": {},
|
||||
"typeCountsByClass": {},
|
||||
"canBarter": false,
|
||||
"statistics": {
|
||||
"resourcesGathered": {
|
||||
"food": 100,
|
||||
"wood": 0,
|
||||
"metal": 0,
|
||||
"stone": 0,
|
||||
"vegetarianFood": 0
|
||||
},
|
||||
treasuresCollected: 0,
|
||||
lootCollected: 0,
|
||||
percentMapExplored: 10,
|
||||
teamPercentMapExplored: 10,
|
||||
percentMapControlled: 10,
|
||||
teamPercentMapControlled: 10,
|
||||
peakPercentOfMapControlled: 10,
|
||||
teamPeakPercentOfMapControlled: 10
|
||||
"percentMapExplored": 10
|
||||
},
|
||||
"sequences": {
|
||||
"unitsTrained": [0, 10],
|
||||
"unitsLost": [0, 9],
|
||||
"buildingsConstructed": [0, 5],
|
||||
"buildingsCaptured": [0, 7],
|
||||
"buildingsLost": [0, 4],
|
||||
"civCentresBuilt": [0, 1],
|
||||
"resourcesGathered": {
|
||||
"food": [0, 100],
|
||||
"wood": [0, 0],
|
||||
"metal": [0, 0],
|
||||
"stone": [0, 0],
|
||||
"vegetarianFood": [0, 0]
|
||||
},
|
||||
"treasuresCollected": [0, 0],
|
||||
"lootCollected": [0, 0],
|
||||
"percentMapExplored": [0, 10],
|
||||
"teamPercentMapExplored": [0, 10],
|
||||
"percentMapControlled": [0, 10],
|
||||
"teamPercentMapControlled": [0, 10],
|
||||
"peakPercentOfMapControlled": [0, 10],
|
||||
"teamPeakPercentOfMapControlled": [0, 10]
|
||||
}
|
||||
}
|
||||
],
|
||||
circularMap: false,
|
||||
timeElapsed: 0,
|
||||
gameType: "conquest",
|
||||
alliedVictory: false,
|
||||
"circularMap": false,
|
||||
"timeElapsed": 0,
|
||||
"gameType": "conquest",
|
||||
"alliedVictory": false,
|
||||
"barterPrices": {
|
||||
"buy": { "food": 150 },
|
||||
"sell": { "food": 25 }
|
||||
|
|
@ -514,15 +534,15 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
|
|||
"food": "Food",
|
||||
"metal": "Metal",
|
||||
"stone": "Stone",
|
||||
"wood": "Wood",
|
||||
"wood": "Wood"
|
||||
},
|
||||
"aiInfluenceGroups": {
|
||||
"food": "ignore",
|
||||
"metal": "sparse",
|
||||
"stone": "sparse",
|
||||
"wood": "abundant",
|
||||
"wood": "abundant"
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -537,7 +557,7 @@ AddMock(10, IID_Health, {
|
|||
GetMaxHitpoints: function() { return 60; },
|
||||
IsRepairable: function() { return false; },
|
||||
IsUnhealable: function() { return false; },
|
||||
IsUndeletable: function() { return false; },
|
||||
IsUndeletable: function() { return false; }
|
||||
});
|
||||
|
||||
AddMock(10, IID_Identity, {
|
||||
|
|
@ -545,7 +565,7 @@ AddMock(10, IID_Identity, {
|
|||
GetVisibleClassesList: function() { return ["class3", "class4"]; },
|
||||
GetRank: function() { return "foo"; },
|
||||
GetSelectionGroupName: function() { return "Selection Group Name"; },
|
||||
HasClass: function() { return true; },
|
||||
HasClass: function() { return true; }
|
||||
});
|
||||
|
||||
AddMock(10, IID_Position, {
|
||||
|
|
@ -558,7 +578,7 @@ AddMock(10, IID_Position, {
|
|||
},
|
||||
IsInWorld: function() {
|
||||
return true;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
AddMock(10, IID_ResourceTrickle, {
|
||||
|
|
@ -583,7 +603,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetEntityState(-1, 10), {
|
|||
rank: "foo",
|
||||
classes: ["class1", "class2"],
|
||||
visibleClasses: ["class3", "class4"],
|
||||
selectionGroupName: "Selection Group Name",
|
||||
selectionGroupName: "Selection Group Name"
|
||||
},
|
||||
fogging: null,
|
||||
foundation: null,
|
||||
|
|
@ -607,7 +627,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetEntityState(-1, 10), {
|
|||
maxHitpoints: 60,
|
||||
needsRepair: false,
|
||||
needsHeal: true,
|
||||
canDelete: true,
|
||||
canDelete: true
|
||||
});
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedEntityState(-1, 10), {
|
||||
|
|
@ -634,5 +654,5 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedEntityState(-1, 10), {
|
|||
"metal": 9
|
||||
}
|
||||
},
|
||||
speed: null,
|
||||
speed: null
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue