Game::Game(MutationOfJBEngine *vm) : _vm(vm), _randomSource("mutationofjb"), _delayedLocalScript(nullptr), _gui(*this, _vm->getScreen()), _currentAction(ActionInfo::Walk), _scriptExecCtx(*this), _taskManager(*this), _assets(*this) { _gameData = new GameData; loadGameData(false); EncryptedFile globalScriptFile; globalScriptFile.open("global.atn"); _globalScript = new Script; _globalScript->loadFromStream(globalScriptFile); globalScriptFile.close(); _localScript = nullptr; _room = new Room(this, _vm->getScreen()); _gui.init(); _taskManager.startTask(TaskPtr(new ObjectAnimationTask)); }
TaskPtr tconn::FindTask(unsigned int pos) { TaskMapIt it=objtaskmap.find(pos); if(it==objtaskmap.end()) return TaskPtr(); return it->second; }
TaskPtr QueueProcessor::GetTask() { Lock lock(m_mutexForGetTask); auto queue = GetNonEmptyQueue(); if (queue) { return queue->Dequeue(); } return TaskPtr(); }
unsigned Discovery::Task::Init(util::Scheduler *poller, Callback *cb) { unsigned rc = m_socket.EnableBroadcast(true); if (rc == 0) m_socket.SetNonBlocking(true); if (rc == 0) { util::IPEndPoint ep = { util::IPAddress::ANY, DISCOVERY_PORT }; rc = m_socket.Bind(ep); } if (rc == 0) { poller->WaitForReadable( util::Bind(TaskPtr(this)).To<&Task::Run>(), m_socket.GetHandle(), false); poller->Wait( util::Bind(TaskPtr(this)).To<&Task::OnTimer>(), 0, 5000); } m_callback = cb; return rc; }
void AgitatedSearchingStateLanternBot::Init(idAI* owner) { // Init base class first State::Init(owner); DM_LOG(LC_AI, LT_INFO)LOGSTRING("AgitatedSearchingStateLanternBot initialised.\r"); assert(owner); // Ensure we are in the correct alert level if (!CheckAlertLevel(owner)) { return; } owner->movementSubsystem->ClearTasks(); owner->senseSubsystem->ClearTasks(); owner->actionSubsystem->ClearTasks(); owner->commSubsystem->ClearTasks(); // grayman #3182 owner->searchSubsystem->ClearTasks(); // grayman #3857 owner->StopMove(MOVE_STATUS_DONE); // Start with an invalid position _curAlertPos = idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); // Move to a position where we can light up the alert position from MoveTowardAlertPos(owner); owner->GetMemory().currentSearchEventID = owner->LogSuspiciousEvent( E_EventTypeMisc, owner->GetPhysics()->GetOrigin(), NULL, true ); // grayman #3857 // This will hold the message to be delivered with the inaudible bark CommMessagePtr message(new CommMessage( CommMessage::RequestForHelp_CommType, // grayman #3857 - asking for a response //CommMessage::DetectedEnemy_CommType, // grayman #3857 - this does nothing when no entity (parameter 4) is provided owner, NULL,// from this AI to anyone NULL, _curAlertPos, owner->GetMemory().currentSearchEventID // grayman #3857 (was '0') )); // The communication system plays starting bark owner->commSubsystem->AddCommTask( CommunicationTaskPtr(new RepeatedBarkTask("snd_spotted_noise", 3000, 4000, message)) ); // Add the script task blowing the alarm whistle owner->actionSubsystem->PushTask(TaskPtr(new ScriptTask("startAlarmWhistle"))); }
void TaskManager::UpdateProcesses(Uint32 deltaMs) { TaskPtr next; for (auto current : task_list) { if (current->IsDead()) { next = current->GetNext(); if (next) { current->SetNext(TaskPtr(nullptr)); Attach(next); } Detach(current); } else if (current->IsActive() && !current->IsPaused()) { current->OnUpdate(deltaMs); } } }
int TaskDialog::createNewTask() { TaskPtr newTask = TaskPtr(new Task()); m_pTaskListModel->addTask(newTask); m_pDataWidgetMapper->toLast(); disableBrowseButtons(true); int execResult = exec(); switch (execResult) { case QDialog::Accepted: // acept new task data m_pDataWidgetMapper->submit(); break; case QDialog::Rejected: // delete new added task m_pTaskListModel->removeLastTask(); break; } return execResult; }
void TakeCoverState::Init(idAI* owner) { // Init base class first State::Init(owner); DM_LOG(LC_AI, LT_INFO)LOGSTRING("TakeCoverState initialised.\r"); assert(owner); // Shortcut reference Memory& memory = owner->GetMemory(); // angua: The last position of the AI before it takes cover, so it can return to it later. memory.positionBeforeTakingCover = owner->GetPhysics()->GetOrigin(); // Fill the subsystems with their tasks // The movement subsystem should wait half a second and then run to Cover position, // wait there for some time and then emerge to have a look. owner->StopMove(MOVE_STATUS_DONE); memory.StopReacting(); // grayman #3559 owner->movementSubsystem->ClearTasks(); owner->movementSubsystem->PushTask(TaskPtr(new WaitTask(500))); owner->movementSubsystem->QueueTask(MoveToCoverTask::CreateInstance()); owner->AI_MOVE_DONE = false; // The communication system // owner->GetSubsystem(SubsysCommunication)->ClearTasks(); // TODO_AI // The sensory system owner->senseSubsystem->ClearTasks(); // No action (in case you were throwing rocks) owner->actionSubsystem->ClearTasks(); // grayman #3857 - Stop searching owner->searchSubsystem->ClearTasks(); }
void MenuItem::setDefaults() { // Not the most efficient, but saves lots of duplication // not m_title m_subtitle = ""; m_icon = ""; m_arrow_on_right = false; m_chain = false; m_copyright_details_pending = false; m_crippled = false; m_implemented = true; m_label_only = false; m_needs_privilege = false; m_not_if_locked = false; m_unsupported = false; m_func = nullptr; m_openable_widget_maker = nullptr; m_p_menuproxy = MenuProxyPtr(nullptr); m_task_tablename = ""; m_p_task = TaskPtr(nullptr); }
CountedPointer<AsyncWriteBuffer::Impl::Task> AsyncWriteBuffer::Impl::Task::Create(AsyncWriteBuffer::Impl *parent, int which) { return TaskPtr(new AsyncWriteBuffer::Impl::Task(parent,which)); }
void SearchingState::StartNewHidingSpotSearch( idAI *owner ) { Memory &memory = owner->GetMemory(); // grayman #3438 - exit if there's no focus for the search if( memory.alertPos.x == idMath::INFINITY ) { return; } // Clear flags memory.restartSearchForHidingSpots = false; memory.noMoreHidingSpots = false; memory.mandatory = false; // grayman #3331 // Clear all the ongoing tasks owner->senseSubsystem->ClearTasks(); owner->actionSubsystem->ClearTasks(); owner->movementSubsystem->ClearTasks(); // Stop moving owner->StopMove( MOVE_STATUS_DONE ); memory.StopReacting(); // grayman #3559 owner->MarkEventAsSearched( memory.currentSearchEventID ); // grayman #3424 memory.lastAlertPosSearched = memory.alertPos; // grayman #3492 // If we are supposed to search the stimulus location do that instead // of just standing around while the search completes if( memory.stimulusLocationItselfShouldBeSearched ) { // The InvestigateSpotTask will take this point as first hiding spot memory.currentSearchSpot = memory.alertPos; // Delegate the spot investigation to a new task, this will take the correct action. owner->actionSubsystem->PushTask( TaskPtr( new InvestigateSpotTask( memory.investigateStimulusLocationClosely ) ) ); //gameRenderWorld->DebugArrow(colorPink, owner->GetEyePosition(), memory.currentSearchSpot, 1, 2000); // Prevent overwriting this hiding spot in the upcoming Think() call memory.hidingSpotInvestigationInProgress = true; // Reset the flags //memory.stimulusLocationItselfShouldBeSearched = false; // grayman #3756 - reset in InvestigateSpotTask() memory.investigateStimulusLocationClosely = false; } else { // AI is not moving, wait for spot search to complete memory.hidingSpotInvestigationInProgress = false; memory.currentSearchSpot = idVec3( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY ); } idVec3 minBounds( memory.alertPos - memory.alertSearchVolume ); idVec3 maxBounds( memory.alertPos + memory.alertSearchVolume ); idVec3 minExclusionBounds( memory.alertPos - memory.alertSearchExclusionVolume ); idVec3 maxExclusionBounds( memory.alertPos + memory.alertSearchExclusionVolume ); // Close any previous search owner->Event_CloseHidingSpotSearch(); // Hiding spot test now started memory.hidingSpotSearchDone = false; memory.hidingSpotTestStarted = true; // Invalidate the vector, clear the indices memory.firstChosenHidingSpotIndex = -1; memory.currentChosenHidingSpotIndex = -1; // Start search int res = owner->StartSearchForHidingSpotsWithExclusionArea( owner->GetEyePosition(), minBounds, maxBounds, minExclusionBounds, maxExclusionBounds, 255, owner ); if( res == 0 ) { // Search completed on first round memory.hidingSpotSearchDone = true; } }
// 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(); } */ }
void BlurInput::processFrame(const FramePtr &ptr) { TaskPtr task = TaskPtr(new BlurTask(&m_component->m_frameSource, ptr)); m_component->m_executor->execute(task); }
void ExamineRopeState::Init(idAI* owner) { //Memory& memory = owner->GetMemory(); State::Init(owner); DM_LOG(LC_AI, LT_INFO)LOGSTRING("ExamineRopeState initialized.\r"); assert(owner); idAFEntity_Generic* rope = _rope.GetEntity(); if ( rope == NULL ) // this could happen if the player frobs the rope arrow { Wrapup(owner); return; } idVec3 goalDirection; idVec3 ownerOrg = owner->GetPhysics()->GetOrigin(); int areaNum = owner->PointReachableAreaNum(ownerOrg, 1.0f); idEntity* bindMaster = rope->GetBindMaster(); goalDirection = ownerOrg - _point; // fallback - use a direction from the point to the AI if ( bindMaster != NULL ) // the bindMaster is the stuck rope arrow { goalDirection = rope->GetPhysics()->GetOrigin() - bindMaster->GetPhysics()->GetOrigin(); // preferred direction } goalDirection.z = 0; // ignore vertical component goalDirection.NormalizeFast(); idVec3 size(16, 16, 82); idAAS* aas = owner->GetAAS(); if (aas) { size = aas->GetSettings()->boundingBoxes[0][1]; } // Move away from _point and perform a trace down to detect the ground. float standOff = 4*size.x; // any closer than this makes the "look up" animation look a bit strained (ouch!) idVec3 startPoint = _point + goalDirection * standOff; idVec3 bottomPoint = startPoint; bottomPoint.z -= 1000; idVec3 tp1 = startPoint; trace_t result; bool tp1Found = false; if ( gameLocal.clip.TracePoint(result, startPoint, bottomPoint, MASK_OPAQUE, NULL) ) { // Found the floor. tp1.z = result.endpos.z + 1; // move the target point to just above the floor tp1Found = true; } // Reverse direction and see if the floor is closer in that direction startPoint = _point - goalDirection * standOff; idVec3 tp2 = startPoint; bool tp2Found = false; bottomPoint = startPoint; bottomPoint.z -= 1000; if (gameLocal.clip.TracePoint(result, startPoint, bottomPoint, MASK_OPAQUE, NULL)) { // Found the floor. tp2.z = result.endpos.z + 1; // move the target point to just above the floor tp2Found = true; } bool use1 = false; if ( tp1Found ) { if ( tp2Found ) { float tp1ZDelta = abs(ownerOrg.z - tp1.z); float tp2ZDelta = abs(ownerOrg.z - tp2.z); use1 = ( tp1ZDelta <= tp2ZDelta ); } else { use1 = true; } } _examineSpot = _point; // if no spots are found for the AI to stage an examination, search around _point int targetAreaNum; aasPath_t path; bool pathToGoal = false; // whether there's a path to the target point near the rope if ( use1 ) { // Is there a path to tp1? targetAreaNum = owner->PointReachableAreaNum(tp1, 1.0f); if ( owner->PathToGoal(path, areaNum, ownerOrg, targetAreaNum, tp1, owner) ) { pathToGoal = true; _examineSpot = tp1; } } if ( !pathToGoal ) { if ( tp2Found ) { // Is there a path to tp2? targetAreaNum = owner->PointReachableAreaNum(tp2, 1.0f); if ( owner->PathToGoal(path, areaNum, ownerOrg, targetAreaNum, tp2, owner) ) { pathToGoal = true; _examineSpot = tp2; } } } if ( pathToGoal ) { owner->actionSubsystem->ClearTasks(); owner->movementSubsystem->ClearTasks(); // if AI is sitting, he has to stand before sending him on his way owner->movementSubsystem->PushTask(TaskPtr(new MoveToPositionTask(_examineSpot,idMath::INFINITY,5))); if (owner->GetMoveType() == MOVETYPE_SIT) { _examineRopeState = EStateSitting; } else { _examineRopeState = EStateStarting; } _waitEndTime = gameLocal.time + 1000; // allow time for move to begin return; } // There's no path to the goal. Go straight to searching. _waitEndTime = 0; _examineRopeState = EStateFinal; }
// Gets called each time the mind is thinking void ExamineRopeState::Think(idAI* owner) { // It's possible that during the examination of a rope, the player // frobs back the rope arrow. You have to account for that. Memory& memory = owner->GetMemory(); idAFEntity_Generic* rope = _rope.GetEntity(); if ( rope == NULL ) // this could happen if the player frobs the rope arrow { Wrapup(owner); return; } // check if something happened to abort the examination if (owner->GetMemory().stopExaminingRope) { Wrapup(owner); return; } owner->PerformVisualScan(); // Let the AI check its senses if (owner->AI_AlertLevel >= owner->thresh_5) // finished if alert level is too high { Wrapup(owner); return; } if ((owner->m_HandlingDoor) || (owner->m_HandlingElevator)) { return; // we're handling a door or elevator, so delay the examination } switch (_examineRopeState) { case EStateSitting: if (gameLocal.time >= _waitEndTime) { if (owner->AI_MOVE_DONE && (owner->GetMoveType() != MOVETYPE_GET_UP)) // standing yet? { owner->movementSubsystem->PushTask(TaskPtr(new MoveToPositionTask(_examineSpot,idMath::INFINITY,5))); _examineRopeState = EStateStarting; _waitEndTime = gameLocal.time + 1000; // allow time for move to begin } } break; case EStateStarting: if (owner->AI_FORWARD || (gameLocal.time >= _waitEndTime)) { _examineRopeState = EStateApproaching; } break; case EStateApproaching: // Walking toward the rope if (owner->AI_MOVE_DONE) { owner->TurnToward(_point); _examineRopeState = EStateTurningToward; _waitEndTime = gameLocal.time + 750; // allow time for turn to complete } break; case EStateTurningToward: if (gameLocal.time >= _waitEndTime) { StartExaminingTop(owner); // AI looks at top of rope _examineRopeState = EStateExamineTop; _waitEndTime = gameLocal.time + 3000; } break; case EStateExamineTop: if (gameLocal.time >= _waitEndTime) { StartExaminingBottom(owner); // AI looks at bottom of rope _waitEndTime = gameLocal.time + 3000; _examineRopeState = EStateExamineBottom; } break; case EStateExamineBottom: if (gameLocal.time >= _waitEndTime) { _waitEndTime = gameLocal.time + 1000; _examineRopeState = EStateFinal; } break; case EStateFinal: if (gameLocal.time >= _waitEndTime) { // Set up search if latched if (owner->m_LatchedSearch) { owner->m_LatchedSearch = false; if (owner->AI_AlertLevel < owner->thresh_4) { memory.alertPos = _examineSpot; memory.alertClass = EAlertVisual_4; // grayman #3498 (was _2) memory.alertType = EAlertTypeSuspiciousItem; // Do search as if there is an enemy that has escaped memory.alertRadius = LOST_ENEMY_ALERT_RADIUS; memory.alertSearchVolume = LOST_ENEMY_SEARCH_VOLUME; memory.alertSearchExclusionVolume.Zero(); owner->AI_VISALERT = false; memory.visualAlert = false; // grayman #2422 memory.mandatory = false; // grayman #3331 // Do new reaction to stimulus memory.stimulusLocationItselfShouldBeSearched = true; // If the rope origin is close to your feet, do a close investigation float ropeDist = rope->GetPhysics()->GetOrigin().z - owner->GetPhysics()->GetOrigin().z; memory.investigateStimulusLocationClosely = ( abs(ropeDist) <= 20 ); memory.alertedDueToCommunication = false; } } Wrapup(owner); return; } break; default: break; } }
TaskPtr JudgeTaskFactory::create(const TaskInputData & input) { return TaskPtr(new JudgeTask(input)); }
void UnreachableTargetState::Init(idAI* owner) { // Init base class first State::Init(owner); DM_LOG(LC_AI, LT_INFO)LOGSTRING("UnreachableTargetState initialised.\r"); assert(owner); // Shortcut reference Memory& memory = owner->GetMemory(); idActor* enemy = owner->GetEnemy(); if (!enemy) { owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY); return; } _enemy = enemy; // This checks if taking cover is possible and enabled for this AI _takingCoverPossible = false; if (owner->spawnArgs.GetBool("taking_cover_enabled","0")) { aasGoal_t hideGoal; // grayman #3280 - enemies look with their eyes, not their feet _takingCoverPossible = owner->LookForCover(hideGoal, enemy, enemy->GetEyePosition()); if (_takingCoverPossible) { // We should not go into TakeCoverState if we are already at a suitable position if (hideGoal.origin == owner->GetPhysics()->GetOrigin() ) { _takingCoverPossible = false; } DM_LOG(LC_AI, LT_INFO)LOGSTRING("Taking Cover Possible: %d \r" , _takingCoverPossible); } } _takeCoverTime = -1; // Fill the subsystems with their tasks // Create the message CommMessagePtr message(new CommMessage( CommMessage::RequestForMissileHelp_CommType, owner, NULL, // from this AI to anyone enemy, memory.lastEnemyPos, 0 )); // grayman #3343 - accommodate different barks for human and non-human enemies idStr bark = ""; idStr enemyAiUse = enemy->spawnArgs.GetString("AIUse"); if ( ( enemyAiUse == AIUSE_MONSTER ) || ( enemyAiUse == AIUSE_UNDEAD ) ) { bark = "snd_cantReachTargetMonster"; } else { bark = "snd_cantReachTarget"; } owner->commSubsystem->AddCommTask(CommunicationTaskPtr(new SingleBarkTask(bark, message))); if (cv_ai_debug_transition_barks.GetBool()) { gameLocal.Printf("%d: %s can't reach the target, barks '%s'\n",gameLocal.time,owner->GetName(),bark.c_str()); } // The sensory system does nothing so far owner->senseSubsystem->ClearTasks(); owner->StopMove(MOVE_STATUS_DONE); owner->movementSubsystem->ClearTasks(); memory.stopRelight = true; // grayman #2603 - abort a relight in progress memory.stopExaminingRope = true; // grayman #2872 - stop examining a rope memory.stopReactingToHit = true; // grayman #2816 owner->actionSubsystem->ClearTasks(); _moveRequired = false; if (owner->spawnArgs.GetBool("outofreach_projectile_enabled", "0")) { // Check the distance between AI and the player, if it is too large try to move closer // Start throwing objects if we are close enough idVec3 enemyDirection = enemy->GetPhysics()->GetOrigin() - owner->GetPhysics()->GetOrigin(); float dist = (enemyDirection).LengthFast(); //TODO: make not hardcoded if (dist > 300) { _moveRequired = true; idVec3 throwPos = enemy->GetPhysics()->GetOrigin() - enemyDirection / dist * 300; // TODO: Trace to get floor position throwPos.z = owner->GetPhysics()->GetOrigin().z; owner->movementSubsystem->PushTask(TaskPtr(new MoveToPositionTask(throwPos))); owner->AI_MOVE_DONE = false; } else { // greebo: Sheathe weapon before starting to throw // FIXME: put weapon to left hand? owner->SheathWeapon(); owner->FaceEnemy(); owner->actionSubsystem->PushTask(ThrowObjectTask::CreateInstance()); // Wait at least 3 sec after starting to throw before taking cover // TODO: make not hardcoded, some randomness? _takeCoverTime = gameLocal.time + 3000; } DM_LOG(LC_AI, LT_INFO)LOGSTRING("move required: %d \r" , _moveRequired); } else { owner->movementSubsystem->PushTask( TaskPtr(new MoveToPositionTask(owner->lastVisibleReachableEnemyPos)) ); _takeCoverTime = gameLocal.time + 3000; } _reachEnemyCheck = 0; }