diff --git a/README.md b/README.md
index 623bc17aa..64c724d0f 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,7 @@ Archive's bin directory contains 2 subdirectories, 'bugfixed' and 'pure'
| bot_deathmatch | 0 | 0 | 1 | Set's the mode for the zBot.
`0` disabled
`1` enable mode Deathmatch and not allow to do the scenario |
| bot_quota_mode | normal | - | - | Determines the type of quota.
`normal` default behaviour
`fill` the server will adjust bots to keep `N` players in the game, where `N` is bot_quota |
| mp_item_staytime | 300 | - | - | Time to remove item that have been dropped from the players. |
+| mp_max_alive_name_changes | -1 | -1 | - | Maximum amount of nickname changes before next respawn.
`-1` Infinity (HLDS behavior)
`0` Allow to change only at spawn
`0>` Allow to change arbitrary amount of nicks |
## How to install zBot for CS 1.6?
* Extract all the files from an [archive](regamedll/extra/zBot/bot_profiles.zip?raw=true)
diff --git a/dist/game.cfg b/dist/game.cfg
index d43e0223c..757579cb6 100644
--- a/dist/game.cfg
+++ b/dist/game.cfg
@@ -172,3 +172,10 @@ sv_alltalk 0
//
// Default value: "300"
mp_item_staytime 300
+
+// Maximum amount of nickname changes before next respawn.
+// -1 - Infinity (HLDS behavior)
+// 0 - Allow to change only at spawn
+// 0> - Allow to change arbitrary amount of nicks
+//
+mp_max_alive_name_changes
diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp
index 30563f23d..c6757e373 100644
--- a/regamedll/dlls/game.cpp
+++ b/regamedll/dlls/game.cpp
@@ -94,27 +94,28 @@ cvar_t sk_scientist_heal3 = { "sk_scientist_heal3", "0", 0, 0.0f, nullptr };
#ifdef REGAMEDLL_ADD
-cvar_t game_version = { "game_version", APP_VERSION, FCVAR_SERVER, 0.0f, nullptr };
-cvar_t maxmoney = { "mp_maxmoney", "16000", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t round_infinite = { "mp_round_infinite", "0", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t hegrenade_penetration = { "mp_hegrenade_penetration", "0", 0, 0.0f, nullptr };
-cvar_t nadedrops = { "mp_nadedrops", "0", 0, 0.0f, nullptr };
-cvar_t roundrespawn_time = { "mp_roundrespawn_time", "20", 0, 20.0f, nullptr };
-cvar_t auto_reload_weapons = { "mp_auto_reload_weapons", "0", 0, 0.0f, nullptr };
-cvar_t refill_bpammo_weapons = { "mp_refill_bpammo_weapons", "0", 0, 0.0f, nullptr }; // Useful for mods like DeathMatch, GunGame, ZombieMod etc
-cvar_t freeforall = { "mp_freeforall", "0", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t auto_join_team = { "mp_auto_join_team", "0", 0, 0.0f, nullptr };
-cvar_t max_teamkills = { "mp_max_teamkills", "3", 0, 3.0f, nullptr };
-cvar_t fraglimit = { "mp_fraglimit", "0", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t round_restart_delay = { "mp_round_restart_delay", "5", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t showtriggers = { "showtriggers", "0", 0, 0.0f, nullptr }; // debug cvar shows triggers
+cvar_t game_version = { "game_version", APP_VERSION, FCVAR_SERVER, 0.0f, nullptr };
+cvar_t maxmoney = { "mp_maxmoney", "16000", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t round_infinite = { "mp_round_infinite", "0", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t hegrenade_penetration = { "mp_hegrenade_penetration", "0", 0, 0.0f, nullptr };
+cvar_t nadedrops = { "mp_nadedrops", "0", 0, 0.0f, nullptr };
+cvar_t roundrespawn_time = { "mp_roundrespawn_time", "20", 0, 20.0f, nullptr };
+cvar_t auto_reload_weapons = { "mp_auto_reload_weapons", "0", 0, 0.0f, nullptr };
+cvar_t refill_bpammo_weapons = { "mp_refill_bpammo_weapons", "0", 0, 0.0f, nullptr }; // Useful for mods like DeathMatch, GunGame, ZombieMod etc
+cvar_t freeforall = { "mp_freeforall", "0", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t auto_join_team = { "mp_auto_join_team", "0", 0, 0.0f, nullptr };
+cvar_t max_teamkills = { "mp_max_teamkills", "3", 0, 3.0f, nullptr };
+cvar_t fraglimit = { "mp_fraglimit", "0", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t round_restart_delay = { "mp_round_restart_delay", "5", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t showtriggers = { "showtriggers", "0", 0, 0.0f, nullptr }; // debug cvar shows triggers
// TODO: Maybe it's better to register in the engine?
-cvar_t hostagehurtable = { "mp_hostage_hurtable", "1", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t roundover = { "mp_roundover", "0", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t forcerespawn = { "mp_forcerespawn", "0", FCVAR_SERVER, 0.0f, nullptr };
-cvar_t show_radioicon = { "mp_show_radioicon", "1", FCVAR_SERVER, 1.0f, nullptr };
-cvar_t item_staytime = { "mp_item_staytime", "300", FCVAR_SERVER, 300.0f, nullptr };
+cvar_t hostagehurtable = { "mp_hostage_hurtable", "1", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t roundover = { "mp_roundover", "0", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t forcerespawn = { "mp_forcerespawn", "0", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t show_radioicon = { "mp_show_radioicon", "1", FCVAR_SERVER, 1.0f, nullptr };
+cvar_t item_staytime = { "mp_item_staytime", "300", FCVAR_SERVER, 300.0f, nullptr };
+cvar_t max_alive_name_changes = { "mp_max_alive_name_changes", "-1", FCVAR_SERVER, -1.0f, nullptr };
void GameDLL_Version_f()
{
@@ -267,6 +268,7 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&forcerespawn);
CVAR_REGISTER(&show_radioicon);
CVAR_REGISTER(&item_staytime);
+ CVAR_REGISTER(&max_alive_name_changes);
// print version
CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n");
diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h
index e67daf872..82b27d4e2 100644
--- a/regamedll/dlls/game.h
+++ b/regamedll/dlls/game.h
@@ -151,6 +151,7 @@ extern cvar_t roundover;
extern cvar_t forcerespawn;
extern cvar_t show_radioicon;
extern cvar_t item_staytime;
+extern cvar_t max_alive_name_changes;
#endif
diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp
index de896ff2e..e218221e9 100644
--- a/regamedll/dlls/player.cpp
+++ b/regamedll/dlls/player.cpp
@@ -164,14 +164,23 @@ LINK_HOOK_CLASS_CHAIN(bool, CBasePlayer, SetClientUserInfoName, (char *infobuffe
bool EXT_FUNC CBasePlayer::__API_HOOK(SetClientUserInfoName)(char *infobuffer, char *szNewName)
{
int nClientIndex = entindex();
- if (pev->deadflag != DEAD_NO)
+ if (pev->deadflag != DEAD_NO
+#ifdef REGAMEDLL_ADD
+ || (m_iNickChangesBeforeSpawn > max_alive_name_changes.value && max_alive_name_changes.value >= 0)
+#endif
+ )
{
m_bHasChangedName = true;
Q_snprintf(m_szNewName, sizeof(m_szNewName), "%s", szNewName);
ClientPrint(pev, HUD_PRINTTALK, "#Name_change_at_respawn");
return false;
}
-
+#ifdef REGAMEDLL_ADD
+ else
+ {
+ m_iNickChangesBeforeSpawn++;
+ }
+#endif
// Set the name
SET_CLIENT_KEY_VALUE(nClientIndex, infobuffer, "name", szNewName);
@@ -3555,6 +3564,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(RoundRespawn)()
CLIENT_COMMAND(edict(), "kill\n");
#endif
}
+
+#ifdef REGAMEDLL_ADD
+ m_iNickChangesBeforeSpawn = 0;
+#endif
if (m_iMenu != Menu_ChooseAppearance)
{
diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h
index 9a29d6b7a..4f0caff7e 100644
--- a/regamedll/dlls/player.h
+++ b/regamedll/dlls/player.h
@@ -855,6 +855,9 @@ class CBasePlayer: public CBaseMonster {
float m_silentTimestamp;
MusicState m_musicState;
float m_flLastCommandTime[COMMANDS_TO_TRACK];
+#ifdef REGAMEDLL_ADD
+ int m_iNickChangesBeforeSpawn;
+#endif
};
class CWShield: public CBaseEntity