Example #1
0
void CNPC_Zombine::DropGrenade( Vector vDir )
{
	if ( m_hGrenade == NULL )
		 return;

	m_hGrenade->SetParent( NULL );
	m_hGrenade->SetOwnerEntity( NULL );

	Vector vGunPos;
	QAngle angles;
	GetAttachment( "grenade_attachment", vGunPos, angles );

	IPhysicsObject *pPhysObj = m_hGrenade->VPhysicsGetObject();

	if ( pPhysObj == NULL )
	{
		m_hGrenade->SetMoveType( MOVETYPE_VPHYSICS );
		m_hGrenade->SetSolid( SOLID_VPHYSICS );
		m_hGrenade->SetCollisionGroup( COLLISION_GROUP_WEAPON );

		m_hGrenade->CreateVPhysics();
	}

	if ( pPhysObj )
	{
		pPhysObj->Wake();
		pPhysObj->SetPosition( vGunPos, angles, true );
		pPhysObj->ApplyForceCenter( vDir * 0.2f );

		pPhysObj->RecheckCollisionFilter();
	}

	m_hGrenade = NULL;
}
void CNPC_Dog::CleanCatchAndThrow( bool bClearTimers )
{
	if ( m_hPhysicsEnt )
	{
		if ( m_bHasObject == true )
		{
			IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();

			m_hPhysicsEnt->SetParent( NULL );
			m_hPhysicsEnt->SetOwnerEntity( NULL );

			Vector vGunPos;
			QAngle angGunAngles;
			GetAttachment( m_iPhysGunAttachment, vGunPos, angGunAngles );

			if ( pPhysObj )
			{
				pPhysObj->Wake();
				pPhysObj->RemoveShadowController();
				pPhysObj->SetPosition( vGunPos, angGunAngles, true );
			}
			else
			{
				Warning( "CleanCatchAndThrow:   m_hPhysicsEnt->VPhysicsGetObject == NULL!\n" );
			}

			m_hPhysicsEnt->SetMoveType( (MoveType_t)m_iContainerMoveType );

			if ( pPhysObj )
			{
				pPhysObj->RecheckCollisionFilter();
			}
	
			ClearBeams();
		}
		
		m_hPhysicsEnt = NULL;
	}

	if ( bClearTimers == true )
	{
		 m_bDoCatchThrowBehavior = false;
		 m_bDoWaitforObjectBehavior = false;
		 m_flTimeToCatch = 0.0f;
		 m_flNextSwat = 0.0f;

		 SetCondition( COND_DOG_LOST_PHYSICS_ENTITY );
	}
}
Example #3
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pEntity - 
//			modelIndex - 
//			&origin - 
//			&angles - 
//			*pSolid - 
// Output : IPhysicsObject
//-----------------------------------------------------------------------------
IPhysicsObject *PhysModelCreate( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles, solid_t *pSolid )
{
	vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex );
	if ( !pCollide || !pCollide->solidCount )
		return NULL;
	
	solid_t tmpSolid;
	if ( !pSolid )
	{
		pSolid = &tmpSolid;
		if ( !PhysModelParseSolidByIndex( tmpSolid, pEntity, pCollide, -1 ) )
			return NULL;
	}

	int surfaceProp = -1;
	if ( pSolid->surfaceprop[0] )
	{
		surfaceProp = physprops->GetSurfaceIndex( pSolid->surfaceprop );
	}
	IPhysicsObject *pObject = physenv->CreatePolyObject( pCollide->solids[pSolid->index], surfaceProp, origin, angles, &pSolid->params );
	//PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) );

	if ( pObject )
	{
		if ( modelinfo->GetModelType(modelinfo->GetModel(modelIndex)) == mod_brush )
		{
			unsigned int contents = modelinfo->GetModelContents( modelIndex );
			Assert(contents!=0);
			// HACKHACK: contents is used to filter collisions
			// HACKHACK: So keep solid on for water brushes since they should pass collision rules (as triggers)
			if ( contents & MASK_WATER )
			{
				contents |= CONTENTS_SOLID;
			}
			if ( contents != pObject->GetContents() && contents != 0 )
			{
				pObject->SetContents( contents );
				pObject->RecheckCollisionFilter();
			}
		}

		g_pPhysSaveRestoreManager->AssociateModel( pObject, modelIndex);
	}

	return pObject;
}
void C_PhysPropClientside::Break()
{
	m_takedamage = DAMAGE_NO;
	
	IPhysicsObject *pPhysics = VPhysicsGetObject();

	Vector velocity;
	AngularImpulse angVelocity;
	Vector origin;
	QAngle angles;
	AddSolidFlags( FSOLID_NOT_SOLID );

	if ( pPhysics )
	{
		pPhysics->GetVelocity( &velocity, &angVelocity );
		pPhysics->GetPosition( &origin, &angles );
		pPhysics->RecheckCollisionFilter();
	}
	else
	{
		velocity = GetAbsVelocity();
		QAngleToAngularImpulse( GetLocalAngularVelocity(), angVelocity );
		origin = GetAbsOrigin();
		angles = GetAbsAngles();
	}

	breakablepropparams_t params( origin, angles, velocity, angVelocity );
	params.impactEnergyScale = m_impactEnergyScale;
	params.defCollisionGroup = GetCollisionGroup();
	if ( params.defCollisionGroup == COLLISION_GROUP_NONE )
	{
		// don't automatically make anything COLLISION_GROUP_NONE or it will
		// collide with debris being ejected by breaking
		params.defCollisionGroup = COLLISION_GROUP_INTERACTIVE;
	}

	// no damage/damage force? set a burst of 100 for some movement
	params.defBurstScale = 100;

	// spwan break chunks
	PropBreakableCreateAll( GetModelIndex(), pPhysics, params, this, -1, false );

	Release(); // destroy object
}
void CNPC_Dog::PickupOrCatchObject( const char *pAttachmentName )
{
	if ( m_hPhysicsEnt )
	{
		InvalidateBoneCache();

		int iAttachment = LookupAttachment( pAttachmentName );

		if ( iAttachment == 0 )
			 iAttachment = m_iPhysGunAttachment;
		
		// Move physobject to shadow
		IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject();
		if ( pPhysicsObject )
		{
			pPhysicsObject->SetShadow( 1e4, 1e4, false, false );
			pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
		}
		
		m_iContainerMoveType = m_hPhysicsEnt->GetMoveType();
		m_hPhysicsEnt->SetMoveType( MOVETYPE_NONE );
		
		m_hPhysicsEnt->SetParent( this, iAttachment );
	
		m_hPhysicsEnt->SetLocalOrigin( vec3_origin );
		m_hPhysicsEnt->SetLocalAngles( vec3_angle );

		m_hPhysicsEnt->SetGroundEntity( NULL );
		

		if ( m_hPhysicsEnt->GetOwnerEntity() == NULL )
			 m_hPhysicsEnt->SetOwnerEntity( this );

		if ( pPhysicsObject )
			 pPhysicsObject->RecheckCollisionFilter();

		m_bHasObject = true;

		//Fire Output!
		m_OnPickup.FireOutput( this, this );
	}
}
Example #6
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pEntity - 
//			modelIndex - 
//			&origin - 
//			&angles - 
// Output : IPhysicsObject
//-----------------------------------------------------------------------------
IPhysicsObject *PhysModelCreateUnmoveable( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles )
{
	vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex );
	if ( !pCollide || !pCollide->solidCount )
		return NULL;

	solid_t solid;

	if ( !PhysModelParseSolidByIndex( solid, pEntity, pCollide, -1 ) )
		return NULL;

	// collisions are off by default
	solid.params.enableCollisions = true;
	//solid.params.mass = 1.0;
	int surfaceProp = -1;
	if ( solid.surfaceprop[0] )
	{
		surfaceProp = physprops->GetSurfaceIndex( solid.surfaceprop );
	}
	solid.params.pGameData = static_cast<void *>(pEntity);
	solid.params.pName = STRING(pEntity->GetModelName());
	IPhysicsObject *pObject = physenv->CreatePolyObjectStatic( pCollide->solids[0], surfaceProp, origin, angles, &solid.params );

	//PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) );
	if ( pObject )
	{
		if ( modelinfo->GetModelType(modelinfo->GetModel(modelIndex)) == mod_brush )
		{
			unsigned int contents = modelinfo->GetModelContents( modelIndex );
			Assert(contents!=0);
			if ( contents != pObject->GetContents() && contents != 0 )
			{
				pObject->SetContents( contents );
				pObject->RecheckCollisionFilter();
			}
		}
		g_pPhysSaveRestoreManager->AssociateModel( pObject, modelIndex);
	}

	return pObject;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CTriggerPortalCleanser::TransferPhysicsObject( CBaseEntity *pFrom, CBaseEntity *pTo, bool wakeUp )
{
	IPhysicsObject *pVPhysics = pFrom->VPhysicsGetObject();
	if ( !pVPhysics || pVPhysics->IsStatic() )
		return false;

	Vector vecVelocity, vecAngular;
	pVPhysics->GetVelocity( &vecVelocity, &vecAngular );

	// clear out the pointer so it won't get deleted
	pFrom->VPhysicsSwapObject( NULL );
	// remove any AI behavior bound to it
	pVPhysics->RemoveShadowController();
	// transfer to the new owner
	pTo->VPhysicsSetObject( pVPhysics );
	pVPhysics->SetGameData( (void *)pTo );
	pTo->VPhysicsUpdate( pVPhysics );
	
	// may have been temporarily disabled by the old object
	pVPhysics->EnableMotion( true );
	pVPhysics->EnableGravity( false );
	
	// Slow down and push up the object.
	vecVelocity /= 2;
	vecAngular /= 2;
	vecVelocity.z += 10;
	pVPhysics->SetVelocity( &vecVelocity, &vecAngular );

	// Update for the new entity solid type
	pVPhysics->RecheckCollisionFilter();
	if ( wakeUp )
	{
		pVPhysics->Wake();
	}

	return true;
}
Example #8
0
// UNDONE: Is this worth it?, just recreate the object instead? (that happens when this returns false anyway)
// recreating works, but is more expensive and won't inherit properties (velocity, constraints, etc)
bool TransferPhysicsObject( CBaseEntity *pFrom, CBaseEntity *pTo )
{
	IPhysicsObject *pVPhysics = pFrom->VPhysicsGetObject();
	if ( !pVPhysics || pVPhysics->IsStatic() )
		return false;

	// clear out the pointer so it won't get deleted
	pFrom->VPhysicsSwapObject( NULL );
	// remove any AI behavior bound to it
	pVPhysics->RemoveShadowController();
	// transfer to the new owner
	pTo->VPhysicsSetObject( pVPhysics );
	pVPhysics->SetGameData( (void *)pTo );
	pTo->VPhysicsUpdate( pVPhysics );
	
	// may have been temporarily disabled by the old object
	pVPhysics->EnableMotion( true );
	pVPhysics->EnableGravity( true );
	
	// Update for the new entity solid type
	pVPhysics->RecheckCollisionFilter();

	return true;
}
void CNPC_Dog::ThrowObject( const char *pAttachmentName )
{
	if ( m_hPhysicsEnt )
	{
		m_bHasObject = false;

		IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();

		if ( pPhysObj )
		{
			Vector vGunPos;
			QAngle angGunAngles;

			AngularImpulse angVelocity = RandomAngularImpulse( -250 , -250 ) / pPhysObj->GetMass();

			InvalidateBoneCache();

			int iAttachment = LookupAttachment( pAttachmentName );

			if ( iAttachment == 0 )
				 iAttachment = m_iPhysGunAttachment;
			
			GetAttachment( iAttachment, vGunPos, angGunAngles );

			pPhysObj->Wake();

			if ( pPhysObj->GetShadowController() )
			{
				m_hPhysicsEnt->SetParent( NULL );
				m_hPhysicsEnt->SetMoveType( (MoveType_t)m_iContainerMoveType );
				m_hPhysicsEnt->SetOwnerEntity( this );

				pPhysObj->RemoveShadowController();
				pPhysObj->SetPosition( m_hPhysicsEnt->GetLocalOrigin(), m_hPhysicsEnt->GetLocalAngles(), true );

				pPhysObj->RecheckCollisionFilter();
				pPhysObj->RecheckContactPoints();
			}
				
			if ( m_hThrowTarget == NULL )
			#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
				m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this); 
			#else
				m_hThrowTarget = AI_GetSinglePlayer();
			#endif //SecobMod__Enable_Fixed_Multiplayer_AI

			Vector vThrowDirection;

			if ( m_hThrowTarget )
			{
				Vector vThrowOrigin = m_hThrowTarget->GetAbsOrigin();
				
				if ( m_hThrowTarget->IsPlayer() )
					 vThrowOrigin = vThrowOrigin + Vector( random->RandomFloat( -128, 128 ), random->RandomFloat( -128, 128 ), 0 );

				Vector vecToss = VecCheckToss( this, vGunPos, vThrowOrigin, m_flThrowArcModifier, 1.0f, true );

				if( vecToss == vec3_origin )
				{
					// Fix up an impossible throw so dog will at least toss the box in the target's general direction instead of dropping it.
					// Also toss it up in the air so it will fall down and break. (Just throw the box up at a 45 degree angle)
					Vector forward, up;
					GetVectors( &forward, NULL, &up );

					vecToss = forward + up;
					VectorNormalize( vecToss );

					vecToss *= pPhysObj->GetMass() * 30.0f;
				}

				vThrowDirection = vecToss + ( m_hThrowTarget->GetSmoothedVelocity() / 2 );
							
				Vector vLinearDrag;

				Vector unitVel = vThrowDirection;
				VectorNormalize( unitVel );

				float flTest = 1000 / vThrowDirection.Length();

				float flDrag = pPhysObj->CalculateLinearDrag( vThrowDirection );
				vThrowDirection = vThrowDirection + ( unitVel * ( flDrag * flDrag ) ) / flTest;
			
				pPhysObj->SetVelocity( &vThrowDirection, &angVelocity );
				
				m_flTimeToCatch = gpGlobals->curtime + dog_max_wait_time.GetFloat();

				//Don't start pulling until the object is away from me.
				//We base the time on the throw velocity.
				m_flTimeToPull = gpGlobals->curtime + ( 1000 / vThrowDirection.Length() );
			}

			//Fire Output!
			m_OnThrow.FireOutput( this, this );

			ClearBeams();
			
			if ( m_bBeamEffects == true )
			{
				EmitSound( "Weapon_PhysCannon.Launch" );
				
				CBeam *pBeam = CBeam::BeamCreate(  "sprites/orangelight1.vmt", 1.8 );

				if ( pBeam != NULL )
				{
					pBeam->PointEntInit( m_hPhysicsEnt->WorldSpaceCenter(), this );
					pBeam->SetEndAttachment( m_iPhysGunAttachment );
					pBeam->SetWidth( 6.4 );
					pBeam->SetEndWidth( 12.8 );					
					pBeam->SetBrightness( 255 );
					pBeam->SetColor( 255, 255, 255 );
					pBeam->LiveForTime( 0.2f );
					pBeam->RelinkBeam();
					pBeam->SetNoise( 2 );
				}
			
				Vector	shotDir = ( m_hPhysicsEnt->WorldSpaceCenter() - vGunPos );
				VectorNormalize( shotDir );

				CPVSFilter filter( m_hPhysicsEnt->WorldSpaceCenter() );
				te->GaussExplosion( filter, 0.0f, m_hPhysicsEnt->WorldSpaceCenter() - ( shotDir * 4.0f ), RandomVector(-1.0f, 1.0f), 0 );
			}
		}
	}
}
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_Dog::StartTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{

	case TASK_DOG_SETUP_THROW_TARGET:
		{
			SetupThrowTarget();
			TaskComplete();
		}
		break;
	case TASK_DOG_GET_PATH_TO_PHYSOBJ:
		{
			FindPhysicsObject( STRING( m_sObjectName ) );

			if ( m_hPhysicsEnt == NULL )
			{
				 FindPhysicsObject( NULL );
				 return;
			}

			IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject();
			
			Vector vecGoalPos;
			Vector vecDir;

			vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
			VectorNormalize(vecDir);
			vecDir.z = 0;
		
			if ( m_hPhysicsEnt->GetOwnerEntity() == NULL )
				 m_hPhysicsEnt->SetOwnerEntity( this );
		
			if ( pPhysicsObject )
				 pPhysicsObject->RecheckCollisionFilter();

			vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

			//If I'm near my goal, then just walk to it.
			Activity aActivity = ACT_RUN;

			if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
				 aActivity = ACT_WALK;

			if ( GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ) == false )
			{
				 if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 )
					  m_hUnreachableObjects.AddToTail( m_hPhysicsEnt );
					
				 FindPhysicsObject( NULL, m_hPhysicsEnt );

				 m_flTimeToCatch = gpGlobals->curtime + 0.1;
				 m_flNextRouteTime = gpGlobals->curtime + 0.3;
				 m_flNextSwat = gpGlobals->curtime + 0.1;

				 GetNavigator()->ClearGoal();
			}
			else
			{
				TaskComplete();
			}
		}
		break;

	case TASK_DOG_FACE_OBJECT:
		{
			if( m_hPhysicsEnt == NULL )
			{
				// Physics Object is gone! Probably was an explosive 
				// or something else broke it.
				TaskFail("Physics ent NULL");
				return;
			}

			Vector vecDir;

			vecDir = m_hPhysicsEnt->WorldSpaceCenter() - GetLocalOrigin();
			VectorNormalize(vecDir);

			GetMotor()->SetIdealYaw( UTIL_VecToYaw( vecDir ) );
			TaskComplete();
		}
		break;
		
	case TASK_DOG_PICKUP_ITEM:
		{
			if( m_hPhysicsEnt == NULL )
			{
				// Physics Object is gone! Probably was an explosive 
				// or something else broke it.
				TaskFail("Physics ent NULL");
				return;
			}
			else
			{
				SetIdealActivity( (Activity)ACT_DOG_PICKUP );
			}
		}

		break;
		
	case TASK_DOG_LAUNCH_ITEM:
		{
			if( m_hPhysicsEnt == NULL )
			{
				// Physics Object is gone! Probably was an explosive 
				// or something else broke it.
				TaskFail("Physics ent NULL");
				return;
			}
			else
			{
				if ( m_hPhysicsEnt == NULL || m_bHasObject == false )
				{
					 TaskFail( "Don't have the item!" );
					 return;
				}

				SetIdealActivity( (Activity)ACT_DOG_THROW );
			}
		}

		break;

	case TASK_DOG_WAIT_FOR_TARGET_TO_FACE:
		{
			if ( CanTargetSeeMe() )
				 TaskComplete();
		}
		break;

	case TASK_DOG_WAIT_FOR_OBJECT:
		{
			SetIdealActivity( (Activity)ACT_DOG_WAITING );
		}
		break;

	case TASK_DOG_CATCH_OBJECT:
	{
		SetIdealActivity( (Activity)ACT_DOG_CATCH  );
	}
	break;
			
	case TASK_DOG_DELAY_SWAT:
		m_flNextSwat = gpGlobals->curtime + pTask->flTaskData;

		if ( m_hThrowTarget == NULL )
		#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
			m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this); 
		#else
			m_hThrowTarget = AI_GetSinglePlayer();
		#endif //SecobMod__Enable_Fixed_Multiplayer_AI

		TaskComplete();
		break;

	default:
		BaseClass::StartTask( pTask );
	}
}
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_Dog::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{

	case TASK_DOG_PICKUP_ITEM:
	{
		 PullObject( false );
	}
	break;

	case TASK_DOG_GET_PATH_TO_PHYSOBJ:
		{
			//Check this cause our object might have been deleted.
			if ( m_hPhysicsEnt == NULL )
				 FindPhysicsObject( NULL );

			//And if we still can't find anything, then just go away.
			if ( m_hPhysicsEnt == NULL )
			{
				TaskFail( "Can't find an object I like!" );
				return;
			}
	
			IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject();
			
			Vector vecGoalPos;
			Vector vecDir;

			vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
			VectorNormalize(vecDir);
			vecDir.z = 0;
		
			if ( m_hPhysicsEnt->GetOwnerEntity() == NULL )
				 m_hPhysicsEnt->SetOwnerEntity( this );
		
			if ( pPhysicsObject )
				 pPhysicsObject->RecheckCollisionFilter();

			vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

			bool bBuiltRoute = false;

			//If I'm near my goal, then just walk to it.
			Activity aActivity = ACT_RUN;

			if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
				 aActivity = ACT_WALK;

			bBuiltRoute = GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL );

			if ( bBuiltRoute == true )
				 TaskComplete();
			else
			{
				m_flTimeToCatch = gpGlobals->curtime + 0.1;
				m_flNextRouteTime = gpGlobals->curtime + 0.3;
				m_flNextSwat = gpGlobals->curtime + 0.1;

				if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 )
					 m_hUnreachableObjects.AddToTail( m_hPhysicsEnt );
								
				m_hPhysicsEnt = NULL;

				GetNavigator()->ClearGoal();
			}
		}
		break;

	case TASK_WAIT:
	{
		if ( IsWaitFinished() )
		{
			TaskComplete();
		}

		if ( m_hPhysicsEnt )
		{
			if ( m_bHasObject == false )
			{
				GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() );
				GetMotor()->UpdateYaw();
			}
		}

		break;
	}

	case TASK_DOG_LAUNCH_ITEM:
		if( IsActivityFinished() )
		{
			if ( m_hPhysicsEnt )
			{
				m_hPhysicsEnt->SetOwnerEntity( NULL );
			}

			TaskComplete();
		}
		break;

	case TASK_DOG_WAIT_FOR_TARGET_TO_FACE:
	{
		if ( CanTargetSeeMe() )
			 TaskComplete();
	}
		break;

	case TASK_WAIT_FOR_MOVEMENT:
		{
			if ( GetState() == NPC_STATE_SCRIPT || IsInAScript() )
			{
			  	 BaseClass::RunTask( pTask );
				 return;
			}

			if ( m_hPhysicsEnt != NULL )
			{
				IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();
					
				if ( !pPhysObj )
				{
					Warning( "npc_dog TASK_WAIT_FOR_MOVEMENT with NULL m_hPhysicsEnt->VPhysicsGetObject\n" );
				}

				if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
					 TaskFail( "Player picked it up!" );

				//If the object is moving then my old goal might not be valid
				//cancel the schedule and make it restart again in a bit.
				if ( pPhysObj && pPhysObj->IsAsleep() == false && GetNavigator()->IsGoalActive() == false )
				{
					Vector vecGoalPos;
					Vector vecDir;
				
					vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
					VectorNormalize(vecDir);
					vecDir.z = 0;
									
					vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

					GetNavigator()->ClearGoal();

					float flDistance = (vecGoalPos - GetLocalOrigin()).Length();

					//If I'm near my goal, then just walk to it.
					Activity aActivity = ACT_RUN;

					if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
						 aActivity = ACT_WALK;

				    GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL );

					if ( flDistance <= DOG_PHYSOBJ_MOVE_TO_DIST )
					{
						TaskComplete();
						GetNavigator()->StopMoving();
					}
				}
			}
			
			BaseClass::RunTask( pTask );
		}
		break;

	case TASK_DOG_WAIT_FOR_OBJECT:
		{
			if ( m_hPhysicsEnt != NULL )
			{
				if ( FVisible( m_hPhysicsEnt ) == false )
				{
					m_flTimeToCatch = 0.0f;
					ClearBeams();
					TaskFail( "Lost sight of the object!" );
					m_hPhysicsEnt->SetOwnerEntity( NULL );
					return;
				}

				m_hPhysicsEnt->SetOwnerEntity( this );

				Vector vForward;
				AngleVectors( GetAbsAngles(), &vForward );


				Vector vGunPos;
				GetAttachment( m_iPhysGunAttachment, vGunPos );

				Vector vToObject = m_hPhysicsEnt->WorldSpaceCenter() - vGunPos;
				float flDistance = vToObject.Length();

				VectorNormalize( vToObject );

				SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() );

				#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
					CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this); 
				#else
					CBasePlayer *pPlayer = AI_GetSinglePlayer();
				#endif //SecobMod__Enable_Fixed_Multiplayer_AI

				float flDistanceToPlayer = flDistance;

				if ( pPlayer )
				{
					flDistanceToPlayer = (pPlayer->GetAbsOrigin() - m_hPhysicsEnt->WorldSpaceCenter()).Length();
				}
			
				IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();
				if ( !pPhysObj )
				{
					Warning( "npc_dog:  TASK_DOG_WAIT_FOR_OBJECT with m_hPhysicsEnt->VPhysicsGetObject == NULL\n" );
				}
					
				if ( pPhysObj && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) && flDistanceToPlayer > ( flDistance * 2 ) )
				{
					if ( m_flTimeToPull <= gpGlobals->curtime )
					{
						Vector vCurrentVel;
						float flCurrentVel;
						AngularImpulse vCurrentAI;

						pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI );

						flCurrentVel = vCurrentVel.Length();
						VectorNormalize( vCurrentVel );

						if ( pPhysObj && flDistance <= DOG_PULL_DISTANCE )
						{
							Vector vDir = ( vGunPos -  m_hPhysicsEnt->WorldSpaceCenter() );
								
							VectorNormalize( vDir );

							vCurrentVel = vCurrentVel * ( flCurrentVel * DOG_PULL_VELOCITY_MOD );

							vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD;
							pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI );

							vDir = vDir * flDistance * DOG_PULL_TO_GUN_VEL_MOD;

							Vector vAngle( 0, 0, 0 );
							pPhysObj->AddVelocity( &vDir, &vAngle );
							
							CreateBeams();
						}
					
						float flDot = DotProduct( vCurrentVel, vForward );

						if ( flDistance >= DOG_PULL_DISTANCE && flDistance <= ( DOG_PULL_DISTANCE * 2 ) && flDot > -0.3 )
						{
							if ( pPhysObj->IsAsleep() == false && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) )
							{
								Vector vecGoalPos;
								Vector vecDir;

								vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
								VectorNormalize(vecDir);
								vecDir.z = 0;
												
								vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

								GetNavigator()->ClearGoal();

								//If I'm near my goal, then just walk to it.
								Activity aActivity = ACT_RUN;

								if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
									 aActivity = ACT_WALK;
									 
								GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ),  AIN_NO_PATH_TASK_FAIL );
							}
						}
					}
				}


				float flDirDot = DotProduct( vToObject, vForward );

				if ( flDirDot < 0.2 )
				{
					GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() );
					GetMotor()->UpdateYaw();
				}

				if ( m_flTimeToCatch < gpGlobals->curtime && m_bDoWaitforObjectBehavior == false ) 
				{
					m_hPhysicsEnt->SetOwnerEntity( NULL );
					m_flTimeToCatch = 0.0f;
					ClearBeams();
					TaskFail( "Done waiting!" );
				}
				else if ( pPhysObj && ( flDistance <= DOG_CATCH_DISTANCE && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) )
				{
					AngularImpulse vZero( 0, 0, 0 );
					pPhysObj->SetVelocity( &vec3_origin, &vZero );

					GetNavigator()->StopMoving();

					//Fire Output!
					m_OnCatch.FireOutput( this, this );
					m_bHasObject = true;
					ClearBeams();
					TaskComplete();
				}
			}
			else
			{
				GetNavigator()->StopMoving();

				ClearBeams();
				TaskFail("No Physics Object!");
			}
			
		}
		break;

	case TASK_DOG_CATCH_OBJECT:
		if( IsActivityFinished() )
		{
			m_flTimeToCatch = 0.0f;
			TaskComplete();
		}
		break;
	default:
		BaseClass::RunTask( pTask );
		break;
	}
}