IPath::SearchResult CPathFinder::GetPath( const MoveData& moveData, const float3& startPos, const CPathFinderDef& pfDef, IPath::Path& path, bool testMobile, bool exactPath, unsigned int maxNodes, bool needPath, int ownerId, bool synced ) { // Clear the given path. path.path.clear(); path.squares.clear(); path.pathCost = PATHCOST_INFINITY; // Store som basic data. maxSquaresToBeSearched = std::min(MAX_SEARCHED_NODES_PF - 8U, maxNodes); this->testMobile = testMobile; this->exactPath = exactPath; this->needPath = needPath; start = startPos; startxSqr = (int(start.x) / SQUARE_SIZE)|1; startzSqr = (int(start.z) / SQUARE_SIZE)|1; // Clamp the start position if (startxSqr < 0) startxSqr = 0; if (startxSqr >= gs->mapx) startxSqr = gs->mapxm1; if (startzSqr < 0) startzSqr = 0; if (startzSqr >= gs->mapy) startzSqr = gs->mapym1; startSquare = startxSqr + startzSqr * gs->mapx; // Start up the search. IPath::SearchResult result = InitSearch(moveData, pfDef, ownerId, synced); // Respond to the success of the search. if (result == IPath::Ok || result == IPath::GoalOutOfRange) { FinishSearch(moveData, path); if (LOG_IS_ENABLED(L_DEBUG)) { LOG_L(L_DEBUG, "Path found."); LOG_L(L_DEBUG, "Nodes tested: %u", testedNodes); LOG_L(L_DEBUG, "Open squares: %u", openSquareBuffer.GetSize()); LOG_L(L_DEBUG, "Path nodes: "_STPF_, path.path.size()); LOG_L(L_DEBUG, "Path cost: %f", path.pathCost); } } else { if (LOG_IS_ENABLED(L_DEBUG)) { LOG_L(L_DEBUG, "No path found!"); LOG_L(L_DEBUG, "Nodes tested: %u", testedNodes); LOG_L(L_DEBUG, "Open squares: %u", openSquareBuffer.GetSize()); } } return result; }
const CKeyBindings::ActionList& CKeyBindings::GetActionList(const CKeySet& ks) const { static const ActionList empty; const ActionList* alPtr = NULL; if (ks.AnyMod()) { KeyMap::const_iterator it = bindings.find(ks); if (it == bindings.end()) { alPtr = ∅ } else { alPtr = &(it->second); } } else { // have to check for an AnyMod keyset as well as the normal one CKeySet anyMod = ks; anyMod.SetAnyBit(); KeyMap::const_iterator nit = bindings.find(ks); KeyMap::const_iterator ait = bindings.find(anyMod); const bool haveNormal = (nit != bindings.end()); const bool haveAnyMod = (ait != bindings.end()); if (!haveNormal && !haveAnyMod) { alPtr = ∅ } else if (haveNormal && !haveAnyMod) { alPtr = &(nit->second); } else if (!haveNormal && haveAnyMod) { alPtr = &(ait->second); } else { // combine the two lists (normal first) static ActionList merged; merged = nit->second; const ActionList& aal = ait->second; for (int i = 0; i < (int)aal.size(); ++i) { merged.push_back(aal[i]); } alPtr = &merged; } } if (LOG_IS_ENABLED(L_DEBUG)) { const bool isEmpty = (alPtr == &empty); LOG_L(L_DEBUG, "GetAction: %s (0x%03X)%s", ks.GetString(false).c_str(), ks.Key(), (isEmpty ? " EMPTY" : "")); if (!isEmpty) { const ActionList& al = *alPtr; for (size_t i = 0; i < al.size(); ++i) { LOG_L(L_DEBUG, " %s \"%s\"", al[i].command.c_str(), al[i].rawline.c_str()); } } } return *alPtr; }
IPath::SearchResult IPathFinder::GetPath( const MoveDef& moveDef, const CPathFinderDef& pfDef, const CSolidObject* owner, float3 startPos, IPath::Path& path, const unsigned int maxNodes ) { startPos.ClampInBounds(); // Clear the path path.path.clear(); path.squares.clear(); path.pathCost = PATHCOST_INFINITY; // initial calculations if (isEstimator) { maxBlocksToBeSearched = std::min(MAX_SEARCHED_NODES_PE - 8U, maxNodes); } else { maxBlocksToBeSearched = std::min(MAX_SEARCHED_NODES_PF - 8U, maxNodes); } mStartBlock.x = startPos.x / BLOCK_PIXEL_SIZE; mStartBlock.y = startPos.z / BLOCK_PIXEL_SIZE; mStartBlockIdx = BlockPosToIdx(mStartBlock); assert((unsigned)mStartBlock.x < nbrOfBlocks.x && (unsigned)mStartBlock.y < nbrOfBlocks.y); // Check cache (when there is one) int2 goalBlock; goalBlock.x = pfDef.goalSquareX / BLOCK_SIZE; goalBlock.y = pfDef.goalSquareZ / BLOCK_SIZE; const CPathCache::CacheItem* ci = GetCache(mStartBlock, goalBlock, pfDef.sqGoalRadius, moveDef.pathType, pfDef.synced); if (ci != nullptr) { path = ci->path; return ci->result; } // Start up a new search IPath::SearchResult result = InitSearch(moveDef, pfDef, owner); // If search was successful, generate new path if (result == IPath::Ok || result == IPath::GoalOutOfRange) { FinishSearch(moveDef, pfDef, path); // Save to cache AddCache(&path, result, mStartBlock, goalBlock, pfDef.sqGoalRadius, moveDef.pathType, pfDef.synced); if (LOG_IS_ENABLED(L_DEBUG)) { LOG_L(L_DEBUG, "==== %s: Search completed ====", (isEstimator) ? "PE" : "PF"); LOG_L(L_DEBUG, "Tested blocks: %u", testedBlocks); LOG_L(L_DEBUG, "Open blocks: %u", openBlockBuffer.GetSize()); LOG_L(L_DEBUG, "Path length: " _STPF_, path.path.size()); LOG_L(L_DEBUG, "Path cost: %f", path.pathCost); LOG_L(L_DEBUG, "=============================="); } } else { if (LOG_IS_ENABLED(L_DEBUG)) { LOG_L(L_DEBUG, "==== %s: Search failed! ====", (isEstimator) ? "PE" : "PF"); LOG_L(L_DEBUG, "Tested blocks: %u", testedBlocks); LOG_L(L_DEBUG, "Open blocks: %u", openBlockBuffer.GetSize()); LOG_L(L_DEBUG, "============================"); } } return result; }