Atlas: Incomplete object (entity+actor) placement code. +/- keys for zooming.
This was SVN commit r3184.
This commit is contained in:
parent
8f976e4b8a
commit
0a252de08c
@ -116,7 +116,7 @@ CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) cons
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CreateUnit: create a new unit and add it to the world
|
||||
CUnit* CUnitManager::CreateUnit(CStr& actorName, CEntity* entity)
|
||||
CUnit* CUnitManager::CreateUnit(const CStr& actorName, CEntity* entity)
|
||||
{
|
||||
CObjectEntry* obj = g_ObjMan.FindObject(actorName);
|
||||
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
void DeleteAll();
|
||||
|
||||
// creates a new unit and adds it to the world
|
||||
CUnit* CreateUnit(CStr& actorName, CEntity* entity);
|
||||
CUnit* CreateUnit(const CStr& actorName, CEntity* entity);
|
||||
|
||||
// return the units
|
||||
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
|
||||
|
@ -26,6 +26,7 @@ void ToolButton::OnClick(wxCommandEvent& WXUNUSED(evt))
|
||||
{
|
||||
if (g_Current)
|
||||
g_Current->SetSelectedAppearance(false);
|
||||
// TODO: set disabled when tool is changed via other (non-button) methods
|
||||
|
||||
// Toggle on/off
|
||||
if (g_Current == this)
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
case WXK_RIGHT: dir = AtlasMessage::eScrollConstantDir::RIGHT; break;
|
||||
case WXK_UP: dir = AtlasMessage::eScrollConstantDir::FORWARDS; break;
|
||||
case WXK_DOWN: dir = AtlasMessage::eScrollConstantDir::BACKWARDS; break;
|
||||
case WXK_SHIFT: dir = -1; break;
|
||||
case WXK_SHIFT: case WXK_CONTROL: dir = -1; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@ -86,24 +86,54 @@ public:
|
||||
|
||||
void OnKeyDown(wxKeyEvent& evt)
|
||||
{
|
||||
if (GetCurrentTool().OnKey(evt, ITool::KEY_DOWN))
|
||||
{
|
||||
// Key event has been handled by the tool, so don't try
|
||||
// to use it for camera motion too
|
||||
return;
|
||||
}
|
||||
|
||||
if (KeyScroll(evt, true))
|
||||
return;
|
||||
|
||||
GetCurrentTool().OnKey(evt, ITool::KEY_DOWN);
|
||||
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
void OnKeyUp(wxKeyEvent& evt)
|
||||
{
|
||||
if (GetCurrentTool().OnKey(evt, ITool::KEY_UP))
|
||||
return;
|
||||
|
||||
if (KeyScroll(evt, false))
|
||||
return;
|
||||
|
||||
GetCurrentTool().OnKey(evt, ITool::KEY_UP);
|
||||
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
void OnChar(wxKeyEvent& evt)
|
||||
{
|
||||
if (GetCurrentTool().OnKey(evt, ITool::KEY_CHAR))
|
||||
return;
|
||||
|
||||
int dir = 0;
|
||||
if (evt.GetKeyCode() == '-' || evt.GetKeyCode() == '_')
|
||||
dir = -1;
|
||||
else if (evt.GetKeyCode() == '+' || evt.GetKeyCode() == '=')
|
||||
dir = +1;
|
||||
// TODO: internationalisation (-/_ and +/= don't always share a key)
|
||||
|
||||
if (dir)
|
||||
{
|
||||
float speed = 16.f;
|
||||
if (wxGetKeyState(WXK_SHIFT))
|
||||
speed *= 4.f;
|
||||
POST_MESSAGE(SmoothZoom(speed*dir));
|
||||
}
|
||||
else
|
||||
evt.Skip();
|
||||
|
||||
}
|
||||
|
||||
void OnMouseCapture(wxMouseCaptureChangedEvent& WXUNUSED(evt))
|
||||
{
|
||||
if (m_MouseCaptured)
|
||||
@ -160,11 +190,12 @@ public:
|
||||
|
||||
#ifndef UI_ONLY
|
||||
|
||||
GetCurrentTool().OnMouse(evt);
|
||||
|
||||
// TODO: if the tool responded to the mouse action, should we avoid moving
|
||||
// the camera too? (This is mostly avoided by not sharing buttons between
|
||||
// camera and tools, so maybe it's not a problem.)
|
||||
if (GetCurrentTool().OnMouse(evt))
|
||||
{
|
||||
// Mouse event has been handled by the tool, so don't try
|
||||
// to use it for camera motion too
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.GetWheelRotation())
|
||||
{
|
||||
@ -230,6 +261,7 @@ BEGIN_EVENT_TABLE(Canvas, wxGLCanvas)
|
||||
EVT_SIZE (Canvas::OnResize)
|
||||
EVT_KEY_DOWN (Canvas::OnKeyDown)
|
||||
EVT_KEY_UP (Canvas::OnKeyUp)
|
||||
EVT_CHAR (Canvas::OnChar)
|
||||
|
||||
EVT_LEFT_DOWN (Canvas::OnMouse)
|
||||
EVT_LEFT_UP (Canvas::OnMouse)
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "Sections/Map/Map.h"
|
||||
#include "Sections/Terrain/Terrain.h"
|
||||
#include "Sections/Object/Object.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -35,6 +36,9 @@ protected:
|
||||
if (event.GetSelection() != -1)
|
||||
newPage = wxDynamicCast(GetPage(event.GetSelection()), Sidebar);
|
||||
|
||||
if (newPage)
|
||||
newPage->OnSwitchTo();
|
||||
|
||||
if (m_Splitter->IsSplit())
|
||||
{
|
||||
wxWindow* bottom;
|
||||
@ -103,6 +107,7 @@ void SectionLayout::Build()
|
||||
wxNotebook* sidebar = new SidebarNotebook(m_HorizSplitter, m_VertSplitter);
|
||||
sidebar->AddPage(new MapSidebar(sidebar), _("Map"), false);
|
||||
sidebar->AddPage(new TerrainSidebar(sidebar), _("Terrain"), false);
|
||||
sidebar->AddPage(new ObjectSidebar(sidebar), _("Object"), false);
|
||||
|
||||
m_VertSplitter->SetDefaultSashPosition(-165);
|
||||
m_VertSplitter->Initialize(m_Canvas);
|
||||
|
@ -5,7 +5,7 @@
|
||||
IMPLEMENT_DYNAMIC_CLASS(Sidebar, wxPanel)
|
||||
|
||||
Sidebar::Sidebar(wxWindow* parent)
|
||||
: wxPanel(parent)
|
||||
: wxPanel(parent), m_AlreadyDisplayed(false)
|
||||
{
|
||||
m_MainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
SetSizer(m_MainSizer);
|
||||
@ -15,3 +15,12 @@ wxWindow* Sidebar::GetBottomBar(wxWindow* WXUNUSED(parent))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Sidebar::OnSwitchTo()
|
||||
{
|
||||
if (m_AlreadyDisplayed)
|
||||
return;
|
||||
|
||||
m_AlreadyDisplayed = true;
|
||||
OnFirstDisplay();
|
||||
}
|
||||
|
@ -9,12 +9,21 @@ public:
|
||||
Sidebar() {}
|
||||
Sidebar(wxWindow* parent);
|
||||
|
||||
void OnSwitchTo();
|
||||
|
||||
virtual wxWindow* GetBottomBar(wxWindow* parent);
|
||||
// called whenever the bottom bar is made visible; should usually be
|
||||
// lazily constructed, then cached forever (to maximise responsiveness)
|
||||
|
||||
protected:
|
||||
wxSizer* m_MainSizer; // vertical box sizer, used by most sidebars
|
||||
|
||||
virtual void OnFirstDisplay() {}
|
||||
// should be overridden when sidebars need to do expensive construction,
|
||||
// so it can be delayed until it is required
|
||||
|
||||
private:
|
||||
bool m_AlreadyDisplayed;
|
||||
};
|
||||
|
||||
#endif // SIDEBAR_H__
|
||||
|
@ -0,0 +1,71 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
#include "Buttons/ActionButton.h"
|
||||
#include "Buttons/ToolButton.h"
|
||||
#include "ScenarioEditor/Tools/Common/Tools.h"
|
||||
|
||||
#include "GameInterface/Messages.h"
|
||||
|
||||
class ObjectSelectListBox : public wxListBox
|
||||
{
|
||||
public:
|
||||
ObjectSelectListBox(wxWindow* parent)
|
||||
: wxListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE)
|
||||
{
|
||||
}
|
||||
|
||||
void OnSelect(wxCommandEvent& evt)
|
||||
{
|
||||
wxString id = static_cast<wxStringClientData*>(evt.GetClientObject())->GetData();
|
||||
SetCurrentTool(_T("PlaceObject"), &id);
|
||||
}
|
||||
private:
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
BEGIN_EVENT_TABLE(ObjectSelectListBox, wxListBox)
|
||||
EVT_LISTBOX(wxID_ANY, ObjectSelectListBox::OnSelect)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ObjectSidebar::ObjectSidebar(wxWindow* parent)
|
||||
: Sidebar(parent), m_BottomBar(NULL)
|
||||
{
|
||||
m_ObjectListBox = new ObjectSelectListBox(this);
|
||||
m_MainSizer->Add(m_ObjectListBox, wxSizerFlags().Proportion(1).Expand());
|
||||
|
||||
}
|
||||
|
||||
wxWindow* ObjectSidebar::GetBottomBar(wxWindow* parent)
|
||||
{
|
||||
if (m_BottomBar)
|
||||
return m_BottomBar;
|
||||
|
||||
// m_BottomBar = new ObjectBottomBar(parent);
|
||||
return m_BottomBar;
|
||||
}
|
||||
|
||||
void ObjectSidebar::OnFirstDisplay()
|
||||
{
|
||||
AtlasMessage::qGetEntitiesList qry;
|
||||
qry.Post();
|
||||
for (std::vector<AtlasMessage::sEntitiesListItem>::iterator it = qry.entities.begin(); it != qry.entities.end(); ++it)
|
||||
{
|
||||
wxString name = it->name.c_str();
|
||||
m_ObjectListBox->Append(name, new wxStringClientData(name));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//TerrainBottomBar::TerrainBottomBar(wxWindow* parent)
|
||||
// : wxPanel(parent, wxID_ANY)
|
||||
//{
|
||||
// wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
// wxNotebook* notebook = new TextureNotebook(this);
|
||||
// sizer->Add(notebook, wxSizerFlags().Expand().Proportion(1));
|
||||
// SetSizer(sizer);
|
||||
//}
|
@ -0,0 +1,22 @@
|
||||
#include "../Common/Sidebar.h"
|
||||
|
||||
class ObjectSidebar : public Sidebar
|
||||
{
|
||||
public:
|
||||
ObjectSidebar(wxWindow* parent);
|
||||
wxWindow* GetBottomBar(wxWindow* parent);
|
||||
|
||||
protected:
|
||||
void OnFirstDisplay();
|
||||
|
||||
private:
|
||||
wxWindow* m_BottomBar;
|
||||
wxListBox* m_ObjectListBox;
|
||||
};
|
||||
|
||||
class ObjectBottomBar : public wxPanel
|
||||
{
|
||||
public:
|
||||
ObjectBottomBar(wxWindow* parent);
|
||||
private:
|
||||
};
|
@ -181,4 +181,4 @@ TerrainBottomBar::TerrainBottomBar(wxWindow* parent)
|
||||
wxNotebook* notebook = new TextureNotebook(this);
|
||||
sizer->Add(notebook, wxSizerFlags().Expand().Proportion(1));
|
||||
SetSizer(sizer);
|
||||
}
|
||||
}
|
||||
|
@ -15,4 +15,4 @@ class TerrainBottomBar : public wxPanel
|
||||
public:
|
||||
TerrainBottomBar(wxWindow* parent);
|
||||
private:
|
||||
};
|
||||
};
|
||||
|
@ -20,12 +20,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
void OnEnable(AlterElevation*)
|
||||
void OnEnable()
|
||||
{
|
||||
g_Brush_Elevation.MakeActive();
|
||||
}
|
||||
|
||||
void OnDisable(AlterElevation*)
|
||||
void OnDisable()
|
||||
{
|
||||
POST_MESSAGE(BrushPreview(false, Position()));
|
||||
}
|
||||
|
@ -5,9 +5,10 @@
|
||||
|
||||
class DummyTool : public ITool
|
||||
{
|
||||
void Init(void*) {}
|
||||
void Shutdown() {}
|
||||
void OnMouse(wxMouseEvent& evt) { evt.Skip(); }
|
||||
void OnKey(wxKeyEvent& evt, KeyEventType) { evt.Skip(); }
|
||||
bool OnMouse(wxMouseEvent& WXUNUSED(evt)) { return false; }
|
||||
bool OnKey(wxKeyEvent& WXUNUSED(evt), KeyEventType) { return false; }
|
||||
void OnTick(float) {}
|
||||
} dummy;
|
||||
|
||||
@ -18,7 +19,7 @@ ITool& GetCurrentTool()
|
||||
return *g_CurrentTool;
|
||||
}
|
||||
|
||||
void SetCurrentTool(const wxString& name)
|
||||
void SetCurrentTool(const wxString& name, void* initData)
|
||||
{
|
||||
if (g_CurrentTool != &dummy)
|
||||
{
|
||||
@ -31,6 +32,7 @@ void SetCurrentTool(const wxString& name)
|
||||
{
|
||||
tool = wxDynamicCast(wxCreateDynamicObject(name), ITool);
|
||||
wxASSERT(tool);
|
||||
tool->Init(initData);
|
||||
}
|
||||
|
||||
if (tool == NULL)
|
||||
|
@ -12,16 +12,18 @@ class ITool : public wxObject
|
||||
public:
|
||||
enum KeyEventType { KEY_DOWN, KEY_UP, KEY_CHAR };
|
||||
|
||||
virtual void Init(void* initData) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void OnMouse(wxMouseEvent& evt) = 0;
|
||||
virtual void OnKey(wxKeyEvent& evt, KeyEventType dir) = 0;
|
||||
virtual bool OnMouse(wxMouseEvent& evt) = 0; // return true if handled
|
||||
virtual bool OnKey(wxKeyEvent& evt, KeyEventType dir) = 0; // return true if handled
|
||||
virtual void OnTick(float dt) = 0; // dt in seconds
|
||||
|
||||
virtual ~ITool() {};
|
||||
};
|
||||
|
||||
extern ITool& GetCurrentTool();
|
||||
extern void SetCurrentTool(const wxString& name); // should usually only be used by tool buttons
|
||||
extern void SetCurrentTool(const wxString& name, void* initData = NULL);
|
||||
// should usually only be used by tool buttons. (TODO: not true)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -58,6 +60,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Init(void* WXUNUSED(initData))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Shutdown()
|
||||
{
|
||||
// This can't be done in the destructor, because ~StateDrivenTool
|
||||
@ -69,8 +75,8 @@ public:
|
||||
protected:
|
||||
// Called when the tool is enabled/disabled; always called in zero or
|
||||
// more enable-->disable pairs per object instance.
|
||||
virtual void OnEnable(T* WXUNUSED(obj)) {}
|
||||
virtual void OnDisable(T* WXUNUSED(obj)) {}
|
||||
virtual void OnEnable() {}
|
||||
virtual void OnDisable() {}
|
||||
|
||||
struct State
|
||||
{
|
||||
@ -87,8 +93,8 @@ protected:
|
||||
|
||||
struct sDisabled : public State
|
||||
{
|
||||
void OnEnter(T* obj) { obj->OnDisable(obj); }
|
||||
void OnLeave(T* obj) { obj->OnEnable(obj); }
|
||||
void OnEnter(T* obj) { obj->OnDisable(); }
|
||||
void OnLeave(T* obj) { obj->OnEnable(); }
|
||||
}
|
||||
Disabled;
|
||||
|
||||
@ -103,14 +109,14 @@ protected:
|
||||
private:
|
||||
State* m_CurrentState;
|
||||
|
||||
virtual void OnMouse(wxMouseEvent& evt)
|
||||
virtual bool OnMouse(wxMouseEvent& evt)
|
||||
{
|
||||
m_CurrentState->OnMouse(static_cast<T*>(this), evt);
|
||||
return m_CurrentState->OnMouse(static_cast<T*>(this), evt);
|
||||
}
|
||||
|
||||
virtual void OnKey(wxKeyEvent& evt, KeyEventType dir)
|
||||
virtual bool OnKey(wxKeyEvent& evt, KeyEventType dir)
|
||||
{
|
||||
m_CurrentState->OnKey(static_cast<T*>(this), evt, dir);
|
||||
return m_CurrentState->OnKey(static_cast<T*>(this), evt, dir);
|
||||
}
|
||||
|
||||
virtual void OnTick(float dt)
|
||||
|
@ -20,13 +20,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
void OnEnable(PaintTerrain*)
|
||||
void OnEnable()
|
||||
{
|
||||
// TODO: multiple independent brushes?
|
||||
g_Brush_Elevation.MakeActive();
|
||||
}
|
||||
|
||||
void OnDisable(PaintTerrain*)
|
||||
void OnDisable()
|
||||
{
|
||||
POST_MESSAGE(BrushPreview(false, Position()));
|
||||
}
|
||||
|
161
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PlaceObject.cpp
Normal file
161
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PlaceObject.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Common/Tools.h"
|
||||
#include "Common/Brushes.h"
|
||||
#include "Common/MiscState.h"
|
||||
#include "GameInterface/Messages.h"
|
||||
|
||||
using AtlasMessage::Position;
|
||||
|
||||
static float g_DefaultAngle = M_PI*3.0/4.0;
|
||||
|
||||
class PlaceObject : public StateDrivenTool<PlaceObject>
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(PlaceObject);
|
||||
|
||||
Position m_ScreenPos, m_ObjPos, m_Target;
|
||||
wxString m_ObjectName;
|
||||
|
||||
public:
|
||||
PlaceObject()
|
||||
{
|
||||
SetState(&Waiting);
|
||||
}
|
||||
|
||||
void SendPreviewCommand()
|
||||
{
|
||||
int dragDistSq =
|
||||
(m_ScreenPos.type1.x-m_Target.type1.x)*(m_ScreenPos.type1.x-m_Target.type1.x)
|
||||
+ (m_ScreenPos.type1.y-m_Target.type1.y)*(m_ScreenPos.type1.y-m_Target.type1.y);
|
||||
bool useTarget = (dragDistSq >= 8*8);
|
||||
POST_MESSAGE(EntityPreview(m_ObjectName.c_str(), m_ObjPos, useTarget, m_Target, g_DefaultAngle));
|
||||
}
|
||||
|
||||
virtual void Init(void* initData)
|
||||
{
|
||||
wxASSERT(initData);
|
||||
wxString& name = *static_cast<wxString*>(initData);
|
||||
m_ObjectName = name;
|
||||
SendPreviewCommand();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
m_ObjectName = _T("");
|
||||
SendPreviewCommand();
|
||||
}
|
||||
|
||||
/*
|
||||
Object placement:
|
||||
* Select unit from list
|
||||
* Move mouse around screen; preview of unit follows mouse
|
||||
* Left mouse down -> remember position, fix preview to point
|
||||
* Mouse move -> if moved > 8px, rotate unit to face mouse; else default orientation
|
||||
* Left mouse release -> finalise placement of object on map
|
||||
|
||||
* Scroll wheel -> rotate default orientation
|
||||
|
||||
* Escape -> cancel placement tool
|
||||
|
||||
TOOD: what happens if somebody saves while the preview is active?
|
||||
*/
|
||||
|
||||
bool OnMouseOverride(wxMouseEvent& evt)
|
||||
{
|
||||
if (evt.GetWheelRotation())
|
||||
{
|
||||
float speed = M_PI/36.f;
|
||||
if (wxGetKeyState(WXK_SHIFT) && wxGetKeyState(WXK_CONTROL))
|
||||
speed /= 64.f;
|
||||
else if (wxGetKeyState(WXK_CONTROL))
|
||||
speed /= 4.f;
|
||||
else if (wxGetKeyState(WXK_SHIFT))
|
||||
speed *= 4.f;
|
||||
g_DefaultAngle += (evt.GetWheelRotation() * speed / evt.GetWheelDelta());
|
||||
SendPreviewCommand();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnKeyOverride(wxKeyEvent& evt, KeyEventType dir)
|
||||
{
|
||||
if (dir == KEY_CHAR && evt.GetKeyCode() == WXK_ESCAPE)
|
||||
{
|
||||
SetState(&Disabled);
|
||||
return true;
|
||||
}
|
||||
// TODO: arrow keys for rotation?
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
struct sWaiting : public State
|
||||
{
|
||||
bool OnMouse(PlaceObject* obj, wxMouseEvent& evt)
|
||||
{
|
||||
if (obj->OnMouseOverride(evt))
|
||||
return true;
|
||||
else if (evt.LeftDown())
|
||||
{
|
||||
obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target = Position(evt.GetPosition());
|
||||
obj->SendPreviewCommand();
|
||||
obj->m_ObjPos = Position::Unchanged(); // make sure object is stationary even if the camera moves
|
||||
SET_STATE(Placing);
|
||||
return true;
|
||||
}
|
||||
else if (evt.Moving())
|
||||
{
|
||||
obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target = Position(evt.GetPosition());
|
||||
obj->SendPreviewCommand();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
bool OnKey(PlaceObject* obj, wxKeyEvent& evt, KeyEventType dir)
|
||||
{
|
||||
return obj->OnKeyOverride(evt, dir);
|
||||
}
|
||||
}
|
||||
Waiting;
|
||||
|
||||
struct sPlacing : public State
|
||||
{
|
||||
bool OnMouse(PlaceObject* obj, wxMouseEvent& evt)
|
||||
{
|
||||
if (obj->OnMouseOverride(evt))
|
||||
return true;
|
||||
else if (evt.LeftUp())
|
||||
{
|
||||
obj->m_Target = Position(evt.GetPosition());
|
||||
// TODO: createobject command, so you can actually place an object
|
||||
SET_STATE(Waiting);
|
||||
obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target;
|
||||
obj->SendPreviewCommand();
|
||||
return true;
|
||||
}
|
||||
else if (evt.Moving())
|
||||
{
|
||||
obj->m_Target = Position(evt.GetPosition());
|
||||
obj->SendPreviewCommand();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
bool OnKey(PlaceObject* obj, wxKeyEvent& evt, KeyEventType dir)
|
||||
{
|
||||
return obj->OnKeyOverride(evt, dir);
|
||||
}
|
||||
}
|
||||
Placing;
|
||||
};
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(PlaceObject, StateDrivenTool<PlaceObject>);
|
@ -1,3 +1,9 @@
|
||||
wxWidgets:
|
||||
* alt+f with notebook tab focussed
|
||||
* wxLogTrace "%s" wxGetMessage (msw/window.cpp)
|
||||
|
||||
==============================
|
||||
|
||||
Colour tester:
|
||||
|
||||
==============================
|
||||
@ -74,7 +80,6 @@ General and/or unsorted miscellany:
|
||||
|
||||
* Don't create a row when editing a blank one then removing focus without typing anything
|
||||
|
||||
|
||||
======
|
||||
|
||||
Done: (newest at top)
|
||||
|
87
source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
Normal file
87
source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "MessageHandler.h"
|
||||
|
||||
#include "simulation/BaseEntityCollection.h"
|
||||
#include "graphics/Unit.h"
|
||||
#include "graphics/UnitManager.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "maths/Matrix3D.h"
|
||||
|
||||
namespace AtlasMessage {
|
||||
|
||||
QUERYHANDLER(GetEntitiesList)
|
||||
{
|
||||
std::vector<CStrW> names;
|
||||
g_EntityTemplateCollection.getBaseEntityNames(names);
|
||||
for (std::vector<CStrW>::iterator it = names.begin(); it != names.end(); ++it)
|
||||
{
|
||||
sEntitiesListItem e;
|
||||
e.name = *it;
|
||||
msg->entities.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static CUnit* g_PreviewUnit = NULL;
|
||||
static CStrW g_PreviewUnitName;
|
||||
|
||||
MESSAGEHANDLER(EntityPreview)
|
||||
{
|
||||
if (msg->name != g_PreviewUnitName)
|
||||
{
|
||||
// Delete old unit
|
||||
if (g_PreviewUnit)
|
||||
{
|
||||
g_UnitMan.RemoveUnit(g_PreviewUnit);
|
||||
delete g_PreviewUnit;
|
||||
g_PreviewUnit = NULL;
|
||||
}
|
||||
|
||||
if (msg->name.length())
|
||||
{
|
||||
// Create new unit
|
||||
CBaseEntity* base = g_EntityTemplateCollection.getTemplate(msg->name);
|
||||
if (base)
|
||||
{
|
||||
g_PreviewUnit = g_UnitMan.CreateUnit(base->m_actorName, 0);
|
||||
// TODO: set player (for colour)
|
||||
// TODO: variations
|
||||
}
|
||||
|
||||
}
|
||||
g_PreviewUnitName = msg->name;
|
||||
}
|
||||
|
||||
// Position/orient unit
|
||||
if (g_PreviewUnit)
|
||||
{
|
||||
static CVector3D pos;
|
||||
msg->pos.GetWorldSpace(pos, pos); // if msg->pos is 'Unchanged', use the previous pos
|
||||
|
||||
float s, c;
|
||||
/*
|
||||
if (msg->usetarget)
|
||||
{
|
||||
// TODO
|
||||
s=1; c=0;
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
s = sin(msg->angle);
|
||||
c = cos(msg->angle);
|
||||
}
|
||||
|
||||
CMatrix3D m;
|
||||
m._11 = -c; m._12 = 0.0f; m._13 = -s; m._14 = pos.X;
|
||||
m._21 = 0.0f; m._22 = 1.0f; m._23 = 0.0f; m._24 = pos.Y;
|
||||
m._31 = s; m._32 = 0.0f; m._33 = -c; m._34 = pos.Z;
|
||||
m._41 = 0.0f; m._42 = 0.0f; m._43 = 0.0f; m._44 = 1.0f;
|
||||
g_PreviewUnit->GetModel()->SetTransform(m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include "MessagesSetup.h"
|
||||
|
||||
// TODO: organisation, documentation, etc
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MESSAGE(CommandString,
|
||||
@ -83,6 +85,28 @@ QUERY(GetTerrainGroupPreviews,
|
||||
);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct sEntitiesListItem
|
||||
{
|
||||
std::wstring name;
|
||||
// ...
|
||||
};
|
||||
QUERY(GetEntitiesList,
|
||||
, // no inputs
|
||||
((std::vector<sEntitiesListItem>, entities))
|
||||
);
|
||||
|
||||
MESSAGE(EntityPreview,
|
||||
((std::wstring, name)) // or empty string => disable
|
||||
((Position, pos))
|
||||
((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle'
|
||||
((Position, target))
|
||||
((float, angle))
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QUERY(Exit,,); // no inputs nor outputs
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user