Skip to content

Commit

Permalink
Allow clients to toggle auto-bunnyhopping as a preference (#9)
Browse files Browse the repository at this point in the history
* Add command to toggle auto-bunnyhopping

* Properly load preferences on reload and create CanBunnyhop

* Add command responses

* Bump version
  • Loading branch information
Mikusch authored Aug 3, 2021
1 parent 4767247 commit 4079673
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
55 changes: 53 additions & 2 deletions addons/sourcemod/scripting/tf-bhop.sp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <clientprefs>
#include <tf2_stocks>
#include <memorypatch>

Expand All @@ -37,21 +38,24 @@ ConVar sv_autobunnyhopping;
ConVar sv_autobunnyhopping_falldamage;
ConVar sv_duckbunnyhopping;

Cookie g_CookieAutoBunnyhoppingDisabled;

Handle g_SDKCallCanAirDash;
Handle g_SDKCallAttribHookValue;
MemoryPatch g_MemoryPatchAllowDuckJumping;
MemoryPatch g_MemoryPatchAllowBunnyJumping;

bool g_IsBunnyHopping[MAXPLAYERS + 1];
bool g_InJumpRelease[MAXPLAYERS + 1];
bool g_IsAutobunnyHoppingDisabled[MAXPLAYERS + 1];
bool g_InTriggerPush;

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"
}

Expand All @@ -60,19 +64,28 @@ 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");
sv_autobunnyhopping_falldamage = CreateConVar("sv_autobunnyhopping_falldamage", "0", "Players can take fall damage while auto-bunnyhopping");
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");
Expand Down Expand Up @@ -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)
Expand All @@ -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;

Expand All @@ -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)
Expand All @@ -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))
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions addons/sourcemod/translations/tf-bhop.phrases.txt
Original file line number Diff line number Diff line change
@@ -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."
}
}

0 comments on commit 4079673

Please sign in to comment.