Index: binaries/data/mods/public/gui/common/settings.js
===================================================================
--- binaries/data/mods/public/gui/common/settings.js (revision 17014)
+++ binaries/data/mods/public/gui/common/settings.js (working copy)
@@ -31,6 +31,7 @@
{
var settings = {
"Ceasefire": loadCeasefire(),
+ "PlayerColors": loadPlayerColors(),
"PopulationCapacities": loadPopulationCapacities(),
"StartingResources": loadSettingValuesFile("starting_resources.json")
};
@@ -88,6 +89,24 @@
}
/**
+* Loads available colors settings.
+*
+* @returns {Array|undefined}
+*/
+function loadPlayerColors()
+{
+ var json = Engine.ReadJSONFile("simulation/data/player_defaults.json");
+
+ if (!json || !json.PlayerData || !Array.isArray(json.PlayerData))
+ {
+ error("Could not load player_defaults.json");
+ return undefined;
+ }
+
+ return json.PlayerData.map(player => player.Color);
+}
+
+/**
* Loads available population capacities.
*
* @returns {Array|undefined}
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.js (revision 17014)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.js (working copy)
@@ -6,6 +6,7 @@
const VICTORY_DEFAULTIDX = 1;
const g_Ceasefire = prepareForDropdown(g_Settings ? g_Settings.Ceasefire : undefined);
+const g_PlayerColors = prepareForDropdown(g_Settings ? g_Settings.PlayerColors : undefined);
const g_PopulationCapacities = prepareForDropdown(g_Settings ? g_Settings.PopulationCapacities : undefined);
const g_StartingResources = prepareForDropdown(g_Settings ? g_Settings.StartingResources : undefined);
@@ -50,6 +51,10 @@
var g_AIs = [];
+var g_PlayerColorsSorted = [];
+var g_PlayerColorIdsSorted = [];
+var g_PlayerColorDisplayNamesSorted = [];
+
var g_ChatMessages = [];
// Data caches
@@ -381,6 +386,37 @@
updateGameAttributes();
};
+ // Populate color drop-down lists.
+ var colorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
+ colorPicker.list = getPlayerColorLabelsSorted();
+ colorPicker.list_data = getPlayerColorIdsSorted();
+ colorPicker.selected = -1;
+ colorPicker.onSelectionChange = function()
+ { // Update color
+ if (this.selected !== -1)
+ {
+ var numPlayers = g_GameAttributes.settings.PlayerData.length;
+ var used = 0;
+ var playerColorsSorted = getPlayerColorsSorted();
+ for (var o = 0; o < numPlayers; o++)
+ {
+ if (rgbValuesMatch(playerColorsSorted[this.list_data[this.selected]], g_GameAttributes.settings.PlayerData[o].Color))
+ {
+ ++used;
+ break;
+ }
+ }
+ if (!used)
+ {
+ copyRgbValuesFromColorIntoColor(playerColorsSorted[this.list_data[this.selected]], g_GameAttributes.settings.PlayerData[playerSlot].Color);
+ }
+ }
+ if (!g_IsInGuiUpdate)
+ {
+ updateGameAttributes();
+ }
+ };
+
// Set events
var civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
civ.onSelectionChange = function() {
@@ -414,6 +450,122 @@
}
}
+// Returns the index of the specified color.
+function getIndexOfColor(color)
+{
+ for (var i = 0; i < g_PlayerColors.length; ++i)
+ {
+ var playerColorsSorted = getPlayerColorsSorted();
+ if (rgbValuesMatch(playerColorsSorted[i], color))
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+function rgbToHsl(color){
+ var r = color.r/255, g = color.g/255, b = color.b/255;
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2;
+ if (max === min)
+ {
+ h = s = 0; // achromatic
+ }
+ else
+ {
+ var d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ switch(max)
+ {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return [h * 360, s * 100, l * 100];
+}
+
+// Get list of player colors sorted by color value.
+// See http://stackoverflow.com/a/11923973/939364
+function getPlayerColorsSorted()
+{
+ if (g_PlayerColorsSorted.length === 0)
+ {
+ var hslArray = [];
+ for (var i = 0; i < g_PlayerColors.length; ++i)
+ {
+ //Transforming rgb to hsl
+ //`hslArray[i][1]` (`i`) is a reference to the rgb color, in order to retrieve it later
+ hslArray[i] = [rgbToHsl(g_PlayerColors[i]),i];
+ }
+
+ var sortedHslArray = [];
+ outerloop:
+ for (var i = 0; i < hslArray.length; ++i)
+ {
+ for (var j = 0; j < sortedHslArray.length; ++j)
+ {
+ if (sortedHslArray[j][0][0] > hslArray[i][0][0])
+ {
+ sortedHslArray.splice(j, 0, hslArray[i]);
+ continue outerloop;
+ }
+ }
+ sortedHslArray.push(hslArray[i]);
+ }
+
+ for (var i = 0; i < sortedHslArray.length; ++i)
+ {
+ g_PlayerColorsSorted[i] = g_PlayerColors[sortedHslArray[i][1]];
+ }
+ }
+ return g_PlayerColorsSorted;
+}
+
+// Get a list of player color display names.
+function getPlayerColorLabelsSorted()
+{
+ if (g_PlayerColorDisplayNamesSorted.length === 0)
+ {
+ var playerColorsSorted = getPlayerColorsSorted();
+ for (var i = 0; i < playerColorsSorted.length; ++i)
+ {
+ g_PlayerColorDisplayNamesSorted[i] = "[color=\"" + playerColorsSorted[i].r + " " + playerColorsSorted[i].g + " " + playerColorsSorted[i].b + " 255\"]" + "█";
+ }
+ }
+ return g_PlayerColorDisplayNamesSorted;
+}
+
+// Get a simple list of color IDs, basically a list of indexes that has as many members as colors there are.
+function getPlayerColorIdsSorted()
+{
+ if (g_PlayerColorIdsSorted.length === 0)
+ {
+ var playerColorsSorted = getPlayerColorsSorted();
+ for (var i = 0; i < playerColorsSorted.length; ++i)
+ {
+ g_PlayerColorIdsSorted[i] = i;
+ }
+ }
+ return g_PlayerColorIdsSorted;
+}
+
+// Determine whether two specified variables contain the same RGB data.
+function rgbValuesMatch(color1, color2)
+{
+ return color1.r === color2.r && color1.g === color2.g && color1.b === color2.b;
+}
+
+// Copy the RGB data from the first color into the second color.
+function copyRgbValuesFromColorIntoColor(color1, color2)
+{
+ color2.r = color1.r;
+ color2.g = color1.g;
+ color2.b = color1.b;
+}
+
function handleNetMessage(message)
{
log("Net message: " + uneval(message));
@@ -1422,6 +1574,7 @@
var pTeam = Engine.GetGUIObjectByName("playerTeam["+i+"]");
var pTeamText = Engine.GetGUIObjectByName("playerTeamText["+i+"]");
var pColor = Engine.GetGUIObjectByName("playerColor["+i+"]");
+ var pColorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]")
// Player data / defaults
var pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};
@@ -1428,8 +1581,8 @@
var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[i] : {};
// Common to all game types
- var color = rgbToGuiColor(getSetting(pData, pDefs, "Color"));
- pColor.sprite = "color:" + color + " 100";
+ var color = getSetting(pData, pDefs, "Color");
+ pColor.sprite = "color:" + rgbToGuiColor(color) + " 100";
pName.caption = translate(getSetting(pData, pDefs, "Name"));
var team = getSetting(pData, pDefs, "Team");
@@ -1449,6 +1602,7 @@
{
pCivText.hidden = false;
pCiv.hidden = true;
+ pColorPicker.hidden = true;
pTeamText.hidden = false;
pTeam.hidden = true;
// Set text values
@@ -1462,10 +1616,12 @@
{
pCivText.hidden = true;
pCiv.hidden = false;
+ pColorPicker.hidden = false;
pTeamText.hidden = true;
pTeam.hidden = false;
// Set dropdown values
pCiv.selected = (civ ? pCiv.list_data.indexOf(civ) : 0);
+ pColorPicker.selected = getIndexOfColor(color);
pTeam.selected = (team !== undefined && team >= 0) ? team+1 : 0;
}
}
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.xml
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.xml (revision 17014)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.xml (working copy)
@@ -72,6 +72,9 @@
@@ -179,7 +182,7 @@
-
+