core/smn_entities.cpp
author Peace-Maker <januk@freenet.de>
Wed Apr 23 08:55:09 2014 -0400 (2014-04-23)
changeset 4330 98726cea1607
parent 4266 b6060fd93236
permissions -rw-r--r--
Mark CS:S as supporting HudMsg (bug 6108, r=psychonic).
dvander@555
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
ds@3099
     5
 * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@555
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@555
    28
 *
dvander@555
    29
 * Version: $Id$
dvander@555
    30
 */
dvander@555
    31
dvander@555
    32
#include "sm_globals.h"
dvander@555
    33
#include "sourcemod.h"
dvander@555
    34
#include "sourcemm_api.h"
dvander@591
    35
#include "PlayerManager.h"
dvander@592
    36
#include "HalfLife2.h"
dvander@3010
    37
#include <IGameConfigs.h>
faluco@694
    38
#include "sm_stringutil.h"
dvander@3010
    39
#include "logic_bridge.h"
faluco@694
    40
skamonkey@3220
    41
// These values need to mirror the values in entity_prop_stocks
skamonkey@3220
    42
#define ENTFLAG_ONGROUND		(1 << 0)
skamonkey@3220
    43
#define ENTFLAG_DUCKING			(1 << 1)
skamonkey@3220
    44
#define ENTFLAG_WATERJUMP		(1 << 2)
skamonkey@3220
    45
#define ENTFLAG_ONTRAIN			(1 << 3)
skamonkey@3220
    46
#define ENTFLAG_INRAIN			(1 << 4)
skamonkey@3220
    47
#define ENTFLAG_FROZEN			(1 << 5)
skamonkey@3220
    48
#define ENTFLAG_ATCONTROLS		(1 << 6)
skamonkey@3220
    49
#define ENTFLAG_CLIENT			(1 << 7)
skamonkey@3220
    50
#define ENTFLAG_FAKECLIENT		(1 << 8)
skamonkey@3220
    51
#define ENTFLAG_INWATER			(1 << 9)
skamonkey@3220
    52
#define ENTFLAG_FLY				(1 << 10)
skamonkey@3220
    53
#define ENTFLAG_SWIM			(1 << 11)
skamonkey@3220
    54
#define ENTFLAG_CONVEYOR		(1 << 12)
skamonkey@3220
    55
#define ENTFLAG_NPC				(1 << 13)
skamonkey@3220
    56
#define ENTFLAG_GODMODE			(1 << 14)
skamonkey@3220
    57
#define ENTFLAG_NOTARGET		(1 << 15)
skamonkey@3220
    58
#define ENTFLAG_AIMTARGET		(1 << 16)
skamonkey@3220
    59
#define ENTFLAG_PARTIALGROUND	(1 << 17)
skamonkey@3220
    60
#define ENTFLAG_STATICPROP		(1 << 18)
skamonkey@3220
    61
#define ENTFLAG_GRAPHED			(1 << 19)
skamonkey@3220
    62
#define ENTFLAG_GRENADE			(1 << 20)
skamonkey@3220
    63
#define ENTFLAG_STEPMOVEMENT	(1 << 21)
skamonkey@3220
    64
#define ENTFLAG_DONTTOUCH		(1 << 22)
skamonkey@3220
    65
#define ENTFLAG_BASEVELOCITY	(1 << 23)
skamonkey@3220
    66
#define ENTFLAG_WORLDBRUSH		(1 << 24)
skamonkey@3220
    67
#define ENTFLAG_OBJECT			(1 << 25)
skamonkey@3220
    68
#define ENTFLAG_KILLME			(1 << 26)
skamonkey@3220
    69
#define ENTFLAG_ONFIRE			(1 << 27)
skamonkey@3220
    70
#define ENTFLAG_DISSOLVING		(1 << 28)
skamonkey@3220
    71
#define ENTFLAG_TRANSRAGDOLL	(1 << 29)
skamonkey@3220
    72
#define ENTFLAG_UNBLOCKABLE_BY_PLAYER	(1 << 30)
skamonkey@3220
    73
#define ENTFLAG_FREEZING		(1 << 31)
skamonkey@3220
    74
#define ENTFLAG_EP2V_UNKNOWN1	(1 << 31)
skamonkey@3220
    75
skamonkey@3220
    76
// Not defined in the sdk as we have no clue what it is
skamonkey@3220
    77
#define FL_EP2V_UNKNOWN			(1 << 2)
skamonkey@3220
    78
faluco@694
    79
enum PropType
faluco@694
    80
{
faluco@694
    81
	Prop_Send = 0,
faluco@694
    82
	Prop_Data
faluco@694
    83
};
dvander@555
    84
dvander@1847
    85
enum PropFieldType
dvander@1847
    86
{
dvander@1847
    87
	PropField_Unsupported,		/**< The type is unsupported. */
dvander@1847
    88
	PropField_Integer,			/**< Valid for SendProp and Data fields */
dvander@1847
    89
	PropField_Float,			/**< Valid for SendProp and Data fields */
dvander@1847
    90
	PropField_Entity,			/**< Valid for Data fields only (SendProp shows as int) */
dvander@1847
    91
	PropField_Vector,			/**< Valid for SendProp and Data fields */
dvander@1847
    92
	PropField_String,			/**< Valid for SendProp and Data fields */
dvander@1884
    93
	PropField_String_T,			/**< Valid for Data fields.  Read only! */
dvander@1847
    94
};
dvander@1847
    95
pred@2746
    96
inline edict_t *BaseEntityToEdict(CBaseEntity *pEntity)
pred@2746
    97
{
pred@2746
    98
	IServerUnknown *pUnk = (IServerUnknown *)pEntity;
pred@2746
    99
	IServerNetworkable *pNet = pUnk->GetNetworkable();
pred@2746
   100
pred@2746
   101
	if (!pNet)
pred@2746
   102
	{
pred@2746
   103
		return NULL;
pred@2746
   104
	}
pred@2746
   105
pred@2746
   106
	return pNet->GetEdict();
pred@2746
   107
}
pred@2746
   108
dvander@555
   109
inline edict_t *GetEdict(cell_t num)
dvander@555
   110
{
fyrenmoo@2879
   111
	edict_t *pEdict;
fyrenmoo@2879
   112
	if (!IndexToAThings(num, NULL, &pEdict))
fyrenmoo@2879
   113
	{
fyrenmoo@2879
   114
		return NULL;
fyrenmoo@2879
   115
	}
fyrenmoo@2879
   116
	
fyrenmoo@2879
   117
	return pEdict;
fyrenmoo@2879
   118
}
fyrenmoo@2879
   119
fyrenmoo@2879
   120
inline CBaseEntity *GetEntity(cell_t num)
fyrenmoo@2879
   121
{
fyrenmoo@2879
   122
	CBaseEntity *pEntity;
fyrenmoo@2879
   123
	if (!IndexToAThings(num, &pEntity, NULL))
fyrenmoo@2879
   124
	{
fyrenmoo@2879
   125
		return NULL;
fyrenmoo@2879
   126
	}
fyrenmoo@2879
   127
fyrenmoo@2879
   128
	return pEntity;
fyrenmoo@2879
   129
}
fyrenmoo@2879
   130
fyrenmoo@2879
   131
/* Given an entity reference or index, fill out a CBaseEntity and/or edict.
fyrenmoo@2879
   132
   If lookup is successful, returns true and writes back the two parameters.
fyrenmoo@2879
   133
   If lookup fails, returns false and doesn't touch the params.  */
fyrenmoo@2879
   134
bool IndexToAThings(cell_t num, CBaseEntity **pEntData, edict_t **pEdictData)
fyrenmoo@2879
   135
{
pred@2746
   136
	CBaseEntity *pEntity = g_HL2.ReferenceToEntity(num);
pred@2746
   137
pred@2746
   138
	if (!pEntity)
pred@2746
   139
	{
fyrenmoo@2879
   140
		return false;
dvander@555
   141
	}
pred@2746
   142
pred@2746
   143
	int index = g_HL2.ReferenceToIndex(num);
pred@2746
   144
	if (index > 0 && index <= g_Players.GetMaxClients())
dvander@556
   145
	{
pred@2746
   146
		CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
dvander@556
   147
		if (!pPlayer || !pPlayer->IsConnected())
dvander@556
   148
		{
fyrenmoo@2879
   149
			return false;
dvander@556
   150
		}
dvander@556
   151
	}
pred@2746
   152
fyrenmoo@2879
   153
	if (pEntData)
dvander@557
   154
	{
fyrenmoo@2879
   155
		*pEntData = pEntity;
dvander@557
   156
	}
pred@2746
   157
fyrenmoo@2879
   158
	if (pEdictData)
dvander@557
   159
	{
fyrenmoo@2879
   160
		edict_t *pEdict = ::BaseEntityToEdict(pEntity);
fyrenmoo@2913
   161
		if (!pEdict || pEdict->IsFree())
dvander@557
   162
		{
fyrenmoo@2879
   163
			pEdict = NULL;
dvander@557
   164
		}
fyrenmoo@2879
   165
fyrenmoo@2879
   166
		*pEdictData = pEdict;
dvander@557
   167
	}
pred@2746
   168
fyrenmoo@2879
   169
	return true;
dvander@557
   170
}
fyrenmoo@2879
   171
/*
fyrenmoo@2879
   172
  <predcrab> AThings is like guaranteed r+ by dvander though
fyrenmoo@2879
   173
  <predcrab> he wont even read the rest of the patch to nit stuff
fyrenmoo@2879
   174
  <Fyren> Like I wasn't going to r? you anyway!
fyrenmoo@2879
   175
  <predcrab> he still sees!
fyrenmoo@2879
   176
  <predcrab> he's everywhere
fyrenmoo@2879
   177
*/
dvander@557
   178
faluco@682
   179
class VEmptyClass {};
faluco@682
   180
datamap_t *VGetDataDescMap(CBaseEntity *pThisPtr, int offset)
faluco@682
   181
{
faluco@682
   182
	void **this_ptr = *reinterpret_cast<void ***>(&pThisPtr);
faluco@682
   183
	void **vtable = *reinterpret_cast<void ***>(pThisPtr);
faluco@682
   184
	void *vfunc = vtable[offset];
faluco@682
   185
faluco@682
   186
	union
faluco@682
   187
	{
faluco@682
   188
		datamap_t *(VEmptyClass::*mfpnew)();
faluco@682
   189
#ifndef PLATFORM_POSIX
faluco@682
   190
		void *addr;
faluco@682
   191
	} u;
faluco@682
   192
	u.addr = vfunc;
faluco@682
   193
#else
faluco@682
   194
		struct  
faluco@682
   195
		{
faluco@682
   196
			void *addr;
faluco@682
   197
			intptr_t adjustor;
faluco@682
   198
		} s;
faluco@682
   199
	} u;
faluco@682
   200
	u.s.addr = vfunc;
faluco@682
   201
	u.s.adjustor = 0;
faluco@682
   202
#endif
faluco@682
   203
faluco@682
   204
	return (datamap_t *)(reinterpret_cast<VEmptyClass *>(this_ptr)->*u.mfpnew)();
faluco@682
   205
}
faluco@682
   206
faluco@682
   207
inline datamap_t *CBaseEntity_GetDataDescMap(CBaseEntity *pEntity)
faluco@682
   208
{
faluco@682
   209
	int offset;
faluco@682
   210
faluco@682
   211
	if (!g_pGameConf->GetOffset("GetDataDescMap", &offset) || !offset)
faluco@682
   212
	{
faluco@682
   213
		return NULL;
faluco@682
   214
	}
faluco@682
   215
faluco@682
   216
	return VGetDataDescMap(pEntity, offset);
faluco@682
   217
}
faluco@682
   218
dvander@965
   219
/* :TODO: Move this! */
dvander@965
   220
datamap_t *CHalfLife2::GetDataMap(CBaseEntity *pEntity)
dvander@965
   221
{
dvander@965
   222
	return CBaseEntity_GetDataDescMap(pEntity);
dvander@965
   223
}
dvander@965
   224
dvander@555
   225
static cell_t GetMaxEntities(IPluginContext *pContext, const cell_t *params)
dvander@555
   226
{
dvander@555
   227
	return gpGlobals->maxEntities;
dvander@555
   228
}
dvander@555
   229
dvander@555
   230
static cell_t CreateEdict(IPluginContext *pContext, const cell_t *params)
dvander@555
   231
{
dvander@555
   232
	edict_t *pEdict = engine->CreateEdict();
dvander@555
   233
dvander@555
   234
	if (!pEdict)
dvander@555
   235
	{
dvander@555
   236
		return 0;
dvander@555
   237
	}
dvander@555
   238
ds@2400
   239
	return IndexOfEdict(pEdict);
dvander@555
   240
}
dvander@555
   241
dvander@555
   242
static cell_t RemoveEdict(IPluginContext *pContext, const cell_t *params)
dvander@555
   243
{
pred@2746
   244
	edict_t *pEdict = GetEdict(params[1]);
dvander@555
   245
dvander@555
   246
	if (!pEdict)
dvander@555
   247
	{
pred@2746
   248
		return pContext->ThrowNativeError("Edict %d (%d) is not a valid edict", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@555
   249
	}
dvander@555
   250
dvander@555
   251
	engine->RemoveEdict(pEdict);
dvander@555
   252
dvander@555
   253
	return 1;
dvander@555
   254
}
dvander@555
   255
dvander@555
   256
static cell_t IsValidEdict(IPluginContext *pContext, const cell_t *params)
dvander@555
   257
{
dvander@556
   258
	edict_t *pEdict = GetEdict(params[1]);
dvander@555
   259
dvander@555
   260
	if (!pEdict)
dvander@555
   261
	{
dvander@555
   262
		return 0;
dvander@555
   263
	}
dvander@555
   264
dvander@555
   265
	/* Shouldn't be necessary... not sure though */
dvander@555
   266
	return pEdict->IsFree() ? 0 : 1;
dvander@555
   267
}
dvander@555
   268
dvander@555
   269
static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params)
dvander@555
   270
{
pred@2746
   271
	CBaseEntity *pEntity = g_HL2.ReferenceToEntity(params[1]);
dvander@555
   272
dvander@555
   273
	return (pEntity != NULL) ? 1 : 0;
dvander@555
   274
}
dvander@555
   275
dvander@555
   276
static cell_t IsEntNetworkable(IPluginContext *pContext, const cell_t *params)
dvander@555
   277
{
dvander@556
   278
	edict_t *pEdict = GetEdict(params[1]);
dvander@555
   279
dvander@556
   280
	if (!pEdict)
dvander@555
   281
	{
dvander@555
   282
		return 0;
dvander@555
   283
	}
dvander@555
   284
dvander@555
   285
	return (pEdict->GetNetworkable() != NULL) ? 1 : 0;
dvander@555
   286
}
dvander@555
   287
dvander@555
   288
static cell_t GetEntityCount(IPluginContext *pContext, const cell_t *params)
dvander@555
   289
{
dvander@555
   290
	return engine->GetEntityCount();
dvander@555
   291
}
dvander@555
   292
dvander@555
   293
static cell_t GetEdictFlags(IPluginContext *pContext, const cell_t *params)
dvander@555
   294
{
dvander@555
   295
	edict_t *pEdict = GetEdict(params[1]);
dvander@555
   296
dvander@555
   297
	if (!pEdict)
dvander@555
   298
	{
pred@2746
   299
		return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@555
   300
	}
dvander@555
   301
dvander@555
   302
	return pEdict->m_fStateFlags;
dvander@555
   303
}
dvander@555
   304
dvander@555
   305
static cell_t SetEdictFlags(IPluginContext *pContext, const cell_t *params)
dvander@555
   306
{
dvander@555
   307
	edict_t *pEdict = GetEdict(params[1]);
dvander@555
   308
dvander@555
   309
	if (!pEdict)
dvander@555
   310
	{
pred@2746
   311
		return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@555
   312
	}
dvander@555
   313
dvander@555
   314
	pEdict->m_fStateFlags = params[2];
dvander@555
   315
dvander@555
   316
	return 1;
dvander@555
   317
}
dvander@555
   318
dvander@556
   319
static cell_t GetEdictClassname(IPluginContext *pContext, const cell_t *params)
dvander@556
   320
{
dvander@556
   321
	edict_t *pEdict = GetEdict(params[1]);
dvander@556
   322
dvander@556
   323
	if (!pEdict)
dvander@556
   324
	{
pred@2746
   325
		return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@556
   326
	}
dvander@556
   327
kyle@3638
   328
	const char *cls = g_HL2.GetEntityClassname(pEdict);
dvander@556
   329
dvander@556
   330
	if (!cls || cls[0] == '\0')
dvander@556
   331
	{
dvander@556
   332
		return 0;
dvander@556
   333
	}
dvander@556
   334
dvander@556
   335
	pContext->StringToLocal(params[2], params[3], cls);
dvander@556
   336
dvander@556
   337
	return 1;
dvander@556
   338
}
dvander@556
   339
dvander@556
   340
static cell_t GetEntityNetClass(IPluginContext *pContext, const cell_t *params)
dvander@556
   341
{
pred@2746
   342
	CBaseEntity *pEntity = g_HL2.ReferenceToEntity(params[1]);
pred@2746
   343
pred@2746
   344
	IServerUnknown *pUnk = (IServerUnknown *)pEntity;
dvander@556
   345
pred@2746
   346
	if (!pEntity)
dvander@556
   347
	{
pred@2746
   348
		return pContext->ThrowNativeError("Invalid entity (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@556
   349
	}
dvander@556
   350
pred@2746
   351
	IServerNetworkable *pNet = pUnk->GetNetworkable();
dvander@556
   352
	if (!pNet)
dvander@556
   353
	{
dvander@556
   354
		return 0;
dvander@556
   355
	}
dvander@556
   356
dvander@556
   357
	ServerClass *pClass = pNet->GetServerClass();
dvander@556
   358
dvander@556
   359
	pContext->StringToLocal(params[2], params[3], pClass->GetName());
dvander@556
   360
dvander@556
   361
	return 1;
dvander@556
   362
}
dvander@556
   363
dvander@557
   364
static cell_t GetEntData(IPluginContext *pContext, const cell_t *params)
dvander@557
   365
{
fyrenmoo@2879
   366
	CBaseEntity *pEntity = GetEntity(params[1]);
dvander@557
   367
pred@2746
   368
	if (!pEntity)
dvander@557
   369
	{
pred@2746
   370
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   371
	}
dvander@557
   372
dvander@557
   373
	int offset = params[2];
dvander@1847
   374
	if (offset <= 0 || offset > 32768)
dvander@557
   375
	{
dvander@557
   376
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   377
	}
dvander@557
   378
dvander@557
   379
	switch (params[3])
dvander@557
   380
	{
dvander@557
   381
	case 4:
dvander@557
   382
		return *(int *)((uint8_t *)pEntity + offset);
dvander@557
   383
	case 2:
dvander@557
   384
		return *(short *)((uint8_t *)pEntity + offset);
dvander@557
   385
	case 1:
dvander@557
   386
		return *((uint8_t *)pEntity + offset);
dvander@557
   387
	default:
dvander@557
   388
		return pContext->ThrowNativeError("Integer size %d is invalid", params[3]);
dvander@557
   389
	}
dvander@557
   390
}
dvander@557
   391
dvander@557
   392
static cell_t SetEntData(IPluginContext *pContext, const cell_t *params)
dvander@557
   393
{
dvander@557
   394
	CBaseEntity *pEntity;
fyrenmoo@2879
   395
	edict_t *pEdict;
dvander@557
   396
fyrenmoo@2879
   397
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@557
   398
	{
pred@2746
   399
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   400
	}
dvander@557
   401
dvander@557
   402
	int offset = params[2];
dvander@1847
   403
	if (offset <= 0 || offset > 32768)
dvander@557
   404
	{
dvander@557
   405
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   406
	}
dvander@557
   407
pred@2746
   408
	if (params[5] && (pEdict != NULL))
dvander@561
   409
	{
dvander@685
   410
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@561
   411
	}
dvander@561
   412
dvander@557
   413
	switch (params[4])
dvander@557
   414
	{
dvander@557
   415
	case 4:
dvander@557
   416
		{
dvander@557
   417
			*(int *)((uint8_t *)pEntity + offset) = params[3];
dvander@557
   418
			break;
dvander@557
   419
		}
dvander@557
   420
	case 2:
dvander@557
   421
		{
dvander@557
   422
			*(short *)((uint8_t *)pEntity + offset) = params[3];
dvander@557
   423
			break;
dvander@557
   424
		}
dvander@557
   425
	case 1:
dvander@557
   426
		{
dvander@557
   427
			*((uint8_t *)pEntity + offset) = params[3];
dvander@557
   428
			break;
dvander@557
   429
		}
dvander@557
   430
	default:
dvander@557
   431
		return pContext->ThrowNativeError("Integer size %d is invalid", params[4]);
dvander@557
   432
	}
dvander@557
   433
dvander@557
   434
	return 1;
dvander@557
   435
}
dvander@557
   436
dvander@557
   437
static cell_t GetEntDataFloat(IPluginContext *pContext, const cell_t *params)
dvander@557
   438
{
fyrenmoo@2879
   439
	CBaseEntity *pEntity = GetEntity(params[1]);
dvander@557
   440
pred@2746
   441
	if (!pEntity)
dvander@557
   442
	{
pred@2746
   443
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   444
	}
dvander@557
   445
dvander@557
   446
	int offset = params[2];
dvander@1847
   447
	if (offset <= 0 || offset > 32768)
dvander@557
   448
	{
dvander@557
   449
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   450
	}
dvander@557
   451
dvander@557
   452
	float f = *(float *)((uint8_t *)pEntity + offset);
dvander@557
   453
dvander@557
   454
	return sp_ftoc(f);
dvander@557
   455
}
dvander@557
   456
dvander@557
   457
static cell_t SetEntDataFloat(IPluginContext *pContext, const cell_t *params)
dvander@557
   458
{
dvander@557
   459
	CBaseEntity *pEntity;
fyrenmoo@2879
   460
	edict_t *pEdict;
dvander@557
   461
fyrenmoo@2879
   462
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@557
   463
	{
pred@2746
   464
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   465
	}
dvander@557
   466
dvander@557
   467
	int offset = params[2];
dvander@1847
   468
	if (offset <= 0 || offset > 32768)
dvander@557
   469
	{
dvander@557
   470
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   471
	}
dvander@557
   472
dvander@557
   473
	*(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[3]);
dvander@557
   474
pred@2746
   475
	if (params[4] && (pEdict != NULL))
dvander@561
   476
	{
dvander@685
   477
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@561
   478
	}
dvander@561
   479
dvander@557
   480
	return 1;
dvander@557
   481
}
dvander@557
   482
dvander@557
   483
static cell_t GetEntDataVector(IPluginContext *pContext, const cell_t *params)
dvander@557
   484
{
fyrenmoo@2879
   485
	CBaseEntity *pEntity = GetEntity(params[1]);
dvander@557
   486
pred@2746
   487
	if (!pEntity)
dvander@557
   488
	{
pred@2746
   489
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   490
	}
dvander@557
   491
dvander@557
   492
	int offset = params[2];
dvander@1847
   493
	if (offset <= 0 || offset > 32768)
dvander@557
   494
	{
dvander@557
   495
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   496
	}
dvander@557
   497
dvander@557
   498
	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
dvander@557
   499
dvander@557
   500
	cell_t *vec;
dvander@557
   501
	pContext->LocalToPhysAddr(params[3], &vec);
dvander@557
   502
faluco@597
   503
	vec[0] = sp_ftoc(v->x);
faluco@597
   504
	vec[1] = sp_ftoc(v->y);
faluco@597
   505
	vec[2] = sp_ftoc(v->z);
dvander@557
   506
dvander@557
   507
	return 1;
dvander@557
   508
}
dvander@557
   509
dvander@557
   510
static cell_t SetEntDataVector(IPluginContext *pContext, const cell_t *params)
dvander@557
   511
{
dvander@557
   512
	CBaseEntity *pEntity;
fyrenmoo@2879
   513
	edict_t *pEdict;
dvander@557
   514
fyrenmoo@2879
   515
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@557
   516
	{
pred@2746
   517
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   518
	}
dvander@557
   519
dvander@557
   520
	int offset = params[2];
dvander@1847
   521
	if (offset <= 0 || offset > 32768)
dvander@557
   522
	{
dvander@557
   523
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   524
	}
dvander@557
   525
dvander@557
   526
	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
dvander@557
   527
dvander@557
   528
	cell_t *vec;
dvander@557
   529
	pContext->LocalToPhysAddr(params[3], &vec);
dvander@557
   530
faluco@597
   531
	v->x = sp_ctof(vec[0]);
faluco@597
   532
	v->y = sp_ctof(vec[1]);
faluco@597
   533
	v->z = sp_ctof(vec[2]);
dvander@557
   534
pred@2746
   535
	if (params[4] && (pEdict != NULL))
dvander@561
   536
	{
dvander@685
   537
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@561
   538
	}
dvander@561
   539
dvander@557
   540
	return 1;
dvander@557
   541
}
dvander@557
   542
dvander@1847
   543
/* THIS GUY IS DEPRECATED. */
dvander@557
   544
static cell_t GetEntDataEnt(IPluginContext *pContext, const cell_t *params)
dvander@557
   545
{
fyrenmoo@2879
   546
	CBaseEntity *pEntity = GetEntity(params[1]);
dvander@557
   547
pred@2746
   548
	if (!pEntity)
dvander@557
   549
	{
pred@2746
   550
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   551
	}
dvander@557
   552
dvander@557
   553
	int offset = params[2];
dvander@1847
   554
	if (offset <= 0 || offset > 32768)
dvander@557
   555
	{
dvander@557
   556
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   557
	}
dvander@557
   558
dvander@557
   559
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
dvander@557
   560
dvander@557
   561
	if (!hndl.IsValid())
dvander@557
   562
	{
dvander@557
   563
		return 0;
dvander@557
   564
	}
dvander@557
   565
pred@2746
   566
	int ref = g_HL2.IndexToReference(hndl.GetEntryIndex());
pred@2746
   567
	return g_HL2.ReferenceToBCompatRef(ref);
dvander@557
   568
}
dvander@557
   569
dvander@1847
   570
int CheckBaseHandle(CBaseHandle &hndl)
dvander@1847
   571
{
dvander@1847
   572
	if (!hndl.IsValid())
dvander@1847
   573
	{
dvander@1847
   574
		return -1;
dvander@1847
   575
	}
dvander@1847
   576
dvander@1847
   577
	int index = hndl.GetEntryIndex();
dvander@1847
   578
dvander@1847
   579
	edict_t *pStoredEdict;
dvander@1847
   580
	CBaseEntity *pStoredEntity;
dvander@1847
   581
fyrenmoo@2879
   582
	if (!IndexToAThings(index, &pStoredEntity, &pStoredEdict))
fyrenmoo@2879
   583
	{
fyrenmoo@2879
   584
		return -1;
fyrenmoo@2879
   585
	}
dvander@1847
   586
dvander@1847
   587
	if (pStoredEdict == NULL || pStoredEntity == NULL)
dvander@1847
   588
	{
dvander@1847
   589
		return -1;
dvander@1847
   590
	}
dvander@1847
   591
dvander@1847
   592
	IServerEntity *pSE = pStoredEdict->GetIServerEntity();
dvander@1847
   593
dvander@1847
   594
	if (pSE == NULL)
dvander@1847
   595
	{
dvander@1847
   596
		return -1;
dvander@1847
   597
	}
dvander@1847
   598
dvander@1847
   599
	if (pSE->GetRefEHandle() != hndl)
dvander@1847
   600
	{
dvander@1847
   601
		return -1;
dvander@1847
   602
	}
dvander@1847
   603
dvander@1847
   604
	return index;
dvander@1847
   605
}
dvander@1847
   606
dvander@1847
   607
static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
dvander@1847
   608
{
fyrenmoo@2879
   609
	CBaseEntity *pEntity = GetEntity(params[1]);
dvander@1847
   610
pred@2746
   611
	if (pEntity == NULL)
dvander@1847
   612
	{
pred@2746
   613
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
   614
	}
dvander@1847
   615
dvander@1847
   616
	int offset = params[2];
dvander@1847
   617
	if (offset <= 0 || offset > 32768)
dvander@1847
   618
	{
dvander@1847
   619
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@1847
   620
	}
dvander@1847
   621
dvander@1847
   622
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
skamonkey@3709
   623
	CBaseEntity *pHandleEntity = g_HL2.ReferenceToEntity(hndl.GetEntryIndex());
dvander@1847
   624
skamonkey@3709
   625
	if (!pHandleEntity || hndl != reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
skamonkey@3708
   626
		return -1;
skamonkey@3708
   627
skamonkey@3709
   628
	return g_HL2.EntityToBCompatRef(pHandleEntity);
dvander@1847
   629
}
dvander@1847
   630
dvander@1847
   631
/* THIS GUY IS DEPRECATED. */
dvander@557
   632
static cell_t SetEntDataEnt(IPluginContext *pContext, const cell_t *params)
dvander@557
   633
{
dvander@557
   634
	CBaseEntity *pEntity;
fyrenmoo@2879
   635
	edict_t *pEdict;
dvander@557
   636
fyrenmoo@2879
   637
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@557
   638
	{
pred@2746
   639
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@557
   640
	}
dvander@557
   641
dvander@557
   642
	int offset = params[2];
dvander@1847
   643
	if (offset <= 0 || offset > 32768)
dvander@557
   644
	{
dvander@557
   645
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@557
   646
	}
dvander@557
   647
dvander@557
   648
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
dvander@557
   649
pred@2748
   650
	if (params[3] == 0 || (unsigned)params[3] == INVALID_EHANDLE_INDEX)
dvander@557
   651
	{
dvander@557
   652
		hndl.Set(NULL);
dvander@557
   653
	} else {
fyrenmoo@2879
   654
		CBaseEntity *pOther = GetEntity(params[3]);
pred@2746
   655
pred@2746
   656
		if (!pOther)
dvander@557
   657
		{
pred@2746
   658
			return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[3]), params[3]);
dvander@557
   659
		}
pred@2746
   660
pred@2746
   661
		IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
pred@2746
   662
		hndl.Set(pHandleEnt);
dvander@557
   663
	}
dvander@557
   664
pred@2746
   665
	if (params[4] && (pEdict != NULL))
dvander@561
   666
	{
dvander@685
   667
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@561
   668
	}
dvander@561
   669
dvander@557
   670
	return 1;
dvander@557
   671
}
dvander@557
   672
dvander@1847
   673
static cell_t SetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
dvander@1847
   674
{
dvander@1847
   675
	CBaseEntity *pEntity;
fyrenmoo@2879
   676
	edict_t *pEdict;
dvander@1847
   677
fyrenmoo@2879
   678
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
   679
	{
pred@2746
   680
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
   681
	}
dvander@1847
   682
dvander@1847
   683
	int offset = params[2];
dvander@1847
   684
	if (offset <= 0 || offset > 32768)
dvander@1847
   685
	{
dvander@1847
   686
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
dvander@1847
   687
	}
dvander@1847
   688
dvander@1847
   689
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
dvander@1847
   690
pred@2748
   691
	if ((unsigned)params[3] == INVALID_EHANDLE_INDEX)
dvander@1847
   692
	{
dvander@1847
   693
		hndl.Set(NULL);
dvander@1847
   694
	}
dvander@1847
   695
	else
dvander@1847
   696
	{
fyrenmoo@2879
   697
		CBaseEntity *pOther = GetEntity(params[3]);
pred@2746
   698
pred@2746
   699
		if (!pOther)
dvander@1847
   700
		{
pred@2746
   701
			return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[3]), params[3]);
dvander@1847
   702
		}
pred@2746
   703
pred@2746
   704
		IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
pred@2746
   705
		hndl.Set(pHandleEnt);
dvander@1847
   706
	}
dvander@1847
   707
pred@2746
   708
	if (params[4] && (pEdict != NULL))
dvander@1847
   709
	{
dvander@1847
   710
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@1847
   711
	}
dvander@1847
   712
dvander@1847
   713
	return 1;
dvander@1847
   714
}
dvander@1847
   715
dvander@558
   716
static cell_t ChangeEdictState(IPluginContext *pContext, const cell_t *params)
dvander@558
   717
{
dvander@558
   718
	edict_t *pEdict = GetEdict(params[1]);
dvander@558
   719
dvander@558
   720
	if (!pEdict)
dvander@558
   721
	{
pred@2746
   722
		return pContext->ThrowNativeError("Edict %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@558
   723
	}
dvander@558
   724
dvander@685
   725
	g_HL2.SetEdictStateChanged(pEdict, params[2]);
dvander@558
   726
dvander@558
   727
	return 1;
dvander@558
   728
}
dvander@558
   729
dvander@561
   730
static cell_t FindSendPropOffs(IPluginContext *pContext, const cell_t *params)
dvander@561
   731
{
dvander@561
   732
	char *cls, *prop;
dvander@561
   733
	pContext->LocalToString(params[1], &cls);
dvander@561
   734
	pContext->LocalToString(params[2], &prop);
dvander@561
   735
dvander@561
   736
	SendProp *pSend = g_HL2.FindInSendTable(cls, prop);
dvander@561
   737
dvander@561
   738
	if (!pSend)
dvander@561
   739
	{
dvander@561
   740
		return -1;
dvander@561
   741
	}
dvander@561
   742
dvander@561
   743
	return pSend->GetOffset();
dvander@561
   744
}
dvander@561
   745
dvander@1847
   746
static cell_t FindSendPropInfo(IPluginContext *pContext, const cell_t *params)
dvander@1847
   747
{
dvander@1847
   748
	char *cls, *prop;
dvander@1847
   749
	sm_sendprop_info_t info;
dvander@1847
   750
	cell_t *pType, *pBits, *pLocal;
dvander@1847
   751
dvander@1847
   752
	pContext->LocalToString(params[1], &cls);
dvander@1847
   753
	pContext->LocalToString(params[2], &prop);
dvander@1847
   754
dvander@1847
   755
	if (!g_HL2.FindSendPropInfo(cls, prop, &info))
dvander@1847
   756
	{
dvander@1847
   757
		return -1;
dvander@1847
   758
	}
dvander@1847
   759
dvander@1847
   760
	pContext->LocalToPhysAddr(params[3], &pType);
dvander@1847
   761
	pContext->LocalToPhysAddr(params[4], &pBits);
dvander@1847
   762
	pContext->LocalToPhysAddr(params[5], &pLocal);
dvander@1847
   763
dvander@1847
   764
	switch (info.prop->GetType())
dvander@1847
   765
	{
dvander@1847
   766
	case DPT_Int:
dvander@1847
   767
		{
dvander@1847
   768
			*pType = PropField_Integer;
dvander@1847
   769
			break;
dvander@1847
   770
		}
dvander@1847
   771
	case DPT_Float:
dvander@1847
   772
		{
dvander@1847
   773
			*pType = PropField_Float;
dvander@1847
   774
			break;
dvander@1847
   775
		}
dvander@1847
   776
	case DPT_String:
dvander@1847
   777
		{
dvander@1847
   778
			*pType = PropField_String;
dvander@1847
   779
			break;
dvander@1847
   780
		}
dvander@1847
   781
	case DPT_Vector:
dvander@1847
   782
		{
dvander@1847
   783
			*pType = PropField_Vector;
dvander@1847
   784
			break;
dvander@1847
   785
		}
dvander@1847
   786
	default:
dvander@1847
   787
		{
dvander@1847
   788
			*pType = PropField_Unsupported;
dvander@1847
   789
			break;
dvander@1847
   790
		}
dvander@1847
   791
	}
dvander@1847
   792
dvander@1847
   793
	*pBits = info.prop->m_nBits;
dvander@1847
   794
	*pLocal = info.prop->GetOffset();
dvander@1847
   795
dvander@1847
   796
	return info.actual_offset;
dvander@1847
   797
}
dvander@1847
   798
kyle@3997
   799
static void GuessDataPropTypes(typedescription_t *td, cell_t * pSize, cell_t * pType)
kyle@3997
   800
{
kyle@3997
   801
	switch (td->fieldType)
kyle@3997
   802
	{
kyle@3997
   803
	case FIELD_TICK:
kyle@3997
   804
	case FIELD_MODELINDEX:
kyle@3997
   805
	case FIELD_MATERIALINDEX:
kyle@3997
   806
	case FIELD_INTEGER:
kyle@3997
   807
	case FIELD_COLOR32:
kyle@3997
   808
		{
kyle@3997
   809
			*pType = PropField_Integer;
kyle@3997
   810
			*pSize = 32;
kyle@3997
   811
			break;
kyle@3997
   812
		}
kyle@3997
   813
	case FIELD_VECTOR:
kyle@3997
   814
	case FIELD_POSITION_VECTOR:
kyle@3997
   815
		{
kyle@3997
   816
			*pType = PropField_Vector;
kyle@3997
   817
			*pSize = 12;
kyle@3997
   818
			break;
kyle@3997
   819
		}
kyle@3997
   820
	case FIELD_SHORT:
kyle@3997
   821
		{
kyle@3997
   822
			*pType = PropField_Integer;
kyle@3997
   823
			*pSize = 16;
kyle@3997
   824
			break;
kyle@3997
   825
		}
kyle@3997
   826
	case FIELD_BOOLEAN:
kyle@3997
   827
		{
kyle@3997
   828
			*pType = PropField_Integer;
kyle@3997
   829
			*pSize = 1;
kyle@3997
   830
			break;
kyle@3997
   831
		}
kyle@3997
   832
	case FIELD_CHARACTER:
kyle@3997
   833
		{
kyle@3997
   834
			if (td->fieldSize == 1)
kyle@3997
   835
			{
kyle@3997
   836
				*pType = PropField_Integer;
kyle@3997
   837
				*pSize = 8;
kyle@3997
   838
			}
kyle@3997
   839
			else
kyle@3997
   840
			{
kyle@3997
   841
				*pType = PropField_String;
kyle@3997
   842
				*pSize = 8 * td->fieldSize;
kyle@3997
   843
			}
kyle@3997
   844
			break;
kyle@3997
   845
		}
kyle@3997
   846
	case FIELD_MODELNAME:
kyle@3997
   847
	case FIELD_SOUNDNAME:
kyle@3997
   848
	case FIELD_STRING:
kyle@3997
   849
		{
kyle@3997
   850
			*pSize = sizeof(string_t);
kyle@3997
   851
			*pType = PropField_String_T;
kyle@3997
   852
			break;
kyle@3997
   853
		}
kyle@3997
   854
	case FIELD_FLOAT:
kyle@3997
   855
	case FIELD_TIME:
kyle@3997
   856
		{
kyle@3997
   857
			*pType = PropField_Float;
kyle@3997
   858
			*pSize = 32;
kyle@3997
   859
			break;
kyle@3997
   860
		}
kyle@3997
   861
	case FIELD_EHANDLE:
kyle@3997
   862
		{
kyle@3997
   863
			*pType = PropField_Entity;
kyle@3997
   864
			*pSize = 32;
kyle@3997
   865
			break;
kyle@3997
   866
		}
kyle@3997
   867
	default:
kyle@3997
   868
		{
kyle@3997
   869
			*pType = PropField_Unsupported;
kyle@3997
   870
			*pSize = 0;
kyle@3997
   871
		}
kyle@3997
   872
	}
kyle@3997
   873
}
kyle@3997
   874
faluco@682
   875
static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params)
faluco@682
   876
{
faluco@682
   877
	CBaseEntity *pEntity;
faluco@682
   878
	datamap_t *pMap;
faluco@682
   879
	typedescription_t *td;
faluco@682
   880
	char *offset;
fyrenmoo@2879
   881
	pEntity = GetEntity(params[1]);
faluco@682
   882
pred@2746
   883
	if (!pEntity)
faluco@682
   884
	{
pred@2746
   885
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
faluco@682
   886
	}
faluco@682
   887
faluco@682
   888
	if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
faluco@682
   889
	{
faluco@682
   890
		return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
faluco@682
   891
	}
faluco@682
   892
faluco@682
   893
	pContext->LocalToString(params[2], &offset);
kyle@3997
   894
	sm_datatable_info_t info;
kyle@3997
   895
	if (!g_HL2.FindDataMapInfo(pMap, offset, &info))
faluco@682
   896
	{
kyle@3997
   897
		return -1;
faluco@682
   898
	}
kyle@3997
   899
	
kyle@3997
   900
	td = info.prop;
faluco@682
   901
dvander@1847
   902
	if (params[0] == 4)
dvander@1847
   903
	{
dvander@1847
   904
		cell_t *pType, *pSize;
dvander@1847
   905
dvander@1847
   906
		pContext->LocalToPhysAddr(params[3], &pType);
dvander@1847
   907
		pContext->LocalToPhysAddr(params[4], &pSize);
kyle@3997
   908
		
kyle@3997
   909
		GuessDataPropTypes(td, pSize, pType);
kyle@3997
   910
	}
dvander@1847
   911
kyle@3997
   912
	return GetTypeDescOffs(td);
kyle@3997
   913
}
kyle@3997
   914
kyle@3997
   915
static cell_t FindDataMapInfo(IPluginContext *pContext, const cell_t *params)
kyle@3997
   916
{
kyle@3997
   917
	CBaseEntity *pEntity;
kyle@3997
   918
	datamap_t *pMap;
kyle@3997
   919
	typedescription_t *td;
kyle@3997
   920
	char *offset;
kyle@3997
   921
	pEntity = GetEntity(params[1]);
kyle@3997
   922
kyle@3997
   923
	if (!pEntity)
kyle@3997
   924
	{
kyle@3997
   925
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
kyle@3997
   926
	}
kyle@3997
   927
kyle@3997
   928
	if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
kyle@3997
   929
	{
kyle@3997
   930
		return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
kyle@3997
   931
	}
kyle@3997
   932
kyle@3997
   933
	pContext->LocalToString(params[2], &offset);
kyle@3997
   934
	sm_datatable_info_t info;
kyle@3997
   935
	if (!g_HL2.FindDataMapInfo(pMap, offset, &info))
kyle@3997
   936
	{
kyle@3997
   937
		return -1;
kyle@3997
   938
	}
kyle@3997
   939
	
kyle@3997
   940
	td = info.prop;
kyle@3997
   941
kyle@3997
   942
	if (params[0] >= 4)
kyle@3997
   943
	{
kyle@3997
   944
		cell_t *pType, *pSize;
kyle@3997
   945
kyle@3997
   946
		pContext->LocalToPhysAddr(params[3], &pType);
kyle@3997
   947
		pContext->LocalToPhysAddr(params[4], &pSize);
kyle@3997
   948
		
kyle@3997
   949
		GuessDataPropTypes(td, pSize, pType);
kyle@3997
   950
		
kyle@3997
   951
		if (params[0] == 5)
dvander@1847
   952
		{
kyle@3997
   953
			cell_t *pLocalOffs;
kyle@3997
   954
			
kyle@3997
   955
			pContext->LocalToPhysAddr(params[5], &pLocalOffs);
kyle@3997
   956
			
kyle@3997
   957
			*pLocalOffs = GetTypeDescOffs(info.prop);
dvander@1847
   958
		}
dvander@1847
   959
	}
dvander@1847
   960
kyle@3997
   961
	return info.actual_offset;
faluco@682
   962
}
faluco@682
   963
faluco@694
   964
static cell_t GetEntDataString(IPluginContext *pContext, const cell_t *params)
faluco@694
   965
{
fyrenmoo@2879
   966
	CBaseEntity *pEntity = GetEntity(params[1]);
faluco@694
   967
pred@2746
   968
	if (!pEntity)
faluco@694
   969
	{
pred@2746
   970
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
faluco@694
   971
	}
faluco@694
   972
faluco@694
   973
	int offset = params[2];
faluco@694
   974
	if (offset < 0 || offset > 32768)
faluco@694
   975
	{
faluco@694
   976
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
faluco@694
   977
	}
faluco@694
   978
faluco@694
   979
	size_t len;
faluco@694
   980
	char *src = (char *)((uint8_t *)pEntity + offset);
faluco@694
   981
	pContext->StringToLocalUTF8(params[3], params[4], src, &len);
faluco@694
   982
faluco@694
   983
	return len;
faluco@694
   984
}
faluco@694
   985
faluco@694
   986
static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
faluco@694
   987
{
faluco@694
   988
	CBaseEntity *pEntity;
fyrenmoo@2879
   989
	edict_t *pEdict;
faluco@694
   990
fyrenmoo@2879
   991
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
faluco@694
   992
	{
pred@2746
   993
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
faluco@694
   994
	}
faluco@694
   995
faluco@694
   996
	int offset = params[2];
faluco@694
   997
	if (offset < 0 || offset > 32768)
faluco@694
   998
	{
faluco@694
   999
		return pContext->ThrowNativeError("Offset %d is invalid", offset);
faluco@694
  1000
	}
faluco@694
  1001
faluco@694
  1002
	char *src;
faluco@694
  1003
	char *dest = (char *)((uint8_t *)pEntity + offset);
faluco@694
  1004
faluco@694
  1005
	pContext->LocalToString(params[3], &src);
faluco@694
  1006
	size_t len = strncopy(dest, src, params[4]);
faluco@694
  1007
pred@2746
  1008
	if (params[5] && (pEdict != NULL))
faluco@694
  1009
	{
faluco@694
  1010
		g_HL2.SetEdictStateChanged(pEdict, offset);
faluco@694
  1011
	}
faluco@694
  1012
faluco@694
  1013
	return len;
faluco@694
  1014
}
faluco@694
  1015
dvander@1847
  1016
#define FIND_PROP_DATA(td) \
dvander@1847
  1017
	datamap_t *pMap; \
dvander@1847
  1018
	if ((pMap = CBaseEntity_GetDataDescMap(pEntity)) == NULL) \
dvander@1847
  1019
	{ \
dvander@1847
  1020
		return pContext->ThrowNativeError("Could not retrieve datamap"); \
dvander@1847
  1021
	} \
kyle@3997
  1022
	sm_datatable_info_t info; \
kyle@3997
  1023
	if (!g_HL2.FindDataMapInfo(pMap, prop, &info)) \
dvander@1847
  1024
	{ \
kyle@3638
  1025
		const char *class_name = g_HL2.GetEntityClassname(pEntity); \
kyle@3997
  1026
		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
kyle@3997
  1027
			prop, \
kyle@3997
  1028
			params[1], \
kyle@3997
  1029
			((class_name) ? class_name : "")); \
kyle@3997
  1030
	} \
kyle@3997
  1031
	td = info.prop;
dvander@1847
  1032
skamonkey@3293
  1033
#define CHECK_SET_PROP_DATA_OFFSET() \
skamonkey@3417
  1034
	if (element < 0 || element >= td->fieldSize) \
skamonkey@3293
  1035
	{ \
skamonkey@3293
  1036
		return pContext->ThrowNativeError("Element %d is out of bounds (Prop %s has %d elements).", \
skamonkey@3293
  1037
			element, \
skamonkey@3293
  1038
			prop, \
skamonkey@3293
  1039
			td->fieldSize); \
skamonkey@3293
  1040
	} \
skamonkey@3293
  1041
	\
kyle@3997
  1042
	offset = info.actual_offset + (element * (td->fieldSizeInBytes / td->fieldSize));
skamonkey@3293
  1043
skamonkey@3293
  1044
#define FIND_PROP_SEND(type, type_name) \
skamonkey@3293
  1045
	sm_sendprop_info_t info;\
skamonkey@3762
  1046
	SendProp *pProp; \
pred@2746
  1047
	IServerUnknown *pUnk = (IServerUnknown *)pEntity; \
pred@2746
  1048
	IServerNetworkable *pNet = pUnk->GetNetworkable(); \
dvander@1847
  1049
	if (!pNet) \
dvander@1847
  1050
	{ \
pred@2746
  1051
		return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]); \
dvander@1847
  1052
	} \
skamonkey@3293
  1053
	if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) \
dvander@1847
  1054
	{ \
kyle@3638
  1055
		const char *class_name = g_HL2.GetEntityClassname(pEntity); \
dvander@1847
  1056
		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
dvander@1847
  1057
			prop, \
dvander@1847
  1058
			params[1], \
kyle@3638
  1059
			((class_name) ? class_name : "")); \
skamonkey@3293
  1060
	} \
skamonkey@3293
  1061
	\
skamonkey@3293
  1062
	offset = info.actual_offset; \
skamonkey@3762
  1063
	pProp = info.prop; \
skamonkey@3762
  1064
	bit_count = pProp->m_nBits; \
skamonkey@3293
  1065
	\
skamonkey@3762
  1066
	switch (pProp->GetType()) \
skamonkey@3293
  1067
	{ \
skamonkey@3293
  1068
	case type: \
skamonkey@3293
  1069
		{ \
skamonkey@3417
  1070
			if (element != 0) \
skamonkey@3293
  1071
			{ \
skamonkey@3293
  1072
				return pContext->ThrowNativeError("SendProp %s is not an array. Element %d is invalid.", \
skamonkey@3293
  1073
					prop, \
skamonkey@3293
  1074
					element); \
skamonkey@3293
  1075
			} \
skamonkey@3293
  1076
			break; \
skamonkey@3293
  1077
		} \
skamonkey@3293
  1078
	case DPT_DataTable: \
skamonkey@3293
  1079
		{ \
skamonkey@3293
  1080
			FIND_PROP_SEND_IN_SENDTABLE(info, pProp, element, type, type_name); \
skamonkey@3293
  1081
			\
skamonkey@3293
  1082
			offset += pProp->GetOffset(); \
skamonkey@3293
  1083
			bit_count = pProp->m_nBits; \
skamonkey@3293
  1084
			break; \
skamonkey@3293
  1085
		} \
skamonkey@3293
  1086
	default: \
skamonkey@3293
  1087
		{ \
skamonkey@3293
  1088
			return pContext->ThrowNativeError("SendProp %s type is not " type_name " (%d != %d)", \
skamonkey@3293
  1089
				prop, \
skamonkey@3762
  1090
				pProp->GetType(), \
skamonkey@3293
  1091
				type); \
skamonkey@3293
  1092
		} \
skamonkey@3293
  1093
	} \
skamonkey@3293
  1094
skamonkey@3293
  1095
#define FIND_PROP_SEND_IN_SENDTABLE(info, pProp, element, type, type_name) \
skamonkey@3762
  1096
	SendTable *pTable = pProp->GetDataTable(); \
skamonkey@3293
  1097
	if (!pTable) \
skamonkey@3293
  1098
	{ \
skamonkey@3293
  1099
		return pContext->ThrowNativeError("Error looking up DataTable for prop %s", \
skamonkey@3293
  1100
			prop); \
skamonkey@3293
  1101
	} \
skamonkey@3293
  1102
	\
skamonkey@3293
  1103
	int elementCount = pTable->GetNumProps(); \
skamonkey@3417
  1104
	if (element < 0 || element >= elementCount) \
skamonkey@3293
  1105
	{ \
skamonkey@3293
  1106
		return pContext->ThrowNativeError("Element %d is out of bounds (Prop %s has %d elements).", \
skamonkey@3293
  1107
			element, \
skamonkey@3293
  1108
			prop, \
skamonkey@3293
  1109
			elementCount); \
skamonkey@3293
  1110
	} \
skamonkey@3293
  1111
	\
skamonkey@3293
  1112
	pProp = pTable->GetProp(element); \
skamonkey@3293
  1113
	if (pProp->GetType() != type) \
skamonkey@3293
  1114
	{ \
skamonkey@3293
  1115
		return pContext->ThrowNativeError("SendProp %s type is not " type_name " ([%d,%d] != %d)", \
skamonkey@3293
  1116
			prop, \
skamonkey@3762
  1117
			pProp->GetType(), \
skamonkey@3762
  1118
			pProp->m_nBits, \
skamonkey@3293
  1119
			type); \
dvander@1847
  1120
	}
dvander@1847
  1121
skamonkey@3293
  1122
dvander@1847
  1123
inline int MatchFieldAsInteger(int field_type)
dvander@1847
  1124
{
dvander@1847
  1125
	switch (field_type)
dvander@1847
  1126
	{
dvander@1847
  1127
	case FIELD_TICK:
dvander@1847
  1128
	case FIELD_MODELINDEX:
dvander@1847
  1129
	case FIELD_MATERIALINDEX:
dvander@1847
  1130
	case FIELD_INTEGER:
dvander@1847
  1131
	case FIELD_COLOR32:
dvander@1847
  1132
		return 32;
dvander@1847
  1133
	case FIELD_SHORT:
dvander@1847
  1134
		return 16;
dvander@1847
  1135
	case FIELD_CHARACTER:
dvander@1847
  1136
		return 8;
dvander@1847
  1137
	case FIELD_BOOLEAN:
dvander@1847
  1138
		return 1;
dvander@1847
  1139
	default:
dvander@1847
  1140
		return 0;
dvander@1847
  1141
	}
dvander@1847
  1142
dvander@1847
  1143
	return 0;
dvander@1847
  1144
}
dvander@1847
  1145
skamonkey@3293
  1146
static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params)
skamonkey@3293
  1147
{
skamonkey@3293
  1148
	CBaseEntity *pEntity;
skamonkey@3293
  1149
	char *prop;
skamonkey@3293
  1150
	edict_t *pEdict;
skamonkey@3293
  1151
skamonkey@3293
  1152
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
skamonkey@3293
  1153
	{
skamonkey@3293
  1154
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
skamonkey@3293
  1155
	}
skamonkey@3293
  1156
skamonkey@3293
  1157
	pContext->LocalToString(params[3], &prop);
skamonkey@3293
  1158
skamonkey@3293
  1159
	switch (params[2])
skamonkey@3293
  1160
	{
skamonkey@3293
  1161
	case Prop_Data:
skamonkey@3293
  1162
		{
skamonkey@3293
  1163
			typedescription_t *td;
skamonkey@3293
  1164
skamonkey@3293
  1165
			FIND_PROP_DATA(td);
skamonkey@3293
  1166
skamonkey@3293
  1167
			return td->fieldSize;
skamonkey@3293
  1168
		}
skamonkey@3293
  1169
	case Prop_Send:
skamonkey@3293
  1170
		{
skamonkey@3293
  1171
			sm_sendprop_info_t info;
skamonkey@3293
  1172
			
skamonkey@3293
  1173
			IServerUnknown *pUnk = (IServerUnknown *)pEntity;
skamonkey@3293
  1174
			IServerNetworkable *pNet = pUnk->GetNetworkable();
skamonkey@3293
  1175
			if (!pNet)
skamonkey@3293
  1176
			{
skamonkey@3293
  1177
				return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]);
skamonkey@3293
  1178
			}
skamonkey@3293
  1179
			if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
skamonkey@3293
  1180
			{
kyle@3638
  1181
				const char *class_name = g_HL2.GetEntityClassname(pEntity);
skamonkey@3293
  1182
				return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
skamonkey@3293
  1183
					prop,
skamonkey@3293
  1184
					params[1],
kyle@3638
  1185
					((class_name) ? class_name : ""));
skamonkey@3293
  1186
			}
skamonkey@3293
  1187
skamonkey@3293
  1188
			if (info.prop->GetType() != DPT_DataTable)
skamonkey@3293
  1189
			{
skamonkey@3293
  1190
				return 0;
skamonkey@3293
  1191
			}
skamonkey@3293
  1192
skamonkey@3293
  1193
			SendTable *pTable = info.prop->GetDataTable();
skamonkey@3293
  1194
			if (!pTable)
skamonkey@3293
  1195
			{
skamonkey@3293
  1196
				return pContext->ThrowNativeError("Error looking up DataTable for prop %s", prop);
skamonkey@3293
  1197
			}
skamonkey@3293
  1198
			
skamonkey@3293
  1199
			return pTable->GetNumProps();
skamonkey@3293
  1200
		}
skamonkey@3293
  1201
	default:
skamonkey@3293
  1202
		{
skamonkey@3293
  1203
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
skamonkey@3293
  1204
		}
skamonkey@3293
  1205
	}
skamonkey@3293
  1206
skamonkey@3293
  1207
	return 1;
skamonkey@3293
  1208
}
skamonkey@3293
  1209
dvander@1847
  1210
static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1211
{
dvander@1847
  1212
	CBaseEntity *pEntity;
dvander@1847
  1213
	char *prop;
dvander@1847
  1214
	int offset;
dvander@1847
  1215
	edict_t *pEdict;
dvander@1847
  1216
	int bit_count;
skamonkey@3398
  1217
	bool is_unsigned = false;
dvander@1847
  1218
skamonkey@3293
  1219
	int element = 0;
skamonkey@3293
  1220
	if (params[0] >= 5)
skamonkey@3293
  1221
	{
skamonkey@3293
  1222
		element = params[5];
skamonkey@3293
  1223
	}
skamonkey@3293
  1224
fyrenmoo@2879
  1225
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1226
	{
pred@2746
  1227
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1228
	}
dvander@1847
  1229
dvander@1847
  1230
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1231
dvander@1847
  1232
	switch (params[2])
dvander@1847
  1233
	{
dvander@1847
  1234
	case Prop_Data:
dvander@1847
  1235
		{
dvander@1847
  1236
			typedescription_t *td;
dvander@1847
  1237
dvander@1847
  1238
			FIND_PROP_DATA(td);
dvander@1847
  1239
dvander@1847
  1240
			if ((bit_count = MatchFieldAsInteger(td->fieldType)) == 0)
dvander@1847
  1241
			{
dvander@1847
  1242
				return pContext->ThrowNativeError("Data field %s is not an integer (%d)", 
dvander@1847
  1243
					prop,
dvander@1847
  1244
					td->fieldType);
dvander@1847
  1245
			}
dvander@1847
  1246
skamonkey@3293
  1247
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1248
dvander@1847
  1249
			break;
dvander@1847
  1250
		}
dvander@1847
  1251
	case Prop_Send:
dvander@1847
  1252
		{
skamonkey@3293
  1253
			FIND_PROP_SEND(DPT_Int, "integer");
skamonkey@3762
  1254
			is_unsigned = ((pProp->GetFlags() & SPROP_UNSIGNED) == SPROP_UNSIGNED);
skamonkey@3712
  1255
skamonkey@3712
  1256
			// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
skamonkey@4141
  1257
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3762
  1258
			if (pProp->GetFlags() & SPROP_VARINT)
skamonkey@3712
  1259
			{
skamonkey@3712
  1260
				bit_count = sizeof(int) * 8;
skamonkey@3712
  1261
			}
skamonkey@3712
  1262
#endif
dvander@1847
  1263
			break;
dvander@1847
  1264
		}
dvander@1847
  1265
	default:
dvander@1847
  1266
		{
dvander@1847
  1267
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1268
		}
dvander@1847
  1269
	}
dvander@1847
  1270
dvander@1847
  1271
	if (bit_count < 1)
dvander@1847
  1272
	{
dvander@1847
  1273
		bit_count = params[4] * 8;
dvander@1847
  1274
	}
dvander@1847
  1275
dvander@1847
  1276
	if (bit_count >= 17)
dvander@1847
  1277
	{
dvander@1847
  1278
		return *(int32_t *)((uint8_t *)pEntity + offset);
dvander@1847
  1279
	}
dvander@1847
  1280
	else if (bit_count >= 9)
dvander@1847
  1281
	{
skamonkey@3398
  1282
		if (is_unsigned)
skamonkey@3398
  1283
		{
skamonkey@3398
  1284
			return *(uint16_t *)((uint8_t *)pEntity + offset);
skamonkey@3398
  1285
		}
skamonkey@3398
  1286
		else
skamonkey@3398
  1287
		{
skamonkey@3398
  1288
			return *(int16_t *)((uint8_t *)pEntity + offset);
skamonkey@3398
  1289
		}
dvander@1847
  1290
	}
dvander@1847
  1291
	else if (bit_count >= 2)
dvander@1847
  1292
	{
skamonkey@3398
  1293
		if (is_unsigned)
skamonkey@3398
  1294
		{
skamonkey@3398
  1295
			return *(uint8_t *)((uint8_t *)pEntity + offset);
skamonkey@3398
  1296
		}
skamonkey@3398
  1297
		else
skamonkey@3398
  1298
		{
skamonkey@3398
  1299
			return *(int8_t *)((uint8_t *)pEntity + offset);
skamonkey@3398
  1300
		}
dvander@1847
  1301
	}
dvander@1847
  1302
	else
dvander@1847
  1303
	{
dvander@1847
  1304
		return *(bool *)((uint8_t *)pEntity + offset) ? 1 : 0;
dvander@1847
  1305
	}
dvander@1847
  1306
dvander@1847
  1307
	return 0;
dvander@1847
  1308
}
dvander@1847
  1309
dvander@1847
  1310
static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
faluco@694
  1311
{
faluco@694
  1312
	CBaseEntity *pEntity;
faluco@694
  1313
	char *prop;
faluco@694
  1314
	int offset;
dvander@1847
  1315
	edict_t *pEdict;
dvander@1847
  1316
	int bit_count;
dvander@1847
  1317
skamonkey@3293
  1318
	int element = 0;
skamonkey@3293
  1319
	if (params[0] >= 6)
skamonkey@3293
  1320
	{
skamonkey@3293
  1321
		element = params[6];
skamonkey@3293
  1322
	}
skamonkey@3293
  1323
fyrenmoo@2879
  1324
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1325
	{
pred@2746
  1326
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1327
	}
dvander@1847
  1328
dvander@1847
  1329
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1330
dvander@1847
  1331
	switch (params[2])
dvander@1847
  1332
	{
dvander@1847
  1333
	case Prop_Data:
dvander@1847
  1334
		{
dvander@1847
  1335
			typedescription_t *td;
dvander@1847
  1336
dvander@1847
  1337
			FIND_PROP_DATA(td);
dvander@1847
  1338
dvander@1847
  1339
			if ((bit_count = MatchFieldAsInteger(td->fieldType)) == 0)
dvander@1847
  1340
			{
dvander@1847
  1341
				return pContext->ThrowNativeError("Data field %s is not an integer (%d)", 
dvander@1847
  1342
					prop,
dvander@1847
  1343
					td->fieldType);
dvander@1847
  1344
			}
dvander@1847
  1345
skamonkey@3293
  1346
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1347
dvander@1847
  1348
			break;
dvander@1847
  1349
		}
dvander@1847
  1350
	case Prop_Send:
dvander@1847
  1351
		{
skamonkey@3293
  1352
			FIND_PROP_SEND(DPT_Int, "integer");
skamonkey@3712
  1353
skamonkey@3712
  1354
			// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
skamonkey@4141
  1355
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3762
  1356
			if (pProp->GetFlags() & SPROP_VARINT)
skamonkey@3712
  1357
			{
skamonkey@3712
  1358
				bit_count = sizeof(int) * 8;
skamonkey@3712
  1359
			}
skamonkey@3712
  1360
#endif
dvander@1847
  1361
			break;
dvander@1847
  1362
		}
dvander@1847
  1363
	default:
dvander@1847
  1364
		{
dvander@1847
  1365
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1366
		}
dvander@1847
  1367
	}
dvander@1847
  1368
dvander@1847
  1369
	if (bit_count < 1)
dvander@1847
  1370
	{
dvander@1847
  1371
		bit_count = params[5] * 8;
dvander@1847
  1372
	}
dvander@1847
  1373
dvander@1847
  1374
	if (bit_count >= 17)
dvander@1847
  1375
	{
dvander@1847
  1376
		*(int32_t *)((uint8_t *)pEntity + offset) = params[4];
dvander@1847
  1377
	}
dvander@1847
  1378
	else if (bit_count >= 9)
dvander@1847
  1379
	{
dvander@1847
  1380
		*(int16_t *)((uint8_t *)pEntity + offset) = (int16_t)params[4];
dvander@1847
  1381
	}
dvander@1847
  1382
	else if (bit_count >= 2)
dvander@1847
  1383
	{
dvander@1847
  1384
		*(int8_t *)((uint8_t *)pEntity + offset) = (int8_t)params[4];
dvander@1847
  1385
	}
dvander@1847
  1386
	else
dvander@1847
  1387
	{
dvander@1847
  1388
		*(bool *)((uint8_t *)pEntity + offset) = params[4] ? true : false;
dvander@1847
  1389
	}
skamonkey@3239
  1390
	
skamonkey@3239
  1391
	if (params[2] == Prop_Send && (pEdict != NULL))
skamonkey@3239
  1392
	{
skamonkey@3239
  1393
		g_HL2.SetEdictStateChanged(pEdict, offset);
skamonkey@3239
  1394
	}
dvander@1847
  1395
dvander@1847
  1396
	return 0;
dvander@1847
  1397
}
dvander@1847
  1398
dvander@1847
  1399
static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1400
{
dvander@1847
  1401
	CBaseEntity *pEntity;
dvander@1847
  1402
	char *prop;
dvander@1847
  1403
	int offset;
skamonkey@3293
  1404
	int bit_count;
dvander@1847
  1405
	edict_t *pEdict;
dvander@1847
  1406
skamonkey@3293
  1407
	int element = 0;
skamonkey@3293
  1408
	if (params[0] >= 4)
skamonkey@3293
  1409
	{
skamonkey@3293
  1410
		element = params[4];
skamonkey@3293
  1411
	}
skamonkey@3293
  1412
fyrenmoo@2879
  1413
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1414
	{
pred@2746
  1415
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1416
	}
dvander@1847
  1417
dvander@1847
  1418
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1419
dvander@1847
  1420
	switch (params[2])
dvander@1847
  1421
	{
dvander@1847
  1422
	case Prop_Data:
dvander@1847
  1423
		{
dvander@1847
  1424
			typedescription_t *td;
dvander@1847
  1425
dvander@1847
  1426
			FIND_PROP_DATA(td);
dvander@1847
  1427
dvander@1847
  1428
			if (td->fieldType != FIELD_FLOAT
dvander@1847
  1429
				&& td->fieldType != FIELD_TIME)
dvander@1847
  1430
			{
dvander@1847
  1431
				return pContext->ThrowNativeError("Data field %s is not a float (%d != [%d,%d])", 
dvander@1847
  1432
					prop,
dvander@1847
  1433
					td->fieldType,
dvander@1847
  1434
					FIELD_FLOAT,
dvander@1847
  1435
					FIELD_TIME);
dvander@1847
  1436
			}
dvander@1847
  1437
skamonkey@3293
  1438
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1439
dvander@1847
  1440
			break;
dvander@1847
  1441
		}
dvander@1847
  1442
	case Prop_Send:
dvander@1847
  1443
		{
skamonkey@3293
  1444
			FIND_PROP_SEND(DPT_Float, "float");
dvander@1847
  1445
			break;
dvander@1847
  1446
		}
dvander@1847
  1447
	default:
dvander@1847
  1448
		{
dvander@1847
  1449
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1450
		}
dvander@1847
  1451
	}
dvander@1847
  1452
dvander@1847
  1453
	float val = *(float *)((uint8_t *)pEntity + offset);
dvander@1847
  1454
dvander@1847
  1455
	return sp_ftoc(val);
dvander@1847
  1456
}
dvander@1847
  1457
dvander@1847
  1458
static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1459
{
dvander@1847
  1460
	CBaseEntity *pEntity;
dvander@1847
  1461
	char *prop;
dvander@1847
  1462
	int offset;
skamonkey@3293
  1463
	int bit_count;
dvander@1847
  1464
	edict_t *pEdict;
dvander@1847
  1465
skamonkey@3293
  1466
	int element = 0;
skamonkey@3293
  1467
	if (params[0] >= 5)
skamonkey@3293
  1468
	{
skamonkey@3293
  1469
		element = params[5];
skamonkey@3293
  1470
	}
skamonkey@3293
  1471
fyrenmoo@2879
  1472
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
faluco@694
  1473
	{
pred@2746
  1474
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
faluco@694
  1475
	}
faluco@694
  1476
dvander@1847
  1477
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1478
faluco@694
  1479
	switch (params[2])
faluco@694
  1480
	{
faluco@694
  1481
	case Prop_Data:
faluco@694
  1482
		{
faluco@694
  1483
			typedescription_t *td;
dvander@1847
  1484
dvander@1847
  1485
			FIND_PROP_DATA(td);
dvander@1847
  1486
dvander@1847
  1487
			if (td->fieldType != FIELD_FLOAT
dvander@1847
  1488
				&& td->fieldType != FIELD_TIME)
faluco@694
  1489
			{
dvander@1847
  1490
				return pContext->ThrowNativeError("Data field %s is not a float (%d != [%d,%d])", 
dvander@1847
  1491
					prop,
dvander@1847
  1492
					td->fieldType,
dvander@1847
  1493
					FIELD_FLOAT,
dvander@1847
  1494
					FIELD_TIME);
dvander@1847
  1495
			}
dvander@1847
  1496
skamonkey@3293
  1497
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1498
dvander@1847
  1499
			break;
dvander@1847
  1500
		}
dvander@1847
  1501
	case Prop_Send:
dvander@1847
  1502
		{
skamonkey@3293
  1503
			FIND_PROP_SEND(DPT_Float, "float");
dvander@1847
  1504
			break;
dvander@1847
  1505
		}
dvander@1847
  1506
	default:
dvander@1847
  1507
		{
dvander@1847
  1508
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1509
		}
dvander@1847
  1510
	}
dvander@1847
  1511
dvander@1847
  1512
	*(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[4]);
dvander@1847
  1513
pred@2746
  1514
	if (params[2] == Prop_Send && (pEdict != NULL))
dvander@1847
  1515
	{
dvander@1847
  1516
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@1847
  1517
	}
dvander@1847
  1518
dvander@1847
  1519
	return 1;
dvander@1847
  1520
}
dvander@1847
  1521
dvander@1847
  1522
static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1523
{
dvander@1847
  1524
	CBaseEntity *pEntity;
dvander@1847
  1525
	char *prop;
dvander@1847
  1526
	int offset;
skamonkey@3293
  1527
	int bit_count;
dvander@1847
  1528
	edict_t *pEdict;
dvander@1847
  1529
skamonkey@3293
  1530
	int element = 0;
skamonkey@3293
  1531
	if (params[0] >= 4)
skamonkey@3293
  1532
 	{
skamonkey@3293
  1533
		element = params[4];
skamonkey@3293
  1534
 	}
skamonkey@3293
  1535
fyrenmoo@2879
  1536
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1537
	{
pred@2746
  1538
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1539
	}
dvander@1847
  1540
dvander@1847
  1541
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1542
dvander@1847
  1543
	switch (params[2])
dvander@1847
  1544
	{
dvander@1847
  1545
	case Prop_Data:
dvander@1847
  1546
		{
dvander@1847
  1547
			typedescription_t *td;
dvander@1847
  1548
dvander@1847
  1549
			FIND_PROP_DATA(td);
dvander@1847
  1550
dvander@1847
  1551
			if (td->fieldType != FIELD_EHANDLE)
faluco@694
  1552
			{
dvander@1847
  1553
				return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)", 
dvander@1847
  1554
					prop,
dvander@1847
  1555
					td->fieldType,
dvander@1847
  1556
					FIELD_EHANDLE);
faluco@694
  1557
			}
dvander@1847
  1558
skamonkey@3293
  1559
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1560
dvander@1847
  1561
			break;
dvander@1847
  1562
		}
dvander@1847
  1563
	case Prop_Send:
dvander@1847
  1564
		{
skamonkey@3293
  1565
			FIND_PROP_SEND(DPT_Int, "integer");
dvander@1847
  1566
			break;
dvander@1847
  1567
		}
dvander@1847
  1568
	default:
dvander@1847
  1569
		{
dvander@1847
  1570
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1571
		}
dvander@1847
  1572
	}
dvander@1847
  1573
dvander@1847
  1574
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
skamonkey@3709
  1575
	CBaseEntity *pHandleEntity = g_HL2.ReferenceToEntity(hndl.GetEntryIndex());
dvander@1847
  1576
skamonkey@3709
  1577
	if (!pHandleEntity || hndl != reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
skamonkey@3708
  1578
		return -1;
skamonkey@3708
  1579
skamonkey@3709
  1580
	return g_HL2.EntityToBCompatRef(pHandleEntity);
dvander@1847
  1581
}
dvander@1847
  1582
dvander@1847
  1583
static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1584
{
dvander@1847
  1585
	CBaseEntity *pEntity;
dvander@1847
  1586
	char *prop;
dvander@1847
  1587
	int offset;
skamonkey@3293
  1588
	int bit_count;
dvander@1847
  1589
	edict_t *pEdict;
dvander@1847
  1590
skamonkey@3293
  1591
	int element = 0;
skamonkey@3293
  1592
	if (params[0] >= 5)
skamonkey@3293
  1593
 	{
skamonkey@3293
  1594
		element = params[5];
skamonkey@3293
  1595
 	}
skamonkey@3293
  1596
fyrenmoo@2879
  1597
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1598
	{
pred@2746
  1599
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1600
	}
dvander@1847
  1601
dvander@1847
  1602
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1603
dvander@1847
  1604
	switch (params[2])
dvander@1847
  1605
	{
dvander@1847
  1606
	case Prop_Data:
dvander@1847
  1607
		{
dvander@1847
  1608
			typedescription_t *td;
dvander@1847
  1609
dvander@1847
  1610
			FIND_PROP_DATA(td);
dvander@1847
  1611
dvander@1847
  1612
			if (td->fieldType != FIELD_EHANDLE)
dvander@1847
  1613
			{
dvander@1847
  1614
				return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)", 
dvander@1847
  1615
					prop,
dvander@1847
  1616
					td->fieldType,
dvander@1847
  1617
					FIELD_EHANDLE);
dvander@1847
  1618
			}
dvander@1847
  1619
skamonkey@3293
  1620
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1621
faluco@694
  1622
			break;
faluco@694
  1623
		}
faluco@694
  1624
	case Prop_Send:
faluco@694
  1625
		{
skamonkey@3293
  1626
			FIND_PROP_SEND(DPT_Int, "integer");
dvander@1847
  1627
			break;
dvander@1847
  1628
		}
dvander@1847
  1629
	default:
dvander@1847
  1630
		{
dvander@1847
  1631
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1632
		}
dvander@1847
  1633
	}
dvander@1847
  1634
dvander@1847
  1635
	CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
dvander@1847
  1636
dvander@1847
  1637
	if (params[4] == -1)
dvander@1847
  1638
	{
dvander@1847
  1639
		hndl.Set(NULL);
dvander@1847
  1640
	}
dvander@1847
  1641
	else
dvander@1847
  1642
	{
fyrenmoo@2879
  1643
		CBaseEntity *pOther = GetEntity(params[4]);
dvander@1847
  1644
pred@2746
  1645
		if (!pOther)
dvander@1847
  1646
		{
pred@2746
  1647
			return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[4]), params[4]);
dvander@1847
  1648
		}
dvander@1847
  1649
pred@2746
  1650
		IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
pred@2746
  1651
		hndl.Set(pHandleEnt);
dvander@1847
  1652
	}
dvander@1847
  1653
pred@2746
  1654
	if (params[2] == Prop_Send && (pEdict != NULL))
dvander@1847
  1655
	{
dvander@1847
  1656
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@1847
  1657
	}
dvander@1847
  1658
dvander@1847
  1659
	return 1;
dvander@1847
  1660
}
dvander@1847
  1661
dvander@1847
  1662
static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1663
{
dvander@1847
  1664
	CBaseEntity *pEntity;
dvander@1847
  1665
	char *prop;
dvander@1847
  1666
	int offset;
skamonkey@3293
  1667
	int bit_count;
dvander@1847
  1668
	edict_t *pEdict;
skamonkey@3293
  1669
skamonkey@3293
  1670
	int element = 0;
skamonkey@3293
  1671
	if (params[0] >= 5)
skamonkey@3293
  1672
 	{
skamonkey@3293
  1673
		element = params[5];
skamonkey@3293
  1674
 	}
dvander@1847
  1675
	
fyrenmoo@2879
  1676
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1677
	{
pred@2746
  1678
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1679
	}
dvander@1847
  1680
dvander@1847
  1681
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1682
dvander@1847
  1683
	switch (params[2])
dvander@1847
  1684
	{
dvander@1847
  1685
	case Prop_Data:
dvander@1847
  1686
		{
dvander@1847
  1687
			typedescription_t *td;
dvander@1847
  1688
			
dvander@1847
  1689
			FIND_PROP_DATA(td);
dvander@1847
  1690
dvander@1847
  1691
			if (td->fieldType != FIELD_VECTOR
dvander@1847
  1692
				&& td->fieldType != FIELD_POSITION_VECTOR)
dvander@1847
  1693
			{
dvander@1847
  1694
				return pContext->ThrowNativeError("Data field %s is not a vector (%d != [%d,%d])", 
dvander@1847
  1695
					prop,
dvander@1847
  1696
					td->fieldType,
dvander@1847
  1697
					FIELD_VECTOR,
dvander@1847
  1698
					FIELD_POSITION_VECTOR);
dvander@1847
  1699
			}
dvander@1847
  1700
skamonkey@3293
  1701
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1702
dvander@1847
  1703
			break;
dvander@1847
  1704
		}
dvander@1847
  1705
	case Prop_Send:
dvander@1847
  1706
		{
skamonkey@3293
  1707
			FIND_PROP_SEND(DPT_Vector, "vector");
dvander@1847
  1708
			break;
dvander@1847
  1709
		}
dvander@1847
  1710
	default:
dvander@1847
  1711
		{
dvander@1847
  1712
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1713
		}
dvander@1847
  1714
	}
dvander@1847
  1715
dvander@1847
  1716
	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
dvander@1847
  1717
dvander@1847
  1718
	cell_t *vec;
dvander@1847
  1719
	pContext->LocalToPhysAddr(params[4], &vec);
dvander@1847
  1720
dvander@1847
  1721
	vec[0] = sp_ftoc(v->x);
dvander@1847
  1722
	vec[1] = sp_ftoc(v->y);
dvander@1847
  1723
	vec[2] = sp_ftoc(v->z);
dvander@1847
  1724
dvander@1847
  1725
	return 1;
dvander@1847
  1726
}
dvander@1847
  1727
dvander@1847
  1728
static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1729
{
dvander@1847
  1730
	CBaseEntity *pEntity;
dvander@1847
  1731
	char *prop;
dvander@1847
  1732
	int offset;
skamonkey@3293
  1733
	int bit_count;
dvander@1847
  1734
	edict_t *pEdict;
skamonkey@3293
  1735
skamonkey@3293
  1736
	int element = 0;
skamonkey@3293
  1737
	if (params[0] >= 5)
skamonkey@3293
  1738
 	{
skamonkey@3293
  1739
		element = params[5];
skamonkey@3293
  1740
 	}
dvander@1847
  1741
	
fyrenmoo@2879
  1742
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1743
	{
pred@2746
  1744
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1745
	}
dvander@1847
  1746
dvander@1847
  1747
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1748
dvander@1847
  1749
	switch (params[2])
dvander@1847
  1750
	{
dvander@1847
  1751
	case Prop_Data:
dvander@1847
  1752
		{
dvander@1847
  1753
			typedescription_t *td;
dvander@1847
  1754
			
dvander@1847
  1755
			FIND_PROP_DATA(td);
dvander@1847
  1756
dvander@1847
  1757
			if (td->fieldType != FIELD_VECTOR
dvander@1847
  1758
				&& td->fieldType != FIELD_POSITION_VECTOR)
faluco@694
  1759
			{
dvander@1847
  1760
				return pContext->ThrowNativeError("Data field %s is not a vector (%d != [%d,%d])", 
dvander@1847
  1761
					prop,
dvander@1847
  1762
					td->fieldType,
dvander@1847
  1763
					FIELD_VECTOR,
dvander@1847
  1764
					FIELD_POSITION_VECTOR);
dvander@1847
  1765
			}
dvander@1847
  1766
skamonkey@3293
  1767
			CHECK_SET_PROP_DATA_OFFSET();
skamonkey@3293
  1768
dvander@1847
  1769
			break;
dvander@1847
  1770
		}
dvander@1847
  1771
	case Prop_Send:
dvander@1847
  1772
		{
skamonkey@3293
  1773
			FIND_PROP_SEND(DPT_Vector, "vector");			
dvander@1847
  1774
			break;
dvander@1847
  1775
		}
dvander@1847
  1776
	default:
dvander@1847
  1777
		{
dvander@1847
  1778
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
dvander@1847
  1779
		}
dvander@1847
  1780
	}
dvander@1847
  1781
dvander@1847
  1782
	Vector *v = (Vector *)((uint8_t *)pEntity + offset);
dvander@1847
  1783
dvander@1847
  1784
	cell_t *vec;
dvander@1847
  1785
	pContext->LocalToPhysAddr(params[4], &vec);
dvander@1847
  1786
dvander@1847
  1787
	v->x = sp_ctof(vec[0]);
dvander@1847
  1788
	v->y = sp_ctof(vec[1]);
dvander@1847
  1789
	v->z = sp_ctof(vec[2]);
dvander@1847
  1790
pred@2746
  1791
	if (params[2] == Prop_Send && (pEdict != NULL))
dvander@1847
  1792
	{
dvander@1847
  1793
		g_HL2.SetEdictStateChanged(pEdict, offset);
dvander@1847
  1794
	}
dvander@1847
  1795
dvander@1847
  1796
	return 1;
dvander@1847
  1797
}
dvander@1847
  1798
dvander@1847
  1799
static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
dvander@1847
  1800
{
dvander@1847
  1801
	CBaseEntity *pEntity;
dvander@1847
  1802
	char *prop;
dvander@1847
  1803
	int offset;
dvander@1847
  1804
	edict_t *pEdict;
dvander@1884
  1805
	bool bIsStringIndex;
skamonkey@3293
  1806
skamonkey@3293
  1807
	int element = 0;
skamonkey@3293
  1808
	if (params[0] >= 6)
skamonkey@3293
  1809
 	{
skamonkey@3293
  1810
		element = params[6];
skamonkey@3293
  1811
 	}
dvander@1847
  1812
	
fyrenmoo@2879
  1813
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
dvander@1847
  1814
	{
pred@2746
  1815
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
dvander@1847
  1816
	}
dvander@1847
  1817
dvander@1847
  1818
	pContext->LocalToString(params[3], &prop);
dvander@1847
  1819
dvander@1884
  1820
	bIsStringIndex = false;
dvander@1884
  1821
dvander@1847
  1822
	switch (params[2])
dvander@1847
  1823
	{
dvander@1847
  1824
	case Prop_Data:
dvander@1847
  1825
		{
dvander@1847
  1826
			typedescription_t *td;
dvander@1847
  1827
			
dvander@1847
  1828
			FIND_PROP_DATA(td);
dvander@1847
  1829
dvander@1884
  1830
			if (td->fieldType != FIELD_CHARACTER
dvander@1900
  1831
				&& td->fieldType != FIELD_STRING
dvander@1900
  1832
				&& td->fieldType != FIELD_MODELNAME 
dvander@1900
  1833
				&& td->fieldType != FIELD_SOUNDNAME)
faluco@694
  1834
			{
dvander@1847
  1835
				return pContext->ThrowNativeError("Data field %s is not a string (%d != %d)", 
dvander@1847
  1836
					prop,
dvander@1847
  1837
					td->fieldType,
dvander@1847
  1838
					FIELD_CHARACTER);
faluco@694
  1839
			}
dvander@1847
  1840
dvander@1900
  1841
			bIsStringIndex = (td->fieldType != FIELD_CHARACTER);
dvander@1884
  1842
skamonkey@3417
  1843
			if (bIsStringIndex && (element < 0 || element >= td->fieldSize))
skamonkey@3293
  1844
			{
skamonkey@3293
  1845
				return pContext->ThrowNativeError("Element %d is out of bounds (Prop %s has %d elements).",
skamonkey@3293
  1846
					element,
skamonkey@3293
  1847
					prop,
skamonkey@3293
  1848
					td->fieldSize);
skamonkey@3293
  1849
			}
skamonkey@3417
  1850
			else if (element != 0)
skamonkey@3293
  1851
			{
skamonkey@3293
  1852
				return pContext->ThrowNativeError("Prop %s is not an array. Element %d is invalid.",
skamonkey@3293
  1853
					prop,
skamonkey@3293
  1854
					element);
skamonkey@3293
  1855
			}
skamonkey@3293
  1856
kyle@3997
  1857
			offset = info.actual_offset;
skamonkey@3293
  1858
			if (bIsStringIndex)
skamonkey@3293
  1859
			{
skamonkey@3293
  1860
				offset += (element * (td->fieldSizeInBytes / td->fieldSize));
skamonkey@3293
  1861
			}
dvander@1847
  1862
			break;
dvander@1847
  1863
		}
dvander@1847
  1864
	case Prop_Send:
dvander@1847
  1865
		{
dvander@1847
  1866
			sm_sendprop_info_t info;
skamonkey@3293
  1867
			
skamonkey@3293
  1868
			IServerUnknown *pUnk = (IServerUnknown *)pEntity;
skamonkey@3293
  1869
			IServerNetworkable *pNet = pUnk->GetNetworkable();
skamonkey@3293
  1870
			if (!pNet)
skamonkey@3293
  1871
			{
skamonkey@3293
  1872
				return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]);
skamonkey@3293
  1873
			}
skamonkey@3293
  1874
			if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
skamonkey@3293
  1875
			{
kyle@3638
  1876
				const char *class_name = g_HL2.GetEntityClassname(pEntity);
skamonkey@3293
  1877
				return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
skamonkey@3293
  1878
					prop,
skamonkey@3293
  1879
					params[1],
kyle@3638
  1880
					((class_name) ? class_name : ""));
skamonkey@3293
  1881
			}
dvander@1847
  1882
skamonkey@3293
  1883
			offset = info.actual_offset;
dvander@1847
  1884
dvander@1847
  1885
			if (info.prop->GetType() != DPT_String)
dvander@1847
  1886
			{
dvander@1847
  1887
				return pContext->ThrowNativeError("SendProp %s is not a string (%d != %d)",
dvander@1847
  1888
					prop,
dvander@1847
  1889
					info.prop->GetType(),
dvander@1847
  1890
					DPT_String);
dvander@1847
  1891
			}
skamonkey@3417
  1892
			else if (element != 0)
skamonkey@3293
  1893
			{
skamonkey@3293
  1894
				return pContext->ThrowNativeError("SendProp %s is not an array. Element %d is invalid.",
skamonkey@3293
  1895
					prop,
skamonkey@3293
  1896
					element);
skamonkey@3293
  1897
 			}
skamonkey@3293
  1898
			
faluco@694
  1899
			break;
faluco@694
  1900
		}
faluco@694
  1901
	default:
faluco@694
  1902
		{
faluco@694
  1903
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
faluco@694
  1904
		}
faluco@694
  1905
	}
faluco@694
  1906
faluco@694
  1907
	size_t len;
dvander@1884
  1908
	const char *src; 
dvander@1884
  1909
	
dvander@1884
  1910
	if (!bIsStringIndex)
dvander@1884
  1911
	{
dvander@1884
  1912
		src = (char *)((uint8_t *)pEntity + offset);
dvander@1884
  1913
	}
dvander@1884
  1914
	else
dvander@1884
  1915
	{
dvander@1884
  1916
		string_t idx;
dvander@1884
  1917
dvander@1884
  1918
		idx = *(string_t *)((uint8_t *)pEntity + offset);
dvander@1884
  1919
		src = (idx == NULL_STRING) ? "" : STRING(idx);
dvander@1884
  1920
	}
dvander@1884
  1921
faluco@694
  1922
	pContext->StringToLocalUTF8(params[4], params[5], src, &len);
faluco@694
  1923
faluco@694
  1924
	return len;
faluco@694
  1925
}
faluco@694
  1926
faluco@694
  1927
static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
faluco@694
  1928
{
faluco@694
  1929
	CBaseEntity *pEntity;
faluco@694
  1930
	char *prop;
faluco@694
  1931
	int offset;
faluco@694
  1932
	int maxlen;
fyrenmoo@2879
  1933
	edict_t *pEdict;
faluco@694
  1934
fyrenmoo@2879
  1935
	if (!IndexToAThings(params[1], &pEntity, &pEdict))
faluco@694
  1936
	{
pred@2746
  1937
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
faluco@694
  1938
	}
faluco@694
  1939
faluco@694
  1940
	switch (params[2])
faluco@694
  1941
	{
faluco@694
  1942
	case Prop_Data:
faluco@694
  1943
		{
faluco@694
  1944
			datamap_t *pMap;
faluco@694
  1945
			if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
faluco@694
  1946
			{
faluco@694
  1947
				return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
faluco@694
  1948
			}
faluco@694
  1949
			pContext->LocalToString(params[3], &prop);
kyle@3997
  1950
			sm_datatable_info_t info;
kyle@3997
  1951
			if (!g_HL2.FindDataMapInfo(pMap, prop, &info))
faluco@694
  1952
			{
kyle@3997
  1953
				return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
faluco@694
  1954
			}
kyle@3997
  1955
			
kyle@3997
  1956
			typedescription_t *td = info.prop;
faluco@694
  1957
			if (td->fieldType != FIELD_CHARACTER)
faluco@694
  1958
			{
faluco@694
  1959
				return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
faluco@694
  1960
			}
kyle@3997
  1961
			offset = info.actual_offset;
faluco@694
  1962
			maxlen = td->fieldSize;
faluco@694
  1963
			break;
faluco@694
  1964
		}
faluco@694
  1965
	case Prop_Send:
faluco@694
  1966
		{
faluco@694
  1967
			char *prop;
pred@2746
  1968
			IServerUnknown *pUnk = (IServerUnknown *)pEntity;
pred@2746
  1969
			IServerNetworkable *pNet = pUnk->GetNetworkable();
faluco@694
  1970
			if (!pNet)
faluco@694
  1971
			{
faluco@694
  1972
				return pContext->ThrowNativeError("The edict is not networkable");
faluco@694
  1973
			}
faluco@694
  1974
			pContext->LocalToString(params[3], &prop);
faluco@694
  1975
			SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
faluco@694
  1976
			if (!pSend)
faluco@694
  1977
			{
faluco@694
  1978
				return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
faluco@694
  1979
			}
faluco@694
  1980
			if (pSend->GetType() != DPT_String)
faluco@694
  1981
			{
faluco@694
  1982
				return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
faluco@694
  1983
			}
faluco@694
  1984
			offset = pSend->GetOffset();
faluco@694
  1985
			maxlen = DT_MAX_STRING_BUFFERSIZE;
faluco@694
  1986
			break;
faluco@694
  1987
		}
faluco@694
  1988
	default:
faluco@694
  1989
		{
faluco@694
  1990
			return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
faluco@694
  1991
		}
faluco@694
  1992
	}
faluco@694
  1993
faluco@694
  1994
	char *src;
faluco@694
  1995
	char *dest = (char *)((uint8_t *)pEntity + offset);
faluco@694
  1996
faluco@694
  1997
	pContext->LocalToString(params[4], &src);
faluco@694
  1998
	size_t len = strncopy(dest, src, maxlen);
faluco@694
  1999
pred@2746
  2000
	if (params[2] == Prop_Send && (pEdict != NULL))
faluco@694
  2001
	{
faluco@694
  2002
		g_HL2.SetEdictStateChanged(pEdict, offset);
faluco@694
  2003
	}
faluco@694
  2004
faluco@694
  2005
	return len;
faluco@694
  2006
}
faluco@694
  2007
skamonkey@3220
  2008
static int32_t SDKEntFlagToSMEntFlag(int flag)
skamonkey@3220
  2009
{
skamonkey@3220
  2010
	switch (flag)
skamonkey@3220
  2011
	{
skamonkey@3220
  2012
		case FL_ONGROUND:
skamonkey@3220
  2013
			return ENTFLAG_ONGROUND;
skamonkey@3220
  2014
		case FL_DUCKING:
skamonkey@3220
  2015
			return ENTFLAG_DUCKING;
skamonkey@3220
  2016
		case FL_WATERJUMP:
skamonkey@3220
  2017
			return ENTFLAG_WATERJUMP;
skamonkey@3220
  2018
		case FL_ONTRAIN:
skamonkey@3220
  2019
			return ENTFLAG_ONTRAIN;
skamonkey@3220
  2020
		case FL_INRAIN:
skamonkey@3220
  2021
			return ENTFLAG_INRAIN;
skamonkey@3220
  2022
		case FL_FROZEN:
skamonkey@3220
  2023
			return ENTFLAG_FROZEN;
skamonkey@3220
  2024
		case FL_ATCONTROLS:
skamonkey@3220
  2025
			return ENTFLAG_ATCONTROLS;
skamonkey@3220
  2026
		case FL_CLIENT:
skamonkey@3220
  2027
			return ENTFLAG_CLIENT;
skamonkey@3220
  2028
		case FL_FAKECLIENT:
skamonkey@3220
  2029
			return ENTFLAG_FAKECLIENT;
skamonkey@3220
  2030
		case FL_INWATER:
skamonkey@3220
  2031
			return ENTFLAG_INWATER;
skamonkey@3220
  2032
		case FL_FLY:
skamonkey@3220
  2033
			return ENTFLAG_FLY;
skamonkey@3220
  2034
		case FL_SWIM:
skamonkey@3220
  2035
			return ENTFLAG_SWIM;
skamonkey@3220
  2036
		case FL_CONVEYOR:
skamonkey@3220
  2037
			return ENTFLAG_CONVEYOR;
skamonkey@3220
  2038
		case FL_NPC:
skamonkey@3220
  2039
			return ENTFLAG_NPC;
skamonkey@3220
  2040
		case FL_GODMODE:
skamonkey@3220
  2041
			return ENTFLAG_GODMODE;
skamonkey@3220
  2042
		case FL_NOTARGET:
skamonkey@3220
  2043
			return ENTFLAG_NOTARGET;
skamonkey@3220
  2044
		case FL_AIMTARGET:
skamonkey@3220
  2045
			return ENTFLAG_AIMTARGET;
skamonkey@3220
  2046
		case FL_PARTIALGROUND:
skamonkey@3220
  2047
			return ENTFLAG_PARTIALGROUND;
skamonkey@3220
  2048
		case FL_STATICPROP:
skamonkey@3220
  2049
			return ENTFLAG_STATICPROP;
skamonkey@3220
  2050
		case FL_GRAPHED:
skamonkey@3220
  2051
			return ENTFLAG_GRAPHED;
skamonkey@3220
  2052
		case FL_GRENADE:
skamonkey@3220
  2053
			return ENTFLAG_GRENADE;
skamonkey@3220
  2054
		case FL_STEPMOVEMENT:
skamonkey@3220
  2055
			return ENTFLAG_STEPMOVEMENT;
skamonkey@3220
  2056
		case FL_DONTTOUCH:
skamonkey@3220
  2057
			return ENTFLAG_DONTTOUCH;
skamonkey@3220
  2058
		case FL_BASEVELOCITY:
skamonkey@3220
  2059
			return ENTFLAG_BASEVELOCITY;
skamonkey@3220
  2060
		case FL_WORLDBRUSH:
skamonkey@3220
  2061
			return ENTFLAG_WORLDBRUSH;
skamonkey@3220
  2062
		case FL_OBJECT:
skamonkey@3220
  2063
			return ENTFLAG_OBJECT;
skamonkey@3220
  2064
		case FL_KILLME:
skamonkey@3220
  2065
			return ENTFLAG_KILLME;
skamonkey@3220
  2066
		case FL_ONFIRE:
skamonkey@3220
  2067
			return ENTFLAG_ONFIRE;
skamonkey@3220
  2068
		case FL_DISSOLVING:
skamonkey@3220
  2069
			return ENTFLAG_DISSOLVING;
skamonkey@3220
  2070
		case FL_TRANSRAGDOLL:
skamonkey@3220
  2071
			return ENTFLAG_TRANSRAGDOLL;
skamonkey@3220
  2072
		case FL_UNBLOCKABLE_BY_PLAYER:
skamonkey@3220
  2073
			return ENTFLAG_UNBLOCKABLE_BY_PLAYER;
skamonkey@3220
  2074
#if SOURCE_ENGINE == SE_ALIENSWARM
skamonkey@3220
  2075
		case FL_FREEZING:
skamonkey@3220
  2076
			return ENTFLAG_FREEZING;
skamonkey@4141
  2077
#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
skamonkey@3220
  2078
		case FL_EP2V_UNKNOWN:
skamonkey@3220
  2079
			return ENTFLAG_EP2V_UNKNOWN1;
skamonkey@3220
  2080
#endif
skamonkey@3220
  2081
		default:
skamonkey@3220
  2082
			return 0;
skamonkey@3220
  2083
	}
skamonkey@3220
  2084
}
skamonkey@3220
  2085
skamonkey@3220
  2086
static int32_t SMEntFlagToSDKEntFlag(int32_t flag)
skamonkey@3220
  2087
{
skamonkey@3220
  2088
	switch (flag)
skamonkey@3220
  2089
	{
skamonkey@3220
  2090
		case ENTFLAG_ONGROUND:
skamonkey@3220
  2091
			return FL_ONGROUND;
skamonkey@3220
  2092
		case ENTFLAG_DUCKING:
skamonkey@3220
  2093
			return FL_DUCKING;
skamonkey@3220
  2094
		case ENTFLAG_WATERJUMP:
skamonkey@3220
  2095
			return FL_WATERJUMP;
skamonkey@3220
  2096
		case ENTFLAG_ONTRAIN:
skamonkey@3220
  2097
			return FL_ONTRAIN;
skamonkey@3220
  2098
		case ENTFLAG_INRAIN:
skamonkey@3220
  2099
			return FL_INRAIN;
skamonkey@3220
  2100
		case ENTFLAG_FROZEN:
skamonkey@3220
  2101
			return FL_FROZEN;
skamonkey@3220
  2102
		case ENTFLAG_ATCONTROLS:
skamonkey@3220
  2103
			return FL_ATCONTROLS;
skamonkey@3220
  2104
		case ENTFLAG_CLIENT:
skamonkey@3220
  2105
			return FL_CLIENT;
skamonkey@3220
  2106
		case ENTFLAG_FAKECLIENT:
skamonkey@3220
  2107
			return FL_FAKECLIENT;
skamonkey@3220
  2108
		case ENTFLAG_INWATER:
skamonkey@3220
  2109
			return FL_INWATER;
skamonkey@3220
  2110
		case ENTFLAG_FLY:
skamonkey@3220
  2111
			return FL_FLY;
skamonkey@3220
  2112
		case ENTFLAG_SWIM:
skamonkey@3220
  2113
			return FL_SWIM;
skamonkey@3220
  2114
		case ENTFLAG_CONVEYOR:
skamonkey@3220
  2115
			return FL_CONVEYOR;
skamonkey@3220
  2116
		case ENTFLAG_NPC:
skamonkey@3220
  2117
			return FL_NPC;
skamonkey@3220
  2118
		case ENTFLAG_GODMODE:
skamonkey@3220
  2119
			return FL_GODMODE;
skamonkey@3220
  2120
		case ENTFLAG_NOTARGET:
skamonkey@3220
  2121
			return FL_NOTARGET;
skamonkey@3220
  2122
		case ENTFLAG_AIMTARGET:
skamonkey@3220
  2123
			return FL_AIMTARGET;
skamonkey@3220
  2124
		case ENTFLAG_PARTIALGROUND:
skamonkey@3220
  2125
			return FL_PARTIALGROUND;
skamonkey@3220
  2126
		case ENTFLAG_STATICPROP:
skamonkey@3220
  2127
			return FL_STATICPROP;
skamonkey@3220
  2128
		case ENTFLAG_GRAPHED:
skamonkey@3220
  2129
			return FL_GRAPHED;
skamonkey@3220
  2130
		case ENTFLAG_GRENADE:
skamonkey@3220
  2131
			return FL_GRENADE;
skamonkey@3220
  2132
		case ENTFLAG_STEPMOVEMENT:
skamonkey@3220
  2133
			return FL_STEPMOVEMENT;
skamonkey@3220
  2134
		case ENTFLAG_DONTTOUCH:
skamonkey@3220
  2135
			return FL_DONTTOUCH;
skamonkey@3220
  2136
		case ENTFLAG_BASEVELOCITY:
skamonkey@3220
  2137
			return FL_BASEVELOCITY;
skamonkey@3220
  2138
		case ENTFLAG_WORLDBRUSH:
skamonkey@3220
  2139
			return FL_WORLDBRUSH;
skamonkey@3220
  2140
		case ENTFLAG_OBJECT:
skamonkey@3220
  2141
			return FL_OBJECT;
skamonkey@3220
  2142
		case ENTFLAG_KILLME:
skamonkey@3220
  2143
			return FL_KILLME;
skamonkey@3220
  2144
		case ENTFLAG_ONFIRE:
skamonkey@3220
  2145
			return FL_ONFIRE;
skamonkey@3220
  2146
		case ENTFLAG_DISSOLVING:
skamonkey@3220
  2147
			return FL_DISSOLVING;
skamonkey@3220
  2148
		case ENTFLAG_TRANSRAGDOLL:
skamonkey@3220
  2149
			return FL_TRANSRAGDOLL;
skamonkey@3220
  2150
		case ENTFLAG_UNBLOCKABLE_BY_PLAYER:
skamonkey@3220
  2151
			return FL_UNBLOCKABLE_BY_PLAYER;
skamonkey@3220
  2152
#if SOURCE_ENGINE == SE_ALIENSWARM
skamonkey@3220
  2153
		case ENTFLAG_FREEZING:
skamonkey@3220
  2154
			return FL_FREEZING;
skamonkey@4141
  2155
#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
skamonkey@3220
  2156
		case ENTFLAG_EP2V_UNKNOWN1:
skamonkey@3220
  2157
			return FL_EP2V_UNKNOWN;
skamonkey@3220
  2158
#endif
skamonkey@3220
  2159
		default:
skamonkey@3220
  2160
			return 0;
skamonkey@3220
  2161
	}
skamonkey@3220
  2162
}
skamonkey@3220
  2163
skamonkey@3220
  2164
static cell_t GetEntityFlags(IPluginContext *pContext, const cell_t *params)
skamonkey@3220
  2165
{
skamonkey@3220
  2166
	CBaseEntity *pEntity = g_HL2.ReferenceToEntity(params[1]);
skamonkey@3220
  2167
	if (!pEntity)
skamonkey@3220
  2168
	{
skamonkey@3220
  2169
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
skamonkey@3220
  2170
	}
skamonkey@3220
  2171
skamonkey@3220
  2172
	const char *prop = g_pGameConf->GetKeyValue("m_fFlags");
skamonkey@3220
  2173
	if (!prop)
skamonkey@3220
  2174
	{
skamonkey@3220
  2175
		return pContext->ThrowNativeError("Could not find m_fFlags prop in gamedata");
skamonkey@3220
  2176
	}
skamonkey@3220
  2177
skamonkey@3220
  2178
	datamap_t *pMap;
skamonkey@3220
  2179
skamonkey@3220
  2180
	if ((pMap = CBaseEntity_GetDataDescMap(pEntity)) == NULL)
skamonkey@3220
  2181
	{
skamonkey@3220
  2182
		return pContext->ThrowNativeError("Could not retrieve datamap");
skamonkey@3220
  2183
	}
kyle@3997
  2184
	
kyle@3997
  2185
	sm_datatable_info_t info;
kyle@3997
  2186
	if (!g_HL2.FindDataMapInfo(pMap, prop, &info))
skamonkey@3220
  2187
	{
skamonkey@3220
  2188
		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d)",
skamonkey@3220
  2189
			prop,
skamonkey@3220
  2190
			params[1]);
skamonkey@3220
  2191
	}
skamonkey@3220
  2192
kyle@3997
  2193
	int offset = info.actual_offset;
skamonkey@3220
  2194
skamonkey@3220
  2195
	int32_t actual_flags = *(int32_t *)((uint8_t *)pEntity + offset);
skamonkey@3220
  2196
	int32_t sm_flags = 0;
skamonkey@3220
  2197
skamonkey@3220
  2198
	for (int32_t i = 0; i < 32; i++)
skamonkey@3220
  2199
	{
skamonkey@3220
  2200
		int32_t flag = (1<<i);
skamonkey@3220
  2201
		if ((actual_flags & flag) == flag)
skamonkey@3220
  2202
		{
skamonkey@3220
  2203
			sm_flags |= SDKEntFlagToSMEntFlag(flag);
skamonkey@3220
  2204
		}
skamonkey@3220
  2205
	}
skamonkey@3220
  2206
skamonkey@3220
  2207
	return sm_flags;
skamonkey@3220
  2208
}
skamonkey@3220
  2209
skamonkey@3220
  2210
static cell_t SetEntityFlags(IPluginContext *pContext, const cell_t *params)
skamonkey@3220
  2211
{
skamonkey@3220
  2212
	CBaseEntity *pEntity = g_HL2.ReferenceToEntity(params[1]);
skamonkey@3220
  2213
	if (!pEntity)
skamonkey@3220
  2214
	{
skamonkey@3220
  2215
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
skamonkey@3220
  2216
	}
skamonkey@3220
  2217
skamonkey@3220
  2218
	const char *prop = g_pGameConf->GetKeyValue("m_fFlags");
skamonkey@3220
  2219
	if (!prop)
skamonkey@3220
  2220
	{
skamonkey@3220
  2221
		return pContext->ThrowNativeError("Could not find m_fFlags prop in gamedata");
skamonkey@3220
  2222
	}
skamonkey@3220
  2223
skamonkey@3220
  2224
	datamap_t *pMap;
skamonkey@3220
  2225
skamonkey@3220
  2226
	if ((pMap = CBaseEntity_GetDataDescMap(pEntity)) == NULL)
skamonkey@3220
  2227
	{
skamonkey@3220
  2228
		return pContext->ThrowNativeError("Could not retrieve datamap");
skamonkey@3220
  2229
	}
kyle@3997
  2230
	
kyle@3997
  2231
	sm_datatable_info_t info;
kyle@3997
  2232
	if (!g_HL2.FindDataMapInfo(pMap, prop, &info))
skamonkey@3220
  2233
	{
skamonkey@3220
  2234
		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d)",
skamonkey@3220
  2235
			prop,
skamonkey@3220
  2236
			params[1]);
skamonkey@3220
  2237
	}
skamonkey@3220
  2238
kyle@3997
  2239
	int offset = info.actual_offset;
skamonkey@3220
  2240
skamonkey@3220
  2241
	int32_t sm_flags = params[2];
skamonkey@3220
  2242
	int32_t actual_flags = 0;
skamonkey@3220
  2243
skamonkey@3220
  2244
	for (int32_t i = 0; i < 32; i++)
skamonkey@3220
  2245
	{
skamonkey@3220
  2246
		int32_t flag = (1<<i);
skamonkey@3220
  2247
		if ((sm_flags & flag) == flag)
skamonkey@3220
  2248
		{
skamonkey@3220
  2249
			actual_flags |= SMEntFlagToSDKEntFlag(flag);
skamonkey@3220
  2250
		}
skamonkey@3220
  2251
	}
skamonkey@3220
  2252
skamonkey@3220
  2253
	*(int32_t *)((uint8_t *)pEntity + offset) = actual_flags;
skamonkey@3220
  2254
skamonkey@3220
  2255
	return 0;
skamonkey@3220
  2256
}
skamonkey@3220
  2257
prodigysim@3585
  2258
static cell_t GetEntityAddress(IPluginContext *pContext, const cell_t *params)
prodigysim@3585
  2259
{
prodigysim@3585
  2260
	CBaseEntity * pEntity = GetEntity(params[1]);
prodigysim@3585
  2261
	if (!pEntity)
prodigysim@3585
  2262
	{
prodigysim@3585
  2263
		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
prodigysim@3585
  2264
	}
prodigysim@3585
  2265
	return reinterpret_cast<cell_t>(pEntity);
prodigysim@3585
  2266
}
prodigysim@3585
  2267
dvander@555
  2268
REGISTER_NATIVES(entityNatives)
dvander@555
  2269
{
dvander@558
  2270
	{"ChangeEdictState",		ChangeEdictState},
dvander@555
  2271
	{"CreateEdict",				CreateEdict},
dvander@1847
  2272
	{"FindDataMapOffs",			FindDataMapOffs},
dvander@1847
  2273
	{"FindSendPropInfo",		FindSendPropInfo},
dvander@561
  2274
	{"FindSendPropOffs",		FindSendPropOffs},
dvander@556
  2275
	{"GetEdictClassname",		GetEdictClassname},
dvander@555
  2276
	{"GetEdictFlags",			GetEdictFlags},
dvander@557
  2277
	{"GetEntData",				GetEntData},
dvander@1847
  2278
	{"GetEntDataEnt",			GetEntDataEnt},		/** DEPRECATED */
dvander@1847
  2279
	{"GetEntDataEnt2",			GetEntDataEnt2},
dvander@557
  2280
	{"GetEntDataFloat",			GetEntDataFloat},
dvander@1847
  2281
	{"GetEntDataString",		GetEntDataString},
dvander@557
  2282
	{"GetEntDataVector",		GetEntDataVector},
dvander@1847
  2283
	{"GetEntProp",				GetEntProp},
skamonkey@3293
  2284
	{"GetEntPropArraySize",		GetEntPropArraySize},
dvander@1847
  2285
	{"GetEntPropEnt",			GetEntPropEnt},
dvander@1847
  2286
	{"GetEntPropFloat",			GetEntPropFloat},
dvander@1847
  2287
	{"GetEntPropString",		GetEntPropString},
dvander@1847
  2288
	{"GetEntPropVector",		GetEntPropVector},
dvander@603
  2289
	{"GetEntityCount",			GetEntityCount},
skamonkey@3220
  2290
	{"GetEntityFlags",			GetEntityFlags},
dvander@556
  2291
	{"GetEntityNetClass",		GetEntityNetClass},
dvander@555
  2292
	{"GetMaxEntities",			GetMaxEntities},
dvander@555
  2293
	{"IsEntNetworkable",		IsEntNetworkable},
dvander@555
  2294
	{"IsValidEdict",			IsValidEdict},
dvander@555
  2295
	{"IsValidEntity",			IsValidEntity},
dvander@555
  2296
	{"RemoveEdict",				RemoveEdict},
dvander@555
  2297
	{"SetEdictFlags",			SetEdictFlags},
dvander@557
  2298
	{"SetEntData",				SetEntData},
dvander@1847
  2299
	{"SetEntDataEnt",			SetEntDataEnt},		/** DEPRECATED */
dvander@1847
  2300
	{"SetEntDataEnt2",			SetEntDataEnt2},
dvander@557
  2301
	{"SetEntDataFloat",			SetEntDataFloat},
dvander@557
  2302
	{"SetEntDataVector",		SetEntDataVector},
faluco@694
  2303
	{"SetEntDataString",		SetEntDataString},
skamonkey@3220
  2304
	{"SetEntityFlags",			SetEntityFlags},
dvander@1847
  2305
	{"SetEntProp",				SetEntProp},
dvander@1847
  2306
	{"SetEntPropEnt",			SetEntPropEnt},
dvander@1847
  2307
	{"SetEntPropFloat",			SetEntPropFloat},
faluco@694
  2308
	{"SetEntPropString",		SetEntPropString},
dvander@1847
  2309
	{"SetEntPropVector",		SetEntPropVector},
prodigysim@3585
  2310
	{"GetEntityAddress",		GetEntityAddress},
kyle@3997
  2311
	{"FindDataMapInfo",		FindDataMapInfo},
faluco@588
  2312
	{NULL,						NULL}
dvander@555
  2313
};