Пример #1
0
//-----------------------------------------------------------------------------
// Purpose: Allows us to take damage from physics objects
//-----------------------------------------------------------------------------
void CBreakable::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
{
	BaseClass::VPhysicsCollision( index, pEvent );

	Vector damagePos;
	pEvent->pInternalData->GetContactPoint( damagePos );
	Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass();
	if ( damageForce == vec3_origin )
	{
		// This can happen if this entity is a func_breakable, and can't move.
		// Use the velocity of the entity that hit us instead.
		damageForce = pEvent->postVelocity[!index] * pEvent->pObjects[!index]->GetMass();
	}

	// If we're supposed to explode on collision, do so
	if ( HasSpawnFlags( SF_BREAK_PHYSICS_BREAK_IMMEDIATELY ) )
	{
		// We're toast
		m_bTookPhysicsDamage = true;
		CBaseEntity *pHitEntity = pEvent->pEntities[!index];

		// HACKHACK: Reset mass to get correct collision response for the object breaking this glass
		if ( m_Material == matGlass )
		{
			pEvent->pObjects[index]->SetMass( 2.0f );
		}
		CTakeDamageInfo dmgInfo( pHitEntity, pHitEntity, damageForce, damagePos, (m_iHealth + 1), DMG_CRUSH );
		PhysCallbackDamage( this, dmgInfo, *pEvent, index );
	}
	else if ( !HasSpawnFlags( SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE ) )
	{
		int otherIndex = !index;
		CBaseEntity *pOther = pEvent->pEntities[otherIndex];

		// We're to take normal damage from this
		int damageType;
		IBreakableWithPropData *pBreakableInterface = assert_cast<IBreakableWithPropData*>(this);
		float damage = CalculateDefaultPhysicsDamage( index, pEvent, m_impactEnergyScale, true, damageType, pBreakableInterface->GetPhysicsDamageTable() );
		if ( damage > 0 )
		{
			// HACKHACK: Reset mass to get correct collision response for the object breaking this glass
			if ( m_Material == matGlass )
			{
				pEvent->pObjects[index]->SetMass( 2.0f );
			}
			CTakeDamageInfo dmgInfo( pOther, pOther, damageForce, damagePos, damage, damageType );
			PhysCallbackDamage( this, dmgInfo, *pEvent, index );
		}
	}
}
Пример #2
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : index - 
//			*pEvent - 
//-----------------------------------------------------------------------------
void CGrubNugget::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
{
	int damageType;
	float damage = CalculateDefaultPhysicsDamage( index, pEvent, 1.0f, true, damageType );
	if ( damage > 5.0f )
	{
		CBaseEntity *pHitEntity = pEvent->pEntities[!index];
		if ( pHitEntity == NULL )
		{
			// hit world
			pHitEntity = GetContainingEntity( INDEXENT(0) );
		}
		
		Vector damagePos;
		pEvent->pInternalData->GetContactPoint( damagePos );
		Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass();
		if ( damageForce == vec3_origin )
		{
			// This can happen if this entity is motion disabled, and can't move.
			// Use the velocity of the entity that hit us instead.
			damageForce = pEvent->postVelocity[!index] * pEvent->pObjects[!index]->GetMass();
		}

		// FIXME: this doesn't pass in who is responsible if some other entity "caused" this collision
		PhysCallbackDamage( this, CTakeDamageInfo( pHitEntity, pHitEntity, damageForce, damagePos, damage, damageType ), *pEvent, index );
	}

	BaseClass::VPhysicsCollision( index, pEvent );
}
void CBreakableSurface::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
{
	if ( !m_bIsBroken )
	{
		int damageType = 0;
		string_t iszDamageTable = ( ( m_nSurfaceType == SHATTERSURFACE_GLASS ) ? ( "glass" ) : ( NULL_STRING ) );
		bool bDamageFromHeldObjects = ( ( m_spawnflags & SF_BREAKABLESURF_DAMAGE_FROM_HELD_OBJECTS ) != 0 );
		float damage = CalculateDefaultPhysicsDamage( index, pEvent, 1.0, false, damageType, iszDamageTable, bDamageFromHeldObjects );

		if ( damage > 10 )
		{
			// HACKHACK: Reset mass to get correct collision response for the object breaking this
			pEvent->pObjects[index]->SetMass( 2.0f );

			Vector normal, damagePos;
			pEvent->pInternalData->GetSurfaceNormal( normal );
			if ( index == 0 )
			{
				normal *= -1.0f;
			}
			pEvent->pInternalData->GetContactPoint( damagePos );
			int otherIndex = !index;
			CBaseEntity *pInflictor = pEvent->pEntities[otherIndex];
			CTakeDamageInfo info( pInflictor, pInflictor, normal, damagePos, damage, damageType );
			PhysCallbackDamage( this, info, *pEvent, index );
		}
		else if ( damage > 0 )
		{
			if ( m_spawnflags & SF_BREAKABLESURF_CRACK_DECALS )
			{

				Vector normal, damagePos;
				pEvent->pInternalData->GetSurfaceNormal( normal );
				if ( index == 0 )
				{
					normal *= -1.0f;
				}
				pEvent->pInternalData->GetContactPoint( damagePos );

				trace_t tr;
				UTIL_TraceLine ( damagePos - normal, damagePos + normal, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );

				// Only place decals and draw effects if we hit something valid
				if ( tr.m_pEnt && tr.m_pEnt == this )
				{
					// Build the impact data
					CEffectData data;
					data.m_vOrigin = tr.endpos;
					data.m_vStart = tr.startpos;
					data.m_nSurfaceProp = tr.surface.surfaceProps;
					data.m_nDamageType = DMG_CLUB;
					data.m_nHitBox = tr.hitbox;
					data.m_nEntIndex = entindex();

					// Send it on its way
					DispatchEffect( "Impact", data );
				}
			}
		}
	}
	BaseClass::VPhysicsCollision( index, pEvent );
}
Пример #4
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRagdollProp::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
{
	BaseClass::VPhysicsCollision( index, pEvent );

	CBaseEntity *pHitEntity = pEvent->pEntities[!index];
	if ( pHitEntity == this )
		return;

	// Don't take physics damage from whoever's holding him with the physcannon.
	if ( VPhysicsGetObject() && (VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD) )
	{
		if ( pHitEntity && (pHitEntity == HasPhysicsAttacker( FLT_MAX )) )
			return;
	}

	// Don't bother taking damage from the physics attacker
	if ( pHitEntity && HasPhysicsAttacker( 0.5f ) == pHitEntity )
		return;

	if( m_bFirstCollisionAfterLaunch )
	{
		HandleFirstCollisionInteractions( index, pEvent );
	}
	
	if ( m_takedamage != DAMAGE_NO )
	{
		int damageType = 0;
		float damage = CalculateDefaultPhysicsDamage( index, pEvent, 1.0f, true, damageType );
		if ( damage > 0 )
		{
			// Take extra damage after we're punted by the physcannon
			if ( m_bFirstCollisionAfterLaunch )
			{
				damage *= 10;
			}

			CBaseEntity *pHitEntity = pEvent->pEntities[!index];
			if ( !pHitEntity )
			{
				// hit world
				pHitEntity = GetContainingEntity( INDEXENT(0) );
			}
			Vector damagePos;
			pEvent->pInternalData->GetContactPoint( damagePos );
			Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass();
			if ( damageForce == vec3_origin )
			{
				// This can happen if this entity is motion disabled, and can't move.
				// Use the velocity of the entity that hit us instead.
				damageForce = pEvent->postVelocity[!index] * pEvent->pObjects[!index]->GetMass();
			}

			// FIXME: this doesn't pass in who is responsible if some other entity "caused" this collision
			PhysCallbackDamage( this, CTakeDamageInfo( pHitEntity, pHitEntity, damageForce, damagePos, damage, damageType ), *pEvent, index );
		}
	}

	if ( m_bFirstCollisionAfterLaunch )
	{
		// Setup the think function to remove the flags
		SetThink( &CRagdollProp::ClearFlagsThink );
		SetNextThink( gpGlobals->curtime );
	}
}