sqwarmed/sdk_src/game/shared/death_pose.cpp

175 lines
3.8 KiB
C++

//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "death_pose.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
#ifdef CLIENT_DLL
void GetRagdollCurSequenceWithDeathPose( C_BaseAnimating *entity, matrix3x4a_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->SetEffects( EF_NOINTERP );
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 );
entity->RemoveEffects( EF_NOINTERP );
}
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