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.

1434 lines
40 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "cbase.h"
  9. #include "animation.h"
  10. #include "studio.h"
  11. #include "bone_setup.h"
  12. #include "ai_basenpc.h"
  13. #include "npcevent.h"
  14. #include "saverestore_utlvector.h"
  15. #include "dt_utlvector_send.h"
  16. #include "datacache/imdlcache.h"
  17. #include "toolframework/itoolframework.h"
  18. #include "cs_player.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. extern ConVar ai_sequence_debug;
  22. BEGIN_SIMPLE_DATADESC( CAnimationLayer )
  23. // DEFINE_FIELD( m_pOwnerEntity, CBaseAnimatingOverlay ),
  24. DEFINE_FIELD( m_fFlags, FIELD_INTEGER ),
  25. DEFINE_FIELD( m_bSequenceFinished, FIELD_BOOLEAN ),
  26. DEFINE_FIELD( m_bLooping, FIELD_BOOLEAN ),
  27. DEFINE_FIELD( m_nSequence, FIELD_INTEGER ),
  28. DEFINE_FIELD( m_flCycle, FIELD_FLOAT ),
  29. DEFINE_FIELD( m_flPrevCycle, FIELD_FLOAT ),
  30. DEFINE_FIELD( m_flPlaybackRate, FIELD_FLOAT),
  31. DEFINE_FIELD( m_flWeight, FIELD_FLOAT),
  32. DEFINE_FIELD( m_flWeightDeltaRate, FIELD_FLOAT),
  33. DEFINE_FIELD( m_flBlendIn, FIELD_FLOAT ),
  34. DEFINE_FIELD( m_flBlendOut, FIELD_FLOAT ),
  35. DEFINE_FIELD( m_flKillRate, FIELD_FLOAT ),
  36. DEFINE_FIELD( m_flKillDelay, FIELD_FLOAT ),
  37. DEFINE_CUSTOM_FIELD( m_nActivity, ActivityDataOps() ),
  38. DEFINE_FIELD( m_nPriority, FIELD_INTEGER ),
  39. DEFINE_FIELD( m_nOrder, FIELD_INTEGER ),
  40. DEFINE_FIELD( m_flLastEventCheck, FIELD_FLOAT ),
  41. DEFINE_FIELD( m_flLastAccess, FIELD_TIME ),
  42. DEFINE_FIELD( m_flLayerAnimtime, FIELD_FLOAT ),
  43. DEFINE_FIELD( m_flLayerFadeOuttime, FIELD_FLOAT ),
  44. END_DATADESC()
  45. BEGIN_DATADESC( CBaseAnimatingOverlay )
  46. DEFINE_UTLVECTOR( m_AnimOverlay, FIELD_EMBEDDED ),
  47. // DEFINE_FIELD( m_nActiveLayers, FIELD_INTEGER ),
  48. // DEFINE_FIELD( m_nActiveBaseLayers, FIELD_INTEGER ),
  49. END_DATADESC()
  50. #define ORDER_BITS 4
  51. #define WEIGHT_BITS 8
  52. BEGIN_SEND_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
  53. SendPropInt (SENDINFO(m_nSequence), ANIMATION_SEQUENCE_BITS,SPROP_UNSIGNED),
  54. SendPropFloat (SENDINFO(m_flCycle), ANIMATION_CYCLE_BITS, SPROP_ROUNDDOWN, 0.0f, 1.0f),
  55. SendPropFloat (SENDINFO(m_flPlaybackRate),WEIGHT_BITS, SPROP_NOSCALE ),
  56. SendPropFloat (SENDINFO(m_flPrevCycle), ANIMATION_CYCLE_BITS, SPROP_ROUNDDOWN, 0.0f, 1.0f),
  57. SendPropFloat (SENDINFO(m_flWeight), WEIGHT_BITS, 0, 0.0f, 1.0f),
  58. SendPropFloat (SENDINFO(m_flWeightDeltaRate),WEIGHT_BITS, SPROP_NOSCALE ),
  59. SendPropInt (SENDINFO(m_nOrder), ORDER_BITS, SPROP_UNSIGNED),
  60. END_SEND_TABLE()
  61. BEGIN_SEND_TABLE_NOBASE( CBaseAnimatingOverlay, DT_OverlayVars )
  62. SendPropUtlVector(
  63. SENDINFO_UTLVECTOR( m_AnimOverlay ),
  64. CBaseAnimatingOverlay::MAX_OVERLAYS, // max elements
  65. SendPropDataTable( NULL, 0, &REFERENCE_SEND_TABLE( DT_Animationlayer ) ) )
  66. END_SEND_TABLE()
  67. IMPLEMENT_SERVERCLASS_ST( CBaseAnimatingOverlay, DT_BaseAnimatingOverlay )
  68. // These are in their own separate data table so CCSPlayer can exclude all of these.
  69. SendPropDataTable( "overlay_vars", 0, &REFERENCE_SEND_TABLE( DT_OverlayVars ) )
  70. END_SEND_TABLE()
  71. CAnimationLayer::CAnimationLayer( )
  72. {
  73. Init( NULL );
  74. }
  75. // 7LS - using '=' operator on a NetworkVar will call the Set(x) fn, which does a comparison of 'x' against the current value to determine if the network state
  76. // needs to change. If the var is a float, and the memory contains NaN's the comp will always fail, so the var will never be set to x
  77. // Calling SetDirect will always assign the var and flag the network state as changed, since it avoids the compare.
  78. // This should probably be done everywhere float NetworkVar's are initialized if memory is not guaranteed to have been prepared appropriately.
  79. void CAnimationLayer::Init( CBaseAnimatingOverlay *pOverlay )
  80. {
  81. m_pOwnerEntity = pOverlay;
  82. m_fFlags = 0;
  83. // 7LS OLD, m_flWeight = 0;
  84. m_flWeight.SetDirect( 0.0f );
  85. m_flWeightDeltaRate.SetDirect( 0.0f );
  86. // 7LS OLD, m_flCycle = 0;
  87. m_flCycle.SetDirect( 0.0f );
  88. // 7LS OLD, m_flPrevCycle = 0;
  89. m_flPrevCycle.SetDirect( 0.0f );
  90. m_bSequenceFinished = false;
  91. m_nActivity = ACT_INVALID;
  92. m_nSequence = 0;
  93. m_nPriority = 0;
  94. m_nOrder.Set( CBaseAnimatingOverlay::MAX_OVERLAYS );
  95. m_flKillRate = 100.0;
  96. m_flKillDelay = 0.0;
  97. m_flPlaybackRate.SetDirect( 1.0f );
  98. m_flLastAccess = gpGlobals->curtime;
  99. m_flLayerAnimtime = 0;
  100. m_flLayerFadeOuttime = 0;
  101. m_bLooping = false;
  102. m_flBlendIn = 0.0f;
  103. m_flBlendOut = 0.0f;
  104. m_flLastEventCheck = 0.0f;
  105. m_pDispatchedStudioHdr = NULL;
  106. m_nDispatchedSrc = ACT_INVALID;
  107. m_nDispatchedDst = ACT_INVALID;
  108. }
  109. //------------------------------------------------------------------------------
  110. // Purpose :
  111. // Input :
  112. // Output :
  113. //------------------------------------------------------------------------------
  114. void CAnimationLayer::StudioFrameAdvance( float flInterval, CBaseAnimating *pOwner )
  115. {
  116. float flCycleRate = pOwner->GetLayerSequenceCycleRate( this, m_nSequence );
  117. m_flPrevCycle = m_flCycle;
  118. m_flCycle += flInterval * flCycleRate * m_flPlaybackRate;
  119. if (m_flCycle < 0.0)
  120. {
  121. if (m_bLooping)
  122. {
  123. m_flCycle = SubtractIntegerPart(m_flCycle);
  124. }
  125. else
  126. {
  127. m_flCycle = 0;
  128. }
  129. }
  130. else if (m_flCycle >= 1.0)
  131. {
  132. m_bSequenceFinished = true;
  133. if (m_bLooping)
  134. {
  135. m_flCycle = SubtractIntegerPart(m_flCycle);
  136. }
  137. else
  138. {
  139. m_flCycle = 1.0;
  140. }
  141. }
  142. if (IsAutoramp())
  143. {
  144. m_flWeight = 1;
  145. // blend in?
  146. if ( m_flBlendIn != 0.0f )
  147. {
  148. if (m_flCycle < m_flBlendIn)
  149. {
  150. m_flWeight = m_flCycle / m_flBlendIn;
  151. }
  152. }
  153. // blend out?
  154. if ( m_flBlendOut != 0.0f )
  155. {
  156. if (m_flCycle > 1.0 - m_flBlendOut)
  157. {
  158. m_flWeight = (1.0 - m_flCycle) / m_flBlendOut;
  159. }
  160. }
  161. m_flWeight = 3.0 * m_flWeight * m_flWeight - 2.0 * m_flWeight * m_flWeight * m_flWeight;
  162. if (m_nSequence == 0)
  163. m_flWeight = 0;
  164. }
  165. }
  166. //------------------------------------------------------------------------------
  167. bool CAnimationLayer::IsAbandoned( void )
  168. {
  169. if (IsActive() && !IsAutokill() && !IsKillMe() && m_flLastAccess > 0.0 && (gpGlobals->curtime - m_flLastAccess > 0.2))
  170. return true;
  171. else
  172. return false;
  173. }
  174. void CAnimationLayer::MarkActive( void )
  175. {
  176. m_flLastAccess = gpGlobals->curtime;
  177. }
  178. //------------------------------------------------------------------------------
  179. ConVar debug_dispatch_server_dump( "debug_dispatch_server_dump", "0" );
  180. void CBaseAnimatingOverlay::AccumulateDispatchedLayers( CBaseAnimatingOverlay *pWeapon, CStudioHdr *pWeaponStudioHdr, IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime )
  181. {
  182. if ( !pWeapon->m_pBoneMergeCache )
  183. return;
  184. // copy matching player pose params to weapon pose params
  185. pWeapon->m_pBoneMergeCache->MergeMatchingPoseParams();
  186. //float poseparam[MAXSTUDIOPOSEPARAM];
  187. //pWeapon->GetPoseParameters( pWeaponStudioHdr, poseparam );
  188. // build a temporary setup for the weapon
  189. CIKContext weaponIK;
  190. weaponIK.Init( pWeaponStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, BONE_USED_BY_BONE_MERGE );
  191. IBoneSetup weaponSetup( pWeaponStudioHdr, BONE_USED_BY_BONE_MERGE, pWeapon->GetPoseParameterArray() );
  192. BoneVector weaponPos[MAXSTUDIOBONES];
  193. BoneQuaternionAligned weaponQ[MAXSTUDIOBONES];
  194. // copy player bones to weapon setup bones
  195. pWeapon->m_pBoneMergeCache->CopyFromFollow( pos, q, BONE_USED_BY_BONE_MERGE, weaponPos, weaponQ );
  196. // do layer animations
  197. // FIXME: some of the layers are player layers, not weapon layers
  198. // FIXME: how to interleave?
  199. for ( int i=0; i < GetNumAnimOverlays(); i++ )
  200. {
  201. CAnimationLayer *pLayer = GetAnimOverlay( i );
  202. if ( pLayer->m_nOrder >= MAX_OVERLAYS || pLayer->GetSequence() <= 1 || pLayer->GetWeight() <= 0.0f )
  203. continue;
  204. UpdateDispatchLayer( pLayer, pWeaponStudioHdr, pLayer->GetSequence() );
  205. if ( pLayer->m_nDispatchedDst > 0 && pLayer->m_nDispatchedDst < pWeaponStudioHdr->GetNumSeq() )
  206. {
  207. weaponSetup.AccumulatePose( weaponPos, weaponQ, pLayer->m_nDispatchedDst, pLayer->GetCycle(), pLayer->GetWeight(), currentTime, &weaponIK );
  208. if ( debug_dispatch_server_dump.GetBool() )
  209. {
  210. Msg( "Dispatch layer sequence: %s\n", pWeapon->GetSequenceName( pLayer->m_nDispatchedDst ) );
  211. }
  212. }
  213. }
  214. if ( debug_dispatch_server_dump.GetBool() )
  215. {
  216. debug_dispatch_server_dump.SetValue( 0 );
  217. }
  218. // FIXME: merge weaponIK into m_pIK
  219. //CBoneBitList boneComputed;
  220. //
  221. //pWeapon->CalculateIKLocks( currentTime );
  222. ////pWeapon->UpdateIKLocks( currentTime );
  223. //weaponIK.UpdateTargets( weaponPos, weaponQ, pWeapon->m_BoneAccessor.GetBoneArrayForWrite(), boneComputed );
  224. //
  225. //pWeapon->CalculateIKLocks( currentTime );
  226. //weaponIK.SolveDependencies( weaponPos, weaponQ, pWeapon->m_BoneAccessor.GetBoneArrayForWrite(), boneComputed );
  227. // merge weapon bones back
  228. pWeapon->m_pBoneMergeCache->CopyToFollow( weaponPos, weaponQ, BONE_USED_BY_BONE_MERGE, pos, q );
  229. }
  230. void CBaseAnimatingOverlay::RegenerateDispatchedLayers( IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime )
  231. {
  232. // find who I'm following and see if I'm their dispatched model
  233. if ( m_pBoneMergeCache && m_pBoneMergeCache->IsCopied() )
  234. {
  235. CBaseEntity *pFollowEnt = GetFollowedEntity();
  236. if ( pFollowEnt )
  237. {
  238. CBaseAnimatingOverlay *pFollow = pFollowEnt->GetBaseAnimatingOverlay();
  239. if ( pFollow )
  240. {
  241. for ( int i=0; i < pFollow->GetNumAnimOverlays(); i++ )
  242. {
  243. CAnimationLayer *pLayer = pFollow->GetAnimOverlay( i );
  244. if ( pLayer->m_pDispatchedStudioHdr == NULL || pLayer->m_nOrder >= MAX_OVERLAYS || pLayer->GetSequence() == -1 || pLayer->GetWeight() <= 0.0f )
  245. continue;
  246. // FIXME: why do the CStudioHdr's not match?
  247. if ( pLayer->m_pDispatchedStudioHdr->GetRenderHdr() == boneSetup.GetStudioHdr()->GetRenderHdr() )
  248. {
  249. if ( pLayer->m_nDispatchedDst != ACT_INVALID )
  250. {
  251. boneSetup.AccumulatePose( pos, q, pLayer->m_nDispatchedDst, pLayer->m_flCycle, pLayer->m_flWeight, currentTime, m_pIk );
  252. }
  253. }
  254. }
  255. }
  256. }
  257. }
  258. }
  259. void CBaseAnimatingOverlay::VerifyOrder( void )
  260. {
  261. #ifdef _DEBUG
  262. int i, j;
  263. // test sorting of the layers
  264. int layer[MAX_OVERLAYS] = {};
  265. int maxOrder = -1;
  266. for (i = 0; i < MAX_OVERLAYS; i++)
  267. {
  268. layer[i] = MAX_OVERLAYS;
  269. }
  270. for (i = 0; i < m_AnimOverlay.Count(); i++)
  271. {
  272. if (m_AnimOverlay[ i ].m_nOrder < MAX_OVERLAYS)
  273. {
  274. j = m_AnimOverlay[ i ].m_nOrder;
  275. Assert( layer[j] == MAX_OVERLAYS );
  276. layer[j] = i;
  277. if (j > maxOrder)
  278. maxOrder = j;
  279. }
  280. }
  281. // make sure they're sequential
  282. // Aim layers are allowed to have gaps, and we are moving aim blending to server
  283. // for ( i = 0; i <= maxOrder; i++ )
  284. // {
  285. // Assert( layer[i] != MAX_OVERLAYS);
  286. // }
  287. /*
  288. for ( i = 0; i < MAX_OVERLAYS; i++ )
  289. {
  290. int j = layer[i];
  291. if (j != MAX_OVERLAYS)
  292. {
  293. char tempstr[512];
  294. Q_snprintf( tempstr, sizeof( tempstr ),"%d : %d :%.2f :%d:%d:%.1f",
  295. j,
  296. m_AnimOverlay[ j ].m_nSequence,
  297. m_AnimOverlay[ j ].m_flWeight,
  298. m_AnimOverlay[ j ].IsActive(),
  299. m_AnimOverlay[ j ].IsKillMe(),
  300. m_AnimOverlay[ j ].m_flKillDelay
  301. );
  302. EntityText( i, tempstr, 0.1 );
  303. }
  304. }
  305. */
  306. #endif
  307. }
  308. //-----------------------------------------------------------------------------
  309. // Purpose: Sets the entity's model, clearing animation data
  310. // Input : *szModelName -
  311. //-----------------------------------------------------------------------------
  312. void CBaseAnimatingOverlay::SetModel( const char *szModelName )
  313. {
  314. for ( int j=0; j<m_AnimOverlay.Count(); ++j )
  315. {
  316. m_AnimOverlay[j].Init( this );
  317. }
  318. BaseClass::SetModel( szModelName );
  319. }
  320. //------------------------------------------------------------------------------
  321. // Purpose : advance the animation frame up to the current time
  322. // if an flInterval is passed in, only advance animation that number of seconds
  323. // Input :
  324. // Output :
  325. //------------------------------------------------------------------------------
  326. void CBaseAnimatingOverlay::StudioFrameAdvance ()
  327. {
  328. float flAdvance = GetAnimTimeInterval();
  329. VerifyOrder();
  330. BaseClass::StudioFrameAdvance();
  331. for ( int i = 0; i < m_AnimOverlay.Count(); i++ )
  332. {
  333. CAnimationLayer *pLayer = &m_AnimOverlay[i];
  334. if (pLayer->IsActive())
  335. {
  336. // Assert( !m_AnimOverlay[ i ].IsAbandoned() );
  337. if (pLayer->IsKillMe())
  338. {
  339. if (pLayer->m_flKillDelay > 0)
  340. {
  341. pLayer->m_flKillDelay -= flAdvance;
  342. pLayer->m_flKillDelay = clamp( pLayer->m_flKillDelay, 0.0, 1.0 );
  343. }
  344. else if (pLayer->m_flWeight != 0.0f)
  345. {
  346. // give it at least one frame advance cycle to propagate 0.0 to client
  347. pLayer->m_flWeight -= pLayer->m_flKillRate * flAdvance;
  348. pLayer->m_flWeight = clamp( pLayer->m_flWeight.Get(), 0.0, 1.0 );
  349. }
  350. else
  351. {
  352. // shift the other layers down in order
  353. if (ai_sequence_debug.GetBool() == true && m_debugOverlays & OVERLAY_NPC_SELECTED_BIT)
  354. {
  355. Msg("removing %d (%d): %s : %5.3f (%.3f)\n", i, pLayer->m_nOrder.Get(), GetSequenceName( pLayer->m_nSequence ), pLayer->m_flCycle.Get(), pLayer->m_flWeight.Get() );
  356. }
  357. FastRemoveLayer( i );
  358. // needs at least one thing cycle dead to trigger sequence change
  359. pLayer->Dying();
  360. continue;
  361. }
  362. }
  363. pLayer->StudioFrameAdvance( flAdvance, this );
  364. if ( pLayer->m_bSequenceFinished && (pLayer->IsAutokill()) )
  365. {
  366. pLayer->m_flWeight = 0.0f;
  367. pLayer->KillMe();
  368. }
  369. }
  370. else if (pLayer->IsDying())
  371. {
  372. pLayer->Dead();
  373. }
  374. else if (pLayer->m_flWeight > 0.0)
  375. {
  376. // Now that the server blends, it is turning off layers all the time. Having a weight left over
  377. // when you're no longer marked as active is now harmless and commonplace. Just clean up.
  378. pLayer->Init( this );
  379. pLayer->Dying();
  380. }
  381. }
  382. if (ai_sequence_debug.GetBool() == true && m_debugOverlays & OVERLAY_NPC_SELECTED_BIT)
  383. {
  384. for ( int i = 0; i < m_AnimOverlay.Count(); i++ )
  385. {
  386. if (m_AnimOverlay[ i ].IsActive())
  387. {
  388. /*
  389. if (m_AnimOverlay[ i ].IsAbandoned())
  390. {
  391. Msg(" %d abandoned %.2f (%.2f)\n", i, gpGlobals->curtime, m_AnimOverlay[ i ].m_flLastAccess );
  392. }
  393. */
  394. Msg(" %d (%d): %s : %5.3f (%.3f)\n", i, m_AnimOverlay[ i ].m_nOrder.Get(), GetSequenceName( m_AnimOverlay[ i ].m_nSequence ), m_AnimOverlay[ i ].m_flCycle.Get(), m_AnimOverlay[ i ].m_flWeight.Get() );
  395. }
  396. }
  397. }
  398. VerifyOrder();
  399. }
  400. //=========================================================
  401. // DispatchAnimEvents
  402. //=========================================================
  403. void CBaseAnimatingOverlay::DispatchAnimEvents ( CBaseAnimating *eventHandler )
  404. {
  405. BaseClass::DispatchAnimEvents( eventHandler );
  406. for ( int i = 0; i < m_AnimOverlay.Count(); i++ )
  407. {
  408. if (m_AnimOverlay[ i ].IsActive() && !m_AnimOverlay[ i ].NoEvents() )
  409. {
  410. m_AnimOverlay[ i ].DispatchAnimEvents( eventHandler, this );
  411. }
  412. }
  413. }
  414. void CAnimationLayer::DispatchAnimEvents( CBaseAnimating *eventHandler, CBaseAnimating *pOwner )
  415. {
  416. animevent_t event;
  417. CStudioHdr *pstudiohdr = pOwner->GetModelPtr( );
  418. if ( !pstudiohdr )
  419. {
  420. Assert(!"CBaseAnimating::DispatchAnimEvents: model missing");
  421. return;
  422. }
  423. if ( !pstudiohdr->SequencesAvailable() )
  424. {
  425. return;
  426. }
  427. if ( m_nSequence < 0 || m_nSequence >= pstudiohdr->GetNumSeq() )
  428. return;
  429. // don't fire if here are no events
  430. if ( pstudiohdr->pSeqdesc( m_nSequence ).numevents == 0 )
  431. {
  432. return;
  433. }
  434. // look from when it last checked to some short time in the future
  435. float flCycleRate = pOwner->GetSequenceCycleRate( m_nSequence ) * m_flPlaybackRate;
  436. float flStart = m_flLastEventCheck;
  437. float flEnd = m_flCycle;
  438. if (!m_bLooping)
  439. {
  440. // fire off events early
  441. float flLastVisibleCycle = 1.0f - (pstudiohdr->pSeqdesc( m_nSequence ).fadeouttime) * flCycleRate;
  442. if (flEnd >= flLastVisibleCycle || flEnd < 0.0)
  443. {
  444. m_bSequenceFinished = true;
  445. flEnd = 1.01f;
  446. }
  447. }
  448. m_flLastEventCheck = flEnd;
  449. /*
  450. if (pOwner->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT)
  451. {
  452. Msg( "%s:%s : checking %.2f %.2f (%d)\n", STRING(pOwner->GetModelName()), pstudiohdr->pSeqdesc( m_nSequence ).pszLabel(), flStart, flEnd, m_bSequenceFinished );
  453. }
  454. */
  455. // FIXME: does not handle negative framerates!
  456. int index = 0;
  457. while ( (index = GetAnimationEvent( pstudiohdr, m_nSequence, &event, flStart, flEnd, index ) ) != 0 )
  458. {
  459. event.pSource = pOwner;
  460. // calc when this event should happen
  461. if (flCycleRate > 0.0)
  462. {
  463. float flCycle = event.cycle;
  464. if (flCycle > m_flCycle)
  465. {
  466. flCycle = flCycle - 1.0;
  467. }
  468. event.eventtime = pOwner->m_flAnimTime + (flCycle - m_flCycle) / flCycleRate + pOwner->GetAnimTimeInterval();
  469. }
  470. // Msg( "dispatch %d (%d : %.2f)\n", index - 1, event.event, event.eventtime );
  471. event.m_bHandledByScript = eventHandler->HandleScriptedAnimEvent( &event );
  472. if ( eventHandler->HandleBehaviorAnimEvent( &event ) )
  473. {
  474. event.m_bHandledByScript = true;
  475. }
  476. eventHandler->HandleAnimEvent( &event );
  477. }
  478. }
  479. void CBaseAnimatingOverlay::GetSkeleton( CStudioHdr *pStudioHdr, BoneVector pos[], BoneQuaternionAligned q[], int boneMask )
  480. {
  481. if(!pStudioHdr)
  482. {
  483. Assert(!"CBaseAnimating::GetSkeleton() without a model");
  484. return;
  485. }
  486. if (!pStudioHdr->SequencesAvailable())
  487. {
  488. return;
  489. }
  490. IBoneSetup boneSetup( pStudioHdr, boneMask, GetPoseParameterArray() );
  491. boneSetup.InitPose( pos, q );
  492. if ( !m_pIk )
  493. {
  494. EnableServerIK();
  495. m_pIk->Init( pStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, BONE_USED_BY_BONE_MERGE );
  496. }
  497. boneSetup.AccumulatePose( pos, q, GetSequence(), GetCycle(), 1.0, gpGlobals->curtime, m_pIk );
  498. // sort the layers
  499. int layer[MAX_OVERLAYS] = {};
  500. for (int i = 0; i < m_AnimOverlay.Count(); i++)
  501. {
  502. layer[i] = MAX_OVERLAYS;
  503. }
  504. for (int i = 0; i < m_AnimOverlay.Count(); i++)
  505. {
  506. CAnimationLayer &pLayer = m_AnimOverlay[i];
  507. if( (pLayer.m_flWeight > 0) && pLayer.IsActive() && pLayer.m_nOrder >= 0 && pLayer.m_nOrder < m_AnimOverlay.Count())
  508. {
  509. layer[pLayer.m_nOrder] = i;
  510. }
  511. }
  512. // check if this is a player with a valid weapon
  513. // look for weapon, pull layer animations from it if/when they exist
  514. CBaseCombatWeapon *pWeapon = NULL;
  515. CBaseWeaponWorldModel *pWeaponWorldModel = NULL;
  516. bool bDoWeaponSetup = false;
  517. if ( this->IsPlayer() )
  518. {
  519. CCSPlayer *pPlayer = ToCSPlayer(this);
  520. if ( pPlayer && pPlayer->m_bUseNewAnimstate )
  521. {
  522. pWeapon = pPlayer->GetActiveWeapon();
  523. if ( pWeapon )
  524. {
  525. pWeaponWorldModel = pWeapon->m_hWeaponWorldModel.Get();
  526. if ( pWeaponWorldModel &&
  527. pWeaponWorldModel->GetModelPtr() &&
  528. pWeaponWorldModel->HoldsPlayerAnimations() )
  529. {
  530. if ( !pWeaponWorldModel->m_pBoneMergeCache )
  531. {
  532. pWeaponWorldModel->m_pBoneMergeCache = new CBoneMergeCache;
  533. pWeaponWorldModel->m_pBoneMergeCache->Init( pWeaponWorldModel );
  534. }
  535. if ( pWeaponWorldModel->m_pBoneMergeCache )
  536. bDoWeaponSetup = true;
  537. }
  538. }
  539. }
  540. }
  541. if ( bDoWeaponSetup )
  542. {
  543. CStudioHdr *pWeaponStudioHdr = pWeaponWorldModel->GetModelPtr();
  544. // copy matching player pose params to weapon pose params
  545. pWeaponWorldModel->m_pBoneMergeCache->MergeMatchingPoseParams();
  546. // build a temporary setup for the weapon
  547. CIKContext weaponIK;
  548. weaponIK.Init( pWeaponStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, BONE_USED_BY_BONE_MERGE );
  549. IBoneSetup weaponSetup( pWeaponStudioHdr, BONE_USED_BY_BONE_MERGE, pWeaponWorldModel->GetPoseParameterArray() );
  550. BoneVector weaponPos[MAXSTUDIOBONES];
  551. BoneQuaternionAligned weaponQ[MAXSTUDIOBONES];
  552. weaponSetup.InitPose( weaponPos, weaponQ );
  553. for ( int i=0; i < GetNumAnimOverlays(); i++ )
  554. {
  555. CAnimationLayer *pLayer = GetAnimOverlay( i );
  556. if ( pLayer->GetSequence() <= 1 || pLayer->GetWeight() <= 0.0f )
  557. continue;
  558. UpdateDispatchLayer( pLayer, pWeaponStudioHdr, pLayer->GetSequence() );
  559. if ( pLayer->m_nDispatchedDst > 0 && pLayer->m_nDispatchedDst < pWeaponStudioHdr->GetNumSeq() )
  560. {
  561. // copy player bones to weapon setup bones
  562. pWeaponWorldModel->m_pBoneMergeCache->CopyFromFollow( pos, q, BONE_USED_BY_BONE_MERGE, weaponPos, weaponQ );
  563. // respect ik rules on archetypal sequence, even if we're not playing it
  564. if ( m_pIk )
  565. {
  566. mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( pLayer->GetSequence() );
  567. m_pIk->AddDependencies( seqdesc, pLayer->GetSequence(), pLayer->GetCycle(), GetPoseParameterArray(), pLayer->GetWeight() );
  568. }
  569. weaponSetup.AccumulatePose( weaponPos, weaponQ, pLayer->m_nDispatchedDst, pLayer->GetCycle(), pLayer->GetWeight(), gpGlobals->curtime, &weaponIK );
  570. pWeaponWorldModel->m_pBoneMergeCache->CopyToFollow( weaponPos, weaponQ, BONE_USED_BY_BONE_MERGE, pos, q );
  571. weaponIK.CopyTo( m_pIk, pWeaponWorldModel->m_pBoneMergeCache->GetRawIndexMapping() );
  572. }
  573. else
  574. {
  575. boneSetup.AccumulatePose( pos, q, pLayer->GetSequence(), pLayer->GetCycle(), pLayer->GetWeight(), gpGlobals->curtime, m_pIk );
  576. }
  577. }
  578. }
  579. else
  580. {
  581. for (int i = 0; i < m_AnimOverlay.Count(); i++)
  582. {
  583. if (layer[i] >= 0 && layer[i] < m_AnimOverlay.Count())
  584. {
  585. CAnimationLayer &pLayer = m_AnimOverlay[layer[i]];
  586. // UNDONE: Is it correct to use overlay weight for IK too?
  587. boneSetup.AccumulatePose( pos, q, pLayer.m_nSequence, pLayer.m_flCycle, pLayer.m_flWeight, gpGlobals->curtime, m_pIk );
  588. }
  589. }
  590. }
  591. if ( m_pIk )
  592. {
  593. CIKContext auto_ik;
  594. auto_ik.Init( pStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, boneMask );
  595. boneSetup.CalcAutoplaySequences( pos, q, gpGlobals->curtime, &auto_ik );
  596. }
  597. else
  598. {
  599. boneSetup.CalcAutoplaySequences( pos, q, gpGlobals->curtime, NULL );
  600. }
  601. boneSetup.CalcBoneAdj( pos, q, GetEncodedControllerArray() );
  602. // Do we care about local weapon bones on the server? They don't drive hitboxes... so I don't think we do.
  603. //RegenerateDispatchedLayers( boneSetup, pos, q, gpGlobals->curtime );
  604. }
  605. //-----------------------------------------------------------------------------
  606. // Purpose: zero's out all non-restore safe fields
  607. // Output :
  608. //-----------------------------------------------------------------------------
  609. void CBaseAnimatingOverlay::OnRestore( )
  610. {
  611. int i;
  612. // force order of unused layers to current MAX_OVERLAYS
  613. // and Tracker 48843 (Alyx skating after restore) restore the owner entity ptr (otherwise the network layer won't get NetworkStateChanged signals until the layer is re-Init()'ed
  614. for (i = 0; i < m_AnimOverlay.Count(); i++)
  615. {
  616. m_AnimOverlay[i].m_pOwnerEntity = this;
  617. if ( !m_AnimOverlay[i].IsActive())
  618. {
  619. m_AnimOverlay[i].m_nOrder.Set( MAX_OVERLAYS );
  620. }
  621. }
  622. // get rid of all layers that shouldn't be restored
  623. for (i = 0; i < m_AnimOverlay.Count(); i++)
  624. {
  625. if ( ( m_AnimOverlay[i].IsActive() && (m_AnimOverlay[i].m_fFlags & ANIM_LAYER_DONTRESTORE) ) ||
  626. ( GetModelPtr() && !IsValidSequence(m_AnimOverlay[i].m_nSequence) ) )
  627. {
  628. FastRemoveLayer( i );
  629. }
  630. }
  631. BaseClass::OnRestore();
  632. }
  633. //-----------------------------------------------------------------------------
  634. // Purpose:
  635. // Output : int
  636. //-----------------------------------------------------------------------------
  637. int CBaseAnimatingOverlay::AddGestureSequence( int sequence, bool autokill /*= true*/ )
  638. {
  639. int i = AddLayeredSequence( sequence, 0 );
  640. // No room?
  641. if ( IsValidLayer( i ) )
  642. {
  643. SetLayerAutokill( i, autokill );
  644. }
  645. return i;
  646. }
  647. //-----------------------------------------------------------------------------
  648. // Purpose:
  649. // Output : int
  650. //-----------------------------------------------------------------------------
  651. int CBaseAnimatingOverlay::AddGestureSequence( int nSequence, float flDuration, bool autokill /*= true*/ )
  652. {
  653. int iLayer = AddGestureSequence( nSequence, autokill );
  654. Assert( iLayer != -1 );
  655. if (iLayer >= 0 && flDuration > 0)
  656. {
  657. m_AnimOverlay[iLayer].m_flPlaybackRate = SequenceDuration( nSequence ) / flDuration;
  658. }
  659. return iLayer;
  660. }
  661. //------------------------------------------------------------------------------
  662. // Purpose :
  663. // Input :
  664. // Output :
  665. //------------------------------------------------------------------------------
  666. int CBaseAnimatingOverlay::AddGesture( Activity activity, bool autokill /*= true*/ )
  667. {
  668. if ( IsPlayingGesture( activity ) )
  669. {
  670. return FindGestureLayer( activity );
  671. }
  672. MDLCACHE_CRITICAL_SECTION();
  673. int seq = SelectWeightedSequence( activity );
  674. if ( seq <= 0 )
  675. {
  676. const char *actname = CAI_BaseNPC::GetActivityName( activity );
  677. DevMsg( "CBaseAnimatingOverlay::AddGesture: model %s missing activity %s\n", STRING(GetModelName()), actname );
  678. return -1;
  679. }
  680. int i = AddGestureSequence( seq, autokill );
  681. Assert( i != -1 );
  682. if ( i != -1 )
  683. {
  684. m_AnimOverlay[ i ].m_nActivity = activity;
  685. }
  686. return i;
  687. }
  688. int CBaseAnimatingOverlay::AddGesture( Activity activity, float flDuration, bool autokill /*= true*/ )
  689. {
  690. int iLayer = AddGesture( activity, autokill );
  691. SetLayerDuration( iLayer, flDuration );
  692. return iLayer;
  693. }
  694. //-----------------------------------------------------------------------------
  695. // Purpose:
  696. // Output : int
  697. //-----------------------------------------------------------------------------
  698. void CBaseAnimatingOverlay::SetLayerDuration( int iLayer, float flDuration )
  699. {
  700. if (IsValidLayer( iLayer ) && flDuration > 0)
  701. {
  702. m_AnimOverlay[iLayer].m_flPlaybackRate = SequenceDuration( m_AnimOverlay[iLayer].m_nSequence ) / flDuration;
  703. }
  704. }
  705. //-----------------------------------------------------------------------------
  706. // Purpose:
  707. // Output : int
  708. //-----------------------------------------------------------------------------
  709. float CBaseAnimatingOverlay::GetLayerDuration( int iLayer )
  710. {
  711. if (IsValidLayer( iLayer ))
  712. {
  713. if (m_AnimOverlay[iLayer].m_flPlaybackRate != 0.0f)
  714. {
  715. return (1.0 - m_AnimOverlay[iLayer].m_flCycle) * SequenceDuration( m_AnimOverlay[iLayer].m_nSequence ) / m_AnimOverlay[iLayer].m_flPlaybackRate;
  716. }
  717. return SequenceDuration( m_AnimOverlay[iLayer].m_nSequence );
  718. }
  719. return 0.0;
  720. }
  721. //-----------------------------------------------------------------------------
  722. // Purpose:
  723. // Output : int
  724. //-----------------------------------------------------------------------------
  725. int CBaseAnimatingOverlay::AddLayeredSequence( int sequence, int iPriority )
  726. {
  727. int i = AllocateLayer( iPriority );
  728. // No room?
  729. if ( IsValidLayer( i ) )
  730. {
  731. m_AnimOverlay[i].m_flCycle = 0;
  732. m_AnimOverlay[i].m_flPrevCycle = 0;
  733. m_AnimOverlay[i].m_flPlaybackRate = 1.0;
  734. m_AnimOverlay[i].m_nActivity = ACT_INVALID;
  735. m_AnimOverlay[i].m_nSequence = sequence;
  736. m_AnimOverlay[i].m_flWeight = 1.0f;
  737. m_AnimOverlay[i].m_flBlendIn = 0.0f;
  738. m_AnimOverlay[i].m_flBlendOut = 0.0f;
  739. m_AnimOverlay[i].m_bSequenceFinished = false;
  740. m_AnimOverlay[i].m_flLastEventCheck = 0;
  741. m_AnimOverlay[i].m_bLooping = ((GetSequenceFlags( GetModelPtr(), sequence ) & STUDIO_LOOPING) != 0);
  742. if (ai_sequence_debug.GetBool() == true && m_debugOverlays & OVERLAY_NPC_SELECTED_BIT)
  743. {
  744. Msg("%5.3f : adding %d (%d): %s : %5.3f (%.3f)\n", gpGlobals->curtime, i, m_AnimOverlay[ i ].m_nOrder.Get(), GetSequenceName( m_AnimOverlay[ i ].m_nSequence ), m_AnimOverlay[ i ].m_flCycle.Get(), m_AnimOverlay[ i ].m_flWeight.Get() );
  745. }
  746. }
  747. return i;
  748. }
  749. //-----------------------------------------------------------------------------
  750. // Purpose:
  751. // Output : int
  752. //-----------------------------------------------------------------------------
  753. bool CBaseAnimatingOverlay::IsValidLayer( int iLayer )
  754. {
  755. return (iLayer >= 0 && iLayer < m_AnimOverlay.Count() && m_AnimOverlay[iLayer].IsActive());
  756. }
  757. //-----------------------------------------------------------------------------
  758. // Purpose:
  759. // Output : int
  760. //-----------------------------------------------------------------------------
  761. int CBaseAnimatingOverlay::AllocateLayer( int iPriority )
  762. {
  763. int i;
  764. // look for an open slot and for existing layers that are lower priority
  765. int iNewOrder = 0;
  766. int iOpenLayer = -1;
  767. int iNumOpen = 0;
  768. for (i = 0; i < m_AnimOverlay.Count(); i++)
  769. {
  770. if ( m_AnimOverlay[i].IsActive() )
  771. {
  772. if (m_AnimOverlay[i].m_nPriority <= iPriority)
  773. {
  774. iNewOrder = MAX( iNewOrder, m_AnimOverlay[i].m_nOrder + 1 );
  775. }
  776. }
  777. else if (m_AnimOverlay[ i ].IsDying())
  778. {
  779. // skip
  780. }
  781. else if (iOpenLayer == -1)
  782. {
  783. iOpenLayer = i;
  784. }
  785. else
  786. {
  787. iNumOpen++;
  788. }
  789. }
  790. if (iOpenLayer == -1)
  791. {
  792. if (m_AnimOverlay.Count() >= MAX_OVERLAYS)
  793. {
  794. return -1;
  795. }
  796. iOpenLayer = m_AnimOverlay.AddToTail();
  797. m_AnimOverlay[iOpenLayer].Init( this );
  798. m_AnimOverlay[iOpenLayer].NetworkStateChanged();
  799. }
  800. // make sure there's always an empty unused layer so that history slots will be available on the client when it is used
  801. if (iNumOpen == 0)
  802. {
  803. if (m_AnimOverlay.Count() < MAX_OVERLAYS)
  804. {
  805. i = m_AnimOverlay.AddToTail();
  806. m_AnimOverlay[i].Init( this );
  807. m_AnimOverlay[i].NetworkStateChanged();
  808. }
  809. }
  810. for (i = 0; i < m_AnimOverlay.Count(); i++)
  811. {
  812. if ( m_AnimOverlay[i].m_nOrder >= iNewOrder && m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS)
  813. {
  814. m_AnimOverlay[i].m_nOrder++;
  815. }
  816. }
  817. m_AnimOverlay[iOpenLayer].m_fFlags = ANIM_LAYER_ACTIVE;
  818. m_AnimOverlay[iOpenLayer].m_nOrder = iNewOrder;
  819. m_AnimOverlay[iOpenLayer].m_nPriority = iPriority;
  820. m_AnimOverlay[iOpenLayer].MarkActive();
  821. VerifyOrder();
  822. return iOpenLayer;
  823. }
  824. //-----------------------------------------------------------------------------
  825. // Purpose:
  826. // Output : int
  827. //-----------------------------------------------------------------------------
  828. void CBaseAnimatingOverlay::SetLayerPriority( int iLayer, int iPriority )
  829. {
  830. if (!IsValidLayer( iLayer ))
  831. {
  832. return;
  833. }
  834. if (m_AnimOverlay[iLayer].m_nPriority == iPriority)
  835. {
  836. return;
  837. }
  838. // look for an open slot and for existing layers that are lower priority
  839. int i;
  840. for (i = 0; i < m_AnimOverlay.Count(); i++)
  841. {
  842. if ( m_AnimOverlay[i].IsActive() )
  843. {
  844. if (m_AnimOverlay[i].m_nOrder > m_AnimOverlay[iLayer].m_nOrder)
  845. {
  846. m_AnimOverlay[i].m_nOrder--;
  847. }
  848. }
  849. }
  850. int iNewOrder = 0;
  851. for (i = 0; i < m_AnimOverlay.Count(); i++)
  852. {
  853. if ( i != iLayer && m_AnimOverlay[i].IsActive() )
  854. {
  855. if (m_AnimOverlay[i].m_nPriority <= iPriority)
  856. {
  857. iNewOrder = MAX( iNewOrder, m_AnimOverlay[i].m_nOrder + 1 );
  858. }
  859. }
  860. }
  861. for (i = 0; i < m_AnimOverlay.Count(); i++)
  862. {
  863. if ( i != iLayer && m_AnimOverlay[i].IsActive() )
  864. {
  865. if ( m_AnimOverlay[i].m_nOrder >= iNewOrder)
  866. {
  867. m_AnimOverlay[i].m_nOrder++;
  868. }
  869. }
  870. }
  871. m_AnimOverlay[iLayer].m_nOrder = iNewOrder;
  872. m_AnimOverlay[iLayer].m_nPriority = iPriority;
  873. m_AnimOverlay[iLayer].MarkActive( );
  874. VerifyOrder();
  875. return;
  876. }
  877. //-----------------------------------------------------------------------------
  878. // Purpose:
  879. // Input : activity -
  880. //-----------------------------------------------------------------------------
  881. int CBaseAnimatingOverlay::FindGestureLayer( Activity activity )
  882. {
  883. for (int i = 0; i < m_AnimOverlay.Count(); i++)
  884. {
  885. if ( !(m_AnimOverlay[i].IsActive()) )
  886. continue;
  887. if ( m_AnimOverlay[i].IsKillMe() )
  888. continue;
  889. if ( m_AnimOverlay[i].m_nActivity == ACT_INVALID )
  890. continue;
  891. if ( m_AnimOverlay[i].m_nActivity == activity )
  892. return i;
  893. }
  894. return -1;
  895. }
  896. //-----------------------------------------------------------------------------
  897. // Purpose:
  898. // Input : activity -
  899. // Output : Returns true on success, false on failure.
  900. //-----------------------------------------------------------------------------
  901. bool CBaseAnimatingOverlay::IsPlayingGesture( Activity activity )
  902. {
  903. return FindGestureLayer( activity ) != -1 ? true : false;
  904. }
  905. //-----------------------------------------------------------------------------
  906. // Purpose:
  907. // Input : activity -
  908. //-----------------------------------------------------------------------------
  909. void CBaseAnimatingOverlay::RestartGesture( Activity activity, bool addifmissing /*=true*/, bool autokill /*=true*/ )
  910. {
  911. int idx = FindGestureLayer( activity );
  912. if ( idx == -1 )
  913. {
  914. if ( addifmissing )
  915. {
  916. AddGesture( activity, autokill );
  917. }
  918. return;
  919. }
  920. m_AnimOverlay[ idx ].m_flCycle = 0.0f;
  921. m_AnimOverlay[ idx ].m_flPrevCycle = 0.0f;
  922. m_AnimOverlay[ idx ].m_flLastEventCheck = 0.0f;
  923. }
  924. //-----------------------------------------------------------------------------
  925. // Purpose:
  926. // Input : activity -
  927. //-----------------------------------------------------------------------------
  928. void CBaseAnimatingOverlay::RemoveGesture( Activity activity )
  929. {
  930. int iLayer = FindGestureLayer( activity );
  931. if ( iLayer == -1 )
  932. return;
  933. RemoveLayer( iLayer );
  934. }
  935. //-----------------------------------------------------------------------------
  936. // Purpose:
  937. //-----------------------------------------------------------------------------
  938. void CBaseAnimatingOverlay::RemoveAllGestures( void )
  939. {
  940. for (int i = 0; i < m_AnimOverlay.Count(); i++)
  941. {
  942. RemoveLayer( i );
  943. }
  944. }
  945. //-----------------------------------------------------------------------------
  946. // Purpose:
  947. //-----------------------------------------------------------------------------
  948. void CBaseAnimatingOverlay::SetLayerCycle( int iLayer, float flCycle )
  949. {
  950. if (!IsValidLayer( iLayer ))
  951. return;
  952. if (!m_AnimOverlay[iLayer].m_bLooping)
  953. {
  954. flCycle = clamp( flCycle, 0.0, 1.0 );
  955. }
  956. m_AnimOverlay[iLayer].m_flCycle = flCycle;
  957. m_AnimOverlay[iLayer].MarkActive( );
  958. }
  959. //-----------------------------------------------------------------------------
  960. // Purpose:
  961. //-----------------------------------------------------------------------------
  962. void CBaseAnimatingOverlay::SetLayerCycle( int iLayer, float flCycle, float flPrevCycle )
  963. {
  964. if (!IsValidLayer( iLayer ))
  965. return;
  966. if (!m_AnimOverlay[iLayer].m_bLooping)
  967. {
  968. flCycle = clamp( flCycle, 0.0, 1.0 );
  969. flPrevCycle = clamp( flPrevCycle, 0.0, 1.0 );
  970. }
  971. m_AnimOverlay[iLayer].m_flCycle = flCycle;
  972. m_AnimOverlay[iLayer].m_flPrevCycle = flPrevCycle;
  973. m_AnimOverlay[iLayer].m_flLastEventCheck = flPrevCycle;
  974. m_AnimOverlay[iLayer].MarkActive( );
  975. }
  976. //-----------------------------------------------------------------------------
  977. // Purpose:
  978. //-----------------------------------------------------------------------------
  979. float CBaseAnimatingOverlay::GetLayerCycle( int iLayer )
  980. {
  981. if (!IsValidLayer( iLayer ))
  982. return 0.0;
  983. return m_AnimOverlay[iLayer].m_flCycle;
  984. }
  985. //-----------------------------------------------------------------------------
  986. // Purpose:
  987. //-----------------------------------------------------------------------------
  988. void CBaseAnimatingOverlay::SetLayerPlaybackRate( int iLayer, float flPlaybackRate )
  989. {
  990. if (!IsValidLayer( iLayer ))
  991. return;
  992. Assert( flPlaybackRate > -1.0 && flPlaybackRate < 40.0);
  993. m_AnimOverlay[iLayer].m_flPlaybackRate = flPlaybackRate;
  994. }
  995. //-----------------------------------------------------------------------------
  996. // Purpose:
  997. //-----------------------------------------------------------------------------
  998. void CBaseAnimatingOverlay::SetLayerWeight( int iLayer, float flWeight )
  999. {
  1000. if (!IsValidLayer( iLayer ))
  1001. return;
  1002. flWeight = clamp( flWeight, 0.0f, 1.0f );
  1003. m_AnimOverlay[iLayer].m_flWeight = flWeight;
  1004. m_AnimOverlay[iLayer].MarkActive( );
  1005. }
  1006. //-----------------------------------------------------------------------------
  1007. // Purpose:
  1008. //-----------------------------------------------------------------------------
  1009. float CBaseAnimatingOverlay::GetLayerWeight( int iLayer )
  1010. {
  1011. if (!IsValidLayer( iLayer ))
  1012. return 0.0;
  1013. return m_AnimOverlay[iLayer].m_flWeight;
  1014. }
  1015. //-----------------------------------------------------------------------------
  1016. // Purpose:
  1017. //-----------------------------------------------------------------------------
  1018. void CBaseAnimatingOverlay::SetLayerBlendIn( int iLayer, float flBlendIn )
  1019. {
  1020. if (!IsValidLayer( iLayer ))
  1021. return;
  1022. m_AnimOverlay[iLayer].m_flBlendIn = flBlendIn;
  1023. }
  1024. //-----------------------------------------------------------------------------
  1025. // Purpose:
  1026. //-----------------------------------------------------------------------------
  1027. void CBaseAnimatingOverlay::SetLayerBlendOut( int iLayer, float flBlendOut )
  1028. {
  1029. if (!IsValidLayer( iLayer ))
  1030. return;
  1031. m_AnimOverlay[iLayer].m_flBlendOut = flBlendOut;
  1032. }
  1033. //-----------------------------------------------------------------------------
  1034. // Purpose:
  1035. //-----------------------------------------------------------------------------
  1036. void CBaseAnimatingOverlay::SetLayerAutokill( int iLayer, bool bAutokill )
  1037. {
  1038. if (!IsValidLayer( iLayer ))
  1039. return;
  1040. if (bAutokill)
  1041. {
  1042. m_AnimOverlay[iLayer].m_fFlags |= ANIM_LAYER_AUTOKILL;
  1043. }
  1044. else
  1045. {
  1046. m_AnimOverlay[iLayer].m_fFlags &= ~ANIM_LAYER_AUTOKILL;
  1047. }
  1048. }
  1049. //-----------------------------------------------------------------------------
  1050. // Purpose:
  1051. //-----------------------------------------------------------------------------
  1052. void CBaseAnimatingOverlay::SetLayerLooping( int iLayer, bool bLooping )
  1053. {
  1054. if (!IsValidLayer( iLayer ))
  1055. return;
  1056. m_AnimOverlay[iLayer].m_bLooping = bLooping;
  1057. }
  1058. //-----------------------------------------------------------------------------
  1059. // Purpose:
  1060. //-----------------------------------------------------------------------------
  1061. void CBaseAnimatingOverlay::SetLayerNoRestore( int iLayer, bool bNoRestore )
  1062. {
  1063. if (!IsValidLayer( iLayer ))
  1064. return;
  1065. if (bNoRestore)
  1066. {
  1067. m_AnimOverlay[iLayer].m_fFlags |= ANIM_LAYER_DONTRESTORE;
  1068. }
  1069. else
  1070. {
  1071. m_AnimOverlay[iLayer].m_fFlags &= ~ANIM_LAYER_DONTRESTORE;
  1072. }
  1073. }
  1074. //-----------------------------------------------------------------------------
  1075. // Purpose:
  1076. //-----------------------------------------------------------------------------
  1077. void CBaseAnimatingOverlay::SetLayerNoEvents( int iLayer, bool bNoEvents )
  1078. {
  1079. if (!IsValidLayer( iLayer ))
  1080. return;
  1081. if (bNoEvents)
  1082. {
  1083. m_AnimOverlay[iLayer].m_fFlags |= ANIM_LAYER_NOEVENTS;
  1084. }
  1085. else
  1086. {
  1087. m_AnimOverlay[iLayer].m_fFlags &= ~ANIM_LAYER_NOEVENTS;
  1088. }
  1089. }
  1090. //-----------------------------------------------------------------------------
  1091. // Purpose:
  1092. //-----------------------------------------------------------------------------
  1093. Activity CBaseAnimatingOverlay::GetLayerActivity( int iLayer )
  1094. {
  1095. if (!IsValidLayer( iLayer ))
  1096. {
  1097. return ACT_INVALID;
  1098. }
  1099. return m_AnimOverlay[iLayer].m_nActivity;
  1100. }
  1101. //-----------------------------------------------------------------------------
  1102. // Purpose:
  1103. //-----------------------------------------------------------------------------
  1104. int CBaseAnimatingOverlay::GetLayerSequence( int iLayer )
  1105. {
  1106. if (!IsValidLayer( iLayer ))
  1107. {
  1108. return ACT_INVALID;
  1109. }
  1110. return m_AnimOverlay[iLayer].m_nSequence;
  1111. }
  1112. //-----------------------------------------------------------------------------
  1113. // Purpose:
  1114. //-----------------------------------------------------------------------------
  1115. void CBaseAnimatingOverlay::RemoveLayer( int iLayer, float flKillRate, float flKillDelay )
  1116. {
  1117. if (!IsValidLayer( iLayer ))
  1118. return;
  1119. if (flKillRate > 0)
  1120. {
  1121. m_AnimOverlay[iLayer].m_flKillRate = m_AnimOverlay[iLayer].m_flWeight / flKillRate;
  1122. }
  1123. else
  1124. {
  1125. m_AnimOverlay[iLayer].m_flKillRate = 100;
  1126. }
  1127. m_AnimOverlay[iLayer].m_flKillDelay = flKillDelay;
  1128. m_AnimOverlay[iLayer].KillMe();
  1129. }
  1130. void CBaseAnimatingOverlay::FastRemoveLayer( int iLayer )
  1131. {
  1132. if (!IsValidLayer( iLayer ))
  1133. return;
  1134. // shift the other layers down in order
  1135. for (int j = 0; j < m_AnimOverlay.Count(); j++ )
  1136. {
  1137. if ((m_AnimOverlay[ j ].IsActive()) && m_AnimOverlay[ j ].m_nOrder > m_AnimOverlay[ iLayer ].m_nOrder)
  1138. {
  1139. m_AnimOverlay[ j ].m_nOrder--;
  1140. }
  1141. }
  1142. m_AnimOverlay[ iLayer ].Init( this );
  1143. VerifyOrder();
  1144. }
  1145. CAnimationLayer *CBaseAnimatingOverlay::GetAnimOverlay( int iIndex, bool bUseOrder )
  1146. {
  1147. iIndex = clamp( iIndex, 0, m_AnimOverlay.Count()-1 );
  1148. if ( !m_AnimOverlay.Count() )
  1149. return NULL;
  1150. if ( bUseOrder )
  1151. {
  1152. FOR_EACH_VEC( m_AnimOverlay, j )
  1153. {
  1154. if ( m_AnimOverlay[j].m_nOrder == iIndex )
  1155. return &m_AnimOverlay[j];
  1156. }
  1157. }
  1158. return &m_AnimOverlay[iIndex];
  1159. }
  1160. void CBaseAnimatingOverlay::SetNumAnimOverlays( int num )
  1161. {
  1162. if ( m_AnimOverlay.Count() < num )
  1163. {
  1164. m_AnimOverlay.AddMultipleToTail( num - m_AnimOverlay.Count() );
  1165. NetworkStateChanged();
  1166. }
  1167. else if ( m_AnimOverlay.Count() > num )
  1168. {
  1169. m_AnimOverlay.RemoveMultiple( num, m_AnimOverlay.Count() - num );
  1170. NetworkStateChanged();
  1171. }
  1172. }
  1173. bool CBaseAnimatingOverlay::HasActiveLayer( void )
  1174. {
  1175. for (int j = 0; j < m_AnimOverlay.Count(); j++ )
  1176. {
  1177. if ( m_AnimOverlay[ j ].IsActive() )
  1178. return true;
  1179. }
  1180. return false;
  1181. }
  1182. bool CBaseAnimatingOverlay::UpdateDispatchLayer( CAnimationLayer *pLayer, CStudioHdr *pWeaponStudioHdr, int iSequence )
  1183. {
  1184. if ( !pWeaponStudioHdr || !pLayer )
  1185. {
  1186. if ( pLayer )
  1187. pLayer->m_nDispatchedDst = ACT_INVALID;
  1188. return false;
  1189. }
  1190. if ( pLayer->m_pDispatchedStudioHdr != pWeaponStudioHdr || pLayer->m_nDispatchedSrc != iSequence || pLayer->m_nDispatchedDst >= pWeaponStudioHdr->GetNumSeq() )
  1191. {
  1192. pLayer->m_pDispatchedStudioHdr = pWeaponStudioHdr;
  1193. pLayer->m_nDispatchedSrc = iSequence;
  1194. if ( pWeaponStudioHdr )
  1195. {
  1196. const char *pszLayerName = GetSequenceName( iSequence );
  1197. pLayer->m_nDispatchedDst = pWeaponStudioHdr->LookupSequence( pszLayerName );
  1198. }
  1199. else
  1200. {
  1201. pLayer->m_nDispatchedDst = ACT_INVALID;
  1202. }
  1203. }
  1204. return (pLayer->m_nDispatchedDst != ACT_INVALID );
  1205. }