mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-05 22:09:59 +03:00
1
This commit is contained in:
246
game/client/tf2/c_ragdoll_shadow.cpp
Normal file
246
game/client/tf2/c_ragdoll_shadow.cpp
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user