diff --git a/README.md b/README.md
index 11d53aa1..4de3ba2a 100644
--- a/README.md
+++ b/README.md
@@ -23,8 +23,6 @@ Includes a records system, map zones (start/end marks etc), bonuses, HUD with us
# Optional requirements, for the best experience:
* [eventqueuefix](https://github.com/hermansimensen/eventqueue-fix)
* Allows for timescaling boosters and is used to fix some exploits. (Use this instead of `boosterfix`)
-* [Bunnyhop Statistics](https://forums.alliedmods.net/showthread.php?t=286135)
- * Used for scroll styles and also required for TF2.
* [SteamWorks](https://forums.alliedmods.net/showthread.php?t=229556)
* Used to grab `{serverip}` in advertisements.
* [DynamicChannels](https://github.com/Vauff/DynamicChannels)
@@ -126,7 +124,6 @@ Admin commands: (ROOT flag)
### shavit-hud
The HUD plugin is `bhoptimer`'s OSD frontend.
It shows most (if not all) of the information that the player needs to see.
-`shavit-hud` integrates with [Bunnyhop Statistics](https://github.com/shavitush/bhopstats) for CS:S.
Some features are: Per-player settings (!hud), truevel, and gradient-like display (CS:GO).
diff --git a/addons/sourcemod/scripting/include/bhopstats.inc b/addons/sourcemod/scripting/include/shavit/bhopstats-timerified.inc
similarity index 66%
rename from addons/sourcemod/scripting/include/bhopstats.inc
rename to addons/sourcemod/scripting/include/shavit/bhopstats-timerified.inc
index 33ca286f..31ea3a37 100644
--- a/addons/sourcemod/scripting/include/bhopstats.inc
+++ b/addons/sourcemod/scripting/include/shavit/bhopstats-timerified.inc
@@ -16,21 +16,12 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*
-*/
+ */
-#if defined _bhopstats_included
+#if defined _shavit_bhopstats_included
#endinput
#endif
-#define _bhopstats_included
-
-#define BHOPSTATS_VERSION "1.2.0"
-
-enum CheatType
-{
- Cheat_HighPerfects = 0,
- Cheat_Auto,
- Cheat_JumpSpam
-}
+#define _shavit_bhopstats_included
/**
* Called when the jump key is pressed.
@@ -40,7 +31,7 @@ enum CheatType
* @param perfect Was the jump perfectly timed?
* @noreturn
*/
-forward void Bunnyhop_OnJumpPressed(int client, bool onground, bool perfect);
+forward void Shavit_Bhopstats_OnJumpPressed(int client, bool onground, bool perfect);
/**
* Called when the jump key is released.
@@ -49,7 +40,7 @@ forward void Bunnyhop_OnJumpPressed(int client, bool onground, bool perfect);
* @param onground True if the jump key will do anything for the player when tapped.
* @noreturn
*/
-forward void Bunnyhop_OnJumpReleased(int client, bool onground);
+forward void Shavit_Bhopstats_OnJumpReleased(int client, bool onground);
/**
* Called when the player touches the ground.
@@ -57,7 +48,7 @@ forward void Bunnyhop_OnJumpReleased(int client, bool onground);
* @param client Client index.
* @noreturn
*/
-forward void Bunnyhop_OnTouchGround(int client);
+forward void Shavit_Bhopstats_OnTouchGround(int client);
/**
* Called when the player leaves the ground, by either jumping or falling from somewhere.
@@ -70,7 +61,7 @@ forward void Bunnyhop_OnTouchGround(int client);
* @param ladder Did the client leave the ground by leaving a ladder, aka ladderstrafing?
* @noreturn
*/
-forward void Bunnyhop_OnLeaveGround(int client, bool jumped, bool ladder);
+forward void Shavit_Bhopstats_OnLeaveGround(int client, bool jumped, bool ladder);
/**
* Retrieves the amount of separate +jump inputs since the player left the ground.
@@ -78,7 +69,7 @@ forward void Bunnyhop_OnLeaveGround(int client, bool jumped, bool ladder);
* @param client Client index.
* @return Amount of +jump inputs since the left the ground, or 0 if the player is on ground.
*/
-native int Bunnyhop_GetScrollCount(int client);
+native int Shavit_Bhopstats_GetScrollCount(int client);
/**
* Checks if the player is on ground, or if the jump key will function as in actually triggering a jump or altering velocity.
@@ -87,7 +78,7 @@ native int Bunnyhop_GetScrollCount(int client);
* @param client Client index.
* @return Boolean value of 'is the player on ground?'
*/
-native bool Bunnyhop_IsOnGround(int client);
+native bool Shavit_Bhopstats_IsOnGround(int client);
/**
* Checks if the player is holding his jump key.
@@ -95,16 +86,16 @@ native bool Bunnyhop_IsOnGround(int client);
* @param client Client index.
* @return Boolean value of 'is the player holding the jump key?''
*/
-native bool Bunnyhop_IsHoldingJump(int client);
+native bool Shavit_Bhopstats_IsHoldingJump(int client);
/**
* Gets a percentage of perfectly timed bunnyhops.
- * Resets at player connection or the Bunnyhop_ResetPerfectJumps native for it is called.
+ * Resets at player connection or the Shavit_Bhopstats_ResetPerfectJumps native for it is called.
*
* @param client Client index.
* @return Perfect jump percentage. Results are from 0.0 to 100.0.
*/
-native float Bunnyhop_GetPerfectJumps(int client);
+native float Shavit_Bhopstats_GetPerfectJumps(int client);
/**
* Resets the perfect jumps percentage of a player back to 0.0.
@@ -112,13 +103,13 @@ native float Bunnyhop_GetPerfectJumps(int client);
* @param client Client index.
* @noreturn
*/
-native void Bunnyhop_ResetPerfectJumps(int client);
+native void Shavit_Bhopstats_ResetPerfectJumps(int client);
-methodmap BunnyhopStats __nullable__
+methodmap Shavit_BunnyhopStats __nullable__
{
- public BunnyhopStats(int client)
+ public Shavit_BunnyhopStats(int client)
{
- return view_as(client);
+ return view_as(client);
}
property int index
@@ -133,7 +124,7 @@ methodmap BunnyhopStats __nullable__
{
public get()
{
- return Bunnyhop_GetScrollCount(this.index);
+ return Shavit_Bhopstats_GetScrollCount(this.index);
}
}
@@ -141,7 +132,7 @@ methodmap BunnyhopStats __nullable__
{
public get()
{
- return Bunnyhop_IsOnGround(this.index);
+ return Shavit_Bhopstats_IsOnGround(this.index);
}
}
@@ -149,7 +140,7 @@ methodmap BunnyhopStats __nullable__
{
public get()
{
- return Bunnyhop_IsHoldingJump(this.index);
+ return Shavit_Bhopstats_IsHoldingJump(this.index);
}
}
@@ -157,59 +148,48 @@ methodmap BunnyhopStats __nullable__
{
public get()
{
- return Bunnyhop_GetPerfectJumps(this.index);
+ return Shavit_Bhopstats_GetPerfectJumps(this.index);
}
}
public void ResetPrefects()
{
- Bunnyhop_ResetPerfectJumps(this.index);
+ Shavit_Bhopstats_ResetPerfectJumps(this.index);
}
public static int GetScrollCount(int client)
{
- return Bunnyhop_GetScrollCount(client);
+ return Shavit_Bhopstats_GetScrollCount(client);
}
public static bool IsOnGround(int client)
{
- return Bunnyhop_IsOnGround(client);
+ return Shavit_Bhopstats_IsOnGround(client);
}
public static bool IsHoldingJump(int client)
{
- return Bunnyhop_IsHoldingJump(client);
+ return Shavit_Bhopstats_IsHoldingJump(client);
}
public static float GetPerfectJumps(int client)
{
- return Bunnyhop_GetPerfectJumps(client);
+ return Shavit_Bhopstats_GetPerfectJumps(client);
}
public static float ResetPrefectJumps(int client)
{
- return Bunnyhop_ResetPerfectJumps(client);
+ return Shavit_Bhopstats_ResetPerfectJumps(client);
}
}
-public SharedPlugin __pl_bhopstats =
-{
- name = "bhopstats",
- file = "bhopstats.smx",
-#if defined REQUIRE_PLUGIN
- required = 1
-#else
- required = 0
-#endif
-};
-
#if !defined REQUIRE_PLUGIN
-public void __pl_bhopstats_SetNTVOptional()
+public void __pl_shavit_bhopstats_SetNTVOptional()
{
- MarkNativeAsOptional("Bunnyhop_GetScrollCount");
- MarkNativeAsOptional("Bunnyhop_IsOnGround");
- MarkNativeAsOptional("Bunnyhop_IsHoldingJump");
- MarkNativeAsOptional("Bunnyhop_GetPerfectJumps");
- MarkNativeAsOptional("Bunnyhop_ResetPerfectJumps");
+ MarkNativeAsOptional("Shavit_Bhopstats_GetScrollCount");
+ MarkNativeAsOptional("Shavit_Bhopstats_IsOnGround");
+ MarkNativeAsOptional("Shavit_Bhopstats_IsHoldingJump");
+ MarkNativeAsOptional("Shavit_Bhopstats_GetPerfectJumps");
+ MarkNativeAsOptional("Shavit_Bhopstats_ResetPerfectJumps");
}
#endif
diff --git a/addons/sourcemod/scripting/include/shavit/bhopstats-timerified.sp b/addons/sourcemod/scripting/include/shavit/bhopstats-timerified.sp
index e69de29b..1baee482 100644
--- a/addons/sourcemod/scripting/include/shavit/bhopstats-timerified.sp
+++ b/addons/sourcemod/scripting/include/shavit/bhopstats-timerified.sp
@@ -0,0 +1,167 @@
+/*
+ * Bunnyhop Statistics API - Plugin
+ * by: shavit
+ *
+ * This file is part of Bunnyhop Statistics API.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ *
+ */
+
+#pragma newdecls required
+#pragma semicolon 1
+
+bool gB_OnGround[MAXPLAYERS+1];
+bool gB_PlayerTouchingGround[MAXPLAYERS+1];
+
+int gI_Scrolls[MAXPLAYERS+1];
+int gI_Buttons[MAXPLAYERS+1];
+bool gB_JumpHeld[MAXPLAYERS+1];
+
+int gI_Jumps[MAXPLAYERS+1];
+int gI_PerfectJumps[MAXPLAYERS+1];
+
+Handle gH_Forwards_OnJumpPressed = null;
+Handle gH_Forwards_OnJumpReleased = null;
+Handle gH_Forwards_OnTouchGround = null;
+Handle gH_Forwards_OnLeaveGround = null;
+
+public void Bhopstats_CreateNatives()
+{
+ CreateNative("Shavit_Bhopstats_GetScrollCount", Native_GetScrollCount);
+ CreateNative("Shavit_Bhopstats_IsOnGround", Native_IsOnGround);
+ CreateNative("Shavit_Bhopstats_IsHoldingJump", Native_IsHoldingJump);
+ CreateNative("Shavit_Bhopstats_GetPerfectJumps", Native_Bhopstats_GetPerfectJumps);
+ CreateNative("Shavit_Bhopstats_ResetPerfectJumps", Native_ResetPerfectJumps);
+}
+
+public void Bhopstats_CreateForwards()
+{
+ gH_Forwards_OnJumpPressed = CreateGlobalForward("Shavit_Bhopstats_OnJumpPressed", ET_Event, Param_Cell, Param_Cell);
+ gH_Forwards_OnJumpReleased = CreateGlobalForward("Shavit_Bhopstats_OnJumpReleased", ET_Event, Param_Cell, Param_Cell);
+ gH_Forwards_OnTouchGround = CreateGlobalForward("Shavit_Bhopstats_OnTouchGround", ET_Event, Param_Cell);
+ gH_Forwards_OnLeaveGround = CreateGlobalForward("Shavit_Bhopstats_OnLeaveGround", ET_Event, Param_Cell, Param_Cell, Param_Cell);
+}
+
+public void Bhopstats_OnClientPutInServer(int client)
+{
+ gB_OnGround[client] = false;
+ gB_PlayerTouchingGround[client] = false;
+
+ gI_Scrolls[client] = 0;
+ gI_Buttons[client] = 0;
+ gB_JumpHeld[client] = false;
+
+ gI_Jumps[client] = 0;
+ gI_PerfectJumps[client] = 0;
+
+ SDKHook(client, SDKHook_PostThinkPost, Bhopstats_PostThinkPost);
+}
+
+public int Native_GetScrollCount(Handle handler, int numParams)
+{
+ return gI_Scrolls[GetNativeCell(1)];
+}
+
+public int Native_IsOnGround(Handle handler, int numParams)
+{
+ return view_as(gB_OnGround[GetNativeCell(1)]);
+}
+
+public int Native_IsHoldingJump(Handle handler, int numParams)
+{
+ return view_as(gI_Buttons[GetNativeCell(1)] & IN_JUMP);
+}
+
+public int Native_Bhopstats_GetPerfectJumps(Handle handler, int numParams)
+{
+ int client = GetNativeCell(1);
+
+ return view_as((float(gI_PerfectJumps[client]) / gI_Jumps[client]) * 100.0);
+}
+
+public int Native_ResetPerfectJumps(Handle handler, int numParams)
+{
+ int client = GetNativeCell(1);
+
+ gI_Jumps[client] = 0;
+ gI_PerfectJumps[client] = 0;
+}
+
+public void Bhopstats_PostThinkPost(int client)
+{
+ if(!IsPlayerAlive(client))
+ {
+ return;
+ }
+
+ int buttons = GetClientButtons(client);
+ bool bOldOnGround = gB_OnGround[client];
+
+ int iGroundEntity = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity");
+ bool bOnLadder = (GetEntityMoveType(client) == MOVETYPE_LADDER);
+ gB_OnGround[client] = (iGroundEntity != -1 || GetEntProp(client, Prop_Send, "m_nWaterLevel") >= 2 || bOnLadder);
+
+ gB_JumpHeld[client] = (buttons & IN_JUMP && !(gI_Buttons[client] & IN_JUMP));
+
+ if(gB_PlayerTouchingGround[client] && gB_OnGround[client])
+ {
+ Call_StartForward(gH_Forwards_OnTouchGround);
+ Call_PushCell(client);
+ Call_Finish();
+
+ gB_PlayerTouchingGround[client] = false;
+ }
+
+ else if(!gB_PlayerTouchingGround[client] && ((gB_JumpHeld[client] && iGroundEntity != -1) || iGroundEntity == -1 || bOnLadder))
+ {
+ Call_StartForward(gH_Forwards_OnLeaveGround);
+ Call_PushCell(client);
+ Call_PushCell(gB_JumpHeld[client]);
+ Call_PushCell(bOnLadder);
+ Call_Finish();
+
+ gB_PlayerTouchingGround[client] = true;
+ gI_Scrolls[client] = 0;
+ }
+
+ if(gB_JumpHeld[client])
+ {
+ gI_Scrolls[client]++;
+
+ Call_StartForward(gH_Forwards_OnJumpPressed);
+ Call_PushCell(client);
+ Call_PushCell(gB_OnGround[client]);
+ Call_Finish();
+
+ if(gB_OnGround[client])
+ {
+ gI_Jumps[client]++;
+
+ if(!bOldOnGround)
+ {
+ gI_PerfectJumps[client]++;
+ }
+ }
+ }
+
+ else if(gI_Buttons[client] & IN_JUMP && !(buttons & IN_JUMP))
+ {
+ Call_StartForward(gH_Forwards_OnJumpReleased);
+ Call_PushCell(client);
+ Call_PushCell(gB_OnGround[client]);
+ Call_Finish();
+ }
+
+ gI_Buttons[client] = buttons;
+}
diff --git a/addons/sourcemod/scripting/include/shavit/core.inc b/addons/sourcemod/scripting/include/shavit/core.inc
index ac395f1e..0d1e07fc 100644
--- a/addons/sourcemod/scripting/include/shavit/core.inc
+++ b/addons/sourcemod/scripting/include/shavit/core.inc
@@ -28,6 +28,8 @@
#define SHAVIT_LOG_QUERIES 0
+#include
+
// status
enum TimerStatus
{
@@ -1351,5 +1353,7 @@ public void __pl_shavit_core_SetNTVOptional()
MarkNativeAsOptional("Shavit_SetStyleSettingFloat");
MarkNativeAsOptional("Shavit_SetStyleSettingBool");
MarkNativeAsOptional("Shavit_SetStyleSettingInt");
+
+ __pl_shavit_bhopstats_SetNTVOptional();
}
#endif
diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp
index 18fcf990..b6e2d65b 100644
--- a/addons/sourcemod/scripting/shavit-core.sp
+++ b/addons/sourcemod/scripting/shavit-core.sp
@@ -29,6 +29,7 @@
#define DEBUG 0
#include
+#include
#undef REQUIRE_PLUGIN
#include
@@ -166,6 +167,7 @@ public Plugin myinfo =
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
+ Bhopstats_CreateNatives();
Shavit_Style_Settings_Natives();
CreateNative("Shavit_CanPause", Native_CanPause);
@@ -240,6 +242,7 @@ public void OnPluginStart()
gH_Forwards_OnProcessMovement = CreateGlobalForward("Shavit_OnProcessMovement", ET_Event, Param_Cell);
gH_Forwards_OnProcessMovementPost = CreateGlobalForward("Shavit_OnProcessMovementPost", ET_Event, Param_Cell);
+ Bhopstats_CreateForwards();
Shavit_Style_Settings_Forwards();
LoadTranslations("shavit-core.phrases");
@@ -1304,7 +1307,7 @@ void ChangeClientStyle(int client, int style, bool manual)
}
// used as an alternative for games where player_jump isn't a thing, such as TF2
-public void Bunnyhop_OnLeaveGround(int client, bool jumped, bool ladder)
+public void Shavit_Bhopstats_OnLeaveGround(int client, bool jumped, bool ladder)
{
if(gB_HookedJump || !jumped || ladder)
{
@@ -2233,6 +2236,8 @@ public void OnClientPutInServer(int client)
return;
}
+ Bhopstats_OnClientPutInServer(client);
+
gB_Auto[client] = true;
gA_Timers[client].fStrafeWarning = 0.0;
gA_Timers[client].bPracticeMode = false;
diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp
index 9ce719dd..3d0b344b 100644
--- a/addons/sourcemod/scripting/shavit-hud.sp
+++ b/addons/sourcemod/scripting/shavit-hud.sp
@@ -33,7 +33,6 @@
#include
#include
#include
-#include
#include
#undef REQUIRE_EXTENSIONS
@@ -88,7 +87,6 @@ bool gB_ReplayPlayback = false;
bool gB_Zones = false;
bool gB_Sounds = false;
bool gB_Rankings = false;
-bool gB_BhopStats = false;
bool gB_DynamicChannels = false;
// cache
@@ -179,7 +177,6 @@ public void OnPluginStart()
gB_Zones = LibraryExists("shavit-zones");
gB_Sounds = LibraryExists("shavit-sounds");
gB_Rankings = LibraryExists("shavit-rankings");
- gB_BhopStats = LibraryExists("bhopstats");
gB_DynamicChannels = LibraryExists("DynamicChannels");
// HUD handle
@@ -313,11 +310,6 @@ public void OnLibraryAdded(const char[] name)
gB_Rankings = true;
}
- else if(StrEqual(name, "bhopstats"))
- {
- gB_BhopStats = true;
- }
-
else if(StrEqual(name, "DynamicChannels"))
{
gB_DynamicChannels = true;
@@ -346,11 +338,6 @@ public void OnLibraryRemoved(const char[] name)
gB_Rankings = false;
}
- else if(StrEqual(name, "bhopstats"))
- {
- gB_BhopStats = false;
- }
-
else if(StrEqual(name, "DynamicChannels"))
{
gB_DynamicChannels = false;
@@ -1770,7 +1757,7 @@ void UpdateKeyOverlay(int client, Panel panel, bool &draw)
char sPanelLine[128];
- if(gB_BhopStats && !Shavit_GetStyleSettingBool(style, "autobhop"))
+ if(!Shavit_GetStyleSettingBool(style, "autobhop"))
{
FormatEx(sPanelLine, 64, " %d%s%d\n", gI_ScrollCount[target], (gI_ScrollCount[target] > 9)? " ":" ", gI_LastScrollCount[target]);
}
@@ -1786,14 +1773,14 @@ void UpdateKeyOverlay(int client, Panel panel, bool &draw)
draw = true;
}
-public void Bunnyhop_OnTouchGround(int client)
+public void Shavit_Bhopstats_OnTouchGround(int client)
{
- gI_LastScrollCount[client] = BunnyhopStats.GetScrollCount(client);
+ gI_LastScrollCount[client] = Shavit_BunnyhopStats.GetScrollCount(client);
}
-public void Bunnyhop_OnJumpPressed(int client)
+public void Shavit_Bhopstats_OnJumpPressed(int client)
{
- gI_ScrollCount[client] = BunnyhopStats.GetScrollCount(client);
+ gI_ScrollCount[client] = Shavit_BunnyhopStats.GetScrollCount(client);
}
void UpdateCenterKeys(int client)
@@ -1861,7 +1848,7 @@ void UpdateCenterKeys(int client)
style = 0;
}
- if(gB_BhopStats && !Shavit_GetStyleSettingBool(style, "autobhop") && IsValidClient(target))
+ if(!Shavit_GetStyleSettingBool(style, "autobhop") && IsValidClient(target))
{
Format(sCenterText, sizeof(sCenterText), "%s\n  %d %d", sCenterText, gI_ScrollCount[target], gI_LastScrollCount[target]);
}