Add weapon flag ITEM_FLAG_NOFIREUNDERWATER (#628)

Implement weapon flag ITEM_FLAG_NOFIREUNDERWATER to allow user to changes behavior firing underwater
This commit is contained in:
Vaqtincha 2021-05-22 16:12:24 +05:00 committed by GitHub
parent bbc54cd30e
commit 8d1f4fb673
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 79 additions and 43 deletions

View File

@ -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();
}
}

View File

@ -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<CBasePlayerWeapon *>(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;
}

View File

@ -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())

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);