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"