ValveSoftware / halflife

Half-Life 1 engine based games
Other
3.72k stars 625 forks source link

[Half-Life] MP5 autoswitch bug #3001

Open BlackShadow opened 3 years ago

BlackShadow commented 3 years ago

When player rans out of ammo except AR grenades MP5 won't allow to use that grenades because autoswitch. If Secondary Attack held, MP5 fires grenades but it's really a hassle. Also MP5 can be still selected in HUD because there's still AR grenades present.

Issue can be seen here:

https://streamable.com/8h8wsi

JoelTroch commented 3 years ago

This happens because BOOL CBasePlayerWeapon::IsUseable() only check the magazine (or clip) if there is one and the primary ammo reserve (9mm in the case of the 9mmAR) if there is one. It does not perform any check for the secondary ammo reserve (ARgrenades) as shown here.

Adding the secondary ammo check should be easy and could be implemented like this:

BOOL CBasePlayerWeapon :: IsUseable( void )
{
    if ( m_iClip <= 0 )
    {
        if ( m_pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] <= 0 && iMaxAmmo1() != -1 )
        {
            if ( m_pPlayer->m_rgAmmo[ SecondaryAmmoIndex() ] <= 0 && iMaxAmmo2() != -1 )
            {
                // clip is empty (or nonexistant) and the player has no more ammo of these types.
                return FALSE;
            }
        }
    }

    return TRUE;
}

This part of the code here might require an update as well to check for m_flNextSecondaryAttack in addition to the existing checks for m_flNextPrimaryAttack. Looking at CMP5::SecondaryAttack()'s code, m_flNextPrimaryAttack and m_flNextSecondaryAttack are updated together with the same value so theorically speaking, that update shouldn't be needed for vanilla Half-Life 1 (but worth mentioning for mod makers/programmers).

SamVanheer commented 3 years ago

@JoelTroch your fix assumes that SecondaryAmmoIndex returns a valid index. By default it returns -1, only if the weapon overrides the method to return m_iSecondaryAmmoType will it return anything else, and then only if the secondary ammo type information is filled in in GetItemInfo.

I've fixed this and logged it as #3029.

Here's the method rewritten to account for the secondary ammo type being optional: https://github.com/Solokiller/halflife-updated/commit/a9b1d9cda8e063258fc9291ada671c09ef71472b

I've also restructured the logic to make it easier to determine when a weapon is usable.