//========= 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