CWeaponBox::Touch: Fix grenade pickup (Resolves #923, Closes #931)

This commit is contained in:
s1lentq 2024-02-01 18:20:11 +07:00
parent f4c4e891ac
commit 4d90a5f4fa
2 changed files with 90 additions and 33 deletions

View File

@ -1846,6 +1846,58 @@ void CWeaponBox::Kill()
UTIL_Remove(this);
}
bool CWeaponBox::GiveAmmoToPlayer(CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon, int iCurrentAmmo, const char *pszAmmo, int iMaxAmmo, CBasePlayerItem **pGivenItem)
{
if (iCurrentAmmo >= iMaxAmmo)
return false; // can't pickup more, these ammo are full in backpack
// If already have a weapon in backpack, just refill ammo for it
if (iCurrentAmmo > 0)
{
int iAmmoIndex = GetAmmoIndex(pszAmmo);
if (iAmmoIndex > 0)
{
// how many gren ammo can pick up?
int iAmmoPickup = min(m_rgAmmo[iAmmoIndex], iMaxAmmo - iCurrentAmmo);
if (iAmmoPickup > 0)
{
if (!FStringNull(m_rgiszAmmo[iAmmoIndex]) &&
pPlayer->GiveAmmo(iAmmoPickup, STRING(m_rgiszAmmo[iAmmoIndex]), iMaxAmmo) != -1)
{
m_rgAmmo[iAmmoIndex] -= iAmmoPickup;
if (m_rgAmmo[iAmmoIndex] < 0)
m_rgAmmo[iAmmoIndex] = 0;
EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
}
}
// ammo exhausted, remove this weapon
if (m_rgAmmo[iAmmoIndex] <= 0)
{
pWeapon->Kill();
// unlink this weapon from the box
return true;
}
// ammo has not been exhausted yet, keep this weapon in weaponbox
return false;
}
}
// If no weapon in backpack, then issue weapon
if (pPlayer->AddPlayerItem(pWeapon))
{
pWeapon->AttachToPlayer(pPlayer);
if (pGivenItem) *pGivenItem = pWeapon;
}
// unlink this weapon from the box
return true;
}
// Try to add my contents to the toucher if the toucher is a player.
void CWeaponBox::Touch(CBaseEntity *pOther)
{
@ -1991,38 +2043,17 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
int playerGrenades = pPlayer->m_rgAmmo[pGrenade->m_iPrimaryAmmoType];
#ifdef REGAMEDLL_FIXES
// sorry for hardcode :(
const int boxAmmoSlot = 1;
CBasePlayerItem *pNext = m_rgpPlayerItems[i]->m_pNext;
if (playerGrenades < pGrenade->iMaxAmmo1())
// Pickup grenade item or refill ammo
if (GiveAmmoToPlayer(pPlayer, pGrenade,
playerGrenades, pGrenade->pszAmmo1(), pGrenade->iMaxAmmo1(), &givenItem))
{
if (m_rgAmmo[boxAmmoSlot] > 1 && playerGrenades > 0)
{
if (!FStringNull(m_rgiszAmmo[boxAmmoSlot])
&& pPlayer->GiveAmmo(1, STRING(m_rgiszAmmo[boxAmmoSlot]), pGrenade->iMaxAmmo1()) != -1)
{
m_rgAmmo[boxAmmoSlot]--;
EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
}
}
else
{
auto pNext = m_rgpPlayerItems[i]->m_pNext;
if (pPlayer->AddPlayerItem(pItem))
{
pItem->AttachToPlayer(pPlayer);
givenItem = pItem;
}
// unlink this weapon from the box
m_rgpPlayerItems[i] = pItem = pNext;
continue;
}
// unlink this weapon from the box
m_rgpPlayerItems[i] = pItem = pNext;
continue;
}
#else
int maxGrenades = 0;
const char *grenadeName = nullptr;
@ -2096,13 +2127,18 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
{
if (!FStringNull(m_rgiszAmmo[n]))
{
// there's some ammo of this type.
#ifndef REGAMEDLL_ADD
pPlayer->GiveAmmo(m_rgAmmo[n], (char *)STRING(m_rgiszAmmo[n]), MaxAmmoCarry(m_rgiszAmmo[n]));
// there's some ammo of this type
if (m_rgAmmo[n] > 0)
{
#ifdef REGAMEDLL_ADD
int iMaxAmmo = m_rgAmmo[n];
#else
pPlayer->GiveAmmo(m_rgAmmo[n], STRING(m_rgiszAmmo[n]), m_rgAmmo[n]);
int iMaxAmmo = MaxAmmoCarry(m_rgiszAmmo[n]);
#endif
pPlayer->GiveAmmo(m_rgAmmo[n], STRING(m_rgiszAmmo[n]), iMaxAmmo);
}
// now empty the ammo from the weaponbox since we just gave it to the player
m_rgiszAmmo[n] = iStringNull;
m_rgAmmo[n] = 0;
@ -2242,6 +2278,24 @@ int CWeaponBox::GiveAmmo(int iCount, char *szName, int iMax, int *pIndex)
return i;
}
int CWeaponBox::GetAmmoIndex(const char *psz) const
{
if (!psz)
return -1;
int i;
for (i = 1; i < MAX_AMMO_SLOTS; i++)
{
if (FStringNull(m_rgiszAmmo[i]))
continue;
if (!Q_stricmp(STRING(m_rgiszAmmo[i]), psz))
return i;
}
return -1;
}
// Is a weapon of this type already packed in this box?
BOOL CWeaponBox::HasWeapon(CBasePlayerItem *pCheckItem)
{

View File

@ -477,6 +477,9 @@ public:
public:
BOOL IsEmpty();
int GiveAmmo(int iCount, char *szName, int iMax, int *pIndex = nullptr);
int GetAmmoIndex(const char *psz) const;
bool GiveAmmoToPlayer(CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon,
int iCurrentAmmo, const char *pszAmmo, int iMaxAmmo, CBasePlayerItem **pGivenItem = NULL);
void EXPORT Kill();
void EXPORT BombThink();
@ -1269,7 +1272,7 @@ inline float CKnife::KnifeSwingDamage(bool fast) const { return fast ? m_flSwing
inline float CKnife::KnifeStabDistance() const { return m_flStabDistance; }
inline float CKnife::KnifeSwingDistance() const { return m_flSwingDistance; }
inline float CKnife::KnifeBackStabMultiplier() const { return m_flBackStabMultiplier; }
#else
#else
inline float CKnife::KnifeStabDamage() const { return KNIFE_STAB_DAMAGE; }
inline float CKnife::KnifeSwingDamage(bool fast) const { return fast ? KNIFE_SWING_DAMAGE_FAST : KNIFE_SWING_DAMAGE; }
inline float CKnife::KnifeStabDistance() const { return KNIFE_STAB_DISTANCE; }