]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - contrib/bobtoolz/DEntity.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / bobtoolz / DEntity.cpp
index 3719d20e7d07f8c1613890519be115458eb83aee..f4d9f0b16dac5927dc77844115e83f0ef9ba4a81 100644 (file)
@@ -1,74 +1,96 @@
 /*
-BobToolz plugin for GtkRadiant
-Copyright (C) 2001 Gordon Biggans
+   BobToolz plugin for GtkRadiant
+   Copyright (C) 2001 Gordon Biggans
 
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-This library 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
-Lesser General Public License for more details.
+   This library 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
+   Lesser General Public License for more details.
 
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 
 // DEntity.cpp: implementation of the DEntity class.
 //
 //////////////////////////////////////////////////////////////////////
 
-#include "StdAfx.h"
+#include "DEntity.h"
+#include "globaldefs.h"
 
-#ifdef _WIN32
+#if GDEF_COMPILER_MSVC
 #pragma warning(disable : 4786)
 #endif
 
-#include "DEntity.h"
+#include <list>
+#include "str.h"
+
+#include "DPoint.h"
+#include "DPlane.h"
+#include "DBrush.h"
+#include "DEPair.h"
+#include "DPatch.h"
 
 #include "dialogs/dialogs-gtk.h"
 #include "misc.h"
 #include "CPortals.h"
 
-const char* brushEntityList[] = {
-       "worldspawn",
-       "trigger_always",
-       "trigger_hurt",
-       "trigger_multiple",
-       "trigger_push",
-       "trigger_teleport",
-       "func_bobbing",
-       "func_button",
-       "func_door",
-       "func_group",
-       "func_pendulum",
-       "func_plat",
-       "func_rotating",
-       "func_static",
-       "func_timer",
-       "func_train",
-       0
+#include "iundo.h"
+#include "ientity.h"
+#include "ieclass.h"
+
+#include "generic/referencecounted.h"
+
+#include <vector>
+#include <list>
+#include <map>
+#include <algorithm>
+
+#include "scenelib.h"
+
+
+const char *brushEntityList[] = {
+        "worldspawn",
+        "trigger_always",
+        "trigger_hurt",
+        "trigger_multiple",
+        "trigger_push",
+        "trigger_teleport",
+        "func_bobbing",
+        "func_button",
+        "func_door",
+        "func_group",
+        "func_pendulum",
+        "func_plat",
+        "func_rotating",
+        "func_static",
+        "func_timer",
+        "func_train",
+        0
 };
 
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
-DEntity::DEntity(char *classname, int ID)
+DEntity::DEntity(const char *classname, int ID)
 {
-       SetClassname(classname);
-       m_nID = ID;
-       QER_Entity = NULL;
+    SetClassname(classname);
+    m_nID = ID;
+    QER_Entity = NULL;
 }
 
 DEntity::~DEntity()
 {
-       ClearPatches();
-       ClearBrushes();
-       ClearEPairs();
+    ClearPatches();
+    ClearBrushes();
+    ClearEPairs();
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -77,599 +99,607 @@ DEntity::~DEntity()
 
 void DEntity::ClearBrushes()
 {
-       for(list<DBrush *>::const_iterator deadBrush=brushList.begin(); deadBrush!=brushList.end(); deadBrush++)
-       {
-               delete *deadBrush;
-       }
-       brushList.clear();
+    for (std::list<DBrush *>::const_iterator deadBrush = brushList.begin(); deadBrush != brushList.end(); deadBrush++) {
+        delete *deadBrush;
+    }
+    brushList.clear();
 }
 
 void DEntity::ClearPatches()
 {
-       for(list<DPatch *>::const_iterator deadPatch=patchList.begin(); deadPatch!=patchList.end(); deadPatch++)
-       {
-               delete *deadPatch;
-       }
-       patchList.clear();
+    for (std::list<DPatch *>::const_iterator deadPatch = patchList.begin(); deadPatch != patchList.end(); deadPatch++) {
+        delete *deadPatch;
+    }
+    patchList.clear();
 }
 
-DPatchDEntity::NewPatch()
+DPatch *DEntity::NewPatch()
 {
-       DPatch* newPatch = new DPatch;
+    DPatch *newPatch = new DPatch;
 
-       patchList.push_back(newPatch);
+    patchList.push_back(newPatch);
 
-       return newPatch;
+    return newPatch;
 }
 
-DBrushDEntity::NewBrush(int ID)
+DBrush *DEntity::NewBrush(int ID)
 {
-       DBrush* newBrush = new DBrush(ID);
+    DBrush *newBrush = new DBrush(ID);
 
-       brushList.push_back(newBrush);
+    brushList.push_back(newBrush);
 
-       return newBrush;
+    return newBrush;
 }
 
-char* getNextBracket(char* s)
+char *getNextBracket(char *s)
 {
-       char* p = s;
-       while(*p)
-       {
-               p++;
-               if(*p == '(')
-                       break;
-       }
+    char *p = s;
+    while (*p) {
+        p++;
+        if (*p == '(') {
+            break;
+        }
+    }
 
-       return p;
+    return p;
 }
 
 bool DEntity::LoadFromPrt(char *filename)
 {
-       CPortals portals;
-       strcpy(portals.fn, filename);
-       portals.Load();
-
-       if(portals.node_count == 0)
-               return FALSE;
-
-       ClearBrushes();
-       ClearEPairs();
-       
-  bool build = false;
-       for(unsigned int i = 0; i < portals.node_count; i++)
-       {
-    build = false;
-               DBrush* brush = NewBrush();
-
-               for(unsigned int j = 0; j < portals.node[i].portal_count; j++)
-               {
-      for(unsigned int k = 0; k < portals.node[i].portal[j].point_count-2; k++) 
-      {
-             vec3_t v1, v2, normal, n;
-             VectorSubtract(portals.node[i].portal[j].point[k+2].p, portals.node[i].portal[j].point[k+1].p, v1);
-             VectorSubtract(portals.node[i].portal[j].point[k].p, portals.node[i].portal[j].point[k+1].p, v2);
-             CrossProduct(v1, v2, n);
-        VectorNormalize(n, v2);
-
-        if(k == 0) 
-        {
-          VectorCopy(v2, normal);
+    CPortals portals;
+    strcpy(portals.fn, filename);
+    portals.Load();
+
+    if (portals.node_count == 0) {
+        return false;
+    }
+
+    ClearBrushes();
+    ClearEPairs();
+
+    bool build = false;
+    for (unsigned int i = 0; i < portals.node_count; i++) {
+        build = false;
+        DBrush *brush = NewBrush();
+
+        for (unsigned int j = 0; j < portals.node[i].portal_count; j++) {
+            for (unsigned int k = 0; k < portals.node[i].portal[j].point_count - 2; k++) {
+                vec3_t v1, v2, normal, n;
+                VectorSubtract(portals.node[i].portal[j].point[k + 2].p, portals.node[i].portal[j].point[k + 1].p, v1);
+                VectorSubtract(portals.node[i].portal[j].point[k].p, portals.node[i].portal[j].point[k + 1].p, v2);
+                CrossProduct(v1, v2, n);
+                VectorNormalize(n, v2);
+
+                if (k == 0) {
+                    VectorCopy(v2, normal);
+                } else {
+                    VectorSubtract(v2, normal, v1);
+                    if (VectorLength(v1) > 0.01) {
+                        build = true;
+                        break;
+                    }
+                }
+            }
+
+            if (!build) {
+                brush->AddFace(portals.node[i].portal[j].point[2].p, portals.node[i].portal[j].point[1].p,
+                               portals.node[i].portal[j].point[0].p, "textures/common/caulk", false);
+            } else {
+                brush->AddFace(portals.node[i].portal[j].point[0].p, portals.node[i].portal[j].point[1].p,
+                               portals.node[i].portal[j].point[2].p, "textures/common/caulk", false);
+            }
         }
-        else
-        {
-          VectorSubtract(v2, normal, v1);
-          if(VectorLength(v1) > 0.01)
-          {
-            build = true;
-            break;
-          }
+        if (build) {
+            brush->BuildInRadiant(false, NULL);
         }
-      }
-
-      if(!build)
-                         brush->AddFace(portals.node[i].portal[j].point[2].p, portals.node[i].portal[j].point[1].p, portals.node[i].portal[j].point[0].p, "textures/common/caulk", FALSE);
-      else
-                         brush->AddFace(portals.node[i].portal[j].point[0].p, portals.node[i].portal[j].point[1].p, portals.node[i].portal[j].point[2].p, "textures/common/caulk", FALSE);
-               }
-    if(build)
-      brush->BuildInRadiant(FALSE, NULL);
-       }
+    }
 
-       return TRUE;
+    return true;
 }
 
-DPlane* DEntity::AddFaceToBrush(vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* faceData, int ID)
+DPlane *DEntity::AddFaceToBrush(vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData *faceData, int ID)
 {
-       DBrush* buildBrush = GetBrushForID(ID);
-       return buildBrush->AddFace(va, vb, vc, faceData);
-       // slow, dont use much
+    DBrush *buildBrush = GetBrushForID(ID);
+    return buildBrush->AddFace(va, vb, vc, faceData);
+    // slow, dont use much
 }
 
-DBrushDEntity::GetBrushForID(int ID)
+DBrush *DEntity::GetBrushForID(int ID)
 {
-       DBrush* buildBrush = NULL;
+    DBrush *buildBrush = NULL;
 
-       for(list<DBrush *>::const_iterator chkBrush=brushList.begin(); chkBrush!=brushList.end(); chkBrush++)
-       {
-               if((*chkBrush)->m_nBrushID == ID)
-               {
-                       buildBrush = (*chkBrush);
-                       break;
-               }
-       }
+    for (std::list<DBrush *>::const_iterator chkBrush = brushList.begin(); chkBrush != brushList.end(); chkBrush++) {
+        if ((*chkBrush)->m_nBrushID == ID) {
+            buildBrush = (*chkBrush);
+            break;
+        }
+    }
 
-       if(!buildBrush)
-               buildBrush = NewBrush(ID);
+    if (!buildBrush) {
+        buildBrush = NewBrush(ID);
+    }
 
-       return buildBrush;
+    return buildBrush;
 }
 
-void DEntity::LoadSelectedBrushes()
-{
-       ClearBrushes();
-       ClearEPairs();
-
-       int count = g_FuncTable.m_pfnAllocateSelectedBrushHandles();
-
-       for(int i = 0; i < count; i++) {
-               brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetSelectedBrushHandle(i);
+template<typename Functor>
+class BrushSelectedVisitor : public SelectionSystem::Visitor {
+    const Functor &m_functor;
+public:
+    BrushSelectedVisitor(const Functor &functor) : m_functor(functor)
+    {
+    }
 
-               if(brush->pPatch)
-                       continue;
+    void visit(scene::Instance &instance) const
+    {
+        if (Node_isBrush(instance.path().top())) {
+            m_functor(instance);
+        }
+    }
+};
 
-               DBrush* loadBrush = NewBrush(i);
-               loadBrush->LoadFromBrush_t(brush, TRUE);
-       }
+template<typename Functor>
+inline const Functor &Scene_forEachSelectedBrush(const Functor &functor)
+{
+    GlobalSelectionSystem().foreachSelected(BrushSelectedVisitor<Functor>(functor));
+    return functor;
+}
 
-       g_FuncTable.m_pfnReleaseSelectedBrushHandles();
+void DEntity_loadBrush(DEntity &entity, scene::Instance &brush)
+{
+    DBrush *loadBrush = entity.NewBrush(static_cast<int>( entity.brushList.size()));
+    loadBrush->LoadFromBrush(brush, true);
 }
 
-void DEntity::LoadSelectedPatches()
+typedef ReferenceCaller<DEntity, void(scene::Instance &), DEntity_loadBrush> DEntityLoadBrushCaller;
+
+void DEntity::LoadSelectedBrushes()
 {
-       ClearPatches();
-       ClearEPairs();
+    ClearBrushes();
+    ClearEPairs();
 
-  int count = g_FuncTable.m_pfnAllocateSelectedPatchHandles();
+    Scene_forEachSelectedBrush(DEntityLoadBrushCaller(*this));
+}
 
-       for(int i = 0; i < count; i++)
-       {
-    //$ FIXME: m_pfnGetPatchHandle
-               patchMesh_t *pmesh = (patchMesh_t*)g_FuncTable.m_pfnGetPatchData(i);
+template<typename Functor>
+class PatchSelectedVisitor : public SelectionSystem::Visitor {
+    const Functor &m_functor;
+public:
+    PatchSelectedVisitor(const Functor &functor) : m_functor(functor)
+    {
+    }
 
-               DPatch* loadPatch = NewPatch();
-               loadPatch->LoadFromBrush_t(pmesh->pSymbiot);
-       }
+    void visit(scene::Instance &instance) const
+    {
+        if (Node_isPatch(instance.path().top())) {
+            m_functor(instance);
+        }
+    }
+};
 
-  g_FuncTable.m_pfnReleasePatchHandles();
+template<typename Functor>
+inline const Functor &Scene_forEachSelectedPatch(const Functor &functor)
+{
+    GlobalSelectionSystem().foreachSelected(PatchSelectedVisitor<Functor>(functor));
+    return functor;
 }
 
-bool* DEntity::BuildIntersectList()
+void DEntity_loadPatch(DEntity &entity, scene::Instance &patch)
 {
-       int max = GetIDMax();
-       if(max == 0)
-               return NULL;
+    DPatch *loadPatch = entity.NewPatch();
+    loadPatch->LoadFromPatch(patch);
+}
 
-       bool* pbIntList = new bool[max];
-       memset(pbIntList, 0, sizeof(bool)*(max));
+typedef ReferenceCaller<DEntity, void(scene::Instance &), DEntity_loadPatch> DEntityLoadPatchCaller;
 
-       for(list<DBrush *>::const_iterator pB1=brushList.begin(); pB1!=brushList.end(); pB1++)
-       {
-               list<DBrush *>::const_iterator pB2=pB1;
-               for(pB2++; pB2!=brushList.end(); pB2++)
-               {
-                       if((*pB1)->IntersectsWith((*pB2)))
-                       {
-                               pbIntList[(*pB1)->m_nBrushID] = TRUE;
-                               pbIntList[(*pB2)->m_nBrushID] = TRUE;
-                       }
-               }
-       }
+void DEntity::LoadSelectedPatches()
+{
+    ClearPatches();
+    ClearEPairs();
 
-       return pbIntList;
+    Scene_forEachSelectedPatch(DEntityLoadPatchCaller(*this));
 }
 
-bool* DEntity::BuildDuplicateList()
+bool *DEntity::BuildIntersectList()
 {
-       int max = GetIDMax();
-       if(max == 0)
-               return NULL;
+    int max = GetIDMax();
+    if (max == 0) {
+        return NULL;
+    }
 
-       bool* pbDupList = new bool[max];
-       memset(pbDupList, 0, sizeof(bool)*(max));
+    bool *pbIntList = new bool[max];
+    memset(pbIntList, 0, sizeof(bool) * (max));
 
-       for(list<DBrush *>::const_iterator pB1=brushList.begin(); pB1!=brushList.end(); pB1++)
-       {
-               list<DBrush *>::const_iterator pB2=pB1;
-               for(pB2++; pB2!=brushList.end(); pB2++)
-               {
-                       if(**pB1 == *pB2)
-                       {
-                               pbDupList[(*pB1)->m_nBrushID] = TRUE;
-                               pbDupList[(*pB2)->m_nBrushID] = TRUE;
-                       }
-               }
-       }
+    for (std::list<DBrush *>::const_iterator pB1 = brushList.begin(); pB1 != brushList.end(); pB1++) {
+        std::list<DBrush *>::const_iterator pB2 = pB1;
+        for (pB2++; pB2 != brushList.end(); pB2++) {
+            if ((*pB1)->IntersectsWith((*pB2))) {
+                pbIntList[(*pB1)->m_nBrushID] = true;
+                pbIntList[(*pB2)->m_nBrushID] = true;
+            }
+        }
+    }
 
-       return pbDupList;
+    return pbIntList;
 }
 
-void DEntity::SelectBrushes(bool *selectList)
+bool *DEntity::BuildDuplicateList()
 {
-       if(selectList == NULL)
-               return;
-
-       g_FuncTable.m_pfnDeselectAllBrushes();
+    int max = GetIDMax();
+    if (max == 0) {
+        return NULL;
+    }
 
-       g_FuncTable.m_pfnAllocateActiveBrushHandles();
+    bool *pbDupList = new bool[max];
+    memset(pbDupList, 0, sizeof(bool) * (max));
 
-       for(std::list<DBrush *>::const_iterator pBrush=brushList.begin(); pBrush!=brushList.end(); pBrush++)
-       {
-               if(selectList[(*pBrush)->m_nBrushID])
-                       g_FuncTable.m_pfnSelectBrush((*pBrush)->QER_brush);
-       }
-       g_FuncTable.m_pfnReleaseActiveBrushHandles();
-}
+    for (std::list<DBrush *>::const_iterator pB1 = brushList.begin(); pB1 != brushList.end(); pB1++) {
+        std::list<DBrush *>::const_iterator pB2 = pB1;
+        for (pB2++; pB2 != brushList.end(); pB2++) {
+            if (**pB1 == *pB2) {
+                pbDupList[(*pB1)->m_nBrushID] = true;
+                pbDupList[(*pB2)->m_nBrushID] = true;
+            }
+        }
+    }
 
-bool DEntity::LoadFromEntity(int id, bool bLoadPatches) {
-       return LoadFromEntity((entity_t*)g_FuncTable.m_pfnGetEntityHandle(id), bLoadPatches);
+    return pbDupList;
 }
 
-bool DEntity::LoadFromEntity(entity_t* ent, bool bLoadPatches) {
-       ClearPatches();
-       ClearBrushes();
-       ClearEPairs();
-
-       QER_Entity = ent;
+void DEntity::SelectBrushes(bool *selectList)
+{
+    if (selectList == NULL) {
+        return;
+    }
 
-       epair_t* epl = *g_EntityTable.m_pfnGetEntityKeyValList(QER_Entity);
-       LoadEPairList(epl);
+    GlobalSelectionSystem().setSelectedAll(false);
 
-       bool keep = FALSE;
-       int i;
-       for(i = 0; brushEntityList[i]; i++)
-       {
-               if(!stricmp(brushEntityList[i], m_Classname))
-               {
-                       keep = TRUE;
-                       break;
-               }
-       }
+    scene::Path path(NodeReference(GlobalSceneGraph().root()));
+    path.push(NodeReference(*QER_Entity));
 
-       if(!keep)
-               return FALSE;
+    for (std::list<DBrush *>::const_iterator pBrush = brushList.begin(); pBrush != brushList.end(); pBrush++) {
+        if (selectList[(*pBrush)->m_nBrushID]) {
+            path.push(NodeReference(*(*pBrush)->QER_brush));
+            Instance_getSelectable(*GlobalSceneGraph().find(path))->setSelected(true);
+            path.pop();
+        }
+    }
+}
 
-       int count = g_FuncTable.m_pfnAllocateEntityBrushHandles(QER_Entity);
+bool DEntity::LoadFromEntity(scene::Node &ent, bool bLoadPatches)
+{
+    ClearPatches();
+    ClearBrushes();
+    ClearEPairs();
 
-       for(i = 0; i < count; i++)
-       {
+    QER_Entity = &ent;
 
-               brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetEntityBrushHandle(i);
+    LoadEPairList(Node_getEntity(ent));
 
-    if(brush == NULL) {
-                       DoMessageBox("GTKRadiant returned a NULL pointer, NOT a good sign", "WARNING!!!", MB_OK);
-      continue;
+    bool keep = false;
+    int i;
+    for (i = 0; brushEntityList[i]; i++) {
+        if (string_equal_nocase(brushEntityList[i], m_Classname)) {
+            keep = true;
+            break;
+        }
     }
 
-               if(brush->pPatch)
-               {
-                       if(bLoadPatches)
-                       {
-                               DPatch* loadPatch = NewPatch();
-                               loadPatch->LoadFromBrush_t(brush);
-                       }
-               }
-               else
-               {
-                       DBrush* loadBrush = NewBrush(i);
-                       loadBrush->LoadFromBrush_t(brush, TRUE);
-               }
-       }
+    if (!keep) {
+        return false;
+    }
 
-       g_FuncTable.m_pfnReleaseEntityBrushHandles();
+    if (Node_getTraversable(ent)) {
+        class load_brushes_t : public scene::Traversable::Walker {
+            DEntity *m_entity;
+            mutable int m_count;
+        public:
+            load_brushes_t(DEntity *entity)
+                    : m_entity(entity), m_count(0)
+            {
+            }
+
+            bool pre(scene::Node &node) const
+            {
+                scene::Path path(NodeReference(GlobalSceneGraph().root()));
+                path.push(NodeReference(*m_entity->QER_Entity));
+                path.push(NodeReference(node));
+                scene::Instance *instance = GlobalSceneGraph().find(path);
+                ASSERT_MESSAGE(instance != 0, "");
+
+                if (Node_isPatch(node)) {
+                    DPatch *loadPatch = m_entity->NewPatch();
+                    loadPatch->LoadFromPatch(*instance);
+                } else if (Node_isBrush(node)) {
+                    DBrush *loadBrush = m_entity->NewBrush(m_count++);
+                    loadBrush->LoadFromBrush(*instance, true);
+                }
+                return false;
+            }
+        } load_brushes(this);
+
+        Node_getTraversable(ent)->traverse(load_brushes);
+    }
 
-       return TRUE;
+    return true;
 }
 
-void DEntity::RemoveNonCheckBrushes(list<Str>* exclusionList, bool useDetail)
+void DEntity::RemoveNonCheckBrushes(std::list<Str> *exclusionList, bool useDetail)
 {
-       list<DBrush *>::iterator chkBrush=brushList.begin();
-
-       while( chkBrush!=brushList.end() )
-       {
-               if(!useDetail)
-               {
-                       if((*chkBrush)->IsDetail())
-                       {
-                               delete *chkBrush;
-                               chkBrush = brushList.erase(chkBrush);
-                               continue;
-                       }
-               }
+    std::list<DBrush *>::iterator chkBrush = brushList.begin();
+
+    while (chkBrush != brushList.end()) {
+        if (!useDetail) {
+            if ((*chkBrush)->IsDetail()) {
+                delete *chkBrush;
+                chkBrush = brushList.erase(chkBrush);
+                continue;
+            }
+        }
 
-               list<Str>::iterator eTexture;
+        std::list<Str>::iterator eTexture;
 
-               for( eTexture=exclusionList->begin(); eTexture!=exclusionList->end(); eTexture++ )
-               {
-                       if((*chkBrush)->HasTexture((*eTexture).GetBuffer()))
-                       {
-                               delete *chkBrush;
-                               chkBrush = brushList.erase(chkBrush);
-                               break;
-                       }
-               }
+        for (eTexture = exclusionList->begin(); eTexture != exclusionList->end(); eTexture++) {
+            if ((*chkBrush)->HasTexture((*eTexture).GetBuffer())) {
+                delete *chkBrush;
+                chkBrush = brushList.erase(chkBrush);
+                break;
+            }
+        }
 
-               if( eTexture == exclusionList->end() )
-                       chkBrush++;
-       }
+        if (eTexture == exclusionList->end()) {
+            chkBrush++;
+        }
+    }
 }
 
-void DEntity::ResetChecks(list<Str>* exclusionList)
+void DEntity::ResetChecks(std::list<Str> *exclusionList)
 {
-       for(list<DBrush *>::const_iterator resetBrush=brushList.begin(); resetBrush!=brushList.end(); resetBrush++)
-       {
-               (*resetBrush)->ResetChecks(exclusionList);
-       }
+    for (std::list<DBrush *>::const_iterator resetBrush = brushList.begin();
+         resetBrush != brushList.end(); resetBrush++) {
+        (*resetBrush)->ResetChecks(exclusionList);
+    }
 }
 
-int DEntity::FixBrushes(bool rebuild)
+int DEntity::FixBrushes()
 {
-       g_FuncTable.m_pfnAllocateActiveBrushHandles();
-
-       int cnt = 0;
+    int count = 0;
 
-       for(list<DBrush *>::const_iterator fixBrush=brushList.begin(); fixBrush!=brushList.end(); fixBrush++)
-       {
-               int count = (*fixBrush)->RemoveRedundantPlanes();
-               if(count)
-               {
-                       cnt += count;
-                       if(rebuild)
-                       {
-                               g_FuncTable.m_pfnDeleteBrushHandle((*fixBrush)->QER_brush);
-
-                               (*fixBrush)->BuildInRadiant(FALSE, NULL);
-                       }
-               }
-       }
-
-       g_FuncTable.m_pfnReleaseActiveBrushHandles();
+    for (std::list<DBrush *>::const_iterator fixBrush = brushList.begin(); fixBrush != brushList.end(); fixBrush++) {
+        count += (*fixBrush)->RemoveRedundantPlanes();
+    }
 
-       return cnt;
+    return count;
 }
 
 void DEntity::BuildInRadiant(bool allowDestruction)
 {
-       bool makeEntity = strcmp(m_Classname, "worldspawn") ? true : false;
+    bool makeEntity = strcmp(m_Classname, "worldspawn") ? true : false;
 
-       if(makeEntity)
-       {
-               entity_t* pE = (entity_t*)g_FuncTable.m_pfnCreateEntityHandle();
+    if (makeEntity) {
+        NodeSmartReference node(GlobalEntityCreator().createEntity(
+                GlobalEntityClassManager().findOrInsert(m_Classname.GetBuffer(),
+                                                        !brushList.empty() || !patchList.empty())));
 
-               epair_t* pEpS = GetNextChainItem(NULL, "classname", m_Classname);
-
-               epair_t* pEp = pEpS;
-
-               for(list<DEPair* >::const_iterator buildEPair=epairList.begin(); buildEPair!=epairList.end(); buildEPair++)
-               {
-                       pEp = GetNextChainItem(pEp, (*buildEPair)->key, (*buildEPair)->value);
-               }
-
-               g_EntityTable.m_pfnSetEntityKeyValList(pE, pEpS);
+        for (std::list<DEPair *>::const_iterator buildEPair = epairList.begin();
+             buildEPair != epairList.end(); buildEPair++) {
+            Node_getEntity(node)->setKeyValue((*buildEPair)->key, (*buildEPair)->value);
+        }
 
-               g_FuncTable.m_pfnCommitEntityHandleToMap(pE);
+        Node_getTraversable(GlobalSceneGraph().root())->insert(node);
 
-               for(list<DBrush *>::const_iterator buildBrush=brushList.begin(); buildBrush!=brushList.end(); buildBrush++)
-                       (*buildBrush)->BuildInRadiant(allowDestruction, NULL, pE);
+        for (std::list<DBrush *>::const_iterator buildBrush = brushList.begin();
+             buildBrush != brushList.end(); buildBrush++) {
+                 (*buildBrush)->BuildInRadiant(allowDestruction, NULL, node.get_pointer());
+        }
 
-               for(list<DPatch *>::const_iterator buildPatch=patchList.begin(); buildPatch!=patchList.end(); buildPatch++)
-                       (*buildPatch)->BuildInRadiant(pE);
+        for (std::list<DPatch *>::const_iterator buildPatch = patchList.begin();
+             buildPatch != patchList.end(); buildPatch++) {
+                 (*buildPatch)->BuildInRadiant(node.get_pointer());
+        }
 
-               QER_Entity = pE;
-       }
-       else
-       {
-               for(list<DBrush *>::const_iterator buildBrush=brushList.begin(); buildBrush!=brushList.end(); buildBrush++)
-                       (*buildBrush)->BuildInRadiant(allowDestruction, NULL);
+        QER_Entity = node.get_pointer();
+    } else {
+        for (std::list<DBrush *>::const_iterator buildBrush = brushList.begin();
+             buildBrush != brushList.end(); buildBrush++) {
+                 (*buildBrush)->BuildInRadiant(allowDestruction, NULL);
+        }
 
-               for(list<DPatch *>::const_iterator buildPatch=patchList.begin(); buildPatch!=patchList.end(); buildPatch++)
-                       (*buildPatch)->BuildInRadiant();
-       }
+        for (std::list<DPatch *>::const_iterator buildPatch = patchList.begin();
+             buildPatch != patchList.end(); buildPatch++) {
+                 (*buildPatch)->BuildInRadiant();
+        }
+    }
 }
 
 
-
-int DEntity::GetIDMax( void ) {
-       int max = -1;
-       for(list<DBrush *>::const_iterator cntBrush=brushList.begin(); cntBrush!=brushList.end(); cntBrush++) {
-               if((*cntBrush)->m_nBrushID > max)
-                       max = (*cntBrush)->m_nBrushID;
-       }
-       return max+1;
+int DEntity::GetIDMax(void)
+{
+    int max = -1;
+    for (std::list<DBrush *>::const_iterator cntBrush = brushList.begin(); cntBrush != brushList.end(); cntBrush++) {
+        if ((*cntBrush)->m_nBrushID > max) {
+            max = (*cntBrush)->m_nBrushID;
+        }
+    }
+    return max + 1;
 }
 
-void DEntity::SetClassname( char *classname ) {
-       m_Classname = classname;
+void DEntity::SetClassname(const char *classname)
+{
+    m_Classname = classname;
 }
 
 void DEntity::SaveToFile(FILE *pFile)
 {
-       fprintf(pFile, "{\n");
+    fprintf(pFile, "{\n");
 
-       fprintf(pFile, "\"classname\" \"%s\"\n", (const char *)m_Classname);
+    fprintf(pFile, "\"classname\" \"%s\"\n", (const char *) m_Classname);
 
-       for(list<DEPair *>::const_iterator ep=epairList.begin(); ep!=epairList.end(); ep++)
-       {
-               fprintf(pFile, "\"%s\" \"%s\"\n", (const char *)(*ep)->key, (const char *)(*ep)->value);
-       }
+    for (std::list<DEPair *>::const_iterator ep = epairList.begin(); ep != epairList.end(); ep++) {
+        fprintf(pFile, "\"%s\" \"%s\"\n", (const char *) (*ep)->key, (const char *) (*ep)->value);
+    }
 
-       for(list<DBrush *>::const_iterator bp=brushList.begin(); bp!=brushList.end(); bp++)
-       {
-               (*bp)->SaveToFile(pFile);
-       }
+    for (std::list<DBrush *>::const_iterator bp = brushList.begin(); bp != brushList.end(); bp++) {
+        (*bp)->SaveToFile(pFile);
+    }
 
-       fprintf(pFile, "}\n");
+    fprintf(pFile, "}\n");
 }
 
 void DEntity::ClearEPairs()
 {
-       for(list<DEPair *>::const_iterator deadEPair=epairList.begin(); deadEPair!=epairList.end(); deadEPair++)
-       {
-               delete (*deadEPair);
-       }
-       epairList.clear();
-}
-
-void DEntity::AddEPair(char *key, char *value) {       
-       DEPair* newEPair; 
-       newEPair = FindEPairByKey( key );
-       if(!newEPair) {
-               newEPair = new DEPair;
-               newEPair->Build(key, value);
-               epairList.push_back(newEPair);
-       } else {
-               newEPair->Build(key, value);
-       }
+    for (std::list<DEPair *>::const_iterator deadEPair = epairList.begin(); deadEPair != epairList.end(); deadEPair++) {
+        delete (*deadEPair);
+    }
+    epairList.clear();
 }
 
-void DEntity::LoadEPairList(epair_t *epl)
+void DEntity::AddEPair(const char *key, const char *value)
 {
-       epair_t* ep = epl;
-       while(ep)
-       {
-               if(!strcmp(ep->key, "classname"))
-                       SetClassname(ep->value);
-               else    
-                       AddEPair(ep->key, ep->value);
-
-               ep = ep->next;
-       }
+    DEPair *newEPair;
+    newEPair = FindEPairByKey(key);
+    if (!newEPair) {
+        newEPair = new DEPair;
+        newEPair->Build(key, value);
+        epairList.push_back(newEPair);
+    } else {
+        newEPair->Build(key, value);
+    }
 }
 
-bool DEntity::ResetTextures(const char* textureName, float fScale[2],     float fShift[2],    int rotation, const char* newTextureName, 
-                            int bResetTextureName,    int bResetScale[2], int bResetShift[2], int bResetRotation, bool rebuild)
+void DEntity::LoadEPairList(Entity *epl)
 {
-       g_FuncTable.m_pfnDeselectAllBrushes();
-
-       g_FuncTable.m_pfnAllocateActiveBrushHandles();
-
-       bool reset = FALSE;
-
-       for(list<DBrush *>::const_iterator resetBrush=brushList.begin(); resetBrush!=brushList.end(); resetBrush++)
-       {
-               bool tmp = (*resetBrush)->ResetTextures(textureName,        fScale,       fShift,       rotation, newTextureName, 
-                                            bResetTextureName,  bResetScale,  bResetShift,  bResetRotation);
-
-               if(tmp)
-               {
-                       reset = TRUE;
-
-                       if(rebuild)
-                       {
-        entity_t *pE = (*resetBrush)->QER_brush->owner;       
-                               g_FuncTable.m_pfnDeleteBrushHandle((*resetBrush)->QER_brush);
-        (*resetBrush)->BuildInRadiant(FALSE, NULL, pE->entityId == 0 ? NULL : pE);
+    class load_epairs_t : public Entity::Visitor {
+        DEntity *m_entity;
+    public:
+        load_epairs_t(DEntity *entity)
+                : m_entity(entity)
+        {
+        }
 
-        if( pE->entityId == 0 ? NULL : pE )
+        void visit(const char *key, const char *value)
         {
+            if (strcmp(key, "classname") == 0) {
+                m_entity->SetClassname(value);
+            } else {
+                m_entity->AddEPair(key, value);
+            }
         }
-                       }
-               }
-       }
 
-  if(bResetTextureName)
-  {
-         for(list<DPatch *>::const_iterator resetPatch=patchList.begin(); resetPatch!=patchList.end(); resetPatch++)
-         {
-                 bool tmp = (*resetPatch)->ResetTextures(textureName, newTextureName);
+    } load_epairs(this);
 
-                 if(tmp)
-                 {
-                         reset = TRUE;
+    epl->forEachKeyValue(load_epairs);
+}
 
-                         if(rebuild)
-                         {
-          entity_t *pE = (*resetPatch)->QER_brush->owner;       
-                                 g_FuncTable.m_pfnDeleteBrushHandle((*resetPatch)->QER_brush);
-          (*resetPatch)->BuildInRadiant(pE->entityId == 0 ? NULL : pE);
-                         }
-                 }
-         }
-  }
+bool DEntity::ResetTextures(const char *textureName, float fScale[2], float fShift[2], int rotation,
+                            const char *newTextureName,
+                            int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation,
+                            bool rebuild)
+{
+    bool reset = false;
+
+    for (std::list<DBrush *>::const_iterator resetBrush = brushList.begin();
+         resetBrush != brushList.end(); resetBrush++) {
+        bool tmp = (*resetBrush)->ResetTextures(textureName, fScale, fShift, rotation, newTextureName,
+                                                bResetTextureName, bResetScale, bResetShift, bResetRotation);
+
+        if (tmp) {
+            reset = true;
+            if (rebuild) {
+                Node_getTraversable(*(*resetBrush)->QER_entity)->erase(*(*resetBrush)->QER_brush);
+                (*resetBrush)->BuildInRadiant(false, NULL, (*resetBrush)->QER_entity);
+            }
+        }
+    }
 
-       g_FuncTable.m_pfnReleaseActiveBrushHandles();
+    if (bResetTextureName) {
+        for (std::list<DPatch *>::const_iterator resetPatch = patchList.begin();
+             resetPatch != patchList.end(); resetPatch++) {
+            bool tmp = (*resetPatch)->ResetTextures(textureName, newTextureName);
+
+            if (tmp) {
+                reset = true;
+                if (rebuild) {
+                    Node_getTraversable(*(*resetPatch)->QER_entity)->erase(*(*resetPatch)->QER_brush);
+                    (*resetPatch)->BuildInRadiant((*resetPatch)->QER_entity);
+                }
+            }
+        }
+    }
 
-       return reset;
+    return reset;
 }
 
-DEPair* DEntity::FindEPairByKey(const char* keyname)
+DEPair *DEntity::FindEPairByKey(const char *keyname)
 {
-       for(list<DEPair *>::const_iterator ep=epairList.begin(); ep!=epairList.end(); ep++)
-       {
-               char* c = (*ep)->key;
-               if(!strcmp(c, keyname))
-                       return *ep;
-       }
-       return NULL;
+    for (std::list<DEPair *>::const_iterator ep = epairList.begin(); ep != epairList.end(); ep++) {
+        char *c = (*ep)->key;
+        if (!strcmp(c, keyname)) {
+            return *ep;
+        }
+    }
+    return NULL;
 }
 
 void DEntity::RemoveFromRadiant()
 {
-       g_EntityTable.m_pfnEntity_Free( (entity_t*)QER_Entity );
+    Node_getTraversable(GlobalSceneGraph().root())->erase(*QER_Entity);
 
-       QER_Entity = NULL;
+    QER_Entity = NULL;
 }
 
-void DEntity::SpawnString(const char* key, const char* defaultstring, const char** out)
+void DEntity::SpawnString(const char *key, const char *defaultstring, const char **out)
 {
-       DEPair* pEP = FindEPairByKey(key);
-       if(pEP) {
-               *out = pEP->value;
-       } else {
-               *out = defaultstring;
-       }
+    DEPair *pEP = FindEPairByKey(key);
+    if (pEP) {
+        *out = pEP->value;
+    } else {
+        *out = defaultstring;
+    }
 }
 
-void DEntity::SpawnInt(const char* key, const char* defaultstring, int* out)
+void DEntity::SpawnInt(const char *key, const char *defaultstring, int *out)
 {
-       DEPair* pEP = FindEPairByKey(key);
-       if(pEP) {
-               *out = atoi(pEP->value);
-       } else {
-               *out = atoi(defaultstring);
-       }
+    DEPair *pEP = FindEPairByKey(key);
+    if (pEP) {
+        *out = atoi(pEP->value);
+    } else {
+        *out = atoi(defaultstring);
+    }
 }
 
-void DEntity::SpawnFloat(const char* key, const char* defaultstring, float* out)
+void DEntity::SpawnFloat(const char *key, const char *defaultstring, float *out)
 {
-       DEPair* pEP = FindEPairByKey(key);
-       if(pEP) {
-               *out = static_cast< float >( atof( pEP->value ) );
-       } else {
-               *out = static_cast< float >( atof(defaultstring) );
-       }
+    DEPair *pEP = FindEPairByKey(key);
+    if (pEP) {
+        *out = static_cast<float>( atof(pEP->value));
+    } else {
+        *out = static_cast<float>( atof(defaultstring));
+    }
 }
 
-void DEntity::SpawnVector(const char* key, const char* defaultstring, vec_t* out)
+void DEntity::SpawnVector(const char *key, const char *defaultstring, vec_t *out)
 {
-       DEPair* pEP = FindEPairByKey(key);
-       if(pEP) {
-               sscanf(pEP->value, "%f %f %f", &out[0], &out[1], &out[2]);
-       } else {
-               sscanf(defaultstring, "%f %f %f", &out[0], &out[1], &out[2]);
-       }
+    DEPair *pEP = FindEPairByKey(key);
+    if (pEP) {
+        sscanf(pEP->value, "%f %f %f", &out[0], &out[1], &out[2]);
+    } else {
+        sscanf(defaultstring, "%f %f %f", &out[0], &out[1], &out[2]);
+    }
 }
 
-int DEntity::GetBrushCount( void ) {
-       return brushList.size();
+int DEntity::GetBrushCount(void)
+{
+    return static_cast<int>( brushList.size());
 }
 
-DBrush* DEntity::FindBrushByPointer( brush_t* brush ) {
-       for(list<DBrush *>::const_iterator listBrush = brushList.begin(); listBrush != brushList.end(); listBrush++) {
-               DBrush* pBrush = (*listBrush);
-               if(pBrush->QER_brush == brush) {
-                       return pBrush;
-               }
-       }
-       return NULL;
+DBrush *DEntity::FindBrushByPointer(scene::Node &brush)
+{
+    for (std::list<DBrush *>::const_iterator listBrush = brushList.begin(); listBrush != brushList.end(); listBrush++) {
+        DBrush *pBrush = (*listBrush);
+        if (pBrush->QER_brush == &brush) {
+            return pBrush;
+        }
+    }
+    return NULL;
 }