#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#define PLUGIN_VERSION "1.2"
#define CVAR_FLAGS FCVAR_NOTIFY
public Plugin myinfo =
{
name = "[L4D] Help survivor",
author = "Alexander Mirny(Rewritten by BloodyBlade)",
description = "Survivors can self-help on button E",
version = PLUGIN_VERSION,
url = ""
}
ConVar hHelpSurvivorOn;
bool bL4D2 = false, bHelpSurvivorOn = false, bHooked = false, bIncap[MAXPLAYERS + 1] = {false, ...}, smoker[MAXPLAYERS + 1] = {false, ...}, hunter[MAXPLAYERS + 1] = {false, ...}, charger[MAXPLAYERS + 1] = {false, ...}, jockey[MAXPLAYERS + 1] = {false, ...};
int iVictim = 0, iUserId = 0, AttackerHealth = 0, Score[MAXPLAYERS + 1] = {0, ...}, gethunter = 0, getsmoker = 0, getcharger = 0, getjockey = 0, iLastTime[MAXPLAYERS + 1] = {0, ...};
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
EngineVersion engine = GetEngineVersion();
if (engine == Engine_Left4Dead)
{
bL4D2 = false;
}
else if(engine == Engine_Left4Dead2)
{
bL4D2 = true;
}
else
{
strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
return APLRes_SilentFailure;
}
return APLRes_Success;
}
public void OnPluginStart()
{
CreateConVar("l4d_help_survivor_version", PLUGIN_VERSION, "[L4D] Help survivor plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
hHelpSurvivorOn = CreateConVar("l4d_help_survivor_on", "1", "Enable/Disable plugin.", CVAR_FLAGS);
AutoExecConfig(true, "l4d_help_survivor");
hHelpSurvivorOn.AddChangeHook(ConVarPluginOnChanged);
}
public void OnConfigsExecuted()
{
IsAllowed();
}
void ConVarPluginOnChanged(ConVar cvar, const char[] OldValue, const char[] NewValue)
{
IsAllowed();
}
void IsAllowed()
{
bHelpSurvivorOn = hHelpSurvivorOn.BoolValue;
if(bHelpSurvivorOn && !bHooked)
{
bHooked = true;
HookEvent("tongue_grab", Events);
HookEvent("lunge_pounce", Events);
HookEvent("pounce_stopped", Events);
HookEvent("tongue_broke_victim_died", Events);
HookEvent("witch_killed", Events);
HookEvent("revive_success", Events);
HookEvent("player_death", Events);
if(bL4D2)
{
HookEvent("charger_carry_start", Events);
HookEvent("charger_carry_end", Events);
HookEvent("charger_carry_kill", Events);
HookEvent("charger_impact", Events);
HookEvent("charger_pummel_start", Events);
HookEvent("charger_pummel_end", Events);
HookEvent("jockey_ride", Events);
HookEvent("jockey_ride_end", Events);
}
}
else if(!bHelpSurvivorOn && bHooked)
{
bHooked = false;
UnhookEvent("tongue_grab", Events);
UnhookEvent("lunge_pounce", Events);
UnhookEvent("pounce_stopped", Events);
UnhookEvent("tongue_broke_victim_died", Events);
UnhookEvent("witch_killed", Events);
UnhookEvent("revive_success", Events);
UnhookEvent("player_death", Events);
if(bL4D2)
{
UnhookEvent("charger_carry_start", Events);
UnhookEvent("charger_carry_end", Events);
UnhookEvent("charger_carry_kill", Events);
UnhookEvent("charger_impact", Events);
UnhookEvent("charger_pummel_start", Events);
UnhookEvent("charger_pummel_end", Events);
UnhookEvent("jockey_ride", Events);
UnhookEvent("jockey_ride_end", Events);
}
}
}
Action Events(Event event, const char[] name, bool dontBroadcast)
{
if (strcmp(name, "tongue_grab") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidInfected(iUserId)) getsmoker = iUserId;
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidSurvivor(iVictim))
{
bIncap[iVictim] = true;
smoker[iVictim] = true;
CreateTimer(1.0, Notification, iVictim);
}
}
else if(strcmp(name, "lunge_pounce") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidInfected(iUserId)) gethunter = iUserId;
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidSurvivor(iVictim))
{
bIncap[iVictim] = true;
hunter[iVictim] = true;
CreateTimer(1.0, Notification, iVictim);
}
}
else if(strcmp(name, "pounce_stopped") == 0)
{
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidInfected(iVictim))
{
gethunter = iVictim;
bIncap[iVictim] = false;
hunter[iVictim] = false;
smoker[iVictim] = false;
charger[iVictim] = false;
jockey[iVictim] = false;
}
}
else if(strcmp(name, "tongue_broke_victim_died") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidSurvivor(iUserId))
{
getsmoker = iUserId;
bIncap[iUserId] = false;
hunter[iUserId] = false;
smoker[iUserId] = false;
charger[iUserId] = false;
jockey[iUserId] = false;
}
}
else if(strcmp(name, "witch_killed") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidSurvivor(iUserId))
{
if(event.GetBool("oneshot"))
{
Score[iUserId] = 200;
}
else
{
Score[iUserId] = 120;
}
}
}
else if(strcmp(name, "revive_success") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidSurvivor(iUserId) && Score[iUserId] == 0)
{
char String_Print[256];
Score[iUserId] = 100;
Format(String_Print, sizeof(String_Print), "\x05Вы спасли члена команды, за спасение получаете \x04%d \x05очков", Score[iUserId]);
PrintToChat(iUserId, String_Print);
}
}
else if(strcmp(name, "player_death") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidInfected(iUserId))
{
int ZClass = GetEntProp(iUserId, Prop_Send, "m_zombieClass");
if(ZClass == 1)
{
getsmoker = 0;
}
else if(ZClass == 3)
{
gethunter = 0;
}
else if(ZClass == 5)
{
getjockey = 0;
}
else if(ZClass == 6)
{
getcharger = 0;
}
}
}
if(bL4D2)
{
if (strcmp(name, "charger_pummel_start") == 0 || strcmp(name, "charger_impact") == 0 || strcmp(name, "charger_carry_start") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidInfected(iUserId)) getcharger = iUserId;
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidSurvivor(iVictim))
{
bIncap[iVictim] = true;
charger[iVictim] = true;
CreateTimer(1.0, Notification, iVictim);
}
}
else if(strcmp(name, "charger_carry_kill") == 0 || strcmp(name, "charger_pummel_end") == 0 || strcmp(name, "charger_carry_end") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidInfected(iUserId)) getcharger = iUserId;
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidSurvivor(iUserId))
{
bIncap[iVictim] = false;
hunter[iVictim] = false;
smoker[iVictim] = false;
charger[iVictim] = false;
jockey[iVictim] = false;
}
}
else if(strcmp(name, "jockey_ride") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidClient(iUserId)) getjockey = iUserId;
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidSurvivor(iVictim))
{
bIncap[iVictim] = true;
jockey[iVictim] = true;
CreateTimer(1.0, Notification, iVictim);
}
}
else if(strcmp(name, "jockey_ride_end") == 0)
{
iUserId = GetClientOfUserId(event.GetInt("userid"));
if(IsValidClient(iUserId)) getjockey = iUserId;
iVictim = GetClientOfUserId(event.GetInt("victim"));
if(IsValidSurvivor(iVictim))
{
bIncap[iVictim] = false;
hunter[iVictim] = false;
smoker[iVictim] = false;
charger[iVictim] = false;
jockey[iVictim] = false;
}
}
}
return Plugin_Continue;
}
Action Notification(Handle timer, int client)
{
if(IsValidSurvivor(client))
{
if(hunter[client]) PrintHintText(client, "Освободите себя от захвата охотника зажмите *Е*");
if(smoker[client]) PrintHintText(client, "Освободите себя от языка курильщика зажмите *Е*");
if(charger[client]) PrintHintText(client, "Освободите себя от захвата громилы зажмите *Е*");
if(jockey[client]) PrintHintText(client, "Освободите себя от захвата жокея зажмите *Е*");
}
return Plugin_Stop;
}
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon)
{
if (IsValidSurvivor(client) && bIncap[client] && buttons & IN_USE)
{
if (iLastTime[client] != 0)
{
if (iLastTime[client] + 1 > GetTime())
{
return Plugin_Continue;
}
}
iLastTime[client] = GetTime();
if(Score[client] < 10)
{
PrintToChat(client, "\x05[ОШИБКА]\x04Не хватает очков.");
return Plugin_Continue;
}
else
{
if(smoker[client])
{
bIncap[client] = false;
if(IsValidInfected(getsmoker))
{
AttackerHealth = GetClientHealth(getsmoker);
DealDamage(getsmoker, AttackerHealth, client, DMG_BULLET, "weapon_hunting_rifle");
}
smoker[client] = false;
}
if(hunter[client])
{
bIncap[client] = false;
if(IsValidInfected(gethunter))
{
AttackerHealth = GetClientHealth(gethunter);
DealDamage(gethunter, AttackerHealth, client, DMG_BULLET, "weapon_hunting_rifle");
}
hunter[client] = false;
}
if(charger[client])
{
bIncap[client] = false;
if(IsValidInfected(getcharger))
{
AttackerHealth = GetClientHealth(getcharger);
DealDamage(getcharger, AttackerHealth, client, DMG_BULLET, "weapon_hunting_rifle");
}
charger[client] = false;
}
if(jockey[client])
{
bIncap[client] = false;
if(IsValidInfected(getjockey))
{
AttackerHealth = GetClientHealth(getjockey);
DealDamage(getjockey, AttackerHealth, client, DMG_BULLET, "weapon_hunting_rifle");
}
jockey[client] = false;
}
Score[client] -= 10;
}
}
return Plugin_Continue;
}
void DealDamage(int victim, int damage, int attacker = 0, int dmg_type = DMG_GENERIC, char[] weapon = "")
{
if(IsValidInfected(victim) && IsPlayerAlive(victim))
{
char dmg_str[16];
IntToString(damage, dmg_str, 16);
char dmg_type_str[32];
IntToString(dmg_type, dmg_type_str, 32);
int pointHurt = CreateEntityByName("point_hurt");
if (pointHurt)
{
DispatchKeyValue(victim, "targetname", "hurtme");
DispatchKeyValue(pointHurt, "DamageTarget", "hurtme");
DispatchKeyValue(pointHurt, "Damage", dmg_str);
DispatchKeyValue(pointHurt, "DamageType", dmg_type_str);
if(!StrEqual(weapon,""))
{
DispatchKeyValue(pointHurt,"classname", weapon);
}
DispatchSpawn(pointHurt);
AcceptEntityInput(pointHurt, "Hurt", (attacker > 0) ? attacker : -1);
DispatchKeyValue(pointHurt, "classname", "point_hurt");
DispatchKeyValue(victim, "targetname", "hurtme");
RemoveEdict(pointHurt);
}
}
}
bool IsValidClient(int client)
{
return client > 0 && client <= MaxClients && IsClientInGame(client);
}
bool IsValidSurvivor(int client)
{
return IsValidClient(client) && GetClientTeam(client) == 2 && IsPlayerAlive(client) && !IsFakeClient(client);
}
bool IsValidInfected(int client)
{
return IsValidClient(client) && GetClientTeam(client) == 3;
}