//------------------------------ RequestPathToItem ----------------------------- // // Given an item type, this method determines the closest reachable graph node // to the bot's position and then creates a instance of the time-sliced // Dijkstra's algorithm, which it registers with the search manager // //----------------------------------------------------------------------------- bool CActor_PathPlanner::RequestPathToItem( unsigned int ItemType ) { //clear the waypoint list and delete any active search GetReadyForNewSearch(); //find the closest visible node to the bots position int ClosestNodeToBot = GetClosestNodeToPosition( m_pOwner->Pos() ); //remove the destination node from the list and return false if no visible //node found. This will occur if the navgraph is badly designed or if the bot //has managed to get itself *inside* the geometry (surrounded by walls), //or an obstacle if ( ClosestNodeToBot == no_closest_node_found ) { #ifdef SHOW_NAVINFO debug_con << "No closest node to bot found!" << ""; #endif return false; } //create an instance of the search algorithm typedef FindActiveTrigger < Trigger < CActorMapa > > t_con; typedef Graph_SearchDijkstras_TS < PlayModel::NavGraph, t_con > DijSearch; m_pCurrentSearch = new DijSearch( m_NavGraph, ClosestNodeToBot, ItemType ); //register the search with the path manager m_pOwner->World()->GetPathManager()->Register( this ); return true; }
//---------------------------- GetCostToNode ---------------------------------- // // returns the cost to travel from the bot's current position to a specific // graph node. This method makes use of the pre-calculated lookup table //----------------------------------------------------------------------------- double Raven_PathPlanner::GetCostToNode(unsigned int NodeIdx)const { //find the closest visible node to the bots position int nd = GetClosestNodeToPosition(m_pOwner->Pos()); //add the cost to this node double cost =Vec2DDistance(m_pOwner->Pos(), m_NavGraph.GetNode(nd).Pos()); //add the cost to the target node and return return cost + m_pOwner->GetWorld()->GetMap()->CalculateCostToTravelBetweenNodes(nd, NodeIdx); }
//----------------------------- GetPath ------------------------------------ // // called by an agent after it has been notified that a search has terminated // successfully. The method extracts the path from m_pCurrentSearch, adds // additional edges appropriate to the search type and returns it as a list of // PathEdges. //----------------------------------------------------------------------------- CActor_PathPlanner::Path CActor_PathPlanner::GetPath() { assert( m_pCurrentSearch && "<CActor_PathPlanner::GetPathAsNodes>: no current search" ); Path path = m_pCurrentSearch->GetPathAsPathEdges(); int closest = GetClosestNodeToPosition( m_pOwner->Pos() ); path.push_front( PathEdge( m_pOwner->Pos(), GetNodePosition( closest ), NavGraphEdge::normal ) ); //if the bot requested a path to a location then an edge leading to the //destination must be added if ( m_pCurrentSearch->GetType() == Graph_SearchTimeSliced < EdgeType >::AStar ) { int idx = m_pOwner->World()->GetCellSpace()->PositionToIndex( m_vDestinationPos ); if ( invalid_node_index != m_pOwner->World()->GetNavGraph().GetNode( idx ).Index() ) { path.push_back( PathEdge( path.back().Destination(), m_vDestinationPos, NavGraphEdge::normal ) ); } } //smooth paths if required if ( script->GetBool( "SmoothPathsQuick" ) ) { SmoothPathEdgesQuick( path ); } if ( script->GetBool( "SmoothPathsPrecise" ) ) { SmoothPathEdgesPrecise( path ); } return path; }
//------------------------ GetCostToClosestItem --------------------------- // // returns the cost to the closest instance of the giver type. This method // makes use of the pre-calculated lookup table. Returns -1 if no active // trigger found //----------------------------------------------------------------------------- double Raven_PathPlanner::GetCostToClosestItem(unsigned int GiverType)const { //find the closest visible node to the bots position int nd = GetClosestNodeToPosition(m_pOwner->Pos()); //if no closest node found return failure if (nd == invalid_node_index) return -1; double ClosestSoFar = MaxDouble; //iterate through all the triggers to find the closest *active* trigger of //type GiverType const Raven_Map::TriggerSystem::TriggerList& triggers = m_pOwner->GetWorld()->GetMap()->GetTriggers(); Raven_Map::TriggerSystem::TriggerList::const_iterator it; for (it = triggers.begin(); it != triggers.end(); ++it) { if ( ((*it)->EntityType() == GiverType) && (*it)->isActive()) { double cost = m_pOwner->GetWorld()->GetMap()->CalculateCostToTravelBetweenNodes(nd, (*it)->GraphNodeIndex()); if (cost < ClosestSoFar) { ClosestSoFar = cost; } } } //return a negative value if no active trigger of the type found if (isEqual(ClosestSoFar, MaxDouble)) { return -1; } return ClosestSoFar; }
//----------------------------- GetPath ------------------------------------ // // called by an agent after it has been notified that a search has terminated // successfully. The method extracts the path from m_pCurrentSearch, adds // additional edges appropriate to the search type and returns it as a list of // PathEdges. //----------------------------------------------------------------------------- Raven_PathPlanner::Path Raven_PathPlanner::GetPath() { assert (m_pCurrentSearch && "<Raven_PathPlanner::GetPathAsNodes>: no current search"); Path path = m_pCurrentSearch->GetPathAsPathEdges(); int closest = GetClosestNodeToPosition(m_pOwner->Pos()); path.push_front(PathEdge(m_pOwner->Pos(), GetNodePosition(closest), NavGraphEdge::normal)); //if the bot requested a path to a location then an edge leading to the //destination must be added if (m_pCurrentSearch->GetType() == Graph_SearchTimeSliced<EdgeType>::AStar) { path.push_back(PathEdge(path.back().Destination(), m_vDestinationPos, NavGraphEdge::normal)); } //smooth paths if required if (UserOptions->m_bSmoothPathsQuick) { SmoothPathEdgesQuick(path); } if (UserOptions->m_bSmoothPathsPrecise) { SmoothPathEdgesPrecise(path); } return path; }
//--------------------------- RequestPathToPosition ------------------------------ // // Given a target, this method first determines if nodes can be reached from // the bot's current position and the target position. If either end point // is unreachable the method returns false. // // If nodes are reachable from both positions then an instance of the time- // sliced A* search is created and registered with the search manager. the // method then returns true. // //----------------------------------------------------------------------------- bool CActor_PathPlanner::RequestPathToPosition( Vector2D TargetPos ) { #ifdef SHOW_NAVINFO debug_con << "------------------------------------------------" << ""; #endif GetReadyForNewSearch(); //make a note of the target position. m_vDestinationPos = TargetPos; //find the closest visible node to the bots position int ClosestNodeToBot = GetClosestNodeToPosition( m_pOwner->Pos() ); //remove the destination node from the list and return false if no visible //node found. This will occur if the navgraph is badly designed or if the bot //has managed to get itself *inside* the geometry (surrounded by walls), //or an obstacle. if ( ClosestNodeToBot == no_closest_node_found ) { #ifdef SHOW_NAVINFO debug_con << "No closest node to bot found!" << ""; #endif return false; } #ifdef SHOW_NAVINFO debug_con << "Closest node to bot is " << ClosestNodeToBot << ""; #endif //find the closest visible node to the target position int ClosestNodeToTarget = GetClosestNodeToPosition( TargetPos ); //return false if there is a problem locating a visible node from the target. //This sort of thing occurs much more frequently than the above. For //example, if the user clicks inside an area bounded by walls or inside an //object. if ( ClosestNodeToTarget == no_closest_node_found ) { #ifdef SHOW_NAVINFO debug_con << "No closest node to target (" << ClosestNodeToTarget << ") found!" << ""; #endif return false; } #ifdef SHOW_NAVINFO debug_con << "Closest node to target is " << ClosestNodeToTarget << ""; #endif //create an instance of a the distributed A* search class typedef Graph_SearchAStar_TS < PlayModel::NavGraph, Heuristic_Euclid > AStar; m_pCurrentSearch = new AStar( m_NavGraph, ClosestNodeToBot, ClosestNodeToTarget, static_cast < ModifierGoalBase* >( m_pOwner->GetModifierGoal() ) ); // NULL? //TODO Modificador objetivos... static_cast < ModifierGoalBase* > ( m_pOwner->GetModifierGoal() ) ); //and register the search with the path manager m_pOwner->World()->GetPathManager()->Register( this ); return true; }
//--------------------------- RequestPathToPosition ------------------------------ // // Given a target, this method first determines if nodes can be reached from // the bot's current position and the target position. If either end point // is unreachable the method returns false. // // If nodes are reachable from both positions then an instance of the time- // sliced A* search is created and registered with the search manager. the // method then returns true. // //----------------------------------------------------------------------------- bool Raven_PathPlanner::RequestPathToPosition(Vector2D TargetPos) { #ifdef SHOW_NAVINFO debug_con << "------------------------------------------------" << ""; #endif GetReadyForNewSearch(); //make a note of the target position. m_vDestinationPos = TargetPos; //if the target is walkable from the bot's position a path does not need to //be calculated, the bot can go straight to the position by ARRIVING at //the current waypoint if (m_pOwner->canWalkTo(TargetPos)) { return true; } //find the closest visible node to the bots position int ClosestNodeToBot = GetClosestNodeToPosition(m_pOwner->Pos()); //remove the destination node from the list and return false if no visible //node found. This will occur if the navgraph is badly designed or if the bot //has managed to get itself *inside* the geometry (surrounded by walls), //or an obstacle. if (ClosestNodeToBot == no_closest_node_found) { #ifdef SHOW_NAVINFO debug_con << "No closest node to bot found!" << ""; #endif return false; } #ifdef SHOW_NAVINFO debug_con << "Closest node to bot is " << ClosestNodeToBot << ""; #endif //find the closest visible node to the target position int ClosestNodeToTarget = GetClosestNodeToPosition(TargetPos); //return false if there is a problem locating a visible node from the target. //This sort of thing occurs much more frequently than the above. For //example, if the user clicks inside an area bounded by walls or inside an //object. if (ClosestNodeToTarget == no_closest_node_found) { #ifdef SHOW_NAVINFO debug_con << "No closest node to target (" << ClosestNodeToTarget << ") found!" << ""; #endif return false; } #ifdef SHOW_NAVINFO debug_con << "Closest node to target is " << ClosestNodeToTarget << ""; #endif //create an instance of a the distributed A* search class typedef Graph_SearchAStar_TS<Raven_Map::NavGraph, Heuristic_Euclid> AStar; m_pCurrentSearch = new AStar(m_NavGraph, ClosestNodeToBot, ClosestNodeToTarget); //and register the search with the path manager m_pOwner->GetWorld()->GetPathManager()->Register(this); return true; }
bool PathPlanner::CreatePathToPosition(vec2 TargetPos, std::list<vec2> &path) { //Flush any current nodes in the path path.clear(); //Make a note of the target position vDestPos = TargetPos; //If the target is unobstructed from the bot's pos, a path does not need to //be calculated, and the bot can ARRIVE directly at the destination. //isPathObstructed is a method that takes a start position, a target position, //and an entity radius and determines if an agent of that size is able //to move unobstructed between the two positions. It is used here to determine //if the bot can move directly to the target location without the need //for planning a path. //mEnt->fRadius is broken, using hard value of 4.099 (from enemy npc radius) /*if (!isPathObstructed(pEnt->pos, vDestPos, 4.099)) { path.push_back(vDestPos); return true; }*/ //Find the closest unobstructed node to the bot's position //GetClosestNodeToPosition is a method that queries the nav graph nodes (NO //NAV GRAPH ATM) nodes to determine the closest unobstructed node to the given //position vector. It is used here to find the closest unobstructed node //to the bot's current location. int ClosestNodeToBot = GetClosestNodeToPosition(pEnt->pos); //If no visible node found return failure. if (ClosestNodeToBot == no_closest_node_found) { return false; } //Find the closest visible unobstructed node to the target position int ClosestNodeToTarget = GetClosestNodeToPosition(vDestPos); if (ClosestNodeToTarget == no_closest_node_found) { return false; } //Create an instance of the A* search class to search for a path between //the closest node to the bot and the closest node to the target position. //This A* search will utilize the Euclidean straight heuristic AStar astar(*pWorldInfo, ClosestNodeToBot, ClosestNodeToTarget); path = astar.GetPathToTarget(); //Convert to indices to vectors /*if (!pathIndices.empty()){ for (std::list<int>::const_iterator nodeIndex = pathIndices.begin(), end = pathIndices.end(); nodeIndex != end; ++nodeIndex) { path.push_back(astar.INDEX_NODE_POINTERS[(*nodeIndex)]->vPos); } path.push_back(TargetPos); } else { return false; }*/ path.push_back(vDestPos); return true; }