diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index f38a2141..4c4b6f18 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -159,7 +159,13 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu } } - + if(path->isStuck() == true && unit->getLastStuckPos() == finalPos && + unit->isLastStuckFrameWithinCurrentFrameTolerance() == true) { + + //printf("$$$$ Unit STILL BLOCKED for [%d - %s]\n",unit->getId(),unit->getFullName().c_str()); + return tsBlocked; + } + TravelState ts = tsImpossible; //route cache miss ts = aStar(unit, finalPos, false, frameIndex); @@ -174,6 +180,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu if( ts == tsBlocked && unit->getInBailOutAttempt() == false && path->isStuck() == true) { + //printf("$$$$ Unit START BAILOUT ATTEMPT for [%d - %s]\n",unit->getId(),unit->getFullName().c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { char szBuf[4096]=""; sprintf(szBuf,"[attempting to BAIL OUT] finalPos [%s] ts [%d]", @@ -205,6 +213,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu } if(canUnitMove) { + //printf("$$$$ Unit BAILOUT(1) ASTAR ATTEMPT for [%d - %s] newFinalPos = [%s]\n",unit->getId(),unit->getFullName().c_str(),newFinalPos.getString().c_str()); + ts= aStar(unit, newFinalPos, true, frameIndex); } } @@ -224,6 +234,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu } if(canUnitMove) { + //printf("$$$$ Unit BAILOUT(1) ASTAR ATTEMPT for [%d - %s] newFinalPos = [%s]\n",unit->getId(),unit->getFullName().c_str(),newFinalPos.getString().c_str()); ts= aStar(unit, newFinalPos, true, frameIndex); } } @@ -231,6 +242,13 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu } } unit->setInBailOutAttempt(false); + + //printf("$$$$ Unit END BAILOUT ATTEMPT for [%d - %s] ts = %d\n",unit->getId(),unit->getFullName().c_str(),ts); + + if(ts == tsBlocked) { + unit->setLastStuckFrameToCurrentFrame(); + unit->setLastStuckPos(finalPos); + } } if(ts == tsArrived || ts == tsBlocked) { if(frameIndex < 0) { @@ -294,7 +312,7 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, bool result = false; Vec2i sucPos= node->pos + Vec2i(i, j); bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos); - if(openPos(sucPos, factions[unit->getFactionIndex()]) == false && canUnitMoveToCell == true) { + if(canUnitMoveToCell == true && openPos(sucPos, factions[unit->getFactionIndex()]) == false) { //if node is not open and canMove then generate another node Node *sucNode= newNode(factions[unit->getFactionIndex()]); if(sucNode != NULL) { @@ -631,13 +649,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout // // START - // Do the a-start base pathfind work if required + // Do the a-star base pathfind work if required int whileLoopCount = 0; while(nodeLimitReached == false) { whileLoopCount++; //b1) is open nodes is empty => failed to find the path if(factions[unit->getFactionIndex()].openNodesList.empty() == true) { + //printf("$$$$ Path for Unit [%d - %s] inBailout = %d BLOCKED\n",unit->getId(),unit->getFullName().c_str(),inBailout); pathFound= false; break; } @@ -652,6 +671,8 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout break; } + //printf("$$$$ Path for Unit [%d - %s] node [%s] whileLoopCount = %d nodePoolCount = %d inBailout = %d\n",unit->getId(),unit->getFullName().c_str(), node->pos.getString().c_str(), whileLoopCount,factions[unit->getFactionIndex()].nodePoolCount,inBailout); + //b4) move this node from closedNodes to openNodes //add all succesors that are not in closedNodes or openNodes to openNodes if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) { @@ -848,6 +869,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout else { if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 5) printf("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts); } + + //printf("$$$$ Path for Unit [%d - %s] return value = %d inBailout = %d\n",unit->getId(),unit->getFullName().c_str(),ts,inBailout); + return ts; } diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 284602a7..9df32b31 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -197,6 +197,8 @@ Game *Unit::game = NULL; Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) { modelFacing = CardinalDir::NORTH; + lastStuckFrame = 0; + lastStuckPos = Vec2i(0,0); RandomGen random; if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { @@ -1872,7 +1874,7 @@ bool Unit::isMeetingPointSettable() const { return (type != NULL ? type->getMeetingPoint() : false); } -int Unit::getFrameCount() { +int Unit::getFrameCount() const { int frameCount = 0; const Game *game = Renderer::getInstance().getGame(); if(game != NULL && game->getWorld() != NULL) { @@ -2066,6 +2068,15 @@ void Unit::setLastHarvestResourceTarget(const Vec2i *pos) { // currentTargetPathTaken.second.push_back(cell); //} +void Unit::setLastStuckFrameToCurrentFrame() { + lastStuckFrame = getFrameCount(); +} + +bool Unit::isLastStuckFrameWithinCurrentFrameTolerance() const { + bool result (getFrameCount() - lastStuckFrame <= 300); + return result; +} + std::string Unit::toString() const { std::string result = ""; diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index ad934a7a..b2c3299a 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -332,6 +332,9 @@ private: bool ignoreCheckCommand; + uint32 lastStuckFrame; + Vec2i lastStuckPos; + public: Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); ~Unit(); @@ -496,6 +499,14 @@ public: std::string toString() const; bool needToUpdate(); + bool isLastStuckFrameWithinCurrentFrameTolerance() const; + uint32 getLastStuckFrame() const { return lastStuckFrame; } + void setLastStuckFrame(uint32 value) { lastStuckFrame = value; } + void setLastStuckFrameToCurrentFrame(); + + Vec2i getLastStuckPos() const { return lastStuckPos; } + void setLastStuckPos(Vec2i pos) { lastStuckPos = pos; } + private: float computeHeight(const Vec2i &pos) const; void updateTarget(); @@ -505,7 +516,7 @@ private: void stopDamageParticles(); void startDamageParticles(); - int getFrameCount(); + int getFrameCount() const; }; }}// end namespace