#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <dhooks>
#pragma newdecls required
int g_shieldAttacker = -1;
Handle g_detourFireBullet;
Handle g_detourIncreaseShieldDamage;
Handle g_detourPrimaryAttack;
Handle g_detourSecondaryAttack;
public void OnPluginStart()
{
GameData conf = new GameData("teamshieldprotect.games");
if (conf == null)
SetFailState("Failed to load teamshieldprotect gamedata");
if (!(g_detourFireBullet = DHookCreateFromConf(conf, "CCSPlayer::FireBullet")))
SetFailState("Failed to setup detour for CCSPlayer::FireBullet");
if (!(g_detourIncreaseShieldDamage = DHookCreateFromConf(conf, "CWeaponShield::IncreaseDamage")))
SetFailState("Failed to setup detour for CWeaponShield::IncreaseDamage");
if (!(g_detourPrimaryAttack = DHookCreateFromConf(conf, "CBaseCombatWeapon::PrimaryAttack")))
SetFailState("Failed to setup detour for CBaseCombatWeapon::PrimaryAttack");
if (!(g_detourSecondaryAttack = DHookCreateFromConf(conf, "CBaseCombatWeapon::SecondaryAttack")))
SetFailState("Failed to setup detour for CBaseCombatWeapon::SecondaryAttack");
delete conf;
if (!DHookEnableDetour(g_detourFireBullet, false, Detour_OnFireBullet))
SetFailState("Failed to detour CCSPlayer::FireBullet");
if (!DHookEnableDetour(g_detourFireBullet, true, Detour_OnFireBulletPost))
SetFailState("Failed to detour CCSPlayer::FireBullet post");
if (!DHookEnableDetour(g_detourIncreaseShieldDamage, false, Detour_OnIncreaseShieldDamage))
SetFailState("Failed to detour CWeaponShield::IncreaseDamage");
DHookAddEntityListener(ListenType_Created, EntityCreated);
}
public void EntityCreated(int entity, const char[] classname)
{
char clsname[32];
GetEntityNetClass(entity, clsname, sizeof(clsname));
if (!strcmp(clsname, "CKnife") ||
!strcmp(clsname, "CKnifeGG"))
{
DHookEntity(g_detourPrimaryAttack, false, entity, _, Detour_OnKnifeAttack);
DHookEntity(g_detourPrimaryAttack, true, entity, _, Detour_OnFireBulletPost);
DHookEntity(g_detourSecondaryAttack, false, entity, _, Detour_OnKnifeAttack);
DHookEntity(g_detourSecondaryAttack, true, entity, _, Detour_OnFireBulletPost);
}
}
public MRESReturn Detour_OnKnifeAttack(int entity, Handle params)
{
g_shieldAttacker = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
return MRES_Ignored;
}
public MRESReturn Detour_OnFireBullet(int client, Handle params)
{
g_shieldAttacker = client;
return MRES_Ignored;
}
public MRESReturn Detour_OnFireBulletPost(int client, Handle params)
{
g_shieldAttacker = -1;
return MRES_Ignored;
}
public MRESReturn Detour_OnIncreaseShieldDamage(int entity, Handle params)
{
if (IsValidClient(g_shieldAttacker))
{
int owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
if (IsValidClient(owner) && GetClientTeam(owner) == GetClientTeam(g_shieldAttacker))
{
DHookSetParam(params, 1, 0.0);
return MRES_ChangedHandled;
}
}
return MRES_Ignored;
}
bool IsValidClient(int client)
{
return (client > 0 && client <= MaxClients && IsClientInGame(client) && IsPlayerAlive(client));
}