diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index 6f0739ca..a1edab48 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -1093,98 +1093,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout const bool tryJPSPathfinder = false; - while(nodeLimitReached == false) { - whileLoopCount++; - - //b1) is open nodes is empty => failed to find the path - if(factions[unitFactionIndex].openNodesList.empty() == true) { - //printf("$$$$ Path for Unit [%d - %s] inBailout = %d BLOCKED\n",unit->getId(),unit->getFullName().c_str(),inBailout); - //printf("Path blocked\n"); - pathFound= false; - break; - } - - //b2) get the minimum heuristic node - //Nodes::iterator it = minHeuristic(); - node = minHeuristicFastLookup(factions[unitFactionIndex]); - //printf("current node [%s]\n",node->pos.getString().c_str()); - - //b3) if minHeuristic is the finalNode, or the path is no more explored => path was found - if(node->pos == finalPos || node->exploredCell == false) { - //printf("Path found\n"); - pathFound= true; - break; - } - - if(tryJPSPathfinder == true) { - closedNodes[node->pos]=true; - } - - //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[unitFactionIndex].nodePoolCount,inBailout); - - //b4) move this node from closedNodes to openNodes - //add all succesors that are not in closedNodes or openNodes to openNodes - if(factions[unitFactionIndex].closedNodesList.find(node->heuristic) == - factions[unitFactionIndex].closedNodesList.end()) { - factions[unitFactionIndex].closedNodesList[node->heuristic].clear(); - } - factions[unitFactionIndex].closedNodesList[node->heuristic].push_back(node); - factions[unitFactionIndex].openPosList[node->pos] = true; - - if(tryJPSPathfinder == true) { - astarJPS(cameFrom, node,finalPos, closedNodes,canAddNode, unit, - nodeLimitReached, maxNodeCount); - } - else { - int failureCount = 0; - int cellCount = 0; - - int tryDirection = factions[unitFactionIndex].random.randRange(0,3); - if(tryDirection == 3) { - for(int i = 1; i >= -1 && nodeLimitReached == false; --i) { - for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) { - if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) { - failureCount++; - } - cellCount++; - } - } - } - else if(tryDirection == 2) { - for(int i = -1; i <= 1 && nodeLimitReached == false; ++i) { - for(int j = 1; j >= -1 && nodeLimitReached == false; --j) { - if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) { - failureCount++; - } - - cellCount++; - } - } - } - else if(tryDirection == 1) { - for(int i = -1; i <= 1 && nodeLimitReached == false; ++i) { - for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) { - if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) { - failureCount++; - } - - cellCount++; - } - } - } - else { - for(int i = 1; i >= -1 && nodeLimitReached == false; --i) { - for(int j = 1; j >= -1 && nodeLimitReached == false; --j) { - if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) { - failureCount++; - } - - cellCount++; - } - } - } - } - } //while + doAStarPathSearch(nodeLimitReached, whileLoopCount, unitFactionIndex, + pathFound, node, finalPos, tryJPSPathfinder, + closedNodes, cameFrom, canAddNode, unit, maxNodeCount); // Now see if the unit is eligble for pathfind max nodes boost? if(nodeLimitReached == true && maxNodeCount != pathFindNodesAbsoluteMax) { diff --git a/source/glest_game/ai/path_finder.h b/source/glest_game/ai/path_finder.h index 23bc4631..29b530ef 100644 --- a/source/glest_game/ai/path_finder.h +++ b/source/glest_game/ai/path_finder.h @@ -303,6 +303,87 @@ private: return result; } + inline void doAStarPathSearch(bool & nodeLimitReached, int & whileLoopCount, + int & unitFactionIndex, bool & pathFound, Node *& node, const Vec2i & finalPos, + const bool tryJPSPathfinder, std::map closedNodes, + std::map cameFrom, std::map , + bool> canAddNode, Unit *& unit, int & maxNodeCount) { + while(nodeLimitReached == false) { + whileLoopCount++; + if(factions[unitFactionIndex].openNodesList.empty() == true) { + pathFound = false; + break; + } + node = minHeuristicFastLookup(factions[unitFactionIndex]); + if(node->pos == finalPos || node->exploredCell == false) { + pathFound = true; + break; + } + if(tryJPSPathfinder == true) { + closedNodes[node->pos] = true; + } + if(factions[unitFactionIndex].closedNodesList.find(node->heuristic) == factions[unitFactionIndex].closedNodesList.end()) { + factions[unitFactionIndex].closedNodesList[node->heuristic].clear(); + } + factions[unitFactionIndex].closedNodesList[node->heuristic].push_back(node); + factions[unitFactionIndex].openPosList[node->pos] = true; + if(tryJPSPathfinder == true) { + astarJPS(cameFrom, node, finalPos, closedNodes, canAddNode, unit, nodeLimitReached, maxNodeCount); + } + else { + int failureCount = 0; + int cellCount = 0; + int tryDirection = factions[unitFactionIndex].random.randRange(0, 3); + if(tryDirection == 3){ + for(int i = 1;i >= -1 && nodeLimitReached == false;--i){ + for(int j = -1;j <= 1 && nodeLimitReached == false;++j){ + if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ + failureCount++; + } + cellCount++; + } + + } + + } + else if(tryDirection == 2) { + for(int i = -1;i <= 1 && nodeLimitReached == false;++i){ + for(int j = 1;j >= -1 && nodeLimitReached == false;--j){ + if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ + failureCount++; + } + cellCount++; + } + + } + + } + else if(tryDirection == 1) { + for(int i = -1;i <= 1 && nodeLimitReached == false;++i){ + for(int j = -1;j <= 1 && nodeLimitReached == false;++j){ + if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ + failureCount++; + } + cellCount++; + } + + } + + } + else{ + for(int i = 1;i >= -1 && nodeLimitReached == false;--i){ + for(int j = 1;j >= -1 && nodeLimitReached == false;--j){ + if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ + failureCount++; + } + cellCount++; + } + } + } + } + } + } + }; }}//end namespace diff --git a/source/glest_game/type_instances/command.h b/source/glest_game/type_instances/command.h index f525ee57..c0a5a6af 100644 --- a/source/glest_game/type_instances/command.h +++ b/source/glest_game/type_instances/command.h @@ -62,12 +62,12 @@ public: Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitType, CardinalDir facing); //get - const CommandType *getCommandType() const {return commandType;} - Vec2i getPos() const {return pos;} - Vec2i getOriginalPos() const {return originalPos;} - Unit* getUnit() const {return unitRef.getUnit();} - const UnitType* getUnitType() const {return unitType;} - CardinalDir getFacing() const {return facing;} + inline const CommandType *getCommandType() const {return commandType;} + inline Vec2i getPos() const {return pos;} + inline Vec2i getOriginalPos() const {return originalPos;} + inline Unit* getUnit() const {return unitRef.getUnit();} + inline const UnitType* getUnitType() const {return unitType;} + inline CardinalDir getFacing() const {return facing;} //Priority: commands of higher priority will cancel commands of lower priority virtual int getPriority(); @@ -80,15 +80,14 @@ public: void setUnit(Unit *unit); - void setStateType(CommandStateType value) { stateType = value; } - CommandStateType getStateType() const { return stateType; } + inline void setStateType(CommandStateType value) { stateType = value; } + inline CommandStateType getStateType() const { return stateType; } - void setStateValue(int value) { stateValue = value; } - int getStateValue() const { return stateValue; } + inline void setStateValue(int value) { stateValue = value; } + inline int getStateValue() const { return stateValue; } - - void setUnitCommandGroupId(int value) { unitCommandGroupId = value; } - int getUnitCommandGroupId() const { return unitCommandGroupId; } + inline void setUnitCommandGroupId(int value) { unitCommandGroupId = value; } + inline int getUnitCommandGroupId() const { return unitCommandGroupId; } std::string toString() const; diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index da13f968..b4eb4919 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -497,16 +497,6 @@ bool Faction::canUnitsPathfind() { return result; } -Unit * Faction::getUnit(int i) const { - Unit *result = units[i]; - return result; -} - -int Faction::getUnitCount() const { - int result = units.size(); - return result; -} - void Faction::signalWorkerThread(int frameIndex) { if(workerThread != NULL) { workerThread->signalPathfinder(frameIndex); diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 9920ce12..bad40285 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -210,9 +210,15 @@ public: void setPersonalityType(FactionPersonalityType pType) { overridePersonalityType=pType; } int getAIBehaviorStaticOverideValue(AIBehaviorStaticValueCategory type) const; - Unit *getUnit(int i) const; - int getUnitCount() const; - Mutex * getUnitMutex() {return unitsMutex;} + inline Unit *getUnit(int i) const { + Unit *result = units[i]; + return result; + } + inline int getUnitCount() const { + int result = units.size(); + return result; + } + inline Mutex * getUnitMutex() {return unitsMutex;} inline const UpgradeManager *getUpgradeManager() const {return &upgradeManager;} inline const Texture2D *getTexture() const {return texture;} diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index dcbdea3e..c22317df 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -10,7 +10,7 @@ // ============================================================== #define NOMINMAX -#include "faction.h" + #include #include "unit.h" #include "unit_particle_type.h" @@ -593,14 +593,6 @@ void Unit::setModelFacing(CardinalDir value) { // ====================================== get ====================================== -int Unit::getFactionIndex() const{ - return faction->getIndex(); -} - -int Unit::getTeam() const{ - return faction->getTeam(); -} - Vec2i Unit::getCenteredPos() const { if(type == NULL) { char szBuf[4096]=""; @@ -1266,14 +1258,6 @@ Command *Unit::getCurrrentCommandThreadSafe() { return NULL; } -//return current command, assert that there is always one command -Command *Unit::getCurrCommand() const { - if(commands.empty() == false) { - return commands.front(); - } - return NULL; -} - void Unit::replaceCurrCommand(Command *cmd) { static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); @@ -3309,35 +3293,6 @@ void Unit::removeBadHarvestPos(const Vec2i &value) { cleanupOldBadHarvestPos(); } -bool Unit::isBadHarvestPos(const Vec2i &value, bool checkPeerUnits) const { - bool result = false; - if(badHarvestPosList.empty() == true) { - return result; - } - - std::map::const_iterator iter = badHarvestPosList.find(value); - if(iter != badHarvestPosList.end()) { - result = true; - } - else if(checkPeerUnits == true) { - // Check if any other units of similar type have this position tagged - // as bad? - for(int i = 0; i < this->getFaction()->getUnitCount(); ++i) { - Unit *peerUnit = this->getFaction()->getUnit(i); - if( peerUnit != NULL && peerUnit->getId() != this->getId() && - peerUnit->getType()->hasCommandClass(ccHarvest) == true && - peerUnit->getType()->getSize() <= this->getType()->getSize()) { - if(peerUnit->isBadHarvestPos(value,false) == true) { - result = true; - break; - } - } - } - } - - return result; -} - void Unit::cleanupOldBadHarvestPos() { const int cleanupInterval = (GameConstants::updateFps * 5); bool needToCleanup = (getFrameCount() % cleanupInterval == 0); diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 4a6b1bfc..5587331b 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -23,6 +23,7 @@ #include "game_constants.h" #include "platform_common.h" #include +#include "faction.h" #include "leak_dumper.h" //#define LEAK_CHECK_UNITS @@ -40,7 +41,7 @@ using Shared::PlatformCommon::Chrono; using Shared::PlatformCommon::ValueCheckerVault; class Map; -class Faction; +//class Faction; class Unit; class Command; class SkillType; @@ -459,8 +460,12 @@ public: inline float getAnimProgress() const {return animProgress;} inline float getHightlight() const {return highlight;} inline int getProgress2() const {return progress2;} - int getFactionIndex() const; - int getTeam() const; + inline int getFactionIndex() const { + return faction->getIndex(); + } + inline int getTeam() const { + return faction->getTeam(); + } inline int getHp() const {return hp;} inline int getEp() const {return ep;} int getProductionPercent() const; @@ -544,7 +549,12 @@ public: //command related bool anyCommand(bool validateCommandtype=false) const; - Command *getCurrCommand() const; + inline Command *getCurrCommand() const { + if(commands.empty() == false) { + return commands.front(); + } + return NULL; + } void replaceCurrCommand(Command *cmd); int getCountOfProducedUnits(const UnitType *ut) const; unsigned int getCommandSize() const; @@ -612,7 +622,34 @@ public: //void setBadHarvestPosList(std::vector > value) { badHarvestPosList = value; } void addBadHarvestPos(const Vec2i &value); void removeBadHarvestPos(const Vec2i &value); - bool isBadHarvestPos(const Vec2i &value,bool checkPeerUnits=true) const; + inline bool isBadHarvestPos(const Vec2i &value,bool checkPeerUnits=true) const { + bool result = false; + if(badHarvestPosList.empty() == true) { + return result; + } + + std::map::const_iterator iter = badHarvestPosList.find(value); + if(iter != badHarvestPosList.end()) { + result = true; + } + else if(checkPeerUnits == true) { + // Check if any other units of similar type have this position tagged + // as bad? + for(int i = 0; i < this->getFaction()->getUnitCount(); ++i) { + Unit *peerUnit = this->getFaction()->getUnit(i); + if( peerUnit != NULL && peerUnit->getId() != this->getId() && + peerUnit->getType()->hasCommandClass(ccHarvest) == true && + peerUnit->getType()->getSize() <= this->getType()->getSize()) { + if(peerUnit->isBadHarvestPos(value,false) == true) { + result = true; + break; + } + } + } + } + + return result; + } void cleanupOldBadHarvestPos(); void setLastHarvestResourceTarget(const Vec2i *pos); diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index 10d216f7..a9463015 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -888,10 +888,6 @@ bool UnitType::hasCommandType(const CommandType *commandType) const { return false; } -bool UnitType::hasCommandClass(CommandClass commandClass) const { - return firstCommandTypeOfClass[commandClass]!=NULL; -} - bool UnitType::hasSkillType(const SkillType *skillType) const { assert(skillType!=NULL); for(int i=0; iisFreeOrMightBeFreeSoon(originPos,pos,field) && - (field==fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && - (field!=fLand || getDeepSubmerged(getCell(pos)) == false); -} - bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const { if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { if(unit->getCurrField() != field) { @@ -753,25 +744,6 @@ bool Map::isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const { return false; } -bool Map::isAproxFreeCellOrMightBeFreeSoon(Vec2i originPos,const Vec2i &pos, Field field, int teamIndex) const { - if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { - const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); - - if(sc->isVisible(teamIndex)) { - return isFreeCellOrMightBeFreeSoon(originPos, pos, field); - } - else if(sc->isExplored(teamIndex)) { - return field==fLand? sc->isFree() && !getDeepSubmerged(getCell(pos)): true; - } - else { - return true; - } - } - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; -} - bool Map::isFreeCells(const Vec2i & pos, int size, Field field) const { for(int i=pos.x; iisFreeOrMightBeFreeSoon(originPos,pos,field) && + (field==fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && + (field!=fLand || getDeepSubmerged(getCell(pos)) == false); + } + + inline bool isAproxFreeCellOrMightBeFreeSoon(Vec2i originPos,const Vec2i &pos, Field field, int teamIndex) const { + if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); + + if(sc->isVisible(teamIndex)) { + return isFreeCellOrMightBeFreeSoon(originPos, pos, field); + } + else if(sc->isExplored(teamIndex)) { + return field==fLand? sc->isFree() && !getDeepSubmerged(getCell(pos)): true; + } + else { + return true; + } + } + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } + bool aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const; string getMapFile() const { return mapFile; }