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