Counter Strike : Global Offensive Source Code
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.

1269 lines
35 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements visual effects entities: sprites, beams, bubbles, etc.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "beam_shared.h"
  9. #include "decals.h"
  10. #include "model_types.h"
  11. #include "IEffects.h"
  12. #include "util_shared.h"
  13. #if !defined( CLIENT_DLL )
  14. #include "ndebugoverlay.h"
  15. #include "sendproxy.h"
  16. #else
  17. #include "iviewrender_beams.h"
  18. #include "c_pixel_visibility.h"
  19. #include "iclientmode.h"
  20. #include "viewrender.h"
  21. #include "view.h"
  22. #include "toolframework_client.h"
  23. #endif
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include "tier0/memdbgon.h"
  26. #define BEAM_DEFAULT_HALO_SCALE 10
  27. #if !defined( CLIENT_DLL )
  28. //-----------------------------------------------------------------------------
  29. // info targets are like point entities except you can force them to spawn on the client
  30. //-----------------------------------------------------------------------------
  31. class CInfoTarget : public CPointEntity
  32. {
  33. public:
  34. DECLARE_CLASS( CInfoTarget, CPointEntity );
  35. void Spawn( void );
  36. virtual int UpdateTransmitState();
  37. };
  38. //-----------------------------------------------------------------------------
  39. // Force transmission
  40. //-----------------------------------------------------------------------------
  41. void CInfoTarget::Spawn( void )
  42. {
  43. BaseClass::Spawn();
  44. if ( HasSpawnFlags(0x01) )
  45. {
  46. SetEFlags( EFL_FORCE_CHECK_TRANSMIT );
  47. }
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Purpose: Always transmitted to clients
  51. //-----------------------------------------------------------------------------
  52. int CInfoTarget::UpdateTransmitState()
  53. {
  54. // Spawn flags 2 means we always transmit
  55. if ( HasSpawnFlags(0x02) )
  56. return SetTransmitState( FL_EDICT_ALWAYS );
  57. return BaseClass::UpdateTransmitState();
  58. }
  59. LINK_ENTITY_TO_CLASS( info_target, CInfoTarget );
  60. #endif
  61. //-----------------------------------------------------------------------------
  62. // Purpose: Returns true if the given entity is a fixed target for lightning.
  63. //-----------------------------------------------------------------------------
  64. bool IsStaticPointEntity( CBaseEntity *pEnt )
  65. {
  66. if ( pEnt->GetMoveParent() )
  67. return false;
  68. if ( !pEnt->GetModelIndex() )
  69. return 1;
  70. if ( FClassnameIs( pEnt, "info_target" ) || FClassnameIs( pEnt, "info_landmark" ) ||
  71. FClassnameIs( pEnt, "path_corner" ) )
  72. return true;
  73. return false;
  74. }
  75. #if defined( CLIENT_DLL )
  76. extern bool ComputeBeamEntPosition( CBaseEntity *pEnt, int nAttachment, bool bInterpretAttachmentIndexAsHitboxIndex, Vector& pt );
  77. extern void RecvProxy_ClrRender( const CRecvProxyData *pData, void *pStruct, void *pOut );
  78. void RecvProxy_Beam_ScrollSpeed( const CRecvProxyData *pData, void *pStruct, void *pOut )
  79. {
  80. C_Beam *beam;
  81. float val;
  82. // Unpack the data.
  83. val = pData->m_Value.m_Float;
  84. val *= 0.1;
  85. beam = ( C_Beam * )pStruct;
  86. Assert( pOut == &beam->m_fSpeed );
  87. beam->m_fSpeed = val;
  88. }
  89. #else
  90. #if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID )
  91. static void* SendProxy_SendPredictableId( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID )
  92. {
  93. CBaseEntity *pEntity = (CBaseEntity *)pStruct;
  94. if ( !pEntity || !pEntity->m_PredictableID->IsActive() )
  95. return NULL;
  96. if ( !pEntity->GetOwnerEntity() )
  97. return NULL;
  98. CBaseEntity *owner = pEntity->GetOwnerEntity();
  99. if ( !owner || !owner->IsPlayer() )
  100. return NULL;
  101. CBasePlayer *pOwner = static_cast< CBasePlayer * >( owner );
  102. if ( !pOwner )
  103. return NULL;
  104. int id_player_index = pEntity->m_PredictableID->GetPlayer();
  105. int owner_player_index = pOwner->entindex() - 1;
  106. // Only send to owner player
  107. // FIXME: Is this ever not the case due to the SetOnly call?
  108. if ( id_player_index != owner_player_index )
  109. return NULL;
  110. pRecipients->SetOnly( owner_player_index );
  111. return ( void * )pVarData;
  112. }
  113. REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendPredictableId );
  114. #endif
  115. #endif
  116. // This table encodes the CBeam data.
  117. IMPLEMENT_NETWORKCLASS_ALIASED( Beam, DT_Beam )
  118. LINK_ENTITY_TO_CLASS_ALIASED( beam, Beam );
  119. #if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID )
  120. BEGIN_NETWORK_TABLE_NOBASE( CBeam, DT_BeamPredictableId )
  121. #if !defined( CLIENT_DLL )
  122. SendPropPredictableId( SENDINFO( m_PredictableID ) ),
  123. SendPropInt( SENDINFO( m_bIsPlayerSimulated ), 1, SPROP_UNSIGNED ),
  124. #else
  125. RecvPropPredictableId( RECVINFO( m_PredictableID ) ),
  126. RecvPropInt( RECVINFO( m_bIsPlayerSimulated ) ),
  127. #endif
  128. END_NETWORK_TABLE()
  129. #endif
  130. BEGIN_NETWORK_TABLE_NOBASE( CBeam, DT_Beam )
  131. #if !defined( CLIENT_DLL )
  132. SendPropInt (SENDINFO(m_nBeamType), Q_log2(NUM_BEAM_TYPES)+1, SPROP_UNSIGNED ),
  133. SendPropInt (SENDINFO(m_nBeamFlags), NUM_BEAM_FLAGS, SPROP_UNSIGNED ),
  134. SendPropInt (SENDINFO(m_nNumBeamEnts ), 5, SPROP_UNSIGNED ),
  135. SendPropArray3
  136. (
  137. SENDINFO_ARRAY3(m_hAttachEntity),
  138. SendPropEHandle( SENDINFO_ARRAY(m_hAttachEntity) )
  139. ),
  140. SendPropArray3
  141. (
  142. SENDINFO_ARRAY3(m_nAttachIndex),
  143. SendPropInt( SENDINFO_ARRAY(m_nAttachIndex), ATTACHMENT_INDEX_BITS, SPROP_UNSIGNED)
  144. ),
  145. SendPropInt (SENDINFO(m_nHaloIndex), 16, SPROP_UNSIGNED ),
  146. SendPropFloat (SENDINFO(m_fHaloScale), 0, SPROP_NOSCALE ),
  147. SendPropFloat (SENDINFO(m_fWidth), 10, SPROP_ROUNDUP, 0.0f, MAX_BEAM_WIDTH ),
  148. SendPropFloat (SENDINFO(m_fEndWidth), 10, SPROP_ROUNDUP, 0.0f, MAX_BEAM_WIDTH ),
  149. SendPropFloat (SENDINFO(m_fFadeLength), 0, SPROP_NOSCALE ),
  150. SendPropFloat (SENDINFO(m_fAmplitude), 8, SPROP_ROUNDDOWN, 0.0f, MAX_BEAM_NOISEAMPLITUDE ),
  151. SendPropFloat (SENDINFO(m_fStartFrame), 8, SPROP_ROUNDDOWN, 0.0f, 256.0f),
  152. SendPropFloat (SENDINFO(m_fSpeed), 8, SPROP_NOSCALE, 0.0f, MAX_BEAM_SCROLLSPEED),
  153. SendPropInt (SENDINFO(m_nRenderFX), 8, SPROP_UNSIGNED ),
  154. SendPropInt (SENDINFO(m_nRenderMode), 8, SPROP_UNSIGNED ),
  155. SendPropFloat (SENDINFO(m_flFrameRate), 10, SPROP_ROUNDUP, -25.0f, 25.0f ),
  156. SendPropFloat (SENDINFO(m_flHDRColorScale), 0, SPROP_NOSCALE, 0.0f, 100.0f ),
  157. SendPropFloat (SENDINFO(m_flFrame), 20, SPROP_ROUNDDOWN | SPROP_CHANGES_OFTEN, 0.0f, 256.0f),
  158. SendPropInt (SENDINFO(m_clrRender), 32, SPROP_UNSIGNED | SPROP_CHANGES_OFTEN, SendProxy_Color32ToInt32 ),
  159. SendPropInt (SENDINFO(m_nClipStyle), CBeam::kBEAMCLIPSTYLE_NUMBITS+1, SPROP_UNSIGNED ),
  160. SendPropVector (SENDINFO(m_vecEndPos), -1, SPROP_COORD ),
  161. SendPropModelIndex(SENDINFO(m_nModelIndex) ),
  162. SendPropVector (SENDINFO(m_vecOrigin), 19, SPROP_CHANGES_OFTEN, MIN_COORD_INTEGER, MAX_COORD_INTEGER),
  163. SendPropEHandle(SENDINFO_NAME(m_hMoveParent, moveparent) ),
  164. #if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID )
  165. SendPropDataTable( "beampredictable_id", 0, &REFERENCE_SEND_TABLE( DT_BeamPredictableId ), SendProxy_SendPredictableId ),
  166. #endif
  167. #else
  168. RecvPropInt (RECVINFO(m_nBeamType)),
  169. RecvPropInt (RECVINFO(m_nBeamFlags)),
  170. RecvPropInt (RECVINFO(m_nNumBeamEnts)),
  171. RecvPropArray3
  172. (
  173. RECVINFO_ARRAY( m_hAttachEntity ),
  174. RecvPropEHandle (RECVINFO(m_hAttachEntity[0]))
  175. ),
  176. RecvPropArray3
  177. (
  178. RECVINFO_ARRAY( m_nAttachIndex ),
  179. RecvPropInt (RECVINFO(m_nAttachIndex[0]))
  180. ),
  181. RecvPropInt (RECVINFO(m_nHaloIndex)),
  182. RecvPropFloat (RECVINFO(m_fHaloScale)),
  183. RecvPropFloat (RECVINFO(m_fWidth)),
  184. RecvPropFloat (RECVINFO(m_fEndWidth)),
  185. RecvPropFloat (RECVINFO(m_fFadeLength)),
  186. RecvPropFloat (RECVINFO(m_fAmplitude)),
  187. RecvPropFloat (RECVINFO(m_fStartFrame)),
  188. RecvPropFloat (RECVINFO(m_fSpeed), 0, RecvProxy_Beam_ScrollSpeed ),
  189. RecvPropFloat(RECVINFO(m_flFrameRate)),
  190. RecvPropFloat(RECVINFO(m_flHDRColorScale)),
  191. RecvPropInt(RECVINFO(m_clrRender), 0, RecvProxy_ClrRender ),
  192. RecvPropInt(RECVINFO(m_nRenderFX)),
  193. RecvPropInt(RECVINFO(m_nRenderMode)),
  194. RecvPropFloat(RECVINFO(m_flFrame)),
  195. RecvPropInt(RECVINFO(m_nClipStyle)),
  196. RecvPropVector(RECVINFO(m_vecEndPos)),
  197. RecvPropInt(RECVINFO(m_nModelIndex)),
  198. RecvPropVector(RECVINFO_NAME(m_vecNetworkOrigin, m_vecOrigin)),
  199. RecvPropInt( RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent ),
  200. #if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID )
  201. RecvPropDataTable( "beampredictable_id", 0, 0, &REFERENCE_RECV_TABLE( DT_BeamPredictableId ) ),
  202. #endif
  203. #endif
  204. END_NETWORK_TABLE()
  205. #if !defined( CLIENT_DLL )
  206. BEGIN_DATADESC( CBeam )
  207. DEFINE_FIELD( m_nHaloIndex, FIELD_MODELINDEX ),
  208. DEFINE_FIELD( m_nBeamType, FIELD_INTEGER ),
  209. DEFINE_FIELD( m_nBeamFlags, FIELD_INTEGER ),
  210. DEFINE_FIELD( m_nNumBeamEnts, FIELD_INTEGER ),
  211. DEFINE_ARRAY( m_hAttachEntity, FIELD_EHANDLE, MAX_BEAM_ENTS ),
  212. DEFINE_ARRAY( m_nAttachIndex, FIELD_INTEGER, MAX_BEAM_ENTS ),
  213. DEFINE_FIELD( m_fWidth, FIELD_FLOAT ),
  214. DEFINE_FIELD( m_fEndWidth, FIELD_FLOAT ),
  215. DEFINE_FIELD( m_fFadeLength, FIELD_FLOAT ),
  216. DEFINE_FIELD( m_fHaloScale, FIELD_FLOAT ),
  217. DEFINE_FIELD( m_fAmplitude, FIELD_FLOAT ),
  218. DEFINE_FIELD( m_fStartFrame, FIELD_FLOAT ),
  219. DEFINE_FIELD( m_fSpeed, FIELD_FLOAT ),
  220. DEFINE_FIELD( m_flFrameRate, FIELD_FLOAT ),
  221. DEFINE_FIELD( m_flFrame, FIELD_FLOAT ),
  222. DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ),
  223. DEFINE_KEYFIELD( m_flDamage, FIELD_FLOAT, "damage" ),
  224. DEFINE_FIELD( m_flFireTime, FIELD_TIME ),
  225. DEFINE_FIELD( m_vecEndPos, FIELD_POSITION_VECTOR ),
  226. DEFINE_FIELD( m_hEndEntity, FIELD_EHANDLE ),
  227. DEFINE_KEYFIELD( m_nDissolveType, FIELD_INTEGER, "dissolvetype" ),
  228. // Inputs
  229. DEFINE_INPUTFUNC( FIELD_FLOAT, "Width", InputWidth ),
  230. DEFINE_INPUTFUNC( FIELD_FLOAT, "Noise", InputNoise ),
  231. DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorRedValue", InputColorRedValue ),
  232. DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorGreenValue", InputColorGreenValue ),
  233. DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorBlueValue", InputColorBlueValue ),
  234. DEFINE_INPUT( m_fSpeed, FIELD_FLOAT, "ScrollSpeed" ),
  235. // don't save this
  236. //DEFINE_FIELD( m_queryHandleHalo, FIELD_ ),
  237. END_DATADESC()
  238. #else
  239. BEGIN_PREDICTION_DATA( CBeam )
  240. DEFINE_PRED_FIELD( m_nBeamType, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  241. DEFINE_PRED_FIELD( m_nNumBeamEnts, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  242. DEFINE_PRED_ARRAY( m_hAttachEntity, FIELD_EHANDLE, MAX_BEAM_ENTS, FTYPEDESC_INSENDTABLE ),
  243. DEFINE_PRED_ARRAY( m_nAttachIndex, FIELD_INTEGER, MAX_BEAM_ENTS, FTYPEDESC_INSENDTABLE ),
  244. DEFINE_PRED_FIELD( m_nHaloIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  245. DEFINE_PRED_FIELD( m_fHaloScale, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  246. DEFINE_PRED_FIELD( m_fWidth, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  247. DEFINE_PRED_FIELD( m_fEndWidth, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  248. DEFINE_PRED_FIELD( m_fFadeLength, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  249. DEFINE_PRED_FIELD( m_fAmplitude, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  250. DEFINE_PRED_FIELD( m_fStartFrame, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  251. DEFINE_PRED_FIELD( m_fSpeed, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  252. DEFINE_PRED_FIELD( m_nRenderFX, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  253. DEFINE_PRED_FIELD( m_nRenderMode, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  254. DEFINE_PRED_FIELD( m_flFrameRate, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  255. DEFINE_PRED_FIELD( m_flFrame, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  256. DEFINE_PRED_FIELD( m_clrRender, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  257. DEFINE_PRED_FIELD_TOL( m_vecEndPos, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.125f ),
  258. DEFINE_PRED_FIELD( m_nModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
  259. DEFINE_PRED_FIELD_TOL( m_vecOrigin, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.125f ),
  260. //DEFINE_PRED_FIELD( m_pMoveParent, SendProxy_MoveParent ),
  261. //DEFINE_PRED_FIELD( m_flHDRColorScale, SendProxy_HDRColorScale ),
  262. END_PREDICTION_DATA()
  263. #endif
  264. //-----------------------------------------------------------------------------
  265. // Purpose:
  266. //-----------------------------------------------------------------------------
  267. CBeam::CBeam( void )
  268. {
  269. #ifdef _DEBUG
  270. // necessary since in debug, we initialize vectors to NAN for debugging
  271. m_vecEndPos.Init();
  272. #endif
  273. m_flHDRColorScale = 1.0f; // default value.
  274. #if !defined( CLIENT_DLL )
  275. m_nDissolveType = -1;
  276. #else
  277. m_queryHandleHalo = 0;
  278. AddToEntityList(ENTITY_LIST_SIMULATE);
  279. #endif
  280. }
  281. //-----------------------------------------------------------------------------
  282. // Purpose:
  283. // Input : *szModelName -
  284. //-----------------------------------------------------------------------------
  285. void CBeam::SetModel( const char *szModelName )
  286. {
  287. int modelIndex = modelinfo->GetModelIndex( szModelName );
  288. const model_t *model = modelinfo->GetModel( modelIndex );
  289. if ( model && modelinfo->GetModelType( model ) != mod_sprite )
  290. {
  291. Msg( "Setting CBeam to non-sprite model %s\n", szModelName );
  292. }
  293. #if !defined( CLIENT_DLL )
  294. UTIL_SetModel( this, szModelName );
  295. #else
  296. BaseClass::SetModel( szModelName );
  297. #endif
  298. }
  299. void CBeam::Spawn( void )
  300. {
  301. SetMoveType( MOVETYPE_NONE );
  302. SetSolid( SOLID_NONE ); // Remove model & collisions
  303. SetRenderMode( kRenderTransTexture );
  304. // Opt out of all shadow routines
  305. // Beams are highly visible; always render these into reflection buffer even when using fast reflection
  306. AddEffects( EF_NOSHADOW | EF_NORECEIVESHADOW | EF_MARKED_FOR_FAST_REFLECTION );
  307. Precache( );
  308. }
  309. void CBeam::Precache( void )
  310. {
  311. if ( GetOwnerEntity() )
  312. {
  313. SetStartEntity( GetOwnerEntity() );
  314. }
  315. if ( m_hEndEntity.Get() )
  316. {
  317. SetEndEntity( m_hEndEntity );
  318. }
  319. }
  320. void CBeam::SetType( int type )
  321. {
  322. Assert( type < NUM_BEAM_TYPES );
  323. m_nBeamType = type;
  324. }
  325. void CBeam::SetBeamFlags( int flags )
  326. {
  327. Assert( flags < (1 << NUM_BEAM_FLAGS) );
  328. m_nBeamFlags = flags;
  329. }
  330. void CBeam::SetBeamFlag( int flag )
  331. {
  332. m_nBeamFlags |= flag;
  333. }
  334. int CBeam::GetType( void ) const
  335. {
  336. return m_nBeamType;
  337. }
  338. int CBeam::GetBeamFlags( void ) const
  339. {
  340. return m_nBeamFlags;
  341. }
  342. void CBeam::SetStartEntity( CBaseEntity *pEntity )
  343. {
  344. Assert( m_nNumBeamEnts >= 2 );
  345. m_hAttachEntity.Set( 0, pEntity );
  346. SetOwnerEntity( pEntity );
  347. RelinkBeam();
  348. if ( pEntity )
  349. {
  350. pEntity->AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
  351. }
  352. }
  353. void CBeam::SetEndEntity( CBaseEntity *pEntity )
  354. {
  355. Assert( m_nNumBeamEnts >= 2 );
  356. m_hAttachEntity.Set( m_nNumBeamEnts-1, pEntity );
  357. m_hEndEntity = pEntity;
  358. RelinkBeam();
  359. if ( pEntity )
  360. {
  361. pEntity->AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
  362. }
  363. }
  364. //-----------------------------------------------------------------------------
  365. // This will change things so the abs position matches the requested spot
  366. //-----------------------------------------------------------------------------
  367. void CBeam::SetAbsStartPos( const Vector &pos )
  368. {
  369. if (!GetMoveParent())
  370. {
  371. SetStartPos( pos );
  372. return;
  373. }
  374. Vector vecLocalPos;
  375. matrix3x4_t worldToBeam;
  376. MatrixInvert( EntityToWorldTransform(), worldToBeam );
  377. VectorTransform( pos, worldToBeam, vecLocalPos );
  378. SetStartPos( vecLocalPos );
  379. }
  380. void CBeam::SetAbsEndPos( const Vector &pos )
  381. {
  382. if (!GetMoveParent())
  383. {
  384. SetEndPos( pos );
  385. return;
  386. }
  387. Vector vecLocalPos;
  388. matrix3x4_t worldToBeam;
  389. MatrixInvert( EntityToWorldTransform(), worldToBeam );
  390. VectorTransform( pos, worldToBeam, vecLocalPos );
  391. SetEndPos( vecLocalPos );
  392. }
  393. #if !defined( CLIENT_DLL )
  394. // These don't take attachments into account
  395. const Vector &CBeam::GetAbsStartPos( void ) const
  396. {
  397. if ( GetType() == BEAM_ENTS && GetStartEntity() )
  398. {
  399. edict_t *pent = INDEXENT( GetStartEntity() );
  400. CBaseEntity *ent = CBaseEntity::Instance( pent );
  401. if ( !ent )
  402. {
  403. return GetAbsOrigin();
  404. }
  405. return ent->GetAbsOrigin();
  406. }
  407. return GetAbsOrigin();
  408. }
  409. const Vector &CBeam::GetAbsEndPos( void ) const
  410. {
  411. if ( GetType() != BEAM_POINTS && GetType() != BEAM_HOSE && GetEndEntity() )
  412. {
  413. edict_t *pent = INDEXENT( GetEndEntity() );
  414. CBaseEntity *ent = CBaseEntity::Instance( pent );
  415. if ( ent )
  416. return ent->GetAbsOrigin();
  417. }
  418. if (!const_cast<CBeam*>(this)->GetMoveParent())
  419. return m_vecEndPos.Get();
  420. // FIXME: Cache this off?
  421. static Vector vecAbsPos;
  422. VectorTransform( m_vecEndPos, EntityToWorldTransform(), vecAbsPos );
  423. return vecAbsPos;
  424. }
  425. #else
  426. //-----------------------------------------------------------------------------
  427. // Unlike the server, these take attachments into account
  428. //-----------------------------------------------------------------------------
  429. const Vector &C_Beam::GetAbsStartPos( void ) const
  430. {
  431. static Vector vecStartAbsPosition;
  432. if ( GetType() != BEAM_POINTS && GetType() != BEAM_HOSE )
  433. {
  434. if (ComputeBeamEntPosition( m_hAttachEntity[0], m_nAttachIndex[0], false, vecStartAbsPosition ))
  435. return vecStartAbsPosition;
  436. }
  437. return GetAbsOrigin();
  438. }
  439. const Vector &C_Beam::GetAbsEndPos( void ) const
  440. {
  441. static Vector vecEndAbsPosition;
  442. if ( GetType() != BEAM_POINTS && GetType() != BEAM_HOSE )
  443. {
  444. if (ComputeBeamEntPosition( m_hAttachEntity[m_nNumBeamEnts-1], m_nAttachIndex[m_nNumBeamEnts-1], false, vecEndAbsPosition ))
  445. return vecEndAbsPosition;
  446. }
  447. if (!const_cast<C_Beam*>(this)->GetMoveParent())
  448. return m_vecEndPos.Get();
  449. // FIXME: Cache this off?
  450. VectorTransform( m_vecEndPos, EntityToWorldTransform(), vecEndAbsPosition );
  451. return vecEndAbsPosition;
  452. }
  453. #endif
  454. CBeam *CBeam::BeamCreate( const char *pSpriteName, float width )
  455. {
  456. // Create a new entity with CBeam private data
  457. CBeam *pBeam = CREATE_ENTITY( CBeam, "beam" );
  458. pBeam->BeamInit( pSpriteName, width );
  459. return pBeam;
  460. }
  461. //-----------------------------------------------------------------------------
  462. // Purpose:
  463. // Input : *pSpriteName -
  464. // &origin -
  465. // animate -
  466. // Output : CSprite
  467. //-----------------------------------------------------------------------------
  468. CBeam *CBeam::BeamCreatePredictable( const char *module, int line, bool persist, const char *pSpriteName, float width, CBasePlayer *pOwner )
  469. {
  470. #if !defined( NO_ENTITY_PREDICTION )
  471. CBeam *pBeam = ( CBeam * )CBaseEntity::CreatePredictedEntityByName( "beam", module, line, persist );
  472. if ( pBeam )
  473. {
  474. pBeam->BeamInit( pSpriteName, width );
  475. pBeam->SetOwnerEntity( pOwner );
  476. pBeam->SetPlayerSimulated( pOwner );
  477. }
  478. return pBeam;
  479. #else
  480. return NULL;
  481. #endif
  482. }
  483. void CBeam::BeamInit( const char *pSpriteName, float width )
  484. {
  485. SetColor( 255, 255, 255 );
  486. SetBrightness( 255 );
  487. SetNoise( 0 );
  488. SetFrame( 0 );
  489. SetScrollRate( 0 );
  490. SetModelName( MAKE_STRING( pSpriteName ) );
  491. SetRenderMode( kRenderTransTexture );
  492. SetTexture( PrecacheModel( pSpriteName ) );
  493. SetWidth( width );
  494. SetEndWidth( width );
  495. SetFadeLength( 0 ); // No fade
  496. Spawn();
  497. for (int i=0;i<MAX_BEAM_ENTS;i++)
  498. {
  499. m_hAttachEntity.Set( i, INVALID_EHANDLE );
  500. m_nAttachIndex.Set( i, 0 );
  501. }
  502. m_nHaloIndex = 0;
  503. m_fHaloScale = BEAM_DEFAULT_HALO_SCALE;
  504. m_nBeamType = 0;
  505. m_nBeamFlags = 0;
  506. }
  507. void CBeam::PointsInit( const Vector &start, const Vector &end )
  508. {
  509. SetType( BEAM_POINTS );
  510. m_nNumBeamEnts = 2;
  511. SetStartPos( start );
  512. SetEndPos( end );
  513. SetStartAttachment( 0 );
  514. SetEndAttachment( 0 );
  515. RelinkBeam();
  516. }
  517. void CBeam::HoseInit( const Vector &start, const Vector &direction )
  518. {
  519. SetType( BEAM_HOSE );
  520. m_nNumBeamEnts = 2;
  521. SetStartPos( start );
  522. SetEndPos( direction );
  523. SetStartAttachment( 0 );
  524. SetEndAttachment( 0 );
  525. RelinkBeam();
  526. }
  527. void CBeam::PointEntInit( const Vector &start, CBaseEntity *pEndEntity )
  528. {
  529. SetType( BEAM_ENTPOINT );
  530. m_nNumBeamEnts = 2;
  531. SetStartPos( start );
  532. SetEndEntity( pEndEntity );
  533. SetStartAttachment( 0 );
  534. SetEndAttachment( 0 );
  535. RelinkBeam();
  536. }
  537. void CBeam::EntsInit( CBaseEntity *pStartEntity, CBaseEntity *pEndEntity )
  538. {
  539. SetType( BEAM_ENTS );
  540. m_nNumBeamEnts = 2;
  541. SetStartEntity( pStartEntity );
  542. SetEndEntity( pEndEntity );
  543. SetStartAttachment( 0 );
  544. SetEndAttachment( 0 );
  545. RelinkBeam();
  546. }
  547. void CBeam::LaserInit( CBaseEntity *pStartEntity, CBaseEntity *pEndEntity )
  548. {
  549. SetType( BEAM_LASER );
  550. m_nNumBeamEnts = 2;
  551. SetStartEntity( pStartEntity );
  552. SetEndEntity( pEndEntity );
  553. SetStartAttachment( 0 );
  554. SetEndAttachment( 0 );
  555. RelinkBeam();
  556. }
  557. void CBeam::SplineInit( int nNumEnts, CBaseEntity** pEntList, int *attachment )
  558. {
  559. if (nNumEnts < 2)
  560. {
  561. Msg("ERROR: Min of 2 ents required for spline beam.\n");
  562. }
  563. else if (nNumEnts > MAX_BEAM_ENTS)
  564. {
  565. Msg("ERROR: Max of %i ents allowed for spline beam.\n",MAX_BEAM_ENTS);
  566. }
  567. SetType( BEAM_SPLINE );
  568. for (int i=0;i<nNumEnts;i++)
  569. {
  570. m_hAttachEntity.Set( i, pEntList[i] );
  571. m_nAttachIndex.Set( i, attachment[i] );
  572. }
  573. m_nNumBeamEnts = nNumEnts;
  574. RelinkBeam();
  575. }
  576. void CBeam::RelinkBeam( void )
  577. {
  578. // FIXME: Why doesn't this just define the absbox too?
  579. // It seems that we don't need to recompute the absbox
  580. // in CBaseEntity::SetObjectCollisionBox, in fact the absbox
  581. // computed there seems way too big
  582. Vector startPos = GetAbsStartPos(), endPos = GetAbsEndPos();
  583. // UNDONE: Should we do this to make the boxes smaller?
  584. //SetAbsOrigin( startPos );
  585. Vector vecBeamMin, vecBeamMax;
  586. VectorMin( startPos, endPos, vecBeamMin );
  587. VectorMax( startPos, endPos, vecBeamMax );
  588. SetCollisionBounds( vecBeamMin - GetAbsOrigin(), vecBeamMax - GetAbsOrigin() );
  589. }
  590. CBaseEntity *CBeam::RandomTargetname( const char *szName )
  591. {
  592. #if !defined( CLIENT_DLL )
  593. int total = 0;
  594. CBaseEntity *pEntity = NULL;
  595. CBaseEntity *pNewEntity = NULL;
  596. while ((pNewEntity = gEntList.FindEntityByName( pNewEntity, szName )) != NULL)
  597. {
  598. total++;
  599. if (random->RandomInt(0,total-1) < 1)
  600. pEntity = pNewEntity;
  601. }
  602. return pEntity;
  603. #else
  604. return NULL;
  605. #endif
  606. }
  607. void CBeam::DoSparks( const Vector &start, const Vector &end )
  608. {
  609. #if !defined( CLIENT_DLL )
  610. if ( HasSpawnFlags(SF_BEAM_SPARKSTART|SF_BEAM_SPARKEND) )
  611. {
  612. if ( HasSpawnFlags( SF_BEAM_SPARKSTART ) )
  613. {
  614. g_pEffects->Sparks( start );
  615. }
  616. if ( HasSpawnFlags( SF_BEAM_SPARKEND ) )
  617. {
  618. g_pEffects->Sparks( end );
  619. }
  620. }
  621. #endif
  622. }
  623. //-----------------------------------------------------------------------------
  624. // Purpose: Damages anything in the beam.
  625. // Input : ptr -
  626. //-----------------------------------------------------------------------------
  627. void CBeam::BeamDamage( trace_t *ptr )
  628. {
  629. RelinkBeam();
  630. #if !defined( CLIENT_DLL )
  631. if ( ptr->fraction != 1.0 && ptr->m_pEnt != NULL )
  632. {
  633. CBaseEntity *pHit = ptr->m_pEnt;
  634. if ( pHit )
  635. {
  636. ClearMultiDamage();
  637. Vector dir = ptr->endpos - GetAbsOrigin();
  638. VectorNormalize( dir );
  639. int nDamageType = DMG_ENERGYBEAM;
  640. if (m_nDissolveType == 0)
  641. {
  642. nDamageType = DMG_DISSOLVE;
  643. }
  644. else if ( m_nDissolveType > 0 )
  645. {
  646. nDamageType = DMG_DISSOLVE | DMG_SHOCK;
  647. }
  648. CTakeDamageInfo info( this, this, m_flDamage * (gpGlobals->curtime - m_flFireTime), nDamageType );
  649. CalculateMeleeDamageForce( &info, dir, ptr->endpos );
  650. pHit->DispatchTraceAttack( info, dir, ptr );
  651. ApplyMultiDamage();
  652. if ( HasSpawnFlags( SF_BEAM_DECALS ) )
  653. {
  654. if ( pHit->IsBSPModel() )
  655. {
  656. UTIL_DecalTrace( ptr, GetDecalName() );
  657. }
  658. }
  659. }
  660. }
  661. #endif
  662. m_flFireTime = gpGlobals->curtime;
  663. }
  664. //-----------------------------------------------------------------------------
  665. // Purpose:
  666. //-----------------------------------------------------------------------------
  667. void CBeam::TurnOn( void )
  668. {
  669. AddEffects( EF_NODRAW );
  670. }
  671. //-----------------------------------------------------------------------------
  672. // Purpose:
  673. //-----------------------------------------------------------------------------
  674. void CBeam::TurnOff( void )
  675. {
  676. RemoveEffects( EF_NODRAW );
  677. }
  678. #if !defined( CLIENT_DLL )
  679. //-----------------------------------------------------------------------------
  680. // Purpose: Input handler for the beam width. Sets the end width based on the
  681. // beam width.
  682. // Input : Beam width in tenths of world units.
  683. //-----------------------------------------------------------------------------
  684. void CBeam::InputWidth( inputdata_t &inputdata )
  685. {
  686. SetWidth( inputdata.value.Float() );
  687. SetEndWidth( inputdata.value.Float() );
  688. }
  689. void CBeam::InputColorRedValue( inputdata_t &inputdata )
  690. {
  691. int nNewColor = clamp( inputdata.value.Float(), 0, 255 );
  692. SetColor( nNewColor, m_clrRender->g, m_clrRender->b );
  693. }
  694. void CBeam::InputColorGreenValue( inputdata_t &inputdata )
  695. {
  696. int nNewColor = clamp( inputdata.value.Float(), 0, 255 );
  697. SetColor( m_clrRender->r, nNewColor, m_clrRender->b );
  698. }
  699. void CBeam::InputColorBlueValue( inputdata_t &inputdata )
  700. {
  701. int nNewColor = clamp( inputdata.value.Float(), 0, 255 );
  702. SetColor( m_clrRender->r, m_clrRender->g, nNewColor );
  703. }
  704. void CBeam::InputNoise( inputdata_t &inputdata )
  705. {
  706. SetNoise( inputdata.value.Float() );
  707. }
  708. int CBeam::UpdateTransmitState( void )
  709. {
  710. // we must call ShouldTransmit() if we have a move parent
  711. if ( GetMoveParent() )
  712. return SetTransmitState( FL_EDICT_FULLCHECK );
  713. return BaseClass::UpdateTransmitState( );
  714. }
  715. void CBeam::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
  716. {
  717. // Are we already marked for transmission?
  718. if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
  719. return;
  720. BaseClass::SetTransmit( pInfo, bAlways );
  721. // Force our attached entities to go too...
  722. for ( int i=0; i < MAX_BEAM_ENTS; ++i )
  723. {
  724. if ( m_hAttachEntity[i].Get() )
  725. {
  726. m_hAttachEntity[i]->SetTransmit( pInfo, bAlways );
  727. }
  728. }
  729. }
  730. int CBeam::ShouldTransmit( const CCheckTransmitInfo *pInfo )
  731. {
  732. if ( IsEffectActive( EF_NODRAW ) )
  733. return FL_EDICT_DONTSEND;
  734. // Transmit us with the same rules as our move parent
  735. if ( GetMoveParent() )
  736. {
  737. return GetMoveParent()->ShouldTransmit( pInfo );
  738. }
  739. return BaseClass::ShouldTransmit( pInfo );
  740. }
  741. #endif
  742. //-----------------------------------------------------------------------------
  743. // Purpose: Draw any debug text overlays.
  744. // Output : Returns the new text offset from the top.
  745. //-----------------------------------------------------------------------------
  746. int CBeam::DrawDebugTextOverlays(void)
  747. {
  748. #if !defined( CLIENT_DLL )
  749. int text_offset = BaseClass::DrawDebugTextOverlays();
  750. if (m_debugOverlays & OVERLAY_TEXT_BIT)
  751. {
  752. // Print state
  753. char tempstr[512];
  754. Q_snprintf(tempstr, sizeof(tempstr), "start: (%.2f,%.2f,%.2f)", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z);
  755. EntityText(text_offset,tempstr,0);
  756. text_offset++;
  757. Q_snprintf(tempstr, sizeof(tempstr), "end : (%.2f,%.2f,%.2f)", m_vecEndPos.GetX(), m_vecEndPos.GetY(), m_vecEndPos.GetZ());
  758. EntityText(text_offset,tempstr,0);
  759. text_offset++;
  760. }
  761. return text_offset;
  762. #else
  763. return 0;
  764. #endif
  765. }
  766. #if defined( CLIENT_DLL )
  767. // Purpose:
  768. // Input : isbeingremoved -
  769. // *predicted -
  770. // Output : Returns true on success, false on failure.
  771. //-----------------------------------------------------------------------------
  772. bool CBeam::OnPredictedEntityRemove( bool isbeingremoved, C_BaseEntity *predicted )
  773. {
  774. BaseClass::OnPredictedEntityRemove( isbeingremoved, predicted );
  775. CBeam *beam = dynamic_cast< CBeam * >( predicted );
  776. if ( !beam )
  777. {
  778. // Hrm, we didn't link up to correct type!!!
  779. Assert( 0 );
  780. // Delete right away since it's fucked up
  781. return true;
  782. }
  783. if ( beam->IsEFlagSet( EFL_KILLME ) )
  784. {
  785. // Don't delete right away
  786. AddEFlags( EFL_KILLME );
  787. return false;
  788. }
  789. // Go ahead and delete if it's not short-lived
  790. return true;
  791. }
  792. extern bool g_bRenderingScreenshot;
  793. extern ConVar r_drawviewmodel;
  794. int CBeam::DrawModel( int flags, const RenderableInstance_t &instance )
  795. {
  796. if ( !m_bReadyToDraw )
  797. return 0;
  798. if ( IsMarkedForDeletion() )
  799. return 0;
  800. if ( CurrentViewID() == VIEW_SHADOW_DEPTH_TEXTURE )
  801. return 0;
  802. // Tracker 16432: If rendering a savegame screenshot don't draw beams
  803. // who have viewmodels as their attached entity
  804. if ( g_bRenderingScreenshot || !r_drawviewmodel.GetBool() )
  805. {
  806. // If the beam is attached
  807. for (int i=0;i<MAX_BEAM_ENTS;i++)
  808. {
  809. C_BaseViewModel *vm = ToBaseViewModel(m_hAttachEntity[i].Get());
  810. if ( vm )
  811. {
  812. return 0;
  813. }
  814. }
  815. }
  816. beams->DrawBeam( this, instance );
  817. return 0;
  818. }
  819. void CBeam::OnDataChanged( DataUpdateType_t updateType )
  820. {
  821. MarkMessageReceived();
  822. // Make sure that the correct model is referenced for this entity
  823. SetModelPointer( modelinfo->GetModel( GetModelIndex() ) );
  824. // Convert weapon world models to viewmodels if they're weapons being carried by the local player
  825. for (int i=0;i<MAX_BEAM_ENTS;i++)
  826. {
  827. C_BaseEntity *pEnt = m_hAttachEntity[i].Get();
  828. if ( pEnt )
  829. {
  830. C_BaseCombatWeapon *pWpn = pEnt->MyCombatWeaponPointer();
  831. if ( pWpn && pWpn->IsCarriedByLocalPlayer() )
  832. {
  833. C_BasePlayer *player = ToBasePlayer( pWpn->GetOwner() );
  834. C_BaseViewModel *pViewModel = player ? player->GetViewModel( 0 ) : NULL;
  835. if ( pViewModel )
  836. {
  837. // Get the viewmodel and use it instead
  838. m_hAttachEntity.Set( i, pViewModel );
  839. }
  840. }
  841. }
  842. }
  843. // Compute the bounds here...
  844. Vector mins, maxs;
  845. ComputeBounds( mins, maxs );
  846. SetCollisionBounds( mins, maxs );
  847. AddToEntityList( ENTITY_LIST_SIMULATE );
  848. }
  849. RenderableTranslucencyType_t CBeam::ComputeTranslucencyType()
  850. {
  851. return RENDERABLE_IS_TRANSLUCENT;
  852. }
  853. //-----------------------------------------------------------------------------
  854. // Purpose: Adds to beam entity list
  855. //-----------------------------------------------------------------------------
  856. bool CBeam::Simulate( void )
  857. {
  858. bool bRet = false;
  859. // If set to invisible, skip. Do this before resetting the entity pointer so it has
  860. // valid data to decide whether it's visible.
  861. if ( ShouldDraw() )
  862. {
  863. //FIXME: If we're hooked up to an attachment point, then recompute our bounds every frame
  864. if ( m_hAttachEntity[0].Get() || m_hAttachEntity[1].Get() )
  865. {
  866. // Compute the bounds here...
  867. Vector mins, maxs;
  868. ComputeBounds( mins, maxs );
  869. SetCollisionBounds( mins, maxs );
  870. bRet = true;
  871. }
  872. MoveToLastReceivedPosition();
  873. }
  874. BaseClass::Simulate();
  875. return bRet;
  876. }
  877. //-----------------------------------------------------------------------------
  878. // Computes the bounding box of a beam local to the origin of the beam
  879. //-----------------------------------------------------------------------------
  880. void CBeam::ComputeBounds( Vector& mins, Vector& maxs )
  881. {
  882. Vector vecAbsStart = GetAbsStartPos();
  883. Vector vecAbsEnd = GetAbsEndPos();
  884. switch( GetType() )
  885. {
  886. case BEAM_LASER:
  887. case BEAM_ENTS:
  888. case BEAM_SPLINE:
  889. {
  890. // Compute the bounds here...
  891. Vector attachmentPoint( 0, 0, 0 );
  892. mins.Init( 99999, 99999, 99999 );
  893. maxs.Init( -99999, -99999, -99999 );
  894. for (int i = 0; i < m_nNumBeamEnts; ++i )
  895. {
  896. C_BaseEntity *pTestEnt = m_hAttachEntity[i].Get();
  897. if ( pTestEnt )
  898. {
  899. if ( pTestEnt == this )
  900. {
  901. mins = maxs = GetAbsOrigin();
  902. }
  903. else
  904. {
  905. // We do this so we don't have to calculate attachments (and do expensive bone-setup calculations) on our attachments.
  906. Vector attMins, attMaxs;
  907. m_hAttachEntity[i]->GetRenderBoundsWorldspace( attMins, attMaxs );
  908. mins = mins.Min( attMins );
  909. mins = mins.Min( attMaxs );
  910. maxs = maxs.Max( attMins );
  911. maxs = maxs.Max( attMaxs );
  912. }
  913. //ASSERT_COORD( mins );
  914. //ASSERT_COORD( maxs );
  915. }
  916. else
  917. {
  918. if (i == 0)
  919. {
  920. VectorCopy( vecAbsStart, attachmentPoint );
  921. }
  922. else if (i == 1)
  923. {
  924. VectorCopy( vecAbsEnd, attachmentPoint );
  925. }
  926. else
  927. {
  928. Assert(0);
  929. }
  930. mins = mins.Min( attachmentPoint );
  931. maxs = maxs.Max( attachmentPoint );
  932. }
  933. }
  934. }
  935. break;
  936. case BEAM_POINTS:
  937. default:
  938. {
  939. for (int i = 0; i < 3; ++i)
  940. {
  941. if (vecAbsStart[i] < vecAbsEnd[i])
  942. {
  943. mins[i] = vecAbsStart[i];
  944. maxs[i] = vecAbsEnd[i];
  945. }
  946. else
  947. {
  948. mins[i] = vecAbsEnd[i];
  949. maxs[i] = vecAbsStart[i];
  950. }
  951. }
  952. }
  953. break;
  954. }
  955. // bloat the bounding box by the width of the beam
  956. float rad = 0.5f * MAX( m_fWidth.Get(), m_fEndWidth.Get() );
  957. Vector vecRad( rad, rad, rad );
  958. mins -= vecRad;
  959. maxs += vecRad;
  960. // Make sure the bounds are measured in *relative coords*
  961. Vector vecAbsOrigin = GetAbsOrigin();
  962. mins -= vecAbsOrigin;
  963. maxs -= vecAbsOrigin;
  964. }
  965. void CBeam::GetToolRecordingState( KeyValues *msg )
  966. {
  967. BaseClass::GetToolRecordingState( msg );
  968. Vector vTemp;
  969. KeyValues *pKV = CIFM_EntityKeyValuesHandler_AutoRegister::FindOrCreateNonConformantKeyValues( msg );
  970. pKV->SetString( CIFM_EntityKeyValuesHandler_AutoRegister::GetHandlerIDKeyString(), "C_Beam" );
  971. pKV->SetInt( "entIndex", (index != -1) ? index : GetRefEHandle().GetSerialNumber() ); //if the index is -1 (client entity), fall back on the serial number
  972. //pKV->SetInt( "beamType", m_nBeamType );
  973. pKV->SetInt( "beamType", BEAM_POINTS ); //need to make sure we remove all dependancy on outside data.
  974. pKV->SetInt( "beamEnts", m_nNumBeamEnts );
  975. vTemp = GetAbsStartPos();
  976. pKV->SetFloat( "start_x", vTemp.x );
  977. pKV->SetFloat( "start_y", vTemp.y );
  978. pKV->SetFloat( "start_z", vTemp.z );
  979. vTemp = GetAbsEndPos();
  980. pKV->SetFloat( "end_x", vTemp.x );
  981. pKV->SetFloat( "end_y", vTemp.y );
  982. pKV->SetFloat( "end_z", vTemp.z );
  983. pKV->SetInt( "ModelIndex", GetModelIndex() );
  984. pKV->SetInt( "HaloIndex", m_nHaloIndex );
  985. pKV->SetFloat( "HaloScale", m_fHaloScale );
  986. pKV->SetFloat( "Width", GetWidth() );
  987. pKV->SetFloat( "EndWidth", GetEndWidth() );
  988. pKV->SetFloat( "FadeLength", GetFadeLength() );
  989. pKV->SetFloat( "Noise", GetNoise() );
  990. pKV->SetInt( "Brightness", GetRenderAlpha() );
  991. pKV->SetFloat( "ScrollRate", GetScrollRate() );
  992. pKV->SetInt( "beamFlags", GetBeamFlags() );
  993. pKV->SetInt( "color_r", GetRenderColorR() );
  994. pKV->SetInt( "color_g", GetRenderColorG() );
  995. pKV->SetInt( "color_b", GetRenderColorB() );
  996. pKV->SetFloat( "color_hdrscale", GetHDRColorScale() );
  997. pKV->SetFloat( "startframe", m_fStartFrame );
  998. pKV->SetFloat( "framerate", m_flFrameRate );
  999. }
  1000. void CBeam::RestoreToToolRecordedState( KeyValues *pKV )
  1001. {
  1002. Vector vTemp;
  1003. SetType( pKV->GetInt( "beamType" ) );
  1004. m_nNumBeamEnts = pKV->GetInt( "beamEnts" );
  1005. vTemp.x = pKV->GetFloat( "start_x" );
  1006. vTemp.y = pKV->GetFloat( "start_y" );
  1007. vTemp.z = pKV->GetFloat( "start_z" );
  1008. SetAbsStartPos( vTemp );
  1009. vTemp.x = pKV->GetFloat( "end_x" );
  1010. vTemp.y = pKV->GetFloat( "end_y" );
  1011. vTemp.z = pKV->GetFloat( "end_z" );
  1012. SetAbsEndPos( vTemp );
  1013. SetModelIndex( pKV->GetInt( "ModelIndex" ) );
  1014. m_nHaloIndex = pKV->GetInt( "HaloIndex" );
  1015. m_fHaloScale = pKV->GetFloat( "HaloScale" );
  1016. SetWidth( pKV->GetFloat( "Width" ) );
  1017. SetEndWidth( pKV->GetFloat( "EndWidth" ) );
  1018. SetFadeLength( pKV->GetFloat( "FadeLength" ) );
  1019. SetNoise( pKV->GetFloat( "Noise" ) );
  1020. int iBrightness = pKV->GetInt( "Brightness", 255 );
  1021. iBrightness = MIN( iBrightness, 255 );
  1022. iBrightness = MAX( iBrightness, 0 );
  1023. SetRenderAlpha( (byte)iBrightness );
  1024. //pKV->GetFloat( "Brightness", 255 ); //<-----------------------------revisit
  1025. SetScrollRate( pKV->GetFloat( "ScrollRate" ) );
  1026. m_nBeamFlags = pKV->GetInt( "beamFlags" );
  1027. SetRenderColorR( (byte)pKV->GetInt( "color_r" ) );
  1028. SetRenderColorG( (byte)pKV->GetInt( "color_g" ) );
  1029. SetRenderColorB( (byte)pKV->GetInt( "color_b" ) );
  1030. SetHDRColorScale( pKV->GetFloat( "color_hdrscale" ) );
  1031. m_fStartFrame = pKV->GetFloat( "startframe" );
  1032. m_flFrameRate = pKV->GetFloat( "framerate" );
  1033. for (int i=0;i<MAX_BEAM_ENTS;i++)
  1034. {
  1035. m_hAttachEntity.Set( i, INVALID_EHANDLE );
  1036. m_nAttachIndex.Set( i, 0 );
  1037. }
  1038. SetSize( -Vector( 16384.0f, 16384.0f, 16384.0f ), Vector( 16384.0f, 16384.0f, 16384.0f ) );
  1039. m_VisibilityBits.SetAll();
  1040. }
  1041. class C_Beam_NonConformantDataHandler : public CIFM_EntityKeyValuesHandler_RecreateEntities
  1042. {
  1043. public:
  1044. C_Beam_NonConformantDataHandler( void )
  1045. : CIFM_EntityKeyValuesHandler_RecreateEntities( "C_Beam" )
  1046. { }
  1047. virtual void *CreateInstance( void )
  1048. {
  1049. return new CBeam;
  1050. }
  1051. virtual void DestroyInstance( void *pEntity )
  1052. {
  1053. CBeam *pCastEntity = (CBeam *)pEntity;
  1054. clienttools->RemoveClientRenderable( pCastEntity );
  1055. delete pCastEntity;
  1056. }
  1057. virtual void HandleInstance( void *pEntity, KeyValues *pKeyValues )
  1058. {
  1059. CBeam *pCastEntity = (CBeam *)pEntity;
  1060. pCastEntity->RestoreToToolRecordedState( pKeyValues );
  1061. if( pCastEntity->RenderHandle() == INVALID_CLIENT_RENDER_HANDLE )
  1062. {
  1063. clienttools->AddClientRenderable( pCastEntity, false, RENDERABLE_IS_TRANSLUCENT );
  1064. }
  1065. clienttools->MarkClientRenderableDirty( pCastEntity );
  1066. }
  1067. };
  1068. static C_Beam_NonConformantDataHandler s_BeamEntityIFMHandler;
  1069. #endif