2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
| mp_fadetoblack | 0 | 0 | 2 | Observer's screen will fade to black on kill event or permanent.<br/> `0` No fade.<br/>`1` Fade to black and won't be able to watch anybody.<br/>`2` fade to black only on kill moment. |
| mp_falldamage | 1 | 0 | 1 | Damage from falling.<br/>`0` disabled <br/>`1` enabled |
| sv_allchat | 1 | 0 | 1 | Players can receive all other players text chat, team restrictions apply<br/>`0` disabled <br/>`1` enabled |
| sv_autobunnyhopping | 0 | 0 | 1 | Players automatically re-jump while holding jump button.<br/>`0` disabled <br/>`1` enabled |
| sv_enablebunnyhopping | 0 | 0 | 1 | Allow player speed to exceed maximum running speed.<br/>`0` disabled <br/>`1` enabled |
</details>

## How to install zBot for CS 1.6?
Expand Down
14 changes: 14 additions & 0 deletions dist/game.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,17 @@ mp_free_armor 0
//
// Default value: "0"
sv_allchat 0
// Players automatically re-jump while holding jump button.
// 0 - disabled (default behaviour)
// 1 - enabled
//
// Default value: "0"
sv_autobunnyhopping 0
// Allow player speed to exceed maximum running speed
// 0 - disabled (default behaviour)
// 1 - enabled
//
// Default value: "0"
sv_enablebunnyhopping 0
2 changes: 2 additions & 0 deletions regamedll/dlls/API/CSPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ void CCSPlayer::Reset()
m_iWeaponInfiniteIds = 0;
m_bCanShootOverride = false;
m_bGameForcingRespawn = false;
m_bAutoBunnyHopping = false;
m_bMegaBunnyJumping = false;
}

void CCSPlayer::OnSpawn()
Expand Down
9 changes: 5 additions & 4 deletions regamedll/dlls/bot/cs_bot_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@ void CCSBotManager::MaintainBotQuota()

int totalHumansInGame = UTIL_HumansInGame();
int humanPlayersInGame = UTIL_HumansInGame(IGNORE_SPECTATORS);
int spectatorPlayersInGame = UTIL_SpectatorsInGame();

// don't add bots until local player has been registered, to make sure he's player ID #1
if (!IS_DEDICATED_SERVER() && totalHumansInGame == 0)
Expand All @@ -872,7 +873,7 @@ void CCSBotManager::MaintainBotQuota()
// unless the round is already in progress, in which case we play with what we've been dealt
if (!isRoundInProgress)
{
desiredBotCount = Q_max(0, desiredBotCount - humanPlayersInGame);
desiredBotCount = Q_max(0, desiredBotCount - humanPlayersInGame + spectatorPlayersInGame);
}
else
{
Expand Down Expand Up @@ -902,7 +903,7 @@ void CCSBotManager::MaintainBotQuota()
// wait for a player to join, if necessary
if (cv_bot_join_after_player.value > 0.0)
{
if (humanPlayersInGame == 0)
if (humanPlayersInGame == 0 && spectatorPlayersInGame == 0)
desiredBotCount = 0;
}

Expand All @@ -917,9 +918,9 @@ void CCSBotManager::MaintainBotQuota()

// if bots will auto-vacate, we need to keep one slot open to allow players to join
if (cv_bot_auto_vacate.value > 0.0)
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - (totalHumansInGame + 1));
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - (humanPlayersInGame + 1));
else
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - totalHumansInGame);
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - humanPlayersInGame + spectatorPlayersInGame);

#ifdef REGAMEDLL_FIXES
// Try to balance teams, if we are in the first specified seconds of a round and bots can join either team.
Expand Down
4 changes: 4 additions & 0 deletions regamedll/dlls/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ cvar_t t_default_weapons_secondary = { "mp_t_default_weapons_secondary", "
cvar_t t_default_weapons_primary = { "mp_t_default_weapons_primary", "", 0, 0.0f, nullptr };
cvar_t free_armor = { "mp_free_armor", "0", 0, 0.0f, nullptr };
cvar_t allchat = { "sv_allchat", "0", 0, 0.0f, nullptr };
cvar_t sv_autobunnyhopping = { "sv_autobunnyhopping", "0", 0, 0.0f, nullptr };
cvar_t sv_enablebunnyhopping = { "sv_enablebunnyhopping", "0", 0, 0.0f, nullptr };

void GameDLL_Version_f()
{
Expand Down Expand Up @@ -387,6 +389,8 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&t_default_weapons_primary);
CVAR_REGISTER(&free_armor);
CVAR_REGISTER(&allchat);
CVAR_REGISTER(&sv_autobunnyhopping);
CVAR_REGISTER(&sv_enablebunnyhopping);

// print version
CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n");
Expand Down
2 changes: 2 additions & 0 deletions regamedll/dlls/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ extern cvar_t t_default_weapons_secondary;
extern cvar_t t_default_weapons_primary;
extern cvar_t free_armor;
extern cvar_t allchat;
extern cvar_t sv_autobunnyhopping;
extern cvar_t sv_enablebunnyhopping;

#endif

Expand Down
6 changes: 6 additions & 0 deletions regamedll/dlls/multiplay_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,13 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(CheckWinConditions)()
#ifdef REGAMEDLL_FIXES
// If a winner has already been determined.. then get the heck out of here
if (m_iRoundWinStatus != WINSTATUS_NONE)
{
// still check if we lost players to where we need to do a full reset next round...
int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT;
InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT);

return;
}
#else
// If a winner has already been determined and game of started.. then get the heck out of here
if (m_bGameStarted && m_iRoundWinStatus != WINSTATUS_NONE)
Expand Down
10 changes: 8 additions & 2 deletions regamedll/dlls/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8216,6 +8216,12 @@ void CBasePlayer::__API_HOOK(SwitchTeam)()
}
}
}

#ifdef REGAMEDLL_FIXES
// Initialize the player counts now that a player has switched teams
int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT;
CSGameRules()->InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT);
#endif
}

void CBasePlayer::UpdateShieldCrosshair(bool draw)
Expand Down Expand Up @@ -10003,8 +10009,8 @@ void EXT_FUNC CBasePlayer::__API_HOOK(OnSpawnEquip)(bool addDefault, bool equipG
{
switch (static_cast<ArmorType>((int)free_armor.value))
{
case ARMOR_KEVLAR: GiveNamedItem("item_kevlar"); break;
case ARMOR_VESTHELM: GiveNamedItem("item_assaultsuit"); break;
case ARMOR_KEVLAR: GiveNamedItemEx("item_kevlar"); break;
case ARMOR_VESTHELM: GiveNamedItemEx("item_assaultsuit"); break;
}
}
#endif
Expand Down
6 changes: 4 additions & 2 deletions regamedll/dlls/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,10 +650,11 @@ class CBasePlayer: public CBaseMonster {
auto item = m_rgpPlayerItems[slot];
while (item)
{
auto next = item->m_pNext;
if (func(static_cast<T *>(item)))
return static_cast<T *>(item);

item = item->m_pNext;
item = next;
}

return nullptr;
Expand All @@ -666,10 +667,11 @@ class CBasePlayer: public CBaseMonster {
{
while (item)
{
auto next = item->m_pNext;
if (func(static_cast<T *>(item)))
return static_cast<T *>(item);

item = item->m_pNext;
item = next;
}
}

Expand Down
60 changes: 60 additions & 0 deletions regamedll/dlls/weapons.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,11 @@ const float MP5N_MAX_SPEED = 250.0f;
const float MP5N_DAMAGE = 26.0f;
const float MP5N_RANGE_MODIFER = 0.84f;
const float MP5N_RELOAD_TIME = 2.63f;
#ifdef REGAMEDLL_FIXES
const float MP5N_ACCURACY_DIVISOR = 220.1f;
#else
const double MP5N_ACCURACY_DIVISOR = 220.1;
#endif

enum mp5n_e
{
Expand Down Expand Up @@ -629,6 +634,11 @@ const float SG552_MAX_SPEED_ZOOM = 200.0f;
const float SG552_DAMAGE = 33.0f;
const float SG552_RANGE_MODIFER = 0.955f;
const float SG552_RELOAD_TIME = 3.0f;
#ifdef REGAMEDLL_FIXES
const float SG552_ACCURACY_DIVISOR = 220.0f;
#else
const int SG552_ACCURACY_DIVISOR = 220;
#endif

enum sg552_e
{
Expand Down Expand Up @@ -677,6 +687,11 @@ const float AK47_MAX_SPEED = 221.0f;
const float AK47_DAMAGE = 36.0f;
const float AK47_RANGE_MODIFER = 0.98f;
const float AK47_RELOAD_TIME = 2.45f;
#ifdef REGAMEDLL_FIXES
const float AK47_ACCURACY_DIVISOR = 200.0f;
#else
const int AK47_ACCURACY_DIVISOR = 200;
#endif

enum ak47_e
{
Expand Down Expand Up @@ -725,6 +740,11 @@ const float AUG_MAX_SPEED = 240.0f;
const float AUG_DAMAGE = 32.0f;
const float AUG_RANGE_MODIFER = 0.96f;
const float AUG_RELOAD_TIME = 3.3f;
#ifdef REGAMEDLL_FIXES
const float AUG_ACCURACY_DIVISOR = 215.0f;
#else
const int AUG_ACCURACY_DIVISOR = 215;
#endif

enum aug_e
{
Expand Down Expand Up @@ -1218,6 +1238,11 @@ const float M249_MAX_SPEED = 220.0f;
const float M249_DAMAGE = 32.0f;
const float M249_RANGE_MODIFER = 0.97f;
const float M249_RELOAD_TIME = 4.7f;
#ifdef REGAMEDLL_FIXES
const float M249_ACCURACY_DIVISOR = 175.0f;
#else
const int M249_ACCURACY_DIVISOR = 175;
#endif

enum m249_e
{
Expand Down Expand Up @@ -1313,6 +1338,11 @@ const float M4A1_DAMAGE_SIL = 33.0f;
const float M4A1_RANGE_MODIFER = 0.97f;
const float M4A1_RANGE_MODIFER_SIL = 0.95f;
const float M4A1_RELOAD_TIME = 3.05f;
#ifdef REGAMEDLL_FIXES
const float M4A1_ACCURACY_DIVISOR = 220.0f;
#else
const int M4A1_ACCURACY_DIVISOR = 220;
#endif

enum m4a1_e
{
Expand Down Expand Up @@ -1373,6 +1403,11 @@ const float MAC10_MAX_SPEED = 250.0f;
const float MAC10_DAMAGE = 29.0f;
const float MAC10_RANGE_MODIFER = 0.82f;
const float MAC10_RELOAD_TIME = 3.15f;
#ifdef REGAMEDLL_FIXES
const float MAC10_ACCURACY_DIVISOR = 200.0f;
#else
const int MAC10_ACCURACY_DIVISOR = 200;
#endif

enum mac10_e
{
Expand Down Expand Up @@ -1485,6 +1520,11 @@ const float P90_MAX_SPEED = 245.0f;
const float P90_DAMAGE = 21.0f;
const float P90_RANGE_MODIFER = 0.885f;
const float P90_RELOAD_TIME = 3.4f;
#ifdef REGAMEDLL_FIXES
const float P90_ACCURACY_DIVISOR = 175.0f;
#else
const int P90_ACCURACY_DIVISOR = 175;
#endif

enum p90_e
{
Expand Down Expand Up @@ -1627,6 +1667,11 @@ const float TMP_MAX_SPEED = 250.0f;
const float TMP_DAMAGE = 20.0f;
const float TMP_RANGE_MODIFER = 0.85f;
const float TMP_RELOAD_TIME = 2.12f;
#ifdef REGAMEDLL_FIXES
const float TMP_ACCURACY_DIVISOR = 200.0f;
#else
const int TMP_ACCURACY_DIVISOR = 200;
#endif

enum tmp_e
{
Expand Down Expand Up @@ -1830,6 +1875,11 @@ const float UMP45_MAX_SPEED = 250.0f;
const float UMP45_DAMAGE = 30.0f;
const float UMP45_RANGE_MODIFER = 0.82f;
const float UMP45_RELOAD_TIME = 3.5f;
#ifdef REGAMEDLL_FIXES
const float UMP45_ACCURACY_DIVISOR = 210.0f;
#else
const int UMP45_ACCURACY_DIVISOR = 210;
#endif

enum ump45_e
{
Expand Down Expand Up @@ -1923,6 +1973,11 @@ const float GALIL_MAX_SPEED = 240.0f;
const float GALIL_DAMAGE = 30.0f;
const float GALIL_RANGE_MODIFER = 0.98f;
const float GALIL_RELOAD_TIME = 2.45f;
#ifdef REGAMEDLL_FIXES
const float GALIL_ACCURACY_DIVISOR = 200.0f;
#else
const int GALIL_ACCURACY_DIVISOR = 200;
#endif

enum galil_e
{
Expand Down Expand Up @@ -1973,6 +2028,11 @@ const float FAMAS_RELOAD_TIME = 3.3f;
const float FAMAS_DAMAGE = 30.0f;
const float FAMAS_DAMAGE_BURST = 34.0f;
const float FAMAS_RANGE_MODIFER = 0.96f;
#ifdef REGAMEDLL_FIXES
const float FAMAS_ACCURACY_DIVISOR = 215.0f;
#else
const int FAMAS_ACCURACY_DIVISOR = 215;
#endif

enum famas_e
{
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_ak47.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ void CAK47::AK47Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 200) + 0.35f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / AK47_ACCURACY_DIVISOR) + 0.35f;

if (m_flAccuracy > 1.25f)
m_flAccuracy = 1.25f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_aug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void CAUG::AUGFire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 215) + 0.3f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / AUG_ACCURACY_DIVISOR) + 0.3f;

if (m_flAccuracy > 1.0f)
m_flAccuracy = 1.0f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_famas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void CFamas::FamasFire(float flSpread, float flCycleTime, BOOL fUseAutoAim, BOOL
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = (m_iShotsFired * m_iShotsFired * m_iShotsFired / 215) + 0.3f;
m_flAccuracy = (m_iShotsFired * m_iShotsFired * m_iShotsFired / FAMAS_ACCURACY_DIVISOR) + 0.3f;

if (m_flAccuracy > 1.0f)
m_flAccuracy = 1.0f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_galil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void CGalil::GalilFire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 200) + 0.35f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / GALIL_ACCURACY_DIVISOR) + 0.35f;

if (m_flAccuracy > 1.25f)
m_flAccuracy = 1.25f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_m249.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void CM249::M249Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 175) + 0.4f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / M249_ACCURACY_DIVISOR) + 0.4f;

if (m_flAccuracy > 0.9f)
m_flAccuracy = 0.9f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_m4a1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ void CM4A1::M4A1Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 220) + 0.3f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / M4A1_ACCURACY_DIVISOR) + 0.3f;

if (m_flAccuracy > 1)
m_flAccuracy = 1;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_mac10.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void CMAC10::MAC10Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 200) + 0.6f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / MAC10_ACCURACY_DIVISOR) + 0.6f;

if (m_flAccuracy > 1.65f)
m_flAccuracy = 1.65f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_mp5navy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void CMP5N::MP5NFire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired) / 220.1) + 0.45f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired) / MP5N_ACCURACY_DIVISOR) + 0.45f;

if (m_flAccuracy > 0.75f)
m_flAccuracy = 0.75f;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_p90.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void CP90::P90Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = (m_iShotsFired * m_iShotsFired / 175) + 0.45f;
m_flAccuracy = (m_iShotsFired * m_iShotsFired / P90_ACCURACY_DIVISOR) + 0.45f;

if (m_flAccuracy > 1)
m_flAccuracy = 1;
Expand Down
2 changes: 1 addition & 1 deletion regamedll/dlls/wpn_shared/wpn_sg552.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void CSG552::SG552Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
m_bDelayFire = true;
m_iShotsFired++;

m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / 220) + 0.3f;
m_flAccuracy = ((m_iShotsFired * m_iShotsFired * m_iShotsFired) / SG552_ACCURACY_DIVISOR) + 0.3f;

if (m_flAccuracy > 1.0f)
m_flAccuracy = 1.0f;
Expand Down