virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
		{
			if ( !PassServerEntityFilter( pHandleEntity, m_pPassEnt ) )
				return false;
			CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );

			if ( pEntity )
			{
				if ( g_pGameRules->ShouldCollide( m_collisionGroupAlreadyChecked, pEntity->GetCollisionGroup() ) )
					return false;
				if ( g_pGameRules->ShouldCollide( m_newCollisionGroup, pEntity->GetCollisionGroup() ) )
					return true;
			}

			return false;
		}
//-----------------------------------------------------------------------------
// The trace filter!
//-----------------------------------------------------------------------------
bool CTraceFilterSimple::ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
{
	if ( !StandardFilterRules( pHandleEntity, contentsMask ) )
		return false;

	if ( m_pPassEnt )
	{
		if ( !PassServerEntityFilter( pHandleEntity, m_pPassEnt ) )
		{
			return false;
		}
	}

	// Don't test if the game code tells us we should ignore this collision...
	CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );
	if ( !pEntity )
		return false;
	if ( !pEntity->ShouldCollide( m_collisionGroup, contentsMask ) )
		return false;
	if ( pEntity && !g_pGameRules->ShouldCollide( m_collisionGroup, pEntity->GetCollisionGroup() ) )
		return false;
	if ( m_pExtraShouldHitCheckFunction &&
		(! ( m_pExtraShouldHitCheckFunction( pHandleEntity, contentsMask ) ) ) )
		return false;

	return true;
}
Example #3
0
	virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
	{
		CBaseEntity *pEntity = (CBaseEntity *)pServerEntity;

		if ( pEntity->GetCollisionGroup() == COLLISION_GROUP_WEAPON )
			return false;

		return BaseClass::ShouldHitEntity( pServerEntity, contentsMask );
	}
void CHL2GameMovement::SetGroundEntity( trace_t *pm )
{
	CBaseEntity *newGround = pm ? pm->m_pEnt : NULL;

	//Adrian: Special case for combine balls.
	if ( newGround && newGround->GetCollisionGroup() == HL2COLLISION_GROUP_COMBINE_BALL_NPC )
	{
		return;
	}

	BaseClass::SetGroundEntity( pm );
}
	virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
	{
		if ( !PassServerEntityFilter( pHandleEntity, m_pPassEnt ) )
			return false;
		CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );
		if ( pEntity )
		{
			if ( pEntity == m_pPassEnt2 )
				return false;
			if ( pEntity->GetCollisionGroup() == TF_COLLISIONGROUP_GRENADES )
				return false;
			if ( pEntity->GetCollisionGroup() == TFCOLLISION_GROUP_ROCKETS )
				return false;
			if ( pEntity->GetCollisionGroup() == COLLISION_GROUP_DEBRIS )
				return false;
			if ( pEntity->GetCollisionGroup() == COLLISION_GROUP_NONE )
				return false;

			return true;
		}

		return true;
	}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pHandleEntity - 
//			contentsMask - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CASW_Trace_Filter_Door_Crush::ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
{
	if ( !StandardFilterRules( pHandleEntity, contentsMask ) )
		return false;

	if ( !PassServerEntityFilter( pHandleEntity, m_pPassEnt ) )
		return false;

	// Don't test if the game code tells us we should ignore this collision...
	CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );
	
	if ( pEntity )
	{
		//Msg("%f CASW_Trace_Filter_Door_Crush::ShouldHitEntity %s\n", gpGlobals->curtime, pEntity->GetClassname());
		if ( !pEntity->ShouldCollide( m_collisionGroup, contentsMask ) )
			return false;
		
		if ( !g_pGameRules->ShouldCollide( m_collisionGroup, pEntity->GetCollisionGroup() ) )
			return false;

		if ( pEntity->Classify() == CLASS_ASW_DOOR )
			return false;

		if ( pEntity->m_takedamage == DAMAGE_NO )
			return false;

		// Translate the vehicle into its driver for damage
		if ( pEntity->GetServerVehicle() != NULL )
		{
			CBaseEntity *pDriver = pEntity->GetServerVehicle()->GetPassenger();

			if ( pDriver != NULL )
			{
				pEntity = pDriver;
			}
		}

		Vector	attackDir = pEntity->WorldSpaceCenter() - m_dmgInfo->GetAttacker()->WorldSpaceCenter();
		VectorNormalize( attackDir );
	
		pEntity->TakeDamage( *m_dmgInfo );

		//CalculateMeleeDamageForce( &info, attackDir, info.GetAttacker()->WorldSpaceCenter(), m_flForceScale );
		return true;
	}

	return false;
}
	virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
	{
		CBaseEntity *pEntity = (CBaseEntity *)pServerEntity;

		if ( pEntity->GetCollisionGroup() == COLLISION_GROUP_WEAPON )
			return false;

		// Don't collide with the tracing entity's vehicle (if it exists)
		if ( pServerEntity == m_pVehicle )
			return false;

		if ( pEntity->GetHealth() > 0 )
		{
			CBreakable *pBreakable = dynamic_cast<CBreakable *>(pEntity);
			if ( pBreakable  && pBreakable->IsBreakable() && pBreakable->GetMaterialType() == matGlass)
			{
				return false;
			}
		}

		return BaseClass::ShouldHitEntity( pServerEntity, contentsMask );
	}
void CGETKnife::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
{
	// Call the baseclass first so we don't interfere with the normal running of things
	BaseClass::VPhysicsCollision( index, pEvent );

	// Grab what we hit
	CBaseEntity *pOther = pEvent->pEntities[!index];

	if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) )
		return;

	if ( !PassServerEntityFilter( this, pOther) )
		return;

	if ( !g_pGameRules->ShouldCollide( GetCollisionGroup(), pOther->GetCollisionGroup() ) )
		return;

	trace_t tr;
	CollisionEventToTrace( index, pEvent, tr );

	Vector vecAiming = pEvent->preVelocity[index];
	VectorNormalize( vecAiming );

	if ( pOther->m_takedamage != DAMAGE_NO && (pOther->IsPlayer() || pOther->IsNPC()) )
	{
		ClearMultiDamage();

		CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), GetDamage(), DMG_SLASH | DMG_NEVERGIB );
		CalculateMeleeDamageForce( &dmgInfo, vecAiming, tr.endpos, TKNIFE_FORCE_SCALE );
		dmgInfo.SetDamagePosition( tr.endpos );

		if ( this->GetOwnerEntity() && this->GetOwnerEntity()->IsPlayer() )
		{
			CBasePlayer *pPlayer = ToBasePlayer( this->GetOwnerEntity() );
			dmgInfo.SetWeapon( pPlayer->Weapon_OwnsThisType( "weapon_throwing_knife" ) );
		}

		pOther->DispatchTraceAttack( dmgInfo, vecAiming, &tr );
		
		ApplyMultiDamage();

		PhysCallbackSetVelocity( pEvent->pObjects[index], vec3_origin );

		SetTouch( NULL );
		SetThink( NULL );

		PhysCallbackRemove( this->NetworkProp() );
	}
	else
	{
		if ( pOther->IsWorld() )
		{
			// We hit the world, we have to check if this is sky
			trace_t tr2;
			Vector origin;
			pEvent->pInternalData->GetContactPoint( origin );
			UTIL_TraceLine( origin, origin + (vecAiming * 4), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr2 );
			if ( tr2.surface.flags & SURF_SKY )
			{
				// We hit sky, remove us NOW
				SetTouch( NULL );
				SetThink( NULL );

				PhysCallbackRemove( this->NetworkProp() );
				return;
			}
		}

		m_bInAir = false;
		
		CollisionProp()->UseTriggerBounds( true, 24 );

		g_PostSimulationQueue.QueueCall( this, &CBaseEntity::SetOwnerEntity, (CBaseEntity*)NULL );

//		const CBaseEntity *host = te->GetSuppressHost();
//		te->SetSuppressHost( NULL );
//		StopParticleEffects( this );
//		te->SetSuppressHost( (CBaseEntity*)host );

		SetTouch( &CGETKnife::PickupTouch );
		SetThink( &CGETKnife::RemoveThink );

		g_PostSimulationQueue.QueueCall(this, &CBaseEntity::SetCollisionGroup, COLLISION_GROUP_DROPPEDWEAPON);

		SetNextThink( gpGlobals->curtime + 10.0f );
	}
}
bool CNPC_Dog::FindPhysicsObject( const char *pPickupName, CBaseEntity *pIgnore )
{
	CBaseEntity		*pEnt = NULL;
	CBaseEntity		*pNearest = NULL;
	float			flDist;
	IPhysicsObject	*pPhysObj = NULL;
	float			flNearestDist = 99999;

	if ( pPickupName != NULL && strlen( pPickupName ) > 0 )
	{
		pEnt = gEntList.FindEntityByName( NULL, pPickupName );
		
		if ( m_hUnreachableObjects.Find( pEnt ) == -1  )
		{
			m_bHasObject = false;
			m_hPhysicsEnt = pEnt;
			return true;
		}
	}
	
	while ( ( pEnt = gEntList.FindEntityByClassname( pEnt, "prop_physics" ) ) != NULL )
	{
		//We don't want this one.
		if ( pEnt == pIgnore )
			 continue;

		if ( m_hUnreachableObjects.Find( pEnt ) != -1 )
			 continue;

		pPhysObj = pEnt->VPhysicsGetObject();

		if( pPhysObj == NULL )
			continue;

		if ( pPhysObj->GetMass() > DOG_MAX_THROW_MASS )
			 continue;
		
		Vector center = pEnt->WorldSpaceCenter();
		flDist = UTIL_DistApprox2D( GetAbsOrigin(), center );

		vcollide_t *pCollide = modelinfo->GetVCollide( pEnt->GetModelIndex() );

		if ( pCollide == NULL )
			 continue;

		if ( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
			 continue;

		if ( pPhysObj->IsMoveable() == false )
			 continue;

		if ( pEnt->GetCollisionGroup() == COLLISION_GROUP_DEBRIS || 
			 pEnt->GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS )
			 continue;

		if ( center.z > EyePosition().z )
			 continue;

		if ( flDist >= flNearestDist )
			 continue;

		if ( FVisible( pEnt ) == false )
			 continue;
		
		pNearest = pEnt;
		flNearestDist = flDist;
	}

	m_bHasObject = false;
	m_hPhysicsEnt = pNearest;

	if ( dog_debug.GetBool() == true )
	{
		if ( pNearest )
			 NDebugOverlay::Box( pNearest->WorldSpaceCenter(), pNearest->CollisionProp()->OBBMins(), pNearest->CollisionProp()->OBBMaxs(), 255, 0, 255, true, 3 );
	}

	if( m_hPhysicsEnt == NULL )
	{
		return false;
	}
	else
	{
		return true;
	}
}
Example #10
0
//Called from PhysicsSimulate() or ReceiveMessage()
bool CDHLProjectile::OnTouch( trace_t &touchtr, bool bDecalOnly /*= false*/, ITraceFilter* pTraceFilter /*= NULL*/ )
{
	//Direction
	Vector vecDir = touchtr.endpos - touchtr.startpos;
	if ( vecDir == vec3_origin ) //Sometimes endpos==startpos so we need to get dir from velocity instead
	{
		#ifdef CLIENT_DLL
			vecDir = GetLocalVelocity();
		#else
			vecDir = m_vecCurVelocity;
		#endif
		VectorNormalize( vecDir );
	}

	CBaseEntity* ent = touchtr.m_pEnt;
	if ( !ent )
		return false;

	if ( touchtr.DidHit() )
	{
		//Never collide with self, shooter, or other projectiles
		if ( ent == this || dynamic_cast<CDHLProjectile*>(ent)
			|| ent == (CBaseEntity*)m_pShooter )
			//|| ( (m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE) && (ent == m_pFiringWeapon) ) ) //Combat knife - don't collide with weapon ent
			return false;

		//Hack: Sometimes hits are registered prematurely (usually to the torso area) with no hitbox.  Pretend nothing happened unless one is found.
		if ( ent->IsPlayer() && touchtr.hitgroup == 0 )
			return false;

		//Check friendly fire
		if ( CheckFriendlyFire( ent ) )
		{
			if ( !bDecalOnly )
			{
				ClearMultiDamage();

				//Do damage
				CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET  );
				if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE )
				{
					//CalculateMeleeDamageForce( &dmgInfo, vecDir, touchtr.endpos, 0.01f );
					Vector vecForce = vecDir;
					VectorNormalize( vecForce );
					//vecForce *= 10.0f; //Ripped from C_ClientRagdoll::ImpactTrace
					dmgInfo.SetDamageForce( vecForce );

					#ifndef CLIENT_DLL
						if ( IsOnFire() )
						{
							CBaseAnimating* pBAnim = dynamic_cast<CBaseAnimating*>(ent);
							if ( pBAnim )
								pBAnim->Ignite( 10.0f, false );
						}
					#endif
				}
				else
					CalculateBulletDamageForce( &dmgInfo, m_iAmmoType, vecDir, touchtr.endpos, 1.0f );
				dmgInfo.SetDamagePosition( touchtr.endpos );
				ent->DispatchTraceAttack( dmgInfo, vecDir, &touchtr );
				ApplyMultiDamage();
			}

			#ifdef CLIENT_DLL
				if ( ent->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
					return false;

				//Decals and such
				if ( !( touchtr.surface.flags & SURF_SKY ) && !touchtr.allsolid )
				{
					IPredictionSystem::SuppressEvents( false );
					if ( (m_iType == DHL_PROJECTILE_TYPE_BULLET || m_iType == DHL_PROJECTILE_TYPE_PELLET) )
					{
						UTIL_ImpactTrace( &touchtr, DMG_BULLET );
					}
					if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE )
						PlayImpactSound( touchtr.m_pEnt, touchtr, touchtr.endpos, touchtr.surface.surfaceProps );
					IPredictionSystem::SuppressEvents( !prediction->IsFirstTimePredicted() );
				}
			#endif
		}

		if ( pTraceFilter && m_iType != DHL_PROJECTILE_TYPE_COMBATKNIFE )
		{
			PenetrationData_t nPenetrationData = DHLShared::TestPenetration( touchtr, m_pShooter, pTraceFilter, 
				m_iTimesPenetrated, m_flDistanceTravelled, m_iAmmoType );
			if ( nPenetrationData.m_bShouldPenetrate )
			{
				m_flDistanceTravelled += GetLocalOrigin().DistTo( nPenetrationData.m_vecNewBulletPos );
				MoveProjectileToPosition( nPenetrationData.m_vecNewBulletPos );
				m_iTimesPenetrated++;
				return true; //Keep going - but don't do anything else in this frame of PhysicsSimulate()
			}
		}
	
		//We're done unless what we hit was breakable glass
		if ( ent->GetCollisionGroup() != COLLISION_GROUP_BREAKABLE_GLASS )
		{
			#ifdef CLIENT_DLL
				m_bCollided = true;
				AddEffects( EF_NODRAW );
				if ( m_pTrail ) //NULL pointer here sometimes somehow...
					m_pTrail->AddEffects( EF_NODRAW );
			#else
				EntityMessageBegin( this );
					WRITE_BYTE( MSG_NOTIFY_REMOVAL );
				MessageEnd();
				
				if ( touchtr.DidHitWorld() && m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE && !( touchtr.surface.flags & SURF_SKY ) )
				{
					CBaseCombatWeapon* pKnifeEnt = assert_cast<CBaseCombatWeapon*>(CreateEntityByName( "weapon_combatknife" ));
					if ( pKnifeEnt )
					{
						pKnifeEnt->AddSpawnFlags( SF_NORESPAWN ); //Needed for weapon spawn & VPhysics setup to work correctly
						pKnifeEnt->SetAbsOrigin( touchtr.endpos );
						QAngle angles = vec3_angle;
						Vector vecKnifeDir = touchtr.startpos - touchtr.endpos;
						VectorAngles( vecKnifeDir, angles );
						angles[PITCH] -= 15.0f; //Correct for the .mdl being offset a bit
						pKnifeEnt->SetLocalAngles( angles );
						DispatchSpawn( pKnifeEnt );

						//Spawns vphys object and sets it up, essentially a copy of CWeaponHL2MPBase::FallInit()
						pKnifeEnt->VPhysicsDestroyObject();
						//Using SOLID_VPHYSICS instead of SOLID_BBOX (as ordinary weapons do) helps resolve some of the client side collision oddities
						Assert( pKnifeEnt->VPhysicsInitNormal( SOLID_VPHYSICS, FSOLID_NOT_STANDABLE | FSOLID_TRIGGER, true ) );
						pKnifeEnt->SetPickupTouch(); //Sets up automagic removal after time
						IPhysicsObject* pKnifePhys = pKnifeEnt->VPhysicsGetObject();
						if ( pKnifePhys )
						{
							//Knives are solid to bullets...the only way to make them non-solid to bullets is to do SetSolid( SOLID_NONE ) or AddSolidFlags( FSOLID_NOT_SOLID )
							//which breaks the +use pickup even with FSOLID_TRIGGER set.  Let's just call it a feature :)
							pKnifePhys->EnableMotion( false );
							pKnifePhys->EnableCollisions( false );
						}

						if ( IsOnFire() )
							pKnifeEnt->Ignite( 10.0f, false );
					}
				}

				//SetThink( &CDHLProjectile::SUB_Remove );
				//SetNextThink( gpGlobals->curtime + 0.1 );
				//SUB_Remove();
				//SetMoveType( MOVETYPE_NONE );
				m_flRemoveAt = gpGlobals->curtime + 0.1f; //Give the notification message a head start so that the client will have time to react
			#endif
		}
	}
	return true;
}
//-----------------------------------------------------------------------------
// Purpose: Return true if the truck's in a valid position
//-----------------------------------------------------------------------------
bool CVehicleTeleportStation::ValidDeployPosition( void )
{
	// Setup for teleporting
	QAngle vecAngles;
	if ( !GetAttachment( "teleport_corner1", m_vecTeleporterMins, vecAngles ) || !GetAttachment( "teleport_corner4", m_vecTeleporterMaxs, vecAngles ) )
		return false;

	m_vecTeleporterMaxs.z += TELEPORT_STATION_ZONE_HEIGHT;

	// Make sure we've got the right mins & maxs
	for ( int i = 0; i < 3; i++ )
	{
		if ( m_vecTeleporterMaxs[i] < m_vecTeleporterMins[i] )
		{
			float flVal = m_vecTeleporterMaxs[i];
			m_vecTeleporterMaxs[i] = m_vecTeleporterMins[i];
			m_vecTeleporterMins[i] = flVal;
		}
	}

	Vector vecDelta = (m_vecTeleporterMaxs - m_vecTeleporterMins) * 0.5;
	Vector vecEnd = (m_vecTeleporterMaxs + m_vecTeleporterMins) * 0.5; 
	Vector vecSrc = vecEnd + Vector(0,0,TELEPORT_STATION_ZONE_HEIGHT * 0.5);

	// Make sure it's clear
	// Take the hull, start it high, and try and trace down
	trace_t tr;
	UTIL_TraceHull( vecSrc, vecEnd, -vecDelta, vecDelta, MASK_SOLID, this, COLLISION_GROUP_PLAYER_MOVEMENT, &tr );

	//NDebugOverlay::Box( m_vecTeleporterMins, Vector(-2,-2,-2), Vector(2,2,2), 0,255,0,8, 0.1 );
	//NDebugOverlay::Box( m_vecTeleporterMaxs, Vector(-2,-2,-2), Vector(2,2,2), 0,255,0,8, 0.1 );
	//NDebugOverlay::Box( vecSrc, -vecDelta, vecDelta, 255,0,0,8, 0.1 );
	//NDebugOverlay::Box( vecEnd, -vecDelta, vecDelta, 0,0,255,8, 0.1 );
	//NDebugOverlay::Line( m_vecTeleporterMins, m_vecTeleporterMaxs, 255,255,255, 1, 0.1 );

	// Make sure it's clear
	if ( tr.startsolid )
		return false;

	// Get a list of nearby entities
	CBaseEntity *pListOfNearbyEntities[100];
	int iNumberOfNearbyEntities = UTIL_EntitiesInBox( pListOfNearbyEntities, 100, m_vecTeleporterMins, m_vecTeleporterMaxs, MASK_ALL );
	for ( i = 0; i < iNumberOfNearbyEntities; i++ )
	{
		CBaseEntity *pEntity = pListOfNearbyEntities[i];
		if ( pEntity->IsSolid( ) )
		{
			if ( pEntity == this )
				continue;
			if ( pEntity->GetCollisionGroup() == TFCOLLISION_GROUP_SHIELD )
				continue;
			if ( pEntity->IsPlayer() )
				continue;

			//NDebugOverlay::Box( pEntity->GetAbsOrigin(), pEntity->WorldAlignMins(), pEntity->WorldAlignMaxs(), 0,255,0,8, 0.1 );
			//NDebugOverlay::Box( pEntity->GetAbsOrigin(), pEntity->GetAbsMins() - pEntity->GetAbsOrigin(), pEntity->GetAbsMaxs() - pEntity->GetAbsOrigin(), 255,0,0,8, 0.1 );
			return false;
		}
	}

	m_vecTeleporterCenter = vecEnd;
	m_vecTeleporterCenter.z = m_vecTeleporterMins.z;
	return true;
}