Merge pull request #418 from AnOldLady/master

Server ragdoll death poses
This commit is contained in:
Blixibon 2025-05-26 10:31:51 -05:00 committed by GitHub
commit e759fa0b56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 0 deletions

View File

@ -1180,6 +1180,11 @@ public:
void SetDeathPose( const int &iDeathPose ) { m_iDeathPose = iDeathPose; }
void SetDeathPoseFrame( const int &iDeathPoseFrame ) { m_iDeathFrame = iDeathPoseFrame; }
#ifdef MAPBASE
int GetDeathPose() { return m_iDeathPose; }
int GetDeathPoseFrame() { return m_iDeathFrame; }
#endif
void SelectDeathPose( const CTakeDamageInfo &info );
virtual bool ShouldPickADeathPose( void ) { return true; }

View File

@ -22,6 +22,7 @@
#include "hierarchy.h"
#ifdef MAPBASE
#include "decals.h"
#include "death_pose.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
@ -29,6 +30,7 @@
#ifdef MAPBASE
ConVar ragdoll_autointeractions("ragdoll_autointeractions", "1", FCVAR_NONE, "Controls whether we should rely on hardcoded keyvalues or automatic flesh checks for ragdoll physgun interactions.");
ConVar ai_death_pose_server_enabled("ai_death_pose_server_enabled", "1", FCVAR_NONE, "Toggles the death pose fix code, but for server ragdolls.");
#define IsBody() VPhysicsIsFlesh()
ConVar ragdoll_always_allow_use( "ragdoll_always_allow_use", "0", FCVAR_NONE, "Allows all ragdolls to be used and, if they aren't explicitly set to prevent pickup, picked up." );
@ -788,7 +790,11 @@ void CRagdollProp::SetOverlaySequence( Activity activity )
}
}
#ifdef MAPBASE
void CRagdollProp::InitRagdoll( const Vector& forceVector, int forceBone, const Vector& forcePos, matrix3x4_t* pPrevBones, matrix3x4_t* pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll, bool bDeathPose )
#else
void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll )
#endif
{
SetCollisionGroup( collisionGroup );
@ -811,7 +817,11 @@ void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const
params.forceVector = forceVector;
params.forceBoneIndex = forceBone;
params.forcePosition = forcePos;
#ifdef MAPBASE
params.pCurrentBones = bDeathPose ? pPrevBones : pBoneToWorld;
#else
params.pCurrentBones = pBoneToWorld;
#endif
params.jointFrictionScale = 1.0;
params.allowStretch = HasSpawnFlags(SF_RAGDOLLPROP_ALLOW_STRETCH);
#ifdef MAPBASE
@ -1492,6 +1502,43 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con
float fPreviousCycle = clamp(pAnimating->GetCycle()-( dt * ( 1 / fSequenceDuration ) ),0.f,1.f);
float fCurCycle = pAnimating->GetCycle();
#ifdef MAPBASE
int deathpose = ACT_INVALID;
int deathframe = 0;
if (ai_death_pose_server_enabled.GetBool() && pAnimating->IsNPC()) {
CAI_BaseNPC* npc = (CAI_BaseNPC*)pAnimating;
if (npc) {
deathpose = Activity(npc->GetDeathPose());
deathframe = npc->GetDeathPoseFrame();
}
}
if (deathpose != ACT_INVALID) {
int currentSequence = pAnimating->GetSequence();
//Force pAnimating to position the deathpose
pAnimating->SetSequence(deathpose);
pAnimating->SetCycle((float)deathframe / MAX_DEATHPOSE_FRAMES);
//Store the position
pAnimating->SetupBones(pBoneToWorldNext, BONE_USED_BY_ANYTHING);
//Restore the current sequence and cycle
pAnimating->SetSequence(currentSequence);
pAnimating->SetCycle(fCurCycle);
pAnimating->SetupBones(pBoneToWorld, BONE_USED_BY_ANYTHING);
}
else {
// Get current bones positions
pAnimating->SetupBones(pBoneToWorldNext, BONE_USED_BY_ANYTHING);
// Get previous bones positions
pAnimating->SetCycle(fPreviousCycle);
pAnimating->SetupBones(pBoneToWorld, BONE_USED_BY_ANYTHING);
// Restore current cycle
pAnimating->SetCycle(fCurCycle);
}
#else
// Get current bones positions
pAnimating->SetupBones( pBoneToWorldNext, BONE_USED_BY_ANYTHING );
// Get previous bones positions
@ -1499,6 +1546,7 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con
pAnimating->SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING );
// Restore current cycle
pAnimating->SetCycle( fCurCycle );
#endif
// Reset previous bone flags
pAnimating->ClearBoneCacheFlags( BCF_NO_ANIMATION_SKIP );
@ -1573,7 +1621,11 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con
}
else
{
#ifdef MAPBASE
pRagdoll->InitRagdoll(info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true, true, deathpose != ACT_INVALID);
#else
pRagdoll->InitRagdoll( info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true );
#endif
}
// Are we dissolving?

View File

@ -75,7 +75,11 @@ public:
// locals
void InitRagdollAnimation( void );
#ifdef MAPBASE
void InitRagdoll( const Vector& forceVector, int forceBone, const Vector& forcePos, matrix3x4_t* pPrevBones, matrix3x4_t* pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll = true, bool bDeathPose = false );
#else
void InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll = true );
#endif
void RecheckCollisionFilter( void );
void SetDebrisThink();