Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hl1_items.h"
  8. #include "ammodef.h"
  9. #define WEAPONBOX_MODEL "models/w_weaponbox.mdl"
  10. class CWeaponBox : public CHL1Item
  11. {
  12. public:
  13. DECLARE_CLASS( CWeaponBox, CHL1Item );
  14. void Spawn( void );
  15. void Precache( void );
  16. bool KeyValue( const char *szKeyName, const char *szValue );
  17. void BoxTouch( CBaseEntity *pPlayer );
  18. DECLARE_DATADESC();
  19. private:
  20. bool PackAmmo( char *szName, int iCount );
  21. int GiveAmmo( int iCount, char *szName, int iMax, int *pIndex = NULL );
  22. int m_cAmmoTypes; // how many ammo types packed into this box (if packed by a level designer)
  23. string_t m_rgiszAmmo[MAX_AMMO_SLOTS]; // ammo names
  24. int m_rgAmmo[MAX_AMMO_SLOTS]; // ammo quantities
  25. };
  26. LINK_ENTITY_TO_CLASS(weaponbox, CWeaponBox);
  27. PRECACHE_REGISTER(weaponbox);
  28. BEGIN_DATADESC( CWeaponBox )
  29. DEFINE_ARRAY( m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ),
  30. DEFINE_ARRAY( m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ),
  31. DEFINE_FIELD( m_cAmmoTypes, FIELD_INTEGER ),
  32. DEFINE_ENTITYFUNC( BoxTouch ),
  33. END_DATADESC()
  34. bool CWeaponBox::KeyValue( const char *szKeyName, const char *szValue )
  35. {
  36. if ( m_cAmmoTypes < MAX_AMMO_SLOTS )
  37. {
  38. if ( PackAmmo( (char *)szKeyName, atoi( szValue ) ) )
  39. {
  40. m_cAmmoTypes++;// count this new ammo type.
  41. return true;
  42. }
  43. }
  44. else
  45. {
  46. Warning( "WeaponBox too full! only %d ammotypes allowed\n", MAX_AMMO_SLOTS );
  47. }
  48. return BaseClass::KeyValue( szKeyName, szValue );
  49. }
  50. void CWeaponBox::Spawn( void )
  51. {
  52. Precache();
  53. SetModel( WEAPONBOX_MODEL );
  54. BaseClass::Spawn();
  55. PrecacheScriptSound( "Item.Pickup" );
  56. SetTouch( &CWeaponBox::BoxTouch );
  57. }
  58. void CWeaponBox::Precache( void )
  59. {
  60. PrecacheModel( WEAPONBOX_MODEL );
  61. }
  62. void CWeaponBox::BoxTouch( CBaseEntity *pOther )
  63. {
  64. if ( !( GetFlags() & FL_ONGROUND ) )
  65. {
  66. return;
  67. }
  68. if ( !pOther->IsPlayer() )
  69. {
  70. // only players may touch a weaponbox.
  71. return;
  72. }
  73. if ( !pOther->IsAlive() )
  74. {
  75. // no dead guys.
  76. return;
  77. }
  78. CBasePlayer *pPlayer = (CBasePlayer *)pOther;
  79. int i;
  80. // dole out ammo
  81. for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ )
  82. {
  83. if ( m_rgiszAmmo[ i ] != NULL_STRING )
  84. {
  85. // there's some ammo of this type.
  86. pPlayer->GiveAmmo( m_rgAmmo[ i ], (char *)STRING( m_rgiszAmmo[ i ] ) );
  87. // now empty the ammo from the weaponbox since we just gave it to the player
  88. m_rgiszAmmo[ i ] = NULL_STRING;
  89. m_rgAmmo[ i ] = 0;
  90. }
  91. }
  92. CPASAttenuationFilter filter( pOther, "Item.Pickup" );
  93. EmitSound( filter, pOther->entindex(), "Item.Pickup" );
  94. SetTouch(NULL);
  95. if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_NO )
  96. {
  97. UTIL_Remove( this );
  98. }
  99. }
  100. bool CWeaponBox::PackAmmo( char *szName, int iCount )
  101. {
  102. char szConvertedName[ 32 ];
  103. if ( FStrEq( szName, "" ) )
  104. {
  105. // error here
  106. Warning( "NULL String in PackAmmo!\n" );
  107. return false;
  108. }
  109. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "%s", szName );
  110. if ( !stricmp( szName, "bolts" ) )
  111. {
  112. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "XBowBolt" );
  113. }
  114. if ( !stricmp( szName, "uranium" ) )
  115. {
  116. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Uranium" );
  117. }
  118. if ( !stricmp( szName, "9mm" ) )
  119. {
  120. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "9mmRound" );
  121. }
  122. if ( !stricmp( szName, "Hand Grenade" ) )
  123. {
  124. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Grenade" );
  125. }
  126. if ( !stricmp( szName, "Hornets" ) )
  127. {
  128. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Hornet" );
  129. }
  130. if ( !stricmp( szName, "ARgrenades" ) )
  131. {
  132. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "MP5_Grenade" );
  133. }
  134. if ( !stricmp( szName, "357" ) )
  135. {
  136. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "357Round" );
  137. }
  138. if ( !stricmp( szName, "rockets" ) )
  139. {
  140. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "RPG_Rocket" );
  141. }
  142. if ( !stricmp( szName, "Satchel Charge" ) )
  143. {
  144. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Satchel" );
  145. }
  146. if ( !stricmp( szName, "buckshot" ) )
  147. {
  148. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Buckshot" );
  149. }
  150. if ( !stricmp( szName, "Snarks" ) )
  151. {
  152. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "Snark" );
  153. }
  154. if ( !stricmp( szName, "Trip Mine" ) )
  155. {
  156. Q_snprintf( szConvertedName, sizeof( szConvertedName ), "TripMine" );
  157. }
  158. int iMaxCarry = GetAmmoDef()->MaxCarry( GetAmmoDef()->Index( szConvertedName ) );
  159. if ( iMaxCarry > 0 && iCount > 0 )
  160. {
  161. //ALERT ( at_console, "Packed %d rounds of %s\n", iCount, STRING(iszName) );
  162. GiveAmmo( iCount, szConvertedName, iMaxCarry );
  163. return true;
  164. }
  165. return false;
  166. }
  167. //=========================================================
  168. // CWeaponBox - GiveAmmo
  169. //=========================================================
  170. int CWeaponBox::GiveAmmo( int iCount, char *szName, int iMax, int *pIndex )
  171. {
  172. int i;
  173. for ( i = 1; ( i < MAX_AMMO_SLOTS ) && ( m_rgiszAmmo[i] != NULL_STRING ); i++ )
  174. {
  175. if ( stricmp( szName, STRING( m_rgiszAmmo[i] ) ) == 0 )
  176. {
  177. if (pIndex)
  178. *pIndex = i;
  179. int iAdd = MIN( iCount, iMax - m_rgAmmo[i]);
  180. if (iCount == 0 || iAdd > 0)
  181. {
  182. m_rgAmmo[i] += iAdd;
  183. return i;
  184. }
  185. return -1;
  186. }
  187. }
  188. if (i < MAX_AMMO_SLOTS)
  189. {
  190. if (pIndex)
  191. *pIndex = i;
  192. m_rgiszAmmo[i] = AllocPooledString( szName );
  193. m_rgAmmo[i] = iCount;
  194. return i;
  195. }
  196. Warning( "out of named ammo slots\n");
  197. return i;
  198. }