diff --git a/proj/sxgame/vs2013/sxgame.vcxproj b/proj/sxgame/vs2013/sxgame.vcxproj
index c6d0cbd4b2f4bce1c8356195b9170b70b6a95fbd..2e16dab93c6757bd80479bc292c96d3455221b3c 100644
--- a/proj/sxgame/vs2013/sxgame.vcxproj
+++ b/proj/sxgame/vs2013/sxgame.vcxproj
@@ -196,7 +196,6 @@
     <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" />
diff --git a/proj/sxgame/vs2013/sxgame.vcxproj.filters b/proj/sxgame/vs2013/sxgame.vcxproj.filters
index d826392c715d3701fdb4c19f13d52066ae3513c7..57e82a2c547b2b30e821154fe9649143bff55863 100644
--- a/proj/sxgame/vs2013/sxgame.vcxproj.filters
+++ b/proj/sxgame/vs2013/sxgame.vcxproj.filters
@@ -312,9 +312,6 @@
     <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">
diff --git a/source/game/BaseAnimating.cpp b/source/game/BaseAnimating.cpp
index 4a19bb739dc4a782fc1a69020555729ee25b9eaf..ee58f156ad3c0e9809ab7654ddfe57699f6e52e1 100644
--- a/source/game/BaseAnimating.cpp
+++ b/source/game/BaseAnimating.cpp
@@ -22,7 +22,7 @@ BEGIN_PROPTABLE(CBaseAnimating)
 	DEFINE_FIELD_FLOATFN(m_fBaseScale, 0, "scale", "Scale", setScale, EDITOR_TEXTFIELD)
 
 	//! Объект референса для цвета свечения
-	DEFINE_FIELD_ENTITY(m_pEntColorRef, 0, "glow_color_ref", "Glow color reference", EDITOR_TEXTFIELD)
+	DEFINE_FIELD_ENTITY(CBaseEntity, m_pEntColorRef, 0, "glow_color_ref", "Glow color reference", EDITOR_TEXTFIELD)
 	//! Цвет свечения
 	DEFINE_FIELD_VECTOR(m_vGlowColor, 0, "glow_color", "Glow color", EDITOR_TEXTFIELD)
 
diff --git a/source/game/BaseAnimating.h b/source/game/BaseAnimating.h
index bd0b17552b36160cbcb93bce68ecde43697b9132..d8d7d9ac88745073cb4d2a639ed3f24eab0fbf11 100644
--- a/source/game/BaseAnimating.h
+++ b/source/game/BaseAnimating.h
@@ -113,7 +113,7 @@ protected:
 	bool m_isStatic = false;
 	bool m_useAutoPhysbox = true;
 
-	CBaseEntity *m_pEntColorRef = NULL;
+	CEntityPointer<CBaseEntity> m_pEntColorRef;
 	float3_t m_vGlowColor;
 
 	virtual void initPhysics();
diff --git a/source/game/BaseEntity.cpp b/source/game/BaseEntity.cpp
index 662e96671799a1c8a3d82d51b5b7392b38e6796b..6f7ff03ccb874d6eeac8470c6a458ce8a8a113c3 100644
--- a/source/game/BaseEntity.cpp
+++ b/source/game/BaseEntity.cpp
@@ -24,11 +24,11 @@ BEGIN_PROPTABLE_NOBASE(CBaseEntity)
 	//! Ориентация в мире, углы эйлера или кватернион
 	DEFINE_FIELD_ANGLESFN(m_qOrientation, 0, "rotation", "Rotation", setOrient, EDITOR_TEXTFIELD)
 	//! Родительский объект в иерархии движения
-	DEFINE_FIELD_PARENT(m_pParent, 0, "parent", "Parent entity", EDITOR_TEXTFIELD)
+	DEFINE_FIELD_ENTITY(CBaseEntity, m_pParent, 0, "parent", "Parent entity", EDITOR_TEXTFIELD)
 	//! Флаги объекта
 	DEFINE_FIELD_FLAGS(m_iFlags, 0, "flags", "Flags", EDITOR_FLAGS)
 	//! Объект-владелец
-	DEFINE_FIELD_ENTITY(m_pOwner, PDFF_NOEXPORT | PDFF_NOEDIT, "owner", "", EDITOR_NONE)
+	DEFINE_FIELD_ENTITY(CBaseEntity, m_pOwner, PDFF_NOEXPORT | PDFF_NOEDIT, "owner", "", EDITOR_NONE)
 	//! Здоровье
 	DEFINE_FIELD_FLOAT(m_fHealth, PDFF_NOEXPORT | PDFF_NOEDIT, "health", "", EDITOR_NONE)
 
@@ -55,9 +55,9 @@ void CBaseEntity::setDefaults()
 				{
 					this->*((const char* ThisClass::*)pt->pData[i].pField) = estr;
 				}
-				else if(pt->pData[i].type == PDF_PARENT)
+				else if(pt->pData[i].type == PDF_ENTITY)
 				{
-					(this->*((CEntityPointer ThisClass::*)pt->pData[i].pField)).init(m_pMgr, this);
+					(this->*((CEntityPointer<CBaseEntity> ThisClass::*)pt->pData[i].pField)).init(m_pMgr, this);
 				}
 			}
 		}
@@ -385,37 +385,9 @@ bool CBaseEntity::setKV(const char * name, const char * value)
 			return(true);
 		}
 		return(false);
-	case PDF_PARENT:
-		(this->*((CEntityPointer ThisClass::*)field->pField)).setEntityName(value);
-		break;
 	case PDF_ENTITY:
-		pEnt = m_pMgr->findEntityByName(value);
-		if(pEnt || !value[0])
-		{
-			if(field->type == PDF_PARENT)
-			{
-				setParent(pEnt);
-			}
-			else
-			{
-				// check type of pEnt
-				if(field->pfnCheckType && !field->pfnCheckType(pEnt))
-				{
-					LibReport(REPORT_MSG_LEVEL_ERROR, "Unable to set entity field '%s' to entity '%s'. Invalid class. Ent: %s", name, value, m_szName);
-					return(false);
-				}
-				if(field->fnSet.e)
-				{
-					(this->*(field->fnSet.e))(pEnt);
-				}
-				else
-				{
-					this->*((CBaseEntity* ThisClass::*)field->pField) = pEnt;
-				}
-			}
-			return(true);
-		}
-		return(false);
+		(this->*((CEntityPointer<CBaseEntity> ThisClass::*)field->pField)).setEntityName(value);
+		return(true);
 	case PDF_FLAGS:
 		if(1 == sscanf(value, "%d", &d))
 		{
@@ -544,19 +516,8 @@ 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_PARENT:
-		(this->*((CEntityPointer ThisClass::*)field->pField)).getEntityName(out, bufsize);
-		break;
 	case PDF_ENTITY:
-		pEnt = this->*((CBaseEntity* ThisClass::*)field->pField);
-		if(!pEnt)
-		{
-			sprintf_s(out, bufsize, "");
-		}
-		else
-		{
-			sprintf_s(out, bufsize, "%s", pEnt->getName());
-		}
+		(this->*((CEntityPointer<CBaseEntity> ThisClass::*)field->pField)).getEntityName(out, bufsize);
 		break;
 	case PDF_OUTPUT:
 		{
@@ -1027,13 +988,13 @@ void CBaseEntity::renderEditor(bool is3D)
 
 }
 
-void CBaseEntity::registerPointer(CEntityPointer *pPtr)
+void CBaseEntity::registerPointer(IEntityPointer *pPtr)
 {
 	ScopedSpinLock lock(m_slPointers);
 	m_aPointers.push_back(pPtr);
 }
 
-void CBaseEntity::unregisterPointer(CEntityPointer *pPtr)
+void CBaseEntity::unregisterPointer(IEntityPointer *pPtr)
 {
 	ScopedSpinLock lock(m_slPointers);
 	int idx = m_aPointers.indexOf(pPtr);
diff --git a/source/game/BaseEntity.h b/source/game/BaseEntity.h
index ff40b13494654a48598c57171533bea63969354f..ad35a5c17fa515d1560c67e8b2bc7b89d5410e00 100644
--- a/source/game/BaseEntity.h
+++ b/source/game/BaseEntity.h
@@ -45,6 +45,8 @@ class SXGAME_EXPORT CBaseEntity
 	DECLARE_PROPTABLE();
 
 	friend class CEntityManager;
+
+	template<typename T>
 	friend class CEntityPointer;
 
 public:
@@ -170,9 +172,9 @@ private:
 	const XGUID *m_pGUID = NULL;
 
 	SpinLock m_slPointers;
-	Array<CEntityPointer*> m_aPointers;
-	void registerPointer(CEntityPointer *pPtr);
-	void unregisterPointer(CEntityPointer *pPtr);
+	Array<IEntityPointer*> m_aPointers;
+	void registerPointer(IEntityPointer *pPtr);
+	void unregisterPointer(IEntityPointer *pPtr);
 	void notifyPointers();
 
 	void onParentSet(CBaseEntity *pNewParent);
@@ -215,12 +217,12 @@ protected:
 
 	//! Родитель
 	// CBaseEntity *m_pParent = NULL;
-	CEntityPointer m_pParent;
+	CEntityPointer<CBaseEntity> m_pParent;
 	//! Индекс кости родителя
 	int m_iParentAttachment = -1;
 
 	//! Владелец
-	CBaseEntity *m_pOwner = NULL;
+	CEntityPointer<CBaseEntity> m_pOwner;
 
 	//! Вызывается на стадии синхронизации
 	virtual void onSync()
diff --git a/source/game/BaseTool.cpp b/source/game/BaseTool.cpp
index e7d1be26f0c896f6c1c0c0ec6ffd0c6e65f1cbae..bbf92e0e6520a533b46bf68874e07e8a5b14ced1 100644
--- a/source/game/BaseTool.cpp
+++ b/source/game/BaseTool.cpp
@@ -179,7 +179,7 @@ void CBaseTool::secondaryAction(BOOL st)
 	m_bInSecondaryAction = st != FALSE;
 	if(m_iZoomable)
 	{
-		((CPlayer*)m_pOwner)->getCrosshair()->enable(!st);
+		((CPlayer*)m_pOwner.getEntity())->getCrosshair()->enable(!st);
 	}
 }
 
@@ -238,7 +238,7 @@ void CBaseTool::onSync()
 {
 	if(m_pOwner)
 	{
-		float3_t ang = ((CPlayer*)m_pOwner)->getWeaponDeltaAngles();
+		float3_t ang = ((CPlayer*)m_pOwner.getEntity())->getWeaponDeltaAngles();
 		m_qOffsetOrient = m_qSlotRotResult * SMQuaternion(ang.x, 'x') * SMQuaternion(ang.y, 'y') * SMQuaternion(ang.z, 'z');
 	}
 	else
@@ -265,7 +265,7 @@ void CBaseTool::_update(float dt)
 		float3 start = m_pParent->getPos();
 		float3 dir = m_pParent->getOrient() * float3(0.0f, 0.0f, 1.0f);
 		float3 end = start + dir * m_fCenterLength;
-		btKinematicClosestNotMeRayResultCallback cb(((CBaseCharacter*)m_pOwner)->getBtCollisionObject(), F3_BTVEC(start), F3_BTVEC(end));
+		btKinematicClosestNotMeRayResultCallback cb(((CBaseCharacter*)m_pOwner.getEntity())->getBtCollisionObject(), F3_BTVEC(start), F3_BTVEC(end));
 		SPhysics_GetDynWorld()->rayTest(F3_BTVEC(start), F3_BTVEC(end), cb);
 
 		m_isClose = cb.hasHit();
@@ -344,7 +344,7 @@ void CBaseTool::_rezoom()
 	m_qSlotRotResult = SMquaternionSlerp(SMquaternionSlerp(m_qSlotRot, m_qSlotRotClose, m_fCloseProgress), m_qSlotRotAim, m_fZoomProgress);
 	if(m_pOwner && m_pOwner->getClassName() && !fstrcmp(m_pOwner->getClassName(), "player"))
 	{
-		((CPlayer*)m_pOwner)->getCamera()->getCamera()->setFOV(SMToRadian(vlerp(*r_default_fov, *r_default_fov - 10.0f, m_fZoomProgress)));
+		((CPlayer*)m_pOwner.getEntity())->getCamera()->getCamera()->setFOV(SMToRadian(vlerp(*r_default_fov, *r_default_fov - 10.0f, m_fZoomProgress)));
 	}
 }
 
diff --git a/source/game/BaseWeapon.cpp b/source/game/BaseWeapon.cpp
index fda77236f49b26bb1e018df98b1b522958ea1f7f..67f5c8803f5bbcb3e3cf75a34eee39b56ff4cc73 100644
--- a/source/game/BaseWeapon.cpp
+++ b/source/game/BaseWeapon.cpp
@@ -230,7 +230,7 @@ void CBaseWeapon::secondaryAction(BOOL st)
 	m_bInSecondaryAction = st != FALSE;
 	if(m_iZoomable)
 	{
-		((CPlayer*)m_pOwner)->getCrosshair()->enable(!st);
+		((CPlayer*)m_pOwner.getEntity())->getCrosshair()->enable(!st);
 	}
 }
 
@@ -254,7 +254,7 @@ void CBaseWeapon::reload()
 			printf(COLOR_MAGENTA "Mag full!\n" COLOR_RESET);
 			return;
 		}
-		int count = ((CBaseCharacter*)m_pOwner)->getInventory()->consumeItems(m_szLoadedAmmo, iWantLoad);
+		int count = ((CBaseCharacter*)m_pOwner.getEntity())->getInventory()->consumeItems(m_szLoadedAmmo, iWantLoad);
 		if(count)
 		{
 			bool isFast = m_iCapacity == m_iCurrentLoad;
@@ -283,7 +283,7 @@ void CBaseWeapon::reload()
 			if(pHUD)
 			{
 				pHUD->setWeaponCurrentLoad((m_pMag ? m_pMag->getLoad() : 0) + m_iCurrentLoad);
-				pHUD->setWeaponMaxAmmo(((CBaseCharacter*)m_pOwner)->getInventory()->getItemCount(m_szLoadedAmmo));
+				pHUD->setWeaponMaxAmmo(((CBaseCharacter*)m_pOwner.getEntity())->getInventory()->getItemCount(m_szLoadedAmmo));
 			}
 		}
 		else
@@ -505,12 +505,12 @@ void CBaseWeapon::updateHUDinfo()
 {
 	if(m_pOwner)
 	{
-		CHUDcontroller * pHUD = ((CBaseCharacter*)m_pOwner)->getHUDcontroller();
+		CHUDcontroller *pHUD = ((CBaseCharacter*)m_pOwner.getEntity())->getHUDcontroller();
 		if(pHUD)
 		{
 			pHUD->setWeaponMaxLoad((m_pMag ? m_pMag->getCapacity() : 0)/* + m_iCapacity*/);
 			pHUD->setWeaponCurrentLoad((m_pMag ? m_pMag->getLoad() : 0) + m_iCurrentLoad);
-			pHUD->setWeaponMaxAmmo(((CBaseCharacter*)m_pOwner)->getInventory()->getItemCount(m_szLoadedAmmo));
+			pHUD->setWeaponMaxAmmo(((CBaseCharacter*)m_pOwner.getEntity())->getInventory()->getItemCount(m_szLoadedAmmo));
 		}
 	}
 }
diff --git a/source/game/EditorObject.cpp b/source/game/EditorObject.cpp
index f30dcc9bfd0bcf962d57df10691813f903173e60..11af1e264f46b7b7d47f0209a4a20f45149e92c2 100644
--- a/source/game/EditorObject.cpp
+++ b/source/game/EditorObject.cpp
@@ -40,13 +40,22 @@ void CEditorObject::_iniFieldList()
 {
 	proptable_t *pTable = CEntityFactoryMap::GetInstance()->getPropTable(m_szClassName);
 	propdata_t *pField = NULL;
-	X_PROP_FIELD xField;
+	X_PROP_FIELD xField = {};
 
 	for(UINT i = 0; i < 16; ++i)
 	{
 		m_aszFlags[i] = NULL;
 	}
 
+	{
+		xField.editorType = XPET_TEXT; 
+		xField.szHelp = "";
+		xField.szKey = "guid";
+		xField.szName = "GUID";
+
+		m_aFields.push_back(xField);
+	}
+
 	while(pTable)
 	{
 		for(int i = 0; i < pTable->numFields; ++i)
@@ -322,7 +331,14 @@ const char* XMETHODCALLTYPE CEditorObject::getKV(const char *szKey)
 
 	char tmp[4096];
 
-	m_pEntity->getKV(szKey, tmp, sizeof(tmp));
+	if(!fstrcmp(szKey, "guid"))
+	{
+		XGUIDToSting(*m_pEntity->getGUID(), tmp, sizeof(tmp));
+	}
+	else
+	{
+		m_pEntity->getKV(szKey, tmp, sizeof(tmp));
+	}
 
 	m_msPropCache[szKey] = tmp;
 	return(m_msPropCache[szKey].c_str());
diff --git a/source/game/EntityManager.cpp b/source/game/EntityManager.cpp
index 92107cac1841c1a07654d8eeee5697d6f28a80cc..0317024cd2de051a5a0880ec26c6f1ab9619c49e 100644
--- a/source/game/EntityManager.cpp
+++ b/source/game/EntityManager.cpp
@@ -1301,18 +1301,18 @@ CBaseline *CEntityManager::deserializeBaseline(ID id, INETbuff *pBuf)
 }
 #endif
 
-void CEntityManager::registerWaitForGUID(const XGUID &guid, CEntityPointer *pPtr)
+void CEntityManager::registerWaitForGUID(const XGUID &guid, IEntityPointer *pPtr)
 {
 	ScopedSpinLock lock(m_slWaitingPointers);
 
 	m_maWaitingPointers[guid].push_back(pPtr);
 }
 
-void CEntityManager::unregisterWaitForGUID(const XGUID &guid, CEntityPointer *pPtr)
+void CEntityManager::unregisterWaitForGUID(const XGUID &guid, IEntityPointer *pPtr)
 {
 	ScopedSpinLock lock(m_slWaitingPointers);
 
-	Array<CEntityPointer*> &list = m_maWaitingPointers[guid];
+	Array<IEntityPointer*> &list = m_maWaitingPointers[guid];
 
 	int idx = list.indexOf(pPtr);
 	assert(idx >= 0);
@@ -1330,10 +1330,10 @@ void CEntityManager::notifyWaitForGUID(const XGUID &guid, CBaseEntity *pEnt)
 {
 	ScopedSpinLock lock(m_slWaitingPointers);
 
-	const Map<XGUID, Array<CEntityPointer*>>::Node *pNode;
+	const Map<XGUID, Array<IEntityPointer*>>::Node *pNode;
 	if(m_maWaitingPointers.KeyExists(guid, &pNode))
 	{
-		Array<CEntityPointer*> &list = m_maWaitingPointers[guid];
+		Array<IEntityPointer*> &list = m_maWaitingPointers[guid];
 		for(UINT i = 0, l = list.size(); i < l; ++i)
 		{
 			list[i]->onWaitDone(pEnt);
diff --git a/source/game/EntityManager.h b/source/game/EntityManager.h
index a411a015b157d6ac1be1b093b48c19cd9cc4f9e9..7355d911ade294ab59460ab7a1b78634278163df 100644
--- a/source/game/EntityManager.h
+++ b/source/game/EntityManager.h
@@ -89,6 +89,7 @@ class CEntityManager
 
 	friend class CBaseEntity;
 	friend class CEntityFactoryMap;
+	template<typename T>
 	friend class CEntityPointer;
 public:
 	CEntityManager();
@@ -183,10 +184,10 @@ protected:
 private:
 	void finalRemove();
 
-	Map<XGUID, Array<CEntityPointer*>> m_maWaitingPointers;
+	Map<XGUID, Array<IEntityPointer*>> m_maWaitingPointers;
 	SpinLock m_slWaitingPointers;
-	void registerWaitForGUID(const XGUID &guid, CEntityPointer *pPtr);
-	void unregisterWaitForGUID(const XGUID &guid, CEntityPointer *pPtr);
+	void registerWaitForGUID(const XGUID &guid, IEntityPointer *pPtr);
+	void unregisterWaitForGUID(const XGUID &guid, IEntityPointer *pPtr);
 	void notifyWaitForGUID(const XGUID &guid, CBaseEntity *pEnt);
 
 	bool m_isOldImported = false;
diff --git a/source/game/EntityPointer.cpp b/source/game/EntityPointer.cpp
deleted file mode 100644
index 64764639e83db911e3f7dd916efe8baf0bd3c263..0000000000000000000000000000000000000000
--- a/source/game/EntityPointer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-#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
index 647f3c682942b42ab8594fce79348bfc9da24b09..da7a94bbce3658bb71ad7a6751405b709c88773f 100644
--- a/source/game/EntityPointer.h
+++ b/source/game/EntityPointer.h
@@ -3,74 +3,267 @@
 
 #include <gdefines.h>
 
+class IEntityPointer
+{
+	friend class CBaseEntity;
+	friend class CEntityManager;
+
+private:
+	virtual void onTargetRemoved() = 0;
+	virtual void onWaitDone(CBaseEntity *pEnt) = 0;
+};
+
 class CBaseEntity;
 class CEntityManager;
-class CEntityPointer
+template<typename T>
+class CEntityPointer: public IEntityPointer
 {
 	DECLARE_CLASS_NOBASE(CEntityPointer);
 	friend class CBaseEntity;
-	friend class CEntityManager;
 public:
 	
-	~CEntityPointer();
+	CEntityPointer():
+		m_pfnCheckEntityType(&CEntityFactoryMap::IsEntityOfClass<T>)
+	{
+	}
+
+	~CEntityPointer()
+	{
+		SAFE_CALL(m_pEntity, unregisterPointer, this);
+
+		unregisterWait();
+	}
 
 	//! Установка имени или GUID связанного объекта
-	void setEntityName(const char *szName);
+	void setEntityName(const char *szName)
+	{
+		if(szName[0] == '{')
+		{
+			XGUID guid;
+			if(XGUIDFromString(&guid, szName))
+			{
+				setEntityGUID(guid);
+				return;
+			}
+		}
+
+		CBaseEntity *pEnt = m_pMgr->findEntityByName(szName);
+
+		if(pEnt)
+		{
+			if(m_pfnCheckEntityType(pEnt))
+			{
+				setEntity(pEnt);
+			}
+			else
+			{
+				char tmp1[64], tmp2[64];
+				XGUIDToSting(m_guid, tmp1, sizeof(tmp1));
+				XGUIDToSting(*m_pThisEntity->getGUID(), tmp2, sizeof(tmp2));
+				LibReport(REPORT_MSG_LEVEL_ERROR, "Unable to link entity '%s' to entity '%s'. Invalid class %s\n", tmp1, tmp2, pEnt->getClassName());
+			}
+		}
+	}
 
 	//! Установка GUID
-	void setEntityGUID(const XGUID &guid);
+	void setEntityGUID(const XGUID &guid)
+	{
+		CBaseEntity *pEnt = m_pMgr->getByGUID(guid);
+		
+		if(pEnt)
+		{
+			if(m_pfnCheckEntityType(pEnt))
+			{
+				setEntity(pEnt);
+			}
+			else
+			{
+				char tmp1[64], tmp2[64];
+				XGUIDToSting(m_guid, tmp1, sizeof(tmp1));
+				XGUIDToSting(*m_pThisEntity->getGUID(), tmp2, sizeof(tmp2));
+				LibReport(REPORT_MSG_LEVEL_ERROR, "Unable to link entity '%s' to entity '%s'. Invalid class %s\n", tmp1, tmp2, pEnt->getClassName());
+			}
+		}
+		else
+		{
+			m_guid = guid;
+			registerWait();
+		}
+	}
 
 	//! Установка
-	void setEntity(CBaseEntity *pEnt);
+	void setEntity(T *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* getEntity();
+	T* getEntity()
+	{
+		return(m_pEntity);
+	}
 
-	void getEntityName(char *szOutput, int iBufSize);
-	const XGUID& getGUID();
+	void 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;
+			}
+		}
 
-	CBaseEntity* operator->();
-	operator CBaseEntity*();
+		if(m_guid == XGUID())
+		{
+			if(iBufSize)
+			{
+				szOutput[0] = 0;
+			}
+			return;
+		}
 
-	CEntityPointer& operator=(CBaseEntity *pEnt);
+		char tmp[64];
+		XGUIDToSting(m_guid, tmp, sizeof(tmp));
+		strncpy(szOutput, tmp, iBufSize);
+		szOutput[iBufSize - 1] = 0;
+	}
+	const XGUID& getGUID()
+	{
+		return(m_guid);
+	}
+
+	T* operator->()
+	{
+		return(getEntity());
+	}
+	operator T*()
+	{
+		return(getEntity());
+	}
+
+	CEntityPointer& operator=(T *pEnt)
+	{
+		setEntity(pEnt);
+		return(*this);
+	}
 
 	//! Вызывается при разрушении связи (pEnt -- указатель на объект, если причиной разрыва связи стало не удаление объекта)
 	template<typename F>
-	void setLinkBrokenListener(void(F::*func)(CBaseEntity*))
+	void setLinkBrokenListener(void(F::*func)(T*))
 	{
 		static_assert(std::is_base_of<CBaseEntity, F>::value, "F must be subclass of CBaseEntity");
 
-		m_pfnOnLinkBroken = func;
+		m_pfnOnLinkBroken = (void(CBaseEntity::*)(T*))func;
 	}
 
 	//! Вызывается при установке связи
 	template<typename F>
-	void setLinkEstablishedListener(void(F::*func)(CBaseEntity*))
+	void setLinkEstablishedListener(void(F::*func)(T*))
 	{
 		static_assert(std::is_base_of<CBaseEntity, F>::value, "F must be subclass of CBaseEntity");
 
-		m_pfnOnLinkEstablished = func;
+		m_pfnOnLinkEstablished = (void(CBaseEntity::*)(T*))func;
 	}
 	
 private:
 	XGUID m_guid;
-	CBaseEntity *m_pEntity = NULL;
+	T *m_pEntity = NULL;
 	CEntityManager *m_pMgr = NULL;
 	CBaseEntity *m_pThisEntity = NULL;
+	bool(*m_pfnCheckEntityType)(CBaseEntity*) = NULL;
 
-	void(CBaseEntity::*m_pfnOnLinkBroken)(CBaseEntity*) = NULL;
-	void(CBaseEntity::*m_pfnOnLinkEstablished)(CBaseEntity*) = NULL;
+	void(CBaseEntity::*m_pfnOnLinkBroken)(T*) = NULL;
+	void(CBaseEntity::*m_pfnOnLinkEstablished)(T*) = NULL;
 
-	void init(CEntityManager *pWorld, CBaseEntity *pThisEntity);
+	void init(CEntityManager *pWorld, CBaseEntity *pThisEntity)
+	{
+		m_pMgr = pWorld;
+		m_pThisEntity = pThisEntity;
+	}
 
-	void onLinkBroken(CBaseEntity *pOldEnt);
-	void onLinkEstablished(CBaseEntity *pNewEnt);
-	void onTargetRemoved();
+	void onLinkBroken(T *pOldEnt)
+	{
+		if(m_pfnOnLinkBroken)
+		{
+			(m_pThisEntity->*m_pfnOnLinkBroken)(pOldEnt);
+		}
+	}
+	void onLinkEstablished(T *pNewEnt)
+	{
+		pNewEnt->registerPointer(this);
+
+		if(m_pfnOnLinkEstablished)
+		{
+			(m_pThisEntity->*m_pfnOnLinkEstablished)(pNewEnt);
+		}
+	}
+	void onTargetRemoved() override
+	{
+		onLinkBroken(NULL);
+		m_pEntity = NULL;
+		registerWait();
+	}
 
 	bool m_isWaiting = false;
-	void registerWait();
-	void unregisterWait();
-	void onWaitDone(CBaseEntity *pEnt);
+	void registerWait()
+	{
+		if(!m_isWaiting)
+		{
+			m_pMgr->registerWaitForGUID(m_guid, this);
+			m_isWaiting = true;
+		}
+	}
+	void unregisterWait()
+	{
+		if(m_isWaiting)
+		{
+			m_pMgr->unregisterWaitForGUID(m_guid, this);
+			m_isWaiting = false;
+		}
+	}
+	void onWaitDone(CBaseEntity *pEnt) override
+	{
+		assert(m_isWaiting);
+
+		m_isWaiting = false;
+
+		if(m_pfnCheckEntityType(pEnt))
+		{
+			m_pEntity = (T*)pEnt;
+
+			onLinkEstablished((T*)pEnt);
+		}
+		else
+		{
+			char tmp1[64], tmp2[64];
+			XGUIDToSting(m_guid, tmp1, sizeof(tmp1));
+			XGUIDToSting(*m_pThisEntity->getGUID(), tmp2, sizeof(tmp2));
+			LibReport(REPORT_MSG_LEVEL_ERROR, "Unable to link entity '%s' to entity '%s'. Invalid class %s\n", tmp1, tmp2, pEnt->getClassName());
+		}
+	}
 };
 
 #endif
diff --git a/source/game/FuncTrain.cpp b/source/game/FuncTrain.cpp
index 466178eb6943f88ef1285a1784121b54f6a26039..550adde21b3ef0d56f6aae4c3b13c06a5e518e18 100644
--- a/source/game/FuncTrain.cpp
+++ b/source/game/FuncTrain.cpp
@@ -16,7 +16,7 @@ BEGIN_PROPTABLE(CFuncTrain)
 	DEFINE_FIELD_FLOAT(m_fSpeed, 0, "speed", "Move speed", EDITOR_TEXTFIELD)
 
 	//! path_corner, с которого начнется движение
-	DEFINE_FIELD_ENTITY2(CPathCorner, m_pStartStop, 0, "start", "Start point", EDITOR_TEXTFIELD)
+	DEFINE_FIELD_ENTITY(CPathCorner, m_pStartStop, 0, "start", "Start point", EDITOR_TEXTFIELD)
 END_PROPTABLE()
 
 REGISTER_ENTITY(CFuncTrain, func_train);
diff --git a/source/game/FuncTrain.h b/source/game/FuncTrain.h
index d03ad5bc8f1c019e474d665df23609b3adb8a050..cc1630befc7d50117e8a94d1e57a27f1cd0d5299 100644
--- a/source/game/FuncTrain.h
+++ b/source/game/FuncTrain.h
@@ -12,8 +12,7 @@ See the license in LICENSE
 #define __FUNC_TRAIN_H
 
 #include "PointEntity.h"
-
-class CPathCorner;
+#include "PathCorner.h"
 
 /*! Поезда класс
 \ingroup cpointentity
@@ -35,7 +34,7 @@ protected:
 	void moveFunc(float dt);
 
 	//! Начальная точка движения
-	CPathCorner *m_pStartStop = NULL;
+	CEntityPointer<CPathCorner> m_pStartStop;
 	//! Текущая точка
 	CPathCorner *m_pCurStop = NULL;
 
diff --git a/source/game/PathCorner.cpp b/source/game/PathCorner.cpp
index 0bfe9cca48b328e1910d47261e4f92628d9dc265..a421a920c563f029f206284a56998d97e687eff8 100644
--- a/source/game/PathCorner.cpp
+++ b/source/game/PathCorner.cpp
@@ -21,12 +21,19 @@ BEGIN_PROPTABLE(CPathCorner)
 	DEFINE_FIELD_FLOAT(m_fNewSpeed, 0, "speed", "New speed", EDITOR_TEXTFIELD)
 
 	//! Следующая точка пути
-	DEFINE_FIELD_ENTITY2FN(CPathCorner, m_pNextStop, 0, "next", "Next stop", setNextPoint, EDITOR_TEXTFIELD)
+	DEFINE_FIELD_ENTITY(CPathCorner, m_pNextStop, 0, "next", "Next stop", EDITOR_TEXTFIELD)
+
+	DEFINE_FIELD_ENTITY(CPathCorner, m_pPrevStop, PDFF_NOEDIT | PDFF_NOEXPORT, "prev", "Prev stop", EDITOR_NONE)
 
 END_PROPTABLE()
 
 REGISTER_ENTITY(CPathCorner, path_corner);
 
+CPathCorner::CPathCorner()
+{
+	m_pNextStop.setLinkEstablishedListener(&CPathCorner::setNextPoint);
+}
+
 CPathCorner::~CPathCorner()
 {
 	setNextPoint(NULL);
diff --git a/source/game/PathCorner.h b/source/game/PathCorner.h
index c15064c6abead767ef84e09d3a4cc9750a68760c..2e67c98e19964cea56e672c6ae4c5d6973af0e9c 100644
--- a/source/game/PathCorner.h
+++ b/source/game/PathCorner.h
@@ -31,7 +31,7 @@ class CPathCorner: public CPointEntity
 	DECLARE_CLASS(CPathCorner, CPointEntity);
 	DECLARE_PROPTABLE();
 public:
-	DECLARE_TRIVIAL_CONSTRUCTOR();
+	DECLARE_CONSTRUCTOR();
 	~CPathCorner();
 
 	//! получает координаты точки на пути на расстоянии dist от начала
@@ -78,9 +78,9 @@ protected:
 	//! @}
 
 	//! Следующая точка
-	CPathCorner *m_pNextStop = NULL;
+	CEntityPointer<CPathCorner> m_pNextStop;
 	//! Предыдущая точка
-	CPathCorner *m_pPrevStop = NULL;
+	CEntityPointer<CPathCorner> m_pPrevStop;
 };
 
 #endif
diff --git a/source/game/TriggerTeleport.cpp b/source/game/TriggerTeleport.cpp
index 15ce00a12360a549bc8d64926d6c540cbdd32195..d96649db9b2372c0926545162c218be4254abd91 100644
--- a/source/game/TriggerTeleport.cpp
+++ b/source/game/TriggerTeleport.cpp
@@ -14,9 +14,9 @@ See the license in LICENSE
 
 BEGIN_PROPTABLE(CTriggerTeleport)
 	//! Локальный маркер для относительных координат
-	DEFINE_FIELD_ENTITY(m_pLandmark, PDFF_NONE, "landmark", "Landmark object", EDITOR_TEXTFIELD)
+	DEFINE_FIELD_ENTITY(CBaseEntity, m_pLandmark, PDFF_NONE, "landmark", "Landmark object", EDITOR_TEXTFIELD)
 	//! Цель
-	DEFINE_FIELD_ENTITY(m_pDestination, PDFF_NONE, "destination", "Destination landmark object", EDITOR_TEXTFIELD)
+	DEFINE_FIELD_ENTITY(CBaseEntity, m_pDestination, PDFF_NONE, "destination", "Destination landmark object", EDITOR_TEXTFIELD)
 END_PROPTABLE()
 
 REGISTER_ENTITY(CTriggerTeleport, trigger_teleport);
diff --git a/source/game/TriggerTeleport.h b/source/game/TriggerTeleport.h
index 721011d6654895ddca79351af5c59eacb673f8c0..61042aa7568c90513d6f8d444b3497c4efc64f67 100644
--- a/source/game/TriggerTeleport.h
+++ b/source/game/TriggerTeleport.h
@@ -31,8 +31,8 @@ protected:
 	virtual void onTouchStart(CBaseEntity *pActivator) override;
 
 private:
-	CBaseEntity *m_pLandmark = NULL;
-	CBaseEntity *m_pDestination = NULL;
+	CEntityPointer<CBaseEntity> m_pLandmark;
+	CEntityPointer<CBaseEntity> m_pDestination;
 };
 
 #endif
diff --git a/source/game/proptable.h b/source/game/proptable.h
index 7a72d969b3ddd35d9aa0d0151d912f69e0781289..40b0e428974c671ca970595fc7ac9c3f05c39585 100644
--- a/source/game/proptable.h
+++ b/source/game/proptable.h
@@ -51,7 +51,6 @@ enum PDF_TYPE
 	PDF_STRING,
 	PDF_ANGLES,
 	PDF_ENTITY,
-	PDF_PARENT,
 	PDF_FLAGS,
 
 	PDF_FLAG,
@@ -193,7 +192,6 @@ struct inputdata_t
 };
 
 typedef void(CBaseEntity::*input_func)(inputdata_t *pInputData);
-typedef bool(*PFNCHECKENTTYPE)(CBaseEntity*);
 
 struct propdata_t
 {
@@ -205,7 +203,7 @@ struct propdata_t
 		szEdName(NULL),
 		editor({})
 	{}
-	propdata_t(fieldtype f, PDF_TYPE t, int fl, const char *key, const char *edname, PFNCHECKENTTYPE pfnCheckType, prop_editor_t ed):
+	propdata_t(fieldtype f, PDF_TYPE t, int fl, const char *key, const char *edname, prop_editor_t ed):
 		pField(f),
 		type(t),
 		flags(fl),
@@ -213,7 +211,7 @@ struct propdata_t
 		szEdName(edname),
 		editor(ed)
 	{}
-	propdata_t(fieldtype f, PDF_TYPE t, int fl, const char *key, const char *edname, PFNFIELDSET _fnSet, PFNCHECKENTTYPE pfnCheckType, prop_editor_t ed):
+	propdata_t(fieldtype f, PDF_TYPE t, int fl, const char *key, const char *edname, PFNFIELDSET _fnSet, prop_editor_t ed):
 		pField(f),
 		type(t),
 		flags(fl),
@@ -242,8 +240,6 @@ struct propdata_t
 	prop_editor_t editor;
 	PFNFIELDSET fnSet;
 
-	PFNCHECKENTTYPE pfnCheckType = NULL;
-
 	template<typename T>
 	static fieldtype ToFieldType(T arg)
 	{
@@ -421,36 +417,31 @@ 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<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_STRING(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<const char* DataClass::*>(&DataClass::field),          PDF_STRING,  flags, keyname, edname, editor
+#define DEFINE_FIELD_VECTOR(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<float3_t DataClass::*>(&DataClass::field),             PDF_VECTOR,  flags, keyname, edname, editor
+#define DEFINE_FIELD_VECTOR4(field, flags, keyname, edname, editor)             , {propdata_t::ToFieldType<float4_t DataClass::*>(&DataClass::field),             PDF_VECTOR4, flags, keyname, edname, editor
+#define DEFINE_FIELD_ANGLES(field, flags, keyname, edname, editor)              , {propdata_t::ToFieldType<SMQuaternion DataClass::*>(&DataClass::field),         PDF_ANGLES,  flags, keyname, edname, editor
+#define DEFINE_FIELD_INT(field, flags, keyname, edname, editor)                 , {propdata_t::ToFieldType<int DataClass::*>(&DataClass::field),                  PDF_INT,     flags, keyname, edname, editor
+#define DEFINE_FIELD_ENUM(type, field, flags, keyname, edname, editor)          , {propdata_t::ToFieldType<type DataClass::*>(&DataClass::field),                 PDF_INT,     flags, keyname, edname, editor
+#define DEFINE_FIELD_FLOAT(field, flags, keyname, edname, editor)               , {propdata_t::ToFieldType<float DataClass::*>(&DataClass::field),                PDF_FLOAT,   flags, keyname, edname, editor
+#define DEFINE_FIELD_BOOL(field, flags, keyname, edname, editor)                , {propdata_t::ToFieldType<bool DataClass::*>(&DataClass::field),                 PDF_BOOL,    flags, keyname, edname, editor
+#define DEFINE_FIELD_ENTITY(type, field, flags, keyname, edname, editor)        , {propdata_t::ToFieldType<CEntityPointer<type> DataClass::*>(&DataClass::field), PDF_ENTITY,  flags, keyname, edname, editor
+#define DEFINE_FIELD_FLAGS(field, flags, keyname, edname, editor)               , {propdata_t::ToFieldType<UINT DataClass::*>(&DataClass::field),                 PDF_FLAGS,   flags, keyname, edname, 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),         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),       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),       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), 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),                 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),                 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),               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),                editor
 //#define DEFINE_FIELD_FLAGSFN(field, flags, keyname, edname, fn, editor)  , {(fieldtype)&DataClass::field, PDF_FLAGS,  flags, keyname, edname, fn, editor
 
 #define DEFINE_INPUT(method, keyname, edname, argtype)   , {propdata_t::ToInputFunc<void(DataClass::*)(inputdata_t*)>(&DataClass::method), argtype, PDFF_NOEDIT | PDFF_INPUT, keyname, edname, EDITOR_NONE
-#define DEFINE_OUTPUT(field, keyname, edname)            , {propdata_t::ToFieldType<output_t DataClass::*>(&DataClass::field), PDF_OUTPUT, PDFF_NOEDIT | PDFF_OUTPUT, keyname, edname, NULL, EDITOR_NONE
+#define DEFINE_OUTPUT(field, keyname, edname)            , {propdata_t::ToFieldType<output_t DataClass::*>(&DataClass::field), PDF_OUTPUT, PDFF_NOEDIT | PDFF_OUTPUT, keyname, edname, EDITOR_NONE
 #define DEFINE_MESSAGE(method, keyname, edname, argtype) , {propdata_t::ToInputFunc<void(DataClass::*)(inputdata_t*)>(&DataClass::method), argtype, PDFF_NOEDIT | PDFF_MESSAGE, keyname, edname, EDITOR_NONE
 
-#define DEFINE_FLAG(value, edname)                       , {(fieldtype)NULL, PDF_FLAG, value, NULL, edname, NULL, EDITOR_FLAGS
+#define DEFINE_FLAG(value, edname)                       , {(fieldtype)NULL, PDF_FLAG, value, NULL, edname, EDITOR_FLAGS
 
 #endif