Exemplo n.º 1
0
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;	
	}
}
Exemplo n.º 2
0
/*
=============
ai_run_missile

Turn in place until within an angle to launch a missile attack
=============
*/
void ai_run_missile(edict_t *self)
{
	self->ideal_yaw = enemy_yaw;
	M_ChangeYaw (self);

	if (FacingIdeal(self))
	{
		self->monsterinfo.attack (self);
		self->monsterinfo.attack_state = AS_STRAIGHT;
	}
}
Exemplo n.º 3
0
/*
=============
ai_run_missile

Turn in place until within an angle to launch a missile attack
=============
*/
void ai_run_missile()
{
	self->s.v.ideal_yaw = enemy_yaw;
	changeyaw( self );

	if ( FacingIdeal() )
	{
		if ( self->th_missile )
			self->th_missile();

		self->attack_state = AS_STRAIGHT;
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pTask - 
//-----------------------------------------------------------------------------
void CNPC_Bug_Builder::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_BBUG_FACE_DAWDLE:
		{
			GetMotor()->UpdateYaw();
			if ( FacingIdeal() )
			{
				TaskComplete();
			}
			break;
		}

	default:
		BaseClass::RunTask( pTask );
		break;
	}
}
Exemplo n.º 5
0
void hhHarvesterSimple::Event_ExitPassageway(hhAIPassageway *pn) {
	if(currPassageway == NULL) {
		gameLocal.Error("%s tried to EXIT a passageway but did NOT have a curr passageway!", (const char*)name);
	}

	HH_ASSERT(currPassageway != NULL);	

	// Store this passageway so we don't jump right back into it.
	lastPassageway = idEntityPtr<idEntity> (pn);
	lastPassagewayTime = gameLocal.time;

	if(GetPhysics())
		GetPhysics()->SetContents(CONTENTS_BODY);	
	currPassageway = NULL;	
	AI_ACTIVATED = true; // Sometimes this is NOT true?!?! 
	StopSound(SND_CHANNEL_VOICE, true);	

	// Teleport to new pos
	idAngles angs = pn->GetAxis().ToAngles();
	idVec3 pos = pn->GetExitPos();	
	Teleport( pos, angs, pn );
	Show();
	
	current_yaw = angs.yaw;
	ideal_yaw	= angs.yaw;
	turnVel		= 0.0f;	
	HH_ASSERT(FacingIdeal());

	// Exit anim to play?	
	idStr exitAnim = pn->spawnArgs.GetString("exit_anim");
	if(exitAnim.Length() && GetAnimator()->HasAnim(exitAnim)) {
		GetAnimator()->ClearAllAnims(gameLocal.GetTime(), 0);
		torsoAnim.UpdateState();
		legsAnim.UpdateState();
		torsoAnim.PlayAnim( GetAnimator()->GetAnim( exitAnim ) );
		legsAnim.PlayAnim( GetAnimator()->GetAnim( exitAnim ) );
	}
}
Exemplo n.º 6
0
//=========================================================
// RunTask 
//=========================================================
void CBaseMonster :: RunTask ( Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_TURN_RIGHT:
	case TASK_TURN_LEFT:
		{
			ChangeYaw( pev->yaw_speed );

			if ( FacingIdeal() )
			{
				TaskComplete();
			}
			break;
		}

	case TASK_PLAY_SEQUENCE_FACE_ENEMY:
	case TASK_PLAY_SEQUENCE_FACE_TARGET:
		{
			CBaseEntity *pTarget;

			if ( pTask->iTask == TASK_PLAY_SEQUENCE_FACE_TARGET )
				pTarget = m_hTargetEnt;
			else
				pTarget = m_hEnemy;
			if ( pTarget )
			{
				pev->ideal_yaw = UTIL_VecToYaw( pTarget->pev->origin - pev->origin );
				ChangeYaw( pev->yaw_speed );
			}
			if ( m_fSequenceFinished )
				TaskComplete();
		}
		break;

	case TASK_PLAY_SEQUENCE:
	case TASK_PLAY_ACTIVE_IDLE:
		{
			if ( m_fSequenceFinished )
			{
				TaskComplete();
			}
			break;
		}


	case TASK_FACE_ENEMY:
		{
			MakeIdealYaw( m_vecEnemyLKP );

			ChangeYaw( pev->yaw_speed );

			if ( FacingIdeal() )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_FACE_HINTNODE:
	case TASK_FACE_LASTPOSITION:
	case TASK_FACE_TARGET:
	case TASK_FACE_IDEAL:
	case TASK_FACE_ROUTE:
		{
			ChangeYaw( pev->yaw_speed );

			if ( FacingIdeal() )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_WAIT_PVS:
		{
			if ( !FNullEnt(FIND_CLIENT_IN_PVS(edict())) )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_WAIT_INDEFINITE:
		{
			// don't do anything.
			break;
		}
	case TASK_WAIT:
	case TASK_WAIT_RANDOM:
		{
			if ( gpGlobals->time >= m_flWaitFinished )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_WAIT_FACE_ENEMY:
		{
			MakeIdealYaw ( m_vecEnemyLKP );
			ChangeYaw( pev->yaw_speed ); 

			if ( gpGlobals->time >= m_flWaitFinished )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_MOVE_TO_TARGET_RANGE:
		{
			float distance;

			if ( m_hTargetEnt == NULL )
				TaskFail();
			else
			{
				distance = ( m_vecMoveGoal - pev->origin ).Length2D();
				// Re-evaluate when you think your finished, or the target has moved too far
				if ( (distance < pTask->flData) || (m_vecMoveGoal - m_hTargetEnt->pev->origin).Length() > pTask->flData * 0.5 )
				{
					m_vecMoveGoal = m_hTargetEnt->pev->origin;
					distance = ( m_vecMoveGoal - pev->origin ).Length2D();
					FRefreshRoute();
				}

				// Set the appropriate activity based on an overlapping range
				// overlap the range to prevent oscillation
				if ( distance < pTask->flData )
				{
					TaskComplete();
					RouteClear();		// Stop moving
				}
				else if ( distance < 190 && m_movementActivity != ACT_WALK )
					m_movementActivity = ACT_WALK;
				else if ( distance >= 270 && m_movementActivity != ACT_RUN )
					m_movementActivity = ACT_RUN;
			}

			break;
		}
	case TASK_WAIT_FOR_MOVEMENT:
		{
			if (MovementIsComplete())
			{
				TaskComplete();
				RouteClear();		// Stop moving
			}
			break;
		}
	case TASK_DIE:
		{
			if ( m_fSequenceFinished && pev->frame >= 255 )
			{
				pev->deadflag = DEAD_DEAD;
				
				SetThink ( NULL );
				StopAnimation();

				if ( !BBoxFlat() )
				{
					// a bit of a hack. If a corpses' bbox is positioned such that being left solid so that it can be attacked will
					// block the player on a slope or stairs, the corpse is made nonsolid. 
//					pev->solid = SOLID_NOT;
					UTIL_SetSize ( pev, Vector ( -4, -4, 0 ), Vector ( 4, 4, 1 ) );
				}
				else // !!!HACKHACK - put monster in a thin, wide bounding box until we fix the solid type/bounding volume problem
					UTIL_SetSize ( pev, Vector ( pev->mins.x, pev->mins.y, pev->mins.z ), Vector ( pev->maxs.x, pev->maxs.y, pev->mins.z + 1 ) );

				if ( ShouldFadeOnDeath() )
				{
					// this monster was created by a monstermaker... fade the corpse out.
					SUB_StartFadeOut();
				}
				else
				{
					// body is gonna be around for a while, so have it stink for a bit.
					CSoundEnt::InsertSound ( bits_SOUND_CARCASS, pev->origin, 384, 30 );
				}
			}
			break;
		}
	case TASK_RANGE_ATTACK1_NOTURN:
	case TASK_MELEE_ATTACK1_NOTURN:
	case TASK_MELEE_ATTACK2_NOTURN:
	case TASK_RANGE_ATTACK2_NOTURN:
	case TASK_RELOAD_NOTURN:
		{
			if ( m_fSequenceFinished )
			{
				m_Activity = ACT_RESET;
				TaskComplete();
			}
			break;
		}
	case TASK_RANGE_ATTACK1:
	case TASK_MELEE_ATTACK1:
	case TASK_MELEE_ATTACK2:
	case TASK_RANGE_ATTACK2:
	case TASK_SPECIAL_ATTACK1:
	case TASK_SPECIAL_ATTACK2:
	case TASK_RELOAD:
		{
			MakeIdealYaw ( m_vecEnemyLKP );
			ChangeYaw ( pev->yaw_speed );

			if ( m_fSequenceFinished )
			{
				m_Activity = ACT_RESET;
				TaskComplete();
			}
			break;
		}
	case TASK_SMALL_FLINCH:
		{
			if ( m_fSequenceFinished )
			{
				TaskComplete();
			}
		}
		break;
	case TASK_WAIT_FOR_SCRIPT:
		{
			if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_PLAY_SCRIPT:
		{
//			ALERT(at_console, "Play Script\n");
			if (m_fSequenceFinished)
			{
//				ALERT(at_console, "Anim Finished\n");
				if (m_pCine->m_iRepeatsLeft > 0)
				{
//					ALERT(at_console, "Frame %f; Repeat %d from %f\n", pev->frame, m_pCine->m_iRepeatsLeft, m_pCine->m_fRepeatFrame);
					m_pCine->m_iRepeatsLeft--;
					pev->frame = m_pCine->m_fRepeatFrame;
					ResetSequenceInfo( );
				}
				else
				{
					TaskComplete();
				}
			}
			break;
		}
	}
}
Exemplo n.º 7
0
//=========================================================
// GetSchedule - Decides which type of schedule best suits
// the monster's current state and conditions. Then calls
// monster's member function to get a pointer to a schedule
// of the proper type.
//=========================================================
Schedule_t *CBaseMonster :: GetSchedule ( void )
{
	switch	( m_MonsterState )
	{
	case MONSTERSTATE_PRONE:
		{
			return GetScheduleOfType( SCHED_BARNACLE_VICTIM_GRAB );
			break;
		}
	case MONSTERSTATE_NONE:
		{
			ALERT ( at_aiconsole, "MONSTERSTATE IS NONE!\n" );
			break;
		}
	case MONSTERSTATE_IDLE:
		{
			if ( HasConditions ( bits_COND_HEAR_SOUND ) )
			{
				return GetScheduleOfType( SCHED_ALERT_FACE );
			}
			else if ( FRouteClear() )
			{
				// no valid route!
				return GetScheduleOfType( SCHED_IDLE_STAND );
			}
			else
			{
				// valid route. Get moving
				return GetScheduleOfType( SCHED_IDLE_WALK );
			}
			break;
		}
	case MONSTERSTATE_ALERT:
		{
			if ( HasConditions( bits_COND_ENEMY_DEAD ) && LookupActivity( ACT_VICTORY_DANCE ) != ACTIVITY_NOT_AVAILABLE )
			{
				return GetScheduleOfType ( SCHED_VICTORY_DANCE );
			}

			if ( HasConditions(bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE) )
			{
				if ( fabs( FlYawDiff() ) < (1.0 - m_flFieldOfView) * 60 ) // roughly in the correct direction
				{
					return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ORIGIN );
				}
				else
				{
					return GetScheduleOfType( SCHED_ALERT_SMALL_FLINCH );
				}
			}

			else if ( HasConditions ( bits_COND_HEAR_SOUND ) )
			{
				return GetScheduleOfType( SCHED_ALERT_FACE );
			}
			else
			{
				return GetScheduleOfType( SCHED_ALERT_STAND );
			}
			break;
		}
	case MONSTERSTATE_COMBAT:
		{
			if ( HasConditions( bits_COND_ENEMY_DEAD ) )
			{
				// clear the current (dead) enemy and try to find another.
				m_hEnemy = NULL;

				if ( GetEnemy() )
				{
					ClearConditions( bits_COND_ENEMY_DEAD );
					return GetSchedule();
				}
				else
				{
					SetState( MONSTERSTATE_ALERT );
					return GetSchedule();
				}
			}

			if ( HasConditions(bits_COND_NEW_ENEMY) )
			{
				return GetScheduleOfType ( SCHED_WAKE_ANGRY );
			}
			else if (HasConditions(bits_COND_LIGHT_DAMAGE) && !HasMemory( bits_MEMORY_FLINCHED) )
			{
				return GetScheduleOfType( SCHED_SMALL_FLINCH );
			}
			else if ( !HasConditions(bits_COND_SEE_ENEMY) )
			{
				// we can't see the enemy
				if ( !HasConditions(bits_COND_ENEMY_OCCLUDED) )
				{
					// enemy is unseen, but not occluded!
					// turn to face enemy
					return GetScheduleOfType( SCHED_COMBAT_FACE );
				}
				else
				{
					// chase!
					return GetScheduleOfType( SCHED_CHASE_ENEMY );
				}
			}
			else  
			{
				// we can see the enemy
				if ( HasConditions(bits_COND_CAN_RANGE_ATTACK1) )
				{
					return GetScheduleOfType( SCHED_RANGE_ATTACK1 );
				}
				if ( HasConditions(bits_COND_CAN_RANGE_ATTACK2) )
				{
					return GetScheduleOfType( SCHED_RANGE_ATTACK2 );
				}
				if ( HasConditions(bits_COND_CAN_MELEE_ATTACK1) )
				{
					return GetScheduleOfType( SCHED_MELEE_ATTACK1 );
				}
				if ( HasConditions(bits_COND_CAN_MELEE_ATTACK2) )
				{
					return GetScheduleOfType( SCHED_MELEE_ATTACK2 );
				}
				if ( !HasConditions(bits_COND_CAN_RANGE_ATTACK1 | bits_COND_CAN_MELEE_ATTACK1) )
				{
					// if we can see enemy but can't use either attack type, we must need to get closer to enemy
					return GetScheduleOfType( SCHED_CHASE_ENEMY );
				}
				else if ( !FacingIdeal() )
				{
					//turn
					return GetScheduleOfType( SCHED_COMBAT_FACE );
				}
				else
				{
					ALERT ( at_aiconsole, "No suitable combat schedule!\n" );
				}
			}
			break;
		}
	case MONSTERSTATE_DEAD:
		{
			return GetScheduleOfType( SCHED_DIE );
			break;
		}
	case MONSTERSTATE_SCRIPT:
		{
			ASSERT( m_pCine != NULL );
			if ( !m_pCine )
			{
				ALERT( at_aiconsole, "Script failed for %s\n", STRING(pev->classname) );
//				ALERT( at_console, "Script failed for %s\n", STRING(pev->classname) );
				CineCleanup();
				return GetScheduleOfType( SCHED_IDLE_STAND );
			}

			return GetScheduleOfType( SCHED_AISCRIPT );
		}
	default:
		{
			ALERT ( at_aiconsole, "Invalid State for GetSchedule!\n" );
			break;
		}
	}

	return &slError[ 0 ];
}
Exemplo n.º 8
0
//=========================================================
// 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;
		}
	}
}
/*
================
rvMonsterStroggMarine::State_Torso_RangedAttack
================
*/
stateResult_t rvMonsterStroggMarine::State_Torso_RangedAttack ( const stateParms_t& parms ) {
	enum { 
		STAGE_START,
		STAGE_START_WAIT,
		STAGE_SHOOT,
		STAGE_SHOOT_WAIT,
		STAGE_END,
		STAGE_END_WAIT,
	};
	//TurnToward(enemy.lastKnownPosition);
	switch ( parms.stage ) {
		case STAGE_START:
			// If moving switch to the moving ranged attack (torso only)
			if ( move.fl.moving && move.fl.running && !actionRangedAttack.fl.overrideLegs && FacingIdeal() ) {
				PostAnimState ( ANIMCHANNEL_TORSO, "Torso_MovingRangedAttack", parms.blendFrames );
				return SRESULT_DONE;
			}

			// Full body animations						
			DisableAnimState ( ANIMCHANNEL_LEGS );

			fireAnimNum = gameLocal.random.RandomInt(2)+1;
			CalculateShots();
			shotsFired = 0;

			// Attack lead in animation?
			if ( HasAnim ( ANIMCHANNEL_TORSO, va("range_attack%d_start", fireAnimNum), true ) ) {
				PlayAnim ( ANIMCHANNEL_TORSO, va("range_attack%d_start", fireAnimNum), parms.blendFrames );
				return SRESULT_STAGE ( STAGE_START_WAIT );
			}

			return SRESULT_STAGE ( STAGE_SHOOT );
			
		case STAGE_START_WAIT:
			// When the pre shooting animation is done head over to shooting
			if ( AnimDone ( ANIMCHANNEL_TORSO, 0 ) ) {
				return SRESULT_STAGE ( STAGE_SHOOT );
			}
			return SRESULT_WAIT;
		
		case STAGE_SHOOT:
			PlayAnim ( ANIMCHANNEL_TORSO, va("range_attack%d_loop", fireAnimNum), 0 );
			shots--;
			shotsFired++;
			return SRESULT_STAGE ( STAGE_SHOOT_WAIT );
		
		case STAGE_SHOOT_WAIT:
			// When the shoot animation is done either play another shot animation
			// or finish up with post_shooting
			if ( AnimDone ( ANIMCHANNEL_TORSO, 0 ) ) {
				if ( shots <= 0 ) {
					return SRESULT_STAGE ( STAGE_END );
				}
				// If our enemy is no longer in our fov we can stop shooting
				if ( !enemy.fl.inFov && shotsFired >= minShots ) { 
					return SRESULT_STAGE ( STAGE_END );
				}
				return SRESULT_STAGE ( STAGE_SHOOT);
			}
			return SRESULT_WAIT;
			
		case STAGE_END:
			// Attack lead in animation?
			if ( HasAnim ( ANIMCHANNEL_TORSO, va("range_attack%d_end", fireAnimNum), true ) ) {
				PlayAnim ( ANIMCHANNEL_TORSO, va("range_attack%d_end", fireAnimNum), parms.blendFrames );
				return SRESULT_STAGE ( STAGE_END_WAIT );
			}			
			return SRESULT_DONE;
			
		case STAGE_END_WAIT:
			if ( AnimDone ( ANIMCHANNEL_TORSO, parms.blendFrames ) ) {
				return SRESULT_DONE;
			}
			return SRESULT_WAIT;
	}
	return SRESULT_ERROR; 
}