Index: binaries/data/mods/public/gui/common/color.js
===================================================================
--- binaries/data/mods/public/gui/common/color.js
+++ binaries/data/mods/public/gui/common/color.js
@@ -158,3 +158,11 @@
"[/color]"
});
}
+
+/**
+ * Adds grey font if savegame/replay is not compatible.
+ */
+function compatibilityColor(text, isCompatible)
+{
+ return isCompatible ? text : '[color="96 96 96"]' + text + '[/color]';
+}
Index: binaries/data/mods/public/gui/common/functions_utility_loadsave.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility_loadsave.js
+++ binaries/data/mods/public/gui/common/functions_utility_loadsave.js
@@ -3,25 +3,28 @@
return b.metadata.time - a.metadata.time;
}
-function generateLabel(metadata, engineInfo)
+function isCompatibleSavegame(metadata, engineInfo)
{
- let dateTimeString = Engine.FormatMillisecondsIntoDateStringLocal(metadata.time*1000, translate("yyyy-MM-dd HH:mm:ss"));
- let dateString = sprintf(translate("\\[%(date)s]"), { "date": dateTimeString });
+ return engineInfo && hasSameSavegameVersion(metadata, engineInfo) &&
+ hasSameEngineVersion(metadata, engineInfo) & hasSameMods(metadata, engineInfo);
+}
- if (engineInfo)
- {
- if (!hasSameSavegameVersion(metadata, engineInfo) || !hasSameEngineVersion(metadata, engineInfo))
- dateString = "[color=\"red\"]" + dateString + "[/color]";
- else if (!hasSameMods(metadata, engineInfo))
- dateString = "[color=\"orange\"]" + dateString + "[/color]";
- }
+function generateSavegameDateString(metadata, engineInfo)
+{
+ let dateString = Engine.FormatMillisecondsIntoDateStringLocal(metadata.time * 1000, translate("yyyy-MM-dd HH:mm:ss"));
+ if (!isCompatibleSavegame(metadata, engineInfo))
+ dateString = compatibilityColor(dateString);
+ return dateString;
+}
+function generateSavegameLabel(metadata, engineInfo)
+{
return sprintf(
metadata.description ?
translate("%(dateString)s %(map)s - %(description)s") :
translate("%(dateString)s %(map)s"),
{
- "dateString": dateString,
+ "dateString": generateSavegameDateString(metadata, engineInfo),
"map": metadata.initAttributes.map,
"description": metadata.description || ""
}
Index: binaries/data/mods/public/gui/replaymenu/replay_menu.js
===================================================================
--- binaries/data/mods/public/gui/replaymenu/replay_menu.js
+++ binaries/data/mods/public/gui/replaymenu/replay_menu.js
@@ -212,12 +212,12 @@
let works = replay.isCompatible;
return {
"directories": replay.directory,
- "months": greyout(getReplayDateTime(replay), works),
- "popCaps": greyout(translatePopulationCapacity(replay.attribs.settings.PopulationCap), works),
- "mapNames": greyout(getReplayMapName(replay), works),
- "mapSizes": greyout(translateMapSize(replay.attribs.settings.Size), works),
- "durations": greyout(getReplayDuration(replay), works),
- "playerNames": greyout(getReplayPlayernames(replay), works)
+ "months": compatibilityColor(getReplayDateTime(replay), works),
+ "popCaps": compatibilityColor(translatePopulationCapacity(replay.attribs.settings.PopulationCap), works),
+ "mapNames": compatibilityColor(getReplayMapName(replay), works),
+ "mapSizes": compatibilityColor(translateMapSize(replay.attribs.settings.Size), works),
+ "durations": compatibilityColor(getReplayDuration(replay), works),
+ "playerNames": compatibilityColor(getReplayPlayernames(replay), works)
};
});
@@ -287,14 +287,6 @@
}
/**
- * Adds grey font if replay is not compatible.
- */
-function greyout(text, isCompatible)
-{
- return isCompatible ? text : '[color="96 96 96"]' + text + '[/color]';
-}
-
-/**
* Returns a human-readable version of the replay date.
*/
function getReplayDateTime(replay)
Index: binaries/data/mods/public/gui/savedgames/load.js
===================================================================
--- binaries/data/mods/public/gui/savedgames/load.js
+++ binaries/data/mods/public/gui/savedgames/load.js
@@ -7,30 +7,88 @@
function init()
{
+ let savedGames = Engine.GetSavedGames();
+
+ // Get current game version and loaded mods
+ let engineInfo = Engine.GetEngineInfo();
+
+ if (Engine.GetGUIObjectByName("compatibilityFilter").checked)
+ savedGames = savedGames.filter(game => isCompatibleSavegame(game.metadata, engineInfo));
+
let gameSelection = Engine.GetGUIObjectByName("gameSelection");
- let savedGames = Engine.GetSavedGames().sort(sortDecreasingDate);
gameSelection.enabled = !!savedGames.length;
- if (!savedGames.length)
+ Engine.GetGUIObjectByName("gameSelectionFeedback").hidden = !!savedGames.length;
+
+ let selectedGameId = gameSelection.list_data[gameSelection.selected];
+
+ // Save metadata for the detailed view
+ g_SavedGamesMetadata = savedGames.map(game =>
{
- gameSelection.list = [translate("No saved games found")];
- gameSelection.selected = -1;
- return;
- }
+ game.metadata.id = game.id;
+ return game.metadata;
+ });
- // Get current game version and loaded mods
- let engineInfo = Engine.GetEngineInfo();
+ const sortKey = gameSelection.selected_column;
+ const sortOrder = gameSelection.selected_column_order;
+ g_SavedGamesMetadata = g_SavedGamesMetadata.sort((a, b) =>
+ {
+ let cmpA, cmpB;
+ switch (sortKey)
+ {
+ case 'date':
+ cmpA = +a.time;
+ cmpB = +b.time;
+ break;
+ case 'mapName':
+ cmpA = translate(a.initAttributes.settings.Name);
+ cmpB = translate(b.initAttributes.settings.Name);
+ break;
+ case 'mapType':
+ cmpA = translateMapType(a.initAttributes.mapType);
+ cmpB = translateMapType(b.initAttributes.mapType);
+ break;
+ case 'description':
+ cmpA = a.description;
+ cmpB = b.description;
+ break;
+ }
+
+ if (cmpA < cmpB)
+ return -sortOrder;
+ else if (cmpA > cmpB)
+ return +sortOrder;
+
+ return 0;
+ });
+
+ let list = g_SavedGamesMetadata.map(metadata => {
+ let isCompatible = isCompatibleSavegame(metadata, engineInfo);
+ return {
+ "date": generateSavegameDateString(metadata, engineInfo),
+ "mapName": compatibilityColor(translate(metadata.initAttributes.settings.Name), isCompatible),
+ "mapType": compatibilityColor(translateMapType(metadata.initAttributes.mapType), isCompatible),
+ "description": compatibilityColor(metadata.description, isCompatible)
+ };
+ });
- g_SavedGamesMetadata = savedGames.map(game => game.metadata);
+ if (list.length)
+ list = prepareForDropdown(list);
- gameSelection.list = savedGames.map(game => generateLabel(game.metadata, engineInfo));
- gameSelection.list_data = savedGames.map(game => game.id);
+ gameSelection.list_date = list.date || [];
+ gameSelection.list_mapName = list.mapName || [];
+ gameSelection.list_mapType = list.mapType || [];
+ gameSelection.list_description = list.description || [];
+
+ // Change these last, otherwise crash
+ gameSelection.list = g_SavedGamesMetadata.map(metadata => generateSavegameLabel(metadata, engineInfo));
+ gameSelection.list_data = g_SavedGamesMetadata.map(metadata => metadata.id);
- if (gameSelection.selected == -1)
+ if (gameSelection.selected == -1 && savedGames.length)
gameSelection.selected = 0;
- else if (gameSelection.selected >= savedGames.length) // happens when deleting the last saved game
- gameSelection.selected = savedGames.length - 1;
+ else if (gameSelection.selected >= g_SavedGamesMetadata.length) // happens when deleting the last saved game
+ gameSelection.selected = g_SavedGamesMetadata.length - 1;
else
- selectionChanged();
+ gameSelection.selected = g_SavedGamesMetadata.findIndex(metadata => metadata.id == selectedGameId);
Engine.GetGUIObjectByName("deleteGameButton").tooltip = deleteTooltip();
}
Index: binaries/data/mods/public/gui/savedgames/load.xml
===================================================================
--- binaries/data/mods/public/gui/savedgames/load.xml
+++ binaries/data/mods/public/gui/savedgames/load.xml
@@ -14,15 +14,47 @@
-