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.

231 lines
9.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include <KeyValues.h>
  8. #include "tf_weapon_parse.h"
  9. #include "tf_shareddefs.h"
  10. #include "tf_playerclass_shared.h"
  11. //-----------------------------------------------------------------------------
  12. // Purpose:
  13. //-----------------------------------------------------------------------------
  14. FileWeaponInfo_t *CreateWeaponInfo()
  15. {
  16. return new CTFWeaponInfo;
  17. }
  18. //-----------------------------------------------------------------------------
  19. // Purpose:
  20. //-----------------------------------------------------------------------------
  21. CTFWeaponInfo::CTFWeaponInfo()
  22. {
  23. m_WeaponData[0].Init();
  24. m_WeaponData[1].Init();
  25. m_bGrenade = false;
  26. m_flDamageRadius = 0.0f;
  27. m_flPrimerTime = 0.0f;
  28. m_bSuppressGrenTimer = false;
  29. m_bLowerWeapon = false;
  30. m_bHasTeamSkins_Viewmodel = false;
  31. m_bHasTeamSkins_Worldmodel = false;
  32. m_szMuzzleFlashModel[0] = '\0';
  33. m_flMuzzleFlashModelDuration = 0;
  34. m_szMuzzleFlashParticleEffect[0] = '\0';
  35. m_szTracerEffect[0] = '\0';
  36. m_szBrassModel[0] = '\0';
  37. m_bDoInstantEjectBrass = true;
  38. m_szExplosionSound[0] = '\0';
  39. m_szExplosionEffect[0] = '\0';
  40. m_szExplosionPlayerEffect[0] = '\0';
  41. m_szExplosionWaterEffect[0] = '\0';
  42. m_iWeaponType = TF_WPN_TYPE_PRIMARY;
  43. }
  44. CTFWeaponInfo::~CTFWeaponInfo()
  45. {
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Purpose:
  49. //-----------------------------------------------------------------------------
  50. void CTFWeaponInfo::Parse( KeyValues *pKeyValuesData, const char *szWeaponName )
  51. {
  52. int i;
  53. BaseClass::Parse( pKeyValuesData, szWeaponName );
  54. // Primary fire mode.
  55. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_nDamage = pKeyValuesData->GetInt( "Damage", 0 );
  56. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flRange = pKeyValuesData->GetFloat( "Range", 8192.0f );
  57. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_nBulletsPerShot = pKeyValuesData->GetInt( "BulletsPerShot", 0 );
  58. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flSpread = pKeyValuesData->GetFloat( "Spread", 0.0f );
  59. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flPunchAngle = pKeyValuesData->GetFloat( "PunchAngle", 0.0f );
  60. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeFireDelay = pKeyValuesData->GetFloat( "TimeFireDelay", 0.0f );
  61. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeIdle = pKeyValuesData->GetFloat( "TimeIdle", 0.0f );
  62. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeIdleEmpty = pKeyValuesData->GetFloat( "TimeIdleEmpy", 0.0f );
  63. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeReloadStart = pKeyValuesData->GetFloat( "TimeReloadStart", 0.0f );
  64. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeReload = pKeyValuesData->GetFloat( "TimeReload", 0.0f );
  65. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_bDrawCrosshair = pKeyValuesData->GetInt( "DrawCrosshair", 1 ) > 0;
  66. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_iAmmoPerShot = pKeyValuesData->GetInt( "AmmoPerShot", 1 );
  67. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_bUseRapidFireCrits = ( pKeyValuesData->GetInt( "UseRapidFireCrits", 0 ) != 0 );
  68. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_iProjectile = TF_PROJECTILE_NONE;
  69. const char *pszProjectileType = pKeyValuesData->GetString( "ProjectileType", "projectile_none" );
  70. for ( i=0;i<TF_NUM_PROJECTILES;i++ )
  71. {
  72. if ( FStrEq( pszProjectileType, g_szProjectileNames[i] ) )
  73. {
  74. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_iProjectile = i;
  75. break;
  76. }
  77. }
  78. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flProjectileSpeed = pKeyValuesData->GetFloat( "ProjectileSpeed", 0.0f );
  79. m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flSmackDelay = pKeyValuesData->GetFloat( "SmackDelay", 0.2f );
  80. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flSmackDelay = pKeyValuesData->GetFloat( "Secondary_SmackDelay", 0.2f );
  81. m_bDoInstantEjectBrass = ( pKeyValuesData->GetInt( "DoInstantEjectBrass", 1 ) != 0 );
  82. const char *pszBrassModel = pKeyValuesData->GetString( "BrassModel", NULL );
  83. if ( pszBrassModel )
  84. {
  85. Q_strncpy( m_szBrassModel, pszBrassModel, sizeof( m_szBrassModel ) );
  86. }
  87. // Secondary fire mode.
  88. // Inherit from primary fire mode
  89. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_nDamage = pKeyValuesData->GetInt( "Secondary_Damage", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_nDamage );
  90. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flRange = pKeyValuesData->GetFloat( "Secondary_Range", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flRange );
  91. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_nBulletsPerShot = pKeyValuesData->GetInt( "Secondary_BulletsPerShot", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_nBulletsPerShot );
  92. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flSpread = pKeyValuesData->GetFloat( "Secondary_Spread", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flSpread );
  93. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flPunchAngle = pKeyValuesData->GetFloat( "Secondary_PunchAngle", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flPunchAngle );
  94. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flTimeFireDelay = pKeyValuesData->GetFloat( "Secondary_TimeFireDelay", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeFireDelay );
  95. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flTimeIdle = pKeyValuesData->GetFloat( "Secondary_TimeIdle", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeIdle );
  96. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flTimeIdleEmpty = pKeyValuesData->GetFloat( "Secondary_TimeIdleEmpy", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeIdleEmpty );
  97. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flTimeReloadStart = pKeyValuesData->GetFloat( "Secondary_TimeReloadStart", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeReloadStart );
  98. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_flTimeReload = pKeyValuesData->GetFloat( "Secondary_TimeReload", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_flTimeReload );
  99. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_bDrawCrosshair = pKeyValuesData->GetInt( "Secondary_DrawCrosshair", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_bDrawCrosshair ) > 0;
  100. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_iAmmoPerShot = pKeyValuesData->GetInt( "Secondary_AmmoPerShot", m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_iAmmoPerShot );
  101. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_bUseRapidFireCrits = ( pKeyValuesData->GetInt( "Secondary_UseRapidFireCrits", 0 ) != 0 );
  102. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_iProjectile = m_WeaponData[TF_WEAPON_PRIMARY_MODE].m_iProjectile;
  103. pszProjectileType = pKeyValuesData->GetString( "Secondary_ProjectileType", "projectile_none" );
  104. for ( i=0;i<TF_NUM_PROJECTILES;i++ )
  105. {
  106. if ( FStrEq( pszProjectileType, g_szProjectileNames[i] ) )
  107. {
  108. m_WeaponData[TF_WEAPON_SECONDARY_MODE].m_iProjectile = i;
  109. break;
  110. }
  111. }
  112. const char *pszWeaponType = pKeyValuesData->GetString( "WeaponType" );
  113. if ( !Q_strcmp( pszWeaponType, "primary" ) )
  114. {
  115. m_iWeaponType = TF_WPN_TYPE_PRIMARY;
  116. }
  117. else if ( !Q_strcmp( pszWeaponType, "secondary" ) )
  118. {
  119. m_iWeaponType = TF_WPN_TYPE_SECONDARY;
  120. }
  121. else if ( !Q_strcmp( pszWeaponType, "melee" ) )
  122. {
  123. m_iWeaponType = TF_WPN_TYPE_MELEE;
  124. }
  125. else if ( !Q_strcmp( pszWeaponType, "grenade" ) )
  126. {
  127. m_iWeaponType = TF_WPN_TYPE_GRENADE;
  128. }
  129. else if ( !Q_strcmp( pszWeaponType, "building" ) )
  130. {
  131. m_iWeaponType = TF_WPN_TYPE_BUILDING;
  132. }
  133. else if ( !Q_strcmp( pszWeaponType, "pda" ) )
  134. {
  135. m_iWeaponType = TF_WPN_TYPE_PDA;
  136. }
  137. else if ( !Q_strcmp( pszWeaponType, "item1" ) )
  138. {
  139. m_iWeaponType = TF_WPN_TYPE_ITEM1;
  140. }
  141. else if ( !Q_strcmp( pszWeaponType, "item2" ) )
  142. {
  143. m_iWeaponType = TF_WPN_TYPE_ITEM2;
  144. }
  145. // Grenade data.
  146. m_bGrenade = ( pKeyValuesData->GetInt( "Grenade", 0 ) != 0 );
  147. m_flDamageRadius = pKeyValuesData->GetFloat( "DamageRadius", 0.0f );
  148. m_flPrimerTime = pKeyValuesData->GetFloat( "PrimerTime", 0.0f );
  149. m_bSuppressGrenTimer = ( pKeyValuesData->GetInt( "PlayGrenTimer", 1 ) <= 0 );
  150. m_bLowerWeapon = ( pKeyValuesData->GetInt( "LowerMainWeapon", 0 ) != 0 );
  151. m_bHasTeamSkins_Viewmodel = ( pKeyValuesData->GetInt( "HasTeamSkins_Viewmodel", 0 ) != 0 );
  152. m_bHasTeamSkins_Worldmodel = ( pKeyValuesData->GetInt( "HasTeamSkins_Worldmodel", 0 ) != 0 );
  153. // Model muzzleflash
  154. const char *pszMuzzleFlashModel = pKeyValuesData->GetString( "MuzzleFlashModel", NULL );
  155. if ( pszMuzzleFlashModel )
  156. {
  157. Q_strncpy( m_szMuzzleFlashModel, pszMuzzleFlashModel, sizeof( m_szMuzzleFlashModel ) );
  158. }
  159. m_flMuzzleFlashModelDuration = pKeyValuesData->GetFloat( "MuzzleFlashModelDuration", 0.2 );
  160. const char *pszMuzzleFlashParticleEffect = pKeyValuesData->GetString( "MuzzleFlashParticleEffect", NULL );
  161. if ( pszMuzzleFlashParticleEffect )
  162. {
  163. Q_strncpy( m_szMuzzleFlashParticleEffect, pszMuzzleFlashParticleEffect, sizeof( m_szMuzzleFlashParticleEffect ) );
  164. }
  165. // Tracer particle effect
  166. const char *pszTracerEffect = pKeyValuesData->GetString( "TracerEffect", NULL );
  167. if ( pszTracerEffect )
  168. {
  169. Q_strncpy( m_szTracerEffect, pszTracerEffect, sizeof( m_szTracerEffect ) );
  170. }
  171. // Explosion effects (used for grenades)
  172. const char *pszSound = pKeyValuesData->GetString( "ExplosionSound", NULL );
  173. if ( pszSound )
  174. {
  175. Q_strncpy( m_szExplosionSound, pszSound, sizeof( m_szExplosionSound ) );
  176. }
  177. const char *pszEffect = pKeyValuesData->GetString( "ExplosionEffect", NULL );
  178. if ( pszEffect )
  179. {
  180. Q_strncpy( m_szExplosionEffect, pszEffect, sizeof( m_szExplosionEffect ) );
  181. }
  182. pszEffect = pKeyValuesData->GetString( "ExplosionPlayerEffect", NULL );
  183. if ( pszEffect )
  184. {
  185. Q_strncpy( m_szExplosionPlayerEffect, pszEffect, sizeof( m_szExplosionPlayerEffect ) );
  186. }
  187. pszEffect = pKeyValuesData->GetString( "ExplosionWaterEffect", NULL );
  188. if ( pszEffect )
  189. {
  190. Q_strncpy( m_szExplosionWaterEffect, pszEffect, sizeof( m_szExplosionWaterEffect ) );
  191. }
  192. m_bDontDrop = ( pKeyValuesData->GetInt( "DontDrop", 0 ) > 0 );
  193. }