//----------------------------------------------------------------------------- // 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 ); }
//----------------------------------------------------------------------------- // 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 ); } } }
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 ); }
//----------------------------------------------------------------------------- // 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 ); } }