Example #1
0
void RagdollActivate( ragdoll_t &ragdoll, vcollide_t *pCollide, int modelIndex, bool bForceWake )
{
	RagdollSetupCollisions( ragdoll, pCollide, modelIndex );
	for ( int i = 0; i < ragdoll.listCount; i++ )
	{
		ragdoll.list[i].pObject->SetGameIndex( i );
		PhysSetGameFlags( ragdoll.list[i].pObject, FVPHYSICS_MULTIOBJECT_ENTITY );
		// now that the relationships are set, activate the collision system
		ragdoll.list[i].pObject->EnableCollisions( true );

		if ( bForceWake == true )
		{
			ragdoll.list[i].pObject->Wake();
		}
	}
	if ( ragdoll.pGroup )
	{
		// NOTE: This also wakes the objects
		ragdoll.pGroup->Activate();
		// so if we didn't want that, we'll need to put them back to sleep here
		if ( !bForceWake )
		{
			for ( int i = 0; i < ragdoll.listCount; i++ )
			{
				ragdoll.list[i].pObject->Sleep();
			}

		}
	}
}
bool CTripmineGrenade::MakeConstraint( CBaseEntity *pObject )
{
	IPhysicsObject *cMinePhysics = VPhysicsGetObject();

	Assert( cMinePhysics );

	IPhysicsObject *pAttached = pObject->VPhysicsGetObject();
	if ( !cMinePhysics || !pAttached )
		return false;

	// constraining to the world means object 1 is fixed
	if ( pAttached == g_PhysWorldObject )
		PhysSetGameFlags( cMinePhysics, FVPHYSICS_CONSTRAINT_STATIC );

	IPhysicsConstraintGroup *pGroup = NULL;

	constraint_fixedparams_t fixed;
	fixed.Defaults();
	fixed.InitWithCurrentObjectState( cMinePhysics, pAttached );
	fixed.constraint.Defaults();

	m_pConstraint = physenv->CreateFixedConstraint( cMinePhysics, pAttached, pGroup, fixed );
	
	if (!m_pConstraint)
		return false;

	m_pConstraint->SetGameData( (void *)this );

	return true;
}
Example #3
0
//---------------------------------------------------------
//---------------------------------------------------------
void CBounceBomb::CloseHooks()
{
	if( !m_bLockSilently )
	{
		EmitSound( "NPC_CombineMine.CloseHooks" );
	}

	if( VPhysicsGetObject() )
	{
		// It's possible to not have a valid physics object here, since this function doubles as an initialization function.
		PhysSetGameFlags( VPhysicsGetObject(), FVPHYSICS_CONSTRAINT_STATIC );
	}

	// Only lock silently the first time we call this.
	m_bLockSilently = false;

	SetPoseParameter( m_iAllHooks, 0 );

	VPhysicsGetObject()->EnableMotion( false );

	// Once I lock down, forget how many tries it took.
	m_iFlipAttempts = 0;

#ifdef _XBOX 
	AddEffects( EF_NOSHADOW );
#endif
}
Example #4
0
CBaseEntity *CreateCombineBall( const Vector &origin, const Vector &velocity, float radius, float mass, float lifetime, CBaseEntity *pOwner )
{
    if(_CreateCombineBall != NULL)
    {
        CBaseEntity *pReturn = NULL;

        pReturn = _CreateCombineBall(origin, velocity, radius, mass, lifetime, pOwner);

        // If the radius is greater than the max, let's do some hacks to make it work
        if ( radius > 12.0f )
        {
            VFuncs::SetCombineBallRadius( pReturn, radius );

            // After changing the radius, we need to recreate the VPhysics object
            VFuncs::VPhysicsDestroyObject( pReturn );
            VFuncs::CreateVPhysics( pReturn );

            // We need to set the same things on the new physics object that Spawn and CreateCombineBall set
            VFuncs::VPhysicsGetObject( pReturn )->SetVelocity( &velocity, NULL );
            PhysSetGameFlags( VFuncs::VPhysicsGetObject( pReturn ), FVPHYSICS_WAS_THROWN );
        }

        return pReturn;
    }
    return NULL;
}
void CWeaponGravityGun::AttachObject( CBaseEntity *pObject, const Vector& start, const Vector &end, float distance )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
	if( !pOwner )
		return;
	m_hObject = pObject;
	m_useDown = false;
	IPhysicsObject *pPhysics = pObject ? (pObject->VPhysicsGetObject()) : NULL;
	if ( pPhysics && pObject->GetMoveType() == MOVETYPE_VPHYSICS )
	{
		m_distance = distance;

		Vector worldPosition;
		pObject->WorldToEntitySpace( end, &worldPosition );
		m_worldPosition = worldPosition;
		m_gravCallback.AttachEntity( pOwner, pObject, pPhysics, pObject->GetAbsOrigin() );

		m_originalObjectPosition = pObject->GetAbsOrigin();

		pPhysics->Wake();
		PhysSetGameFlags( pPhysics, FVPHYSICS_PLAYER_HELD );

#ifndef CLIENT_DLL
		Pickup_OnPhysGunPickup( pObject, pOwner );
#endif
	}
	else
	{
		m_hObject = NULL;
	}
}
Example #6
0
bool CPhysBox::CreateVPhysics()
{
	solid_t tmpSolid;
	PhysModelParseSolid( tmpSolid, this, GetModelIndex() );
	if ( m_massScale > 0 )
	{
		float mass = tmpSolid.params.mass * m_massScale;
		mass = clamp( mass, 0.5, 1e6 );
		tmpSolid.params.mass = mass;
	}

	PhysSolidOverride( tmpSolid, m_iszOverrideScript );
	IPhysicsObject *pPhysics = VPhysicsInitNormal( GetSolid(), GetSolidFlags(), true, &tmpSolid );

	if ( m_damageType == 1 )
	{
		PhysSetGameFlags( pPhysics, FVPHYSICS_DMG_SLICE );
	}

	// Wake it up if not asleep
	if ( !HasSpawnFlags(SF_PHYSBOX_ASLEEP) )
	{
		VPhysicsGetObject()->Wake();
	}

	if ( HasSpawnFlags(SF_PHYSBOX_MOTIONDISABLED) || m_damageToEnableMotion > 0  )
	{
		VPhysicsGetObject()->EnableMotion( false );
	}

	// only send data when physics moves this object
	NetworkStateManualMode( true );

	return true;
}
Example #7
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRagdollProp::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason )
{
	CDefaultPlayerPickupVPhysics::OnPhysGunDrop( pPhysGunUser, Reason );
	m_hPhysicsAttacker = pPhysGunUser;
	m_flLastPhysicsInfluenceTime = gpGlobals->curtime;

	if( HasPhysgunInteraction( "onpickup", "boogie" ) )
	{
		CRagdollBoogie::Create( this, 150, gpGlobals->curtime, 3.0f, SF_RAGDOLL_BOOGIE_ELECTRICAL );
	}

	if ( HasSpawnFlags( SF_RAGDOLLPROP_USE_LRU_RETIREMENT ) )
	{
		s_RagdollLRU.MoveToTopOfLRU( this );
	}

	// Make sure it's interactive debris for at most 5 seconds
	if ( GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS )
	{
		SetContextThink( &CRagdollProp::SetDebrisThink, gpGlobals->curtime + 5, s_pDebrisContext );
	}

	if ( Reason != LAUNCHED_BY_CANNON )
		return;

	if( HasPhysgunInteraction( "onlaunch", "spin_zaxis" ) )
	{
		Vector vecAverageCenter( 0, 0, 0 );

		// Get the average position, apply forces to produce a spin
		int j;
		ragdoll_t *pRagdollPhys = GetRagdoll( );
		for ( j = 0; j < pRagdollPhys->listCount; ++j )
		{
			Vector vecCenter;
			pRagdollPhys->list[j].pObject->GetPosition( &vecCenter, NULL );
			vecAverageCenter += vecCenter;
		}

		vecAverageCenter /= pRagdollPhys->listCount;

		Vector vecZAxis( 0, 0, 1 );
		for ( j = 0; j < pRagdollPhys->listCount; ++j )
		{
			Vector vecDelta;
			pRagdollPhys->list[j].pObject->GetPosition( &vecDelta, NULL );
			vecDelta -= vecAverageCenter;

			Vector vecDir;
			CrossProduct( vecZAxis, vecDelta, vecDir );
			vecDir *= 100;
			pRagdollPhys->list[j].pObject->AddVelocity( &vecDir, NULL );
		}
	}

	PhysSetGameFlags( VPhysicsGetObject(), FVPHYSICS_WAS_THROWN );
	m_bFirstCollisionAfterLaunch = true;
}
Example #8
0
bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t &params, IPhysicsEnvironment *pPhysEnv )
{
	RagdollCreateObjects( pPhysEnv, ragdoll, params );

	if ( !ragdoll.listCount )
		return false;

	int forceBone = params.forceBoneIndex;
	
	int i;
	float totalMass = 0;
	for ( i = 0; i < ragdoll.listCount; i++ )
	{
		totalMass += ragdoll.list[i].pObject->GetMass();
	}
	totalMass = max(totalMass,1);

	// apply force to the model
	Vector nudgeForce = params.forceVector;
	Vector forcePosition = params.forcePosition;
	// UNDONE: Test scaling the force by total mass on all bones
	
	Assert( forceBone < ragdoll.listCount );

	if ( forceBone >= 0 && forceBone < ragdoll.listCount )
	{
		ragdoll.list[forceBone].pObject->ApplyForceCenter( nudgeForce );
		//nudgeForce *= 0.5;
		ragdoll.list[forceBone].pObject->GetPosition( &forcePosition, NULL );
	}

	for ( i = 0; i < ragdoll.listCount; i++ )
	{
		PhysSetGameFlags( ragdoll.list[i].pObject, FVPHYSICS_PART_OF_RAGDOLL );
	}

	if ( forcePosition != vec3_origin )
	{
		for ( i = 0; i < ragdoll.listCount; i++ )
		{
			if ( forceBone != i )
			{
				float scale = ragdoll.list[i].pObject->GetMass() / totalMass;
				ragdoll.list[i].pObject->ApplyForceOffset( scale * nudgeForce, forcePosition );
			}
		}
	}

	return true;
}
void CGrabController::AttachEntity( CBaseEntity *pEntity, IPhysicsObject *pPhys, const Vector &position, const QAngle &rotation )
{
	pPhys->GetDamping( NULL, &m_saveRotDamping );
	float damping = 10;
	pPhys->SetDamping( NULL, &damping );

	m_controller = physenv->CreateMotionController( this );
	m_controller->AttachObject( pPhys );
	m_controller->SetPriority( IPhysicsMotionController::HIGH_PRIORITY );

	pPhys->Wake();
	PhysSetGameFlags( pPhys, FVPHYSICS_PLAYER_HELD );
	SetTargetPosition( position, rotation );
	m_attachedEntity = pEntity;
	m_flLoadWeight = pPhys->GetMass();
}
bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t &params, IPhysicsCollision *pPhysCollision, IPhysicsEnvironment *pPhysEnv, IPhysicsSurfaceProps *pSurfaceDatabase )
{
	RagdollCreateObjects( pPhysCollision, pPhysEnv, pSurfaceDatabase, ragdoll, params );

	if ( !ragdoll.listCount )
		return false;

	int forceBone = params.forceBoneIndex;
	
	int i;
	float totalMass = 0;
	for ( i = 0; i < ragdoll.listCount; i++ )
	{
		totalMass += ragdoll.list[i].pObject->GetMass();
	}
	totalMass = max(totalMass,1);

	// distribute half to the forced bone, half to the rest of the model
	Vector nudgeForce = params.forceVector;
	if ( forceBone >= 0 && forceBone <= ragdoll.listCount )
	{
		nudgeForce *= 0.5;
		ragdoll.list[forceBone].pObject->ApplyForceCenter( nudgeForce );
	}
	else if ( params.forcePosition != vec3_origin )
	{
		for ( i = 0; i < ragdoll.listCount; i++ )
		{
			float scale = ragdoll.list[i].pObject->GetMass() / totalMass;
			ragdoll.list[i].pObject->ApplyForceOffset( scale * nudgeForce, params.forcePosition );
		}
		nudgeForce.Init();
	}

	RagdollApplyAnimationAsVelocity( ragdoll, params.pPrevBones, params.pCurrentBones, params.boneDt );

	for ( i = 0; i < ragdoll.listCount; i++ )
	{
		float scale = ragdoll.list[i].pObject->GetMass() / totalMass;
		ragdoll.list[i].pObject->ApplyForceCenter( scale * nudgeForce );
		PhysSetGameFlags( ragdoll.list[i].pObject, FVPHYSICS_PART_OF_RAGDOLL );
	}
	return true;
}
Example #11
0
static void RagdollAddSolids( IPhysicsEnvironment *pPhysEnv, ragdoll_t &ragdoll, const ragdollparams_t &params, cache_ragdollsolid_t *pSolids, int solidCount, const cache_ragdollconstraint_t *pConstraints, int constraintCount )
{
	const char *pszName = params.pStudioHdr->pszName();
	Vector position;
	matrix3x4_t xform;
	// init parent index
	for ( int i = 0; i < solidCount; i++ )
	{
		ragdoll.list[i].parentIndex = -1;
	}
	// now set from constraints
	for ( int i = 0; i < constraintCount; i++ )
	{
		// save parent index
		ragdoll.list[pConstraints[i].childIndex].parentIndex = pConstraints[i].parentIndex;
		MatrixGetColumn( pConstraints[i].constraintToAttached, 3, ragdoll.list[pConstraints[i].childIndex].originParentSpace );
	}

	// now setup the solids, using parent indices
	for ( int i = 0; i < solidCount; i++ )
	{	
		ragdoll.boneIndex[i] = pSolids[i].boneIndex;
		pSolids[i].params.pName = pszName;
		pSolids[i].params.pGameData = params.pGameData;
		ragdoll.list[i].pObject = pPhysEnv->CreatePolyObject( params.pCollide->solids[pSolids[i].collideIndex], pSolids[i].surfacePropIndex, vec3_origin, vec3_angle, &pSolids[i].params );
		ragdoll.list[i].pObject->SetGameIndex( i );
		int parentIndex = ragdoll.list[i].parentIndex;
		MatrixCopy( params.pCurrentBones[ragdoll.boneIndex[i]], xform );
		if ( parentIndex >= 0 )
		{
			Assert(parentIndex<i);
			ragdoll.list[parentIndex].pObject->LocalToWorld( &position, ragdoll.list[i].originParentSpace );
			MatrixSetColumn( position, 3, xform );
		}
		ragdoll.list[i].pObject->SetPositionMatrix( xform, true );

		PhysSetGameFlags( ragdoll.list[i].pObject, FVPHYSICS_PART_OF_RAGDOLL );

	}
	ragdoll.listCount = solidCount;
}
void CWeaponGravityGun::AttachObject( CBaseEntity *pObject, IPhysicsObject *pPhysics, short physicsbone, const Vector& start, const Vector &end, float distance )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
	if( !pOwner )
		return;
	m_hObject = pObject;
	m_physicsBone = physicsbone;
	m_useDown = false;
	if ( pPhysics && pObject->GetMoveType() == MOVETYPE_VPHYSICS )
	{
		m_distance = distance;

		Vector worldPosition;
		pPhysics->WorldToLocal( &worldPosition, end );
		m_worldPosition = worldPosition;
		Vector vecOrigin;
		pPhysics->GetPosition( &vecOrigin, NULL );
		m_gravCallback.AttachEntity( pOwner, pObject, pPhysics, physicsbone, vecOrigin );

		m_originalObjectPosition = vecOrigin;

		pPhysics->Wake();
		IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
		int count = pObject->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) );
		for ( int i = 0; i < count; i++ )
		{
			PhysSetGameFlags( pList[i], FVPHYSICS_PLAYER_HELD );
		}

#ifndef CLIENT_DLL
		Pickup_OnPhysGunPickup( pObject, pOwner );
#endif
	}
	else
	{
		m_hObject = NULL;
		m_physicsBone = 0;
	}
}
//-----------------------------------------------------------------------------
// Purpose: Initializes the vehicle physics
//			Called by our outer vehicle in it's Spawn()
//-----------------------------------------------------------------------------
bool CFourWheelVehiclePhysics::Initialize( const char *pVehicleScript, unsigned int nVehicleType )
{
	// Ok, turn on the simulation now
	// FIXME: Disabling collisions here is necessary because we seem to be
	// getting a one-frame collision between the old + new collision models
	if ( m_pOuter->VPhysicsGetObject() )
	{
		m_pOuter->VPhysicsGetObject()->EnableCollisions(false);
	}
	m_pOuter->VPhysicsDestroyObject();

	// Create the vphysics model + teleport it into position
	solid_t solid;
	vehicleparams_t vehicle;
	if (!ParseVehicleScript( pVehicleScript, solid, vehicle ))
	{
		UTIL_Remove(m_pOuter);
		return false;
	}

	// NOTE: this needs to be greater than your max framerate (so zero is still instant)
	m_throttleRate = 10000.0;
	if ( vehicle.engine.throttleTime > 0 )
	{
		m_throttleRate = 1.0 / vehicle.engine.throttleTime;
	}

	m_flMaxSpeed = vehicle.engine.maxSpeed;

	IPhysicsObject *pBody = m_pOuter->VPhysicsInitNormal( SOLID_VPHYSICS, 0, false, &solid );
	PhysSetGameFlags( pBody, FVPHYSICS_NO_SELF_COLLISIONS | FVPHYSICS_MULTIOBJECT_ENTITY );
	m_pVehicle = physenv->CreateVehicleController( pBody, vehicle, nVehicleType, physgametrace );
	m_wheelCount = m_pVehicle->GetWheelCount();
	for ( int i = 0; i < m_wheelCount; i++ )
	{
		m_pWheels[i] = m_pVehicle->GetWheel( i );
	}
	return true;
}
void CGrabController::AttachEntity( CBasePlayer *pPlayer, CBaseEntity *pEntity, IPhysicsObject *pPhys, bool bIsMegaPhysCannon, const Vector &vGrabPosition, bool bUseGrabPosition )
{
	// play the impact sound of the object hitting the player
	// used as feedback to let the player know he picked up the object
	int hitMaterial = pPhys->GetMaterialIndex();
	int playerMaterial = pPlayer->VPhysicsGetObject() ? pPlayer->VPhysicsGetObject()->GetMaterialIndex() : hitMaterial;
	PhysicsImpactSound( pPlayer, pPhys, CHAN_STATIC, hitMaterial, playerMaterial, 1.0, 64 );
	Vector position;
	QAngle angles;
	pPhys->GetPosition( &position, &angles );
	// If it has a preferred orientation, use that instead.
	Pickup_GetPreferredCarryAngles( pEntity, pPlayer, pPlayer->EntityToWorldTransform(), angles );

//	ComputeMaxSpeed( pEntity, pPhys );

	// If we haven't been killed by a grab, we allow the gun to grab the nearest part of a ragdoll
	if ( bUseGrabPosition )
	{
		IPhysicsObject *pChild = GetRagdollChildAtPosition( pEntity, vGrabPosition );
		
		if ( pChild )
		{
			pPhys = pChild;
		}
	}

	// Carried entities can never block LOS
	m_bCarriedEntityBlocksLOS = pEntity->BlocksLOS();
	pEntity->SetBlocksLOS( false );
	m_controller = physenv->CreateMotionController( this );
	m_controller->AttachObject( pPhys, true );
	// Don't do this, it's causing trouble with constraint solvers.
	//m_controller->SetPriority( IPhysicsMotionController::HIGH_PRIORITY );

	pPhys->Wake();
	PhysSetGameFlags( pPhys, FVPHYSICS_PLAYER_HELD );
	SetTargetPosition( position, angles );
	m_attachedEntity = pEntity;
	IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
	int count = pEntity->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) );
	m_flLoadWeight = 0;
	float damping = 10;
	float flFactor = count / 7.5f;
	if ( flFactor < 1.0f )
	{
		flFactor = 1.0f;
	}
	for ( int i = 0; i < count; i++ )
	{
		float mass = pList[i]->GetMass();
		pList[i]->GetDamping( NULL, &m_savedRotDamping[i] );
		m_flLoadWeight += mass;
		m_savedMass[i] = mass;

		// reduce the mass to prevent the player from adding crazy amounts of energy to the system
		pList[i]->SetMass( REDUCED_CARRY_MASS / flFactor );
		pList[i]->SetDamping( NULL, &damping );
	}
	
	// Give extra mass to the phys object we're actually picking up
	pPhys->SetMass( REDUCED_CARRY_MASS );
	pPhys->EnableDrag( false );

	m_errorTime = bIsMegaPhysCannon ? -1.5f : -1.0f; // 1 seconds until error starts accumulating
	m_error = 0;
	m_contactAmount = 0;

	m_attachedAnglesPlayerSpace = TransformAnglesToPlayerSpace( angles, pPlayer );
	if ( m_angleAlignment != 0 )
	{
		m_attachedAnglesPlayerSpace = AlignAngles( m_attachedAnglesPlayerSpace, m_angleAlignment );
	}

	// Ragdolls don't offset this way
	if ( dynamic_cast<CRagdollProp*>(pEntity) )
	{
		m_attachedPositionObjectSpace.Init();
	}
	else
	{
		VectorITransform( pEntity->WorldSpaceCenter(), pEntity->EntityToWorldTransform(), m_attachedPositionObjectSpace );
	}

	// If it's a prop, see if it has desired carry angles
	CPhysicsProp *pProp = dynamic_cast<CPhysicsProp *>(pEntity);
	if ( pProp )
	{
		m_bHasPreferredCarryAngles = pProp->GetPropDataAngles( "preferred_carryangles", m_vecPreferredCarryAngles );
		m_flDistanceOffset = pProp->GetCarryDistanceOffset();
	}
	else
	{
		m_bHasPreferredCarryAngles = false;
		m_flDistanceOffset = 0;
	}

	m_bAllowObjectOverhead = IsObjectAllowedOverhead( pEntity );
}