text: //========= Copyright Valve Corporation, All rights reserved. ============//
  //
  // Purpose:
  //
  //=============================================================================
  
  #include "cbase.h"
  #include "death_pose.h"
  
  #ifdef CLIENT_DLL
  
  void GetRagdollCurSequenceWithDeathPose( C_BaseAnimating *entity, matrix3x4_t *curBones, float flTime, int activity, int frame )
  {
      // blow the cached prev bones
      entity->InvalidateBoneCache();
  
      Vector vPrevOrigin = entity->GetAbsOrigin();
  
      entity->Interpolate( flTime );
  
      if ( activity != ACT_INVALID )
      {
          Vector vNewOrigin = entity->GetAbsOrigin();
          Vector vDirection = vNewOrigin - vPrevOrigin;
  
          float flVelocity = VectorNormalize( vDirection );
  
          Vector vAdjustedOrigin = vNewOrigin + vDirection * ( ( flVelocity * flVelocity ) * gpGlobals->frametime );
  
          int iTempSequence = entity->GetSequence();
          float flTempCycle = entity->GetCycle();
  
          entity->SetSequence( activity );
  
          entity->SetCycle( (float)frame / MAX_DEATHPOSE_FRAMES );
  
          entity->SetAbsOrigin( vAdjustedOrigin );
  
          // Now do the current bone setup
          entity->SetupBones( curBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, flTime );
  
          entity->SetAbsOrigin( vNewOrigin );
  
          // blow the cached prev bones
          entity->InvalidateBoneCache();
  
          entity->SetSequence( iTempSequence );
          entity->SetCycle( flTempCycle );
  
          entity->Interpolate( gpGlobals->curtime );
  
          entity->SetupBones( NULL, -1, BONE_USED_BY_ANYTHING, gpGlobals->curtime );
      }
      else
      {
          entity->SetupBones( curBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, flTime );
  
          // blow the cached prev bones
          entity->InvalidateBoneCache();
  
          entity->SetupBones( NULL, -1, BONE_USED_BY_ANYTHING, flTime );
      }
  }
  
  #else // !CLIENT_DLL
  
  Activity GetDeathPoseActivity( CBaseAnimating *entity, const CTakeDamageInfo &info )
  {
      if ( !entity )
      {
          return ACT_INVALID;
      }
  
      Activity aActivity;
  
      Vector vForward, vRight;
      entity->GetVectors( &vForward, &vRight, NULL );
  
      Vector vDir = -info.GetDamageForce();
      VectorNormalize( vDir );
  
      float flDotForward  = DotProduct( vForward, vDir );
      float flDotRight    = DotProduct( vRight, vDir );
  
      bool bNegativeForward = false;
      bool bNegativeRight = false;
  
      if ( flDotForward < 0.0f )
      {
          bNegativeForward = true;
          flDotForward = flDotForward * -1;
      }
  
      if ( flDotRight < 0.0f )
      {
          bNegativeRight = true;
          flDotRight = flDotRight * -1;
      }
  
      if ( flDotRight > flDotForward )
      {
          if ( bNegativeRight == true )
              aActivity = ACT_DIE_LEFTSIDE;
          else
              aActivity = ACT_DIE_RIGHTSIDE;
      }
      else
      {
          if ( bNegativeForward == true )
              aActivity = ACT_DIE_BACKSIDE;
          else
              aActivity = ACT_DIE_FRONTSIDE;
      }
  
      return aActivity;
  }
  
  void SelectDeathPoseActivityAndFrame( CBaseAnimating *entity, const CTakeDamageInfo &info, int hitgroup, Activity& activity, int& frame )
  {
      activity = ACT_INVALID;
      frame = 0;
  
      if ( !entity->GetModelPtr() )
          return;
  
      activity = GetDeathPoseActivity( entity, info );
      frame = DEATH_FRAME_HEAD;
  
      switch( hitgroup )
      {
          //Do normal ragdoll stuff if no specific hitgroup was hit.
          case HITGROUP_GENERIC:
          default:
          {
              return;
          }
  
          case HITGROUP_HEAD:
          {
              frame = DEATH_FRAME_HEAD;
              break;
          }
          case HITGROUP_LEFTARM:
              frame = DEATH_FRAME_LEFTARM;
              break;
  
          case HITGROUP_RIGHTARM:
              frame = DEATH_FRAME_RIGHTARM;
              break;
  
          case HITGROUP_CHEST:
          case HITGROUP_STOMACH:
              frame = DEATH_FRAME_STOMACH;
              break;
  
          case HITGROUP_LEFTLEG:
              frame = DEATH_FRAME_LEFTLEG;
              break;
  
          case HITGROUP_RIGHTLEG:
              frame = DEATH_FRAME_RIGHTLEG;
              break;
      }
  }
  
  #endif // !CLIENT_DLL
  