#pragma semicolon 1
#pragma newdecls required
#include <sdkhooks>
#include <sdktools_engine>
#include <sdktools_functions>
#define PLUGIN_VERSION "1.1rc"
#define CVAR_FLAGS FCVAR_NOTIFY
static const char
PL_NAME[] = "MirrorDamage",
PL_VER[] = "1.0.0";
float
fMultiplier;
bool
bEnable,
bSlap,
bNotice,
bBlock,
bHooked[MAXPLAYERS + 1];
public Plugin myinfo =
{
name = PL_NAME,
version = PL_VER,
description = "Simple plugin for mirror friendlyfire",
author = "Grey83",
url = "https://steamcommunity.com/groups/grey83ds"
}
public void OnPluginStart()
{
CreateConVar("sm_mirrordamage_version", PLUGIN_VERSION, PL_NAME, FCVAR_DONTRECORD|FCVAR_NOTIFY|FCVAR_SPONLY);
ConVar cvar;
cvar = CreateConVar("sm_mirrordamage_enable", "1", "Enable/Disable plugin", CVAR_FLAGS, true, _, true, 1.0);
cvar.AddChangeHook(CVarChange_Enable);
CVarChange_Enable(cvar, "", "");
cvar = CreateConVar("sm_mirrordamage_multiplier", "0.7", "Amount of damage to inflict to attacker, def 70%", CVAR_FLAGS, true, 0.1, true, 10.0);
cvar.AddChangeHook(CVarChange_Multiplier);
fMultiplier = cvar.FloatValue;
cvar = CreateConVar("sm_mirrordamage_slap", "0", "Slap attacker?! or just subtraction health", CVAR_FLAGS, true, _, true, 1.0);
cvar.AddChangeHook(CVarChange_Slap);
bSlap = cvar.BoolValue;
cvar = CreateConVar("sm_mirrordamage_annonce", "0", "Type in chat about friendlyfire?!", CVAR_FLAGS, true, _, true, 1.0);
cvar.AddChangeHook(CVarChange_Notice);
bNotice = cvar.BoolValue;
cvar = CreateConVar("sm_mirrordamage_block", "1", "Block damage to the victim?", CVAR_FLAGS, true, _, true, 1.0);
cvar.AddChangeHook(CVarChange_Block);
bBlock = cvar.BoolValue;
AutoExecConfig(true, "MirrorDamage");
}
public void CVarChange_Enable(ConVar cvar, const char[] oldValue, const char[] newValue)
{
bool hooked;
if(hooked == (bEnable = cvar.BoolValue))
return;
if((hooked ^= true))
{
for(int i; ++i <= MaxClients;) if(IsClientInGame(i)) AddHook(i);
}
else
{
for(int i; ++i <= MaxClients;) if(bHooked[i])
{
bHooked[i] = false;
SDKUnhook(i, SDKHook_OnTakeDamage, OnTakeDamage);
}
}
}
public void CVarChange_Multiplier(ConVar cvar, const char[] oldValue, const char[] newValue)
{
fMultiplier = cvar.FloatValue;
}
public void CVarChange_Slap(ConVar cvar, const char[] oldValue, const char[] newValue)
{
bSlap = cvar.BoolValue;
}
public void CVarChange_Notice(ConVar cvar, const char[] oldValue, const char[] newValue)
{
bNotice = cvar.BoolValue;
}
public void CVarChange_Block(ConVar cvar, const char[] oldValue, const char[] newValue)
{
bBlock = cvar.BoolValue;
}
public void OnClientPutInServer(int client)
{
if(bEnable) AddHook(client);
}
void AddHook(int client)
{
if(!IsFakeClient(client) || (!IsClientReplay(client) && !IsClientSourceTV(client)))
{
bHooked[client] = true;
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}
}
public void OnClientDisconnect(int client)
{
bHooked[client] = false;
}
Action OnTakeDamage(int client, int &attacker, int &inflictor, float &damage, int &damagetype)
{
if(!attacker || client == attacker || !IsClientInGame(attacker) || !IsPlayerAlive(attacker)
|| GetClientTeam(client) != GetClientTeam(attacker))
return Plugin_Continue;
float dmg = damage * fMultiplier;
if(bSlap) SlapPlayer(attacker, RoundFloat(dmg));
else
{
static float pos[3];
GetClientEyePosition(attacker, pos);
SDKHooks_TakeDamage(attacker, attacker, attacker, dmg, DMG_PLASMA, _, NULL_VECTOR, pos);
}
if(bNotice) PrintToChatAll("%N attacked a teammate", attacker);
if(bBlock)
{
damage = 0.0;
return Plugin_Changed;
}
return Plugin_Continue;
}