diff --git a/binaries/data/mods/public/gui/common/gamedescription.js b/binaries/data/mods/public/gui/common/gamedescription.js
index 8c3c4518a2..3cdb761dd6 100644
--- a/binaries/data/mods/public/gui/common/gamedescription.js
+++ b/binaries/data/mods/public/gui/common/gamedescription.js
@@ -449,13 +449,9 @@ function getGameDescription()
/**
* Sets the win/defeat icon to indicate current player's state.
- * @param {string} state - The current in-game state of the player.
- * @param {string} imageID - The name of the XML image object to update.
*/
-function setOutcomeIcon(state, imageID)
+function setOutcomeIcon(state, image)
{
- let image = Engine.GetGUIObjectByName(imageID);
-
if (state == "won")
{
image.sprite = "stretched:session/icons/victory.png";
diff --git a/binaries/data/mods/public/gui/session/diplomacy/DiplomacyDialog.js b/binaries/data/mods/public/gui/session/diplomacy/DiplomacyDialog.js
new file mode 100644
index 0000000000..23a7563353
--- /dev/null
+++ b/binaries/data/mods/public/gui/session/diplomacy/DiplomacyDialog.js
@@ -0,0 +1,89 @@
+/**
+ * This class is concerned with opening, closing and resizing the diplomacy dialog and
+ * relaying events to the classes that update individual elements of the dialog.
+ */
+class DiplomacyDialog
+{
+ constructor(diplomacyColors)
+ {
+ this.diplomacyDialogCeasefireCounter = new DiplomacyDialogCeasefireCounter();
+ this.diplomacyDialogColorsButton = new DiplomacyDialogColorsButton(diplomacyColors);
+ this.diplomacyDialogPlayerControlManager = undefined;
+
+ this.diplomacyDialogPanel = Engine.GetGUIObjectByName("diplomacyDialogPanel");
+ Engine.GetGUIObjectByName("diplomacyClose").onPress = this.close.bind(this);
+ }
+
+ onPlayerInit()
+ {
+ this.diplomacyDialogPlayerControlManager = new DiplomacyDialogPlayerControlManager();
+ this.resize();
+ }
+
+ onSpyResponse(notification, player)
+ {
+ this.diplomacyDialogPlayerControlManager.onSpyResponse(notification, player);
+ }
+
+ update()
+ {
+ if (!this.isOpen())
+ return;
+
+ if (g_ViewedPlayer >= 1)
+ this.updatePanels();
+ else
+ this.close();
+ }
+
+ updatePanels()
+ {
+ this.diplomacyDialogCeasefireCounter.update();
+ this.diplomacyDialogColorsButton.update();
+ this.diplomacyDialogPlayerControlManager.update();
+ }
+
+ open()
+ {
+ closeOpenDialogs();
+
+ if (g_ViewedPlayer < 1)
+ return;
+
+ this.updatePanels();
+ this.diplomacyDialogPanel.hidden = false;
+ }
+
+ close()
+ {
+ this.diplomacyDialogPanel.hidden = true;
+ }
+
+ isOpen()
+ {
+ return !this.diplomacyDialogPanel.hidden;
+ }
+
+ toggle()
+ {
+ let open = this.isOpen();
+
+ closeOpenDialogs();
+
+ if (!open)
+ this.open();
+ }
+
+ resize()
+ {
+ let widthOffset = DiplomacyDialogPlayerControl.prototype.TributeButtonManager.getWidthOffset() / 2;
+ let heightOffset = DiplomacyDialogPlayerControl.prototype.DiplomacyPlayerText.getHeightOffset() / 2;
+
+ let size = this.diplomacyDialogPanel.size;
+ size.left -= widthOffset;
+ size.right += widthOffset;
+ size.top -= heightOffset;
+ size.bottom += heightOffset;
+ this.diplomacyDialogPanel.size = size;
+ }
+}
diff --git a/binaries/data/mods/public/gui/session/diplomacy_window.xml b/binaries/data/mods/public/gui/session/diplomacy/DiplomacyDialog.xml
similarity index 94%
rename from binaries/data/mods/public/gui/session/diplomacy_window.xml
rename to binaries/data/mods/public/gui/session/diplomacy/DiplomacyDialog.xml
index 20cf482166..6c00abf1ad 100644
--- a/binaries/data/mods/public/gui/session/diplomacy_window.xml
+++ b/binaries/data/mods/public/gui/session/diplomacy/DiplomacyDialog.xml
@@ -55,11 +55,12 @@
-
diff --git a/binaries/data/mods/public/gui/session/minimap/MiniMapDiplomacyColorsButton.js b/binaries/data/mods/public/gui/session/minimap/MiniMapDiplomacyColorsButton.js
new file mode 100644
index 0000000000..3e14ded4a6
--- /dev/null
+++ b/binaries/data/mods/public/gui/session/minimap/MiniMapDiplomacyColorsButton.js
@@ -0,0 +1,36 @@
+/**
+ * The purpose of this class is to exclusively manage the diplomacy colors button within the minimap.
+ */
+class MiniMapDiplomacyColorsButton
+{
+ constructor(diplomacyColors)
+ {
+ this.diplomacyColorsButton = Engine.GetGUIObjectByName("diplomacyColorsButton");
+ this.diplomacyColorsButton.onPress = diplomacyColors.toggle.bind(diplomacyColors);
+
+ this.diplomacyColors = diplomacyColors;
+ }
+
+ update()
+ {
+ this.diplomacyColorsButton.tooltip =
+ colorizeHotkey("%(hotkey)s" + " ", "session.diplomacycolors") +
+ translate(this.Tooltip);
+
+ this.diplomacyColorsButton.sprite =
+ "stretched:" +
+ (this.diplomacyColors.isEnabled() ? this.SpriteEnabled : this.SpriteDisabled);
+
+ this.diplomacyColorsButton.sprite_over =
+ "stretched:" +
+ (this.diplomacyColors.isEnabled() ? this.SpriteEnabledOver : this.SpriteDisabledOver);
+ }
+}
+
+MiniMapDiplomacyColorsButton.prototype.Tooltip = markForTranslation("Toggle Diplomacy Colors");
+
+MiniMapDiplomacyColorsButton.prototype.SpriteEnabled = "session/minimap-diplomacy-on.png";
+MiniMapDiplomacyColorsButton.prototype.SpriteDisabled = "session/minimap-diplomacy-off.png";
+
+MiniMapDiplomacyColorsButton.prototype.SpriteEnabledOver = "session/minimap-diplomacy-on-highlight.png";
+MiniMapDiplomacyColorsButton.prototype.SpriteDisabledOver = "session/minimap-diplomacy-off-highlight.png";
diff --git a/binaries/data/mods/public/gui/session/minimap/MiniMapIdleWorkerButton.js b/binaries/data/mods/public/gui/session/minimap/MiniMapIdleWorkerButton.js
new file mode 100644
index 0000000000..54f16bc6b7
--- /dev/null
+++ b/binaries/data/mods/public/gui/session/minimap/MiniMapIdleWorkerButton.js
@@ -0,0 +1,32 @@
+/**
+ * If the button that this class manages is pressed, an idle unit having one of the given classes is selected.
+ */
+class MiniMapIdleWorkerButton
+{
+ constructor(idleClasses)
+ {
+ this.idleWorkerButton = Engine.GetGUIObjectByName("idleWorkerButton");
+ this.idleWorkerButton.onPress = this.onPress.bind(this);
+ this.idleClasses = idleClasses;
+ }
+
+ update()
+ {
+ this.idleWorkerButton.tooltip =
+ colorizeHotkey("%(hotkey)s" + " ", "selection.idleworker") +
+ translate(this.Tooltip);
+
+ this.idleWorkerButton.enabled = Engine.GuiInterfaceCall("HasIdleUnits", {
+ "viewedPlayer": g_ViewedPlayer,
+ "idleClasses": this.idleClasses,
+ "excludeUnits": []
+ });
+ }
+
+ onPress()
+ {
+ findIdleUnit(this.idleClasses);
+ }
+}
+
+MiniMapIdleWorkerButton.prototype.Tooltip = markForTranslation("Find idle worker");
diff --git a/binaries/data/mods/public/gui/session/minimap/MiniMapPanel.js b/binaries/data/mods/public/gui/session/minimap/MiniMapPanel.js
new file mode 100644
index 0000000000..d3133bf81b
--- /dev/null
+++ b/binaries/data/mods/public/gui/session/minimap/MiniMapPanel.js
@@ -0,0 +1,18 @@
+/**
+ * This class is concerned with managing the different elements of the minimap panel.
+ */
+class MiniMapPanel
+{
+ constructor(diplomacyColors, idleWorkerClasses)
+ {
+ this.diplomacyColorsButton = new MiniMapDiplomacyColorsButton(diplomacyColors);
+ this.idleWorkerButton = new MiniMapIdleWorkerButton(idleWorkerClasses);
+ this.minimap = new Minimap();
+ }
+
+ update()
+ {
+ this.diplomacyColorsButton.update();
+ this.idleWorkerButton.update();
+ }
+}
diff --git a/binaries/data/mods/public/gui/session/selection_details.js b/binaries/data/mods/public/gui/session/selection_details.js
index ec36c835ca..ca1b759543 100644
--- a/binaries/data/mods/public/gui/session/selection_details.js
+++ b/binaries/data/mods/public/gui/session/selection_details.js
@@ -72,7 +72,6 @@ function displaySingle(entState)
let civEmblem = g_CivData[playerState.civ].Emblem;
let playerName = playerState.name;
- let playerColor = rgbToGuiColor(g_DisplayedPlayerColors[entState.player], 128);
// Indicate disconnected players by prefixing their name
if (g_Players[entState.player].offline)
@@ -158,7 +157,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_DisplayedPlayerColors[playerID], 128);
+ unitCaptureBar.sprite = "color:" + g_DiplomacyColors.getPlayerColor(playerID, 128);
unitCaptureBar.hidden = false;
return startSize + size;
};
@@ -286,7 +285,10 @@ function displaySingle(entState)
Engine.GetGUIObjectByName("specific").caption = specificName;
Engine.GetGUIObjectByName("player").caption = playerName;
- Engine.GetGUIObjectByName("playerColorBackground").sprite = "color:" + playerColor;
+
+ Engine.GetGUIObjectByName("playerColorBackground").sprite =
+ "color:" + g_DiplomacyColors.getPlayerColor(entState.player, 128);
+
Engine.GetGUIObjectByName("generic").caption = genericName == specificName ? "" :
sprintf(translate("(%(genericName)s)"), {
"genericName": genericName
@@ -401,7 +403,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_DisplayedPlayerColors[pID], 128);
+ unitCaptureBar.sprite = "color:" + g_DiplomacyColors.getPlayerColor(pID, 128);
unitCaptureBar.hidden = false;
return startSize + size;
};
diff --git a/binaries/data/mods/public/gui/session/selection_panels.js b/binaries/data/mods/public/gui/session/selection_panels.js
index 86e70db901..e6da553f58 100644
--- a/binaries/data/mods/public/gui/session/selection_panels.js
+++ b/binaries/data/mods/public/gui/session/selection_panels.js
@@ -382,7 +382,7 @@ g_SelectionPanels.Garrison = {
"playername": g_Players[entState.player].name
});
- data.guiSelection.sprite = getPlayerHighlightColor(entState.player);
+ data.guiSelection.sprite = "color:" + g_DiplomacyColors.getPlayerColor(entState.player, 160);
data.button.sprite_disabled = data.button.sprite;
// Selection panel buttons only appear disabled if they
@@ -873,7 +873,7 @@ g_SelectionPanels.Selection = {
});
data.button.tooltip = tooltip;
- data.guiSelection.sprite = getPlayerHighlightColor(unitOwner);
+ data.guiSelection.sprite = "color:" + g_DiplomacyColors.getPlayerColor(unitOwner, 160);
data.guiSelection.hidden = !g_IsObserver;
data.countDisplay.caption = data.item.ents.length || "";
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 ed00cc26b3..45633865ae 100644
--- a/binaries/data/mods/public/gui/session/selection_panels_helpers.js
+++ b/binaries/data/mods/public/gui/session/selection_panels_helpers.js
@@ -31,11 +31,6 @@ function hasSameRestrictionCategory(templateName1, templateName2)
return false;
}
-function getPlayerHighlightColor(player)
-{
- return "color:" + rgbToGuiColor(g_DisplayedPlayerColors[player], 160);
-}
-
/**
* Returns a "color:255 0 0 Alpha" string based on how many resources are needed.
*/
diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js
index 73820e8eea..1807c6b727 100644
--- a/binaries/data/mods/public/gui/session/session.js
+++ b/binaries/data/mods/public/gui/session/session.js
@@ -11,20 +11,13 @@ const g_VictoryDurations = prepareForDropdown(g_Settings && g_Settings.VictoryDu
const g_VictoryConditions = g_Settings && g_Settings.VictoryConditions;
var g_Chat;
+var g_DiplomacyButton;
+var g_DiplomacyColors;
+var g_DiplomacyDialog;
+var g_MiniMapPanel;
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;
-
/**
* Colors to flash when pop limit reached.
*/
@@ -272,8 +265,12 @@ function init(initData, hotloadData)
restoreSavedGameData(initData.savedGUIData);
}
- g_DeveloperOverlay = new DeveloperOverlay();
g_Chat = new Chat();
+ g_DeveloperOverlay = new DeveloperOverlay();
+ g_DiplomacyColors = new DiplomacyColors();
+ g_DiplomacyDialog = new DiplomacyDialog(g_DiplomacyColors);
+ g_DiplomacyButton = new DiplomacyButton(g_DiplomacyDialog);
+ g_MiniMapPanel = new MiniMapPanel(g_DiplomacyColors, g_WorkerTypes);
LoadModificationTemplates();
updatePlayerData();
@@ -296,13 +293,14 @@ function initGUIObjects()
{
initMenu();
updateGameSpeedControl();
- resizeDiplomacyDialog();
resizeTradeDialog();
initBarterButtons();
initPanelEntities();
+ g_DiplomacyColors.onPlayerInit();
initViewedPlayerDropdown();
Engine.SetBoundingBoxDebugOverlay(false);
updateEnabledRangeOverlayTypes();
+ g_DiplomacyDialog.onPlayerInit();
}
function updatePlayerData()
@@ -353,69 +351,13 @@ 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";
-
- Engine.GetGUIObjectByName("diplomacyColorsWindowButtonIcon").sprite = g_DiplomacyColorsToggle ?
- "stretched:session/icons/diplomacy-on.png" :
- "stretched:session/icons/diplomacy.png";
-
- updateDisplayedPlayerColors();
-}
-
/**
- * Updates the displayed colors of players in the simulation and GUI.
+ * Called when the user changed the diplomacy colors in the options.
+ * TODO: Remove this proxy and make the options page agnostic of the session page.
*/
function updateDisplayedPlayerColors()
{
- if (g_DiplomacyColorsToggle)
- {
- let getDiplomacyColor = stance =>
- guiToRgbColor(Engine.ConfigDB_GetValue("user", "gui.session.diplomacycolors." + stance)) ||
- guiToRgbColor(Engine.ConfigDB_GetValue("default", "gui.session.diplomacycolors." + stance));
-
- 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 ? getDiplomacyColor("self") :
- g_Players[g_ViewedPlayer].isAlly[i] ? getDiplomacyColor("ally") :
- g_Players[g_ViewedPlayer].isNeutral[i] ? getDiplomacyColor("neutral") :
- getDiplomacyColor("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();
+ g_DiplomacyColors.updateDisplayedPlayerColors();
}
/**
@@ -423,22 +365,6 @@ function updateDisplayedPlayerColors()
*/
function updateHotkeyTooltips()
{
- Engine.GetGUIObjectByName("idleWorkerButton").tooltip =
- colorizeHotkey("%(hotkey)s" + " ", "selection.idleworker") +
- translate("Find idle worker");
-
- Engine.GetGUIObjectByName("diplomacyColorsButton").tooltip =
- colorizeHotkey("%(hotkey)s" + " ", "session.diplomacycolors") +
- translate("Toggle Diplomacy Colors");
-
- Engine.GetGUIObjectByName("diplomacyColorsWindowButton").tooltip =
- colorizeHotkey("%(hotkey)s" + " ", "session.diplomacycolors") +
- translate("Toggle Diplomacy Colors");
-
- Engine.GetGUIObjectByName("diplomacyButton").tooltip =
- colorizeHotkey("%(hotkey)s" + " ", "session.gui.diplomacy.toggle") +
- translate("Diplomacy");
-
Engine.GetGUIObjectByName("tradeButton").tooltip =
colorizeHotkey("%(hotkey)s" + " ", "session.gui.barter.toggle") +
translate("Barter & Trade");
@@ -506,7 +432,6 @@ function initializeMusic()
function initViewedPlayerDropdown()
{
- g_DisplayedPlayerColors = g_Players.map(player => player.color);
updateViewedPlayerDropdown();
// Select "observer" in the view player dropdown when rejoining as a defeated player
@@ -551,7 +476,7 @@ function selectViewPlayer(playerID)
}
Engine.SetViewedPlayer(g_ViewedPlayer);
- updateDisplayedPlayerColors();
+ g_DiplomacyColors.updateDisplayedPlayerColors();
updateTopPanel();
g_Chat.onUpdatePlayers();
updateHotkeyTooltips();
@@ -561,8 +486,7 @@ function selectViewPlayer(playerID)
Engine.GuiInterfaceCall("ResetTemplateModified");
onSimulationUpdate();
- if (g_IsDiplomacyOpen)
- openDiplomacy();
+ g_DiplomacyDialog.update();
if (g_IsTradeOpen)
openTrade();
@@ -687,7 +611,8 @@ function updateTopPanel()
resPop.size = resPopSize;
Engine.GetGUIObjectByName("population").hidden = !isPlayer;
- Engine.GetGUIObjectByName("diplomacyButton").hidden = !isPlayer;
+ g_DiplomacyButton.update();
+
Engine.GetGUIObjectByName("tradeButton").hidden = !isPlayer ||
(!g_ResourceData.GetTradableCodes().length && !g_ResourceData.GetBarterableCodes().length);
Engine.GetGUIObjectByName("observerText").hidden = isPlayer;
@@ -846,15 +771,6 @@ function changeGameSpeed(speed)
Engine.SetSimRate(speed);
}
-function updateIdleWorkerButton()
-{
- Engine.GetGUIObjectByName("idleWorkerButton").enabled = Engine.GuiInterfaceCall("HasIdleUnits", {
- "viewedPlayer": g_ViewedPlayer,
- "idleClasses": g_WorkerTypes,
- "excludeUnits": []
- });
-}
-
function onSimulationUpdate()
{
// Templates change depending on technologies and auras, so they have to be reloaded after such a change.
@@ -946,7 +862,6 @@ function updateGUIObjects()
updateSelectionDetails();
updateBuildingPlacementPreview();
updateTimeNotifications();
- updateIdleWorkerButton();
if (g_IsTradeOpen)
{
@@ -969,8 +884,9 @@ function updateGUIObjects()
}
updateViewedPlayerDropdown();
- updateDiplomacy();
g_DeveloperOverlay.update();
+ g_DiplomacyDialog.update();
+ g_MiniMapPanel.update();
}
function saveResPopTooltipSort()
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index 54f42feba9..05ac96e0f6 100644
--- a/binaries/data/mods/public/gui/session/session.xml
+++ b/binaries/data/mods/public/gui/session/session.xml
@@ -5,6 +5,10 @@
+
+
+
+
@@ -97,8 +101,8 @@
+
-
@@ -120,7 +124,7 @@
-
+
-
- toggleDiplomacy();
-
diff --git a/binaries/data/mods/public/gui/summary/summary.js b/binaries/data/mods/public/gui/summary/summary.js
index 4a643e6c4d..7deecee717 100644
--- a/binaries/data/mods/public/gui/summary/summary.js
+++ b/binaries/data/mods/public/gui/summary/summary.js
@@ -418,7 +418,7 @@ function updatePanelData(panelInfo)
boxSize.right = rowPlayerObjectWidth;
rowPlayerObject.size = boxSize;
- setOutcomeIcon(playerState.state, playerOutcome);
+ setOutcomeIcon(playerState.state, Engine.GetGUIObjectByName(playerOutcome));
playerNameColumn = Engine.GetGUIObjectByName(playerNameColumn);
playerNameColumn.caption = g_GameData.sim.playerStates[i + 1].name;