From 8d1f4fb673012fbfa912f4f22ec726684cfa7908 Mon Sep 17 00:00:00 2001 From: Vaqtincha <51029683+Vaqtincha@users.noreply.github.com> Date: Sat, 22 May 2021 16:12:24 +0500 Subject: [PATCH] Add weapon flag ITEM_FLAG_NOFIREUNDERWATER (#628) Implement weapon flag ITEM_FLAG_NOFIREUNDERWATER to allow user to changes behavior firing underwater --- regamedll/dlls/client.cpp | 9 ++++++++- regamedll/dlls/multiplay_gamerules.cpp | 24 ++++++++++++++++++++++-- regamedll/dlls/weapons.cpp | 17 ++++++++++++++++- regamedll/dlls/weapons.h | 11 ++++++----- regamedll/dlls/wpn_shared/wpn_famas.cpp | 15 +++++++-------- regamedll/dlls/wpn_shared/wpn_galil.cpp | 14 ++++++-------- regamedll/dlls/wpn_shared/wpn_m3.cpp | 16 +++++++--------- regamedll/dlls/wpn_shared/wpn_xm1014.cpp | 16 +++++++--------- 8 files changed, 79 insertions(+), 43 deletions(-) diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp index 4bb326ac..58aff3d2 100644 --- a/regamedll/dlls/client.cpp +++ b/regamedll/dlls/client.cpp @@ -245,6 +245,13 @@ void WriteSigonMessages() else pszName = info.pszName; + int iFlags = info.iFlags; + +#ifdef PLAY_GAMEDLL + // TODO: fix test demo + iFlags &= ~ITEM_FLAG_NOFIREUNDERWATER; +#endif + MESSAGE_BEGIN(MSG_INIT, gmsgWeaponList); WRITE_STRING(pszName); WRITE_BYTE(CBasePlayer::GetAmmoIndex(info.pszAmmo1)); @@ -254,7 +261,7 @@ void WriteSigonMessages() WRITE_BYTE(info.iSlot); WRITE_BYTE(info.iPosition); WRITE_BYTE(info.iId); - WRITE_BYTE(info.iFlags); + WRITE_BYTE(iFlags); MESSAGE_END(); } } diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index 8d87ff93..1c0da2db 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -3254,6 +3254,17 @@ BOOL EXT_FUNC CHalfLifeMultiplay::__API_HOOK(FShouldSwitchWeapon)(CBasePlayer *p return FALSE; } +#ifdef REGAMEDLL_FIXES + if (pPlayer->pev->waterlevel == 3) + { + if (pWeapon->iFlags() & ITEM_FLAG_NOFIREUNDERWATER) + return FALSE; + + if (pPlayer->m_pActiveItem->iFlags() & ITEM_FLAG_NOFIREUNDERWATER) + return TRUE; + } +#endif + if (pWeapon->iWeight() > pPlayer->m_pActiveItem->iWeight()) return TRUE; @@ -3268,6 +3279,7 @@ BOOL EXT_FUNC CHalfLifeMultiplay::__API_HOOK(GetNextBestWeapon)(CBasePlayer *pPl CBasePlayerItem *pBest; // this will be used in the event that we don't find a weapon in the same category. int iBestWeight; int i; + bool inWater = pPlayer->pev->waterlevel == 3; if (!pCurrentWeapon->CanHolster()) { @@ -3285,7 +3297,11 @@ BOOL EXT_FUNC CHalfLifeMultiplay::__API_HOOK(GetNextBestWeapon)(CBasePlayer *pPl while (pCheck) { // don't reselect the weapon we're trying to get rid of - if (pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon) + if (pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon +#ifdef REGAMEDLL_FIXES + && !(inWater && (pCheck->iFlags() & ITEM_FLAG_NOFIREUNDERWATER)) +#endif + ) { //ALERT (at_console, "Considering %s\n", STRING(pCheck->pev->classname)); // we keep updating the 'best' weapon just in case we can't find a weapon of the same weight @@ -3688,7 +3704,11 @@ void CHalfLifeMultiplay::PlayerThink(CBasePlayer *pPlayer) if (pPlayer->m_pActiveItem && pPlayer->m_pActiveItem->IsWeapon()) { CBasePlayerWeapon *pWeapon = static_cast(pPlayer->m_pActiveItem->GetWeaponPtr()); - if (pWeapon->m_iWeaponState & WPNSTATE_SHIELD_DRAWN) + if (pWeapon->m_iWeaponState & WPNSTATE_SHIELD_DRAWN +#ifdef REGAMEDLL_ADD + || ((pWeapon->iFlags() & ITEM_FLAG_NOFIREUNDERWATER) && pPlayer->pev->waterlevel == 3) +#endif + ) { pPlayer->m_bCanShoot = false; } diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index 72c3eeac..ba5543ee 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -747,6 +747,12 @@ void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bI vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, m_fBurstSpread, 8192, 2, BULLET_PLAYER_556MM, 30, 0.96, m_pPlayer->pev, false, m_pPlayer->random_seed); --m_pPlayer->ammo_556nato; +#ifdef REGAMEDLL_ADD + // HACKHACK: client-side weapon prediction fix + if (!(iFlags() & ITEM_FLAG_NOFIREUNDERWATER) && m_pPlayer->pev->waterlevel == 3) + flag = 0; +#endif + PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireFamas, 0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, int(m_pPlayer->pev->punchangle.x * 10000000), int(m_pPlayer->pev->punchangle.y * 10000000), FALSE, FALSE); } @@ -963,7 +969,16 @@ void CBasePlayerWeapon::ItemPostFrame() #endif (m_pPlayer->m_bCanShoot && g_pGameRules->IsMultiplayer() && !g_pGameRules->IsFreezePeriod() && !m_pPlayer->m_bIsDefusing) || !g_pGameRules->IsMultiplayer()) { - PrimaryAttack(); + // don't fire underwater + if (m_pPlayer->pev->waterlevel == 3 && (iFlags() & ITEM_FLAG_NOFIREUNDERWATER)) + { + PlayEmptySound(); + m_flNextPrimaryAttack = GetNextAttackDelay(0.15); + } + else + { + PrimaryAttack(); + } } } else if ((m_pPlayer->pev->button & IN_RELOAD) && iMaxClip() != WEAPON_NOCLIP && !m_fInReload && m_flNextPrimaryAttack < UTIL_WeaponTimeBase()) diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h index 82257a64..04429c46 100644 --- a/regamedll/dlls/weapons.h +++ b/regamedll/dlls/weapons.h @@ -35,11 +35,12 @@ const float MAX_DIST_RELOAD_SOUND = 512.0f; #define MAX_WEAPONS 32 -#define ITEM_FLAG_SELECTONEMPTY 1 -#define ITEM_FLAG_NOAUTORELOAD 2 -#define ITEM_FLAG_NOAUTOSWITCHEMPTY 4 -#define ITEM_FLAG_LIMITINWORLD 8 -#define ITEM_FLAG_EXHAUSTIBLE 16 // A player can totally exhaust their ammo supply and lose this weapon +#define ITEM_FLAG_SELECTONEMPTY BIT(0) +#define ITEM_FLAG_NOAUTORELOAD BIT(1) +#define ITEM_FLAG_NOAUTOSWITCHEMPTY BIT(2) +#define ITEM_FLAG_LIMITINWORLD BIT(3) +#define ITEM_FLAG_EXHAUSTIBLE BIT(4) // A player can totally exhaust their ammo supply and lose this weapon +#define ITEM_FLAG_NOFIREUNDERWATER BIT(5) #define WEAPON_IS_ONTARGET 0x40 diff --git a/regamedll/dlls/wpn_shared/wpn_famas.cpp b/regamedll/dlls/wpn_shared/wpn_famas.cpp index 5fb044fb..f414f02b 100644 --- a/regamedll/dlls/wpn_shared/wpn_famas.cpp +++ b/regamedll/dlls/wpn_shared/wpn_famas.cpp @@ -54,7 +54,7 @@ int CFamas::GetItemInfo(ItemInfo *p) p->iSlot = 0; p->iPosition = 18; p->iId = m_iId = WEAPON_FAMAS; - p->iFlags = 0; + p->iFlags = ITEM_FLAG_NOFIREUNDERWATER; p->iWeight = FAMAS_WEIGHT; return 1; @@ -90,13 +90,6 @@ void CFamas::SecondaryAttack() void CFamas::PrimaryAttack() { - if (m_pPlayer->pev->waterlevel == 3) - { - PlayEmptySound(); - m_flNextPrimaryAttack = GetNextAttackDelay(0.15); - return; - } - bool bFireBurst = (m_iWeaponState & WPNSTATE_FAMAS_BURST_MODE) == WPNSTATE_FAMAS_BURST_MODE; if (!(m_pPlayer->pev->flags & FL_ONGROUND)) @@ -178,6 +171,12 @@ void CFamas::FamasFire(float flSpread, float flCycleTime, BOOL fUseAutoAim, BOOL flag = 0; #endif +#ifdef REGAMEDLL_ADD + // HACKHACK: client-side weapon prediction fix + if (!(iFlags() & ITEM_FLAG_NOFIREUNDERWATER) && m_pPlayer->pev->waterlevel == 3) + flag = 0; +#endif + PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireFamas, 0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, int(m_pPlayer->pev->punchangle.x * 10000000), int(m_pPlayer->pev->punchangle.y * 10000000), FALSE, FALSE); diff --git a/regamedll/dlls/wpn_shared/wpn_galil.cpp b/regamedll/dlls/wpn_shared/wpn_galil.cpp index f5d3e2d5..aae7ca8c 100644 --- a/regamedll/dlls/wpn_shared/wpn_galil.cpp +++ b/regamedll/dlls/wpn_shared/wpn_galil.cpp @@ -48,7 +48,7 @@ int CGalil::GetItemInfo(ItemInfo *p) p->iSlot = 0; p->iPosition = 17; p->iId = m_iId = WEAPON_GALIL; - p->iFlags = 0; + p->iFlags = ITEM_FLAG_NOFIREUNDERWATER; p->iWeight = GALIL_WEIGHT; return 1; @@ -70,13 +70,6 @@ void CGalil::SecondaryAttack() void CGalil::PrimaryAttack() { - if (m_pPlayer->pev->waterlevel == 3) - { - PlayEmptySound(); - m_flNextPrimaryAttack = GetNextAttackDelay(0.15); - return; - } - if (!(m_pPlayer->pev->flags & FL_ONGROUND)) { GalilFire(0.04 + (0.3 * m_flAccuracy), 0.0875, FALSE); @@ -143,6 +136,11 @@ void CGalil::GalilFire(float flSpread, float flCycleTime, BOOL fUseAutoAim) flag = 0; #endif +#ifdef REGAMEDLL_ADD + // HACKHACK: client-side weapon prediction fix + if (!(iFlags() & ITEM_FLAG_NOFIREUNDERWATER) && m_pPlayer->pev->waterlevel == 3) + flag = 0; +#endif PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireGalil, 0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, int(m_pPlayer->pev->punchangle.x * 10000000), int(m_pPlayer->pev->punchangle.y * 10000000), FALSE, FALSE); diff --git a/regamedll/dlls/wpn_shared/wpn_m3.cpp b/regamedll/dlls/wpn_shared/wpn_m3.cpp index 69822960..3251ae9a 100644 --- a/regamedll/dlls/wpn_shared/wpn_m3.cpp +++ b/regamedll/dlls/wpn_shared/wpn_m3.cpp @@ -49,7 +49,7 @@ int CM3::GetItemInfo(ItemInfo *p) p->iSlot = 0; p->iPosition = 5; p->iId = m_iId = WEAPON_M3; - p->iFlags = 0; + p->iFlags = ITEM_FLAG_NOFIREUNDERWATER; p->iWeight = M3_WEIGHT; return 1; @@ -72,14 +72,6 @@ void CM3::PrimaryAttack() Vector vecAiming, vecSrc, vecDir; int flag; - // don't fire underwater - if (m_pPlayer->pev->waterlevel == 3) - { - PlayEmptySound(); - m_flNextPrimaryAttack = GetNextAttackDelay(0.15); - return; - } - if (m_iClip <= 0) { #ifdef BUILD_LATEST_FIXES @@ -146,6 +138,12 @@ void CM3::PrimaryAttack() flag = 0; #endif +#ifdef REGAMEDLL_ADD + // HACKHACK: client-side weapon prediction fix + if (!(iFlags() & ITEM_FLAG_NOFIREUNDERWATER) && m_pPlayer->pev->waterlevel == 3) + flag = 0; +#endif + PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireM3, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, FALSE, FALSE); if (!m_iClip && 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 9689844f..ec7a01de 100644 --- a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp +++ b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp @@ -47,7 +47,7 @@ int CXM1014::GetItemInfo(ItemInfo *p) p->iSlot = 0; p->iPosition = 12; p->iId = m_iId = WEAPON_XM1014; - p->iFlags = 0; + p->iFlags = ITEM_FLAG_NOFIREUNDERWATER; p->iWeight = XM1014_WEIGHT; return 1; @@ -70,14 +70,6 @@ void CXM1014::PrimaryAttack() Vector vecAiming, vecSrc, vecDir; int flag; - // don't fire underwater - if (m_pPlayer->pev->waterlevel == 3) - { - PlayEmptySound(); - m_flNextPrimaryAttack = GetNextAttackDelay(0.15); - return; - } - if (m_iClip <= 0) { #ifdef BUILD_LATEST_FIXES @@ -144,6 +136,12 @@ void CXM1014::PrimaryAttack() flag = 0; #endif +#ifdef REGAMEDLL_ADD + // HACKHACK: client-side weapon prediction fix + if (!(iFlags() & ITEM_FLAG_NOFIREUNDERWATER) && m_pPlayer->pev->waterlevel == 3) + flag = 0; +#endif + PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireXM1014, 0, (float *)&g_vecZero, (float *)&g_vecZero, m_vVecAiming.x, m_vVecAiming.y, 7, int(m_vVecAiming.x * 100), m_iClip == 0, FALSE);