summaryrefslogtreecommitdiff
path: root/game/server/hl1/hl1_weaponbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/hl1/hl1_weaponbox.cpp')
-rw-r--r--game/server/hl1/hl1_weaponbox.cpp242
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;
+}