PageRenderTime 60ms CodeModel.GetById 49ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/sourcemod/scripting/include/entity.inc

https://bitbucket.org/kimoto/sushi
Pascal | 716 lines | 683 code | 17 blank | 16 comment | 16 complexity | 8df436c19cb8df0e2f8d092e65cdf5e6 MD5 | raw file
  1/**
  2 * vim: set ts=4 :
  3 * =============================================================================
  4 * SourceMod (C)2004-2011 AlliedModders LLC.  All rights reserved.
  5 * =============================================================================
  6 *
  7 * This file is part of the SourceMod/SourcePawn SDK.
  8 *
  9 * This program is free software; you can redistribute it and/or modify it under
 10 * the terms of the GNU General Public License, version 3.0, as published by the
 11 * Free Software Foundation.
 12 * 
 13 * This program is distributed in the hope that it will be useful, but WITHOUT
 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 15 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 16 * details.
 17 *
 18 * You should have received a copy of the GNU General Public License along with
 19 * this program.  If not, see <http://www.gnu.org/licenses/>.
 20 *
 21 * As a special exception, AlliedModders LLC gives you permission to link the
 22 * code of this program (as well as its derivative works) to "Half-Life 2," the
 23 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
 24 * by the Valve Corporation.  You must obey the GNU General Public License in
 25 * all respects for all other code used.  Additionally, AlliedModders LLC grants
 26 * this exception to all derivative works.  AlliedModders LLC defines further
 27 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
 28 * or <http://www.sourcemod.net/license.php>.
 29 *
 30 * Version: $Id$
 31 */
 32 
 33#if defined _entity_included
 34 #endinput
 35#endif
 36#define _entity_included
 37
 38/**
 39 * Property types for entities.
 40 */
 41enum PropType
 42{
 43	Prop_Send = 0,	/**< This property is networked. */
 44	Prop_Data = 1,	/**< This property is for save game data fields. */
 45};
 46
 47/**
 48 * @section For more information on these, see the HL2SDK (public/edict.h)
 49 */
 50#define FL_EDICT_CHANGED		(1<<0)	/**< Game DLL sets this when the entity state changes
 51										 Mutually exclusive with FL_EDICT_PARTIAL_CHANGE. */
 52#define FL_EDICT_FREE			(1<<1)	/**< this edict if free for reuse */
 53#define FL_EDICT_FULL			(1<<2)	/**< this is a full server entity */
 54#define FL_EDICT_FULLCHECK		(0<<0)  /**< call ShouldTransmit() each time, this is a fake flag */
 55#define FL_EDICT_ALWAYS			(1<<3)	/**< always transmit this entity */
 56#define FL_EDICT_DONTSEND		(1<<4)	/**< don't transmit this entity */
 57#define FL_EDICT_PVSCHECK		(1<<5)	/**< always transmit entity, but cull against PVS */
 58#define FL_EDICT_PENDING_DORMANT_CHECK	(1<<6)
 59#define FL_EDICT_DIRTY_PVS_INFORMATION	(1<<7)
 60#define FL_FULL_EDICT_CHANGED		(1<<8)
 61
 62enum PropFieldType
 63{
 64	PropField_Unsupported,		/**< The type is unsupported. */
 65	PropField_Integer,			/**< Valid for SendProp and Data fields */
 66	PropField_Float,			/**< Valid for SendProp and Data fields */
 67	PropField_Entity,			/**< Valid for Data fields only (SendProp shows as int) */
 68	PropField_Vector,			/**< Valid for SendProp and Data fields */
 69	PropField_String,			/**< Valid for SendProp and Data fields */
 70	PropField_String_T,			/**< Valid for Data fields.  Read only.  
 71									 Note that the size of a string_t is dynamic, and 
 72									 thus FindDataMapOffs() will return the constant size 
 73									 of the string_t container (which is 32 bits right now).
 74								 */
 75};
 76
 77/**
 78 * @endsection
 79 */
 80
 81/**
 82 * Returns the maximum number of entities.
 83 *
 84 * @return				Maximum number of entities.
 85 */
 86native GetMaxEntities();
 87
 88/**
 89 * Returns the number of entities in the server.
 90 *
 91 * @return				Number of entities in the server.
 92 */
 93native GetEntityCount();
 94
 95/**
 96 * Returns whether or not an entity is valid.  Returns false
 97 * if there is no matching CBaseEntity for this edict index.
 98 *
 99 * @param edict			Index of the entity/edict.
100 * @return				True if valid, false otherwise.
101 */
102native bool:IsValidEntity(edict);
103
104/**
105 * Returns whether or not an edict index is valid.
106 *
107 * @param edict			Index of the edict.
108 * @return				True if valid, false otherwise.
109 */
110native bool:IsValidEdict(edict);
111
112/**
113 * Returns whether or not an entity is a valid networkable edict.
114 *
115 * @param edict			Index of the edict.
116 * @return				True if networkable, false if invalid or not networkable.
117 */
118native bool:IsEntNetworkable(edict);
119
120/**
121 * Creates a new edict (the basis of a networkable entity)
122 *
123 * @return				Index of the edict, 0 on failure.
124 */
125native CreateEdict();
126
127/** 
128 * Removes an edict from the world.
129 *
130 * @param edict			Index of the edict.
131 * @noreturn
132 * @error				Invalid edict index.
133 */
134native RemoveEdict(edict);
135
136/**
137 * Returns the flags on an edict.  These are not the same as entity flags.
138 *
139 * @param edict			Index of the entity.
140 * @return				Edict flags.
141 * @error				Invalid edict index.
142 */
143native GetEdictFlags(edict);
144
145/**
146 * Sets the flags on an edict.  These are not the same as entity flags.
147 *
148 * @param edict			Index of the entity.
149 * @param flags			Flags to set.
150 * @noreturn
151 * @error				Invalid edict index.
152 */
153native SetEdictFlags(edict, flags);
154
155/**
156 * Retrieves an edict classname.
157 *
158 * @param edict			Index of the entity.
159 * @param clsname		Buffer to store the classname.
160 * @param maxlength		Maximum length of the buffer.
161 * @return				True on success, false if there is no classname set.
162 */
163native bool:GetEdictClassname(edict, String:clsname[], maxlength);
164
165/**
166 * Retrieves an entity's networkable serverclass name.
167 * This is not the same as the classname and is used for networkable state changes.
168 *
169 * @param edict			Index of the entity.
170 * @param clsname		Buffer to store the serverclass name.
171 * @param maxlength		Maximum lnegth of the buffer.
172 * @return				True on success, false if the edict is not networkable.
173 * @error				Invalid edict index.
174 */
175native bool:GetEntityNetClass(edict, String:clsname[], maxlength);
176
177/**
178 * @section Entity offset functions
179 *
180 * Offsets should be specified in byte distance from the CBaseEntity 
181 * structure, not short (double byte) or integer (four byte) multiples.  
182 * It is somewhat common practice to use offsets aligned to their final 
183 * type, and thus make sure you are not falling to this error in SourceMod.
184 * For example, if your "integer-aligned" offset was 119, your byte-aligned
185 * offset is 119*4, or 476.
186 
187 * Specifying incorrect offsets or the incorrect data type for an offset
188 * can have fatal consequences.  If you are hardcoding offsets, and the 
189 * layout of CBaseEntity does not match, you can easily crash the server.
190 *
191 * The reasonable bounds for offsets is greater than or equal to 0 and 
192 * below 32768.  Offsets out of these bounds will throw an error.  However,
193 * this does not represent any real range, it is simply a sanity check for
194 * illegal values.  Any range outside of the CBaseEntity structure's private
195 * size will cause undefined behaviour or even crash.
196 */
197 
198/**
199 * Marks an entity as state changed.  This can be useful if you set an offset 
200 * and wish for it to be immediately changed over the network.  By default this 
201 * is not done for offset setting functions.  
202 *
203 * @param edict			Index to the edict.
204 * @param offset		Offset to mark as changed.  If 0, 
205 *						the entire edict is marked as changed.
206 * @noreturn
207 * @error				Invalid entity or offset out of bounds.
208 */
209native ChangeEdictState(edict, offset = 0);
210
211/**
212 * Peeks into an entity's object data and retrieves the integer value at 
213 * the given offset.
214 * 
215 * @param entity		Edict index.
216 * @param offset		Offset to use.
217 * @param size			Number of bytes to read (valid values are 1, 2, or 4).
218 * @return				Value at the given memory location.
219 * @error				Invalid entity or offset out of reasonable bounds.
220 */
221native GetEntData(entity, offset, size=4);
222
223/**
224 * Peeks into an entity's object data and sets the integer value at 
225 * the given offset.
226 *
227 * @param entity		Edict index.
228 * @param offset		Offset to use.
229 * @param size			Number of bytes to write (valid values are 1, 2, or 4).
230 * @param changeState	If true, change will be sent over the network.
231 * @return				Value at the given memory location.
232 * @error				Invalid entity or offset out of reasonable bounds.
233 * @noreturn
234 */
235native SetEntData(entity, offset, any:value, size=4, bool:changeState=false);
236
237/**
238 * Peeks into an entity's object data and retrieves the float value at 
239 * the given offset.
240 * 
241 * @param entity		Edict index.
242 * @param offset		Offset to use.
243 * @return				Value at the given memory location.
244 * @error				Invalid entity or offset out of reasonable bounds.
245 */
246native Float:GetEntDataFloat(entity, offset);
247
248/**
249 * Peeks into an entity's object data and sets the float value at 
250 * the given offset.
251 *
252 * @param entity		Edict index.
253 * @param offset		Offset to use.
254 * @param changeState	If true, change will be sent over the network.
255 * @return				Value at the given memory location.
256 * @error				Invalid entity or offset out of reasonable bounds.
257 * @noreturn
258 */
259native SetEntDataFloat(entity, offset, Float:value, bool:changeState=false);
260
261/**
262 * This function is deprecated.  Use GetEntDataEnt2 instead, for 
263 * reasons explained in the notes.
264 *
265 * Note: This function returns 0 on failure, which may be misleading, 
266 * as the number 0 is also used for the world entity index.
267 *
268 * Note: This function makes no attempt to validate the returned 
269 * entity, and in fact, it could be garbage or completely unexpected.
270 * 
271 * @param entity		Edict index.
272 * @param offset		Offset to use.
273 * @return				Entity index at the given location, or 0 if none.
274 * @error				Invalid entity or offset out of reasonable bounds.
275 */
276#pragma deprecated Use GetEntDataEnt2() instead.
277native GetEntDataEnt(entity, offset);
278
279/**
280 * This function is deprecated.   Use SetEntDataEnt2 instead, for 
281 * reasons explained in the notes.
282 *
283 * Note: This function uses 0 as an indicator to unset data, but 
284 * 0 is also the world entity index.  Thus, the a property cannot 
285 * be set to the world entity using this native.
286 * 
287 * @param entity		Edict index.
288 * @param offset		Offset to use.
289 * @param other			Entity index to set, or 0 to clear.
290 * @param changeState	If true, change will be sent over the network.
291 * @noreturn
292 * @error				Invalid entity or offset out of reasonable bounds.
293 */
294#pragma deprecated Use SetEntDataEnt2() instead.
295native SetEntDataEnt(entity, offset, other, bool:changeState=false);
296
297/**
298 * Peeks into an entity's object data and retrieves the entity index 
299 * at the given offset.
300 *
301 * Note: This will only work on offsets that are stored as "entity 
302 * handles" (which usually looks like m_h* in properties).  These 
303 * are not SourceMod Handles, but internal Source structures.
304 * 
305 * @param entity		Edict index.
306 * @param offset		Offset to use.
307 * @return				Entity index at the given location.  If there is no entity, 
308 *						or the stored entity is invalid, then -1 is returned.
309 * @error				Invalid input entity, or offset out of reasonable bounds.
310 */
311native GetEntDataEnt2(entity, offset);
312
313/**
314 * Peeks into an entity's object data and sets the entity index at the 
315 * given offset.
316 *
317 * Note: This will only work on offsets that are stored as "entity 
318 * handles" (which usually looks like m_h* in properties).  These 
319 * are not SourceMod Handles, but internal Source structures.
320 * 
321 * @param entity		Edict index.
322 * @param offset		Offset to use.
323 * @param other			Entity index to set, or -1 to clear.
324 * @param changeState	If true, change will be sent over the network.
325 * @noreturn
326 * @error				Invalid input entity, or offset out of reasonable bounds.
327 */
328native SetEntDataEnt2(entity, offset, other, bool:changeState=false);
329
330/**
331 * Peeks into an entity's object data and retrieves the vector at the 
332 * given offset.
333 * @note Both a Vector and a QAngle are three floats.  This is a 
334 * convenience function and will work with both types.
335 * 
336 * @param entity		Edict index.
337 * @param offset		Offset to use.
338 * @param vec			Vector buffer to store data in.
339 * @noreturn
340 * @error				Invalid entity or offset out of reasonable bounds.
341 */
342native GetEntDataVector(entity, offset, Float:vec[3]);
343
344/**
345 * Peeks into an entity's object data and sets the vector at the given 
346 * offset.
347 * @note Both a Vector and a QAngle are three floats.  This is a 
348 * convenience function and will work with both types.
349 * 
350 * @param entity		Edict index.
351 * @param offset		Offset to use.
352 * @param vec			Vector to set.
353 * @param changeState	If true, change will be sent over the network.
354 * @noreturn
355 * @error				Invalid entity or offset out of reasonable bounds.
356 */
357native SetEntDataVector(entity, offset, const Float:vec[3], bool:changeState=false);
358
359/**
360 * Peeks into an entity's object data and retrieves the string at 
361 * the given offset.
362 * 
363 * @param entity		Edict index.
364 * @param offset		Offset to use.
365 * @param buffer		Destination string buffer.
366 * @param maxlen		Maximum length of output string buffer.
367 * @return			Number of non-null bytes written.
368 * @error				Invalid entity or offset out of reasonable bounds.
369 */
370native GetEntDataString(entity, offset, String:buffer[], maxlen);
371
372/**
373 * Peeks into an entity's object data and sets the string at 
374 * the given offset.
375 * 
376 * @param entity		Edict index.
377 * @param offset		Offset to use.
378 * @param buffer		String to set.
379 * @param maxlen		Maximum length of bytes to write.
380 * @param changeState	If true, change will be sent over the network.
381 * @return			Number of non-null bytes written.
382 * @error				Invalid entity or offset out of reasonable bounds.
383 */
384native SetEntDataString(entity, offset, const String:buffer[], maxlen, bool:changeState=false);
385
386/**
387 * @endsection
388 */
389
390/**
391 * Given a ServerClass name, finds a networkable send property offset.
392 * This information is cached for future calls.
393 *
394 * Note, this function may return offsets that do not work!
395 * If a property is nested beneath a parent object, the resulting offset 
396 * will be invalid for direct use with data functions.  Therefore, you 
397 * should use FindSendPropInfo() instead.  An example of such a property is 
398 * CTFPlayer::DT_LocalPlayer.m_nDisguiseClass on Team Fortress.
399 *
400 * @param cls			Classname.
401 * @param prop			Property name.
402 * @return				An offset, or -1 on failure.
403 */
404native FindSendPropOffs(const String:cls[], const String:prop[]);
405
406/**
407 * Given a ServerClass name, finds a networkable send property offset.
408 * This information is cached for future calls.
409 * 
410 * Note: This function will correctly compute nested offsets, unlike 
411 * FindSendPropOffs().  YOU SHOULD NOT use this function to self-compute 
412 * nested offsets.  For example, it is okay to add indexes for arrays, 
413 * but not to add DT_LocalPlayer to m_nDisguiseClass.
414 *
415 * @param cls			Classname.
416 * @param prop			Property name.
417 * @param type			Optional parameter to store the type.
418 * @param num_bits		Optional parameter to store the number of bits the field 
419 *						uses, if applicable (otherwise 0 is stored).  The number 
420 *						of bits varies for integers and floats, and is always 0 
421 * 						for strings.
422 * @param local_offset	Optional parameter to store the local offset, as 
423 *						FindSendPropOffs() would return.
424 * @return				On success, returns an absolutely computed offset.
425 *						If no offset is available, 0 is returned.
426 *						If the property is not found, -1 is returned.
427 */
428native FindSendPropInfo(const String:cls[], 
429						const String:prop[], 
430						&PropFieldType:type=PropFieldType:0,
431						&num_bits=0,
432						&local_offset=0);
433
434/**
435 * Given an entity, finds a datamap property offset.
436 * This information is cached for future calls.
437 *
438 * @param entity		Entity index.
439 * @param prop			Property name.
440 * @param type			Optional parameter to store the type.
441 * @param num_bits		Optional parameter to store the number of bits the field 
442 *						uses.  The bit count will either be 1 (for boolean) or 
443 *						divisible by 8 (including 0 if unknown).
444 * @return				An offset, or -1 on failure.
445 */
446native FindDataMapOffs(entity, 
447					   const String:prop[],
448					   &PropFieldType:type=PropFieldType:0,
449					   &num_bits=0);
450
451/**
452 * Wrapper function for finding a send property for a particular entity.
453 *
454 * @param ent			Entity index.
455 * @param prop			Property name.
456 * @param actual		Defaults to false for backwards compatibility.
457 *						If true, the newer FindSendPropInfo() function 
458 *						is used instead.
459 * @return				An offset, or -1 on failure.
460 */
461stock GetEntSendPropOffs(ent, const String:prop[], bool:actual=false)
462{
463	decl String:cls[64];
464	
465	if (!GetEntityNetClass(ent, cls, sizeof(cls)))
466	{
467		return -1;
468	}
469	
470	if (actual)
471	{
472		return FindSendPropInfo(cls, prop);
473	}
474	else
475	{
476		return FindSendPropOffs(cls, prop);
477	}
478}
479
480/**
481 * Retrieves an integer value from an entity's property.
482 *
483 * This function is considered safer and more robust over GetEntData, 
484 * because it performs strict offset checking and typing rules.
485 * 
486 * @param entity		Entity/edict index.
487 * @param type			Property type.
488 * @param prop			Property name.
489 * @param size			Number of bytes to write (valid values are 1, 2, or 4).
490 *						This value is auto-detected, and the size parameter is 
491 *						only used as a fallback in case detection fails.
492 * @param element		Element # (starting from 0) if property is an array.
493 * @return				Value at the given property offset.
494 * @error				Invalid entity or property not found.
495 */
496native GetEntProp(entity, PropType:type, const String:prop[], size=4, element=0);
497
498/**
499 * Sets an integer value in an entity's property.
500 *
501 * This function is considered safer and more robust over SetEntData, 
502 * because it performs strict offset checking and typing rules.
503 * 
504 * @param entity		Entity/edict index.
505 * @param type			Property type.
506 * @param prop			Property name.
507 * @param value			Value to set.
508 * @param size			Number of bytes to write (valid values are 1, 2, or 4).
509 *						This value is auto-detected, and the size parameter is 
510 *						only used as a fallback in case detection fails.
511 * @param element		Element # (starting from 0) if property is an array.
512 * @error				Invalid entity or offset out of reasonable bounds.
513 * @noreturn
514 */
515native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4, element=0);
516
517/**
518 * Retrieves a float value from an entity's property.
519 *
520 * This function is considered safer and more robust over GetEntDataFloat, 
521 * because it performs strict offset checking and typing rules.
522 * 
523 * @param entity		Entity/edict index.
524 * @param type			Property type.
525 * @param prop			Property name.
526 * @param element		Element # (starting from 0) if property is an array.
527 * @return				Value at the given property offset.
528 * @error				Invalid entity or offset out of reasonable bounds.
529 */
530native Float:GetEntPropFloat(entity, PropType:type, const String:prop[], element=0);
531
532/**
533 * Sets a float value in an entity's property.
534 *
535 * This function is considered safer and more robust over SetEntDataFloat, 
536 * because it performs strict offset checking and typing rules.
537 * 
538 * @param entity		Entity/edict index.
539 * @param type			Property type.
540 * @param prop			Property name.
541 * @param value			Value to set.
542 * @param element		Element # (starting from 0) if property is an array.
543 * @noreturn
544 * @error				Invalid entity or offset out of reasonable bounds.
545 */
546native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value, element=0);
547
548/**
549 * Retrieves an entity index from an entity's property.
550 *
551 * This function is considered safer and more robust over GetEntDataEnt*, 
552 * because it performs strict offset checking and typing rules.
553 * 
554 * @param entity		Entity/edict index.
555 * @param type			Property type.
556 * @param prop			Property name.
557 * @param element		Element # (starting from 0) if property is an array.
558 * @return				Entity index at the given property.
559 *						If there is no entity, or the entity is not valid, 
560 *						then -1 is returned.
561 * @error				Invalid entity or offset out of reasonable bounds.
562 */
563native GetEntPropEnt(entity, PropType:type, const String:prop[], element=0);
564
565/**
566 * Sets an entity index in an entity's property.
567 *
568 * This function is considered safer and more robust over SetEntDataEnt*, 
569 * because it performs strict offset checking and typing rules.
570 * 
571 * @param entity		Entity/edict index.
572 * @param type			Property type.
573 * @param prop			Property name.
574 * @param other			Entity index to set, or -1 to unset.
575 * @param element		Element # (starting from 0) if property is an array.
576 * @noreturn
577 * @error				Invalid entity or offset out of reasonable bounds.
578 */
579native SetEntPropEnt(entity, PropType:type, const String:prop[], other, element=0);
580
581/**
582 * Retrieves a vector of floats from an entity, given a named network property.
583 *
584 * This function is considered safer and more robust over GetEntDataVector, 
585 * because it performs strict offset checking and typing rules.
586 * 
587 * @param entity		Entity/edict index.
588 * @param type			Property type.
589 * @param prop			Property name.
590 * @param vec			Vector buffer to store data in.
591 * @param element		Element # (starting from 0) if property is an array.
592 * @noreturn
593 * @error				Invalid entity, property not found, or property not 
594 *						actually a vector data type.
595 */
596native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3], element=0);
597
598/**
599 * Sets a vector of floats in an entity, given a named network property.
600 *
601 * This function is considered safer and more robust over SetEntDataVector, 
602 * because it performs strict offset checking and typing rules.
603 * 
604 * @param entity		Entity/edict index.
605 * @param type			Property type.
606 * @param prop			Property name.
607 * @param vec			Vector to set.
608 * @param element		Element # (starting from 0) if property is an array.
609 * @noreturn
610 * @error				Invalid entity, property not found, or property not 
611 *						actually a vector data type.
612 */
613native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:vec[3], element=0);
614
615/**
616 * Gets a network property as a string.
617 * 
618 * @param entity		Edict index.
619 * @param type			Property type.
620 * @param prop			Property to use.
621 * @param buffer		Destination string buffer.
622 * @param maxlen		Maximum length of output string buffer.		
623 * @param element		Element # (starting from 0) if property is an array.
624 * @return				Number of non-null bytes written.
625 * @error				Invalid entity, offset out of reasonable bounds, or property is not a valid string.
626 */
627native GetEntPropString(entity, PropType:type, const String:prop[], String:buffer[], maxlen, element=0);
628
629/**
630 * Sets a network property as a string.
631 *
632 * This cannot set property fields of type PropField_String_T (such as "m_target").
633 * To set such fields, you should use DispatchKeyValue() from SDKTools.
634 * 
635 * @param entity		Edict index.
636 * @param type			Property type.
637 * @param prop			Property to use.
638 * @param buffer		String to set.		
639 * @return				Number of non-null bytes written.
640 * @error				Invalid entity, offset out of reasonable bounds, or property is not a valid string.
641 */
642native SetEntPropString(entity, PropType:type, const String:prop[], const String:buffer[]);
643
644/**
645 * Retrieves the count of values that an entity property's array can store.
646 * 
647 * @param entity		Entity/edict index.
648 * @param type			Property type.
649 * @param prop			Property name.
650 * @return				Size of array (in elements) or 1 if property is not an array.
651 * @error				Invalid entity or property not found.
652 */
653native GetEntPropArraySize(entity, PropType:type, const String:prop[]);
654
655/**
656 * Copies an array of cells from an entity at a given offset.
657 *
658 * @param entity		Entity index.
659 * @param offset		Offset to use.
660 * @param array			Array to read into.
661 * @param arraySize		Number of values to read.
662 * @param dataSize		Size of each value in bytes (1, 2, or 4).
663 * @noreturn
664 * @error				Invalid entity or offset out of reasonable bounds.
665 */
666stock GetEntDataArray(entity, offset, array[], arraySize, dataSize=4)
667{
668	for (new i=0; i<arraySize; i++)
669	{
670		array[i] = GetEntData(entity, offset + i*dataSize, dataSize)
671	}
672}
673
674/**
675 * Copies an array of cells to an entity at a given offset.
676 *
677 * @param entity		Entity index.
678 * @param offset		Offset to use.
679 * @param array			Array of values to copy.
680 * @param arraySize		Number of values to copy.
681 * @param dataSize		Size of each value in bytes (1, 2, or 4).
682 * @param changeState	True to set the network state as changed; false otherwise.
683 * @noreturn
684 * @error				Invalid entity or offset out of reasonable bounds.
685 */
686stock SetEntDataArray(entity, offset, const array[], arraySize, dataSize=4, bool:changeState=false)
687{
688	for (new i=0; i<arraySize; i++)
689	{
690		SetEntData(entity, offset + i*dataSize, array[i], dataSize, changeState);
691	}
692}
693
694/**
695 * Gets the memory address of an entity.
696 * 
697 * @param entity		Entity index.
698 * @return				Address of the entity.
699 * @error				Invalid entity.
700 */
701native Address:GetEntityAddress(entity);
702
703/**
704 * Retrieves the classname of an entity.
705 * This is like GetEdictClassname(), except it works for ALL
706 * entities, not just edicts.
707 *
708 * @param edict			Index of the entity.
709 * @param clsname		Buffer to store the classname.
710 * @param maxlength		Maximum length of the buffer.
711 * @return				True on success, false if there is no classname set.
712 */
713stock bool:GetEntityClassname(entity, String:clsname[], maxlength)
714{
715	return !!GetEntPropString(entity, Prop_Data, "m_iClassname", clsname, maxlength);
716}