Index: binaries/data/mods/public/gui/autostart/autostart.js =================================================================== --- binaries/data/mods/public/gui/autostart/autostart.js +++ binaries/data/mods/public/gui/autostart/autostart.js @@ -11,7 +11,7 @@ settings.launchGame(assignments); Engine.SwitchGuiPage("page_loading.xml", { - "attribs": settings.toInitAttributes(), + "attribs": settings.finalizedAttributes, "playerAssignments": assignments }); } Index: binaries/data/mods/public/gui/campaigns/default_menu/CampaignMenu.js =================================================================== --- binaries/data/mods/public/gui/campaigns/default_menu/CampaignMenu.js +++ binaries/data/mods/public/gui/campaigns/default_menu/CampaignMenu.js @@ -64,7 +64,7 @@ if (level.Preview) gameSettings.mapPreview.setCustom("cropped:" + 400/512 + "," + 300/512 + ":" + level.Preview); - gameSettings.mapName.set(this.getLevelName(level)); + gameSettings.mapName.setCustom(this.getLevelName(level)); // TODO: level description should also be passed, ideally. if (level.useGameSetup) @@ -98,7 +98,7 @@ gameSettings.launchGame(assignments); Engine.SwitchGuiPage("page_loading.xml", { - "attribs": gameSettings.toInitAttributes(), + "attribs": gameSettings.finalizedAttributes, "playerAssignments": assignments }); } 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 @@ -37,7 +37,8 @@ this[name] = new GameSettings.prototype.Attributes[comp](this); } for (let comp in this) - this[comp].init(); + if (this[comp].init) + this[comp].init(); return this; } @@ -114,18 +115,20 @@ { this.pickRandomItems(); - Engine.SetRankedGame(this.rating.enabled); + let attribs = this.toInitAttributes(); + for (const comp in this) + if (this[comp].onFinalizeAttributes) + this[comp].onFinalizeAttributes(attribs, playerAssignments); - // Replace player names with the real players. - for (let guid in playerAssignments) - if (playerAssignments[guid].player !== -1) - this.playerName.values[playerAssignments[guid].player -1] = playerAssignments[guid].name; + Object.defineProperty(this, "finalizedAttributes", { + "value": attribs + }); // NB: for multiplayer support, the clients must be listening to "start" net messages. if (this.isNetworked) - Engine.StartNetworkGame(this.toInitAttributes()); + Engine.StartNetworkGame(this.finalizedAttributes); else - Engine.StartGame(this.toInitAttributes(), playerAssignments.local.player); + Engine.StartGame(this.finalizedAttributes, playerAssignments.local.player); } } Index: binaries/data/mods/public/gui/gamesettings/attributes/CampaignData.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/CampaignData.js +++ binaries/data/mods/public/gui/gamesettings/attributes/CampaignData.js @@ -4,10 +4,6 @@ */ GameSettings.prototype.Attributes.CampaignData = class CampaignData extends GameSetting { - init() - { - } - toInitAttributes(attribs) { if (this.value) Index: binaries/data/mods/public/gui/gamesettings/attributes/CircularMap.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/CircularMap.js +++ binaries/data/mods/public/gui/gamesettings/attributes/CircularMap.js @@ -9,19 +9,14 @@ this.settings.map.watch(() => this.onMapChange(), ["map"]); } - toInitAttributes(attribs) + onMapChange() { - if (this.value) - attribs.settings.CircularMap = this.value; + this.value = this.getMapSetting("CircularMap") || false; } - /** - * Exceptionally, this setting has no Deserialize: it's entirely determined by the map - */ - - onMapChange() + onFinalizeAttributes(attribs) { - this.value = this.getMapSetting("CircularMap") || false; + attribs.settings.CircularMap = this.value; } setValue(val) Index: binaries/data/mods/public/gui/gamesettings/attributes/MapName.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/MapName.js +++ binaries/data/mods/public/gui/gamesettings/attributes/MapName.js @@ -6,31 +6,25 @@ { init() { + this.isDefault = true; + this.value = undefined; + this.settings.map.watch(() => this.updateName(), ["map"]); } - toInitAttributes(attribs) + updateName() { - if (this.value) - attribs.settings.Name = this.value; - else - { - // Copy from the map data by default - this helps make InitAttributes self-sufficient, - // which is nice for replays / saved games. - // Fallback to the map name to avoid 'undefined' errors. - attribs.settings.Name = this.settings.map?.data?.settings?.Name || this.settings.map.map; - } + if (this.isDefault) + this.value = this.settings.map?.data?.settings?.Name || this.settings.map.map; } - fromInitAttributes(attribs) + onFinalizeAttributes(attribs) { - // Ser/Deser from a different attribute name as a poor man's not-persisted-setting. - // TODO: split this off more properly. - if (attribs.mapName) - this.value = attribs.mapName; + attribs.settings.Name = this.value; } - set(name) + setCustom(name) { + this.isDefault = false; this.value = name; } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/MapPreview.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/MapPreview.js +++ binaries/data/mods/public/gui/gamesettings/attributes/MapPreview.js @@ -7,24 +7,13 @@ init() { this.isDefault = true; + this.value = undefined; this.settings.map.watch(() => this.updatePreview(), ["map"]); this.settings.biome.watch(() => this.updatePreview(), ["biome"]); this.settings.landscape.watch(() => this.updatePreview(), ["value"]); this.settings.daytime.watch(() => this.updatePreview(), ["value"]); } - toInitAttributes(attribs) - { - // TODO: this shouldn't be persisted, only serialised for the game proper. - if (this.value) - attribs.mapPreview = this.value; - } - - fromInitAttributes(attribs) - { - // For now - this won't be deserialized or persisted match settings will be problematic. - } - getPreviewForSubtype(basepath, subtype) { if (!subtype) @@ -71,4 +60,9 @@ this.isDefault = false; this.value = preview; } + + onFinalizeAttributes(attribs) + { + attribs.mapPreview = this.value; + } }; 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 @@ -1,23 +1,7 @@ GameSettings.prototype.Attributes.MatchID = class MatchID extends GameSetting { - init() + onFinalizeAttributes(attribs) { - this.matchID = 0; - } - - toInitAttributes(attribs) - { - attribs.matchID = this.matchID; - } - - fromInitAttributes(attribs) - { - if (attribs.matchID !== undefined) - this.matchID = attribs.matchID; - } - - pickRandomItems() - { - this.matchID = Engine.GetMatchID(); + attribs.matchID = Engine.GetMatchID(); } }; 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 @@ -92,6 +92,14 @@ return picked; } + onFinalizeAttributes(attribs, playerAssignments) + { + // Replace client player names with the real players. + for (const guid in playerAssignments) + if (playerAssignments[guid].player !== -1) + attribs.settings.PlayerData[playerAssignments[guid].player -1].Name = playerAssignments[guid].name; + } + _getMapData(i) { let data = this.settings.map.data; Index: binaries/data/mods/public/gui/gamesettings/attributes/Rating.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/Rating.js +++ binaries/data/mods/public/gui/gamesettings/attributes/Rating.js @@ -36,4 +36,9 @@ !this.settings.cheats.enabled; this.enabled = this.available; } + + onFinalizeAttributes() + { + Engine.SetRankedGame(this.enabled); + } }; 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 @@ -1,30 +1,8 @@ GameSettings.prototype.Attributes.Seeds = class Seeds extends GameSetting { - init() + onFinalizeAttributes(attribs) { - this.seed = 0; - this.AIseed = 0; - } - - toInitAttributes(attribs) - { - // Seed is used for map generation and simulation. - attribs.settings.Seed = this.seed; - attribs.settings.AISeed = this.AIseed; - } - - fromInitAttributes(attribs) - { - // Seed is used for map generation and simulation. - if (this.getLegacySetting(attribs, "Seed") !== undefined) - this.seed = this.getLegacySetting(attribs, "Seed"); - if (this.getLegacySetting(attribs, "AISeed") !== undefined) - this.AIseed = this.getLegacySetting(attribs, "AISeed"); - } - - pickRandomItems() - { - this.seed = randIntExclusive(0, Math.pow(2, 32)); - this.AIseed = randIntExclusive(0, Math.pow(2, 32)); + attribs.settings.Seed = randIntExclusive(0, Math.pow(2, 32)); + attribs.settings.AISeed = randIntExclusive(0, Math.pow(2, 32)); } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/StartingCamera.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/StartingCamera.js +++ binaries/data/mods/public/gui/gamesettings/attributes/StartingCamera.js @@ -11,21 +11,6 @@ this.settings.map.watch(() => this.onMapChange(), ["map"]); } - toInitAttributes(attribs) - { - if (!attribs.settings.PlayerData) - attribs.settings.PlayerData = []; - while (attribs.settings.PlayerData.length < this.values.length) - attribs.settings.PlayerData.push({}); - for (let i in this.values) - if (this.values[i]) - attribs.settings.PlayerData[i].StartingCamera = this.values[i]; - } - - /** - * Exceptionally, this setting has no Deserialize: it's entirely determined by the map - */ - _resize(nb) { while (this.values.length > nb) @@ -41,4 +26,15 @@ for (let i in pData) this.values[i] = pData?.[i]?.StartingCamera; } + + onFinalizeAttributes(attribs) + { + if (!attribs.settings.PlayerData) + attribs.settings.PlayerData = []; + while (attribs.settings.PlayerData.length < this.values.length) + attribs.settings.PlayerData.push({}); + for (let i in this.values) + if (this.values[i]) + attribs.settings.PlayerData[i].StartingCamera = this.values[i]; + } }; Index: binaries/data/mods/public/gui/gamesettings/attributes/TriggerScripts.js =================================================================== --- binaries/data/mods/public/gui/gamesettings/attributes/TriggerScripts.js +++ binaries/data/mods/public/gui/gamesettings/attributes/TriggerScripts.js @@ -8,18 +8,6 @@ this.settings.victoryConditions.watch(() => this.updateVictoryScripts(), ["active"]); } - toInitAttributes(attribs) - { - let scripts = new Set(this.victory); - for (let elem of this.map) - scripts.add(elem); - attribs.settings.TriggerScripts = Array.from(scripts); - } - - /** - * Exceptionally, this setting has no Deserialize: it's entirely determined from other settings. - */ - updateVictoryScripts() { let setting = this.settings.victoryConditions; @@ -39,4 +27,12 @@ } this.map = new Set(this.settings.map.data.settings.TriggerScripts); } + + onFinalizeAttributes(attribs) + { + let scripts = new Set(this.victory); + for (let elem of this.map) + scripts.add(elem); + attribs.settings.TriggerScripts = Array.from(scripts); + } }; Index: binaries/data/mods/public/gui/gamesetup/Controllers/GameSettingsController.js =================================================================== --- binaries/data/mods/public/gui/gamesetup/Controllers/GameSettingsController.js +++ binaries/data/mods/public/gui/gamesetup/Controllers/GameSettingsController.js @@ -280,7 +280,7 @@ switchToLoadingPage(attributes) { Engine.SwitchGuiPage("page_loading.xml", { - "attribs": attributes?.initAttributes || g_GameSettings.toInitAttributes(), + "attribs": attributes?.initAttributes || g_GameSettings.finalizedAttributes, "playerAssignments": g_PlayerAssignments }); }