summaryrefslogtreecommitdiff
path: root/game/client/tf2/c_ragdoll_shadow.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf2/c_ragdoll_shadow.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf2/c_ragdoll_shadow.cpp')
-rw-r--r--game/client/tf2/c_ragdoll_shadow.cpp246
1 files changed, 246 insertions, 0 deletions
diff --git a/game/client/tf2/c_ragdoll_shadow.cpp b/game/client/tf2/c_ragdoll_shadow.cpp
new file mode 100644
index 0000000..efb705b
--- /dev/null
+++ b/game/client/tf2/c_ragdoll_shadow.cpp
@@ -0,0 +1,246 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "model_types.h"
+#include "vcollide.h"
+#include "vcollide_parse.h"
+#include "solidsetdefaults.h"
+#include "c_basetfplayer.h"
+#include "bone_setup.h"
+#include "engine/ivmodelinfo.h"
+
+CPhysCollide *PhysCreateBbox( const Vector &mins, const Vector &maxs );
+extern CSolidSetDefaults g_SolidSetup;
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_RagdollShadow : public C_BaseAnimating
+{
+ DECLARE_CLASS( C_RagdollShadow, C_BaseAnimating );
+public:
+ DECLARE_CLIENTCLASS();
+
+ C_RagdollShadow( void );
+ ~C_RagdollShadow( void );
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+
+ virtual void ClientThink( void );
+ virtual int DrawModel( int flags );
+
+public:
+ IPhysicsObject *VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation );
+ void VPhysicsSetObject( IPhysicsObject *pPhysics );
+ void VPhysicsDestroyObject( void );
+
+ int m_nPlayer;
+ EHANDLE m_hPlayer;
+
+ IPhysicsObject *m_pPhysicsObject;
+ IPhysicsSpring *m_pSpring;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_RagdollShadow, DT_RagdollShadow, CRagdollShadow )
+ RecvPropInt( RECVINFO( m_nPlayer ) ),
+END_RECV_TABLE()
+
+C_RagdollShadow::C_RagdollShadow( void )
+{
+ m_nPlayer = -1;
+ m_hPlayer = NULL;
+
+ m_pPhysicsObject = NULL;
+ m_pSpring = NULL;
+}
+
+C_RagdollShadow::~C_RagdollShadow( void )
+{
+ VPhysicsDestroyObject();
+
+ delete m_pSpring;
+}
+
+void C_RagdollShadow::VPhysicsDestroyObject( void )
+{
+ if ( m_pPhysicsObject )
+ {
+ physenv->DestroyObject( m_pPhysicsObject );
+ m_pPhysicsObject = NULL;
+ }
+}
+
+// Create a physics thingy based on an existing collision model
+IPhysicsObject *PhysModelCreateCustom( C_BaseEntity *pEntity, const CPhysCollide *pModel, const Vector &origin, const QAngle &angles, const char *props )
+{
+ solid_t solid;
+ solid.params = g_PhysDefaultObjectParams;
+ solid.params.mass = 85.0f;
+ solid.params.inertia = 1e24f;
+ int surfaceProp = -1;
+ if ( props && props[0] )
+ {
+ surfaceProp = physprops->GetSurfaceIndex( props );
+ }
+ solid.params.pGameData = static_cast<void *>(pEntity);
+ IPhysicsObject *pObject = physenv->CreatePolyObject( pModel, surfaceProp, origin, angles, &solid.params );
+ return pObject;
+}
+
+IPhysicsObject *PhysModelCreateRagdoll( C_BaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles )
+{
+ vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex );
+ if ( !pCollide )
+ return NULL;
+
+ solid_t solid;
+ memset( &solid, 0, sizeof(solid) );
+ solid.params = g_PhysDefaultObjectParams;
+
+ IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide->pKeyValues );
+ while ( !pParse->Finished() )
+ {
+ const char *pBlock = pParse->GetCurrentBlockName();
+ if ( !strcmpi( pBlock, "solid" ) )
+ {
+ pParse->ParseSolid( &solid, &g_SolidSetup );
+ break;
+ }
+ else
+ {
+ pParse->SkipBlock();
+ }
+ }
+ physcollision->VPhysicsKeyParserDestroy( pParse );
+
+ // collisions are off by default
+ solid.params.enableCollisions = true;
+
+ int surfaceProp = -1;
+ if ( solid.surfaceprop[0] )
+ {
+ surfaceProp = physprops->GetSurfaceIndex( solid.surfaceprop );
+ }
+ solid.params.pGameData = static_cast<void *>(pEntity);
+ solid.params.pName = "ragdoll_player";
+ IPhysicsObject *pObject = physenv->CreatePolyObject( pCollide->solids[0], surfaceProp, origin, angles, &solid.params );
+ //PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) );
+ return pObject;
+}
+
+void C_RagdollShadow::VPhysicsSetObject( IPhysicsObject *pPhysics )
+{
+ if ( m_pPhysicsObject && pPhysics )
+ {
+ Warning( "C_RagdollShadow::Overwriting physics object!\n" );
+ }
+ m_pPhysicsObject = pPhysics;
+}
+
+
+// This creates a vphysics object with a shadow controller that follows the AI
+IPhysicsObject *C_RagdollShadow::VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation )
+{
+ CStudioHdr *hdr = GetModelPtr();
+ if ( !hdr )
+ {
+ return NULL;
+ }
+
+ // If this entity already has a physics object, then it should have been deleted prior to making this call.
+ Assert(!m_pPhysicsObject);
+
+ // make sure m_vecOrigin / m_vecAngles are correct
+ const Vector &origin = GetAbsOrigin();
+ QAngle angles = GetAbsAngles();
+ IPhysicsObject *pPhysicsObject = NULL;
+
+ if ( GetSolid() == SOLID_BBOX )
+ {
+ const char *pSurfaceProps = "flesh";
+ if ( GetModelIndex() && modelinfo->GetModelType( GetModel() ) == mod_studio )
+ {
+ pSurfaceProps = Studio_GetDefaultSurfaceProps( hdr );
+ }
+ angles = vec3_angle;
+ CPhysCollide *pCollide = PhysCreateBbox( WorldAlignMins(), WorldAlignMaxs() );
+ if ( !pCollide )
+ return NULL;
+ pPhysicsObject = PhysModelCreateCustom( this, pCollide, origin, angles, pSurfaceProps );
+ }
+ else
+ {
+ pPhysicsObject = PhysModelCreateRagdoll( this, GetModelIndex(), origin, angles );
+ }
+ VPhysicsSetObject( pPhysicsObject );
+ pPhysicsObject->SetShadow( 1e4, 1e4, allowPhysicsMovement, allowPhysicsRotation );
+ pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
+// PhysAddShadow( this );
+ return pPhysicsObject;
+}
+
+void C_RagdollShadow::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ // Has to happen *after* the client handle is set
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+
+ bool bnewentity = (updateType == DATA_UPDATE_CREATED);
+ if ( bnewentity && ( m_nPlayer != 0 ) )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+
+ Assert( !m_pPhysicsObject );
+
+ C_BaseEntity *pl = static_cast< C_BaseEntity * >( cl_entitylist->GetEnt( m_nPlayer ) );
+ if ( pl )
+ {
+ m_hPlayer = pl;
+ }
+
+ m_pPhysicsObject = VPhysicsInitShadow( true, false );
+ }
+
+ if ( m_pPhysicsObject )
+ {
+ // Create the spring if we don't have one yet
+ if ( !m_pSpring )
+ {
+ C_BaseTFPlayer *pl = static_cast< C_BaseTFPlayer * >( (C_BaseEntity *)m_hPlayer );
+ if ( pl && pl->VPhysicsGetObject() )
+ {
+ springparams_t spring;
+ spring.constant = 15000;
+ spring.damping = 1.0;
+ spring.naturalLength = 0.0f;
+ spring.relativeDamping = 100.0f;
+ VectorCopy( vec3_origin, spring.startPosition );
+ VectorCopy( vec3_origin, spring.endPosition );
+ spring.useLocalPositions = true;
+
+ m_pSpring = physenv->CreateSpring( m_pPhysicsObject, pl->VPhysicsGetObject(), &spring );
+
+ PhysDisableObjectCollisions( m_pPhysicsObject, pl->VPhysicsGetObject() );
+ }
+ }
+
+ m_pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
+ }
+
+}
+
+void C_RagdollShadow::ClientThink( void )
+{
+ BaseClass::ClientThink();
+}
+
+int C_RagdollShadow::DrawModel( int flags )
+{
+// int drawn = BaseClass::DrawModel( flags );
+// return drawn;
+ return 0;
+}