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 {