Skip to content

Commit

Permalink
CWeaponBox::Touch: Fix grenade pickup (Resolves #923, Closes #931)
Browse files Browse the repository at this point in the history
  • Loading branch information
s1lentq committed Feb 1, 2024
1 parent f4c4e89 commit 4d90a5f
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 33 deletions.
118 changes: 86 additions & 32 deletions regamedll/dlls/weapons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down
5 changes: 4 additions & 1 deletion regamedll/dlls/weapons.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,9 @@ class CWeaponBox: public CBaseEntity
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();
Expand Down Expand Up @@ -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; }
Expand Down

0 comments on commit 4d90a5f

Please sign in to comment.