#pragma semicolon 1 #pragma newdecls required #include #include #include #undef REQUIRE_PLUGIN #include #define REQUIRE_PLUGIN ConVar g_CVar_sv_enablebunnyhopping; ConVar g_CVar_zr_disablebunnyhopping; enum { LIMITED_NONE = 0, LIMITED_GENERAL = 1, LIMITED_ZOMBIE = 2 } bool g_bEnabled = false; bool g_bZombieEnabled = false; bool g_bInOnPlayerRunCmd = false; int g_ClientLimited[MAXPLAYERS + 1] = {LIMITED_NONE, ...}; int g_ActiveLimitedFlags = LIMITED_GENERAL; public Plugin myinfo = { name = "Selective Bunnyhop", author = "BotoX", description = "Disables bunnyhop on certain players/groups", version = "0.1" } public void OnPluginStart() { g_CVar_sv_enablebunnyhopping = FindConVar("sv_enablebunnyhopping"); g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_REPLICATED; g_CVar_sv_enablebunnyhopping.AddChangeHook(OnConVarChanged); g_bEnabled = g_CVar_sv_enablebunnyhopping.BoolValue; g_CVar_zr_disablebunnyhopping = CreateConVar("zr_disablebunnyhopping", "0", "Disable bhop for zombies.", FCVAR_NOTIFY); g_CVar_zr_disablebunnyhopping.AddChangeHook(OnConVarChanged); g_bZombieEnabled = g_CVar_zr_disablebunnyhopping.BoolValue; HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy); /* Late load */ for(int i = 1; i <= MaxClients; i++) { if(!IsClientInGame(i) || IsFakeClient(i)) return; if(ZR_IsClientZombie(i)) AddLimitedFlag(i, LIMITED_ZOMBIE); } UpdateLimitedFlags(); UpdateClients(); } public void OnClientPutInServer(int client) { TransmitConVar(client); } public void OnPluginEnd() { g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled; g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_REPLICATED|FCVAR_NOTIFY; for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && !IsFakeClient(i)) { if(g_CVar_sv_enablebunnyhopping.BoolValue) g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "1"); else g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "0"); } } } public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) { if(convar == g_CVar_sv_enablebunnyhopping) { if(g_bInOnPlayerRunCmd) return; g_bEnabled = convar.BoolValue; UpdateClients(); } else if(convar == g_CVar_zr_disablebunnyhopping) { g_bZombieEnabled = convar.BoolValue; UpdateLimitedFlags(); } } public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) { if(!g_bEnabled) return Plugin_Continue; bool bEnableBunnyhopping = !(g_ClientLimited[client] & g_ActiveLimitedFlags); if(bEnableBunnyhopping == g_CVar_sv_enablebunnyhopping.BoolValue) return Plugin_Continue; if(!g_bInOnPlayerRunCmd) { g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_NOTIFY; g_bInOnPlayerRunCmd = true; } g_CVar_sv_enablebunnyhopping.BoolValue = bEnableBunnyhopping; return Plugin_Continue; } public void OnRunThinkFunctionsPost(bool simulating) { if(g_bInOnPlayerRunCmd) { g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled; g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_NOTIFY; g_bInOnPlayerRunCmd = false; } } public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn) { AddLimitedFlag(client, LIMITED_ZOMBIE); } public void ZR_OnClientHumanPost(int client, bool respawn, bool protect) { RemoveLimitedFlag(client, LIMITED_ZOMBIE); } public void ZR_OnClientRespawned(int client, ZR_RespawnCondition condition) { if(condition == ZR_Respawn_Human) RemoveLimitedFlag(client, LIMITED_ZOMBIE); else AddLimitedFlag(client, LIMITED_ZOMBIE); } public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) { RemoveLimitedFlag(-1, LIMITED_ZOMBIE); } void UpdateLimitedFlags() { int Flags = LIMITED_GENERAL; if(g_bZombieEnabled) Flags |= LIMITED_ZOMBIE; if(g_ActiveLimitedFlags != Flags) { g_ActiveLimitedFlags = Flags; UpdateClients(); } g_ActiveLimitedFlags = Flags; } stock void AddLimitedFlag(int client, int Flag) { if(client == -1) { for(int i = 1; i <= MaxClients; i++) _AddLimitedFlag(i, Flag); } else _AddLimitedFlag(client, Flag); } stock void _AddLimitedFlag(int client, int Flag) { bool bWasLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); g_ClientLimited[client] |= Flag; bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); if(bIsLimited != bWasLimited) TransmitConVar(client); } stock void RemoveLimitedFlag(int client, int Flag) { if(client == -1) { for(int i = 1; i <= MaxClients; i++) _RemoveLimitedFlag(i, Flag); } else _RemoveLimitedFlag(client, Flag); } stock void _RemoveLimitedFlag(int client, int Flag) { bool bWasLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); g_ClientLimited[client] &= ~Flag; bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); if(bIsLimited != bWasLimited) TransmitConVar(client); } stock void UpdateClients() { for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i)) TransmitConVar(i); } } stock void TransmitConVar(int client) { if(!IsClientInGame(client) || IsFakeClient(client)) return; bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); if(g_bEnabled && !bIsLimited) g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "1"); else g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "0"); }