diff --git a/binaries/data/mods/official/art/actors/structures/celts/house.xml b/binaries/data/mods/official/art/actors/structures/celts/house.xml
index 43731f9642..18325286fe 100644
--- a/binaries/data/mods/official/art/actors/structures/celts/house.xml
+++ b/binaries/data/mods/official/art/actors/structures/celts/house.xml
@@ -5,21 +5,21 @@
structural/celt_ho_1.pmd
-
+
structural/celt_struct_1.dds
structural/celt_ho_2.pmd
-
+
structural/celt_struct_1.dds
structural/celt_ho_3.pmd
-
+
structural/celt_struct_1.dds
diff --git a/binaries/data/mods/official/art/actors/structures/persians/house.xml b/binaries/data/mods/official/art/actors/structures/persians/house.xml
index 7030544176..216b94d7d6 100644
--- a/binaries/data/mods/official/art/actors/structures/persians/house.xml
+++ b/binaries/data/mods/official/art/actors/structures/persians/house.xml
@@ -5,28 +5,28 @@
structural/pers_ho_a.pmd
-
+
structural/pers_struct_a.dds
structural/pers_ho_b.pmd
-
+
structural/pers_struct_a.dds
structural/pers_ho_c.pmd
-
+
structural/pers_struct_a.dds
structural/pers_ho_d.pmd
-
+
structural/pers_struct_a.dds
diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index 7209d0df94..12e4a89f27 100755
--- a/source/graphics/GameView.cpp
+++ b/source/graphics/GameView.cpp
@@ -555,7 +555,7 @@ void CGameView::SetCameraTarget( const CVector3D& target )
{
// Maintain the same orientation and level of zoom, if we can
// (do this by working out the point the camera is looking at, saving
- // the difference beteen that position and the camera point, and restoring
+ // the difference between that position and the camera point, and restoring
// that difference to our new target)
CVector3D CurrentTarget = m_Camera.GetFocus();
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
index c9995d3e14..7a6869b18a 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
@@ -27,7 +27,8 @@ public:
Canvas(wxWindow* parent, int* attribList)
: wxGLCanvas(parent, -1, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS, _T("GLCanvas"), attribList),
m_SuppressResize(true),
- m_MouseState(NONE), m_LastMouseState(NONE), m_MouseCaptured(false)
+ m_MouseState(NONE), m_LastMouseState(NONE), m_MouseCaptured(false),
+ m_LastMousePos(-1, -1)
{
}
@@ -132,9 +133,29 @@ public:
ReleaseMouse();
}
+ // Set focus when clicking
if (evt.ButtonDown())
SetFocus();
+ // TODO or at least to think about: When using other controls in the
+ // editor, it's annoying that keyboard/scrollwheel no longer navigate
+ // around the world until you click on it.
+ // Setting focus back whenever the mouse moves over the GL window
+ // feels like a fairly natural solution to me, since I can use
+ // e.g. brush-editing controls normally, and then move the mouse to
+ // see the brush outline and magically get given back full control
+ // of the camera.
+ if (evt.Moving())
+ SetFocus();
+
+ // Reject motion events if the mouse has not actually moved
+ if (evt.Moving() || evt.Dragging())
+ {
+ if (m_LastMousePos == evt.GetPosition())
+ return;
+ m_LastMousePos = evt.GetPosition();
+ }
+
g_CurrentTool->OnMouse(evt);
// TODO: if the tool responded to the mouse action, should we avoid moving
@@ -197,6 +218,8 @@ private:
int m_MouseState, m_LastMouseState;
bool m_MouseCaptured;
+ wxPoint m_LastMousePos;
+
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(Canvas, wxGLCanvas)
@@ -249,6 +272,7 @@ enum
// ID_SaveAs,
ID_Wireframe,
+ ID_MessageTrace,
};
BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
@@ -260,6 +284,7 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
EVT_MENU(wxID_REDO, ScenarioEditor::OnRedo)
EVT_MENU(ID_Wireframe, ScenarioEditor::OnWireframe)
+ EVT_MENU(ID_MessageTrace, ScenarioEditor::OnMessageTrace)
EVT_IDLE(ScenarioEditor::OnIdle)
END_EVENT_TABLE()
@@ -312,6 +337,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
menuBar->Append(menuMisc, _("&Misc hacks"));
{
menuMisc->AppendCheckItem(ID_Wireframe, _("&Wireframe"));
+ menuMisc->AppendCheckItem(ID_MessageTrace, _("Message debug trace"));
}
//////////////////////////////////////////////////////////////////////////
@@ -436,6 +462,11 @@ void ScenarioEditor::OnWireframe(wxCommandEvent& event)
POST_COMMAND(RenderStyle(event.IsChecked()));
}
+void ScenarioEditor::OnMessageTrace(wxCommandEvent& event)
+{
+ POST_COMMAND(MessageTrace(event.IsChecked()));
+}
+
//////////////////////////////////////////////////////////////////////////
AtlasMessage::Position::Position(const wxPoint& pt)
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
index 57436c9cad..ac3fb0b08a 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
@@ -16,6 +16,7 @@ public:
void OnRedo(wxCommandEvent& event);
void OnWireframe(wxCommandEvent& event);
+ void OnMessageTrace(wxCommandEvent& event);
static AtlasWindowCommandProc& GetCommandProc();
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp
index ecf57993f4..e9162bdd93 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp
@@ -50,8 +50,12 @@ public:
else if (evt.Moving())
{
POST_COMMAND(BrushPreview(true, Position(evt.GetPosition())));
+ return true;
+ }
+ else
+ {
+ return false;
}
- return false;
}
}
Waiting;
@@ -59,6 +63,11 @@ public:
struct sAltering_common : public State
{
+ void OnEnter(AlterElevation* obj)
+ {
+ POST_COMMAND(BrushPreview(true, obj->m_Pos));
+ }
+
void OnLeave(AlterElevation*)
{
ScenarioEditor::GetCommandProc().FinaliseLastCommand();
@@ -73,7 +82,8 @@ public:
}
else if (evt.Dragging())
{
- obj->m_Pos = Position(evt.GetPosition());
+ wxPoint pos = evt.GetPosition();
+ obj->m_Pos = Position(pos);
POST_COMMAND(BrushPreview(true, obj->m_Pos));
return true;
}
@@ -85,7 +95,8 @@ public:
void OnTick(AlterElevation* obj, float dt)
{
- ADD_WORLDCOMMAND(AlterElevation, (obj->m_Pos, dt*4096.f*GetDirection()));
+ ADD_WORLDCOMMAND(AlterElevation, (obj->m_Pos, dt*4096.f*GetDirection()*g_Brush_Elevation.GetStrength()));
+ obj->m_Pos = Position::Unchanged();
}
virtual bool IsMouseUp(wxMouseEvent& evt) = 0;
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp
index b542527bdb..0c56fe3cc0 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp
@@ -5,7 +5,7 @@
#include "GameInterface/Messages.h"
Brush::Brush()
-: m_BrushShape(SQUARE), m_BrushSize(4), m_IsActive(false)
+: m_Shape(SQUARE), m_Size(4), m_Strength(1.f), m_IsActive(false)
{
}
@@ -13,55 +13,58 @@ Brush::~Brush()
{
}
-int Brush::GetWidth()
+int Brush::GetWidth() const
{
- switch (m_BrushShape)
+ switch (m_Shape)
{
case CIRCLE:
- return m_BrushSize*2 + 1;
+ return m_Size;
case SQUARE:
- return m_BrushSize;
+ return m_Size;
default:
wxFAIL;
return -1;
}
}
-int Brush::GetHeight()
+int Brush::GetHeight() const
{
- switch (m_BrushShape)
+/*
+ switch (m_Shape)
{
- case CIRCLE:
- return m_BrushSize*2 + 1;
- case SQUARE:
- return m_BrushSize;
+ case RECTANGLE or something:
default:
- wxFAIL;
- return -1;
+ return GetWidth();
}
+*/
+ return GetWidth();
}
-float* Brush::GetNewedData()
+float* Brush::GetNewedData() const
{
int width = GetWidth();
int height = GetHeight();
float* data = new float[width*height];
- switch (m_BrushShape)
+ switch (m_Shape)
{
case CIRCLE:
{
int i = 0;
- for (int y = -m_BrushSize; y <= m_BrushSize; ++y)
+ // All calculations are done in units of half-tiles, since that
+ // is the required precision
+ int mid_x = m_Size-1;
+ int mid_y = m_Size-1;
+ for (int y = 0; y < m_Size; ++y)
{
- for (int x = -m_BrushSize; x <= m_BrushSize; ++x)
+ for (int x = 0; x < m_Size; ++x)
{
- // TODO: proper circle rasterization, with variable smoothness etc
- if (x*x + y*y <= m_BrushSize*m_BrushSize - 4)
- data[i++] = 1.f;
- else if (x*x + y*y <= m_BrushSize*m_BrushSize)
- data[i++] = 0.5f;
+ float dist_sq = // scaled to 0 in centre, 1 on edge
+ ((2*x - mid_x)*(2*x - mid_x) +
+ (2*y - mid_y)*(2*y - mid_y)) / (float)(m_Size*m_Size);
+ if (dist_sq <= 1.f)
+ data[i++] = (sqrtf(2.f - dist_sq) - 1.f) / (sqrt(2.f) - 1.f);
else
data[i++] = 0.f;
}
@@ -82,6 +85,11 @@ float* Brush::GetNewedData()
return data;
}
+float Brush::GetStrength() const
+{
+ return m_Strength;
+}
+
//////////////////////////////////////////////////////////////////////////
class BrushShapeCtrl : public wxRadioBox
@@ -91,7 +99,7 @@ public:
: wxRadioBox(parent, wxID_ANY, _("Shape"), wxDefaultPosition, wxDefaultSize, shapes, 0, wxRA_SPECIFY_ROWS),
m_Brush(brush)
{
- SetSelection(m_Brush.m_BrushShape);
+ SetSelection(m_Brush.m_Shape);
}
private:
@@ -99,7 +107,7 @@ private:
void OnChange(wxCommandEvent& WXUNUSED(evt))
{
- m_Brush.m_BrushShape = (Brush::BrushShape)GetSelection();
+ m_Brush.m_Shape = (Brush::BrushShape)GetSelection();
m_Brush.Send();
}
@@ -114,7 +122,7 @@ class BrushSizeCtrl: public wxSpinCtrl
{
public:
BrushSizeCtrl(wxWindow* parent, Brush& brush)
- : wxSpinCtrl(parent, wxID_ANY, wxString::Format(_T("%d"), brush.m_BrushSize), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 50, brush.m_BrushSize),
+ : wxSpinCtrl(parent, wxID_ANY, wxString::Format(_T("%d"), brush.m_Size), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, brush.m_Size),
m_Brush(brush)
{
}
@@ -124,7 +132,7 @@ private:
void OnChange(wxSpinEvent& WXUNUSED(evt))
{
- m_Brush.m_BrushSize = GetValue();
+ m_Brush.m_Size = GetValue();
m_Brush.Send();
}
@@ -135,6 +143,31 @@ BEGIN_EVENT_TABLE(BrushSizeCtrl, wxSpinCtrl)
END_EVENT_TABLE()
+class BrushStrengthCtrl : public wxSpinCtrl
+{
+public:
+ BrushStrengthCtrl(wxWindow* parent, Brush& brush)
+ : wxSpinCtrl(parent, wxID_ANY, wxString::Format(_T("%d"), (int)(10.f*brush.m_Strength)), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, (int)(10.f*brush.m_Strength)),
+ m_Brush(brush)
+ {
+ }
+
+private:
+ Brush& m_Brush;
+
+ void OnChange(wxSpinEvent& WXUNUSED(evt))
+ {
+ m_Brush.m_Strength = GetValue()/10.f;
+ m_Brush.Send();
+ }
+
+ DECLARE_EVENT_TABLE();
+};
+BEGIN_EVENT_TABLE(BrushStrengthCtrl, wxSpinCtrl)
+ EVT_SPINCTRL(wxID_ANY, BrushStrengthCtrl::OnChange)
+END_EVENT_TABLE()
+
+
void Brush::CreateUI(wxWindow* parent, wxSizer* sizer)
{
@@ -144,9 +177,12 @@ void Brush::CreateUI(wxWindow* parent, wxSizer* sizer)
// TODO (maybe): get rid of the extra static box, by not using wxRadioBox
sizer->Add(new BrushShapeCtrl(parent, shapes, *this));
- wxSizer* spinnerSizer = new wxBoxSizer(wxHORIZONTAL);
+ // TODO: These are yucky
+ wxSizer* spinnerSizer = new wxFlexGridSizer(2);
spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Size")));
spinnerSizer->Add(new BrushSizeCtrl(parent, *this));
+ spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Strength")));
+ spinnerSizer->Add(new BrushStrengthCtrl(parent, *this));
sizer->Add(spinnerSizer);
}
@@ -164,7 +200,7 @@ void Brush::MakeActive()
void Brush::Send()
{
if (m_IsActive)
- POST_COMMAND(SetBrush(GetWidth(), GetHeight(), GetNewedData()));
+ POST_COMMAND(Brush(GetWidth(), GetHeight(), GetNewedData()));
}
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.h
index e964e03094..2d8e792934 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.h
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.h
@@ -3,18 +3,22 @@
class BrushShapeCtrl;
class BrushSizeCtrl;
+class BrushStrengthCtrl;
class Brush
{
friend class BrushShapeCtrl;
friend class BrushSizeCtrl;
+ friend class BrushStrengthCtrl;
public:
Brush();
~Brush();
- int GetWidth();
- int GetHeight();
- float* GetNewedData(); // freshly allocated via new[]
+ int GetWidth() const;
+ int GetHeight() const;
+ float* GetNewedData() const; // freshly allocated via new[]
+
+ float GetStrength() const;
void CreateUI(wxWindow* parent, wxSizer* sizer);
@@ -27,8 +31,9 @@ private:
void Send();
enum BrushShape { SQUARE = 0, CIRCLE };
- BrushShape m_BrushShape;
- int m_BrushSize;
+ BrushShape m_Shape;
+ int m_Size;
+ float m_Strength;
bool m_IsActive;
};
diff --git a/source/tools/atlas/GameInterface/GameLoop.cpp b/source/tools/atlas/GameInterface/GameLoop.cpp
index 9eda9c8cda..8ab420c1e6 100644
--- a/source/tools/atlas/GameInterface/GameLoop.cpp
+++ b/source/tools/atlas/GameInterface/GameLoop.cpp
@@ -37,6 +37,10 @@ void (*Atlas_NotifyEndOfFrame)();
static MessagePasserImpl msgPasser_Command;
static MessagePasserImpl msgPasser_Input;
+MessagePasser* AtlasMessage::g_MessagePasser_Command = &msgPasser_Command;
+MessagePasser* AtlasMessage::g_MessagePasser_Input = &msgPasser_Input;
+
+
static InputProcessor g_Input;
static GameLoopState state;
diff --git a/source/tools/atlas/GameInterface/Handlers/Brush.cpp b/source/tools/atlas/GameInterface/Handlers/Brush.cpp
index 2667f3eda0..aa6826425d 100644
--- a/source/tools/atlas/GameInterface/Handlers/Brush.cpp
+++ b/source/tools/atlas/GameInterface/Handlers/Brush.cpp
@@ -6,7 +6,7 @@
namespace AtlasMessage {
-MESSAGEHANDLER(SetBrush)
+MESSAGEHANDLER(Brush)
{
g_CurrentBrush.SetData(msg->width, msg->height, msg->data);
}
diff --git a/source/tools/atlas/GameInterface/Handlers/Elevation.cpp b/source/tools/atlas/GameInterface/Handlers/Elevation.cpp
index f7983218eb..a6efe3ed62 100644
--- a/source/tools/atlas/GameInterface/Handlers/Elevation.cpp
+++ b/source/tools/atlas/GameInterface/Handlers/Elevation.cpp
@@ -49,9 +49,13 @@ BEGIN_COMMAND(AlterElevation)
roundingError -= (float)(int)roundingError;
}
+ static CVector3D previousPosition;
+ d->pos.GetWorldSpace(g_CurrentBrush.m_Centre, previousPosition);
+ previousPosition = g_CurrentBrush.m_Centre;
+
int x0, y0;
- d->pos.GetWorldSpace(g_CurrentBrush.m_Centre);
g_CurrentBrush.GetBottomRight(x0, y0);
+
for (int dy = 0; dy < g_CurrentBrush.m_H; ++dy)
for (int dx = 0; dx < g_CurrentBrush.m_W; ++dx)
{
diff --git a/source/tools/atlas/GameInterface/Handlers/Map.cpp b/source/tools/atlas/GameInterface/Handlers/Map.cpp
index 82e325470b..daf733c79e 100644
--- a/source/tools/atlas/GameInterface/Handlers/Map.cpp
+++ b/source/tools/atlas/GameInterface/Handlers/Map.cpp
@@ -47,7 +47,7 @@ MESSAGEHANDLER(GenerateMap)
for (int z = 0; z < vertices; ++z)
for (int x = 0; x < vertices; ++x)
// heightmap[x + z*vertices] = 32768 +(int)(2048.f*(rand()/(float)RAND_MAX-0.5f));
- heightmap[x + z*vertices] = 32768;
+ heightmap[x + z*vertices] = 16384;
// Initialise terrain using the heightmap
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
diff --git a/source/tools/atlas/GameInterface/MessagePasserImpl.cpp b/source/tools/atlas/GameInterface/MessagePasserImpl.cpp
index 0f51327857..e24ef373f8 100644
--- a/source/tools/atlas/GameInterface/MessagePasserImpl.cpp
+++ b/source/tools/atlas/GameInterface/MessagePasserImpl.cpp
@@ -1,23 +1,25 @@
#include "precompiled.h"
#include "MessagePasserImpl.h"
+#include "Messages.h"
-#define MESSAGE_TRACE 0
-
-#if MESSAGE_TRACE
-#include "Messages.h" // for mCommand implementation
-#endif
+#include "lib/timer.h"
using namespace AtlasMessage;
+template MessagePasserImpl::MessagePasserImpl()
+: m_Trace(false)
+{
+}
+
template void MessagePasserImpl::Add(T* msg)
{
debug_assert(msg);
-#if MESSAGE_TRACE
- debug_printf("Add %s\n", msg->GetType());
-#endif
+ if (m_Trace)
+ debug_printf("%8.3f add message: %s\n", get_time(), msg->GetType());
+
m_Mutex.Lock();
m_Queue.push(msg);
@@ -42,9 +44,7 @@ template T* MessagePasserImpl::Retrieve()
m_Mutex.Unlock();
-#if MESSAGE_TRACE
- if (msg) debug_printf("Retrieved %s\n", msg->GetType());
-#endif
+// if (m_Trace && msg) debug_printf("%8.3f retrieved message: %s\n", get_time(), msg->GetType());
return msg;
}
@@ -57,8 +57,10 @@ template bool MessagePasserImpl::IsEmpty()
return empty;
}
-MessagePasser* g_MessagePasser_Command = NULL;
-MessagePasser* g_MessagePasser_Input = NULL;
+template void MessagePasserImpl::SetTrace(bool t)
+{
+ m_Trace = t;
+}
// Explicit instantiation:
template MessagePasserImpl;
diff --git a/source/tools/atlas/GameInterface/MessagePasserImpl.h b/source/tools/atlas/GameInterface/MessagePasserImpl.h
index 70496838a2..0c991f44fd 100644
--- a/source/tools/atlas/GameInterface/MessagePasserImpl.h
+++ b/source/tools/atlas/GameInterface/MessagePasserImpl.h
@@ -6,11 +6,15 @@
template class MessagePasserImpl : public AtlasMessage::MessagePasser
{
public:
+ MessagePasserImpl();
virtual void Add(T* msg);
virtual T* Retrieve();
virtual bool IsEmpty();
+ void SetTrace(bool t);
+
private:
CMutex m_Mutex;
std::queue m_Queue;
+ bool m_Trace;
};
diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h
index 3973a13c55..fe3e22b200 100644
--- a/source/tools/atlas/GameInterface/Messages.h
+++ b/source/tools/atlas/GameInterface/Messages.h
@@ -36,9 +36,13 @@ COMMAND(RenderStyle,
((bool, wireframe))
);
+COMMAND(MessageTrace,
+ ((bool, enable))
+ );
+
//////////////////////////////////////////////////////////////////////////
-COMMAND(SetBrush,
+COMMAND(Brush,
((int, width)) // number of vertices
((int, height))
((float*, data)) // width*height array, allocated with new[]
diff --git a/source/tools/atlas/GameInterface/MessagesSetup.h b/source/tools/atlas/GameInterface/MessagesSetup.h
index 18f3872b52..591dbad257 100644
--- a/source/tools/atlas/GameInterface/MessagesSetup.h
+++ b/source/tools/atlas/GameInterface/MessagesSetup.h
@@ -26,11 +26,18 @@ struct Position
union {
struct { float x, y, z; } type0; // world-space coordinates
struct { int x, y; } type1; // screen-space coordinates, to be projected onto terrain
+ // type2: "same as previous" (e.g. for elevation-editing when the mouse hasn't moved)
};
+ // Constructs a position with the meaning "same as previous", which is handled
+ // in an unspecified way by various message handlers.
+ static Position Unchanged() { Position p; p.type = 2; return p; }
+
// Only for use in the game, not the UI.
- void GetWorldSpace(CVector3D& vec) const; // (implementation in Misc.cpp)
- void GetScreenSpace(float& x, float& y) const; // (implementation in Misc.cpp)
+ // Implementations in Misc.cpp.
+ void GetWorldSpace(CVector3D& vec) const;
+ void GetWorldSpace(CVector3D& vec, const CVector3D& prev) const;
+ void GetScreenSpace(float& x, float& y) const;
};
//////////////////////////////////////////////////////////////////////////
diff --git a/source/tools/atlas/GameInterface/Misc.cpp b/source/tools/atlas/GameInterface/Misc.cpp
index 992f202dc5..8e1c4e8bb6 100644
--- a/source/tools/atlas/GameInterface/Misc.cpp
+++ b/source/tools/atlas/GameInterface/Misc.cpp
@@ -19,12 +19,29 @@ void AtlasMessage::Position::GetWorldSpace(CVector3D& vec) const
vec = g_Game->GetView()->GetCamera()->GetWorldCoordinates(type1.x, type1.y);
break;
+ case 2:
+ debug_warn("Invalid Position acquisition (unchanged without previous)");
+ vec.Set(0.f, 0.f, 0.f);
+ break;
+
default:
debug_warn("Invalid Position type");
vec.Set(0.f, 0.f, 0.f);
}
}
+void AtlasMessage::Position::GetWorldSpace(CVector3D& vec, const CVector3D& prev) const
+{
+ switch (type)
+ {
+ case 2:
+ vec = prev;
+ break;
+ default:
+ GetWorldSpace(vec);
+ }
+}
+
void AtlasMessage::Position::GetScreenSpace(float& x, float& y) const
{
switch (type)