Skip to content

Commit

Permalink
Update l4d_reverse_ff.sp
Browse files Browse the repository at this point in the history
Updates for version 2.9, including new option to specify damage for bot/human victim.
  • Loading branch information
Mystik-Spiral authored Oct 9, 2024
1 parent 8f40936 commit 4523089
Showing 1 changed file with 99 additions and 95 deletions.
194 changes: 99 additions & 95 deletions l4d_reverse_ff.sp
Original file line number Diff line number Diff line change
@@ -1,101 +1,64 @@
/*
Reverse Friendly-Fire (l4d_reverse_ff) by Mystik Spiral
Reverse Friendly-Fire (l4d_reverse_ff) by Mystik Spiral
Purpose:
Left4Dead(2) SourceMod plugin that reverses friendly-fire...attacker takes damage, victim does not.
Objectives:
- Do not allow griefers to cause friendly-fire damage to other players.
- Incentivize all players to improve their shooting tactics and aim.
Description and options:
Reverses friendly-fire weapon damage on survivor team and claw attacks on infected team.
Does not reverse burn/blast damage, except for grenade launcher (see Suggestion section below).
Supports client language translation, currently English, French, Spanish, Russian, and Traditional Chinese.
Please note the following for the true(1) / false(0) options below:
· The victim never takes damage from the attacker.
· 1 = friendly-fire is reversed for that option and the attacker takes damage.
· 0 = friendly-fire is disabled for that option and the attacker does not take damage.
- Option to ReverseFF when attacker is an admin. [reverseff_admin (default: 0/false)]
- Option to ReverseFF when victim is a bot. [reverseff_bot (default: 0/false)]
- Option to ReverseFF when victim is incapacitated. [reverseff_incapped (default: 0/false)]
- Option to ReverseFF when attacker is incapacitated. [reverseff_attackerincapped (default: 0/false)]
- Option to ReverseFF when damage from mounted gun. [reverseff_mountedgun (default: 1/true)]
- Option to ReverseFF when damage from melee weapon. [reverseff_melee (default: 1/true)]
- Option to ReverseFF when damage from chainsaw. [reverseff_chainsaw (default: 1/true)]
- Option to ReverseFF during Smoker pull or Charger carry. [reverseff_pullcarry (default: 0/false)]
- Option to specify extra damage if attacker used explosive/incendiary ammo. [reverseff_multiplier (default: 1.125 = 12.5%)]
- Option to specify percentage of damage reversed for survivor (0=min, 2=max). [reverseff_dmgmodifier (default: 1.0=damage unmodified)]
- Option to specify percentage of damage reversed for infected (0=min, 2=max). [reverseff_dmgmodinfected (default: 1.0=damage unmodified)]
- Option to specify maximum survivor damage allowed per chapter before kick/ban (0=disable). [reverseff_survivormaxdmg (default: 200)]
- Option to specify maximum infected damage allowed per chapter before kick/ban (0=disable). [reverseff_infectedmaxdmg (default: 50)]
- Option to specify maximum tank damage allowed per chapter before kick/ban (0=disable). [reverseff_tankmaxdmg (default: 300)]
- Option to specify kick/ban duration in minutes. (0=permanent ban, -1=kick instead of ban). [reverseff_banduration (default: 10)]
- Option to specify no ReverseFF based on distance between victim and attacker (0=disable). [reverseff_proximity (default: 32)]
- Option to enable/disable plugin (0=Plugin off, 1=Plugin on) [reverseff_enable (default=1)]
- Option to enable/disable plugin by game mode. [reverseff_modes_on, reverseff_modes_off, reverseff_modes_tog]
- Option to enable/disable plugin announcement (0=Announcement off, 1=Announcement on) [reverseff_announcement (default=1)]
- Option to display/suppress ReverseFF chat messages (0=Suppress chat messages, 1=Display chat messages) [reverseff_chatmsg (default=1)]
Credits:
CFG file requested by user2000
Victim incapacitated option requested by Shao
L4D1/2 engine check fix requested by Crasher_3637/Psyk0tik
Reverse accusation vocalizations requested by kooper990
Kick or ban option requested by Maku and Crasher_3637/Psyk0tik
ReverseFF for infected requested by Kai0205
Short FF grace immediately after killing SI requested by Kai0205
L4D1/2 specific checks fix requested by kooper990 and Marttt
Attacker incapped option and mounted gun option requested by Shao
Melee and chainsaw option requested by Shao
Charger carry and Smoker pull option requested by Shao
Chainsaw damage fix by pan0s
Damage modifier by percentage requested by TrueDarkness
Promximity option requested by Shao
Announcement option requested by tamasa1969
Chat option requested by kevinracer
Cooldown timer requested by Shao
Game modes on/off/tog by Silvers
GetClientDist adapted from UndoFF by dcx2
Traditional Chinese translation by in2002
SM 11 compile warnings fix requested by S.A.S
Grenade stumble effect option requested by Automage
Option to reverse the logic of reverseff_proximity requested by Smeraldo
Add missing victim/attacker validation in datapack passed to chainsaw timer requested by S.A.S
Want to contribute code enhancements?
Create a pull request using this GitHub repository: https://github.com/Mystik-Spiral/l4d_reverse_ff
Plugin discussion: https://forums.alliedmods.net/showthread.php?t=329035
Reverses friendly-fire in Left4Dead(2).
Attacker takes damage, victim does not.
GitHub: https://github.com/Mystik-Spiral/l4d_reverse_ff
AlliedModders: https://forums.alliedmods.net/showthread.php?t=329035
*/

// ====================================================================================================
// Defines for Plugin Info
// ====================================================================================================
#define PLUGIN_NAME "[L4D & L4D2] Reverse Friendly-Fire"
#define PLUGIN_AUTHOR "Mystik Spiral"
#define PLUGIN_DESCRIPTION "Reverses friendly-fire... attacker takes damage, victim does not."
#define PLUGIN_VERSION "2.9"
#define PLUGIN_URL "https://forums.alliedmods.net/showthread.php?t=329035"

// ====================================================================================================
// Plugin Info
// ====================================================================================================
public Plugin myinfo =
{
name = PLUGIN_NAME,
author = PLUGIN_AUTHOR,
description = PLUGIN_DESCRIPTION,
version = PLUGIN_VERSION,
url = PLUGIN_URL
}

// ====================================================================================================
// Additional Defines
// ====================================================================================================
#define TRANSLATION_FILENAME "l4d_reverse_ff.phrases"
#define CVAR_FLAGS FCVAR_NOTIFY
#define CVAR_FLAGS_PLUGIN_VERSION FCVAR_NOTIFY|FCVAR_DONTRECORD|FCVAR_SPONLY

// ====================================================================================================
// Includes
// ====================================================================================================
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>

// ====================================================================================================
// Pragmas
// ====================================================================================================
#pragma semicolon 1
#pragma newdecls required

#define PLUGIN_VERSION "2.8.6"
#define CVAR_FLAGS FCVAR_NOTIFY
#define TRANSLATION_FILENAME "l4d_reverse_ff.phrases"

// ====================================================================================================
// Global Variables
// ====================================================================================================
ConVar cvar_reverseff_admin;
ConVar cvar_reverseff_multiplier;
ConVar cvar_reverseff_dmgmodifier;
ConVar cvar_reverseff_botdmgmodifier;
ConVar cvar_reverseff_humandmgmodifier;
ConVar cvar_reverseff_dmgmodinfected;
ConVar cvar_reverseff_bot;
ConVar cvar_reverseff_survivormaxdmg;
Expand All @@ -117,6 +80,8 @@ ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModesOn, g_hCvarModesOff, g_hCvar

float g_fCvarDamageMultiplier;
float g_fCvarDamageModifier;
float g_fCvarBotDmgModifier;
float g_fCvarHumanDmgModifier;
float g_fCvarDamageModifierInfected;
float g_fAccumDamage[MAXPLAYERS + 1];
float g_fAccumDamageAsTank[MAXPLAYERS + 1];
Expand Down Expand Up @@ -153,15 +118,9 @@ bool g_bLateLoad;

Handle g_hEndGrace[MAXPLAYERS + 1];

public Plugin myinfo =
{
name = "[L4D & L4D2] Reverse Friendly-Fire",
author = "Mystic Spiral",
description = "Reverses friendly-fire... attacker takes damage, victim does not.",
version = PLUGIN_VERSION,
url = "https://forums.alliedmods.net/showthread.php?t=329035"
}

// ====================================================================================================
// Verify game engine
// ====================================================================================================
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
EngineVersion test = GetEngineVersion();
Expand All @@ -181,6 +140,9 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
return APLRes_SilentFailure;
}

// ====================================================================================================
// Functions
// ====================================================================================================
public void OnAllPluginsLoaded()
{
if (FindConVar("RBaEA_version") != null)
Expand All @@ -196,13 +158,15 @@ public void OnPluginStart()
{
LoadPluginTranslations();

CreateConVar("reverseff_version", PLUGIN_VERSION, "Reverse Friendly-Fire", FCVAR_NOTIFY|FCVAR_DONTRECORD);
CreateConVar("reverseff_version", PLUGIN_VERSION, PLUGIN_DESCRIPTION, CVAR_FLAGS_PLUGIN_VERSION);
cvar_reverseff_admin = CreateConVar("reverseff_admin", "0", "0=Do not ReverseFF if attacker is admin, 1=ReverseFF if attacker is admin", CVAR_FLAGS);
cvar_reverseff_bot = CreateConVar("reverseff_bot", "0", "0=Do not ReverseFF if victim is bot, 1=ReverseFF if victim is bot", CVAR_FLAGS);
cvar_reverseff_incapped = CreateConVar("reverseff_incapped", "0", "0=Do not ReverseFF if victim is incapped, 1=ReverseFF if victim is incapped", CVAR_FLAGS);
cvar_reverseff_attackerincapped = CreateConVar("reverseff_attackerincapped", "0", "0=Do not ReverseFF if attacker is incapped, 1=ReverseFF if attacker is incapped", CVAR_FLAGS);
cvar_reverseff_multiplier = CreateConVar("reverseff_multiplier", "1.125", "Special ammo damage multiplier (default=12.5%)", CVAR_FLAGS);
cvar_reverseff_dmgmodifier = CreateConVar("reverseff_dmgmodifier", "1.0", "0.0=no dmg, 1.0=dmg unmodified, 2.0=double dmg\n0.01=1% real dmg, 0.1=10% real dmg, 0.5=50% real dmg\n1.01=1% more dmg, 1.1=10% more dmg, 1.5=50% more dmg", CVAR_FLAGS);
cvar_reverseff_botdmgmodifier = CreateConVar("reverseff_botdmgmodifier", "0.0", "Damage bot victim:\n0.0=no dmg, 1.0=dmg unmodified, 2.0=double dmg\n0.01=1% real dmg, 0.1=10% real dmg, 0.5=50% real dmg\n1.01=1% more dmg, 1.1=10% more dmg, 1.5=50% more dmg", CVAR_FLAGS);
cvar_reverseff_humandmgmodifier = CreateConVar("reverseff_humandmgmodifier", "0.0", "Damage human victim:\n0.0=no dmg, 1.0=dmg unmodified, 2.0=double dmg\n0.01=1% real dmg, 0.1=10% real dmg, 0.5=50% real dmg\n1.01=1% more dmg, 1.1=10% more dmg, 1.5=50% more dmg", CVAR_FLAGS);
cvar_reverseff_dmgmodinfected = CreateConVar("reverseff_dmgmodinfected", "1.0", "0.0=no dmg, 1.0=dmg unmodified, 2.0=double dmg\n0.01=1% real dmg, 0.1=10% real dmg, 0.5=50% real dmg\n1.01=1% more dmg, 1.1=10% more dmg, 1.5=50% more dmg", CVAR_FLAGS);
cvar_reverseff_survivormaxdmg = CreateConVar("reverseff_survivormaxdmg", "200", "Maximum damage allowed before kick/ban survivor (0=disable)", CVAR_FLAGS);
cvar_reverseff_infectedmaxdmg = CreateConVar("reverseff_infectedmaxdmg", "50", "Maximum damage allowed before kick/ban infected (0=disable)", CVAR_FLAGS);
Expand All @@ -226,6 +190,8 @@ public void OnPluginStart()
cvar_reverseff_admin.AddChangeHook(action_ConVarChanged);
cvar_reverseff_multiplier.AddChangeHook(action_ConVarChanged);
cvar_reverseff_dmgmodifier.AddChangeHook(action_ConVarChanged);
cvar_reverseff_botdmgmodifier.AddChangeHook(action_ConVarChanged);
cvar_reverseff_humandmgmodifier.AddChangeHook(action_ConVarChanged);
cvar_reverseff_dmgmodinfected.AddChangeHook(action_ConVarChanged);
cvar_reverseff_bot.AddChangeHook(action_ConVarChanged);
cvar_reverseff_survivormaxdmg.AddChangeHook(action_ConVarChanged);
Expand Down Expand Up @@ -325,6 +291,8 @@ void GetCvars()
g_bCvarReverseIfAdmin = cvar_reverseff_admin.BoolValue;
g_fCvarDamageMultiplier = cvar_reverseff_multiplier.FloatValue;
g_fCvarDamageModifier = cvar_reverseff_dmgmodifier.FloatValue;
g_fCvarBotDmgModifier = cvar_reverseff_botdmgmodifier.FloatValue;
g_fCvarHumanDmgModifier = cvar_reverseff_humandmgmodifier.FloatValue;
g_fCvarDamageModifierInfected = cvar_reverseff_dmgmodinfected.FloatValue;
g_bCvarReverseIfBot = cvar_reverseff_bot.BoolValue;
g_fSurvivorMaxDamage = cvar_reverseff_survivormaxdmg.FloatValue;
Expand Down Expand Up @@ -474,6 +442,38 @@ public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &dam
//treat friendly-fire from bot attacker normally, which is 0 damage anyway
return Plugin_Continue;
}
float fBotDamage = 0.0;
//check if attacker is a non-bot survivor and victim is a bot survivor that will be damaged
if (IsFakeClient(victim) && !IsFakeClient(attacker) && 0.0 < g_fCvarBotDmgModifier <= 2.0)
{
//apply reverseff_botdmgmodifier damage modifier
fBotDamage = damage * g_fCvarBotDmgModifier;
//if we are modifying damage ensure damage is at least 1
if (g_fCvarBotDmgModifier != 1.0 && 0.0 < fBotDamage < 1.0)
{
fBotDamage = 1.0;
}
if (fBotDamage >= 1.0)
{
SDKHooks_TakeDamage(victim, inflictor, attacker, fBotDamage, damagetype, weapon, damageForce, damagePosition);
}
}
float fHumanDamage = 0.0;
//check if attacker is a non-bot survivor and victim is a non-bot survivor that will be damaged
if (!IsFakeClient(victim) && !IsFakeClient(attacker) && 0.0 < g_fCvarHumanDmgModifier <= 2.0)
{
//apply reverseff_humandmgmodifier damage modifier
fHumanDamage = damage * g_fCvarHumanDmgModifier;
//if we are modifying damage ensure damage is at least 1
if (g_fCvarHumanDmgModifier != 1.0 && 0.0 < fHumanDamage < 1.0)
{
fHumanDamage = 1.0;
}
if (fHumanDamage >= 1.0)
{
SDKHooks_TakeDamage(victim, inflictor, attacker, fHumanDamage, damagetype, weapon, damageForce, damagePosition);
}
}
char sInflictorClass[32];
if (inflictor > MaxClients)
{
Expand Down Expand Up @@ -623,10 +623,14 @@ public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &dam
else
{
//inflict (non-chainsaw) damage to attacker
//if we did not previously damage victim...
//add 1HP to victim then damage them for 1HP so the displayed message and vocalization order are correct,
//then damage attacker as self-inflicted for actual damage so there is no vocalization, just pain grunt.
SetEntityHealth(victim, GetClientHealth(victim) + 1);
SDKHooks_TakeDamage(victim, inflictor, attacker, 1.0, 0, weapon, g_fDmgFrc, g_fDmgPos);
if (fBotDamage < 1.0 && fHumanDamage < 1.0)
{
SetEntityHealth(victim, GetClientHealth(victim) + 1);
SDKHooks_TakeDamage(victim, inflictor, attacker, 1.0, 0, weapon, g_fDmgFrc, g_fDmgPos);
}
//if using grenade launcher and reverseff_glstumble is false then ignore stumble effect, else reverse stumble effect
if (bWeaponGL && !g_bCvarGLstumble)
{
Expand Down

0 comments on commit 4523089

Please sign in to comment.