aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/server/physics_prop_ragdoll.h
blob: 7c24b47ee03f67cc5d7ac5fefa0861df5f341450 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#ifndef PHYSICS_PROP_RAGDOLL_H
#define PHYSICS_PROP_RAGDOLL_H
#ifdef _WIN32
#pragma once
#endif

#include "ragdoll_shared.h"
#include "player_pickup.h"


//-----------------------------------------------------------------------------
// Purpose: entity class for simple ragdoll physics
//-----------------------------------------------------------------------------

// UNDONE: Move this to a private header
class CRagdollProp : public CBaseAnimating, public CDefaultPlayerPickupVPhysics
{
	DECLARE_CLASS( CRagdollProp, CBaseAnimating );

public:
	CRagdollProp( void );
	~CRagdollProp( void );

	virtual void UpdateOnRemove( void );

	void DrawDebugGeometryOverlays();

	void Spawn( void );
	void Precache( void );

	// Disable auto fading under dx7 or when level fades are specified
	void DisableAutoFade();

	int ObjectCaps();

	DECLARE_SERVERCLASS();
	// Don't treat as a live target
	virtual bool IsAlive( void ) { return false; }
	
	virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &dir, trace_t *ptr, CDmgAccumulator *pAccumulator );
	virtual bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
	virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
	virtual void SetupBones( matrix3x4_t *pBoneToWorld, int boneMask );
	virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
	virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );

	virtual int DrawDebugTextOverlays(void);

	// Response system stuff
	virtual IResponseSystem *GetResponseSystem();
	virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set );
	void SetSourceClassName( const char *pClassname );

	// Physics attacker
	virtual CBasePlayer *HasPhysicsAttacker( float dt );

	// locals
	void InitRagdollAnimation( void );
	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 );
	
	void RecheckCollisionFilter( void );
	void SetDebrisThink();
	void ClearFlagsThink( void );
	inline ragdoll_t *GetRagdoll( void ) { return &m_ragdoll; }

	virtual bool	IsRagdoll() { return true; }

	// Damage passing
	virtual void	SetDamageEntity( CBaseEntity *pEntity );
	virtual int		OnTakeDamage( const CTakeDamageInfo &info );
	virtual void OnSave( IEntitySaveUtils *pUtils );
	virtual void OnRestore();

	// Purpose: CDefaultPlayerPickupVPhysics
	virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
 	virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
	virtual void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason );
	virtual AngularImpulse	PhysGunLaunchAngularImpulse();
	bool HasPhysgunInteraction( const char *pszKeyName, const char *pszValue );
	void HandleFirstCollisionInteractions( int index, gamevcollisionevent_t *pEvent );

	void			SetUnragdoll( CBaseAnimating *pOther );

	void			SetBlendWeight( float weight ) { m_flBlendWeight = weight; }
	void			SetOverlaySequence( Activity activity );
	void			FadeOut( float flDelay = 0, float fadeTime = -1 );
	bool			IsFading();
	CBaseEntity*	GetKiller() { return m_hKiller; }
	void			SetKiller( CBaseEntity *pKiller ) { m_hKiller = pKiller; }
	void			GetAngleOverrideFromCurrentState( char *pOut, int size );

	void			DisableMotion( void );

	// Input/Output
	void			InputStartRadgollBoogie( inputdata_t &inputdata );
	void			InputEnableMotion( inputdata_t &inputdata );
	void			InputDisableMotion( inputdata_t &inputdata );
	void			InputTurnOn( inputdata_t &inputdata );
	void			InputTurnOff( inputdata_t &inputdata );
	void			InputFadeAndRemove( inputdata_t &inputdata );

	DECLARE_DATADESC();

protected:
	void CalcRagdollSize( void );
	ragdoll_t			m_ragdoll;

private:
	void UpdateNetworkDataFromVPhysics( IPhysicsObject *pPhysics, int index );
	void FadeOutThink();

	bool				m_bStartDisabled;

	CNetworkArray( Vector, m_ragPos, RAGDOLL_MAX_ELEMENTS );
	CNetworkArray( QAngle, m_ragAngles, RAGDOLL_MAX_ELEMENTS );

	string_t			m_anglesOverrideString;

	typedef CHandle<CBaseAnimating> CBaseAnimatingHandle;
	CNetworkVar( CBaseAnimatingHandle, m_hUnragdoll );


	unsigned int		m_lastUpdateTickCount;
	bool				m_allAsleep;
	bool				m_bFirstCollisionAfterLaunch;
	EHANDLE				m_hDamageEntity;
	EHANDLE				m_hKiller;	// Who killed me?
	CHandle<CBasePlayer>	m_hPhysicsAttacker;
	float					m_flLastPhysicsInfluenceTime;
	float				m_flFadeOutStartTime;
	float				m_flFadeTime;


	string_t			m_strSourceClassName;
	bool				m_bHasBeenPhysgunned;

	// If not 1, then allow underlying sequence to blend in with simulated bone positions
	CNetworkVar( float, m_flBlendWeight );
	CNetworkVar( int, m_nOverlaySequence );
	float	m_flDefaultFadeScale;
	
	Vector				m_ragdollMins[RAGDOLL_MAX_ELEMENTS];
	Vector				m_ragdollMaxs[RAGDOLL_MAX_ELEMENTS];
};

CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, const CTakeDamageInfo &info, int collisionGroup, bool bUseLRURetirement = false );
CRagdollProp *CreateServerRagdollAttached( CBaseAnimating *pAnimating, const Vector &vecForce, int forceBone, int collisionGroup, IPhysicsObject *pAttached, CBaseAnimating *pParentEntity, int boneAttach, const Vector &originAttached, int parentBoneAttach, const Vector &boneOrigin );
void DetachAttachedRagdoll( CBaseEntity *pRagdollIn );
void DetachAttachedRagdollsForEntity( CBaseEntity *pRagdollParent );
CBaseAnimating *CreateServerRagdollSubmodel( CBaseAnimating *pOwner, const char *pModelName, const Vector &position, const QAngle &angles, int collisionGroup );

bool Ragdoll_IsPropRagdoll( CBaseEntity *pEntity );
void Ragdoll_GetAngleOverrideString( char *pOut, int size, CBaseEntity *pEntity );
ragdoll_t *Ragdoll_GetRagdoll( CBaseEntity *pEntity );

#endif // PHYSICS_PROP_RAGDOLL_H