diff --git a/README.md b/README.md
index d224265e1..d16cf5cc8 100644
--- a/README.md
+++ b/README.md
@@ -140,6 +140,7 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
| mp_stamina_restore_rate | 0 | 0.0 | - | Framerate (FPS), that used as reference when restoring stamina (fuser2) after jump. |
| mp_logkills | 1 | 0 | 1 | Log kills.
`0` disabled
`1` enabled |
| mp_jump_height | 45 | 0.0 | - | Player jump height. |
+| mp_longjump_cooldown | 0.0 | 0.0 | - | Cooldown time (in seconds) between long jumps to prevent abuse.
`0` disabled
`>0` seconds before the player can long jump again. During cooldown, only a regular vertical jump is performed. |
| bot_excellent_morale | 0 | 0 | 1 | Bots always have great morale regardless of defeat or victory. |
| mp_randomspawn | 0 | 0 | 1 | Random player spawns
`0` disabled
`1` enabled
`NOTE`: Navigation `maps/.nav` file required |
| mp_playerid_showhealth | 1 | 0 | 2 | Player ID display mode.
`0` don't show health
`1` show health for teammates only (default CS behaviour)
`2` show health for all players |
diff --git a/dist/game.cfg b/dist/game.cfg
index fc59a237e..14c752a46 100644
--- a/dist/game.cfg
+++ b/dist/game.cfg
@@ -670,6 +670,13 @@ mp_stamina_restore_rate "0"
// Default value: "45"
mp_jump_height "45"
+// Cooldown time (in seconds) between long jumps to prevent abuse.
+// 0 - disabled (default behaviour)
+// >0 - seconds before the player can long jump again
+//
+// Default value: "0.0"
+mp_longjump_cooldown "0.0"
+
// Bots always have great morale regardless of defeat or victory.
// 0 - disabled (default behaviour)
// 1 - enabled
diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp
index 01e07b92a..b62448568 100644
--- a/regamedll/dlls/game.cpp
+++ b/regamedll/dlls/game.cpp
@@ -174,6 +174,7 @@ cvar_t assist_damage_threshold = { "mp_assist_damage_threshold", "40",
cvar_t freezetime_duck = { "mp_freezetime_duck", "1", 0, 1.0f, nullptr };
cvar_t freezetime_jump = { "mp_freezetime_jump", "1", 0, 1.0f, nullptr };
cvar_t jump_height = { "mp_jump_height", "45", FCVAR_SERVER, 45.0f, nullptr };
+cvar_t longjump_cooldown = { "mp_longjump_cooldown", "0.0", 0, 0.0f, nullptr };
cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
@@ -469,6 +470,7 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&freezetime_duck);
CVAR_REGISTER(&freezetime_jump);
CVAR_REGISTER(&jump_height);
+ CVAR_REGISTER(&longjump_cooldown);
CVAR_REGISTER(&defuser_allocation);
CVAR_REGISTER(&location_area_info);
CVAR_REGISTER(&chat_loc_fallback);
diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h
index 741e0a571..a195e4fc2 100644
--- a/regamedll/dlls/game.h
+++ b/regamedll/dlls/game.h
@@ -203,6 +203,7 @@ extern cvar_t assist_damage_threshold;
extern cvar_t freezetime_duck;
extern cvar_t freezetime_jump;
extern cvar_t jump_height;
+extern cvar_t longjump_cooldown;
extern cvar_t defuser_allocation;
extern cvar_t location_area_info;
extern cvar_t chat_loc_fallback;
diff --git a/regamedll/pm_shared/pm_shared.cpp b/regamedll/pm_shared/pm_shared.cpp
index 846b410d0..b524513e3 100644
--- a/regamedll/pm_shared/pm_shared.cpp
+++ b/regamedll/pm_shared/pm_shared.cpp
@@ -2762,25 +2762,40 @@ void EXT_FUNC __API_HOOK(PM_Jump)()
// UNDONE: note this should be based on forward angles, not current velocity.
if (cansuperjump && (pmove->cmd.buttons & IN_DUCK) && pmove->flDuckTime > 0 && Length(pmove->velocity) > 50)
{
- pmove->punchangle[0] = -5.0f;
-
-#ifdef REGAMEDLL_API
- if (pmoveplayer->m_flLongJumpForce > 0.0)
+#ifdef REGAMEDLL_ADD
+ if (pmove->fuser4 > 0.0f)
{
- fvel = pmoveplayer->m_flLongJumpForce;
+ pmove->velocity[2] = PM_JumpHeight(false);
}
else
#endif
{
- fvel = PLAYER_LONGJUMP_SPEED * 1.6f;
- }
+ pmove->punchangle[0] = -5.0f;
- for (int i = 0; i < 2; i++)
- {
- pmove->velocity[i] = pmove->forward[i] * fvel;
- }
+#ifdef REGAMEDLL_API
+ if (pmoveplayer->m_flLongJumpForce > 0.0)
+ {
+ fvel = pmoveplayer->m_flLongJumpForce;
+ }
+ else
+#endif
+ {
+ fvel = PLAYER_LONGJUMP_SPEED * 1.6f;
+ }
- pmove->velocity[2] = PM_JumpHeight(true);
+ for (int i = 0; i < 2; i++)
+ {
+ pmove->velocity[i] = pmove->forward[i] * fvel;
+ }
+
+ pmove->velocity[2] = PM_JumpHeight(true);
+#ifdef REGAMEDLL_ADD
+ if (longjump_cooldown.value > 0.0f)
+ {
+ pmove->fuser4 = longjump_cooldown.value * 1000.0f;
+ }
+#endif
+ }
}
else
{
@@ -3112,6 +3127,18 @@ void PM_ReduceTimers()
pmove->fuser2 = 0;
}
}
+
+#ifdef REGAMEDLL_ADD
+ if (pmove->fuser4 > 0.0)
+ {
+ pmove->fuser4 -= pmove->cmd.msec;
+
+ if (pmove->fuser4 < 0.0)
+ {
+ pmove->fuser4 = 0;
+ }
+ }
+#endif
}
qboolean PM_ShouldDoSpectMode()