예제 #1
0
int CNPC_BaseTurret::OnTakeDamage( const CTakeDamageInfo &info )
{
	int retVal = 0;

	if (!m_takedamage)
		return 0;

	switch( m_lifeState )
	{
	case LIFE_ALIVE:
		retVal = OnTakeDamage_Alive( info );
		if ( m_iHealth <= 0 )
		{
			IPhysicsObject *pPhysics = VPhysicsGetObject();
			if ( pPhysics )
			{
				pPhysics->EnableCollisions( false );
			}
			
			Event_Killed( info );	
			Event_Dying();
		}
		return retVal;
		break;

	case LIFE_DYING:
		return OnTakeDamage_Dying( info );
	
	default:
	case LIFE_DEAD:
		return OnTakeDamage_Dead( info );
	}
}
예제 #2
0
void CFuncVehicleClip::InputDisable( inputdata_t &data )
{
	IPhysicsObject *pPhys = VPhysicsGetObject();
	if ( pPhys )
	{
		pPhys->EnableCollisions( false );
	}
	AddSolidFlags( FSOLID_NOT_SOLID );
}
예제 #3
0
void CFuncVehicleClip::InputEnable( inputdata_t &data )
{
	IPhysicsObject *pPhys = VPhysicsGetObject();
	if ( pPhys )
	{
		pPhys->EnableCollisions( true );
	}
	RemoveSolidFlags( FSOLID_NOT_SOLID );
}
예제 #4
0
void CFuncWallToggle::TurnOn( void )
{
	IPhysicsObject *pPhys = VPhysicsGetObject();
	if ( pPhys )
	{
		pPhys->EnableCollisions( true );
	}
	RemoveSolidFlags( FSOLID_NOT_SOLID );
	RemoveEffects( EF_NODRAW );
}
예제 #5
0
void CFuncWallToggle::TurnOff( void )
{
	IPhysicsObject *pPhys = VPhysicsGetObject();
	if ( pPhys )
	{
		pPhys->EnableCollisions( false );
	}
	AddSolidFlags( FSOLID_NOT_SOLID );
	AddEffects( EF_NODRAW );
}
예제 #6
0
bool CFuncBrush::CreateVPhysics( void )
{
	IPhysicsObject *pPhys = VPhysicsInitShadow( false, false );
	if ( pPhys )
	{
		int contents = modelinfo->GetModelContents( GetModelIndex() );
		if ( ! (contents & (MASK_SOLID|MASK_PLAYERSOLID|MASK_NPCSOLID)) )
		{
			// leave the physics shadow there in case it has crap constrained to it
			// but disable collisions with it
			pPhys->EnableCollisions( false );
		}
	}
	return true;
}
예제 #7
0
파일: ragdoll.cpp 프로젝트: BoXorz/MSS
CRagdoll::~CRagdoll( void )
{
    for ( int i = 0; i < m_ragdoll.listCount; i++ )
    {
        IPhysicsObject *pObject = m_ragdoll.list[i].pObject;
        if ( pObject )
        {
            g_pPhysSaveRestoreManager->ForgetModel( m_ragdoll.list[i].pObject );
            // Disable collision on all ragdoll parts before calling RagdollDestroy
            // (which might cause touch callbacks on the ragdoll otherwise, which is
            // very bad for a half deleted ragdoll).
            pObject->EnableCollisions( false );
        }
    }

    RagdollDestroy( m_ragdoll );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAI_PassengerBehaviorZombie::StartDismount( void )
{
	// Leap off the vehicle
	int nSequence = FindExitSequence();
	Assert( nSequence != -1 );

	SetTransitionSequence( nSequence );
	GetOuter()->SetIdealActivity( ACT_SCRIPT_CUSTOM_MOVE );

	// This removes the NPC from the vehicle's handling and fires all necessary outputs
	m_hVehicle->RemovePhysicsChild( GetOuter() );
	m_hVehicle->NPC_RemovePassenger( GetOuter() );
	m_hVehicle->NPC_FinishedExitVehicle( GetOuter(), (IsPassengerHostile()==false) );

	// Detach from the parent
	GetOuter()->SetParent( NULL );
	GetOuter()->SetMoveType( MOVETYPE_STEP );
	GetMotor()->SetYawLocked( false );

	QAngle vecAngles = GetAbsAngles();
	vecAngles.z = 0.0f;
	GetOuter()->SetAbsAngles( vecAngles );

	// HACK: Will this work?
	IPhysicsObject *pPhysObj = GetOuter()->VPhysicsGetObject();
	if ( pPhysObj != NULL )
	{
		pPhysObj->EnableCollisions( true );
	}

	// Clear this
	m_PassengerIntent = PASSENGER_INTENT_NONE;
	SetPassengerState( PASSENGER_STATE_EXITING );

	// Get the velocity
	Vector vecUp, vecJumpDir;
	GetOuter()->GetVectors( &vecJumpDir, NULL, &vecUp );

	// Move back and up
	vecJumpDir *= random->RandomFloat( -400.0f, -500.0f );
	vecJumpDir += vecUp * 150.0f;
	GetOuter()->SetAbsVelocity( vecJumpDir );
}
예제 #9
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;
}