diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index d14a83ba..e6524a96 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -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) { diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h index 82e1356d..c9cd58c3 100644 --- a/regamedll/dlls/weapons.h +++ b/regamedll/dlls/weapons.h @@ -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; }