added amb719, added TE hooks and read prop natives to read props before transmission
authorBorja Ferrer <faluco@alliedmods.net>
Fri Aug 03 01:53:00 2007 +0000 (2007-08-03)
changeset 1255e3db1a9eb578
parent 1254 35fe1f1f2a6e
child 1256 76416aff76c3
added amb719, added TE hooks and read prop natives to read props before transmission
extensions/sdktools/extension.cpp
extensions/sdktools/tempents.cpp
extensions/sdktools/tempents.h
extensions/sdktools/tenatives.cpp
plugins/include/sdktools_tempents.inc
     1.1 --- a/extensions/sdktools/extension.cpp	Thu Aug 02 23:11:07 2007 +0000
     1.2 +++ b/extensions/sdktools/extension.cpp	Fri Aug 03 01:53:00 2007 +0000
     1.3 @@ -119,6 +119,7 @@
     1.4  	ShutdownHelpers();
     1.5  
     1.6  	g_TEManager.Shutdown();
     1.7 +	s_TempEntHooks.Shutdown();
     1.8  
     1.9  	gameconfs->CloseGameConfigFile(g_pGameConf);
    1.10  	playerhelpers->RemoveClientListener(&g_SdkTools);
    1.11 @@ -143,6 +144,7 @@
    1.12  	SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
    1.13  
    1.14  	g_TEManager.Initialize();
    1.15 +	s_TempEntHooks.Initialize();
    1.16  	InitializeValveGlobals();
    1.17  }
    1.18  
    1.19 @@ -176,6 +178,7 @@
    1.20  	ShutdownHelpers();
    1.21  
    1.22  	g_TEManager.Shutdown();
    1.23 +	s_TempEntHooks.Shutdown();
    1.24  }
    1.25  
    1.26  bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar)
     2.1 --- a/extensions/sdktools/tempents.cpp	Thu Aug 02 23:11:07 2007 +0000
     2.2 +++ b/extensions/sdktools/tempents.cpp	Fri Aug 03 01:53:00 2007 +0000
     2.3 @@ -143,6 +143,31 @@
     2.4  	return true;
     2.5  }
     2.6  
     2.7 +bool TempEntityInfo::TE_GetEntData(const char *name, int *value)
     2.8 +{
     2.9 +	/* Search for our offset */
    2.10 +	int size;
    2.11 +	int offset = _FindOffset(name, &size);
    2.12 +
    2.13 +	if (offset < 0)
    2.14 +	{
    2.15 +		return false;
    2.16 +	}
    2.17 +
    2.18 +	if (size <= 8)
    2.19 +	{
    2.20 +		*value = *((uint8_t *)m_Me + offset);
    2.21 +	} else if (size <= 16) {
    2.22 +		*value = *(short *)((uint8_t *)m_Me + offset);
    2.23 +	} else if (size <= 32) {
    2.24 +		*value = *(int *)((uint8_t *)m_Me + offset);
    2.25 +	} else {
    2.26 +		return false;
    2.27 +	}
    2.28 +
    2.29 +	return true;
    2.30 +}
    2.31 +
    2.32  bool TempEntityInfo::TE_SetEntDataFloat(const char *name, float value)
    2.33  {
    2.34  	/* Search for our offset */
    2.35 @@ -158,6 +183,21 @@
    2.36  	return true;
    2.37  }
    2.38  
    2.39 +bool TempEntityInfo::TE_GetEntDataFloat(const char *name, float *value)
    2.40 +{
    2.41 +	/* Search for our offset */
    2.42 +	int offset = _FindOffset(name);
    2.43 +
    2.44 +	if (offset < 0)
    2.45 +	{
    2.46 +		return false;
    2.47 +	}
    2.48 +
    2.49 +	*value = *(float *)((uint8_t *)m_Me + offset);
    2.50 +
    2.51 +	return true;
    2.52 +}
    2.53 +
    2.54  bool TempEntityInfo::TE_SetEntDataVector(const char *name, float vector[3])
    2.55  {
    2.56  	/* Search for our offset */
    2.57 @@ -176,6 +216,24 @@
    2.58  	return true;
    2.59  }
    2.60  
    2.61 +bool TempEntityInfo::TE_GetEntDataVector(const char *name, float vector[3])
    2.62 +{
    2.63 +	/* Search for our offset */
    2.64 +	int offset = _FindOffset(name);
    2.65 +
    2.66 +	if (offset < 0)
    2.67 +	{
    2.68 +		return false;
    2.69 +	}
    2.70 +
    2.71 +	Vector *v = (Vector *)((uint8_t *)m_Me + offset);
    2.72 +	vector[0] = v->x;
    2.73 +	vector[1] = v->y;
    2.74 +	vector[2] = v->z;
    2.75 +
    2.76 +	return true;
    2.77 +}
    2.78 +
    2.79  bool TempEntityInfo::TE_SetEntDataFloatArray(const char *name, cell_t *array, int size)
    2.80  {
    2.81  	/* Search for our offset */
    2.82 @@ -314,6 +372,11 @@
    2.83  	return te;
    2.84  }
    2.85  
    2.86 +const char *TempEntityManager::GetNameFromThisPtr(void *me)
    2.87 +{
    2.88 +	return *(const char **)((unsigned char *)me + m_NameOffs);
    2.89 +}
    2.90 +
    2.91  void TempEntityManager::DumpList()
    2.92  {
    2.93  	unsigned int index = 0;
     3.1 --- a/extensions/sdktools/tempents.h	Thu Aug 02 23:11:07 2007 +0000
     3.2 +++ b/extensions/sdktools/tempents.h	Fri Aug 03 01:53:00 2007 +0000
     3.3 @@ -53,6 +53,9 @@
     3.4  	bool TE_SetEntDataFloat(const char *name, float value);
     3.5  	bool TE_SetEntDataVector(const char *name, float vector[3]);
     3.6  	bool TE_SetEntDataFloatArray(const char *name, cell_t *array, int size);
     3.7 +	bool TE_GetEntData(const char *name, int *value);
     3.8 +	bool TE_GetEntDataFloat(const char *name, float *value);
     3.9 +	bool TE_GetEntDataVector(const char *name, float vector[3]);
    3.10  	void Send(IRecipientFilter &filter, float delay);
    3.11  private:
    3.12  	int _FindOffset(const char *name, int *size=NULL);
    3.13 @@ -72,6 +75,7 @@
    3.14  	void Shutdown();
    3.15  public:
    3.16  	TempEntityInfo *GetTempEntityInfo(const char *name);
    3.17 +	const char *GetNameFromThisPtr(void *me);
    3.18  public:
    3.19  	void DumpList();
    3.20  	void DumpProps(FILE *fp);
    3.21 @@ -85,6 +89,31 @@
    3.22  	bool m_Loaded;
    3.23  };
    3.24  
    3.25 +struct TEHookInfo
    3.26 +{
    3.27 +	TempEntityInfo *te;
    3.28 +	List<IPluginFunction *> lst;
    3.29 +};
    3.30 +
    3.31 +class TempEntHooks
    3.32 +{
    3.33 +public:
    3.34 +	void Initialize();
    3.35 +	void Shutdown();
    3.36 +	bool AddHook(const char *name, IPluginFunction *pFunc);
    3.37 +	bool RemoveHook(const char *name, IPluginFunction *pFunc);
    3.38 +	void OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID);
    3.39 +private:
    3.40 +	void _IncRefCounter();
    3.41 +	void _DecRefCounter();
    3.42 +	size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
    3.43 +private:
    3.44 +	IBasicTrie *m_TEHooks;
    3.45 +	List<TEHookInfo *> m_HookInfo;
    3.46 +	size_t m_HookCount;
    3.47 +};
    3.48 +
    3.49  extern TempEntityManager g_TEManager;
    3.50 +extern TempEntHooks s_TempEntHooks;
    3.51  
    3.52  #endif //_INCLUDE_SOURCEMOD_TEMPENTS_H_
     4.1 --- a/extensions/sdktools/tenatives.cpp	Thu Aug 02 23:11:07 2007 +0000
     4.2 +++ b/extensions/sdktools/tenatives.cpp	Fri Aug 03 01:53:00 2007 +0000
     4.3 @@ -32,9 +32,166 @@
     4.4  
     4.5  #include "tempents.h"
     4.6  #include "CellRecipientFilter.h"
     4.7 +#include <IForwardSys.h>
     4.8 +
     4.9 +SH_DECL_HOOK5_void(IVEngineServer, PlaybackTempEntity, SH_NOATTRIB, 0, IRecipientFilter &, float, const void *, const SendTable *, int);
    4.10  
    4.11  CellRecipientFilter g_TERecFilter;
    4.12  TempEntityInfo *g_CurrentTE = NULL;
    4.13 +int g_TEPlayers[256];
    4.14 +
    4.15 +/*************************
    4.16 +*                        *
    4.17 +* Temp Entity Hook Class *
    4.18 +*                        *
    4.19 +**************************/
    4.20 +
    4.21 +void TempEntHooks::Initialize()
    4.22 +{
    4.23 +	m_TEHooks = adtfactory->CreateBasicTrie();
    4.24 +}
    4.25 +
    4.26 +void TempEntHooks::Shutdown()
    4.27 +{
    4.28 +	List<TEHookInfo *>::iterator iter;
    4.29 +	for (iter=m_HookInfo.begin(); iter!=m_HookInfo.end(); iter++)
    4.30 +	{
    4.31 +		delete (*iter);
    4.32 +	}
    4.33 +	if (m_HookCount)
    4.34 +	{
    4.35 +		m_HookCount = 1;
    4.36 +		_DecRefCounter();
    4.37 +	}
    4.38 +	m_TEHooks->Destroy();
    4.39 +}
    4.40 +
    4.41 +void TempEntHooks::_IncRefCounter()
    4.42 +{
    4.43 +	if (m_HookCount++ == 0)
    4.44 +	{
    4.45 +		SH_ADD_HOOK_MEMFUNC(IVEngineServer, PlaybackTempEntity, engine, this, &TempEntHooks::OnPlaybackTempEntity, false);
    4.46 +	}
    4.47 +}
    4.48 +
    4.49 +void TempEntHooks::_DecRefCounter()
    4.50 +{
    4.51 +	if (--m_HookCount == 0)
    4.52 +	{
    4.53 +		SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, PlaybackTempEntity, engine, this, &TempEntHooks::OnPlaybackTempEntity, false);
    4.54 +	}
    4.55 +}
    4.56 +
    4.57 +size_t TempEntHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
    4.58 +{
    4.59 +	size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
    4.60 +
    4.61 +	for (size_t i=0; i<size; i++)
    4.62 +	{
    4.63 +		pl_array[i] = pFilter->GetRecipientIndex(i);
    4.64 +	}
    4.65 +
    4.66 +	return size;
    4.67 +}
    4.68 +
    4.69 +bool TempEntHooks::AddHook(const char *name, IPluginFunction *pFunc)
    4.70 +{
    4.71 +	TEHookInfo *pInfo;
    4.72 +
    4.73 +	if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
    4.74 +	{
    4.75 +		pInfo->lst.push_back(pFunc);
    4.76 +	} else {
    4.77 +		TempEntityInfo *te;
    4.78 +		if (!(te=g_TEManager.GetTempEntityInfo(name)))
    4.79 +		{
    4.80 +			return false;
    4.81 +		}
    4.82 +
    4.83 +		pInfo = new TEHookInfo;
    4.84 +		pInfo->te = te;
    4.85 +		pInfo->lst.push_back(pFunc);
    4.86 +
    4.87 +		m_TEHooks->Insert(name, reinterpret_cast<void *>(pInfo));
    4.88 +		m_HookInfo.push_back(pInfo);
    4.89 +	}
    4.90 +
    4.91 +	_IncRefCounter();
    4.92 +
    4.93 +	return true;
    4.94 +}
    4.95 +
    4.96 +bool TempEntHooks::RemoveHook(const char *name, IPluginFunction *pFunc)
    4.97 +{
    4.98 +	TEHookInfo *pInfo;
    4.99 +
   4.100 +	if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
   4.101 +	{
   4.102 +		List<IPluginFunction *>::iterator iter;
   4.103 +		if ((iter=pInfo->lst.find(pFunc)) != pInfo->lst.end())
   4.104 +		{
   4.105 +			pInfo->lst.erase(iter);
   4.106 +			if (pInfo->lst.empty())
   4.107 +			{
   4.108 +				m_HookInfo.remove(pInfo);
   4.109 +				m_TEHooks->Delete(name);
   4.110 +				delete pInfo;
   4.111 +			}
   4.112 +			_DecRefCounter();
   4.113 +		} else {
   4.114 +			return false;
   4.115 +		}
   4.116 +	} else {
   4.117 +		return false;
   4.118 +	}
   4.119 +
   4.120 +	return true;
   4.121 +}
   4.122 +
   4.123 +void TempEntHooks::OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID)
   4.124 +{
   4.125 +	TEHookInfo *pInfo;
   4.126 +	const char *name = g_TEManager.GetNameFromThisPtr(const_cast<void *>(pSender));
   4.127 +
   4.128 +	if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
   4.129 +	{
   4.130 +		List<IPluginFunction *>::iterator iter;
   4.131 +		IPluginFunction *pFunc;
   4.132 +		size_t size;
   4.133 +		cell_t res = static_cast<ResultType>(Pl_Continue);
   4.134 +
   4.135 +		TempEntityInfo *oldinfo = g_CurrentTE;
   4.136 +		g_CurrentTE = pInfo->te;
   4.137 +		size = _FillInPlayers(g_TEPlayers, &filter);
   4.138 +
   4.139 +		for (iter=pInfo->lst.begin(); iter!=pInfo->lst.end(); iter++)
   4.140 +		{
   4.141 +			pFunc = (*iter);
   4.142 +			pFunc->PushString(name);
   4.143 +			pFunc->PushArray(g_TEPlayers, size);
   4.144 +			pFunc->PushCell(size);
   4.145 +			pFunc->PushFloat(delay);
   4.146 +			pFunc->Execute(&res);
   4.147 +
   4.148 +			if (res != Pl_Continue)
   4.149 +			{
   4.150 +				g_CurrentTE = oldinfo;
   4.151 +				RETURN_META(MRES_SUPERCEDE);
   4.152 +			}
   4.153 +		}
   4.154 +
   4.155 +		g_CurrentTE = oldinfo;
   4.156 +		RETURN_META(MRES_IGNORED);
   4.157 +	}
   4.158 +}
   4.159 +
   4.160 +/**********************
   4.161 +*                     *
   4.162 +* Temp Entity Natives *
   4.163 +*                     *
   4.164 +***********************/
   4.165 +
   4.166 +TempEntHooks s_TempEntHooks;
   4.167  
   4.168  static cell_t smn_TEStart(IPluginContext *pContext, const cell_t *params)
   4.169  {
   4.170 @@ -77,6 +234,29 @@
   4.171  	return 1;
   4.172  }
   4.173  
   4.174 +static cell_t smn_TEReadNum(IPluginContext *pContext, const cell_t *params)
   4.175 +{
   4.176 +	if (!g_TEManager.IsAvailable())
   4.177 +	{
   4.178 +		return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
   4.179 +	}
   4.180 +	if (!g_CurrentTE)
   4.181 +	{
   4.182 +		return pContext->ThrowNativeError("No TempEntity call is in progress");
   4.183 +	}
   4.184 +
   4.185 +	char *prop;
   4.186 +	int val;
   4.187 +	pContext->LocalToString(params[1], &prop);
   4.188 +
   4.189 +	if (!g_CurrentTE->TE_GetEntData(prop, &val))
   4.190 +	{
   4.191 +		return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
   4.192 +	}
   4.193 +
   4.194 +	return val;
   4.195 +}
   4.196 +
   4.197  static cell_t smn_TE_WriteFloat(IPluginContext *pContext, const cell_t *params)
   4.198  {
   4.199  	if (!g_TEManager.IsAvailable())
   4.200 @@ -99,6 +279,29 @@
   4.201  	return 1;
   4.202  }
   4.203  
   4.204 +static cell_t smn_TE_ReadFloat(IPluginContext *pContext, const cell_t *params)
   4.205 +{
   4.206 +	if (!g_TEManager.IsAvailable())
   4.207 +	{
   4.208 +		return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
   4.209 +	}
   4.210 +	if (!g_CurrentTE)
   4.211 +	{
   4.212 +		return pContext->ThrowNativeError("No TempEntity call is in progress");
   4.213 +	}
   4.214 +
   4.215 +	char *prop;
   4.216 +	float val;
   4.217 +	pContext->LocalToString(params[1], &prop);
   4.218 +
   4.219 +	if (!g_CurrentTE->TE_GetEntDataFloat(prop, &val))
   4.220 +	{
   4.221 +		return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
   4.222 +	}
   4.223 +
   4.224 +	return sp_ftoc(val);
   4.225 +}
   4.226 +
   4.227  static cell_t smn_TEWriteVector(IPluginContext *pContext, const cell_t *params)
   4.228  {
   4.229  	if (!g_TEManager.IsAvailable())
   4.230 @@ -125,6 +328,36 @@
   4.231  	return 1;
   4.232  }
   4.233  
   4.234 +static cell_t smn_TEReadVector(IPluginContext *pContext, const cell_t *params)
   4.235 +{
   4.236 +	if (!g_TEManager.IsAvailable())
   4.237 +	{
   4.238 +		return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
   4.239 +	}
   4.240 +	if (!g_CurrentTE)
   4.241 +	{
   4.242 +		return pContext->ThrowNativeError("No TempEntity call is in progress");
   4.243 +	}
   4.244 +
   4.245 +	char *prop;
   4.246 +	pContext->LocalToString(params[1], &prop);
   4.247 +
   4.248 +	cell_t *addr;
   4.249 +	float vec[3];
   4.250 +	pContext->LocalToPhysAddr(params[2], &addr);
   4.251 +
   4.252 +	if (!g_CurrentTE->TE_GetEntDataVector(prop, vec))
   4.253 +	{
   4.254 +		return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
   4.255 +	}
   4.256 +
   4.257 +	addr[0] = sp_ftoc(vec[0]);
   4.258 +	addr[1] = sp_ftoc(vec[1]);
   4.259 +	addr[2] = sp_ftoc(vec[2]);
   4.260 +
   4.261 +	return 1;
   4.262 +}
   4.263 +
   4.264  static cell_t smn_TEWriteFloatArray(IPluginContext *pContext, const cell_t *params)
   4.265  {
   4.266  	if (!g_TEManager.IsAvailable())
   4.267 @@ -190,15 +423,60 @@
   4.268  	return g_CurrentTE->IsValidProp(prop) ? 1 : 0;
   4.269  }
   4.270  
   4.271 +static cell_t smn_AddTempEntHook(IPluginContext *pContext, const cell_t *params)
   4.272 +{
   4.273 +	char *name;
   4.274 +	IPluginFunction *pFunc;
   4.275 +
   4.276 +	pContext->LocalToString(params[1], &name);
   4.277 +	pFunc = pContext->GetFunctionById(params[2]);
   4.278 +	if (!pFunc)
   4.279 +	{
   4.280 +		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   4.281 +	}
   4.282 +
   4.283 +	if (!s_TempEntHooks.AddHook(name, pFunc))
   4.284 +	{
   4.285 +		return pContext->ThrowNativeError("Invalid TempEntity name: \"%s\"", name);
   4.286 +	}
   4.287 +
   4.288 +	return 1;
   4.289 +}
   4.290 +
   4.291 +static cell_t smn_RemoveTempEntHook(IPluginContext *pContext, const cell_t *params)
   4.292 +{
   4.293 +	char *name;
   4.294 +	IPluginFunction *pFunc;
   4.295 +
   4.296 +	pContext->LocalToString(params[1], &name);
   4.297 +	pFunc = pContext->GetFunctionById(params[2]);
   4.298 +	if (!pFunc)
   4.299 +	{
   4.300 +		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   4.301 +	}
   4.302 +
   4.303 +	if (!s_TempEntHooks.RemoveHook(name, pFunc))
   4.304 +	{
   4.305 +		return pContext->ThrowNativeError("Invalid hooked TempEntity name or function");
   4.306 +	}
   4.307 +
   4.308 +	return 1;
   4.309 +}
   4.310 +
   4.311  sp_nativeinfo_t g_TENatives[] = 
   4.312  {
   4.313  	{"TE_Start",				smn_TEStart},
   4.314  	{"TE_WriteNum",				smn_TEWriteNum},
   4.315 +	{"TE_ReadNum",				smn_TEReadNum},
   4.316  	{"TE_WriteFloat",			smn_TE_WriteFloat},
   4.317 +	{"TE_ReadFloat",			smn_TE_ReadFloat},
   4.318  	{"TE_WriteVector",			smn_TEWriteVector},
   4.319 +	{"TE_ReadVector",			smn_TEReadVector},
   4.320  	{"TE_WriteAngles",			smn_TEWriteVector},
   4.321  	{"TE_Send",					smn_TESend},
   4.322  	{"TE_IsValidProp",			smn_TEIsValidProp},
   4.323  	{"TE_WriteFloatArray",		smn_TEWriteFloatArray},
   4.324 +	{"AddTempEntHook",			smn_AddTempEntHook},
   4.325 +	{"RemoveTempEntHook",		smn_RemoveTempEntHook},
   4.326  	{NULL,						NULL}
   4.327  };
     5.1 --- a/plugins/include/sdktools_tempents.inc	Thu Aug 02 23:11:07 2007 +0000
     5.2 +++ b/plugins/include/sdktools_tempents.inc	Fri Aug 03 01:53:00 2007 +0000
     5.3 @@ -19,6 +19,37 @@
     5.4  #define _sdktools_tempents_included
     5.5  
     5.6  /**
     5.7 + * Called when a temp entity is going to be sent.
     5.8 + *
     5.9 + * @param te_name	TE name.
    5.10 + * @param Players	Array containing target player indexes.
    5.11 + * @param numClients	Number of players in the array.
    5.12 + * @param delay		Delay in seconds to send the TE.
    5.13 + * @return		Plugin_Continue to allow the transmission of the TE, Plugin_Stop to block it.
    5.14 + */
    5.15 +functag TEHook Action:public(const String:te_name[], const Players[], numClients, Float:delay);
    5.16 +
    5.17 +/**
    5.18 + * Hooks a temp entity.
    5.19 + *
    5.20 + * @param te_name	TE name to hook.
    5.21 + * @param hook		Function to use as a hook.
    5.22 + * @noreturn
    5.23 + * @error		Temp Entity name not available or invalid function hook.
    5.24 + */
    5.25 +native AddTempEntHook(const String:te_name[], TEHook:hook);
    5.26 +
    5.27 +/**
    5.28 + * Removes a temp entity.
    5.29 + *
    5.30 + * @param te_name	TE name to unhook.
    5.31 + * @param hook		Function used for the hook.
    5.32 + * @noreturn
    5.33 + * @error		Temp Entity name not available or invalid function hook.
    5.34 + */
    5.35 +native RemoveTempEntHook(const String:te_name[], TEHook:hook);
    5.36 +
    5.37 +/**
    5.38   * Starts a temp entity transmission.
    5.39   *
    5.40   * @param te_name	TE name.
    5.41 @@ -46,6 +77,16 @@
    5.42  native TE_WriteNum(const String:prop[], value);
    5.43  
    5.44  /**
    5.45 + * Reads an integer value in the current temp entity.
    5.46 + *
    5.47 + * @param prop		Property to use.
    5.48 + * @param value		Integer value to read.
    5.49 + * @return		Property value.
    5.50 + * @error		Property not found.
    5.51 + */
    5.52 +native TE_ReadNum(const String:prop[]);
    5.53 +
    5.54 +/**
    5.55   * Sets a floating point number in the current temp entity.
    5.56   *
    5.57   * @param prop		Property to use.
    5.58 @@ -56,6 +97,16 @@
    5.59  native TE_WriteFloat(const String:prop[], Float:value);
    5.60  
    5.61  /**
    5.62 + * Reads a floating point number in the current temp entity.
    5.63 + *
    5.64 + * @param prop		Property to use.
    5.65 + * @param value		Floating point number to read.
    5.66 + * @noreturn		Property value.
    5.67 + * @error		Property not found.
    5.68 + */
    5.69 +native Float:TE_ReadFloat(const String:prop[]);
    5.70 +
    5.71 +/**
    5.72   * Sets a vector in the current temp entity.
    5.73   *
    5.74   * @param prop		Property to use.
    5.75 @@ -66,6 +117,16 @@
    5.76  native TE_WriteVector(const String:prop[], const Float:vector[3]);
    5.77  
    5.78  /**
    5.79 + * Reads a vector in the current temp entity.
    5.80 + *
    5.81 + * @param prop		Property to use.
    5.82 + * @param vector	Vector to read.
    5.83 + * @noreturn
    5.84 + * @error		Property not found.
    5.85 + */
    5.86 +native TE_ReadVector(const String:prop[], Float:vector[3]);
    5.87 +
    5.88 +/**
    5.89   * Sets a QAngle in the current temp entity.
    5.90   *
    5.91   * @param prop		Property to use.