Atlas: Allow placement of actors.
This was SVN commit r3275.
This commit is contained in:
parent
709d1389da
commit
ed7c2fe3d6
@ -400,6 +400,8 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
|
||||
toolbar->AddToolButton(_("Paint Terrain"), _("Paint terrain texture"), _T("paintterrain.png"), _T("PaintTerrain"));
|
||||
toolbar->Realize();
|
||||
SetToolBar(toolbar);
|
||||
// Set the default tool to be selected
|
||||
SetCurrentTool(_T(""));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Main window
|
||||
|
@ -12,7 +12,7 @@ class ObjectSelectListBox : public wxListBox
|
||||
{
|
||||
public:
|
||||
ObjectSelectListBox(wxWindow* parent)
|
||||
: wxListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE)
|
||||
: wxListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -28,35 +28,87 @@ BEGIN_EVENT_TABLE(ObjectSelectListBox, wxListBox)
|
||||
EVT_LISTBOX(wxID_ANY, ObjectSelectListBox::OnSelect)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
|
||||
class ObjectChoiceCtrl : public wxChoice
|
||||
{
|
||||
public:
|
||||
ObjectChoiceCtrl(wxWindow* parent, const wxArrayString& strings, ObjectSidebar& sidebar)
|
||||
: wxChoice(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, strings),
|
||||
m_Sidebar(sidebar)
|
||||
{
|
||||
SetSelection(0);
|
||||
}
|
||||
|
||||
void OnSelect(wxCommandEvent& evt)
|
||||
{
|
||||
m_Sidebar.SetObjectFilter(evt.GetSelection());
|
||||
}
|
||||
private:
|
||||
ObjectSidebar& m_Sidebar;
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
BEGIN_EVENT_TABLE(ObjectChoiceCtrl, wxChoice)
|
||||
EVT_CHOICE(wxID_ANY, ObjectChoiceCtrl::OnSelect)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ObjectSidebar::ObjectSidebar(wxWindow* parent)
|
||||
: Sidebar(parent), m_BottomBar(NULL)
|
||||
struct ObjectSidebarImpl
|
||||
{
|
||||
m_ObjectListBox = new ObjectSelectListBox(this);
|
||||
m_MainSizer->Add(m_ObjectListBox, wxSizerFlags().Proportion(1).Expand());
|
||||
|
||||
ObjectSidebarImpl() : m_BottomBar(NULL), m_ObjectListBox(NULL) { }
|
||||
wxWindow* m_BottomBar;
|
||||
wxListBox* m_ObjectListBox;
|
||||
std::vector<AtlasMessage::sObjectsListItem> m_Objects;
|
||||
};
|
||||
|
||||
ObjectSidebar::ObjectSidebar(wxWindow* parent)
|
||||
: Sidebar(parent), p(new ObjectSidebarImpl())
|
||||
{
|
||||
wxArrayString strings;
|
||||
strings.Add(_("Entities"));
|
||||
strings.Add(_("Actors (all)"));
|
||||
m_MainSizer->Add(new ObjectChoiceCtrl(this, strings, *this), wxSizerFlags().Expand());
|
||||
|
||||
p->m_ObjectListBox = new ObjectSelectListBox(this);
|
||||
m_MainSizer->Add(p->m_ObjectListBox, wxSizerFlags().Proportion(1).Expand());
|
||||
}
|
||||
|
||||
ObjectSidebar::~ObjectSidebar()
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
wxWindow* ObjectSidebar::GetBottomBar(wxWindow* WXUNUSED(parent))
|
||||
{
|
||||
if (m_BottomBar)
|
||||
return m_BottomBar;
|
||||
if (p->m_BottomBar)
|
||||
return p->m_BottomBar;
|
||||
|
||||
// m_BottomBar = new ObjectBottomBar(parent);
|
||||
return m_BottomBar;
|
||||
return p->m_BottomBar;
|
||||
}
|
||||
|
||||
void ObjectSidebar::OnFirstDisplay()
|
||||
{
|
||||
AtlasMessage::qGetEntitiesList qry;
|
||||
AtlasMessage::qGetObjectsList qry;
|
||||
qry.Post();
|
||||
for (std::vector<AtlasMessage::sEntitiesListItem>::iterator it = qry.entities.begin(); it != qry.entities.end(); ++it)
|
||||
p->m_Objects = qry.objects;
|
||||
SetObjectFilter(0);
|
||||
}
|
||||
|
||||
void ObjectSidebar::SetObjectFilter(int type)
|
||||
{
|
||||
p->m_ObjectListBox->Freeze();
|
||||
p->m_ObjectListBox->Clear();
|
||||
for (std::vector<AtlasMessage::sObjectsListItem>::iterator it = p->m_Objects.begin(); it != p->m_Objects.end(); ++it)
|
||||
{
|
||||
wxString id = it->id.c_str();
|
||||
wxString name = it->name.c_str();
|
||||
m_ObjectListBox->Append(name, new wxStringClientData(id));
|
||||
if (it->type == type)
|
||||
{
|
||||
wxString id = it->id.c_str();
|
||||
wxString name = it->name.c_str();
|
||||
p->m_ObjectListBox->Append(name, new wxStringClientData(id));
|
||||
}
|
||||
}
|
||||
p->m_ObjectListBox->Thaw();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,17 +1,19 @@
|
||||
#include "../Common/Sidebar.h"
|
||||
|
||||
struct ObjectSidebarImpl;
|
||||
class ObjectSidebar : public Sidebar
|
||||
{
|
||||
public:
|
||||
ObjectSidebar(wxWindow* parent);
|
||||
~ObjectSidebar();
|
||||
wxWindow* GetBottomBar(wxWindow* parent);
|
||||
void SetObjectFilter(int type);
|
||||
|
||||
protected:
|
||||
void OnFirstDisplay();
|
||||
|
||||
private:
|
||||
wxWindow* m_BottomBar;
|
||||
wxListBox* m_ObjectListBox;
|
||||
ObjectSidebarImpl* p;
|
||||
};
|
||||
|
||||
class ObjectBottomBar : public wxPanel
|
||||
|
@ -29,9 +29,9 @@ public:
|
||||
+ (m_ScreenPos.type1.y-m_Target.type1.y)*(m_ScreenPos.type1.y-m_Target.type1.y);
|
||||
bool useTarget = (dragDistSq >= 16*16);
|
||||
if (preview)
|
||||
POST_MESSAGE(EntityPreview(m_ObjectID.c_str(), m_ObjPos, useTarget, m_Target, g_DefaultAngle));
|
||||
POST_MESSAGE(ObjectPreview(m_ObjectID.c_str(), m_ObjPos, useTarget, m_Target, g_DefaultAngle));
|
||||
else
|
||||
POST_COMMAND(CreateEntity, (m_ObjectID.c_str(), m_ObjPos, useTarget, m_Target, g_DefaultAngle));
|
||||
POST_COMMAND(CreateObject,(m_ObjectID.c_str(), m_ObjPos, useTarget, m_Target, g_DefaultAngle));
|
||||
}
|
||||
|
||||
virtual void Init(void* initData)
|
||||
@ -60,7 +60,7 @@ public:
|
||||
* Mouse move -> if moved > [limit], rotate unit to face mouse; else default orientation
|
||||
* Left mouse release -> finalise placement of object on map
|
||||
|
||||
* Scroll wheel -> rotate default orientation
|
||||
* Page up/down -> rotate default orientation
|
||||
|
||||
* Escape -> cancel placement tool
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "graphics/Unit.h"
|
||||
#include "graphics/UnitManager.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "graphics/ObjectManager.h"
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/CLogger.h"
|
||||
@ -20,18 +21,41 @@
|
||||
|
||||
namespace AtlasMessage {
|
||||
|
||||
QUERYHANDLER(GetEntitiesList)
|
||||
static bool SortObjectsList(const sObjectsListItem& a, const sObjectsListItem& b)
|
||||
{
|
||||
return a.name < b.name;
|
||||
}
|
||||
|
||||
QUERYHANDLER(GetObjectsList)
|
||||
{
|
||||
std::vector<CStrW> names;
|
||||
g_EntityTemplateCollection.getBaseEntityNames(names);
|
||||
for (std::vector<CStrW>::iterator it = names.begin(); it != names.end(); ++it)
|
||||
{
|
||||
//CBaseEntity* baseent = g_EntityTemplateCollection.getTemplate(*it);
|
||||
sEntitiesListItem e;
|
||||
e.id = *it;
|
||||
e.name = *it; //baseent->m_Tag
|
||||
msg->entities.push_back(e);
|
||||
std::vector<CStrW> names;
|
||||
g_EntityTemplateCollection.getBaseEntityNames(names);
|
||||
for (std::vector<CStrW>::iterator it = names.begin(); it != names.end(); ++it)
|
||||
{
|
||||
//CBaseEntity* baseent = g_EntityTemplateCollection.getTemplate(*it);
|
||||
sObjectsListItem e;
|
||||
e.id = L"(e) " + *it;
|
||||
e.name = *it; //baseent->m_Tag
|
||||
e.type = 0;
|
||||
msg->objects.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<CStr> names;
|
||||
//g_ObjMan.GetPropObjectNames(names);
|
||||
g_ObjMan.GetAllObjectNames(names);
|
||||
for (std::vector<CStr>::iterator it = names.begin(); it != names.end(); ++it)
|
||||
{
|
||||
sObjectsListItem e;
|
||||
e.id = L"(n) " + CStrW(*it);
|
||||
e.name = CStrW(*it).AfterFirst(/*L"props/"*/ L"actors/");
|
||||
e.type = 1;
|
||||
msg->objects.push_back(e);
|
||||
}
|
||||
}
|
||||
std::sort(msg->objects.begin(), msg->objects.end(), SortObjectsList);
|
||||
}
|
||||
|
||||
|
||||
@ -104,7 +128,27 @@ static CVector3D GetUnitPos(const Position& pos)
|
||||
return vec;
|
||||
}
|
||||
|
||||
MESSAGEHANDLER(EntityPreview)
|
||||
static bool ParseObjectName(const std::wstring& obj, bool& isEntity, std::wstring& name)
|
||||
{
|
||||
if (obj.substr(0, 4) == L"(e) ")
|
||||
{
|
||||
isEntity = true;
|
||||
name = obj.substr(4);
|
||||
return true;
|
||||
}
|
||||
else if (obj.substr(0, 4) == L"(n) ")
|
||||
{
|
||||
isEntity = false;
|
||||
name = obj.substr(4);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MESSAGEHANDLER(ObjectPreview)
|
||||
{
|
||||
if (msg->id != g_PreviewUnitID)
|
||||
{
|
||||
@ -116,18 +160,27 @@ MESSAGEHANDLER(EntityPreview)
|
||||
g_PreviewUnit = NULL;
|
||||
}
|
||||
|
||||
if (msg->id.length())
|
||||
bool isEntity;
|
||||
std::wstring name;
|
||||
if (ParseObjectName(msg->id, isEntity, name))
|
||||
{
|
||||
// Create new unit
|
||||
CBaseEntity* base = g_EntityTemplateCollection.getTemplate(msg->id);
|
||||
if (base) // (ignore errors)
|
||||
if (isEntity)
|
||||
{
|
||||
g_PreviewUnit = g_UnitMan.CreateUnit(base->m_actorName, NULL);
|
||||
// TODO: set player (for colour)
|
||||
// TODO: variations
|
||||
CBaseEntity* base = g_EntityTemplateCollection.getTemplate(name);
|
||||
if (base) // (ignore errors)
|
||||
{
|
||||
g_PreviewUnit = g_UnitMan.CreateUnit(base->m_actorName, NULL);
|
||||
// TODO: set player (for colour)
|
||||
// TODO: variations
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_PreviewUnit = g_UnitMan.CreateUnit(name, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
g_PreviewUnitID = msg->id;
|
||||
}
|
||||
|
||||
@ -161,7 +214,7 @@ MESSAGEHANDLER(EntityPreview)
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_COMMAND(CreateEntity)
|
||||
BEGIN_COMMAND(CreateObject)
|
||||
|
||||
CVector3D m_Pos;
|
||||
float m_Angle;
|
||||
@ -190,21 +243,50 @@ BEGIN_COMMAND(CreateEntity)
|
||||
|
||||
void Redo()
|
||||
{
|
||||
CBaseEntity* base = g_EntityTemplateCollection.getTemplate(d->id);
|
||||
if (! base)
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to load entity template '%ls'", d->id.c_str());
|
||||
else
|
||||
bool isEntity;
|
||||
std::wstring name;
|
||||
if (ParseObjectName(d->id, isEntity, name))
|
||||
{
|
||||
HEntity ent = g_EntityManager.create(base, m_Pos, m_Angle);
|
||||
if (isEntity)
|
||||
{
|
||||
CBaseEntity* base = g_EntityTemplateCollection.getTemplate(name);
|
||||
if (! base)
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to load entity template '%ls'", name.c_str());
|
||||
else
|
||||
{
|
||||
HEntity ent = g_EntityManager.create(base, m_Pos, m_Angle);
|
||||
|
||||
if (! ent)
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to create entity of type '%ls'", d->id.c_str());
|
||||
if (! ent)
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to create entity of type '%ls'", name.c_str());
|
||||
else
|
||||
{
|
||||
// TODO: proper player ID
|
||||
ent->SetPlayer(g_Game->GetLocalPlayer());
|
||||
|
||||
ent->m_actor->SetID(m_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: proper player ID
|
||||
ent->SetPlayer(g_Game->GetLocalPlayer());
|
||||
CUnit* unit = g_UnitMan.CreateUnit(name, NULL);
|
||||
if (! unit)
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to load nonentity actor '%ls'", name.c_str());
|
||||
else
|
||||
{
|
||||
unit->SetID(m_ID);
|
||||
|
||||
ent->m_actor->SetID(m_ID);
|
||||
float s = sin(m_Angle);
|
||||
float c = cos(m_Angle);
|
||||
|
||||
CMatrix3D m;
|
||||
m._11 = -c; m._12 = 0.0f; m._13 = -s; m._14 = m_Pos.X;
|
||||
m._21 = 0.0f; m._22 = 1.0f; m._23 = 0.0f; m._24 = m_Pos.Y;
|
||||
m._31 = s; m._32 = 0.0f; m._33 = -c; m._34 = m_Pos.Z;
|
||||
m._41 = 0.0f; m._42 = 0.0f; m._43 = 0.0f; m._44 = 1.0f;
|
||||
unit->GetModel()->SetTransform(m);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,11 +294,19 @@ BEGIN_COMMAND(CreateEntity)
|
||||
void Undo()
|
||||
{
|
||||
CUnit* unit = g_UnitMan.FindByID(m_ID);
|
||||
if (unit && unit->GetEntity())
|
||||
unit->GetEntity()->kill();
|
||||
if (unit)
|
||||
{
|
||||
if (unit->GetEntity())
|
||||
unit->GetEntity()->kill();
|
||||
else
|
||||
{
|
||||
g_UnitMan.RemoveUnit(unit);
|
||||
delete unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_COMMAND(CreateEntity)
|
||||
END_COMMAND(CreateObject)
|
||||
|
||||
|
||||
QUERYHANDLER(SelectObject)
|
||||
|
@ -87,18 +87,18 @@ QUERY(GetTerrainGroupPreviews,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct sEntitiesListItem
|
||||
struct sObjectsListItem
|
||||
{
|
||||
std::wstring id;
|
||||
std::wstring name;
|
||||
// ...
|
||||
int type; // 0 = entity, 1 = actor
|
||||
};
|
||||
QUERY(GetEntitiesList,
|
||||
QUERY(GetObjectsList,
|
||||
, // no inputs
|
||||
((std::vector<sEntitiesListItem>, entities))
|
||||
((std::vector<sObjectsListItem>, objects))
|
||||
);
|
||||
|
||||
MESSAGE(EntityPreview,
|
||||
MESSAGE(ObjectPreview,
|
||||
((std::wstring, id)) // or empty string => disable
|
||||
((Position, pos))
|
||||
((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle'
|
||||
@ -106,7 +106,7 @@ MESSAGE(EntityPreview,
|
||||
((float, angle))
|
||||
);
|
||||
|
||||
COMMAND(CreateEntity, NOMERGE,
|
||||
COMMAND(CreateObject, NOMERGE,
|
||||
((std::wstring, id))
|
||||
((Position, pos))
|
||||
((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle'
|
||||
|
Loading…
Reference in New Issue
Block a user