diff --git a/README.md b/README.md
index 8db6dad24..e482d7e0c 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,13 @@ Archive's bin directory contains 2 subdirectories, 'bugfixed' and 'pure'
ReGameDLL_CS also have beta version with latest changes from official version of Counter-Strike.
* Enter `-beta` option at the command line HLDS.
+## Commands
+| Command | Description |
+| :---------------------------------- | :---------------------------------------------- |
+| game version | Will show GameDLL build version, date & URL. |
+| endround | Args:
`T` force round end with Terrorists win.
`CT` force round end with Counter-Terrorists win.
or terminate round draw when called without arguments. |
+| mp_swapteams | Swap the teams and restart the game. |
+
## Configuration (cvars)
Click to expand
@@ -76,6 +83,7 @@ Archive's bin directory contains 2 subdirectories, 'bugfixed' and 'pure'
| mp_radio_timeout | 1.5 | 0.0 | - | Delay between player Radio messages. (in seconds).
`0` disable delay |
| mp_radio_maxinround | 60 | - | - | Maximum Radio messages count for player per round.
`0` disable radio messages |
| mp_buy_anywhere | 0 | 0 | 3 | When set, players can buy anywhere, not only in buyzones.
`0` disabled.
`1` both teams
`2` only Terrorists team
`3` only CT team |
+| mp_weapons_allow_map_placed | 1 | 0 | 1 | When set, map weapons (located on the floor by map) will be shown.
`0` hide all map weapons.
`1` enabled
`NOTE`: Effect will work after round restart. |
## How to install zBot for CS 1.6?
diff --git a/dist/game.cfg b/dist/game.cfg
index 18599ae73..b096befb9 100644
--- a/dist/game.cfg
+++ b/dist/game.cfg
@@ -336,3 +336,11 @@ mp_buy_anywhere 0
//
// Default value: "0"
mp_unduck_method 0
+
+// When set, map weapons (located on the floor) will be shown.
+// NOTE: Effect will work after round restart.
+// 0 - hide all map weapons
+// 1 - enabled (default behaviour)
+//
+// Default value: "1"
+mp_weapons_allow_map_placed 1
diff --git a/gradle.properties b/gradle.properties
index 8b0952612..9c1255b4f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,3 @@
majorVersion=5
-minorVersion=11
+minorVersion=12
maintenanceVersion=0
diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp
index 17ddcb35c..8d209b317 100644
--- a/regamedll/dlls/API/CAPI_Impl.cpp
+++ b/regamedll/dlls/API/CAPI_Impl.cpp
@@ -162,6 +162,11 @@ GAMEHOOK_REGISTRY(CBasePlayer_RemoveSpawnProtection);
GAMEHOOK_REGISTRY(IsPenetrableEntity);
GAMEHOOK_REGISTRY(CBasePlayer_HintMessageEx);
GAMEHOOK_REGISTRY(CBasePlayer_UseEmpty);
+GAMEHOOK_REGISTRY(CBasePlayerWeapon_CanDeploy);
+GAMEHOOK_REGISTRY(CBasePlayerWeapon_DefaultDeploy);
+GAMEHOOK_REGISTRY(CBasePlayerWeapon_DefaultReload);
+GAMEHOOK_REGISTRY(CBasePlayerWeapon_DefaultShotgunReload);
+GAMEHOOK_REGISTRY(CBasePlayer_DropIdlePlayer);
int CReGameApi::GetMajorVersion() {
return REGAMEDLL_API_VERSION_MAJOR;
diff --git a/regamedll/dlls/API/CAPI_Impl.h b/regamedll/dlls/API/CAPI_Impl.h
index 3e8b6a554..2f9020bb2 100644
--- a/regamedll/dlls/API/CAPI_Impl.h
+++ b/regamedll/dlls/API/CAPI_Impl.h
@@ -54,6 +54,11 @@
return g_ReGameHookchains.m_##className##_##functionName.callChain(&className::functionName##_OrigFunc, this);\
}
+#define LINK_HOOK_CLASS_CHAIN3(ret, className, subClassName, functionName)\
+ ret subClassName::functionName() {\
+ return g_ReGameHookchains.m_##className##_##functionName.callChain(reinterpret_cast(&subClassName::functionName##_OrigFunc), this);\
+ }
+
#define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN(className, customPrefix, functionName, args, ...)\
void className::functionName args {\
g_ReGameHookchains.m_##customPrefix##_##functionName.callChain(&className::functionName##_OrigFunc, this, __VA_ARGS__);\
@@ -123,6 +128,7 @@
#define LINK_HOOK_CLASS_VOID_CHAIN2(...)
#define LINK_HOOK_CLASS_CHAIN(...)
#define LINK_HOOK_CLASS_CHAIN2(...)
+#define LINK_HOOK_CLASS_CHAIN3(...)
#define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN(...)
#define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2(...)
#define LINK_HOOK_CLASS_CUSTOM_CHAIN(...)
@@ -541,6 +547,26 @@ typedef IHookChainRegistryClassImpl CReGameHook_CBasePlayer_UseEmpty;
typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_UseEmpty;
+// CBasePlayerWeapon::CanDeploy hook
+typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_CanDeploy;
+typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_CanDeploy;
+
+// CBasePlayerWeapon::DefaultDeploy hook
+typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_DefaultDeploy;
+typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy;
+
+// CBasePlayerWeapon::DefaultReload hook
+typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_DefaultReload;
+typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_DefaultReload;
+
+// CBasePlayerWeapon::DefaultShotgunReload hook
+typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_DefaultShotgunReload;
+typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload;
+
+// CBasePlayer::DropIdlePlayer hook
+typedef IHookChainClassImpl CReGameHook_CBasePlayer_DropIdlePlayer;
+typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_DropIdlePlayer;
+
class CReGameHookchains: public IReGameHookchains {
public:
// CBasePlayer virtual
@@ -650,6 +676,11 @@ class CReGameHookchains: public IReGameHookchains {
CReGameHookRegistry_IsPenetrableEntity m_IsPenetrableEntity;
CReGameHookRegistry_CBasePlayer_HintMessageEx m_CBasePlayer_HintMessageEx;
CReGameHookRegistry_CBasePlayer_UseEmpty m_CBasePlayer_UseEmpty;
+ CReGameHookRegistry_CBasePlayerWeapon_CanDeploy m_CBasePlayerWeapon_CanDeploy;
+ CReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy m_CBasePlayerWeapon_DefaultDeploy;
+ CReGameHookRegistry_CBasePlayerWeapon_DefaultReload m_CBasePlayerWeapon_DefaultReload;
+ CReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload m_CBasePlayerWeapon_DefaultShotgunReload;
+ CReGameHookRegistry_CBasePlayer_DropIdlePlayer m_CBasePlayer_DropIdlePlayer;
public:
virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn();
@@ -758,6 +789,11 @@ class CReGameHookchains: public IReGameHookchains {
virtual IReGameHookRegistry_IsPenetrableEntity *IsPenetrableEntity();
virtual IReGameHookRegistry_CBasePlayer_HintMessageEx *CBasePlayer_HintMessageEx();
virtual IReGameHookRegistry_CBasePlayer_UseEmpty *CBasePlayer_UseEmpty();
+ virtual IReGameHookRegistry_CBasePlayerWeapon_CanDeploy *CBasePlayerWeapon_CanDeploy();
+ virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy *CBasePlayerWeapon_DefaultDeploy();
+ virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultReload *CBasePlayerWeapon_DefaultReload();
+ virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload *CBasePlayerWeapon_DefaultShotgunReload();
+ virtual IReGameHookRegistry_CBasePlayer_DropIdlePlayer *CBasePlayer_DropIdlePlayer();
};
extern CReGameHookchains g_ReGameHookchains;
diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp
index 2f3afa492..4fd70c230 100644
--- a/regamedll/dlls/API/CSPlayer.cpp
+++ b/regamedll/dlls/API/CSPlayer.cpp
@@ -229,6 +229,11 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
if (pPlayer->RemovePlayerItem(pItem)) {
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
+ // No more weapon
+ if ((pPlayer->pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
+ pPlayer->m_iHideHUD |= HIDEHUD_WEAPONS;
+ }
+
pItem->Kill();
if (!pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]) {
diff --git a/regamedll/dlls/ammo.cpp b/regamedll/dlls/ammo.cpp
index b6df2d2c0..bfef8749e 100644
--- a/regamedll/dlls/ammo.cpp
+++ b/regamedll/dlls/ammo.cpp
@@ -81,13 +81,6 @@ void CBasePlayerAmmo::DefaultTouch(CBaseEntity *pOther)
#endif
}
}
- else if (gEvilImpulse101)
- {
- // evil impulse 101 hack, kill always
- SetTouch(nullptr);
- SetThink(&CBaseEntity::SUB_Remove);
- pev->nextthink = gpGlobals->time + 0.1f;
- }
}
void C9MMAmmo::Spawn()
diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp
index 6c00f1b5c..61e47105f 100644
--- a/regamedll/dlls/client.cpp
+++ b/regamedll/dlls/client.cpp
@@ -1,6 +1,5 @@
#include "precompiled.h"
-int giPrecacheGrunt = 0;
int gmsgWeapPickup = 0;
int gmsgHudText = 0;
int gmsgHudTextPro = 0;
@@ -1843,7 +1842,11 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot)
}
pPlayer->RemoveAllItems(TRUE);
+
+#ifndef REGAMEDLL_FIXES
+ // NOTE: It is already does reset inside RemoveAllItems
pPlayer->m_bHasC4 = false;
+#endif
#ifdef REGAMEDLL_FIXES
if (pPlayer->m_iTeam != SPECTATOR)
@@ -3151,7 +3154,11 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
}
else if (FStrEq(pcmd, "become_vip"))
{
- if (pPlayer->m_iJoiningState != JOINED || pPlayer->m_iTeam != CT)
+ if (pPlayer->m_iJoiningState != JOINED || pPlayer->m_iTeam != CT
+#ifdef REGAMEDLL_FIXES
+ || !CSGameRules()->m_bMapHasVIPSafetyZone
+#endif
+ )
{
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Command_Not_Available");
return;
@@ -4168,9 +4175,6 @@ void ClientPrecache()
PRECACHE_SOUND("player/geiger2.wav");
PRECACHE_SOUND("player/geiger1.wav");
- if (giPrecacheGrunt)
- UTIL_PrecacheOther("enemy_terrorist");
-
g_iShadowSprite = PRECACHE_MODEL("sprites/shadow_circle.spr");
PRECACHE_MODEL("sprites/wall_puff1.spr");
diff --git a/regamedll/dlls/client.h b/regamedll/dlls/client.h
index 07cf8ff46..c709a1f36 100644
--- a/regamedll/dlls/client.h
+++ b/regamedll/dlls/client.h
@@ -207,7 +207,6 @@ inline const char *GetTeamName(int team)
}
}
-extern int giPrecacheGrunt;
extern int gmsgWeapPickup;
extern int gmsgHudText;
extern int gmsgHudTextPro;
diff --git a/regamedll/dlls/doors.cpp b/regamedll/dlls/doors.cpp
index 8a68bf593..c16fe0083 100644
--- a/regamedll/dlls/doors.cpp
+++ b/regamedll/dlls/doors.cpp
@@ -510,7 +510,12 @@ void CBaseDoor::DoorGoUp()
if (TheBots)
{
- TheBots->OnEvent(EVENT_DOOR, m_hActivator);
+#ifdef REGAMEDLL_FIXES
+ if (m_hActivator && m_hActivator->IsPlayer())
+#endif
+ {
+ TheBots->OnEvent(EVENT_DOOR, m_hActivator);
+ }
}
}
}
@@ -680,7 +685,12 @@ void CBaseDoor::DoorGoDown()
if (TheBots)
{
- TheBots->OnEvent(EVENT_DOOR, m_hActivator);
+#ifdef REGAMEDLL_FIXES
+ if (m_hActivator && m_hActivator->IsPlayer())
+#endif
+ {
+ TheBots->OnEvent(EVENT_DOOR, m_hActivator);
+ }
}
}
}
diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp
index 162fea26d..1a3a18650 100644
--- a/regamedll/dlls/game.cpp
+++ b/regamedll/dlls/game.cpp
@@ -124,6 +124,7 @@ cvar_t respawn_immunity_effects = { "mp_respawn_immunity_effects", "1", FCVAR_S
cvar_t kill_filled_spawn = { "mp_kill_filled_spawn", "1", 0, 0.0f, nullptr };
cvar_t afk_bomb_drop_time = { "mp_afk_bomb_drop_time", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t buy_anywhere = { "mp_buy_anywhere", "0", FCVAR_SERVER, 0.0f, nullptr };
+cvar_t weapons_allow_map_placed = { "mp_weapons_allow_map_placed", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t allow_point_servercommand = { "mp_allow_point_servercommand", "0", 0, 0.0f, nullptr };
cvar_t hullbounds_sets = { "mp_hullbounds_sets", "1", 0, 0.0f, nullptr };
@@ -172,6 +173,12 @@ void GameDLL_EndRound_f()
CSGameRules()->OnRoundEnd_Intercept(WINSTATUS_DRAW, ROUND_END_DRAW, CSGameRules()->GetRoundRestartDelay());
}
+void GameDLL_SwapTeams_f()
+{
+ CSGameRules()->SwapAllPlayers();
+ CVAR_SET_FLOAT("sv_restartround", 1.0);
+}
+
#endif // REGAMEDLL_ADD
void EXT_FUNC GameDLLInit()
@@ -298,6 +305,7 @@ void EXT_FUNC GameDLLInit()
ADD_SERVER_COMMAND("game", GameDLL_Version_f);
ADD_SERVER_COMMAND("endround", GameDLL_EndRound_f);
+ ADD_SERVER_COMMAND("mp_swapteams", GameDLL_SwapTeams_f);
CVAR_REGISTER(&game_version);
CVAR_REGISTER(&maxmoney);
@@ -335,6 +343,7 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&allow_point_servercommand);
CVAR_REGISTER(&hullbounds_sets);
CVAR_REGISTER(&unduck_method);
+ CVAR_REGISTER(&weapons_allow_map_placed);
CVAR_REGISTER(&ff_damage_reduction_bullets);
CVAR_REGISTER(&ff_damage_reduction_grenade);
diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h
index 3bf50ab05..293417267 100644
--- a/regamedll/dlls/game.h
+++ b/regamedll/dlls/game.h
@@ -161,6 +161,7 @@ extern cvar_t respawn_immunity_effects;
extern cvar_t kill_filled_spawn;
extern cvar_t afk_bomb_drop_time;
extern cvar_t buy_anywhere;
+extern cvar_t weapons_allow_map_placed;
extern cvar_t allow_point_servercommand;
extern cvar_t hullbounds_sets;
extern cvar_t unduck_method;
diff --git a/regamedll/dlls/items.cpp b/regamedll/dlls/items.cpp
index 774e47ebb..38f226ab6 100644
--- a/regamedll/dlls/items.cpp
+++ b/regamedll/dlls/items.cpp
@@ -127,10 +127,6 @@ void CItem::ItemTouch(CBaseEntity *pOther)
else
UTIL_Remove(this);
}
- else if (gEvilImpulse101)
- {
- UTIL_Remove(this);
- }
}
CBaseEntity *CItem::Respawn()
diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp
index 77e52cdd5..7ac7e341e 100644
--- a/regamedll/dlls/multiplay_gamerules.cpp
+++ b/regamedll/dlls/multiplay_gamerules.cpp
@@ -606,9 +606,23 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(CleanUpMap)()
const int grenadesRemoveCount = 20;
UTIL_RemoveOther("grenade", grenadesRemoveCount);
+#ifndef REGAMEDLL_FIXES
// Remove defuse kit
// Old code only removed 4 kits and stopped.
UTIL_RemoveOther("item_thighpack");
+#else
+ // Don't remove level items
+ CItemThighPack *pDefuser = nullptr;
+
+ while ((pDefuser = UTIL_FindEntityByClassname(pDefuser, "item_thighpack")))
+ {
+ if (pDefuser->pev->spawnflags & SF_NORESPAWN)
+ {
+ pDefuser->SetThink(&CBaseEntity::SUB_Remove);
+ pDefuser->pev->nextthink = gpGlobals->time + 0.1;
+ }
+ }
+#endif
#ifdef REGAMEDLL_FIXES
UTIL_RemoveOther("gib");
diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp
index 5218b53ba..32ab60f40 100644
--- a/regamedll/dlls/player.cpp
+++ b/regamedll/dlls/player.cpp
@@ -82,7 +82,6 @@ const char *CDeadHEV::m_szPoses[] =
"deadtable"
};
-int gEvilImpulse101;
entvars_t *g_pevLastInflictor;
LINK_ENTITY_TO_CLASS(player, CBasePlayer, CCSPlayer)
@@ -1302,6 +1301,10 @@ void PackPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
if (!pItem)
return;
+ if (pItem->m_flStartThrow != 0.0f || pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()] <= 0) {
+ return;
+ }
+
const char *modelName = GetCSModelName(pItem->m_iId);
if (modelName)
{
@@ -1319,10 +1322,6 @@ void PackPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
break;
}
- if (pItem->m_flStartThrow && pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()] <= 0) {
- return;
- }
-
Vector vecAngles = pPlayer->pev->angles;
Vector dir(Q_cos(vecAngles.y) * flOffset, Q_sin(vecAngles.y) * flOffset, 0.0f);
@@ -1397,7 +1396,15 @@ void CBasePlayer::PackDeadPlayerItems()
else if (pPlayerItem->iItemSlot() == GRENADE_SLOT)
{
if (AreRunningCZero())
- PackPlayerItem(this, pPlayerItem, true);
+ {
+
+#ifdef REGAMEDLL_FIXES
+ if (pPlayerItem->m_flStartThrow == 0.0f && m_rgAmmo[pPlayerItem->PrimaryAmmoIndex()] > 0)
+#endif
+ {
+ PackPlayerItem(this, pPlayerItem, true);
+ }
+ }
#ifdef REGAMEDLL_ADD
else
{
@@ -1577,6 +1584,9 @@ void CBasePlayer::RemoveAllItems(BOOL removeSuit)
#ifdef REGAMEDLL_FIXES
m_iHideHUD |= HIDEHUD_WEAPONS;
+
+ m_bHasNightVision = false;
+ SendItemStatus();
#endif
// send Selected Weapon Message to our client
@@ -1709,6 +1719,16 @@ void BuyZoneIcon_Clear(CBasePlayer *pPlayer)
{
if (pPlayer->m_iMenu <= Menu_BuyItem)
{
+
+#ifdef REGAMEDLL_FIXES
+ // NOTE: is client-side bug
+ if (pPlayer->m_bVGUIMenus)
+ {
+ MESSAGE_BEGIN(MSG_ONE, gmsgBuyClose, nullptr, pPlayer->pev);
+ MESSAGE_END();
+ }
+#endif
+
CLIENT_COMMAND(ENT(pPlayer->pev), "slot10\n");
}
else if (pPlayer->m_iMenu == Menu_ClientBuy)
@@ -1990,6 +2010,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
#ifdef REGAMEDLL_FIXES
m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()]--;
+ pHEGrenade->m_flStartThrow = 0;
#endif
}
break;
@@ -2003,6 +2024,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
#ifdef REGAMEDLL_FIXES
m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()]--;
+ pFlashbang->m_flStartThrow = 0;
#endif
}
break;
@@ -2016,6 +2038,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
#ifdef REGAMEDLL_FIXES
m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()]--;
+ pSmoke->m_flStartThrow = 0;
#endif
}
break;
@@ -2035,6 +2058,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
pev->flags &= ~FL_ONGROUND;
+#ifdef REGAMEDLL_FIXES
+ // FlashlightTurnOff()
+ pev->effects &= ~EF_DIMLIGHT;
+#endif
+
if (fadetoblack.value == 0.0)
{
pev->iuser1 = OBS_CHASE_FREE;
@@ -2135,7 +2163,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
if (m_bHasC4)
{
DropPlayerItem("weapon_c4");
+
+#ifndef REGAMEDLL_FIXES
+ // NOTE: It is already does reset inside DropPlayerItem
SetProgressBarTime(0);
+#endif
}
else if (m_bHasDefuser)
{
@@ -2183,10 +2215,16 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
if ((pev->health < -9000 && iGib != GIB_NEVER) || iGib == GIB_ALWAYS)
{
+
+#ifndef REGAMEDLL_FIXES
pev->solid = SOLID_NOT;
+#endif
GibMonster();
pev->effects |= EF_NODRAW;
+
+#ifndef REGAMEDLL_FIXES
CSGameRules()->CheckWinConditions();
+#endif
return;
}
@@ -3443,6 +3481,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Disappear)()
pev->solid = SOLID_NOT;
pev->flags &= ~FL_ONGROUND;
+#ifdef REGAMEDLL_FIXES
+ // FlashlightTurnOff()
+ pev->effects &= ~EF_DIMLIGHT;
+#endif
+
SetSuitUpdate(nullptr, SUIT_SENTENCE, SUIT_REPEAT_OK);
m_iClientHealth = 0;
@@ -3464,12 +3507,19 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Disappear)()
if (m_bHasC4)
{
DropPlayerItem("weapon_c4");
+
+#ifndef REGAMEDLL_FIXES
+ // NOTE: It is already does reset inside DropPlayerItem
SetProgressBarTime(0);
+#endif
}
else if (m_bHasDefuser)
{
RemoveDefuser();
+
+#ifndef REGAMEDLL_FIXES
GiveNamedItem("item_thighpack");
+#endif
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
WRITE_BYTE(STATUSICON_HIDE);
@@ -3835,7 +3885,7 @@ void CBasePlayer::PlayerUse()
}
}
- bool useNewHostages = !TheNavAreaList.empty();
+ bool useNewHostages = !TheNavAreaList.empty() && AreImprovAllowed();
CBaseEntity *pObject = nullptr;
CBaseEntity *pClosest = nullptr;
Vector vecLOS;
@@ -4266,26 +4316,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(PreThink)()
real_t flLastMove = gpGlobals->time - m_fLastMovement;
//check if this player has been inactive for 2 rounds straight
- if (flLastMove > CSGameRules()->m_fMaxIdlePeriod)
+ if (!IsBot() && flLastMove > CSGameRules()->m_fMaxIdlePeriod)
{
- if (!IsBot() && autokick.value)
- {
- // Log the kick
- UTIL_LogPrintf("\"%s<%i><%s><%s>\" triggered \"Game_idle_kick\" (auto)\n", STRING(pev->netname), GETPLAYERUSERID(edict()), GETPLAYERAUTHID(edict()), GetTeam(m_iTeam));
- UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_idle_kick", STRING(pev->netname));
-
-#ifdef REGAMEDLL_FIXES
- int iUserID = GETPLAYERUSERID(edict());
- if (iUserID != -1)
- {
- SERVER_COMMAND(UTIL_VarArgs("kick #%d \"Player idle\"\n", iUserID));
- }
-#else
- SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pev->netname)));
-#endif // #ifdef REGAMEDLL_FIXES
-
- m_fLastMovement = gpGlobals->time;
- }
+ DropIdlePlayer("Player idle");
+
+ m_fLastMovement = gpGlobals->time;
}
#ifdef REGAMEDLL_ADD
if (afk_bomb_drop_time.value > 0.0 && IsBombGuy())
@@ -4727,7 +4762,7 @@ void CBasePlayer::UpdatePlayerSound()
// weapon recoil, or anything shoves the player abnormally fast.
// NOTE: 512 units is a pretty large radius for a sound made by the player's body.
// then again, I think some materials are pretty loud.
- if (iBodyVolume> 512)
+ if (iBodyVolume > 512)
{
iBodyVolume = 512;
}
@@ -5211,6 +5246,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Spawn)()
#ifdef REGAMEDLL_FIXES
pev->watertype = CONTENTS_EMPTY;
pev->waterlevel = 0;
+ pev->basevelocity = g_vecZero; // pushed by trigger_push
#endif
m_bitsHUDDamage = -1;
@@ -5431,6 +5467,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Spawn)()
m_bHasPrimary = false;
m_bHasNightVision = false;
+#ifdef REGAMEDLL_FIXES
+ m_iHideHUD |= HIDEHUD_WEAPONS;
+#endif
+
SendItemStatus();
}
else
@@ -5653,7 +5693,13 @@ void CBasePlayer::Reset()
m_bNotKilled = false;
+#ifdef REGAMEDLL_FIXES
+ // RemoveShield() included
+ RemoveAllItems(TRUE);
+#else
RemoveShield();
+#endif
+
CheckStartMoney();
AddAccount(startmoney.value, RT_PLAYER_RESET);
@@ -5746,6 +5792,11 @@ void CBasePlayer::SelectItem(const char *pstr)
if (!pItem || pItem == m_pActiveItem)
return;
+#ifdef REGAMEDLL_FIXES
+ if (!pItem->CanDeploy())
+ return;
+#endif
+
ResetAutoaim();
// FIX, this needs to queue them up and delay
@@ -5790,6 +5841,11 @@ void CBasePlayer::SelectLastItem()
if (!m_pLastItem || m_pLastItem == m_pActiveItem)
return;
+#ifdef REGAMEDLL_FIXES
+ if (!m_pLastItem->CanDeploy())
+ return;
+#endif
+
ResetAutoaim();
if (m_pActiveItem)
@@ -6133,23 +6189,7 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse)
switch (iImpulse)
{
- case 76:
- {
- if (!giPrecacheGrunt)
- {
- giPrecacheGrunt = 1;
- ALERT(at_console, "You must now restart to use Grunt-o-matic.\n");
- }
- else
- {
- UTIL_MakeVectors(Vector(0, pev->v_angle.y, 0));
- CBaseEntity::Create("monster_human_grunt", pev->origin + gpGlobals->v_forward * 128, pev->angles);
- }
- break;
- }
case 101:
- gEvilImpulse101 = TRUE;
-
#ifdef REGAMEDLL_ADD
AddAccount(int(maxmoney.value));
ALERT(at_console, "Crediting %s with $%i\n", STRING(pev->netname), int(maxmoney.value));
@@ -6161,6 +6201,7 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse)
case 102:
CGib::SpawnRandomGibs(pev, 1, 1);
break;
+#ifndef REGAMEDLL_FIXES
case 103:
{
// What the hell are you doing?
@@ -6175,10 +6216,12 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse)
}
break;
}
+#endif
case 104:
// Dump all of the global state varaibles (and global entity names)
gGlobalState.DumpGlobals();
break;
+#ifndef REGAMEDLL_FIXES
case 105:
{
// player makes no sound for monsters to hear.
@@ -6194,6 +6237,7 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse)
}
break;
}
+#endif
case 106:
{
// Give me the classname and targetname of this entity.
@@ -6234,18 +6278,6 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse)
break;
}
- case 195:
- // show shortest paths for entire level to nearest node
- CBaseEntity::Create("node_viewer_fly", pev->origin, pev->angles);
- break;
- case 196:
- // show shortest paths for entire level to nearest node
- CBaseEntity::Create("node_viewer_large", pev->origin, pev->angles);
- break;
- case 197:
- // show shortest paths for entire level to nearest node
- CBaseEntity::Create("node_viewer_human", pev->origin, pev->angles);
- break;
case 202:
{
// Random blood splatter
@@ -6390,7 +6422,7 @@ void OLD_CheckRescueZone(CBasePlayer *pPlayer)
CBaseEntity *pSpot = nullptr;
while ((pSpot = UTIL_FindEntityByClassname(pSpot, "info_hostage_rescue")))
{
- if ((pSpot->pev->origin - pPlayer->pev->origin).Length() <= 256.0f)
+ if ((pSpot->pev->origin - pPlayer->pev->origin).Length() <= MAX_HOSTAGES_RESCUE_RADIUS)
{
pPlayer->m_signals.Signal(SIGNAL_RESCUE);
#ifdef REGAMEDLL_FIXES
@@ -6507,8 +6539,6 @@ BOOL EXT_FUNC CBasePlayer::__API_HOOK(AddPlayerItem)(CBasePlayerItem *pItem)
pItem->Kill();
}
- else if (gEvilImpulse101)
- pItem->Kill();
return FALSE;
}
@@ -6544,10 +6574,6 @@ BOOL EXT_FUNC CBasePlayer::__API_HOOK(AddPlayerItem)(CBasePlayerItem *pItem)
return TRUE;
}
- else if (gEvilImpulse101)
- {
- pItem->Kill();
- }
return FALSE;
}
@@ -6630,7 +6656,7 @@ int EXT_FUNC CBasePlayer::__API_HOOK(GiveAmmo)(int iCount, const char *szName, i
{
// Send the message that ammo has been picked up
MESSAGE_BEGIN(MSG_ONE, gmsgAmmoPickup, nullptr, pev);
- WRITE_BYTE(GetAmmoIndex(szName)); // ammo ID
+ WRITE_BYTE(i); // ammo ID
WRITE_BYTE(iAdd); // amount
MESSAGE_END();
}
@@ -6721,12 +6747,12 @@ void CBasePlayer::SendAmmoUpdate()
m_rgAmmoLast[i] = m_rgAmmo[i];
assert(m_rgAmmo[i] >= 0);
- assert(m_rgAmmo[i] < 255);
+ assert(m_rgAmmo[i] <= 255);
// send "Ammo" update message
MESSAGE_BEGIN(MSG_ONE, gmsgAmmoX, nullptr, pev);
WRITE_BYTE(i);
- WRITE_BYTE(clamp(m_rgAmmo[i], 0, 254)); // clamp the value to one byte
+ WRITE_BYTE(clamp(m_rgAmmo[i], 0, 255)); // clamp the value to one byte
MESSAGE_END();
}
}
@@ -6734,12 +6760,13 @@ void CBasePlayer::SendAmmoUpdate()
void CBasePlayer::SendHostagePos()
{
- CBaseEntity *pHostage = nullptr;
+ CHostage *pHostage = nullptr;
+
while ((pHostage = UTIL_FindEntityByClassname(pHostage, "hostage_entity")))
{
MESSAGE_BEGIN(MSG_ONE, gmsgHostagePos, nullptr, pev);
WRITE_BYTE(1);
- WRITE_BYTE(((CHostage *)pHostage)->m_iHostageIndex);
+ WRITE_BYTE(pHostage->m_iHostageIndex);
WRITE_COORD(pHostage->pev->origin.x);
WRITE_COORD(pHostage->pev->origin.y);
WRITE_COORD(pHostage->pev->origin.z);
@@ -6761,7 +6788,7 @@ void CBasePlayer::SendHostageIcons()
}
int hostagesCount = 0;
- CBaseEntity *pHostage = nullptr;
+ CHostage *pHostage = nullptr;
while ((pHostage = UTIL_FindEntityByClassname(pHostage, "hostage_entity")))
{
@@ -6793,8 +6820,6 @@ void CBasePlayer::SendHostageIcons()
void CBasePlayer::SendWeatherInfo()
{
- CBaseEntity *pEnt;
-
auto SendReceiveW = [&](BYTE byte)
{
MESSAGE_BEGIN(MSG_ONE, gmsgReceiveW, nullptr, pev);
@@ -6803,17 +6828,17 @@ void CBasePlayer::SendWeatherInfo()
};
/* Rain */
- if ((pEnt = UTIL_FindEntityByClassname(nullptr, "env_rain")))
+ if (UTIL_FindEntityByClassname(nullptr, "env_rain"))
return SendReceiveW(1);
- if ((pEnt = UTIL_FindEntityByClassname(nullptr, "func_rain")))
+ if (UTIL_FindEntityByClassname(nullptr, "func_rain"))
return SendReceiveW(1);
/* Snow */
- if ((pEnt = UTIL_FindEntityByClassname(nullptr, "env_snow")))
+ if (UTIL_FindEntityByClassname(nullptr, "env_snow"))
return SendReceiveW(2);
- if ((pEnt = UTIL_FindEntityByClassname(nullptr, "func_snow")))
+ if (UTIL_FindEntityByClassname(nullptr, "func_snow"))
return SendReceiveW(2);
}
@@ -7237,13 +7262,13 @@ bool CBasePlayer::ShouldToShowAccount(CBasePlayer *pReceiver) const
switch (iShowAccount)
{
// show field to teammates
- case 3: return pReceiver->m_iTeam == m_iTeam;
+ case 3: return !CSGameRules()->IsFreeForAll() && pReceiver->m_iTeam == m_iTeam;
// show field to all clients
case 4: return true;
// show field to teammates and spectators
- case 5: return (pReceiver->m_iTeam == m_iTeam || pReceiver->m_iTeam == SPECTATOR);
+ case 5: return ((!CSGameRules()->IsFreeForAll() && pReceiver->m_iTeam == m_iTeam) || pReceiver->m_iTeam == SPECTATOR);
default:
break;
}
@@ -7269,13 +7294,13 @@ bool CBasePlayer::ShouldToShowHealthInfo(CBasePlayer *pReceiver) const
switch (iShowHealth)
{
// show field to teammates
- case 3: return pReceiver->m_iTeam == m_iTeam;
+ case 3: return !CSGameRules()->IsFreeForAll() && pReceiver->m_iTeam == m_iTeam;
// show field to all clients
case 4: return true;
// show field to teammates and spectators
- case 5: return (pReceiver->m_iTeam == m_iTeam || pReceiver->m_iTeam == SPECTATOR);
+ case 5: return ((!CSGameRules()->IsFreeForAll() && pReceiver->m_iTeam == m_iTeam) || pReceiver->m_iTeam == SPECTATOR);
default:
break;
}
@@ -7517,10 +7542,12 @@ void CBasePlayer::UpdateStatusBar()
{
CBasePlayer *pTarget = (CBasePlayer *)pEntity;
+ bool sameTeam = !CSGameRules()->IsFreeForAll() && pTarget->m_iTeam == m_iTeam;
+
newSBarState[SBAR_ID_TARGETNAME] = ENTINDEX(pTarget->edict());
- newSBarState[SBAR_ID_TARGETTYPE] = (pTarget->m_iTeam == m_iTeam) ? SBAR_TARGETTYPE_TEAMMATE : SBAR_TARGETTYPE_ENEMY;
+ newSBarState[SBAR_ID_TARGETTYPE] = sameTeam ? SBAR_TARGETTYPE_TEAMMATE : SBAR_TARGETTYPE_ENEMY;
- if (pTarget->m_iTeam == m_iTeam || GetObserverMode() != OBS_NONE)
+ if (sameTeam || GetObserverMode() != OBS_NONE)
{
if (playerid.value != PLAYERID_MODE_OFF || GetObserverMode() != OBS_NONE)
Q_strcpy(sbuf0, "1 %c1: %p2\n2 %h: %i3%%");
@@ -7680,6 +7707,14 @@ CBaseEntity *EXT_FUNC CBasePlayer::__API_HOOK(DropPlayerItem)(const char *pszIte
// take item off hud
pev->weapons &= ~(1 << pWeapon->m_iId);
+
+#ifdef REGAMEDLL_FIXES
+ // No more weapon
+ if ((pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
+ m_iHideHUD |= HIDEHUD_WEAPONS;
+ }
+#endif
+
g_pGameRules->GetNextBestWeapon(this, pWeapon);
UTIL_MakeVectors(pev->angles);
@@ -7935,6 +7970,8 @@ void CBasePlayer::__API_HOOK(SwitchTeam)()
SendItemStatus();
SetProgressBarTime(0);
+#ifndef REGAMEDLL_FIXES
+ // NOTE: unreachable code - Vaqtincha
for (int i = 0; i < MAX_ITEM_TYPES; i++)
{
m_pActiveItem = m_rgpPlayerItems[i];
@@ -7945,6 +7982,8 @@ void CBasePlayer::__API_HOOK(SwitchTeam)()
m_rgpPlayerItems[i] = nullptr;
}
}
+#endif
+
}
szOldTeam = GetTeam(oldTeam);
@@ -9624,6 +9663,14 @@ void CBasePlayer::RemoveBomb()
if (RemovePlayerItem(pBomb)) {
pev->weapons &= ~(1 << pBomb->m_iId);
+
+#ifdef REGAMEDLL_FIXES
+ // No more weapon
+ if ((pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
+ m_iHideHUD |= HIDEHUD_WEAPONS;
+ }
+#endif
+
pBomb->Kill();
}
}
@@ -9859,3 +9906,28 @@ void CBasePlayer::__API_HOOK(RemoveSpawnProtection)()
CSPlayer()->m_flSpawnProtectionEndTime = 0.0f;
}
+
+LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayer, DropIdlePlayer, (const char *reason), reason)
+
+void EXT_FUNC CBasePlayer::__API_HOOK(DropIdlePlayer)(const char *reason)
+{
+ if (!autokick.value)
+ return;
+
+ edict_t *pEntity = edict();
+
+ int iUserID = GETPLAYERUSERID(pEntity);
+
+ // Log the kick
+ UTIL_LogPrintf("\"%s<%i><%s><%s>\" triggered \"Game_idle_kick\" (auto)\n", STRING(pev->netname), iUserID , GETPLAYERAUTHID(pEntity), GetTeam(m_iTeam));
+ UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_idle_kick", STRING(pev->netname));
+
+#ifdef REGAMEDLL_FIXES
+ if (iUserID != -1)
+ {
+ SERVER_COMMAND(UTIL_VarArgs("kick #%d \"%s\"\n", iUserID, reason));
+ }
+#else
+ SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pev->netname)));
+#endif // #ifdef REGAMEDLL_FIXES
+}
diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h
index e6a4576c8..3c7060914 100644
--- a/regamedll/dlls/player.h
+++ b/regamedll/dlls/player.h
@@ -429,6 +429,7 @@ class CBasePlayer: public CBaseMonster {
void RemoveSpawnProtection_OrigFunc();
bool HintMessageEx_OrigFunc(const char *pMessage, float duration = 6.0f, bool bDisplayIfPlayerDead = false, bool bOverride = false);
void UseEmpty_OrigFunc();
+ void DropIdlePlayer_OrigFunc(const char *reason);
CCSPlayer *CSPlayer() const;
#endif // REGAMEDLL_API
@@ -625,6 +626,7 @@ class CBasePlayer: public CBaseMonster {
void SetSpawnProtection(float flProtectionTime);
void RemoveSpawnProtection();
void UseEmpty();
+ void DropIdlePlayer(const char *reason);
// templates
template
@@ -940,7 +942,6 @@ inline CBasePlayer *UTIL_PlayerByIndexSafe(int playerIndex)
return pPlayer;
}
-extern int gEvilImpulse101;
extern entvars_t *g_pevLastInflictor;
extern CBaseEntity *g_pLastSpawn;
extern CBaseEntity *g_pLastCTSpawn;
diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp
index 6a05d1ce1..2eff9fb01 100644
--- a/regamedll/dlls/weapons.cpp
+++ b/regamedll/dlls/weapons.cpp
@@ -576,11 +576,6 @@ void CBasePlayerItem::DefaultTouch(CBaseEntity *pOther)
// can I have this?
if (!g_pGameRules->CanHavePlayerItem(pPlayer, this))
{
- if (gEvilImpulse101)
- {
- UTIL_Remove(this);
- }
-
return;
}
@@ -1055,7 +1050,19 @@ void CBasePlayerItem::DestroyItem()
if (m_pPlayer)
{
// if attached to a player, remove.
- m_pPlayer->RemovePlayerItem(this);
+ if (m_pPlayer->RemovePlayerItem(this))
+ {
+
+#ifdef REGAMEDLL_FIXES
+ m_pPlayer->pev->weapons &= ~(1 << m_iId);
+
+ // No more weapon
+ if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
+ m_pPlayer->m_iHideHUD |= HIDEHUD_WEAPONS;
+ }
+#endif
+
+ }
}
Kill();
@@ -1227,7 +1234,7 @@ BOOL CBasePlayerWeapon::AddPrimaryAmmo(int iCount, char *szName, int iMaxClip, i
if (iMaxClip < 1)
{
- m_iClip = -1;
+ m_iClip = WEAPON_NOCLIP;
iIdAmmo = m_pPlayer->GiveAmmo(iCount, szName, iMaxCarry);
}
else if (m_iClip == 0)
@@ -1288,12 +1295,16 @@ BOOL CBasePlayerWeapon::IsUseable()
return TRUE;
}
-BOOL CBasePlayerWeapon::CanDeploy()
+LINK_HOOK_CLASS_CHAIN2(BOOL, CBasePlayerWeapon, CanDeploy)
+
+BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(CanDeploy)()
{
return TRUE;
}
-BOOL CBasePlayerWeapon::DefaultDeploy(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal)
+LINK_HOOK_CLASS_CHAIN(BOOL, CBasePlayerWeapon, DefaultDeploy, (char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal), szViewModel, szWeaponModel, iAnim, szAnimExt, skiplocal)
+
+BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultDeploy)(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal)
{
if (!CanDeploy())
return FALSE;
@@ -1343,7 +1354,9 @@ void CBasePlayerWeapon::ReloadSound()
}
}
-int CBasePlayerWeapon::DefaultReload(int iClipSize, int iAnim, float fDelay)
+LINK_HOOK_CLASS_CHAIN(int, CBasePlayerWeapon, DefaultReload, (int iClipSize, int iAnim, float fDelay), iClipSize, iAnim, fDelay)
+
+int EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultReload)(int iClipSize, int iAnim, float fDelay)
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
return FALSE;
@@ -1365,6 +1378,63 @@ int CBasePlayerWeapon::DefaultReload(int iClipSize, int iAnim, float fDelay)
return TRUE;
}
+LINK_HOOK_CLASS_CHAIN(bool, CBasePlayerWeapon, DefaultShotgunReload, (int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2), iAnim, iStartAnim, fDelay, fStartDelay, pszReloadSound1, pszReloadSound2)
+
+bool EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultShotgunReload)(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2)
+{
+ if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == iMaxClip())
+ return false;
+
+ // don't reload until recoil is done
+ if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
+ return false;
+
+ // check to see if we're ready to reload
+ if (m_fInSpecialReload == 0)
+ {
+ m_pPlayer->SetAnimation(PLAYER_RELOAD);
+ SendWeaponAnim(iStartAnim, UseDecrement() != FALSE);
+
+ m_fInSpecialReload = 1;
+ m_flNextSecondaryAttack = m_flTimeWeaponIdle = m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fStartDelay;
+ m_flNextPrimaryAttack = GetNextAttackDelay(fStartDelay);
+ }
+ else if (m_fInSpecialReload == 1)
+ {
+ if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
+ return false;
+
+ // was waiting for gun to move to side
+ m_fInSpecialReload = 2;
+
+ const char *pszReloadSound = nullptr;
+ if (pszReloadSound1 && pszReloadSound2) pszReloadSound = RANDOM_LONG(0, 1) ? pszReloadSound1 : pszReloadSound2;
+ else if (pszReloadSound1) pszReloadSound = pszReloadSound1;
+ else if (pszReloadSound2) pszReloadSound = pszReloadSound2;
+
+ if (pszReloadSound && pszReloadSound[0] != '\0')
+ {
+ EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_ITEM, pszReloadSound, VOL_NORM, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 31));
+ }
+
+ SendWeaponAnim(iAnim, UseDecrement());
+
+ m_flTimeWeaponIdle = m_flNextReload = UTIL_WeaponTimeBase() + fDelay;
+ }
+ else
+#ifdef BUILD_LATEST_FIXES
+ if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
+#endif
+ {
+ m_iClip++;
+ m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
+ m_pPlayer->ammo_buckshot--;
+ m_fInSpecialReload = 1;
+ }
+
+ return true;
+}
+
BOOL CBasePlayerWeapon::PlayEmptySound()
{
if (m_iPlayEmptySound)
@@ -1450,7 +1520,7 @@ int CBasePlayerWeapon::ExtractClipAmmo(CBasePlayerWeapon *pWeapon)
iAmmo = m_iClip;
}
- return pWeapon->m_pPlayer->GiveAmmo(iAmmo, (char *)pszAmmo1(), iMaxAmmo1());
+ return pWeapon->m_pPlayer->GiveAmmo(iAmmo, pszAmmo1(), iMaxAmmo1());
}
// RetireWeapon - no more ammo for this gun, put it away.
@@ -2107,6 +2177,12 @@ void CArmoury::Spawn()
void CArmoury::Restart()
{
#ifdef REGAMEDLL_FIXES
+ if (!weapons_allow_map_placed.value)
+ {
+ Hide();
+ return;
+ }
+
// This code refers to the mode of Escape. (Because there is relationship to the team Terrorists)
if (CSGameRules()->m_bMapHasEscapeZone)
#endif
diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h
index 9f8e85aeb..f3d90ebb5 100644
--- a/regamedll/dlls/weapons.h
+++ b/regamedll/dlls/weapons.h
@@ -395,8 +395,14 @@ class CBasePlayerWeapon: public CBasePlayerItem
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void HandleInfiniteAmmo();
void InstantReload(bool bCanRefillBPAmmo = false);
+ bool DefaultShotgunReload(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1 = nullptr, const char *pszReloadSound2 = nullptr);
#ifdef REGAMEDLL_API
+ BOOL CanDeploy_OrigFunc();
+ BOOL DefaultDeploy_OrigFunc(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal);
+ BOOL DefaultReload_OrigFunc(int iClipSize, int iAnim, float fDelay);
+ bool DefaultShotgunReload_OrigFunc(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2);
+
CCSPlayerWeapon *CSPlayerWeapon() const;
#endif
@@ -808,7 +814,6 @@ class CAWP: public CBasePlayerWeapon
#define BOMB_FLAG_DROPPED 0 // if the bomb was dropped due to voluntary dropping or death/disconnect
#define BOMB_FLAG_PLANTED 1 // if the bomb has been planted will also trigger the round timer to hide will also show where the dropped bomb on the Terrorist team's radar.
-const float C4_MAX_AMMO = 1.0f;
const float C4_MAX_SPEED = 250.0f;
const float C4_ARMING_ON_TIME = 3.0f;
@@ -945,6 +950,10 @@ class CFlashbang: public CBasePlayerWeapon
#endif
}
+#ifdef REGAMEDLL_API
+ BOOL CanDeploy_OrigFunc();
+#endif
+
public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void SetPlayerShieldAnim();
@@ -1101,6 +1110,10 @@ class CHEGrenade: public CBasePlayerWeapon
#endif
}
+#ifdef REGAMEDLL_API
+ BOOL CanDeploy_OrigFunc();
+#endif
+
public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void SetPlayerShieldAnim();
@@ -1576,6 +1589,10 @@ class CSmokeGrenade: public CBasePlayerWeapon
#endif
}
+#ifdef REGAMEDLL_API
+ BOOL CanDeploy_OrigFunc();
+#endif
+
public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void SetPlayerShieldAnim();
diff --git a/regamedll/dlls/weapontype.cpp b/regamedll/dlls/weapontype.cpp
index 07d67c602..cc08aed76 100644
--- a/regamedll/dlls/weapontype.cpp
+++ b/regamedll/dlls/weapontype.cpp
@@ -255,7 +255,7 @@ WeaponInfoStruct g_weaponInfo_default[] =
{ WEAPON_P90, P90_PRICE, AMMO_57MM_PRICE, AMMO_57MM_BUY, P90_MAX_CLIP, MAX_AMMO_57MM, AMMO_57MM, "weapon_p90", "ammo_57mm", "57mm" },
#ifdef REGAMEDLL_FIXES
- { WEAPON_C4, 0, 0, 0, 0, 0, AMMO_C4, "weapon_c4", nullptr, "C4" },
+ { WEAPON_C4, 0, 0, 0, 0, MAX_AMMO_C4, AMMO_C4, "weapon_c4", nullptr, "C4" },
{ WEAPON_KNIFE, 0, 0, 0, 0, 0, AMMO_NONE, "weapon_knife", nullptr, nullptr },
{ WEAPON_HEGRENADE, (WeaponCostType)HEGRENADE_PRICE, AMMO_HEGRENADE_PRICE, AMMO_HEGRENADE_BUY, 0, MAX_AMMO_HEGRENADE, AMMO_HEGRENADE, "weapon_hegrenade", nullptr, "HEGrenade" },
{ WEAPON_SMOKEGRENADE, (WeaponCostType)SMOKEGRENADE_PRICE, AMMO_SMOKEGRENADE_PRICE, AMMO_SMOKEGRENADE_BUY, 0, MAX_AMMO_SMOKEGRENADE, AMMO_SMOKEGRENADE, "weapon_smokegrenade", nullptr, "SmokeGrenade" },
@@ -285,7 +285,7 @@ AmmoInfoStruct g_ammoInfo_default[] =
{ AMMO_FLASHBANG, AMMO_FLASHBANG_PRICE, AMMO_FLASHBANG_BUY, MAX_AMMO_FLASHBANG, nullptr, "Flashbang" },
{ AMMO_HEGRENADE, AMMO_HEGRENADE_PRICE, AMMO_HEGRENADE_BUY, MAX_AMMO_HEGRENADE, nullptr, "HEGrenade" },
{ AMMO_SMOKEGRENADE, AMMO_SMOKEGRENADE_PRICE, AMMO_SMOKEGRENADE_BUY, MAX_AMMO_SMOKEGRENADE, nullptr, "SmokeGrenade" },
- { AMMO_C4, 0, 0, 0, nullptr, "C4" },
+ { AMMO_C4, 0, 0, MAX_AMMO_C4, nullptr, "C4" },
};
AmmoInfoStruct g_ammoInfo[ARRAYSIZE(g_ammoInfo_default)];
diff --git a/regamedll/dlls/weapontype.h b/regamedll/dlls/weapontype.h
index 7b842c0ca..e3527e5fa 100644
--- a/regamedll/dlls/weapontype.h
+++ b/regamedll/dlls/weapontype.h
@@ -263,6 +263,7 @@ enum MaxAmmoType
MAX_AMMO_SMOKEGRENADE = 1,
MAX_AMMO_HEGRENADE = 1,
MAX_AMMO_FLASHBANG = 2,
+ MAX_AMMO_C4 = 1,
};
enum AmmoType
diff --git a/regamedll/dlls/wpn_shared/wpn_c4.cpp b/regamedll/dlls/wpn_shared/wpn_c4.cpp
index e1a0c0a0b..dbe0c7e39 100644
--- a/regamedll/dlls/wpn_shared/wpn_c4.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_c4.cpp
@@ -44,7 +44,7 @@ int CC4::GetItemInfo(ItemInfo *p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "C4";
- p->iMaxAmmo1 = C4_MAX_AMMO;
+ p->iMaxAmmo1 = MAX_AMMO_C4;
p->pszAmmo2 = nullptr;
p->iMaxAmmo2 = -1;
p->iMaxClip = WEAPON_NOCLIP;
@@ -88,7 +88,11 @@ void CC4::Holster(int skiplocal)
if (!m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
{
+#ifndef REGAMEDLL_FIXES
+ // Moved to DestroyItem()
m_pPlayer->pev->weapons &= ~(1 << WEAPON_C4);
+#endif
+
DestroyItem();
}
diff --git a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp
index bf8e4f305..c5462e49b 100644
--- a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp
@@ -74,7 +74,10 @@ void CFlashbang::Holster(int skiplocal)
if (!m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
{
+#ifndef REGAMEDLL_FIXES
+ // Moved to DestroyItem()
m_pPlayer->pev->weapons &= ~(1 << WEAPON_FLASHBANG);
+#endif
DestroyItem();
}
@@ -261,7 +264,9 @@ void CFlashbang::WeaponIdle()
}
}
-BOOL CFlashbang::CanDeploy()
+LINK_HOOK_CLASS_CHAIN3(BOOL, CBasePlayerWeapon, CFlashbang, CanDeploy)
+
+BOOL EXT_FUNC CFlashbang::__API_HOOK(CanDeploy)()
{
return m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0;
}
diff --git a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp
index 338ae2179..3f17e7254 100644
--- a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp
@@ -77,7 +77,11 @@ void CHEGrenade::Holster(int skiplocal)
if (!m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
{
+#ifndef REGAMEDLL_FIXES
+ // Moved to DestroyItem()
m_pPlayer->pev->weapons &= ~(1 << WEAPON_HEGRENADE);
+#endif
+
DestroyItem();
}
@@ -256,7 +260,9 @@ void CHEGrenade::WeaponIdle()
}
}
-BOOL CHEGrenade::CanDeploy()
+LINK_HOOK_CLASS_CHAIN3(BOOL, CBasePlayerWeapon, CHEGrenade, CanDeploy)
+
+BOOL EXT_FUNC CHEGrenade::__API_HOOK(CanDeploy)()
{
return m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0;
}
diff --git a/regamedll/dlls/wpn_shared/wpn_m3.cpp b/regamedll/dlls/wpn_shared/wpn_m3.cpp
index 810008e21..bd27b399e 100644
--- a/regamedll/dlls/wpn_shared/wpn_m3.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_m3.cpp
@@ -177,43 +177,9 @@ void CM3::PrimaryAttack()
void CM3::Reload()
{
- if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == iMaxClip())
- return;
-
- // don't reload until recoil is done
- if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
- return;
-
- // check to see if we're ready to reload
- if (m_fInSpecialReload == 0)
- {
- m_pPlayer->SetAnimation(PLAYER_RELOAD);
- SendWeaponAnim(M3_START_RELOAD, UseDecrement() != FALSE);
-
- m_fInSpecialReload = 1;
- m_flNextSecondaryAttack = m_flTimeWeaponIdle = m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.55f;
- m_flNextPrimaryAttack = GetNextAttackDelay(0.55);
- }
- else if (m_fInSpecialReload == 1)
- {
- if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
- return;
-
- // was waiting for gun to move to side
- m_fInSpecialReload = 2;
- SendWeaponAnim(M3_RELOAD, UseDecrement());
-
- m_flTimeWeaponIdle = m_flNextReload = UTIL_WeaponTimeBase() + 0.45f;
- }
- else
-#ifdef BUILD_LATEST_FIXES
- if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
-#endif
+ if (!DefaultShotgunReload(M3_RELOAD, M3_START_RELOAD, 0.45f, 0.55f))
{
- m_iClip++;
- m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
- m_pPlayer->ammo_buckshot--;
- m_fInSpecialReload = 1;
+ /* do nothing */
}
}
diff --git a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp
index 306b508f3..d63fe3a69 100644
--- a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp
@@ -78,7 +78,11 @@ void CSmokeGrenade::Holster(int skiplocal)
{
// no more smokegrenades!
// clear the smokegrenade of bits for HUD
+#ifndef REGAMEDLL_FIXES
+ // Moved to DestroyItem()
m_pPlayer->pev->weapons &= ~(1 << WEAPON_SMOKEGRENADE);
+#endif
+
DestroyItem();
}
@@ -270,7 +274,9 @@ void CSmokeGrenade::WeaponIdle()
}
}
-BOOL CSmokeGrenade::CanDeploy()
+LINK_HOOK_CLASS_CHAIN3(BOOL, CBasePlayerWeapon, CSmokeGrenade, CanDeploy)
+
+BOOL EXT_FUNC CSmokeGrenade::__API_HOOK(CanDeploy)()
{
return m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0;
}
diff --git a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp
index b123f8c3c..4590e3e33 100644
--- a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp
@@ -174,49 +174,9 @@ void CXM1014::PrimaryAttack()
void CXM1014::Reload()
{
- if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == iMaxClip())
- return;
-
- // don't reload until recoil is done
- if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
- return;
-
- // check to see if we're ready to reload
- if (m_fInSpecialReload == 0)
- {
- m_pPlayer->SetAnimation(PLAYER_RELOAD);
- SendWeaponAnim(XM1014_START_RELOAD, UseDecrement() != FALSE);
-
- m_fInSpecialReload = 1;
- m_flNextSecondaryAttack = m_flTimeWeaponIdle = m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.55f;
- m_flNextPrimaryAttack = GetNextAttackDelay(0.55);
- }
- else if (m_fInSpecialReload == 1)
- {
- if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
- return;
-
- // was waiting for gun to move to side
- m_fInSpecialReload = 2;
-
- if (RANDOM_LONG(0, 1))
- EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_ITEM, "weapons/reload1.wav", VOL_NORM, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 31));
- else
- EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_ITEM, "weapons/reload3.wav", VOL_NORM, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 31));
-
- SendWeaponAnim(XM1014_RELOAD, UseDecrement());
-
- m_flTimeWeaponIdle = m_flNextReload = UTIL_WeaponTimeBase() + 0.3f;
- }
- else
-#ifdef BUILD_LATEST_FIXES
- if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
-#endif
+ if (!DefaultShotgunReload(XM1014_RELOAD, XM1014_START_RELOAD, 0.3f, 0.55f, "weapons/reload1.wav", "weapons/reload3.wav"))
{
- m_iClip++;
- m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
- m_pPlayer->ammo_buckshot--;
- m_fInSpecialReload = 1;
+ /* do nothing */
}
}
diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h
index 200414682..8c8e56dca 100644
--- a/regamedll/public/regamedll/regamedll_api.h
+++ b/regamedll/public/regamedll/regamedll_api.h
@@ -38,7 +38,7 @@
#include
#define REGAMEDLL_API_VERSION_MAJOR 5
-#define REGAMEDLL_API_VERSION_MINOR 11
+#define REGAMEDLL_API_VERSION_MINOR 12
// CBasePlayer::Spawn hook
typedef IHookChainClass IReGameHook_CBasePlayer_Spawn;
@@ -444,6 +444,26 @@ typedef IHookChainRegistryClass IReGameHook_CBasePlayer_UseEmpty;
typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_UseEmpty;
+// CBasePlayerWeapon::CanDeploy hook
+typedef IHookChainClass IReGameHook_CBasePlayerWeapon_CanDeploy;
+typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_CanDeploy;
+
+// CBasePlayerWeapon::DefaultDeploy hook
+typedef IHookChainClass IReGameHook_CBasePlayerWeapon_DefaultDeploy;
+typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy;
+
+// CBasePlayerWeapon::DefaultReload hook
+typedef IHookChainClass IReGameHook_CBasePlayerWeapon_DefaultReload;
+typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_DefaultReload;
+
+// CBasePlayerWeapon::DefaultShotgunReload hook
+typedef IHookChainClass IReGameHook_CBasePlayerWeapon_DefaultShotgunReload;
+typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload;
+
+// CBasePlayer::DropIdlePlayer hook
+typedef IHookChainClass IReGameHook_CBasePlayer_DropIdlePlayer;
+typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_DropIdlePlayer;
+
class IReGameHookchains {
public:
virtual ~IReGameHookchains() {}
@@ -554,6 +574,11 @@ class IReGameHookchains {
virtual IReGameHookRegistry_IsPenetrableEntity *IsPenetrableEntity() = 0;
virtual IReGameHookRegistry_CBasePlayer_HintMessageEx *CBasePlayer_HintMessageEx() = 0;
virtual IReGameHookRegistry_CBasePlayer_UseEmpty *CBasePlayer_UseEmpty() = 0;
+ virtual IReGameHookRegistry_CBasePlayerWeapon_CanDeploy *CBasePlayerWeapon_CanDeploy() = 0;
+ virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy *CBasePlayerWeapon_DefaultDeploy() = 0;
+ virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultReload *CBasePlayerWeapon_DefaultReload() = 0;
+ virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload *CBasePlayerWeapon_DefaultShotgunReload() = 0;
+ virtual IReGameHookRegistry_CBasePlayer_DropIdlePlayer *CBasePlayer_DropIdlePlayer() = 0;
};
struct ReGameFuncs_t {