summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/include/smlib/entities.inc
diff options
context:
space:
mode:
Diffstat (limited to 'sourcemod/scripting/include/smlib/entities.inc')
-rw-r--r--sourcemod/scripting/include/smlib/entities.inc2098
1 files changed, 2098 insertions, 0 deletions
diff --git a/sourcemod/scripting/include/smlib/entities.inc b/sourcemod/scripting/include/smlib/entities.inc
new file mode 100644
index 0000000..91c136b
--- /dev/null
+++ b/sourcemod/scripting/include/smlib/entities.inc
@@ -0,0 +1,2098 @@
+#if defined _smlib_entities_included
+ #endinput
+#endif
+#define _smlib_entities_included
+
+#include <sourcemod>
+#include <sdktools_entinput>
+#include <sdktools_functions>
+
+/**
+ * Macro for iterating trough all children (entities it is parent of) of an entity.
+ *
+ * @param 1 Entity Index of the parent.
+ * @param 2 Name of the children entity index variable (will be only valid in the loop).
+ */
+#define LOOP_CHILDREN(%1,%2) for (int %2=Entity_GetNextChild(%1); %2 != INVALID_ENT_REFERENCE; %2=Entity_GetNextChild(%1, ++%2))
+
+/*
+ * Checks if an entity is valid and exists.
+ *
+ * @param entity Entity Index.
+ * @return True if the entity is valid, false otherwise.
+ */
+stock bool Entity_IsValid(int entity)
+{
+ return IsValidEntity(entity);
+}
+
+/**
+ * Finds an entity by its name.
+ * You can optionally specify the classname to search for.
+ * Note: If the classname is specified it uses The Sourcemod native
+ * function FindEntityByClassname() which uses the engine's
+ * linked entity list for finding entities. This might be
+ * cheaper, use this if you call this function very often.
+ *
+ * @param name Name of the entity you want so search.
+ * @param className Optional: Classname of the entity
+ * @return Entity index or INVALID_ENT_REFERENCE if not matching entity was found.
+ */
+stock int Entity_FindByName(const char[] name, const char[] className="")
+{
+ if (className[0] == '\0') {
+ // Hack: Double the limit to gets none-networked entities too.
+ int realMaxEntities = GetMaxEntities() * 2;
+ for (int entity=0; entity < realMaxEntities; entity++) {
+
+ if (!IsValidEntity(entity)) {
+ continue;
+ }
+
+ if (Entity_NameMatches(entity, name)) {
+ return entity;
+ }
+ }
+ }
+ else {
+ int entity = INVALID_ENT_REFERENCE;
+ while ((entity = FindEntityByClassname(entity, className)) != INVALID_ENT_REFERENCE) {
+
+ if (Entity_NameMatches(entity, name)) {
+ return entity;
+ }
+ }
+ }
+
+ return INVALID_ENT_REFERENCE;
+}
+
+/**
+ * Finds an entity by its HammerID.
+ * The newer version of Valve's Hammer editor
+ * sets a unique ID for each entity in a map.
+ * It only finds the first occurence.
+ * Note: If the classname is specified it uses The Sourcemod native
+ * function FindEntityByClassname() which uses the engine's
+ * linked entity list for finding entities. This might be
+ * cheaper, use this if you call this function very often.
+ *
+ * @param hammerId Hammer editor ID
+ * @param className Optional: Classname of the entity
+ * @return Edict Index or INVALID_ENT_REFERENCE if no entity was found.
+ */
+stock int Entity_FindByHammerId(int hammerId, const char[] className="")
+{
+ if (className[0] == '\0') {
+ // Hack: Double the limit to gets none-networked entities too.
+ int realMaxEntities = GetMaxEntities() * 2;
+ for (int entity=0; entity < realMaxEntities; entity++) {
+
+ if (!IsValidEntity(entity)) {
+ continue;
+ }
+
+ if (Entity_GetHammerId(entity) == hammerId) {
+ return entity;
+ }
+ }
+ }
+ else {
+ int entity = INVALID_ENT_REFERENCE;
+ while ((entity = FindEntityByClassname(entity, className)) != INVALID_ENT_REFERENCE) {
+
+ if (Entity_GetHammerId(entity) == hammerId) {
+ return entity;
+ }
+ }
+ }
+
+ return INVALID_ENT_REFERENCE;
+}
+
+/**
+ * Searches for an entity by classname.
+ * This is a wrapper around FindEntityByClassname
+ * and has been added for completion.
+ *
+ * @param startEnt The entity index after which to begin searching from. Use -1 to start from the first entity.
+ * @param classname Classname of the entity to find.
+ * @return Entity index >= 0 if found, -1 otherwise.
+ */
+
+stock int Entity_FindByClassName(int startEntity, const char[] className)
+{
+ return FindEntityByClassname(startEntity, className);
+}
+
+/**
+ * Checks if an entity (partially) matches a specific entity class.
+ *
+ * @param entity Entity Index.
+ * @param className Classname String.
+ * @partialMatch If to do a partial classname check.
+ * @return True if the classname matches, false otherwise.
+ */
+stock bool Entity_ClassNameMatches(int entity, const char[] className, bool partialMatch=false)
+{
+ char entity_className[64];
+ Entity_GetClassName(entity, entity_className, sizeof(entity_className));
+
+ if (partialMatch) {
+ return (StrContains(entity_className, className) != -1);
+ }
+
+ return StrEqual(entity_className, className);
+}
+
+/**
+ * Checks if an entity matches a name
+ *
+ * @param entity Entity Index.
+ * @param class Name String.
+ * @return True if the name matches, false otherwise.
+ */
+stock bool Entity_NameMatches(int entity, const char[] name)
+{
+ char entity_name[128];
+ Entity_GetName(entity, entity_name, sizeof(entity_name));
+
+ return StrEqual(name, entity_name);
+}
+
+/**
+ * Gets the Name of an entity.
+ *
+ * @param entity Entity index.
+ * @param buffer Return/Output buffer.
+ * @param size Max size of buffer.
+ * @return Number of non-null bytes written.
+ */
+stock int Entity_GetName(int entity, char[] buffer, int size)
+{
+ return GetEntPropString(entity, Prop_Data, "m_iName", buffer, size);
+}
+
+/**
+ * Sets the Name of an entity.
+ *
+ * @param entity Entity index.
+ * @param name The name you want to give.
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_SetName(int entity, const char[] name, any ...)
+{
+ char format[128];
+ VFormat(format, sizeof(format), name, 3);
+
+ return DispatchKeyValue(entity, "targetname", format);
+}
+
+/**
+ * Gets the Classname of an entity.
+ * This is like GetEdictClassname(), except it works for ALL
+ * entities, not just edicts.
+ *
+ * @param entity Entity index.
+ * @param buffer Return/Output buffer.
+ * @param size Max size of buffer.
+ * @return Number of non-null bytes written.
+ */
+stock int Entity_GetClassName(int entity, char[] buffer, int size)
+{
+ return GetEntPropString(entity, Prop_Data, "m_iClassname", buffer, size);
+}
+
+/**
+ * Sets the Classname of an entity.
+ *
+ * @param entity Entity index.
+ * @param name The name you want to give.
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_SetClassName(int entity, const char[] className)
+{
+ return DispatchKeyValue(entity, "classname", className);
+}
+
+/**
+ * Gets the Target name of an other entity
+ *
+ * @param entity Entity index.
+ * @param buffer Return/Output buffer.
+ * @param size Max size of buffer.
+ * @return Number of non-null bytes written.
+ */
+stock int Entity_GetTargetName(int entity, char[] buffer, int size)
+{
+ return GetEntPropString(entity, Prop_Data, "m_target", buffer, size);
+}
+
+/**
+ * Sets the Target name of an other Entity
+ *
+ * @param entity Entity index.
+ * @param name The target name you want to set
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_SetTargetName(int entity, const char[] name, any ...)
+{
+ char format[128];
+ VFormat(format, sizeof(format), name, 3);
+
+ return DispatchKeyValue(entity, "target", format);
+}
+
+/**
+ * Gets the Global Name of an entity.
+ *
+ * @param entity Entity index.
+ * @param buffer Return/Output buffer.
+ * @param size Max size of buffer.
+ * @return Number of non-null bytes written.
+ */
+stock int Entity_GetGlobalName(int entity, char[] buffer, int size)
+{
+ return GetEntPropString(entity, Prop_Data, "m_iGlobalname", buffer, size);
+}
+
+/**
+ * Sets the Global Name of an entity.
+ *
+ * @param entity Entity index.
+ * @param name The global name you want to set.
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_SetGlobalName(int entity, const char[] name, any ...)
+{
+ char format[128];
+ VFormat(format, sizeof(format), name, 3);
+
+ return DispatchKeyValue(entity, "globalname", format);
+}
+
+/**
+ * Gets the Parent name of an entity.
+ *
+ * @param entity Entity index.
+ * @param buffer Return/Output buffer.
+ * @param size Max size of buffer.
+ * @return Number of non-null bytes written.
+ */
+stock int Entity_GetParentName(int entity, char[] buffer, int size)
+{
+ return GetEntPropString(entity, Prop_Data, "m_iParent", buffer, size);
+}
+
+/**
+ * Sets the Parent name of an entity.
+ *
+ * @param entity Entity index.
+ * @param name The parent name you want to set.
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_SetParentName(int entity, const char[] name, any ...)
+{
+ char format[128];
+ VFormat(format, sizeof(format), name, 3);
+
+ return DispatchKeyValue(entity, "parentname", format);
+}
+
+/**
+ * Gets the Hammer-ID of an entity.
+ * The Hammer Editor gives every entity a unique ID.
+ * Note: Old maps don't have Hammer-ID's set for entities
+ *
+ * @param entity Entity index.
+ * @return Hammer ID.
+ */
+stock int Entity_GetHammerId(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_iHammerID");
+}
+
+/**
+ * Gets the radius (m_flRadius) of an entity.
+ *
+ * @param entity Entity index.
+ * @return Radius
+ */
+stock float Entity_GetRadius(int entity)
+{
+ return GetEntPropFloat(entity, Prop_Data, "m_flRadius");
+}
+
+/**
+ * Sets the radius (m_flRadius) of an entity.
+ *
+ * @param entity Entity index.
+ * @param radius Radius value
+ */
+stock void Entity_SetRadius(int entity, float radius)
+{
+ SetEntPropFloat(entity, Prop_Data, "m_flRadius", radius);
+}
+
+/**
+ * Gets the Mins of an entity.
+ *
+ * @param entity Entity index.
+ * @param vec Buffer to hold the vector.
+ */
+stock void Entity_GetMinSize(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Send, "m_vecMins", vec);
+}
+
+/**
+ * Sets the Mins of an entity.
+ *
+ * @param entity Entity index.
+ * @param vec Vector.
+ */
+stock void Entity_SetMinSize(int entity, const float vecMins[3])
+{
+ SetEntPropVector(entity, Prop_Send, "m_vecMins", vecMins);
+}
+
+/**
+ * Gets the Mins of an entity.
+ * This functions isn't safe to use, use Entity_SetMinMaxSize() instead.
+ *
+ * @param entity Entity index
+ * @param vec Buffer to hold the vector
+ */
+stock void Entity_GetMaxSize(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Send, "m_vecMaxs", vec);
+}
+
+/**
+ * Sets the Maxs of an entity.
+ * This functions isn't safe to use, use Entity_SetMinMaxSize() instead.
+ *
+ * @param entity Entity index.
+ * @param vec Buffer to hold the vector.
+ */
+stock void Entity_SetMaxSize(int entity, const float vecMaxs[3])
+{
+ SetEntPropVector(entity, Prop_Send, "m_vecMaxs", vecMaxs);
+}
+
+/**
+ * Sets the Min and Max Size of an entity.
+ * Code is taken from HL2SDK and rewritten for Sourcemod.
+ *
+ * @param entity Entity index.
+ * @param vecMins Min size Vector
+ * @param vecMaxs Max size Vector
+ */
+stock void Entity_SetMinMaxSize(int entity, float vecMins[3], float vecMaxs[3])
+{
+ // Taken from hl2sdk-ob-valve\game\server\util.cpp SetMinMaxSize()
+ // Todo: Replace this by a SDK call
+ for (int i=0; i<3; i++) {
+
+ if (vecMins[i] > vecMaxs[i]) {
+ ThrowError("Error: mins[%d] > maxs[%d] of entity %d", i, i, EntRefToEntIndex(entity));
+ }
+ }
+
+ float m_vecMins[3], m_vecMaxs[3];
+ Entity_GetMinSize(entity, m_vecMins);
+ Entity_GetMaxSize(entity, m_vecMaxs);
+
+ if (Math_VectorsEqual(m_vecMins, vecMins) && Math_VectorsEqual(m_vecMaxs, vecMaxs)) {
+ return;
+ }
+
+ Entity_SetMinSize(entity, vecMins);
+ Entity_SetMaxSize(entity, vecMaxs);
+
+ float vecSize[3];
+ SubtractVectors(vecMaxs, vecMins, vecSize);
+ Entity_SetRadius(entity, GetVectorLength(vecSize) * 0.5);
+
+ Entity_MarkSurrBoundsDirty(entity);
+}
+
+/*
+ * Spawn Flags
+ * Many entities define their specific spawnflags, check the HL2SDK.
+ */
+
+/*
+ * Phys prop spawnflags
+ * Taken from hl2sdk-ob-valve\game\shared\props_shared.h
+ */
+#define SF_PHYSPROP_START_ASLEEP 0x000001
+#define SF_PHYSPROP_DONT_TAKE_PHYSICS_DAMAGE 0x000002 // this prop can't be damaged by physics collisions
+#define SF_PHYSPROP_DEBRIS 0x000004
+#define SF_PHYSPROP_MOTIONDISABLED 0x000008 // motion disabled at startup (flag only valid in spawn - motion can be enabled via input)
+#define SF_PHYSPROP_TOUCH 0x000010 // can be 'crashed through' by running player (plate glass)
+#define SF_PHYSPROP_PRESSURE 0x000020 // can be broken by a player standing on it
+#define SF_PHYSPROP_ENABLE_ON_PHYSCANNON 0x000040 // enable motion only if the player grabs it with the physcannon
+#define SF_PHYSPROP_NO_ROTORWASH_PUSH 0x000080 // The rotorwash doesn't push these
+#define SF_PHYSPROP_ENABLE_PICKUP_OUTPUT 0x000100 // If set, allow the player to +USE this for the purposes of generating an output
+#define SF_PHYSPROP_PREVENT_PICKUP 0x000200 // If set, prevent +USE/Physcannon pickup of this prop
+#define SF_PHYSPROP_PREVENT_PLAYER_TOUCH_ENABLE 0x000400 // If set, the player will not cause the object to enable its motion when bumped into
+#define SF_PHYSPROP_HAS_ATTACHED_RAGDOLLS 0x000800 // Need to remove attached ragdolls on enable motion/etc
+#define SF_PHYSPROP_FORCE_TOUCH_TRIGGERS 0x001000 // Override normal debris behavior and respond to triggers anyway
+#define SF_PHYSPROP_FORCE_SERVER_SIDE 0x002000 // Force multiplayer physics object to be serverside
+#define SF_PHYSPROP_RADIUS_PICKUP 0x004000 // For Xbox, makes small objects easier to pick up by allowing them to be found
+#define SF_PHYSPROP_ALWAYS_PICK_UP 0x100000 // Physcannon can always pick this up, no matter what mass or constraints may apply.
+#define SF_PHYSPROP_NO_COLLISIONS 0x200000 // Don't enable collisions on spawn
+#define SF_PHYSPROP_IS_GIB 0x400000 // Limit # of active gibs
+
+/*
+ * Physbox Spawnflags. Start at 0x01000 to avoid collision with CBreakable's
+ * Taken from hl2sdk-ob-valve\game\server\physobj.h
+ */
+#define SF_PHYSBOX_ASLEEP 0x01000
+#define SF_PHYSBOX_IGNOREUSE 0x02000
+#define SF_PHYSBOX_DEBRIS 0x04000
+#define SF_PHYSBOX_MOTIONDISABLED 0x08000
+#define SF_PHYSBOX_USEPREFERRED 0x10000
+#define SF_PHYSBOX_ENABLE_ON_PHYSCANNON 0x20000
+#define SF_PHYSBOX_NO_ROTORWASH_PUSH 0x40000 // The rotorwash doesn't push these
+#define SF_PHYSBOX_ENABLE_PICKUP_OUTPUT 0x80000
+#define SF_PHYSBOX_ALWAYS_PICK_UP 0x100000 // Physcannon can always pick this up, no matter what mass or constraints may apply.
+#define SF_PHYSBOX_NEVER_PICK_UP 0x200000 // Physcannon will never be able to pick this up.
+#define SF_PHYSBOX_NEVER_PUNT 0x400000 // Physcannon will never be able to punt this object.
+#define SF_PHYSBOX_PREVENT_PLAYER_TOUCH_ENABLE 0x800000 // If set, the player will not cause the object to enable its motion when bumped into
+
+/*
+ * Spawnflags for func breakable
+ * Taken from hl2sdk-ob-valve\game\server\func_break.h
+ */
+#define SF_BREAK_TRIGGER_ONLY 0x0001 // may only be broken by trigger
+#define SF_BREAK_TOUCH 0x0002 // can be 'crashed through' by running player (plate glass)
+#define SF_BREAK_PRESSURE 0x0004 // can be broken by a player standing on it
+#define SF_BREAK_PHYSICS_BREAK_IMMEDIATELY 0x0200 // the first physics collision this breakable has will immediately break it
+#define SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE 0x0400 // this breakable doesn't take damage from physics collisions
+#define SF_BREAK_NO_BULLET_PENETRATION 0x0800 // don't allow bullets to penetrate
+
+/*
+ * Spawnflags for func_pushable (it's also func_breakable, so don't collide with those flags)
+ * Taken from hl2sdk-ob-valve\game\server\func_break.h
+ */
+#define SF_PUSH_BREAKABLE 0x0080
+#define SF_PUSH_NO_USE 0x0100 // player cannot +use pickup this ent
+
+/**
+ * Gets the Spawnflags of an entity.
+ *
+ * @param entity Entity index.
+ * @return Spawnflags value
+ */
+stock int Entity_GetSpawnFlags(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_spawnflags");
+}
+
+/**
+ * Sets the Spawnflags of an entity.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ */
+stock void Entity_SetSpawnFlags(int entity, int flags)
+{
+ SetEntProp(entity, Prop_Data, "m_spawnflags", flags);
+}
+
+/**
+ * Adds Spawnflags to an entity.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ */
+stock void Entity_AddSpawnFlags(int entity, int flags)
+{
+ int spawnFlags = Entity_GetSpawnFlags(entity);
+ spawnFlags |= flags;
+ Entity_SetSpawnFlags(entity, spawnFlags);
+}
+
+/**
+ * Removes Spawnflags from an entity.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ */
+stock void Entity_RemoveSpawnFlags(int entity, int flags)
+{
+ int spawnFlags = Entity_GetSpawnFlags(entity);
+ spawnFlags &= ~flags;
+ Entity_SetSpawnFlags(entity, spawnFlags);
+}
+
+/**
+ * Clears all Spawnflags of an entity.
+ *
+ * @param entity Entity index.
+ * @noretur */
+stock void Entity_ClearSpawnFlags(int entity)
+{
+ Entity_SetSpawnFlags(entity, 0);
+}
+
+/**
+ * Returns whether the entity has specific Spawnflags.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value.
+ * @return True if the entity has the spawnflags set, false otherwise.
+ */
+stock bool Entity_HasSpawnFlags(int entity, int flags)
+{
+ return Entity_GetSpawnFlags(entity) & flags == flags;
+}
+
+/*
+ * Entity flags, CBaseEntity::m_iEFlags
+ * Taken from: hl2sdk-ob-valve\game\shared\shareddefs.h
+ */
+enum Entity_Flags
+{
+ EFL_KILLME = (1<<0), // This entity is marked for death -- This allows the game to actually delete ents at a safe time
+ EFL_DORMANT = (1<<1), // Entity is dormant, no updates to client
+ EFL_NOCLIP_ACTIVE = (1<<2), // Lets us know when the noclip command is active.
+ EFL_SETTING_UP_BONES = (1<<3), // Set while a model is setting up its bones.
+ EFL_KEEP_ON_RECREATE_ENTITIES = (1<<4), // This is a special entity that should not be deleted when we restart entities only
+
+ EFL_HAS_PLAYER_CHILD= (1<<4), // One of the child entities is a player.
+
+ EFL_DIRTY_SHADOWUPDATE = (1<<5), // Client only- need shadow manager to update the shadow...
+ EFL_NOTIFY = (1<<6), // Another entity is watching events on this entity (used by teleport)
+
+ // The default behavior in ShouldTransmit is to not send an entity if it doesn't
+ // have a model. Certain entities want to be sent anyway because all the drawing logic
+ // is in the client DLL. They can set this flag and the engine will transmit them even
+ // if they don't have a model.
+ EFL_FORCE_CHECK_TRANSMIT = (1<<7),
+
+ EFL_BOT_FROZEN = (1<<8), // This is set on bots that are frozen.
+ EFL_SERVER_ONLY = (1<<9), // Non-networked entity.
+ EFL_NO_AUTO_EDICT_ATTACH = (1<<10), // Don't attach the edict; we're doing it explicitly
+
+ // Some dirty bits with respect to abs computations
+ EFL_DIRTY_ABSTRANSFORM = (1<<11),
+ EFL_DIRTY_ABSVELOCITY = (1<<12),
+ EFL_DIRTY_ABSANGVELOCITY = (1<<13),
+ EFL_DIRTY_SURR_COLLISION_BOUNDS = (1<<14),
+ EFL_DIRTY_SPATIAL_PARTITION = (1<<15),
+// UNUSED = (1<<16),
+
+ EFL_IN_SKYBOX = (1<<17), // This is set if the entity detects that it's in the skybox.
+ // This forces it to pass the "in PVS" for transmission.
+ EFL_USE_PARTITION_WHEN_NOT_SOL = (1<<18), // Entities with this flag set show up in the partition even when not solid
+ EFL_TOUCHING_FLUID = (1<<19), // Used to determine if an entity is floating
+
+ // FIXME: Not really sure where I should add this...
+ EFL_IS_BEING_LIFTED_BY_BARNACLE = (1<<20),
+ EFL_NO_ROTORWASH_PUSH = (1<<21), // I shouldn't be pushed by the rotorwash
+ EFL_NO_THINK_FUNCTION = (1<<22),
+ EFL_NO_GAME_PHYSICS_SIMULATION = (1<<23),
+
+ EFL_CHECK_UNTOUCH = (1<<24),
+ EFL_DONTBLOCKLOS = (1<<25), // I shouldn't block NPC line-of-sight
+ EFL_DONTWALKON = (1<<26), // NPC;s should not walk on this entity
+ EFL_NO_DISSOLVE = (1<<27), // These guys shouldn't dissolve
+ EFL_NO_MEGAPHYSCANNON_RAGDOLL = (1<<28), // Mega physcannon can't ragdoll these guys.
+ EFL_NO_WATER_VELOCITY_CHANGE = (1<<29), // Don't adjust this entity's velocity when transitioning into water
+ EFL_NO_PHYSCANNON_INTERACTION = (1<<30), // Physcannon can't pick these up or punt them
+ EFL_NO_DAMAGE_FORCES = (1<<31), // Doesn't accept forces from physics damage
+};
+
+/**
+ * Gets the Entity flags (m_iEFlags) of an entity.
+ *
+ * @param entity Entity index.
+ * @return Entity flags value
+ */
+stock Entity_Flags Entity_GetEFlags(int entity)
+{
+ return view_as<Entity_Flags>(GetEntProp(entity, Prop_Data, "m_iEFlags"));
+}
+
+/**
+ * Sets the entity's Entity flags (m_iEFlags).
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ */
+stock void Entity_SetEFlags(int entity, Entity_Flags flags)
+{
+ SetEntProp(entity, Prop_Data, "m_iEFlags", flags);
+}
+
+/**
+ * Adds Entity flags (m_iEFlags) to an entity.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ */
+stock void Entity_AddEFlags(int entity, Entity_Flags flags)
+{
+ Entity_Flags setFlags = Entity_GetEFlags(entity);
+ setFlags |= flags;
+ Entity_SetEFlags(entity, setFlags);
+}
+
+/**
+ * Removes Entity flags (m_iEFlags) from an entity.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ */
+stock void Entity_RemoveEFlags(int entity, Entity_Flags flags)
+{
+ Entity_Flags setFlags = Entity_GetEFlags(entity);
+ setFlags &= ~flags;
+ Entity_SetEFlags(entity, setFlags);
+}
+
+/**
+ * Checks if the entity has specific Entity flags (m_iEFlags) set.
+ *
+ * @param entity Entity index.
+ * @param flags Flags value
+ * @return True if the flags are set, false otherwise.
+ */
+stock bool Entity_HasEFlags(int entity, Entity_Flags flags)
+{
+ Entity_Flags currentEFlags = Entity_GetEFlags(entity);
+
+ return currentEFlags & flags == flags;
+}
+
+/**
+ * Marks the surrounding bounds of an entity as outdated.
+ * You normally call this when a collision setting has changed.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_MarkSurrBoundsDirty(int entity)
+{
+ Entity_AddEFlags(entity, EFL_DIRTY_SURR_COLLISION_BOUNDS);
+}
+
+/*
+ * CBaseEntity::m_fFlags Functions
+ * Use the FL_ Defines (FL_ONGROUND, ...) or
+ * special entity specific flags.
+ * Note: The flag FL_AIMTARGET probably doesn't work as
+ * we have current no way of adding/removing it to the AimTarget List.
+ */
+
+/**
+ * Gets the Flags of an entity.
+ *
+ * @param entity Entity Index.
+ * @return Entity Flags.
+ */
+stock int Entity_GetFlags(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_fFlags");
+}
+
+/**
+ * Sets the Flags of an entity.
+ *
+ * @param entity Entity index.
+ * @param flags New Flags value
+ */
+stock void Entity_SetFlags(int entity, int flags)
+{
+ SetEntProp(entity, Prop_Data, "m_fFlags", flags);
+}
+
+/**
+ * Adds Flags to the entity
+ *
+ * @param entity Entity index.
+ * @param flags Flags to add
+ * @noreturn
+ */
+stock void Entity_AddFlags(int entity, int flags)
+{
+ int setFlags = Entity_GetFlags(entity);
+ setFlags |= flags;
+ Entity_SetFlags(entity, setFlags);
+}
+
+/**
+ * Removes flags from the entity
+ *
+ * @param entity Entity index.
+ * @param flags Flags to remove
+ */
+stock void Entity_RemoveFlags(int entity, int flags)
+{
+ int setFlags = Entity_GetFlags(entity);
+ setFlags &= ~flags;
+ Entity_SetFlags(entity, setFlags);
+}
+
+/**
+ * Toggles the specified flag on the entity.
+ * Adds the flag to the entity if it doesn't exists
+ * or removes it otherwise.
+ *
+ * @param entity Entity index.
+ * @param flags Flag to Toggle
+ */
+stock void Entity_ToggleFlag(int entity, int flag)
+{
+ int setFlag = Entity_GetFlags(entity);
+ setFlag ^= flag;
+ Entity_SetFlags(entity, setFlag);
+}
+
+/**
+ * Removes all flags from the entity
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_ClearFlags(int entity)
+{
+ Entity_SetFlags(entity, 0);
+}
+
+/* edict->solid values
+ * NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves
+ * SOLID only effects OTHER entities colliding with this one when they move - UGH!
+ *
+ * Solid type basically describes how the bounding volume of the object is represented
+ * NOTE: These numerical values are used in the FGD by the prop code (see prop_dynamic)
+ * Taken from: hl2sdk-ob-valve\public\const.h
+ */
+
+enum SolidFlags_t
+{
+ FSOLID_CUSTOMRAYTEST = 0x0001, // Ignore solid type + always call into the entity for ray tests
+ FSOLID_CUSTOMBOXTEST = 0x0002, // Ignore solid type + always call into the entity for swept box tests
+ FSOLID_NOT_SOLID = 0x0004, // Are we currently not solid?
+ FSOLID_TRIGGER = 0x0008, // This is something may be collideable but fires touch functions
+ // even when it's not collideable (when the FSOLID_NOT_SOLID flag is set)
+ FSOLID_NOT_STANDABLE = 0x0010, // You can't stand on this
+ FSOLID_VOLUME_CONTENTS = 0x0020, // Contains volumetric contents (like water)
+ FSOLID_FORCE_WORLD_ALIGNED = 0x0040, // Forces the collision rep to be world-aligned even if it's SOLID_BSP or SOLID_VPHYSICS
+ FSOLID_USE_TRIGGER_BOUNDS = 0x0080, // Uses a special trigger bounds separate from the normal OBB
+ FSOLID_ROOT_PARENT_ALIGNED = 0x0100, // Collisions are defined in root parent's local coordinate space
+ FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, // This trigger will touch debris objects
+
+ FSOLID_MAX_BITS = 10
+};
+
+/**
+ * Gets the solid flags of the entity
+ *
+ * @param entity Entity index.
+ * @return Solid Flags.
+ */
+stock SolidFlags_t Entity_GetSolidFlags(int entity)
+{
+ return view_as<SolidFlags_t>(GetEntProp(entity, Prop_Data, "m_usSolidFlags", 2));
+}
+
+/**
+ * Sets the solid flags of the entity
+ *
+ * @param entity Entity index.
+ * @param flags Solid Flags.
+ */
+stock void Entity_SetSolidFlags(int entity, SolidFlags_t flags)
+{
+ SolidFlags_t oldFlags = Entity_GetSolidFlags(entity);
+ flags = flags & view_as<SolidFlags_t>(0xFFFF);
+
+ if (oldFlags == flags) {
+ return;
+ }
+
+ SetEntProp(entity, Prop_Data, "m_usSolidFlags", flags, 2);
+
+ // These two flags, if changed, can produce different surrounding bounds
+ if ((oldFlags & (FSOLID_FORCE_WORLD_ALIGNED | FSOLID_USE_TRIGGER_BOUNDS)) !=
+ (flags & (FSOLID_FORCE_WORLD_ALIGNED | FSOLID_USE_TRIGGER_BOUNDS)))
+ {
+ Entity_MarkSurrBoundsDirty(entity);
+ }
+}
+
+/**
+ * Adds solid flags to the entity
+ *
+ * @param entity Entity index.
+ * @param flags Solid Flags.
+ */
+stock void Entity_AddSolidFlags(int entity, SolidFlags_t flags)
+{
+ SolidFlags_t newFlags = Entity_GetSolidFlags(entity);
+ newFlags |= flags;
+ Entity_SetSolidFlags(entity, newFlags);
+}
+
+/**
+ * Removes solid flags from the entity.
+ *
+ * @param entity Entity index.
+ * @param flags Solid Flags.
+ */
+stock void Entity_RemoveSolidFlags(int entity, SolidFlags_t flags)
+{
+ SolidFlags_t newFlags = Entity_GetSolidFlags(entity);
+ newFlags &= ~flags;
+ Entity_SetSolidFlags(entity, newFlags);
+}
+
+/**
+ * Removes all solid flags from the entity.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_ClearSolidFlags(int entity)
+{
+ Entity_SetSolidFlags(entity, view_as<SolidFlags_t>(0));
+}
+
+/**
+ * Checks whether certain solid flags are set on the entity.
+ *
+ * @param entity Entity index.
+ * @param flags Solid Flags.
+ * @return True if the specified flags are set, false otherwise.
+ */
+stock bool Entity_SolidFlagsSet(int entity, SolidFlags_t flagMask)
+{
+ return Entity_GetSolidFlags(entity) & flagMask == flagMask;
+}
+
+enum SolidType_t
+{
+ SOLID_NONE = 0, // no solid model
+ SOLID_BSP = 1, // a BSP tree
+ SOLID_BBOX = 2, // an AABB
+ SOLID_OBB = 3, // an OBB (not implemented yet)
+ SOLID_OBB_YAW = 4, // an OBB, constrained so that it can only yaw
+ SOLID_CUSTOM = 5, // Always call into the entity for tests
+ SOLID_VPHYSICS = 6, // solid vphysics object, get vcollide from the model and collide with that
+ SOLID_LAST,
+};
+
+/**
+ * Gets the solidity type of the entity
+ *
+ * @param entity Entity index.
+ * @return Solid Type
+ */
+stock SolidType_t Entity_GetSolidType(int entity)
+{
+ return view_as<SolidType_t>(GetEntProp(entity, Prop_Data, "m_nSolidType", 1));
+}
+
+/**
+ * Sets the solidity type of the entity
+ *
+ * @param entity Entity index.
+ * @param Solid Type value.
+ */
+stock void Entity_SetSolidType(int entity, SolidType_t value)
+{
+ SetEntProp(entity, Prop_Send, "m_nSolidType", value, 1);
+ Entity_MarkSurrBoundsDirty(entity);
+}
+
+/**
+ * Checks whether the entity is solid or not.
+ *
+ * @param entity Entity index.
+ * @return True if the entity is solid, false otherwise.
+ */
+stock bool Entity_IsSolid(int entity)
+{
+ return (Entity_GetSolidType(entity) != SOLID_NONE &&
+ !Entity_SolidFlagsSet(entity, FSOLID_NOT_SOLID));
+}
+
+/**
+ * Retrieves the model path of a given entity.
+ * Returns "*num" for Brush entities.
+ *
+ * @param entity entity reference or index
+ * @param model buffer String for the model
+ * @param size max size of buffer string
+ * @return Number of non-null bytes written.
+ */
+stock int Entity_GetModel(int entity, char[] buffer, int size)
+{
+ return GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, size);
+}
+
+/**
+ * Sets the model to a given entity.
+ * Be sure it has been precached.
+ * This is an alias for SetEntityModel()
+ *
+ * @param entity Entity index
+ * @param model Model name
+ */
+stock void Entity_SetModel(int entity, const char[] model)
+{
+ SetEntityModel(entity, model);
+}
+
+/**
+ * Gets the entity's model index, if it has one set.
+ *
+ * @param entity Entity index.
+ * @return The Entity's model index
+ */
+stock int Entity_GetModelIndex(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_nModelIndex", 2);
+}
+
+/**
+ * Sets the entity's model index (must be precached)
+ *
+ * @param entity Entity index.
+ * @param index Model Index.
+ */
+stock void Entity_SetModelIndex(int entity, int index)
+{
+ SetEntProp(entity, Prop_Data, "m_nModelIndex", index, 2);
+}
+
+/**
+* Sets the entity's maxspeed to the given value (in units per second)
+*
+* @param entity Entity index
+* @param maxspeed the maximum speed the entity can move
+* @noreturn
+*/
+stock void Entity_SetMaxSpeed(int entity, float value)
+{
+ SetEntPropFloat(entity, Prop_Data, "m_flMaxspeed", value);
+}
+
+/*
+ * Collision groups
+ * Taken from hl2sdk-ob-valve/public/const.h
+ */
+enum Collision_Group_t
+{
+ COLLISION_GROUP_NONE = 0,
+ COLLISION_GROUP_DEBRIS, // Collides with nothing but world and static stuff
+ COLLISION_GROUP_DEBRIS_TRIGGER, // Same as debris, but hits triggers
+ COLLISION_GROUP_INTERACTIVE_DEB, // Collides with everything except other interactive debris or debris
+ COLLISION_GROUP_INTERACTIVE, // Collides with everything except interactive debris or debris
+ COLLISION_GROUP_PLAYER,
+ COLLISION_GROUP_BREAKABLE_GLASS,
+ COLLISION_GROUP_VEHICLE,
+ COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player, for
+ // TF2, this filters out other players and CBaseObjects
+ COLLISION_GROUP_NPC, // Generic NPC group
+ COLLISION_GROUP_IN_VEHICLE, // for any entity inside a vehicle
+ COLLISION_GROUP_WEAPON, // for any weapons that need collision detection
+ COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
+ COLLISION_GROUP_PROJECTILE, // Projectiles!
+ COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
+ COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
+ COLLISION_GROUP_DISSOLVING, // Things that are dissolving are in this group
+ COLLISION_GROUP_PUSHAWAY, // Nonsolid on client and server, pushaway in player code
+
+ COLLISION_GROUP_NPC_ACTOR, // Used so NPCs in scripts ignore the player.
+ COLLISION_GROUP_NPC_SCRIPTED // USed for NPCs in scripts that should not collide with each other
+};
+
+/**
+ * Gets the collision group of an entity.
+ *
+ * @param entity entity index
+ * @return Entity collision group.
+ */
+stock Collision_Group_t Entity_GetCollisionGroup(int entity)
+{
+ return view_as<Collision_Group_t>(GetEntProp(entity, Prop_Data, "m_CollisionGroup"));
+}
+
+/**
+ * Sets the collision group of an entity.
+ *
+ * @param entity entity index
+ * @param value the new collision group.
+ */
+stock void Entity_SetCollisionGroup(int entity, Collision_Group_t value)
+{
+ SetEntProp(entity, Prop_Data, "m_CollisionGroup", value);
+}
+
+/**
+ * Functions for getting / setting the origin (position) of an entity.
+ * Go to http://developer.valvesoftware.com/wiki/Origin
+ * if you want to learn more about origins
+ */
+
+/**
+ * Gets the Absolute Origin (position) of an entity.
+ *
+ * @param entity Entity index.
+ * @param vec 3 dimensional vector array.
+ */
+stock void Entity_GetAbsOrigin(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Send, "m_vecOrigin", vec);
+}
+
+/**
+ * Sets the Absolute Origin (position) of an entity.
+ *
+ * @param entity Entity index.
+ * @param vec 3 dimensional vector array.
+ */
+stock void Entity_SetAbsOrigin(int entity, const float vec[3])
+{
+ // We use TeleportEntity to set the origin more safely
+ // Todo: Replace this with a call to UTIL_SetOrigin() or CBaseEntity::SetLocalOrigin()
+ TeleportEntity(entity, vec, NULL_VECTOR, NULL_VECTOR);
+}
+
+/**
+ * Functions for getting / setting the angles (rotation) of an entity.
+ * http://developer.valvesoftware.com/wiki/Angles
+ * if you want to learn more about angles
+ */
+
+/**
+ * Gets the Angles of an entity
+ *
+ * @param entity Entity index.
+ * @param vec 3 dimensional vector array.
+ * @noreturn
+ */
+stock void Entity_GetAbsAngles(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Data, "m_angAbsRotation", vec);
+}
+
+/**
+ * Sets the Angles of an entity
+ *
+ * @param entity Entity index.
+ * @param vec 3 dimensional vector array.
+ */
+stock void Entity_SetAbsAngles(int entity, const float vec[3])
+{
+ // We use TeleportEntity to set the angles more safely
+ // Todo: Replace this with a call to CBaseEntity::SetLocalAngles()
+ TeleportEntity(entity, NULL_VECTOR, vec, NULL_VECTOR);
+}
+
+/**
+ * Functions for getting / setting the velocity of an entity.
+ * Go to http://developer.valvesoftware.com/wiki/Velocity
+ * if you want to learn more about the different kind of velocities.
+ */
+
+/**
+ * Gets the Local velocity of an entity.
+ * The local velocity is the velocity generated by the entity.
+ *
+ * @param entity Entity index.
+ * @param vel An 3 dim array
+ */
+stock void Entity_GetLocalVelocity(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Data, "m_vecVelocity", vec);
+}
+
+/**
+ * Sets the Local velocity of an entity.
+ * The local velocity is the velocity generated by the entity.
+ * Only use this if you know what you are doing,
+ * the entity can overwrite this value on next frame.
+ *
+ * @param entity Entity index.
+ * @param vel An 3 dim array
+ */
+stock void Entity_SetLocalVelocity(int entity, const float vec[3])
+{
+ SetEntPropVector(entity, Prop_Data, "m_vecVelocity", vec);
+}
+
+/**
+ * Gets the Base velocity of an entity.
+ * The base velocity is the velocity applied
+ * to the entity from other sources .
+ *
+ * @param entity Entity index.
+ * @param vel An 3 dim array
+ */
+stock void Entity_GetBaseVelocity(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Data, "m_vecBaseVelocity", vec);
+}
+
+/**
+ * Sets the Base velocity of an entity.
+ * The base velocity is the velocity applied
+ * to the entity from other sources .
+ *
+ * @param entity Entity index.
+ * @param vel An 3 dim array
+ */
+stock void Entity_SetBaseVelocity(int entity, const float vec[3])
+{
+ SetEntPropVector(entity, Prop_Data, "m_vecBaseVelocity", vec);
+}
+
+/**
+ * Gets the Absolute velocity of an entity.
+ * The absolute velocity is the sum of the local
+ * and base velocities. It's the actual value used to move.
+ *
+ * @param entity Entity index.
+ * @param vel An 3 dim array
+ */
+stock void Entity_GetAbsVelocity(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Data, "m_vecAbsVelocity", vec);
+}
+
+/**
+ * Sets the Absolute velocity of an entity.
+ * The absolute velocity is the sum of the local
+ * and base velocities. It's the actual value used to move.
+ *
+ * @param entity Entity index.
+ * @param vel An 3 dim array
+ */
+stock void Entity_SetAbsVelocity(int entity, const float vec[3])
+{
+ // We use TeleportEntity to set the velocity more safely
+ // Todo: Replace this with a call to CBaseEntity::SetAbsVelocity()
+ TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vec);
+}
+
+/**
+ * Returns true if the entity is locked.
+ *
+ * @param entity Entity index.
+ * @return True if locked otherwise false.
+ */
+stock bool Entity_IsLocked(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_bLocked", 1) != 0;
+}
+
+/**
+ * Locks an entity.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_Lock(int entity)
+{
+ SetEntProp(entity, Prop_Data, "m_bLocked", 1, 1);
+}
+/**
+ * Unlocks an entity.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_UnLock(int entity)
+{
+ SetEntProp(entity, Prop_Data, "m_bLocked", 0, 1);
+}
+
+/**
+ * Gets the health of an entity.
+ *
+ * @param entity entity index.
+ * @return current health points
+ */
+stock int Entity_GetHealth(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_iHealth");
+}
+
+/**
+ * Sets the health of an entity.
+ *
+ * @param entity Entity index.
+ * @param value Health to set (anything above 511 will overload)
+ * @param ignoreMax Ignore the entity's maxhealth setting.
+ * @param kill Kill the entity if health gets to 0.
+ * @return The health the entity actually got set to.
+ */
+stock int Entity_SetHealth(int entity, int value, bool ignoreMax=false, bool kill=true)
+{
+ int health = value;
+
+ if (!ignoreMax) {
+ int maxHealth = Entity_GetMaxHealth(entity);
+
+ if (health > maxHealth) {
+ health = maxHealth;
+ }
+ }
+
+ if (health < 0) {
+ health = 0;
+ }
+
+ SetEntProp(entity, Prop_Data, "m_iHealth", health);
+
+ if (health <= 0) {
+ Entity_Kill(entity);
+ }
+
+ return health;
+}
+
+/**
+ * Add health to an entity
+ *
+ * @param entity Entity index
+ * @param value Health to add
+ * @param ignoreMax Ignore the entity's maxhealth setting.
+ * @param kill Kill the entity if health gets to 0.
+ * @return Returns the new health value set
+ */
+stock int Entity_AddHealth(int entity, int value, bool ignoreMax=false, bool kill=true)
+{
+ int health = Entity_GetHealth(entity);
+
+ health += value;
+
+ return Entity_SetHealth(entity, health, ignoreMax, kill);
+}
+
+/**
+ * Takes health from an entity
+ *
+ * @param entity entity index
+ * @param value health to add
+ * @return returns the new health value set
+ */
+stock int Entity_TakeHealth(int entity, int value, bool ignoreMax=false, bool kill=true)
+{
+ int health = Entity_GetHealth(entity);
+
+ health -= value;
+
+ return Entity_SetHealth(entity, health, ignoreMax, kill);
+}
+
+/**
+ * Get the max health of an entity
+ *
+ * @param entity Entity Index
+ * @return Max health points
+ */
+stock int Entity_GetMaxHealth(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_iMaxHealth");
+}
+
+
+/**
+ * Set the max health of an entity.
+ *
+ * @param entity Entity index
+ * @param value Max health to set (anything above 511 will overload)
+ */
+stock void Entity_SetMaxHealth(int entity, int value)
+{
+ SetEntProp(entity, Prop_Data, "m_iMaxHealth", value);
+}
+
+/**
+ * Returns the Float distance between an entity
+ * and a vector origin.
+ *
+ * @param entity Entity Index.
+ * @param target Vector Origin.
+ * @return Distance Float value.
+ */
+stock float Entity_GetDistanceOrigin(int entity, const float vec[3])
+{
+ float entityVec[3];
+ Entity_GetAbsOrigin(entity, entityVec);
+
+ return GetVectorDistance(entityVec, vec);
+}
+
+/**
+ * Returns the Float distance between two entities.
+ * Both entities must be valid.
+ *
+ * @param entity Entity Index.
+ * @param target Target Entity Index.
+ * @return Distance Float value.
+ */
+stock float Entity_GetDistance(int entity, int target)
+{
+ float targetVec[3];
+ Entity_GetAbsOrigin(target, targetVec);
+
+ return Entity_GetDistanceOrigin(entity, targetVec);
+}
+
+/**
+ * Checks if the given 2 entitys are within a given range.
+ *
+ * @param entity Entity Index.
+ * @param target Target Entity Index.
+ * @param distance Max Float distance.
+ * @return True if the given entities are closer than the given distance value, false otherwise.
+ */
+stock bool Entity_InRange(int entity, int target, float distance)
+{
+ if (Entity_GetDistance(entity, target) > distance) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Enables the motion of an entity.
+ *
+ * @param entity Entity index.
+ * @return True on success, false otherwise
+ */
+stock bool Entity_EnableMotion(int entity)
+{
+ return AcceptEntityInput(entity, "enablemotion");
+}
+
+/**
+ * Disables the motion of an entity.
+ *
+ * @param entity Entity index.
+ * @return True on success, false otherwise
+ */
+stock bool Entity_DisableMotion(int entity)
+{
+ return AcceptEntityInput(entity, "disablemotion");
+}
+
+/**
+ * Freezes an entity by setting the FL_FROZEN flag.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_Freeze(int entity)
+{
+ Entity_AddFlags(entity, FL_FROZEN);
+}
+
+/**
+ * Unfreezes an entity by removing the FL_FROZEN flag.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_UnFreeze(int entity)
+{
+ Entity_RemoveFlags(entity, FL_FROZEN);
+}
+
+
+/**
+ * This function points an entity to another with the targetname
+ * and name. Useful for allot of entities like trigger_teleport.
+ * If the name is not specified it will be generated automatically.
+ *
+ * @param entity Entity index.
+ * @param target Target entity index.
+ * @param Optional: target name
+ */
+stock void Entity_PointAtTarget(int entity, int target, const char[] name="")
+{
+ char targetName[128];
+ Entity_GetTargetName(entity, targetName, sizeof(targetName));
+
+ if (name[0] == '\0') {
+
+ if (targetName[0] == '\0') {
+ // Let's generate our own name
+ Format(
+ targetName,
+ sizeof(targetName),
+ "_smlib_Entity_PointAtTarget:%d",
+ target
+ );
+ }
+ }
+ else {
+ strcopy(targetName, sizeof(targetName), name);
+ }
+
+ Entity_SetTargetName(entity, targetName);
+ Entity_SetName(target, targetName);
+}
+
+/**
+ * This function points a point_hurt entity to another damage target entity..
+ * and name. Useful for allot of entities like trigger_teleport.
+ * If the name is not specified it will be generated automatically.
+ *
+ * @param entity Entity index.
+ * @param target Target entity index.
+ * @param Optional: target name
+ */
+stock void Entity_PointHurtAtTarget(int entity, int target, const char[] name="")
+{
+ char targetName[128];
+ Entity_GetTargetName(entity, targetName, sizeof(targetName));
+
+ if (name[0] == '\0') {
+
+ if (targetName[0] == '\0') {
+ // Let's generate our own name
+ Format(
+ targetName,
+ sizeof(targetName),
+ "_smlib_Entity_PointHurtAtTarget:%d",
+ target
+ );
+ }
+ }
+ else {
+ strcopy(targetName, sizeof(targetName), name);
+ }
+
+ DispatchKeyValue(entity, "DamageTarget", targetName);
+ Entity_SetName(target, targetName);
+}
+
+/**
+ * Checks if an entity is a player or not.
+ * No checks are done if the entity is actually valid,
+ * the player is connected or ingame.
+ *
+ * @param entity Entity index.
+ * @return True if the entity is a player, false otherwise.
+ */
+stock bool Entity_IsPlayer(int entity)
+{
+ if (entity < 1 || entity > MaxClients) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Creates an entity by classname.
+ *
+ * @param className Classname String.
+ * @param ForceEdictIndex Edict Index to use.
+ * @return Entity Index or INVALID_ENT_REFERENCE if the slot is already in use.
+ */
+stock int Entity_Create(const char[] className, int ForceEdictIndex=-1)
+{
+ if (ForceEdictIndex != -1 && Entity_IsValid(ForceEdictIndex)) {
+ return INVALID_ENT_REFERENCE;
+ }
+
+ return CreateEntityByName(className, ForceEdictIndex);
+}
+
+/**
+ * Kills an entity on the next frame (delayed).
+ * It is safe to use with entity loops.
+ * If the entity is is player ForcePlayerSuicide() is called.
+ *
+ * @param kenny Entity index.
+ * @param killChildren When true, kennys children are killed too.
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_Kill(int kenny, bool killChildren=false)
+{
+ if (Entity_IsPlayer(kenny)) {
+ // Oh My God! They Killed Kenny!!
+ ForcePlayerSuicide(kenny);
+ return true;
+ }
+
+ if(killChildren){
+ return AcceptEntityInput(kenny, "KillHierarchy");
+ }
+ else {
+ return AcceptEntityInput(kenny, "Kill");
+ }
+}
+
+/**
+ * Kills all entities with the given networked classname.
+ * It is safe to use with entity loops.
+ * If the entity is is player ForcePlayerSuicide() is called.
+ *
+ * @param className Entity Network Class to search for.
+ * @return Number of entities killed.
+ */
+stock int Entity_KillAllByClassName(const char[] className)
+{
+ int x = 0;
+
+ int entity = INVALID_ENT_REFERENCE;
+ while ((entity = FindEntityByClassname(entity, className)) != INVALID_ENT_REFERENCE) {
+ AcceptEntityInput(entity, "kill");
+ x++;
+ }
+
+ return x;
+}
+
+/**
+ * Gets the owner of an entity.
+ * For example the owner of a weapon entity.
+ *
+ * @param entity Entity index.
+ * @return Ground Entity or -1
+ */
+stock int Entity_GetOwner(int entity)
+{
+ return GetEntPropEnt(entity, Prop_Data, "m_hOwnerEntity");
+}
+
+/**
+ * Sets the owner of an entity.
+ * For example the owner of a weapon entity.
+ *
+ * @param entity Entity index.
+ */
+stock void Entity_SetOwner(int entity, int newOwner)
+{
+ SetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity", newOwner);
+}
+
+/**
+ * Get's the ground entity this entity stands on.
+ *
+ * @param entity Entity index.
+ * @return Ground Entity or -1
+ */
+stock int Entity_GetGroundEntity(int entity)
+{
+ return GetEntPropEnt(entity, Prop_Data, "m_hGroundEntity");
+}
+
+/*
+ * Damage definitions
+ */
+
+#if !defined DMG_GENERIC
+
+#define DMG_GENERIC 0 // generic damage was done
+#define DMG_CRUSH (1 << 0) // crushed by falling or moving object.
+ // NOTE: It's assumed crush damage is occurring as a result of physics collision, so no extra physics force is generated by crush damage.
+ // DON'T use DMG_CRUSH when damaging entities unless it's the result of a physics collision. You probably want DMG_CLUB instead.
+#define DMG_BULLET (1 << 1) // shot
+#define DMG_SLASH (1 << 2) // cut, clawed, stabbed
+#define DMG_BURN (1 << 3) // heat burned
+#define DMG_VEHICLE (1 << 4) // hit by a vehicle
+#define DMG_FALL (1 << 5) // fell too far
+#define DMG_BLAST (1 << 6) // explosive blast damage
+#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt
+#define DMG_SHOCK (1 << 8) // electric shock
+#define DMG_SONIC (1 << 9) // sound pulse shockwave
+#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
+#define DMG_PREVENT_PHYSICS_FORCE (1 << 11) // Prevent a physics force
+#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death
+#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death.
+#define DMG_DROWN (1 << 14) // Drowning
+
+
+#define DMG_PARALYZE (1 << 15) // slows affected creature down
+#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad
+#define DMG_POISON (1 << 17) // blood poisoning - heals over time like drowning damage
+#define DMG_RADIATION (1 << 18) // radiation exposure
+#define DMG_DROWNRECOVER (1 << 19) // drowning recovery
+#define DMG_ACID (1 << 20) // toxic chemicals or acid burns
+#define DMG_SLOWBURN (1 << 21) // in an oven
+
+#define DMG_REMOVENORAGDOLL (1<<22) // with this bit OR'd in, no ragdoll will be created, and the target will be quietly removed.
+ // use this to kill an entity that you've already got a server-side ragdoll for
+
+#define DMG_PHYSGUN (1<<23) // Hit by manipulator. Usually doesn't do any damage.
+#define DMG_PLASMA (1<<24) // Shot by Cremator
+#define DMG_AIRBOAT (1<<25) // Hit by the airboat's gun
+
+#define DMG_DISSOLVE (1<<26) // Dissolving!
+#define DMG_BLAST_SURFACE (1<<27) // A blast on the surface of water that cannot harm things underwater
+#define DMG_DIRECT (1<<28)
+#define DMG_BUCKSHOT (1<<29) // not quite a bullet. Little, rounder, different.
+
+#endif
+
+/**
+ * Does damage to an entity.
+ * This is a powerful function that allows you to specify
+ * who the attacker is, the damage type and also what weapon
+ * should be displayed in the hud kill message.
+ * Note that for entities that fire another entity (RPG's, Crossbow's,
+ * you have to pass the bullet's class, not the weapon's class !
+ * It hasn't been tested how expensive this function is, as it
+ * uses the entity point_hurt.
+ * If you need a cheaper function use Entity_RemoveHealth().
+ *
+ * @param entity Entity index.
+ * @param damage Amount of damage.
+ * @param attacker Entity Index of the attacker.
+ * @param damageType Use the DMG_ definations.
+ * @param fakeClassName Classname to fake, you can set this if you
+ * want a specific weapon to be shown in the HUD kill message.
+ * @param customOrigin Teleport point_hurt to origin before triggering hurt
+ * useful for damage force calculations e.g. explosions, gun fire direction, ect.
+ * @return True on success, false otherwise.
+ */
+stock bool Entity_Hurt(int entity, int damage, int attacker=0, int damageType=DMG_GENERIC, const char[] fakeClassName="", float customOrigin[3]={0.0, 0.0, 0.0})
+{
+ static int point_hurt = INVALID_ENT_REFERENCE;
+
+ if (point_hurt == INVALID_ENT_REFERENCE || !IsValidEntity(point_hurt)) {
+ point_hurt = EntIndexToEntRef(Entity_Create("point_hurt"));
+
+ if (point_hurt == INVALID_ENT_REFERENCE) {
+ return false;
+ }
+
+ DispatchSpawn(point_hurt);
+ }
+
+ AcceptEntityInput(point_hurt, "TurnOn");
+ SetEntProp(point_hurt, Prop_Data, "m_nDamage", damage);
+ SetEntProp(point_hurt, Prop_Data, "m_bitsDamageType", damageType);
+
+ char orignalTargetName[128];
+ Entity_GetName(entity, orignalTargetName, sizeof(orignalTargetName));
+ Entity_PointHurtAtTarget(point_hurt, entity);
+
+ if (fakeClassName[0] != '\0') {
+ Entity_SetClassName(point_hurt, fakeClassName);
+ }
+
+ TeleportEntity(point_hurt, customOrigin, NULL_VECTOR, NULL_VECTOR);
+
+ AcceptEntityInput(point_hurt, "Hurt", attacker);
+ AcceptEntityInput(point_hurt, "TurnOff");
+
+ if (fakeClassName[0] != '\0') {
+ Entity_SetClassName(point_hurt, "point_hurt");
+ }
+
+ DispatchKeyValue(entity, "targetname", orignalTargetName);
+ return true;
+}
+
+/*
+ * Gets the parent entity of an entity.
+ *
+ * @param entity Entity Index.
+ * @return Entity Index of the parent.
+ */
+stock int Entity_GetParent(int entity)
+{
+ return GetEntPropEnt(entity, Prop_Data, "m_pParent");
+}
+
+/*
+ * Clears the parent of an entity.
+ *
+ * @param entity Entity Index.
+ */
+stock void Entity_ClearParent(int entity)
+{
+ //SetVariantString("");
+ AcceptEntityInput(entity, "ClearParent");
+}
+
+/*
+ * Sets the parent entity of an entity.
+ *
+ * @param entity Entity Index.
+ * @param parent Entity Index of the new parent.
+ */
+stock void Entity_SetParent(int entity, int parent)
+{
+ SetVariantString("!activator");
+ AcceptEntityInput(entity, "SetParent", parent);
+}
+
+
+/*
+ * Callback for Change_OverTime.
+ * Note that every parameter is a reference and can be changed during this callback.
+ * You can get the elapsed time since start by multiply tick with currentCall.
+ *
+ * @param entity Entity Index.
+ * @param interval The current interval from the current game time to execute the next call of this function.
+ * @param currentCall The current call number (0 is the 1st call at 0.0 seconds, 1 the 2nd call at tick*1 seconds, ...).
+ * @return When true this callback will be called again at the next defined tick, otherwise it won't.
+ */
+typedef Entity_ChangeOverTimeCallback = function bool (int &entity, float &interval, int &currentCall);
+
+/*
+ * Creates a timer and provides a callback to change various things about an entity over time.
+ *
+ * @param entity Entity Index.
+ * @param interval Interval from the current game time to execute the given function.
+ * @noreturn
+ */
+stock void Entity_ChangeOverTime(int entity, float interval=0.1, Entity_ChangeOverTimeCallback valueCallback)
+{
+ DataPack dataPack = CreateDataPack();
+ WritePackCell(dataPack, EntIndexToEntRef(entity));
+ WritePackFloat(dataPack, interval);
+ WritePackCell(dataPack, 0);
+ WritePackFunction(dataPack, valueCallback);
+ ResetPack(dataPack);
+ __smlib_Timer_ChangeOverTime(INVALID_HANDLE,dataPack);
+}
+
+public Action __smlib_Timer_ChangeOverTime(Handle Timer, DataPack dataPack)
+{
+ int entity = EntRefToEntIndex(ReadPackCell(dataPack));
+ if(!Entity_IsValid(entity)){
+ return Plugin_Stop;
+ }
+
+ float interval = ReadPackFloat(dataPack);
+ int currentCall = ReadPackCell(dataPack);
+ Function callback = ReadPackFunction(dataPack);
+
+ any result;
+ Call_StartFunction(INVALID_HANDLE, callback);
+ Call_PushCellRef(entity);
+ Call_PushFloatRef(interval);
+ Call_PushCellRef(currentCall);
+ Call_Finish(result);
+
+ if(result == false){
+ return Plugin_Stop;
+ }
+
+ ResetPack(dataPack,true);
+ WritePackCell(dataPack, EntIndexToEntRef(entity));
+ WritePackFloat(dataPack, interval);
+ WritePackCell(dataPack, currentCall+1);
+ WritePackFunction(dataPack, callback);
+ ResetPack(dataPack);
+ CreateTimer(interval, __smlib_Timer_ChangeOverTime, dataPack);
+ return Plugin_Stop;
+}
+
+
+/**
+ * Gets the next child, entity is parent of.
+ *
+ * @param parent Entity Index (of Parent)
+ * @param start Start Index.
+ * @return Entity Index or -1 if no entity was found.
+ */
+stock int Entity_GetNextChild(int parent, int start=0)
+{
+ int maxEntities = GetMaxEntities();
+ for (int entity=start; entity < maxEntities; entity++) {
+
+ if (!Entity_IsValid(entity)) {
+ continue;
+ }
+
+ if (entity > 0 && entity <= MaxClients && !IsClientConnected(entity)) {
+ continue;
+ }
+
+ if (Entity_GetParent(entity) == parent) {
+ return entity;
+ }
+ }
+
+ return INVALID_ENT_REFERENCE;
+}
+/**
+ * Gets the move/open direction of an entity (only available for func_door*, prop_door* and func_movelinear).
+ * Ex: if vec[2] is 1.0 a func_door moves straight up.
+ *
+ * @param entity Entity index.
+ * @param vec Vector.
+ */
+stock void Entity_GetMoveDirection(int entity, float vec[3])
+{
+ GetEntPropVector(entity, Prop_Data, "m_vecMoveDir", vec);
+}
+/**
+ * Sets the move/open direction of an entity (only available for func_door*, prop_door* and func_movelinear).
+ * Ex: if vec[2] is 1.0 a func_door moves straight up.
+ *
+ * @param entity Entity index.
+ * @param vec Vector.
+ */
+stock void Entity_SetMoveDirection(int entity, const float vec[3])
+{
+ SetEntPropVector(entity, Prop_Data, "m_vecMoveDir", vec);
+}
+
+/**
+ * Returns if the entity will force close (won't be blockable by players and/or objects) or not when triggered to move.
+ *
+ * @param entity Entity index.
+ * @return True if the door will force close, otherwise false.
+ */
+stock bool Entity_GetForceClose(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_bForceClosed") != 0;
+}
+
+/**
+ * Sets if the door should force close (souldn't be blockable by players and/or objects) or not when triggered to move.
+ *
+ * @param entity Entity index.
+ * @param forceClose If true the door will force close, otherwise it won't.
+ */
+stock void Entity_SetForceClose(int entity, bool forceClose)
+{
+ SetEntProp(entity, Prop_Data, "m_bForceClosed", forceClose);
+}
+
+/**
+ * Gets the speed of a moving entity (like doors: open close speed).
+ *
+ * @param entity Entity index.
+ * @return Speed of the entity.
+ */
+stock float Entity_GetSpeed(int entity)
+{
+ return GetEntPropFloat(entity, Prop_Data, "m_flSpeed");
+}
+
+/**
+ * Sets how fast an entity moves (like doors: open close speed).
+ *
+ * @param entity Entity index.
+ * @param speed The new speed of the entity.
+ */
+stock void Entity_SetSpeed(int entity, float speed)
+{
+ SetEntPropFloat(entity, Prop_Data, "m_flSpeed", speed);
+}
+
+/**
+ * Gets the damage of a moving entity when blocked (like doors when open or close and players and/or objects are between the entity and something else).
+ * Note: Negative values add health to the blocking entity.
+ *
+ * @param entity Entity index.
+ * @return Damage.
+ */
+stock float Entity_GetBlockDamage(int entity)
+{
+ return GetEntPropFloat(entity, Prop_Data, "m_flBlockDamage");
+}
+
+/**
+ * Sets the damage of a moving entity when blocked (like doors when open or close and players and/or objects are between the entity and something else).
+ * Note: Negative values add health to the blocking entity.
+ *
+ * @param entity Entity index.
+ * @param damage Damage.
+ */
+stock void Entity_SetBlockDamage(int entity, float damage)
+{
+ SetEntPropFloat(entity, Prop_Data, "m_flBlockDamage", damage);
+}
+
+/**
+ * Returns if the given entity is disabled or not.
+ *
+ * @param entity Entity index.
+ * @return True if entity is disabled, otherwise false.
+ */
+stock bool Entity_IsDisabled(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_bDisabled", 1) != 0;
+}
+
+/**
+ * Disables the given entity.
+ *
+ * @param entity Entity index.
+ * @return True if successful otherwise false.
+ */
+stock bool Entity_Disable(int entity)
+{
+ return AcceptEntityInput(entity, "Disable");
+}
+
+/**
+ * Enables the given entity.
+ *
+ * @param entity Entity index.
+ * @return True if successful otherwise false.
+ */
+stock bool Entity_Enable(int entity)
+{
+ return AcceptEntityInput(entity, "Enable");
+}
+
+
+// settings for m_takedamage taken from hl2sdk-ob-valve\game\shared\shareddefs.h
+#define DAMAGE_NO 0
+#define DAMAGE_EVENTS_ONLY 1 // Call damage functions, but don't modify health
+#define DAMAGE_YES 2
+#define DAMAGE_AIM 3
+
+/**
+ * Sets the mode for an entity to take damage.
+ * Note: This is used to give a client god mode (DAMAGE_NO).
+ *
+ * @param entity Entity index.
+ * @param value Mode, use DAMAGE_* defines.
+ */
+stock void Entity_SetTakeDamage(int entity, int value)
+{
+ SetEntProp(entity, Prop_Data, "m_takedamage", value, 1);
+}
+
+/**
+ * Gets the mode for an entity to take damage.
+ * Note: When the return value is DAMAGE_NO then the client is using godmode.
+ *
+ * @param entity Entity index.
+ * @return Take damage mode (DAMAGE_*).
+ */
+stock int Entity_GetTakeDamage(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_takedamage", 1);
+}
+
+/**
+ * Sets the minimum of damage required to hurt this entity.
+ * Example: This is used to block any damage done by projectile weapons against a gun ship in Half-Life 2.
+ *
+ * @param entity Entity index.
+ * @param minDamage Minimum required damage.
+ */
+stock void Entity_SetMinHealthDamage(int entity, int minDamage)
+{
+ SetEntProp(entity, Prop_Data, "m_iMinHealthDmg", minDamage);
+}
+
+/**
+ * Gets the minimum of damage required to hurt this entity.
+ * Example: This is used to block any damage done by projectile weapons against a gun ship in Half-Life 2.
+ *
+ * @param entity Entity index.
+ * @return Minimum required damage.
+ */
+stock int Entity_GetMinHealthDamage(int entity)
+{
+ return GetEntProp(entity, Prop_Data, "m_iMinHealthDmg");
+}
+
+/**
+ * Gets an entity's color.
+ *
+ * @param entity Entity index
+ * @param color 4 dimensional array where [r,g,b,a] values are stored
+ * @error Invalid entity index, or lack of mod compliance.
+ */
+stock void Entity_GetRenderColor(int entity, int color[4])
+{
+ static bool gotconfig = false;
+ static char prop[32];
+
+ if (!gotconfig) {
+ Handle gc = LoadGameConfigFile("core.games");
+ bool exists = GameConfGetKeyValue(gc, "m_clrRender", prop, sizeof(prop));
+ delete gc;
+
+ if (!exists) {
+ strcopy(prop, sizeof(prop), "m_clrRender");
+ }
+
+ gotconfig = true;
+ }
+
+ int offset = GetEntSendPropOffs(entity, prop);
+
+ if (offset <= 0) {
+ ThrowError("SetEntityRenderColor not supported by this mod");
+ }
+
+ for (int i=0; i < 4; i++) {
+ color[i] = GetEntData(entity, offset + i, 1);
+ }
+}
+
+/**
+ * Sets an entity's color.
+ * Doesn't change the value, if set to -1.
+ *
+ * @param entity Entity index
+ * @param r Amount of red (0-255)
+ * @param g Amount of green (0-255)
+ * @param b Amount of blue (0-255)
+ * @param a Amount of alpha (0-255)
+ * @error Invalid entity index, or lack of mod compliance.
+ */
+stock void Entity_SetRenderColor(int entity, int r=-1, int g=-1, int b=-1, int a=-1)
+{
+ static bool gotconfig = false;
+ static char prop[32];
+
+ if (!gotconfig) {
+ Handle gc = LoadGameConfigFile("core.games");
+ bool exists = GameConfGetKeyValue(gc, "m_clrRender", prop, sizeof(prop));
+ delete gc;
+
+ if (!exists) {
+ strcopy(prop, sizeof(prop), "m_clrRender");
+ }
+
+ gotconfig = true;
+ }
+
+ int offset = GetEntSendPropOffs(entity, prop);
+
+ if (offset <= 0) {
+ ThrowError("SetEntityRenderColor not supported by this mod");
+ }
+
+ if(r != -1) {
+ SetEntData(entity, offset, r, 1, true);
+ }
+
+ if(g != -1) {
+ SetEntData(entity, offset + 1, g, 1, true);
+ }
+
+ if(b != -1) {
+ SetEntData(entity, offset + 2, b, 1, true);
+ }
+
+ if(a != -1) {
+ SetEntData(entity, offset + 3, a, 1, true);
+ }
+}
+
+/**
+ * Sends the 'addouput' command to an entity.
+ *
+ * @param entity Entity Index.
+ * @param input Input command.
+ * @param activator Entity index which initiated the sequence of actions (-1 for a NULL entity).
+ * @param caller Entity index from which this event is sent (-1 for a NULL entity).
+ * @param outputid Unknown.
+ * @return True if successful, otherwise false.
+ */
+stock bool Entity_AddOutput(int entity, const char[] input, int activator=-1, int caller=-1, int outputid=0)
+{
+ SetVariantString(input);
+ return AcceptEntityInput(entity, "addoutput", activator, caller, outputid);
+}