core/smn_entities.cpp
changeset 1952 b7aa2b626807
child 2051 568678a2e847
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/core/smn_entities.cpp	Sun Mar 30 07:00:22 2008 +0000
     1.3 @@ -0,0 +1,1796 @@
     1.4 +/**
     1.5 + * vim: set ts=4 :
     1.6 + * =============================================================================
     1.7 + * SourceMod
     1.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     1.9 + * =============================================================================
    1.10 + *
    1.11 + * This program is free software; you can redistribute it and/or modify it under
    1.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    1.13 + * Free Software Foundation.
    1.14 + * 
    1.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    1.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    1.18 + * details.
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License along with
    1.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    1.22 + *
    1.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    1.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    1.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    1.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    1.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    1.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    1.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    1.30 + * or <http://www.sourcemod.net/license.php>.
    1.31 + *
    1.32 + * Version: $Id$
    1.33 + */
    1.34 +
    1.35 +#include "sm_globals.h"
    1.36 +#include "sourcemod.h"
    1.37 +#include "sourcemm_api.h"
    1.38 +#include "server_class.h"
    1.39 +#include "PlayerManager.h"
    1.40 +#include "HalfLife2.h"
    1.41 +#include "GameConfigs.h"
    1.42 +#include "sm_stringutil.h"
    1.43 +
    1.44 +enum PropType
    1.45 +{
    1.46 +	Prop_Send = 0,
    1.47 +	Prop_Data
    1.48 +};
    1.49 +
    1.50 +enum PropFieldType
    1.51 +{
    1.52 +	PropField_Unsupported,		/**< The type is unsupported. */
    1.53 +	PropField_Integer,			/**< Valid for SendProp and Data fields */
    1.54 +	PropField_Float,			/**< Valid for SendProp and Data fields */
    1.55 +	PropField_Entity,			/**< Valid for Data fields only (SendProp shows as int) */
    1.56 +	PropField_Vector,			/**< Valid for SendProp and Data fields */
    1.57 +	PropField_String,			/**< Valid for SendProp and Data fields */
    1.58 +	PropField_String_T,			/**< Valid for Data fields.  Read only! */
    1.59 +};
    1.60 +
    1.61 +inline edict_t *GetEdict(cell_t num)
    1.62 +{
    1.63 +	edict_t *pEdict = engine->PEntityOfEntIndex(num);
    1.64 +	if (!pEdict || pEdict->IsFree())
    1.65 +	{
    1.66 +		return NULL;
    1.67 +	}
    1.68 +	if (num > 0 && num <= g_Players.GetMaxClients())
    1.69 +	{
    1.70 +		CPlayer *pPlayer = g_Players.GetPlayerByIndex(num);
    1.71 +		if (!pPlayer || !pPlayer->IsConnected())
    1.72 +		{
    1.73 +			return NULL;
    1.74 +		}
    1.75 +	}
    1.76 +	return pEdict;
    1.77 +}
    1.78 +
    1.79 +inline edict_t *GetEntity(cell_t num, CBaseEntity **pData)
    1.80 +{
    1.81 +	edict_t *pEdict = engine->PEntityOfEntIndex(num);
    1.82 +	if (!pEdict || pEdict->IsFree())
    1.83 +	{
    1.84 +		return NULL;
    1.85 +	}
    1.86 +	if (num > 0 && num <= g_Players.GetMaxClients())
    1.87 +	{
    1.88 +		CPlayer *pPlayer = g_Players.GetPlayerByIndex(num);
    1.89 +		if (!pPlayer || !pPlayer->IsConnected())
    1.90 +		{
    1.91 +			return NULL;
    1.92 +		}
    1.93 +	}
    1.94 +	IServerUnknown *pUnk;
    1.95 +	if ((pUnk=pEdict->GetUnknown()) == NULL)
    1.96 +	{
    1.97 +		return NULL;
    1.98 +	}
    1.99 +	*pData = pUnk->GetBaseEntity();
   1.100 +	return pEdict;
   1.101 +}
   1.102 +
   1.103 +class VEmptyClass {};
   1.104 +datamap_t *VGetDataDescMap(CBaseEntity *pThisPtr, int offset)
   1.105 +{
   1.106 +	void **this_ptr = *reinterpret_cast<void ***>(&pThisPtr);
   1.107 +	void **vtable = *reinterpret_cast<void ***>(pThisPtr);
   1.108 +	void *vfunc = vtable[offset];
   1.109 +
   1.110 +	union
   1.111 +	{
   1.112 +		datamap_t *(VEmptyClass::*mfpnew)();
   1.113 +#ifndef PLATFORM_POSIX
   1.114 +		void *addr;
   1.115 +	} u;
   1.116 +	u.addr = vfunc;
   1.117 +#else
   1.118 +		struct  
   1.119 +		{
   1.120 +			void *addr;
   1.121 +			intptr_t adjustor;
   1.122 +		} s;
   1.123 +	} u;
   1.124 +	u.s.addr = vfunc;
   1.125 +	u.s.adjustor = 0;
   1.126 +#endif
   1.127 +
   1.128 +	return (datamap_t *)(reinterpret_cast<VEmptyClass *>(this_ptr)->*u.mfpnew)();
   1.129 +}
   1.130 +
   1.131 +inline datamap_t *CBaseEntity_GetDataDescMap(CBaseEntity *pEntity)
   1.132 +{
   1.133 +	int offset;
   1.134 +
   1.135 +	if (!g_pGameConf->GetOffset("GetDataDescMap", &offset) || !offset)
   1.136 +	{
   1.137 +		return NULL;
   1.138 +	}
   1.139 +
   1.140 +	return VGetDataDescMap(pEntity, offset);
   1.141 +}
   1.142 +
   1.143 +/* :TODO: Move this! */
   1.144 +datamap_t *CHalfLife2::GetDataMap(CBaseEntity *pEntity)
   1.145 +{
   1.146 +	return CBaseEntity_GetDataDescMap(pEntity);
   1.147 +}
   1.148 +
   1.149 +static cell_t GetMaxEntities(IPluginContext *pContext, const cell_t *params)
   1.150 +{
   1.151 +	return gpGlobals->maxEntities;
   1.152 +}
   1.153 +
   1.154 +static cell_t CreateEdict(IPluginContext *pContext, const cell_t *params)
   1.155 +{
   1.156 +	edict_t *pEdict = engine->CreateEdict();
   1.157 +
   1.158 +	if (!pEdict)
   1.159 +	{
   1.160 +		return 0;
   1.161 +	}
   1.162 +
   1.163 +	return engine->IndexOfEdict(pEdict);
   1.164 +}
   1.165 +
   1.166 +static cell_t RemoveEdict(IPluginContext *pContext, const cell_t *params)
   1.167 +{
   1.168 +	edict_t *pEdict = engine->PEntityOfEntIndex(params[1]);
   1.169 +
   1.170 +	if (!pEdict)
   1.171 +	{
   1.172 +		return pContext->ThrowNativeError("Edict %d is not a valid edict", params[1]);
   1.173 +	}
   1.174 +
   1.175 +	engine->RemoveEdict(pEdict);
   1.176 +
   1.177 +	return 1;
   1.178 +}
   1.179 +
   1.180 +static cell_t IsValidEdict(IPluginContext *pContext, const cell_t *params)
   1.181 +{
   1.182 +	edict_t *pEdict = GetEdict(params[1]);
   1.183 +
   1.184 +	if (!pEdict)
   1.185 +	{
   1.186 +		return 0;
   1.187 +	}
   1.188 +
   1.189 +	/* Shouldn't be necessary... not sure though */
   1.190 +	return pEdict->IsFree() ? 0 : 1;
   1.191 +}
   1.192 +
   1.193 +static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params)
   1.194 +{
   1.195 +	edict_t *pEdict = GetEdict(params[1]);
   1.196 +
   1.197 +	if (!pEdict)
   1.198 +	{
   1.199 +		return 0;
   1.200 +	}
   1.201 +
   1.202 +	IServerUnknown *pUnknown = pEdict->GetUnknown();
   1.203 +	if (!pUnknown)
   1.204 +	{
   1.205 +		return 0;
   1.206 +	}
   1.207 +
   1.208 +	CBaseEntity *pEntity = pUnknown->GetBaseEntity();
   1.209 +	return (pEntity != NULL) ? 1 : 0;
   1.210 +}
   1.211 +
   1.212 +static cell_t IsEntNetworkable(IPluginContext *pContext, const cell_t *params)
   1.213 +{
   1.214 +	edict_t *pEdict = GetEdict(params[1]);
   1.215 +
   1.216 +	if (!pEdict)
   1.217 +	{
   1.218 +		return 0;
   1.219 +	}
   1.220 +
   1.221 +	return (pEdict->GetNetworkable() != NULL) ? 1 : 0;
   1.222 +}
   1.223 +
   1.224 +static cell_t GetEntityCount(IPluginContext *pContext, const cell_t *params)
   1.225 +{
   1.226 +	return engine->GetEntityCount();
   1.227 +}
   1.228 +
   1.229 +static cell_t GetEdictFlags(IPluginContext *pContext, const cell_t *params)
   1.230 +{
   1.231 +	edict_t *pEdict = GetEdict(params[1]);
   1.232 +
   1.233 +	if (!pEdict)
   1.234 +	{
   1.235 +		return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
   1.236 +	}
   1.237 +
   1.238 +	return pEdict->m_fStateFlags;
   1.239 +}
   1.240 +
   1.241 +static cell_t SetEdictFlags(IPluginContext *pContext, const cell_t *params)
   1.242 +{
   1.243 +	edict_t *pEdict = GetEdict(params[1]);
   1.244 +
   1.245 +	if (!pEdict)
   1.246 +	{
   1.247 +		return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
   1.248 +	}
   1.249 +
   1.250 +	pEdict->m_fStateFlags = params[2];
   1.251 +
   1.252 +	return 1;
   1.253 +}
   1.254 +
   1.255 +static cell_t GetEdictClassname(IPluginContext *pContext, const cell_t *params)
   1.256 +{
   1.257 +	edict_t *pEdict = GetEdict(params[1]);
   1.258 +
   1.259 +	if (!pEdict)
   1.260 +	{
   1.261 +		return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
   1.262 +	}
   1.263 +
   1.264 +	const char *cls = pEdict->GetClassName();
   1.265 +
   1.266 +	if (!cls || cls[0] == '\0')
   1.267 +	{
   1.268 +		return 0;
   1.269 +	}
   1.270 +
   1.271 +	pContext->StringToLocal(params[2], params[3], cls);
   1.272 +
   1.273 +	return 1;
   1.274 +}
   1.275 +
   1.276 +static cell_t GetEntityNetClass(IPluginContext *pContext, const cell_t *params)
   1.277 +{
   1.278 +	edict_t *pEdict = GetEdict(params[1]);
   1.279 +
   1.280 +	if (!pEdict)
   1.281 +	{
   1.282 +		return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
   1.283 +	}
   1.284 +
   1.285 +	IServerNetworkable *pNet = pEdict->GetNetworkable();
   1.286 +	if (!pNet)
   1.287 +	{
   1.288 +		return 0;
   1.289 +	}
   1.290 +
   1.291 +	ServerClass *pClass = pNet->GetServerClass();
   1.292 +
   1.293 +	pContext->StringToLocal(params[2], params[3], pClass->GetName());
   1.294 +
   1.295 +	return 1;
   1.296 +}
   1.297 +
   1.298 +static cell_t GetEntData(IPluginContext *pContext, const cell_t *params)
   1.299 +{
   1.300 +	CBaseEntity *pEntity;
   1.301 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.302 +
   1.303 +	if (!pEdict || !pEntity)
   1.304 +	{
   1.305 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.306 +	}
   1.307 +
   1.308 +	int offset = params[2];
   1.309 +	if (offset <= 0 || offset > 32768)
   1.310 +	{
   1.311 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.312 +	}
   1.313 +
   1.314 +	switch (params[3])
   1.315 +	{
   1.316 +	case 4:
   1.317 +		return *(int *)((uint8_t *)pEntity + offset);
   1.318 +	case 2:
   1.319 +		return *(short *)((uint8_t *)pEntity + offset);
   1.320 +	case 1:
   1.321 +		return *((uint8_t *)pEntity + offset);
   1.322 +	default:
   1.323 +		return pContext->ThrowNativeError("Integer size %d is invalid", params[3]);
   1.324 +	}
   1.325 +}
   1.326 +
   1.327 +static cell_t SetEntData(IPluginContext *pContext, const cell_t *params)
   1.328 +{
   1.329 +	CBaseEntity *pEntity;
   1.330 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.331 +
   1.332 +	if (!pEdict || !pEntity)
   1.333 +	{
   1.334 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.335 +	}
   1.336 +
   1.337 +	int offset = params[2];
   1.338 +	if (offset <= 0 || offset > 32768)
   1.339 +	{
   1.340 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.341 +	}
   1.342 +
   1.343 +	if (params[5])
   1.344 +	{
   1.345 +		g_HL2.SetEdictStateChanged(pEdict, offset);
   1.346 +	}
   1.347 +
   1.348 +	switch (params[4])
   1.349 +	{
   1.350 +	case 4:
   1.351 +		{
   1.352 +			*(int *)((uint8_t *)pEntity + offset) = params[3];
   1.353 +			break;
   1.354 +		}
   1.355 +	case 2:
   1.356 +		{
   1.357 +			*(short *)((uint8_t *)pEntity + offset) = params[3];
   1.358 +			break;
   1.359 +		}
   1.360 +	case 1:
   1.361 +		{
   1.362 +			*((uint8_t *)pEntity + offset) = params[3];
   1.363 +			break;
   1.364 +		}
   1.365 +	default:
   1.366 +		return pContext->ThrowNativeError("Integer size %d is invalid", params[4]);
   1.367 +	}
   1.368 +
   1.369 +	return 1;
   1.370 +}
   1.371 +
   1.372 +static cell_t GetEntDataFloat(IPluginContext *pContext, const cell_t *params)
   1.373 +{
   1.374 +	CBaseEntity *pEntity;
   1.375 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.376 +
   1.377 +	if (!pEdict || !pEntity)
   1.378 +	{
   1.379 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.380 +	}
   1.381 +
   1.382 +	int offset = params[2];
   1.383 +	if (offset <= 0 || offset > 32768)
   1.384 +	{
   1.385 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.386 +	}
   1.387 +
   1.388 +	float f = *(float *)((uint8_t *)pEntity + offset);
   1.389 +
   1.390 +	return sp_ftoc(f);
   1.391 +}
   1.392 +
   1.393 +static cell_t SetEntDataFloat(IPluginContext *pContext, const cell_t *params)
   1.394 +{
   1.395 +	CBaseEntity *pEntity;
   1.396 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.397 +
   1.398 +	if (!pEdict || !pEntity)
   1.399 +	{
   1.400 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.401 +	}
   1.402 +
   1.403 +	int offset = params[2];
   1.404 +	if (offset <= 0 || offset > 32768)
   1.405 +	{
   1.406 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.407 +	}
   1.408 +
   1.409 +	*(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[3]);
   1.410 +
   1.411 +	if (params[4])
   1.412 +	{
   1.413 +		g_HL2.SetEdictStateChanged(pEdict, offset);
   1.414 +	}
   1.415 +
   1.416 +	return 1;
   1.417 +}
   1.418 +
   1.419 +static cell_t GetEntDataVector(IPluginContext *pContext, const cell_t *params)
   1.420 +{
   1.421 +	CBaseEntity *pEntity;
   1.422 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.423 +
   1.424 +	if (!pEdict || !pEntity)
   1.425 +	{
   1.426 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.427 +	}
   1.428 +
   1.429 +	int offset = params[2];
   1.430 +	if (offset <= 0 || offset > 32768)
   1.431 +	{
   1.432 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.433 +	}
   1.434 +
   1.435 +	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
   1.436 +
   1.437 +	cell_t *vec;
   1.438 +	pContext->LocalToPhysAddr(params[3], &vec);
   1.439 +
   1.440 +	vec[0] = sp_ftoc(v->x);
   1.441 +	vec[1] = sp_ftoc(v->y);
   1.442 +	vec[2] = sp_ftoc(v->z);
   1.443 +
   1.444 +	return 1;
   1.445 +}
   1.446 +
   1.447 +static cell_t SetEntDataVector(IPluginContext *pContext, const cell_t *params)
   1.448 +{
   1.449 +	CBaseEntity *pEntity;
   1.450 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.451 +
   1.452 +	if (!pEdict || !pEntity)
   1.453 +	{
   1.454 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.455 +	}
   1.456 +
   1.457 +	int offset = params[2];
   1.458 +	if (offset <= 0 || offset > 32768)
   1.459 +	{
   1.460 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.461 +	}
   1.462 +
   1.463 +	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
   1.464 +
   1.465 +	cell_t *vec;
   1.466 +	pContext->LocalToPhysAddr(params[3], &vec);
   1.467 +
   1.468 +	v->x = sp_ctof(vec[0]);
   1.469 +	v->y = sp_ctof(vec[1]);
   1.470 +	v->z = sp_ctof(vec[2]);
   1.471 +
   1.472 +	if (params[4])
   1.473 +	{
   1.474 +		g_HL2.SetEdictStateChanged(pEdict, offset);
   1.475 +	}
   1.476 +
   1.477 +	return 1;
   1.478 +}
   1.479 +
   1.480 +/* THIS GUY IS DEPRECATED. */
   1.481 +static cell_t GetEntDataEnt(IPluginContext *pContext, const cell_t *params)
   1.482 +{
   1.483 +	CBaseEntity *pEntity;
   1.484 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.485 +
   1.486 +	if (!pEdict || !pEntity)
   1.487 +	{
   1.488 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.489 +	}
   1.490 +
   1.491 +	int offset = params[2];
   1.492 +	if (offset <= 0 || offset > 32768)
   1.493 +	{
   1.494 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.495 +	}
   1.496 +
   1.497 +	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
   1.498 +
   1.499 +	if (!hndl.IsValid())
   1.500 +	{
   1.501 +		return 0;
   1.502 +	}
   1.503 +
   1.504 +	return hndl.GetEntryIndex();
   1.505 +}
   1.506 +
   1.507 +int CheckBaseHandle(CBaseHandle &hndl)
   1.508 +{
   1.509 +	if (!hndl.IsValid())
   1.510 +	{
   1.511 +		return -1;
   1.512 +	}
   1.513 +
   1.514 +	int index = hndl.GetEntryIndex();
   1.515 +
   1.516 +	edict_t *pStoredEdict;
   1.517 +	CBaseEntity *pStoredEntity;
   1.518 +
   1.519 +	pStoredEdict = GetEntity(index, &pStoredEntity);
   1.520 +
   1.521 +	if (pStoredEdict == NULL || pStoredEntity == NULL)
   1.522 +	{
   1.523 +		return -1;
   1.524 +	}
   1.525 +
   1.526 +	IServerEntity *pSE = pStoredEdict->GetIServerEntity();
   1.527 +
   1.528 +	if (pSE == NULL)
   1.529 +	{
   1.530 +		return -1;
   1.531 +	}
   1.532 +
   1.533 +	if (pSE->GetRefEHandle() != hndl)
   1.534 +	{
   1.535 +		return -1;
   1.536 +	}
   1.537 +
   1.538 +	return index;
   1.539 +}
   1.540 +
   1.541 +static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
   1.542 +{
   1.543 +	CBaseEntity *pEntity;
   1.544 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.545 +
   1.546 +	if (pEdict == NULL || pEntity == NULL)
   1.547 +	{
   1.548 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.549 +	}
   1.550 +
   1.551 +	int offset = params[2];
   1.552 +	if (offset <= 0 || offset > 32768)
   1.553 +	{
   1.554 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.555 +	}
   1.556 +
   1.557 +	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
   1.558 +
   1.559 +	return CheckBaseHandle(hndl);
   1.560 +}
   1.561 +
   1.562 +/* THIS GUY IS DEPRECATED. */
   1.563 +static cell_t SetEntDataEnt(IPluginContext *pContext, const cell_t *params)
   1.564 +{
   1.565 +	CBaseEntity *pEntity;
   1.566 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.567 +
   1.568 +	if (!pEdict || !pEntity)
   1.569 +	{
   1.570 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.571 +	}
   1.572 +
   1.573 +	int offset = params[2];
   1.574 +	if (offset <= 0 || offset > 32768)
   1.575 +	{
   1.576 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.577 +	}
   1.578 +
   1.579 +	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
   1.580 +
   1.581 +	if (params[3] == 0)
   1.582 +	{
   1.583 +		hndl.Set(NULL);
   1.584 +	} else {
   1.585 +		edict_t *pEdict = GetEdict(params[3]);
   1.586 +		if (!pEdict)
   1.587 +		{
   1.588 +			return pContext->ThrowNativeError("Entity %d is invalid", params[3]);
   1.589 +		}
   1.590 +		IServerEntity *pEntOther = pEdict->GetIServerEntity();
   1.591 +		hndl.Set(pEntOther);
   1.592 +	}
   1.593 +
   1.594 +	if (params[4])
   1.595 +	{
   1.596 +		g_HL2.SetEdictStateChanged(pEdict, offset);
   1.597 +	}
   1.598 +
   1.599 +	return 1;
   1.600 +}
   1.601 +
   1.602 +static cell_t SetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
   1.603 +{
   1.604 +	CBaseEntity *pEntity;
   1.605 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.606 +
   1.607 +	if (!pEdict || !pEntity)
   1.608 +	{
   1.609 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.610 +	}
   1.611 +
   1.612 +	int offset = params[2];
   1.613 +	if (offset <= 0 || offset > 32768)
   1.614 +	{
   1.615 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.616 +	}
   1.617 +
   1.618 +	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
   1.619 +
   1.620 +	if (params[3] == -1)
   1.621 +	{
   1.622 +		hndl.Set(NULL);
   1.623 +	}
   1.624 +	else
   1.625 +	{
   1.626 +		edict_t *pEdict = GetEdict(params[3]);
   1.627 +		if (!pEdict)
   1.628 +		{
   1.629 +			return pContext->ThrowNativeError("Entity %d is invalid", params[3]);
   1.630 +		}
   1.631 +		IServerEntity *pEntOther = pEdict->GetIServerEntity();
   1.632 +		hndl.Set(pEntOther);
   1.633 +	}
   1.634 +
   1.635 +	if (params[4])
   1.636 +	{
   1.637 +		g_HL2.SetEdictStateChanged(pEdict, offset);
   1.638 +	}
   1.639 +
   1.640 +	return 1;
   1.641 +}
   1.642 +
   1.643 +static cell_t ChangeEdictState(IPluginContext *pContext, const cell_t *params)
   1.644 +{
   1.645 +	edict_t *pEdict = GetEdict(params[1]);
   1.646 +
   1.647 +	if (!pEdict)
   1.648 +	{
   1.649 +		return pContext->ThrowNativeError("Edict %d is invalid", params[1]);
   1.650 +	}
   1.651 +
   1.652 +	g_HL2.SetEdictStateChanged(pEdict, params[2]);
   1.653 +
   1.654 +	return 1;
   1.655 +}
   1.656 +
   1.657 +static cell_t FindSendPropOffs(IPluginContext *pContext, const cell_t *params)
   1.658 +{
   1.659 +	char *cls, *prop;
   1.660 +	pContext->LocalToString(params[1], &cls);
   1.661 +	pContext->LocalToString(params[2], &prop);
   1.662 +
   1.663 +	SendProp *pSend = g_HL2.FindInSendTable(cls, prop);
   1.664 +
   1.665 +	if (!pSend)
   1.666 +	{
   1.667 +		return -1;
   1.668 +	}
   1.669 +
   1.670 +	return pSend->GetOffset();
   1.671 +}
   1.672 +
   1.673 +static cell_t FindSendPropInfo(IPluginContext *pContext, const cell_t *params)
   1.674 +{
   1.675 +	char *cls, *prop;
   1.676 +	sm_sendprop_info_t info;
   1.677 +	cell_t *pType, *pBits, *pLocal;
   1.678 +
   1.679 +	pContext->LocalToString(params[1], &cls);
   1.680 +	pContext->LocalToString(params[2], &prop);
   1.681 +
   1.682 +	if (!g_HL2.FindSendPropInfo(cls, prop, &info))
   1.683 +	{
   1.684 +		return -1;
   1.685 +	}
   1.686 +
   1.687 +	pContext->LocalToPhysAddr(params[3], &pType);
   1.688 +	pContext->LocalToPhysAddr(params[4], &pBits);
   1.689 +	pContext->LocalToPhysAddr(params[5], &pLocal);
   1.690 +
   1.691 +	switch (info.prop->GetType())
   1.692 +	{
   1.693 +	case DPT_Int:
   1.694 +		{
   1.695 +			*pType = PropField_Integer;
   1.696 +			break;
   1.697 +		}
   1.698 +	case DPT_Float:
   1.699 +		{
   1.700 +			*pType = PropField_Float;
   1.701 +			break;
   1.702 +		}
   1.703 +	case DPT_String:
   1.704 +		{
   1.705 +			*pType = PropField_String;
   1.706 +			break;
   1.707 +		}
   1.708 +	case DPT_Vector:
   1.709 +		{
   1.710 +			*pType = PropField_Vector;
   1.711 +			break;
   1.712 +		}
   1.713 +	default:
   1.714 +		{
   1.715 +			*pType = PropField_Unsupported;
   1.716 +			break;
   1.717 +		}
   1.718 +	}
   1.719 +
   1.720 +	*pBits = info.prop->m_nBits;
   1.721 +	*pLocal = info.prop->GetOffset();
   1.722 +
   1.723 +	return info.actual_offset;
   1.724 +}
   1.725 +
   1.726 +static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params)
   1.727 +{
   1.728 +	CBaseEntity *pEntity;
   1.729 +	datamap_t *pMap;
   1.730 +	typedescription_t *td;
   1.731 +	char *offset;
   1.732 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.733 +
   1.734 +	if (!pEdict || !pEntity)
   1.735 +	{
   1.736 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.737 +	}
   1.738 +
   1.739 +	if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
   1.740 +	{
   1.741 +		return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
   1.742 +	}
   1.743 +
   1.744 +	pContext->LocalToString(params[2], &offset);
   1.745 +	if ((td=g_HL2.FindInDataMap(pMap, offset)) == NULL)
   1.746 +	{
   1.747 +		return -1;
   1.748 +	}
   1.749 +
   1.750 +	if (params[0] == 4)
   1.751 +	{
   1.752 +		cell_t *pType, *pSize;
   1.753 +
   1.754 +		pContext->LocalToPhysAddr(params[3], &pType);
   1.755 +		pContext->LocalToPhysAddr(params[4], &pSize);
   1.756 +
   1.757 +		switch (td->fieldType)
   1.758 +		{
   1.759 +		case FIELD_TICK:
   1.760 +		case FIELD_MODELINDEX:
   1.761 +		case FIELD_MATERIALINDEX:
   1.762 +		case FIELD_INTEGER:
   1.763 +		case FIELD_COLOR32:
   1.764 +			{
   1.765 +				*pType = PropField_Integer;
   1.766 +				*pSize = 32;
   1.767 +				break;
   1.768 +			}
   1.769 +		case FIELD_VECTOR:
   1.770 +		case FIELD_POSITION_VECTOR:
   1.771 +			{
   1.772 +				*pType = PropField_Vector;
   1.773 +				*pSize = 12;
   1.774 +				break;
   1.775 +			}
   1.776 +		case FIELD_SHORT:
   1.777 +			{
   1.778 +				*pType = PropField_Integer;
   1.779 +				*pSize = 16;
   1.780 +				break;
   1.781 +			}
   1.782 +		case FIELD_BOOLEAN:
   1.783 +			{
   1.784 +				*pType = PropField_Integer;
   1.785 +				*pSize = 1;
   1.786 +				break;
   1.787 +			}
   1.788 +		case FIELD_CHARACTER:
   1.789 +			{
   1.790 +				if (td->fieldSize == 1)
   1.791 +				{
   1.792 +					*pType = PropField_Integer;
   1.793 +					*pSize = 8;
   1.794 +				}
   1.795 +				else
   1.796 +				{
   1.797 +					*pType = PropField_String;
   1.798 +					*pSize = 8 * td->fieldSize;
   1.799 +				}
   1.800 +				break;
   1.801 +			}
   1.802 +		case FIELD_MODELNAME:
   1.803 +		case FIELD_SOUNDNAME:
   1.804 +		case FIELD_STRING:
   1.805 +			{
   1.806 +				*pSize = sizeof(string_t);
   1.807 +				*pType = PropField_String_T;
   1.808 +				break;
   1.809 +			}
   1.810 +		case FIELD_FLOAT:
   1.811 +		case FIELD_TIME:
   1.812 +			{
   1.813 +				*pType = PropField_Float;
   1.814 +				*pSize = 32;
   1.815 +				break;
   1.816 +			}
   1.817 +		case FIELD_EHANDLE:
   1.818 +			{
   1.819 +				*pType = PropField_Entity;
   1.820 +				*pSize = 32;
   1.821 +				break;
   1.822 +			}
   1.823 +		default:
   1.824 +			{
   1.825 +				*pType = PropField_Unsupported;
   1.826 +				*pSize = 0;
   1.827 +			}
   1.828 +		}
   1.829 +	}
   1.830 +
   1.831 +	return td->fieldOffset[TD_OFFSET_NORMAL];
   1.832 +}
   1.833 +
   1.834 +static cell_t GetEntDataString(IPluginContext *pContext, const cell_t *params)
   1.835 +{
   1.836 +	CBaseEntity *pEntity;
   1.837 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.838 +
   1.839 +	if (!pEdict || !pEntity)
   1.840 +	{
   1.841 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.842 +	}
   1.843 +
   1.844 +	int offset = params[2];
   1.845 +	if (offset < 0 || offset > 32768)
   1.846 +	{
   1.847 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.848 +	}
   1.849 +
   1.850 +	size_t len;
   1.851 +	char *src = (char *)((uint8_t *)pEntity + offset);
   1.852 +	pContext->StringToLocalUTF8(params[3], params[4], src, &len);
   1.853 +
   1.854 +	return len;
   1.855 +}
   1.856 +
   1.857 +static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
   1.858 +{
   1.859 +	CBaseEntity *pEntity;
   1.860 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
   1.861 +
   1.862 +	if (!pEdict || !pEntity)
   1.863 +	{
   1.864 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.865 +	}
   1.866 +
   1.867 +	int offset = params[2];
   1.868 +	if (offset < 0 || offset > 32768)
   1.869 +	{
   1.870 +		return pContext->ThrowNativeError("Offset %d is invalid", offset);
   1.871 +	}
   1.872 +
   1.873 +	char *src;
   1.874 +	char *dest = (char *)((uint8_t *)pEntity + offset);
   1.875 +
   1.876 +	pContext->LocalToString(params[3], &src);
   1.877 +	size_t len = strncopy(dest, src, params[4]);
   1.878 +
   1.879 +	if (params[5])
   1.880 +	{
   1.881 +		g_HL2.SetEdictStateChanged(pEdict, offset);
   1.882 +	}
   1.883 +
   1.884 +	return len;
   1.885 +}
   1.886 +
   1.887 +#define FIND_PROP_DATA(td) \
   1.888 +	datamap_t *pMap; \
   1.889 +	if ((pMap = CBaseEntity_GetDataDescMap(pEntity)) == NULL) \
   1.890 +	{ \
   1.891 +		return pContext->ThrowNativeError("Could not retrieve datamap"); \
   1.892 +	} \
   1.893 +	if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \
   1.894 +	{ \
   1.895 +		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
   1.896 +			prop, \
   1.897 +			params[1], \
   1.898 +			class_name); \
   1.899 +	}
   1.900 +
   1.901 +#define FIND_PROP_SEND(pProp) \
   1.902 +	IServerNetworkable *pNet = pEdict->GetNetworkable(); \
   1.903 +	if (!pNet) \
   1.904 +	{ \
   1.905 +		return pContext->ThrowNativeError("Edict %d is not networkable", params[1]); \
   1.906 +	} \
   1.907 +	if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, pProp)) \
   1.908 +	{ \
   1.909 +		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
   1.910 +			prop, \
   1.911 +			params[1], \
   1.912 +			class_name); \
   1.913 +	}
   1.914 +
   1.915 +inline int MatchFieldAsInteger(int field_type)
   1.916 +{
   1.917 +	switch (field_type)
   1.918 +	{
   1.919 +	case FIELD_TICK:
   1.920 +	case FIELD_MODELINDEX:
   1.921 +	case FIELD_MATERIALINDEX:
   1.922 +	case FIELD_INTEGER:
   1.923 +	case FIELD_COLOR32:
   1.924 +		return 32;
   1.925 +	case FIELD_SHORT:
   1.926 +		return 16;
   1.927 +	case FIELD_CHARACTER:
   1.928 +		return 8;
   1.929 +	case FIELD_BOOLEAN:
   1.930 +		return 1;
   1.931 +	default:
   1.932 +		return 0;
   1.933 +	}
   1.934 +
   1.935 +	return 0;
   1.936 +}
   1.937 +
   1.938 +static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
   1.939 +{
   1.940 +	CBaseEntity *pEntity;
   1.941 +	char *prop;
   1.942 +	int offset;
   1.943 +	const char *class_name;
   1.944 +	edict_t *pEdict;
   1.945 +	int bit_count;
   1.946 +
   1.947 +	pEdict = GetEntity(params[1], &pEntity);
   1.948 +
   1.949 +	if (!pEdict || !pEntity)
   1.950 +	{
   1.951 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
   1.952 +	}
   1.953 +
   1.954 +	if ((class_name = pEdict->GetClassName()) == NULL)
   1.955 +	{
   1.956 +		class_name = "";
   1.957 +	}
   1.958 +
   1.959 +	pContext->LocalToString(params[3], &prop);
   1.960 +
   1.961 +	switch (params[2])
   1.962 +	{
   1.963 +	case Prop_Data:
   1.964 +		{
   1.965 +			typedescription_t *td;
   1.966 +
   1.967 +			FIND_PROP_DATA(td);
   1.968 +
   1.969 +			if ((bit_count = MatchFieldAsInteger(td->fieldType)) == 0)
   1.970 +			{
   1.971 +				return pContext->ThrowNativeError("Data field %s is not an integer (%d)", 
   1.972 +					prop,
   1.973 +					td->fieldType);
   1.974 +			}
   1.975 +
   1.976 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
   1.977 +			break;
   1.978 +		}
   1.979 +	case Prop_Send:
   1.980 +		{
   1.981 +			sm_sendprop_info_t info;
   1.982 +
   1.983 +			FIND_PROP_SEND(&info);
   1.984 +
   1.985 +			if (info.prop->GetType() != DPT_Int)
   1.986 +			{
   1.987 +				return pContext->ThrowNativeError("SendProp %s is not an integer ([%d,%d] != %d)",
   1.988 +					prop,
   1.989 +					info.prop->GetType(),
   1.990 +					info.prop->m_nBits,
   1.991 +					DPT_Int);
   1.992 +			}
   1.993 +
   1.994 +			bit_count = info.prop->m_nBits;
   1.995 +			offset = info.actual_offset;
   1.996 +			break;
   1.997 +		}
   1.998 +	default:
   1.999 +		{
  1.1000 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1001 +		}
  1.1002 +	}
  1.1003 +
  1.1004 +	if (bit_count < 1)
  1.1005 +	{
  1.1006 +		bit_count = params[4] * 8;
  1.1007 +	}
  1.1008 +
  1.1009 +	if (bit_count >= 17)
  1.1010 +	{
  1.1011 +		return *(int32_t *)((uint8_t *)pEntity + offset);
  1.1012 +	}
  1.1013 +	else if (bit_count >= 9)
  1.1014 +	{
  1.1015 +		return *(int16_t *)((uint8_t *)pEntity + offset);
  1.1016 +	}
  1.1017 +	else if (bit_count >= 2)
  1.1018 +	{
  1.1019 +		return *(int8_t *)((uint8_t *)pEntity + offset);
  1.1020 +	}
  1.1021 +	else
  1.1022 +	{
  1.1023 +		return *(bool *)((uint8_t *)pEntity + offset) ? 1 : 0;
  1.1024 +	}
  1.1025 +
  1.1026 +	return 0;
  1.1027 +}
  1.1028 +
  1.1029 +static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
  1.1030 +{
  1.1031 +	CBaseEntity *pEntity;
  1.1032 +	char *prop;
  1.1033 +	int offset;
  1.1034 +	const char *class_name;
  1.1035 +	edict_t *pEdict;
  1.1036 +	int bit_count;
  1.1037 +
  1.1038 +	pEdict = GetEntity(params[1], &pEntity);
  1.1039 +
  1.1040 +	if (!pEdict || !pEntity)
  1.1041 +	{
  1.1042 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1043 +	}
  1.1044 +
  1.1045 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1046 +	{
  1.1047 +		class_name = "";
  1.1048 +	}
  1.1049 +
  1.1050 +	pContext->LocalToString(params[3], &prop);
  1.1051 +
  1.1052 +	switch (params[2])
  1.1053 +	{
  1.1054 +	case Prop_Data:
  1.1055 +		{
  1.1056 +			typedescription_t *td;
  1.1057 +
  1.1058 +			FIND_PROP_DATA(td);
  1.1059 +
  1.1060 +			if ((bit_count = MatchFieldAsInteger(td->fieldType)) == 0)
  1.1061 +			{
  1.1062 +				return pContext->ThrowNativeError("Data field %s is not an integer (%d)", 
  1.1063 +					prop,
  1.1064 +					td->fieldType);
  1.1065 +			}
  1.1066 +
  1.1067 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1068 +			break;
  1.1069 +		}
  1.1070 +	case Prop_Send:
  1.1071 +		{
  1.1072 +			sm_sendprop_info_t info;
  1.1073 +
  1.1074 +			FIND_PROP_SEND(&info);
  1.1075 +
  1.1076 +			if (info.prop->GetType() != DPT_Int)
  1.1077 +			{
  1.1078 +				return pContext->ThrowNativeError("SendProp %s is not an integer ([%d,%d] != %d)",
  1.1079 +					prop,
  1.1080 +					info.prop->GetType(),
  1.1081 +					info.prop->m_nBits,
  1.1082 +					DPT_Int);
  1.1083 +			}
  1.1084 +
  1.1085 +			bit_count = info.prop->m_nBits;
  1.1086 +			offset = info.actual_offset;
  1.1087 +			break;
  1.1088 +		}
  1.1089 +	default:
  1.1090 +		{
  1.1091 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1092 +		}
  1.1093 +	}
  1.1094 +
  1.1095 +	if (bit_count < 1)
  1.1096 +	{
  1.1097 +		bit_count = params[5] * 8;
  1.1098 +	}
  1.1099 +
  1.1100 +	if (bit_count >= 17)
  1.1101 +	{
  1.1102 +		*(int32_t *)((uint8_t *)pEntity + offset) = params[4];
  1.1103 +	}
  1.1104 +	else if (bit_count >= 9)
  1.1105 +	{
  1.1106 +		*(int16_t *)((uint8_t *)pEntity + offset) = (int16_t)params[4];
  1.1107 +	}
  1.1108 +	else if (bit_count >= 2)
  1.1109 +	{
  1.1110 +		*(int8_t *)((uint8_t *)pEntity + offset) = (int8_t)params[4];
  1.1111 +	}
  1.1112 +	else
  1.1113 +	{
  1.1114 +		*(bool *)((uint8_t *)pEntity + offset) = params[4] ? true : false;
  1.1115 +	}
  1.1116 +
  1.1117 +	return 0;
  1.1118 +}
  1.1119 +
  1.1120 +static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
  1.1121 +{
  1.1122 +	CBaseEntity *pEntity;
  1.1123 +	char *prop;
  1.1124 +	int offset;
  1.1125 +	const char *class_name;
  1.1126 +	edict_t *pEdict;
  1.1127 +
  1.1128 +	pEdict = GetEntity(params[1], &pEntity);
  1.1129 +
  1.1130 +	if (!pEdict || !pEntity)
  1.1131 +	{
  1.1132 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1133 +	}
  1.1134 +
  1.1135 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1136 +	{
  1.1137 +		class_name = "";
  1.1138 +	}
  1.1139 +
  1.1140 +	pContext->LocalToString(params[3], &prop);
  1.1141 +
  1.1142 +	switch (params[2])
  1.1143 +	{
  1.1144 +	case Prop_Data:
  1.1145 +		{
  1.1146 +			typedescription_t *td;
  1.1147 +
  1.1148 +			FIND_PROP_DATA(td);
  1.1149 +
  1.1150 +			if (td->fieldType != FIELD_FLOAT
  1.1151 +				&& td->fieldType != FIELD_TIME)
  1.1152 +			{
  1.1153 +				return pContext->ThrowNativeError("Data field %s is not a float (%d != [%d,%d])", 
  1.1154 +					prop,
  1.1155 +					td->fieldType,
  1.1156 +					FIELD_FLOAT,
  1.1157 +					FIELD_TIME);
  1.1158 +			}
  1.1159 +
  1.1160 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1161 +			break;
  1.1162 +		}
  1.1163 +	case Prop_Send:
  1.1164 +		{
  1.1165 +			sm_sendprop_info_t info;
  1.1166 +
  1.1167 +			FIND_PROP_SEND(&info);
  1.1168 +
  1.1169 +			if (info.prop->GetType() != DPT_Float)
  1.1170 +			{
  1.1171 +				return pContext->ThrowNativeError("SendProp %s is not a float (%d != %d)",
  1.1172 +					prop,
  1.1173 +					info.prop->GetType(),
  1.1174 +					DPT_Float);
  1.1175 +			}
  1.1176 +
  1.1177 +			offset = info.actual_offset;
  1.1178 +			break;
  1.1179 +		}
  1.1180 +	default:
  1.1181 +		{
  1.1182 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1183 +		}
  1.1184 +	}
  1.1185 +
  1.1186 +	float val = *(float *)((uint8_t *)pEntity + offset);
  1.1187 +
  1.1188 +	return sp_ftoc(val);
  1.1189 +}
  1.1190 +
  1.1191 +static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
  1.1192 +{
  1.1193 +	CBaseEntity *pEntity;
  1.1194 +	char *prop;
  1.1195 +	int offset;
  1.1196 +	const char *class_name;
  1.1197 +	edict_t *pEdict;
  1.1198 +
  1.1199 +	pEdict = GetEntity(params[1], &pEntity);
  1.1200 +
  1.1201 +	if (!pEdict || !pEntity)
  1.1202 +	{
  1.1203 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1204 +	}
  1.1205 +
  1.1206 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1207 +	{
  1.1208 +		class_name = "";
  1.1209 +	}
  1.1210 +
  1.1211 +	pContext->LocalToString(params[3], &prop);
  1.1212 +
  1.1213 +	switch (params[2])
  1.1214 +	{
  1.1215 +	case Prop_Data:
  1.1216 +		{
  1.1217 +			typedescription_t *td;
  1.1218 +
  1.1219 +			FIND_PROP_DATA(td);
  1.1220 +
  1.1221 +			if (td->fieldType != FIELD_FLOAT
  1.1222 +				&& td->fieldType != FIELD_TIME)
  1.1223 +			{
  1.1224 +				return pContext->ThrowNativeError("Data field %s is not a float (%d != [%d,%d])", 
  1.1225 +					prop,
  1.1226 +					td->fieldType,
  1.1227 +					FIELD_FLOAT,
  1.1228 +					FIELD_TIME);
  1.1229 +			}
  1.1230 +
  1.1231 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1232 +			break;
  1.1233 +		}
  1.1234 +	case Prop_Send:
  1.1235 +		{
  1.1236 +			sm_sendprop_info_t info;
  1.1237 +
  1.1238 +			FIND_PROP_SEND(&info);
  1.1239 +
  1.1240 +			if (info.prop->GetType() != DPT_Float)
  1.1241 +			{
  1.1242 +				return pContext->ThrowNativeError("SendProp %s is not a float (%d != %d)",
  1.1243 +					prop,
  1.1244 +					info.prop->GetType(),
  1.1245 +					DPT_Float);
  1.1246 +			}
  1.1247 +
  1.1248 +			offset = info.actual_offset;
  1.1249 +			break;
  1.1250 +		}
  1.1251 +	default:
  1.1252 +		{
  1.1253 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1254 +		}
  1.1255 +	}
  1.1256 +
  1.1257 +	*(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[4]);
  1.1258 +
  1.1259 +	if (params[2] == Prop_Send)
  1.1260 +	{
  1.1261 +		g_HL2.SetEdictStateChanged(pEdict, offset);
  1.1262 +	}
  1.1263 +
  1.1264 +	return 1;
  1.1265 +}
  1.1266 +
  1.1267 +static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
  1.1268 +{
  1.1269 +	CBaseEntity *pEntity;
  1.1270 +	char *prop;
  1.1271 +	int offset;
  1.1272 +	const char *class_name;
  1.1273 +	edict_t *pEdict;
  1.1274 +
  1.1275 +	pEdict = GetEntity(params[1], &pEntity);
  1.1276 +
  1.1277 +	if (!pEdict || !pEntity)
  1.1278 +	{
  1.1279 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1280 +	}
  1.1281 +
  1.1282 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1283 +	{
  1.1284 +		class_name = "";
  1.1285 +	}
  1.1286 +
  1.1287 +	pContext->LocalToString(params[3], &prop);
  1.1288 +
  1.1289 +	switch (params[2])
  1.1290 +	{
  1.1291 +	case Prop_Data:
  1.1292 +		{
  1.1293 +			typedescription_t *td;
  1.1294 +
  1.1295 +			FIND_PROP_DATA(td);
  1.1296 +
  1.1297 +			if (td->fieldType != FIELD_EHANDLE)
  1.1298 +			{
  1.1299 +				return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)", 
  1.1300 +					prop,
  1.1301 +					td->fieldType,
  1.1302 +					FIELD_EHANDLE);
  1.1303 +			}
  1.1304 +
  1.1305 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1306 +			break;
  1.1307 +		}
  1.1308 +	case Prop_Send:
  1.1309 +		{
  1.1310 +			sm_sendprop_info_t info;
  1.1311 +
  1.1312 +			FIND_PROP_SEND(&info);
  1.1313 +
  1.1314 +			if (info.prop->GetType() != DPT_Int)
  1.1315 +			{
  1.1316 +				return pContext->ThrowNativeError("SendProp %s is not an integer (%d != %d)",
  1.1317 +					prop,
  1.1318 +					info.prop->GetType(),
  1.1319 +					DPT_Int);
  1.1320 +			}
  1.1321 +
  1.1322 +			offset = info.actual_offset;
  1.1323 +			break;
  1.1324 +		}
  1.1325 +	default:
  1.1326 +		{
  1.1327 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1328 +		}
  1.1329 +	}
  1.1330 +
  1.1331 +	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
  1.1332 +
  1.1333 +	return CheckBaseHandle(hndl);
  1.1334 +}
  1.1335 +
  1.1336 +static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
  1.1337 +{
  1.1338 +	CBaseEntity *pEntity;
  1.1339 +	char *prop;
  1.1340 +	int offset;
  1.1341 +	const char *class_name;
  1.1342 +	edict_t *pEdict;
  1.1343 +
  1.1344 +	pEdict = GetEntity(params[1], &pEntity);
  1.1345 +
  1.1346 +	if (!pEdict || !pEntity)
  1.1347 +	{
  1.1348 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1349 +	}
  1.1350 +
  1.1351 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1352 +	{
  1.1353 +		class_name = "";
  1.1354 +	}
  1.1355 +
  1.1356 +	pContext->LocalToString(params[3], &prop);
  1.1357 +
  1.1358 +	switch (params[2])
  1.1359 +	{
  1.1360 +	case Prop_Data:
  1.1361 +		{
  1.1362 +			typedescription_t *td;
  1.1363 +
  1.1364 +			FIND_PROP_DATA(td);
  1.1365 +
  1.1366 +			if (td->fieldType != FIELD_EHANDLE)
  1.1367 +			{
  1.1368 +				return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)", 
  1.1369 +					prop,
  1.1370 +					td->fieldType,
  1.1371 +					FIELD_EHANDLE);
  1.1372 +			}
  1.1373 +
  1.1374 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1375 +			break;
  1.1376 +		}
  1.1377 +	case Prop_Send:
  1.1378 +		{
  1.1379 +			sm_sendprop_info_t info;
  1.1380 +
  1.1381 +			FIND_PROP_SEND(&info);
  1.1382 +
  1.1383 +			if (info.prop->GetType() != DPT_Int)
  1.1384 +			{
  1.1385 +				return pContext->ThrowNativeError("SendProp %s is not an integer (%d != %d)",
  1.1386 +					prop,
  1.1387 +					info.prop->GetType(),
  1.1388 +					DPT_Int);
  1.1389 +			}
  1.1390 +
  1.1391 +			offset = info.actual_offset;
  1.1392 +			break;
  1.1393 +		}
  1.1394 +	default:
  1.1395 +		{
  1.1396 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1397 +		}
  1.1398 +	}
  1.1399 +
  1.1400 +	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
  1.1401 +
  1.1402 +	if (params[4] == -1)
  1.1403 +	{
  1.1404 +		hndl.Set(NULL);
  1.1405 +	}
  1.1406 +	else
  1.1407 +	{
  1.1408 +		edict_t *pOther;
  1.1409 +		CBaseEntity *pOtherEnt;
  1.1410 +
  1.1411 +		if ((pOther = GetEntity(params[4], &pOtherEnt)) == NULL)
  1.1412 +		{
  1.1413 +			return pContext->ThrowNativeError("Invalid entity %d", params[4]);
  1.1414 +		}
  1.1415 +
  1.1416 +		hndl.Set(pOther->GetIServerEntity());
  1.1417 +	}
  1.1418 +
  1.1419 +	if (params[2] == Prop_Send)
  1.1420 +	{
  1.1421 +		g_HL2.SetEdictStateChanged(pEdict, offset);
  1.1422 +	}
  1.1423 +
  1.1424 +	return 1;
  1.1425 +}
  1.1426 +
  1.1427 +static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
  1.1428 +{
  1.1429 +	CBaseEntity *pEntity;
  1.1430 +	char *prop;
  1.1431 +	int offset;
  1.1432 +	const char *class_name;
  1.1433 +	edict_t *pEdict;
  1.1434 +	
  1.1435 +	pEdict = GetEntity(params[1], &pEntity);
  1.1436 +
  1.1437 +	if (!pEdict || !pEntity)
  1.1438 +	{
  1.1439 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1440 +	}
  1.1441 +
  1.1442 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1443 +	{
  1.1444 +		class_name = "";
  1.1445 +	}
  1.1446 +
  1.1447 +	pContext->LocalToString(params[3], &prop);
  1.1448 +
  1.1449 +	switch (params[2])
  1.1450 +	{
  1.1451 +	case Prop_Data:
  1.1452 +		{
  1.1453 +			typedescription_t *td;
  1.1454 +			
  1.1455 +			FIND_PROP_DATA(td);
  1.1456 +
  1.1457 +			if (td->fieldType != FIELD_VECTOR
  1.1458 +				&& td->fieldType != FIELD_POSITION_VECTOR)
  1.1459 +			{
  1.1460 +				return pContext->ThrowNativeError("Data field %s is not a vector (%d != [%d,%d])", 
  1.1461 +					prop,
  1.1462 +					td->fieldType,
  1.1463 +					FIELD_VECTOR,
  1.1464 +					FIELD_POSITION_VECTOR);
  1.1465 +			}
  1.1466 +
  1.1467 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1468 +			break;
  1.1469 +		}
  1.1470 +	case Prop_Send:
  1.1471 +		{
  1.1472 +			sm_sendprop_info_t info;
  1.1473 +
  1.1474 +			FIND_PROP_SEND(&info);
  1.1475 +
  1.1476 +			if (info.prop->GetType() != DPT_Vector)
  1.1477 +			{
  1.1478 +				return pContext->ThrowNativeError("SendProp %s is not a vector (%d != %d)",
  1.1479 +					prop,
  1.1480 +					info.prop->GetType(),
  1.1481 +					DPT_Vector);
  1.1482 +			}
  1.1483 +
  1.1484 +			offset = info.actual_offset;
  1.1485 +			break;
  1.1486 +		}
  1.1487 +	default:
  1.1488 +		{
  1.1489 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1490 +		}
  1.1491 +	}
  1.1492 +
  1.1493 +	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
  1.1494 +
  1.1495 +	cell_t *vec;
  1.1496 +	pContext->LocalToPhysAddr(params[4], &vec);
  1.1497 +
  1.1498 +	vec[0] = sp_ftoc(v->x);
  1.1499 +	vec[1] = sp_ftoc(v->y);
  1.1500 +	vec[2] = sp_ftoc(v->z);
  1.1501 +
  1.1502 +	return 1;
  1.1503 +}
  1.1504 +
  1.1505 +static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
  1.1506 +{
  1.1507 +	CBaseEntity *pEntity;
  1.1508 +	char *prop;
  1.1509 +	int offset;
  1.1510 +	const char *class_name;
  1.1511 +	edict_t *pEdict;
  1.1512 +	
  1.1513 +	pEdict = GetEntity(params[1], &pEntity);
  1.1514 +
  1.1515 +	if (!pEdict || !pEntity)
  1.1516 +	{
  1.1517 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1518 +	}
  1.1519 +
  1.1520 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1521 +	{
  1.1522 +		class_name = "";
  1.1523 +	}
  1.1524 +
  1.1525 +	pContext->LocalToString(params[3], &prop);
  1.1526 +
  1.1527 +	switch (params[2])
  1.1528 +	{
  1.1529 +	case Prop_Data:
  1.1530 +		{
  1.1531 +			typedescription_t *td;
  1.1532 +			
  1.1533 +			FIND_PROP_DATA(td);
  1.1534 +
  1.1535 +			if (td->fieldType != FIELD_VECTOR
  1.1536 +				&& td->fieldType != FIELD_POSITION_VECTOR)
  1.1537 +			{
  1.1538 +				return pContext->ThrowNativeError("Data field %s is not a vector (%d != [%d,%d])", 
  1.1539 +					prop,
  1.1540 +					td->fieldType,
  1.1541 +					FIELD_VECTOR,
  1.1542 +					FIELD_POSITION_VECTOR);
  1.1543 +			}
  1.1544 +
  1.1545 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1546 +			break;
  1.1547 +		}
  1.1548 +	case Prop_Send:
  1.1549 +		{
  1.1550 +			sm_sendprop_info_t info;
  1.1551 +
  1.1552 +			FIND_PROP_SEND(&info);
  1.1553 +
  1.1554 +			if (info.prop->GetType() != DPT_Vector)
  1.1555 +			{
  1.1556 +				return pContext->ThrowNativeError("SendProp %s is not a vector (%d != %d)",
  1.1557 +					prop,
  1.1558 +					info.prop->GetType(),
  1.1559 +					DPT_Vector);
  1.1560 +			}
  1.1561 +
  1.1562 +			offset = info.actual_offset;
  1.1563 +			break;
  1.1564 +		}
  1.1565 +	default:
  1.1566 +		{
  1.1567 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1568 +		}
  1.1569 +	}
  1.1570 +
  1.1571 +	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
  1.1572 +
  1.1573 +	cell_t *vec;
  1.1574 +	pContext->LocalToPhysAddr(params[4], &vec);
  1.1575 +
  1.1576 +	v->x = sp_ctof(vec[0]);
  1.1577 +	v->y = sp_ctof(vec[1]);
  1.1578 +	v->z = sp_ctof(vec[2]);
  1.1579 +
  1.1580 +	if (params[2] == Prop_Send)
  1.1581 +	{
  1.1582 +		g_HL2.SetEdictStateChanged(pEdict, offset);
  1.1583 +	}
  1.1584 +
  1.1585 +	return 1;
  1.1586 +}
  1.1587 +
  1.1588 +static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
  1.1589 +{
  1.1590 +	CBaseEntity *pEntity;
  1.1591 +	char *prop;
  1.1592 +	int offset;
  1.1593 +	const char *class_name;
  1.1594 +	edict_t *pEdict;
  1.1595 +	bool bIsStringIndex;
  1.1596 +	
  1.1597 +	pEdict = GetEntity(params[1], &pEntity);
  1.1598 +
  1.1599 +	if (!pEdict || !pEntity)
  1.1600 +	{
  1.1601 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1602 +	}
  1.1603 +
  1.1604 +	if ((class_name = pEdict->GetClassName()) == NULL)
  1.1605 +	{
  1.1606 +		class_name = "";
  1.1607 +	}
  1.1608 +
  1.1609 +	pContext->LocalToString(params[3], &prop);
  1.1610 +
  1.1611 +	bIsStringIndex = false;
  1.1612 +
  1.1613 +	switch (params[2])
  1.1614 +	{
  1.1615 +	case Prop_Data:
  1.1616 +		{
  1.1617 +			typedescription_t *td;
  1.1618 +			
  1.1619 +			FIND_PROP_DATA(td);
  1.1620 +
  1.1621 +			if (td->fieldType != FIELD_CHARACTER
  1.1622 +				&& td->fieldType != FIELD_STRING
  1.1623 +				&& td->fieldType != FIELD_MODELNAME 
  1.1624 +				&& td->fieldType != FIELD_SOUNDNAME)
  1.1625 +			{
  1.1626 +				return pContext->ThrowNativeError("Data field %s is not a string (%d != %d)", 
  1.1627 +					prop,
  1.1628 +					td->fieldType,
  1.1629 +					FIELD_CHARACTER);
  1.1630 +			}
  1.1631 +
  1.1632 +			bIsStringIndex = (td->fieldType != FIELD_CHARACTER);
  1.1633 +
  1.1634 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1635 +			break;
  1.1636 +		}
  1.1637 +	case Prop_Send:
  1.1638 +		{
  1.1639 +			sm_sendprop_info_t info;
  1.1640 +
  1.1641 +			FIND_PROP_SEND(&info);
  1.1642 +
  1.1643 +			if (info.prop->GetType() != DPT_String)
  1.1644 +			{
  1.1645 +				return pContext->ThrowNativeError("SendProp %s is not a string (%d != %d)",
  1.1646 +					prop,
  1.1647 +					info.prop->GetType(),
  1.1648 +					DPT_String);
  1.1649 +			}
  1.1650 +
  1.1651 +			offset = info.actual_offset;
  1.1652 +			break;
  1.1653 +			break;
  1.1654 +		}
  1.1655 +	default:
  1.1656 +		{
  1.1657 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1658 +		}
  1.1659 +	}
  1.1660 +
  1.1661 +	size_t len;
  1.1662 +	const char *src; 
  1.1663 +	
  1.1664 +	if (!bIsStringIndex)
  1.1665 +	{
  1.1666 +		src = (char *)((uint8_t *)pEntity + offset);
  1.1667 +	}
  1.1668 +	else
  1.1669 +	{
  1.1670 +		string_t idx;
  1.1671 +
  1.1672 +		idx = *(string_t *)((uint8_t *)pEntity + offset);
  1.1673 +		src = (idx == NULL_STRING) ? "" : STRING(idx);
  1.1674 +	}
  1.1675 +
  1.1676 +	pContext->StringToLocalUTF8(params[4], params[5], src, &len);
  1.1677 +
  1.1678 +	return len;
  1.1679 +}
  1.1680 +
  1.1681 +static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
  1.1682 +{
  1.1683 +	CBaseEntity *pEntity;
  1.1684 +	char *prop;
  1.1685 +	int offset;
  1.1686 +	int maxlen;
  1.1687 +	edict_t *pEdict = GetEntity(params[1], &pEntity);
  1.1688 +
  1.1689 +	if (!pEdict || !pEntity)
  1.1690 +	{
  1.1691 +		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
  1.1692 +	}
  1.1693 +
  1.1694 +	switch (params[2])
  1.1695 +	{
  1.1696 +	case Prop_Data:
  1.1697 +		{
  1.1698 +			datamap_t *pMap;
  1.1699 +			typedescription_t *td;
  1.1700 +			if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
  1.1701 +			{
  1.1702 +				return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
  1.1703 +			}
  1.1704 +			pContext->LocalToString(params[3], &prop);
  1.1705 +			if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
  1.1706 +			{
  1.1707 +				return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
  1.1708 +			}
  1.1709 +			if (td->fieldType != FIELD_CHARACTER)
  1.1710 +			{
  1.1711 +				return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
  1.1712 +			}
  1.1713 +			offset = td->fieldOffset[TD_OFFSET_NORMAL];
  1.1714 +			maxlen = td->fieldSize;
  1.1715 +			break;
  1.1716 +		}
  1.1717 +	case Prop_Send:
  1.1718 +		{
  1.1719 +			char *prop;
  1.1720 +			IServerNetworkable *pNet = pEdict->GetNetworkable();
  1.1721 +			if (!pNet)
  1.1722 +			{
  1.1723 +				return pContext->ThrowNativeError("The edict is not networkable");
  1.1724 +			}
  1.1725 +			pContext->LocalToString(params[3], &prop);
  1.1726 +			SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
  1.1727 +			if (!pSend)
  1.1728 +			{
  1.1729 +				return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
  1.1730 +			}
  1.1731 +			if (pSend->GetType() != DPT_String)
  1.1732 +			{
  1.1733 +				return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
  1.1734 +			}
  1.1735 +			offset = pSend->GetOffset();
  1.1736 +			maxlen = DT_MAX_STRING_BUFFERSIZE;
  1.1737 +			break;
  1.1738 +		}
  1.1739 +	default:
  1.1740 +		{
  1.1741 +			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
  1.1742 +		}
  1.1743 +	}
  1.1744 +
  1.1745 +	char *src;
  1.1746 +	char *dest = (char *)((uint8_t *)pEntity + offset);
  1.1747 +
  1.1748 +	pContext->LocalToString(params[4], &src);
  1.1749 +	size_t len = strncopy(dest, src, maxlen);
  1.1750 +
  1.1751 +	if (params[2] == Prop_Send)
  1.1752 +	{
  1.1753 +		g_HL2.SetEdictStateChanged(pEdict, offset);
  1.1754 +	}
  1.1755 +
  1.1756 +	return len;
  1.1757 +}
  1.1758 +
  1.1759 +REGISTER_NATIVES(entityNatives)
  1.1760 +{
  1.1761 +	{"ChangeEdictState",		ChangeEdictState},
  1.1762 +	{"CreateEdict",				CreateEdict},
  1.1763 +	{"FindDataMapOffs",			FindDataMapOffs},
  1.1764 +	{"FindSendPropInfo",		FindSendPropInfo},
  1.1765 +	{"FindSendPropOffs",		FindSendPropOffs},
  1.1766 +	{"GetEdictClassname",		GetEdictClassname},
  1.1767 +	{"GetEdictFlags",			GetEdictFlags},
  1.1768 +	{"GetEntData",				GetEntData},
  1.1769 +	{"GetEntDataEnt",			GetEntDataEnt},		/** DEPRECATED */
  1.1770 +	{"GetEntDataEnt2",			GetEntDataEnt2},
  1.1771 +	{"GetEntDataFloat",			GetEntDataFloat},
  1.1772 +	{"GetEntDataString",		GetEntDataString},
  1.1773 +	{"GetEntDataVector",		GetEntDataVector},
  1.1774 +	{"GetEntProp",				GetEntProp},
  1.1775 +	{"GetEntPropEnt",			GetEntPropEnt},
  1.1776 +	{"GetEntPropFloat",			GetEntPropFloat},
  1.1777 +	{"GetEntPropString",		GetEntPropString},
  1.1778 +	{"GetEntPropVector",		GetEntPropVector},
  1.1779 +	{"GetEntityCount",			GetEntityCount},
  1.1780 +	{"GetEntityNetClass",		GetEntityNetClass},
  1.1781 +	{"GetMaxEntities",			GetMaxEntities},
  1.1782 +	{"IsEntNetworkable",		IsEntNetworkable},
  1.1783 +	{"IsValidEdict",			IsValidEdict},
  1.1784 +	{"IsValidEntity",			IsValidEntity},
  1.1785 +	{"RemoveEdict",				RemoveEdict},
  1.1786 +	{"SetEdictFlags",			SetEdictFlags},
  1.1787 +	{"SetEntData",				SetEntData},
  1.1788 +	{"SetEntDataEnt",			SetEntDataEnt},		/** DEPRECATED */
  1.1789 +	{"SetEntDataEnt2",			SetEntDataEnt2},
  1.1790 +	{"SetEntDataFloat",			SetEntDataFloat},
  1.1791 +	{"SetEntDataVector",		SetEntDataVector},
  1.1792 +	{"SetEntDataString",		SetEntDataString},
  1.1793 +	{"SetEntProp",				SetEntProp},
  1.1794 +	{"SetEntPropEnt",			SetEntPropEnt},
  1.1795 +	{"SetEntPropFloat",			SetEntPropFloat},
  1.1796 +	{"SetEntPropString",		SetEntPropString},
  1.1797 +	{"SetEntPropVector",		SetEntPropVector},
  1.1798 +	{NULL,						NULL}
  1.1799 +};