diff --git a/binaries/data/mods/internal/art/textures/terrain/types/special/blackness.dds b/binaries/data/mods/public/art/textures/terrain/types/special/blackness.dds similarity index 100% rename from binaries/data/mods/internal/art/textures/terrain/types/special/blackness.dds rename to binaries/data/mods/public/art/textures/terrain/types/special/blackness.dds diff --git a/binaries/data/mods/internal/art/textures/terrain/types/special/blackness.xml b/binaries/data/mods/public/art/textures/terrain/types/special/blackness.xml similarity index 100% rename from binaries/data/mods/internal/art/textures/terrain/types/special/blackness.xml rename to binaries/data/mods/public/art/textures/terrain/types/special/blackness.xml diff --git a/binaries/data/mods/internal/art/textures/terrain/types/special/terrains.xml b/binaries/data/mods/public/art/textures/terrain/types/special/terrains.xml similarity index 100% rename from binaries/data/mods/internal/art/textures/terrain/types/special/terrains.xml rename to binaries/data/mods/public/art/textures/terrain/types/special/terrains.xml diff --git a/binaries/data/mods/internal/art/textures/terrain/types/special/whiteness.dds b/binaries/data/mods/public/art/textures/terrain/types/special/whiteness.dds similarity index 100% rename from binaries/data/mods/internal/art/textures/terrain/types/special/whiteness.dds rename to binaries/data/mods/public/art/textures/terrain/types/special/whiteness.dds diff --git a/binaries/data/tools/atlas/scripts/section/object.js b/binaries/data/tools/atlas/scripts/section/object.js index 6a451b85cb..3f0cd06ab7 100644 --- a/binaries/data/tools/atlas/scripts/section/object.js +++ b/binaries/data/tools/atlas/scripts/section/object.js @@ -18,7 +18,7 @@ var actorViewer = { distance: 20, angle: 0, elevation: Math.PI / 6, - actor: "(n) structures/fndn_1x1.xml", + actor: "actor|structures/fndn_1x1.xml", animation: "idle", // Animation playback speed speed: 0, @@ -37,7 +37,7 @@ actorViewer.toggle = function () { }; actorViewer.postToGame = function () { - Atlas.Message.SetActorViewer(this.actor, this.animation, this.speed, false); + Atlas.Message.SetActorViewer(this.actor, this.animation, this.speed, false); }; actorViewer.postLookAt = function () { @@ -194,6 +194,40 @@ function init(window, bottomWindow) window.sizer.add(viewerButton, 0, wxStretch.EXPAND); + + // Actor viewer settings: + var displaySettingsBoxBox = new wxStaticBox(bottomWindow, -1, "Display settings"); + actorViewer.controls.push(displaySettingsBoxBox); + var displaySettingsBox = new wxStaticBoxSizer(displaySettingsBoxBox, wxOrientation.VERTICAL); + displaySettingsBox.minSize = new wxSize(140, -1); + var displaySettings = [ + ["Wireframe", "Toggle wireframe / solid rendering", "wireframe", false], + ["Move", "Toggle movement along ground when playing walk/run animations", "walk", false], + ["Ground", "Toggle the ground plane", "ground", true], + ["Shadows", "Toggle shadow rendering", "shadows", true], + ["Poly count", "Toggle polygon-count statistics - turn off ground and shadows for more useful data", "stats", false] + ]; + // NOTE: there's also a background colour setting, which isn't exposed + // by this UI because I don't know if it's worth the effort + for each (var setting in displaySettings) { + var button = new wxButton(bottomWindow, -1, setting[0]); + actorViewer.controls.push(button); + button.toolTip = setting[1]; + // Set the default value + Atlas.Message.SetViewParamB(Atlas.RenderView.ACTOR, setting[2], setting[3]); + // Toggle the value on clicks + (function (s) { // local scope for closure + button.onClicked = function () { + s[3] = !s[3]; + Atlas.Message.SetViewParamB(Atlas.RenderView.ACTOR, s[2], s[3]); + }; + })(setting); + displaySettingsBox.add(button, 0, wxStretch.EXPAND); + } + // TODO: It might be nice to add an "edit this actor" button + // in the actor viewer (when we have working actor hotloading) + + var playerSelector = new wxChoice(bottomWindow, -1, wxDefaultPosition, wxDefaultSize, ["Gaia", "Player 1", "Player 2", "Player 3", "Player 4", "Player 5", "Player 6", "Player 7", "Player 8"] ); @@ -236,13 +270,13 @@ function init(window, bottomWindow) animationBox.add(animationSelector, 0, wxStretch.EXPAND); animationBox.add(animationSpeedSizer, 0, wxStretch.EXPAND); + var animationSizer = new wxBoxSizer(wxOrientation.VERTICAL); animationSizer.minSize = new wxSize(160, -1); animationSizer.add(playerSelector, 0, wxStretch.EXPAND); animationSizer.add(animationBox, 0, wxStretch.EXPAND); - for each (ctrl in actorViewer.controls) ctrl.show(false); @@ -297,6 +331,7 @@ function init(window, bottomWindow) bottomWindow.sizer = new wxBoxSizer(wxOrientation.HORIZONTAL); + bottomWindow.sizer.add(displaySettingsBox); bottomWindow.sizer.add(animationSizer); bottomWindow.sizer.add(variationControlBox, 0, wxStretch.EXPAND); diff --git a/binaries/system/ActorViewer.bat b/binaries/system/ActorViewer.bat deleted file mode 100644 index 3312613d93..0000000000 --- a/binaries/system/ActorViewer.bat +++ /dev/null @@ -1 +0,0 @@ -start pyrogenesis.exe -editor -actorviewer diff --git a/build/premake/premake.lua b/build/premake/premake.lua index 51c8ae6597..dc2526ff8b 100755 --- a/build/premake/premake.lua +++ b/build/premake/premake.lua @@ -790,7 +790,6 @@ function setup_atlas_packages() atlas_src = { "ActorEditor", - "ActorViewer", "ColourTester", "CustomControls/Buttons", "CustomControls/Canvas", diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 66ef0fe1e3..48c1d211dd 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -84,9 +84,7 @@ CGame::CGame(): if (g_UseSimulation2) { - m_Simulation2->LoadScripts(L"simulation/components/interfaces/"); - m_Simulation2->LoadScripts(L"simulation/helpers/"); - m_Simulation2->LoadScripts(L"simulation/components/"); + m_Simulation2->LoadDefaultScripts(); m_Simulation2->ResetState(); CScriptVal initData; // TODO: ought to get this from the GUI, somehow diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 5ca997f49e..5af1503af0 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -266,6 +266,15 @@ bool CSimulation2::LoadScripts(const VfsPath& path) return m->LoadScripts(path); } +bool CSimulation2::LoadDefaultScripts() +{ + return ( + m->LoadScripts(L"simulation/components/interfaces/") && + m->LoadScripts(L"simulation/helpers/") && + m->LoadScripts(L"simulation/components/") + ); +} + LibError CSimulation2::ReloadChangedFile(const VfsPath& path) { return m->ReloadChangedFile(path); diff --git a/source/simulation2/Simulation2.h b/source/simulation2/Simulation2.h index 61dd1a3fc2..df1ea2e902 100644 --- a/source/simulation2/Simulation2.h +++ b/source/simulation2/Simulation2.h @@ -54,9 +54,16 @@ public: * Load all scripts in the specified directory (non-recursively), * so they can register new component types and functions. This * should be called immediately after constructing the CSimulation2 object. + * @return false on failure */ bool LoadScripts(const VfsPath& path); + /** + * Call LoadScripts for each of the game's standard simulation script paths. + * @return false on failure + */ + bool LoadDefaultScripts(); + /** * Reload any scripts that were loaded from the given filename. * (This is used to implement hotloading.) diff --git a/source/simulation2/components/tests/test_Pathfinder.h b/source/simulation2/components/tests/test_Pathfinder.h index d666499a9c..dad8098c2e 100644 --- a/source/simulation2/components/tests/test_Pathfinder.h +++ b/source/simulation2/components/tests/test_Pathfinder.h @@ -72,9 +72,7 @@ public: CTerrain terrain; CSimulation2 sim2(NULL, &terrain); - sim2.LoadScripts(L"simulation/components/interfaces/"); - sim2.LoadScripts(L"simulation/helpers/"); - sim2.LoadScripts(L"simulation/components/"); + sim2.LoadDefaultScripts(); sim2.ResetState(); CMapReader* mapReader = new CMapReader(); // it'll call "delete this" itself diff --git a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp b/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp deleted file mode 100644 index d02298565f..0000000000 --- a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp +++ /dev/null @@ -1,459 +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 "ActorViewer.h" - -#include "wx/treectrl.h" -#include "wx/regex.h" - -#include "General/Datafile.h" - -#include "ScenarioEditor/Tools/Common/Tools.h" -#include "ScenarioEditor/ScenarioEditor.h" -#include "ScenarioEditor/Sections/Environment/LightControl.h" -//#include "ScenarioEditor/Sections/Object/VariationControl.h" - -#include "GameInterface/Messages.h" - -#include "CustomControls/Canvas/Canvas.h" -#include "CustomControls/ColourDialog/ColourDialog.h" -#include "CustomControls/SnapSplitterWindow/SnapSplitterWindow.h" - -#include "ActorEditor/ActorEditor.h" - -using namespace AtlasMessage; - -const float M_PIf = 3.14159265f; - -////////////////////////////////////////////////////////////////////////// - -wxWindow* Tooltipped(wxWindow* window, const wxString& tip) -{ - window->SetToolTip(tip); - return window; -} - -////////////////////////////////////////////////////////////////////////// - -class ActorCanvas : public Canvas -{ -public: - ActorCanvas(wxWindow* parent, int* attribList) - : Canvas(parent, attribList, wxBORDER_SUNKEN), - m_Distance(20.f), m_Angle(0.f), m_Elevation(M_PIf/6.f), m_LastIsValid(false) - { - } - - void PostLookAt() - { - float offset = 0.3f; // slight fudge so we turn nicely when going over the top of the unit - POST_MESSAGE(LookAt, (eRenderView::ACTOR, - Position( - m_Distance*cos(m_Elevation)*sin(m_Angle) + offset*cos(m_Angle), - m_Distance*sin(m_Elevation), - m_Distance*cos(m_Elevation)*cos(m_Angle) - offset*sin(m_Angle)), - Position(0, 0, 0))); - } - -protected: - virtual void HandleMouseEvent(wxMouseEvent& evt) - { - bool camera_changed = false; - - if (evt.GetWheelRotation()) - { - float speed = -1.f * ScenarioEditor::GetSpeedModifier(); - - m_Distance += evt.GetWheelRotation() * speed / evt.GetWheelDelta(); - - camera_changed = true; - } - - if (evt.ButtonDown(wxMOUSE_BTN_LEFT) || evt.ButtonDown(wxMOUSE_BTN_RIGHT)) - { - m_LastX = evt.GetX(); - m_LastY = evt.GetY(); - m_LastIsValid = true; - } - else if (evt.Dragging() - && (evt.ButtonIsDown(wxMOUSE_BTN_LEFT) || evt.ButtonIsDown(wxMOUSE_BTN_RIGHT)) - && m_LastIsValid) - { - int dx = evt.GetX() - m_LastX; - int dy = evt.GetY() - m_LastY; - m_LastX = evt.GetX(); - m_LastY = evt.GetY(); - - m_Angle += dx * M_PIf/256.f * ScenarioEditor::GetSpeedModifier(); - - if (evt.ButtonIsDown(wxMOUSE_BTN_LEFT)) - m_Distance += dy / 8.f * ScenarioEditor::GetSpeedModifier(); - else // evt.ButtonIsDown(wxMOUSE_BTN_RIGHT)) - m_Elevation += dy * M_PIf/256.f * ScenarioEditor::GetSpeedModifier(); - - camera_changed = true; - } - else if (evt.ButtonUp(wxMOUSE_BTN_ANY) - && ! (evt.ButtonIsDown(wxMOUSE_BTN_LEFT) || evt.ButtonIsDown(wxMOUSE_BTN_RIGHT)) - ) - { - // In some situations (e.g. double-clicking the title bar to - // maximise the window) we get a dragging event without the matching - // buttondown; so disallow dragging when all buttons were released since - // the last buttondown. - // (TODO: does this problem affect the scenario editor too?) - m_LastIsValid = false; - } - - m_Distance = std::max(m_Distance, 1/64.f); // don't let people fly through the origin - - if (camera_changed) - PostLookAt(); - } - -private: - float m_Distance; - float m_Angle; - float m_Elevation; - int m_LastX, m_LastY; - bool m_LastIsValid; -}; - -////////////////////////////////////////////////////////////////////////// - -class StringTreeItemData : public wxTreeItemData -{ -public: - StringTreeItemData(const wxString& string) : m_String(string) {} - wxString m_String; -}; - -enum -{ - ID_Actors, - ID_Animations, - ID_Play, - ID_Pause, - ID_Slow, - ID_Edit, - ID_Background, - ID_ToggleWireframe, - ID_ToggleWalking, - ID_ToggleGround, - ID_ToggleShadows, - ID_ToggleStats, -}; - -BEGIN_EVENT_TABLE(ActorViewer, wxFrame) - EVT_CLOSE(ActorViewer::OnClose) - EVT_TREE_SEL_CHANGED(ID_Actors, ActorViewer::OnTreeSelection) - EVT_COMBOBOX(ID_Animations, ActorViewer::OnAnimationSelection) - EVT_TEXT_ENTER(ID_Animations, ActorViewer::OnAnimationSelection) - EVT_BUTTON(ID_Play, ActorViewer::OnSpeedButton) - EVT_BUTTON(ID_Pause, ActorViewer::OnSpeedButton) - EVT_BUTTON(ID_Slow, ActorViewer::OnSpeedButton) - EVT_BUTTON(ID_Edit, ActorViewer::OnEditButton) - EVT_BUTTON(ID_Background, ActorViewer::OnBackgroundButton) - EVT_BUTTON(ID_ToggleWireframe, ActorViewer::OnToggleButton) - EVT_BUTTON(ID_ToggleWalking, ActorViewer::OnToggleButton) - EVT_BUTTON(ID_ToggleGround, ActorViewer::OnToggleButton) - EVT_BUTTON(ID_ToggleShadows, ActorViewer::OnToggleButton) - EVT_BUTTON(ID_ToggleStats, ActorViewer::OnToggleButton) -END_EVENT_TABLE() - -static void SendToGame(const AtlasMessage::sEnvironmentSettings& settings) -{ - POST_COMMAND(SetEnvironmentSettings, (settings)); -} - -ActorViewer::ActorViewer(wxWindow* parent, ScriptInterface& scriptInterface) - : wxFrame(parent, wxID_ANY, _("Actor Viewer"), wxDefaultPosition, wxSize(800, 600)), - m_CurrentSpeed(0.f), m_BackgroundColour(wxColour(255, 255, 255)), - m_ToggledWalking(false), m_ToggledWireframe(false), m_ToggledGround(true), - m_ToggledShadows(true), m_ToggledStats(false), - m_ScriptInterface(scriptInterface), - m_ObjectSettings(m_ObjectSelection, m_ScriptInterface) -{ - SetIcon(wxIcon(_T("ICON_ActorEditor"))); - - // XXX: need to init m_ScriptInterface - - m_ObjectSettings.Init(AtlasMessage::eRenderView::ACTOR); - - SnapSplitterWindow* splitter = new SnapSplitterWindow(this, 0); - splitter->SetDefaultSashPosition(250); - - wxPanel* sidePanel = new wxPanel(splitter); - - // TODO: don't have this duplicated from ScenarioEditor.cpp - int glAttribList[] = { - WX_GL_RGBA, - WX_GL_DOUBLEBUFFER, - WX_GL_DEPTH_SIZE, 24, - WX_GL_BUFFER_SIZE, 24, - WX_GL_MIN_ALPHA, 8, - 0 - }; - - ActorCanvas* canvas = new ActorCanvas(splitter, glAttribList); - - splitter->SplitVertically(sidePanel, canvas); - -#ifdef __WXMSW__ - wglMakeCurrent(NULL, NULL); -#elif defined(__WXGTK__) - // Need to make sure the canvas is realized by GTK, so that its context is valid - Show(true); - wxSafeYield(); -#endif - POST_MESSAGE(SetCanvas, (static_cast(canvas))); - - POST_MESSAGE(Init, (false)); - - canvas->InitSize(); - canvas->PostLookAt(); - - ////////////////////////////////////////////////////////////////////////// - - // Construct a tree containing all the available actors - - qGetObjectsList qry; - qry.Post(); - std::vector objects = *qry.objects; - - m_TreeCtrl = new wxTreeCtrl(sidePanel, ID_Actors); - wxTreeItemId root = m_TreeCtrl->AddRoot(_("Actors")); - - std::map treeEntries; - - wxRegEx stripDirs (_T("^([^/]+)/"), wxRE_EXTENDED); // the non-empty string up to the first slash - - for (std::vector::iterator it = objects.begin(); it != objects.end(); ++it) - { - if (it->type != 1) - continue; - - wxString name = it->name.c_str(); - // Loop through the directory components of the name, stripping them - // off and search down the tree hierarchy - wxString path = _T(""); - wxTreeItemId treeItem = root; - while (stripDirs.Matches(name)) - { - wxString dir = stripDirs.GetMatch(name, 1); - path += dir + _T("/"); - - // If we've got 'path' in the tree already, use it - std::map::iterator entry = treeEntries.find(path.c_str()); - if (entry != treeEntries.end()) - { - treeItem = entry->second; - } - else - { - // Add this new path into the tree - treeItem = m_TreeCtrl->AppendItem(treeItem, dir); - treeEntries.insert(std::make_pair(path, treeItem)); - } - - // Remove the leading directory name from the full filename - stripDirs.Replace(&name, _T("")); - } - - m_TreeCtrl->AppendItem(treeItem, name, -1, -1, new StringTreeItemData(it->name.c_str())); - } - - m_TreeCtrl->Expand(root); - - - wxArrayString animations; - - AtObj animationsList (Datafile::ReadList("animations")); - for (AtIter it = animationsList["item"]; it.defined(); ++it) - animations.Add((const wchar_t *)it); - - m_AnimationBox = new wxComboBox(sidePanel, ID_Animations, _T("Idle"), wxDefaultPosition, wxDefaultSize, animations); - - m_EnvironmentSettings.sunelevation = 45 * M_PIf/180; - m_EnvironmentSettings.sunrotation = 315 * M_PIf/180; - m_EnvironmentSettings.sunoverbrightness = 1.0f; - m_EnvironmentSettings.suncolour = Colour(255, 255, 255); - m_EnvironmentSettings.terraincolour = Colour(164, 164, 164); - m_EnvironmentSettings.unitcolour = Colour(164, 164, 164); - LightControl* lightControl = new LightControl(sidePanel, wxSize(90, 90), m_EnvironmentSettings); - m_EnvConn = m_EnvironmentSettings.RegisterObserver(0, &SendToGame); - SendToGame(m_EnvironmentSettings); - - wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); - wxSizer* bottomSizer = new wxBoxSizer(wxHORIZONTAL); - wxSizer* bottomLeftSizer = new wxBoxSizer(wxVERTICAL); - wxSizer* bottomRightSizer = new wxBoxSizer(wxVERTICAL); - wxSizer* playButtonSizer = new wxBoxSizer(wxHORIZONTAL); - wxSizer* optionButtonSizer = new wxBoxSizer(wxVERTICAL); -// wxSizer* variationSizer = new wxStaticBoxSizer(wxVERTICAL, sidePanel, _("Variation")); - - playButtonSizer->Add(new wxButton(sidePanel, ID_Play, _("Play")), wxSizerFlags().Proportion(1)); - playButtonSizer->Add(new wxButton(sidePanel, ID_Pause, _("Pause")), wxSizerFlags().Proportion(1)); - playButtonSizer->Add(new wxButton(sidePanel, ID_Slow, _("Slow")), wxSizerFlags().Proportion(1)); - - optionButtonSizer->Add(new wxButton(sidePanel, ID_Edit, _("Edit actor")), wxSizerFlags().Expand()); - optionButtonSizer->Add(Tooltipped(new wxButton(sidePanel, ID_ToggleWireframe, _("Wireframe")), _("Toggle wireframe / solid rendering")), wxSizerFlags().Expand()); - optionButtonSizer->Add(Tooltipped(new wxButton(sidePanel, ID_Background, _("Background")), _("Change the background colour")), wxSizerFlags().Expand()); - optionButtonSizer->Add(Tooltipped(new wxButton(sidePanel, ID_ToggleWalking, _("Move")), _("Toggle movement along ground when playing walk/run animations")), wxSizerFlags().Expand()); - optionButtonSizer->Add(Tooltipped(new wxButton(sidePanel, ID_ToggleGround, _("Ground")), _("Toggle the ground plane")), wxSizerFlags().Expand()); - optionButtonSizer->Add(Tooltipped(new wxButton(sidePanel, ID_ToggleShadows, _("Shadows")), _("Toggle shadow rendering")), wxSizerFlags().Expand()); - optionButtonSizer->Add(Tooltipped(new wxButton(sidePanel, ID_ToggleStats, _("Poly count")), _("Toggle polygon-count statistics - turn off ground and shadows for more useful data")), wxSizerFlags().Expand()); - -// variationSizer->Add(new VariationControl(sidePanel, m_ObjectSettings), wxSizerFlags().Expand().Proportion(1)); - - mainSizer->Add(m_TreeCtrl, wxSizerFlags().Expand().Proportion(1)); - mainSizer->Add(bottomSizer, wxSizerFlags().Expand()); - - bottomSizer->Add(bottomLeftSizer, wxSizerFlags().Expand().Border(wxRIGHT, 5)); - bottomSizer->Add(bottomRightSizer, wxSizerFlags().Expand().Proportion(1)); - - bottomLeftSizer->Add(lightControl, wxSizerFlags().Expand()); - bottomLeftSizer->Add(optionButtonSizer, wxSizerFlags().Expand().Border(wxTOP, 4)); - - bottomRightSizer->Add(m_AnimationBox, wxSizerFlags().Expand()); - bottomRightSizer->Add(playButtonSizer, wxSizerFlags().Expand()); -// bottomRightSizer->Add(variationSizer, wxSizerFlags().Expand().Proportion(1)); - - sidePanel->SetSizer(mainSizer); - - ////////////////////////////////////////////////////////////////////////// - - // Pretend to have selected a unit, so the variations thing works properly - m_ObjectSelection.push_back(0); - - // Start by displaying the default non-existent actor - m_CurrentActor = _T("structures/fndn_1x1.xml"); - SetActorView(); - - POST_MESSAGE(RenderEnable, (eRenderView::ACTOR)); - -#ifdef __WXGTK__ - // HACK: because of how we fiddle with stuff earlier to make sure the canvas - // is displayed, the layout gets messed up, and it only seems to be fixable - // by changing the window's size - SetSize(GetSize() + wxSize(1, 0)); -#endif -} - -void ActorViewer::OnClose(wxCloseEvent& WXUNUSED(event)) -{ - POST_MESSAGE(Shutdown, ()); - - AtlasMessage::qExit().Post(); - // blocks until engine has noticed the message, so we won't be - // destroying the GLCanvas while it's still rendering - - Destroy(); -} - -void ActorViewer::SetActorView(bool flushCache) -{ - POST_MESSAGE(SetActorViewer, (m_CurrentActor.c_str(), m_AnimationBox->GetValue().c_str(), m_CurrentSpeed, flushCache)); - m_ObjectSelection.NotifyObservers(); -} - -void ActorViewer::OnTreeSelection(wxTreeEvent& event) -{ - wxTreeItemData* data = m_TreeCtrl->GetItemData(event.GetItem()); - if (! data) - return; - - m_CurrentActor = static_cast(data)->m_String; - SetActorView(); -} - -void ActorViewer::OnAnimationSelection(wxCommandEvent& WXUNUSED(event)) -{ - SetActorView(); -} - -void ActorViewer::OnSpeedButton(wxCommandEvent& event) -{ - if (event.GetId() == ID_Play) - m_CurrentSpeed = 1.f; - else if (event.GetId() == ID_Pause) - m_CurrentSpeed = 0.f; - else if (event.GetId() == ID_Slow) - m_CurrentSpeed = 0.1f; - else - { - wxLogDebug(_T("Invalid OnSpeedButton (%d)"), event.GetId()); - m_CurrentSpeed = 1.f; - } - - SetActorView(); -} - -void ActorViewer::OnActorEdited() -{ - SetActorView(true); -} - -void ActorViewer::OnEditButton(wxCommandEvent& WXUNUSED(event)) -{ - wxFileName dir (_T("mods/public/art/actors/") + m_CurrentActor, wxPATH_UNIX); - dir.MakeAbsolute(Datafile::GetDataDirectory()); - - ActorEditor* ed = new ActorEditor(NULL); - ed->OpenFile(dir.GetFullPath()); - ed->Show(); - - m_ActorConns.Add(ed->sig_FileSaved.connect( - boost::bind(std::mem_fun(&ActorViewer::OnActorEdited), this) - )); -} - - -void ActorViewer::OnBackgroundButton(wxCommandEvent& WXUNUSED(event)) -{ - ColourDialog dlg (this, _T("Actor Viewer/BackgroundColour"), m_BackgroundColour); - - if (dlg.ShowModal() == wxID_OK) - { - wxColour& c = dlg.GetColourData().GetColour(); - m_BackgroundColour = c; - POST_MESSAGE(SetViewParamC, (eRenderView::ACTOR, L"background", - AtlasMessage::Colour(c.Red(), c.Green(), c.Blue()))); - } -} - -void ActorViewer::OnToggleButton(wxCommandEvent& event) -{ -#define CASE(name, str) \ - case ID_Toggle##name: \ - m_Toggled##name = !m_Toggled##name; \ - POST_MESSAGE(SetViewParamB, (eRenderView::ACTOR, str, m_Toggled##name)); \ - break - - switch (event.GetId()) - { - CASE(Wireframe, L"wireframe"); - CASE(Walking, L"walk"); - CASE(Ground, L"ground"); - CASE(Shadows, L"shadows"); - CASE(Stats, L"stats"); - default: - wxFAIL_MSG(_T("Incorrect ID in OnToggleButton")); - } -} diff --git a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h b/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h deleted file mode 100644 index ab60e1533e..0000000000 --- a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h +++ /dev/null @@ -1,64 +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 "Windows/AtlasWindow.h" - -#include "GameInterface/Messages.h" -#include "General/Observable.h" -#include "ScenarioEditor/Tools/Common/ObjectSettings.h" - -#include "wx/treectrl.h" - -class wxTreeCtrl; -class wxTreeEvent; -class ScriptInterface; - -class ActorViewer : public wxFrame -{ -public: - ActorViewer(wxWindow* parent, ScriptInterface& scriptInterface); - -private: - void SetActorView(bool flushCache = false); - void OnClose(wxCloseEvent& event); - void OnTreeSelection(wxTreeEvent& event); - void OnAnimationSelection(wxCommandEvent& event); - void OnSpeedButton(wxCommandEvent& event); - void OnEditButton(wxCommandEvent& event); - void OnToggleButton(wxCommandEvent& event); - void OnBackgroundButton(wxCommandEvent& event); - - void OnActorEdited(); - ObservableScopedConnections m_ActorConns; - - wxTreeCtrl* m_TreeCtrl; - wxComboBox* m_AnimationBox; - wxString m_CurrentActor; - float m_CurrentSpeed; - - ScriptInterface& m_ScriptInterface; - - Observable > m_ObjectSelection; - ObjectSettings m_ObjectSettings; - wxColour m_BackgroundColour; - bool m_ToggledWireframe, m_ToggledWalking, m_ToggledGround, m_ToggledShadows, m_ToggledStats; - - Observable m_EnvironmentSettings; - ObservableScopedConnection m_EnvConn; - - DECLARE_EVENT_TABLE(); -}; diff --git a/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp b/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp index 80667887c7..3fa860c82a 100644 --- a/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp +++ b/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp @@ -24,7 +24,6 @@ #include "General/Datafile.h" #include "ActorEditor/ActorEditor.h" -#include "ActorViewer/ActorViewer.h" #include "ArchiveViewer/ArchiveViewer.h" #include "ColourTester/ColourTester.h" #include "FileConverter/FileConverter.h" @@ -217,11 +216,6 @@ public: m_ScriptInterface = new ScriptInterface(&ScenarioEditorSubmitCommand); frame = new ScenarioEditor(NULL, *m_ScriptInterface); } - else if (g_InitialWindowType == _T("ActorViewer")) - { - m_ScriptInterface = new ScriptInterface(&ScenarioEditorSubmitCommand); - frame = new ActorViewer(NULL, *m_ScriptInterface); - } else { wxFAIL_MSG(_("Internal error: invalid window type")); diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 65b6997576..bf5b7d3ef2 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -25,13 +25,10 @@ #include "graphics/Model.h" #include "graphics/ObjectManager.h" #include "graphics/Patch.h" -#include "graphics/SkeletonAnim.h" -#include "graphics/SkeletonAnimDef.h" #include "graphics/SkeletonAnimManager.h" #include "graphics/Terrain.h" #include "graphics/TextureEntry.h" #include "graphics/TextureManager.h" -#include "graphics/Unit.h" #include "graphics/UnitManager.h" #include "maths/MathUtil.h" #include "ps/Font.h" @@ -40,20 +37,22 @@ #include "renderer/Renderer.h" #include "renderer/Scene.h" #include "renderer/SkyManager.h" -#include "simulation/EntityTemplateCollection.h" -#include "simulation/EntityTemplate.h" +#include "simulation2/Simulation2.h" +#include "simulation2/components/ICmpPosition.h" +#include "simulation2/components/ICmpVisual.h" struct ActorViewerImpl : public Scene { NONCOPYABLE(ActorViewerImpl); public: ActorViewerImpl() - : Unit(NULL), ColladaManager(), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager), - ObjectManager(MeshManager, SkeletonAnimManager) + : Entity(INVALID_ENTITY), Terrain(), ColladaManager(), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager), + ObjectManager(MeshManager, SkeletonAnimManager), UnitManager(), Simulation2(&UnitManager, &Terrain) { + UnitManager.SetObjectManager(ObjectManager); } - CUnit* Unit; + entity_id_t Entity; CStrW CurrentUnitID; CStrW CurrentUnitAnim; float CurrentSpeed; @@ -69,35 +68,27 @@ public: CMeshManager MeshManager; CSkeletonAnimManager SkeletonAnimManager; CObjectManager ObjectManager; + CUnitManager UnitManager; + CSimulation2 Simulation2; // Simplistic implementation of the Scene interface - void EnumerateObjects(const CFrustum& UNUSED(frustum), SceneCollector* c) + void EnumerateObjects(const CFrustum& frustum, SceneCollector* c) { if (GroundEnabled) c->Submit(Terrain.GetPatch(0, 0)); - if (Unit) - c->SubmitRecursive(Unit->GetModel()); + Simulation2.RenderSubmit(*c, frustum, false); } }; ActorViewer::ActorViewer() : m(*new ActorViewerImpl()) { - m.Unit = NULL; m.WalkEnabled = false; m.GroundEnabled = true; m.ShadowsEnabled = g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWS); m.Background = SColor4ub(255, 255, 255, 255); - // Set up the renderer - g_TexMan.LoadTerrainTextures(); - g_Renderer.LoadAlphaMaps(); - g_Renderer.GetSkyManager()->m_RenderSky = false; - // (TODO: should these be unloaded properly some time? and what should - // happen if we want the actor viewer and scenario editor loaded at - // the same time?) - // Create a tiny empty piece of terrain, just so we can put shadows // on it without having to think too hard m.Terrain.Initialize(1, NULL); @@ -115,17 +106,29 @@ ActorViewer::ActorViewer() } } } + else + { + debug_warn(L"Failed to load whiteness texture"); + } + + // Start the simulation + m.Simulation2.LoadDefaultScripts(); + m.Simulation2.ResetState(); } ActorViewer::~ActorViewer() { - delete m.Unit; delete &m; } -CUnit* ActorViewer::GetUnit() +CSimulation2* ActorViewer::GetSimulation2() { - return m.Unit; + return &m.Simulation2; +} + +entity_id_t ActorViewer::GetEntity() +{ + return m.Entity; } void ActorViewer::UnloadObjects() @@ -133,64 +136,38 @@ void ActorViewer::UnloadObjects() m.ObjectManager.UnloadObjects(); } -// We want to support selection of both entities and actors in the -// Actor Viewer tool, so work out the actor corresponding to the given -// string -static bool ParseObjectName(const CStrW& obj, CStrW& name) -{ - if (obj.substr(0, 4) == L"(e) ") - { - CStrW entname = obj.substr(4); - CEntityTemplate* entity = g_EntityTemplateCollection.GetTemplate(entname); - if (! entity) - return false; - name = entity->m_actorName; - return true; - } - else if (obj.substr(0, 4) == L"(n) ") - { - name = obj.substr(4); - return true; - } - else - { - // By default, assume it's just an actor name. (TODO: This - // case is probably only used by the obsolete standalone - // Actor Viewer and should get removed eventually.) - name = obj; - return true; - } -} - void ActorViewer::SetActor(const CStrW& name, const CStrW& animation) { bool needsAnimReload = false; - CStrW id; - if (! ParseObjectName(name, id)) - id = L""; + CStrW id = name; - if (! m.Unit || id != m.CurrentUnitID) + // Recreate the entity, if we don't have one or if the new one is different + if (m.Entity == INVALID_ENTITY || id != m.CurrentUnitID) { - delete m.Unit; - m.Unit = NULL; + // Delete the old entity (if any) + if (m.Entity != INVALID_ENTITY) + { + m.Simulation2.DestroyEntity(m.Entity); + m.Simulation2.FlushDestroyedEntities(); + m.Entity = INVALID_ENTITY; + } // If there's no actor to display, return with nothing loaded if (id.empty()) return; - m.Unit = CUnit::Create(CStr(id), NULL, std::set(), m.ObjectManager); + m.Entity = m.Simulation2.AddEntity(L"preview|" + id); - if (! m.Unit) + if (m.Entity == INVALID_ENTITY) return; - float angle = (float)M_PI; - CMatrix3D mat; - mat.SetYRotation(angle + (float)M_PI); - mat.Translate(CELL_SIZE * PATCH_SIZE/2, 0.f, CELL_SIZE * PATCH_SIZE/2); - m.Unit->GetModel()->SetTransform(mat); - m.Unit->GetModel()->ValidatePosition(); - + CmpPtr cmpPosition(m.Simulation2, m.Entity); + if (!cmpPosition.null()) + { + cmpPosition->JumpTo(entity_pos_t::FromInt(CELL_SIZE*PATCH_SIZE/2), entity_pos_t::FromInt(CELL_SIZE*PATCH_SIZE/2)); + cmpPosition->SetYRotation(entity_angle_t::FromFloat((float)M_PI)); + } needsAnimReload = true; } @@ -203,8 +180,8 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation) float speed; // TODO: this is just copied from template_unit.xml and isn't the - // same for all units. But we don't know anything about entities here, - // so what to do? + // same for all units. We ought to get it from the entity definition + // (if there is one) if (anim == "walk") speed = 7.f; else if (anim == "run") @@ -213,8 +190,12 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation) speed = 0.f; m.CurrentSpeed = speed; - m.Unit->SetEntitySelection(anim); - m.Unit->SetRandomAnimation(anim, false, speed); + CmpPtr cmpVisual(m.Simulation2, m.Entity); + if (!cmpVisual.null()) + { + // TODO: SetEntitySelection(anim) + cmpVisual->SelectAnimation(anim, false, speed); + } } m.CurrentUnitID = id; @@ -249,13 +230,17 @@ void ActorViewer::Render() bool oldShadows = g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWS); g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS, m.ShadowsEnabled); + bool oldSky = g_Renderer.GetSkyManager()->m_RenderSky; + g_Renderer.GetSkyManager()->m_RenderSky = false; + g_Renderer.BeginFrame(); // Find the centre of the interesting region, in the middle of the patch // and half way up the model (assuming there is one) CVector3D centre; - if (m.Unit) - m.Unit->GetModel()->GetBounds().GetCentre(centre); + CmpPtr cmpVisual(m.Simulation2, m.Entity); + if (!cmpVisual.null()) + cmpVisual->GetBounds().GetCentre(centre); else centre.Y = 0.f; centre.X = centre.Z = CELL_SIZE * PATCH_SIZE/2; @@ -301,45 +286,30 @@ void ActorViewer::Render() g_Renderer.EndFrame(); + // Restore the old renderer state g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS, oldShadows); + g_Renderer.GetSkyManager()->m_RenderSky = oldSky; ogl_WarnIfError(); } void ActorViewer::Update(float dt) { - if (m.Unit) + m.Simulation2.Update(dt); + m.Simulation2.Interpolate(dt); + + if (m.WalkEnabled && m.CurrentSpeed) { - m.Unit->GetModel()->Update(dt); - - CMatrix3D mat = m.Unit->GetModel()->GetTransform(); - - if (m.WalkEnabled && m.CurrentSpeed) + CmpPtr cmpPosition(m.Simulation2, m.Entity); + if (!cmpPosition.null()) { // Move the model by speed*dt forwards - float z = mat.GetTranslation().Z; + float z = cmpPosition->GetPosition().Z.ToFloat(); z -= m.CurrentSpeed*dt; // Wrap at the edges, so it doesn't run off into the horizon if (z < CELL_SIZE*PATCH_SIZE * 0.4f) z = CELL_SIZE*PATCH_SIZE * 0.6f; - mat.Translate(0.f, 0.f, z - mat.GetTranslation().Z); + cmpPosition->JumpTo(cmpPosition->GetPosition().X, entity_pos_t::FromFloat(z)); } - - m.Unit->GetModel()->SetTransform(mat); - m.Unit->GetModel()->ValidatePosition(); } } - -bool ActorViewer::HasAnimation() const -{ - if (m.Unit && - m.Unit->GetModel()->GetAnimation() && - m.Unit->GetModel()->GetAnimation()->m_AnimDef && - m.Unit->GetModel()->GetAnimation()->m_AnimDef->GetNumFrames() > 1) - return true; - - if (m.Unit && m.WalkEnabled && m.CurrentSpeed) - return true; - - return false; -} diff --git a/source/tools/atlas/GameInterface/ActorViewer.h b/source/tools/atlas/GameInterface/ActorViewer.h index 3e5e011d24..729726063f 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.h +++ b/source/tools/atlas/GameInterface/ActorViewer.h @@ -18,9 +18,11 @@ #ifndef INCLUDED_ACTORVIEWER #define INCLUDED_ACTORVIEWER +#include "simulation2/system/Entity.h" + struct ActorViewerImpl; struct SColor4ub; -class CUnit; +class CSimulation2; class CStrW; class ActorViewer @@ -30,9 +32,10 @@ public: ActorViewer(); ~ActorViewer(); + CSimulation2* GetSimulation2(); + entity_id_t GetEntity(); void SetActor(const CStrW& id, const CStrW& animation); void UnloadObjects(); - CUnit* GetUnit(); void SetBackgroundColour(const SColor4ub& colour); void SetWalkEnabled(bool enabled); void SetGroundEnabled(bool enabled); @@ -40,10 +43,6 @@ public: void SetStatsEnabled(bool enabled); void Render(); void Update(float dt); - - // Returns whether there is a selected actor which has more than one - // frame of animation - bool HasAnimation() const; private: ActorViewerImpl& m; diff --git a/source/tools/atlas/GameInterface/GameLoop.cpp b/source/tools/atlas/GameInterface/GameLoop.cpp index b518976bfb..52f6477e78 100644 --- a/source/tools/atlas/GameInterface/GameLoop.cpp +++ b/source/tools/atlas/GameInterface/GameLoop.cpp @@ -80,12 +80,10 @@ static void* LaunchWindow(void* data) } // Work out which Atlas window to launch, given the command-line arguments -static const wchar_t* FindWindowName(const CmdLineArgs& args) +static const wchar_t* FindWindowName(const CmdLineArgs& UNUSED(args)) { - if (args.Has("actorviewer")) - return L"ActorViewer"; - else - return L"ScenarioEditor"; + return L"ScenarioEditor"; + // (This is a bit pointless - there's no choice since we've deleted the ActorViewer) } static ErrorReaction AtlasDisplayError(const wchar_t* text, size_t flags) diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp index cc2937d321..b8975922ac 100644 --- a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -190,12 +190,14 @@ MESSAGEHANDLER(SetSelectionPreview) QUERYHANDLER(GetObjectSettings) { - if (g_UseSimulation2) + View* view = View::GetView(msg->view); + CSimulation2* simulation = view->GetSimulation2(); + if (simulation) { sObjectSettings settings; settings.player = 0; - CmpPtr cmpOwner (*g_Game->GetSimulation2(), msg->id); + CmpPtr cmpOwner (*simulation, view->GetEntityId(msg->id)); if (!cmpOwner.null()) { int32_t player = cmpOwner->GetOwner(); @@ -210,7 +212,7 @@ QUERYHANDLER(GetObjectSettings) return; } - CUnit* unit = View::GetView(msg->view)->GetUnit(msg->id); + CUnit* unit = view->GetUnit(msg->id); if (! unit) return; sObjectSettings settings; @@ -265,9 +267,11 @@ BEGIN_COMMAND(SetObjectSettings) { sObjectSettings settings = msg->settings; - if (g_UseSimulation2) + View* view = View::GetView(msg->view); + CSimulation2* simulation = view->GetSimulation2(); + if (simulation) { - CmpPtr cmpOwner (*g_Game->GetSimulation2(), msg->id); + CmpPtr cmpOwner (*simulation, view->GetEntityId(msg->id)); m_PlayerOld = 0; if (!cmpOwner.null()) { @@ -280,7 +284,7 @@ BEGIN_COMMAND(SetObjectSettings) } else { - CUnit* unit = View::GetView(msg->view)->GetUnit(msg->id); + CUnit* unit = view->GetUnit(msg->id); if (! unit) return; m_PlayerOld = unit->GetPlayerID(); m_SelectionsOld = unit->GetActorSelections(); @@ -310,9 +314,11 @@ BEGIN_COMMAND(SetObjectSettings) private: void Set(size_t player, const std::set& selections) { - if (g_UseSimulation2) + View* view = View::GetView(msg->view); + CSimulation2* simulation = view->GetSimulation2(); + if (simulation) { - CmpPtr cmpOwner (*g_Game->GetSimulation2(), msg->id); + CmpPtr cmpOwner (*simulation, view->GetEntityId(msg->id)); if (!cmpOwner.null()) cmpOwner->SetOwner(player); // TODO: selections @@ -320,7 +326,7 @@ private: return; } - CUnit* unit = View::GetView(msg->view)->GetUnit(msg->id); + CUnit* unit = view->GetUnit(msg->id); if (! unit) return; unit->SetPlayerID(player); diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index f5854d571f..9e06a6d6c5 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -85,14 +85,19 @@ CCamera& ViewActor::GetCamera() return m_Camera; } -CUnit* ViewActor::GetUnit(AtlasMessage::ObjectID UNUSED(id)) +CSimulation2* ViewActor::GetSimulation2() { - return m_ActorViewer->GetUnit(); + return m_ActorViewer->GetSimulation2(); +} + +entity_id_t ViewActor::GetEntityId(AtlasMessage::ObjectID UNUSED(obj)) +{ + return m_ActorViewer->GetEntity(); } bool ViewActor::WantsHighFramerate() { - if (m_SpeedMultiplier != 0.f && m_ActorViewer->HasAnimation()) + if (m_SpeedMultiplier != 0.f) return true; return false; @@ -155,6 +160,13 @@ ViewGame::~ViewGame() std::for_each(m_SavedStates.begin(), m_SavedStates.end(), delete_pair_2nd); } +CSimulation2* ViewGame::GetSimulation2() +{ + if (g_UseSimulation2) + return g_Game->GetSimulation2(); + return NULL; +} + void ViewGame::Update(float frameLength) { float actualFrameLength = frameLength * m_SpeedMultiplier; diff --git a/source/tools/atlas/GameInterface/View.h b/source/tools/atlas/GameInterface/View.h index 3e13bb3ba4..d77b2720ea 100644 --- a/source/tools/atlas/GameInterface/View.h +++ b/source/tools/atlas/GameInterface/View.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,8 +23,10 @@ #include "graphics/Camera.h" #include "Messages.h" +#include "simulation2/system/Entity.h" class CUnit; +class CSimulation2; class ViewGame; class ViewActor; @@ -36,6 +38,8 @@ public: virtual void Update(float UNUSED(frameLength)) { }; virtual void Render() { }; virtual CCamera& GetCamera() = 0; + virtual CSimulation2* GetSimulation2() { return NULL; } + virtual entity_id_t GetEntityId(AtlasMessage::ObjectID obj) { return (entity_id_t)obj; } virtual CUnit* GetUnit(AtlasMessage::ObjectID UNUSED(id)) { return NULL; } virtual bool WantsHighFramerate() { return false; } @@ -73,6 +77,7 @@ public: virtual void Render(); virtual CCamera& GetCamera(); virtual CUnit* GetUnit(AtlasMessage::ObjectID id); + virtual CSimulation2* GetSimulation2(); virtual bool WantsHighFramerate(); void SetSpeedMultiplier(float speed); @@ -96,7 +101,8 @@ public: virtual void Update(float frameLength); virtual void Render(); virtual CCamera& GetCamera(); - virtual CUnit* GetUnit(AtlasMessage::ObjectID id); + virtual CSimulation2* GetSimulation2(); + virtual entity_id_t GetEntityId(AtlasMessage::ObjectID obj); virtual bool WantsHighFramerate(); virtual void SetParam(const std::wstring& name, bool value);