IPath::SearchResult CPathFinder::InitSearch(const MoveDef& moveDef, const CPathFinderDef& pfDef, const CSolidObject* owner, bool synced) { // If exact path is reqired and the goal is blocked, then no search is needed. if (exactPath && pfDef.GoalIsBlocked(moveDef, CMoveMath::BLOCK_STRUCTURE, owner)) return IPath::CantGetCloser; // Clamp the start position if (startxSqr >= gs->mapx) { startxSqr = gs->mapxm1; } if (startzSqr >= gs->mapy) { startzSqr = gs->mapym1; } const bool isStartGoal = pfDef.IsGoal(startxSqr, startzSqr); // although our starting square may be inside the goal radius, the starting coordinate may be outside. // in this case we do not want to return CantGetCloser, but instead a path to our starting square. if (isStartGoal && pfDef.startInGoalRadius) return IPath::CantGetCloser; // Clear the system from last search. ResetSearch(); // Marks and store the start-square. squareStates.nodeMask[mStartSquareIdx] = (PATHOPT_START | PATHOPT_OPEN); squareStates.fCost[mStartSquareIdx] = 0.0f; squareStates.gCost[mStartSquareIdx] = 0.0f; squareStates.SetMaxCost(NODE_COST_F, 0.0f); squareStates.SetMaxCost(NODE_COST_G, 0.0f); dirtySquares.push_back(mStartSquareIdx); // Make the beginning the fest square found. mGoalSquareIdx = mStartSquareIdx; mGoalHeuristic = pfDef.Heuristic(startxSqr, startzSqr); // Adding the start-square to the queue. openSquareBuffer.SetSize(0); PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize()); os->fCost = 0.0f; os->gCost = 0.0f; os->nodePos.x = startxSqr; os->nodePos.y = startzSqr; os->nodeNum = mStartSquareIdx; openSquares.push(os); // perform the search IPath::SearchResult result = DoSearch(moveDef, pfDef, owner, synced); // if no improvements are found, then return CantGetCloser instead if ((mGoalSquareIdx == mStartSquareIdx && (!isStartGoal || pfDef.startInGoalRadius)) || mGoalSquareIdx == 0) { return IPath::CantGetCloser; } return result; }
// set up the starting point of the search IPath::SearchResult CPathFinder::InitSearch(const MoveData& moveData, const CPathFinderDef& pfDef, int ownerId, bool synced) { // If exact path is reqired and the goal is blocked, then no search is needed. if (exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN))) return IPath::CantGetCloser; // Clamp the start position if (startxSqr < 0) { startxSqr = 0; } if (startxSqr >= gs->mapx) { startxSqr = gs->mapx - 1; } if (startzSqr < 0) { startzSqr = 0; } if (startzSqr >= gs->mapy) { startzSqr = gs->mapy - 1; } // If the starting position is a goal position, then no search need to be performed. if (pfDef.IsGoal(startxSqr, startzSqr)) return IPath::CantGetCloser; // Clear the system from last search. ResetSearch(); // Marks and store the start-square. squareStates[startSquare].nodeMask = (PATHOPT_START | PATHOPT_OPEN); squareStates[startSquare].fCost = 0.0f; squareStates[startSquare].gCost = 0.0f; squareStates.SetMaxFCost(0.0f); squareStates.SetMaxGCost(0.0f); dirtySquares.push_back(startSquare); // Make the beginning the fest square found. goalSquare = startSquare; goalHeuristic = pfDef.Heuristic(startxSqr, startzSqr); // Adding the start-square to the queue. openSquareBuffer.SetSize(0); PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize()); os->fCost = 0.0f; os->gCost = 0.0f; os->nodePos.x = startxSqr; os->nodePos.y = startzSqr; os->nodeNum = startSquare; openSquares.push(os); // perform the search IPath::SearchResult result = DoSearch(moveData, pfDef, ownerId, synced); // if no improvements are found, then return CantGetCloser instead if (goalSquare == startSquare || goalSquare == 0) { return IPath::CantGetCloser; } return result; }
/* Setting up the starting point of the search. */ IPath::SearchResult CPathFinder::InitSearch(const MoveData& moveData, const CPathFinderDef& pfDef) { //If exact path is reqired and the goal is blocked, then no search is needed. if(exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN))) return CantGetCloser; //Clamp the start position if (startxSqr < 0) startxSqr=0; if (startxSqr >= gs->mapx) startxSqr = gs->mapx-1; if (startzSqr < 0) startzSqr =0; if (startzSqr >= gs->mapy) startzSqr = gs->mapy-1; //If the starting position is a goal position, then no search need to be performed. if(pfDef.IsGoal(startxSqr, startzSqr)) return CantGetCloser; //Clearing the system from last search. ResetSearch(); //Marks and store the start-square. squareState[startSquare].status = (PATHOPT_START | PATHOPT_OPEN); squareState[startSquare].cost = 0; dirtySquares.push_back(startSquare); //Make the beginning the fest square found. goalSquare = startSquare; goalHeuristic = pfDef.Heuristic(startxSqr, startzSqr); //Adding the start-square to the queue. openSquareBufferPointer = &openSquareBuffer[0]; OpenSquare *os = openSquareBufferPointer; //Taking first OpenSquare in buffer. os->currentCost = 0; os->cost = 0; os->square.x = startxSqr; os->square.y = startzSqr; os->sqr = startSquare; openSquares.push(os); //Performs the search. SearchResult result = DoSearch(moveData, pfDef); //If no improvement has been found then return CantGetCloser instead. if(goalSquare == startSquare || goalSquare == 0) { return CantGetCloser; } else return result; }
/** * Search with several start positions */ IPath::SearchResult CPathFinder::GetPath( const MoveData& moveData, const std::vector<float3>& startPos, const CPathFinderDef& pfDef, IPath::Path& path, int ownerId, bool synced ) { // Clear the given path. path.path.clear(); path.squares.clear(); path.pathCost = PATHCOST_INFINITY; // Store som basic data. maxSquaresToBeSearched = MAX_SEARCHED_NODES_PF - 8U; testMobile = false; exactPath = true; needPath = true; // If exact path is reqired and the goal is blocked, then no search is needed. if (exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN))) return IPath::CantGetCloser; // If the starting position is a goal position, then no search need to be performed. if (pfDef.IsGoal(startxSqr, startzSqr)) return IPath::CantGetCloser; // Clearing the system from last search. ResetSearch(); openSquareBuffer.SetSize(0); for (std::vector<float3>::const_iterator si = startPos.begin(); si != startPos.end(); ++si) { start = *si; startxSqr = (int(start.x) / SQUARE_SIZE) | 1; startzSqr = (int(start.z) / SQUARE_SIZE) | 1; startSquare = startxSqr + startzSqr * gs->mapx; goalSquare = startSquare; squareStates[startSquare].nodeMask = (PATHOPT_START | PATHOPT_OPEN); squareStates[startSquare].fCost = 0.0f; squareStates[startSquare].gCost = 0.0f; dirtySquares.push_back(startSquare); if (openSquareBuffer.GetSize() >= MAX_SEARCHED_NODES_PF) { continue; } PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize()); os->fCost = 0.0f; os->gCost = 0.0f; os->nodePos.x = startxSqr; os->nodePos.y = startzSqr; os->nodeNum = startSquare; openSquareBuffer.SetSize(openSquareBuffer.GetSize() + 1); openSquares.push(os); } // note: DoSearch, not InitSearch IPath::SearchResult result = DoSearch(moveData, pfDef, ownerId, synced); // Respond to the success of the search. if (result == IPath::Ok) { FinishSearch(moveData, path); if (PATHDEBUG) { LogObject() << "Path found.\n"; LogObject() << "Nodes tested: " << testedNodes << "\n"; LogObject() << "Open squares: " << openSquareBuffer.GetSize() << "\n"; LogObject() << "Path nodes: " << path.path.size() << "\n"; LogObject() << "Path cost: " << path.pathCost << "\n"; } } else { if (PATHDEBUG) { LogObject() << "No path found!\n"; LogObject() << "Nodes tested: " << testedNodes << "\n"; LogObject() << "Open squares: " << openSquareBuffer.GetSize() << "\n"; } } return result; }
/* Search with several start positions */ IPath::SearchResult CPathFinder::GetPath(const MoveData& moveData, std::vector<float3> startPos, const CPathFinderDef& pfDef, Path& path) { //Clear the given path. path.path.clear(); path.pathCost = PATHCOST_INFINITY; //Store som basic data. maxNodesToBeSearched = MAX_SEARCHED_SQARES; testMobile=false; exactPath = true; needPath=true; //If exact path is reqired and the goal is blocked, then no search is needed. if(exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN))) return CantGetCloser; //If the starting position is a goal position, then no search need to be performed. if(pfDef.IsGoal(startxSqr, startzSqr)) return CantGetCloser; //Clearing the system from last search. ResetSearch(); openSquareBufferPointer = &openSquareBuffer[0]; for(std::vector<float3>::iterator si=startPos.begin(); si!=startPos.end(); ++si) { start = *si; startxSqr = (int(start.x) / SQUARE_SIZE)|1; startzSqr = (int(start.z) / SQUARE_SIZE)|1; startSquare = startxSqr + startzSqr * gs->mapx; squareState[startSquare].status = (PATHOPT_START | PATHOPT_OPEN); squareState[startSquare].cost = 0; dirtySquares.push_back(startSquare); goalSquare = startSquare; OpenSquare *os = ++openSquareBufferPointer; //Taking first OpenSquare in buffer. os->currentCost = 0; os->cost = 0; os->square.x = startxSqr; os->square.y = startzSqr; os->sqr = startSquare; openSquares.push(os); } //Performs the search. SearchResult result = DoSearch(moveData, pfDef); //Respond to the success of the search. if(result == Ok) { FinishSearch(moveData, path); if(PATHDEBUG) { *info << "Path found.\n"; *info << "Nodes tested: " << (int)testedNodes << "\n"; *info << "Open squares: " << (openSquareBufferPointer - openSquareBuffer) << "\n"; *info << "Path steps: " << (int)(path.path.size()) << "\n"; *info << "Path cost: " << path.pathCost << "\n"; } } else { if(PATHDEBUG) { *info << "Path not found!\n"; *info << "Nodes tested: " << (int)testedNodes << "\n"; *info << "Open squares: " << (openSquareBufferPointer - openSquareBuffer) << "\n"; } } return result; }