Index: binaries/data/mods/public/gui/gamesettings/GameSettings.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/GameSettings.js +++ binaries/data/mods/public/gui/gamesettings/GameSettings.js @@ -89,19 +89,26 @@ { let components = Object.keys(this); let i = 0; - while (components.length && i < 100) + // Re-pick if any random setting was unrandomised, to make sure dependencies are cleared. + let pickedThisLoop = true; + while (pickedThisLoop && i <= components.length) { - // Re-pick if any random setting was unrandomised, - // to make sure dependencies are cleared. - // TODO: there's probably a better way to handle this. - components = components.filter(comp => this[comp].pickRandomItems ? - !!this[comp].pickRandomItems() : false); + pickedThisLoop = false; + let allHaveValue = true; + for (const comp in this) + if (this[comp].pickRandomItems) + { + const result = this[comp].pickRandomItems(); + pickedThisLoop = pickedThisLoop || result.picked; + allHaveValue = allHaveValue && result.hasValue; + } + if (allHaveValue) + return; ++i; } - if (i === 100) - { - throw new Error("Infinite loop picking random items, remains : " + uneval(components)); - } + + + throw new Error("Possible infinite loop picking random items, remains : " + uneval(components.filter(comp => this[comp].pickRandomItems && !this[comp].pickRandomItems().hasValue))); } /** Index: binaries/data/mods/public/gui/gamesettings/attributes/Biome.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/Biome.js +++ binaries/data/mods/public/gui/gamesettings/attributes/Biome.js @@ -83,11 +83,12 @@ { // If the map is random, we need to wait until it selects to know if we need to pick a biome. if (this.settings.map.map === "random") - return true; + return { "picked": false, "hasValue": false }; if (this.biome !== "random") - return false; + return { "picked": false, "hasValue": true }; + this.biome = pickRandom(Array.from(this.available)); - return true; + return { "picked": true, "hasValue": true }; } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/Daytime.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/Daytime.js +++ binaries/data/mods/public/gui/gamesettings/attributes/Daytime.js @@ -45,12 +45,12 @@ { // If the map is random, we need to wait until it is selected. if (this.settings.map.map === "random") - return true; + return { "picked": false, "hasValue": false }; if (this.value !== "random") - return false; + return { "picked": false, "hasValue": true }; this.value = pickRandom(this.data).Id; - return true; + return { "picked": true, "hasValue": true }; } /** Index: binaries/data/mods/public/gui/gamesettings/attributes/Landscape.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/Landscape.js +++ binaries/data/mods/public/gui/gamesettings/attributes/Landscape.js @@ -58,10 +58,10 @@ { // If the map is random, we need to wait until it is selected. if (this.settings.map.map === "random") - return true; + return { "picked": false, "hasValue": false }; if (!this.value || !this.value.startsWith("random")) - return false; + return { "picked": false, "hasValue": true }; let items = []; if (this.value.indexOf("_") !== -1) @@ -73,6 +73,6 @@ items = this.data.map(x => x.Items.map(item => item.Id)).flat(); this.value = pickRandom(items); - return true; + return { "picked": true, "hasValue": true }; } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/Map.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/Map.js +++ binaries/data/mods/public/gui/gamesettings/attributes/Map.js @@ -55,9 +55,9 @@ pickRandomItems() { if (this.map !== "random") - return false; + return { "picked": false, "hasValue": true }; this.selectMap(pickRandom(this.randomOptions)); - return true; + return { "picked": true, "hasValue": true }; } setRandomOptions(options) Index: binaries/data/mods/public/gui/gamesettings/attributes/MatchID.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/MatchID.js +++ binaries/data/mods/public/gui/gamesettings/attributes/MatchID.js @@ -19,5 +19,6 @@ pickRandomItems() { this.matchID = Engine.GetMatchID(); + return { "picked": true, "hasValue": true }; } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/PlayerCiv.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/PlayerCiv.js +++ binaries/data/mods/public/gui/gamesettings/attributes/PlayerCiv.js @@ -95,7 +95,7 @@ if (picked) this.trigger("values"); - return picked; + return { "picked": picked, "hasValue": true }; } _getMapData(i) Index: binaries/data/mods/public/gui/gamesettings/attributes/PlayerName.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/PlayerName.js +++ binaries/data/mods/public/gui/gamesettings/attributes/PlayerName.js @@ -55,6 +55,7 @@ pickRandomItems() { let picked = false; + let hasValue = true; for (let i in this.values) { if (!!this.values[i] && @@ -66,8 +67,13 @@ continue; let civ = this.settings.playerCiv.values[i]; - if (!civ || civ == "random") + if (!civ) continue; + else if (civ == "random") + { + hasValue = false; + continue; + } picked = true; // Pick one of the available botnames for the chosen civ @@ -89,7 +95,7 @@ } if (picked) this.trigger("values"); - return picked; + return { "picked": picked, "hasValue": hasValue }; } _getMapData(i) Index: binaries/data/mods/public/gui/gamesettings/attributes/Seeds.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/Seeds.js +++ binaries/data/mods/public/gui/gamesettings/attributes/Seeds.js @@ -26,5 +26,6 @@ { this.seed = randIntExclusive(0, Math.pow(2, 32)); this.AIseed = randIntExclusive(0, Math.pow(2, 32)); + return { "picked": true, "hasValue": true }; } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/TeamPlacement.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/TeamPlacement.js +++ binaries/data/mods/public/gui/gamesettings/attributes/TeamPlacement.js @@ -41,12 +41,12 @@ { // If the map is random, we need to wait until it is selected. if (this.settings.map.map === "random") - return true; + return { "picked": false, "hasValue": false }; if (this.value !== "random") - return false; + return { "picked": false, "hasValue": true }; this.value = pickRandom(this.available).Id; - return true; + return { "picked": true, "hasValue": true }; } };