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.

1872 lines
58 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "tier0/vprof.h"
  8. #include "animation.h"
  9. #include "studio.h"
  10. #include "apparent_velocity_helper.h"
  11. #include "utldict.h"
  12. #include "multiplayer_animstate.h"
  13. #include "activitylist.h"
  14. #include "basecombatweapon_shared.h"
  15. #include "datacache/imdlcache.h"
  16. #ifdef CLIENT_DLL
  17. #include "c_baseplayer.h"
  18. #include "engine/ivdebugoverlay.h"
  19. #include "filesystem.h"
  20. #include "eventlist.h"
  21. #ifdef DEMOPOLISH_ENABLED
  22. #include "demo_polish/demo_polish.h"
  23. #endif
  24. ConVar anim_showmainactivity( "anim_showmainactivity", "0", FCVAR_CHEAT, "Show the idle, walk, run, and/or sprint activities." );
  25. #else
  26. #include "player.h"
  27. #endif
  28. #if defined( PORTAL ) && defined( CLIENT_DLL )
  29. #include "c_portal_player.h"
  30. #endif
  31. // NOTE: This has to be the last file included!
  32. #include "tier0/memdbgon.h"
  33. #define MOVING_MINIMUM_SPEED 0.5f
  34. ConVar anim_showstate( "anim_showstate", "-1", FCVAR_CHEAT | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Show the (client) animation state for the specified entity (-1 for none)." );
  35. ConVar anim_showstatelog( "anim_showstatelog", "0", FCVAR_CHEAT | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "1 to output anim_showstate to Msg(). 2 to store in AnimState.log. 3 for both." );
  36. ConVar mp_showgestureslots( "mp_showgestureslots", "-1", FCVAR_CHEAT | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Show multiplayer client/server gesture slot information for the specified player index (-1 for no one)." );
  37. ConVar mp_slammoveyaw( "mp_slammoveyaw", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Force movement yaw along an animation path." );
  38. mstudioevent_for_client_server_t *GetEventIndexForSequence( mstudioseqdesc_t &seqdesc );
  39. //-----------------------------------------------------------------------------
  40. // Purpose:
  41. // Input : *pPlayer -
  42. // &movementData -
  43. //-----------------------------------------------------------------------------
  44. CMultiPlayerAnimState::CMultiPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData )
  45. #ifdef CLIENT_DLL
  46. : m_iv_flMaxGroundSpeed( "CMultiPlayerAnimState::m_iv_flMaxGroundSpeed" )
  47. #endif
  48. {
  49. // Pose parameters.
  50. m_bPoseParameterInit = false;
  51. m_PoseParameterData.Init();
  52. m_DebugAnimData.Init();
  53. m_pPlayer = NULL;
  54. m_angRender.Init();
  55. m_bCurrentFeetYawInitialized = false;
  56. m_flLastAnimationStateClearTime = 0.0f;
  57. m_flEyeYaw = 0.0f;
  58. m_flEyePitch = 0.0f;
  59. m_flGoalFeetYaw = 0.0f;
  60. m_flCurrentFeetYaw = 0.0f;
  61. m_flLastAimTurnTime = 0.0f;
  62. // Jumping.
  63. m_bJumping = false;
  64. m_flJumpStartTime = 0.0f;
  65. m_bFirstJumpFrame = false;
  66. // Swimming
  67. m_bInSwim = false;
  68. m_bFirstSwimFrame = true;
  69. // Dying
  70. m_bDying = false;
  71. m_bFirstDyingFrame = true;
  72. m_eCurrentMainSequenceActivity = ACT_INVALID;
  73. m_nSpecificMainSequence = -1;
  74. // Weapon data.
  75. m_hActiveWeapon = NULL;
  76. // Ground speed interpolators.
  77. #ifdef CLIENT_DLL
  78. m_iv_flMaxGroundSpeed.Setup( &m_flMaxGroundSpeed, LATCH_ANIMATION_VAR | INTERPOLATE_LINEAR_ONLY );
  79. m_flLastGroundSpeedUpdateTime = 0.0f;
  80. #endif
  81. m_flMaxGroundSpeed = 0.0f;
  82. m_bForceAimYaw = false;
  83. Init( pPlayer, movementData );
  84. InitGestureSlots();
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose:
  88. // Input : -
  89. //-----------------------------------------------------------------------------
  90. CMultiPlayerAnimState::~CMultiPlayerAnimState()
  91. {
  92. ShutdownGestureSlots();
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose:
  96. // Input : *pPlayer -
  97. // &movementData -
  98. //-----------------------------------------------------------------------------
  99. void CMultiPlayerAnimState::Init( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData )
  100. {
  101. // Get the player this animation data works on.
  102. m_pPlayer = pPlayer;
  103. // Copy the movement data.
  104. memcpy( &m_MovementData, &movementData, sizeof( MultiPlayerMovementData_t ) );
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose:
  108. // Input : -
  109. //-----------------------------------------------------------------------------
  110. void CMultiPlayerAnimState::ClearAnimationState()
  111. {
  112. // Reset state.
  113. m_bJumping = false;
  114. m_bDying = false;
  115. m_bCurrentFeetYawInitialized = false;
  116. m_flLastAnimationStateClearTime = gpGlobals->curtime;
  117. ResetGestureSlots();
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Purpose:
  121. // Input : event -
  122. //-----------------------------------------------------------------------------
  123. void CMultiPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
  124. {
  125. switch( event )
  126. {
  127. case PLAYERANIMEVENT_ATTACK_PRIMARY:
  128. {
  129. // Weapon primary fire.
  130. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE );
  131. break;
  132. }
  133. case PLAYERANIMEVENT_ATTACK_SECONDARY:
  134. {
  135. // Weapon secondary fire.
  136. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_SECONDARYFIRE );
  137. break;
  138. }
  139. case PLAYERANIMEVENT_ATTACK_GRENADE:
  140. {
  141. // Grenade throw.
  142. RestartGesture( GESTURE_SLOT_GRENADE, ACT_MP_ATTACK_STAND_GRENADE );
  143. break;
  144. }
  145. case PLAYERANIMEVENT_RELOAD:
  146. {
  147. // Weapon reload.
  148. if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
  149. {
  150. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH );
  151. }
  152. else if ( m_bInSwim )
  153. {
  154. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_SWIM );
  155. }
  156. else
  157. {
  158. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND );
  159. }
  160. break;
  161. }
  162. case PLAYERANIMEVENT_RELOAD_LOOP:
  163. {
  164. // Weapon reload.
  165. if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
  166. {
  167. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH_LOOP );
  168. }
  169. else if ( m_bInSwim )
  170. {
  171. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_SWIM_LOOP );
  172. }
  173. else
  174. {
  175. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND_LOOP );
  176. }
  177. break;
  178. }
  179. case PLAYERANIMEVENT_RELOAD_END:
  180. {
  181. // Weapon reload.
  182. if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
  183. {
  184. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH_END );
  185. }
  186. else if ( m_bInSwim )
  187. {
  188. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_SWIM_END );
  189. }
  190. else
  191. {
  192. RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND_END );
  193. }
  194. break;
  195. }
  196. case PLAYERANIMEVENT_JUMP:
  197. {
  198. // Jump.
  199. m_bJumping = true;
  200. m_bFirstJumpFrame = true;
  201. m_flJumpStartTime = gpGlobals->curtime;
  202. RestartMainSequence();
  203. #if defined( CLIENT_DLL ) && defined( DEMO_POLISH )
  204. // Notify demo polish recorder
  205. if ( IsDemoPolishEnabled() && IsDemoPolishRecording() )
  206. {
  207. DemoPolish_GetRecorder().RecordJumpEvent( GetBasePlayer()->entindex() );
  208. }
  209. #endif
  210. break;
  211. }
  212. case PLAYERANIMEVENT_DIE:
  213. {
  214. // Should be here - not supporting this yet!
  215. Assert( 0 );
  216. // Start playing the death animation
  217. m_bDying = true;
  218. RestartMainSequence();
  219. break;
  220. }
  221. case PLAYERANIMEVENT_SPAWN:
  222. {
  223. // Player has respawned. Clear flags.
  224. ClearAnimationState();
  225. break;
  226. }
  227. case PLAYERANIMEVENT_SNAP_YAW:
  228. m_PoseParameterData.m_flLastAimTurnTime = 0.0f;
  229. break;
  230. case PLAYERANIMEVENT_CUSTOM:
  231. {
  232. Activity iIdealActivity = TranslateActivity( (Activity)nData );
  233. m_nSpecificMainSequence = GetBasePlayer()->SelectWeightedSequence( iIdealActivity );
  234. RestartMainSequence();
  235. }
  236. break;
  237. case PLAYERANIMEVENT_CUSTOM_GESTURE:
  238. // Weapon primary fire.
  239. RestartGesture( GESTURE_SLOT_CUSTOM, (Activity)nData );
  240. break;
  241. case PLAYERANIMEVENT_CUSTOM_SEQUENCE:
  242. m_nSpecificMainSequence = nData;
  243. RestartMainSequence();
  244. break;
  245. case PLAYERANIMEVENT_CUSTOM_GESTURE_SEQUENCE:
  246. // Weapon primary fire.
  247. // RestartGestureSequence( nData, false );
  248. break;
  249. case PLAYERANIMEVENT_FLINCH_CHEST:
  250. PlayFlinchGesture( ACT_MP_GESTURE_FLINCH_CHEST );
  251. break;
  252. case PLAYERANIMEVENT_FLINCH_HEAD:
  253. PlayFlinchGesture( ACT_MP_GESTURE_FLINCH_HEAD );
  254. break;
  255. case PLAYERANIMEVENT_FLINCH_LEFTARM:
  256. PlayFlinchGesture( ACT_MP_GESTURE_FLINCH_LEFTARM );
  257. break;
  258. case PLAYERANIMEVENT_FLINCH_RIGHTARM:
  259. PlayFlinchGesture( ACT_MP_GESTURE_FLINCH_RIGHTARM );
  260. break;
  261. case PLAYERANIMEVENT_FLINCH_LEFTLEG:
  262. PlayFlinchGesture( ACT_MP_GESTURE_FLINCH_LEFTLEG );
  263. break;
  264. case PLAYERANIMEVENT_FLINCH_RIGHTLEG:
  265. PlayFlinchGesture( ACT_MP_GESTURE_FLINCH_RIGHTLEG );
  266. break;
  267. default:
  268. break;
  269. }
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Purpose:
  273. //-----------------------------------------------------------------------------
  274. void CMultiPlayerAnimState::PlayFlinchGesture( Activity iActivity )
  275. {
  276. if ( !IsGestureSlotActive( GESTURE_SLOT_FLINCH ) )
  277. {
  278. // See if we have the custom flinch. If not, revert to chest
  279. if ( iActivity != ACT_MP_GESTURE_FLINCH_CHEST && GetBasePlayer()->SelectWeightedSequence( iActivity ) == -1 )
  280. {
  281. RestartGesture( GESTURE_SLOT_FLINCH, ACT_MP_GESTURE_FLINCH_CHEST );
  282. }
  283. else
  284. {
  285. RestartGesture( GESTURE_SLOT_FLINCH, iActivity );
  286. }
  287. }
  288. }
  289. //=============================================================================
  290. //
  291. // Multiplayer gesture code.
  292. //
  293. //-----------------------------------------------------------------------------
  294. // Purpose:
  295. //-----------------------------------------------------------------------------
  296. bool CMultiPlayerAnimState::InitGestureSlots( void )
  297. {
  298. // Get the base player.
  299. CBasePlayer *pPlayer = GetBasePlayer();
  300. if( pPlayer )
  301. {
  302. // Set the number of animation overlays we will use.
  303. pPlayer->SetNumAnimOverlays( GESTURE_SLOT_COUNT );
  304. }
  305. // Setup the number of gesture slots.
  306. m_aGestureSlots.AddMultipleToTail( GESTURE_SLOT_COUNT );
  307. MDLCACHE_CRITICAL_SECTION();
  308. for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture )
  309. {
  310. m_aGestureSlots[iGesture].m_pAnimLayer = pPlayer->GetAnimOverlay( iGesture );
  311. if ( !m_aGestureSlots[iGesture].m_pAnimLayer )
  312. return false;
  313. ResetGestureSlot( iGesture );
  314. }
  315. return true;
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Purpose:
  319. //-----------------------------------------------------------------------------
  320. void CMultiPlayerAnimState::ShutdownGestureSlots( void )
  321. {
  322. // Clean up the gesture slots.
  323. m_aGestureSlots.Purge();
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Purpose:
  327. //-----------------------------------------------------------------------------
  328. void CMultiPlayerAnimState::ResetGestureSlots( void )
  329. {
  330. // Clear out all the gesture slots.
  331. for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture )
  332. {
  333. ResetGestureSlot( iGesture );
  334. }
  335. }
  336. //-----------------------------------------------------------------------------
  337. // Purpose:
  338. //-----------------------------------------------------------------------------
  339. void CMultiPlayerAnimState::ResetGestureSlot( int iGestureSlot )
  340. {
  341. // Sanity Check
  342. Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
  343. GestureSlot_t *pGestureSlot = &m_aGestureSlots[iGestureSlot];
  344. if ( pGestureSlot )
  345. {
  346. #ifdef CLIENT_DLL
  347. // briefly set to 1.0 so we catch the events, before we reset the slot
  348. pGestureSlot->m_pAnimLayer->SetCycle( 1.0 );
  349. RunGestureSlotAnimEventsToCompletion( pGestureSlot );
  350. #endif
  351. pGestureSlot->m_iGestureSlot = GESTURE_SLOT_INVALID;
  352. pGestureSlot->m_iActivity = ACT_INVALID;
  353. pGestureSlot->m_bAutoKill = false;
  354. pGestureSlot->m_bActive = false;
  355. if ( pGestureSlot->m_pAnimLayer )
  356. {
  357. pGestureSlot->m_pAnimLayer->SetOrder( CBaseAnimatingOverlay::MAX_OVERLAYS );
  358. #ifdef CLIENT_DLL
  359. pGestureSlot->m_pAnimLayer->Reset();
  360. #endif
  361. }
  362. }
  363. }
  364. #ifdef CLIENT_DLL
  365. //-----------------------------------------------------------------------------
  366. // Purpose:
  367. //-----------------------------------------------------------------------------
  368. void CMultiPlayerAnimState::RunGestureSlotAnimEventsToCompletion( GestureSlot_t *pGesture )
  369. {
  370. CBasePlayer *pPlayer = GetBasePlayer();
  371. if( !pPlayer )
  372. return;
  373. // Get the studio header for the player.
  374. CStudioHdr *pStudioHdr = pPlayer->GetModelPtr();
  375. if ( !pStudioHdr )
  376. return;
  377. // Do all the anim events between previous cycle and 1.0, inclusive
  378. mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( pGesture->m_pAnimLayer->GetSequence() );
  379. if ( seqdesc.numevents > 0 )
  380. {
  381. mstudioevent_t *pevent = GetEventIndexForSequence( seqdesc );
  382. for (int i = 0; i < (int)seqdesc.numevents; i++)
  383. {
  384. if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
  385. {
  386. if ( !( pevent[i].type & AE_TYPE_CLIENT ) )
  387. continue;
  388. }
  389. else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system
  390. continue;
  391. if ( pevent[i].cycle > pGesture->m_pAnimLayer->GetPrevCycle() &&
  392. pevent[i].cycle <= pGesture->m_pAnimLayer->GetCycle() )
  393. {
  394. pPlayer->FireEvent( pPlayer->GetAbsOrigin(), pPlayer->GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() );
  395. }
  396. }
  397. }
  398. }
  399. #endif
  400. //-----------------------------------------------------------------------------
  401. // Purpose:
  402. //-----------------------------------------------------------------------------
  403. bool CMultiPlayerAnimState::IsGestureSlotActive( int iGestureSlot )
  404. {
  405. // Sanity Check
  406. Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
  407. return m_aGestureSlots[iGestureSlot].m_bActive;
  408. }
  409. //-----------------------------------------------------------------------------
  410. // Purpose:
  411. //-----------------------------------------------------------------------------
  412. bool CMultiPlayerAnimState::IsGestureSlotPlaying( int iGestureSlot, Activity iGestureActivity )
  413. {
  414. // Sanity Check
  415. Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
  416. // Check to see if the slot is active.
  417. if ( !IsGestureSlotActive( iGestureSlot ) )
  418. return false;
  419. return ( m_aGestureSlots[iGestureSlot].m_iActivity == iGestureActivity );
  420. }
  421. //-----------------------------------------------------------------------------
  422. // Purpose:
  423. //-----------------------------------------------------------------------------
  424. void CMultiPlayerAnimState::RestartGesture( int iGestureSlot, Activity iGestureActivity, bool bAutoKill )
  425. {
  426. // Sanity Check
  427. Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
  428. if ( !IsGestureSlotPlaying( iGestureSlot, iGestureActivity ) )
  429. {
  430. #ifdef CLIENT_DLL
  431. if ( IsGestureSlotActive( iGestureSlot ) )
  432. {
  433. GestureSlot_t *pGesture = &m_aGestureSlots[iGestureSlot];
  434. if ( pGesture && pGesture->m_pAnimLayer )
  435. {
  436. pGesture->m_pAnimLayer->SetCycle( 1.0 ); // run until the end
  437. RunGestureSlotAnimEventsToCompletion( &m_aGestureSlots[iGestureSlot] );
  438. }
  439. }
  440. #endif
  441. Activity iIdealGestureActivity = TranslateActivity( iGestureActivity );
  442. AddToGestureSlot( iGestureSlot, iIdealGestureActivity, bAutoKill );
  443. return;
  444. }
  445. // Reset the cycle = restart the gesture.
  446. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetCycle( 0.0f );
  447. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetPrevCycle( 0.0f );
  448. }
  449. //-----------------------------------------------------------------------------
  450. // Purpose:
  451. //-----------------------------------------------------------------------------
  452. void CMultiPlayerAnimState::AddToGestureSlot( int iGestureSlot, Activity iGestureActivity, bool bAutoKill )
  453. {
  454. // Sanity Check
  455. Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
  456. CBasePlayer *pPlayer = GetBasePlayer();
  457. if ( !pPlayer )
  458. return;
  459. // Make sure we have a valid animation layer to fill out.
  460. if ( !m_aGestureSlots[iGestureSlot].m_pAnimLayer )
  461. return;
  462. // Get the sequence.
  463. int iGestureSequence = pPlayer->SelectWeightedSequence( iGestureActivity );
  464. if ( iGestureSequence <= 0 )
  465. return;
  466. #ifdef CLIENT_DLL
  467. // Setup the gesture.
  468. m_aGestureSlots[iGestureSlot].m_iGestureSlot = iGestureSlot;
  469. m_aGestureSlots[iGestureSlot].m_iActivity = iGestureActivity;
  470. m_aGestureSlots[iGestureSlot].m_bAutoKill = bAutoKill;
  471. m_aGestureSlots[iGestureSlot].m_bActive = true;
  472. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetSequence( iGestureSequence );
  473. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetOrder( iGestureSlot );
  474. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetWeight( 1.0f );
  475. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetPlaybackRate( 1.0f );
  476. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetCycle( 0.0f );
  477. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetPrevCycle( 0.0f );
  478. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLayerAnimtime = 0.0f;
  479. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLayerFadeOuttime = 0.0f;
  480. pPlayer->SetOverlayPrevEventCycle(iGestureSlot, -1.0);
  481. #else
  482. // Setup the gesture.
  483. m_aGestureSlots[iGestureSlot].m_iGestureSlot = iGestureSlot;
  484. m_aGestureSlots[iGestureSlot].m_iActivity = iGestureActivity;
  485. m_aGestureSlots[iGestureSlot].m_bAutoKill = bAutoKill;
  486. m_aGestureSlots[iGestureSlot].m_bActive = true;
  487. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nActivity = iGestureActivity;
  488. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nOrder = iGestureSlot;
  489. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nPriority = 0;
  490. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flCycle = 0.0f;
  491. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPrevCycle = 0.0f;
  492. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPlaybackRate = 1.0f;
  493. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nActivity = iGestureActivity;
  494. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nSequence = iGestureSequence;
  495. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flWeight = 1.0f;
  496. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flBlendIn = 0.0f;
  497. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flBlendOut = 0.0f;
  498. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_bSequenceFinished = false;
  499. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLastEventCheck = 0.0f;
  500. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLastEventCheck = gpGlobals->curtime;
  501. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_bLooping = false;//( ( GetSequenceFlags( GetModelPtr(), iGestureSequence ) & STUDIO_LOOPING ) != 0);
  502. if ( bAutoKill )
  503. {
  504. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags |= ANIM_LAYER_AUTOKILL;
  505. }
  506. else
  507. {
  508. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags &= ~ANIM_LAYER_AUTOKILL;
  509. }
  510. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags |= ANIM_LAYER_ACTIVE;
  511. #endif
  512. }
  513. //-----------------------------------------------------------------------------
  514. // Purpose:
  515. //-----------------------------------------------------------------------------
  516. void CMultiPlayerAnimState::AddVCDSequenceToGestureSlot( int iGestureSlot, int iGestureSequence, bool bAutoKill )
  517. {
  518. // Sanity Check
  519. Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
  520. CBasePlayer *pPlayer = GetBasePlayer();
  521. if ( !pPlayer )
  522. return;
  523. // Make sure we have a valid animation layer to fill out.
  524. if ( !m_aGestureSlots[iGestureSlot].m_pAnimLayer )
  525. return;
  526. // Set the activity.
  527. Activity iGestureActivity = ACT_MP_VCD;
  528. #ifdef CLIENT_DLL
  529. // Setup the gesture.
  530. m_aGestureSlots[iGestureSlot].m_iGestureSlot = iGestureSlot;
  531. m_aGestureSlots[iGestureSlot].m_iActivity = iGestureActivity;
  532. m_aGestureSlots[iGestureSlot].m_bAutoKill = bAutoKill;
  533. m_aGestureSlots[iGestureSlot].m_bActive = true;
  534. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetSequence( iGestureSequence );
  535. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetOrder( iGestureSlot );
  536. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetWeight( 1.0f );
  537. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetPlaybackRate( 1.0f );
  538. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetCycle( 0.0f );
  539. m_aGestureSlots[iGestureSlot].m_pAnimLayer->SetPrevCycle( 0.0f );
  540. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLayerAnimtime = 0.0f;
  541. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLayerFadeOuttime = 0.0f;
  542. pPlayer->SetOverlayPrevEventCycle(iGestureSlot, -1.0);
  543. #else
  544. // Setup the gesture.
  545. m_aGestureSlots[iGestureSlot].m_iGestureSlot = iGestureSlot;
  546. m_aGestureSlots[iGestureSlot].m_iActivity = iGestureActivity;
  547. m_aGestureSlots[iGestureSlot].m_bAutoKill = bAutoKill;
  548. m_aGestureSlots[iGestureSlot].m_bActive = true;
  549. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nActivity = iGestureActivity;
  550. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nOrder = iGestureSlot;
  551. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nPriority = 0;
  552. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flCycle = 0.0f;
  553. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPrevCycle = 0.0f;
  554. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPlaybackRate = 1.0f;
  555. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nActivity = iGestureActivity;
  556. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nSequence = iGestureSequence;
  557. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flWeight = 1.0f;
  558. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flBlendIn = 0.0f;
  559. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flBlendOut = 0.0f;
  560. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_bSequenceFinished = false;
  561. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLastEventCheck = 0.0f;
  562. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLastEventCheck = gpGlobals->curtime;
  563. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_bLooping = false;//( ( GetSequenceFlags( GetModelPtr(), iGestureSequence ) & STUDIO_LOOPING ) != 0);
  564. if ( bAutoKill )
  565. {
  566. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags |= ANIM_LAYER_AUTOKILL;
  567. }
  568. else
  569. {
  570. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags &= ~ANIM_LAYER_AUTOKILL;
  571. }
  572. m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags |= ANIM_LAYER_ACTIVE;
  573. #endif
  574. }
  575. //-----------------------------------------------------------------------------
  576. // Purpose:
  577. //-----------------------------------------------------------------------------
  578. void CMultiPlayerAnimState::ShowDebugInfo( void )
  579. {
  580. if ( anim_showstate.GetInt() == GetBasePlayer()->entindex() )
  581. {
  582. DebugShowAnimStateForPlayer( GetBasePlayer()->IsServer() );
  583. }
  584. }
  585. //-----------------------------------------------------------------------------
  586. // Purpose: Cancel the current gesture and restart the main sequence.
  587. //-----------------------------------------------------------------------------
  588. void CMultiPlayerAnimState::RestartMainSequence( void )
  589. {
  590. CBaseAnimatingOverlay *pPlayer = GetBasePlayer();
  591. if ( pPlayer )
  592. {
  593. pPlayer->m_flAnimTime = gpGlobals->curtime;
  594. pPlayer->SetCycle( 0 );
  595. }
  596. }
  597. //-----------------------------------------------------------------------------
  598. // Purpose:
  599. // Input : *idealActivity -
  600. // Output : Returns true on success, false on failure.
  601. //-----------------------------------------------------------------------------
  602. bool CMultiPlayerAnimState::HandleJumping( Activity &idealActivity )
  603. {
  604. if ( m_bJumping )
  605. {
  606. if ( m_bFirstJumpFrame )
  607. {
  608. m_bFirstJumpFrame = false;
  609. RestartMainSequence(); // Reset the animation.
  610. }
  611. // Check to see if we hit water and stop jumping animation.
  612. if ( GetBasePlayer()->GetWaterLevel() >= WL_Waist )
  613. {
  614. m_bJumping = false;
  615. RestartMainSequence();
  616. }
  617. // Don't check if he's on the ground for a sec.. sometimes the client still has the
  618. // on-ground flag set right when the message comes in.
  619. else if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
  620. {
  621. if ( GetBasePlayer()->GetFlags() & FL_ONGROUND )
  622. {
  623. m_bJumping = false;
  624. RestartMainSequence();
  625. }
  626. }
  627. }
  628. if ( m_bJumping )
  629. {
  630. idealActivity = ACT_MP_JUMP;
  631. return true;
  632. }
  633. else
  634. {
  635. return false;
  636. }
  637. }
  638. //-----------------------------------------------------------------------------
  639. // Purpose:
  640. // Input : *idealActivity -
  641. // Output : Returns true on success, false on failure.
  642. //-----------------------------------------------------------------------------
  643. bool CMultiPlayerAnimState::HandleDucking( Activity &idealActivity )
  644. {
  645. if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
  646. {
  647. if ( GetOuterXYSpeed() > MOVING_MINIMUM_SPEED )
  648. {
  649. idealActivity = ACT_MP_CROUCHWALK;
  650. }
  651. else
  652. {
  653. idealActivity = ACT_MP_CROUCH_IDLE;
  654. }
  655. return true;
  656. }
  657. return false;
  658. }
  659. //-----------------------------------------------------------------------------
  660. // Purpose:
  661. // Input : &idealActivity -
  662. // Output : Returns true on success, false on failure.
  663. //-----------------------------------------------------------------------------
  664. bool CMultiPlayerAnimState::HandleSwimming( Activity &idealActivity )
  665. {
  666. if ( GetBasePlayer()->GetWaterLevel() >= WL_Waist )
  667. {
  668. if ( m_bFirstSwimFrame )
  669. {
  670. // Reset the animation.
  671. RestartMainSequence();
  672. m_bFirstSwimFrame = false;
  673. }
  674. idealActivity = ACT_MP_SWIM;
  675. m_bInSwim = true;
  676. return true;
  677. }
  678. else
  679. {
  680. m_bInSwim = false;
  681. if ( !m_bFirstSwimFrame )
  682. {
  683. m_bFirstSwimFrame = true;
  684. }
  685. }
  686. return false;
  687. }
  688. //-----------------------------------------------------------------------------
  689. // Purpose:
  690. // Input : *idealActivity -
  691. // Output : Returns true on success, false on failure.
  692. //-----------------------------------------------------------------------------
  693. bool CMultiPlayerAnimState::HandleDying( Activity &idealActivity )
  694. {
  695. if ( m_bDying )
  696. {
  697. if ( m_bFirstDyingFrame )
  698. {
  699. // Reset the animation.
  700. RestartMainSequence();
  701. m_bFirstDyingFrame = false;
  702. }
  703. idealActivity = ACT_DIESIMPLE;
  704. return true;
  705. }
  706. else
  707. {
  708. if ( !m_bFirstDyingFrame )
  709. {
  710. m_bFirstDyingFrame = true;
  711. }
  712. }
  713. return false;
  714. }
  715. //-----------------------------------------------------------------------------
  716. // Purpose:
  717. // Input : *idealActivity -
  718. // Output : Returns true on success, false on failure.
  719. //-----------------------------------------------------------------------------
  720. bool CMultiPlayerAnimState::HandleMoving( Activity &idealActivity )
  721. {
  722. // In TF we run all the time now.
  723. float flSpeed = GetOuterXYSpeed();
  724. if ( flSpeed > MOVING_MINIMUM_SPEED )
  725. {
  726. // Always assume a run.
  727. idealActivity = ACT_MP_RUN;
  728. }
  729. return true;
  730. }
  731. //-----------------------------------------------------------------------------
  732. // Purpose:
  733. // Input : -
  734. // Output : Activity
  735. //-----------------------------------------------------------------------------
  736. Activity CMultiPlayerAnimState::CalcMainActivity()
  737. {
  738. Activity idealActivity = ACT_MP_STAND_IDLE;
  739. if ( HandleJumping( idealActivity ) ||
  740. HandleDucking( idealActivity ) ||
  741. HandleSwimming( idealActivity ) ||
  742. HandleDying( idealActivity ) )
  743. {
  744. // intentionally blank
  745. }
  746. else
  747. {
  748. HandleMoving( idealActivity );
  749. }
  750. ShowDebugInfo();
  751. // Client specific.
  752. #ifdef CLIENT_DLL
  753. if ( anim_showmainactivity.GetBool() )
  754. {
  755. DebugShowActivity( idealActivity );
  756. }
  757. #endif
  758. return idealActivity;
  759. }
  760. //-----------------------------------------------------------------------------
  761. // Purpose:
  762. // Input : actDesired -
  763. // Output : Activity
  764. //-----------------------------------------------------------------------------
  765. Activity CMultiPlayerAnimState::TranslateActivity( Activity actDesired )
  766. {
  767. // Translate activities for swimming.
  768. if ( m_bInSwim )
  769. {
  770. switch ( actDesired )
  771. {
  772. case ACT_MP_ATTACK_STAND_PRIMARYFIRE: { actDesired = ACT_MP_ATTACK_SWIM_PRIMARYFIRE; break; }
  773. case ACT_MP_ATTACK_STAND_SECONDARYFIRE: { actDesired = ACT_MP_ATTACK_SWIM_SECONDARYFIRE; break; }
  774. case ACT_MP_ATTACK_STAND_GRENADE: { actDesired = ACT_MP_ATTACK_SWIM_GRENADE; break; }
  775. case ACT_MP_RELOAD_STAND: { actDesired = ACT_MP_RELOAD_SWIM; break; }
  776. }
  777. }
  778. return actDesired;
  779. }
  780. //-----------------------------------------------------------------------------
  781. // Purpose:
  782. // Input : -
  783. // Output : float
  784. //-----------------------------------------------------------------------------
  785. float CMultiPlayerAnimState::GetCurrentMaxGroundSpeed()
  786. {
  787. CStudioHdr *pStudioHdr = GetBasePlayer()->GetModelPtr();
  788. if ( pStudioHdr == NULL )
  789. return 1.0f;
  790. float prevX = GetBasePlayer()->GetPoseParameter( m_PoseParameterData.m_iMoveX );
  791. float prevY = GetBasePlayer()->GetPoseParameter( m_PoseParameterData.m_iMoveY );
  792. float d = sqrt( prevX * prevX + prevY * prevY );
  793. float newX, newY;
  794. if ( d == 0.0 )
  795. {
  796. newX = 1.0;
  797. newY = 0.0;
  798. }
  799. else
  800. {
  801. newX = prevX / d;
  802. newY = prevY / d;
  803. }
  804. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, newX );
  805. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, newY );
  806. float speed = GetBasePlayer()->GetSequenceGroundSpeed( GetBasePlayer()->GetSequence() );
  807. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, prevX );
  808. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, prevY );
  809. return speed;
  810. }
  811. //-----------------------------------------------------------------------------
  812. // Purpose:
  813. // Input : *bIsMoving -
  814. // Output : float
  815. //-----------------------------------------------------------------------------
  816. ConVar movement_anim_playback_minrate( "movement_anim_playback_minrate", "0.25" );
  817. float CMultiPlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
  818. {
  819. // Get the player's current velocity and speed.
  820. Vector vecVelocity;
  821. GetOuterAbsVelocity( vecVelocity );
  822. float flSpeed = vecVelocity.Length2D();
  823. // Determine if the player is considered moving or not.
  824. bool bMoving = ( flSpeed > MOVING_MINIMUM_SPEED );
  825. // Initialize the return data.
  826. *bIsMoving = false;
  827. float flReturn = 1.0f;
  828. // If we are moving.
  829. if ( bMoving )
  830. {
  831. // float flGroundSpeed = GetInterpolatedGroundSpeed();
  832. float flGroundSpeed = GetCurrentMaxGroundSpeed();
  833. if ( flGroundSpeed < 0.001f )
  834. {
  835. flReturn = 0.01;
  836. }
  837. else
  838. {
  839. // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
  840. flReturn = flSpeed / flGroundSpeed;
  841. flReturn = clamp( flReturn, movement_anim_playback_minrate.GetFloat(), 10.0f );
  842. }
  843. *bIsMoving = true;
  844. }
  845. return flReturn;
  846. }
  847. //-----------------------------------------------------------------------------
  848. // Purpose:
  849. // Output : float
  850. //-----------------------------------------------------------------------------
  851. float CMultiPlayerAnimState::GetInterpolatedGroundSpeed( void )
  852. {
  853. return m_flMaxGroundSpeed;
  854. }
  855. //-----------------------------------------------------------------------------
  856. // Purpose:
  857. // Input : *pStudioHdr -
  858. //-----------------------------------------------------------------------------
  859. void CMultiPlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr )
  860. {
  861. VPROF( "CBasePlayerAnimState::ComputeSequences" );
  862. // Lower body (walk/run/idle).
  863. ComputeMainSequence();
  864. // The groundspeed interpolator uses the main sequence info.
  865. UpdateInterpolators();
  866. ComputeGestureSequence( pStudioHdr );
  867. }
  868. //-----------------------------------------------------------------------------
  869. // Purpose:
  870. // Input : -
  871. //-----------------------------------------------------------------------------
  872. void CMultiPlayerAnimState::ComputeMainSequence()
  873. {
  874. VPROF( "CBasePlayerAnimState::ComputeMainSequence" );
  875. CBaseAnimatingOverlay *pPlayer = GetBasePlayer();
  876. // Have our class or the mod-specific class determine what the current activity is.
  877. Activity idealActivity = CalcMainActivity();
  878. #ifdef CLIENT_DLL
  879. Activity oldActivity = m_eCurrentMainSequenceActivity;
  880. #endif
  881. // Store our current activity so the aim and fire layers know what to do.
  882. m_eCurrentMainSequenceActivity = idealActivity;
  883. // Hook to force playback of a specific requested full-body sequence
  884. if ( m_nSpecificMainSequence >= 0 )
  885. {
  886. if ( pPlayer->GetSequence() != m_nSpecificMainSequence )
  887. {
  888. pPlayer->ResetSequence( m_nSpecificMainSequence );
  889. ResetGroundSpeed();
  890. return;
  891. }
  892. if ( !pPlayer->IsSequenceFinished() )
  893. return;
  894. m_nSpecificMainSequence = -1;
  895. RestartMainSequence();
  896. ResetGroundSpeed();
  897. }
  898. // Export to our outer class..
  899. int animDesired = SelectWeightedSequence( TranslateActivity( idealActivity ) );
  900. if ( pPlayer->GetSequenceActivity( pPlayer->GetSequence() ) == pPlayer->GetSequenceActivity( animDesired ) )
  901. return;
  902. if ( animDesired < 0 )
  903. {
  904. animDesired = 0;
  905. }
  906. pPlayer->ResetSequence( animDesired );
  907. #ifdef CLIENT_DLL
  908. // If we went from idle to walk, reset the interpolation history.
  909. // Kind of hacky putting this here.. it might belong outside the base class.
  910. if ( (oldActivity == ACT_MP_CROUCH_IDLE || oldActivity == ACT_MP_STAND_IDLE || oldActivity == ACT_MP_STAND_SECONDARY || oldActivity == ACT_MP_DEPLOYED_IDLE || oldActivity == ACT_MP_CROUCH_DEPLOYED_IDLE ) &&
  911. (idealActivity == ACT_MP_WALK || idealActivity == ACT_MP_CROUCHWALK ) )
  912. {
  913. ResetGroundSpeed();
  914. }
  915. #endif
  916. }
  917. //-----------------------------------------------------------------------------
  918. // Purpose:
  919. //-----------------------------------------------------------------------------
  920. void CMultiPlayerAnimState::ResetGroundSpeed( void )
  921. {
  922. #ifdef CLIENT_DLL
  923. m_flMaxGroundSpeed = GetCurrentMaxGroundSpeed();
  924. m_iv_flMaxGroundSpeed.Reset( gpGlobals->curtime );
  925. m_iv_flMaxGroundSpeed.NoteChanged( gpGlobals->curtime, gpGlobals->curtime, 0, false );
  926. #endif
  927. }
  928. //-----------------------------------------------------------------------------
  929. // Purpose:
  930. // Input : -
  931. //-----------------------------------------------------------------------------
  932. void CMultiPlayerAnimState::UpdateInterpolators()
  933. {
  934. VPROF( "CBasePlayerAnimState::UpdateInterpolators" );
  935. // First, figure out their current max speed based on their current activity.
  936. float flCurMaxSpeed = GetCurrentMaxGroundSpeed();
  937. #ifdef CLIENT_DLL
  938. float flGroundSpeedInterval = 0.1;
  939. // Only update this 10x/sec so it has an interval to interpolate over.
  940. if ( gpGlobals->curtime - m_flLastGroundSpeedUpdateTime >= flGroundSpeedInterval )
  941. {
  942. m_flLastGroundSpeedUpdateTime = gpGlobals->curtime;
  943. m_flMaxGroundSpeed = flCurMaxSpeed;
  944. m_iv_flMaxGroundSpeed.NoteChanged( gpGlobals->curtime, flGroundSpeedInterval, false );
  945. }
  946. m_iv_flMaxGroundSpeed.Interpolate( gpGlobals->curtime, flGroundSpeedInterval );
  947. #else
  948. m_flMaxGroundSpeed = flCurMaxSpeed;
  949. #endif
  950. }
  951. //-----------------------------------------------------------------------------
  952. // Purpose:
  953. //-----------------------------------------------------------------------------
  954. void CMultiPlayerAnimState::ComputeFireSequence( void )
  955. {
  956. }
  957. //-----------------------------------------------------------------------------
  958. // Purpose:
  959. // Input : *pStudioHdr -
  960. //-----------------------------------------------------------------------------
  961. void CMultiPlayerAnimState::ComputeGestureSequence( CStudioHdr *pStudioHdr )
  962. {
  963. // Update all active gesture layers.
  964. for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture )
  965. {
  966. if ( !m_aGestureSlots[iGesture].m_bActive )
  967. continue;
  968. UpdateGestureLayer( pStudioHdr, &m_aGestureSlots[iGesture] );
  969. }
  970. }
  971. //-----------------------------------------------------------------------------
  972. // Purpose:
  973. //-----------------------------------------------------------------------------
  974. void CMultiPlayerAnimState::UpdateGestureLayer( CStudioHdr *pStudioHdr, GestureSlot_t *pGesture )
  975. {
  976. // Sanity check.
  977. if ( !pStudioHdr || !pGesture )
  978. return;
  979. CBasePlayer *pPlayer = GetBasePlayer();
  980. if( !pPlayer )
  981. return;
  982. // Get the current cycle.
  983. float flCycle = pGesture->m_pAnimLayer->GetCycle();
  984. flCycle += pPlayer->GetSequenceCycleRate( pStudioHdr, pGesture->m_pAnimLayer->GetSequence() ) * gpGlobals->frametime;
  985. pGesture->m_pAnimLayer->SetPrevCycle( pGesture->m_pAnimLayer->GetCycle() );
  986. pGesture->m_pAnimLayer->SetCycle( flCycle );
  987. if( flCycle > 1.0f )
  988. {
  989. #ifdef CLIENT_DLL
  990. RunGestureSlotAnimEventsToCompletion( pGesture );
  991. #endif
  992. if ( pGesture->m_bAutoKill )
  993. {
  994. ResetGestureSlot( pGesture->m_iGestureSlot );
  995. return;
  996. }
  997. else
  998. {
  999. pGesture->m_pAnimLayer->SetCycle( 1.0f );
  1000. }
  1001. }
  1002. #ifndef CLIENT_DLL
  1003. if ( pGesture->m_iActivity != ACT_INVALID && pGesture->m_pAnimLayer->m_nActivity == ACT_INVALID )
  1004. {
  1005. ResetGestureSlot( pGesture->m_iGestureSlot );
  1006. }
  1007. #endif
  1008. }
  1009. extern ConVar mp_facefronttime;
  1010. extern ConVar mp_feetyawrate;
  1011. //-----------------------------------------------------------------------------
  1012. // Purpose:
  1013. // Input : eyeYaw -
  1014. // eyePitch -
  1015. //-----------------------------------------------------------------------------
  1016. void CMultiPlayerAnimState::Update( float eyeYaw, float eyePitch )
  1017. {
  1018. // Profile the animation update.
  1019. VPROF( "CMultiPlayerAnimState::Update" );
  1020. // Get the studio header for the player.
  1021. CStudioHdr *pStudioHdr = GetBasePlayer()->GetModelPtr();
  1022. if ( !pStudioHdr )
  1023. return;
  1024. // Check to see if we should be updating the animation state - dead, ragdolled?
  1025. if ( !ShouldUpdateAnimState() )
  1026. {
  1027. ClearAnimationState();
  1028. return;
  1029. }
  1030. // Store the eye angles.
  1031. m_flEyeYaw = AngleNormalize( eyeYaw );
  1032. m_flEyePitch = AngleNormalize( eyePitch );
  1033. // Compute the player sequences.
  1034. ComputeSequences( pStudioHdr );
  1035. if ( SetupPoseParameters( pStudioHdr ) )
  1036. {
  1037. // Pose parameter - what direction are the player's legs running in.
  1038. ComputePoseParam_MoveYaw( pStudioHdr );
  1039. // Pose parameter - Torso aiming (up/down).
  1040. ComputePoseParam_AimPitch( pStudioHdr );
  1041. // Pose parameter - Torso aiming (rotation).
  1042. ComputePoseParam_AimYaw( pStudioHdr );
  1043. }
  1044. #ifdef CLIENT_DLL
  1045. if ( C_BasePlayer::IsLocalPlayer( GetBasePlayer() ) &&
  1046. GetBasePlayer()->ShouldDrawLocalPlayer() )
  1047. {
  1048. GetBasePlayer()->SetPlaybackRate( 1.0f );
  1049. }
  1050. #endif
  1051. if( mp_showgestureslots.GetInt() == GetBasePlayer()->entindex() )
  1052. {
  1053. DebugGestureInfo();
  1054. }
  1055. }
  1056. //-----------------------------------------------------------------------------
  1057. // Purpose:
  1058. // Input : -
  1059. // Output : Returns true on success, false on failure.
  1060. //-----------------------------------------------------------------------------
  1061. bool CMultiPlayerAnimState::ShouldUpdateAnimState()
  1062. {
  1063. // Don't update anim state if we're not visible
  1064. if ( GetBasePlayer()->IsEffectActive( EF_NODRAW ) )
  1065. return false;
  1066. // By default, don't update their animation state when they're dead because they're
  1067. // either a ragdoll or they're not drawn.
  1068. #ifdef CLIENT_DLL
  1069. if ( GetBasePlayer()->IsDormant() )
  1070. return false;
  1071. #endif
  1072. return (GetBasePlayer()->IsAlive() || m_bDying);
  1073. }
  1074. //-----------------------------------------------------------------------------
  1075. // Purpose:
  1076. //-----------------------------------------------------------------------------
  1077. bool CMultiPlayerAnimState::SetupPoseParameters( CStudioHdr *pStudioHdr )
  1078. {
  1079. // Check to see if this has already been done.
  1080. if ( m_bPoseParameterInit )
  1081. return true;
  1082. // Save off the pose parameter indices.
  1083. if ( !pStudioHdr )
  1084. return false;
  1085. // Look for the movement blenders.
  1086. m_PoseParameterData.m_iMoveX = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "move_x" );
  1087. m_PoseParameterData.m_iMoveY = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "move_y" );
  1088. if ( ( m_PoseParameterData.m_iMoveX < 0 ) || ( m_PoseParameterData.m_iMoveY < 0 ) )
  1089. return false;
  1090. // Look for the aim pitch blender.
  1091. m_PoseParameterData.m_iAimPitch = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "body_pitch" );
  1092. if ( m_PoseParameterData.m_iAimPitch < 0 )
  1093. return false;
  1094. // Look for aim yaw blender.
  1095. m_PoseParameterData.m_iAimYaw = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "body_yaw" );
  1096. if ( m_PoseParameterData.m_iAimYaw < 0 )
  1097. return false;
  1098. m_bPoseParameterInit = true;
  1099. return true;
  1100. }
  1101. float SnapYawTo( float flValue )
  1102. {
  1103. float flSign = 1.0f;
  1104. if ( flValue < 0.0f )
  1105. {
  1106. flSign = -1.0f;
  1107. flValue = -flValue;
  1108. }
  1109. if ( flValue < 23.0f )
  1110. {
  1111. flValue = 0.0f;
  1112. }
  1113. else if ( flValue < 67.0f )
  1114. {
  1115. flValue = 45.0f;
  1116. }
  1117. else if ( flValue < 113.0f )
  1118. {
  1119. flValue = 90.0f;
  1120. }
  1121. else if ( flValue < 157 )
  1122. {
  1123. flValue = 135.0f;
  1124. }
  1125. else
  1126. {
  1127. flValue = 180.0f;
  1128. }
  1129. return ( flValue * flSign );
  1130. }
  1131. //-----------------------------------------------------------------------------
  1132. // Purpose:
  1133. // Input : *pStudioHdr -
  1134. //-----------------------------------------------------------------------------
  1135. void CMultiPlayerAnimState::ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr )
  1136. {
  1137. // Get the estimated movement yaw.
  1138. EstimateYaw();
  1139. // Get the view yaw.
  1140. float flAngle = AngleNormalize( m_flEyeYaw );
  1141. // Calc side to side turning - the view vs. movement yaw.
  1142. float flYaw = flAngle - m_PoseParameterData.m_flEstimateYaw;
  1143. flYaw = AngleNormalize( -flYaw );
  1144. // Get the current speed the character is running.
  1145. bool bIsMoving;
  1146. float flPlaybackRate = CalcMovementPlaybackRate( &bIsMoving );
  1147. // Setup the 9-way blend parameters based on our speed and direction.
  1148. Vector2D vecCurrentMoveYaw( 0.0f, 0.0f );
  1149. if ( bIsMoving )
  1150. {
  1151. if ( mp_slammoveyaw.GetBool() )
  1152. {
  1153. flYaw = SnapYawTo( flYaw );
  1154. }
  1155. vecCurrentMoveYaw.x = cos( DEG2RAD( flYaw ) ) * flPlaybackRate;
  1156. vecCurrentMoveYaw.y = -sin( DEG2RAD( flYaw ) ) * flPlaybackRate;
  1157. }
  1158. // Set the 9-way blend movement pose parameters.
  1159. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, vecCurrentMoveYaw.x );
  1160. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, vecCurrentMoveYaw.y );
  1161. m_DebugAnimData.m_vecMoveYaw = vecCurrentMoveYaw;
  1162. }
  1163. //-----------------------------------------------------------------------------
  1164. // Purpose:
  1165. //-----------------------------------------------------------------------------
  1166. void CMultiPlayerAnimState::EstimateYaw( void )
  1167. {
  1168. // Get the frame time.
  1169. float flDeltaTime = gpGlobals->frametime;
  1170. if ( flDeltaTime == 0.0f )
  1171. return;
  1172. // Get the player's velocity and angles.
  1173. Vector vecEstVelocity;
  1174. GetOuterAbsVelocity( vecEstVelocity );
  1175. QAngle angles = GetBasePlayer()->GetLocalAngles();
  1176. // If we are not moving, sync up the feet and eyes slowly.
  1177. if ( vecEstVelocity.x == 0.0f && vecEstVelocity.y == 0.0f )
  1178. {
  1179. float flYawDelta = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
  1180. flYawDelta = AngleNormalize( flYawDelta );
  1181. if ( flDeltaTime < 0.25f )
  1182. {
  1183. flYawDelta *= ( flDeltaTime * 4.0f );
  1184. }
  1185. else
  1186. {
  1187. flYawDelta *= flDeltaTime;
  1188. }
  1189. m_PoseParameterData.m_flEstimateYaw += flYawDelta;
  1190. AngleNormalize( m_PoseParameterData.m_flEstimateYaw );
  1191. }
  1192. else
  1193. {
  1194. m_PoseParameterData.m_flEstimateYaw = ( atan2( vecEstVelocity.y, vecEstVelocity.x ) * 180.0f / M_PI );
  1195. m_PoseParameterData.m_flEstimateYaw = clamp( m_PoseParameterData.m_flEstimateYaw, -180.0f, 180.0f );
  1196. }
  1197. }
  1198. //-----------------------------------------------------------------------------
  1199. // Purpose:
  1200. //-----------------------------------------------------------------------------
  1201. void CMultiPlayerAnimState::ComputePoseParam_AimPitch( CStudioHdr *pStudioHdr )
  1202. {
  1203. // Get the view pitch.
  1204. float flAimPitch = m_flEyePitch;
  1205. // Set the aim pitch pose parameter and save.
  1206. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimPitch, -flAimPitch );
  1207. m_DebugAnimData.m_flAimPitch = flAimPitch;
  1208. }
  1209. //-----------------------------------------------------------------------------
  1210. // Purpose:
  1211. //-----------------------------------------------------------------------------
  1212. void CMultiPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr )
  1213. {
  1214. // Get the movement velocity.
  1215. Vector vecVelocity;
  1216. GetOuterAbsVelocity( vecVelocity );
  1217. // Check to see if we are moving.
  1218. bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false;
  1219. // If we are moving or are prone and undeployed.
  1220. if ( bMoving || m_bForceAimYaw )
  1221. {
  1222. // The feet match the eye direction when moving - the move yaw takes care of the rest.
  1223. m_flGoalFeetYaw = m_flEyeYaw;
  1224. }
  1225. // Else if we are not moving.
  1226. else
  1227. {
  1228. // Initialize the feet.
  1229. if ( m_PoseParameterData.m_flLastAimTurnTime <= 0.0f )
  1230. {
  1231. m_flGoalFeetYaw = m_flEyeYaw;
  1232. m_flCurrentFeetYaw = m_flEyeYaw;
  1233. m_PoseParameterData.m_flLastAimTurnTime = gpGlobals->curtime;
  1234. }
  1235. // Make sure the feet yaw isn't too far out of sync with the eye yaw.
  1236. // TODO: Do something better here!
  1237. else
  1238. {
  1239. float flYawDelta = AngleNormalize( m_flGoalFeetYaw - m_flEyeYaw );
  1240. if ( fabs( flYawDelta ) > 45.0f/*m_AnimConfig.m_flMaxBodyYawDegrees*/ )
  1241. {
  1242. #if defined( CLIENT_DLL ) && defined( DEMO_POLISH )
  1243. float const flCurrentFootYaw = m_flGoalFeetYaw;
  1244. #endif
  1245. float flSide = ( flYawDelta > 0.0f ) ? -1.0f : 1.0f;
  1246. m_flGoalFeetYaw += ( 45.0f/*m_AnimConfig.m_flMaxBodyYawDegrees*/ * flSide );
  1247. #if defined( CLIENT_DLL ) && defined( DEMO_POLISH )
  1248. if ( IsDemoPolishRecording() )
  1249. {
  1250. CDemoPolishRecorder::Instance().RecordStandingHeadingChange( GetBasePlayer()->entindex(), flCurrentFootYaw, m_flGoalFeetYaw );
  1251. }
  1252. #endif
  1253. }
  1254. }
  1255. }
  1256. // Fix up the feet yaw.
  1257. m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );
  1258. if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
  1259. {
  1260. if ( m_bForceAimYaw )
  1261. {
  1262. m_flCurrentFeetYaw = m_flGoalFeetYaw;
  1263. }
  1264. else
  1265. {
  1266. ConvergeYawAngles( m_flGoalFeetYaw, /*DOD_BODYYAW_RATE*/720.0f, gpGlobals->frametime, m_flCurrentFeetYaw );
  1267. m_flLastAimTurnTime = gpGlobals->curtime;
  1268. }
  1269. }
  1270. // Rotate the body into position.
  1271. m_angRender[YAW] = m_flCurrentFeetYaw;
  1272. // Find the aim(torso) yaw base on the eye and feet yaws.
  1273. float flAimYaw = m_flEyeYaw - m_flCurrentFeetYaw;
  1274. flAimYaw = AngleNormalize( flAimYaw );
  1275. // Set the aim yaw and save.
  1276. GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimYaw, -flAimYaw );
  1277. m_DebugAnimData.m_flAimYaw = flAimYaw;
  1278. // Turn off a force aim yaw - either we have already updated or we don't need to.
  1279. m_bForceAimYaw = false;
  1280. #ifndef CLIENT_DLL
  1281. QAngle angle = GetBasePlayer()->GetAbsAngles();
  1282. angle[YAW] = m_flCurrentFeetYaw;
  1283. GetBasePlayer()->SetAbsAngles( angle );
  1284. #endif
  1285. }
  1286. //-----------------------------------------------------------------------------
  1287. // Purpose:
  1288. // Input : flGoalYaw -
  1289. // flYawRate -
  1290. // flDeltaTime -
  1291. // &flCurrentYaw -
  1292. //-----------------------------------------------------------------------------
  1293. void CMultiPlayerAnimState::ConvergeYawAngles( float flGoalYaw, float flYawRate, float flDeltaTime, float &flCurrentYaw )
  1294. {
  1295. #define FADE_TURN_DEGREES 60.0f
  1296. // Find the yaw delta.
  1297. float flDeltaYaw = flGoalYaw - flCurrentYaw;
  1298. float flDeltaYawAbs = fabs( flDeltaYaw );
  1299. flDeltaYaw = AngleNormalize( flDeltaYaw );
  1300. // Always do at least a bit of the turn (1%).
  1301. float flScale = 1.0f;
  1302. flScale = flDeltaYawAbs / FADE_TURN_DEGREES;
  1303. flScale = clamp( flScale, 0.01f, 1.0f );
  1304. float flYaw = flYawRate * flDeltaTime * flScale;
  1305. if ( flDeltaYawAbs < flYaw )
  1306. {
  1307. flCurrentYaw = flGoalYaw;
  1308. }
  1309. else
  1310. {
  1311. float flSide = ( flDeltaYaw < 0.0f ) ? -1.0f : 1.0f;
  1312. flCurrentYaw += ( flYaw * flSide );
  1313. }
  1314. flCurrentYaw = AngleNormalize( flCurrentYaw );
  1315. #undef FADE_TURN_DEGREES
  1316. }
  1317. //-----------------------------------------------------------------------------
  1318. // Purpose:
  1319. // Input : -
  1320. // Output : const QAngle&
  1321. //-----------------------------------------------------------------------------
  1322. const QAngle& CMultiPlayerAnimState::GetRenderAngles()
  1323. {
  1324. #if defined( PORTAL ) && defined( CLIENT_DLL )
  1325. C_Portal_Player *pPlayer = (C_Portal_Player *)GetBasePlayer();
  1326. if( pPlayer )
  1327. {
  1328. if( pPlayer->GetOriginInterpolator().GetInterpolatedTime( pPlayer->GetEffectiveInterpolationCurTime( gpGlobals->curtime ) ) < pPlayer->m_fLatestServerTeleport )
  1329. {
  1330. m_angRender_InterpHistory = TransformAnglesToWorldSpace( m_angRender, pPlayer->m_matLatestServerTeleportationInverseMatrix.As3x4() );
  1331. return m_angRender_InterpHistory;
  1332. }
  1333. }
  1334. #endif
  1335. return m_angRender;
  1336. }
  1337. //-----------------------------------------------------------------------------
  1338. // Purpose:
  1339. // Input : vel -
  1340. //-----------------------------------------------------------------------------
  1341. void CMultiPlayerAnimState::GetOuterAbsVelocity( Vector& vel )
  1342. {
  1343. #if defined( CLIENT_DLL )
  1344. GetBasePlayer()->EstimateAbsVelocity( vel );
  1345. #else
  1346. vel = GetBasePlayer()->GetAbsVelocity();
  1347. #endif
  1348. }
  1349. //-----------------------------------------------------------------------------
  1350. // Purpose:
  1351. //-----------------------------------------------------------------------------
  1352. void CMultiPlayerAnimState::Release( void )
  1353. {
  1354. delete this;
  1355. }
  1356. //-----------------------------------------------------------------------------
  1357. // Purpose:
  1358. // Input : -
  1359. // Output : float
  1360. //-----------------------------------------------------------------------------
  1361. float CMultiPlayerAnimState::GetOuterXYSpeed()
  1362. {
  1363. Vector vel;
  1364. GetOuterAbsVelocity( vel );
  1365. return vel.Length2D();
  1366. }
  1367. //-----------------------------------------------------------------------------
  1368. // Purpose:
  1369. //-----------------------------------------------------------------------------
  1370. void Anim_StateLog( const char *pMsg, ... )
  1371. {
  1372. // Format the string.
  1373. char str[4096];
  1374. va_list marker;
  1375. va_start( marker, pMsg );
  1376. Q_vsnprintf( str, sizeof( str ), pMsg, marker );
  1377. va_end( marker );
  1378. // Log it?
  1379. if ( anim_showstatelog.GetInt() == 1 || anim_showstatelog.GetInt() == 3 )
  1380. {
  1381. Msg( "%s", str );
  1382. }
  1383. if ( anim_showstatelog.GetInt() > 1 )
  1384. {
  1385. // static FileHandle_t hFile = filesystem->Open( "AnimState.log", "wt" );
  1386. // filesystem->FPrintf( hFile, "%s", str );
  1387. // filesystem->Flush( hFile );
  1388. }
  1389. }
  1390. //-----------------------------------------------------------------------------
  1391. // Purpose:
  1392. //-----------------------------------------------------------------------------
  1393. void Anim_StatePrintf( int iLine, const char *pMsg, ... )
  1394. {
  1395. // Format the string.
  1396. char str[4096];
  1397. va_list marker;
  1398. va_start( marker, pMsg );
  1399. Q_vsnprintf( str, sizeof( str ), pMsg, marker );
  1400. va_end( marker );
  1401. // Show it with Con_NPrintf.
  1402. engine->Con_NPrintf( iLine, "%s", str );
  1403. // Log it.
  1404. Anim_StateLog( "%s\n", str );
  1405. }
  1406. //-----------------------------------------------------------------------------
  1407. // Purpose:
  1408. //-----------------------------------------------------------------------------
  1409. void CMultiPlayerAnimState::DebugShowAnimStateForPlayer( bool bIsServer )
  1410. {
  1411. // Get the player's velocity.
  1412. Vector vecVelocity;
  1413. GetOuterAbsVelocity( vecVelocity );
  1414. // Start animation state logging.
  1415. int iLine = 5;
  1416. if ( bIsServer )
  1417. {
  1418. iLine = 12;
  1419. }
  1420. // Anim_StateLog( "-------------%s: frame %d -----------------\n", bIsServer ? "Server" : "Client", gpGlobals->framecount );
  1421. Anim_StatePrintf( iLine++, "-------------%s: frame %d -----------------\n", bIsServer ? "Server" : "Client", gpGlobals->framecount );
  1422. // Write out the main sequence and its data.
  1423. Anim_StatePrintf( iLine++, "Main: %s, Cycle: %.2f\n", GetSequenceName( GetBasePlayer()->GetModelPtr(), GetBasePlayer()->GetSequence() ), GetBasePlayer()->GetCycle() );
  1424. #if 0
  1425. if ( m_bPlayingGesture )
  1426. {
  1427. Anim_StatePrintf( iLine++, "Gesture: %s, Cycle: %.2f\n",
  1428. GetSequenceName( GetBasePlayer()->GetModelPtr(), m_iGestureSequence ),
  1429. m_flGestureCycle );
  1430. }
  1431. #endif
  1432. // Write out the layers and their data.
  1433. for ( int iAnim = 0; iAnim < GetBasePlayer()->GetNumAnimOverlays(); ++iAnim )
  1434. {
  1435. #ifdef CLIENT_DLL
  1436. C_AnimationLayer *pLayer = GetBasePlayer()->GetAnimOverlay( iAnim );
  1437. if ( pLayer && ( pLayer->GetOrder() != CBaseAnimatingOverlay::MAX_OVERLAYS ) )
  1438. {
  1439. Anim_StatePrintf( iLine++, "Layer %s: Weight: %.2f, Cycle: %.2f", GetSequenceName( GetBasePlayer()->GetModelPtr(), pLayer->GetSequence() ), pLayer->GetWeight(), pLayer->GetCycle() );
  1440. }
  1441. #else
  1442. CAnimationLayer *pLayer = GetBasePlayer()->GetAnimOverlay( iAnim );
  1443. if ( pLayer && ( pLayer->m_nOrder != CBaseAnimatingOverlay::MAX_OVERLAYS ) )
  1444. {
  1445. Anim_StatePrintf( iLine++, "Layer %s: Weight: %.2f, Cycle: %.2f", GetSequenceName( GetBasePlayer()->GetModelPtr(), pLayer->GetSequence() ), pLayer->GetWeight(), pLayer->GetCycle() );
  1446. }
  1447. #endif
  1448. }
  1449. // Write out the speed data.
  1450. Anim_StatePrintf( iLine++, "Time: %.2f, Speed: %.2f, MaxSpeed: %.2f", gpGlobals->curtime, vecVelocity.Length2D(), GetCurrentMaxGroundSpeed() );
  1451. // Write out the 9-way blend data.
  1452. Anim_StatePrintf( iLine++, "EntityYaw: %.2f, AimYaw: %.2f, AimPitch: %.2f, MoveX: %.2f, MoveY: %.2f", m_angRender[YAW], m_DebugAnimData.m_flAimYaw, m_DebugAnimData.m_flAimPitch, m_DebugAnimData.m_vecMoveYaw.x, m_DebugAnimData.m_vecMoveYaw.y );
  1453. // Anim_StateLog( "--------------------------------------------\n\n" );
  1454. Anim_StatePrintf( iLine++, "--------------------------------------------\n\n" );
  1455. DebugShowEyeYaw();
  1456. }
  1457. //-----------------------------------------------------------------------------
  1458. // Purpose:
  1459. //-----------------------------------------------------------------------------
  1460. void CMultiPlayerAnimState::DebugShowEyeYaw( void )
  1461. {
  1462. #ifdef _NDEBUG
  1463. float flBaseSize = 10;
  1464. float flHeight = 80;
  1465. Vector vecPos = GetOuter()->GetAbsOrigin() + Vector( 0.0f, 0.0f, 3.0f );
  1466. QAngle angles( 0.0f, 0.0f, 0.0f );
  1467. angles[YAW] = m_flEyeYaw;
  1468. Vector vecForward, vecRight, vecUp;
  1469. AngleVectors( angles, &vecForward, &vecRight, &vecUp );
  1470. // Draw a red triangle on the ground for the eye yaw.
  1471. debugoverlay->AddTriangleOverlay( ( vecPos + vecRight * flBaseSize / 2.0f ),
  1472. ( vecPos - vecRight * flBaseSize / 2.0f ),
  1473. ( vecPos + vecForward * flHeight, 255, 0, 0, 255, false, 0.01f );
  1474. #endif
  1475. }
  1476. #if defined( CLIENT_DLL )
  1477. //-----------------------------------------------------------------------------
  1478. // Purpose:
  1479. // Input : activity -
  1480. //-----------------------------------------------------------------------------
  1481. void CMultiPlayerAnimState::DebugShowActivity( Activity activity )
  1482. {
  1483. #ifdef _DEBUG
  1484. const char *pszActivity = "other";
  1485. switch( activity )
  1486. {
  1487. case ACT_MP_STAND_IDLE:
  1488. {
  1489. pszActivity = "idle";
  1490. break;
  1491. }
  1492. case ACT_MP_SPRINT:
  1493. {
  1494. pszActivity = "sprint";
  1495. break;
  1496. }
  1497. case ACT_MP_WALK:
  1498. {
  1499. pszActivity = "walk";
  1500. break;
  1501. }
  1502. case ACT_MP_RUN:
  1503. {
  1504. pszActivity = "run";
  1505. break;
  1506. }
  1507. }
  1508. Msg( "Activity: %s\n", pszActivity );
  1509. #endif
  1510. }
  1511. #endif
  1512. //-----------------------------------------------------------------------------
  1513. // Purpose:
  1514. // Input : iStartLine -
  1515. //-----------------------------------------------------------------------------
  1516. void CMultiPlayerAnimState::DebugShowAnimState( int iStartLine )
  1517. {
  1518. Vector vOuterVel;
  1519. GetOuterAbsVelocity( vOuterVel );
  1520. Anim_StateLog( "----------------- frame %d -----------------\n", gpGlobals->framecount );
  1521. int iLine = iStartLine;
  1522. Anim_StatePrintf( iLine++, "main: %s, cycle: %.2f\n", GetSequenceName( GetBasePlayer()->GetModelPtr(), GetBasePlayer()->GetSequence() ), GetBasePlayer()->GetCycle() );
  1523. #if defined( CLIENT_DLL )
  1524. for ( int i=0; i < GetBasePlayer()->GetNumAnimOverlays()-1; i++ )
  1525. {
  1526. C_AnimationLayer *pLayer = GetBasePlayer()->GetAnimOverlay( i /*i+1?*/ );
  1527. Anim_StatePrintf( iLine++, "%s, weight: %.2f, cycle: %.2f, aim (%d)",
  1528. pLayer->GetOrder() == CBaseAnimatingOverlay::MAX_OVERLAYS ? "--" : GetSequenceName( GetBasePlayer()->GetModelPtr(), pLayer->GetSequence() ),
  1529. pLayer->GetOrder() == CBaseAnimatingOverlay::MAX_OVERLAYS ? -1 :(float)pLayer->GetWeight(),
  1530. pLayer->GetOrder() == CBaseAnimatingOverlay::MAX_OVERLAYS ? -1 :(float)pLayer->GetCycle(),
  1531. i
  1532. );
  1533. }
  1534. #endif
  1535. Anim_StatePrintf( iLine++, "vel: %.2f, time: %.2f, max: %.2f",
  1536. vOuterVel.Length2D(), gpGlobals->curtime, GetInterpolatedGroundSpeed() );
  1537. // AnimStatePrintf( iLine++, "ent yaw: %.2f, body_yaw: %.2f, body_pitch: %.2f, move_x: %.2f, move_y: %.2f",
  1538. // m_angRender[YAW], g_flLastBodyYaw, g_flLastBodyPitch, m_vLastMovePose.x, m_vLastMovePose.y );
  1539. Anim_StateLog( "--------------------------------------------\n\n" );
  1540. // Draw a red triangle on the ground for the eye yaw.
  1541. float flBaseSize = 10;
  1542. float flHeight = 80;
  1543. Vector vBasePos = GetBasePlayer()->GetAbsOrigin() + Vector( 0, 0, 3 );
  1544. QAngle angles( 0, 0, 0 );
  1545. angles[YAW] = m_flEyeYaw;
  1546. Vector vForward, vRight, vUp;
  1547. AngleVectors( angles, &vForward, &vRight, &vUp );
  1548. debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 255, 0, 0, 255, false, 0.01 );
  1549. // Draw a blue triangle on the ground for the body yaw.
  1550. angles[YAW] = m_angRender[YAW];
  1551. AngleVectors( angles, &vForward, &vRight, &vUp );
  1552. debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 0, 0, 255, 255, false, 0.01 );
  1553. }
  1554. // Debug!
  1555. const char *s_aGestureSlotNames[GESTURE_SLOT_COUNT] =
  1556. {
  1557. "Attack and Reload",
  1558. "Grenade",
  1559. "Jump",
  1560. "Swim",
  1561. "Flinch",
  1562. "VCD",
  1563. "Custom"
  1564. };
  1565. //-----------------------------------------------------------------------------
  1566. // Purpose:
  1567. //-----------------------------------------------------------------------------
  1568. void CMultiPlayerAnimState::DebugGestureInfo( void )
  1569. {
  1570. CBasePlayer *pPlayer = GetBasePlayer();
  1571. if ( !pPlayer )
  1572. return;
  1573. int iLine = ( pPlayer->IsServer() ? 12 : ( 14 + GESTURE_SLOT_COUNT ) );
  1574. Anim_StatePrintf( iLine++, "%s\n", ( pPlayer->IsServer() ? "Server" : "Client" ) );
  1575. for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture )
  1576. {
  1577. GestureSlot_t *pGesture = &m_aGestureSlots[iGesture];
  1578. if ( pGesture )
  1579. {
  1580. if( pGesture->m_bActive )
  1581. {
  1582. Anim_StatePrintf( iLine++, "Gesture Slot %d(%s): %s %s(A:%s, C:%f P:%f)\n",
  1583. iGesture,
  1584. s_aGestureSlotNames[iGesture],
  1585. ActivityList_NameForIndex( pGesture->m_iActivity ),
  1586. GetSequenceName( pPlayer->GetModelPtr(), pGesture->m_pAnimLayer->GetSequence() ),
  1587. ( pGesture->m_bAutoKill ? "true" : "false" ),
  1588. pGesture->m_pAnimLayer->GetCycle(), pGesture->m_pAnimLayer->GetPlaybackRate() );
  1589. }
  1590. else
  1591. {
  1592. Anim_StatePrintf( iLine++, "Gesture Slot %d(%s): NOT ACTIVE!\n", iGesture, s_aGestureSlotNames[iGesture] );
  1593. }
  1594. }
  1595. }
  1596. }
  1597. //-----------------------------------------------------------------------------
  1598. // Purpose: New Model, init the pose parameters
  1599. //-----------------------------------------------------------------------------
  1600. void CMultiPlayerAnimState::OnNewModel( void )
  1601. {
  1602. m_bPoseParameterInit = false;
  1603. ClearAnimationState();
  1604. }