PHP Code:
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <dhooks>
#include <morecolors>
#include <tf2_stocks>
#pragma semicolon 1;
#pragma newdecls required;
Handle hDispenseAmmo;
Handle hDispenseMetal;
Handle hStartHealing;
Handle hDispenseAmmoCall;
Handle hDispenseMetalCall;
Handle hStartHealingCall;
Handle hRemoveHealingTargetCall;
Handle hCvar_Metal;
Handle hCvar_Ammo;
Handle hCvar_Heal;
Handle hCvar_Debug;
//412 398 CObjectDispenser::DispenseAmmo(CTFPlayer *)
//405 391 CObjectDispenser::DispenseMetal(CTFPlayer *)
//417 403 CObjectDispenser::StartHealing(CBaseEntity *)
// CObjectDispenser::RemoveHealingTarget(CObjectDispenser *this, CBaseEntity *)
public void OnPluginStart()
{
Handle hGameConf = LoadGameConfigFile("tf2.dispenser");
if(hGameConf == INVALID_HANDLE) SetFailState("tf2.dispenser.txt Not Found check you gamedata folder");
int DispenseAmmoOffset = GameConfGetOffset(hGameConf, "CObjectDispenser::DispenseAmmo");
if(DispenseAmmoOffset == -1) SetFailState("Failed To Get Offset For CObjectDispenser::DispenseAmmo");
int DispenseMetalOffset = GameConfGetOffset(hGameConf, "CObjectDispenser::DispenseMetal");
if(DispenseMetalOffset == -1) SetFailState("Failed To Get Offset For CObjectDispenser::DispenseMetal");
int StartHealingOffset = GameConfGetOffset(hGameConf, "CObjectDispenser::StartHealing");
if(StartHealingOffset == -1) SetFailState("Failed To Get Offset For CObjectDispenser::StartHealing");
hDispenseAmmo = DHookCreate(DispenseAmmoOffset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, DispenseAmmo);
DHookAddParam(hDispenseAmmo, HookParamType_CBaseEntity, _, DHookPass_ByRef);
hDispenseMetal = DHookCreate(DispenseMetalOffset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, DispenseMetal);
DHookAddParam(hDispenseMetal, HookParamType_CBaseEntity, _, DHookPass_ByRef);
hStartHealing = DHookCreate(StartHealingOffset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, StartHealing);
DHookAddParam(hStartHealing, HookParamType_CBaseEntity, _, DHookPass_ByRef);
StartPrepSDKCall(SDKCall_Entity);
PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "CObjectDispenser::StartHealing");
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
hStartHealingCall = EndPrepSDKCall();
if(hStartHealingCall == INVALID_HANDLE) SetFailState("Failed To End SDKCall hStartHealingCall");
StartPrepSDKCall(SDKCall_Entity);
PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "CObjectDispenser::DispenseAmmo");
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
hDispenseAmmoCall = EndPrepSDKCall();
if(hDispenseAmmoCall == INVALID_HANDLE) SetFailState("Failed To End SDKCall hDispenseAmmoCall");
StartPrepSDKCall(SDKCall_Entity);
PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "CObjectDispenser::DispenseMetal");
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
hDispenseMetalCall = EndPrepSDKCall();
if(hDispenseMetalCall == INVALID_HANDLE) SetFailState("Failed To End SDKCall hDispenseMetalCall");
StartPrepSDKCall(SDKCall_Entity);
PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "CObjectDispenser::RemoveHealingTarget");
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
hRemoveHealingTargetCall = EndPrepSDKCall();
if(hRemoveHealingTargetCall == INVALID_HANDLE) SetFailState("Failed To End SDKCall hRemoveHealingTargetCall");
hCvar_Metal = CreateConVar("dispenser_metal", "1");
hCvar_Ammo = CreateConVar("dispenser_ammo", "1");
hCvar_Heal = CreateConVar("dispenser_heal", "1");
hCvar_Debug = CreateConVar("dispenser_debug", "1");
delete hGameConf;
int ent = -1;
while((ent = FindEntityByClassname(ent, "obj_dispenser")) != INVALID_ENT_REFERENCE)
{
if(IsValidEntity(ent)) OnSpawnPost(ent);
}
/*
ent = -1;
while((ent = FindEntityByClassname(ent, "dispenser_touch_trigger")) != INVALID_ENT_REFERENCE)
{
if(IsValidEntity(ent)) OnSpawnPostTrigger(ent);
}
*/
}
/*
public void EndTouch(int entity, int other)
{
int owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
int DispenserTeam = GetEntProp(owner, Prop_Send, "m_iTeamNum");
if((other >= 1 && other <= MaxClients) && (GetClientTeam(other) != DispenserTeam))
{
SDKCall(hRemoveHealingTargetCall, owner, other);
}
}
public void StartTouch(int entity, int other)
{
int owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
int DispenserTeam = GetEntProp(owner, Prop_Send, "m_iTeamNum");
if((other >= 1 && other <= MaxClients) && (GetClientTeam(other) != DispenserTeam))
{
SDKCall(hStartHealingCall, owner, other);
}
}
*/
public MRESReturn DispenseAmmo(int thisp, Handle hReturn, Handle hParams)
{
if(GetConVarBool(hCvar_Debug))
{
PrintDebug("DispenseAmmo", thisp, hReturn, hParams);
}
if(hReturn != INVALID_HANDLE && !GetConVarBool(hCvar_Ammo))
{
DHookSetReturn(hReturn, false);
return MRES_Supercede;
}
return MRES_Ignored;
}
public MRESReturn DispenseMetal(int thisp, Handle hReturn, Handle hParams)
{
if(GetConVarBool(hCvar_Debug))
{
PrintDebug("DispenseMetal", thisp, hReturn, hParams);
}
if(hReturn != INVALID_HANDLE && !GetConVarBool(hCvar_Metal))
{
DHookSetReturn(hReturn, false);
return MRES_Supercede;
}
return MRES_Ignored;
}
public MRESReturn StartHealing(int thisp, Handle hReturn, Handle hParams)
{
if(GetConVarBool(hCvar_Debug))
{
PrintDebug("StartHealing", thisp, hReturn, hParams);
}
if(hReturn != INVALID_HANDLE && !GetConVarBool(hCvar_Heal))
{
DHookSetReturn(hReturn, false);
return MRES_Supercede;
}
return MRES_Ignored;
}
public void PrintDebug(char[] functionname, int thisp, Handle hReturn, Handle hParams)
{
CPrintToChatAll("{green}----------- {blue}%s {green}----------", functionname);
CPrintToChatAll("{blue}hReturn {white}is {green}%i %s", ((hReturn != INVALID_HANDLE) ? DHookGetReturn(hReturn) : 0), ((hReturn == INVALID_HANDLE) ? "{fullred}INVALID_HANDLE" : ""));
CPrintToChatAll("{blue}hParams {white}(1) is {green}%N %s", ((hParams != INVALID_HANDLE) ? DHookGetParam(hParams, 1) : 0), ((hParams == INVALID_HANDLE) ? "{fullred}INVALID_HANDLE" : ""));
CPrintToChatAll("{blue}thisp {white}is {green}%i", thisp);
CPrintToChatAll("{green}--------------------------------------- \n");
}
public void OnEntityCreated(int entity, const char[] classname)
{
if(StrEqual(classname, "obj_dispenser", false))
{
SDKHook(entity, SDKHook_SpawnPost, OnSpawnPost);
}
/*
if(StrEqual(classname, "dispenser_touch_trigger", false))
{
SDKHook(entity, SDKHook_SpawnPost, OnSpawnPostTrigger);
}
*/
}
public void OnSpawnPost(int entity)
{
DHookEntity(hDispenseAmmo, false, entity);
DHookEntity(hDispenseMetal, false, entity);
DHookEntity(hStartHealing, false, entity);
}
/*
public void OnSpawnPostTrigger(int entity)
{
SDKHook(entity, SDKHook_StartTouch, StartTouch);
SDKHook(entity, SDKHook_EndTouch, EndTouch);
}
*/
you can also make client-specific by using DHookGetParam(Handle:hParams, num);