diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 0c2cc5b292..3f8e9d1bdc 100644
--- a/binaries/data/config/default.cfg
+++ b/binaries/data/config/default.cfg
@@ -385,6 +385,12 @@ phase = completed ; Show a chat notification if you or an ally h
enable = true ; Enable/disable the splashscreen
version = 0 ; Splashscreen version (date of last modification). By default, 0 to force splashscreen to appear at first launch
+[gui.session.diplomacycolors]
+self = "21 55 149" ; Color of your units when diplomacy colors are enabled
+ally = "86 180 31" ; Color of allies when diplomacy colors are enabled
+neutral = "231 200 5" ; Color of neutral players when diplomacy colors are enabled
+enemy = "150 20 20" ; Color of enemies when diplomacy colors are enabled
+
[joystick] ; EXPERIMENTAL: joystick/gamepad settings
enable = false
deadzone = 8192
diff --git a/binaries/data/mods/public/gui/common/color.js b/binaries/data/mods/public/gui/common/color.js
index 63835df1d3..091cbe1169 100644
--- a/binaries/data/mods/public/gui/common/color.js
+++ b/binaries/data/mods/public/gui/common/color.js
@@ -17,12 +17,27 @@ function rgbToGuiColor(color, alpha)
if (color && ("r" in color) && ("g" in color) && ("b" in color))
ret = color.r + " " + color.g + " " + color.b;
- if (alpha)
+ if (alpha !== undefined)
ret += " " + alpha;
return ret;
}
+function guiToRgbColor(string)
+{
+ let color = string.split(" ");
+ if (color.length != 3 && color.length != 4 ||
+ color.some(num => !Number.isInteger(+num) || num < 0 || num > 255))
+ return undefined;
+
+ return {
+ "r": +color[0],
+ "g": +color[1],
+ "b": +color[2],
+ "alpha": color.length == 4 ? +color[3] : undefined
+ };
+}
+
/**
* True if the colors are identical.
*
diff --git a/binaries/data/mods/public/gui/options/options.js b/binaries/data/mods/public/gui/options/options.js
index efc1f1ade2..e202cde761 100644
--- a/binaries/data/mods/public/gui/options/options.js
+++ b/binaries/data/mods/public/gui/options/options.js
@@ -8,6 +8,11 @@ var g_Options;
*/
var g_HasCallback;
+/**
+ * Functions to call after closing the page.
+ */
+var g_Callbacks;
+
/**
* Vertical size of a tab button.
*/
@@ -68,6 +73,29 @@ var g_OptionType = {
"guiToValue": control => control.caption,
"guiSetter": "onTextEdit"
},
+ "color":
+ {
+ "configToValue": value => value,
+ "valueToGui": (value, control) => {
+ control.caption = value;
+ },
+ "guiToValue": control => control.caption,
+ "guiSetter": "onTextEdit",
+ "sanitizeValue": (value, control, option) => {
+ let color = guiToRgbColor(value);
+ let sanitized = rgbToGuiColor(color);
+ if (control)
+ {
+ control.sprite = sanitized == value ? "ModernDarkBoxWhite" : "ModernDarkBoxWhiteInvalid";
+ control.children[1].sprite = sanitized == value ? "color:" + value : "color:255 0 255";
+ }
+ return sanitized;
+ },
+ "tooltip": (value, option) =>
+ sprintf(translate("Default: %(value)s"), {
+ "value": Engine.ConfigDB_GetValue("default", option.config)
+ })
+ },
"number":
{
"configToValue": value => value,
@@ -137,6 +165,7 @@ var g_OptionType = {
function init(data, hotloadData)
{
+ g_Callbacks = new Set();
g_HasCallback = hotloadData && hotloadData.callback || data && data.callback;
g_TabCategorySelected = hotloadData ? hotloadData.tabCategorySelected : 0;
@@ -217,6 +246,9 @@ function displayOptions()
if (option.function)
Engine[option.function](value);
+ if (option.callback)
+ g_Callbacks.add(option.callback);
+
enableButtons();
};
@@ -346,7 +378,7 @@ function closePage()
function closePageWithoutConfirmation()
{
if (g_HasCallback)
- Engine.PopGuiPageCB();
+ Engine.PopGuiPageCB(g_Callbacks);
else
Engine.PopGuiPage();
}
diff --git a/binaries/data/mods/public/gui/options/options.json b/binaries/data/mods/public/gui/options/options.json
index 0a0f7db891..554c2bbcbc 100644
--- a/binaries/data/mods/public/gui/options/options.json
+++ b/binaries/data/mods/public/gui/options/options.json
@@ -454,19 +454,22 @@
"type": "boolean",
"label": "Attack Range Visualization",
"tooltip": "Display the attack range of selected defensive structures (can also be toggled in-game with the hotkey).",
- "config": "gui.session.attackrange"
+ "config": "gui.session.attackrange",
+ "callback": "updateEnabledRangeOverlayTypes"
},
{
"type": "boolean",
"label": "Aura Range Visualization",
"tooltip": "Display the range of auras of selected units and structures (can also be toggled in-game with the hotkey).",
- "config": "gui.session.aurasrange"
+ "config": "gui.session.aurasrange",
+ "callback": "updateEnabledRangeOverlayTypes"
},
{
"type": "boolean",
"label": "Heal Range Visualization",
"tooltip": "Display the healing range of selected units (can also be toggled in-game with the hotkey).",
- "config": "gui.session.healrange"
+ "config": "gui.session.healrange",
+ "callback": "updateEnabledRangeOverlayTypes"
},
{
"type": "boolean",
@@ -490,6 +493,34 @@
{ "value": -1, "label": "Ascending" },
{ "value": 1, "label": "Descending" }
]
+ },
+ {
+ "type": "color",
+ "label": "Diplomacy Colors: Self",
+ "tooltip": "Color of your units when diplomacy colors are enabled.",
+ "config": "gui.session.diplomacycolors.self",
+ "callback": "updateDisplayedPlayerColors"
+ },
+ {
+ "type": "color",
+ "label": "Diplomacy Colors: Ally",
+ "tooltip": "Color of allies when diplomacy colors are enabled.",
+ "config": "gui.session.diplomacycolors.ally",
+ "callback": "updateDisplayedPlayerColors"
+ },
+ {
+ "type": "color",
+ "label": "Diplomacy Colors: Neutral",
+ "tooltip": "Color of neutral players when diplomacy colors are enabled.",
+ "config": "gui.session.diplomacycolors.neutral",
+ "callback": "updateDisplayedPlayerColors"
+ },
+ {
+ "type": "color",
+ "label": "Diplomacy Colors: Enemy",
+ "tooltip": "Color of enemies when diplomacy colors are enabled.",
+ "config": "gui.session.diplomacycolors.enemy",
+ "callback": "updateDisplayedPlayerColors"
}
]
}
diff --git a/binaries/data/mods/public/gui/options/options.xml b/binaries/data/mods/public/gui/options/options.xml
index eb822d4907..6f742702b4 100644
--- a/binaries/data/mods/public/gui/options/options.xml
+++ b/binaries/data/mods/public/gui/options/options.xml
@@ -27,6 +27,10 @@
+
diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js
index 337b894fd1..6a9e6a7655 100644
--- a/binaries/data/mods/public/gui/session/menu.js
+++ b/binaries/data/mods/public/gui/session/menu.js
@@ -252,10 +252,19 @@ function openOptions()
pauseGame();
Engine.PushGuiPage("page_options.xml", {
- "callback": "resumeGame"
+ "callback": "optionsPageClosed"
});
}
+function optionsPageClosed(data)
+{
+ for (let callback of data)
+ if (global[callback])
+ global[callback]();
+
+ resumeGame();
+}
+
function openChat(command = "")
{
if (g_Disconnected)
diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js
index 9374f6618d..ca267aab37 100644
--- a/binaries/data/mods/public/gui/session/session.js
+++ b/binaries/data/mods/public/gui/session/session.js
@@ -23,11 +23,6 @@ var g_DiplomacyColorsToggle = false;
*/
var g_DisplayedPlayerColors;
-/**
- * The self/ally/neutral/enemy color codes.
- */
-var g_DiplomacyColorPalette;
-
/**
* Colors to flash when pop limit reached.
*/
@@ -295,7 +290,6 @@ 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();
@@ -311,7 +305,7 @@ function init(initData, hotloadData)
g_Selection.selected = hotloadData.selection;
Engine.SetBoundingBoxDebugOverlay(false);
-
+ updateEnabledRangeOverlayTypes();
initChatWindow();
sendLobbyPlayerlistUpdate();
@@ -400,6 +394,10 @@ 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)
@@ -413,10 +411,10 @@ function updateDisplayedPlayerColors()
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_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;
}
@@ -892,12 +890,6 @@ function onSimulationUpdate()
handleNotifications();
updateGUIObjects();
- for (let type of ["Attack", "Auras", "Heal"])
- Engine.GuiInterfaceCall("EnableVisualRangeOverlayType", {
- "type": type,
- "enabled": Engine.ConfigDB_GetValue("user", "gui.session." + type.toLowerCase() + "range") == "true"
- });
-
if (g_ConfirmExit)
confirmExit();
}
@@ -1423,6 +1415,15 @@ function toggleRangeOverlay(type)
});
}
+function updateEnabledRangeOverlayTypes()
+{
+ for (let type of ["Attack", "Auras", "Heal"])
+ Engine.GuiInterfaceCall("EnableVisualRangeOverlayType", {
+ "type": type,
+ "enabled": Engine.ConfigDB_GetValue("user", "gui.session." + type.toLowerCase() + "range") == "true"
+ });
+}
+
// Update the additional list of entities to be highlighted.
function updateAdditionalHighlight()
{
diff --git a/binaries/data/mods/public/simulation/data/settings/diplomacy_colors.json b/binaries/data/mods/public/simulation/data/settings/diplomacy_colors.json
deleted file mode 100644
index fad87f74bb..0000000000
--- a/binaries/data/mods/public/simulation/data/settings/diplomacy_colors.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "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 }
-}