Remove useless persistMatchSettings and handle some which weren't handled

Fixing issues in dc18d94030

Everyone make sure to delete savegames, saved campaigns an most
importantly your matchsettings.json's (regular alpha players won't
notice since there is a version check, but if you already have your
stuff at A26/svn, you will have some issues)

Reported By: elexis
Comments By: wraitii, Freagarach
Differential Revision: D4240
This was SVN commit r26393.
This commit is contained in:
bb 2022-02-15 21:13:10 +00:00
parent 3484a3d483
commit 071fddd598
25 changed files with 143 additions and 122 deletions

View file

@ -11,7 +11,7 @@ function init(initData)
settings.launchGame(assignments);
Engine.SwitchGuiPage("page_loading.xml", {
"attribs": settings.toInitAttributes(),
"attribs": settings.finalizedAttributes,
"playerAssignments": assignments
});
}

View file

@ -40,10 +40,14 @@ class CampaignMenu extends AutoWatcher
if (!meetsRequirements(this.run, level))
return;
// TODO: level description should also be passed, ideally.
const settings = {
"mapType": level.MapType,
"map": "maps/" + level.Map,
"settings": {
// TODO: don't translate this here.
"mapName": this.getLevelName(level),
"mapPreview": level.Preview && "cropped:" + 400/512 + "," + 300/512 + ":" + level.Preview,
"CheatsEnabled": true
},
"campaignData": {
@ -62,11 +66,6 @@ class CampaignMenu extends AutoWatcher
const gameSettings = new GameSettings().init();
gameSettings.fromInitAttributes(settings);
if (level.Preview)
gameSettings.mapPreview.setCustom("cropped:" + 400/512 + "," + 300/512 + ":" + level.Preview);
gameSettings.mapName.set(this.getLevelName(level));
// TODO: level description should also be passed, ideally.
if (level.useGameSetup)
{
// Setup some default AI on the non-human players.
@ -98,7 +97,7 @@ class CampaignMenu extends AutoWatcher
gameSettings.launchGame(assignments);
Engine.SwitchGuiPage("page_loading.xml", {
"attribs": gameSettings.toInitAttributes(),
"attribs": gameSettings.finalizedAttributes,
"playerAssignments": assignments
});
}

View file

@ -37,7 +37,8 @@ class GameSettings
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,22 @@ class GameSettings
{
this.pickRandomItems();
Engine.SetRankedGame(this.rating.enabled);
// Let the settings finalize themselves. Let them do anything they need to do before the
// game starts and set any value in the attributes which mustn't be persisted.
const 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": deepfreeze(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);
}
}

View file

@ -4,10 +4,6 @@
*/
GameSettings.prototype.Attributes.CampaignData = class CampaignData extends GameSetting
{
init()
{
}
toInitAttributes(attribs)
{
if (this.value)

View file

@ -8,8 +8,6 @@ GameSettings.prototype.Attributes.Ceasefire = class Ceasefire extends GameSettin
toInitAttributes(attribs)
{
if (!this.value)
return;
attribs.settings.Ceasefire = this.value;
}

View file

@ -5,19 +5,19 @@ GameSettings.prototype.Attributes.CircularMap = class CircularMap extends GameSe
{
init()
{
this.value = undefined;
this.value = false;
this.settings.map.watch(() => this.onMapChange(), ["map"]);
}
toInitAttributes(attribs)
{
if (this.value)
attribs.settings.CircularMap = this.value;
attribs.settings.CircularMap = this.value;
}
/**
* Exceptionally, this setting has no Deserialize: it's entirely determined by the map
*/
fromInitAttributes(attribs)
{
this.value = !!this.getLegacySetting(attribs, "CircularMap");
}
onMapChange()
{

View file

@ -13,9 +13,8 @@ GameSettings.prototype.Attributes.GameSpeed = class GameSpeed extends GameSettin
fromInitAttributes(attribs)
{
if (!attribs.gameSpeed)
return;
this.gameSpeed = +attribs.gameSpeed;
if (attribs.gameSpeed)
this.gameSpeed = +attribs.gameSpeed;
}
onMapChange()

View file

@ -6,31 +6,23 @@ GameSettings.prototype.Attributes.MapName = class MapName extends GameSetting
{
init()
{
this.value = undefined;
this.settings.map.watch(() => this.updateName(), ["map"]);
}
toInitAttributes(attribs)
{
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;
}
attribs.settings.mapName = this.value;
}
fromInitAttributes(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;
if (attribs?.settings?.mapName)
this.value = attribs.settings.mapName;
}
set(name)
updateName()
{
this.value = name;
this.value = this.settings.map?.data?.settings?.Name || this.settings.map.map;
}
};

View file

@ -6,7 +6,7 @@ GameSettings.prototype.Attributes.MapPreview = class MapPreview extends GameSett
{
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"]);
@ -15,14 +15,14 @@ GameSettings.prototype.Attributes.MapPreview = class MapPreview extends GameSett
toInitAttributes(attribs)
{
// TODO: this shouldn't be persisted, only serialised for the game proper.
if (this.value)
attribs.mapPreview = this.value;
if (this.value !== undefined)
attribs.settings.mapPreview = this.value;
}
fromInitAttributes(attribs)
{
// For now - this won't be deserialized or persisted match settings will be problematic.
if (!!this.getLegacySetting(attribs, "mapPreview"))
this.value = this.getLegacySetting(attribs, "mapPreview");
}
getPreviewForSubtype(basepath, subtype)
@ -48,10 +48,6 @@ GameSettings.prototype.Attributes.MapPreview = class MapPreview extends GameSett
updatePreview()
{
// Don't overwrite the preview if it's been manually set.
if (!this.isDefault)
return;
if (!this.settings.map.map)
{
this.value = undefined;
@ -65,10 +61,4 @@ GameSettings.prototype.Attributes.MapPreview = class MapPreview extends GameSett
this.getPreviewForSubtype(mapPath, this.settings.daytime.value) ||
this.settings.mapCache.getMapPreview(this.settings.map.type, this.settings.map.map);
}
setCustom(preview)
{
this.isDefault = false;
this.value = preview;
}
};

View file

@ -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();
}
};

View file

@ -2,9 +2,8 @@
* Stores in-game names for all players.
*
* NB: the regular gamesetup has a particular handling of this setting.
* The names are loaded from the map, but the GUI also show playernames
* and forces them when starting the game.
* This is therefore just handling map-defined names & AI random bot names.
* The names are loaded from the map, but the GUI also show playernames.
* Force these at the start of the match.
*/
GameSettings.prototype.Attributes.PlayerName = class PlayerName extends GameSetting
{
@ -27,6 +26,21 @@ GameSettings.prototype.Attributes.PlayerName = class PlayerName extends GameSett
attribs.settings.PlayerData[i].Name = this.values[i];
}
fromInitAttributes(attribs)
{
if (!this.getLegacySetting(attribs, "PlayerData"))
return;
const pData = this.getLegacySetting(attribs, "PlayerData");
if (this.values.length < pData.length)
this._resize(pData.length);
for (const i in pData)
if (pData[i] && pData[i].Name !== undefined)
{
this.values[i] = pData[i].Name;
this.trigger("values");
}
}
_resize(nb)
{
while (this.values.length > nb)
@ -92,6 +106,14 @@ GameSettings.prototype.Attributes.PlayerName = class PlayerName extends GameSett
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;

View file

@ -36,4 +36,9 @@ GameSettings.prototype.Attributes.Rating = class Rating extends GameSetting
!this.settings.cheats.enabled;
this.enabled = this.available;
}
onFinalizeAttributes()
{
Engine.SetRankedGame(this.enabled);
}
};

View file

@ -9,7 +9,8 @@ GameSettings.prototype.Attributes.RegicideGarrison = class RegicideGarrison exte
toInitAttributes(attribs)
{
attribs.settings.RegicideGarrison = this.enabled;
if (this.available)
attribs.settings.RegicideGarrison = this.enabled;
}
fromInitAttributes(attribs)

View file

@ -10,7 +10,7 @@ GameSettings.prototype.Attributes.SeaLevelRise = class SeaLevelRise extends Game
toInitAttributes(attribs)
{
if (this.value)
if (this.value !== undefined)
attribs.settings.SeaLevelRiseTime = this.value;
}

View file

@ -2,20 +2,18 @@ GameSettings.prototype.Attributes.Seeds = class Seeds extends GameSetting
{
init()
{
this.seed = 0;
this.AIseed = 0;
this.seed = "random";
this.AIseed = "random";
}
toInitAttributes(attribs)
{
// Seed is used for map generation and simulation.
attribs.settings.Seed = this.seed;
attribs.settings.AISeed = this.AIseed;
attribs.settings.Seed = this.seed == "random" ? this.seed : +this.seed;
attribs.settings.AISeed = this.AIseed == "random" ? this.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)
@ -24,7 +22,18 @@ GameSettings.prototype.Attributes.Seeds = class Seeds extends GameSetting
pickRandomItems()
{
this.seed = randIntExclusive(0, Math.pow(2, 32));
this.AIseed = randIntExclusive(0, Math.pow(2, 32));
let picked = false;
if (this.seed === "random")
{
this.seed = randIntExclusive(0, Math.pow(2, 32));
picked = true;
}
if (this.AIseed === "random")
{
this.AIseed = randIntExclusive(0, Math.pow(2, 32));
picked = true;
}
return picked;
}
};

View file

@ -17,14 +17,25 @@ GameSettings.prototype.Attributes.StartingCamera = class StartingCamera extends
attribs.settings.PlayerData = [];
while (attribs.settings.PlayerData.length < this.values.length)
attribs.settings.PlayerData.push({});
for (let i in this.values)
for (const 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
*/
fromInitAttributes(attribs)
{
if (!this.getLegacySetting(attribs, "PlayerData"))
return;
const pData = this.getLegacySetting(attribs, "PlayerData");
if (this.values.length < pData.length)
this._resize(pData.length);
for (const i in pData)
if (pData[i] && pData[i].StartingCamera !== undefined)
{
this.values[i] = pData[i].StartingCamera;
this.trigger("values");
}
}
_resize(nb)
{

View file

@ -9,7 +9,7 @@ GameSettings.prototype.Attributes.TeamPlacement = class TeamPlacement extends Ga
toInitAttributes(attribs)
{
if (this.value)
if (this.value !== undefined)
attribs.settings.TeamPlacement = this.value;
}

View file

@ -2,23 +2,23 @@ GameSettings.prototype.Attributes.TriggerScripts = class TriggerScripts extends
{
init()
{
this.victory = new Set();
this.map = new Set();
this.customScripts = new Set();
this.victoryScripts = new Set();
this.mapScripts = new Set();
this.settings.map.watch(() => this.updateMapScripts(), ["map"]);
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);
attribs.settings.TriggerScripts = Array.from(this.customScripts);
}
/**
* Exceptionally, this setting has no Deserialize: it's entirely determined from other settings.
*/
fromInitAttributes(attribs)
{
if (!!this.getLegacySetting(attribs, "TriggerScripts"))
this.customScripts = new Set(this.getLegacySetting(attribs, "TriggerScripts"));
}
updateVictoryScripts()
{
@ -26,7 +26,7 @@ GameSettings.prototype.Attributes.TriggerScripts = class TriggerScripts extends
let scripts = new Set();
for (let cond of setting.active)
setting.conditions[cond].Scripts.forEach(script => scripts.add(script));
this.victory = scripts;
this.victoryScripts = scripts;
}
updateMapScripts()
@ -34,9 +34,19 @@ GameSettings.prototype.Attributes.TriggerScripts = class TriggerScripts extends
if (!this.settings.map.data || !this.settings.map.data.settings ||
!this.settings.map.data.settings.TriggerScripts)
{
this.map = new Set();
this.mapScripts = new Set();
return;
}
this.map = new Set(this.settings.map.data.settings.TriggerScripts);
this.mapScripts = new Set(this.settings.map.data.settings.TriggerScripts);
}
onFinalizeAttributes(attribs)
{
const scripts = this.customScripts;
for (const elem of this.victoryScripts)
scripts.add(elem);
for (const elem of this.mapScripts)
scripts.add(elem);
attribs.settings.TriggerScripts = Array.from(scripts);
}
};

View file

@ -280,7 +280,7 @@ class GameSettingsController
switchToLoadingPage(attributes)
{
Engine.SwitchGuiPage("page_loading.xml", {
"attribs": attributes?.initAttributes || g_GameSettings.toInitAttributes(),
"attribs": attributes?.initAttributes || g_GameSettings.finalizedAttributes,
"playerAssignments": g_PlayerAssignments
});
}

View file

@ -105,8 +105,8 @@ class SavegameList
cmpB = +b.time;
break;
case 'mapName':
cmpA = translate(a.initAttributes.settings.Name);
cmpB = translate(b.initAttributes.settings.Name);
cmpA = translate(a.initAttributes.settings.mapName);
cmpB = translate(b.initAttributes.settings.mapName);
break;
case 'mapType':
cmpA = translateMapType(a.initAttributes.mapType);
@ -131,7 +131,7 @@ class SavegameList
this.campaignFilter(metadata, this.campaignRun);
return {
"date": this.generateSavegameDateString(metadata, engineInfo),
"mapName": compatibilityColor(translate(metadata.initAttributes.settings.Name), isCompatible),
"mapName": compatibilityColor(translate(metadata.initAttributes.settings.mapName), isCompatible),
"mapType": compatibilityColor(translateMapType(metadata.initAttributes.mapType), isCompatible),
"description": compatibilityColor(metadata.description, isCompatible)
};

View file

@ -8,7 +8,7 @@ class TitleDisplay
let loadingMapName = Engine.GetGUIObjectByName("loadingMapName");
loadingMapName.caption = sprintf(
data.attribs.mapType == "random" ? this.Generating : this.Loading,
{ "map": translate(data.attribs.settings.Name) });
{ "map": translate(data.attribs.settings.mapName) });
}
}

View file

@ -280,7 +280,7 @@ function filterReplay(replay)
// Filter by map name
let mapNameFilter = Engine.GetGUIObjectByName("mapNameFilter");
if (mapNameFilter.selected > 0 && replay.attribs.settings.Name != mapNameFilter.list_data[mapNameFilter.selected])
if (mapNameFilter.selected > 0 && replay.attribs.settings.mapName != mapNameFilter.list_data[mapNameFilter.selected])
return false;
// Filter by map size

View file

@ -106,8 +106,8 @@ function loadReplays(replaySelectionData, compareFiles)
sanitizeInitAttributes(replay.attribs);
// Extract map names
if (g_MapNames.indexOf(replay.attribs.settings.Name) == -1 && replay.attribs.settings.Name != "")
g_MapNames.push(replay.attribs.settings.Name);
if (g_MapNames.indexOf(replay.attribs.settings.mapName) == -1 && replay.attribs.settings.mapName != "")
g_MapNames.push(replay.attribs.settings.mapName);
// Extract playernames
for (let playerData of replay.attribs.settings.PlayerData)
@ -168,8 +168,8 @@ function sanitizeInitAttributes(attribs)
if (!attribs.settings.Size)
attribs.settings.Size = -1;
if (!attribs.settings.Name)
attribs.settings.Name = "";
if (!attribs.settings.mapName)
attribs.settings.mapName = "";
if (!attribs.settings.PlayerData)
attribs.settings.PlayerData = [];
@ -277,7 +277,7 @@ function displayReplayDetails()
let replay = g_ReplaysFiltered[selected];
Engine.GetGUIObjectByName("sgMapName").caption = translate(replay.attribs.settings.Name);
Engine.GetGUIObjectByName("sgMapName").caption = translate(replay.attribs.settings.mapName);
Engine.GetGUIObjectByName("sgMapSize").caption = translateMapSize(replay.attribs.settings.Size);
Engine.GetGUIObjectByName("sgMapType").caption = translateMapType(replay.attribs.mapType);
Engine.GetGUIObjectByName("sgVictory").caption = replay.attribs.settings.VictoryConditions.map(victoryConditionName =>
@ -326,7 +326,7 @@ function getReplayPlayernames(replay)
*/
function getReplayMapName(replay)
{
return translate(replay.attribs.settings.Name);
return translate(replay.attribs.settings.mapName);
}
/**

View file

@ -30,7 +30,7 @@ class LobbyRatingReporter
let report = {
"playerID": Engine.GetPlayerID(),
"matchID": g_InitAttributes.matchID,
"mapName": g_InitAttributes.settings.Name,
"mapName": g_InitAttributes.settings.mapName,
"timeElapsed": extendedSimState.timeElapsed,
};

View file

@ -530,7 +530,7 @@ function initGUILabels()
Engine.GetGUIObjectByName("mapName").caption = sprintf(
translate("%(mapName)s - %(mapType)s"), {
"mapName": translate(g_GameData.sim.mapSettings.Name),
"mapName": translate(g_GameData.sim.mapSettings.mapName),
"mapType": mapSize ? mapSize.Name : (mapType ? mapType.Title : "")
});
}