void CEnvHeadcrabCanister::TestForCollisionsAgainstWorld( const Vector &vecEndPosition ) { // Splash damage! // Iterate on all entities in the vicinity. float flDamageRadius = m_flDamageRadius; float flDamage = m_flDamage; CEntity *pEntity; for ( CEntitySphereQuery sphere( vecEndPosition, flDamageRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() ) { if ( pEntity == this ) continue; if ( !pEntity->IsSolid() ) continue; // Get distance to object and use it as a scale value. Vector vecSegment; VectorSubtract( pEntity->GetAbsOrigin(), vecEndPosition, vecSegment ); float flDistance = VectorNormalize( vecSegment ); float flFactor = 1.0f / ( flDamageRadius * (INNER_RADIUS_FRACTION - 1) ); flFactor *= flFactor; float flScale = flDistance - flDamageRadius; flScale *= flScale * flFactor; if ( flScale > 1.0f ) { flScale = 1.0f; } // Check for a physics object and apply force! Vector vecForceDir = vecSegment; IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject(); if ( pPhysObject ) { // Send it flying!!! float flMass = PhysGetEntityMass( pEntity ); vecForceDir *= flMass * 750 * flScale; pPhysObject->ApplyForceCenter( vecForceDir ); } if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) ) { CTakeDamageInfo info( BaseEntity(), BaseEntity(), flDamage * flScale, DMG_BLAST ); CalculateExplosiveDamageForce( &info, vecSegment, pEntity->GetAbsOrigin() ); pEntity->TakeDamage( info ); } if ( pEntity->IsPlayer() && !(static_cast<CPlayer*>(pEntity)->IsInAVehicle()) ) { if (vecSegment.z < 0.1f) { vecSegment.z = 0.1f; VectorNormalize( vecSegment ); } float flAmount = SimpleSplineRemapVal( flScale, 0.0f, 1.0f, 250.0f, 1000.0f ); pEntity->ApplyAbsVelocityImpulse( vecSegment * flAmount ); } } }
//----------------------------------------------------------------------------- // Test for impact! //----------------------------------------------------------------------------- void CEnvHeadcrabCanister::TestForCollisionsAgainstEntities( const Vector &vecEndPosition ) { // Debugging!! // NDebugOverlay::Box( GetAbsOrigin(), m_vecMin * 0.5f, m_vecMax * 0.5f, 255, 255, 0, 0, 5 ); // NDebugOverlay::Box( vecEndPosition, m_vecMin, m_vecMax, 255, 0, 0, 0, 5 ); float flRadius = CollisionProp()->BoundingRadius(); Vector vecMins( -flRadius, -flRadius, -flRadius ); Vector vecMaxs( flRadius, flRadius, flRadius ); Ray_t ray; ray.Init( GetAbsOrigin(), vecEndPosition, vecMins, vecMaxs ); CCollideList collideList( &ray, BaseEntity(), MASK_SOLID ); enginetrace->EnumerateEntities( ray, false, &collideList ); float flDamage = m_flDamage; // Now get each entity and react accordinly! for( int iEntity = collideList.m_Entities.Count(); --iEntity >= 0; ) { CEntity *pEntity = collideList.m_Entities[iEntity]; Vector vecForceDir = m_Shared.m_vecDirection; // Check for a physics object and apply force! IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject(); if ( pPhysObject ) { float flMass = PhysGetEntityMass( pEntity ); vecForceDir *= flMass * 750; pPhysObject->ApplyForceCenter( vecForceDir ); } if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) ) { CTakeDamageInfo info( BaseEntity(), BaseEntity(), flDamage, DMG_BLAST ); CalculateExplosiveDamageForce( &info, vecForceDir, pEntity->GetAbsOrigin() ); pEntity->TakeDamage( info ); } } }