diff --git a/binaries/data/tools/atlas/lists.xml b/binaries/data/tools/atlas/lists.xml index f4d954cd1b..469b93ab60 100644 --- a/binaries/data/tools/atlas/lists.xml +++ b/binaries/data/tools/atlas/lists.xml @@ -46,14 +46,24 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/binaries/data/tools/atlas/scripts/common/terrain.js b/binaries/data/tools/atlas/scripts/common/terrain.js new file mode 100644 index 0000000000..d80b75c1ae --- /dev/null +++ b/binaries/data/tools/atlas/scripts/common/terrain.js @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////////// +// Terrain preview page +// +// Used by new dialog and terrain panel + +global.TerrainPreviewPage = function(panel, name, width, height) +{ + this.panel = panel; + this.name = name; + + // Size of texture preview images + this.w = width ? width : 120 + this.h = height ? height : 40; + + this.lastTerrainSelection = null; // button that was last selected, so we can undo its colouring + this.previewReloadTimer = null; +} + +global.TerrainPreviewPage.prototype = { + reloadPreviews: function() + { + this.panel.freeze(); + this.scrolled.destroyChildren(); + this.itemSizer.clear(); + + this.lastTerrainSelection = null; // clear any reference to deleted window + + var previews = Atlas.Message.GetTerrainGroupPreviews(this.name, this.w, this.h).previews; + var i = 0; + var names = []; + var allLoaded = true; + for each (var p in previews) + { + if (!p.loaded) + { + allLoaded = false; + } + + // Create a wrapped-text label (replacing '_' with ' ' so there are more wrapping opportunities) + var labelText = p.name.replace(/_/g, ' '); + var label = new wxStaticText(this.scrolled, -1, labelText, wxDefaultPosition, wxDefaultSize, wxStaticText.ALIGN_CENTER); + label.wrap(this.w); + + var imgSizer = new wxBoxSizer(wxOrientation.VERTICAL); + var button = new wxBitmapButton(this.scrolled, -1, p.imagedata); + var self = this; + button.terrainName = p.name; + button.onClicked = function() + { + Atlas.SetSelectedTexture(this.terrainName); + if (self.lastTerrainSelection) + { + self.lastTerrainSelection.backgroundColour = wxNullColour; + } + this.backgroundColour = new wxColour(255, 255, 0); + self.lastTerrainSelection = this; + }; + imgSizer.add(button, 0, wxAlignment.CENTRE); + imgSizer.add(label, 1, wxAlignment.CENTRE); + this.itemSizer.add(imgSizer, 0, wxAlignment.CENTRE | wxStretch.EXPAND); + } + this.itemSizer.layout(); + this.panel.layout(); + this.panel.thaw(); + + // If not all textures were loaded yet, run a timer to reload the previews + // every so often until they've all finished + if (allLoaded && this.previewReloadTimer) + { + this.previewReloadTimer.stop(); + this.previewReloadTimer = null; + } + else if (!allLoaded && !this.previewReloadTimer) + { + this.previewReloadTimer = new wxTimer(); + var self = this; + this.previewReloadTimer.onNotify = function() { self.reloadPreviews(); }; + this.previewReloadTimer.start(2000); + } + }, + + display: function() + { + if (this.loaded) + { + return; + } + + this.panel.sizer = new wxBoxSizer(wxOrientation.VERTICAL); + var scrolled = new wxScrolledWindow(this.panel, -1, wxDefaultPosition, wxDefaultSize, wxWindow.VSCROLL); + scrolled.setScrollRate(0, 10); + scrolled.backgroundColour = new wxColour(255, 255, 255); + this.panel.sizer.add(scrolled, 1, wxStretch.EXPAND); + + var itemSizer = new wxGridSizer(6, 4, 0); + scrolled.sizer = itemSizer; + + // Adjust the number of columns to fit in the available area + var w = this.w; + scrolled.onSize = function (evt) + { + var numCols = Math.max(1, Math.floor(evt.size.width / (w+16))); + if (itemSizer.cols != numCols) + { + itemSizer.cols = numCols; + } + }; + + this.scrolled = scrolled; + this.itemSizer = itemSizer; + this.reloadPreviews(); + + // TODO: fix keyboard navigation of the terrain previews + + this.loaded = true; + } +}; + +global.TerrainPreviewNotebook = function(window) +{ + var terrainGroups = Atlas.Message.GetTerrainGroups(); + var nb = new wxNotebook(window, -1); + window.sizer = new wxBoxSizer(wxOrientation.VERTICAL); + window.sizer.add(nb, 1, wxStretch.EXPAND); + + var pages = []; + nb.onPageChanged = function (evt) + { + pages[evt.selection].display() + evt.skip = true; + } + for each (var groupName in terrainGroups.groupNames) + { + var panel = new wxPanel(nb, -1); + var page = new global.TerrainPreviewPage(panel, groupName); + pages.push(page); + nb.addPage(panel, groupName); // TODO: use Titlecase letters + } +} diff --git a/binaries/data/tools/atlas/scripts/editorstate.js b/binaries/data/tools/atlas/scripts/editorstate.js index 6ebccffe2b..07815a9bae 100644 --- a/binaries/data/tools/atlas/scripts/editorstate.js +++ b/binaries/data/tools/atlas/scripts/editorstate.js @@ -38,7 +38,7 @@ defaults.objectSettings.onSelectionChange = function () { if (settings.player != -1) this.playerID = settings.player; this.actorSelections = settings.selections; - this.variantGroups = settings.variantgroups; + this.variantGroups = settings.variantGroups; } this.notifyObservers(); } diff --git a/binaries/data/tools/atlas/scripts/section/map.js b/binaries/data/tools/atlas/scripts/section/map.js index ba21db6097..68a7b87e2f 100644 --- a/binaries/data/tools/atlas/scripts/section/map.js +++ b/binaries/data/tools/atlas/scripts/section/map.js @@ -1,4 +1,5 @@ -function setupSimTest(window) + +function setupSimTest(window, rmsPanel) { var state = 'inactive'; // inactive, playing var speed = 0; @@ -32,7 +33,19 @@ function setupSimTest(window) function updateEnableStatus() { for (var i in buttons) + { buttons[i][3].enable = buttons[i][2](); + } + + if (state == 'playing') + { + // Disable RMS controls + rmsPanel.enable = false; + } + else + { + rmsPanel.enable = true; + } } var speeds = [ 1/8, 1, 8 ]; @@ -56,67 +69,468 @@ function setupSimTest(window) } updateEnableStatus(); window.sizer.add(sizer, 0, wxStretch.EXPAND | wxDirection.LEFT|wxDirection.RIGHT, 2); - - var dumpDisplayButton = new wxButton(window, -1, 'Display sim state'); - dumpDisplayButton.onClicked = function () - { - var state = Atlas.Message.SimStateDebugDump(false).dump; - if (state.length > 10240) // avoid giant message boxes that crash - state = state.substr(0, 10240)+"..."; - wxMessageBox(state); - }; - window.sizer.add(dumpDisplayButton); - - var dumpButton = new wxButton(window, -1, 'Dump sim state to disk'); - dumpButton.toolTip = 'Saves to sim-dump-$(TIMESTAMP).txt in working directory'; - dumpButton.onClicked = function () { - var filename = 'sim-dump-' + (new Date().getTime()) + '.txt'; - var state = Atlas.Message.SimStateDebugDump(false).dump; - var file = new wxFFile(filename, 'w'); // TODO: error check - file.write(state); - file.close(); - }; - window.sizer.add(dumpButton); - - var dumpBinButton = new wxButton(window, -1, 'Dump binary sim state to disk'); - dumpBinButton.toolTip = 'Saves to sim-dump-$(TIMESTAMP).dat in working directory'; - dumpBinButton.onClicked = function () { - var filename = 'sim-dump-' + (new Date().getTime()) + '.dat'; - var state = Atlas.Message.SimStateDebugDump(true).dump; - var file = new wxFFile(filename, 'w'); // TODO: error check - file.write(state); - file.close(); - }; - window.sizer.add(dumpBinButton); + } -function generateRMS(name) +//TODO: Would be nicer not to use an extra settings property, this is to avoid the observer data getting written to maps +// perhaps that single element can be excluded +var defaults = { + mapSettings : { + settings: { + Name: 'Untitled', + Description : '', + PlayerData : [] + } + } +}; + +var g_observer; + +// Flag if we should only notify other scripts not this one (prevents recursion) +var g_externalNotify; + +// Merges the 'defs' tree into 'obj', overwriting any old values with +// the same keys +function setDefaults(defs, obj) { - var cwd = wxFileName.cwd; - wxFileName.cwd = Atlas.GetDataDirectory(); - var ret = wxExecute([ 'rmgen.exe', name, '_atlasrm' ], wxExecFlag.SYNC); // TODO: portability - wxFileName.cwd = cwd; - if (ret == 0) - Atlas.Message.LoadMap('_atlasrm.pmp'); - else - wxMessageBox('Failed to run rmgen (error code: '+ret+')'); + if (defs instanceof Object) + { + for (var k in defs) { + if (obj instanceof Object && k in obj) + setDefaults(defs[k], obj[k]); + else + obj[k] = defs[k]; + } + } +} + +// Read civ data and player defaults +function getStartingData() +{ + // Load civilization data + if (!Atlas.State.CivData) + { + Atlas.State.CivData = []; + Atlas.State.CivNames = []; + Atlas.State.CivCodes = []; + + var dataArray = Atlas.Message.GetCivData().data; + if (dataArray) + { // parse JSON strings into objects + for (var i = 0; i < dataArray.length; ++i) + { + var civ = JSON.parse(dataArray[i]); + if (civ) + { + Atlas.State.CivData.push(civ); + Atlas.State.CivNames.push(civ.Name); + Atlas.State.CivCodes.push(civ.Code); + } + } + } + } + + // Load player default data (names, civs, colors, etc) + if (!Atlas.State.PlayerDefaults) + { + var rawData = Atlas.Message.GetPlayerDefaults().defaults; + if(rawData) + { + Atlas.State.PlayerDefaults = JSON.parse(rawData).PlayerData; + } + } +} + +function getMapSettings() +{ + // Get map settings to populate GUI + var settings = Atlas.Message.GetMapSettings().settings; + if (settings) + { + Atlas.State.mapSettings.settings = JSON.parse(settings); + } +} + +function makeObservable(obj) +{ + // If the object has already been set up as observable, don't do any more work. + // (In particular, don't delete any old observers, so they don't get lost when + // this script is reloaded.) + if (typeof obj._observers != 'undefined') + return; + + obj._observers = []; + obj.registerObserver = function (callback) { + this._observers.push(callback); + } + obj.unregisterObserver = function (callback) { + this._observers = this._observers.filter(function (o) { return o !== callback }); + } + obj.notifyObservers = function () { + for each (var o in this._observers) + o(this); + }; } function init(window) { window.sizer = new wxBoxSizer(wxOrientation.VERTICAL); - var button = new wxButton(window, -1, 'Generate empty map'); - button.onClicked = function () { Atlas.Message.GenerateMap(9); }; - window.sizer.add(button, 0, wxDirection.ALL, 2); + // Don't overwrite old data when script is hotloaded + setDefaults(defaults, Atlas.State); + + /////////////////////////////////////////////////////////////////////// + // Map setting controls + // Map name + var settingsSizer = new wxStaticBoxSizer(new wxStaticBox(window, -1, 'Map settings'), wxOrientation.VERTICAL); + var boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + boxSizer.add(new wxStaticText(window, -1, 'Name'), 0, wxAlignment.CENTER_VERTICAL); + boxSizer.add(10, 0); + var mapNameCtrl = new wxTextCtrl(window, -1, 'Untitled'); + mapNameCtrl.toolTip = "Enter a name for the map here"; + mapNameCtrl.onText = function(evt) + { + Atlas.State.mapSettings.settings.Name = evt.string; + }; + boxSizer.add(mapNameCtrl, 1); + function updateMapName() + { + mapNameCtrl.value = Atlas.State.mapSettings.settings.Name ? Atlas.State.mapSettings.settings.Name : 'Untitled'; + } + settingsSizer.add(boxSizer, 0, wxStretch.EXPAND); - var sizer = new wxBoxSizer(wxOrientation.HORIZONTAL); - var rmsFilename = new wxTextCtrl(window, -1, 'cantabrian_highlands'); - var rmsButton = new wxButton(window, -1, 'Run RMS'); - rmsButton.onClicked = function () { generateRMS(rmsFilename.value) } - sizer.add(rmsFilename, 1); - sizer.add(rmsButton, 0); - window.sizer.add(sizer, 0, wxStretch.EXPAND | wxDirection.ALL, 2); + settingsSizer.add(5, 5, 0); // Add space - setupSimTest(window); + // Map description + boxSizer = new wxBoxSizer(wxOrientation.VERTICAL); + boxSizer.add(new wxStaticText(window, -1, 'Description'), wxAlignment.RIGHT); + var mapDescCtrl = new wxTextCtrl(window, -1, '', wxDefaultPosition, new wxSize(-1, 100), wxTextCtrl.MULTILINE); + mapDescCtrl.toolTip = "Enter an interesting description for the map here"; + mapDescCtrl.onText = function(evt) + { + Atlas.State.mapSettings.settings.Description = evt.string; + }; + boxSizer.add(mapDescCtrl, 0, wxStretch.EXPAND); + function updateMapDesc() + { + mapDescCtrl.value = Atlas.State.mapSettings.settings.Description ? Atlas.State.mapSettings.settings.Description : ''; + } + settingsSizer.add(boxSizer, 0, wxStretch.EXPAND); + + settingsSizer.add(5, 5, 0); // Add space + + // Reveal map + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + boxSizer.add(new wxStaticText(window, -1, 'Reveal map'), wxAlignment.LEFT); + boxSizer.add(10, 0); + var revealMapCtrl = new wxCheckBox(window, -1, ''); + revealMapCtrl.toolTip = 'If checked, players will see the whole map explored and their enemies'; + revealMapCtrl.onCheckBox = function(evt) + { + Atlas.State.mapSettings.settings.RevealMap = evt.checked; + }; + boxSizer.add(revealMapCtrl); + function updateRevealMap() + { // Defaults to false if setting doesn't exist + revealMapCtrl.value = Atlas.State.mapSettings.settings.RevealMap; + } + settingsSizer.add(boxSizer, 0, wxStretch.EXPAND); + + settingsSizer.add(5, 5, 0); // Add space + + // Game type + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + boxSizer.add(new wxStaticText(window, -1, 'Game type'), 0, wxAlignment.CENTER_VERTICAL); + boxSizer.add(10, 0); + var gameTypes = ["conquest", "endless"]; + var gameTypeCtrl = new wxChoice(window, -1, wxDefaultPosition, new wxSize(100,-1), gameTypes); + gameTypeCtrl.toolTip = 'Select the game type / victory conditions'; + gameTypeCtrl.onChoice = function (evt) + { + if (evt.selection != -1) + { + Atlas.State.mapSettings.settings.GameType = evt.string; + } + }; + boxSizer.add(gameTypeCtrl); + function updateGameType() + { + var idx = Atlas.State.mapSettings.settings.GameType ? gameTypes.indexOf(Atlas.State.mapSettings.settings.GameType) : 0; + gameTypeCtrl.selection = idx; + } + settingsSizer.add(boxSizer, 0, wxStretch.EXPAND); + + settingsSizer.add(5, 5, 0); // Add space + + // Number of players + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + boxSizer.add(new wxStaticText(window, -1, 'Number of Players'), 0, wxAlignment.CENTER_VERTICAL); + boxSizer.add(10, 0); + var numPlayers = new wxSpinCtrl(window, -1, '8', wxDefaultPosition, new wxSize(40, -1)); + numPlayers.toolTip = 'Select the number of players on this map'; + numPlayers.setRange(1, 8); + numPlayers.onSpinCtrl = function(evt) + { + // Adjust player data accordingly + if (!Atlas.State.mapSettings.settings.PlayerData) + Atlas.State.mapSettings.settings.PlayerData = []; + + Atlas.State.numPlayers = evt.position; + var curPlayers = Atlas.State.mapSettings.settings.PlayerData.length; + + if (curPlayers < evt.position) + { // Add extra players from default + for (var i = curPlayers; i < evt.position; ++i) + { + Atlas.State.mapSettings.settings.PlayerData.push(Atlas.State.PlayerDefaults[i]); + } + } + else + { //Remove extra players + Atlas.State.mapSettings.settings.PlayerData = Atlas.State.mapSettings.settings.PlayerData.slice(0, evt.position); + } + + g_externalNotify = true; + Atlas.State.mapSettings.notifyObservers(); + g_externalNotify = false; + }; + boxSizer.add(numPlayers); + function updateNumPlayers() + { + numPlayers.value = Atlas.State.mapSettings.settings.PlayerData ? Atlas.State.mapSettings.settings.PlayerData.length : 8; + } + settingsSizer.add(boxSizer, 0, wxStretch.EXPAND); + + window.sizer.add(settingsSizer, 0, wxStretch.EXPAND | wxDirection.LEFT|wxDirection.RIGHT, 2); + + /////////////////////////////////////////////////////////////////////// + // Keyword list + + var keywordSizer = new wxStaticBoxSizer(new wxStaticBox(window, -1, 'Keywords'), wxOrientation.VERTICAL); + var keywords = ["demo", "hidden"]; + var keywordCtrl = new wxListBox(window, -1, wxDefaultPosition, wxDefaultSize, keywords, wxListBox.MULTIPLE); + keywordCtrl.toolTip = 'Select keyword(s) to apply to this map'; + keywordCtrl.onListBox = function() + { + var kws = []; + // Convert selections to keywords array + var selections = this.selections; + for (var i = 0; i < selections.length; ++i) + { + kws.push(keywords[selections[i]]); + } + Atlas.State.mapSettings.settings.Keywords = kws; + }; + function updateKeywords() + { + var kws = Atlas.State.mapSettings.settings.Keywords; + if (kws) + { + for (var i = 0; i < kws.length; ++i) + { + var idx = keywords.indexOf(kws[i]); + if (idx != -1) + { + // TODO: There doesn't appear to be a way to set selections + } + else + { // New keyword, add to list + keywordCtrl.insertItems([kws[i]]); + } + } + } + } + + keywordSizer.add(keywordCtrl, 0, wxStretch.EXPAND); + + window.sizer.add(keywordSizer, 0, wxStretch.EXPAND | wxDirection.LEFT|wxDirection.RIGHT, 2); + + /////////////////////////////////////////////////////////////////////// + // Random map controls + var rmsPanel = new wxPanel(window, -1); + var rmsSizer = new wxStaticBoxSizer(new wxStaticBox(rmsPanel, -1, 'Random map'), wxOrientation.VERTICAL); + + var scriptNames = []; + var scriptData = []; + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + var rmsChoice = new wxChoice(rmsPanel, -1, wxDefaultPosition, wxDefaultSize, scriptNames); + rmsChoice.toolTip = "Select the random map script to run"; + function loadScriptChoices() + { + // Reload RMS data + scriptNames = []; + scriptData = []; + + // Get array of RMS data + var rawData = Atlas.Message.GetRMSData().data; + for (var i = 0; i < rawData.length; ++i) + { + // Parse JSON strings to objects + var data = JSON.parse(rawData[i]); + if (data && data.settings) + { + scriptData.push(data); + scriptNames.push(data.settings.Name); + } + } + + // Add script names to choice control + rmsChoice.clear(); + rmsChoice.append(scriptNames); + rmsChoice.selection = 0; + } + boxSizer.add(rmsChoice, 1, wxAlignment.CENTER_VERTICAL); + boxSizer.add(5, 0); + var rmsReload = new wxButton(rmsPanel, -1, 'R', wxDefaultPosition, new wxSize(20, -1)); + rmsReload.toolTip = 'Click to refresh random map list'; + rmsReload.onClicked = function() + { + loadScriptChoices(); + }; + boxSizer.add(rmsReload, 0, wxAlignment.CENTER_VERTICAL); + rmsSizer.add(boxSizer, 0, wxStretch.EXPAND | wxDirection.ALL, 2); + + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + boxSizer.add(new wxStaticText(rmsPanel, -1, 'Map size'), 0, wxAlignment.CENTER_VERTICAL); + boxSizer.add(10, 0); + // TODO: Get this data from single location (currently specified here, Atlas\lists.xml, and game setup) + var sizeNames = ["Tiny", "Small", "Medium", "Normal", "Large", "Very Large", "Giant"]; + var sizePatches = [8, 12, 16, 20, 24, 28, 32]; + var sizeChoice = new wxChoice(rmsPanel, -1, wxDefaultPosition, wxDefaultSize, sizeNames); + var numChoices = sizeNames.length; + sizeChoice.toolTip = 'Select the desired map size\n'+sizeNames[0]+' = '+sizePatches[0]+' patches, '+sizeNames[numChoices-1]+' = '+sizePatches[numChoices-1]+' patches'; + sizeChoice.selection = 0; + boxSizer.add(sizeChoice, 1); + rmsSizer.add(boxSizer, 0, wxStretch.EXPAND | wxDirection.ALL, 2); + + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + var generateBtn = new wxButton(rmsPanel, -1, 'Generate'); + generateBtn.toolTip = 'Generate random map using selected script'; + generateBtn.onClicked = function () + { + var selection = rmsChoice.selection; + if (selection != -1) + { + var RMSData = scriptData[selection].settings; + if (RMSData) + { + if (useRandomCtrl.value) + { // Generate random seed + generateRandomSeed(); + } + + // Base terrains must be array + var terrainArray = []; + if (RMSData.BaseTerrain instanceof Array) + { + terrainArray = RMSData.BaseTerrain; + } + else + { // Add string to array + terrainArray.push(RMSData.BaseTerrain); + } + + // Stringify player data + var pDataStr = JSON.stringify(Atlas.State.mapSettings.settings.PlayerData); + + // Generate map + var ret = Atlas.Message.GenerateMap( + RMSData.Script, + sizePatches[sizeChoice.selection], + Atlas.State.Seed ? Atlas.State.Seed : 0, + terrainArray, + RMSData.BaseHeight, + pDataStr + ); + + // Check for error + if (ret.status < 0) + { + wxMessageBox("Random map script '"+RMSData.Script+"' failed. Loading blank map."); + + Atlas.Message.LoadMap("_default"); + } + Atlas.State.mapSettings.notifyObservers(); + } + } + }; + boxSizer.add(generateBtn, 0); + boxSizer.add(5, 0); + boxSizer.add(new wxStaticText(rmsPanel, -1, 'Random seed'), 0, wxAlignment.CENTER_VERTICAL); + boxSizer.add(5, 0); + var useRandomCtrl = new wxCheckBox(rmsPanel, -1, ''); + useRandomCtrl.toolTip = 'Always generate a new random seed'; + useRandomCtrl.value = true; + boxSizer.add(useRandomCtrl, 0, wxAlignment.CENTER_VERTICAL); + rmsSizer.add(boxSizer, 0, wxStretch.EXPAND | wxDirection.ALL, 2); + + boxSizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + boxSizer.add(new wxStaticText(rmsPanel, -1, 'Seed'), 0, wxAlignment.CENTER_VERTICAL); + boxSizer.add(10, 0); + var seedCtrl = new wxTextCtrl(rmsPanel, -1, '', wxDefaultPosition, new wxSize(60,-1)); + seedCtrl.toolTip = 'Enter a numeric seed value here'; + seedCtrl.onText = function() + { + var num = parseInt(this.value, 10); + if (!isNaN(num)) + { + Atlas.State.Seed = num; + } + else + { + // TODO: Can allow text by hashing it into a seed value - for fun? + } + }; + boxSizer.add(seedCtrl, 1); + function generateRandomSeed() + { + seedCtrl.value = Math.floor(Math.random() * 2147483648)+ 1; + } + rmsSizer.add(boxSizer, 0, wxStretch.EXPAND | wxDirection.ALL, 2); + + // TODO: Possibly have controls for base height + terrain to override RMS + + rmsPanel.sizer = rmsSizer; + window.sizer.add(rmsPanel, 0, wxStretch.EXPAND | wxDirection.LEFT|wxDirection.RIGHT, 2); + + /////////////////////////////////////////////////////////////////////// + // Simulation controls + setupSimTest(window, rmsPanel); + + + // Initial seed + seedCtrl.value = 0; + + g_observer = function() + { + if (!g_externalNotify) + { + // If we don't have civ data or player defaults yet, get those + getStartingData(); + + // Load map settings from engine + getMapSettings(); + + // Load RMS names from engine + loadScriptChoices(); + + // Update UI controls + updateMapName(); + updateMapDesc(); + updateRevealMap(); + updateGameType(); + updateNumPlayers(); + updateKeywords(); + } + } + + // Set up observers (so that this script can be notified when map data is loaded) + makeObservable(Atlas.State.mapSettings); + + Atlas.State.mapSettings.registerObserver(g_observer); +} + +function deinit() +{ + Atlas.State.mapSettings.unregisterObserver(g_observer); } diff --git a/binaries/data/tools/atlas/scripts/section/terrain.js b/binaries/data/tools/atlas/scripts/section/terrain.js index 95c2553dd6..79cd3c9a72 100644 --- a/binaries/data/tools/atlas/scripts/section/terrain.js +++ b/binaries/data/tools/atlas/scripts/section/terrain.js @@ -55,111 +55,6 @@ var brush = { } }; -var lastTerrainSelection = null; // button that was last selected, so we can undo its colouring -function onTerrainSelect() -{ - Atlas.SetSelectedTexture(this.terrainName); - if (lastTerrainSelection) - lastTerrainSelection.backgroundColour = wxNullColour; - this.backgroundColour = new wxColour(255, 255, 0); - lastTerrainSelection = this; -} - -function TerrainPreviewPage(panel, name) -{ - this.panel = panel; - this.name = name; - - // Size of texture preview images - this.w = 120 - this.h = 40; - - this.previewReloadTimer = null; -} - -TerrainPreviewPage.prototype = { - reloadPreviews: function() { - this.panel.freeze(); - this.scrolled.destroyChildren(); - this.itemSizer.clear(); - - lastTerrainSelection = null; // clear any reference to deleted window - - // TODO: Do something clever like load the preview images asynchronously, - // to avoid the annoying freeze when switching tabs - var previews = Atlas.Message.GetTerrainGroupPreviews(this.name, this.w, this.h).previews; - var i = 0; - var names = []; - var allLoaded = true; - for each (var p in previews) - { - if (!p.loaded) - allLoaded = false; - - // Create a wrapped-text label (replacing '_' with ' ' so there are more wrapping opportunities) - var labelText = p.name.replace(/_/g, ' '); - var label = new wxStaticText(this.scrolled, -1, labelText, wxDefaultPosition, wxDefaultSize, wxStaticText.ALIGN_CENTER); - label.wrap(this.w); - - var imgSizer = new wxBoxSizer(wxOrientation.VERTICAL); - var button = new wxBitmapButton(this.scrolled, -1, p.imagedata); - button.terrainName = p.name; - button.onClicked = onTerrainSelect; - imgSizer.add(button, 0, wxAlignment.CENTRE); - imgSizer.add(label, 1, wxAlignment.CENTRE); - this.itemSizer.add(imgSizer, 0, wxAlignment.CENTRE | wxStretch.EXPAND); - } - this.itemSizer.layout(); - this.panel.layout(); - this.panel.thaw(); - - // If not all textures were loaded yet, run a timer to reload the previews - // every so often until they've all finished - if (allLoaded && this.previewReloadTimer) - { - this.previewReloadTimer.stop(); - this.previewReloadTimer = null; - } - else if (!allLoaded && !this.previewReloadTimer) - { - this.previewReloadTimer = new wxTimer(); - var self = this; - this.previewReloadTimer.onNotify = function() { self.reloadPreviews(); }; - this.previewReloadTimer.start(2000); - } - }, - - display: function() { - if (this.loaded) - return; - - this.panel.sizer = new wxBoxSizer(wxOrientation.VERTICAL); - var scrolled = new wxScrolledWindow(this.panel, -1, wxDefaultPosition, wxDefaultSize, wxWindow.VSCROLL); - scrolled.setScrollRate(0, 10); - scrolled.backgroundColour = new wxColour(255, 255, 255); - this.panel.sizer.add(scrolled, 1, wxStretch.EXPAND); - - var itemSizer = new wxGridSizer(6, 4, 0); - scrolled.sizer = itemSizer; - - // Adjust the number of columns to fit in the available area - var w = this.w; - scrolled.onSize = function (evt) { - var numCols = Math.max(1, Math.floor(evt.size.width / (w+16))); - if (itemSizer.cols != numCols) - itemSizer.cols = numCols; - }; - - this.scrolled = scrolled; - this.itemSizer = itemSizer; - this.reloadPreviews(); - - // TODO: fix keyboard navigation of the terrain previews - - this.loaded = true; - } -}; - function init(window, bottomWindow) { window.sizer = new wxBoxSizer(wxOrientation.VERTICAL); @@ -256,7 +151,7 @@ function init(window, bottomWindow) visualiseSizer.add(visualiseSettingsSizer); visualiseSettingsSizer.add(new wxStaticText(window, -1, 'Passability'), 0, wxAlignment.RIGHT); - var passabilityClasses = Atlas.Message.GetTerrainPassabilityClasses().classnames; + var passabilityClasses = Atlas.Message.GetTerrainPassabilityClasses().classNames; var passabilitySelector = new wxChoice(window, -1, wxDefaultPosition, wxDefaultSize, ["(none)"].concat(passabilityClasses) ); @@ -287,11 +182,11 @@ function init(window, bottomWindow) pages[evt.selection].display() evt.skip = true; } - for each (var groupname in terrainGroups.groupnames) + for each (var groupName in terrainGroups.groupNames) { var panel = new wxPanel(nb, -1); - var page = new TerrainPreviewPage(panel, groupname); + var page = new global.TerrainPreviewPage(panel, groupName); pages.push(page); - nb.addPage(panel, groupname); // TODO: use Titlecase letters + nb.addPage(panel, groupName); // TODO: use Titlecase letters } } diff --git a/binaries/data/tools/atlas/scripts/terrainpreview.js b/binaries/data/tools/atlas/scripts/terrainpreview.js new file mode 100644 index 0000000000..291205e1d1 --- /dev/null +++ b/binaries/data/tools/atlas/scripts/terrainpreview.js @@ -0,0 +1,21 @@ + +function init(window) +{ + var terrainGroups = Atlas.Message.GetTerrainGroups(); + var nb = new wxNotebook(window, -1); + window.sizer = new wxBoxSizer(wxOrientation.VERTICAL); + window.sizer.add(nb, 1, wxStretch.EXPAND); + + var pages = []; + nb.onPageChanged = function (evt) { + pages[evt.selection].display() + evt.skip = true; + } + for each (var groupName in terrainGroups.groupNames) + { + var panel = new wxPanel(nb, -1); + var page = new global.TerrainPreviewPage(panel, groupName); + pages.push(page); + nb.addPage(panel, groupName); // TODO: use Titlecase letters + } +} diff --git a/build/premake/premake.lua b/build/premake/premake.lua index e0415c7a5b..a48d05d64f 100644 --- a/build/premake/premake.lua +++ b/build/premake/premake.lua @@ -811,6 +811,7 @@ function setup_atlas_packages() "CustomControls/EditableListCtrl", "CustomControls/FileHistory", "CustomControls/HighResTimer", + "CustomControls/NewDialog", "CustomControls/SnapSplitterWindow", "CustomControls/VirtualDirTreeCtrl", "CustomControls/Windows", @@ -822,9 +823,6 @@ function setup_atlas_packages() "ScenarioEditor/Sections/Common", "ScenarioEditor/Sections/Cinematic", "ScenarioEditor/Sections/Environment", - "ScenarioEditor/Sections/Map", - "ScenarioEditor/Sections/Object", - "ScenarioEditor/Sections/Terrain", "ScenarioEditor/Sections/Trigger", "ScenarioEditor/Tools", "ScenarioEditor/Tools/Common", diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index c646e0a60c..77df93487f 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -52,7 +52,6 @@ #include "renderer/Renderer.h" #include "renderer/WaterManager.h" #include "scripting/ScriptableObject.h" -#include "simulation/LOSManager.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpPosition.h" #include "simulation2/components/ICmpRangeManager.h" diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 760b8e9076..707ff72d4f 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -517,3 +517,104 @@ std::string CSimulation2::GenerateSchema() { return m->m_ComponentManager.GenerateSchema(); } + +std::vector CSimulation2::GetRMSData() +{ + VfsPath path(L"maps/random/"); + VfsPaths pathnames; + + std::vector data; + + // Find all ../maps/random/*.json + LibError ret = fs_util::GetPathnames(g_VFS, path, L"*.json", pathnames); + if (ret == INFO::OK) + { + for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it) + { + // Load JSON file + CVFSFile file; + PSRETURN ret = file.Load(g_VFS, *it); + if (ret != PSRETURN_OK) + { + LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret)); + } + else + { + data.push_back(std::string(file.GetBuffer(), file.GetBuffer() + file.GetBufferSize())); + } + } + } + else + { + // Some error reading directory + wchar_t error[200]; + LOGERROR(L"Error reading directory '%ls': %hs", path.string().c_str(), error_description_r(ret, error, ARRAY_SIZE(error))); + } + + return data; +} + +std::vector CSimulation2::GetCivData() +{ + VfsPath path(L"civs/"); + VfsPaths pathnames; + + std::vector data; + + // Load all JSON files in civs directory + LibError ret = fs_util::GetPathnames(g_VFS, path, L"*.json", pathnames); + if (ret == INFO::OK) + { + for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it) + { + // Load JSON file + CVFSFile file; + PSRETURN ret = file.Load(g_VFS, *it); + if (ret != PSRETURN_OK) + { + LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret)); + } + else + { + data.push_back(std::string(file.GetBuffer(), file.GetBuffer() + file.GetBufferSize())); + } + } + } + else + { + // Some error reading directory + wchar_t error[200]; + LOGERROR(L"Error reading directory '%ls': %hs", path.string().c_str(), error_description_r(ret, error, ARRAY_SIZE(error))); + } + + // Convert from vector to array and stringify + return data; +} + +std::string CSimulation2::GetPlayerDefaults() +{ + VfsPath path = VfsPath(L"simulation/data/player_defaults.json"); + + std::string data; + + if (!VfsFileExists(g_VFS, path)) + { + LOGERROR(L"File '%ls' does not exist", path.string().c_str()); + } + else + { + // Load JSON file + CVFSFile file; + PSRETURN ret = file.Load(g_VFS, path); + if (ret != PSRETURN_OK) + { + LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret)); + } + else + { + data = std::string(file.GetBuffer(), file.GetBuffer() + file.GetBufferSize()); + } + } + + return data; +} diff --git a/source/simulation2/Simulation2.h b/source/simulation2/Simulation2.h index 0205f39a8c..b9ce02eaaa 100644 --- a/source/simulation2/Simulation2.h +++ b/source/simulation2/Simulation2.h @@ -202,6 +202,30 @@ public: std::string GenerateSchema(); + ///////////////////////////////////////////////////////////////////////////// + // Some functions for Atlas UI to be able to access VFS data + + /** + * Get random map script data + * + * @return vector of strings containing JSON format data + */ + std::vector GetRMSData(); + + /** + * Get civilization data + * + * @return vector of strings containing JSON format data + */ + std::vector GetCivData(); + + /** + * Get player default data + * + * @return string containing JSON format data + */ + std::string GetPlayerDefaults(); + private: CSimulation2Impl* m; diff --git a/source/tools/atlas/AtlasScript/ScriptInterface.cpp b/source/tools/atlas/AtlasScript/ScriptInterface.cpp index a98b42efbe..58fa4e8fa8 100644 --- a/source/tools/atlas/AtlasScript/ScriptInterface.cpp +++ b/source/tools/atlas/AtlasScript/ScriptInterface.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -259,9 +259,13 @@ namespace template<> struct ToJSVal { - static jsval Convert(JSContext* WXUNUSED(cx), const size_t& val) + static jsval Convert(JSContext* cx, const size_t& val) { - return INT_TO_JSVAL(val); + if (val <= JSVAL_INT_MAX) + return INT_TO_JSVAL(val); + jsval rval = JSVAL_VOID; + JS_NewNumberValue(cx, val, &rval); // ignore return value + return rval; } }; @@ -295,6 +299,17 @@ namespace } }; + template<> struct ToJSVal + { + static jsval Convert(JSContext* cx, const std::string& val) + { + JSString* str = JS_NewStringCopyN(cx, val.c_str(), val.length()); + if (str) + return STRING_TO_JSVAL(str); + return JSVAL_VOID; + } + }; + //////////////////////////////////////////////////////////////// // wxJS types: @@ -388,9 +403,9 @@ namespace JS_DefineProperty(cx, obj, "loaded", ToJSVal::Convert(cx, val.loaded), NULL, NULL, JSPROP_ENUMERATE); - unsigned char* buf = (unsigned char*)(malloc(val.imagedata.GetSize())); - memcpy(buf, val.imagedata.GetBuffer(), val.imagedata.GetSize()); - jsval bmp = wxjs::gui::Bitmap::CreateObject(cx, new wxBitmap (wxImage(val.imagewidth, val.imageheight, buf))); + unsigned char* buf = (unsigned char*)(malloc(val.imageData.GetSize())); + memcpy(buf, val.imageData.GetBuffer(), val.imageData.GetSize()); + jsval bmp = wxjs::gui::Bitmap::CreateObject(cx, new wxBitmap (wxImage(val.imageWidth, val.imageHeight, buf))); JS_DefineProperty(cx, obj, "imagedata", bmp, NULL, NULL, JSPROP_ENUMERATE); return OBJECT_TO_JSVAL(obj); @@ -418,7 +433,7 @@ namespace if (! obj) return JSVAL_VOID; JS_DefineProperty(cx, obj, "player", ToJSVal::Convert(cx, val.player), NULL, NULL, JSPROP_ENUMERATE); JS_DefineProperty(cx, obj, "selections", ToJSVal >::Convert(cx, *val.selections), NULL, NULL, JSPROP_ENUMERATE); - JS_DefineProperty(cx, obj, "variantgroups", ToJSVal > >::Convert(cx, *val.variantgroups), NULL, NULL, JSPROP_ENUMERATE); + JS_DefineProperty(cx, obj, "variantgroups", ToJSVal > >::Convert(cx, *val.variantGroups), NULL, NULL, JSPROP_ENUMERATE); return OBJECT_TO_JSVAL(obj); } }; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index f66b52ceb9..6a59117928 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -33,6 +33,7 @@ #include "CustomControls/HighResTimer/HighResTimer.h" #include "CustomControls/Buttons/ToolButton.h" #include "CustomControls/Canvas/Canvas.h" +#include "CustomControls/NewDialog/NewDialog.h" #include "GameInterface/MessagePasser.h" #include "GameInterface/Messages.h" @@ -301,7 +302,7 @@ enum { ID_Quit = 1, -// ID_New, + ID_New, ID_Open, ID_Save, ID_SaveAs, @@ -313,6 +314,8 @@ enum ID_CameraReset, ID_RenderPathFixed, ID_RenderPathShader, + ID_DumpState, + ID_DumpBinaryState, ID_Toolbar // must be last in the list }; @@ -321,7 +324,7 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame) EVT_CLOSE(ScenarioEditor::OnClose) EVT_TIMER(wxID_ANY, ScenarioEditor::OnTimer) -// EVT_MENU(ID_New, ScenarioEditor::OnNew) + EVT_MENU(ID_New, ScenarioEditor::OnNew) EVT_MENU(ID_Open, ScenarioEditor::OnOpen) EVT_MENU(ID_Save, ScenarioEditor::OnSave) EVT_MENU(ID_SaveAs, ScenarioEditor::OnSaveAs) @@ -336,6 +339,8 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame) EVT_MENU(ID_Screenshot, ScenarioEditor::OnScreenshot) EVT_MENU(ID_JavaScript, ScenarioEditor::OnJavaScript) EVT_MENU(ID_CameraReset, ScenarioEditor::OnCameraReset) + EVT_MENU(ID_DumpState, ScenarioEditor::OnDumpState) + EVT_MENU(ID_DumpBinaryState, ScenarioEditor::OnDumpState) EVT_MENU(ID_RenderPathFixed, ScenarioEditor::OnRenderPath) EVT_MENU(ID_RenderPathShader, ScenarioEditor::OnRenderPath) @@ -425,10 +430,36 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac wxFFile file (filename.GetFullPath()); wxString script; if (! file.ReadAll(&script)) + { wxLogError(_("Failed to read script")); + } GetScriptInterface().LoadScript(filename.GetFullName(), script); } + // Load common scripts + const wxString commonPath(_T("tools/atlas/scripts/common/")); + wxFileName filename(commonPath, wxPATH_UNIX); + filename.MakeAbsolute(Datafile::GetDataDirectory()); + wxArrayString filenames; + if (wxDir::GetAllFiles(filename.GetFullPath(), &filenames, _T("*.js")) > 0) + { + for (size_t i = 0; i < filenames.GetCount(); ++i) + { + wxFFile file (filenames[i]); + wxString script; + if (! file.ReadAll(&script)) + { + wxLogError(_("Failed to read script")); + } + GetScriptInterface().LoadScript(filename.GetFullName(), script); + } + } + else + { + wxLogError(_("Failed to read common scripts directory")); + } + + // Initialise things that rely on scripts m_ObjectSettings.Init(AtlasMessage::eRenderView::GAME); @@ -452,7 +483,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac wxMenu *menuFile = new wxMenu; menuBar->Append(menuFile, _("&File")); { -// menuFile->Append(ID_New, _("&New")); + menuFile->Append(ID_New, _("&New...")); menuFile->Append(ID_Open, _("&Open...")); menuFile->Append(ID_Save, _("&Save")); menuFile->Append(ID_SaveAs, _("Save &As...")); @@ -485,6 +516,11 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac menuMisc->Append(ID_JavaScript, _("&JS console")); menuMisc->Append(ID_CameraReset, _("&Reset camera")); + wxMenu *menuSS = new wxMenu; + menuMisc->AppendSubMenu(menuSS, _("Si&mulation state")); + menuSS->Append(ID_DumpState, _("&Dump to disk")); + menuSS->Append(ID_DumpBinaryState, _("Dump &binary to disk")); + wxMenu *menuRP = new wxMenu; menuMisc->AppendSubMenu(menuRP, _("Render &path")); menuRP->Append(ID_RenderPathFixed, _("&Fixed function")); @@ -554,7 +590,13 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac // Start with a blank map (so that the editor can assume there's always // a valid map loaded) - POST_MESSAGE(GenerateMap, (9)); + POST_MESSAGE(LoadMap, (_T("_default"))); + + // Wait for blank map + qry.Post(); + + // Notify UI scripts that map settings have been loaded + m_ScriptInterface.Eval(_T("Atlas.State.mapSettings.notifyObservers()")); POST_MESSAGE(RenderEnable, (eRenderView::GAME)); @@ -640,6 +682,51 @@ void ScenarioEditor::OnRedo(wxCommandEvent&) ////////////////////////////////////////////////////////////////////////// +void ScenarioEditor::OnNew(wxCommandEvent& WXUNUSED(event)) +{ + NewDialog dlg(NULL, _("Create new map"), wxSize(600, 400), *this); + + if(dlg.ShowModal() == wxID_OK) + { + wxBusyInfo busy(_("Creating blank map")); + + // Generate new blank map + size_t patches = dlg.GetSelectedSize(); + size_t height = dlg.GetBaseHeight(); + + // Get terrain texture + // TODO: Support choosing multiple textures + std::vector textures; + std::wstring baseTexture(g_SelectedTexture.wc_str()); + textures.push_back(baseTexture); + + // Get player data + std::string pData; + m_ScriptInterface.Eval(_T("JSON.stringify(Atlas.State.mapSettings.settings.PlayerData)"), pData); + + // Generate map + // Script name, size (patches), seed, base terrain(s), base height, player data + qGenerateMap qry(L"blank.js", patches, 0, textures, height, pData); + + // Wait for map generation to finish + qry.Post(); + + if (qry.status < 0) + { // Map generation failed + wxMessageDialog msgDlg(NULL, _T("Random map script 'blank.js'. Loading blank map."), _T("Error"), wxICON_ERROR); + + qPing pingQry; + POST_MESSAGE(LoadMap, (_T("_default"))); + + // Wait for blank map + pingQry.Post(); + } + + // Notify UI scripts that map settings have been loaded + m_ScriptInterface.Eval(_T("Atlas.State.mapSettings.notifyObservers()")); + } +} + void ScenarioEditor::OpenFile(const wxString& name) { wxBusyInfo busy(_("Loading map")); @@ -661,6 +748,9 @@ void ScenarioEditor::OpenFile(const wxString& name) qPing qry; qry.Post(); + // Notify UI scripts that map settings have been loaded + m_ScriptInterface.Eval(_T("Atlas.State.mapSettings.notifyObservers()")); + // TODO: Make this a non-undoable command } @@ -687,15 +777,25 @@ void ScenarioEditor::OnOpen(wxCommandEvent& WXUNUSED(event)) void ScenarioEditor::OnMRUFile(wxCommandEvent& event) { - wxString file (m_FileHistory.GetHistoryFile(event.GetId() - wxID_FILE1)); - if (file.Len()) - OpenFile(file); + wxString filename(m_FileHistory.GetHistoryFile(event.GetId() - wxID_FILE1)); + if (filename.Len()) + { + OpenFile(filename); + } + else + { //Remove from MRU + m_FileHistory.RemoveFileFromHistory(event.GetId() - wxID_FILE1); + wxMessageDialog msgDlg(NULL, _T("File '/mods/*/maps/scenarios/")+filename + _T("' does not exist!"), _T("Error"), wxICON_ERROR); + msgDlg.ShowModal(); + } } void ScenarioEditor::OnSave(wxCommandEvent& event) { if (m_OpenFilename.IsEmpty()) + { OnSaveAs(event); + } else { wxBusyInfo busy(_("Saving map")); @@ -705,11 +805,22 @@ void ScenarioEditor::OnSave(wxCommandEvent& event) // the preview units.) m_ToolManager.SetCurrentTool(_T("")); + qPing qry; + + // Save map settings + std::string settings; + if (m_ScriptInterface.Eval(_T("JSON.stringify(Atlas.State.mapSettings.settings)"), settings)) + { + POST_MESSAGE(SetMapSettings, (settings)); + + // Wait for it to finish saving + qry.Post(); + } + std::wstring map = m_OpenFilename.c_str(); POST_MESSAGE(SaveMap, (map)); // Wait for it to finish saving - qPing qry; qry.Post(); } } @@ -727,6 +838,18 @@ void ScenarioEditor::OnSaveAs(wxCommandEvent& WXUNUSED(event)) m_ToolManager.SetCurrentTool(_T("")); + qPing qry; + + // Save map settings + std::string settings; + if (m_ScriptInterface.Eval(_T("JSON.stringify(Atlas.State.mapSettings.settings)"), settings)) + { + POST_MESSAGE(SetMapSettings, (settings)); + + // Wait for it to finish saving + qry.Post(); + } + // TODO: Work when the map is not in .../maps/scenarios/ std::wstring map = dlg.GetFilename().c_str(); POST_MESSAGE(SaveMap, (map)); @@ -734,7 +857,6 @@ void ScenarioEditor::OnSaveAs(wxCommandEvent& WXUNUSED(event)) SetOpenFilename(dlg.GetFilename()); // Wait for it to finish saving - qPing qry; qry.Post(); } } @@ -793,6 +915,42 @@ void ScenarioEditor::OnRenderPath(wxCommandEvent& event) } } +void ScenarioEditor::OnDumpState(wxCommandEvent& event) +{ + wxDateTime time = wxDateTime::Now(); + wxString filename; + bool doBinary = false; + + switch (event.GetId()) + { + case ID_DumpState: + filename = wxString::Format(_T("sim-dump-%d.txt"), time.GetTicks()); + break; + case ID_DumpBinaryState: + doBinary = true; + filename = wxString::Format(_T("sim-dump-%d.dat"), time.GetTicks()); + break; + } + + qSimStateDebugDump q(doBinary); + q.Post(); + + wxString state(std::wstring(*q.dump)); + + wxFFile file(filename.c_str(), _T("w")); + if (file.IsOpened() && !file.Error()) + { + file.Write(state); + file.Close(); + } + else + { + wxMessageDialog msgDlg(NULL, _("Error writing to file: ") + filename, _("Error"), wxICON_ERROR); + msgDlg.ShowModal(); + } +} + + ////////////////////////////////////////////////////////////////////////// Position::Position(const wxPoint& pt) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h index 42950f5c1b..da12993dd9 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -35,7 +35,7 @@ public: void OnTimer(wxTimerEvent& event); void OnIdle(wxIdleEvent& event); -// void OnNew(wxCommandEvent& event); + void OnNew(wxCommandEvent& event); void OnOpen(wxCommandEvent& event); void OnSave(wxCommandEvent& event); void OnSaveAs(wxCommandEvent& event); @@ -52,6 +52,7 @@ public: void OnJavaScript(wxCommandEvent& event); void OnCameraReset(wxCommandEvent& event); void OnRenderPath(wxCommandEvent& event); + void OnDumpState(wxCommandEvent& event); void OpenFile(const wxString& name); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp index 7541bc2e4b..660bd771d4 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -27,7 +27,6 @@ #include "ScenarioEditor.h" #include "AtlasScript/ScriptInterface.h" -#include "Sections/Terrain/Terrain.h" #include "Sections/Environment/Environment.h" #include "Sections/Cinematic/Cinematic.h" #include "Sections/Trigger/Trigger.h" @@ -315,7 +314,6 @@ void SectionLayout::Build(ScenarioEditor& scenarioEditor) ADD_SIDEBAR_SCRIPT(_T("map"), _T("map.png"), _("Map")); ADD_SIDEBAR_SCRIPT(_T("terrain"), _T("terrain.png"), _("Terrain")); - //ADD_SIDEBAR(TerrainSidebar, _T("terrain.png"), _("Terrain")); ADD_SIDEBAR_SCRIPT(_T("object"), _T("object.png"), _("Object")); ADD_SIDEBAR(EnvironmentSidebar, _T("environment.png"), _("Environment")); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp deleted file mode 100644 index 4f7b9835f7..0000000000 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "Terrain.h" - -#include "Buttons/ToolButton.h" -#include "General/Datafile.h" -#include "ScenarioEditor/ScenarioEditor.h" -#include "ScenarioEditor/Tools/Common/Brushes.h" -#include "ScenarioEditor/Tools/Common/MiscState.h" - -#include "GameInterface/Messages.h" - -#include "wx/spinctrl.h" -#include "wx/listctrl.h" -#include "wx/image.h" -#include "wx/imaglist.h" -#include "wx/busyinfo.h" -#include "wx/notebook.h" - -class TextureNotebook; - -class TerrainBottomBar : public wxPanel -{ -public: - TerrainBottomBar(wxWindow* parent); - void LoadTerrain(); -private: - TextureNotebook* m_Textures; -}; - - -TerrainSidebar::TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) -: Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer) -{ - // TODO: Less ugliness - - m_MainSizer->Add(new wxStaticText(this, wxID_ANY, _T("TODO: Make this much less ugly\n"))); - - { - wxSizer* sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Elevation tools")); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Modify"), _T("AlterElevation"), wxSize(50,20))); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T("SmoothElevation"), wxSize(50,20))); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Flatten"), _T("FlattenElevation"), wxSize(50,20))); -// sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T(""), wxSize(50,20))); -// sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Sample"), _T(""), wxSize(50,20))); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Paint"), _T("PaintTerrain"), wxSize(50,20))); - m_MainSizer->Add(sizer); - } - - { - wxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Brush")); - g_Brush_Elevation.CreateUI(this, sizer); - m_MainSizer->Add(sizer); - } - - m_BottomBar = new TerrainBottomBar(bottomBarContainer); -} - -void TerrainSidebar::OnFirstDisplay() -{ - static_cast(m_BottomBar)->LoadTerrain(); -} - -////////////////////////////////////////////////////////////////////////// - -class TextureNotebookPage : public wxPanel -{ -public: - TextureNotebookPage(wxWindow* parent, const wxString& name) - : wxPanel(parent, wxID_ANY), m_Name(name), m_ListCtrl(NULL) - { - } - - void OnDisplay() - { - if (m_ListCtrl) - { - int sel = m_ListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (sel != -1) - SetSelection(m_ListCtrl->GetItemData(sel)); - return; - } - - wxBusyInfo busy (_("Loading terrain previews")); - - m_TextureNames.Clear(); - - wxSizer* sizer = new wxBoxSizer(wxVERTICAL); - - m_ListCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON | wxLC_SINGLE_SEL | wxLC_AUTOARRANGE); - - const int imageWidth = 64; - const int imageHeight = 32; - wxImageList* imglist = new wxImageList(imageWidth, imageHeight, false, 0); - - AtlasMessage::qGetTerrainGroupPreviews qry(m_Name.c_str(), imageWidth, imageHeight); - qry.Post(); - - std::vector previews = *qry.previews; - - int i = 0; - for (std::vector::iterator it = previews.begin(); it != previews.end(); ++it) - { - unsigned char* buf = (unsigned char*)(malloc(it->imagedata.GetSize())); - // it->imagedata.GetBuffer() gives a Shareable*, which - // is stored the same as a unsigned char*, so we can just copy it. - memcpy(buf, it->imagedata.GetBuffer(), it->imagedata.GetSize()); - wxImage img (imageWidth, imageHeight, buf); - imglist->Add(wxBitmap(img)); - - wxListItem item; - - wxString name = it->name.c_str(); - m_TextureNames.Add(name); - // Add spaces into the displayed name, so Windows doesn't just say - // "grass_..." in the list ctrl for every terrain - name.Replace(_T("_"), _T(" ")); - item.SetText(name); - - item.SetData(i); - item.SetId(i); - item.SetImage(i); - - m_ListCtrl->InsertItem(item); - ++i; - } - m_ListCtrl->AssignImageList(imglist, wxIMAGE_LIST_NORMAL); - - sizer->Add(m_ListCtrl, wxSizerFlags().Expand().Proportion(1)); - SetSizer(sizer); - Layout(); // required to make things size correctly - } - - void OnSelect(wxListEvent& evt) - { - SetSelection(evt.GetData()); - } - - void SetSelection(int n) - { - if (n >= 0 && n < (int)m_TextureNames.GetCount()) - g_SelectedTexture = m_TextureNames[n]; - } - -private: - wxListCtrl* m_ListCtrl; - wxString m_Name; - wxArrayString m_TextureNames; - - DECLARE_EVENT_TABLE(); -}; - -BEGIN_EVENT_TABLE(TextureNotebookPage, wxPanel) - EVT_LIST_ITEM_SELECTED(wxID_ANY, TextureNotebookPage::OnSelect) -END_EVENT_TABLE(); - - -class TextureNotebook : public wxNotebook -{ -public: - TextureNotebook(wxWindow *parent) - : wxNotebook(parent, wxID_ANY/*, wxDefaultPosition, wxDefaultSize, wxNB_FIXEDWIDTH*/) - { - } - - void LoadTerrain() - { - wxBusyInfo busy (_("Loading terrain groups")); - - DeleteAllPages(); - m_TerrainGroups.Clear(); - - // Get the list of terrain groups from the engine - AtlasMessage::qGetTerrainGroups qry; - qry.Post(); - std::vector groupnames = *qry.groupnames; - for (std::vector::iterator it = groupnames.begin(); it != groupnames.end(); ++it) - m_TerrainGroups.Add(it->c_str()); - - for (size_t i = 0; i < m_TerrainGroups.GetCount(); ++i) - { - wxString visibleName = m_TerrainGroups[i]; - if (visibleName.Len()) - visibleName[0] = wxToupper(visibleName[0]); - AddPage(new TextureNotebookPage(this, m_TerrainGroups[i]), visibleName); - } - } - -protected: - void OnPageChanged(wxNotebookEvent& event) - { - if (event.GetSelection() >= 0 && event.GetSelection() < (int)GetPageCount()) - { - static_cast(GetPage(event.GetSelection()))->OnDisplay(); - } - event.Skip(); - } - -private: - wxArrayString m_TerrainGroups; - DECLARE_EVENT_TABLE(); -}; - -BEGIN_EVENT_TABLE(TextureNotebook, wxNotebook) - EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, TextureNotebook::OnPageChanged) -END_EVENT_TABLE(); - -////////////////////////////////////////////////////////////////////////// - -TerrainBottomBar::TerrainBottomBar(wxWindow* parent) - : wxPanel(parent, wxID_ANY) -{ - wxSizer* sizer = new wxBoxSizer(wxVERTICAL); - m_Textures = new TextureNotebook(this); - sizer->Add(m_Textures, wxSizerFlags().Expand().Proportion(1)); - SetSizer(sizer); -} - -void TerrainBottomBar::LoadTerrain() -{ - m_Textures->LoadTerrain(); -} diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index 12cf0de5c9..4a4ff52c53 100644 --- a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -31,8 +31,6 @@ #include "ps/World.h" #include "renderer/Renderer.h" #include "scriptinterface/ScriptInterface.h" -#include "simulation/LOSManager.h" -#include "simulation/Simulation.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpPlayer.h" #include "simulation2/components/ICmpPlayerManager.h" @@ -55,16 +53,8 @@ namespace g_Game->SetPlayerID(1); } - void StartGame(const CStrW& map) + void StartGame(const CScriptValRooted& attrs) { - CStrW mapBase = map.BeforeLast(L".pmp"); // strip the file extension, if any - - ScriptInterface& scriptInterface = g_Game->GetSimulation2()->GetScriptInterface(); - CScriptValRooted attrs; - scriptInterface.Eval("({})", attrs); - scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario"), false); - scriptInterface.SetProperty(attrs.get(), "map", std::wstring(mapBase), false); - g_Game->StartGame(attrs); // TODO: Non progressive load can fail - need a decent way to handle this @@ -82,22 +72,62 @@ namespace namespace AtlasMessage { -MESSAGEHANDLER(GenerateMap) +QUERYHANDLER(GenerateMap) { InitGame(); - // Load the empty default map - StartGame(L"_default"); + // Random map + ScriptInterface& scriptInterface = g_Game->GetSimulation2()->GetScriptInterface(); + + CScriptValRooted attrs; + scriptInterface.Eval("({})", attrs); + scriptInterface.SetProperty(attrs.get(), "mapType", std::string("random")); + scriptInterface.SetProperty(attrs.get(), "script", std::wstring(*msg->script)); - // TODO: use msg->size somehow - // (e.g. load the map then resize the terrain to match it) - UNUSED2(msg); + CScriptValRooted settings; + scriptInterface.Eval("({})", settings); + scriptInterface.SetProperty(settings.get(), "Size", (size_t)msg->size); + scriptInterface.SetProperty(settings.get(), "Seed", (size_t)msg->seed); + scriptInterface.SetProperty(settings.get(), "BaseTerrain", std::vector(*msg->terrain)); + scriptInterface.SetProperty(settings.get(), "BaseHeight", (size_t)msg->height); + scriptInterface.SetProperty(settings.get(), "CircularMap", true); // now default to circular map + + CScriptValRooted pData = scriptInterface.ParseJSON(*msg->playerData); + scriptInterface.SetProperty(settings.get(), "PlayerData", pData); + + scriptInterface.SetProperty(attrs.get(), "settings", settings, false); + + try + { + StartGame(attrs); + + msg->status = 0; + } + catch (PSERROR_Game_World_MapLoadFailed e) + { + // Cancel loading + LDR_Cancel(); + + msg->status = -1; + } } MESSAGEHANDLER(LoadMap) { InitGame(); - StartGame(*msg->filename); + + // Scenario + CStrW map = *msg->filename; + CStrW mapBase = map.BeforeLast(L".pmp"); // strip the file extension, if any + + ScriptInterface& scriptInterface = g_Game->GetSimulation2()->GetScriptInterface(); + + CScriptValRooted attrs; + scriptInterface.Eval("({})", attrs); + scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario")); + scriptInterface.SetProperty(attrs.get(), "map", std::wstring(mapBase)); + + StartGame(attrs); } MESSAGEHANDLER(SaveMap) @@ -111,4 +141,19 @@ MESSAGEHANDLER(SaveMap) g_Game->GetSimulation2()); } +QUERYHANDLER(GetMapSettings) +{ + msg->settings = g_Game->GetSimulation2()->GetMapSettingsString(); +} + +MESSAGEHANDLER(SetMapSettings) +{ + g_Game->GetSimulation2()->SetMapSettings(*msg->settings); +} + +QUERYHANDLER(GetRMSData) +{ + msg->data = g_Game->GetSimulation2()->GetRMSData(); +} + } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h b/source/tools/atlas/GameInterface/Handlers/PlayerHandlers.cpp similarity index 64% rename from source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h rename to source/tools/atlas/GameInterface/Handlers/PlayerHandlers.cpp index 719b2a2cdf..208f2fdb76 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h +++ b/source/tools/atlas/GameInterface/Handlers/PlayerHandlers.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -15,13 +15,24 @@ * along with 0 A.D. If not, see . */ -#include "../Common/Sidebar.h" +#include "precompiled.h" -class TerrainSidebar : public Sidebar +#include "MessageHandler.h" + +#include "ps/Game.h" +#include "simulation2/Simulation2.h" + + +namespace AtlasMessage { + +QUERYHANDLER(GetCivData) { -public: - TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer); + msg->data = g_Game->GetSimulation2()->GetCivData(); +} -protected: - virtual void OnFirstDisplay(); -}; +QUERYHANDLER(GetPlayerDefaults) +{ + msg->defaults = g_Game->GetSimulation2()->GetPlayerDefaults(); +} + +} diff --git a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp index 404dba5f62..ff3d4a0916 100644 --- a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp @@ -42,10 +42,10 @@ namespace AtlasMessage { QUERYHANDLER(GetTerrainGroups) { const CTerrainTextureManager::TerrainGroupMap &groups = g_TexMan.GetGroups(); - std::vector groupnames; + std::vector groupNames; for (CTerrainTextureManager::TerrainGroupMap::const_iterator it = groups.begin(); it != groups.end(); ++it) - groupnames.push_back(it->first.FromUTF8()); - msg->groupnames = groupnames; + groupNames.push_back(it->first.FromUTF8()); + msg->groupNames = groupNames; } static bool CompareTerrain(const sTerrainGroupPreview& a, const sTerrainGroupPreview& b) @@ -57,13 +57,13 @@ QUERYHANDLER(GetTerrainGroupPreviews) { std::vector previews; - CTerrainGroup* group = g_TexMan.FindGroup(CStrW(*msg->groupname).ToUTF8()); + CTerrainGroup* group = g_TexMan.FindGroup(CStrW(*msg->groupName).ToUTF8()); for (std::vector::const_iterator it = group->GetTerrains().begin(); it != group->GetTerrains().end(); ++it) { previews.push_back(sTerrainGroupPreview()); previews.back().name = (*it)->GetTag().FromUTF8(); - std::vector buf (msg->imagewidth*msg->imageheight*3); + std::vector buf (msg->imageWidth*msg->imageHeight*3); // It's not good to shrink the entire texture to fit the small preview // window, since it's the fine details in the texture that are @@ -78,11 +78,11 @@ QUERYHANDLER(GetTerrainGroupPreviews) glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &w); glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &h); - if (w < msg->imagewidth || h < msg->imageheight) + if (w < msg->imageWidth || h < msg->imageHeight) { // Oops, too small to preview - just use a flat colour u32 c = (*it)->GetBaseColor(); - for (ssize_t i = 0; i < msg->imagewidth*msg->imageheight; ++i) + for (ssize_t i = 0; i < msg->imageWidth*msg->imageHeight; ++i) { buf[i*3+0] = (c>>16) & 0xff; buf[i*3+1] = (c>>8) & 0xff; @@ -97,12 +97,12 @@ QUERYHANDLER(GetTerrainGroupPreviews) // Extract the middle section (as a representative preview), // and copy into buf - unsigned char* texdata_ptr = texdata + (w*(h - msg->imageheight)/2 + (w - msg->imagewidth)/2) * 3; + unsigned char* texdata_ptr = texdata + (w*(h - msg->imageHeight)/2 + (w - msg->imageWidth)/2) * 3; unsigned char* buf_ptr = &buf[0]; - for (ssize_t y = 0; y < msg->imageheight; ++y) + for (ssize_t y = 0; y < msg->imageHeight; ++y) { - memcpy(buf_ptr, texdata_ptr, msg->imagewidth*3); - buf_ptr += msg->imagewidth*3; + memcpy(buf_ptr, texdata_ptr, msg->imageWidth*3); + buf_ptr += msg->imageWidth*3; texdata_ptr += w*3; } @@ -110,9 +110,9 @@ QUERYHANDLER(GetTerrainGroupPreviews) } previews.back().loaded = (*it)->GetTexture()->IsLoaded(); - previews.back().imagewidth = msg->imagewidth; - previews.back().imageheight = msg->imageheight; - previews.back().imagedata = buf; + previews.back().imageWidth = msg->imageWidth; + previews.back().imageHeight = msg->imageHeight; + previews.back().imageData = buf; } // Sort the list alphabetically by name @@ -127,10 +127,10 @@ QUERYHANDLER(GetTerrainPassabilityClasses) { std::map classes = cmpPathfinder->GetPassabilityClasses(); - std::vector classnames; + std::vector classNames; for (std::map::iterator it = classes.begin(); it != classes.end(); ++it) - classnames.push_back(CStr(it->first).FromUTF8()); - msg->classnames = classnames; + classNames.push_back(CStr(it->first).FromUTF8()); + msg->classNames = classNames; } } diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 4d293bc697..1812d3f028 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -130,9 +130,17 @@ MESSAGE(ResizeScreen, ); ////////////////////////////////////////////////////////////////////////// +// Messages for map panel -MESSAGE(GenerateMap, - ((int, size)) // size in number of patches +QUERY(GenerateMap, + ((std::wstring, script)) // name of script + ((size_t, size)) // size in number of patches + ((size_t, seed)) // seed for rng + ((std::vector, terrain)) // base terrain(s) + ((size_t, height)) // base height + ((std::string, playerData)) // JSON player data + , + ((int, status)) // Status code, 0 for success, or < 0 for failure ); MESSAGE(LoadMap, @@ -143,6 +151,33 @@ MESSAGE(SaveMap, ((std::wstring, filename)) ); +QUERY(GetMapSettings, + , + ((std::string, settings)) + ); + +MESSAGE(SetMapSettings, + ((std::string, settings)) + ); + +QUERY(GetRMSData, + , + ((std::vector, data)) + ); + +////////////////////////////////////////////////////////////////////////// +// Messages for player panel + +QUERY(GetCivData, + , + ((std::vector, data)) + ); + +QUERY(GetPlayerDefaults, + , + ((std::string, defaults)) + ); + ////////////////////////////////////////////////////////////////////////// MESSAGE(RenderStyle, @@ -193,7 +228,7 @@ MESSAGE(BrushPreview, QUERY(GetTerrainGroups, , // no inputs - ((std::vector, groupnames)) + ((std::vector, groupNames)) ); #ifndef MESSAGES_SKIP_STRUCTS @@ -201,24 +236,24 @@ struct sTerrainGroupPreview { Shareable name; Shareable loaded; - Shareable imagewidth; - Shareable imageheight; - Shareable > imagedata; // RGB*width*height + Shareable imageWidth; + Shareable imageHeight; + Shareable > imageData; // RGB*width*height }; SHAREABLE_STRUCT(sTerrainGroupPreview); #endif QUERY(GetTerrainGroupPreviews, - ((std::wstring, groupname)) - ((int, imagewidth)) - ((int, imageheight)) + ((std::wstring, groupName)) + ((int, imageWidth)) + ((int, imageHeight)) , ((std::vector, previews)) ); QUERY(GetTerrainPassabilityClasses, , // no inputs - ((std::vector, classnames)) + ((std::vector, classNames)) ); ////////////////////////////////////////////////////////////////////////// @@ -247,7 +282,7 @@ struct sObjectSettings // Some settings are immutable and therefore are ignored (and should be left // empty) when passed from the editor to the game: - Shareable > > variantgroups; + Shareable > > variantGroups; }; SHAREABLE_STRUCT(sObjectSettings); #endif diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index a627e7eda7..acb34ee7e0 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -35,7 +35,6 @@ #include "ps/GameSetup/GameSetup.h" #include "ps/World.h" #include "renderer/Renderer.h" -#include "simulation/Simulation.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpObstructionManager.h" #include "simulation2/components/ICmpPathfinder.h"