1
0
forked from mirrors/0ad
Files
0ad/binaries/data/mods/public/gui/maps/MapCache.js
T
wraitii dc18d94030 Separate Game Settings from the GUI Gamesetup
Split the gamesetup in two: the 'GameAttributes' part into gamesettings/
and the GUI/Presentation part in gamesetup/. This makes it easier to
separate the presentation from the data.

The immediate benefit is that campaigns & autostart scripts don't need
to load the gamesetup folder at all. This also makes it much easier for
any modder that would want to to change the GameSetup itself.

Each 'game attribute' is given a unique class extending GameSetting
(with a few exceptions), in charge of:
- 'Serializing' to the JSON-compatible 'InitAttributes' format, which is
used for persisted settings, network synchronization, map script
settings, hotloading.
- Deserializing from the same format.
- Watching for settings it depends on (such that e.g. unexploring the
map also unreveals it).

The GUI controls remain in charge of presenting the state accurately,
however they now directly subscribe to changes of the GameSettings for
update. The updating logic in general has been lightened on the GUI
side, making it more straightforward to know when something will update,
and reducing un-necessary computations (in theory - in practice, I
believe the gamesetup was already fairly good about this).
The 'Controller' class of the gamesetup have also been lightened, since
more responsibility now lies with GameSettings. In particular, this
include code to actually launch a game.

In general the GameSettings class is permissive - the GUI gamesetup has
tighter restriction for what the player can/cannot modify. This is
intended to give flexibility for campaign maps, which may want to change
arbitrary settings.

Further work would be useful, non-exhaustively:
- the setting of default values remains messy. They currently exist
somethings in GameSettings, sometimes in the GUI gamesetup, and in the
simulation itself (in case attributes are not set).
- the availability and 'lockedness' of settings remains a
work-in-progress.
- some attributes, like disabled technologies, should probably be
removed and triggers used instead.
- the Handling of AI and player-specific data could be improved.
- settings Persistence should follow its own path - not all settings are
worth persisting.
- GAIA settings are added simulation-side but not in the GUI, which is
confusing.

Thanks langbart & Freagarach for testing.

Follows the gamesetup rewrite in 34138a7764.

Refs #3049

Differential Revision: https://code.wildfiregames.com/D3243
This was SVN commit r25077.
2021-03-18 13:59:53 +00:00

103 lines
2.3 KiB
JavaScript

/**
* This class obtains, caches, and provides the game settings from map XML and JSON files.
*/
class MapCache
{
constructor()
{
this.cache = {};
}
checkIfExists(mapType, mapPath)
{
if (!mapPath || mapPath == "random")
return true;
return g_Settings.MapTypes.find(type => type.Name == mapType).CheckIfExists(mapPath);
}
getMapData(mapType, mapPath)
{
if (!mapPath || mapPath == "random")
return undefined;
if (!this.cache[mapPath])
{
let mapData = g_Settings.MapTypes.find(type => type.Name == mapType).GetData(mapPath);
// Remove gaia, TODO: Maps should be consistent
if (mapData &&
mapData.settings &&
mapData.settings.PlayerData &&
mapData.settings.PlayerData.length &&
!mapData.settings.PlayerData[0])
{
mapData.settings.PlayerData.shift();
}
this.cache[mapPath] = mapData;
}
return this.cache[mapPath];
}
/**
* Doesn't translate, so that lobby page viewers can do that locally.
* The result is to be used with translateMapName.
*/
getTranslatableMapName(mapType, mapPath)
{
if (mapPath == "random")
return "random";
let mapData = this.getMapData(mapType, mapPath);
return mapData && mapData.settings && mapData.settings.Name || undefined;
}
translateMapName(mapName)
{
return mapName == "random" ?
translateWithContext("map selection", "Random") :
mapName ? translate(mapName) : "";
}
getTranslatedMapDescription(mapType, mapPath)
{
if (mapPath == "random")
return translate("A randomly selected map.");
let mapData = this.getMapData(mapType, mapPath);
return mapData && mapData.settings && translate(mapData.settings.Description) || "";
}
previewExists(filename)
{
return Engine.TextureExists(this.TexturesPath + this.PreviewsPath + filename);
}
getMapPreview(mapType, mapPath, filename = undefined)
{
if (!filename)
{
let mapData = this.getMapData(mapType, mapPath);
filename = mapData && mapData.settings && mapData.settings.Preview || this.DefaultPreview;
}
return "cropped:" + this.PreviewWidth + "," + this.PreviewHeight + ":" + this.PreviewsPath + filename;
}
}
MapCache.prototype.TexturesPath =
"art/textures/ui/";
MapCache.prototype.PreviewsPath =
"session/icons/mappreview/";
MapCache.prototype.DefaultPreview =
"nopreview.png";
MapCache.prototype.PreviewWidth =
400 / 512;
MapCache.prototype.PreviewHeight =
300 / 512;