Forgot to update SVN with TS3.0 and RegisterHamFromEntity changes

This commit is contained in:
Steve Dudenhoeffer 2007-07-19 18:43:27 +00:00
parent 4b02ffa920
commit 2cbf7fca08
12 changed files with 475 additions and 203 deletions

View File

@ -64,6 +64,7 @@ void OnAmxxAttach(void)
assert(strcmp(hooklist[Ham_Weapon_ExtractAmmo].name, "weapon_extractammo")==0); assert(strcmp(hooklist[Ham_Weapon_ExtractAmmo].name, "weapon_extractammo")==0);
assert(strcmp(hooklist[Ham_TS_BreakableRespawn].name, "ts_breakablerespawn")==0); assert(strcmp(hooklist[Ham_TS_BreakableRespawn].name, "ts_breakablerespawn")==0);
assert(strcmp(hooklist[Ham_NS_UpdateOnRemove].name, "ns_updateonremove")==0); assert(strcmp(hooklist[Ham_NS_UpdateOnRemove].name, "ns_updateonremove")==0);
assert(strcmp(hooklist[Ham_TS_ShouldCollide].name, "ts_shouldcollide")==0);
MF_AddNatives(pdata_natives_safe); MF_AddNatives(pdata_natives_safe);
if (ReadConfig() > 0) if (ReadConfig() > 0)

View File

@ -624,3 +624,20 @@ cell Call_Float_Void(AMX *amx, cell *params)
return 1; return 1;
} }
cell Call_Void_Float_Int(AMX* amx, cell* params)
{
SETUP(2);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, float, char)>(__func)(pv, 0, amx_ctof2(params[3]), static_cast<char>(params[4]));
#elif defined __linux__
reinterpret_cast<void (*)(void*, float, char)>(__func)(pv, amx_ctof2(params[3]), static_cast<char>(params[4]));
#endif
return 1;
}
cell Call_Deprecated(AMX *amx, cell *params)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Ham function is deprecated.");
return 0;
}

View File

@ -86,4 +86,8 @@ cell Call_Void_ItemInfo(AMX *amx, cell *params);
cell Call_Float_Void(AMX *amx, cell *params); cell Call_Float_Void(AMX *amx, cell *params);
cell Call_Void_Float_Int(AMX* amx, cell* params);
cell Call_Deprecated(AMX* amx, cell* params);
#endif #endif

View File

@ -922,220 +922,229 @@
pev 0 pev 0
base 0x60 base 0x60
spawn 5 spawn 9
precache 6 precache 10
keyvalue 7 keyvalue 11
objectcaps 10 objectcaps 14
activate 11 activate 15
setobjectcollisionbox 12 setobjectcollisionbox 18
classify 13 classify 19
deathnotice 14 deathnotice 20
traceattack 15 traceattack 21
takedamage 16 takedamage 22
takehealth 17 takehealth 23
killed 18 killed 24
bloodcolor 19 bloodcolor 25
tracebleed 20 tracebleed 26
istriggered 21 istriggered 27
mymonsterpointer 22 mymonsterpointer 28
mysquadmonsterpointer 23 mysquadmonsterpointer 29
gettogglestate 24 gettogglestate 30
addpoints 25 addpoints 31
addpointstoteam 26 addpointstoteam 32
addplayeritem 27 addplayeritem 33
removeplayeritem 28 removeplayeritem 34
giveammo 29 giveammo 35
getdelay 30 getdelay 36
ismoving 31 ismoving 37
overridereset 32 overridereset 38
damagedecal 33 damagedecal 39
settogglestate 34 settogglestate 40
startsneaking 35 startsneaking 41
stopsneaking 36 stopsneaking 42
oncontrols 37 oncontrols 43
issneaking 38 issneaking 44
isalive 39 isalive 45
isbspmodel 40 isbspmodel 46
reflectgauss 41 reflectgauss 47
hastarget 42 hastarget 48
isinworld 43 isinworld 49
isplayer 44 isplayer 50
isnetclient 45 isnetclient 51
teamid 46 teamid 52
getnexttarget 47 getnexttarget 53
think 48 think 54
touch 49 touch 55
use 50 use 56
blocked 51 blocked 57
respawn 52 respawn 59
updateowner 53 updateowner 60
fbecomeprone 54 fbecomeprone 61
center 55 center 62
eyeposition 56 eyeposition 63
earposition 57 earposition 64
bodytarget 58 bodytarget 65
illumination 59 illumination 66
fvisible 60 fvisible 67
fvecvisible 61 fvecvisible 68
player_jump 79 player_jump 86
player_duck 80 player_duck 87
player_prethink 81 player_prethink 88
player_postthink 82 player_postthink 89
player_getgunposition 83 player_getgunposition 90
player_shouldfadeondeath 70 player_shouldfadeondeath 77
player_impulsecommands 85 player_impulsecommands 92
player_updateclientdata 84 player_updateclientdata 91
item_addtoplayer 63 item_addtoplayer 70
item_addduplicate 64 item_addduplicate 71
item_getiteminfo 65 item_candeploy 73
item_candeploy 66 item_deploy 74
item_deploy 67 item_canholster 75
item_canholster 68 item_holster 76
item_holster 69 item_updateiteminfo 77
item_updateiteminfo 70 item_preframe 78
item_preframe 71 item_postframe 79
item_postframe 72 item_drop 80
item_drop 73 item_kill 81
item_kill 74 item_attachtoplayer 82
item_attachtoplayer 75 item_primaryammoindex 83
item_primaryammoindex 76 item_secondaryammoindex 84
item_secondaryammoindex 77 item_updateclientdata 85
item_updateclientdata 78 item_getweaponptr 86
item_getweaponptr 79 item_itemslot 87
item_itemslot 80
weapon_extractammo 81 weapon_extractammo 88
weapon_extractclipammo 82 weapon_extractclipammo 89
weapon_addweapon 83 weapon_addweapon 90
weapon_playemptysound 84 weapon_playemptysound 91
weapon_resetemptysound 85 weapon_resetemptysound 92
weapon_sendweaponanim 86 weapon_sendweaponanim 93
weapon_isusable 87 weapon_isusable 94
weapon_primaryattack 88 weapon_primaryattack 95
weapon_secondaryattack 89 weapon_secondaryattack 96
weapon_reload 91 weapon_reload 98
weapon_weaponidle 92 weapon_weaponidle 99
weapon_retireweapon 93 weapon_retireweapon 100
weapon_shouldweaponidle 94 weapon_shouldweaponidle 101
weapon_usedecrement 95 weapon_usedecrement 102
ts_breakablerespawn 2 ts_breakablerespawn 2
ts_canusedthroughwalls 3 ts_canusedthroughwalls 3
ts_respawnwait 4 ts_giveslowmul 4
ts_weapon_alternateattack 90 ts_goslow 5
ts_inslow 6
ts_isobjective 7
ts_enableobjective 8
ts_onfreeentprivatedata 12
ts_shouldcollide 13
ts_weapon_alternateattack 97
@end @end
@section ts windows @section ts windows
pev 4 pev 4
base 0x0 base 0x0
ts_breakablerespawn 0 spawn 7
ts_canusedthroughwalls 1 precache 8
ts_respawnwait 2 keyvalue 9
spawn 3 objectcaps 12
precache 4 activate 13
keyvalue 5 setobjectcollisionbox 16
objectcaps 8 classify 17
activate 9 deathnotice 18
setobjectcollisionbox 10 traceattack 19
classify 11 takedamage 20
deathnotice 12 takehealth 21
traceattack 13 killed 22
takedamage 14 bloodcolor 23
takehealth 15 tracebleed 24
killed 16 istriggered 25
bloodcolor 17 mymonsterpointer 26
tracebleed 18 mysquadmonsterpointer 27
istriggered 19 gettogglestate 28
mymonsterpointer 20 addpoints 29
mysquadmonsterpointer 21 addpointstoteam 30
gettogglestate 22 addplayeritem 31
addpoints 23 removeplayeritem 32
addpointstoteam 24 giveammo 33
addplayeritem 25 getdelay 34
removeplayeritem 26 ismoving 35
giveammo 27 overridereset 36
getdelay 28 damagedecal 37
ismoving 29 settogglestate 38
overridereset 30 startsneaking 39
damagedecal 31 stopsneaking 40
settogglestate 32 oncontrols 41
startsneaking 33 issneaking 42
stopsneaking 34 isalive 43
oncontrols 35 isbspmodel 44
issneaking 36 reflectgauss 45
isalive 37 hastarget 46
isbspmodel 38 isinworld 47
reflectgauss 39 isplayer 48
hastarget 40 isnetclient 49
isinworld 41 teamid 50
isplayer 42 getnexttarget 51
isnetclient 43 think 52
teamid 44 touch 53
getnexttarget 45 use 54
think 46 blocked 55
touch 47 respawn 57
use 48 updateowner 58
blocked 49 fbecomeprone 59
respawn 50 center 60
updateowner 51 eyeposition 61
fbecomeprone 52 earposition 62
center 53 bodytarget 63
eyeposition 54 illumination 64
earposition 55 fvisible 65
bodytarget 56 fvecvisible 66
illumination 57
fvisible 58
fvecvisible 59
player_jump 77 player_jump 84
player_duck 78 player_duck 85
player_prethink 79 player_prethink 86
player_postthink 80 player_postthink 87
player_getgunposition 81 player_getgunposition 88
player_shouldfadeondeath 68 player_shouldfadeondeath 75
player_impulsecommands 83 player_impulsecommands 90
player_updateclientdata 82 player_updateclientdata 89
item_addtoplayer 61 item_addtoplayer 68
item_addduplicate 62 item_addduplicate 69
item_getiteminfo 63 item_candeploy 71
item_candeploy 64 item_deploy 72
item_deploy 65 item_canholster 73
item_canholster 66 item_holster 74
item_holster 67 item_updateiteminfo 75
item_updateiteminfo 68 item_preframe 76
item_preframe 69 item_postframe 77
item_postframe 70 item_drop 78
item_drop 71 item_kill 79
item_kill 72 item_attachtoplayer 80
item_attachtoplayer 73 item_primaryammoindex 81
item_primaryammoindex 74 item_secondaryammoindex 82
item_secondaryammoindex 75 item_updateclientdata 83
item_updateclientdata 76 item_getweaponptr 84
item_getweaponptr 77 item_itemslot 85
item_itemslot 78
weapon_extractammo 79 weapon_extractammo 86
weapon_extractclipammo 80 weapon_extractclipammo 87
weapon_addweapon 81 weapon_addweapon 88
weapon_playemptysound 82 weapon_playemptysound 89
weapon_resetemptysound 83 weapon_resetemptysound 90
weapon_sendweaponanim 84 weapon_sendweaponanim 91
weapon_isusable 85 weapon_isusable 92
weapon_primaryattack 86 weapon_primaryattack 93
weapon_secondaryattack 87 weapon_secondaryattack 94
weapon_reload 89 weapon_reload 96
weapon_weaponidle 90 weapon_weaponidle 97
weapon_retireweapon 91 weapon_retireweapon 98
weapon_shouldweaponidle 92 weapon_shouldweaponidle 99
weapon_usedecrement 93 weapon_usedecrement 100
ts_breakablerespawn 0 ts_breakablerespawn 0
ts_canusedthroughwalls 1 ts_canusedthroughwalls 1
ts_respawnwait 2 ts_giveslowmul 2
ts_weapon_alternateattack 88 ts_goslow 3
ts_inslow 4
ts_isobjective 5
ts_enableobjective 6
ts_onfreeentprivatedata 10
ts_shouldcollide 11
ts_weapon_alternateattack 95
@end @end
; Sven-Coop has no linux binaries. This makes disassembly much harder. ; Sven-Coop has no linux binaries. This makes disassembly much harder.

View File

@ -175,6 +175,13 @@ enum
Ham_NS_ResetEntity, Ham_NS_ResetEntity,
Ham_NS_UpdateOnRemove, Ham_NS_UpdateOnRemove,
Ham_TS_GiveSlowMul,
Ham_TS_GoSlow,
Ham_TS_InSlow,
Ham_TS_IsObjective,
Ham_TS_EnableObjective,
Ham_TS_OnFreeEntPrivateData,
Ham_TS_ShouldCollide,
HAM_LAST_ENTRY_DONT_USE_ME_LOL HAM_LAST_ENTRY_DONT_USE_ME_LOL
}; };

View File

@ -970,7 +970,6 @@ float Hook_Float_Void(Hook *hook, void *pthis)
origret=reinterpret_cast<float (*)(void*)>(hook->func)(pthis); origret=reinterpret_cast<float (*)(void*)>(hook->func)(pthis);
#endif #endif
fflush(stdout);
POST_START() POST_START()
POST_END() POST_END()
@ -980,3 +979,30 @@ float Hook_Float_Void(Hook *hook, void *pthis)
CHECK_RETURN() CHECK_RETURN()
return ret; return ret;
} }
void Hook_Void_Float_Int(Hook* hook, void* pthis, float f1, int i1)
{
PUSH_VOID()
MAKE_VECTOR()
P_FLOAT(f1)
P_INT(i1)
PRE_START()
, f1, i1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, float, int)>(hook->func)(pthis, 0, f1, i1);
#elif defined __linux__
reinterpret_cast<void (*)(void*, float, int)>(hook->func)(pthis, f1, i1);
#endif
POST_START()
, f1, i1
POST_END()
KILL_VECTOR()
POP()
}
void Hook_Deprecated(Hook* hook)
{
}

View File

@ -174,4 +174,14 @@ const bool RT_Float_Void = false;
const int PC_Float_Void = 0; const int PC_Float_Void = 0;
float Hook_Float_Void(Hook *hook, void *pthis); float Hook_Float_Void(Hook *hook, void *pthis);
const bool RT_Void_Float_Int = true;
const int PC_Void_Float_Int = 2;
void Hook_Void_Float_Int(Hook *hook, void *pthis, float f1, int i1);
const bool RT_Deprecated = true;
const int PC_Deprecated = 0;
void Hook_Deprecated(Hook* hook);
#endif #endif

View File

@ -167,3 +167,11 @@ int Create_Float_Void(AMX *amx, const char *func)
{ {
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE); return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE);
} }
int Create_Void_Float_Int(AMX* amx, const char* func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_FLOAT, FP_CELL, FP_DONE);
}
int Create_Deprecated(AMX* amx, const char* func)
{
return -1;
}

View File

@ -86,4 +86,9 @@ int Create_Void_ItemInfo(AMX *amx, const char *func);
int Create_Float_Void(AMX *amx, const char *func); int Create_Float_Void(AMX *amx, const char *func);
int Create_Void_Float_Int(AMX *amx, const char *func);
int Create_Deprecated(AMX* amx, const char* func);
#endif #endif

View File

@ -164,7 +164,7 @@ hook_t hooklist[] =
/* The Specialists */ /* The Specialists */
{ V("ts_breakablerespawn", Int_Int) }, { V("ts_breakablerespawn", Int_Int) },
{ V("ts_canusedthroughwalls", Int_Void) }, { V("ts_canusedthroughwalls", Int_Void) },
{ V("ts_respawnwait", Int_Void) }, { V("ts_respawnwait", Deprecated) },
/* Counter-Strike */ /* Counter-Strike */
{ V("cstrike_restart", Void_Void) }, { V("cstrike_restart", Void_Void) },
@ -203,6 +203,14 @@ hook_t hooklist[] =
{ V("ns_resetentity", Void_Void) }, { V("ns_resetentity", Void_Void) },
{ V("ns_updateonremove", Void_Void) }, { V("ns_updateonremove", Void_Void) },
{ V("ts_giveslowmul", Void_Void) },
{ V("ts_goslow", Void_Float_Int) },
{ V("ts_inslow", Int_Void) },
{ V("ts_isobjective", Int_Void) },
{ V("ts_enableobjective", Void_Int) },
{ V("ts_onfreeentprivatedata", Void_Void) },
{ V("ts_shouldcollide", Int_Cbase) },
}; };
@ -307,6 +315,103 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
return reinterpret_cast<cell>(pfwd); return reinterpret_cast<cell>(pfwd);
} }
// RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0);
static cell AMX_NATIVE_CALL RegisterHamFromEntity(AMX *amx, cell *params)
{
// Make sure the function we're requesting is within bounds
int func=params[1];
int post=params[4];
CHECK_FUNCTION(func);
char *function=MF_GetAmxString(amx, params[3], 0, NULL);
int entid=params[2];
char classname[64];
// Check the entity
edict_t *Entity=INDEXENT_NEW(entid);
if (Entity->pvPrivateData == NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for entity id \"%d\", hook for \"%s\" not active.",entid,function);
return 0;
}
void **vtable=GetVTable(Entity->pvPrivateData, Offsets.GetBase());
if (vtable == NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for entity id \"%d\", hook for \"%s\" not active.",entid,function);
return 0;
}
// Verify that the function is valid
// Don't fail the plugin if this fails, just emit a normal error
int fwd=hooklist[func].makefunc(amx, function);
if (fwd == -1)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function);
return 0;
}
// We've passed all tests...
int **ivtable=(int **)vtable;
void *vfunction=(void *)ivtable[hooklist[func].vtid];
// Check the list of this function's hooks, see if the function we have is a hook
CVector<Hook *>::iterator end=hooks[func].end();
for (CVector<Hook *>::iterator i=hooks[func].begin();
i!=end;
++i)
{
if ((*i)->tramp == vfunction)
{
// Yes, this function is hooked
Forward *pfwd=new Forward(fwd);
if (post)
{
(*i)->post.push_back(pfwd);
}
else
{
(*i)->pre.push_back(pfwd);
}
return reinterpret_cast<cell>(pfwd);
}
}
// Note down the classname for the given class
// It may very well be wrong (such as lots of TS weapons have the same classname)
// but it's the best we can do, and better than nothing.
// (only used for display)
snprintf(classname, sizeof(classname) - 1, "%s", STRING(Entity->v.classname));
// If we got here, the function is not hooked
Hook *hook=new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].paramcount, classname);
hooks[func].push_back(hook);
Forward *pfwd=new Forward(fwd);
if (post)
{
hook->post.push_back(pfwd);
}
else
{
hook->pre.push_back(pfwd);
}
return reinterpret_cast<cell>(pfwd);
}
static cell AMX_NATIVE_CALL ExecuteHam(AMX *amx, cell *params) static cell AMX_NATIVE_CALL ExecuteHam(AMX *amx, cell *params)
{ {
int func=params[1]; int func=params[1];
@ -369,6 +474,7 @@ static cell AMX_NATIVE_CALL EnableHamForward(AMX *amx, cell *params)
AMX_NATIVE_INFO RegisterNatives[] = AMX_NATIVE_INFO RegisterNatives[] =
{ {
{ "RegisterHam", RegisterHam }, { "RegisterHam", RegisterHam },
{ "RegisterHamFromEntity", RegisterHamFromEntity },
{ "ExecuteHam", ExecuteHam }, { "ExecuteHam", ExecuteHam },
{ "ExecuteHamB", ExecuteHamB }, { "ExecuteHamB", ExecuteHamB },
{ "IsHamValid", IsHamValid }, { "IsHamValid", IsHamValid },

View File

@ -30,6 +30,10 @@
* - All functions and forwards (eg: {Register,Execute}Ham[B]) require * - All functions and forwards (eg: {Register,Execute}Ham[B]) require
* the mod to have the pev and base keys in addition to the function * the mod to have the pev and base keys in addition to the function
* keys for the corresponding mod/operating system in hamdata.ini * keys for the corresponding mod/operating system in hamdata.ini
*
* - Some functions that return booleans may need to be logically ANDed
* to get the results desired. e.g: if (ExecuteHam(Ham_TS_IsObjective, this) & 0x0000FFFF != 0) { // true.. }
* because the module will return the full integer value.
*/ */
enum Ham enum Ham
@ -830,7 +834,7 @@ enum Ham
Ham_TS_CanUsedThroughWalls, Ham_TS_CanUsedThroughWalls,
/** /**
* Description: - * Description: Unsure - this was removed in TS 3.0 (and thus is deprecated).
* Forward params: function(this) * Forward params: function(this)
* Return type: Integer (I think...) * Return type: Integer (I think...)
* Execute params: ExecuteHam(Ham_TS_RespawnWait, this); * Execute params: ExecuteHam(Ham_TS_RespawnWait, this);
@ -1049,6 +1053,65 @@ enum Ham
Ham_NS_UpdateOnRemove, Ham_NS_UpdateOnRemove,
/** Virtual functions added to TS in TS 3 */
/**
* Description: Unsure.
* Forward params: function(this)
* Return type: None.
* Execute params: ExecuteHam(Ham_TS_GiveSlowMul, this)
*/
Ham_TS_GiveSlowMul,
/**
* Description: Unsure. The second paramater is actually a char.
* Forward params: function(this, Float:someval, someotherval)
* Return type: None.
* Execute params: ExecuteHam(Ham_TS_GoSlow, this, Float:someval, someotherval)
*/
Ham_TS_GoSlow,
/**
* Description: Probably returns true if the user is in slow mo.
* Forward params: function(this)
* Return type: Integer (boolean).
* Execute params: ExecuteHam(Ham_TS_InSlow, this)
*/
Ham_TS_InSlow,
/**
* Description: Returns true if the entity is an objective.
* Forward params: function(this)
* Return type: Integer (boolean).
* Execute params: ExecuteHam(Ham_TS_IsObjective, this)
*/
Ham_TS_IsObjective,
/**
* Description: Unsure.
* Forward params: function(this, bool:someval)
* Return type: None.
* Execute params: ExecuteHam(Ham_TS_EnableObjective, this, bool:someval)
*/
Ham_TS_EnableObjective,
/**
* Description: Probably called when the engine call to OnEntFreePrivateData is called (the entity destructor.)
* Forward params: function(this)
* Return type: None.
* Execute params: ExecuteHam(Ham_TS_OnEntFreePrivateData, this)
*/
Ham_TS_OnFreeEntPrivateData,
/**
* Description: Probably called when the engine call to ShouldCollide is called.
* Forward params: function(this, otherEntity)
* Return type: Integer (boolean).
* Execute params: ExecuteHam(Ham_TS_ShouldCollide, this, otherEntity)
*/
Ham_TS_ShouldCollide,
/** /**
* DONT USE ME LOL * DONT USE ME LOL
*/ */

View File

@ -55,16 +55,32 @@
/** /**
* Hooks the virtual table for the specified entity class. * Hooks the virtual table for the specified entity class.
* An example would be: RegisterHam(Ham_TakeDamage, "player_hurt", "player"); * An example would be: RegisterHam(Ham_TakeDamage, "player", "player_hurt");
* Look at the Ham enum for parameter lists. * Look at the Ham enum for parameter lists.
* *
* @param function The function to hook. * @param function The function to hook.
* @param EntityClass The entity classname to hook.
* @param callback The forward to call. * @param callback The forward to call.
* @param entity The entity classname to hook.
* @param post Whether or not to forward this in post. * @param post Whether or not to forward this in post.
* @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off. * @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off.
*/ */
native HamHook:RegisterHam(Ham:function, const EntityClassname[], const Callback[], Post=0); native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0);
/**
* Hooks the virtual table for the specified entity's class.
* An example would be: RegisterHam(Ham_TakeDamage, id, "player_hurt");
* Look at the Ham enum for parameter lists.
* Note: This will cause hooks for the entire internal class that the entity is
* not exclusively for the provided entity.
*
* @param function The function to hook.
* @param EntityId The entity classname to hook.
* @param callback The forward to call.
* @param post Whether or not to forward this in post.
* @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off.
*/
native HamHook:RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0);
/** /**
* Stops a ham forward from triggering. * Stops a ham forward from triggering.