diff --git a/proj/sxgame/vs2013/sxgame.vcxproj b/proj/sxgame/vs2013/sxgame.vcxproj
index fed316c00790aab5a2a61029057c26bc4a5ba285..c6d0cbd4b2f4bce1c8356195b9170b70b6a95fbd 100644
--- a/proj/sxgame/vs2013/sxgame.vcxproj
+++ b/proj/sxgame/vs2013/sxgame.vcxproj
@@ -196,6 +196,7 @@
     <ClCompile Include="..\..\..\source\game\EditorOutputsTab.cpp" />
     <ClCompile Include="..\..\..\source\game\EntityFactory.cpp" />
     <ClCompile Include="..\..\..\source\game\EntityManager.cpp" />
+    <ClCompile Include="..\..\..\source\game\EntityPointer.cpp" />
     <ClCompile Include="..\..\..\source\game\EnvSkybox.cpp" />
     <ClCompile Include="..\..\..\source\game\FuncRotating.cpp" />
     <ClCompile Include="..\..\..\source\game\FuncTrain.cpp" />
@@ -267,6 +268,7 @@
     <ClInclude Include="..\..\..\source\game\EditorExtension.h" />
     <ClInclude Include="..\..\..\source\game\EditorObject.h" />
     <ClInclude Include="..\..\..\source\game\EditorOutputsTab.h" />
+    <ClInclude Include="..\..\..\source\game\EntityPointer.h" />
     <ClInclude Include="..\..\..\source\game\EnvSkybox.h" />
     <ClInclude Include="..\..\..\source\game\FuncRotating.h" />
     <ClInclude Include="..\..\..\source\game\GameStateManager.h" />
diff --git a/proj/sxgame/vs2013/sxgame.vcxproj.filters b/proj/sxgame/vs2013/sxgame.vcxproj.filters
index b56011f928a25960c1a89f27dddcc5c7969112e0..d826392c715d3701fdb4c19f13d52066ae3513c7 100644
--- a/proj/sxgame/vs2013/sxgame.vcxproj.filters
+++ b/proj/sxgame/vs2013/sxgame.vcxproj.filters
@@ -312,6 +312,9 @@
     <ClCompile Include="..\..\..\source\common\guid.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\source\game\EntityPointer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\source\game\sxgame.h">
@@ -539,6 +542,9 @@
     <ClInclude Include="..\..\..\source\game\SoundEmitter.h">
       <Filter>Header Files\ents\sound</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\source\game\EntityPointer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\..\source\game\sxgame.rc">
diff --git a/source/common b/source/common
index 7ec71171b2e0446fd49751e3ec10176efbdfe867..12785328cefb95553e293d215b37a4cb89cee666 160000
--- a/source/common
+++ b/source/common
@@ -1 +1 @@
-Subproject commit 7ec71171b2e0446fd49751e3ec10176efbdfe867
+Subproject commit 12785328cefb95553e293d215b37a4cb89cee666
diff --git a/source/game/BaseEntity.cpp b/source/game/BaseEntity.cpp
index 42f68bb83186cc50a6430106f26885f5df9109a4..a20c4d1b7996804f159c5c4ae2a4634904209f9d 100644
--- a/source/game/BaseEntity.cpp
+++ b/source/game/BaseEntity.cpp
@@ -43,15 +43,22 @@ REGISTER_ENTITY_NOLISTING(CBaseEntity, base_entity);
 
 void CBaseEntity::setDefaults()
 {
-	proptable_t * pt = getPropTable();
-	const char * estr = GetEmptyString();
+	proptable_t *pt = getPropTable();
+	const char *estr = GetEmptyString();
 	while(pt)
 	{
 		for(int i = 0; i < pt->numFields; ++i)
 		{
-			if(pt->pData[i].type == PDF_STRING && !(pt->pData[i].flags & PDFF_INPUT))
+			if(!(pt->pData[i].flags & PDFF_INPUT))
 			{
-				this->*((const char * ThisClass::*)pt->pData[i].pField) = estr;
+				if(pt->pData[i].type == PDF_STRING)
+				{
+					this->*((const char* ThisClass::*)pt->pData[i].pField) = estr;
+				}
+				else if(pt->pData[i].type == PDF_PARENT)
+				{
+					(this->*((CEntityPointer ThisClass::*)pt->pData[i].pField)).init(m_pMgr, this);
+				}
 			}
 		}
 		pt = pt->pBaseProptable;
@@ -61,6 +68,9 @@ void CBaseEntity::setDefaults()
 CBaseEntity::CBaseEntity()
 {
 	m_pLightSystem = GameData::m_pLightSystem;
+
+	m_pParent.setLinkEstablishedListener(&CBaseEntity::onParentSet);
+	m_pParent.setLinkBrokenListener(&CBaseEntity::onParentUnset);
 }
 
 /*void CBaseEntity::setDefaults()
@@ -104,6 +114,11 @@ CBaseEntity::~CBaseEntity()
 		}
 		pt = pt->pBaseProptable;
 	}
+
+	if(m_pParent)
+	{
+		m_pParent->removeChild(this);
+	}
 }
 
 void CBaseEntity::setClassName(const char * name)
@@ -139,25 +154,24 @@ void CBaseEntity::getSphere(float3 * center, float * radius)
 		radius = 0;
 }
 
-void CBaseEntity::setPos(const float3 & pos)
+void CBaseEntity::setPos(const float3 &pos)
 {
-	CBaseEntity *pParent = NULL;
-	if(m_pParent)
-	{
-		pParent = m_pParent;
-		setParent(NULL);
-	}
 	m_vPosition = pos;
 
+	onParentMoved(true);
+
 	if(m_pEditorRigidBody)
 	{
 		m_pEditorRigidBody->getWorldTransform().setOrigin(F3_BTVEC(m_vPosition));
 		SPhysics_GetDynWorld()->updateSingleAabb(m_pEditorRigidBody);
 	}
 
-	if(pParent)
 	{
-		setParent(pParent, m_iParentAttachment);
+		ScopedSpinLock lock(m_slChildren);
+		for(UINT i = 0, l = m_aChildren.size(); i < l; ++i)
+		{
+			m_aChildren[i]->onParentMoved(m_isSeparateMovement);
+		}
 	}
 }
 
@@ -169,6 +183,16 @@ float3 CBaseEntity::getPos()
 void CBaseEntity::setOrient(const SMQuaternion & q)
 {
 	m_vOrientation = q;
+
+	onParentMoved(true);
+
+	{
+		ScopedSpinLock lock(m_slChildren);
+		for(UINT i = 0, l = m_aChildren.size(); i < l; ++i)
+		{
+			m_aChildren[i]->onParentMoved(m_isSeparateMovement);
+		}
+	}
 }
 void CBaseEntity::setOffsetOrient(const SMQuaternion & q)
 {
@@ -190,6 +214,32 @@ SMQuaternion CBaseEntity::getOrient()
 	return(m_vOrientation);
 }
 
+void CBaseEntity::onParentMoved(bool bAdjustOffsets)
+{
+	if(!m_pParent || m_isInOnParentMoved)
+	{
+		return;
+	}
+
+	m_isInOnParentMoved = true;
+
+	float3 vParentPos = ID_VALID(m_iParentAttachment) ? m_pParent->getAttachmentPos(m_iParentAttachment) : m_pParent->getPos();
+	SMQuaternion qParentOrient = ID_VALID(m_iParentAttachment) ? m_pParent->getAttachmentRot(m_iParentAttachment) : m_pParent->getOrient();
+
+	if(bAdjustOffsets)
+	{
+		m_vOffsetPos = (float3)(qParentOrient.Conjugate() * (m_vPosition - vParentPos));
+		m_vOffsetOrient = m_vOrientation * qParentOrient.Conjugate();
+	}
+	else
+	{
+		setPos(vParentPos + qParentOrient * m_vOffsetPos);
+		setOrient(m_vOffsetOrient * qParentOrient);
+	}
+
+	m_isInOnParentMoved = false;
+}
+
 UINT CBaseEntity::getFlags()
 {
 	return(m_iFlags);
@@ -335,8 +385,10 @@ bool CBaseEntity::setKV(const char * name, const char * value)
 			return(true);
 		}
 		return(false);
-	case PDF_ENTITY:
 	case PDF_PARENT:
+		(this->*((CEntityPointer ThisClass::*)field->pField)).setEntityName(value);
+		break;
+	case PDF_ENTITY:
 		pEnt = m_pMgr->findEntityByName(value);
 		if(pEnt || !value[0])
 		{
@@ -492,9 +544,11 @@ bool CBaseEntity::getKV(const char * name, char * out, int bufsize)
 		//f3 = SMMatrixToEuler(q.GetMatrix());
 		sprintf_s(out, bufsize, "%f %f %f %f", q.x, q.y, q.z, q.w);
 		break;
-	case PDF_ENTITY:
 	case PDF_PARENT:
-		pEnt = this->*((CBaseEntity * ThisClass::*)field->pField);
+		(this->*((CEntityPointer ThisClass::*)field->pField)).getEntityName(out, bufsize);
+		break;
+	case PDF_ENTITY:
+		pEnt = this->*((CBaseEntity* ThisClass::*)field->pField);
 		if(!pEnt)
 		{
 			sprintf_s(out, bufsize, "");
@@ -554,21 +608,45 @@ bool CBaseEntity::getKV(const char * name, char * out, int bufsize)
 	return(true);
 }
 
-void CBaseEntity::setParent(CBaseEntity * pEnt, int attachment)
+void CBaseEntity::onParentSet(CBaseEntity *pNewParent)
+{
+	if(pNewParent)
+	{
+		onParentMoved(true);
+		
+		pNewParent->addChild(this);
+	}
+}
+
+void CBaseEntity::onParentUnset(CBaseEntity *pOldParent)
+{
+	if(pOldParent)
+	{
+		pOldParent->removeChild(this);
+	}
+}
+
+void CBaseEntity::addChild(CBaseEntity *pEnt)
+{
+	ScopedSpinLock lock(m_slChildren);
+	m_aChildren.push_back(pEnt);
+}
+void CBaseEntity::removeChild(CBaseEntity *pEnt)
+{
+	ScopedSpinLock lock(m_slChildren);
+	int idx = m_aChildren.indexOf(pEnt);
+	assert(idx >= 0);
+	if(idx >= 0)
+	{
+		m_aChildren.erase(idx);
+	}
+}
+
+void CBaseEntity::setParent(CBaseEntity *pEnt, int attachment)
 {
 	m_pParent = pEnt;
 	if(pEnt)
 	{
-		if(attachment >= 0)
-		{
-			m_vOffsetPos = (float3)(m_vPosition - m_pParent->getAttachmentPos(attachment));
-			m_vOffsetOrient = m_vOrientation * m_pParent->getAttachmentRot(attachment).Conjugate();
-		}
-		else
-		{
-			m_vOffsetPos = m_pParent->getOrient().Conjugate() * (float3)(m_vPosition - m_pParent->getPos());
-			m_vOffsetOrient = m_vOrientation * m_pParent->getOrient().Conjugate();
-		}
 		m_iParentAttachment = attachment;
 	}
 }
@@ -613,35 +691,6 @@ CBaseEntity* CBaseEntity::getParent()
 void CBaseEntity::onSync()
 {
 	m_bSynced = true;
-
-	if(m_pParent)
-	{
-		if(!m_pParent->m_bSynced)
-		{
-			m_pParent->onSync();
-		}
-		if(m_iParentAttachment >= 0)
-		{
-			m_vPosition = (float3)(m_pParent->getAttachmentPos(m_iParentAttachment) + m_vOffsetPos);
-			m_vOrientation = m_pParent->getAttachmentRot(m_iParentAttachment) * m_vOffsetOrient;
-		}
-		else
-		{
-			m_vPosition = (float3)(m_pParent->getPos() + m_pParent->getOrient() * m_vOffsetPos);
-			m_vOrientation = m_vOffsetOrient * m_pParent->getOrient();
-		}
-		//if(m_pPhysObj)
-		//{
-		//	m_pPhysObj->setPos(m_vPosition);
-		//	m_pPhysObj->setOrient(m_vOrientation);
-		//}
-	}
-	//else if(m_pPhysObj)
-	//{
-	//	m_vPosition = m_pPhysObj->GetPos();
-	//	m_vOrientation = m_pPhysObj->getOrient();
-	//}
-
 }
 
 void CBaseEntity::onPostLoad()
@@ -982,3 +1031,28 @@ void CBaseEntity::renderEditor(bool is3D)
 {
 
 }
+
+void CBaseEntity::registerPointer(CEntityPointer *pPtr)
+{
+	ScopedSpinLock lock(m_slPointers);
+	m_aPointers.push_back(pPtr);
+}
+
+void CBaseEntity::unregisterPointer(CEntityPointer *pPtr)
+{
+	ScopedSpinLock lock(m_slPointers);
+	int idx = m_aPointers.indexOf(pPtr);
+	if(idx >= 0)
+	{
+		m_aPointers.erase(idx);
+	}
+}
+
+void CBaseEntity::notifyPointers()
+{
+	ScopedSpinLock lock(m_slPointers);
+	for(UINT i = 0, l = m_aPointers.size(); i < l; ++i)
+	{
+		m_aPointers[i]->onTargetRemoved();
+	}
+}
diff --git a/source/game/BaseEntity.h b/source/game/BaseEntity.h
index e785a1dbe82577de029a29f6fd4848ef81b6f1b6..2b5b68118633c92f95148d136996b2b1adc4fbfc 100644
--- a/source/game/BaseEntity.h
+++ b/source/game/BaseEntity.h
@@ -45,6 +45,7 @@ class SXGAME_EXPORT CBaseEntity
 	DECLARE_PROPTABLE();
 
 	friend class CEntityManager;
+	friend class CEntityPointer;
 
 public:
 	//! Конструктор
@@ -139,14 +140,19 @@ public:
 	virtual void renderEditor(bool is3D);
 
 
-	CBaseEntity *getEntByName(const char *szName, CBaseEntity *pStartFrom);
+	CBaseEntity* getEntByName(const char *szName, CBaseEntity *pStartFrom);
 	int countEntByName(const char *szName);
 
-	const XGUID *getGUID()
+	const XGUID* getGUID()
 	{
 		return(m_pGUID);
 	}
 
+	void setSeparateMovement(bool set)
+	{
+		m_isSeparateMovement = set;
+	}
+
 private:
 	void setClassName(const char *name);
 	void setDefaults();
@@ -163,6 +169,24 @@ private:
 	const char *m_szClassName = NULL;
 	const XGUID *m_pGUID = NULL;
 
+	SpinLock m_slPointers;
+	Array<CEntityPointer*> m_aPointers;
+	void registerPointer(CEntityPointer *pPtr);
+	void unregisterPointer(CEntityPointer *pPtr);
+	void notifyPointers();
+
+	void onParentSet(CBaseEntity *pNewParent);
+	void onParentUnset(CBaseEntity *pOldParent);
+
+	Array<CBaseEntity*> m_aChildren;
+	SpinLock m_slChildren;
+	void addChild(CBaseEntity *pEnt);
+	void removeChild(CBaseEntity *pEnt);
+
+	bool m_isSeparateMovement = false;
+	bool m_isInOnParentMoved = false;
+	void onParentMoved(bool bAdjustOffsets = false);
+
 protected:
 	virtual void _cleanup();
 	virtual void _initEditorBoxes();
@@ -198,7 +222,8 @@ protected:
 	const char *m_szName = NULL;
 
 	//! Родитель
-	CBaseEntity *m_pParent = NULL;
+	// CBaseEntity *m_pParent = NULL;
+	CEntityPointer m_pParent;
 	//! Индекс кости родителя
 	int m_iParentAttachment = -1;
 
diff --git a/source/game/BaseLight.h b/source/game/BaseLight.h
index f3cd1aac80e06808cc636f93cf017792edb9ce56..d24d8716d035aec6ad9ed352e3e98ce311316184 100644
--- a/source/game/BaseLight.h
+++ b/source/game/BaseLight.h
@@ -99,7 +99,7 @@ protected:
 
 	void setLinkedTo(CBaseEntity *pEnt);
 
-	void onSync();
+	void onSync() override;
 
 	void addLinkedLight(CBaseLight *pEnt);
 	void removeLinkedLight(CBaseLight *pEnt);
diff --git a/source/game/BaseTool.h b/source/game/BaseTool.h
index 6b00d4b5a6fbd81593c411a80561b2b9a5a70876..5689a976495505ed9c32b6566cba81e62bc3e24f 100644
--- a/source/game/BaseTool.h
+++ b/source/game/BaseTool.h
@@ -39,7 +39,7 @@ public:
 	DECLARE_CONSTRUCTOR();
 	~CBaseTool();
 
-	virtual void onPostLoad();
+	void onPostLoad() override;
 
 	virtual void primaryAction(BOOL st);
 	virtual void secondaryAction(BOOL st);
@@ -54,7 +54,7 @@ public:
 
 	void dbgMove(int dir, float delta);
 
-	void onSync();
+	void onSync() override;
 
 	void setParent(CBaseEntity * pEnt, int attachment = -1);
 
diff --git a/source/game/BaseTrigger.h b/source/game/BaseTrigger.h
index 87bb957ed45b0f4af09465bd8ff5d4c702ea0ed8..25d6855c841fd7ad82672372d04e70b31502ad46 100644
--- a/source/game/BaseTrigger.h
+++ b/source/game/BaseTrigger.h
@@ -28,8 +28,8 @@ public:
 	DECLARE_TRIVIAL_CONSTRUCTOR();
 	~CBaseTrigger();
 
-	void onSync();
-	void onPostLoad();
+	void onSync() override;
+	void onPostLoad() override;
 
 	void enable();
 	void disable();
diff --git a/source/game/BaseWeapon.h b/source/game/BaseWeapon.h
index ff14e812a4c8ca04d642fb2c593a3269787749e2..f9f6203a0a33efd63cfde21633c307bb31829ba1 100644
--- a/source/game/BaseWeapon.h
+++ b/source/game/BaseWeapon.h
@@ -63,7 +63,7 @@ class CBaseWeapon: public CBaseTool
 public:
 	DECLARE_CONSTRUCTOR();
 	~CBaseWeapon();
-	virtual void onPostLoad();
+	void onPostLoad() override;
 
 	virtual void primaryAction(BOOL st);
 	virtual void secondaryAction(BOOL st);
diff --git a/source/game/EditorObject.cpp b/source/game/EditorObject.cpp
index fdd850716425677728253c588672db2a9e40e43a..f30dcc9bfd0bcf962d57df10691813f903173e60 100644
--- a/source/game/EditorObject.cpp
+++ b/source/game/EditorObject.cpp
@@ -123,29 +123,68 @@ void CEditorObject::_iniFieldList()
 
 void XMETHODCALLTYPE CEditorObject::setPos(const float3_t &pos)
 {
-	if(m_pEntity)
+	SAFE_CALL(m_pEntity, setPos, pos);
+	m_vPos = pos;
+}
+
+void CEditorObject::setPos(const float3_t &pos, bool isSeparate)
+{
+	if(isSeparate)
 	{
-		m_pEntity->setPos(pos);
+		SAFE_CALL(m_pEntity, setSeparateMovement, true);
+	}
+
+	setPos(pos);
+
+	if(isSeparate)
+	{
+		SAFE_CALL(m_pEntity, setSeparateMovement, false);
 	}
-	m_vPos = pos;
 }
 
 void XMETHODCALLTYPE CEditorObject::setScale(const float3_t &vScale)
 {
-	//@TODO: Implement me
+	// TODO Implement me
 	m_vScale = vScale;
 }
 
-void XMETHODCALLTYPE CEditorObject::setOrient(const SMQuaternion &orient)
+void CEditorObject::setScale(const float3_t &vScale, bool isSeparate)
 {
-	if(m_pEntity)
+	if(isSeparate)
 	{
-		m_pEntity->setOrient(orient);
+		SAFE_CALL(m_pEntity, setSeparateMovement, true);
 	}
 
+	setScale(vScale);
+
+	if(isSeparate)
+	{
+		SAFE_CALL(m_pEntity, setSeparateMovement, false);
+	}
+}
+
+void XMETHODCALLTYPE CEditorObject::setOrient(const SMQuaternion &orient)
+{
+	SAFE_CALL(m_pEntity, setOrient, orient);
+
 	m_qRot = orient;
 }
 
+void CEditorObject::setOrient(const SMQuaternion &orient, bool isSeparate)
+{
+	if(isSeparate)
+	{
+		SAFE_CALL(m_pEntity, setSeparateMovement, true);
+	}
+
+	setOrient(orient);
+
+	if(isSeparate)
+	{
+		SAFE_CALL(m_pEntity, setSeparateMovement, false);
+	}
+}
+
 float3_t XMETHODCALLTYPE CEditorObject::getPos()
 {
 	if(m_pEntity)
@@ -254,9 +293,9 @@ void XMETHODCALLTYPE CEditorObject::create()
 
 	m_pEntity->setFlags(m_pEntity->getFlags() | EF_LEVEL | EF_EXPORT);
 
-	setPos(getPos());
-	setOrient(getOrient());
-	setScale(getScale());
+	setPos(m_vPos, true);
+	setOrient(m_qRot, true);
+	setScale(m_vScale, true);
 }
 
 void CEditorObject::resync()
diff --git a/source/game/EditorObject.h b/source/game/EditorObject.h
index 71b4d2ad131321322bca6163adda3916c81dff17..e0b4c8141a6fc1df9d2191cfa9bf23a7ab56f616 100644
--- a/source/game/EditorObject.h
+++ b/source/game/EditorObject.h
@@ -16,8 +16,11 @@ public:
 	~CEditorObject();
 
 	void XMETHODCALLTYPE setPos(const float3_t &pos) override;
+	void setPos(const float3_t &pos, bool isSeparate);
 	void XMETHODCALLTYPE setOrient(const SMQuaternion &orient) override;
-	void XMETHODCALLTYPE setScale(const float3_t &pos) override;
+	void setOrient(const SMQuaternion &orient, bool isSeparate);
+	void XMETHODCALLTYPE setScale(const float3_t &scale) override;
+	void setScale(const float3_t &scale, bool isSeparate);
 
 	void XMETHODCALLTYPE getBound(float3 *pvMin, float3 *pvMax) override;
 
diff --git a/source/game/EntityManager.cpp b/source/game/EntityManager.cpp
index 896dea78609b9a3b3244df9e7b4fcf807fff3b99..7de487b99d6da8d7f0be66cf3e1713d12af618ef 100644
--- a/source/game/EntityManager.cpp
+++ b/source/game/EntityManager.cpp
@@ -260,6 +260,11 @@ const XGUID* CEntityManager::reg(CBaseEntity *pEnt, const XGUID *pGUID)
 
 	m_vEntList.push_back(pEnt);
 
+	if(pGUID)
+	{
+		notifyWaitForGUID(*pGUID, pEnt);
+	}
+
 	return(pNewGUID);
 }
 void CEntityManager::unreg(CBaseEntity *pEnt)
@@ -268,7 +273,10 @@ void CEntityManager::unreg(CBaseEntity *pEnt)
 
 	int iKey = m_vEntList.indexOf(pEnt);
 	assert(iKey >= 0);
-	m_vEntList.erase(iKey);
+	UINT uLast = m_vEntList.size() - 1;
+	m_vEntList[iKey] = m_vEntList[uLast];
+	m_vEntList[uLast] = NULL;
+	m_vEntList.erase(uLast);
 
 	timeout_t * t;
 	timeout_output_t * to;
@@ -472,9 +480,9 @@ bool CEntityManager::import(const char * file, bool shouldSendProgress)
 	{
 		pEventChannel = Core_GetIXCore()->getEventChannel<XEventLevelProgress>(EVENT_LEVEL_PROGRESS_GUID);
 	}
-	ISXConfig * conf = Core_CrConfig();
+	ISXConfig *conf = Core_CrConfig();
 	const char *sect;
-	CBaseEntity * pEnt = NULL;
+	CBaseEntity *pEnt = NULL;
 	Array<CBaseEntity*> tmpList;
 
 	char szFullPath[1024];
@@ -835,6 +843,7 @@ void CEntityManager::entKV(int argc, const char **argv)
 	if(id < 0 || (UINT)id >= m_vEntList.size() || !(pEnt = m_vEntList[id]))
 	{
 		printf(COLOR_LRED "Invalid entity id\n" COLOR_RESET);
+		return;
 	}
 	char buf[128];
 	buf[0] = 0;
@@ -847,7 +856,7 @@ void CEntityManager::entKV(int argc, const char **argv)
 			{
 				for(int i = 0; i < pt->numFields; ++i)
 				{
-					if(pt->pData[i].szKey)
+					if(pt->pData[i].szKey && !(pt->pData[i].flags & PDFF_INPUT))
 					{
 						pEnt->getKV(pt->pData[i].szKey, buf, sizeof(buf));
 						printf("%s = %s\n", pt->pData[i].szKey, buf);
@@ -958,6 +967,8 @@ void CEntityManager::sheduleDestroy(CBaseEntity *pEnt)
 	{
 		pEnt->_releaseEditorBoxes();
 	}
+
+	pEnt->notifyPointers();
 }
 
 void CEntityManager::setEditorMode(bool isEditor)
@@ -1293,3 +1304,44 @@ CBaseline *CEntityManager::deserializeBaseline(ID id, INETbuff *pBuf)
 	return(pBaseline);
 }
 #endif
+
+void CEntityManager::registerWaitForGUID(const XGUID &guid, CEntityPointer *pPtr)
+{
+	ScopedSpinLock lock(m_slWaitingPointers);
+
+	m_maWaitingPointers[guid].push_back(pPtr);
+}
+
+void CEntityManager::unregisterWaitForGUID(const XGUID &guid, CEntityPointer *pPtr)
+{
+	ScopedSpinLock lock(m_slWaitingPointers);
+
+	Array<CEntityPointer*> &list = m_maWaitingPointers[guid];
+
+	int idx = list.indexOf(pPtr);
+	assert(idx >= 0);
+	if(idx >= 0)
+	{
+		list.erase(idx);
+	}
+	if(!list.size())
+	{
+		m_maWaitingPointers.erase(guid);
+	}
+}
+
+void CEntityManager::notifyWaitForGUID(const XGUID &guid, CBaseEntity *pEnt)
+{
+	ScopedSpinLock lock(m_slWaitingPointers);
+
+	const Map<XGUID, Array<CEntityPointer*>>::Node *pNode;
+	if(m_maWaitingPointers.KeyExists(guid, &pNode))
+	{
+		Array<CEntityPointer*> &list = m_maWaitingPointers[guid];
+		for(UINT i = 0, l = list.size(); i < l; ++i)
+		{
+			list[i]->onWaitDone(pEnt);
+		}
+		m_maWaitingPointers.erase(guid);
+	}
+}
diff --git a/source/game/EntityManager.h b/source/game/EntityManager.h
index cb031a1f0e3a3cfb2805098a97668aeaab5ab980..5cbd65f3a45fe43bed7cd6fe86838e45e17b77ae 100644
--- a/source/game/EntityManager.h
+++ b/source/game/EntityManager.h
@@ -89,6 +89,7 @@ class CEntityManager
 
 	friend class CBaseEntity;
 	friend class CEntityFactoryMap;
+	friend class CEntityPointer;
 public:
 	CEntityManager();
 	~CEntityManager();
@@ -181,6 +182,12 @@ protected:
 
 private:
 	void finalRemove();
+
+	Map<XGUID, Array<CEntityPointer*>> m_maWaitingPointers;
+	SpinLock m_slWaitingPointers;
+	void registerWaitForGUID(const XGUID &guid, CEntityPointer *pPtr);
+	void unregisterWaitForGUID(const XGUID &guid, CEntityPointer *pPtr);
+	void notifyWaitForGUID(const XGUID &guid, CBaseEntity *pEnt);
 };
 
 #endif
diff --git a/source/game/EntityPointer.cpp b/source/game/EntityPointer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64764639e83db911e3f7dd916efe8baf0bd3c263
--- /dev/null
+++ b/source/game/EntityPointer.cpp
@@ -0,0 +1,175 @@
+#include "EntityPointer.h"
+#include "BaseEntity.h"
+
+CEntityPointer::~CEntityPointer()
+{
+	if(m_pEntity)
+	{
+		m_pEntity->unregisterPointer(this);
+	}
+
+	unregisterWait();
+}
+
+void CEntityPointer::setEntityName(const char *szName)
+{
+	if(szName[0] == '{')
+	{
+		XGUID guid;
+		if(XGUIDFromString(&guid, szName))
+		{
+			setEntityGUID(guid);
+			return;
+		}
+	}
+
+	setEntity(m_pMgr->findEntityByName(szName));
+}
+
+void CEntityPointer::setEntityGUID(const XGUID &guid)
+{
+	CBaseEntity *pEnt = m_pMgr->getByGUID(guid);
+	setEntity(pEnt);
+	if(!pEnt)
+	{
+		m_guid = guid;
+		registerWait();
+	}
+}
+
+void CEntityPointer::setEntity(CBaseEntity *pEnt)
+{
+	if(m_pEntity != pEnt)
+	{
+		unregisterWait();
+
+		if(m_pEntity)
+		{
+			onLinkBroken(m_pEntity);
+		}
+		m_pEntity = pEnt;
+		if(pEnt)
+		{
+			m_guid = *pEnt->getGUID();
+		}
+		else
+		{
+			m_guid = XGUID();
+		}
+		if(m_pEntity)
+		{
+			onLinkEstablished(m_pEntity);
+		}
+	}
+}
+
+CBaseEntity* CEntityPointer::getEntity()
+{
+	return(m_pEntity);
+}
+
+CBaseEntity* CEntityPointer::operator->()
+{
+	return(getEntity());
+}
+CEntityPointer::operator CBaseEntity*()
+{
+	return(getEntity());
+}
+
+CEntityPointer& CEntityPointer::operator=(CBaseEntity *pEnt)
+{
+	setEntity(pEnt);
+	return(*this);
+}
+
+void CEntityPointer::getEntityName(char *szOutput, int iBufSize)
+{
+	if(m_pEntity && m_pEntity->getName()[0])
+	{
+		if(m_pMgr->countEntityByName(m_pEntity->getName()) == 1)
+		{
+			strncpy(szOutput, m_pEntity->getName(), iBufSize);
+			szOutput[iBufSize - 1] = 0;
+			return;
+		}
+	}
+	
+	if(m_guid == XGUID())
+	{
+		if(iBufSize)
+		{
+			szOutput[0] = 0;
+		}
+		return;
+	}
+
+	char tmp[64];
+	XGUIDToSting(m_guid, tmp, sizeof(tmp));
+	strncpy(szOutput, tmp, iBufSize);
+	szOutput[iBufSize - 1] = 0;
+}
+const XGUID& CEntityPointer::getGUID()
+{
+	return(m_guid);
+}
+
+void CEntityPointer::init(CEntityManager *pWorld, CBaseEntity *pThisEntity)
+{
+	m_pMgr = pWorld;
+	m_pThisEntity = pThisEntity;
+}
+
+void CEntityPointer::onLinkBroken(CBaseEntity *pOldEnt)
+{
+	if(m_pfnOnLinkBroken)
+	{
+		(m_pThisEntity->*m_pfnOnLinkBroken)(pOldEnt);
+	}
+}
+
+void CEntityPointer::onLinkEstablished(CBaseEntity *pNewEnt)
+{
+	pNewEnt->registerPointer(this);
+
+	if(m_pfnOnLinkEstablished)
+	{
+		(m_pThisEntity->*m_pfnOnLinkEstablished)(pNewEnt);
+	}
+}
+
+void CEntityPointer::onTargetRemoved()
+{
+	onLinkBroken(NULL);
+	m_pEntity = NULL;
+	registerWait();
+}
+
+void CEntityPointer::registerWait()
+{
+	if(!m_isWaiting)
+	{
+		m_pMgr->registerWaitForGUID(m_guid, this);
+		m_isWaiting = true;
+	}
+}
+
+void CEntityPointer::unregisterWait()
+{
+	if(m_isWaiting)
+	{
+		m_pMgr->unregisterWaitForGUID(m_guid, this);
+		m_isWaiting = false;
+	}
+}
+
+void CEntityPointer::onWaitDone(CBaseEntity *pEnt)
+{
+	assert(m_isWaiting);
+
+	m_isWaiting = false;
+
+	m_pEntity = pEnt;
+
+	onLinkEstablished(pEnt);
+}
diff --git a/source/game/EntityPointer.h b/source/game/EntityPointer.h
new file mode 100644
index 0000000000000000000000000000000000000000..647f3c682942b42ab8594fce79348bfc9da24b09
--- /dev/null
+++ b/source/game/EntityPointer.h
@@ -0,0 +1,76 @@
+#ifndef __ENTITY_POINTER_H
+#define __ENTITY_POINTER_H
+
+#include <gdefines.h>
+
+class CBaseEntity;
+class CEntityManager;
+class CEntityPointer
+{
+	DECLARE_CLASS_NOBASE(CEntityPointer);
+	friend class CBaseEntity;
+	friend class CEntityManager;
+public:
+	
+	~CEntityPointer();
+
+	//! Установка имени или GUID связанного объекта
+	void setEntityName(const char *szName);
+
+	//! Установка GUID
+	void setEntityGUID(const XGUID &guid);
+
+	//! Установка
+	void setEntity(CBaseEntity *pEnt);
+
+	//! Получение указателя на объект
+	CBaseEntity* getEntity();
+
+	void getEntityName(char *szOutput, int iBufSize);
+	const XGUID& getGUID();
+
+	CBaseEntity* operator->();
+	operator CBaseEntity*();
+
+	CEntityPointer& operator=(CBaseEntity *pEnt);
+
+	//! Вызывается при разрушении связи (pEnt -- указатель на объект, если причиной разрыва связи стало не удаление объекта)
+	template<typename F>
+	void setLinkBrokenListener(void(F::*func)(CBaseEntity*))
+	{
+		static_assert(std::is_base_of<CBaseEntity, F>::value, "F must be subclass of CBaseEntity");
+
+		m_pfnOnLinkBroken = func;
+	}
+
+	//! Вызывается при установке связи
+	template<typename F>
+	void setLinkEstablishedListener(void(F::*func)(CBaseEntity*))
+	{
+		static_assert(std::is_base_of<CBaseEntity, F>::value, "F must be subclass of CBaseEntity");
+
+		m_pfnOnLinkEstablished = func;
+	}
+	
+private:
+	XGUID m_guid;
+	CBaseEntity *m_pEntity = NULL;
+	CEntityManager *m_pMgr = NULL;
+	CBaseEntity *m_pThisEntity = NULL;
+
+	void(CBaseEntity::*m_pfnOnLinkBroken)(CBaseEntity*) = NULL;
+	void(CBaseEntity::*m_pfnOnLinkEstablished)(CBaseEntity*) = NULL;
+
+	void init(CEntityManager *pWorld, CBaseEntity *pThisEntity);
+
+	void onLinkBroken(CBaseEntity *pOldEnt);
+	void onLinkEstablished(CBaseEntity *pNewEnt);
+	void onTargetRemoved();
+
+	bool m_isWaiting = false;
+	void registerWait();
+	void unregisterWait();
+	void onWaitDone(CBaseEntity *pEnt);
+};
+
+#endif
diff --git a/source/game/FuncTrain.h b/source/game/FuncTrain.h
index 458ece6bda83a8126c30dccd41b2a4d0da55780d..d03ad5bc8f1c019e474d665df23609b3adb8a050 100644
--- a/source/game/FuncTrain.h
+++ b/source/game/FuncTrain.h
@@ -31,7 +31,7 @@ public:
 	void start();
 
 protected:
-	void onPostLoad();
+	void onPostLoad() override;
 	void moveFunc(float dt);
 
 	//! Начальная точка движения
diff --git a/source/game/NPCBase.h b/source/game/NPCBase.h
index de5fe426d44975c57dcaa96a29080670b6867135..bc871dad50df2a4158d8856002274a9951fc4032 100644
--- a/source/game/NPCBase.h
+++ b/source/game/NPCBase.h
@@ -72,7 +72,7 @@ public:
 	void stopOrientAt();
 
 protected:
-	void onSync();
+	void onSync() override;
 
 	//void think(float fDelta);
 
diff --git a/source/game/PathCorner.h b/source/game/PathCorner.h
index d43ada71889815f3fcfeaaa67e14438dc84c2a9b..c15064c6abead767ef84e09d3a4cc9750a68760c 100644
--- a/source/game/PathCorner.h
+++ b/source/game/PathCorner.h
@@ -55,7 +55,7 @@ public:
 protected:
 	//! Пересчитывает путь
 	void recalcPath(float t);
-	void onPostLoad();
+	void onPostLoad() override;
 
 	//! Тип сглаживания
 	int m_type = PCT_SPLINE;
diff --git a/source/game/Player.h b/source/game/Player.h
index de742773b12fb8fef834494cf612f5c014f51805..c85778560b17befa0e9463727df07c9b37d653b7 100644
--- a/source/game/Player.h
+++ b/source/game/Player.h
@@ -47,7 +47,7 @@ public:
 	//! Обновляет инпут от игрока
 	virtual void updateInput(float dt);
 
-	void onSync();
+	void onSync() override;
 	
 	//! Получает смещения для задержки движения модели оружия при вращении игрока
 	float3_t & getWeaponDeltaAngles();
diff --git a/source/game/PointCamera.h b/source/game/PointCamera.h
index 93472ef70de4c951e7aa435ecfc40b9765b235f4..6ef275b7ac28398f6ec1d29e6097690c63b39a83 100644
--- a/source/game/PointCamera.h
+++ b/source/game/PointCamera.h
@@ -35,7 +35,7 @@ public:
 protected:
 	ICamera * m_pSXC;
 
-	void onSync();
+	void onSync() override;
 };
 
 #endif
diff --git a/source/game/PropBreakable.h b/source/game/PropBreakable.h
index 5209a0c5275823d8accd370a985cec2d11fef847..bc00d2aa0906c95eff56a981a9293acf87b2e49b 100644
--- a/source/game/PropBreakable.h
+++ b/source/game/PropBreakable.h
@@ -24,7 +24,7 @@ class CPropBreakable: public CPropDynamic
 public:
 	DECLARE_TRIVIAL_CONSTRUCTOR();
 	~CPropBreakable();
-	virtual void onPostLoad();
+	void onPostLoad() override;
 
 	void onDeath(CBaseEntity *pAttacker, CBaseEntity *pInflictor);
 protected:
diff --git a/source/game/proptable.h b/source/game/proptable.h
index 8c2272019d37e05e7d3d0752dbbb47f021928db4..7a72d969b3ddd35d9aa0d0151d912f69e0781289 100644
--- a/source/game/proptable.h
+++ b/source/game/proptable.h
@@ -8,6 +8,7 @@ See the license in LICENSE
 #define __PROPTABLE_H
 
 #include <common/Math.h>
+#include "EntityPointer.h"
 
 class CBaseEntity;
 
@@ -420,29 +421,29 @@ const char * GetEmptyString();
 #define EDITOR_SOUND EDITOR_FILEFIELD FILE_OPTION("Select sound", "ogg") EDITOR_FILE_END()
 #define EDITOR_TEXTURE EDITOR_FILEFIELD FILE_OPTION("Select texture", "dds") EDITOR_FILE_END()
 
-#define DEFINE_FIELD_STRING(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<const char* DataClass::*>(&DataClass::field),  PDF_STRING,  flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_VECTOR(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<float3_t DataClass::*>(&DataClass::field),     PDF_VECTOR,  flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_VECTOR4(field, flags, keyname, edname, editor)             , {propdata_t::ToFieldType<float4_t DataClass::*>(&DataClass::field),     PDF_VECTOR4, flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_ANGLES(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<SMQuaternion DataClass::*>(&DataClass::field), PDF_ANGLES,  flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_INT(field, flags, keyname, edname, editor)                 , {propdata_t::ToFieldType<int DataClass::*>(&DataClass::field),          PDF_INT,     flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_ENUM(type, field, flags, keyname, edname, editor)          , {propdata_t::ToFieldType<type DataClass::*>(&DataClass::field),         PDF_INT,     flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_FLOAT(field, flags, keyname, edname, editor)               , {propdata_t::ToFieldType<float DataClass::*>(&DataClass::field),        PDF_FLOAT,   flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_BOOL(field, flags, keyname, edname, editor)                , {propdata_t::ToFieldType<bool DataClass::*>(&DataClass::field),         PDF_BOOL,    flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_ENTITY(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<CBaseEntity* DataClass::*>(&DataClass::field), PDF_ENTITY,  flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_ENTITY2(type, field, flags, keyname, edname, editor)       , {propdata_t::ToFieldType<type* DataClass::*>(&DataClass::field),        PDF_ENTITY,  flags, keyname, edname, CEntityFactoryMap::IsEntityOfClass<type>, editor
-#define DEFINE_FIELD_PARENT(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<CBaseEntity* DataClass::*>(&DataClass::field), PDF_PARENT,  flags, keyname, edname, NULL,                                     editor
-#define DEFINE_FIELD_FLAGS(field, flags, keyname, edname, editor)               , {propdata_t::ToFieldType<UINT DataClass::*>(&DataClass::field),         PDF_FLAGS,   flags, keyname, edname, NULL,                                     editor
-
-#define DEFINE_FIELD_STRINGFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<const char* DataClass::*>(&DataClass::field),  PDF_STRING,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const char*>(&DataClass::fn),         NULL,                                     editor
-#define DEFINE_FIELD_VECTORFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<float3_t DataClass::*>(&DataClass::field),     PDF_VECTOR,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const float3&>(&DataClass::fn),       NULL,                                     editor
-#define DEFINE_FIELD_VECTOR4FN(field, flags, keyname, edname, fn, editor)       , {propdata_t::ToFieldType<float4_t DataClass::*>(&DataClass::field),     PDF_VECTOR4, flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const float4&>(&DataClass::fn),       NULL,                                     editor
-#define DEFINE_FIELD_ANGLESFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<SMQuaternion DataClass::*>(&DataClass::field), PDF_ANGLES,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const SMQuaternion&>(&DataClass::fn), NULL,                                     editor
-#define DEFINE_FIELD_INTFN(field, flags, keyname, edname, fn, editor)           , {propdata_t::ToFieldType<int DataClass::*>(&DataClass::field),          PDF_INT,     flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, int>(&DataClass::fn),                 NULL,                                     editor
-#define DEFINE_FIELD_ENUMFN(type, field, flags, keyname, edname, fn, editor)    , {propdata_t::ToFieldType<type DataClass::*>(&DataClass::field),         PDF_INT,     flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, int>(&DataClass::fn),                 NULL,                                     editor
-#define DEFINE_FIELD_FLOATFN(field, flags, keyname, edname, fn, editor)         , {propdata_t::ToFieldType<float DataClass::*>(&DataClass::field),        PDF_FLOAT,   flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, float>(&DataClass::fn),               NULL,                                     editor
-#define DEFINE_FIELD_BOOLFN(field, flags, keyname, edname, fn, editor)          , {propdata_t::ToFieldType<bool DataClass::*>(&DataClass::field),         PDF_BOOL,    flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, bool>(&DataClass::fn),                NULL,                                     editor
-#define DEFINE_FIELD_ENTITYFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<CBaseEntity* DataClass::*>(&DataClass::field), PDF_ENTITY,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, CBaseEntity*>(&DataClass::fn),        NULL,                                     editor
-#define DEFINE_FIELD_ENTITY2FN(type, field, flags, keyname, edname, fn, editor) , {propdata_t::ToFieldType<type* DataClass::*>(&DataClass::field),        PDF_ENTITY,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, type*>(&DataClass::fn),               CEntityFactoryMap::IsEntityOfClass<type>, editor
+#define DEFINE_FIELD_STRING(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<const char* DataClass::*>(&DataClass::field),    PDF_STRING,  flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_VECTOR(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<float3_t DataClass::*>(&DataClass::field),       PDF_VECTOR,  flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_VECTOR4(field, flags, keyname, edname, editor)             , {propdata_t::ToFieldType<float4_t DataClass::*>(&DataClass::field),       PDF_VECTOR4, flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_ANGLES(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<SMQuaternion DataClass::*>(&DataClass::field),   PDF_ANGLES,  flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_INT(field, flags, keyname, edname, editor)                 , {propdata_t::ToFieldType<int DataClass::*>(&DataClass::field),            PDF_INT,     flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_ENUM(type, field, flags, keyname, edname, editor)          , {propdata_t::ToFieldType<type DataClass::*>(&DataClass::field),           PDF_INT,     flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_FLOAT(field, flags, keyname, edname, editor)               , {propdata_t::ToFieldType<float DataClass::*>(&DataClass::field),          PDF_FLOAT,   flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_BOOL(field, flags, keyname, edname, editor)                , {propdata_t::ToFieldType<bool DataClass::*>(&DataClass::field),           PDF_BOOL,    flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_ENTITY(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<CBaseEntity* DataClass::*>(&DataClass::field),   PDF_ENTITY,  flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_ENTITY2(type, field, flags, keyname, edname, editor)       , {propdata_t::ToFieldType<type* DataClass::*>(&DataClass::field),          PDF_ENTITY,  flags, keyname, edname, CEntityFactoryMap::IsEntityOfClass<type>, editor
+#define DEFINE_FIELD_PARENT(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<CEntityPointer DataClass::*>(&DataClass::field), PDF_PARENT,  flags, keyname, edname, NULL,                                     editor
+#define DEFINE_FIELD_FLAGS(field, flags, keyname, edname, editor)               , {propdata_t::ToFieldType<UINT DataClass::*>(&DataClass::field),           PDF_FLAGS,   flags, keyname, edname, NULL,                                     editor
+
+#define DEFINE_FIELD_STRINGFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<const char* DataClass::*>(&DataClass::field),    PDF_STRING,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const char*>(&DataClass::fn),         NULL,                                     editor
+#define DEFINE_FIELD_VECTORFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<float3_t DataClass::*>(&DataClass::field),       PDF_VECTOR,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const float3&>(&DataClass::fn),       NULL,                                     editor
+#define DEFINE_FIELD_VECTOR4FN(field, flags, keyname, edname, fn, editor)       , {propdata_t::ToFieldType<float4_t DataClass::*>(&DataClass::field),       PDF_VECTOR4, flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const float4&>(&DataClass::fn),       NULL,                                     editor
+#define DEFINE_FIELD_ANGLESFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<SMQuaternion DataClass::*>(&DataClass::field),   PDF_ANGLES,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, const SMQuaternion&>(&DataClass::fn), NULL,                                     editor
+#define DEFINE_FIELD_INTFN(field, flags, keyname, edname, fn, editor)           , {propdata_t::ToFieldType<int DataClass::*>(&DataClass::field),            PDF_INT,     flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, int>(&DataClass::fn),                 NULL,                                     editor
+#define DEFINE_FIELD_ENUMFN(type, field, flags, keyname, edname, fn, editor)    , {propdata_t::ToFieldType<type DataClass::*>(&DataClass::field),           PDF_INT,     flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, int>(&DataClass::fn),                 NULL,                                     editor
+#define DEFINE_FIELD_FLOATFN(field, flags, keyname, edname, fn, editor)         , {propdata_t::ToFieldType<float DataClass::*>(&DataClass::field),          PDF_FLOAT,   flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, float>(&DataClass::fn),               NULL,                                     editor
+#define DEFINE_FIELD_BOOLFN(field, flags, keyname, edname, fn, editor)          , {propdata_t::ToFieldType<bool DataClass::*>(&DataClass::field),           PDF_BOOL,    flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, bool>(&DataClass::fn),                NULL,                                     editor
+#define DEFINE_FIELD_ENTITYFN(field, flags, keyname, edname, fn, editor)        , {propdata_t::ToFieldType<CBaseEntity* DataClass::*>(&DataClass::field),   PDF_ENTITY,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, CBaseEntity*>(&DataClass::fn),        NULL,                                     editor
+#define DEFINE_FIELD_ENTITY2FN(type, field, flags, keyname, edname, fn, editor) , {propdata_t::ToFieldType<type* DataClass::*>(&DataClass::field),          PDF_ENTITY,  flags, keyname, edname, propdata_t::ToPFNFieldSet<DataClass, type*>(&DataClass::fn),               CEntityFactoryMap::IsEntityOfClass<type>, editor
 //#define DEFINE_FIELD_PARENTFN(field, flags, keyname, edname, fn, editor) , {(fieldtype)&DataClass::field, PDF_PARENT, flags, keyname, edname, fn, editor
 //#define DEFINE_FIELD_FLAGSFN(field, flags, keyname, edname, fn, editor)  , {(fieldtype)&DataClass::field, PDF_FLAGS,  flags, keyname, edname, fn, editor