You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
5.4 KiB
242 lines
5.4 KiB
//========= 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; |
|
}
|
|
|