diff --git a/binaries/data/mods/public/gui/common/functions_utility.js b/binaries/data/mods/public/gui/common/functions_utility.js index 7d5eb06fe2..f49f2c7661 100644 --- a/binaries/data/mods/public/gui/common/functions_utility.js +++ b/binaries/data/mods/public/gui/common/functions_utility.js @@ -17,61 +17,32 @@ function getRandom(randomMin, randomMax) // ==================================================================== -function parseDelimiterString (parseString, delimiter) -{ - // Seeks through the delimiters in a string and populates the elements of an array with fields found between them. - - // Declare local variables. - var parseLoop = 0; - var parseElement = 0; - var seekDelimiter = 0; - var parseArray = new Array(); - - // While we're still within the bounds of the string, - while (parseLoop <= parseString.length) - { - // Seek until we find a delimiter. - seekDelimiter = parseLoop; - while (parseString[seekDelimiter] != delimiter && seekDelimiter <= parseString.length) - seekDelimiter++; - - // If we found a delimiter within the string, - if (seekDelimiter != parseString.length) - { - // Store sub-string between start point and delimiter in array element. - parseArray[parseElement] = parseString.substring(parseLoop, seekDelimiter); - parseElement++; - } - - // Move to after delimiter position for next seek. - parseLoop = seekDelimiter+1; - } - - // Store length of array. - parseArray.length = parseElement; - - return parseArray; -} - -// ==================================================================== - -// Get list of XML files in pathname excepting those starting with _ +// Get list of XML files in pathname with recursion, excepting those starting with _ function getXMLFileList(pathname) { - var files = buildDirEntList(pathname, "*.xml", false); + var files = buildDirEntList(pathname, "*.xml", true); - // Remove the path and extension from each name, since we just want the filename - files = [ n.substring(pathname.length, n.length-4) for each (n in files) ]; + var result = []; + + // Get only subpath from filename and discard extension + for (var i = 0; i < files.length; ++i) + { + var file = files[i]; + file = file.substring(pathname.length, file.length-4); - // Remove any files starting with "_" (these are for special maps used by the engine/editor) - files = [ n for each (n in files) if (n[0] != "_") ]; + // Split path into directories so we can check for beginning _ character + var tokens = file.split("/"); + + if (tokens[tokens.length-1][0] != "_") + result.push(file); + } - return files; + return result; } // ==================================================================== -// Get list of JSON files in pathname excepting those starting with _ +// Get list of JSON files in pathname function getJSONFileList(pathname) { var files = buildDirEntList(pathname, "*.json", false); @@ -79,9 +50,6 @@ function getJSONFileList(pathname) // Remove the path and extension from each name, since we just want the filename files = [ n.substring(pathname.length, n.length-5) for each (n in files) ]; - // Remove any files starting with "_" (these are for special maps used by the engine/editor) - files = [ n for each (n in files) if (n[0] != "_") ]; - return files; } @@ -152,18 +120,6 @@ function escapeText(text) // ==================================================================== -function addArrayElement(Array) -{ - // Adds an element to an array, updates its given index, and returns the index of the element. - - Array[Array.last] = new Object(); - Array.last++; - - return (Array.last - 1); -} - -// ==================================================================== - function toTitleCase (string) { if (!string) diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index c53d4a32f7..0f790f7b16 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -42,6 +42,8 @@ var g_ChatMessages = []; var g_MapData = {}; var g_CivData = {}; +var g_MapFilters = []; + function init(attribs) { @@ -78,6 +80,18 @@ function init(attribs) mapTypes.list = ["Scenario"]; // TODO: May offer saved game type for multiplayer games? mapTypes.list_data = ["scenario"]; + // Setup map filters - will appear in order they are added + addFilter("Default", function(settings) { return settings && !keywordTestOR(settings.Keywords, ["demo", "test"]); }); + addFilter("Demo Maps", function(settings) { return settings && keywordTestAND(settings.Keywords, ["demo"]); }); + addFilter("Test Maps", function(settings) { return settings && keywordTestAND(settings.Keywords, ["test"]); }); + addFilter("Old Maps", function(settings) { return !settings; }); + addFilter("All Maps", function(settings) { return true; }); + + //Populate map filters dropdown + var mapFilters = getGUIObjectByName("mapFilterSelection"); + mapFilters.list = getFilters(); + g_GameAttributes.mapFilter = "Default"; + // Setup controls for host only if (g_IsController) { @@ -89,6 +103,7 @@ function init(attribs) g_GameAttributes.map = "Gold_Rush"; mapTypes.selected = 0; + mapFilters.selected = 0; initMapNameList(); @@ -146,7 +161,8 @@ function init(attribs) { // If we're a network client, disable all the map controls // TODO: make them look visually disabled so it's obvious why they don't work - getGUIObjectByName("mapTypeSelection").enabled = false; + getGUIObjectByName("mapTypeSelection").hidden = true; + getGUIObjectByName("mapFilterSelection").hidden = true; getGUIObjectByName("mapSelection").enabled = false; // Disable player and game options controls @@ -359,12 +375,17 @@ function initMapNameList() return; } - // Cache map data - for (var file in mapFiles) - loadMapData(mapFiles[file]); - - var mapList = [ { "name": getMapDisplayName(file), "file": file } for each (file in mapFiles) ]; - + // Apply map filter, if any defined + var mapList = []; + for (var i = 0; i < mapFiles.length; ++i) + { + var file = mapFiles[i]; + var mapData = loadMapData(file); + + if (g_GameAttributes.mapFilter && mapData && testFilter(g_GameAttributes.mapFilter, mapData.settings)) + mapList.push({ "name": getMapDisplayName(file), "file": file }); + } + // Alphabetically sort the list, ignoring case mapList.sort(sortNameIgnoreCase); @@ -373,8 +394,8 @@ function initMapNameList() // Select the default map var selected = mapListFiles.indexOf(g_GameAttributes.map); - // Default to the first element if we can't find the one we searched for - if (selected == -1) + // Default to the first element if list is not empty and we can't find the one we searched for + if (selected == -1 && mapList.length) selected = 0; // Update the list control @@ -385,6 +406,9 @@ function initMapNameList() function loadMapData(name) { + if (!name) + return undefined; + if (!g_MapData[name]) { switch (g_GameAttributes.mapType) @@ -469,6 +493,26 @@ function selectMapType(type) onGameAttributesChange(); } +function selectMapFilter(filterName) +{ + // Avoid recursion + if (g_IsInGuiUpdate) + return; + + // Network clients can't change map filter + if (g_IsNetworked && !g_IsController) + return; + + g_GameAttributes.mapFilter = filterName; + + initMapNameList(); + + if (g_IsNetworked) + Engine.SetNetworkGameAttributes(g_GameAttributes); + else + onGameAttributesChange(); +} + // Called when the user selects a map from the list function selectMap(name) { @@ -479,6 +523,10 @@ function selectMap(name) // Network clients can't change map if (g_IsNetworked && !g_IsController) return; + + // Return if we have no map + if (!name) + return; g_GameAttributes.map = name; @@ -543,12 +591,14 @@ function onGameAttributesChange() // Update some controls for clients if (!g_IsController) { - var mapTypeSelectionBox = getGUIObjectByName("mapTypeSelection"); - var mapTypeIdx = mapTypeSelectionBox.list_data.indexOf(g_GameAttributes.mapType); - mapTypeSelectionBox.selected = mapTypeIdx; + var mapFilterHeading = getGUIObjectByName("mapFilterHeading"); + mapFilterHeading.caption = "Map Filter: "+g_GameAttributes.mapFilter; + var mapTypeSelection = getGUIObjectByName("mapTypeSelection"); + var mapTypeHeading = getGUIObjectByName("mapTypeHeading"); + var idx = mapTypeSelection.list_data.indexOf(g_GameAttributes.mapType); + mapTypeHeading.caption = "Match Type: "+mapTypeSelection.list[idx]; var mapSelectionBox = getGUIObjectByName("mapSelection"); - var mapIdx = mapSelectionBox.list_data.indexOf(mapName); - mapSelectionBox.selected = mapIdx; + mapSelectionBox.selected = mapSelectionBox.list_data.indexOf(mapName); initMapNameList(); @@ -577,6 +627,7 @@ function onGameAttributesChange() // Show options for host/controller if (g_IsController) { + getGUIObjectByName("numPlayersSelection").selected = g_NumPlayers - 1; numPlayersBox.hidden = false; mapSize.hidden = false; revealMap.hidden = false; @@ -836,3 +887,78 @@ function addChatMessage(msg) getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); } + + +// Basic map filters API + +// Add a new map list filter +function addFilter(name, filterFunc) +{ + if (filterFunc instanceof Object) + { // Basic validity test + var newFilter = {}; + newFilter.name = name; + newFilter.filter = filterFunc; + + g_MapFilters.push(newFilter); + } + else + { + error("Invalid map filter: "+name); + } +} + +// Get array of map filter names +function getFilters() +{ + var filters = []; + for (var i = 0; i < g_MapFilters.length; ++i) + { + filters.push(g_MapFilters[i].name); + } + + return filters; +} + +// Test map filter on given map settings object +function testFilter(name, mapSettings) +{ + for (var i = 0; i < g_MapFilters.length; ++i) + { + if (g_MapFilters[i].name == name) + { // Found filter + return g_MapFilters[i].filter(mapSettings); + } + } + + error("Invalid map filter: "+name); + return false; +} + +// Test an array of keywords against a match array using AND logic +function keywordTestAND(keywords, matches) +{ + if (!keywords || !matches) + return false; + + for (var m = 0; m < matches.length; ++m) + { // Fail on not match + if (keywords.indexOf(matches[m]) == -1) + return false; + } + return true; +} + +// Test an array of keywords against a match array using OR logic +function keywordTestOR(keywords, matches) +{ + if (!keywords || !matches) + return false; + + for (var m = 0; m < matches.length; ++m) + { // Success on match + if (keywords.indexOf(matches[m]) != -1) + return true; + } + return false; +} diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.xml b/binaries/data/mods/public/gui/gamesetup/gamesetup.xml index 028ae4cb13..39aa538c38 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.xml +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.xml @@ -29,8 +29,7 @@ - Match Type - + Match Type: selectMapType(this.list_data[this.selected]); + + Map Filter: + + selectMapFilter(this.list[this.selected]); + selectMap(this.list_data[this.selected]); - [Map name] - [Description] + + diff --git a/binaries/data/mods/public/maps/scenarios/Celtic_Buildings.xml b/binaries/data/mods/public/maps/scenarios/Celtic_Buildings.xml index 85b9e00129..4287d77244 100644 --- a/binaries/data/mods/public/maps/scenarios/Celtic_Buildings.xml +++ b/binaries/data/mods/public/maps/scenarios/Celtic_Buildings.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a594c5dae81bfe7e9bdc16e14bfbb9ef4e1c5769e8695091e6de2d7fd724b9ed -size 35887 +oid sha256:47dbc53bec7294c3aa3a86b358ba5e88229112dd1f5609578b2b29e4ca14ddaa +size 35911 diff --git a/binaries/data/mods/public/maps/scenarios/Combat_demo.xml b/binaries/data/mods/public/maps/scenarios/Combat_demo.xml index bf3d5671d4..1f834d6dd0 100755 --- a/binaries/data/mods/public/maps/scenarios/Combat_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Combat_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ef7d697da2ebd077ece9d66b8a3baf45f299f0a8991407bf0b03357e578efe3 -size 43467 +oid sha256:2d29139107fb66eea4ed0c6d10f01d1cff278ec4df5b7a553de69662676bc831 +size 43491 diff --git a/binaries/data/mods/public/maps/scenarios/Combat_demo_(huge).xml b/binaries/data/mods/public/maps/scenarios/Combat_demo_(huge).xml index 4a290dc56c..7b6bc068b4 100755 --- a/binaries/data/mods/public/maps/scenarios/Combat_demo_(huge).xml +++ b/binaries/data/mods/public/maps/scenarios/Combat_demo_(huge).xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23cfd7aff683873d37f9c01bfb07b05d7aaa4a49bed5336191eb83fbc36024b2 -size 2836 +oid sha256:f1af6b6dde1e44ef7126355bfe25a3e4ed4cdf678a12351d8d1bdf89b9e86314 +size 2860 diff --git a/binaries/data/mods/public/maps/scenarios/Fishing_demo.xml b/binaries/data/mods/public/maps/scenarios/Fishing_demo.xml index 13ad49086e..2f70ddbc6e 100644 --- a/binaries/data/mods/public/maps/scenarios/Fishing_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Fishing_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5daed9b303bb77c280f874d67e448e8c84402fb4ee4b57bf8e629bdf96a1cdb3 -size 2051 +oid sha256:3d38a8132595af354d0b82e689efb624730b84a74b44d512c7e7161c0f0e9b6c +size 2075 diff --git a/binaries/data/mods/public/maps/scenarios/Miletus.xml b/binaries/data/mods/public/maps/scenarios/Miletus.xml index a7d706e603..ede6a60348 100644 --- a/binaries/data/mods/public/maps/scenarios/Miletus.xml +++ b/binaries/data/mods/public/maps/scenarios/Miletus.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7b11ee5339e95fac77dfb7cf63298c740cde50bc1ba587990add008b8604096 -size 195886 +oid sha256:5439c4a2474592653db4552f692666ef7209f7cf576ba7344712605dfd0ec697 +size 195910 diff --git a/binaries/data/mods/public/maps/scenarios/Multiplayer_demo.xml b/binaries/data/mods/public/maps/scenarios/Multiplayer_demo.xml index c31c2b4eec..6dd4b01edc 100644 --- a/binaries/data/mods/public/maps/scenarios/Multiplayer_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Multiplayer_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2611813b4b5ba8d294b243b31a878d0f54188e4b882499ed614d9c6b76279fbc -size 106527 +oid sha256:87761993cf7ee225bd6edaeded6621829460a1cd9e36a936b8b21d879c0f7040 +size 106550 diff --git a/binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml b/binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml index 1d3f2e0790..26b1346b27 100644 --- a/binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2cf11c18063f26e1dafdec17cad7442ae81132cbbbb8bb579cdfa9155910f63 -size 19660 +oid sha256:84878e1254bf30d40958a27b2135d56f4dbed79ba7cdabfbfd3cdeada2efc6ce +size 19684 diff --git a/binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml b/binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml index bb14f8b980..c1c2fb53ef 100644 --- a/binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e503bd8c5ab7f1bdd58f35701843856ffd605e50b502f444205889862ec584b7 -size 7792 +oid sha256:3d8fd7ed494a99dde8d8f9c98464fa103c724d12aafa38b95b90478b2d1a9695 +size 7816 diff --git a/binaries/data/mods/public/maps/scenarios/Resource_demo.xml b/binaries/data/mods/public/maps/scenarios/Resource_demo.xml index aaf962938e..bd66187f03 100644 --- a/binaries/data/mods/public/maps/scenarios/Resource_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Resource_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fc54241f79b0c5599cd209c85b98d880b33c7d4cbb30896071721dfaedd203e -size 43073 +oid sha256:92efba457a8d51c57abd83c2e368069789ac9f184fb7683b5a2a7731067fe34d +size 43097 diff --git a/binaries/data/mods/public/maps/scenarios/Round_256r.xml b/binaries/data/mods/public/maps/scenarios/Round_256r.xml index 213e9d64ab..1bae8188fa 100644 --- a/binaries/data/mods/public/maps/scenarios/Round_256r.xml +++ b/binaries/data/mods/public/maps/scenarios/Round_256r.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3735b59dfb8e306e0f3fd5f76bbdea7b5772459003241f7a5228f7c58bfa2bec -size 1259 +oid sha256:cbae08c5ed1a7ca5779f7959f90ecff5d1b7ec346bd476182b79802a21f82599 +size 1283 diff --git a/binaries/data/mods/public/maps/scenarios/Units_demo.xml b/binaries/data/mods/public/maps/scenarios/Units_demo.xml index ca5cb3e0f7..bbcbec078d 100644 --- a/binaries/data/mods/public/maps/scenarios/Units_demo.xml +++ b/binaries/data/mods/public/maps/scenarios/Units_demo.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c2e180b3b959d421fedcca9eb1c14742b917010883faba814c8578c59d7afab -size 2363 +oid sha256:4b5bdfec10c985668216314a92a94a565cf1a96fa3df22657d57c4e64cc7ddc9 +size 2387 diff --git a/binaries/data/mods/public/maps/scenarios/We are Legion.xml b/binaries/data/mods/public/maps/scenarios/We are Legion.xml index 6ed0f7630d..c0d35749c2 100644 --- a/binaries/data/mods/public/maps/scenarios/We are Legion.xml +++ b/binaries/data/mods/public/maps/scenarios/We are Legion.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24625e7bcbdcdfcda8bc7df2a8a59c10bf4b4b7a89928aa57d9f206857bc87a1 -size 45734 +oid sha256:e4d4b008b1fdd9f077c16399e7c27418611657dab79f33c3010ca38d903c387e +size 45758 diff --git a/binaries/data/mods/public/maps/scenarios/shipattacks.xml b/binaries/data/mods/public/maps/scenarios/shipattacks.xml index d77b65015f..b385f6af83 100644 --- a/binaries/data/mods/public/maps/scenarios/shipattacks.xml +++ b/binaries/data/mods/public/maps/scenarios/shipattacks.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:511dd61efd42006eeccb82bfa66b264442d50a3f3ce8d2c93209d734217d8436 -size 4885 +oid sha256:430b5c33e7c91e826c18888aa0aaabcc078a8429ef890da13fe48d6d08c6a00a +size 4909 diff --git a/binaries/data/mods/public/maps/scenarios/tower_attacks.xml b/binaries/data/mods/public/maps/scenarios/tower_attacks.xml index 0755a9f284..fc322b98d6 100644 --- a/binaries/data/mods/public/maps/scenarios/tower_attacks.xml +++ b/binaries/data/mods/public/maps/scenarios/tower_attacks.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f857971c2cf308ca563936b68a8dc8bf8223cdc904e469a7b5c7745a964dc45e -size 14714 +oid sha256:3af89796fc5c91be8d47c48580d38d9e6f21835332ffb78d7f89cb1a6440bccc +size 14738