#pragma semicolon 1 #include #include #include #include bool g_bKnifeRevert; bool g_bSlayKnifer; float g_fMaxDistance; float g_fMaxTime; int g_iClientIndexKnifer; int g_iClientIndexKnifedZombie; bool g_bKnife; bool g_bInfectedInRadius[MAXPLAYERS + 1]; public Plugin myinfo = { name = "KnifeRevert", author = "Dogan", description = "Tool for Admins to prevent teamkilling cause of zombie knifing (ZE)", version = "1.1.0", url = "" } public void OnPluginStart() { ConVar cvar; HookConVarChange((cvar = CreateConVar("sm_kr_enabled", "1", "1 = sm_zabuse is available, 0 = sm_zabuse is not available", FCVAR_NONE, true, 0.0, true, 1.0)), g_cvZAbuse); g_bKnifeRevert = cvar.BoolValue; HookConVarChange((cvar = CreateConVar("sm_kr_slay", "0", "1 = slays the knifer automatically when sm_zabuse is used, 0 = don't do anything to the knifer", FCVAR_NONE, true, 0.0, true, 1.0)), g_cvSlayKnifer); g_bSlayKnifer = cvar.BoolValue; HookConVarChange((cvar = CreateConVar("sm_kr_maxdistance", "150.0", "max distance from the zombie that got knifed forward where infected humans will be rezurrected")), g_cvMaxDistance); g_fMaxDistance = cvar.FloatValue; HookConVarChange((cvar = CreateConVar("sm_kr_time", "6.0", "max time until sm_zabuse is available after a knife")), g_cvMaxTime); g_fMaxTime = cvar.FloatValue; delete cvar; HookEvent("player_hurt", OnPlayerHurt); RegAdminCmd("sm_kr", Command_KnifeRevert, ADMFLAG_GENERIC, "Undoes the damage caused by a zombie after being knifed forward"); RegAdminCmd("sm_kniferevert", Command_KnifeRevert, ADMFLAG_GENERIC, "Undoes the damage caused by a zombie after being knifed forward"); AutoExecConfig(true, "plugin.KnifeRevert"); g_iClientIndexKnifer = -1; g_iClientIndexKnifedZombie = -1; } public void g_cvZAbuse(ConVar convar, const char[] oldValue, const char[] newValue) { g_bKnifeRevert = convar.BoolValue; } public void g_cvSlayKnifer(ConVar convar, const char[] oldValue, const char[] newValue) { g_bSlayKnifer = convar.BoolValue; } public void g_cvMaxDistance(ConVar convar, const char[] oldValue, const char[] newValue) { g_fMaxDistance = convar.FloatValue; } public void g_cvMaxTime(ConVar convar, const char[] oldValue, const char[] newValue) { g_fMaxTime = convar.FloatValue; } public void OnPlayerHurt(Handle hEvent, const char[] name, bool dontBroadcast) { if(!g_bKnifeRevert) return; int attacker; int victim; char sWepName[64]; GetEventString(hEvent, "weapon", sWepName, sizeof(sWepName)); if((attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"))) == 0) return; if((victim = GetClientOfUserId(GetEventInt(hEvent, "userid"))) == 0) return; if(!IsClientInGame(attacker) || !IsPlayerAlive(attacker)) return; if(!IsClientInGame(victim) || !IsPlayerAlive(victim)) return; if(victim != attacker && GetClientTeam(victim) == CS_TEAM_T && GetClientTeam(attacker) == CS_TEAM_CT) { if(StrEqual(sWepName, "knife")) { int damage = GetEventInt(hEvent, "dmg_health"); if(damage < 35) return; g_iClientIndexKnifer = attacker; g_iClientIndexKnifedZombie = victim; g_bKnife = true; CreateTimer(g_fMaxTime, OnClientKnife, _, TIMER_FLAG_NO_MAPCHANGE); } } } public Action OnClientKnife(Handle timer) { g_bKnife = false; g_iClientIndexKnifer = -1; g_iClientIndexKnifedZombie = -1; for(int i = 1; i <= MaxClients; i++) { if(g_bInfectedInRadius[i]) { g_bInfectedInRadius[i] = false; } } } public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn) { if(!g_bKnifeRevert || !g_bKnife) return; static float fVec1[3]; static float fVec2[3]; GetClientAbsOrigin(g_iClientIndexKnifedZombie, fVec1); GetClientAbsOrigin(client, fVec2); float fDistance = GetVectorDistance(fVec1, fVec2, false); if(fDistance <= g_fMaxDistance) g_bInfectedInRadius[client] = true; } public Action Command_KnifeRevert(int client, int argc) { if(!g_bKnifeRevert) { ReplyToCommand(client, "[SM] Disabled on this Map."); return Plugin_Handled; } if(!g_bKnife) { ReplyToCommand(client, "[SM] Not available right now because there was no active Zombie Knifing the past %d Seconds.", RoundFloat(g_fMaxTime)); return Plugin_Handled; } ReplyToCommand(client, "[SM] You undid the damage from the previous Knife!"); PrintToChatAll("[SM] %N undid the damage from the previous Zombie Knife.", client); LogAction(client, -1, "\"%L\" undid the damage from the previous Zombie Knife.", client); if(g_bSlayKnifer) { ForcePlayerSuicide(g_iClientIndexKnifer); PrintToChat(g_iClientIndexKnifer, "[SM] You got slayed for knifing a Zombie forward!"); } int IdKnifedZombie = GetClientUserId(g_iClientIndexKnifedZombie); ServerCommand("zr_ztele_force #%d", IdKnifedZombie); PrintToChat(g_iClientIndexKnifedZombie, "[SM] You got teleported back because you were knifed forward."); for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && IsPlayerAlive(i) && g_bInfectedInRadius[i]) { ZR_HumanClient(i, false, false); PrintToChat(i, "[SM] You were rezurrected because you died after a Zombie was knifed forward."); } } return Plugin_Handled; }