1
0
forked from 0ad/0ad

Add new Keywords tag to maps. Add map list filtering API to game setup. Add some default filters that use map keywords. Cleaned up client game setup a bit. Removed deprecated GUI utility functions.

This was SVN commit r8800.
This commit is contained in:
historic_bruno 2010-12-06 02:51:21 +00:00
parent 01f699b62d
commit 6a20743dc3
17 changed files with 199 additions and 108 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -29,8 +29,7 @@
<!-- Map selection -->
<object size="0 0 250 100%">
<object name="mapSelectionHeading" type="text" text_valign="center" size="0 0 100% 30" font="serif-bold-16">Match Type</object>
<object name="mapTypeHeading" type="text" text_valign="center" size="0 0 100% 30" font="serif-bold-16">Match Type:</object>
<object name="mapTypeSelection"
type="dropdown"
style="wheatDropDown"
@ -39,19 +38,29 @@
tooltip="Select a map type.">
<action on="SelectionChange">selectMapType(this.list_data[this.selected]);</action>
</object>
<object name="mapFilterHeading" type="text" text_valign="center" size="0 34 100% 64" font="serif-bold-14">Map Filter:</object>
<object name="mapFilterSelection"
type="dropdown"
style="wheatDropDown"
size="100 34 100% 64"
tooltip_style="onscreenToolTip"
tooltip="Select a map filter.">
<action on="SelectionChange">selectMapFilter(this.list[this.selected]);</action>
</object>
<object name="mapSelection"
style="wheatList"
type="list"
size="0 36 100% 100%-200"
size="0 70 100% 100%-200"
tooltip_style="onscreenToolTip"
tooltip="Select a map to play on.">
<action on="SelectionChange">selectMap(this.list_data[this.selected]);</action>
</object>
<object type="image" style="indentedPanel" size="0 100%-190 100% 100%">
<object name="mapInfoName" type="text" size="0 0 100% 30" font="serif-bold-18">[Map name]</object>
<object name="mapInfoDescription" type="text" size="0 24 100% 100%" font="serif-13">[Description]</object>
<object name="mapInfoName" type="text" size="0 0 100% 30" font="serif-bold-18"/>
<object name="mapInfoDescription" type="text" size="0 24 100% 100%" font="serif-13"/>
</object>
</object>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.