diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index fd603e76..161f3a8b 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -220,17 +220,23 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu int unitFactionIndex = unit->getFactionIndex(); + bool minorDebugPathfinderPerformance = false; + Chrono chrono; + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + if(minorDebugPathfinderPerformance) chrono.start(); + + uint32 searched_node_count = 0; minorDebugPathfinder = false; bool enableFastPathfinder = Config::getInstance().getBool("EnableFastPathFinder","false"); if(enableFastPathfinder == true) { if(minorDebugPathfinder) printf("Fast Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getPos().getString().c_str(),finalPos.getString().c_str(),frameIndex); - ts = aStarFast(unit, finalPos, false, frameIndex, maxNodeCount); + ts = aStarFast(unit, finalPos, false, frameIndex, maxNodeCount,&searched_node_count); } else { if(minorDebugPathfinder) printf("Legacy Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getPos().getString().c_str(),finalPos.getString().c_str(),frameIndex); - ts = aStar(unit, finalPos, false, frameIndex, maxNodeCount); + ts = aStar(unit, finalPos, false, frameIndex, maxNodeCount,&searched_node_count); } //post actions @@ -309,10 +315,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu int maxBailoutNodeCount = (PathFinder::pathFindBailoutRadius * 2); if(enableFastPathfinder == true) { - ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount); + ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count); } else { - ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount); + ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count); } } } @@ -336,10 +342,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu int maxBailoutNodeCount = (PathFinder::pathFindBailoutRadius * 2); if(enableFastPathfinder == true) { - ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount); + ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count); } else { - ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount); + ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count); } } } @@ -387,6 +393,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu if(frameIndex < 0) { unit->setCurrSkill(scStop); } + + if(minorDebugPathfinderPerformance && chrono.getMillis() >= 1) printf("Unit [%d - %s] astar #2 took [%lld] msecs, ts = %d searched_node_count = %d.\n",unit->getId(),unit->getType()->getName().c_str(),(long long int)chrono.getMillis(),ts,searched_node_count); return tsBlocked; } } @@ -405,6 +413,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu } if(minorDebugPathfinder) printf("Pathfind Unit [%d - %s] INT BAILOUT ATTEMPT BLOCKED frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),frameIndex); + + if(minorDebugPathfinderPerformance && chrono.getMillis() >= 1) printf("Unit [%d - %s] astar #3 took [%lld] msecs, ts = %d searched_node_count = %d.\n",unit->getId(),unit->getType()->getName().c_str(),(long long int)chrono.getMillis(),ts,searched_node_count); return tsBlocked; } } @@ -414,12 +424,16 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu } break; } + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() >= 1) printf("In [%s::%s Line: %d] fastastar took [%lld] msecs, ts = %d nodeSearchCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts,nodeSearchCount); + if(minorDebugPathfinderPerformance && chrono.getMillis() >= 1) printf("Unit [%d - %s] astar took [%lld] msecs, ts = %d searched_node_count = %d.\n",unit->getId(),unit->getType()->getName().c_str(),(long long int)chrono.getMillis(),ts,searched_node_count); + return ts; } // ==================== PRIVATE ==================== -TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount) { +TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount,uint32 *searched_node_count) { TravelState ts = tsImpossible; Chrono chrono; @@ -448,9 +462,6 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in clearUnitPrecache(unit); } -///////////////////////////////////// - - // check the pre-cache to see if we can re-use a cached path if(frameIndex < 0) { if(factions[unitFactionIndex].precachedTravelState.find(unit->getId()) != factions[unitFactionIndex].precachedTravelState.end()) { @@ -677,7 +688,6 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in //b) loop bool pathFound = true; bool nodeLimitReached = false; - Node *node = NULL; if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -738,20 +748,15 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in } // - // START - // Do the a-star base pathfind work if required - -/////////////////////////////////////// - - //finalPos= computeNearestFreePos(unit, finalPos); + FastAINodeCache nodeCache(unit); // Start of New Fast AStar FastAINode *fromNode = map->getCellNode(unit->getPos()); FastAINode *toNode = map->getCellNode(finalPos); //FastAstar *fa = createFastAstar(); FastAstar *fa = factions[unitFactionIndex].fa; - astarStartSearch(fa,fromNode,toNode, unit); + astarStartSearch(fa,fromNode,toNode, &nodeCache); pathFound = false; unsigned int nodeSearchCount=0; @@ -766,6 +771,9 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in solution = getSolution(fa,count); } + if(searched_node_count != NULL) { + *searched_node_count = nodeSearchCount; + } if(count <= 1 || getLastSearchState(fa) != SEARCH_STATE_SUCCEEDED) { if(minorDebugPathfinder) printf("Fast Pathfind Unit [%d - %s] NOT FOUND PATH frameIndex = %d nodeSearchCount = %d\n",unit->getId(),unit->getType()->getName().c_str(),frameIndex,nodeSearchCount); @@ -1265,7 +1273,7 @@ void PathFinder::astarJPS(std::map cameFrom, Node *& node, //route a unit using A* algorithm TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout, - int frameIndex, int maxNodeCount) { + int frameIndex, int maxNodeCount, uint32 *searched_node_count) { Chrono chrono; if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); @@ -1622,6 +1630,10 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout pathFound, node, finalPos, tryJPSPathfinder, closedNodes, cameFrom, canAddNode, unit, maxNodeCount,frameIndex); + if(searched_node_count != NULL) { + *searched_node_count = whileLoopCount; + } + // Now see if the unit is eligble for pathfind max nodes boost? if(nodeLimitReached == true) { unit->incrementPathfindFailedConsecutiveFrameCount(); diff --git a/source/glest_game/ai/path_finder.h b/source/glest_game/ai/path_finder.h index 1fa8efae..2f012939 100644 --- a/source/glest_game/ai/path_finder.h +++ b/source/glest_game/ai/path_finder.h @@ -170,8 +170,8 @@ public: void loadGame(const XmlNode *rootNode); private: - TravelState aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1); - TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1); + TravelState aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1,uint32 *searched_node_count=NULL); + TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1,uint32 *searched_node_count=NULL); //Node *newNode(FactionState &faction,int maxNodeCount); inline static Node *newNode(FactionState &faction, int maxNodeCount) { if( faction.nodePoolCount < faction.nodePool.size() && diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index bad40285..0def844f 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -151,10 +151,33 @@ private: TechTree *techTree; const XmlNode *loadWorldNode; + std::map > > mapSharedPathFinderCache; + public: Faction(); ~Faction(); + inline const bool * aproxCanMoveSoonCached(int size, Field field, const Vec2i &pos1, const Vec2i &pos2) const { + const bool *result = NULL; +// std::map > >::const_iterator iterFind1 = mapSharedPathFinderCache.find(size); +// if(iterFind1 != mapSharedPathFinderCache.end()) { +// std::map >::const_iterator iterFind2 = iterFind1->second.find(field); +// if(iterFind2 != iterFind1->second.end()) { +// std::map::const_iterator iterFind3 = iterFind2->second.find(pos2); +// if(iterFind3 != iterFind2->second.end()) { +// result = &iterFind3->second; +// } +// } +// } + return result; + } + inline void addAproxCanMoveSoonCached(int size, Field field, const Vec2i &pos1, const Vec2i &pos2,bool result) { + //mapSharedPathFinderCache[size][field][pos2]=result; + } + inline void clearAproxCanMoveSoonCached() { + //mapSharedPathFinderCache.clear(); + } + inline void addLivingUnits(int id) { livingUnits.insert(id); } inline void addLivingUnitsp(Unit *unit) { livingUnitsp.insert(unit); } diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index bdf41369..0655a714 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -857,10 +857,6 @@ bool Unit::isBuilt() const{ return (isBeingBuilt() == false); } -bool Unit::isPutrefacting() const{ - return deadCount!=0; -} - bool Unit::isAlly(const Unit *unit) const { if(unit == NULL) { char szBuf[4096]=""; diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index b60464d5..ab9a1ac6 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -530,7 +530,9 @@ public: bool isBeingBuilt() const; bool isBuilt() const; bool isAnimProgressBound() const; - bool isPutrefacting() const; + bool isPutrefacting() const { + return deadCount!=0; + } bool isAlly(const Unit *unit) const; bool isDamaged() const; bool isInteresting(InterestingUnitType iut) const; diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 33d61316..6cf6d501 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -307,13 +307,30 @@ FastAINode * FastAINode::getNodeForEdgeIndex(int index,void *userData) const { resultNode = map->getCellNode(pos.x-1,pos.y-1,false); break; } - if(resultNode != NULL) { - Unit *unit = (Unit *)userData; - if(resultNode->getPos() != unit->getCurrentPathFinderDesiredFinalPos()) { - if(map->aproxCanMoveSoon(unit, pos, resultNode->getPos()) == false) { + bool checkCellObjects = true; + if(checkCellObjects == true && resultNode != NULL) { + FastAINodeCache *nodeCache = (FastAINodeCache *)userData; + std::map >::const_iterator iterFind = nodeCache->cachedCanMoveSoonList.find(pos); + if(iterFind != nodeCache->cachedCanMoveSoonList.end() && + iterFind->second.find(resultNode->getPos()) != iterFind->second.end()) { + const std::map &mapCache2 = iterFind->second; + std::map::const_iterator iterFind2 = mapCache2.find(resultNode->getPos()); + + if(iterFind2->second == false) { resultNode = NULL; } } + else { + const Vec2i &nodePos = resultNode->getPos(); + + if(resultNode->getPos() != nodeCache->unit->getCurrentPathFinderDesiredFinalPos()) { + if(map->aproxCanMoveSoon(nodeCache->unit, pos, resultNode->getPos()) == false) { + resultNode = NULL; + } + } + + nodeCache->cachedCanMoveSoonList[pos][nodePos] = (resultNode != NULL); + } } return resultNode; @@ -323,7 +340,38 @@ float FastAINode::getDistance(const AI_Node *node,void *userData) { return pos.dist(dynamic_cast(node)->pos); } float FastAINode::getCost(void *userData) { - return 1.0f; + float result = 1.0f; +// bool checkCellObjects = true; +// if(checkCellObjects == true) { +// FastAINode *resultNode = map->getCellNode(pos,false); +// if(resultNode != NULL) { +// FastAINodeCache *nodeCache = (FastAINodeCache *)userData; +// std::map >::const_iterator iterFind = nodeCache->cachedCanMoveSoonList.find(pos); +// if(iterFind != nodeCache->cachedCanMoveSoonList.end() && +// iterFind->second.find(resultNode->getPos()) != iterFind->second.end()) { +// const std::map &mapCache2 = iterFind->second; +// std::map::const_iterator iterFind2 = mapCache2.find(resultNode->getPos()); +// +// if(iterFind2->second == false) { +// resultNode = NULL; +// result = 9999999; +// } +// } +// else { +// const Vec2i &nodePos = resultNode->getPos(); +// +// if(resultNode->getPos() != nodeCache->unit->getCurrentPathFinderDesiredFinalPos()) { +// if(map->aproxCanMoveSoon(nodeCache->unit, pos, resultNode->getPos()) == false) { +// resultNode = NULL; +// result = 9999999; +// } +// } +// +// nodeCache->cachedCanMoveSoonList[pos][nodePos] = (resultNode != NULL); +// } +// } +// } + return result; } unsigned int FastAINode::getEdgeCount(void *userData) const { @@ -1127,104 +1175,6 @@ bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, s return true; } -//checks if a unit can move from between 2 cells using only visible cells (for pathfinding) -bool Map::aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const { - if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false || - isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - - int size= unit->getType()->getSize(); - int teamIndex= unit->getTeam(); - Field field= unit->getCurrField(); - - //single cell units - if(size == 1) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),pos2, field, teamIndex) == false) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - if(pos1.x != pos2.x && pos1.y != pos2.y) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) { - - //Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field); - //Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject(); - - //printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1)); - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) { - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - } - - bool isBadHarvestPos = false; - if(unit != NULL) { - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; - } - } - } - - if(unit == NULL || isBadHarvestPos == true) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - - return true; - } - //multi cell units - else { - for(int i = pos2.x; i < pos2.x + size; ++i) { - for(int j = pos2.y; j < pos2.y + size; ++j) { - - Vec2i cellPos = Vec2i(i,j); - if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { - if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),cellPos, field, teamIndex) == false) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - } - } - else { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - } - } - - bool isBadHarvestPos = false; - if(unit != NULL) { - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; - } - } - } - - if(unit == NULL || isBadHarvestPos == true) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - - } - return true; -} Vec2i Map::computeRefPos(const Selection *selection) const { Vec2i total= Vec2i(0); diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index ad764d14..895c3941 100644 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -27,6 +27,7 @@ #include #include "unit_type.h" #include "fast_path_finder.h" +#include "command.h" #include "leak_dumper.h" @@ -193,6 +194,15 @@ public: /// Represents the game map (and loads it from a gbm file) // ===================================================== +class FastAINodeCache { +public: + FastAINodeCache(Unit *unit) { + this->unit = unit; + } + Unit *unit; + std::map > cachedCanMoveSoonList; +}; + class FastAINode : public AI_Node { protected: Vec2i pos; @@ -432,7 +442,118 @@ public: return false; } - bool aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const; + //checks if a unit can move from between 2 cells using only visible cells (for pathfinding) + inline bool aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const { + if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false || + isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) { + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } + + int size= unit->getType()->getSize(); + int teamIndex= unit->getTeam(); + Field field= unit->getCurrField(); + + const bool *cachedResult = unit->getFaction()->aproxCanMoveSoonCached(size,field,pos1,pos2); + if(cachedResult != NULL) { + return *cachedResult; + } + + //single cell units + if(size == 1) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),pos2, field, teamIndex) == false) { + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + if(pos1.x != pos2.x && pos1.y != pos2.y) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) { + + //Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field); + //Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject(); + + //printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1)); + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) { + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + } + + bool isBadHarvestPos = false; + if(unit != NULL) { + Command *command= unit->getCurrCommand(); + if(command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + } + + if(unit == NULL || isBadHarvestPos == true) { + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, true); + return true; + } + //multi cell units + else { + for(int i = pos2.x; i < pos2.x + size; ++i) { + for(int j = pos2.y; j < pos2.y + size; ++j) { + + Vec2i cellPos = Vec2i(i,j); + if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),cellPos, field, teamIndex) == false) { + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + } + } + else { + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + } + } + + bool isBadHarvestPos = false; + if(unit != NULL) { + Command *command= unit->getCurrCommand(); + if(command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + } + + if(unit == NULL || isBadHarvestPos == true) { + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); + return false; + } + + } + unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, true); + return true; + } string getMapFile() const { return mapFile; } diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 2b87dc83..c2b7479e 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -399,6 +399,7 @@ void World::updateAllFactionUnits() { throw megaglest_runtime_error("faction == NULL"); } faction->clearUnitsPathfinding(); + faction->clearAproxCanMoveSoonCached(); } // Signal the faction threads to do any pre-processing diff --git a/source/shared_lib/include/graphics/vec.h b/source/shared_lib/include/graphics/vec.h index eee7917f..d8835ea3 100644 --- a/source/shared_lib/include/graphics/vec.h +++ b/source/shared_lib/include/graphics/vec.h @@ -172,7 +172,7 @@ public: return x*v.x+y*v.y; } - float dist(const Vec2 &v) const{ + inline float dist(const Vec2 &v) const{ return Vec2(v-*this).length(); } @@ -392,7 +392,7 @@ public: return x*v.x + y*v.y + z*v.z; } - float dist(const Vec3 &v) const{ + inline float dist(const Vec3 &v) const{ return Vec3(v-*this).length(); }