//---------------------------- Activate --------------------------------------- //----------------------------------------------------------------------------- void Goal_NegotiateDoor::Activate() { m_iStatus = active; //if this goal is reactivated then there may be some existing subgoals that //must be removed RemoveAllSubgoals(); //get the position of the closest navigable switch Vector2D posSw = m_pOwner->GetWorld()->GetPosOfClosestSwitch(m_pOwner->Pos(), m_PathEdge.DoorID()); //because goals are *pushed* onto the front of the subgoal list they must //be added in reverse order. //first the goal to traverse the edge that passes through the door AddSubgoal(new Goal_TraverseEdge(m_pOwner, m_PathEdge, m_bLastEdgeInPath)); //next, the goal that will move the bot to the beginning of the edge that //passes through the door AddSubgoal(new Goal_MoveToPosition(m_pOwner, m_PathEdge.Source())); //finally, the Goal that will direct the bot to the location of the switch AddSubgoal(new Goal_MoveToPosition(m_pOwner, posSw)); }
//------------------------------ Activate ------------------------------------- //----------------------------------------------------------------------------- void Goal_FollowPath::Activate() { m_iStatus = active; //get a reference to the next edge PathEdge edge = m_Path.front(); //remove the edge from the path m_Path.pop_front(); //some edges specify that the bot should use a specific behavior when //following them. This switch statement queries the edge behavior flag and //adds the appropriate goals/s to the subgoal list. switch(edge.Behavior()) { case NavGraphEdge::normal: { AddSubgoal(new Goal_TraverseEdge(m_pOwner, edge, m_Path.empty())); } break; case NavGraphEdge::goes_through_door: { //also add a goal that is able to handle opening the door AddSubgoal(new Goal_NegotiateDoor(m_pOwner, edge, m_Path.empty())); } break; case NavGraphEdge::jump: { //add subgoal to jump along the edge } break; case NavGraphEdge::grapple: { //add subgoal to grapple along the edge } break; default: throw std::runtime_error("<Goal_FollowPath::Activate>: Unrecognized edge type"); } }
//---------------------------- HandleMessage ---------------------------------- //----------------------------------------------------------------------------- bool Goal_Explore::HandleMessage(const Telegram& msg) { //first, pass the message down the goal hierarchy bool bHandled = ForwardMessageToFrontMostSubgoal(msg); //if the msg was not handled, test to see if this goal can handle it if (bHandled == false) { switch(msg.Msg) { case Msg_PathReady: //clear any existing goals RemoveAllSubgoals(); AddSubgoal(new Goal_FollowPath(m_pOwner, m_pOwner->GetPathPlanner()->GetPath())); return true; //msg handled case Msg_NoPathAvailable: m_iStatus = failed; return true; //msg handled default: return false; } } //handled by subgoals return true; }
//------------------------------ Activate ------------------------------------- //----------------------------------------------------------------------------- void Goal_InstallBomb::Activate() { m_iStatus = active; //if this goal is reactivated then there may be some existing subgoals that //must be removed RemoveAllSubgoals(); if (!m_bDestinationIsSet) { //grab a random location //m_CurrentDestination = m_pOwner->GetOwner()->GetCloseWallPos(m_pOwner->Center()); m_CurrentDestination = m_pOwner->GetOwner()->GetMap()->GetRandomNodeLocation(); m_bDestinationIsSet = true; } //and request a path to that position m_pOwner->GetPathPlanner()->RequestPathToPosition(m_CurrentDestination); //the bot may have to wait a few update cycles before a path is calculated //so for appearances sake it simple ARRIVES at the destination until a path //has been found AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_CurrentDestination)); }
//------------------------------- Activate ------------------------------------ //----------------------------------------------------------------------------- void Goal_AttackTarget::Activate() { m_iStatus = active; //if this goal is reactivated then there may be some existing subgoals that //must be removed RemoveAllSubgoals(); //it is possible for a bot's target to die whilst this goal is active so we //must test to make sure the bot always has an active target if (!m_pOwner->GetTargetSys()->isTargetPresent()) { m_iStatus = completed; return; } //if the bot is able to shoot the target (there is LOS between bot and //target), then select a tactic to follow while shooting if (m_pOwner->GetTargetSys()->isTargetShootable()) { //if the bot has space to strafe then do so Vector2D dummy; if (m_pOwner->canStepLeft(dummy) || m_pOwner->canStepRight(dummy)) { AddSubgoal(new Goal_DodgeSideToSide(m_pOwner)); } //if not able to strafe, head directly at the target's position else { AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_pOwner->GetTargetBot()->Pos())); } } //if the target is not visible, go hunt it. else { AddSubgoal(new Goal_HuntTarget(m_pOwner)); } }
void GoalFollowPath::Activate(const UpdateArgs& args) { status = Active; // get a reference to the next edge PathEdge edge = path.front(); // remove the edge from the path path.pop_front(); // add a TIKI_NEW subgoal to traverse an edge, if we loop, don't arrive AddSubgoal(TIKI_NEW GoalTraverseEdge(owner, edge, path.empty())); }
//------------------------------- Activate ------------------------------------ //----------------------------------------------------------------------------- void Goal_GetItem::Activate() { m_iStatus = active; m_pGiverTrigger = 0; //request a path to the item m_pOwner->GetPathPlanner()->RequestPathToItem(m_iItemToGet); //the bot may have to wait a few update cycles before a path is calculated //so for appearances sake it just wanders AddSubgoal(new Goal_Wander(m_pOwner)); }
//------------------------------- Activate ------------------------------------ //----------------------------------------------------------------------------- void Goal_GoToGrave::Activate() { m_iStatus = active; m_pGiverTrigger = 0; //request a path to the grave m_pOwner->GetPathPlanner()->RequestPathToPosition(m_grave->Position); //the bot may have to wait a few update cycles before a path is calculated //so for appearances sake it just wanders AddSubgoal(new Goal_Wander(m_pOwner)); }
//---------------------------- Initialize ------------------------------------- //----------------------------------------------------------------------------- void Goal_HuntTarget::Activate() { m_iStatus = active; //if this goal is reactivated then there may be some existing subgoals that //must be removed RemoveAllSubgoals(); //it is possible for the target to die whilst this goal is active so we //must test to make sure the bot always has an active target if (m_pOwner->GetTargetSys()->isTargetPresent()) { //grab a local copy of the last recorded position (LRP) of the target const Vector2D lrp = m_pOwner->GetTargetSys()->GetLastRecordedPosition(); //if the bot has reached the LRP and it still hasn't found the target //it starts to search by using the explore goal to move to random //map locations if (lrp.isZero() || m_pOwner->isAtPosition(lrp)) { AddSubgoal(new Goal_Explore(m_pOwner)); } //else move to the LRP else { AddSubgoal(new Goal_MoveToPosition(m_pOwner, lrp)); } } //if their is no active target then this goal can be removed from the queue else { m_iStatus = completed; } }
//------------------------------- Activate ------------------------------------ //----------------------------------------------------------------------------- void Goal_MoveToPosition::Activate() { m_iStatus = active; //make sure the subgoal list is clear. RemoveAllSubgoals(); //requests a path to the target position from the path planner. Because, for //demonstration purposes, the Raven path planner uses time-slicing when //processing the path requests the bot may have to wait a few update cycles //before a path is calculated. Consequently, for appearances sake, it just //seeks directly to the target position whilst it's awaiting notification //that the path planning request has succeeded/failed if (m_pOwner->GetPathPlanner()->RequestPathToPosition(m_vDestination)) { AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_vDestination)); } }
//---------------------------- HandleMessage ---------------------------------- //----------------------------------------------------------------------------- bool Goal_GetItem::HandleMessage(const Telegram& msg) { //first, pass the message down the goal hierarchy bool bHandled = ForwardMessageToFrontMostSubgoal(msg); //if the msg was not handled, test to see if this goal can handle it if (bHandled == false) { switch(msg.Msg) { case Msg_PathReady: //clear any existing goals RemoveAllSubgoals(); AddSubgoal(new Goal_FollowPath(m_pOwner, m_pOwner->GetPathPlanner()->GetPath())); //get the pointer to the item m_pGiverTrigger = static_cast<Raven_Map::TriggerType*>(msg.ExtraInfo); return true; //msg handled case Msg_NoPathAvailable: m_iStatus = failed; return true; //msg handled default: return false; } } //handled by subgoals return true; }