I have created a set of stocks for you to use in your plugins to play with Entities
You will need a copy of PimpinJuice's sigscan extension:
http://forums.alliedmods.net/showthread.php?t=53893
All of the signatures have been taken from my big list:
http://forums.alliedmods.net/showthread.php?t=55565 So check here if you want to do some more hacking
Ok...
If you are creating a plugin with these stocks, you will need to include the following:
Code:
#include <sourcemod>
#include <sigoffset>
#include <entity>
#include <clients>
And have the following globals:
Code:
new ScanCreateIndex, ScanTeleportIndex, ScanSpawnIndex, ScanSetModelIndex, ScanRemoveIndex;
new MyEntity;
InitEntitySigs
This stock will scan the memory for the required functions you need for these few stocks.
Code:
/**
* Scans the memory for the required functions
* MUST be called first!
* @return 1 on success, 0 on error;
*/
stock InitEntitySigs()
{
ScanCreateIndex = SignatureScanFind("CreateEntityByName",
"\x56\x8b\x74\x24\x0c\x83\xfe\xff\x57\x8b\x7c\x24\x0c\x74\x25\x8b\x0d\x68\x69\x5f\x22\x8b\x01\x56\xff\x50\x54\x85\xc0\xa3\x9c\xfa\x5c\x22\x75\x10\x56\x57\x68\x08\x6d\x4e\x22\xff\x15\xfc\xb1\x48\x22\x83\xc4\x0c",
"xxxxxxxxxxxxx??xxxxxxxxx???xx???????xx???????????xxx",
52,
"_Z18CreateEntityByNamePKci");
ScanSpawnIndex = SignatureScanFind("DispatchSpawn",
"\x53\x55\x56\x8b\x74\x24\x10\x85\xf6\x57\x0f\x84\x3a\x01\x00\x00\x8b\x1d\xa4\x69\x5f\x22\x8b\x03\x8b\xcb\xff\x50\x60\x8b\x16\x8b\xce\xff\x52\x08\x8b\x0d\xa4\x69\x5f\x22\x8b\x28",
"xxxxxxxxxx????????????xxxxxxxxxxxxxxxxxxxxxx",
44,
"_Z13DispatchSpawnP11CBaseEntity");
ScanTeleportIndex = SignatureScanFind("CBaseEntity::Teleport",
"\x83\xEC\x18\x53\x56\x8B\xD9\x8B\x0D\x78\xB2\x46\x22\x33\xF6\x33\xC0\x3B\xCE\x7E\x21\x8B\x15\x6C\xB2\x46\x22\xEB\x03\x8D\x49\x00\x39\x1C\x82\x74\x09\x83\xC0\x01\x3B\xC1\x7C\xF4\xEB\x08\x3B\xC6\x0F\x8D\x17\x01\x00\x00\x55\x57\x8D\x44\x24\x10\x50\x51\xB9\x6C\xB2\x46\x22\x89\x5C\x24\x18\xE8\xB4\x88\xF9\xFF\x8D\x4C\x24\x14\x51\x53\x89\x44\x24\x18\x89\x74\x24\x1C\x89\x74\x24\x20\x89\x74\x24\x24\x89\x74\x24\x28\x89\x74\x24\x2C",
"xxxxxxx??????xxxxxx?????????????xxx?????xx????xx??????x?????xx?????xxxx?????????xxxxxxxxxxxxxxxxxxxxxxxxxx",
106,
"_ZN11CBaseEntity8TeleportEPK6VectorPK6QAngleS");
ScanSetModelIndex = SignatureScanFind("CBaseEntity::SetModel",
"\x56\x8b\x74\x24\x08\x57\x8b\xf9\x8b\x0d\x8c\x69\x5f\x22\x8b\x01\x56\xff\x50\x08\x8b\x0d\x8c\x69\x5f\x22\x8b\x11\x50\xff\x52\x04\x85\xc0\x74\x20\x8b\x0d\x8c\x69\x5f\x22\x8b\x11\x50\xff\xf2\x24\x83\xf8\x01",
"xxxxxxxx??????xxx?????????xxx???xx????????xxx??xxxx",
51,
"_ZN11CBaseEntity8SetModelEPKc");
ScanRemoveIndex = SignatureScanFind("UTIL_Remove",
"\x8b\x44\x24\x04\x85\xc0\x74\x0e\x05\x48\x01\x00\x00\x89\x44\x24\x04\xe9\x7a\xff\xff\xff\xc3",
"xxxxxx???????xxxx?????x",
23,
"_Z11UTIL_RemoveP11CBaseEntity");
return !(ScanCreateIndex == -1 || ScanSpawnIndex == -1 || ScanTeleportIndex == -1 || ScanSetModelIndex == -1 || ScanRemoveIndex == -1);
}
CreateEntity
This stock will allow you to create a new entity. The class name that you need to specify is the 'type' of entity to create. For example:
prop_ragdoll,
hostage_entity. A list of these can be found from HAMMER in the SDK tools.
Code:
/**
* Creates the entity from the given class name
* @param EntClass The class of entity to create, eg: prop_ragdol, weapon_awp...
* @return the edict index.
*/
stock CreateEntity(String:EntClass[])
{
for(new i = 64;i<4096;++i)
{
if(IsValidEntity(i))
continue;
else
{
return SignatureScan_HandleToIndex(
SignatureScanCall_NoIndex(ScanCreateIndex,
PARAM_CONST_CHAR_PTR, EntClass,
PARAM_INT, i));
}
}
}
SpawnEntity
This stock will spawn the entity that you created earlier into the world at the desired location.
Code:
/**
* Spawns the entity
* @param entity The entity ID.
* @param Vector:origin the place the entity should spawn at.
* @param Vector:velocity the velocity to move the entity.
* @return 1 on success, 0 on error.
*/
stock SpawnEntity(entity, Float:origin[], angle, Float:velocity[])
{
if (!IsValidEntity(entity) ||
ScanSpawnIndex == -1 ||
ScanTeleportIndex == -1)
return 0;
// Spawn it
SignatureScanCall_NoIndex(ScanSpawnIndex,
PARAM_CBASEENTITY,
entity);
// Teleport the entity
SignatureScanCall(ScanTeleportIndex,
entity, SIGTYPE_CBASEENTITY,
PARAM_VECTOR, origin,
PARAM_QANGLE, angle,
PARAM_VECTOR, velocity);
return 1;
}
RemoveEntity
This stock will completely unload and remove an entity from the world
Code:
/**
* Removes the entity from the world
* @param entity The entity id to remove
* @return 1 on success, 0 on error.
*/
stock RemoveEntity(entity)
{
if (!IsValidEntity(entity) ||
ScanRemoveIndex == -1)
return 0;
SignatureScanCall_NoIndex(ScanRemoveIndex,
PARAM_CBASEENTITY,
entity);
return 1;
}
EntityModel
This stock will change the model of the current entity. Precaching is done inside this stock ;)
Code:
/**
* Sets an entities model
* @param entity The entity id to change
* @param String:model The model to change it to
* @return 1 on success, 0 on error.
*/
stock EntityModel(entity, String:model[])
{
if (!IsValidEntity(entity) ||
ScanSetModelIndex == -1)
return 0;
PrecacheModel(model, true);
SignatureScanCall(ScanSetModelIndex, entity, SIGTYPE_CBASEENTITY,
PARAM_CONST_CHAR_PTR, model);
return 1;
}
-----------------------------------------------------------------------
Sample Plugin
This is a small sample plugin that i have made just to show you how all of this would look in a plugin
Code:
#include <sourcemod>
#include <sigoffset>
#include <entity>
#include <clients>
#pragma semicolon 1
new ScanCreateIndex, ScanTeleportIndex, ScanSpawnIndex, ScanSetModelIndex, ScanRemoveIndex;
new MyEntity;
public OnPluginStart()
{
RegConsoleCmd("dropdoll", DropRagDoll);
}
public Action:DropRagDoll(client, args)
{
// Find our functions
InitEntitySigs();
// Create our ragdoll entity
MyEntity = CreateEntity("prop_ragdoll");
new Float:vec[3];
// Get our location
GetClientAbsOrigin(client, vec);
// Offset a little
vec[0] += 5;
vec[1] += 5;
vec[2] += 5;
// Give the ragdoll a model so we can see it
EntityModel(MyEntity, "models/Alyx.mdl");
// Spawn the entity at our location +5
SpawnEntity(MyEntity, vec, -1, vec);
}
/**
* Scans the memory for the required functions
* MUST be called first!
* @return 1 on success, 0 on error;
*/
stock InitEntitySigs()
{
ScanCreateIndex = SignatureScanFind("CreateEntityByName",
"\x56\x8b\x74\x24\x0c\x83\xfe\xff\x57\x8b\x7c\x24\x0c\x74\x25\x8b\x0d\x68\x69\x5f\x22\x8b\x01\x56\xff\x50\x54\x85\xc0\xa3\x9c\xfa\x5c\x22\x75\x10\x56\x57\x68\x08\x6d\x4e\x22\xff\x15\xfc\xb1\x48\x22\x83\xc4\x0c",
"xxxxxxxxxxxxx??xxxxxxxxx???xx???????xx???????????xxx",
52,
"_Z18CreateEntityByNamePKci");
ScanSpawnIndex = SignatureScanFind("DispatchSpawn",
"\x53\x55\x56\x8b\x74\x24\x10\x85\xf6\x57\x0f\x84\x3a\x01\x00\x00\x8b\x1d\xa4\x69\x5f\x22\x8b\x03\x8b\xcb\xff\x50\x60\x8b\x16\x8b\xce\xff\x52\x08\x8b\x0d\xa4\x69\x5f\x22\x8b\x28",
"xxxxxxxxxx????????????xxxxxxxxxxxxxxxxxxxxxx",
44,
"_Z13DispatchSpawnP11CBaseEntity");
ScanTeleportIndex = SignatureScanFind("CBaseEntity::Teleport",
"\x83\xEC\x18\x53\x56\x8B\xD9\x8B\x0D\x78\xB2\x46\x22\x33\xF6\x33\xC0\x3B\xCE\x7E\x21\x8B\x15\x6C\xB2\x46\x22\xEB\x03\x8D\x49\x00\x39\x1C\x82\x74\x09\x83\xC0\x01\x3B\xC1\x7C\xF4\xEB\x08\x3B\xC6\x0F\x8D\x17\x01\x00\x00\x55\x57\x8D\x44\x24\x10\x50\x51\xB9\x6C\xB2\x46\x22\x89\x5C\x24\x18\xE8\xB4\x88\xF9\xFF\x8D\x4C\x24\x14\x51\x53\x89\x44\x24\x18\x89\x74\x24\x1C\x89\x74\x24\x20\x89\x74\x24\x24\x89\x74\x24\x28\x89\x74\x24\x2C",
"xxxxxxx??????xxxxxx?????????????xxx?????xx????xx??????x?????xx?????xxxx?????????xxxxxxxxxxxxxxxxxxxxxxxxxx",
106,
"_ZN11CBaseEntity8TeleportEPK6VectorPK6QAngleS");
ScanSetModelIndex = SignatureScanFind("CBaseEntity::SetModel",
"\x56\x8b\x74\x24\x08\x57\x8b\xf9\x8b\x0d\x8c\x69\x5f\x22\x8b\x01\x56\xff\x50\x08\x8b\x0d\x8c\x69\x5f\x22\x8b\x11\x50\xff\x52\x04\x85\xc0\x74\x20\x8b\x0d\x8c\x69\x5f\x22\x8b\x11\x50\xff\xf2\x24\x83\xf8\x01",
"xxxxxxxx??????xxx?????????xxx???xx????????xxx??xxxx",
51,
"_ZN11CBaseEntity8SetModelEPKc");
ScanRemoveIndex = SignatureScanFind("UTIL_Remove",
"\x8b\x44\x24\x04\x85\xc0\x74\x0e\x05\x48\x01\x00\x00\x89\x44\x24\x04\xe9\x7a\xff\xff\xff\xc3",
"xxxxxx???????xxxx?????x",
23,
"_Z11UTIL_RemoveP11CBaseEntity");
return !(ScanCreateIndex == -1 || ScanSpawnIndex == -1 || ScanTeleportIndex == -1 || ScanSetModelIndex == -1 || ScanRemoveIndex == -1);
}
/**
* Creates the entity from the given class name
* @param EntClass The class of entity to create, eg: prop_ragdol, weapon_awp...
* @return the edict index.
*/
stock CreateEntity(String:EntClass[])
{
for(new i = 64;i<4096;++i)
{
if(IsValidEntity(i))
continue;
else
{
return SignatureScan_HandleToIndex(
SignatureScanCall_NoIndex(ScanCreateIndex,
PARAM_CONST_CHAR_PTR, EntClass,
PARAM_INT, i));
}
}
}
/**
* Spawns the entity
* @param entity The entity ID.
* @param Vector:origin the place the entity should spawn at.
* @param Vector:velocity the velocity to move the entity.
* @return 1 on success, 0 on error.
*/
stock SpawnEntity(entity, Float:origin[], angle, Float:velocity[])
{
if (!IsValidEntity(entity) ||
ScanSpawnIndex == -1 ||
ScanTeleportIndex == -1)
return 0;
// Spawn it
SignatureScanCall_NoIndex(ScanSpawnIndex,
PARAM_CBASEENTITY,
entity);
// Teleport the entity
SignatureScanCall(ScanTeleportIndex,
entity, SIGTYPE_CBASEENTITY,
PARAM_VECTOR, origin,
PARAM_QANGLE, angle,
PARAM_VECTOR, velocity);
return 1;
}
/**
* Removes the entity from the world
* @param entity The entity id to remove
* @return 1 on success, 0 on error.
*/
stock RemoveEntity(entity)
{
if (!IsValidEntity(entity) ||
ScanRemoveIndex == -1)
return 0;
SignatureScanCall_NoIndex(ScanRemoveIndex,
PARAM_CBASEENTITY,
entity);
return 1;
}
/**
* Sets an entities model
* @param entity The entity id to change
* @param String:model The model to change it to
* @return 1 on success, 0 on error.
*/
stock EntityModel(entity, String:model[])
{
if (!IsValidEntity(entity) ||
ScanSetModelIndex == -1)
return 0;
PrecacheModel(model);
SignatureScanCall(ScanSetModelIndex, entity, SIGTYPE_CBASEENTITY,
PARAM_CONST_CHAR_PTR, model);
return 1;
}
// Yarrrr!
This is the result of this plugin:
[IMG]http://img513.**************/img513/6973/dedust0013rc6.jpg[/IMG]