Index: binaries/data/mods/public/gui/aiconfig/aiconfig.js
===================================================================
--- binaries/data/mods/public/gui/aiconfig/aiconfig.js
+++ binaries/data/mods/public/gui/aiconfig/aiconfig.js
@@ -16,20 +16,20 @@
let aiSelection = Engine.GetGUIObjectByName("aiSelection");
aiSelection.list = g_AIDescriptions.map(ai => ai.data.name);
aiSelection.selected = g_AIDescriptions.findIndex(ai => ai.id == settings.id);
- aiSelection.hidden = !settings.isController;
+ aiSelection.hidden = !settings.canPlayerChange;
let aiSelectionText = Engine.GetGUIObjectByName("aiSelectionText");
aiSelectionText.caption = aiSelection.list[aiSelection.selected];
- aiSelectionText.hidden = settings.isController;
+ aiSelectionText.hidden = settings.canPlayerChange;
let aiDiff = Engine.GetGUIObjectByName("aiDifficulty");
aiDiff.list = prepareForDropdown(g_Settings.AIDifficulties).Title;
aiDiff.selected = settings.difficulty;
- aiDiff.hidden = !settings.isController;
+ aiDiff.hidden = !settings.canPlayerChange;
let aiDiffText = Engine.GetGUIObjectByName("aiDifficultyText");
aiDiffText.caption = aiDiff.list[aiDiff.selected];
- aiDiffText.hidden = settings.isController;
+ aiDiffText.hidden = settings.canPlayerChange;
}
function selectAI(idx)
Index: binaries/data/mods/public/gui/common/settings.js
===================================================================
--- binaries/data/mods/public/gui/common/settings.js
+++ binaries/data/mods/public/gui/common/settings.js
@@ -32,14 +32,15 @@
"AIDescriptions": loadAIDescriptions(),
"AIDifficulties": loadAIDifficulties(),
"Ceasefire": loadCeasefire(),
- "VictoryDurations": loadVictoryDuration(),
"GameSpeeds": loadSettingValuesFile("game_speeds.json"),
+ "GuestSettings": loadSettingValuesFile("guest_settings.json"),
"MapTypes": loadMapTypes(),
"MapSizes": loadSettingValuesFile("map_sizes.json"),
"PlayerDefaults": loadPlayerDefaults(),
"PopulationCapacities": loadPopulationCapacities(),
"StartingResources": loadSettingValuesFile("starting_resources.json"),
- "VictoryConditions": loadVictoryConditions()
+ "VictoryConditions": loadVictoryConditions(),
+ "VictoryDurations": loadVictoryDuration()
};
if (Object.keys(settings).some(key => settings[key] === undefined))
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.js
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.js
@@ -3,6 +3,7 @@
const g_Ceasefire = prepareForDropdown(g_Settings && g_Settings.Ceasefire);
const g_GameSpeeds = prepareForDropdown(g_Settings && g_Settings.GameSpeeds.filter(speed => !speed.ReplayOnly));
+const g_GuestSettings = prepareForDropdown(g_Settings && g_Settings.GuestSettings);
const g_MapSizes = prepareForDropdown(g_Settings && g_Settings.MapSizes);
const g_MapTypes = prepareForDropdown(g_Settings && g_Settings.MapTypes);
const g_PopulationCapacities = prepareForDropdown(g_Settings && g_Settings.PopulationCapacities);
@@ -123,6 +124,7 @@
"netstatus": msg => handleNetStatusMessage(msg),
"netwarn": msg => addNetworkWarning(msg),
"gamesetup": msg => handleGamesetupMessage(msg),
+ "changesetting": msg => handleChangeSettingMessage(msg),
"players": msg => handlePlayerAssignmentMessage(msg),
"ready": msg => handleReadyMessage(msg),
"start": msg => handleGamestartMessage(msg),
@@ -311,6 +313,7 @@
"populationCap",
"startingResources",
"ceasefire",
+ "guestSettings",
],
"Checkbox": [
"exploreMap",
@@ -526,6 +529,18 @@
g_GameAttributes.gameSpeed = g_GameSpeeds.Speed[idx];
},
},
+ "guestSettings": {
+ "title": () => translate("Guest Settings"),
+ "tooltip": () => translate("Set which settings can be changed by every player."),
+ "labels": () => g_GuestSettings.Title,
+ "ids": () => g_GuestSettings.Data,
+ "default": () => g_GuestSettings.Default,
+ "defined": () => g_GameAttributes.guestSettings !== undefined,
+ "get": () => g_GameAttributes.guestSettings,
+ "select": (idx) => {
+ g_GameAttributes.guestSettings = g_GuestSettings.Data[idx];
+ },
+ },
};
/**
@@ -764,10 +779,10 @@
g_PlayerAssignments[Engine.GetPlayerGUID()].player == -1 && !g_IsController,
},
"civResetButton": {
- "hidden": () => g_GameAttributes.mapType == "scenario" || !g_IsController,
+ "hidden": () => g_GameAttributes.mapType == "scenario" || !canPlayerChange("civResetButton"),
},
"teamResetButton": {
- "hidden": () => g_GameAttributes.mapType == "scenario" || !g_IsController,
+ "hidden": () => g_GameAttributes.mapType == "scenario" || !canPlayerChange("teamResetButton"),
},
// Display these after having hidden every GUI object in the "More Options" dialog
"moreOptionsLabel": {
@@ -954,18 +969,8 @@
dropdown.list_data = data.ids(idx);
dropdown.onSelectionChange = function() {
-
- if (!g_IsController ||
- g_IsInGuiUpdate ||
- !this.list_data[this.selected] ||
- data.hidden && data.hidden(idx) ||
- data.enabled && !data.enabled(idx))
- return;
-
- data.select(this.selected, idx);
-
- supplementDefaults();
- updateGameAttributes();
+ changeSetting(this,{ "setting": name, "index": idx, "type": "dropdown",
+ "value": this.list_data[this.selected] });
};
}
@@ -979,19 +984,7 @@
{
let [guiName, guiIdx] = getGUIObjectNameFromSetting(name);
Engine.GetGUIObjectByName(guiName + guiIdx).onPress = function() {
-
- let obj = g_Checkboxes[name];
-
- if (!g_IsController ||
- g_IsInGuiUpdate ||
- obj.enabled && !obj.enabled() ||
- obj.hidden && obj.hidden())
- return;
-
- obj.set(this.checked);
-
- supplementDefaults();
- updateGameAttributes();
+ changeSetting(this, { "setting": name, "type": "checkbox", "value": this.checked });
};
}
@@ -1054,6 +1047,76 @@
}
/**
+ * Returns if the player is allowed to change this setting
+ */
+function canPlayerChange(setting, index = -1, guid = Engine.GetPlayerGUID())
+{
+ if (g_IsController)
+ return true;
+
+ if (g_PlayerAssignments[guid] === undefined || g_PlayerAssignments[guid].player <= 0 || setting == "guestSettings")
+ return false;
+
+ if (g_GuestSettings.Data.indexOf(setting) == -1)
+ return g_GameAttributes.guestSettings == "all";
+
+ if (index >= 0 && index != g_PlayerAssignments[guid].player-1)
+ return g_GameAttributes.guestSettings == "all";
+
+ return g_GuestSettings.Data.indexOf(g_GameAttributes.guestSettings) >= g_GuestSettings.Data.indexOf(setting);
+}
+
+/**
+ * Changes a setting.
+ */
+function changeSetting(element, data, guid, force = false)
+{
+ if (!data || !data.setting || !data.type)
+ return;
+
+ if (!canPlayerChange(data.setting, data.index || -1, guid) || g_IsInGuiUpdate && !force)
+ return;
+
+ if (data.type == "misc")
+ {
+ switch (data.setting)
+ {
+ case "resetCivilizations":
+ resetCivilizations();
+ break;
+ case "resetTeams":
+ resetTeams();
+ break;
+ case "aiSettings":
+ AIConfigCallback(data.value, false);
+ break;
+ }
+ }
+ else if (data.type == "checkbox" || data.type == "dropdown")
+ {
+ let obj = (data.type == "checkbox" ? g_Checkboxes :
+ (data.index === undefined ? g_Dropdowns : g_PlayerDropdowns))[data.setting];
+ if (obj.enabled && !obj.enabled() || obj.hidden && obj.hidden())
+ return;
+ if (data.type == "checkbox")
+ obj.set(data.value);
+ else
+ {
+ if (!data.value)
+ return;
+ let selected = element.list_data.indexOf(data.value);
+ if (selected != -1)
+ obj.select(selected, data.index);
+ }
+ if (!g_IsController)
+ Engine.NetworkChangeSetting(data);
+
+ supplementDefaults();
+ updateGameAttributes();
+ }
+}
+
+/**
* Called when the client disconnects.
* The other cases from NetClient should never occur in the gamesetup.
*/
@@ -1108,7 +1171,7 @@
}
/**
- * Called whenever the host changed any setting.
+ * Called whenever the host sent new game attributes.
*/
function handleGamesetupMessage(message)
{
@@ -1130,6 +1193,28 @@
}
/**
+ * Called whenever a client changes a setting.
+ * @param {Object} message
+ */
+function handleChangeSettingMessage(message)
+{
+ if (!message.guid || !message.data /*|| !message.data.setting || !message.data.type ||
+ !canPlayerChange(message.data.setting, message.data.index || -1, message.guid)*/)
+ return;
+
+
+ let [guiName, guiIdx] = getGUIObjectNameFromSetting(message.data.setting);
+ let idxName = message.data.index === undefined ? "": "[" + message.data.index + "]";
+
+ let element = Engine.GetGUIObjectByName(guiName + guiIdx + idxName);
+ changeSetting(element, message.data, message.guid, true);
+ /*warn("The player with guid " + message.guid + " has changed the setting " +
+ message.data.setting + " with type " + message.data.type + " and index " +
+ message.data.index + " to the value " + message.data.value + ". Type is " + typeof message.data.value);*/
+
+}
+
+/**
* Called whenever a client joins/leaves or any gamesetting is changed.
*/
function handlePlayerAssignmentMessage(message)
@@ -1516,7 +1601,7 @@
let enabled = !indexHidden && (!obj.enabled || obj.enabled(idx));
let hidden = indexHidden || obj.hidden && obj.hidden(idx);
- dropdown.hidden = !g_IsController || !enabled || hidden;
+ dropdown.hidden = !canPlayerChange(name, idx) || !enabled || hidden;
dropdown.selected = indexHidden ? -1 : selected;
dropdown.tooltip = !indexHidden && obj.tooltip ? obj.tooltip(idx) : "";
@@ -1528,7 +1613,7 @@
if (label && !indexHidden)
{
- label.hidden = g_IsController && enabled || hidden;
+ label.hidden = canPlayerChange(name, idx) && enabled || hidden;
label.caption = selected == -1 ? translateWithContext("option value", "Unknown") : dropdown.list[selected];
}
}
@@ -1553,11 +1638,11 @@
checkbox.checked = checked;
checkbox.enabled = enabled;
- checkbox.hidden = hidden || !g_IsController;
+ checkbox.hidden = hidden || !canPlayerChange(name);
checkbox.tooltip = obj.tooltip ? obj.tooltip() : "";
label.caption = checked ? translate("Yes") : translate("No");
- label.hidden = hidden || g_IsController;
+ label.hidden = hidden || canPlayerChange(name);
if (frame)
frame.hidden = hidden;
@@ -1795,7 +1880,7 @@
Engine.PushGuiPage("page_aiconfig.xml", {
"callback": "AIConfigCallback",
- "isController": g_IsController,
+ "canPlayerChange": canPlayerChange("aiSettings"),
"playerSlot": playerSlot,
"id": g_GameAttributes.settings.PlayerData[playerSlot].AI,
"difficulty": g_GameAttributes.settings.PlayerData[playerSlot].AIDiff
@@ -1805,12 +1890,18 @@
/**
* Called after closing the dialog.
*/
-function AIConfigCallback(ai)
+function AIConfigCallback(ai, resetViewedAI = true)
{
- g_LastViewedAIPlayer = -1;
+ if (resetViewedAI)
+ g_LastViewedAIPlayer = -1;
- if (!ai.save || !g_IsController)
+ if (!ai.save)
return;
+ if (!g_IsController)
+ {
+ Engine.NetworkChangeSetting({ "setting": "aiSettings", "type": "misc", "value": ai});
+ return;
+ }
g_GameAttributes.settings.PlayerData[ai.playerSlot].AI = ai.id;
g_GameAttributes.settings.PlayerData[ai.playerSlot].AIDiff = ai.difficulty;
@@ -1979,6 +2070,12 @@
function resetCivilizations()
{
+ if (!g_IsController)
+ {
+ Engine.NetworkChangeSetting({ "setting": "resetCivilizations", "type": "misc" });
+ return;
+ }
+
for (let i in g_GameAttributes.settings.PlayerData)
g_GameAttributes.settings.PlayerData[i].Civ = "random";
@@ -1987,6 +2084,12 @@
function resetTeams()
{
+ if (!g_IsController)
+ {
+ Engine.NetworkChangeSetting({ "setting": "resetTeams", "type": "misc" });
+ return;
+ }
+
for (let i in g_GameAttributes.settings.PlayerData)
g_GameAttributes.settings.PlayerData[i].Team = -1;
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.xml
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.xml
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.xml
@@ -110,7 +110,7 @@
-
+