plugins/include/entity.inc
author David Anderson <dvander@alliedmods.net>
Mon Mar 12 00:06:20 2007 +0000 (2007-03-12)
changeset 599 3a098eff4890
parent 561 49f639ad7d5e
child 610 2fe5613a35e3
permissions -rw-r--r--
used a better error number
dvander@554
     1
/**
dvander@554
     2
 * vim: set ts=4 :
dvander@554
     3
 * ===============================================================
dvander@554
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@554
     5
 * ===============================================================
dvander@554
     6
 *
dvander@554
     7
 *  This file is part of the SourceMod/SourcePawn SDK.  This file may only be used 
dvander@554
     8
 * or modified under the Terms and Conditions of its License Agreement, which is found 
dvander@554
     9
 * in LICENSE.txt.  The Terms and Conditions for making SourceMod extensions/plugins 
dvander@554
    10
 * may change at any time.  To view the latest information, see:
dvander@554
    11
 *   http://www.sourcemod.net/license.php
dvander@554
    12
 *
dvander@554
    13
 * Version: $Id$
dvander@554
    14
 */
dvander@554
    15
 
dvander@554
    16
#if defined _entity_included
dvander@554
    17
 #endinput
dvander@554
    18
#endif
dvander@554
    19
#define _entity_included
dvander@554
    20
dvander@555
    21
dvander@555
    22
/**
dvander@555
    23
 * For more information on these, see the HL2SDK (public/edict.h)
dvander@555
    24
 */
dvander@555
    25
#define FL_EDICT_CHANGED	(1<<0)	/**< Game DLL sets this when the entity state changes
dvander@555
    26
										 Mutually exclusive with FL_EDICT_PARTIAL_CHANGE. */
dvander@555
    27
#define FL_EDICT_FREE		(1<<1)	/**< this edict if free for reuse */
dvander@555
    28
#define FL_EDICT_FULL		(1<<2)	/**< this is a full server entity */
dvander@555
    29
#define FL_EDICT_FULLCHECK	(0<<0)  /**< call ShouldTransmit() each time, this is a fake flag */
dvander@555
    30
#define FL_EDICT_ALWAYS		(1<<3)	/**< always transmit this entity */
dvander@555
    31
#define FL_EDICT_DONTSEND	(1<<4)	/**< don't transmit this entity */
dvander@555
    32
#define FL_EDICT_PVSCHECK	(1<<5)	/**< always transmit entity, but cull against PVS */
dvander@555
    33
#define FL_EDICT_PENDING_DORMANT_CHECK	(1<<6)
dvander@555
    34
#define FL_EDICT_DIRTY_PVS_INFORMATION	(1<<7)
dvander@555
    35
#define FL_FULL_EDICT_CHANGED			(1<<8)
dvander@555
    36
dvander@554
    37
/**
dvander@554
    38
 * Returns the maximum number of entities.
dvander@554
    39
 *
dvander@554
    40
 * @return				Maximum number of entities.
dvander@554
    41
 */
dvander@554
    42
native GetMaxEntities();
dvander@554
    43
dvander@554
    44
/**
dvander@554
    45
 * Returns the number of entities in the server.
dvander@554
    46
 *
dvander@554
    47
 * @return				Number of entities in the server.
dvander@554
    48
 */
dvander@554
    49
native GetEntityCount();
dvander@554
    50
dvander@554
    51
/**
dvander@554
    52
 * Returns whether or not an entity is valid.  Returns false
dvander@554
    53
 * if there is no matching CBaseEntity for this edict index.
dvander@554
    54
 *
dvander@555
    55
 * @param edict			Index of the entity/edict.
dvander@554
    56
 * @return				True if valid, false otherwise.
dvander@554
    57
 */
dvander@554
    58
native bool:IsValidEntity(edict);
dvander@554
    59
dvander@554
    60
/**
dvander@554
    61
 * Returns whether or not an edict index is valid.
dvander@554
    62
 *
dvander@554
    63
 * @param edict			Index of the edict.
dvander@554
    64
 * @return				True if valid, false otherwise.
dvander@554
    65
 */
dvander@554
    66
native bool:IsValidEdict(edict);
dvander@554
    67
dvander@554
    68
/**
dvander@555
    69
 * Returns whether or not an entity is a valid networkable edict.
dvander@555
    70
 *
dvander@555
    71
 * @param edict			Index of the edict.
dvander@555
    72
 * @return				True if networkable, false if invalid or not networkable.
dvander@555
    73
 */
dvander@555
    74
native bool:IsEntNetworkable(edict);
dvander@555
    75
dvander@555
    76
/**
dvander@554
    77
 * Creates a new edict (the basis of a networkable entity)
dvander@554
    78
 *
dvander@555
    79
 * @return				Index of the edict, 0 on failure.
dvander@554
    80
 */
dvander@554
    81
native CreateEdict();
dvander@554
    82
dvander@554
    83
/** 
dvander@554
    84
 * Removes an edict from the world.
dvander@554
    85
 *
dvander@555
    86
 * @param edict			Index of the edict.
dvander@554
    87
 * @noreturn
dvander@555
    88
 * @error				Invalid edict index.
dvander@554
    89
 */
dvander@554
    90
native RemoveEdict(edict);
dvander@555
    91
dvander@555
    92
/**
dvander@555
    93
 * Returns the flags on an edict.  These are not the same as entity flags.
dvander@555
    94
 *
dvander@555
    95
 * @param edict			Index of the entity.
dvander@555
    96
 * @return				Edict flags.
dvander@555
    97
 * @error				Invalid edict index.
dvander@555
    98
 */
dvander@555
    99
native GetEdictFlags(edict);
dvander@555
   100
dvander@555
   101
/**
dvander@555
   102
 * Sets the flags on an edict.  These are not the same as entity flags.
dvander@555
   103
 *
dvander@555
   104
 * @param edict			Index of the entity.
dvander@555
   105
 * @param flags			Flags to set.
dvander@555
   106
 * @noreturn
dvander@555
   107
 * @error				Invalid edict index.
dvander@555
   108
 */
dvander@556
   109
native SetEdictFlags(edict, flags);
dvander@556
   110
dvander@556
   111
/**
dvander@556
   112
 * Retrieves an edict classname.
dvander@556
   113
 *
dvander@556
   114
 * @param edict			Index of the entity.
dvander@556
   115
 * @param clsname		Buffer to store the classname.
dvander@556
   116
 * @param maxlength		Maximum length of the buffer.
dvander@556
   117
 * @return				True on success, false if there is no classname set.
dvander@556
   118
 */
dvander@556
   119
native bool:GetEdictClassname(edict, String:clsname[], maxlength);
dvander@556
   120
dvander@556
   121
/**
dvander@556
   122
 * Retrieves an entity's networkable serverclass name.
dvander@556
   123
 * This is not the same as the classname and is used for networkable state changes.
dvander@556
   124
 *
dvander@556
   125
 * @param edict			Index of the entity.
dvander@556
   126
 * @param clsname		Buffer to store the serverclass name.
dvander@556
   127
 * @param maxlength		Maximum lnegth of the buffer.
dvander@556
   128
 * @return				True on success, false if the edict is not networkable.
dvander@556
   129
 * @error				Invalid edict index.
dvander@556
   130
 */
dvander@556
   131
native bool:GetEntityNetClass(edict, String:clsname[], maxlength);
dvander@557
   132
dvander@557
   133
/**
dvander@557
   134
 * @section Entity offset functions
dvander@557
   135
 *
dvander@557
   136
 * Offsets should be specified in byte distance from the CBaseEntity 
dvander@557
   137
 * structure, not short (double byte) or integer (four byte) multiples.  
dvander@557
   138
 * It is somewhat common practice to use offsets aligned to their final 
dvander@557
   139
 * type, and thus make sure you are not falling to this error in SourceMod.
dvander@557
   140
 * For example, if your "integer-aligned" offset was 119, your byte-aligned
dvander@557
   141
 * offset is 119*4, or 476.
dvander@557
   142
 
dvander@557
   143
 * Specifying incorrect offsets or the incorrect data type for an offset
dvander@557
   144
 * can have fatal consequences.  If you are hardcoding offsets, and the 
dvander@557
   145
 * layout of CBaseEntity does not match, you can easily crash the server.
dvander@557
   146
 *
dvander@557
   147
 * The reasonable bounds for offsets is greater than or equal to 0 and 
dvander@557
   148
 * below 32768.  Offsets out of these bounds will throw an error.  However,
dvander@557
   149
 * this does not represent any real range, it is simply a sanity check for
dvander@557
   150
 * illegal values.  Any range outside of the CBaseEntity structure's private
dvander@557
   151
 * size will cause undefined behaviour or even crash.
dvander@557
   152
 */
dvander@558
   153
 
dvander@558
   154
/**
dvander@558
   155
 * Marks an entity as state changed.  This can be useful if you set an offset 
dvander@558
   156
 * and wish for it to be immediately changed over the network.  By default this 
dvander@558
   157
 * is not done for offset setting functions.  
dvander@558
   158
 *
dvander@558
   159
 * @param edict			Index to the edict.
dvander@558
   160
 * @param offset		Offset to mark as changed.  If 0, 
dvander@558
   161
 *						the entire edict is marked as changed.
dvander@558
   162
 * @noreturn
dvander@558
   163
 * @error				Invalid entity or offset out of bounds.
dvander@558
   164
 */
dvander@558
   165
native ChangeEdictState(edict, offset = 0);
dvander@557
   166
dvander@557
   167
/**
dvander@557
   168
 * Peeks into an entity's object data and retrieves the integer value at 
dvander@557
   169
 * the given offset.
dvander@557
   170
 * 
dvander@557
   171
 * @param entity		Edict index.
dvander@557
   172
 * @param offset		Offset to use.
dvander@557
   173
 * @param size			Number of bytes to read (valid values are 1, 2, or 4).
dvander@557
   174
 * @return				Value at the given memory location.
dvander@557
   175
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   176
 */
dvander@557
   177
native GetEntData(entity, offset, size=4);
dvander@557
   178
dvander@557
   179
/**
dvander@557
   180
 * Peeks into an entity's object data and sets the integer value at 
dvander@557
   181
 * the given offset.
dvander@557
   182
 *
dvander@557
   183
 * @param entity		Edict index.
dvander@557
   184
 * @param offset		Offset to use.
dvander@557
   185
 * @param size			Number of bytes to write (valid values are 1, 2, or 4).
dvander@561
   186
 * @param changeState	If true, change will be sent over the network.
dvander@557
   187
 * @return				Value at the given memory location.
dvander@557
   188
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   189
 * @noreturn
dvander@557
   190
 */
dvander@561
   191
native SetEntData(entity, offset, value, size=4, bool:changeState=false);
dvander@557
   192
dvander@557
   193
/**
dvander@557
   194
 * Peeks into an entity's object data and retrieves the float value at 
dvander@557
   195
 * the given offset.
dvander@557
   196
 * 
dvander@557
   197
 * @param entity		Edict index.
dvander@557
   198
 * @param offset		Offset to use.
dvander@557
   199
 * @return				Value at the given memory location.
dvander@557
   200
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   201
 */
dvander@557
   202
native Float:GetEntDataFloat(entity, offset);
dvander@557
   203
dvander@557
   204
/**
dvander@557
   205
 * Peeks into an entity's object data and sets the integer value at 
dvander@557
   206
 * the given offset.
dvander@557
   207
 *
dvander@557
   208
 * @param entity		Edict index.
dvander@557
   209
 * @param offset		Offset to use.
dvander@561
   210
 * @param changeState	If true, change will be sent over the network.
dvander@557
   211
 * @return				Value at the given memory location.
dvander@557
   212
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   213
 * @noreturn
dvander@557
   214
 */
dvander@561
   215
native SetEntDataFloat(entity, offset, Float:value, bool:changeState=false);
dvander@557
   216
dvander@557
   217
/**
dvander@557
   218
 * Peeks into an entity's object data and retrieves the entity handle
dvander@557
   219
 * info at the given offset.
dvander@557
   220
 * 
dvander@557
   221
 * @param entity		Edict index.
dvander@557
   222
 * @param offset		Offset to use.
dvander@557
   223
 * @return				Entity index at the given location, or 0 if none.
dvander@557
   224
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   225
 */
dvander@557
   226
native GetEntDataEnt(entity, offset);
dvander@557
   227
dvander@557
   228
/**
dvander@557
   229
 * Peeks into an entity's object data and sest the entity handle info
dvander@557
   230
 * at the given offset.
dvander@557
   231
 * 
dvander@557
   232
 * @param entity		Edict index.
dvander@557
   233
 * @param offset		Offset to use.
dvander@557
   234
 * @param other			Entity index to set, or 0 to clear.
dvander@561
   235
 * @param changeState	If true, change will be sent over the network.
dvander@557
   236
 * @noreturn
dvander@557
   237
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   238
 */
dvander@561
   239
native SetEntDataEnt(entity, offset, other, bool:changeState=false);
dvander@557
   240
dvander@557
   241
/**
dvander@557
   242
 * Peeks into an entity's object data and retrieves the vector at the 
dvander@557
   243
 * given offset.
dvander@557
   244
 * @note Both a Vector and a QAngle are three floats.  This is a 
dvander@557
   245
 * convenience function and will work with both types.
dvander@557
   246
 * 
dvander@557
   247
 * @param entity		Edict index.
dvander@557
   248
 * @param offset		Offset to use.
dvander@557
   249
 * @param vec			Vector buffer to store data in.
dvander@557
   250
 * @noreturn
dvander@557
   251
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   252
 */
dvander@557
   253
native GetEntDataVector(entity, offset, Float:vec[3]);
dvander@557
   254
dvander@557
   255
/**
dvander@557
   256
 * Peeks into an entity's object data and sets the vector at the given 
dvander@557
   257
 * offset.
dvander@557
   258
 * @note Both a Vector and a QAngle are three floats.  This is a 
dvander@557
   259
 * convenience function and will work with both types.
dvander@557
   260
 * 
dvander@557
   261
 * @param entity		Edict index.
dvander@557
   262
 * @param offset		Offset to use.
dvander@557
   263
 * @param vec			Vector to set.
dvander@561
   264
 * @param changeState	If true, change will be sent over the network.
dvander@557
   265
 * @noreturn
dvander@557
   266
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@557
   267
 */
dvander@561
   268
native SetEntDataVector(entity, offset, const Float:vec[3], bool:changeState=false);
dvander@561
   269
dvander@561
   270
/**
dvander@561
   271
 * Given a ServerClass name, finds a networkable send property offset.
dvander@561
   272
 * This information is cached for future calls.
dvander@561
   273
 *
dvander@561
   274
 * @param cls			Classname.
dvander@561
   275
 * @param prop			Property name.
dvander@561
   276
 * @return				An offset, or -1 on failure.
dvander@561
   277
 */
dvander@561
   278
native FindSendPropOffs(const String:cls[], const String:prop[]);
dvander@561
   279
dvander@561
   280
/**
dvander@561
   281
 * Wrapper function for finding a send property for a particular entity.
dvander@561
   282
 *
dvander@561
   283
 * @param ent			Entity index.
dvander@561
   284
 * @param prop			Property name.
dvander@561
   285
 * @return				An offset, or -1 on failure.
dvander@561
   286
 */
dvander@561
   287
stock GetEntSendPropOffs(ent, const String:prop[])
dvander@561
   288
{
dvander@561
   289
	decl String:cls[64];
dvander@561
   290
	
dvander@561
   291
	if (!GetEntityNetClass(ent, cls, sizeof(cls)))
dvander@561
   292
	{
dvander@561
   293
		return -1;
dvander@561
   294
	}
dvander@561
   295
	
dvander@561
   296
	return FindSendPropOffs(cls, prop);
dvander@561
   297
}
dvander@561
   298
dvander@561
   299
/**
dvander@561
   300
 * Gets a network property as an integer; wrapper around GetEntData().
dvander@561
   301
 * 
dvander@561
   302
 * @param entity		Edict index.
dvander@561
   303
 * @param prop			Property to use.
dvander@561
   304
 * @param size			Number of bytes to read (valid values are 1, 2, or 4).
dvander@561
   305
 * @return				Value at the given property offset.
dvander@561
   306
 * @error				Invalid entity or property not found.
dvander@561
   307
 */
dvander@561
   308
stock GetEntProp(entity, const String:prop[], size=4)
dvander@561
   309
{
dvander@561
   310
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   311
	if (offs == -1)
dvander@561
   312
	{
dvander@561
   313
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   314
	}
dvander@561
   315
	return GetEntData(entity, offs, size);
dvander@561
   316
}
dvander@561
   317
dvander@561
   318
/**
dvander@561
   319
 * Sets a network property as an integer; wrapper around GetEntData().
dvander@561
   320
 *
dvander@561
   321
 * @param entity		Edict index.
dvander@561
   322
 * @param prop			Property to use.
dvander@561
   323
 * @param size			Number of bytes to write (valid values are 1, 2, or 4).
dvander@561
   324
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   325
 * @noreturn
dvander@561
   326
 */
dvander@561
   327
stock SetEntProp(entity, const String:prop[], value, size=4)
dvander@561
   328
{
dvander@561
   329
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   330
	if (offs == -1)
dvander@561
   331
	{
dvander@561
   332
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   333
	}
dvander@561
   334
	return SetEntData(entity, offs, value, size, true);
dvander@561
   335
}
dvander@561
   336
dvander@561
   337
/**
dvander@561
   338
 * Gets a network property as a float; wrapper around GetEntDataFloat().
dvander@561
   339
 * 
dvander@561
   340
 * @param entity		Edict index.
dvander@561
   341
 * @param prop			Property to use.
dvander@561
   342
 * @return				Value at the given property offset..
dvander@561
   343
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   344
 */
dvander@561
   345
stock Float:GetEntPropFloat(entity, const String:prop[])
dvander@561
   346
{
dvander@561
   347
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   348
	if (offs == -1)
dvander@561
   349
	{
dvander@561
   350
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   351
	}
dvander@561
   352
	return GetEntDataFloat(entity, offs);
dvander@561
   353
}
dvander@561
   354
dvander@561
   355
/**
dvander@561
   356
 * Sets a network property as a float; wrapper around SetEntDataFloat().
dvander@561
   357
 * 
dvander@561
   358
 * @param entity		Edict index.
dvander@561
   359
 * @param prop			Property to use.
dvander@561
   360
 * @param value			Value to set.
dvander@561
   361
 * @noreturn
dvander@561
   362
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   363
 */
dvander@561
   364
stock SetEntPropFloat(entity, const String:prop[], Float:value)
dvander@561
   365
{
dvander@561
   366
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   367
	if (offs == -1)
dvander@561
   368
	{
dvander@561
   369
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   370
	}
dvander@561
   371
	return SetEntDataFloat(entity, offs, value, true);
dvander@561
   372
}
dvander@561
   373
dvander@561
   374
/**
dvander@561
   375
 * Gets a network property as a handle entity; wrapper around GetEntDataEnt().
dvander@561
   376
 * 
dvander@561
   377
 * @param entity		Edict index.
dvander@561
   378
 * @param prop			Property to use.
dvander@561
   379
 * @return				Entity index at the given property, or 0 if none.
dvander@561
   380
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   381
 */
dvander@561
   382
stock GetEntPropEnt(entity, const String:prop[])
dvander@561
   383
{
dvander@561
   384
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   385
	if (offs == -1)
dvander@561
   386
	{
dvander@561
   387
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   388
	}
dvander@561
   389
	return GetEntDataEnt(entity, offs);
dvander@561
   390
}
dvander@561
   391
dvander@561
   392
/**
dvander@561
   393
 * Sets a network property as a handle entity; wrapper around SetEntDataEnt().
dvander@561
   394
 * 
dvander@561
   395
 * @param entity		Edict index.
dvander@561
   396
 * @param prop			Property to use.
dvander@561
   397
 * @param other			Entity index to set, or 0 to unset.
dvander@561
   398
 * @noreturn
dvander@561
   399
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   400
 */
dvander@561
   401
stock SetEntPropEnt(entity, const String:prop[], other)
dvander@561
   402
{
dvander@561
   403
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   404
	if (offs == -1)
dvander@561
   405
	{
dvander@561
   406
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   407
	}
dvander@561
   408
	return SetEntDataEnt(entity, offs, other, true);
dvander@561
   409
}
dvander@561
   410
dvander@561
   411
/**
dvander@561
   412
 * Gets a network property as a vector; wrapper around GetEntDataVector().
dvander@561
   413
 * @note Both a Vector and a QAngle are three floats.  This is a 
dvander@561
   414
 * convenience function and will work with both types.
dvander@561
   415
 * 
dvander@561
   416
 * @param entity		Edict index.
dvander@561
   417
 * @param prop			Property to use.
dvander@561
   418
 * @param vec			Vector buffer to store data in.
dvander@561
   419
 * @noreturn
dvander@561
   420
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   421
 */
dvander@561
   422
stock GetEntPropVector(entity, const String:prop[], Float:vec[3])
dvander@561
   423
{
dvander@561
   424
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   425
	if (offs == -1)
dvander@561
   426
	{
dvander@561
   427
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   428
	}
dvander@561
   429
	return GetEntDataVector(entity, offs, vec);
dvander@561
   430
}
dvander@561
   431
dvander@561
   432
/**
dvander@561
   433
 * Sets a network property as a vector; wrapper around SetEntDataVector().
dvander@561
   434
 * @note Both a Vector and a QAngle are three floats.  This is a 
dvander@561
   435
 * convenience function and will work with both types.
dvander@561
   436
 * 
dvander@561
   437
 * @param entity		Edict index.
dvander@561
   438
 * @param prop			Property to use.
dvander@561
   439
 * @param vec			Vector to set.
dvander@561
   440
 * @noreturn
dvander@561
   441
 * @error				Invalid entity or offset out of reasonable bounds.
dvander@561
   442
 */
dvander@561
   443
stock SetEntPropVector(entity, const String:prop[], const Float:vec[3])
dvander@561
   444
{
dvander@561
   445
	new offs = GetEntSendPropOffs(entity, prop);
dvander@561
   446
	if (offs == -1)
dvander@561
   447
	{
dvander@561
   448
		ThrowError("Property \"%s\" not found for entity %d", prop, entity);
dvander@561
   449
	}
dvander@561
   450
	return SetEntDataVector(entity, offs, vec, true);
dvander@561
   451
}