1
0
forked from 0ad/0ad

Atlas: Allow placement of actors.

This was SVN commit r3275.
This commit is contained in:
Ykkrosh 2005-12-22 04:20:16 +00:00
parent 709d1389da
commit ed7c2fe3d6
6 changed files with 202 additions and 56 deletions

View File

@ -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

View File

@ -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();
}
//////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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'