void CRebelZombie::StartTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_ZOMBIE_EXPRESS_ANGER: { if ( random->RandomInt( 1, 4 ) == 2 ) { SetIdealActivity( (Activity)ACT_REBEL_ZOMBIE_TANTRUM ); } else { TaskComplete(); } break; } case TASK_ZOMBIE_YAW_TO_DOOR: { AssertMsg( m_hBlockingDoor != NULL, "Expected condition handling to break schedule before landing here" ); if ( m_hBlockingDoor != NULL ) { GetMotor()->SetIdealYaw( m_flDoorBashYaw ); } TaskComplete(); break; } case TASK_ZOMBIE_ATTACK_DOOR: { m_DurationDoorBash.Reset(); SetIdealActivity( SelectDoorBash() ); break; } case TASK_ZOMBIE_CHARGE_ENEMY: { if ( !GetEnemy() ) TaskFail( FAIL_NO_ENEMY ); else if ( GetNavigator()->SetVectorGoalFromTarget( GetEnemy()->GetLocalOrigin() ) ) { m_vPositionCharged = GetEnemy()->GetLocalOrigin(); TaskComplete(); } else TaskFail( FAIL_NO_ROUTE ); break; } default: BaseClass::StartTask( pTask ); break; } }
void CASW_Parasite::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_RANGE_ATTACK1: case TASK_RANGE_ATTACK2: { if ( IsActivityFinished() ) { TaskComplete(); m_bMidJump = false; SetTouch( NULL ); SetThink( &CASW_Parasite::CallNPCThink ); SetIdealActivity( ACT_IDLE ); } break; } case TASK_PARASITE_JUMP_FROM_EGG: GetMotor()->UpdateYaw(); if ( FacingIdeal() ) { TaskComplete(); } break; default: BaseClass::RunTask( pTask ); break; } }
//----------------------------------------------------------------------------- // Purpose: Target doesn't exist or has eluded us, so search for one //----------------------------------------------------------------------------- void CNPC_CombineCamera::SearchThink() { // Allow descended classes a chance to do something before the think function if (PreThink(CAMERA_SEARCHING)) return; SetNextThink( gpGlobals->curtime + 0.05f ); SetIdealActivity((Activity) ACT_COMBINE_CAMERA_OPEN_IDLE); if ( !GetTarget() ) { // Try to acquire a new target if (MaintainEnemy()) { SetThink( &CNPC_CombineCamera::ActiveThink ); return; } } // Display that we're scanning m_vecGoalAngles.x = 15.0f; m_vecGoalAngles.y = GetAbsAngles().y + (sin(gpGlobals->curtime * 2.0f) * 45.0f); // Turn and ping UpdateFacing(); Ping(); SetEyeState(CAMERA_EYE_IDLE); }
void CNPC_Dog::PrescheduleThink( void ) { BaseClass::PrescheduleThink(); if ( m_hPhysicsEnt ) { IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); } } if ( m_flTimeToCatch < gpGlobals->curtime ) m_flTimeToCatch = 0.0f; if ( GetIdealActivity() == ACT_IDLE ) { if ( m_hPhysicsEnt && m_bHasObject == true ) { SetIdealActivity( (Activity)ACT_DOG_WAITING ); } } }
void CNPC_Dog::SetTurnActivity( void ) { BaseClass::SetTurnActivity(); if ( GetIdealActivity() == ACT_IDLE ) { if ( m_hPhysicsEnt && m_bHasObject == true ) SetIdealActivity( (Activity)ACT_DOG_WAITING ); } }
void CASW_Parasite::IdleInEgg(bool b) { if (b) { SetActivity((Activity) ACT_ASW_EGG_IDLE); SetIdealActivity((Activity) ACT_ASW_EGG_IDLE); SetContextThink( &CASW_Parasite::RunAnimation, gpGlobals->curtime + 0.1f, s_pParasiteAnimThink ); } m_bDoEggIdle = b; }
// Purpose: Monitor the antlion's jump to play the proper landing sequence bool CASW_Alien_Jumper::CheckLanding( void ) { trace_t tr; Vector testPos; //Amount of time to predict forward const float timeStep = 0.1f; //Roughly looks one second into the future testPos = GetAbsOrigin() + ( GetAbsVelocity() * timeStep ); testPos[2] -= ( 0.5 * sv_gravity.GetFloat() * GetGravity() * timeStep * timeStep); if ( asw_debug_aliens.GetInt() == 2 ) { NDebugOverlay::Line( GetAbsOrigin(), testPos, 255, 0, 0, 0, 0.5f ); NDebugOverlay::Cross3D( m_vecSavedJump, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, true, 0.5f ); } // Look below AI_TraceHull( GetAbsOrigin(), testPos, NAI_Hull::Mins( GetHullType() ), NAI_Hull::Maxs( GetHullType() ), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &tr ); //See if we're about to contact, or have already contacted the ground if ( ( tr.fraction != 1.0f ) || ( GetFlags() & FL_ONGROUND ) ) { int sequence = SelectWeightedSequence( (Activity)ACT_ASW_ALIEN_LAND ); if ( GetSequence() != sequence ) { VacateStrategySlot(); SetIdealActivity( (Activity) ACT_ASW_ALIEN_LAND ); CreateDust( false ); EmitSound( "ASW_Drone.Land" ); // asw todo: make the alien attack here? //if ( GetEnemy() && GetEnemy()->IsPlayer() ) //{ //CBasePlayer *pPlayer = ToBasePlayer( GetEnemy() ); //if ( pPlayer && pPlayer->IsInAVehicle() == false ) //MeleeAttack( ANTLION_MELEE1_RANGE, sk_antlion_swipe_damage.GetFloat(), QAngle( 4.0f, 0.0f, 0.0f ), Vector( -250.0f, 1.0f, 1.0f ) ); //} SetAbsVelocity( GetAbsVelocity() * 0.33f ); return false; } return IsActivityFinished(); } return false; }
//----------------------------------------------------------------------------- // Purpose: Deploy and start searching for targets. //----------------------------------------------------------------------------- void CNPC_CombineCamera::Deploy() { m_vecGoalAngles = GetAbsAngles(); SetNextThink( gpGlobals->curtime ); SetEyeState(CAMERA_EYE_IDLE); m_bActive = true; SetHeight(COMBINE_CAMERA_DEPLOY_HEIGHT); SetIdealActivity((Activity) ACT_COMBINE_CAMERA_OPEN_IDLE); m_flPlaybackRate = 0; SetThink(&CNPC_CombineCamera::SearchThink); EmitSound("NPC_CombineCamera.Move"); }
//----------------------------------------------------------------------------- // Purpose: // Input : pTask - //----------------------------------------------------------------------------- void CNPC_Headcrab::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_RANGE_ATTACK1: { SetIdealActivity( ACT_RANGE_ATTACK1 ); SetTouch( LeapTouch ); break; } default: { BaseClass::StartTask( pTask ); } } }
//----------------------------------------------------------------------------- // Purpose: Allows a generic think function before the others are called // Input : state - which state the camera is currently in //----------------------------------------------------------------------------- bool CNPC_CombineCamera::PreThink(cameraState_e state) { CheckPVSCondition(); MaintainActivity(); StudioFrameAdvance(); // If we're disabled, shut down if ( !m_bEnabled ) { SetIdealActivity((Activity) ACT_COMBINE_CAMERA_CLOSED_IDLE); SetNextThink( gpGlobals->curtime + 0.1f ); return true; } // Do not interrupt current think function return false; }
//----------------------------------------------------------------------------- // Purpose: // Input : pTarget - //----------------------------------------------------------------------------- void CNPC_CombineCamera::TrackTarget( CBaseEntity *pTarget ) { if (!pTarget) return; // Calculate direction to target Vector vecMid = EyePosition(); Vector vecMidTarget = pTarget->BodyTarget(vecMid); Vector vecDirToTarget = vecMidTarget - vecMid; // We want to look at the target's eyes so we don't jitter Vector vecDirToTargetEyes = pTarget->WorldSpaceCenter() - vecMid; VectorNormalize(vecDirToTargetEyes); QAngle vecAnglesToTarget; VectorAngles(vecDirToTargetEyes, vecAnglesToTarget); // Draw debug info if (g_debug_combine_camera.GetBool()) { NDebugOverlay::Cross3D(vecMid, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05); NDebugOverlay::Cross3D(pTarget->WorldSpaceCenter(), -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05); NDebugOverlay::Line(vecMid, pTarget->WorldSpaceCenter(), 0, 255, 0, false, 0.05); NDebugOverlay::Cross3D(vecMid, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05); NDebugOverlay::Cross3D(vecMidTarget, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05); NDebugOverlay::Line(vecMid, vecMidTarget, 0, 255, 0, false, 0.05f); } Vector vecMuzzle, vecMuzzleDir; QAngle vecMuzzleAng; GetAttachment("eyes", vecMuzzle, &vecMuzzleDir); SetIdealActivity((Activity) ACT_COMBINE_CAMERA_OPEN_IDLE); m_vecGoalAngles.y = vecAnglesToTarget.y; m_vecGoalAngles.x = vecAnglesToTarget.x; // Turn to face UpdateFacing(); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pTask - //----------------------------------------------------------------------------- void CNPC_Headcrab::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_RANGE_ATTACK1: case TASK_RANGE_ATTACK2: { if ( IsSequenceFinished() ) { TaskComplete(); SetTouch( NULL ); SetIdealActivity( ACT_IDLE ); } break; } default: { CAI_BaseNPC::RunTask( pTask ); } } }
void CASW_Parasite::StartTask(const Task_t *pTask) { switch (pTask->iTask) { /* case TASK_STOP_MOVING: { if (m_bDoEggIdle) { SetIdealActivity( (Activity) ACT_ASW_EGG_IDLE ); TaskComplete(); return; } if ( ( GetNavigator()->IsGoalSet() && GetNavigator()->IsGoalActive() ) || GetNavType() == NAV_JUMP ) { DbgNavMsg( this, "Start TASK_STOP_MOVING\n" ); if ( pTask->flTaskData == 1 ) { DbgNavMsg( this, "Initiating stopping path\n" ); GetNavigator()->StopMoving( false ); } else { GetNavigator()->ClearGoal(); } // E3 Hack if (LookupPoseParameter( "move_yaw") >= 0) { SetPoseParameter( "move_yaw", 0 ); } } else { if ( pTask->flTaskData == 1 && GetNavigator()->SetGoalFromStoppingPath() ) { DbgNavMsg( this, "Start TASK_STOP_MOVING\n" ); DbgNavMsg( this, "Initiating stopping path\n" ); } else { GetNavigator()->ClearGoal(); if (m_bDoEggIdle) SetIdealActivity( (Activity) ACT_ASW_EGG_IDLE ); else SetIdealActivity( GetStoppedActivity() ); TaskComplete(); } } } */ case TASK_PARASITE_JUMP_FROM_EGG: { DoJumpFromEgg(); break; } case TASK_RANGE_ATTACK1: { SetIdealActivity( ACT_RANGE_ATTACK1 ); break; } default: { BaseClass::StartTask( pTask ); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : pTask - //----------------------------------------------------------------------------- void CNPC_Crow::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_CROW_TAKEOFF: { if ( GetNavigator()->IsGoalActive() ) { GetMotor()->SetIdealYawToTargetAndUpdate( GetAbsOrigin() + GetNavigator()->GetCurWaypointPos(), AI_KEEP_YAW_SPEED ); } else TaskFail( FAIL_NO_ROUTE ); if ( IsActivityFinished() ) { TaskComplete(); SetIdealActivity( ACT_FLY ); m_bSoar = false; m_flSoarTime = gpGlobals->curtime + random->RandomFloat( 2, 5 ); } break; } case TASK_CROW_HOP: { if ( IsActivityFinished() ) { TaskComplete(); SetIdealActivity( ACT_IDLE ); } if ( ( GetAbsOrigin().z < m_flHopStartZ ) && ( !( GetFlags() & FL_ONGROUND ) ) ) { // // We've hopped off of something! See if we're going to fall very far. // trace_t tr; AI_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -32 ), MASK_SOLID, this, HL2COLLISION_GROUP_CROW, &tr ); if ( tr.fraction == 1.0f ) { // // We're falling! Better fly away. SelectSchedule will check ONGROUND and do the right thing. // TaskComplete(); } else { // // We'll be okay. Don't check again unless what we're hopping onto moves // out from under us. // m_flHopStartZ = GetAbsOrigin().z - ( 32 * tr.fraction ); } } break; } // // Face the direction we are flying. // case TASK_CROW_FLY: { GetMotor()->SetIdealYawToTargetAndUpdate( GetAbsOrigin() + GetAbsVelocity(), AI_KEEP_YAW_SPEED ); break; } case TASK_CROW_FALL_TO_GROUND: { if ( GetFlags() & FL_ONGROUND ) { SetFlyingState( FlyState_Walking ); TaskComplete(); } break; } case TASK_CROW_WAIT_FOR_BARNACLE_KILL: { if ( m_flNextFlinchTime < gpGlobals->curtime ) { m_flNextFlinchTime = gpGlobals->curtime + random->RandomFloat( 0.5f, 2.0f ); // dvs: TODO: squirm // dvs: TODO: spawn feathers EmitSound( "NPC_Crow.Squawk" ); } break; } default: { CAI_BaseNPC::RunTask( pTask ); } } }
//========================================================= // RunTask //========================================================= void CNPC_Stalker::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_ANNOUNCE_ATTACK: { // Stop waiting if enemy facing me or lost enemy CBaseCombatCharacter* pBCC = GetEnemyCombatCharacterPointer(); if (!pBCC || pBCC->FInViewCone( this )) { TaskComplete(); } if ( IsWaitFinished() ) { TaskComplete(); } break; } case TASK_STALKER_ZIGZAG : { if (GetNavigator()->GetGoalType() == GOALTYPE_NONE) { TaskComplete(); GetNavigator()->StopMoving(); // Stop moving } else if (!GetNavigator()->IsGoalActive()) { SetIdealActivity( GetStoppedActivity() ); } else if (ValidateNavGoal()) { SetIdealActivity( GetNavigator()->GetMovementActivity() ); AddZigZagToPath(); } break; } case TASK_RANGE_ATTACK1: UpdateAttackBeam(); if ( !TaskIsRunning() || HasCondition( COND_TASK_FAILED )) { KillAttackBeam(); } break; case TASK_FACE_ENEMY: { if ( GetEnemy() != NULL ) { BaseClass:: RunTask( pTask ); return; } GetMotor()->SetIdealYawToTargetAndUpdate( m_vLaserCurPos ); if ( FacingIdeal() ) { TaskComplete(); } break; } default: { BaseClass::RunTask( pTask ); break; } } }
//----------------------------------------------------------------------------- // Purpose: Handles all flight movement. // Input : flInterval - Seconds to simulate. //----------------------------------------------------------------------------- void CNPC_Crow::MoveCrowFly( float flInterval ) { // // Bound interval so we don't get ludicrous motion when debugging // or when framerate drops catastrophically. // if (flInterval > 1.0) { flInterval = 1.0; } m_flDangerSoundTime = gpGlobals->curtime + 5.0f; // // Determine the goal of our movement. // Vector vecMoveGoal = GetAbsOrigin(); if ( GetNavigator()->IsGoalActive() ) { vecMoveGoal = GetNavigator()->GetCurWaypointPos(); if ( GetNavigator()->CurWaypointIsGoal() == false ) { AI_ProgressFlyPathParams_t params( MASK_NPCSOLID ); params.bTrySimplify = false; GetNavigator()->ProgressFlyPath( params ); // ignore result, crow handles completion directly // Fly towards the hint. if ( GetNavigator()->GetPath()->GetCurWaypoint() ) { vecMoveGoal = GetNavigator()->GetCurWaypointPos(); } } } else { // No movement goal. vecMoveGoal = GetAbsOrigin(); SetAbsVelocity( vec3_origin ); return; } Vector vecMoveDir = ( vecMoveGoal - GetAbsOrigin() ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); // // Fly towards the movement goal. // float flDistance = ( vecMoveGoal - GetAbsOrigin() ).Length(); if ( vecMoveGoal != m_vDesiredTarget ) { m_vDesiredTarget = vecMoveGoal; } else { m_vCurrentTarget = ( m_vDesiredTarget - GetAbsOrigin() ); VectorNormalize( m_vCurrentTarget ); } float flLerpMod = 0.25f; if ( flDistance <= 256.0f ) { flLerpMod = 1.0f - ( flDistance / 256.0f ); } VectorLerp( vForward, m_vCurrentTarget, flLerpMod, vForward ); if ( flDistance < CROW_AIRSPEED * flInterval ) { if ( GetNavigator()->IsGoalActive() ) { if ( GetNavigator()->CurWaypointIsGoal() ) { m_bReachedMoveGoal = true; } else { GetNavigator()->AdvancePath(); } } else m_bReachedMoveGoal = true; } if ( GetHintNode() ) { AIMoveTrace_t moveTrace; GetMoveProbe()->MoveLimit( NAV_FLY, GetAbsOrigin(), GetNavigator()->GetCurWaypointPos(), MASK_NPCSOLID, GetNavTargetEntity(), &moveTrace ); //See if it succeeded if ( IsMoveBlocked( moveTrace.fStatus ) ) { Vector vNodePos = vecMoveGoal; GetHintNode()->GetPosition(this, &vNodePos); GetNavigator()->SetGoal( vNodePos ); } } // // Look to see if we are going to hit anything. // VectorNormalize( vForward ); Vector vecDeflect; if ( Probe( vForward, CROW_AIRSPEED * flInterval, vecDeflect ) ) { vForward = vecDeflect; VectorNormalize( vForward ); } SetAbsVelocity( vForward * CROW_AIRSPEED ); if ( GetAbsVelocity().Length() > 0 && GetNavigator()->CurWaypointIsGoal() && flDistance < CROW_AIRSPEED ) { SetIdealActivity( (Activity)ACT_CROW_LAND ); } //Bank and set angles. Vector vRight; QAngle vRollAngle; VectorAngles( vForward, vRollAngle ); vRollAngle.z = 0; AngleVectors( vRollAngle, NULL, &vRight, NULL ); float flRoll = DotProduct( vRight, vecMoveDir ) * 45; flRoll = clamp( flRoll, -45, 45 ); vRollAngle[ROLL] = flRoll; SetAbsAngles( vRollAngle ); }
//----------------------------------------------------------------------------- // Purpose: // Input : pTask - //----------------------------------------------------------------------------- void CNPC_Crow::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { // // This task enables us to build a path that requires flight. // // case TASK_CROW_PREPARE_TO_FLY: // { // SetFlyingState( FlyState_Flying ); // TaskComplete(); // break; // } case TASK_CROW_TAKEOFF: { if ( random->RandomInt( 1, 4 ) == 1 ) { AlertSound(); } FlapSound(); SetIdealActivity( ( Activity )ACT_CROW_TAKEOFF ); break; } case TASK_CROW_PICK_EVADE_GOAL: { if ( GetEnemy() != NULL ) { // // Get our enemy's position in x/y. // Vector vecEnemyOrigin = GetEnemy()->GetAbsOrigin(); vecEnemyOrigin.z = GetAbsOrigin().z; // // Pick a hop goal a random distance along a vector away from our enemy. // m_vSavePosition = GetAbsOrigin() - vecEnemyOrigin; VectorNormalize( m_vSavePosition ); m_vSavePosition = GetAbsOrigin() + m_vSavePosition * ( 32 + random->RandomInt( 0, 32 ) ); GetMotor()->SetIdealYawToTarget( m_vSavePosition ); TaskComplete(); } else { TaskFail( "No enemy" ); } break; } case TASK_CROW_FALL_TO_GROUND: { SetFlyingState( FlyState_Falling ); break; } case TASK_FIND_HINTNODE: { if ( GetGoalEnt() ) { TaskComplete(); return; } // Overloaded because we search over a greater distance. if ( !GetHintNode() ) { SetHintNode(CAI_HintManager::FindHint( this, HINT_CROW_FLYTO_POINT, bits_HINT_NODE_NEAREST | bits_HINT_NODE_USE_GROUP, 10000 )); } if ( GetHintNode() ) { TaskComplete(); } else { TaskFail( FAIL_NO_HINT_NODE ); } break; } case TASK_GET_PATH_TO_HINTNODE: { //How did this happen?! if ( GetGoalEnt() == this ) { SetGoalEnt( NULL ); } if ( GetGoalEnt() ) { SetFlyingState( FlyState_Flying ); StartTargetHandling( GetGoalEnt() ); m_bReachedMoveGoal = false; TaskComplete(); SetHintNode( NULL ); return; } if ( GetHintNode() ) { Vector vHintPos; GetHintNode()->GetPosition(this, &vHintPos); SetNavType( NAV_FLY ); CapabilitiesAdd( bits_CAP_MOVE_FLY ); if ( !GetNavigator()->SetGoal( vHintPos ) ) SetHintNode(NULL); CapabilitiesRemove( bits_CAP_MOVE_FLY ); } if ( GetHintNode() ) { m_bReachedMoveGoal = false; TaskComplete(); } else { TaskFail( FAIL_NO_ROUTE ); } break; } // // We have failed to fly normally. Pick a random "up" direction and fly that way. // case TASK_CROW_FLY: { float flYaw = UTIL_AngleMod( random->RandomInt( -180, 180 ) ); Vector vecNewVelocity( cos( DEG2RAD( flYaw ) ), sin( DEG2RAD( flYaw ) ), random->RandomFloat( 0.1f, 0.5f ) ); vecNewVelocity *= CROW_AIRSPEED; SetAbsVelocity( vecNewVelocity ); SetIdealActivity( ACT_FLY ); m_bSoar = false; m_flSoarTime = gpGlobals->curtime + random->RandomFloat( 2, 5 ); break; } case TASK_CROW_PICK_RANDOM_GOAL: { m_vSavePosition = GetLocalOrigin() + Vector( random->RandomFloat( -48.0f, 48.0f ), random->RandomFloat( -48.0f, 48.0f ), 0 ); TaskComplete(); break; } case TASK_CROW_HOP: { SetIdealActivity( ACT_HOP ); m_flHopStartZ = GetLocalOrigin().z; break; } case TASK_CROW_WAIT_FOR_BARNACLE_KILL: { break; } default: { BaseClass::StartTask( pTask ); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CFastZombie::StartTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_FASTZOMBIE_VERIFY_ATTACK: // Simply ensure that the zombie still has a valid melee attack if( HasCondition( COND_CAN_MELEE_ATTACK1 ) ) { TaskComplete(); } else { TaskFail(""); } break; case TASK_FASTZOMBIE_JUMP_BACK: { SetActivity( ACT_IDLE ); RemoveFlag( FL_ONGROUND ); BeginAttackJump(); Vector forward; AngleVectors( GetLocalAngles(), &forward ); // // Take him off ground so engine doesn't instantly reset FL_ONGROUND. // UTIL_SetOrigin( this, GetLocalOrigin() + Vector( 0 , 0 , 1 )); ApplyAbsVelocityImpulse( forward * -200 + Vector( 0, 0, 200 ) ); } break; case TASK_FASTZOMBIE_UNSTICK_JUMP: { RemoveFlag( FL_ONGROUND ); // Call begin attack jump. A little bit later if we fail to pathfind, we check // this value to see if we just jumped. If so, we assume we've jumped // to someplace that's not pathing friendly, and so must jump again to get out. BeginAttackJump(); // // Take him off ground so engine doesn't instantly reset FL_ONGROUND. // UTIL_SetOrigin( this, GetLocalOrigin() + Vector( 0 , 0 , 1 )); CBaseEntity *pEnemy = GetEnemy(); Vector vecJumpDir; if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN ) { // Jump off the pipe backwards! Vector forward; GetVectors( &forward, NULL, NULL ); ApplyAbsVelocityImpulse( forward * -200 ); } else if( pEnemy ) { vecJumpDir = pEnemy->GetLocalOrigin() - GetLocalOrigin(); VectorNormalize( vecJumpDir ); vecJumpDir.z = 0; ApplyAbsVelocityImpulse( vecJumpDir * 300 + Vector( 0, 0, 200 ) ); } else { Msg("UNHANDLED CASE! Stuck Fast Zombie with no enemy!\n"); } } break; case TASK_WAIT_FOR_MOVEMENT: // If we're waiting for movement, that means that pathfinding succeeded, and // we're about to be moving. So we aren't stuck. So clear this flag. m_fJustJumped = false; BaseClass::StartTask( pTask ); break; case TASK_FACE_ENEMY: { // We don't use the base class implementation of this, because GetTurnActivity // stomps our landing scrabble animations (sjb) Vector flEnemyLKP = GetEnemyLKP(); GetMotor()->SetIdealYawToTarget( flEnemyLKP ); } break; case TASK_FASTZOMBIE_LAND_RECOVER: { // Set the ideal yaw Vector flEnemyLKP = GetEnemyLKP(); GetMotor()->SetIdealYawToTarget( flEnemyLKP ); // figure out which way to turn. float flDeltaYaw = GetMotor()->DeltaIdealYaw(); if( flDeltaYaw < 0 ) { SetIdealActivity( (Activity)ACT_FASTZOMBIE_LAND_RIGHT ); } else { SetIdealActivity( (Activity)ACT_FASTZOMBIE_LAND_LEFT ); } TaskComplete(); } break; case TASK_RANGE_ATTACK1: // Make melee attacks impossible until we land! m_flNextMeleeAttack = gpGlobals->curtime + 60; SetTouch( LeapAttackTouch ); break; case TASK_FASTZOMBIE_DO_ATTACK: SetActivity( (Activity)ACT_FASTZOMBIE_LEAP_SOAR ); break; default: BaseClass::StartTask( pTask ); break; } }
//========================================================= // start task //========================================================= void CNPC_Houndeye::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_HOUND_GET_PATH_TO_CIRCLE: { if (GetEnemy() == NULL) { TaskFail(FAIL_NO_ENEMY); } else { Vector vTargetPos = GetEnemyLKP(); vTargetPos.z = GetFloorZ(vTargetPos); if (GetNavigator()->SetRadialGoal(vTargetPos, random->RandomInt(50,500), 90, 175, m_bLoopClockwise)) { TaskComplete(); return; } TaskFail(FAIL_NO_ROUTE); } break; } case TASK_HOUND_REVERSE_STRAFE_DIR: { // Try the other direction m_bLoopClockwise = (m_bLoopClockwise) ? false : true; TaskComplete(); break; } // Override to set appropriate distances case TASK_GET_PATH_TO_ENEMY_LOS: { float flMaxRange = HOUNDEYE_MAX_ATTACK_RADIUS * 0.9; float flMinRange = HOUNDEYE_MIN_ATTACK_RADIUS; Vector posLos; bool foundLos = false; if (GetEnemy() != NULL) { foundLos = GetTacticalServices()->FindLos(GetEnemyLKP(),GetEnemy()->EyePosition(), flMinRange, flMaxRange, 0.0, &posLos); } else { TaskFail(FAIL_NO_TARGET); return; } if (foundLos) { GetNavigator()->SetGoal( AI_NavGoal_t( posLos, ACT_RUN, AIN_HULL_TOLERANCE ) ); } else { TaskFail(FAIL_NO_SHOOT); } break; } case TASK_HOUND_FALL_ASLEEP: { m_fAsleep = true; // signal that hound is lying down (must stand again before doing anything else!) TaskComplete( true ); break; } case TASK_HOUND_WAKE_UP: { m_fAsleep = false; // signal that hound is standing again TaskComplete( true ); break; } case TASK_HOUND_OPEN_EYE: { m_fDontBlink = false; // turn blinking back on and that code will automatically open the eye TaskComplete( true ); break; } case TASK_HOUND_CLOSE_EYE: { //<<TEMP>> pev->skin = 0; m_fDontBlink = true; // tell blink code to leave the eye alone. break; } case TASK_HOUND_THREAT_DISPLAY: { SetIdealActivity( ACT_IDLE_ANGRY ); break; } case TASK_HOUND_HOP_BACK: { SetIdealActivity( ACT_LEAP ); break; } case TASK_RANGE_ATTACK1: { SetIdealActivity( ACT_RANGE_ATTACK1 ); break; } default: { BaseClass::StartTask(pTask); break; } } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pTask - //----------------------------------------------------------------------------- void CNPC_VehicleDriver::StartTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_RUN_PATH: case TASK_WALK_PATH: TaskComplete(); break; case TASK_FACE_IDEAL: case TASK_FACE_ENEMY: { // Vehicle ignores face commands, since it can't rotate on the spot. TaskComplete(); } break; case TASK_VEHICLEDRIVER_GET_PATH: { if ( !GetGoalEnt() ) { TaskFail( FAIL_NO_TARGET ); return; } CheckForTeleport(); if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH ) { NDebugOverlay::Box( GetGoalEnt()->GetAbsOrigin(), -Vector(50,50,50), Vector(50,50,50), 255,255,255, true, 5); } AI_NavGoal_t goal( GOALTYPE_PATHCORNER, GetGoalEnt()->GetLocalOrigin(), ACT_WALK, AIN_DEF_TOLERANCE, AIN_YAW_TO_DEST); if ( !GetNavigator()->SetGoal( goal ) ) { TaskFail( FAIL_NO_ROUTE ); return; } TaskComplete(); } break; case TASK_WAIT_FOR_MOVEMENT: { if (GetNavigator()->GetGoalType() == GOALTYPE_NONE) { TaskComplete(); GetNavigator()->StopMoving(); // Stop moving } else if (!GetNavigator()->IsGoalActive()) { SetIdealActivity( GetStoppedActivity() ); } else { // Check validity of goal type ValidateNavGoal(); } } break; default: BaseClass::StartTask( pTask ); break; } }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::Spawn( void ) { Precache( ); SetModel( "models/combine_dropship.mdl" ); BaseClass::Spawn(); ExtractBbox( SelectHeaviestSequence( ACT_DROPSHIP_DEPLOY_IDLE ), m_cullBoxMins, m_cullBoxMaxs ); BaseClass::Spawn(); InitPathingData( DROPSHIP_LEAD_DISTANCE, DROPSHIP_MIN_CHASE_DIST_DIFF, DROPSHIP_AVOID_DIST ); // create the correct bin for the ship to carry switch ( m_iCrateType ) { case CRATE_ROLLER_HOPPER: break; case CRATE_SOLDIER: m_hContainer = CreateEntityByName( "prop_dynamic" ); if ( m_hContainer ) { m_hContainer->SetModel( "models/props_junk/trashdumpster02.mdl" ); m_hContainer->SetLocalOrigin( GetAbsOrigin() ); m_hContainer->SetLocalAngles( GetLocalAngles() ); m_hContainer->SetAbsAngles( GetAbsAngles() ); m_hContainer->SetParent(this, 0); m_hContainer->SetOwnerEntity(this); m_hContainer->SetSolid( SOLID_VPHYSICS ); m_hContainer->Spawn(); } break; case CRATE_NONE: default: break; } m_iHealth = 100; m_flFieldOfView = 0.5; // 60 degrees m_iContainerMoveType = MOVETYPE_NONE; //InitBoneControllers(); InitCustomSchedules(); if ( m_hContainer ) { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_CARGO ); } else { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_EXAGG ); } m_flMaxSpeed = DROPSHIP_MAX_SPEED; m_flMaxSpeedFiring = BASECHOPPER_MAX_FIRING_SPEED; m_hPickupTarget = NULL; //!!!HACKHACK // This tricks the AI code that constantly complains that the vehicle has no schedule. SetSchedule( SCHED_IDLE_STAND ); m_iLandState = LANDING_NO; }
//--------------------------------------------------------- //--------------------------------------------------------- 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_BigMomma::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_CHECK_NODE_PROXIMITY: { } break; case TASK_FIND_NODE: { CBaseEntity *pTarget = GetTarget(); if ( !HasMemory( bits_MEMORY_ADVANCE_NODE ) ) { if ( pTarget ) m_iszTarget = pTarget->m_target; } NodeStart( m_iszTarget ); TaskComplete(); //Msg( "BM: Found node %s\n", STRING( m_iszTarget ) ); } break; case TASK_NODE_DELAY: m_nodeTime = gpGlobals->curtime + pTask->flTaskData; TaskComplete(); //Msg( "BM: FAIL! Delay %.2f\n", pTask->flTaskData ); break; case TASK_PROCESS_NODE: //Msg( "BM: Reached node %s\n", STRING( m_iszTarget ) ); NodeReach(); TaskComplete(); break; case TASK_PLAY_NODE_PRESEQUENCE: case TASK_PLAY_NODE_SEQUENCE: { const char *pSequence = NULL; int iSequence; if ( pTask->iTask == TASK_PLAY_NODE_SEQUENCE ) pSequence = GetNodeSequence(); else pSequence = GetNodePresequence(); //Msg( "BM: Playing node sequence %s\n", pSequence ); if ( pSequence ) //ugh { iSequence = LookupSequence( pSequence ); if ( iSequence != -1 ) { SetIdealActivity( ACT_DO_NOT_DISTURB ); SetSequence( iSequence ); SetCycle( 0.0f ); ResetSequenceInfo(); //Msg( "BM: Sequence %s %f\n", GetNodeSequence(), gpGlobals->curtime ); return; } } TaskComplete(); } break; case TASK_NODE_YAW: GetMotor()->SetIdealYaw( GetNodeYaw() ); TaskComplete(); break; case TASK_WAIT_NODE: m_flWait = gpGlobals->curtime + GetNodeDelay(); /*if ( GetTarget() && GetTarget()->GetSpawnFlags() & SF_INFOBM_WAIT ) Msg( "BM: Wait at node %s forever\n", STRING( m_iszTarget) ); else Msg( "BM: Wait at node %s for %.2f\n", STRING( m_iszTarget ), GetNodeDelay() );*/ break; case TASK_MOVE_TO_NODE_RANGE: { CBaseEntity *pTarget = GetTarget(); if ( !pTarget ) TaskFail( FAIL_NO_TARGET ); else { if ( ( pTarget->GetAbsOrigin() - GetAbsOrigin() ).Length() < GetNodeRange() ) TaskComplete(); else { Activity act = ACT_WALK; if ( pTarget->GetSpawnFlags() & SF_INFOBM_RUN ) act = ACT_RUN; AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, act ); if ( !GetNavigator()->SetGoal( goal ) ) { TaskFail( NO_TASK_FAILURE ); } } } } //Msg( "BM: Moving to node %s\n", STRING( m_iszTarget ) ); break; case TASK_MELEE_ATTACK1: { // Play an attack sound here CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "BigMomma.Attack" ); BaseClass::StartTask( pTask ); } break; default: BaseClass::StartTask( pTask ); break; } }
//========================================================= // Stop - //========================================================= void CNPC_Controller::Stop( void ) { SetIdealActivity( GetStoppedActivity() ); }
//----------------------------------------------------------------------------- // Purpose: Handles all flight movement because we don't ever build paths when // when we are flying. // Input : flInterval - Seconds to simulate. //----------------------------------------------------------------------------- bool CNPC_Crow::OverrideMove( float flInterval ) { if ( GetNavigator()->GetPath()->CurWaypointNavType() == NAV_FLY && GetNavigator()->GetNavType() != NAV_FLY ) { SetNavType( NAV_FLY ); } if ( IsFlying() ) { if ( GetNavigator()->GetPath()->GetCurWaypoint() ) { if ( m_flLastStuckCheck <= gpGlobals->curtime ) { if ( m_vLastStoredOrigin == GetAbsOrigin() ) { if ( GetAbsVelocity() == vec3_origin ) { float flDamage = m_iHealth; CTakeDamageInfo dmgInfo( this, this, flDamage, DMG_GENERIC ); GuessDamageForce( &dmgInfo, vec3_origin - Vector( 0, 0, 0.1 ), GetAbsOrigin() ); TakeDamage( dmgInfo ); return false; } else { m_vLastStoredOrigin = GetAbsOrigin(); } } else { m_vLastStoredOrigin = GetAbsOrigin(); } m_flLastStuckCheck = gpGlobals->curtime + 1.0f; } if (m_bReachedMoveGoal ) { SetIdealActivity( (Activity)ACT_CROW_LAND ); SetFlyingState( FlyState_Landing ); TaskMovementComplete(); } else { SetIdealActivity ( ACT_FLY ); MoveCrowFly( flInterval ); } } else { SetSchedule( SCHED_CROW_IDLE_FLY ); SetFlyingState( FlyState_Flying ); SetIdealActivity ( ACT_FLY ); } return true; } return false; }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::PrescheduleThink( void ) { BaseClass::PrescheduleThink(); // keep track of think time deltas for burn calc below float dt = gpGlobals->curtime - m_flLastTime; m_flLastTime = gpGlobals->curtime; switch( m_iLandState ) { case LANDING_NO: { if ( IsActivityFinished() && (GetActivity() != ACT_DROPSHIP_FLY_IDLE_EXAGG && GetActivity() != ACT_DROPSHIP_FLY_IDLE_CARGO) ) { if ( m_hContainer ) { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_CARGO ); } else { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_EXAGG ); } } DoRotorWash(); } break; case LANDING_LEVEL_OUT: { // Approach the drop point Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); // If we're slowing, make it look like we're slowing /* if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } */ // Are we there yet? float flSpeed = GetAbsVelocity().Length(); if ( flDistance < 70 && flSpeed < 100 ) { m_flLandingSpeed = flSpeed; m_iLandState = LANDING_DESCEND; // save off current angles so we can work them out over time QAngle angles = GetLocalAngles(); m_existPitch = angles.x; m_existRoll = angles.z; } DoRotorWash(); } break; case LANDING_DESCEND: { float flAltitude; SetLocalAngularVelocity( vec3_angle ); // Ensure we land on the drop point Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); float flRampedSpeed = m_flLandingSpeed * (flDistance / 70); Vector vecVelocity = (flRampedSpeed / flDistance) * vecToTarget; vecVelocity.z = -75; SetAbsVelocity( vecVelocity ); flAltitude = GetAltitude(); if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } if ( flAltitude < 72 ) { QAngle angles = GetLocalAngles(); // Level out quickly. angles.x = UTIL_Approach( 0.0, angles.x, 0.2 ); angles.z = UTIL_Approach( 0.0, angles.z, 0.2 ); SetLocalAngles( angles ); } else { // randomly move as if buffeted by ground effects // gently flatten ship from starting pitch/yaw m_existPitch = UTIL_Approach( 0.0, m_existPitch, 1 ); m_existRoll = UTIL_Approach( 0.0, m_existRoll, 1 ); QAngle angles = GetLocalAngles(); angles.x = m_existPitch + ( sin( gpGlobals->curtime * 3.5f ) * DROPSHIP_MAX_LAND_TILT ); angles.z = m_existRoll + ( sin( gpGlobals->curtime * 3.75f ) * DROPSHIP_MAX_LAND_TILT ); SetLocalAngles( angles ); // figure out where to face (nav point) Vector targetDir = GetDesiredPosition() - GetAbsOrigin(); // NDebugOverlay::Cross3D( m_pGoalEnt->GetAbsOrigin(), -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 20 ); QAngle targetAngles = GetAbsAngles(); targetAngles.y += UTIL_AngleDiff(UTIL_VecToYaw( targetDir ), targetAngles.y); // orient ship towards path corner on the way down angles = GetAbsAngles(); angles.y = UTIL_Approach(targetAngles.y, angles.y, 2 ); SetAbsAngles( angles ); } if ( flAltitude <= 0.5f ) { m_iLandState = LANDING_TOUCHDOWN; // upon landing, make sure ship is flat QAngle angles = GetLocalAngles(); angles.x = 0; angles.z = 0; SetLocalAngles( angles ); // TODO: Release cargo anim SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } DoRotorWash(); // place danger sounds 1 foot above ground to get troops to scatter if they are below dropship Vector vecBottom = GetAbsOrigin(); vecBottom.z += WorldAlignMins().z; Vector vecSpot = vecBottom + Vector(0, 0, -1) * (GetAltitude() - 12 ); CSoundEnt::InsertSound( SOUND_DANGER, vecSpot, 400, 0.2, this, 0 ); CSoundEnt::InsertSound( SOUND_PHYSICS_DANGER, vecSpot, 400, 0.2, this, 1 ); // NDebugOverlay::Cross3D( vecSpot, -Vector(4,4,4), Vector(4,4,4), 255, 0, 255, false, 10.0f ); // now check to see if player is below us, if so, cause heat damage to them (i.e. get them to move) trace_t tr; Vector vecBBoxMin = CRATE_BBOX_MIN; // use flat box for check vecBBoxMin.z = -5; Vector vecBBoxMax = CRATE_BBOX_MAX; vecBBoxMax.z = 5; Vector pEndPoint = vecBottom + Vector(0, 0, -1) * ( GetAltitude() - 12 ); AI_TraceHull( vecBottom, pEndPoint, vecBBoxMin, vecBBoxMax, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0f ) { if ( tr.GetEntityIndex() == 1 ) // player??? { CTakeDamageInfo info( this, this, 20 * dt, DMG_BURN ); CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); pPlayer->TakeDamage( info ); } } } break; case LANDING_TOUCHDOWN: { if ( IsActivityFinished() && ( GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } m_iLandState = LANDING_UNLOADING; m_flTroopDeployPause = gpGlobals->curtime + DROPSHIP_PAUSE_B4_TROOP_UNLOAD; m_flTimeTakeOff = m_flTroopDeployPause + DROPSHIP_DEPLOY_TIME; } break; case LANDING_UNLOADING: { // pause before dropping troops if ( gpGlobals->curtime > m_flTroopDeployPause ) { if ( m_hContainer ) // don't drop troops if we don't have a crate any more { SpawnTroops(); m_flTroopDeployPause = m_flTimeTakeOff + 2; // only drop once } } // manage engine wash and volume if ( m_flTimeTakeOff - gpGlobals->curtime < 0.5f ) { m_engineThrust = UTIL_Approach( 1.0f, m_engineThrust, 0.1f ); DoRotorWash(); } else { float idleVolume = 0.2f; m_engineThrust = UTIL_Approach( idleVolume, m_engineThrust, 0.04f ); if ( m_engineThrust > idleVolume ) { DoRotorWash(); // make sure we're kicking up dust/water as long as engine thrust is up } } if( gpGlobals->curtime > m_flTimeTakeOff ) { m_iLandState = LANDING_LIFTOFF; SetActivity( (Activity)ACT_DROPSHIP_LIFTOFF ); m_engineThrust = 1.0f; // ensure max volume once we're airborne if ( m_bIsFiring ) { StopCannon(); // kill cannon sounds if they are on } // detach container from ship if ( m_hContainer && m_leaveCrate ) { m_hContainer->SetParent(NULL); m_hContainer->SetMoveType( (MoveType_t)m_iContainerMoveType ); // If the container has a physics object, remove it's shadow IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->RemoveShadowController(); } m_hContainer = NULL; } } } break; case LANDING_LIFTOFF: { // give us some clearance before changing back to larger hull -- keeps ship from getting stuck on // things like the player, etc since we "pop" the hull... if ( GetAltitude() > 120 ) { m_OnFinishedDropoff.FireOutput( this, this ); m_iLandState = LANDING_NO; // change bounding box back to normal ship hull Vector vecBBMin, vecBBMax; ExtractBbox( SelectHeaviestSequence( ACT_DROPSHIP_DEPLOY_IDLE ), vecBBMin, vecBBMax ); UTIL_SetSize( this, vecBBMin, vecBBMax ); Relink(); } } break; case LANDING_SWOOPING: { // Did we lose our pickup target? if ( !m_hPickupTarget ) { m_iLandState = LANDING_NO; } else { // Decrease altitude and speed to hit the target point. Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); // Start cheating when we get near it if ( flDistance < 50 ) { /* if ( flDistance > 10 ) { // Cheat and ensure we touch the target float flSpeed = GetAbsVelocity().Length(); Vector vecVelocity = vecToTarget; VectorNormalize( vecVelocity ); SetAbsVelocity( vecVelocity * min(flSpeed,flDistance) ); } else */ { // Grab the target m_hContainer = m_hPickupTarget; m_hPickupTarget = NULL; m_iContainerMoveType = m_hContainer->GetMoveType(); // If the container has a physics object, move it to shadow IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), false, false ); pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 ); } int iIndex = 0;//LookupAttachment("Cargo"); /* Vector vecOrigin; QAngle vecAngles; GetAttachment( iIndex, vecOrigin, vecAngles ); m_hContainer->SetAbsOrigin( vecOrigin ); m_hContainer->SetAbsAngles( vec3_angle ); */ m_hContainer->SetAbsOrigin( GetAbsOrigin() ); m_hContainer->SetParent(this, iIndex); m_hContainer->SetMoveType( MOVETYPE_PUSH ); m_hContainer->RemoveFlag( FL_ONGROUND ); m_hContainer->Relink(); m_hContainer->SetAbsAngles( vec3_angle ); m_OnFinishedPickup.FireOutput( this, this ); m_iLandState = LANDING_NO; } } } DoRotorWash(); } break; } DoCombatStuff(); if ( GetActivity() != GetIdealActivity() ) { //Msg( "setactivity" ); SetActivity( GetIdealActivity() ); } }