source: ps/trunk/binaries/data/mods/public/gui/replaymenu/replay_actions.js@ 25268

Last change on this file since 25268 was 25268, checked in by Silier, 3 years ago

Check for replay compatibility when opening summary screen

Summary screen and mainly its statistics can be influenced by mod as much as replay itself with mod removing or adding classes and trackers to the game.
Summary screen allows to replay the match without checking compatibility, that is fine I think if it is prevented to see summary of incompatible replay in a first place.

Therefore this is adding compatibility check for opening summary of replay.

Differential revision: D3799
Fixes: #6119
Tested by: @Langbart

  • Property svn:eol-style set to native
File size: 6.2 KB
Line 
1/**
2 * Creates the data for restoring selection, order and filters when returning to the replay menu.
3 */
4function createReplaySelectionData(selectedDirectory)
5{
6 let replaySelection = Engine.GetGUIObjectByName("replaySelection");
7 let dateTimeFilter = Engine.GetGUIObjectByName("dateTimeFilter");
8 let playersFilter = Engine.GetGUIObjectByName("playersFilter");
9 let mapNameFilter = Engine.GetGUIObjectByName("mapNameFilter");
10 let mapSizeFilter = Engine.GetGUIObjectByName("mapSizeFilter");
11 let populationFilter = Engine.GetGUIObjectByName("populationFilter");
12 let durationFilter = Engine.GetGUIObjectByName("durationFilter");
13 let compatibilityFilter = Engine.GetGUIObjectByName("compatibilityFilter");
14 let singleplayerFilter = Engine.GetGUIObjectByName("singleplayerFilter");
15 let victoryConFilter = Engine.GetGUIObjectByName("victoryConditionFilter");
16 let ratedGamesFilter = Engine.GetGUIObjectByName("ratedGamesFilter");
17
18 return {
19 "directory": selectedDirectory,
20 "column": replaySelection.selected_column,
21 "columnOrder": replaySelection.selected_column_order,
22 "filters": {
23 "date": dateTimeFilter.list_data[dateTimeFilter.selected],
24 "playernames": playersFilter.caption,
25 "mapName": mapNameFilter.list_data[mapNameFilter.selected],
26 "mapSize": mapSizeFilter.list_data[mapSizeFilter.selected],
27 "popCap": populationFilter.list_data[populationFilter.selected],
28 "duration": durationFilter.list_data[durationFilter.selected],
29 "compatibility": compatibilityFilter.checked,
30 "singleplayer": singleplayerFilter.list_data[singleplayerFilter.selected],
31 "victoryCondition": victoryConFilter.list_data[victoryConFilter.selected],
32 "ratedGames": ratedGamesFilter.selected
33 }
34 };
35}
36
37/**
38 * Starts the selected visual replay, or shows an error message in case of incompatibility.
39 */
40function startReplay()
41{
42 var selected = Engine.GetGUIObjectByName("replaySelection").selected;
43 if (selected == -1)
44 return;
45
46 var replay = g_ReplaysFiltered[selected];
47 if (isReplayCompatible(replay))
48 reallyStartVisualReplay(replay.directory);
49 else
50 displayReplayCompatibilityError(replay);
51}
52
53/**
54 * Attempts the visual replay, regardless of the compatibility.
55 *
56 * @param replayDirectory {string}
57 */
58function reallyStartVisualReplay(replayDirectory)
59{
60 if (!Engine.StartVisualReplay(replayDirectory))
61 {
62 warn('Replay "' + escapeText(Engine.GetReplayDirectoryName(replayDirectory)) + '" not found! Please click on reload cache.');
63 return;
64 }
65
66 Engine.SwitchGuiPage("page_loading.xml", {
67 "attribs": Engine.GetReplayAttributes(replayDirectory),
68 "playerAssignments": {
69 "local": {
70 "name": singleplayerName(),
71 "player": -1
72 }
73 },
74 "savedGUIData": "",
75 "replaySelectionData": createReplaySelectionData(replayDirectory)
76 });
77}
78
79/**
80 * Shows an error message stating why the replay is not compatible.
81 *
82 * @param replay {Object}
83 */
84function displayReplayCompatibilityError(replay)
85{
86 var errMsg;
87 if (replayHasSameEngineVersion(replay))
88 {
89 let gameMods = replay.attribs.mods || [];
90 errMsg = translate("This replay needs a different sequence of mods:") + "\n" +
91 comparedModsString(gameMods, g_EngineInfo.mods);
92 }
93 else
94 {
95 errMsg = translate("This replay is not compatible with your version of the game!") + "\n";
96 errMsg += sprintf(translate("Your version: %(version)s"), { "version": g_EngineInfo.engine_version }) + "\n";
97 errMsg += sprintf(translate("Required version: %(version)s"), { "version": replay.attribs.engine_version });
98 }
99
100 messageBox(500, 200, errMsg, translate("Incompatible replay"));
101}
102
103/**
104 * Opens the summary screen of the given replay, if its data was found in that directory, , or shows an error message in case of incompatibility.
105 */
106function showReplaySummary()
107{
108 let selected = Engine.GetGUIObjectByName("replaySelection").selected;
109 if (selected == -1)
110 return;
111
112 let replay = g_ReplaysFiltered[selected];
113 if (isReplayCompatible(replay))
114 reallyShowReplaySummary(replay.directory);
115 else
116 displayReplayCompatibilityError(replay);
117}
118
119function reallyShowReplaySummary(directory)
120{
121 // Load summary screen data from the selected replay directory
122 let simData = Engine.GetReplayMetadata(directory);
123
124 if (!simData)
125 {
126 messageBox(500, 200, translate("No summary data available."), translate("Error"));
127 return;
128 }
129
130 Engine.SwitchGuiPage("page_summary.xml", {
131 "sim": simData,
132 "gui": {
133 "dialog": false,
134 "isReplay": true,
135 "replayDirectory": directory,
136 "replaySelectionData": createReplaySelectionData(directory),
137 "summarySelection": g_SummarySelection
138 }
139 });
140}
141
142function reloadCache()
143{
144 let selected = Engine.GetGUIObjectByName("replaySelection").selected;
145 loadReplays(selected > -1 ? createReplaySelectionData(g_ReplaysFiltered[selected].directory) : "", true);
146}
147
148/**
149 * Callback.
150 */
151function deleteReplayButtonPressed()
152{
153 if (!Engine.GetGUIObjectByName("deleteReplayButton").enabled)
154 return;
155
156 if (Engine.HotkeyIsPressed("session.savedgames.noconfirmation"))
157 deleteReplayWithoutConfirmation();
158 else
159 deleteReplay();
160}
161/**
162 * Shows a confirmation dialog and deletes the selected replay from the disk in case.
163 */
164function deleteReplay()
165{
166 // Get selected replay
167 var selected = Engine.GetGUIObjectByName("replaySelection").selected;
168 if (selected == -1)
169 return;
170
171 var replay = g_ReplaysFiltered[selected];
172
173 messageBox(
174 500, 200,
175 translate("Are you sure you want to delete this replay permanently?") + "\n" +
176 escapeText(Engine.GetReplayDirectoryName(replay.directory)),
177 translate("Delete replay"),
178 [translate("No"), translate("Yes")],
179 [null, function() { reallyDeleteReplay(replay.directory); }]
180 );
181}
182
183/**
184 * Attempts to delete the selected replay from the disk.
185 */
186function deleteReplayWithoutConfirmation()
187{
188 var selected = Engine.GetGUIObjectByName("replaySelection").selected;
189 if (selected > -1)
190 reallyDeleteReplay(g_ReplaysFiltered[selected].directory);
191}
192
193/**
194 * Attempts to delete the given replay directory from the disk.
195 *
196 * @param replayDirectory {string}
197 */
198function reallyDeleteReplay(replayDirectory)
199{
200 var replaySelection = Engine.GetGUIObjectByName("replaySelection");
201 var selectedIndex = replaySelection.selected;
202
203 if (!Engine.DeleteReplay(replayDirectory))
204 error("Could not delete replay!");
205
206 // Refresh replay list
207 init();
208
209 replaySelection.selected = Math.min(selectedIndex, g_ReplaysFiltered.length - 1);
210}
Note: See TracBrowser for help on using the repository browser.