Ejemplo n.º 1
0
// Gets called each time the mind is thinking
void IdleSleepState::Think(idAI* owner)
{
	Memory& memory = owner->GetMemory();

	if (_startSleeping && owner->GetMoveType() == MOVETYPE_ANIM)
	{
		if (owner->ReachedPos(memory.idlePosition, MOVE_TO_POSITION) 
			&& owner->GetCurrentYaw() == memory.idleYaw)
		{
			owner->AI_LAY_DOWN_LEFT = owner->spawnArgs.GetBool("lay_down_left", "1");
			owner->LayDown();
		}
	}
	else if (owner->GetMoveType() == MOVETYPE_GET_UP_FROM_LYING)
	{
		owner->GetMind()->SwitchState(owner->backboneStates[ERelaxed]);
		owner->commSubsystem->ClearTasks();
		return;
	}

	UpdateAlertLevel();

	// Ensure we are in the correct alert level
	if (!CheckAlertLevel(owner)) return;
}
// Gets called each time the mind is thinking
void AgitatedSearchingStateLanternBot::Think(idAI* owner)
{
	UpdateAlertLevel();

	// Ensure we are in the correct alert level
	if (!CheckAlertLevel(owner))
	{
//		owner->GetMind()->EndState(); // grayman #3182 - already done in CheckAlertLevel()
		return;
	}

	// Move (if alert position has changed)
	MoveTowardAlertPos(owner);

	if (owner->GetMoveStatus() == MOVE_STATUS_DONE)
	{
		// Look at alert position, now that we've finished moving
		owner->TurnToward(_curAlertPos);

		// Let the alertness decrease from now on
		CalculateAlertDecreaseRate(owner);
	}
	else
	{
		// Moving along, ensure that we're not dropping out of this state as long as we're moving
		_alertLevelDecreaseRate = 0;
		return;
	}
}
Ejemplo n.º 3
0
// Gets called each time the mind is thinking
void ObservantState::Think(idAI* owner)
{
	UpdateAlertLevel();
	// Ensure we are in the correct alert level
	if (!CheckAlertLevel(owner))
	{
		return;
	}
	
	// grayman #3520 - look at alert spots
	if (owner->m_lookAtAlertSpot)
	{
		owner->m_lookAtAlertSpot = false;
		if ( owner->GetMoveType() != MOVETYPE_SLEEP ) // grayman #3487 - not if asleep
		{
			idVec3 alertSpot = owner->m_lookAtPos;
			if ( alertSpot.x != idMath::INFINITY )
			{
				if (owner->CheckFOV(alertSpot))
				{
					owner->Event_LookAtPosition(alertSpot,((float)owner->AI_AlertLevel)/10.0f);
				}
			}
		}
		owner->m_lookAtPos = idVec3(idMath::INFINITY,idMath::INFINITY,idMath::INFINITY);
	}

	// grayman #2866 - zero alert decrease rate if handling a door or elevator

	if ((owner->m_HandlingDoor) || (owner->m_HandlingElevator))
	{
		_alertLevelDecreaseRate = 0;
	}
	else
	{
		_alertLevelDecreaseRate = owner->GetMemory().savedAlertLevelDecreaseRate;
	}

	if (owner->GetMoveType() != MOVETYPE_SLEEP)
	{
		// Let the AI check its senses
		owner->PerformVisualScan();
	}
}
// Gets called each time the mind is thinking
void SearchingState::Think( idAI *owner ) {
	UpdateAlertLevel();
	// Ensure we are in the correct alert level
	if( !CheckAlertLevel( owner ) ) {
		return;
	}
	// grayman #3063 - move up so it gets done each time,
	// regardless of what state the hiding spot search is in.
	// Let the AI check its senses
	owner->PerformVisualScan();
	if( owner->GetMoveType() == MOVETYPE_SIT
			|| owner->GetMoveType() == MOVETYPE_SLEEP
			|| owner->GetMoveType() == MOVETYPE_SIT_DOWN
			|| owner->GetMoveType() == MOVETYPE_LAY_DOWN ) {
		owner->GetUp();
		return;
	}
	Memory &memory = owner->GetMemory();
	owner->MarkEventAsSearched( memory.currentSearchEventID ); // grayman #3424
	// grayman #3520 - look at alert spots
	if( owner->m_lookAtAlertSpot ) {
		owner->m_lookAtAlertSpot = false;
		idVec3 alertSpot = owner->m_lookAtPos;
		if( alertSpot.x != idMath::INFINITY ) { // grayman #3438
			if( !owner->CheckFOV( alertSpot ) ) {
				// Search spot is not within FOV, turn towards the position
				owner->TurnToward( alertSpot );
				owner->Event_LookAtPosition( alertSpot, 2.0f );
			} else {
				owner->Event_LookAtPosition( alertSpot, 2.0f );
			}
		}
		owner->m_lookAtPos = idVec3( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY );
	}
	// grayman #3200 - if asked to restart the hiding spot search, don't continue with the current hiding spot search
	if( memory.restartSearchForHidingSpots ) {
		// We should restart the search (probably due to a new incoming stimulus)
		// Setup a new hiding spot search
		StartNewHidingSpotSearch( owner );
	} else if( !memory.hidingSpotSearchDone ) { // Do we have an ongoing hiding spot search?
		// Let the hiding spot search do its task
		PerformHidingSpotSearch( owner );
		// Let the AI check its senses
		//		owner->PerformVisualScan(); // grayman #3063 - moved to front
		/*
				// angua: commented this out, problems with getting up from sitting
				idStr waitState(owner->WaitState());
				if (waitState.IsEmpty())
				{
					// Waitstate is not matching, this means that the animation
					// can be started.
					owner->SetAnimState(ANIMCHANNEL_TORSO, "Torso_LookAround", 5);
					//owner->SetAnimState(ANIMCHANNEL_LEGS, "Legs_LookAround", 5);

					// Set the waitstate, this gets cleared by
					// the script function when the animation is done.
					owner->SetWaitState("look_around");
				}
		*/
	}
	// Is a hiding spot search in progress?
	else if( !memory.hidingSpotInvestigationInProgress ) {
		// Spot search and investigation done, what next?
		// Have run out of hiding spots?
		if( memory.noMoreHidingSpots ) {
			if( gameLocal.time >= memory.nextTime2GenRandomSpot ) {
				memory.nextTime2GenRandomSpot = gameLocal.time + DELAY_RANDOM_SPOT_GEN * ( 1 + ( gameLocal.random.RandomFloat() - 0.5 ) / 3 );
				// grayman #2422
				// Generate a random search point, but make sure it's inside an AAS area
				// and that it's also inside the search volume.
				idVec3 p;		// random point
				int areaNum;	// p's area number
				idVec3 searchSize = owner->m_searchLimits.GetSize();
				idVec3 searchCenter = owner->m_searchLimits.GetCenter();
				//gameRenderWorld->DebugBox(colorWhite, idBox(owner->m_searchLimits), MS2SEC(memory.nextTime2GenRandomSpot - gameLocal.time));
				bool validPoint = false;
				for( int i = 0 ; i < 6 ; i++ ) {
					p = searchCenter;
					p.x += gameLocal.random.RandomFloat() * ( searchSize.x ) - searchSize.x / 2;
					p.y += gameLocal.random.RandomFloat() * ( searchSize.y ) - searchSize.y / 2;
					p.z += gameLocal.random.RandomFloat() * ( searchSize.z ) - searchSize.z / 2;
					//p.z += gameLocal.random.RandomFloat()*(searchSize.z/2) - searchSize.z/4;
					areaNum = owner->PointReachableAreaNum( p );
					if( areaNum == 0 ) {
						//gameRenderWorld->DebugArrow(colorRed, owner->GetEyePosition(), p, 1, MS2SEC(memory.nextTime2GenRandomSpot - gameLocal.time));
						continue;
					}
					owner->GetAAS()->PushPointIntoAreaNum( areaNum, p ); // if this point is outside this area, it will be moved to one of the area's edges
					if( !owner->m_searchLimits.ContainsPoint( p ) ) {
						//gameRenderWorld->DebugArrow(colorPink, owner->GetEyePosition(), p, 1, MS2SEC(memory.nextTime2GenRandomSpot - gameLocal.time));
						continue;
					}
					//gameRenderWorld->DebugArrow(colorGreen, owner->GetEyePosition(), p, 1, MS2SEC(memory.nextTime2GenRandomSpot - gameLocal.time));
					validPoint = true;
					break;
				}
				if( validPoint ) {
					// grayman #2422 - the point chosen
					memory.currentSearchSpot = p;
					// Choose to investigate spots closely on a random basis
					// grayman #2801 - and only if you weren't hit by a projectile
					memory.investigateStimulusLocationClosely = ( ( gameLocal.random.RandomFloat() < 0.3f ) && ( memory.alertType != EAlertTypeHitByProjectile ) );
					owner->actionSubsystem->PushTask( TaskPtr( InvestigateSpotTask::CreateInstance() ) );
					//gameRenderWorld->DebugArrow(colorGreen, owner->GetEyePosition(), memory.currentSearchSpot, 1, 500);
					// Set the flag to TRUE, so that the sensory scan can be performed
					memory.hidingSpotInvestigationInProgress = true;
				}
				if( !validPoint ) { // no valid random point found
					// Stop moving, the algorithm will choose another spot the next round
					owner->StopMove( MOVE_STATUS_DONE );
					memory.StopReacting(); // grayman #3559
					// grayman #2422 - at least turn toward and look at the last invalid point some of the time
					// grayman #3492 - do it every time
					//if ( gameLocal.random.RandomFloat() < 0.5 )
					//{
					p.z += 60; // look up a bit, to simulate searching for the player's head
					if( !owner->CheckFOV( p ) ) {
						owner->TurnToward( p );
					}
					owner->Event_LookAtPosition( p, MS2SEC( memory.nextTime2GenRandomSpot - gameLocal.time + 100 ) );
					//gameRenderWorld->DebugArrow(colorPink, owner->GetEyePosition(), p, 1, MS2SEC(memory.nextTime2GenRandomSpot - gameLocal.time + 100));
					//}
				}
			}
		}
		// We should have more hiding spots, try to get the next one
		else if( !ChooseNextHidingSpotToSearch( owner ) ) {
			// No more hiding spots to search
			DM_LOG( LC_AI, LT_INFO )LOGSTRING( "No more hiding spots!\r" );
			// Stop moving, the algorithm will choose another spot the next round
			owner->StopMove( MOVE_STATUS_DONE );
			memory.StopReacting(); // grayman #3559
		} else {
			// ChooseNextHidingSpot returned TRUE, so we have memory.currentSearchSpot set
			//gameRenderWorld->DebugArrow(colorBlue, owner->GetEyePosition(), memory.currentSearchSpot, 1, 2000);
			// Delegate the spot investigation to a new task, this will take the correct action.
			owner->actionSubsystem->PushTask( InvestigateSpotTask::CreateInstance() );
			// Prevent falling into the same hole twice
			memory.hidingSpotInvestigationInProgress = true;
		}
	}
	/* grayman #3200 - moved up
		else if (memory.restartSearchForHidingSpots)
		{
			// We should restart the search (probably due to a new incoming stimulus)
			// Setup a new hiding spot search
			StartNewHidingSpotSearch(owner);
		}

		else // grayman #3063 - moved to front
		{
			// Move to Hiding spot is ongoing, do additional sensory tasks here

			// Let the AI check its senses
			owner->PerformVisualScan();
		}
	 */
}
Ejemplo n.º 5
0
// Gets called each time the mind is thinking
void FleeDoneState::Think(idAI* owner)
{
	if ( owner->AI_DEAD || owner->AI_KNOCKEDOUT ) // grayman #3317 - quit if KO'ed or dead
	{
		WrapUp(owner);
		owner->GetMind()->EndState();
		return;
	}

	UpdateAlertLevel();
		
	// Ensure we are in the correct alert level
	if (!CheckAlertLevel(owner)) 
	{
		// terminate FleeDoneState when time is over
		WrapUp(owner);
		owner->GetMind()->EndState();
		return;
	}

	// Let the AI check its senses
	owner->PerformVisualScan();
	if (owner->AI_ALERTED)
	{
		// terminate FleeDoneState when the AI is alerted
		WrapUp(owner);

		owner->GetMind()->EndState();
		return; // grayman #3474
	}

	if ( !owner->emitFleeBarks ) // grayman #3474
	{
		// not crying for help, time to end this state
		WrapUp(owner);
		owner->GetMind()->EndState();
		return;
	}

	// Shortcut reference
	Memory& memory = owner->GetMemory();

	if (!_searchForFriendDone)
	{
		idActor* friendlyAI = owner->FindFriendlyAI(-1);
		if ( friendlyAI != NULL)
		{
			// We found a friend, cry for help to him
			DM_LOG(LC_AI, LT_INFO)LOGSTRING("%s found friendly AI %s, crying for help\r", owner->name.c_str(),friendlyAI->name.c_str());

			_searchForFriendDone = true;
			owner->movementSubsystem->ClearTasks();
			owner->SetTurnRate(_oldTurnRate);

			owner->TurnToward(friendlyAI->GetPhysics()->GetOrigin());
			//float distanceToFriend = (friendlyAI->GetPhysics()->GetOrigin() - owner->GetPhysics()->GetOrigin()).LengthFast();

			// Cry for help
			// Create a new help message
			CommMessagePtr message(new CommMessage(
				CommMessage::RequestForHelp_CommType, 
				owner, friendlyAI,
				NULL,
				memory.alertPos,
				memory.currentSearchEventID // grayman #3857 (was '0')
			)); 

			CommunicationTaskPtr barkTask(new SingleBarkTask("snd_flee", message));

			if (cv_ai_debug_transition_barks.GetBool())
			{
				gameLocal.Printf("%d: %s flees, barks 'snd_flee'\n",gameLocal.time,owner->GetName());
			}

			owner->commSubsystem->AddCommTask(barkTask);
			memory.lastTimeVisualStimBark = gameLocal.time;
		}
		else if (gameLocal.time >= _turnEndTime)
		{
			// We didn't find a friend, stop looking for them after some time
			_searchForFriendDone = true;
			owner->movementSubsystem->ClearTasks();
			owner->SetTurnRate(_oldTurnRate);

			// Play the cowering animation
			owner->SetAnimState(ANIMCHANNEL_TORSO, "Torso_Cower", 4);
			owner->SetAnimState(ANIMCHANNEL_LEGS, "Legs_Cower", 4);
		}
	}
}