From 1c30450b34f6e84f667c55721aa0ac979d613b0a Mon Sep 17 00:00:00 2001 From: Nord1cWarr1or Date: Thu, 27 Aug 2026 18:08:41 +0300 Subject: [PATCH 1/9] Fix func_vehicle and func_tracktrain engine sound bleeding into adjacent precached sounds (#1185) --- regamedll/dlls/plats.cpp | 31 ++++++++++++++++++++++++++++++- regamedll/dlls/vehicle.cpp | 30 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/regamedll/dlls/plats.cpp b/regamedll/dlls/plats.cpp index f0735053b..4069d521c 100644 --- a/regamedll/dlls/plats.cpp +++ b/regamedll/dlls/plats.cpp @@ -1051,12 +1051,19 @@ void CFuncTrackTrain::StopSound() // if sound playing, stop it if (m_soundPlaying && pev->noise) { +#ifdef REGAMEDLL_FIXES + // Stop the sound through the engine sound API: SND_STOP is delivered as a reliable + // broadcast, while the event is PVS-filtered and can be missed by distant players, + // leaving the engine loop running on their side. + EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), 0, 0, SND_STOP, PITCH_NORM); +#else unsigned short us_encode; unsigned short us_sound = ((unsigned short)(m_sounds) & 0x0007) << 12; us_encode = us_sound; PLAYBACK_EVENT_FULL(FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0); +#endif EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/ttrain_brake1.wav", m_flVolume, ATTN_NORM, 0, 100); } @@ -1070,19 +1077,40 @@ void CFuncTrackTrain::UpdateSound() #ifdef REGAMEDLL_FIXES float flpitch = TRAIN_STARTPITCH + (Q_abs(pev->speed) * (TRAIN_MAXPITCH - TRAIN_STARTPITCH) / TRAIN_MAXSPEED); + + // The engine sound API carries the pitch as a byte, keep it inside the intended range + if (flpitch > TRAIN_MAXPITCH) + flpitch = TRAIN_MAXPITCH; + + // Never report the engine pitch as exactly PITCH_NORM: a looping sound that is + // re-pitched to 100 drops out of the client's pitch-shifting mixer back into the + // plain playback path, which then runs past the end of the wave and mixes in + // whatever sound follows it in the client's sound cache. + // Same guard as CFuncRotating::RampPitchVol() and CAmbientGeneric. + int ipitch = int(flpitch); + if (ipitch == PITCH_NORM) + ipitch = PITCH_NORM - 1; #else float flpitch = TRAIN_STARTPITCH + (Q_abs(int(pev->speed)) * (TRAIN_MAXPITCH - TRAIN_STARTPITCH) / TRAIN_MAXSPEED); + int ipitch = int(flpitch); #endif if (!m_soundPlaying) { // play startup sound for train EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/ttrain_start1.wav", m_flVolume, ATTN_NORM, 0, 100); - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, 0, int(flpitch)); + EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, 0, ipitch); m_soundPlaying = 1; } else { +#ifdef REGAMEDLL_FIXES + // Update pitch/volume through the engine sound API instead of the client event: + // the event packs the pitch as pitch / 10 into 6 bits, so the range is quantized + // to steps of 10 and everything in [100, 110) arrives as PITCH_NORM. The event is + // also PVS-filtered, while the sound itself is started with a reliable broadcast. + EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH | SND_CHANGE_VOL, ipitch); +#else // update pitch // EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, int(flpitch)); @@ -1099,6 +1127,7 @@ void CFuncTrackTrain::UpdateSound() us_encode = us_sound | us_pitch | us_volume; PLAYBACK_EVENT_FULL(FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0); +#endif } } diff --git a/regamedll/dlls/vehicle.cpp b/regamedll/dlls/vehicle.cpp index 7bf2d4184..83b69db4b 100644 --- a/regamedll/dlls/vehicle.cpp +++ b/regamedll/dlls/vehicle.cpp @@ -288,10 +288,17 @@ void CFuncVehicle::StopSound() { if (m_soundPlaying && pev->noise) { +#ifdef REGAMEDLL_FIXES + // Stop the sound through the engine sound API: SND_STOP is delivered as a reliable + // broadcast, while the event is PVS-filtered and can be missed by distant players, + // leaving the engine loop running on their side. + EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), 0, 0, SND_STOP, PITCH_NORM); +#else unsigned short us_sound = ((unsigned short)m_sounds & 0x0007) << 12; unsigned short us_encode = us_sound; PLAYBACK_EVENT_FULL(FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, us_encode, 0, 1, 0); +#endif } m_soundPlaying = 0; @@ -311,6 +318,19 @@ void CFuncVehicle::UpdateSound() if (flpitch > 200) flpitch = 200; +#ifdef REGAMEDLL_FIXES + // Never report the engine pitch as exactly PITCH_NORM: a looping sound that is + // re-pitched to 100 drops out of the client's pitch-shifting mixer back into the + // plain playback path, which then runs past the end of the wave and mixes in + // whatever sound follows it in the client's sound cache. + // Same guard as CFuncRotating::RampPitchVol() and CAmbientGeneric. + int ipitch = int(flpitch); + if (ipitch == PITCH_NORM) + ipitch = PITCH_NORM - 1; +#else + int ipitch = int(flpitch); +#endif + if (!m_soundPlaying) { if (m_sounds < 5) @@ -318,17 +338,25 @@ void CFuncVehicle::UpdateSound() EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/vehicle_brake1.wav", m_flVolume, ATTN_NORM, 0, 100); } - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, 0, int(flpitch)); + EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, 0, ipitch); m_soundPlaying = 1; } else { +#ifdef REGAMEDLL_FIXES + // Update pitch/volume through the engine sound API instead of the client event: + // the event packs the pitch as pitch / 10 into 6 bits, so the range is quantized + // to steps of 10 and everything in [100, 110) arrives as PITCH_NORM. The event is + // also PVS-filtered, while the sound itself is started with a reliable broadcast. + EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH | SND_CHANGE_VOL, ipitch); +#else unsigned short us_sound = ((unsigned short)(m_sounds) & 0x0007) << 12; unsigned short us_pitch = ((unsigned short)(flpitch / 10.0) & 0x003F) << 6; unsigned short us_volume = ((unsigned short)(m_flVolume * 40) & 0x003F); unsigned short us_encode = us_sound | us_pitch | us_volume; PLAYBACK_EVENT_FULL(FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0); +#endif } } From 9d24cfc3e4b77191703c7cad4b33c73a0aad571c Mon Sep 17 00:00:00 2001 From: Anton Bolshakov Date: Thu, 27 Aug 2026 23:24:48 +0800 Subject: [PATCH 2/9] regamedll: remove -s strip flag to preserve linker markers (#1176) The -s flag strips all symbols from the output shared library, including sentinel symbols used by packaging systems to verify LDFLAGS were respected (e.g. Gentoo's __gentoo_check_ldflags__). Same issue fixed in the sibling project: https://github.com/rehlds/Metamod-R/pull/93 --- regamedll/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt index b06fbde60..1eb1d4dd3 100644 --- a/regamedll/CMakeLists.txt +++ b/regamedll/CMakeLists.txt @@ -41,7 +41,7 @@ set(LINK_LIBS dl) # do not strip debuginfo during link if (NOT DEBUG) - set(LINK_FLAGS "-s") + set(LINK_FLAGS "") endif() # add -m32 flag only on 64-bit systems, if building for 64-bit wasn't enabled with XASH_COMPAT From 8e774428174224aadd3c25a13560248c2742005f Mon Sep 17 00:00:00 2001 From: Nord1cWarr1or Date: Thu, 27 Aug 2026 18:32:18 +0300 Subject: [PATCH 3/9] Use sv_zmax for player ID trace range instead of hardcoded MAX_ID_RANGE (#1182) --- regamedll/dlls/game.cpp | 2 ++ regamedll/dlls/game.h | 1 + regamedll/dlls/player.cpp | 8 +++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index 01e07b92a..839dfba1a 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -10,6 +10,7 @@ cvar_t *g_psv_stopspeed = nullptr; cvar_t *g_psv_stepsize = nullptr; cvar_t *g_psv_clienttrace = nullptr; cvar_t *g_psv_maxvelocity = nullptr; +cvar_t *g_psv_zmax = nullptr; cvar_t displaysoundlist = { "displaysoundlist", "0", 0, 0.0f, nullptr }; cvar_t timelimit = { "mp_timelimit", "0", FCVAR_SERVER, 0.0f, nullptr }; @@ -272,6 +273,7 @@ void EXT_FUNC GameDLLInit() g_psv_stepsize = CVAR_GET_POINTER("sv_stepsize"); g_psv_clienttrace = CVAR_GET_POINTER("sv_clienttrace"); g_psv_maxvelocity = CVAR_GET_POINTER("sv_maxvelocity"); + g_psv_zmax = CVAR_GET_POINTER("sv_zmax"); CVAR_REGISTER(&displaysoundlist); CVAR_REGISTER(&timelimit); diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h index 741e0a571..45f5330d9 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -50,6 +50,7 @@ extern cvar_t *g_psv_stopspeed; extern cvar_t *g_psv_stepsize; extern cvar_t *g_psv_clienttrace; extern cvar_t *g_psv_maxvelocity; +extern cvar_t *g_psv_zmax; extern cvar_t displaysoundlist; extern cvar_t timelimit; diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index 25b538ef2..a5419bd70 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -8252,7 +8252,13 @@ void EXT_FUNC CBasePlayer::__API_HOOK(UpdateStatusBar)() UTIL_MakeVectors(pev->v_angle + pev->punchangle); Vector vecSrc = EyePosition(); - Vector vecEnd = vecSrc + (gpGlobals->v_forward * ((pev->flags & FL_SPECTATOR) != 0 ? MAX_SPEC_ID_RANGE : MAX_ID_RANGE)); + Vector vecEnd = vecSrc + (gpGlobals->v_forward * ((pev->flags & FL_SPECTATOR) != 0 ? MAX_SPEC_ID_RANGE : +#ifdef REGAMEDLL_ADD + (g_psv_zmax ? g_psv_zmax->value : MAX_ID_RANGE) +#else + MAX_ID_RANGE +#endif + )); UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr); From 46674c181783aabb07dde0baa8eead611be6e6fb Mon Sep 17 00:00:00 2001 From: Nord1cWarr1or Date: Thu, 27 Aug 2026 18:32:27 +0300 Subject: [PATCH 4/9] Fix func_vehicle engine sound not stopping on round restart (#1183) --- regamedll/dlls/player.cpp | 26 +++++++++++++++-- regamedll/dlls/trains.h | 4 +++ regamedll/dlls/vehicle.cpp | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index a5419bd70..8a219ead3 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -4281,7 +4281,19 @@ void CBasePlayer::PlayerUse() if (legacy_vehicle_block.value == 0) return; #endif - ((CFuncVehicle *)pTrain)->m_pDriver = nullptr; + CFuncVehicle *pVehicle = (CFuncVehicle *)pTrain; + pVehicle->m_pDriver = nullptr; +#ifdef REGAMEDLL_FIXES + if (Q_abs(pTrain->pev->speed) < 50) + { + pVehicle->StopSound(); + pVehicle->SetThink(nullptr); + pTrain->pev->speed = 0; + pTrain->pev->velocity = g_vecZero; + pTrain->pev->avelocity = g_vecZero; + pVehicle->m_fEngineOn = FALSE; + } +#endif } return; } @@ -4299,8 +4311,18 @@ void CBasePlayer::PlayerUse() if (pTrain->Classify() == CLASS_VEHICLE) { + CFuncVehicle *pVehicle = (CFuncVehicle *)pTrain; +#ifdef REGAMEDLL_FIXES + if (!pVehicle->m_fEngineOn) + { + EMIT_SOUND(ENT(pev), CHAN_ITEM, "plats/vehicle_ignition.wav", 0.8, ATTN_NORM); + pVehicle->m_fEngineOn = TRUE; + pVehicle->UpdateSound(); + } +#else EMIT_SOUND(ENT(pev), CHAN_ITEM, "plats/vehicle_ignition.wav", 0.8, ATTN_NORM); - ((CFuncVehicle *)pTrain)->m_pDriver = this; +#endif + pVehicle->m_pDriver = this; } else EMIT_SOUND(ENT(pev), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM); diff --git a/regamedll/dlls/trains.h b/regamedll/dlls/trains.h index ebef8bf5f..33de0b548 100644 --- a/regamedll/dlls/trains.h +++ b/regamedll/dlls/trains.h @@ -198,6 +198,10 @@ class CFuncVehicle: public CBaseEntity Vector m_vSurfaceNormal; Vector m_vVehicleDirection; CBaseEntity *m_pDriver; +#ifdef REGAMEDLL_FIXES + int m_iCollisionCount; + BOOL m_fEngineOn; +#endif private: unsigned short m_usAdjustPitch; diff --git a/regamedll/dlls/vehicle.cpp b/regamedll/dlls/vehicle.cpp index 83b69db4b..fef3f7833 100644 --- a/regamedll/dlls/vehicle.cpp +++ b/regamedll/dlls/vehicle.cpp @@ -469,6 +469,9 @@ void CFuncVehicle::CollisionDetection() if (tr.flFraction == 1.0f) { +#ifdef REGAMEDLL_FIXES + m_iCollisionCount = 0; +#endif return; } } @@ -482,6 +485,16 @@ void CFuncVehicle::CollisionDetection() } else if (tr.vecPlaneNormal.z < 0.65 || tr.fStartSolid) { +#ifdef REGAMEDLL_FIXES + m_iCollisionCount++; + if (m_iCollisionCount >= 3) + { + pev->speed = 0; + pev->velocity = g_vecZero; + pev->avelocity = g_vecZero; + } + else +#endif pev->speed *= -1.0; } else @@ -500,6 +513,16 @@ void CFuncVehicle::CollisionDetection() } else if (tr.vecPlaneNormal[2] < 0.65f || tr.fStartSolid) { +#ifdef REGAMEDLL_FIXES + m_iCollisionCount++; + if (m_iCollisionCount >= 3) + { + pev->speed = 0; + pev->velocity = g_vecZero; + pev->avelocity = g_vecZero; + } + else +#endif pev->speed *= -1.0; } else @@ -530,6 +553,9 @@ void CFuncVehicle::CollisionDetection() if (tr.flFraction == 1.0f) { +#ifdef REGAMEDLL_FIXES + m_iCollisionCount = 0; +#endif return; } } @@ -544,6 +570,16 @@ void CFuncVehicle::CollisionDetection() } else if (tr.vecPlaneNormal.z < 0.65 || tr.fStartSolid) { +#ifdef REGAMEDLL_FIXES + m_iCollisionCount++; + if (m_iCollisionCount >= 3) + { + pev->speed = 0; + pev->velocity = g_vecZero; + pev->avelocity = g_vecZero; + } + else +#endif pev->speed *= -1.0; } else @@ -627,6 +663,12 @@ void CFuncVehicle::Next() pev->avelocity = g_vecZero; pev->velocity = g_vecZero; +#ifdef REGAMEDLL_FIXES + // Ensure idle sound is playing when vehicle stops + if (m_fEngineOn && !m_soundPlaying) + UpdateSound(); +#endif + SetThink(&CFuncVehicle::Next); NextThink(pev->ltime + time, TRUE); return; @@ -833,8 +875,13 @@ void CFuncVehicle::Find() UTIL_SetOrigin(pev, nextPos); NextThink(pev->ltime + 0.1, FALSE); SetThink(&CFuncVehicle::Next); +#ifdef REGAMEDLL_FIXES + if (m_fEngineOn) + pev->speed = m_startSpeed; +#else pev->speed = m_startSpeed; UpdateSound(); +#endif } void CFuncVehicle::NearestPath() @@ -930,6 +977,10 @@ void CFuncVehicle::Spawn() m_dir = 1; m_flTurnStartTime = -1; +#ifdef REGAMEDLL_FIXES + m_iCollisionCount = 0; + m_fEngineOn = FALSE; +#endif if (FStringNull(pev->target)) { @@ -974,6 +1025,10 @@ void CFuncVehicle::Restart() m_flTurnStartTime = -1; m_flUpdateSound = -1; m_pDriver = nullptr; +#ifdef REGAMEDLL_FIXES + m_iCollisionCount = 0; + m_fEngineOn = FALSE; +#endif if (FStringNull(pev->target)) { @@ -982,6 +1037,9 @@ void CFuncVehicle::Restart() UTIL_SetOrigin(pev, pev->oldorigin); STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noise)); +#ifdef REGAMEDLL_FIXES + m_soundPlaying = 0; +#endif NextThink(pev->ltime + 0.1f, FALSE); SetThink(&CFuncVehicle::Find); From c683c475d443da49838044cd3c961afe772f4909 Mon Sep 17 00:00:00 2001 From: arc <57247272+bucketss@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:32:56 -0400 Subject: [PATCH 5/9] Fix: only clear g_pMapInfo from the instance that owns it (#1175) CMapInfo::OnCreate() is first-wins, but OnDestroy() clears the global unconditionally. A guard was present in the original ~CMapInfo(), then was cut along with the function it was part of in 183a9f6, and the guard was never restored when the function returned in 49c64e4. --- regamedll/dlls/mapinfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/regamedll/dlls/mapinfo.cpp b/regamedll/dlls/mapinfo.cpp index 48200b6f6..1c81e45e4 100644 --- a/regamedll/dlls/mapinfo.cpp +++ b/regamedll/dlls/mapinfo.cpp @@ -22,7 +22,9 @@ void CMapInfo::OnCreate() void CMapInfo::OnDestroy() { - g_pMapInfo = nullptr; + // Only the instance that owns the global may clear it. + if (g_pMapInfo == this) + g_pMapInfo = nullptr; } void CMapInfo::CheckMapInfo() From 139197e87df77b8a38840c9ab7e4f78913059d1f Mon Sep 17 00:00:00 2001 From: Anton Bolshakov Date: Thu, 27 Aug 2026 23:33:10 +0800 Subject: [PATCH 6/9] regamedll: allow text relocations for non-PIC i386 shared library (#1177) The library is built with POSITION_INDEPENDENT_CODE OFF, producing non-PIC i386 objects that have relocations in read-only .text sections. Modern ld (>= 2.36) rejects these by default: ld: read-only segment has dynamic relocations Add -Wl,-z,notext to restore the historical permissive behaviour. Same fix applied to the sibling project: https://github.com/rehlds/ReHLDS/pull/1195 --- regamedll/CMakeLists.txt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt index 1eb1d4dd3..58632b93d 100644 --- a/regamedll/CMakeLists.txt +++ b/regamedll/CMakeLists.txt @@ -417,6 +417,8 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 4) set(LINK_FLAGS "${LINK_FLAGS} -L${PROJECT_SOURCE_DIR}/lib/linux32") endif() +set(LINK_FLAGS "${LINK_FLAGS} -Wl,-z,notext") + set_target_properties(regamedll PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS} LINK_FLAGS ${LINK_FLAGS} @@ -424,15 +426,21 @@ set_target_properties(regamedll PROPERTIES if (XASH_COMPAT) if (CMAKE_SYSTEM_NAME STREQUAL "Android") - set_target_properties(regamedll PROPERTIES + set(LINK_FLAGS "${LINK_FLAGS} -Wl,-z,notext") + +set_target_properties(regamedll PROPERTIES OUTPUT_NAME server) else() - set_target_properties(regamedll PROPERTIES + set(LINK_FLAGS "${LINK_FLAGS} -Wl,-z,notext") + +set_target_properties(regamedll PROPERTIES PREFIX "" OUTPUT_NAME cs${POSTFIX}) endif() else() - set_target_properties(regamedll PROPERTIES + set(LINK_FLAGS "${LINK_FLAGS} -Wl,-z,notext") + +set_target_properties(regamedll PROPERTIES OUTPUT_NAME cs PREFIX "" POSITION_INDEPENDENT_CODE OFF) From b0889847fe6d03898be88acc9e366660efb40ab5 Mon Sep 17 00:00:00 2001 From: Nord1cWarr1or Date: Fri, 28 Aug 2026 02:19:49 +0300 Subject: [PATCH 7/9] Add mp_longjump_cooldown CVar to prevent LongJump abuse (#1181) * Add mp_longjump_cooldown CVar to prevent LongJump abuse * Remove FCVAR_SERVER from mp_longjump_cooldown cvar --- README.md | 1 + dist/game.cfg | 7 +++++ regamedll/dlls/game.cpp | 2 ++ regamedll/dlls/game.h | 1 + regamedll/pm_shared/pm_shared.cpp | 51 +++++++++++++++++++++++-------- 5 files changed, 50 insertions(+), 12 deletions(-) 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 839dfba1a..7f3e8102f 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -175,6 +175,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 }; @@ -471,6 +472,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 45f5330d9..32e6ae015 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -204,6 +204,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() From 4a50c42e85fd3778c2b7d24731c7d30c83bbab01 Mon Sep 17 00:00:00 2001 From: Nord1cWarr1or Date: Thu, 17 Sep 2026 11:29:36 +0300 Subject: [PATCH 8/9] ci: fix Linux build after Debian 11 EOL (#1193) Debian 11 left LTS on 2026-08-31. The bullseye-security suite is frozen and its pool is being pruned from deb.debian.org, so the apt step fails with exit code 100: expired InRelease on update, or 404 on fetched packages. Keep the same debian:11-slim container and gcc 10 toolchain: the release binaries must keep passing glibc_test.sh with the current baseline. Point the base suite at archive.debian.org and pin bullseye-security to its last complete snapshot (2026-08-31), fetched via the cloudflare snapshot mirror with apt retries (plain snapshot.debian.org resets connections under CI burst load, and debian:11-slim needs ca-certificates bootstrapped from the archive for https). Verified in Docker and CI: the same toolchain (gcc 10.2.1, cmake 3.18.4), builds succeed, glibc_test.sh passes on every artifact. Resolves: #1192 --- .github/workflows/build.yml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 61c858563..22442c86b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -196,9 +196,23 @@ jobs: steps: - name: Install dependencies run: | - dpkg --add-architecture i386 - apt-get update - apt-get install -y \ + # Debian 11 reached end of LTS on 2026-08-31: the bullseye-security + # suite is frozen and its pool is being pruned from deb.debian.org. + # Keep the same toolchain, but fetch the base suite from the Debian + # archive and pin the security suite to its last complete snapshot. + # The security suite is fetched from the cloudflare snapshot mirror: + # plain snapshot.debian.org throttles CI bursts with connection + # resets, and https needs ca-certificates, which debian:11-slim + # does not ship, so bootstrap it from the archive first. + cat > /etc/apt/sources.list <<'EOF' + deb http://archive.debian.org/debian bullseye main + deb http://archive.debian.org/debian bullseye-updates main + EOF + apt-get -o Acquire::Check-Valid-Until=false update + apt-get install -y --no-install-recommends ca-certificates + echo 'deb https://snapshot-cloudflare.debian.org/archive/debian-security/20260831T000000Z bullseye-security main' > /etc/apt/sources.list.d/bullseye-security.list + apt-get -o Acquire::Check-Valid-Until=false -o Acquire::Retries=5 update + apt-get -o Acquire::Retries=5 install -y \ gcc-multilib g++-multilib \ build-essential \ libc6-dev libc6-dev-i386 \ From 72b2ae26a80f6640a0658315255dc6eebd9c0d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0=D0=B2=20?= =?UTF-8?q?=D0=A1=D1=83=D1=85=D0=BE=D0=B2?= <22411953+Vladislav4KZ@users.noreply.github.com> Date: Mon, 19 Oct 2026 20:27:57 +0000 Subject: [PATCH 9/9] cmake: don't pass -z notext on Android --- regamedll/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt index 875048bc5..c4b22a8e0 100644 --- a/regamedll/CMakeLists.txt +++ b/regamedll/CMakeLists.txt @@ -437,7 +437,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT ANDROID) set(LINK_FLAGS "${LINK_FLAGS} -L${PROJECT_SOURCE_DIR}/lib/linux32") endif() -if (UNIX AND NOT APPLE) +if (UNIX AND NOT APPLE AND NOT ANDROID) set(LINK_FLAGS "${LINK_FLAGS} -Wl,-z,notext") endif()