source-engine/game/server/hl1/hl1_weaponbox.cpp
2022-04-16 12:05:19 +03:00

243 lines
5.4 KiB
C++

//========= 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;
}