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