diff --git a/addons/sourcemod/scripting/tf-bhop.sp b/addons/sourcemod/scripting/tf-bhop.sp index f6fc329..64b0036 100644 --- a/addons/sourcemod/scripting/tf-bhop.sp +++ b/addons/sourcemod/scripting/tf-bhop.sp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,8 @@ ConVar sv_autobunnyhopping; ConVar sv_autobunnyhopping_falldamage; ConVar sv_duckbunnyhopping; +Cookie g_CookieAutoBunnyhoppingDisabled; + Handle g_SDKCallCanAirDash; Handle g_SDKCallAttribHookValue; MemoryPatch g_MemoryPatchAllowDuckJumping; @@ -44,6 +47,7 @@ MemoryPatch g_MemoryPatchAllowBunnyJumping; bool g_IsBunnyHopping[MAXPLAYERS + 1]; bool g_InJumpRelease[MAXPLAYERS + 1]; +bool g_IsAutobunnyHoppingDisabled[MAXPLAYERS + 1]; bool g_InTriggerPush; public Plugin myinfo = @@ -51,7 +55,7 @@ public Plugin myinfo = name = "Team Fortress 2 Bunnyhop", author = "Mikusch", description = "Simple TF2 bunnyhopping plugin", - version = "1.4.7", + version = "1.5.0", url = "https://github.com/Mikusch/tf-bhop" } @@ -60,6 +64,8 @@ public void OnPluginStart() if (GetEngineVersion() != Engine_TF2) SetFailState("This plugin is only compatible with Team Fortress 2"); + LoadTranslations("tf-bhop.phrases"); + sv_enablebunnyhopping = CreateConVar("sv_enablebunnyhopping", "1", "Allow player speed to exceed maximum running speed"); sv_enablebunnyhopping.AddChangeHook(ConVarChanged_PreventBunnyJumping); sv_autobunnyhopping = CreateConVar("sv_autobunnyhopping", "1", "Players automatically re-jump while holding jump button"); @@ -67,12 +73,19 @@ public void OnPluginStart() sv_duckbunnyhopping = CreateConVar("sv_duckbunnyhopping", "1", "Allow jumping while ducked"); sv_duckbunnyhopping.AddChangeHook(ConVarChanged_DuckBunnyhopping); + g_CookieAutoBunnyhoppingDisabled = new Cookie("autobunnyhopping_disabled", "Do not automatically re-jump while holding jump button", CookieAccess_Protected); + + RegConsoleCmd("sm_bhop", ConCmd_ToggleAutoBunnyhopping, "Toggle auto-bunnyhopping preference"); + AutoExecConfig(); for (int client = 1; client <= MaxClients; client++) { if (IsClientInGame(client)) OnClientPutInServer(client); + + if (AreClientCookiesCached(client)) + OnClientCookiesCached(client); } GameData gamedata = new GameData("tf-bhop"); @@ -131,6 +144,13 @@ public void OnClientPutInServer(int client) SDKHook(client, SDKHook_OnTakeDamage, OnClientTakeDamage); } +public void OnClientDisconnect(int client) +{ + g_IsBunnyHopping[client] = false; + g_InJumpRelease[client] = false; + g_IsAutobunnyHoppingDisabled[client] = false; +} + 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 (sv_autobunnyhopping.BoolValue) @@ -145,7 +165,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 { g_InJumpRelease[client] = false; } - else if (!g_InJumpRelease[client] && !IsInAVehicle(client) && GetWaterLevel(client) < WL_Waist && !TF2_IsPlayerInCondition(client, TFCond_HalloweenGhostMode) && !TF2_IsPlayerInCondition(client, TFCond_GrapplingHookLatched)) + else if (CanBunnyhop(client)) { g_InTriggerPush = false; @@ -172,6 +192,16 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 } } +public void OnClientCookiesCached(int client) +{ + char value[8]; + g_CookieAutoBunnyhoppingDisabled.Get(client, value, sizeof(value)); + + bool result; + if (value[0] != '\0' && StringToIntEx(value, result) > 0) + g_IsAutobunnyHoppingDisabled[client] = result; +} + public void ConVarChanged_DuckBunnyhopping(ConVar convar, const char[] oldValue, const char[] newValue) { if (g_MemoryPatchAllowDuckJumping) @@ -194,6 +224,17 @@ public void ConVarChanged_PreventBunnyJumping(ConVar convar, const char[] oldVal } } +public Action ConCmd_ToggleAutoBunnyhopping(int client, int args) +{ + bool value = g_IsAutobunnyHoppingDisabled[client] = !g_IsAutobunnyHoppingDisabled[client]; + + char strValue[8]; + if (IntToString(value, strValue, sizeof(strValue)) > 0) + g_CookieAutoBunnyhoppingDisabled.Set(client, strValue); + + ReplyToCommand(client, "%t", value ? "Auto-bunnyhopping disabled" : "Auto-bunnyhopping enabled"); +} + public Action OnClientTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype) { if (sv_autobunnyhopping.BoolValue && !sv_autobunnyhopping_falldamage.BoolValue && g_IsBunnyHopping[victim] && (attacker == 0) && (damagetype & DMG_FALL)) @@ -235,6 +276,16 @@ void CreateMemoryPatch(MemoryPatch &handle, const char[] name) LogError("Failed to create memory patch %s", name); } +bool CanBunnyhop(int client) +{ + return !g_IsAutobunnyHoppingDisabled[client] + && !g_InJumpRelease[client] + && !IsInAVehicle(client) + && GetWaterLevel(client) < WL_Waist + && !TF2_IsPlayerInCondition(client, TFCond_HalloweenGhostMode) + && !TF2_IsPlayerInCondition(client, TFCond_GrapplingHookLatched); +} + bool CanAirDash(int client) { if (g_SDKCallCanAirDash) diff --git a/addons/sourcemod/translations/tf-bhop.phrases.txt b/addons/sourcemod/translations/tf-bhop.phrases.txt new file mode 100644 index 0000000..fc530f5 --- /dev/null +++ b/addons/sourcemod/translations/tf-bhop.phrases.txt @@ -0,0 +1,12 @@ +"Phrases" +{ + "Auto-bunnyhopping enabled" + { + "en" "You will now automatically re-jump while holding the jump button." + } + + "Auto-bunnyhopping disabled" + { + "en" "You will no longer automatically re-jump while holding the jump button." + } +}