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