Sighvatr Posted February 4, 2013 Report Share Posted February 4, 2013 What about certain maps that is a large to huge size, but must be played by a 2-4 players? Quote Link to comment Share on other sites More sharing options...
Pureon Posted February 4, 2013 Report Share Posted February 4, 2013 What about certain maps that is a large to huge size, but must be played by a 2-4 players?Yes this will be possible, the restrictions can work both ways. It's up to the creator of the random map to assign the restrictions manually, or just leave it on default (if that's possible). We don't want to be too restrictive on playable options if there's no reason to be. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 4, 2013 Report Share Posted February 4, 2013 (edited) Yes this will be possible, the restrictions can work both ways. It's up to the creator of the random map to assign the restrictions manually, or just leave it on default (if that's possible). We don't want to be too restrictive on playable options if there's no reason to be.Yep. And I think even [4, 6, 8, 8, 8, 8, 8] would do. Tiny maps give Iberians no walls anyway, the main problem on tiny maps. Lower limits should not be set by default but only by maps. Even number seam better to me (for 2 equally strong teams). Edited February 4, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
Pureon Posted February 5, 2013 Report Share Posted February 5, 2013 Indeed, sounds good to me. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 5, 2013 Report Share Posted February 5, 2013 (edited) \binaries\data\mods\public\gui\gamesetup\gamesetup.js seams to be the file in question (function selectMap() line 745). Until now MAX_PLAYERS is a constant. Better to add another variable and do something like min(MAX_PLAYERS, max_players_rms) or change it to a variable entirely (I guess the first is best)?source\ps\scripting\JSInterface_Console.cpp handles autostart options but I'll leave them untouched (for testing player caps are not whanted anyway I guess).Still searching where the RMS.JSON file is loaded to add the "MaximumPlayers" and "MinimumPlayers" settings...EDIT: Should be binaries\data\mods\public\gui\common\functions_utility.js function parseJSONData() line 60. Seams just to load all data so no change needed here.Should be quite simple at first glance. Edited February 5, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
Pureon Posted February 5, 2013 Report Share Posted February 5, 2013 Should be quite simple at first glance.Great to hear, lets hope it remains that way. Thanks for keeping us updated Quote Link to comment Share on other sites More sharing options...
Spahbod Posted February 5, 2013 Author Report Share Posted February 5, 2013 \binaries\data\mods\public\gui\gamesetup\gamesetup.js seams to be the file in question (function selectMap() line 745). Until now MAX_PLAYERS is a constant. Better to add another variable and do something like min(MAX_PLAYERS, max_players_rms) or change it to a variable entirely (I guess the first is best)?source\ps\scripting\JSInterface_Console.cpp handles autostart options but I'll leave them untouched (for testing player caps are not whanted anyway I guess).Still searching where the RMS.JSON file is loaded to add the "MaximumPlayers" and "MinimumPlayers" settings...EDIT: Should be binaries\data\mods\public\gui\common\functions_utility.js function parseJSONData() line 60. Seams just to load all data so no change needed here.Should be quite simple at first glance.I just saw your previous post today so sorry about not being a help on this. But you found it all yourself . I wouldn't mind if the autostart is not limited for people who want to experience unusual variations.About your question, I think it is better not to change the constant. But a new global variable won't be needed as far as I can see. You can write a function that changes the player number list directly and call it on every map and map-size selection change. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 6, 2013 Report Share Posted February 6, 2013 (edited) Trying to figure out what information to use: g_GameAttributes or g_MapData ?Trying to figure out in which order things are called (or if at all have to be taken into consideration): initMain() -> selectMapType() -> selectMap() -> onGameAttributesChange() -> updatePlayerList() ?What to do if a "random" random map is chosen (default after switching to random maps)? The default maximum number of players for RMS should override the caps for the (later chosen) specific random map in this case??? Or should the caps be defined seperately for this case (more restrictive)?General notes on gamesetup.js:- Indentation in otherwise empty lines is sometimes missing: Fixed...- Many empty lines (I'll leave them though double empty lines inside functions seam excessive to me).- Last settings for this game type (single-player or multi-player) for each mod should be saved and be used the next time this type of game in the specific mod is chosen (Still find the mod design ugly... IMO a civ-build-tree (containing the wanted civilizations) including units, buildings, techs and their dependencies should be determined and loaded for each map. The map could leave it empty so a default civ-build-tree is loaded. The map could also specify if a specific civ-build-tree is needed for this map of if it can be chosen in the game-setup-menu).Actual file:////////////////////////////////////////////////////////////////////////////////////////////////// Constantsconst DEFAULT_NETWORKED_MAP = "Acropolis 1";const DEFAULT_OFFLINE_MAP = "Acropolis 1";// TODO: Move these somewhere like simulation\data\game_types.json, Atlas needs them tooconst VICTORY_TEXT = ["Conquest", "None"];const VICTORY_DATA = ["conquest", "endless"];const VICTORY_DEFAULTIDX = 0;const POPULATION_CAP = ["50", "100", "150", "200", "250", "300", "Unlimited"];const POPULATION_CAP_DATA = [50, 100, 150, 200, 250, 300, 10000];const POPULATION_CAP_DEFAULTIDX = 5;const STARTING_RESOURCES = ["Very Low", "Low", "Medium", "High", "Very High", "Deathmatch"];const STARTING_RESOURCES_DATA = [100, 300, 500, 1000, 3000, 50000];const STARTING_RESOURCES_DEFAULTIDX = 1;// Max number of players for this mod (the entire game?)const MAX_PLAYERS = 8;// The default upper player linit for random maps by map size:// [Tiny, Small, Medium, Normal, Large, Very Large, Giant]// Ignored if explicitely defined in the RMS.// Still capped at MAX_PLAYERS if excessing it in getMaxPlayersRMS().const MAX_PLAYERS_BY_MAP_SIZE_RMS = [4, 6, 8, 8, 8, 8, 8];////////////////////////////////////////////////////////////////////////////////////////////////// Is this is a networked game, or offlinevar g_IsNetworked;// Is this user in control of game settings (i.e. is a network server, or offline player)var g_IsController;// Are we currently updating the GUI in response to network messages instead of user input// (and therefore shouldn't send further messages to the network)var g_IsInGuiUpdate;var g_PlayerAssignments = {};// Default game setup attributesvar g_DefaultPlayerData = [];var g_GameAttributes = {settings: {}};var g_MapSizes = {};var g_AIs = [];var g_ChatMessages = [];// Data cachesvar g_MapData = {};var g_CivData = {};var g_MapFilters = [];// Warn about the AI's nonexistent naval map support.var g_NavalWarning = "\n\n[font=\"serif-bold-12\"][color=\"orange\"]Warning:[/color][/font] \The AI does not support naval maps and may cause severe performance issues. \Naval maps are recommended to be played with human opponents only.";// To prevent the display locking up while we load the map metadata,// we'll start with a 'loading' message and switch to the main screen in the// tick handlervar g_LoadingState = 0; // 0 = not started, 1 = loading, 2 = loaded////////////////////////////////////////////////////////////////////////////////////////////////function init(attribs){switch (attribs.type){case "offline":g_IsNetworked = false;g_IsController = true;break;case "server":g_IsNetworked = true;g_IsController = true;break;case "client":g_IsNetworked = true;g_IsController = false;break;default:error("Unexpected 'type' in gamesetup init: "+attribs.type);}}// Called after the map data is loaded and cachedfunction initMain(){// Load AI list and hide deprecated AIsg_AIs = Engine.GetAIs();// Sort AIs by displayed nameg_AIs.sort(function (a, {return a.data.name < b.data.name ? -1 : b.data.name < a.data.name ? +1 : 0;});// Get default player data - remove gaiag_DefaultPlayerData = initPlayerDefaults();g_DefaultPlayerData.shift();for (var i = 0; i < g_DefaultPlayerData.length; i++)g_DefaultPlayerData[i].Civ = "random";g_MapSizes = initMapSizes();// Init civsinitCivNameList();// Init map typesvar mapTypes = getGUIObjectByName("mapTypeSelection");mapTypes.list = ["Scenario","Random"];mapTypes.list_data = ["scenario","random"];// Setup map filters - will appear in order they are addedaddFilter("Default", function(settings) { return settings && !keywordTestOR(settings.Keywords, ["naval", "demo", "hidden"]); });addFilter("Naval Maps", function(settings) { return settings && keywordTestAND(settings.Keywords, ["naval"]); });addFilter("Demo Maps", function(settings) { return settings && keywordTestAND(settings.Keywords, ["demo"]); });addFilter("Old Maps", function(settings) { return !settings; });addFilter("All Maps", function(settings) { return true; });// Populate map filters dropdownvar mapFilters = getGUIObjectByName("mapFilterSelection");mapFilters.list = getFilters();g_GameAttributes.mapFilter = "Default";// Setup controls for host onlyif (g_IsController){mapTypes.selected = 0;mapFilters.selected = 0;initMapNameList();var numPlayersSelection = getGUIObjectByName("numPlayersSelection");var players = [];for (var i = 1; i <= MAX_PLAYERS; ++i)players.push(i);numPlayersSelection.list = players;numPlayersSelection.list_data = players;numPlayersSelection.selected = MAX_PLAYERS - 1;var populationCaps = getGUIObjectByName("populationCap");populationCaps.list = POPULATION_CAP;populationCaps.list_data = POPULATION_CAP_DATA;populationCaps.selected = POPULATION_CAP_DEFAULTIDX;populationCaps.onSelectionChange = function(){if (this.selected != -1){g_GameAttributes.settings.PopulationCap = POPULATION_CAP_DATA[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}}var startingResourcesL = getGUIObjectByName("startingResources");startingResourcesL.list = STARTING_RESOURCES;startingResourcesL.list_data = STARTING_RESOURCES_DATA;startingResourcesL.selected = STARTING_RESOURCES_DEFAULTIDX;startingResourcesL.onSelectionChange = function(){if (this.selected != -1){g_GameAttributes.settings.StartingResources = STARTING_RESOURCES_DATA[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}}var victoryConditions = getGUIObjectByName("victoryCondition");victoryConditions.list = VICTORY_TEXT;victoryConditions.list_data = VICTORY_DATA;victoryConditions.onSelectionChange = function(){ // Update attributes so other players can see changeif (this.selected != -1){g_GameAttributes.settings.GameType = VICTORY_DATA[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}};victoryConditions.selected = VICTORY_DEFAULTIDX;var mapSize = getGUIObjectByName("mapSize");mapSize.list = g_MapSizes.names;mapSize.list_data = g_MapSizes.tiles;mapSize.onSelectionChange = function(){ // Update attributes so other players can see changeif (this.selected != -1){g_GameAttributes.settings.Size = g_MapSizes.tiles[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}};getGUIObjectByName("revealMap").onPress = function(){ // Update attributes so other players can see changeg_GameAttributes.settings.RevealMap = this.checked;if (!g_IsInGuiUpdate){updateGameAttributes();}};getGUIObjectByName("lockTeams").onPress = function(){ // Update attributes so other players can see changeg_GameAttributes.settings.LockTeams = this.checked;if (!g_IsInGuiUpdate){updateGameAttributes();}};getGUIObjectByName("enableCheats").onPress = function(){ // Update attributes so other players can see changeg_GameAttributes.settings.CheatsEnabled = this.checked;if (!g_IsInGuiUpdate){updateGameAttributes();}};}else{// 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 workgetGUIObjectByName("mapTypeSelection").hidden = true;getGUIObjectByName("mapTypeText").hidden = false;getGUIObjectByName("mapFilterSelection").hidden = true;getGUIObjectByName("mapFilterText").hidden = false;getGUIObjectByName("mapSelectionText").hidden = false;getGUIObjectByName("mapSelection").hidden = true;getGUIObjectByName("victoryConditionText").hidden = false;getGUIObjectByName("victoryCondition").hidden = true;// Disable player and game options controls// TODO: Shouldn't players be able to choose their own assignment?for (var i = 0; i < MAX_PLAYERS; ++i){getGUIObjectByName("playerAssignment["+i+"]").enabled = false;getGUIObjectByName("playerCiv["+i+"]").hidden = true;getGUIObjectByName("playerTeam["+i+"]").hidden = true;}getGUIObjectByName("numPlayersSelection").hidden = true;}// Set up multiplayer/singleplayer bits:if (!g_IsNetworked){getGUIObjectByName("chatPanel").hidden = true;getGUIObjectByName("enableCheats").checked = true;g_GameAttributes.settings.CheatsEnabled = true;}else{getGUIObjectByName("enableCheatsDesc").hidden = false;getGUIObjectByName("enableCheats").checked = false;g_GameAttributes.settings.CheatsEnabled = false;if (g_IsController){getGUIObjectByName("enableCheats").hidden = false;}else{getGUIObjectByName("enableCheatsText").hidden = false;}}// Settings for all possible player slotsvar boxSpacing = 32;for (var i = 0; i < MAX_PLAYERS; ++i){// Space player boxesvar box = getGUIObjectByName("playerBox["+i+"]");var boxSize = box.size;var h = boxSize.bottom - boxSize.top;boxSize.top = i * boxSpacing;boxSize.bottom = i * boxSpacing + h;box.size = boxSize;// Populate team dropdownsvar team = getGUIObjectByName("playerTeam["+i+"]");team.list = ["None", "1", "2", "3", "4"];team.list_data = [-1, 0, 1, 2, 3];team.selected = 0;let playerSlot = i; // declare for inner function useteam.onSelectionChange = function(){ // Update teamif (this.selected != -1){g_GameAttributes.settings.PlayerData[playerSlot].Team = this.selected - 1;}if (!g_IsInGuiUpdate){updateGameAttributes();}};// Set eventsvar civ = getGUIObjectByName("playerCiv["+i+"]");civ.onSelectionChange = function(){ // Update civif ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario")){g_GameAttributes.settings.PlayerData[playerSlot].Civ = this.list_data[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}};}if (g_IsNetworked){// For multiplayer, focus the chat input box by defaultgetGUIObjectByName("chatInput").focus();}else{// For single-player, focus the map list by default,// to allow easy keyboard selection of mapsgetGUIObjectByName("mapSelection").focus();}}function handleNetMessage(message){log("Net message: "+uneval(message));switch (message.type){case "netstatus":switch (message.status){case "disconnected":Engine.DisconnectNetworkGame();Engine.PopGuiPage();reportDisconnect(message.reason);break;default:error("Unrecognised netstatus type "+message.status);break;}break;case "gamesetup":if (message.data) // (the host gets undefined data on first connect, so skip that){g_GameAttributes = message.data;}onGameAttributesChange();break;case "players":// Find and report all joinings/leavingsfor (var host in message.hosts){if (! g_PlayerAssignments[host]){addChatMessage({ "type": "connect", "username": message.hosts[host].name });}}for (var host in g_PlayerAssignments){if (! message.hosts[host]){addChatMessage({ "type": "disconnect", "guid": host });}}// Update the player listg_PlayerAssignments = message.hosts;updatePlayerList();break;case "start":Engine.SwitchGuiPage("page_loading.xml", {"attribs": g_GameAttributes,"isNetworked" : g_IsNetworked,"playerAssignments": g_PlayerAssignments});break;case "chat":addChatMessage({ "type": "message", "guid": message.guid, "text": message.text });break;default:error("Unrecognised net message type "+message.type);}}// Get display name from map datafunction getMapDisplayName(map){var mapData = loadMapData(map);if (!mapData || !mapData.settings || !mapData.settings.Name){ // Give some msg that map format is unsupportedlog("Map data missing in scenario '"+map+"' - likely unsupported format");return map;}return mapData.settings.Name;}// Get display name from map datafunction getMapPreview(map){var mapData = loadMapData(map);if (!mapData || !mapData.settings || !mapData.settings.Preview){ // Give some msg that map format is unsupportedreturn "nopreview.png";}return mapData.settings.Preview;}// Get a setting if it exists or return defaultfunction getSetting(settings, defaults, property){if (settings && (property in settings)){return settings[property];}// Use defaultsif (defaults && (property in defaults)){return defaults[property];}return undefined;}// Get the maximum number of players for this random map and map size/*What to use: g_GameAttributes or g_MapData ???*/function getMaxPlayersRMS(rms, size, maxPlayersByMapSizeRMS){// Make arguments optionalif (g_GameAttributes.map):rms = (rms || g_GameAttributes.map);elsewarn("getMaxPlayersRMS: g_GameAttributes.map = " + uneval(g_GameAttributes.map));// size = ( || );if (g_MapData[rms][MaximumPlayersByMapSize])maxPlayersByMapSizeRMS = (maxPlayersByMapSizeRMS || g_MapData[rms][MaximumPlayersByMapSize]);elsemaxPlayersByMapSizeRMS = (maxPlayersByMapSizeRMS || MAX_PLAYERS_BY_MAP_SIZE_RMS);var maxPlayers = MAX_PLAYERS;return maxPlayers;}// Initialize the dropdowns containing all the available civsfunction initCivNameList(){// Cache civ datag_CivData = loadCivData();// Extract name/code, and skip civs that are explicitly disabled// (intended for unusable incomplete civs)var civList = [{ "name": civ.Name, "code": civ.Code }for each (civ in g_CivData)if (civ.SelectableInGameSetup !== false)];// Alphabetically sort the list, ignoring casecivList.sort(sortNameIgnoreCase);var civListNames = [ civ.name for each (civ in civList) ];var civListCodes = [ civ.code for each (civ in civList) ];// Add random civ to beginning of listcivListNames.unshift("[color=\"orange\"]Random");civListCodes.unshift("random");// Update the dropdownsfor (var i = 0; i < MAX_PLAYERS; ++i){var civ = getGUIObjectByName("playerCiv["+i+"]");civ.list = civListNames;civ.list_data = civListCodes;civ.selected = 0;}}// Initialise the list control containing all the available mapsfunction initMapNameList(){// Get a list of map filenames// TODO: Should verify these are valid maps before adding to listvar mapSelectionBox = getGUIObjectByName("mapSelection")var mapFiles;switch (g_GameAttributes.mapType){case "scenario":mapFiles = getXMLFileList(g_GameAttributes.mapPath);break;case "random":mapFiles = getJSONFileList(g_GameAttributes.mapPath);break;default:error("initMapNameList: Unexpected map type '"+g_GameAttributes.mapType+"'");return;}// Apply map filter, if any definedvar 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 casemapList.sort(sortNameIgnoreCase);if (g_GameAttributes.mapType == "random")mapList.unshift({ "name": "[color=\"orange\"]Random[/color]", "file": "random" });var mapListNames = [ map.name for each (map in mapList) ];var mapListFiles = [ map.file for each (map in mapList) ];// Select the default mapvar selected = mapListFiles.indexOf(g_GameAttributes.map);// Default to the first element if list is not empty and we can't find the one we searched forif (selected == -1 && mapList.length){selected = 0;}// Update the list controlmapSelectionBox.list = mapListNames;mapSelectionBox.list_data = mapListFiles;mapSelectionBox.selected = selected;}function loadMapData(name){if (!name){return undefined;}if (name == "random"){g_MapData[name] = {settings : {"Name" : "Random", "Description" : "Randomly selects a map from the list"}};return g_MapData[name];}if (!g_MapData[name]){switch (g_GameAttributes.mapType){case "scenario":g_MapData[name] = Engine.LoadMapSettings(g_GameAttributes.mapPath+name);break;case "random":g_MapData[name] = parseJSONData(g_GameAttributes.mapPath+name+".json");break;default:error("loadMapData: Unexpected map type '"+g_GameAttributes.mapType+"'");return undefined;}}return g_MapData[name];}////////////////////////////////////////////////////////////////////////////////////////////////// GUI event handlersfunction cancelSetup(){Engine.DisconnectNetworkGame();}function onTick(){// First tick happens before first render, so don't load yetif (g_LoadingState == 0){g_LoadingState++;}else if (g_LoadingState == 1){getGUIObjectByName("loadingWindow").hidden = true;getGUIObjectByName("setupWindow").hidden = false;initMain();g_LoadingState++;}else if (g_LoadingState == 2){while (true){var message = Engine.PollNetworkClient();if (!message){break;}handleNetMessage(message);}}}// Called when user selects number of playersfunction selectNumPlayers(num){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change number of playersif (g_IsNetworked && !g_IsController){return;}// Only meaningful for random mapsif (g_GameAttributes.mapType != "random"){return;}// Update player datavar pData = g_GameAttributes.settings.PlayerData;if (pData && num < pData.length){// Remove extra player datag_GameAttributes.settings.PlayerData = pData.slice(0, num);}else{// Add player data from defaultsfor (var i = pData.length; i < num; ++i){g_GameAttributes.settings.PlayerData.push(g_DefaultPlayerData[i]);}}// Some players may have lost their assigned slotfor (var guid in g_PlayerAssignments){var player = g_PlayerAssignments[guid].player;if (player > num){if (g_IsNetworked)Engine.AssignNetworkPlayer(player, "");elseg_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1} };}}updateGameAttributes();}// Called when the user selects a map type from the listfunction selectMapType(type){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change map typeif (g_IsNetworked && !g_IsController){return;}// Reset game attributesg_GameAttributes.map = "";g_GameAttributes.mapType = type;// Clear old map datag_MapData = {};// Select correct pathswitch (g_GameAttributes.mapType){case "scenario":// Set a default map// TODO: This should be remembered from the last sessiong_GameAttributes.map = (g_IsNetworked ? DEFAULT_NETWORKED_MAP : DEFAULT_OFFLINE_MAP);g_GameAttributes.mapPath = "maps/scenarios/";break;case "random":g_GameAttributes.mapPath = "maps/random/";g_GameAttributes.settings = {PlayerData: g_DefaultPlayerData.slice(0, 4),Seed: Math.floor(Math.random() * 65536),CheatsEnabled: g_GameAttributes.settings.CheatsEnabled};break;default:error("selectMapType: Unexpected map type '"+g_GameAttributes.mapType+"'");return;}initMapNameList();updateGameAttributes();}function selectMapFilter(filterName){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change map filterif (g_IsNetworked && !g_IsController){return;}g_GameAttributes.mapFilter = filterName;initMapNameList();updateGameAttributes();}// Called when the user selects a map from the listfunction selectMap(name){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change mapif (g_IsNetworked && !g_IsController){return;}// Return if we have no mapif (!name){return;}var mapData = loadMapData(name);var mapSettings = (mapData && mapData.settings ? deepcopy(mapData.settings) : {});// Copy any new settingsg_GameAttributes.map = name;g_GameAttributes.script = mapSettings.Script;if (mapData !== "Random")for (var prop in mapSettings)g_GameAttributes.settings[prop] = mapSettings[prop];// Use default AI if the map doesn't specify any explicitlyfor (var i = 0; i < g_GameAttributes.settings.PlayerData.length; ++i){if (!('AI' in g_GameAttributes.settings.PlayerData[i])){g_GameAttributes.settings.PlayerData[i].AI = g_DefaultPlayerData[i].AI;}}// Reset player assignments on map changeif (!g_IsNetworked){ // Slot 1g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1} };}else{var numPlayers = (mapSettings.PlayerData ? mapSettings.PlayerData.length : g_GameAttributes.settings.PlayerData.length);for (var guid in g_PlayerAssignments){ // Unassign extra playersvar player = g_PlayerAssignments[guid].player;if (player <= MAX_PLAYERS && player > numPlayers){Engine.AssignNetworkPlayer(player, "");}}}updateGameAttributes();}function launchGame(){if (g_IsNetworked && !g_IsController){error("Only host can start game");return;}// Check that we have a mapif (!g_GameAttributes.map){return;}if (g_GameAttributes.map == "random")selectMap(getGUIObjectByName("mapSelection").list_data[Math.floor(Math.random() *(getGUIObjectByName("mapSelection").list.length - 1)) + 1]);g_GameAttributes.settings.mapType = g_GameAttributes.mapType;var numPlayers = g_GameAttributes.settings.PlayerData.length;// Assign random civilizations to players with that choice// (this is synchronized because we're the host)var cultures = [];for each (civ in g_CivData)if ((civ.Culture !== undefined)&&(cultures.indexOf(civ.Culture) < 0)&&(civ.SelectableInGameSetup == undefined)||(civ.SelectableInGameSetup))cultures.push(civ.Culture);var allcivs = new Array(cultures.length);for (var i = 0; i < allcivs.length; ++i)allcivs[i] = [];for each (civ in g_CivData)if ((civ.Culture !== undefined)&&(civ.SelectableInGameSetup == undefined)||(civ.SelectableInGameSetup))allcivs[cultures.indexOf(civ.Culture)].push(civ.Code);const romanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];for (var i = 0; i < numPlayers; ++i){civs = allcivs[Math.floor(Math.random()*allcivs.length)];if (g_GameAttributes.settings.PlayerData[i].Civ == "random")g_GameAttributes.settings.PlayerData[i].Civ = civs[Math.floor(Math.random()*civs.length)];// Setting names for AI players. Check if the player is AI and the match is not a scenarioif ((g_GameAttributes.mapType !== "scenario")&&(g_GameAttributes.settings.PlayerData[i].AI)){// Get the civ specific namesif (g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].AINames !== undefined){var civAINames = shuffleArray(g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].AINames);}else{var civAINames = [g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].Name];}// Choose the namevar usedName = 0;if (i < civAINames.length)var chosenName = civAINames[i];elsevar chosenName = civAINames[Math.floor(Math.random() * civAINames.length)];for (var j = 0; j < numPlayers; ++j)if (g_GameAttributes.settings.PlayerData[j].Name.indexOf(chosenName) !== -1)usedName++;// Assign civ specific names to AI playersif (usedName)g_GameAttributes.settings.PlayerData[i].Name = chosenName + " " + romanNumbers[usedName+1];elseg_GameAttributes.settings.PlayerData[i].Name = chosenName;}}if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);Engine.StartNetworkGame();}else{// Find the player ID which the user has been assigned tovar numPlayers = g_GameAttributes.settings.PlayerData.length;var playerID = -1;for (var i = 0; i < numPlayers; ++i){var assignBox = getGUIObjectByName("playerAssignment["+i+"]");if (assignBox.list_data[assignBox.selected] == "local"){playerID = i+1;}}// Remove extra player datag_GameAttributes.settings.PlayerData = g_GameAttributes.settings.PlayerData.slice(0, numPlayers);Engine.StartGame(g_GameAttributes, playerID);Engine.SwitchGuiPage("page_loading.xml", {"attribs": g_GameAttributes,"isNetworked" : g_IsNetworked,"playerAssignments": g_PlayerAssignments});}}////////////////////////////////////////////////////////////////////////////////////////////////function onGameAttributesChange(){g_IsInGuiUpdate = true;// Don't set any attributes here, just show the changes in GUIvar mapName = g_GameAttributes.map || "";var mapSettings = g_GameAttributes.settings;var numPlayers = (mapSettings.PlayerData ? mapSettings.PlayerData.length : MAX_PLAYERS);// Update some controls for clientsif (!g_IsController){getGUIObjectByName("mapFilterText").caption = g_GameAttributes.mapFilter;var mapTypeSelection = getGUIObjectByName("mapTypeSelection");var idx = mapTypeSelection.list_data.indexOf(g_GameAttributes.mapType);getGUIObjectByName("mapTypeText").caption = mapTypeSelection.list[idx];var mapSelectionBox = getGUIObjectByName("mapSelection");mapSelectionBox.selected = mapSelectionBox.list_data.indexOf(mapName);getGUIObjectByName("mapSelectionText").caption = getMapDisplayName(mapName);var populationCapBox = getGUIObjectByName("populationCap");populationCapBox.selected = populationCapBox.list_data.indexOf(mapSettings.PopulationCap);var startingResourcesBox = getGUIObjectByName("startingResources");startingResourcesBox.selected = startingResourcesBox.list_data.indexOf(mapSettings.StartingResources);initMapNameList();}// Controls common to all map typesvar numPlayersSelection = getGUIObjectByName("numPlayersSelection");var revealMap = getGUIObjectByName("revealMap");var victoryCondition = getGUIObjectByName("victoryCondition");var lockTeams = getGUIObjectByName("lockTeams");var mapSize = getGUIObjectByName("mapSize");var enableCheats = getGUIObjectByName("enableCheats");var populationCap = getGUIObjectByName("populationCap");var startingResources = getGUIObjectByName("startingResources");var numPlayersText= getGUIObjectByName("numPlayersText");var mapSizeText = getGUIObjectByName("mapSizeText");var revealMapText = getGUIObjectByName("revealMapText");var victoryConditionText = getGUIObjectByName("victoryConditionText");var lockTeamsText = getGUIObjectByName("lockTeamsText");var enableCheatsText = getGUIObjectByName("enableCheatsText");var populationCapText = getGUIObjectByName("populationCapText");var startingResourcesText = getGUIObjectByName("startingResourcesText");var sizeIdx = (g_MapSizes.tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.tiles.indexOf(mapSettings.Size) : g_MapSizes.default);var victoryIdx = (VICTORY_DATA.indexOf(mapSettings.GameType) != -1 ? VICTORY_DATA.indexOf(mapSettings.GameType) : VICTORY_DEFAULTIDX);enableCheats.checked = (g_GameAttributes.settings.CheatsEnabled === undefined || !g_GameAttributes.settings.CheatsEnabled ? false : true)enableCheatsText.caption = (enableCheats.checked ? "Yes" : "No");populationCap.selected = (POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) != -1 ? POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) : POPULATION_CAP_DEFAULTIDX);populationCapText.caption = POPULATION_CAP[populationCap.selected];startingResources.selected = (STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) != -1 ? STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) : STARTING_RESOURCES_DEFAULTIDX);startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];// Handle map type specific logicswitch (g_GameAttributes.mapType){case "random":if (g_IsController){ //HostnumPlayersSelection.selected = numPlayers - 1;numPlayersSelection.hidden = false;mapSize.hidden = false;revealMap.hidden = false;victoryCondition.hidden = false;lockTeams.hidden = false;populationCap.hidden = false;startingResources.hidden = false;numPlayersText.hidden = true;mapSizeText.hidden = true;revealMapText.hidden = true;victoryConditionText.hidden = true;lockTeamsText.hidden = true;populationCapText.hidden = true;startingResourcesText.hidden = true;// Update map previewgetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);mapSizeText.caption = "Map size:";mapSize.selected = sizeIdx;revealMapText.caption = "Reveal map:";revealMap.checked = (mapSettings.RevealMap ? true : false);victoryConditionText.caption = "Victory condition:";victoryCondition.selected = victoryIdx;lockTeamsText.caption = "Teams locked:";lockTeams.checked = (mapSettings.LockTeams ? true : false);}else{// ClientnumPlayersText.hidden = false;mapSizeText.hidden = false;revealMapText.hidden = false;victoryConditionText.hidden = false;lockTeamsText.hidden = false;populationCap.hidden = true;populationCapText.hidden = false;startingResources.hidden = true;startingResourcesText.hidden = false;// Update map previewgetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);numPlayersText.caption = numPlayers;mapSizeText.caption = g_MapSizes.names[sizeIdx];revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");victoryConditionText.caption = VICTORY_TEXT[victoryIdx];lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");}break;case "scenario":// For scenario just reflect settings for the current mapnumPlayersSelection.hidden = true;mapSize.hidden = true;revealMap.hidden = true;victoryCondition.hidden = true;lockTeams.hidden = true;numPlayersText.hidden = false;mapSizeText.hidden = false;revealMapText.hidden = false;victoryConditionText.hidden = false;lockTeamsText.hidden = false;populationCap.hidden = true;populationCapText.hidden = false;startingResources.hidden = true;startingResourcesText.hidden = false;// Update map previewgetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);numPlayersText.caption = numPlayers;mapSizeText.caption = "Default";revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");victoryConditionText.caption = VICTORY_TEXT[victoryIdx];lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");getGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;break;default:error("onGameAttributesChange: Unexpected map type '"+g_GameAttributes.mapType+"'");return;}// Display map namegetGUIObjectByName("mapInfoName").caption = getMapDisplayName(mapName);// Load the description from the map file, if there is onevar description = mapSettings.Description || "Sorry, no description available.";if (g_GameAttributes.mapFilter == "Naval Maps")description += g_NavalWarning;// Describe the number of playersvar playerString = numPlayers + " " + (numPlayers == 1 ? "player" : "players") + ". ";for (var i = 0; i < MAX_PLAYERS; ++i){// Show only needed player slotsgetGUIObjectByName("playerBox["+i+"]").hidden = (i >= numPlayers);// Show player data or defaults as necessaryif (i < numPlayers){var pName = getGUIObjectByName("playerName["+i+"]");var pCiv = getGUIObjectByName("playerCiv["+i+"]");var pCivText = getGUIObjectByName("playerCivText["+i+"]");var pTeam = getGUIObjectByName("playerTeam["+i+"]");var pTeamText = getGUIObjectByName("playerTeamText["+i+"]");var pColor = getGUIObjectByName("playerColour["+i+"]");// Player data / defaultsvar pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[i] : {};// Common to all game typesvar color = iColorToString(getSetting(pData, pDefs, "Colour"));pColor.sprite = "colour:"+color+" 100";pName.caption = getSetting(pData, pDefs, "Name");var team = getSetting(pData, pDefs, "Team");var civ = getSetting(pData, pDefs, "Civ");// For clients or scenarios, hide some player dropdownsif (!g_IsController || g_GameAttributes.mapType == "scenario"){pCivText.hidden = false;pCiv.hidden = true;pTeamText.hidden = false;pTeam.hidden = true;// Set text valuesif (civ == "random"){pCivText.caption = "[color=\"orange\"]Random";}else{pCivText.caption = g_CivData[civ].Name;}pTeamText.caption = (team !== undefined && team >= 0) ? team+1 : "-";}else if (g_GameAttributes.mapType == "random"){pCivText.hidden = true;pCiv.hidden = false;pTeamText.hidden = true;pTeam.hidden = false;// Set dropdown valuespCiv.selected = (civ ? pCiv.list_data.indexOf(civ) : 0);pTeam.selected = (team !== undefined && team >= 0) ? team+1 : 0;}}}getGUIObjectByName("mapInfoDescription").caption = playerString + description;g_IsInGuiUpdate = false;// Game attributes include AI settings, so update the player listupdatePlayerList();}function updateGameAttributes(){if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);}else{onGameAttributesChange();}}function updatePlayerList(){g_IsInGuiUpdate = true;var hostNameList = [];var hostGuidList = [];var assignments = [];var aiAssignments = {};var noAssignment;var assignedCount = 0;for (var guid in g_PlayerAssignments){var name = g_PlayerAssignments[guid].name;var hostID = hostNameList.length;var player = g_PlayerAssignments[guid].player;hostNameList.push(name);hostGuidList.push(guid);assignments[player] = hostID;if (player != 255)assignedCount++;}// Only enable start button if we have enough assigned playersif (g_IsController)getGUIObjectByName("startGame").enabled = (assignedCount > 0);for each (var ai in g_AIs){if (ai.data.hidden){// If the map uses a hidden AI then don't hide itvar usedByMap = false;for (var i = 0; i < MAX_PLAYERS; ++i) {if (i < g_GameAttributes.settings.PlayerData.length &&g_GameAttributes.settings.PlayerData[i].AI == ai.id){usedByMap = true;}}if (!usedByMap){continue;}}// Give AI a different color so it stands outaiAssignments[ai.id] = hostNameList.length;hostNameList.push("[color=\"70 150 70 255\"]AI: " + ai.data.name);hostGuidList.push("ai:" + ai.id);}noAssignment = hostNameList.length;hostNameList.push("[color=\"140 140 140 255\"]Unassigned");hostGuidList.push("");for (var i = 0; i < MAX_PLAYERS; ++i){let playerSlot = i;let playerID = i+1; // we don't show Gaia, so first slot is ID 1var selection = assignments[playerID];var configButton = getGUIObjectByName("playerConfig["+i+"]");configButton.hidden = true;// Look for valid player slotsif (playerSlot < g_GameAttributes.settings.PlayerData.length){// If no human is assigned, look for an AI insteadif (selection === undefined){var aiId = g_GameAttributes.settings.PlayerData[playerSlot].AI;if (aiId){// Check for a valid AIif (aiId in aiAssignments)selection = aiAssignments[aiId];elsewarn("AI \""+aiId+"\" not present. Defaulting to unassigned.");}if (!selection)selection = noAssignment;// Since no human is assigned, show the AI config buttonif (g_IsController){configButton.hidden = false;configButton.onpress = function(){Engine.PushGuiPage("page_aiconfig.xml", {ais: g_AIs,id: g_GameAttributes.settings.PlayerData[playerSlot].AI,callback: function(ai) {g_GameAttributes.settings.PlayerData[playerSlot].AI = ai.id;if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);}else{updatePlayerList();}}});};}}else{// There was a human, so make sure we don't have any AI left// over in their slot, if we're in charge of the attributesif (g_IsController && g_GameAttributes.settings.PlayerData[playerSlot].AI && g_GameAttributes.settings.PlayerData[playerSlot].AI != ""){g_GameAttributes.settings.PlayerData[playerSlot].AI = "";if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);}}}var assignBox = getGUIObjectByName("playerAssignment["+i+"]");assignBox.list = hostNameList;assignBox.list_data = hostGuidList;if (assignBox.selected != selection){assignBox.selected = selection;}if (g_IsNetworked && g_IsController){assignBox.onselectionchange = function (){if (!g_IsInGuiUpdate){var guid = hostGuidList[this.selected];if (guid == ""){// Unassign any host from this player slotEngine.AssignNetworkPlayer(playerID, "");// Remove AI from this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = "";}else if (guid.substr(0, 3) == "ai:"){// Unassign any host from this player slotEngine.AssignNetworkPlayer(playerID, "");// Set the AI for this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = guid.substr(3);}elseswapPlayers(guid, playerSlot);Engine.SetNetworkGameAttributes(g_GameAttributes);}};}else if (!g_IsNetworked){assignBox.onselectionchange = function (){if (!g_IsInGuiUpdate){var guid = hostGuidList[this.selected];if (guid == ""){// Remove AI from this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = "";}else if (guid.substr(0, 3) == "ai:"){// Set the AI for this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = guid.substr(3);}elseswapPlayers(guid, playerSlot);updatePlayerList();}};}}}g_IsInGuiUpdate = false;}function swapPlayers(guid, newSlot){// Player slots are indexed from 0 as Gaia is omitted.var newPlayerID = newSlot + 1;var playerID = g_PlayerAssignments[guid].player;// Attempt to swap the player or AI occupying the target slot,// if any, into the slot this player is currently in.if (playerID != 255){for (var i in g_PlayerAssignments){// Move the player in the destination slot into the current slot.if (g_PlayerAssignments[i].player == newPlayerID){if (g_IsNetworked)Engine.AssignNetworkPlayer(playerID, i);elseg_PlayerAssignments[i].player = playerID;break;}}// Transfer the AI from the target slot to the current slot.g_GameAttributes.settings.PlayerData[playerID - 1].AI = g_GameAttributes.settings.PlayerData[newSlot].AI;}if (g_IsNetworked)Engine.AssignNetworkPlayer(newPlayerID, guid);elseg_PlayerAssignments[guid].player = newPlayerID;// Remove AI from this player slotg_GameAttributes.settings.PlayerData[newSlot].AI = "";}function submitChatInput(){var input = getGUIObjectByName("chatInput");var text = input.caption;if (text.length){Engine.SendNetworkChat(text);input.caption = "";}}function addChatMessage(msg){var username = escapeText(msg.username || g_PlayerAssignments[msg.guid].name);var message = escapeText(msg.text);// TODO: Maybe host should have distinct font/color?var color = "white";if (g_PlayerAssignments[msg.guid] && g_PlayerAssignments[msg.guid].player != 255){ // Valid player who has been assigned - get player colourvar player = g_PlayerAssignments[msg.guid].player - 1;var mapName = g_GameAttributes.map;var mapData = loadMapData(mapName);var mapSettings = (mapData && mapData.settings ? mapData.settings : {});var pData = mapSettings.PlayerData ? mapSettings.PlayerData[player] : {};var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[player] : {};color = iColorToString(getSetting(pData, pDefs, "Colour"));}var formatted;switch (msg.type){case "connect":formatted = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font] [color="gold"]has joined[/color]';break;case "disconnect":formatted = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font] [color="gold"]has left[/color]';break;case "message":formatted = '[font="serif-bold-13"]<[color="'+ color +'"]' + username + '[/color]>[/font] ' + message;break;default:error("Invalid chat message '" + uneval(msg) + "'");return;}g_ChatMessages.push(formatted);getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");}function toggleMoreOptions(){getGUIObjectByName("moreOptions").hidden = !getGUIObjectByName("moreOptions").hidden;}////////////////////////////////////////////////////////////////////////////////////////////////// Basic map filters API// Add a new map list filterfunction addFilter(name, filterFunc){if (filterFunc instanceof Object){ // Basic validity testvar newFilter = {};newFilter.name = name;newFilter.filter = filterFunc;g_MapFilters.push(newFilter);}else{error("Invalid map filter: "+name);}}// Get array of map filter namesfunction 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 objectfunction testFilter(name, mapSettings){for (var i = 0; i < g_MapFilters.length; ++i){if (g_MapFilters[i].name == name){ // Found filterreturn g_MapFilters[i].filter(mapSettings);}}error("Invalid map filter: "+name);return false;}// Test an array of keywords against a match array using AND logicfunction keywordTestAND(keywords, matches){if (!keywords || !matches){return false;}for (var m = 0; m < matches.length; ++m){ // Fail on not matchif (keywords.indexOf(matches[m]) == -1){return false;}}return true;}// Test an array of keywords against a match array using OR logicfunction keywordTestOR(keywords, matches){if (!keywords || !matches){return false;}for (var m = 0; m < matches.length; ++m){ // Success on matchif (keywords.indexOf(matches[m]) != -1){return true;}}return false;} Edited February 6, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
Spahbod Posted February 6, 2013 Author Report Share Posted February 6, 2013 Trying to figure out what information to use: g_GameAttributes or g_MapData ?The latter I think.What to do if a "random" random map is chosen (default after switching to random maps)? The default maximum number of players for RMS should override the caps for the (later chosen) specific random map in this case??? Or should the caps be defined seperately for this case (more restrictive)?I find the last option more suitable. Another way could be not to choose a map in that the current player/size adjustment is unsuitable. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 6, 2013 Report Share Posted February 6, 2013 (edited) I find the last option more suitable. Another way could be not to choose a map in that the current player/size adjustment is unsuitable.Good idea! (The last one) Analyzing the structure of g_MapData...Getting error: "onTick is not defined". Why ever. Searching... Fixed...Call order without clicking anything:initMain (g_MapData empty...)selectMapType (g_MapData empty...)selectMap (g_MapData loaded)onGameAttributesChangeupdatePlayerListonGameAttributesChangeupdatePlayerListselectMaponGameAttributesChangeupdatePlayerListonGameAttributesChangeupdatePlayerListselectMaponGameAttributesChangeupdatePlayerListonGameAttributesChangeupdatePlayerListAdditionally called when switching map type to random map:selectMapType (g_MapData not updated yet)selectMap (g_MapData updated to "Aegean Sea")onGameAttributesChangeupdatePlayerListonGameAttributesChangeupdatePlayerListSo nothing to change for the call order AFAIKS...Final g_MapData (unevaled):g_MapData: ({aegean_sea:{settings:{Name:"Aegean Sea", Script:"aegean_sea.js", Description:"Players start in two sides of a sea with scattered islands\n\nAegean Sea is a part of Mediterranean Sea between southern Balkan and Anatolia. There are more than 100 islands located in the region. By the game's timeline, nearly all of the inhabitants of the areas surrounding the sea were Greek. Many of the islands in the Aegean have safe harbours and bays. In ancient times, navigation through the sea was easier than travelling across the rough terrain of the Greek mainland (and to some extent the coastal areas of Anatolia). Many of the islands are volcanic, and marble and iron are mined on other islands. The larger islands have some fertile valleys and plains.", BaseTerrain:["medit_grass_shrubs", "medit_rocks_grass_shrubs", "medit_rocks_shrubs", "medit_rocks_grass", "medit_shrubs"], BaseHeight:1, Keywords:["naval"], CircularMap:true, Preview:"aegean_sea.png", XXXXXX:"Optionally define other things here, like we woul...Is there a way to avoid log() from being cut?Finalizing making getMaxPlayersRMS() arguments optional (I still need g_GameAttributes.map for the propper g_MapData key and there seams to be no way to avoid this. Same with map size: g_GameAttributes.settings.Size)... Done!This code additions should do (EDITED! The other was buggy. Still returning warnings at GUI initialization but returns correct values in any case):// The default upper player linit for random maps by map size:// [Tiny, Small, Medium, Normal, Large, Very Large, Giant]// Ignored if explicitely defined in the RMS.// Still capped at MAX_PLAYERS if excessing it in getMaxPlayersRMS().const MAX_PLAYERS_BY_MAP_SIZE_RMS = [4, 6, 8, 8, 8, 8, 8];(Bla blub...)// Takes a map size in tiles and returns the index of this size (0: Tiny, 1: Small, ...)function mapSizeToSizeIndex(size){var sizeIndex = undefined;if (size == 128)sizeIndex = 0;if (size == 192)sizeIndex = 1;if (size == 256)sizeIndex = 2;if (size == 320)sizeIndex = 3;if (size == 384)sizeIndex = 4;if (size == 448)sizeIndex = 5;if (size == 512)sizeIndex = 6;return sizeIndex;}// Get the maximum number of players for this random map and map sizefunction getMaxPlayersRMS(rms, mapSize, maxPlayersByMapSizeRMS){// Make arguments optional// The map name as key for g_MapDataif (g_GameAttributes.map || rms)rms = (rms || g_GameAttributes.map);else{warn("getMaxPlayersRMS: g_GameAttributes.map is undefined! Returning MAX_PLAYERS = " + MAX_PLAYERS);return MAX_PLAYERS;}// The map size to determin which index of the mlayer cap array to useif (mapSize || g_GameAttributes.settings.Size)mapSize = (mapSize || g_GameAttributes.settings.Size);else{warn("getMaxPlayersRMS: g_GameAttributes.settings.Size is undefined! Returning MAX_PLAYERS = " + MAX_PLAYERS);return MAX_PLAYERS;}// The max number of players by map size arrayif (g_MapData[rms].settings && g_MapData[rms].settings.MaximumPlayersByMapSize)maxPlayersByMapSizeRMS = (maxPlayersByMapSizeRMS || g_MapData[rms].settings.MaximumPlayersByMapSize);elsemaxPlayersByMapSizeRMS = (maxPlayersByMapSizeRMS || MAX_PLAYERS_BY_MAP_SIZE_RMS);// Getting the return valuevar maxPlayers = Math.min(maxPlayersByMapSizeRMS[mapSizeToSizeIndex(mapSize)], MAX_PLAYERS);return maxPlayers;}Grrr... again the error: "onTick is not defined". Why ever. Searching (again)... Fixed again!Searching where exactly to replace MAX_PLAYERS with getMaxPlayersRMS()... Oh, guessing always since if it's an scenario the scenario defines the number of players, not MAX_PLAYERS... Not really but I think I got it mainly right...Have to go now. I hope to finish this tomorrow (Likely without the "Random" random map case sanely implemented)...Comments/suggestions/criticism welcome!Seams to work somehow but the dropdown for number of players still contain 8 choices and lowering the map size does not result in lowering the number of player slots... I seam to need to change/update g_GameAttributes.settings.PlayerData as well. But doing this inside the function leads to problems when called from onGameAttributesChange (because it changes the game attribute again and run into an infinite loop)... Ah there's a g_IsInGuiUpdate variable (little blind FeXoR)...How to change the content of the number of players drop down? ...getGUIObjectByName("numPlayersSelection").list and list_data...It seams to be best to use the function for scenarios as well because setting PlayerData it not always mapType dependent(?)Work in progress... Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) just a suggestion, I can’t code js, but a quick google query told me it’s possiblechange function mapSizeToSizeIndex(size) to:function mapSizeToSizeIndex(size){ var sizeIndex = undefined; switch (size) { case 128: sizeIndex = 0; break; case 192: sizeIndex = 1; break; case 256: sizeIndex = 2; break; case 320: sizeIndex = 3; break; case 384: sizeIndex = 4; break; case 448: sizeIndex = 5; break; case 512: sizeIndex = 6; break; default: //some error handling here, since invalid size passed } return sizeIndex;}or:(shorter version without a variable)function mapSizeToSizeIndex(size){ switch (size) { case 128: return 0; case 192: return 1; case 256: return 2; case 320: return 3; case 384: return 4; case 448: return 5; case 512: return 6; default: //some error handling here, since invalid size passed return undefined; }}or:the shortest version that uses the specific values 'size' can havethis one is fragile, you may use a variable for the calculation and error-check before returning the valuefunction mapSizeToSizeIndex(size){ return (size/64-2);} Edited February 7, 2013 by luziferius Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) just a suggestion, I can’t code js, but a quick google query told me it’s possiblechange function mapSizeToSizeIndex(size) to:function mapSizeToSizeIndex(size){ var sizeIndex = undefined; switch (size) { case 128: sizeIndex = 0; break; case 192: sizeIndex = 1; break; case 256: sizeIndex = 2; break; case 320: sizeIndex = 3; break; case 384: sizeIndex = 4; break; case 448: sizeIndex = 5; break; case 512: sizeIndex = 6; break; default: //some error handling here, since invalid size passed } return sizeIndex;}or:(shorter version without a variable)function mapSizeToSizeIndex(size){ switch (size) { case 128: return 0; case 192: return 1; case 256: return 2; case 320: return 3; case 384: return 4; case 448: return 5; case 512: return 6; default: //some error handling here, since invalid size passed return undefined; }}or:the shortest version that uses the specific values 'size' can havethis one is fragile, you may use a variable for the calculation and error-check before returning the valuefunction mapSizeToSizeIndex(size){ return (size/64-2);}Good suggestion. Indeed with the last example I don't need any function but just use it as index right away.Actual code now:////////////////////////////////////////////////////////////////////////////////////////////////// Constantsconst DEFAULT_NETWORKED_MAP = "Acropolis 1";const DEFAULT_OFFLINE_MAP = "Acropolis 1";// TODO: Move these somewhere like simulation\data\game_types.json, Atlas needs them tooconst VICTORY_TEXT = ["Conquest", "None"];const VICTORY_DATA = ["conquest", "endless"];const VICTORY_DEFAULTIDX = 0;const POPULATION_CAP = ["50", "100", "150", "200", "250", "300", "Unlimited"];const POPULATION_CAP_DATA = [50, 100, 150, 200, 250, 300, 10000];const POPULATION_CAP_DEFAULTIDX = 5;const STARTING_RESOURCES = ["Very Low", "Low", "Medium", "High", "Very High", "Deathmatch"];const STARTING_RESOURCES_DATA = [100, 300, 500, 1000, 3000, 50000];const STARTING_RESOURCES_DEFAULTIDX = 1;// Max number of players for this mod (the entire game?)const MAX_PLAYERS = 8;// The default upper player linit for random maps by map size:// [Tiny, Small, Medium, Normal, Large, Very Large, Giant]// Ignored if explicitely defined in the RMS.// Still capped at MAX_PLAYERS if excessing it in getMaxPlayersRMS().const MAX_PLAYERS_BY_MAP_SIZE_RMS = [2, 3, 4, 5, 6, 7, 8];////////////////////////////////////////////////////////////////////////////////////////////////// Is this is a networked game, or offlinevar g_IsNetworked;// Is this user in control of game settings (i.e. is a network server, or offline player)var g_IsController;// Are we currently updating the GUI in response to network messages instead of user input// (and therefore shouldn't send further messages to the network)var g_IsInGuiUpdate;var g_PlayerAssignments = {};// Default game setup attributesvar g_DefaultPlayerData = [];var g_GameAttributes = {settings: {}};var g_MapSizes = {};var g_AIs = [];var g_ChatMessages = [];// Data cachesvar g_MapData = {};var g_CivData = {};var g_MapFilters = [];// Warn about the AI's nonexistent naval map support.var g_NavalWarning = "\n\n[font=\"serif-bold-12\"][color=\"orange\"]Warning:[/color][/font] \The AI does not support naval maps and may cause severe performance issues. \Naval maps are recommended to be played with human opponents only.";// To prevent the display locking up while we load the map metadata,// we'll start with a 'loading' message and switch to the main screen in the// tick handlervar g_LoadingState = 0; // 0 = not started, 1 = loading, 2 = loaded////////////////////////////////////////////////////////////////////////////////////////////////function init(attribs){switch (attribs.type){case "offline":g_IsNetworked = false;g_IsController = true;break;case "server":g_IsNetworked = true;g_IsController = true;break;case "client":g_IsNetworked = true;g_IsController = false;break;default:error("Unexpected 'type' in gamesetup init: "+attribs.type);}}// Called after the map data is loaded and cachedfunction initMain(){// Load AI list and hide deprecated AIsg_AIs = Engine.GetAIs();// Sort AIs by displayed nameg_AIs.sort(function (a, {return a.data.name < b.data.name ? -1 : b.data.name < a.data.name ? +1 : 0;});// Get default player data - remove gaiag_DefaultPlayerData = initPlayerDefaults();g_DefaultPlayerData.shift();for (var i = 0; i < g_DefaultPlayerData.length; i++)g_DefaultPlayerData[i].Civ = "random";g_MapSizes = initMapSizes();// Init civsinitCivNameList();// Init map typesvar mapTypes = getGUIObjectByName("mapTypeSelection");mapTypes.list = ["Scenario","Random"];mapTypes.list_data = ["scenario","random"];// Setup map filters - will appear in order they are addedaddFilter("Default", function(settings) { return settings && !keywordTestOR(settings.Keywords, ["naval", "demo", "hidden"]); });addFilter("Naval Maps", function(settings) { return settings && keywordTestAND(settings.Keywords, ["naval"]); });addFilter("Demo Maps", function(settings) { return settings && keywordTestAND(settings.Keywords, ["demo"]); });addFilter("Old Maps", function(settings) { return !settings; });addFilter("All Maps", function(settings) { return true; });// Populate map filters dropdownvar mapFilters = getGUIObjectByName("mapFilterSelection");mapFilters.list = getFilters();g_GameAttributes.mapFilter = "Default";// Setup controls for host onlyif (g_IsController){mapTypes.selected = 0;mapFilters.selected = 0;initMapNameList();var numPlayersSelection = getGUIObjectByName("numPlayersSelection");var players = [];for (var i = 1; i <= MAX_PLAYERS; ++i)players.push(i);numPlayersSelection.list = players;numPlayersSelection.list_data = players;numPlayersSelection.selected = MAX_PLAYERS - 1;var populationCaps = getGUIObjectByName("populationCap");populationCaps.list = POPULATION_CAP;populationCaps.list_data = POPULATION_CAP_DATA;populationCaps.selected = POPULATION_CAP_DEFAULTIDX;populationCaps.onSelectionChange = function(){if (this.selected != -1){g_GameAttributes.settings.PopulationCap = POPULATION_CAP_DATA[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}}var startingResourcesL = getGUIObjectByName("startingResources");startingResourcesL.list = STARTING_RESOURCES;startingResourcesL.list_data = STARTING_RESOURCES_DATA;startingResourcesL.selected = STARTING_RESOURCES_DEFAULTIDX;startingResourcesL.onSelectionChange = function(){if (this.selected != -1){g_GameAttributes.settings.StartingResources = STARTING_RESOURCES_DATA[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}}var victoryConditions = getGUIObjectByName("victoryCondition");victoryConditions.list = VICTORY_TEXT;victoryConditions.list_data = VICTORY_DATA;victoryConditions.onSelectionChange = function(){ // Update attributes so other players can see changeif (this.selected != -1){g_GameAttributes.settings.GameType = VICTORY_DATA[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}};victoryConditions.selected = VICTORY_DEFAULTIDX;var mapSize = getGUIObjectByName("mapSize");mapSize.list = g_MapSizes.names;mapSize.list_data = g_MapSizes.tiles;mapSize.onSelectionChange = function(){ // Update attributes so other players can see changeif (this.selected != -1){g_GameAttributes.settings.Size = g_MapSizes.tiles[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}};getGUIObjectByName("revealMap").onPress = function(){ // Update attributes so other players can see changeg_GameAttributes.settings.RevealMap = this.checked;if (!g_IsInGuiUpdate){updateGameAttributes();}};getGUIObjectByName("lockTeams").onPress = function(){ // Update attributes so other players can see changeg_GameAttributes.settings.LockTeams = this.checked;if (!g_IsInGuiUpdate){updateGameAttributes();}};getGUIObjectByName("enableCheats").onPress = function(){ // Update attributes so other players can see changeg_GameAttributes.settings.CheatsEnabled = this.checked;if (!g_IsInGuiUpdate){updateGameAttributes();}};}else{// 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 workgetGUIObjectByName("mapTypeSelection").hidden = true;getGUIObjectByName("mapTypeText").hidden = false;getGUIObjectByName("mapFilterSelection").hidden = true;getGUIObjectByName("mapFilterText").hidden = false;getGUIObjectByName("mapSelectionText").hidden = false;getGUIObjectByName("mapSelection").hidden = true;getGUIObjectByName("victoryConditionText").hidden = false;getGUIObjectByName("victoryCondition").hidden = true;// Disable player and game options controls// TODO: Shouldn't players be able to choose their own assignment?for (var i = 0; i < MAX_PLAYERS; ++i){getGUIObjectByName("playerAssignment["+i+"]").enabled = false;getGUIObjectByName("playerCiv["+i+"]").hidden = true;getGUIObjectByName("playerTeam["+i+"]").hidden = true;}getGUIObjectByName("numPlayersSelection").hidden = true;}// Set up multiplayer/singleplayer bits:if (!g_IsNetworked){getGUIObjectByName("chatPanel").hidden = true;getGUIObjectByName("enableCheats").checked = true;g_GameAttributes.settings.CheatsEnabled = true;}else{getGUIObjectByName("enableCheatsDesc").hidden = false;getGUIObjectByName("enableCheats").checked = false;g_GameAttributes.settings.CheatsEnabled = false;if (g_IsController){getGUIObjectByName("enableCheats").hidden = false;}else{getGUIObjectByName("enableCheatsText").hidden = false;}}// Settings for all possible player slotsvar boxSpacing = 32;for (var i = 0; i < MAX_PLAYERS; ++i){// Space player boxesvar box = getGUIObjectByName("playerBox["+i+"]");var boxSize = box.size;var h = boxSize.bottom - boxSize.top;boxSize.top = i * boxSpacing;boxSize.bottom = i * boxSpacing + h;box.size = boxSize;// Populate team dropdownsvar team = getGUIObjectByName("playerTeam["+i+"]");team.list = ["None", "1", "2", "3", "4"];team.list_data = [-1, 0, 1, 2, 3];team.selected = 0;let playerSlot = i; // declare for inner function useteam.onSelectionChange = function(){ // Update teamif (this.selected != -1){g_GameAttributes.settings.PlayerData[playerSlot].Team = this.selected - 1;}if (!g_IsInGuiUpdate){updateGameAttributes();}};// Set eventsvar civ = getGUIObjectByName("playerCiv["+i+"]");civ.onSelectionChange = function(){ // Update civif ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario")){g_GameAttributes.settings.PlayerData[playerSlot].Civ = this.list_data[this.selected];}if (!g_IsInGuiUpdate){updateGameAttributes();}};}if (g_IsNetworked){// For multiplayer, focus the chat input box by defaultgetGUIObjectByName("chatInput").focus();}else{// For single-player, focus the map list by default,// to allow easy keyboard selection of mapsgetGUIObjectByName("mapSelection").focus();}}function handleNetMessage(message){log("Net message: "+uneval(message));switch (message.type){case "netstatus":switch (message.status){case "disconnected":Engine.DisconnectNetworkGame();Engine.PopGuiPage();reportDisconnect(message.reason);break;default:error("Unrecognised netstatus type "+message.status);break;}break;case "gamesetup":if (message.data) // (the host gets undefined data on first connect, so skip that){g_GameAttributes = message.data;}onGameAttributesChange();break;case "players":// Find and report all joinings/leavingsfor (var host in message.hosts){if (! g_PlayerAssignments[host]){addChatMessage({ "type": "connect", "username": message.hosts[host].name });}}for (var host in g_PlayerAssignments){if (! message.hosts[host]){addChatMessage({ "type": "disconnect", "guid": host });}}// Update the player listg_PlayerAssignments = message.hosts;updatePlayerList();break;case "start":Engine.SwitchGuiPage("page_loading.xml", {"attribs": g_GameAttributes,"isNetworked" : g_IsNetworked,"playerAssignments": g_PlayerAssignments});break;case "chat":addChatMessage({ "type": "message", "guid": message.guid, "text": message.text });break;default:error("Unrecognised net message type "+message.type);}}// Get display name from map datafunction getMapDisplayName(map){var mapData = loadMapData(map);if (!mapData || !mapData.settings || !mapData.settings.Name){ // Give some msg that map format is unsupportedlog("Map data missing in scenario '"+map+"' - likely unsupported format");return map;}return mapData.settings.Name;}// Get display name from map datafunction getMapPreview(map){var mapData = loadMapData(map);if (!mapData || !mapData.settings || !mapData.settings.Preview){ // Give some msg that map format is unsupportedreturn "nopreview.png";}return mapData.settings.Preview;}// Get a setting if it exists or return defaultfunction getSetting(settings, defaults, property){if (settings && (property in settings)){return settings[property];}// Use defaultsif (defaults && (property in defaults)){return defaults[property];}return undefined;}// Takes a map size in tiles and returns the index of this size (0: Tiny, 1: Small, ...)function mapSizeToSizeIndex(size){var sizeIndex = undefined;if (size == 128)sizeIndex = 0;if (size == 192)sizeIndex = 1;if (size == 256)sizeIndex = 2;if (size == 320)sizeIndex = 3;if (size == 384)sizeIndex = 4;if (size == 448)sizeIndex = 5;if (size == 512)sizeIndex = 6;return sizeIndex;}// Get the maximum number of players for this random map and map size// Include the scenario case?function getMaxPlayersRMS(mapName, mapSize, maxPlayersByMapSizeRMS){log("g_GameAttributes.mapType = " + g_GameAttributes.mapType);// Make arguments optional// The map name as key for g_MapDatamapName = (mapName || g_GameAttributes.map);// The map size to determin which index of the player cap array to useif (mapSize || g_GameAttributes.settings.Size)mapSize = (mapSize || g_GameAttributes.settings.Size);else{// Only a log to not show up at gui initializationlog("getMaxPlayersRMS: g_GameAttributes.settings.Size is undefined! Returning MAX_PLAYERS = " + MAX_PLAYERS);return MAX_PLAYERS;}// The max number of players by map size arrayif (g_MapData[mapName].settings && g_MapData[mapName].settings.MaximumPlayersByMapSize)maxPlayersByMapSizeRMS = (maxPlayersByMapSizeRMS || g_MapData[mapName].settings.MaximumPlayersByMapSize);elsemaxPlayersByMapSizeRMS = (maxPlayersByMapSizeRMS || MAX_PLAYERS_BY_MAP_SIZE_RMS);// Getting the return valuevar maxPlayers = Math.min(maxPlayersByMapSizeRMS[Math.round(mapSize/64 - 2)], MAX_PLAYERS);return maxPlayers;}// Initialize the dropdowns containing all the available civsfunction initCivNameList(){// Cache civ datag_CivData = loadCivData();// Extract name/code, and skip civs that are explicitly disabled// (intended for unusable incomplete civs)var civList = [{ "name": civ.Name, "code": civ.Code }for each (civ in g_CivData)if (civ.SelectableInGameSetup !== false)];// Alphabetically sort the list, ignoring casecivList.sort(sortNameIgnoreCase);var civListNames = [ civ.name for each (civ in civList) ];var civListCodes = [ civ.code for each (civ in civList) ];// Add random civ to beginning of listcivListNames.unshift("[color=\"orange\"]Random");civListCodes.unshift("random");// Update the dropdownsfor (var i = 0; i < MAX_PLAYERS; ++i){var civ = getGUIObjectByName("playerCiv["+i+"]");civ.list = civListNames;civ.list_data = civListCodes;civ.selected = 0;}}// Initialise the list control containing all the available mapsfunction initMapNameList(){// Get a list of map filenames// TODO: Should verify these are valid maps before adding to listvar mapSelectionBox = getGUIObjectByName("mapSelection")var mapFiles;switch (g_GameAttributes.mapType){case "scenario":mapFiles = getXMLFileList(g_GameAttributes.mapPath);break;case "random":mapFiles = getJSONFileList(g_GameAttributes.mapPath);break;default:error("initMapNameList: Unexpected map type '"+g_GameAttributes.mapType+"'");return;}// Apply map filter, if any definedvar 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 casemapList.sort(sortNameIgnoreCase);if (g_GameAttributes.mapType == "random")mapList.unshift({ "name": "[color=\"orange\"]Random[/color]", "file": "random" });var mapListNames = [ map.name for each (map in mapList) ];var mapListFiles = [ map.file for each (map in mapList) ];// Select the default mapvar selected = mapListFiles.indexOf(g_GameAttributes.map);// Default to the first element if list is not empty and we can't find the one we searched forif (selected == -1 && mapList.length){selected = 0;}// Update the list controlmapSelectionBox.list = mapListNames;mapSelectionBox.list_data = mapListFiles;mapSelectionBox.selected = selected;}function loadMapData(name){if (!name){return undefined;}if (name == "random"){g_MapData[name] = {settings : {"Name" : "Random", "Description" : "Randomly selects a map from the list"}};return g_MapData[name];}if (!g_MapData[name]){switch (g_GameAttributes.mapType){case "scenario":g_MapData[name] = Engine.LoadMapSettings(g_GameAttributes.mapPath+name);break;case "random":g_MapData[name] = parseJSONData(g_GameAttributes.mapPath+name+".json");break;default:error("loadMapData: Unexpected map type '"+g_GameAttributes.mapType+"'");return undefined;}}return g_MapData[name];}////////////////////////////////////////////////////////////////////////////////////////////////// GUI event handlersfunction cancelSetup(){Engine.DisconnectNetworkGame();}function onTick(){// First tick happens before first render, so don't load yetif (g_LoadingState == 0){g_LoadingState++;}else if (g_LoadingState == 1){getGUIObjectByName("loadingWindow").hidden = true;getGUIObjectByName("setupWindow").hidden = false;initMain();g_LoadingState++;}else if (g_LoadingState == 2){while (true){var message = Engine.PollNetworkClient();if (!message){break;}handleNetMessage(message);}}}// Called when user selects number of playersfunction selectNumPlayers(num){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change number of playersif (g_IsNetworked && !g_IsController){return;}// Only meaningful for random mapsif (g_GameAttributes.mapType != "random"){return;}// Update player datavar pData = g_GameAttributes.settings.PlayerData;// DEBUG To change?if (pData && num < pData.length){// Remove extra player datag_GameAttributes.settings.PlayerData = pData.slice(0, num);}else{// Add player data from defaultsfor (var i = pData.length; i < num; ++i){g_GameAttributes.settings.PlayerData.push(g_DefaultPlayerData[i]);}}// Some players may have lost their assigned slotfor (var guid in g_PlayerAssignments){var player = g_PlayerAssignments[guid].player;if (player > num){if (g_IsNetworked)Engine.AssignNetworkPlayer(player, "");elseg_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1} };}}updateGameAttributes();}// Called when the user selects a map type from the listfunction selectMapType(type){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change map typeif (g_IsNetworked && !g_IsController){return;}// Reset game attributesg_GameAttributes.map = "";g_GameAttributes.mapType = type;// Clear old map datag_MapData = {};// Select correct pathswitch (g_GameAttributes.mapType){case "scenario":// Set a default map// TODO: This should be remembered from the last sessiong_GameAttributes.map = (g_IsNetworked ? DEFAULT_NETWORKED_MAP : DEFAULT_OFFLINE_MAP);g_GameAttributes.mapPath = "maps/scenarios/";break;case "random":g_GameAttributes.mapPath = "maps/random/";g_GameAttributes.settings = {// DEBUG To change?PlayerData: g_DefaultPlayerData.slice(0, 4),Seed: Math.floor(Math.random() * 65536),CheatsEnabled: g_GameAttributes.settings.CheatsEnabled};break;default:error("selectMapType: Unexpected map type '"+g_GameAttributes.mapType+"'");return;}initMapNameList();updateGameAttributes();}function selectMapFilter(filterName){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change map filterif (g_IsNetworked && !g_IsController){return;}g_GameAttributes.mapFilter = filterName;initMapNameList();updateGameAttributes();}// Called when the user selects a map from the listfunction selectMap(name){// Avoid recursionif (g_IsInGuiUpdate){return;}// Network clients can't change mapif (g_IsNetworked && !g_IsController){return;}// Return if we have no mapif (!name){return;}var mapData = loadMapData(name);var mapSettings = (mapData && mapData.settings ? deepcopy(mapData.settings) : {});// Copy any new settingsg_GameAttributes.map = name;g_GameAttributes.script = mapSettings.Script;if (mapData !== "Random")for (var prop in mapSettings)g_GameAttributes.settings[prop] = mapSettings[prop];// Use default AI if the map doesn't specify any explicitly// DEBUG To change?for (var i = 0; i < g_GameAttributes.settings.PlayerData.length; ++i){if (!('AI' in g_GameAttributes.settings.PlayerData[i])){g_GameAttributes.settings.PlayerData[i].AI = g_DefaultPlayerData[i].AI;}}// Reset player assignments on map changeif (!g_IsNetworked){ // Slot 1g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1} };}else{// DEBUG To change? BTW: if mapSettings.PlayerData does not exist g_GameAttributes.settings.PlayerData is not set properly either?!var numPlayers = (mapSettings.PlayerData ? mapSettings.PlayerData.length : g_GameAttributes.settings.PlayerData.length);for (var guid in g_PlayerAssignments){ // Unassign extra playersvar player = g_PlayerAssignments[guid].player;if (player <= MAX_PLAYERS && player > numPlayers){Engine.AssignNetworkPlayer(player, "");}}}updateGameAttributes();}function launchGame(){if (g_IsNetworked && !g_IsController){error("Only host can start game");return;}// Check that we have a mapif (!g_GameAttributes.map){return;}if (g_GameAttributes.map == "random")selectMap(getGUIObjectByName("mapSelection").list_data[Math.floor(Math.random() *(getGUIObjectByName("mapSelection").list.length - 1)) + 1]);g_GameAttributes.settings.mapType = g_GameAttributes.mapType;var numPlayers = g_GameAttributes.settings.PlayerData.length;// Assign random civilizations to players with that choice// (this is synchronized because we're the host)var cultures = [];for each (civ in g_CivData)if ((civ.Culture !== undefined)&&(cultures.indexOf(civ.Culture) < 0)&&(civ.SelectableInGameSetup == undefined)||(civ.SelectableInGameSetup))cultures.push(civ.Culture);var allcivs = new Array(cultures.length);for (var i = 0; i < allcivs.length; ++i)allcivs[i] = [];for each (civ in g_CivData)if ((civ.Culture !== undefined)&&(civ.SelectableInGameSetup == undefined)||(civ.SelectableInGameSetup))allcivs[cultures.indexOf(civ.Culture)].push(civ.Code);const romanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];for (var i = 0; i < numPlayers; ++i){civs = allcivs[Math.floor(Math.random()*allcivs.length)];if (g_GameAttributes.settings.PlayerData[i].Civ == "random")g_GameAttributes.settings.PlayerData[i].Civ = civs[Math.floor(Math.random()*civs.length)];// Setting names for AI players. Check if the player is AI and the match is not a scenarioif ((g_GameAttributes.mapType !== "scenario")&&(g_GameAttributes.settings.PlayerData[i].AI)){// Get the civ specific namesif (g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].AINames !== undefined){var civAINames = shuffleArray(g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].AINames);}else{var civAINames = [g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].Name];}// Choose the namevar usedName = 0;if (i < civAINames.length)var chosenName = civAINames[i];elsevar chosenName = civAINames[Math.floor(Math.random() * civAINames.length)];for (var j = 0; j < numPlayers; ++j)if (g_GameAttributes.settings.PlayerData[j].Name.indexOf(chosenName) !== -1)usedName++;// Assign civ specific names to AI playersif (usedName)g_GameAttributes.settings.PlayerData[i].Name = chosenName + " " + romanNumbers[usedName+1];elseg_GameAttributes.settings.PlayerData[i].Name = chosenName;}}if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);Engine.StartNetworkGame();}else{// Find the player ID which the user has been assigned tovar numPlayers = g_GameAttributes.settings.PlayerData.length;var playerID = -1;for (var i = 0; i < numPlayers; ++i){var assignBox = getGUIObjectByName("playerAssignment["+i+"]");if (assignBox.list_data[assignBox.selected] == "local"){playerID = i+1;}}// Remove extra player datag_GameAttributes.settings.PlayerData = g_GameAttributes.settings.PlayerData.slice(0, numPlayers);Engine.StartGame(g_GameAttributes, playerID);Engine.SwitchGuiPage("page_loading.xml", {"attribs": g_GameAttributes,"isNetworked" : g_IsNetworked,"playerAssignments": g_PlayerAssignments});}}////////////////////////////////////////////////////////////////////////////////////////////////function onGameAttributesChange(){g_IsInGuiUpdate = true;// Don't set any attributes here, just show the changes in GUIvar mapName = g_GameAttributes.map || "";var mapSettings = g_GameAttributes.settings;// DEBUG To change?var numPlayers = (mapSettings.PlayerData ? mapSettings.PlayerData.length : MAX_PLAYERS);if (g_GameAttributes.mapType == "random")numPlayers = Math.min(numPlayers, getMaxPlayersRMS());// Update some controls for clientsif (!g_IsController){getGUIObjectByName("mapFilterText").caption = g_GameAttributes.mapFilter;var mapTypeSelection = getGUIObjectByName("mapTypeSelection");var idx = mapTypeSelection.list_data.indexOf(g_GameAttributes.mapType);getGUIObjectByName("mapTypeText").caption = mapTypeSelection.list[idx];var mapSelectionBox = getGUIObjectByName("mapSelection");mapSelectionBox.selected = mapSelectionBox.list_data.indexOf(mapName);getGUIObjectByName("mapSelectionText").caption = getMapDisplayName(mapName);var populationCapBox = getGUIObjectByName("populationCap");populationCapBox.selected = populationCapBox.list_data.indexOf(mapSettings.PopulationCap);var startingResourcesBox = getGUIObjectByName("startingResources");startingResourcesBox.selected = startingResourcesBox.list_data.indexOf(mapSettings.StartingResources);initMapNameList();}// Controls common to all map types// DEBUG To change? ToDo: Remove redundant players from g_GameAttributes.settings.playerData later! Where? When?var numPlayersSelection = getGUIObjectByName("numPlayersSelection");var players = [];for (var i = 1; i <= MAX_PLAYERS; ++i){if (!(g_GameAttributes.mapType == "random" && i > getMaxPlayersRMS()))players.push(i);}numPlayersSelection.list = players;numPlayersSelection.list_data = players;numPlayersSelection.selected = players.length - 1;var revealMap = getGUIObjectByName("revealMap");var victoryCondition = getGUIObjectByName("victoryCondition");var lockTeams = getGUIObjectByName("lockTeams");var mapSize = getGUIObjectByName("mapSize");var enableCheats = getGUIObjectByName("enableCheats");var populationCap = getGUIObjectByName("populationCap");var startingResources = getGUIObjectByName("startingResources");var numPlayersText= getGUIObjectByName("numPlayersText");var mapSizeText = getGUIObjectByName("mapSizeText");var revealMapText = getGUIObjectByName("revealMapText");var victoryConditionText = getGUIObjectByName("victoryConditionText");var lockTeamsText = getGUIObjectByName("lockTeamsText");var enableCheatsText = getGUIObjectByName("enableCheatsText");var populationCapText = getGUIObjectByName("populationCapText");var startingResourcesText = getGUIObjectByName("startingResourcesText");var sizeIdx = (g_MapSizes.tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.tiles.indexOf(mapSettings.Size) : g_MapSizes.default);var victoryIdx = (VICTORY_DATA.indexOf(mapSettings.GameType) != -1 ? VICTORY_DATA.indexOf(mapSettings.GameType) : VICTORY_DEFAULTIDX);enableCheats.checked = (g_GameAttributes.settings.CheatsEnabled === undefined || !g_GameAttributes.settings.CheatsEnabled ? false : true)enableCheatsText.caption = (enableCheats.checked ? "Yes" : "No");populationCap.selected = (POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) != -1 ? POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) : POPULATION_CAP_DEFAULTIDX);populationCapText.caption = POPULATION_CAP[populationCap.selected];startingResources.selected = (STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) != -1 ? STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) : STARTING_RESOURCES_DEFAULTIDX);startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];// Handle map type specific logicswitch (g_GameAttributes.mapType){case "random":if (g_IsController){ //HostnumPlayersSelection.selected = numPlayers - 1;numPlayersSelection.hidden = false;mapSize.hidden = false;revealMap.hidden = false;victoryCondition.hidden = false;lockTeams.hidden = false;populationCap.hidden = false;startingResources.hidden = false;numPlayersText.hidden = true;mapSizeText.hidden = true;revealMapText.hidden = true;victoryConditionText.hidden = true;lockTeamsText.hidden = true;populationCapText.hidden = true;startingResourcesText.hidden = true;// Update map previewgetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);mapSizeText.caption = "Map size:";mapSize.selected = sizeIdx;revealMapText.caption = "Reveal map:";revealMap.checked = (mapSettings.RevealMap ? true : false);victoryConditionText.caption = "Victory condition:";victoryCondition.selected = victoryIdx;lockTeamsText.caption = "Teams locked:";lockTeams.checked = (mapSettings.LockTeams ? true : false);}else{// ClientnumPlayersText.hidden = false;mapSizeText.hidden = false;revealMapText.hidden = false;victoryConditionText.hidden = false;lockTeamsText.hidden = false;populationCap.hidden = true;populationCapText.hidden = false;startingResources.hidden = true;startingResourcesText.hidden = false;// Update map previewgetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);numPlayersText.caption = numPlayers;mapSizeText.caption = g_MapSizes.names[sizeIdx];revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");victoryConditionText.caption = VICTORY_TEXT[victoryIdx];lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");}break;case "scenario":// For scenario just reflect settings for the current mapnumPlayersSelection.hidden = true;mapSize.hidden = true;revealMap.hidden = true;victoryCondition.hidden = true;lockTeams.hidden = true;numPlayersText.hidden = false;mapSizeText.hidden = false;revealMapText.hidden = false;victoryConditionText.hidden = false;lockTeamsText.hidden = false;populationCap.hidden = true;populationCapText.hidden = false;startingResources.hidden = true;startingResourcesText.hidden = false;// Update map previewgetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);numPlayersText.caption = numPlayers;mapSizeText.caption = "Default";revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");victoryConditionText.caption = VICTORY_TEXT[victoryIdx];lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");getGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;break;default:error("onGameAttributesChange: Unexpected map type '"+g_GameAttributes.mapType+"'");return;}// Display map namegetGUIObjectByName("mapInfoName").caption = getMapDisplayName(mapName);// Load the description from the map file, if there is onevar description = mapSettings.Description || "Sorry, no description available.";if (g_GameAttributes.mapFilter == "Naval Maps")description += g_NavalWarning;// Describe the number of playersvar playerString = numPlayers + " " + (numPlayers == 1 ? "player" : "players") + ". ";// DEBUG To change?for (var i = 0; i < MAX_PLAYERS; ++i){// Show only needed player slotsgetGUIObjectByName("playerBox["+i+"]").hidden = (i >= numPlayers);// Show player data or defaults as necessaryif (i < numPlayers){var pName = getGUIObjectByName("playerName["+i+"]");var pCiv = getGUIObjectByName("playerCiv["+i+"]");var pCivText = getGUIObjectByName("playerCivText["+i+"]");var pTeam = getGUIObjectByName("playerTeam["+i+"]");var pTeamText = getGUIObjectByName("playerTeamText["+i+"]");var pColor = getGUIObjectByName("playerColour["+i+"]");// Player data / defaultsvar pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[i] : {};// Common to all game typesvar color = iColorToString(getSetting(pData, pDefs, "Colour"));pColor.sprite = "colour:"+color+" 100";pName.caption = getSetting(pData, pDefs, "Name");var team = getSetting(pData, pDefs, "Team");var civ = getSetting(pData, pDefs, "Civ");// For clients or scenarios, hide some player dropdownsif (!g_IsController || g_GameAttributes.mapType == "scenario"){pCivText.hidden = false;pCiv.hidden = true;pTeamText.hidden = false;pTeam.hidden = true;// Set text valuesif (civ == "random"){pCivText.caption = "[color=\"orange\"]Random";}else{pCivText.caption = g_CivData[civ].Name;}pTeamText.caption = (team !== undefined && team >= 0) ? team+1 : "-";}else if (g_GameAttributes.mapType == "random"){pCivText.hidden = true;pCiv.hidden = false;pTeamText.hidden = true;pTeam.hidden = false;// Set dropdown valuespCiv.selected = (civ ? pCiv.list_data.indexOf(civ) : 0);pTeam.selected = (team !== undefined && team >= 0) ? team+1 : 0;}}}getGUIObjectByName("mapInfoDescription").caption = playerString + description;g_IsInGuiUpdate = false;// Game attributes include AI settings, so update the player listupdatePlayerList();}function updateGameAttributes(){if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);}else{onGameAttributesChange();}}function updatePlayerList(){g_IsInGuiUpdate = true;var hostNameList = [];var hostGuidList = [];var assignments = [];var aiAssignments = {};var noAssignment;var assignedCount = 0;for (var guid in g_PlayerAssignments){var name = g_PlayerAssignments[guid].name;var hostID = hostNameList.length;var player = g_PlayerAssignments[guid].player;hostNameList.push(name);hostGuidList.push(guid);assignments[player] = hostID;if (player != 255)assignedCount++;}// Only enable start button if we have enough assigned playersif (g_IsController)getGUIObjectByName("startGame").enabled = (assignedCount > 0);for each (var ai in g_AIs){if (ai.data.hidden){// If the map uses a hidden AI then don't hide itvar usedByMap = false;for (var i = 0; i < MAX_PLAYERS; ++i) {if (i < g_GameAttributes.settings.PlayerData.length &&g_GameAttributes.settings.PlayerData[i].AI == ai.id){usedByMap = true;}}if (!usedByMap){continue;}}// Give AI a different color so it stands outaiAssignments[ai.id] = hostNameList.length;hostNameList.push("[color=\"70 150 70 255\"]AI: " + ai.data.name);hostGuidList.push("ai:" + ai.id);}noAssignment = hostNameList.length;hostNameList.push("[color=\"140 140 140 255\"]Unassigned");hostGuidList.push("");for (var i = 0; i < MAX_PLAYERS; ++i){let playerSlot = i;let playerID = i+1; // we don't show Gaia, so first slot is ID 1var selection = assignments[playerID];var configButton = getGUIObjectByName("playerConfig["+i+"]");configButton.hidden = true;// Look for valid player slotsif (playerSlot < g_GameAttributes.settings.PlayerData.length){// If no human is assigned, look for an AI insteadif (selection === undefined){var aiId = g_GameAttributes.settings.PlayerData[playerSlot].AI;if (aiId){// Check for a valid AIif (aiId in aiAssignments)selection = aiAssignments[aiId];elsewarn("AI \""+aiId+"\" not present. Defaulting to unassigned.");}if (!selection)selection = noAssignment;// Since no human is assigned, show the AI config buttonif (g_IsController){configButton.hidden = false;configButton.onpress = function(){Engine.PushGuiPage("page_aiconfig.xml", {ais: g_AIs,id: g_GameAttributes.settings.PlayerData[playerSlot].AI,callback: function(ai) {g_GameAttributes.settings.PlayerData[playerSlot].AI = ai.id;if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);}else{updatePlayerList();}}});};}}else{// There was a human, so make sure we don't have any AI left// over in their slot, if we're in charge of the attributesif (g_IsController && g_GameAttributes.settings.PlayerData[playerSlot].AI && g_GameAttributes.settings.PlayerData[playerSlot].AI != ""){g_GameAttributes.settings.PlayerData[playerSlot].AI = "";if (g_IsNetworked){Engine.SetNetworkGameAttributes(g_GameAttributes);}}}var assignBox = getGUIObjectByName("playerAssignment["+i+"]");assignBox.list = hostNameList;assignBox.list_data = hostGuidList;if (assignBox.selected != selection){assignBox.selected = selection;}if (g_IsNetworked && g_IsController){assignBox.onselectionchange = function (){if (!g_IsInGuiUpdate){var guid = hostGuidList[this.selected];if (guid == ""){// Unassign any host from this player slotEngine.AssignNetworkPlayer(playerID, "");// Remove AI from this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = "";}else if (guid.substr(0, 3) == "ai:"){// Unassign any host from this player slotEngine.AssignNetworkPlayer(playerID, "");// Set the AI for this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = guid.substr(3);}elseswapPlayers(guid, playerSlot);Engine.SetNetworkGameAttributes(g_GameAttributes);}};}else if (!g_IsNetworked){assignBox.onselectionchange = function (){if (!g_IsInGuiUpdate){var guid = hostGuidList[this.selected];if (guid == ""){// Remove AI from this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = "";}else if (guid.substr(0, 3) == "ai:"){// Set the AI for this player slotg_GameAttributes.settings.PlayerData[playerSlot].AI = guid.substr(3);}elseswapPlayers(guid, playerSlot);updatePlayerList();}};}}}g_IsInGuiUpdate = false;}function swapPlayers(guid, newSlot){// Player slots are indexed from 0 as Gaia is omitted.var newPlayerID = newSlot + 1;var playerID = g_PlayerAssignments[guid].player;// Attempt to swap the player or AI occupying the target slot,// if any, into the slot this player is currently in.if (playerID != 255){for (var i in g_PlayerAssignments){// Move the player in the destination slot into the current slot.if (g_PlayerAssignments[i].player == newPlayerID){if (g_IsNetworked)Engine.AssignNetworkPlayer(playerID, i);elseg_PlayerAssignments[i].player = playerID;break;}}// Transfer the AI from the target slot to the current slot.g_GameAttributes.settings.PlayerData[playerID - 1].AI = g_GameAttributes.settings.PlayerData[newSlot].AI;}if (g_IsNetworked)Engine.AssignNetworkPlayer(newPlayerID, guid);elseg_PlayerAssignments[guid].player = newPlayerID;// Remove AI from this player slotg_GameAttributes.settings.PlayerData[newSlot].AI = "";}function submitChatInput(){var input = getGUIObjectByName("chatInput");var text = input.caption;if (text.length){Engine.SendNetworkChat(text);input.caption = "";}}function addChatMessage(msg){var username = escapeText(msg.username || g_PlayerAssignments[msg.guid].name);var message = escapeText(msg.text);// TODO: Maybe host should have distinct font/color?var color = "white";if (g_PlayerAssignments[msg.guid] && g_PlayerAssignments[msg.guid].player != 255){ // Valid player who has been assigned - get player colourvar player = g_PlayerAssignments[msg.guid].player - 1;var mapName = g_GameAttributes.map;var mapData = loadMapData(mapName);var mapSettings = (mapData && mapData.settings ? mapData.settings : {});var pData = mapSettings.PlayerData ? mapSettings.PlayerData[player] : {};var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[player] : {};color = iColorToString(getSetting(pData, pDefs, "Colour"));}var formatted;switch (msg.type){case "connect":formatted = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font] [color="gold"]has joined[/color]';break;case "disconnect":formatted = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font] [color="gold"]has left[/color]';break;case "message":formatted = '[font="serif-bold-13"]<[color="'+ color +'"]' + username + '[/color]>[/font] ' + message;break;default:error("Invalid chat message '" + uneval(msg) + "'");return;}g_ChatMessages.push(formatted);getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");}function toggleMoreOptions(){getGUIObjectByName("moreOptions").hidden = !getGUIObjectByName("moreOptions").hidden;}////////////////////////////////////////////////////////////////////////////////////////////////// Basic map filters API// Add a new map list filterfunction addFilter(name, filterFunc){if (filterFunc instanceof Object){ // Basic validity testvar newFilter = {};newFilter.name = name;newFilter.filter = filterFunc;g_MapFilters.push(newFilter);}else{error("Invalid map filter: "+name);}}// Get array of map filter namesfunction 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 objectfunction testFilter(name, mapSettings){for (var i = 0; i < g_MapFilters.length; ++i){if (g_MapFilters[i].name == name){ // Found filterreturn g_MapFilters[i].filter(mapSettings);}}error("Invalid map filter: "+name);return false;}// Test an array of keywords against a match array using AND logicfunction keywordTestAND(keywords, matches){if (!keywords || !matches){return false;}for (var m = 0; m < matches.length; ++m){ // Fail on not matchif (keywords.indexOf(matches[m]) == -1){return false;}}return true;}// Test an array of keywords against a match array using OR logicfunction keywordTestOR(keywords, matches){if (!keywords || !matches){return false;}for (var m = 0; m < matches.length; ++m){ // Success on matchif (keywords.indexOf(matches[m]) != -1){return true;}}return false;}ToDo:- Drop redundant players from g_GameAttributes.settings.playerData (at select map/size? Or just call selectNumPlayers() if to many players there?) Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 you still include the old mapSizeToSizeIndex(size), but don’t call it at all…a minor typo in one of the first comments: 'player linit' (just use search function to find it) Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) you still include the old mapSizeToSizeIndex(size), but don’t call it at all…a minor typo in one of the first comments:'player linit' (just use search function to find it)Removed and fixed ^^Well it's a work in progress version.Can you see why the selected number of players (in the gui and maybe somewhere else too) is not lowered when the map size is lowered and results in less players possible than selected?To reproduce:- Select map type "Random"- Select map size Giant- Select number of players 8- Lower the map size The number of players available in number of players dropdown as well as the player-slots will be lowered and the maximum possible number of players selected as expected.- Raise the map size again: Now the number of players is automatically raised so I assume there are still 8 slots filled. Not sure...http://fexor.dyndns.org/files/0ad/gamesetup/gamesetup.js Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) I really don’t know the code, where should that js file be placed?EDIT: found it. ~/.cache/0ad/mods/public/gui/gamesetup/gamesetup.jsI’ll try what I can…EDIT2: looks like a logic bug. the player number is not updated. it just updates the UI and removes the player from the UI. It does not set the actual player number variable:select 3 players, change to tiny. UI says 2 players. click start. 3 players are placed.you should call selectNumPlayers() when you have to remove a player due to map limitations. that function seems to be able to do everything needed.so:(something like this pseudo-code)if (current_player_count > max_supported_count_by_current_size)selectNumPlayers(max_supported_count_by_current_size);I just haven’t found the line where to place this. Edited February 7, 2013 by luziferius Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) I really don’t know the code, where should that js file be placed?EDIT: found it. ~/.cache/0ad/mods/public/gui/gamesetup/gamesetup.jsI’ll try what I can…I made a stupid mistake: I set the gui dropdown content in onGameAttributesChange() which is stupid. Should be done in selectMapType(), selectMap() and the point where the map size is changed (not sure where. Might still be onGameAttributesChange()...). Added changeMaxPlayers() to take care of the dropdown content..http://fexor.dyndns.org/files/0ad/gamesetup/Now i got it right. Just a fail by one somewhere (the selected number of players decrease when changing map size). Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 this one is broken…you need the placement in onGameAttributesChange() to update the UI. your current version does not Update the UI. It just needs to additionally set the player count with selectNumPlayers(). I just don’t know a sane position for this one. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) this one is broken…you need the placement in onGameAttributesChange() to update the UI. your current version does not Update the UI. It just needs to additionally set the player count with selectNumPlayers(). I just don’t know a sane position for this one.I changed it perhaps after you checked.It works for me now. The changed code is marked with "DEBUG" comments to find it. There seams to be a failed by one though in changeMaxPlayers().EDIT: changeMaxPlayers() seams to be ok, must be somewhere else. Searching...EDIT2: Oh, was ofc the function changeMaxPlayers(). Fixed.Testing welcome.http://fexor.dyndns.org/files/0ad/gamesetup/Thanks for your help luziferius!Now checking with edited RMS json... Works perfectly AFAIK ^^ Yippie!Added the json for Belgian Uplands to test and set the default to less restrictive values.Put it to:AppData\Local\0ad\cache\mods\public\maps\random Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 Tested it once(configured 6 players, changed to Tiny, the UI updated properly, raising map size kept the 2 players, raised again to 6 players, switched to Tiny, clicked on Start, got a match with 2 players)working!! Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) Wonderful!Thx much!Now adding lower player limits (though I don't really see why this is needed).Oh! There appears an error when switching to random map, scenario, random map... Fixed!http://fexor.dyndns.org/files/0ad/gamesetup/ Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) I would say change the constant MAX_PLAYERS_BY_MAP_SIZE_RMS to:const MAX_PLAYERS_BY_MAP_SIZE_RMS = [2, 2, 3, 4, 6, 8, 8];this way it exactly matches the number of players in the size description.with current settings, you can’t play with 8 players on a “Very Large (8 players)” map…orconst MAX_PLAYERS_BY_MAP_SIZE_RMS = [2, 3, 4, 5, 7, 8, 8];this way it matches number of players in the size description +1or:const MAX_PLAYERS_BY_MAP_SIZE_RMS = [4, 6, 8, 8, 8, 8, 8];that one would be very permissive and might not work with many mapsabout minimal player count: some RMS might not work with 1 or 2 players…Canyon throws an exeption with only one player…or the layout may be broken (for whatever reason)but I think one of those is a reasonable default:const MIN_PLAYERS_BY_MAP_SIZE_RMS = [1, 1, 1, 1, 1, 1, 1];const MIN_PLAYERS_BY_MAP_SIZE_RMS = [2, 2, 2, 2, 2, 2, 2];it should only be set otherwise by a RMS that needs this Edited February 7, 2013 by luziferius Quote Link to comment Share on other sites More sharing options...
FeXoR Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) I would say change the constant MAX_PLAYERS_BY_MAP_SIZE_RMS to:const MAX_PLAYERS_BY_MAP_SIZE_RMS = [2, 2, 3, 4, 6, 8, 8];this way it exactly matches the number of players in the size description.with current settings, you can’t play with 8 players on a “Very Large (8 players)” map…orconst MAX_PLAYERS_BY_MAP_SIZE_RMS = [2, 3, 4, 5, 7, 8, 8];this way it matches number of players in the size description +1or:const MAX_PLAYERS_BY_MAP_SIZE_RMS = [4, 6, 8, 8, 8, 8, 8];that one would be very permissive and might not work with many mapsabout minimal player count: some RMS might not work with 1 or 2 players…Canyon throws an exeption with only one player…or the layout may be broken (for whatever reason)but I think one of those is a reasonable default:const MIN_PLAYERS_BY_MAP_SIZE_RMS = [1, 1, 1, 1, 1, 1, 1];const MIN_PLAYERS_BY_MAP_SIZE_RMS = [2, 2, 2, 2, 2, 2, 2];it should only be set otherwise by a RMS that needs thisYes, the verion above already does that. Upper limit: [4, 6, 8, 8, 8, 8, 8] (The extreme values where for testing only)Lower caps will stay 1 by default and can then be changed by the map. Edited February 7, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
Pureon Posted February 7, 2013 Report Share Posted February 7, 2013 Great work guys Quote Link to comment Share on other sites More sharing options...
luziferius Posted February 7, 2013 Report Share Posted February 7, 2013 (edited) while you are at it…Would it be ok to either reduce the default player count to 3 or default map size to Normal for random maps?I think it’s odd that the game defaults to 4 players on “Medium (3 players)”…Either 3 players on “Medium (3 players)” (better performance wise)or 4 players on “Normal (4 players)”.BTW the link in your last post is broken… Edited February 7, 2013 by luziferius Quote Link to comment Share on other sites More sharing options...
Pureon Posted February 7, 2013 Report Share Posted February 7, 2013 while you are at it…Would it be ok to either reduce the default player count to 3 or default map size to Normal for random maps?I think it’s odd that the game defaults to 4 players on “Medium (3 players)”…Either 3 players on “Medium (3 players)” (better performance wise)or 4 players on “Normal (4 players)”.That's not a bad idea. Until the game's performance is sufficiently improved, we should probably reduce the default random map setting to 2 players on medium Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.