diff --git a/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-off-highlight.png b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-off-highlight.png
new file mode 100644
index 0000000000..35f3989903
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-off-highlight.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:54c2d0feeb6acd6c38c103fe18b2de348b8cd1ddccac659db10817fe7b92d710
+size 6044
diff --git a/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-off.png b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-off.png
new file mode 100644
index 0000000000..85512f8996
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-off.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae8a1a15ca0938a53052d597cb7a49c3ef895cf6c8d107a747638a411c390873
+size 4870
diff --git a/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-on-highlight.png b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-on-highlight.png
new file mode 100644
index 0000000000..65e5ca7c27
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-on-highlight.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ac6819131a123e69965bb812589d6cf3f072ff58cc1794b56493dbc9bd09846b
+size 6134
diff --git a/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-on.png b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-on.png
new file mode 100644
index 0000000000..5108a63d5f
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/ui/session/minimap-diplomacy-on.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:103baf3ce588f5b201ef8a4056fce1ce3282bda0fe79e21d3034af9dd6be4af7
+size 4870
diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js
index 34b3f8e67a..b9277dabc4 100644
--- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js
+++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js
@@ -1047,7 +1047,7 @@ var g_PlayerMiscElements = {
},
},
"playerColor": {
- "sprite": (playerIdx) => "color:" + rgbToGuiColor(g_GameAttributes.settings.PlayerData[playerIdx].Color) + " 100",
+ "sprite": (playerIdx) => "color:" + rgbToGuiColor(g_GameAttributes.settings.PlayerData[playerIdx].Color, 100),
},
"playerConfig": {
"hidden": (playerIdx) => !g_GameAttributes.settings.PlayerData[playerIdx].AI,
diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js
index 7332a74a39..5dd4f5a6b4 100644
--- a/binaries/data/mods/public/gui/session/menu.js
+++ b/binaries/data/mods/public/gui/session/menu.js
@@ -433,7 +433,7 @@ function diplomacySetupTexts(i, rowsize)
row.size = size;
row.hidden = false;
- row.sprite = "color: " + rgbToGuiColor(g_Players[i].color) + " 32";
+ row.sprite = "color:" + rgbToGuiColor(g_DisplayedPlayerColors[i], 32);
setOutcomeIcon(g_Players[i].state, "diplomacyPlayerOutcome[" + (i - 1) + "]");
diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js
index b727b76c6b..ae4209ac63 100644
--- a/binaries/data/mods/public/gui/session/messages.js
+++ b/binaries/data/mods/public/gui/session/messages.js
@@ -331,17 +331,22 @@ var g_NotificationsTypes =
},
"diplomacy": function(notification, player)
{
+ updatePlayerData();
+ if (g_DiplomacyColorsToggle)
+ updateDisplayedPlayerColors();
+
addChatMessage({
"type": "diplomacy",
"sourcePlayer": player,
"targetPlayer": notification.targetPlayer,
"status": notification.status
});
- updatePlayerData();
},
"ceasefire-ended": function(notification, player)
{
updatePlayerData();
+ if (g_DiplomacyColorsToggle)
+ updateDisplayedPlayerColors();
},
"tutorial": function(notification, player)
{
@@ -965,7 +970,7 @@ function colorizePlayernameByGUID(guid)
function colorizePlayernameHelper(username, playerID)
{
- let playerColor = playerID > -1 ? rgbToGuiColor(g_Players[playerID].color) : "white";
+ let playerColor = playerID > -1 ? rgbToGuiColor(g_DisplayedPlayerColors[playerID]) : "white";
return coloredText(username || translate("Unknown Player"), playerColor);
}
diff --git a/binaries/data/mods/public/gui/session/minimap_panel.xml b/binaries/data/mods/public/gui/session/minimap_panel.xml
index 6980215203..761706a6b6 100644
--- a/binaries/data/mods/public/gui/session/minimap_panel.xml
+++ b/binaries/data/mods/public/gui/session/minimap_panel.xml
@@ -21,11 +21,25 @@
name="idleWorkerButton"
type="button"
size="100%-120 100%-120 100%-5 100%-5"
- tooltip_style="sessionToolTip" hotkey="selection.idleworker"
+ tooltip_style="sessionToolTip"
+ hotkey="selection.idleworker"
sprite="stretched:session/minimap-idle.png"
sprite_over="stretched:session/minimap-idle-highlight.png"
sprite_disabled="stretched:session/minimap-idle-disabled.png"
>
findIdleUnit(g_WorkerTypes);
+
+
+
diff --git a/binaries/data/mods/public/gui/session/selection_details.js b/binaries/data/mods/public/gui/session/selection_details.js
index 9434a83c30..f4b1a4da77 100644
--- a/binaries/data/mods/public/gui/session/selection_details.js
+++ b/binaries/data/mods/public/gui/session/selection_details.js
@@ -72,7 +72,7 @@ function displaySingle(entState)
let civEmblem = g_CivData[playerState.civ].Emblem;
let playerName = playerState.name;
- let playerColor = playerState.color.r + " " + playerState.color.g + " " + playerState.color.b + " 128";
+ let playerColor = rgbToGuiColor(g_DisplayedPlayerColors[entState.player], 128);
// Indicate disconnected players by prefixing their name
if (g_Players[entState.player].offline)
@@ -138,7 +138,7 @@ function displaySingle(entState)
let size = 100 * Math.max(0, Math.min(1, entState.capturePoints[playerID] / entState.maxCapturePoints));
sizeObj.rright = startSize + size;
unitCaptureBar.size = sizeObj;
- unitCaptureBar.sprite = "color: " + rgbToGuiColor(g_Players[playerID].color, 128);
+ unitCaptureBar.sprite = "color:" + rgbToGuiColor(g_DisplayedPlayerColors[playerID], 128);
unitCaptureBar.hidden = false;
return startSize + size;
};
@@ -271,7 +271,7 @@ function displaySingle(entState)
Engine.GetGUIObjectByName("specific").caption = specificName;
Engine.GetGUIObjectByName("player").caption = playerName;
- Engine.GetGUIObjectByName("playerColorBackground").sprite = "color: " + playerColor;
+ Engine.GetGUIObjectByName("playerColorBackground").sprite = "color:" + playerColor;
Engine.GetGUIObjectByName("generic").caption = genericName == specificName ? "" :
sprintf(translate("(%(genericName)s)"), {
"genericName": genericName
@@ -382,7 +382,7 @@ function displayMultiple(entStates)
let size = 100 * Math.max(0, Math.min(1, capturePoints[pID] / maxCapturePoints));
sizeObj.rbottom = startSize + size;
unitCaptureBar.size = sizeObj;
- unitCaptureBar.sprite = "color: " + rgbToGuiColor(g_Players[pID].color, 128);
+ unitCaptureBar.sprite = "color:" + rgbToGuiColor(g_DisplayedPlayerColors[pID], 128);
unitCaptureBar.hidden = false;
return startSize + size;
};
diff --git a/binaries/data/mods/public/gui/session/selection_panels_helpers.js b/binaries/data/mods/public/gui/session/selection_panels_helpers.js
index 0322d619e8..54d1827726 100644
--- a/binaries/data/mods/public/gui/session/selection_panels_helpers.js
+++ b/binaries/data/mods/public/gui/session/selection_panels_helpers.js
@@ -33,7 +33,7 @@ function hasSameRestrictionCategory(templateName1, templateName2)
function getPlayerHighlightColor(player)
{
- return "color:" + rgbToGuiColor(g_Players[player].color) + " 160";
+ return "color:" + rgbToGuiColor(g_DisplayedPlayerColors[player], 160);
}
/**
diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js
index d7a1cf3766..aa74bd8316 100644
--- a/binaries/data/mods/public/gui/session/session.js
+++ b/binaries/data/mods/public/gui/session/session.js
@@ -11,6 +11,22 @@ const g_VictoryConditions = prepareForDropdown(g_Settings && g_Settings.VictoryC
const g_VictoryDurations = prepareForDropdown(g_Settings && g_Settings.VictoryDurations);
var g_GameSpeeds;
+/**
+ * Whether to display diplomacy colors (where players see self/ally/neutral/enemy each in different colors and
+ * observers see each team in a different color) or regular player colors.
+ */
+var g_DiplomacyColorsToggle = false;
+
+/**
+ * The array of displayed player colors (either the diplomacy color or regular color for each player).
+ */
+var g_DisplayedPlayerColors;
+
+/**
+ * The self/ally/neutral/enemy color codes.
+ */
+var g_DiplomacyColorPalette;
+
/**
* Colors to flash when pop limit reached.
*/
@@ -278,6 +294,8 @@ function init(initData, hotloadData)
for (let slot in Engine.GetGUIObjectByName("panelEntityPanel").children)
initPanelEntities(slot);
+ g_DiplomacyColorPalette = Engine.ReadJSONFile(g_SettingsDirectory + "diplomacy_colors.json");
+ g_DisplayedPlayerColors = g_Players.map(player => player.color);
updateViewedPlayerDropdown();
// Select "observer" in the view player dropdown when rejoining as a defeated player
@@ -358,6 +376,59 @@ function updatePlayerData()
g_Players = playerData;
}
+function updateDiplomacyColorsButton()
+{
+ g_DiplomacyColorsToggle = !g_DiplomacyColorsToggle;
+ let diplomacyColorsButton = Engine.GetGUIObjectByName("diplomacyColorsButton");
+ diplomacyColorsButton.sprite = g_DiplomacyColorsToggle ?
+ "stretched:session/minimap-diplomacy-on.png" :
+ "stretched:session/minimap-diplomacy-off.png";
+ diplomacyColorsButton.sprite_over = g_DiplomacyColorsToggle ?
+ "stretched:session/minimap-diplomacy-on-highlight.png" :
+ "stretched:session/minimap-diplomacy-off-highlight.png";
+ updateDisplayedPlayerColors();
+}
+
+/**
+ * Updates the displayed colors of players in the simulation and GUI.
+ */
+function updateDisplayedPlayerColors()
+{
+ if (g_DiplomacyColorsToggle)
+ {
+ let teamRepresentatives = {};
+ for (let i = 1; i < g_Players.length; ++i)
+ if (g_ViewedPlayer <= 0)
+ {
+ // Observers and gaia see team colors
+ let team = g_Players[i].team;
+ g_DisplayedPlayerColors[i] = g_Players[teamRepresentatives[team] || i].color;
+ if (team != -1 && !teamRepresentatives[team])
+ teamRepresentatives[team] = i;
+ }
+ else
+ // Players see colors depending on diplomacy
+ g_DisplayedPlayerColors[i] =
+ g_ViewedPlayer == i ? g_DiplomacyColorPalette.Self :
+ g_Players[g_ViewedPlayer].isAlly[i] ? g_DiplomacyColorPalette.Ally :
+ g_Players[g_ViewedPlayer].isNeutral[i] ? g_DiplomacyColorPalette.Neutral :
+ g_DiplomacyColorPalette.Enemy;
+
+ g_DisplayedPlayerColors[0] = g_Players[0].color;
+ }
+ else
+ g_DisplayedPlayerColors = g_Players.map(player => player.color);
+
+ Engine.GuiInterfaceCall("UpdateDisplayedPlayerColors", {
+ "displayedPlayerColors": g_DisplayedPlayerColors,
+ "displayDiplomacyColors": g_DiplomacyColorsToggle,
+ "showAllStatusBars": g_ShowAllStatusBars,
+ "selected": g_Selection.toList()
+ });
+
+ updateGUIObjects();
+}
+
/**
* Depends on the current player (g_IsObserver).
*/
@@ -477,6 +548,7 @@ function selectViewPlayer(playerID)
}
Engine.SetViewedPlayer(g_ViewedPlayer);
+ updateDisplayedPlayerColors();
updateTopPanel();
updateChatAddressees();
updateHotkeyTooltips();
@@ -899,6 +971,7 @@ function updateGUIObjects()
global.music.setState(global.music.states[battleState]);
}
+ updateViewedPlayerDropdown();
updateDiplomacy();
}
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
index 48b286ba10..bdec9c0d7f 100644
--- a/binaries/data/mods/public/simulation/components/GuiInterface.js
+++ b/binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -769,6 +769,39 @@ GuiInterface.prototype.GetAllBuildableEntities = function(player, cmd)
return buildableEnts;
};
+GuiInterface.prototype.UpdateDisplayedPlayerColors = function(player, data)
+{
+ let updateEntityColor = (iids, entities) => {
+ for (let ent of entities)
+ for (let iid of iids)
+ {
+ let cmp = Engine.QueryInterface(ent, iid);
+ if (cmp)
+ cmp.UpdateColor();
+ }
+ };
+
+ let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ let numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers();
+ for (let i = 1; i < numPlayers; ++i)
+ {
+ let cmpPlayer = QueryPlayerIDInterface(i, IID_Player);
+ if (!cmpPlayer)
+ continue;
+
+ cmpPlayer.SetDisplayDiplomacyColor(data.displayDiplomacyColors);
+ if (data.displayDiplomacyColors)
+ cmpPlayer.SetDiplomacyColor(data.displayedPlayerColors[i]);
+
+ updateEntityColor(data.showAllStatusBars && (i == player || player == -1) ?
+ [IID_Minimap, IID_RangeOverlayRenderer, IID_RallyPointRenderer, IID_StatusBars] :
+ [IID_Minimap, IID_RangeOverlayRenderer, IID_RallyPointRenderer],
+ cmpRangeManager.GetEntitiesByPlayer(i));
+ }
+ updateEntityColor([IID_Selectable, IID_StatusBars], data.selected);
+ Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager).UpdateColors();
+};
+
GuiInterface.prototype.SetSelectionHighlight = function(player, cmd)
{
let playerColors = {}; // cache of owner -> color map
@@ -791,7 +824,7 @@ GuiInterface.prototype.SetSelectionHighlight = function(player, cmd)
color = { "r":1, "g":1, "b":1 };
let cmpPlayer = QueryPlayerIDInterface(owner);
if (cmpPlayer)
- color = cmpPlayer.GetColor();
+ color = cmpPlayer.GetDisplayedColor();
playerColors[owner] = color;
}
@@ -1902,6 +1935,7 @@ let exposedFunctions = {
"GetFormationInfoFromTemplate": 1,
"IsStanceSelected": 1,
+ "UpdateDisplayedPlayerColors": 1,
"SetSelectionHighlight": 1,
"GetAllBuildableEntities": 1,
"SetStatusBars": 1,
diff --git a/binaries/data/mods/public/simulation/components/Player.js b/binaries/data/mods/public/simulation/components/Player.js
index f539fca219..d7369e7ec6 100644
--- a/binaries/data/mods/public/simulation/components/Player.js
+++ b/binaries/data/mods/public/simulation/components/Player.js
@@ -21,6 +21,21 @@ Player.prototype.Schema =
"" +
"";
+/**
+ * Don't serialize diplomacyColor or displayDiplomacyColor since they're modified by the GUI.
+ */
+Player.prototype.Serialize = function()
+{
+ let state = {};
+ for (let key in this)
+ if (this.hasOwnProperty(key))
+ state[key] = this[key];
+
+ state.diplomacyColor = undefined;
+ state.displayDiplomacyColor = false;
+ return state;
+};
+
/**
* Which units will be shown with special icons at the top.
*/
@@ -32,6 +47,8 @@ Player.prototype.Init = function()
this.name = undefined; // define defaults elsewhere (supporting other languages)
this.civ = undefined;
this.color = undefined;
+ this.diplomacyColor = undefined;
+ this.displayDiplomacyColor = false;
this.popUsed = 0; // population of units owned or trained by this player
this.popBonuses = 0; // sum of population bonuses of player's entities
this.maxPop = 300; // maximum population
@@ -122,7 +139,7 @@ Player.prototype.SetColor = function(r, g, b)
{
var colorInitialized = !!this.color;
- this.color = { "r": r/255.0, "g": g/255.0, "b": b/255.0, "a": 1.0 };
+ this.color = { "r": r / 255, "g": g / 255, "b": b / 255, "a": 1 };
// Used in Atlas
if (colorInitialized)
@@ -131,11 +148,26 @@ Player.prototype.SetColor = function(r, g, b)
});
};
+Player.prototype.SetDiplomacyColor = function(color)
+{
+ this.diplomacyColor = { "r": color.r / 255, "g": color.g / 255, "b": color.b / 255, "a": 1 };
+};
+
+Player.prototype.SetDisplayDiplomacyColor = function(displayDiplomacyColor)
+{
+ this.displayDiplomacyColor = displayDiplomacyColor;
+};
+
Player.prototype.GetColor = function()
{
return this.color;
};
+Player.prototype.GetDisplayedColor = function()
+{
+ return this.displayDiplomacyColor ? this.diplomacyColor : this.color;
+};
+
// Try reserving num population slots. Returns 0 on success or number of missing slots otherwise.
Player.prototype.TryReservePopulationSlots = function(num)
{
diff --git a/binaries/data/mods/public/simulation/components/StatusBars.js b/binaries/data/mods/public/simulation/components/StatusBars.js
index 3bbfcfbf5f..3dcc21c634 100644
--- a/binaries/data/mods/public/simulation/components/StatusBars.js
+++ b/binaries/data/mods/public/simulation/components/StatusBars.js
@@ -33,6 +33,10 @@ StatusBars.prototype.Init = function()
{
this.enabled = false;
this.showRank = false;
+
+ // Whether the status bars used the player colors anywhere (e.g. in the capture bar)
+ this.usedPlayerColors = false;
+
this.auraSources = new Map();
};
@@ -103,6 +107,12 @@ StatusBars.prototype.OnPackProgressUpdate = function(msg)
this.RegenerateSprites();
};
+StatusBars.prototype.UpdateColor = function()
+{
+ if (this.usedPlayerColors)
+ this.RegenerateSprites();
+};
+
StatusBars.prototype.RegenerateSprites = function()
{
let cmpOverlayRenderer = Engine.QueryInterface(this.entity, IID_OverlayRenderer);
@@ -199,6 +209,8 @@ StatusBars.prototype.AddCaptureBar = function(cmpOverlayRenderer, yoffset)
let owner = cmpOwnership.GetOwner();
if (owner == INVALID_PLAYER)
return 0;
+
+ this.usedPlayerColors = true;
let cp = cmpCapturable.GetCapturePoints();
// Size of health bar (in world-space units)
@@ -210,7 +222,7 @@ StatusBars.prototype.AddCaptureBar = function(cmpOverlayRenderer, yoffset)
let setCaptureBarPart = function(playerID, startSize)
{
- let c = QueryPlayerIDInterface(playerID).GetColor();
+ let c = QueryPlayerIDInterface(playerID).GetDisplayedColor();
let strColor = (c.r * 255) + " " + (c.g * 255) + " " + (c.b * 255) + " 255";
let size = width * cp[playerID] / cmpCapturable.GetMaxCapturePoints();
diff --git a/binaries/data/mods/public/simulation/data/settings/diplomacy_colors.json b/binaries/data/mods/public/simulation/data/settings/diplomacy_colors.json
new file mode 100644
index 0000000000..fad87f74bb
--- /dev/null
+++ b/binaries/data/mods/public/simulation/data/settings/diplomacy_colors.json
@@ -0,0 +1,6 @@
+{
+ "Self": { "r": 0, "g": 68, "b": 255 },
+ "Ally": { "r": 94, "g": 255, "b": 0 },
+ "Neutral": { "r": 255, "g": 220, "b": 0 },
+ "Enemy": { "r": 255, "g": 0, "b": 0 }
+}
diff --git a/source/graphics/TerritoryTexture.cpp b/source/graphics/TerritoryTexture.cpp
index af398b3c52..f2f7592a28 100644
--- a/source/graphics/TerritoryTexture.cpp
+++ b/source/graphics/TerritoryTexture.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -53,7 +53,7 @@ void CTerritoryTexture::DeleteTexture()
bool CTerritoryTexture::UpdateDirty()
{
CmpPtr cmpTerritoryManager(m_Simulation, SYSTEM_ENTITY);
- return cmpTerritoryManager && cmpTerritoryManager->NeedUpdate(&m_DirtyID);
+ return cmpTerritoryManager && cmpTerritoryManager->NeedUpdateTexture(&m_DirtyID);
}
void CTerritoryTexture::BindTexture(int unit)
@@ -178,7 +178,7 @@ void CTerritoryTexture::GenerateBitmap(const Grid& territories, u8* bitmap,
CColor color(1, 0, 1, 1);
CmpPtr cmpPlayer(m_Simulation, cmpPlayerManager->GetPlayerByID(p));
if (cmpPlayer)
- color = cmpPlayer->GetColor();
+ color = cmpPlayer->GetDisplayedColor();
colors.push_back(color);
}
diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp
index 0502de3b84..807f9dfd08 100644
--- a/source/ps/Game.cpp
+++ b/source/ps/Game.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -449,7 +449,7 @@ void CGame::CachePlayerColors()
if (!cmpPlayer)
m_PlayerColors[i] = BrokenColor;
else
- m_PlayerColors[i] = cmpPlayer->GetColor();
+ m_PlayerColors[i] = cmpPlayer->GetDisplayedColor();
}
}
diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp
index 0e84e4c606..614ea5a502 100644
--- a/source/simulation2/components/CCmpAIManager.cpp
+++ b/source/simulation2/components/CCmpAIManager.cpp
@@ -1032,11 +1032,11 @@ public:
passabilityMap = &cmpPathfinder->GetPassabilityGrid();
// Get the territory data
- // Since getting the territory grid can trigger a recalculation, we check NeedUpdate first
+ // Since getting the territory grid can trigger a recalculation, we check NeedUpdateAI first
Grid dummyGrid2;
const Grid* territoryMap = &dummyGrid2;
CmpPtr cmpTerritoryManager(GetSystemEntity());
- if (cmpTerritoryManager && cmpTerritoryManager->NeedUpdate(&m_TerritoriesDirtyID, &m_TerritoriesDirtyBlinkingID))
+ if (cmpTerritoryManager && cmpTerritoryManager->NeedUpdateAI(&m_TerritoriesDirtyID, &m_TerritoriesDirtyBlinkingID))
territoryMap = &cmpTerritoryManager->GetTerritoryGrid();
LoadPathfinderClasses(state);
@@ -1094,9 +1094,9 @@ public:
}
// Update the territory data
- // Since getting the territory grid can trigger a recalculation, we check NeedUpdate first
+ // Since getting the territory grid can trigger a recalculation, we check NeedUpdateAI first
CmpPtr cmpTerritoryManager(GetSystemEntity());
- if (cmpTerritoryManager && (cmpTerritoryManager->NeedUpdate(&m_TerritoriesDirtyID, &m_TerritoriesDirtyBlinkingID) || m_JustDeserialized))
+ if (cmpTerritoryManager && (cmpTerritoryManager->NeedUpdateAI(&m_TerritoriesDirtyID, &m_TerritoriesDirtyBlinkingID) || m_JustDeserialized))
{
const Grid& territoryMap = cmpTerritoryManager->GetTerritoryGrid();
m_Worker.UpdateTerritoryMap(territoryMap);
diff --git a/source/simulation2/components/CCmpMinimap.cpp b/source/simulation2/components/CCmpMinimap.cpp
index f8a519587c..69accff3a4 100644
--- a/source/simulation2/components/CCmpMinimap.cpp
+++ b/source/simulation2/components/CCmpMinimap.cpp
@@ -232,7 +232,7 @@ public:
if (!cmpPlayer)
return;
- CColor color = cmpPlayer->GetColor();
+ CColor color = cmpPlayer->GetDisplayedColor();
m_R = (u8) (color.r * 255);
m_G = (u8) (color.g * 255);
m_B = (u8) (color.b * 255);
diff --git a/source/simulation2/components/CCmpRallyPointRenderer.cpp b/source/simulation2/components/CCmpRallyPointRenderer.cpp
index 7557622fcf..96fe7606bf 100644
--- a/source/simulation2/components/CCmpRallyPointRenderer.cpp
+++ b/source/simulation2/components/CCmpRallyPointRenderer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -351,6 +351,12 @@ public:
return !m_RallyPoints.empty();
}
+ void UpdateColor()
+ {
+ UpdateLineColor();
+ ConstructAllOverlayLines();
+ }
+
private:
/**
@@ -598,7 +604,7 @@ void CCmpRallyPointRenderer::UpdateLineColor()
if (!cmpPlayer)
return;
- m_LineColor = cmpPlayer->GetColor();
+ m_LineColor = cmpPlayer->GetDisplayedColor();
}
void CCmpRallyPointRenderer::RecomputeAllRallyPointPaths()
diff --git a/source/simulation2/components/CCmpRangeOverlayRenderer.cpp b/source/simulation2/components/CCmpRangeOverlayRenderer.cpp
index 003afabab0..a0be8af731 100644
--- a/source/simulation2/components/CCmpRangeOverlayRenderer.cpp
+++ b/source/simulation2/components/CCmpRangeOverlayRenderer.cpp
@@ -154,7 +154,7 @@ public:
if (!cmpPlayer)
return;
- CColor color = cmpPlayer->GetColor();
+ CColor color = cmpPlayer->GetDisplayedColor();
m_Color = color;
}
diff --git a/source/simulation2/components/CCmpSelectable.cpp b/source/simulation2/components/CCmpSelectable.cpp
index 489d1901d1..d8e1adbdae 100644
--- a/source/simulation2/components/CCmpSelectable.cpp
+++ b/source/simulation2/components/CCmpSelectable.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -244,7 +244,7 @@ public:
/**
* Set the color of the current owner.
*/
- void UpdatePlayerColor();
+ virtual void UpdateColor();
private:
SOverlayDescriptor m_OverlayDescriptor;
@@ -333,7 +333,7 @@ void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global))
if (msgData.from == INVALID_PLAYER || msgData.to == INVALID_PLAYER)
break;
- UpdatePlayerColor();
+ UpdateColor();
InvalidateStaticOverlay();
break;
}
@@ -345,7 +345,7 @@ void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global))
if (!cmpOwnership || msgData.player != cmpOwnership->GetOwner())
break;
- UpdatePlayerColor();
+ UpdateColor();
break;
}
case MT_PositionChanged:
@@ -378,7 +378,7 @@ void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global))
}
}
-void CCmpSelectable::UpdatePlayerColor()
+void CCmpSelectable::UpdateColor()
{
CmpPtr cmpOwnership(GetEntityHandle());
@@ -393,7 +393,7 @@ void CCmpSelectable::UpdatePlayerColor()
{
CmpPtr cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(cmpOwnership->GetOwner()));
if (cmpPlayer)
- color = cmpPlayer->GetColor();
+ color = cmpPlayer->GetDisplayedColor();
}
// Update the highlight color, while keeping the current alpha target value intact
@@ -556,7 +556,7 @@ void CCmpSelectable::RenderSubmit(SceneCollector& collector)
{
if (!m_Cached)
{
- UpdatePlayerColor();
+ UpdateColor();
m_Cached = true;
}
diff --git a/source/simulation2/components/CCmpTerritoryManager.cpp b/source/simulation2/components/CCmpTerritoryManager.cpp
index e49947c0fd..9659f395f4 100644
--- a/source/simulation2/components/CCmpTerritoryManager.cpp
+++ b/source/simulation2/components/CCmpTerritoryManager.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -102,6 +102,7 @@ public:
struct SBoundaryLine
{
bool blinking;
+ player_id_t owner;
CColor color;
SOverlayTexturedLine overlay;
};
@@ -128,6 +129,7 @@ public:
m_DirtyID = 1;
m_DirtyBlinkingID = 1;
m_Visible = true;
+ m_ColorChanged = false;
m_AnimTime = 0.0;
@@ -258,6 +260,8 @@ public:
size_t m_DirtyID;
size_t m_DirtyBlinkingID;
+ bool m_ColorChanged;
+
void MakeDirty()
{
SAFE_DELETE(m_Territories);
@@ -266,25 +270,24 @@ public:
m_TriggerEvent = true;
}
- virtual bool NeedUpdate(size_t* dirtyID) const
+ virtual bool NeedUpdateTexture(size_t* dirtyID)
{
- if (*dirtyID != m_DirtyID)
- {
- *dirtyID = m_DirtyID;
- return true;
- }
- return false;
+ if (*dirtyID == m_DirtyID && !m_ColorChanged)
+ return false;
+
+ *dirtyID = m_DirtyID;
+ m_ColorChanged = false;
+ return true;
}
- virtual bool NeedUpdate(size_t* dirtyID, size_t* dirtyBlinkingID) const
+ virtual bool NeedUpdateAI(size_t* dirtyID, size_t* dirtyBlinkingID) const
{
- if (*dirtyID != m_DirtyID || *dirtyBlinkingID != m_DirtyBlinkingID)
- {
- *dirtyID = m_DirtyID;
- *dirtyBlinkingID = m_DirtyBlinkingID;
- return true;
- }
- return false;
+ if (*dirtyID == m_DirtyID && *dirtyBlinkingID == m_DirtyBlinkingID)
+ return false;
+
+ *dirtyID = m_DirtyID;
+ *dirtyBlinkingID = m_DirtyBlinkingID;
+ return true;
}
void CalculateCostGrid();
@@ -306,6 +309,8 @@ public:
m_Visible = visible;
}
+ void UpdateColors();
+
private:
bool m_Visible;
@@ -623,10 +628,11 @@ void CCmpTerritoryManager::UpdateBoundaryLines()
CColor color(1, 0, 1, 1);
CmpPtr cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(boundaries[i].owner));
if (cmpPlayer)
- color = cmpPlayer->GetColor();
+ color = cmpPlayer->GetDisplayedColor();
m_BoundaryLines.push_back(SBoundaryLine());
m_BoundaryLines.back().blinking = boundaries[i].blinking;
+ m_BoundaryLines.back().owner = boundaries[i].owner;
m_BoundaryLines.back().color = color;
m_BoundaryLines.back().overlay.m_SimContext = &GetSimContext();
m_BoundaryLines.back().overlay.m_TextureBase = textureBase;
@@ -805,6 +811,25 @@ bool CCmpTerritoryManager::IsTerritoryBlinking(entity_pos_t x, entity_pos_t z)
return (m_Territories->get(i, j) & TERRITORY_BLINKING_MASK) != 0;
}
+void CCmpTerritoryManager::UpdateColors()
+{
+ m_ColorChanged = true;
+
+ CmpPtr cmpPlayerManager(GetSystemEntity());
+ if (!cmpPlayerManager)
+ return;
+
+ for (SBoundaryLine& boundaryLine : m_BoundaryLines)
+ {
+ CmpPtr cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(boundaryLine.owner));
+ if (!cmpPlayer)
+ continue;
+
+ boundaryLine.color = cmpPlayer->GetDisplayedColor();
+ boundaryLine.overlay.m_Color = boundaryLine.color;
+ }
+}
+
TerritoryOverlay::TerritoryOverlay(CCmpTerritoryManager& manager) :
TerrainTextureOverlay((float)Pathfinding::NAVCELLS_PER_TILE / ICmpTerritoryManager::NAVCELLS_PER_TERRITORY_TILE),
m_TerritoryManager(manager)
diff --git a/source/simulation2/components/ICmpPlayer.cpp b/source/simulation2/components/ICmpPlayer.cpp
index 75a9a4c6b5..5f1f0d386b 100644
--- a/source/simulation2/components/ICmpPlayer.cpp
+++ b/source/simulation2/components/ICmpPlayer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -33,9 +33,9 @@ class CCmpPlayerScripted : public ICmpPlayer
public:
DEFAULT_SCRIPT_WRAPPER(PlayerScripted)
- virtual CColor GetColor()
+ virtual CColor GetDisplayedColor()
{
- return m_Script.Call("GetColor");
+ return m_Script.Call("GetDisplayedColor");
}
virtual std::wstring GetCiv()
diff --git a/source/simulation2/components/ICmpPlayer.h b/source/simulation2/components/ICmpPlayer.h
index 2968e62157..02f64b1da5 100644
--- a/source/simulation2/components/ICmpPlayer.h
+++ b/source/simulation2/components/ICmpPlayer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ class CFixedVector3D;
class ICmpPlayer : public IComponent
{
public:
- virtual CColor GetColor() = 0;
+ virtual CColor GetDisplayedColor() = 0;
virtual std::wstring GetCiv() = 0;
virtual CFixedVector3D GetStartingCameraPos() = 0;
virtual CFixedVector3D GetStartingCameraRot() = 0;
diff --git a/source/simulation2/components/ICmpRallyPointRenderer.cpp b/source/simulation2/components/ICmpRallyPointRenderer.cpp
index 3ef6b04966..aaba61c3a3 100644
--- a/source/simulation2/components/ICmpRallyPointRenderer.cpp
+++ b/source/simulation2/components/ICmpRallyPointRenderer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -29,4 +29,5 @@ DEFINE_INTERFACE_METHOD_2("UpdatePosition", void, ICmpRallyPointRenderer, Update
DEFINE_INTERFACE_METHOD_1("AddPosition", void, ICmpRallyPointRenderer, AddPosition_wrapper, CFixedVector2D)
DEFINE_INTERFACE_METHOD_0("Reset", void, ICmpRallyPointRenderer, Reset)
DEFINE_INTERFACE_METHOD_CONST_0("IsSet", bool, ICmpRallyPointRenderer, IsSet)
+DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpRallyPointRenderer, UpdateColor)
END_INTERFACE_WRAPPER(RallyPointRenderer)
diff --git a/source/simulation2/components/ICmpRallyPointRenderer.h b/source/simulation2/components/ICmpRallyPointRenderer.h
index 50629f2bc6..2133f658d5 100644
--- a/source/simulation2/components/ICmpRallyPointRenderer.h
+++ b/source/simulation2/components/ICmpRallyPointRenderer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -50,6 +50,9 @@ public:
/// Returns true if at least one display rally point is set
virtual bool IsSet() const = 0;
+ /// Updates the line color
+ virtual void UpdateColor() = 0;
+
DECLARE_INTERFACE_TYPE(RallyPointRenderer)
};
diff --git a/source/simulation2/components/ICmpRangeOverlayRenderer.cpp b/source/simulation2/components/ICmpRangeOverlayRenderer.cpp
index 217eda980c..50b13e6935 100644
--- a/source/simulation2/components/ICmpRangeOverlayRenderer.cpp
+++ b/source/simulation2/components/ICmpRangeOverlayRenderer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -23,4 +23,5 @@
BEGIN_INTERFACE_WRAPPER(RangeOverlayRenderer)
DEFINE_INTERFACE_METHOD_4("AddRangeOverlay", void, ICmpRangeOverlayRenderer, AddRangeOverlay, float, std::string, std::string, float)
DEFINE_INTERFACE_METHOD_0("ResetRangeOverlays", void, ICmpRangeOverlayRenderer, ResetRangeOverlays)
+DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpRangeOverlayRenderer, UpdateColor)
END_INTERFACE_WRAPPER(RangeOverlayRenderer)
diff --git a/source/simulation2/components/ICmpRangeOverlayRenderer.h b/source/simulation2/components/ICmpRangeOverlayRenderer.h
index 86911ad2cf..09591a35c9 100644
--- a/source/simulation2/components/ICmpRangeOverlayRenderer.h
+++ b/source/simulation2/components/ICmpRangeOverlayRenderer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -34,6 +34,11 @@ public:
*/
virtual void ResetRangeOverlays() = 0;
+ /**
+ * Updates the overlay color to match the player color.
+ */
+ virtual void UpdateColor() = 0;
+
DECLARE_INTERFACE_TYPE(RangeOverlayRenderer)
};
diff --git a/source/simulation2/components/ICmpSelectable.cpp b/source/simulation2/components/ICmpSelectable.cpp
index 58e1d7fc64..ad3dc1271b 100644
--- a/source/simulation2/components/ICmpSelectable.cpp
+++ b/source/simulation2/components/ICmpSelectable.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -25,6 +25,7 @@
BEGIN_INTERFACE_WRAPPER(Selectable)
DEFINE_INTERFACE_METHOD_2("SetSelectionHighlight", void, ICmpSelectable, SetSelectionHighlight, CColor, bool)
+DEFINE_INTERFACE_METHOD_0("UpdateColor", void, ICmpSelectable, UpdateColor)
END_INTERFACE_WRAPPER(Selectable)
bool ICmpSelectable::ms_EnableDebugOverlays = false;
diff --git a/source/simulation2/components/ICmpSelectable.h b/source/simulation2/components/ICmpSelectable.h
index a09fc75557..67d3349424 100644
--- a/source/simulation2/components/ICmpSelectable.h
+++ b/source/simulation2/components/ICmpSelectable.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -31,7 +31,7 @@ public:
virtual bool IsEditorOnly() const = 0;
/**
- * Set the selection highlight state.
+ * Sets the selection highlight state.
* The highlight is typically a circle/square overlay around the unit.
* @param color color and alpha of the selection highlight. Set color.a = 0 to hide the highlight.
* @param selected whether the entity is selected; affects desaturation for always visible highlights.
@@ -54,7 +54,12 @@ public:
}
/**
- * Set the alpha of the selection highlight. Set to 0 to hide the highlight.
+ * Updates the selection color to match the current owner.
+ */
+ virtual void UpdateColor() = 0;
+
+ /**
+ * Sets the alpha of the selection highlight. Set to 0 to hide the highlight.
*/
virtual void SetSelectionHighlightAlpha(float alpha) = 0;
diff --git a/source/simulation2/components/ICmpTerritoryManager.cpp b/source/simulation2/components/ICmpTerritoryManager.cpp
index 22eff21cc3..232dbf5dd2 100644
--- a/source/simulation2/components/ICmpTerritoryManager.cpp
+++ b/source/simulation2/components/ICmpTerritoryManager.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -28,4 +28,5 @@ DEFINE_INTERFACE_METHOD_2("IsConnected", bool, ICmpTerritoryManager, IsConnected
DEFINE_INTERFACE_METHOD_3("SetTerritoryBlinking", void, ICmpTerritoryManager, SetTerritoryBlinking, entity_pos_t, entity_pos_t, bool)
DEFINE_INTERFACE_METHOD_2("IsTerritoryBlinking", bool, ICmpTerritoryManager, IsTerritoryBlinking, entity_pos_t, entity_pos_t)
DEFINE_INTERFACE_METHOD_1("GetTerritoryPercentage", u8, ICmpTerritoryManager, GetTerritoryPercentage, player_id_t)
+DEFINE_INTERFACE_METHOD_0("UpdateColors", void, ICmpTerritoryManager, UpdateColors)
END_INTERFACE_WRAPPER(TerritoryManager)
diff --git a/source/simulation2/components/ICmpTerritoryManager.h b/source/simulation2/components/ICmpTerritoryManager.h
index ff28d6d085..2999339073 100644
--- a/source/simulation2/components/ICmpTerritoryManager.h
+++ b/source/simulation2/components/ICmpTerritoryManager.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -29,8 +29,15 @@ class Grid;
class ICmpTerritoryManager : public IComponent
{
public:
- virtual bool NeedUpdate(size_t* dirtyID) const = 0;
- virtual bool NeedUpdate(size_t* dirtyID, size_t* dirtyBlinkingID) const = 0;
+ /**
+ * Returns whether the territory texture needs to be updated.
+ */
+ virtual bool NeedUpdateTexture(size_t* dirtyID) = 0;
+
+ /**
+ * Returns whether the AI territory map needs to be updated.
+ */
+ virtual bool NeedUpdateAI(size_t* dirtyID, size_t* dirtyBlinkingID) const = 0;
/**
* Number of pathfinder navcells per territory tile.
@@ -91,6 +98,11 @@ public:
*/
virtual void SetVisibility(bool visible) = 0;
+ /**
+ * Updates the boundary and territory colors.
+ */
+ virtual void UpdateColors() = 0;
+
DECLARE_INTERFACE_TYPE(TerritoryManager)
};
diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
index 9b194e9966..ef8f533576 100644
--- a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
+++ b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -145,7 +145,10 @@ static CColor GetOwnerPlayerColor(PlayerColorMap& colorMap, entity_id_t id)
entity_id_t playerEnt = cmpPlayerManager->GetPlayerByID(owner);
CmpPtr cmpPlayer(sim, playerEnt);
if (cmpPlayer)
- color = colorMap[owner] = cmpPlayer->GetColor();
+ {
+ colorMap[owner] = cmpPlayer->GetDisplayedColor();
+ color = colorMap[owner];
+ }
}
}
return color;