Allow filtering the replaylist by single/multiplayer, victorycondition and rated games. Patch by Imarok, fixes #3436.

This was SVN commit r18111.
This commit is contained in:
elexis 2016-04-30 13:24:28 +00:00
parent 4cfd0d64fb
commit 7ab5f8daf6
4 changed files with 111 additions and 11 deletions

View File

@ -11,6 +11,9 @@ function createReplaySelectionData(selectedDirectory)
let populationFilter = Engine.GetGUIObjectByName("populationFilter");
let durationFilter = Engine.GetGUIObjectByName("durationFilter");
let compatibilityFilter = Engine.GetGUIObjectByName("compatibilityFilter");
let singleplayerFilter = Engine.GetGUIObjectByName("singleplayerFilter");
let victoryConFilter = Engine.GetGUIObjectByName("victoryConditionFilter");
let ratedGamesFilter = Engine.GetGUIObjectByName("ratedGamesFilter");
return {
"directory": selectedDirectory,
@ -23,7 +26,10 @@ function createReplaySelectionData(selectedDirectory)
"mapSize": mapSizeFilter.list_data[mapSizeFilter.selected],
"popCap": populationFilter.list_data[populationFilter.selected],
"duration": durationFilter.list_data[durationFilter.selected],
"compatibility": compatibilityFilter.checked
"compatibility": compatibilityFilter.checked,
"singleplayer": singleplayerFilter.list_data[singleplayerFilter.selected],
"victoryCondition": victoryConFilter.list_data[victoryConFilter.selected],
"ratedGames": ratedGamesFilter.selected
}
};
}

View File

@ -33,6 +33,9 @@ function initFilters(filters)
initMapNameFilter(filters && filters.mapName);
initPopCapFilter(filters && filters.popCap);
initDurationFilter(filters && filters.duration);
initSingleplayerFilter(filters && filters.singleplayer);
initVictoryConditionFilter(filters && filters.victoryCondition);
initRatedGamesFilter(filters && filters.ratedGames);
}
/**
@ -133,6 +136,45 @@ function initDurationFilter(duration)
durationFilter.selected = 0;
}
function initSingleplayerFilter(singleplayer)
{
let singleplayerFilter = Engine.GetGUIObjectByName("singleplayerFilter");
singleplayerFilter.list = [translate("Single- and multiplayer"), translate("Single Player"), translate("Multiplayer")];
singleplayerFilter.list_data = ["", "Singleplayer", "Multiplayer"];
if (singleplayer)
singleplayerFilter.selected = singleplayerFilter.list_data.indexOf(singleplayer);
if (singleplayerFilter.selected < 0 || singleplayerFilter.selected >= singleplayerFilter.list.length)
singleplayerFilter.selected = 0;
}
function initVictoryConditionFilter(victoryCondition)
{
let victoryConditionFilter = Engine.GetGUIObjectByName("victoryConditionFilter");
victoryConditionFilter.list = [translateWithContext("victory condition", "Any gametype")].concat(g_VictoryConditions.map(victoryCondition => translateVictoryCondition(victoryCondition)));
victoryConditionFilter.list_data = [""].concat(g_VictoryConditions);
if (victoryCondition)
victoryConditionFilter.selected = victoryConditionFilter.list_data.indexOf(victoryCondition);
if (victoryConditionFilter.selected < 0 || victoryConditionFilter.selected >= victoryConditionFilter.list.length)
victoryConditionFilter.selected = 0;
}
function initRatedGamesFilter(ratedGames)
{
let ratedGamesFilter = Engine.GetGUIObjectByName("ratedGamesFilter");
ratedGamesFilter.list = [translate("Rated and unrated games"), translate("Rated games"), translate("Unrated games")];
ratedGamesFilter.list_data = ["", "rated", "not rated"];
if (ratedGames)
ratedGamesFilter.selected = ratedGamesFilter.list_data.indexOf(ratedGames);
if (ratedGamesFilter.selected < 0 || ratedGamesFilter.selected >= ratedGamesFilter.list.length)
ratedGamesFilter.selected = 0;
}
/**
* Initializes g_ReplaysFiltered with replays that are not filtered out and sort it.
*/
@ -193,14 +235,31 @@ function filterReplay(replay)
if (compatibilityFilter.checked && !isReplayCompatible(replay))
return false;
// Filter by singleplayer / multiplayer
let singleplayerFilter = Engine.GetGUIObjectByName("singleplayerFilter");
if (singleplayerFilter.selected == 1 && replay.isMultiplayer ||
singleplayerFilter.selected == 2 && !replay.isMultiplayer)
return false;
// Filter by victory condition
let victoryConditionFilter = Engine.GetGUIObjectByName("victoryConditionFilter");
if (victoryConditionFilter.selected > 0 && replay.attribs.settings.GameType != victoryConditionFilter.list_data[victoryConditionFilter.selected])
return false;
// Filter by rating
let ratedGamesFilter = Engine.GetGUIObjectByName("ratedGamesFilter");
if (ratedGamesFilter.selected == 1 && !replay.isRated ||
ratedGamesFilter.selected == 2 && replay.isRated)
return false
// Filter date/time (select a month)
var dateTimeFilter = Engine.GetGUIObjectByName("dateTimeFilter");
let dateTimeFilter = Engine.GetGUIObjectByName("dateTimeFilter");
if (dateTimeFilter.selected > 0 && getReplayMonth(replay) != dateTimeFilter.list_data[dateTimeFilter.selected])
return false;
// Filter by playernames
var playersFilter = Engine.GetGUIObjectByName("playersFilter");
var keywords = playersFilter.caption.toLowerCase().split(" ");
let playersFilter = Engine.GetGUIObjectByName("playersFilter");
let keywords = playersFilter.caption.toLowerCase().split(" ");
if (keywords.length)
{
// We just check if all typed words are somewhere in the playerlist of that replay
@ -210,22 +269,22 @@ function filterReplay(replay)
}
// Filter by map name
var mapNameFilter = Engine.GetGUIObjectByName("mapNameFilter");
let mapNameFilter = Engine.GetGUIObjectByName("mapNameFilter");
if (mapNameFilter.selected > 0 && getReplayMapName(replay) != mapNameFilter.list_data[mapNameFilter.selected])
return false;
// Filter by map size
var mapSizeFilter = Engine.GetGUIObjectByName("mapSizeFilter");
let mapSizeFilter = Engine.GetGUIObjectByName("mapSizeFilter");
if (mapSizeFilter.selected > 0 && replay.attribs.settings.Size != mapSizeFilter.list_data[mapSizeFilter.selected])
return false;
// Filter by population capacity
var populationFilter = Engine.GetGUIObjectByName("populationFilter");
let populationFilter = Engine.GetGUIObjectByName("populationFilter");
if (populationFilter.selected > 0 && replay.attribs.settings.PopulationCap != populationFilter.list_data[populationFilter.selected])
return false;
// Filter by game duration
var durationFilter = Engine.GetGUIObjectByName("durationFilter");
let durationFilter = Engine.GetGUIObjectByName("durationFilter");
if (durationFilter.selected > 0)
{
let interval = g_DurationFilterIntervals[durationFilter.selected];

View File

@ -33,6 +33,11 @@ var g_Playernames = [];
*/
var g_MapNames = [];
/**
* Sorted list of the victory conditions occuring in the replays
*/
var g_VictoryConditions = [];
/**
* Directory name of the currently selected replay. Used to restore the selection after changing filters.
*/
@ -62,7 +67,7 @@ function init(data)
/**
* Store the list of replays loaded in C++ in g_Replays.
* Check timestamp and compatibility and extract g_Playernames, g_MapNames.
* Check timestamp and compatibility and extract g_Playernames, g_MapNames, g_VictoryConditions.
* Restore selected filters and item.
*/
function loadReplays(replaySelectionData)
@ -75,6 +80,7 @@ function loadReplays(replaySelectionData)
g_Playernames = [];
for (let replay of g_Replays)
{
let nonAIPlayers = 0;
// Use time saved in file, otherwise file mod date
replay.timestamp = replay.attribs.timestamp ? +replay.attribs.timestamp : +replay.filemod_timestamp-replay.duration;
@ -87,6 +93,10 @@ function loadReplays(replaySelectionData)
if (g_MapNames.indexOf(replay.attribs.settings.Name) == -1 && replay.attribs.settings.Name != "")
g_MapNames.push(replay.attribs.settings.Name);
// Extract victory conditions
if (replay.attribs.settings.GameType && g_VictoryConditions.indexOf(replay.attribs.settings.GameType) == -1)
g_VictoryConditions.push(replay.attribs.settings.GameType);
// Extract playernames
for (let playerData of replay.attribs.settings.PlayerData)
{
@ -101,9 +111,19 @@ function loadReplays(replaySelectionData)
if (g_Playernames.indexOf(playername) == -1)
g_Playernames.push(playername);
++nonAIPlayers;
}
replay.isMultiplayer = nonAIPlayers > 1;
replay.isRated = nonAIPlayers == 2 &&
replay.attribs.settings.PlayerData.length == 2 &&
replay.attribs.settings.RatingEnabled;
}
g_MapNames.sort();
g_VictoryConditions.sort();
// Reload filters (since they depend on g_Replays and its derivatives)
initFilters(replaySelectionData && replaySelectionData.filters);

View File

@ -110,8 +110,23 @@
<translatableAttribute id="caption">Filter compatible replays</translatableAttribute>
</object>
<!-- Singleplayer / Multiplayer Filter -->
<object name="singleplayerFilter" type="dropdown" style="ModernDropDown" size="0 30 100% 55" font="sans-bold-13">
<action on="SelectionChange">displayReplayList();</action>
</object>
<!-- Victory Condition Filter -->
<object name="victoryConditionFilter" type="dropdown" style="ModernDropDown" size="0 60 100% 85" font="sans-bold-13">
<action on="SelectionChange">displayReplayList();</action>
</object>
<!-- Rated Games Filter -->
<object name="ratedGamesFilter" type="dropdown" style="ModernDropDown" size="0 90 100% 115" font="sans-bold-13">
<action on="SelectionChange">displayReplayList();</action>
</object>
<!-- Placeholder to show if no replay is selected -->
<object name="replayInfoEmpty" size="0 30 100% 100%-60" type="image" sprite="ModernDarkBoxGold" hidden="false">
<object name="replayInfoEmpty" size="0 120 100% 100%-60" type="image" sprite="ModernDarkBoxGold" hidden="false">
<object name="logo" size="50%-110 40 50%+110 140" type="image" sprite="logo"/>
<object name="subjectBox" type="image" sprite="ModernDarkBoxWhite" size="3% 180 97% 99%">
<object name="subject" size="5 5 100%-5 100%-5" type="text" style="ModernText" text_align="center"/>
@ -119,7 +134,7 @@
</object>
<!-- -->
<object name="replayInfo" size="0 30 100% 100%-60" type="image" sprite="ModernDarkBoxGold" hidden="true">
<object name="replayInfo" size="0 120 100% 100%-60" type="image" sprite="ModernDarkBoxGold" hidden="true">
<!-- Map Name Label -->
<object name="sgMapName" size="0 5 100% 20" type="text" style="ModernLabelText"/>