diff options
Diffstat (limited to 'game/server/hl1/hl1_weaponbox.cpp')
| -rw-r--r-- | game/server/hl1/hl1_weaponbox.cpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/game/server/hl1/hl1_weaponbox.cpp b/game/server/hl1/hl1_weaponbox.cpp new file mode 100644 index 0000000..07a745e --- /dev/null +++ b/game/server/hl1/hl1_weaponbox.cpp @@ -0,0 +1,242 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + + +#include "cbase.h" +#include "hl1_items.h" +#include "ammodef.h" + + +#define WEAPONBOX_MODEL "models/w_weaponbox.mdl" + + +class CWeaponBox : public CHL1Item +{ +public: + DECLARE_CLASS( CWeaponBox, CHL1Item ); + + void Spawn( void ); + void Precache( void ); + bool KeyValue( const char *szKeyName, const char *szValue ); + void BoxTouch( CBaseEntity *pPlayer ); + + DECLARE_DATADESC(); + +private: + bool PackAmmo( char *szName, int iCount ); + int GiveAmmo( int iCount, char *szName, int iMax, int *pIndex = NULL ); + + int m_cAmmoTypes; // how many ammo types packed into this box (if packed by a level designer) + string_t m_rgiszAmmo[MAX_AMMO_SLOTS]; // ammo names + int m_rgAmmo[MAX_AMMO_SLOTS]; // ammo quantities +}; +LINK_ENTITY_TO_CLASS(weaponbox, CWeaponBox); +PRECACHE_REGISTER(weaponbox); + +BEGIN_DATADESC( CWeaponBox ) + DEFINE_ARRAY( m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ), + DEFINE_ARRAY( m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ), + DEFINE_FIELD( m_cAmmoTypes, FIELD_INTEGER ), + + DEFINE_ENTITYFUNC( BoxTouch ), +END_DATADESC() + + +bool CWeaponBox::KeyValue( const char *szKeyName, const char *szValue ) +{ + if ( m_cAmmoTypes < MAX_AMMO_SLOTS ) + { + if ( PackAmmo( (char *)szKeyName, atoi( szValue ) ) ) + { + m_cAmmoTypes++;// count this new ammo type. + + return true; + } + } + else + { + Warning( "WeaponBox too full! only %d ammotypes allowed\n", MAX_AMMO_SLOTS ); + } + + return BaseClass::KeyValue( szKeyName, szValue ); +} + +void CWeaponBox::Spawn( void ) +{ + Precache(); + SetModel( WEAPONBOX_MODEL ); + BaseClass::Spawn(); + + PrecacheScriptSound( "Item.Pickup" ); + + SetTouch( &CWeaponBox::BoxTouch ); +} + + +void CWeaponBox::Precache( void ) +{ + PrecacheModel( WEAPONBOX_MODEL ); +} + + +void CWeaponBox::BoxTouch( CBaseEntity *pOther ) +{ + if ( !( GetFlags() & FL_ONGROUND ) ) + { + return; + } + + if ( !pOther->IsPlayer() ) + { + // only players may touch a weaponbox. + return; + } + + if ( !pOther->IsAlive() ) + { + // no dead guys. + return; + } + + CBasePlayer *pPlayer = (CBasePlayer *)pOther; + int i; + +// dole out ammo + for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ ) + { + if ( m_rgiszAmmo[ i ] != NULL_STRING ) + { + // there's some ammo of this type. + pPlayer->GiveAmmo( m_rgAmmo[ i ], (char *)STRING( m_rgiszAmmo[ i ] ) ); + + // now empty the ammo from the weaponbox since we just gave it to the player + m_rgiszAmmo[ i ] = NULL_STRING; + m_rgAmmo[ i ] = 0; + } + } + + CPASAttenuationFilter filter( pOther, "Item.Pickup" ); + EmitSound( filter, pOther->entindex(), "Item.Pickup" ); + + SetTouch(NULL); + if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_NO ) + { + UTIL_Remove( this ); + } +} + + +bool CWeaponBox::PackAmmo( char *szName, int iCount ) +{ + char szConvertedName[ 32 ]; + + if ( FStrEq( szName, "" ) ) + { + // error here + Warning( "NULL String in PackAmmo!\n" ); + return false; + } + + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "%s", szName ); + if ( !stricmp( szName, "bolts" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "XBowBolt" ); + } + if ( !stricmp( szName, "uranium" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Uranium" ); + } + if ( !stricmp( szName, "9mm" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "9mmRound" ); + } + if ( !stricmp( szName, "Hand Grenade" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Grenade" ); + } + if ( !stricmp( szName, "Hornets" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Hornet" ); + } + if ( !stricmp( szName, "ARgrenades" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "MP5_Grenade" ); + } + if ( !stricmp( szName, "357" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "357Round" ); + } + if ( !stricmp( szName, "rockets" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "RPG_Rocket" ); + } + if ( !stricmp( szName, "Satchel Charge" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Satchel" ); + } + if ( !stricmp( szName, "buckshot" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Buckshot" ); + } + if ( !stricmp( szName, "Snarks" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Snark" ); + } + if ( !stricmp( szName, "Trip Mine" ) ) + { + Q_snprintf( szConvertedName, sizeof( szConvertedName ), "TripMine" ); + } + + int iMaxCarry = GetAmmoDef()->MaxCarry( GetAmmoDef()->Index( szConvertedName ) ); + + if ( iMaxCarry > 0 && iCount > 0 ) + { + //ALERT ( at_console, "Packed %d rounds of %s\n", iCount, STRING(iszName) ); + GiveAmmo( iCount, szConvertedName, iMaxCarry ); + return true; + } + + return false; +} + +//========================================================= +// CWeaponBox - GiveAmmo +//========================================================= +int CWeaponBox::GiveAmmo( int iCount, char *szName, int iMax, int *pIndex ) +{ + int i; + + for ( i = 1; ( i < MAX_AMMO_SLOTS ) && ( m_rgiszAmmo[i] != NULL_STRING ); i++ ) + { + if ( stricmp( szName, STRING( m_rgiszAmmo[i] ) ) == 0 ) + { + if (pIndex) + *pIndex = i; + + int iAdd = MIN( iCount, iMax - m_rgAmmo[i]); + if (iCount == 0 || iAdd > 0) + { + m_rgAmmo[i] += iAdd; + + return i; + } + return -1; + } + } + + if (i < MAX_AMMO_SLOTS) + { + if (pIndex) + *pIndex = i; + + m_rgiszAmmo[i] = AllocPooledString( szName ); + m_rgAmmo[i] = iCount; + + return i; + } + Warning( "out of named ammo slots\n"); + return i; +} |