- initial attempt to enable pathfinder caching (think it might work now). Please test
This commit is contained in:
parent
53e8d96092
commit
16c7316887
|
@ -39,7 +39,7 @@ namespace Glest{ namespace Game{
|
|||
|
||||
const int PathFinder::maxFreeSearchRadius = 10;
|
||||
//const int PathFinder::pathFindNodesMax= 400;
|
||||
int PathFinder::pathFindNodesMax = 1000;
|
||||
int PathFinder::pathFindNodesMax = 1200;
|
||||
const int PathFinder::pathFindRefresh = 10;
|
||||
const int PathFinder::pathFindBailoutRadius = 20;
|
||||
|
||||
|
@ -59,6 +59,7 @@ PathFinder::PathFinder(const Map *map) {
|
|||
void PathFinder::init(const Map *map) {
|
||||
PathFinder::pathFindNodesMax = Config::getInstance().getInt("MaxPathfinderNodeCount",intToStr(PathFinder::pathFindNodesMax).c_str());
|
||||
nodePool.resize(pathFindNodesMax);
|
||||
useMaxNodeCount = PathFinder::pathFindNodesMax;
|
||||
this->map= map;
|
||||
}
|
||||
|
||||
|
@ -312,9 +313,9 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
// ==================== PRIVATE ====================
|
||||
|
||||
|
||||
void PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached) {
|
||||
bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached) {
|
||||
bool result = false;
|
||||
Vec2i sucPos= node->pos + Vec2i(i, j);
|
||||
|
||||
bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
|
||||
if(openPos(sucPos) == false && canUnitMoveToCell == true) {
|
||||
//if node is not open and canMove then generate another node
|
||||
|
@ -330,11 +331,14 @@ void PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
|
|||
}
|
||||
openNodesList[sucNode->heuristic].push_back(sucNode);
|
||||
openPosList[sucNode->pos] = true;
|
||||
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
nodeLimitReached= true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//route a unit using A* algorithm
|
||||
|
@ -355,118 +359,140 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
|||
const Vec2i unitPos = unit->getPos();
|
||||
const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
|
||||
|
||||
float dist= unitPos.dist(finalPos);
|
||||
|
||||
useMaxNodeCount = PathFinder::pathFindNodesMax;
|
||||
if(dist <= 10) {
|
||||
useMaxNodeCount = (int)dist * 20;
|
||||
if(useMaxNodeCount <= 0) {
|
||||
useMaxNodeCount = 200;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
UnitPathInterface *path= unit->getPath();
|
||||
// Check the previous path find cache for the unit to see if its good to
|
||||
// use
|
||||
const bool tryLastPathCache = Config::getInstance().getBool("EnablePathfinderCache","false");
|
||||
if(tryLastPathCache == true && path != NULL) {
|
||||
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
|
||||
if(basicPathFinder != NULL && basicPathFinder->getLastPathCacheQueueCount() > 0) {
|
||||
vector<Vec2i> cachedPath= basicPathFinder->getLastPathCacheQueue();
|
||||
for(int i = 0; i < cachedPath.size(); ++i) {
|
||||
Vec2i &pos1 = cachedPath[i];
|
||||
// Looking to find if the unit is in one of the cells in the cached path
|
||||
if(unitPos == pos1) {
|
||||
// Now see if we can re-use this path to get to the final destination
|
||||
for(int j = i+1; j < cachedPath.size(); ++j) {
|
||||
Vec2i &pos2 = cachedPath[j];
|
||||
bool canUnitMoveToCell = map->aproxCanMove(unit, pos1, pos2);
|
||||
if(canUnitMoveToCell == true) {
|
||||
if(pos2 == finalPos) {
|
||||
//on the way
|
||||
ts= tsMoving;
|
||||
const bool showConsoleDebugInfo = Config::getInstance().getBool("EnablePathfinderDistanceOutput","false");
|
||||
const bool tryLastPathCache = Config::getInstance().getBool("EnablePathfinderCache","true");
|
||||
if((showConsoleDebugInfo || tryLastPathCache) && dist > 60) {
|
||||
if(showConsoleDebugInfo) printf("Distance from [%d - %s] to destination is %.2f tryLastPathCache = %d\n",unit->getId(),unit->getFullName().c_str(), dist,tryLastPathCache);
|
||||
|
||||
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());
|
||||
if(tryLastPathCache == true && path != NULL) {
|
||||
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
|
||||
if(basicPathFinder != NULL && basicPathFinder->getLastPathCacheQueueCount() > 0) {
|
||||
vector<Vec2i> cachedPath= basicPathFinder->getLastPathCacheQueue();
|
||||
for(int i = 0; i < cachedPath.size(); ++i) {
|
||||
Vec2i &pos1 = cachedPath[i];
|
||||
// Looking to find if the unit is in one of the cells in the cached path
|
||||
if(unitPos == pos1) {
|
||||
// Now see if we can re-use this path to get to the final destination
|
||||
for(int j = i+1; j < cachedPath.size(); ++j) {
|
||||
Vec2i &pos2 = cachedPath[j];
|
||||
bool canUnitMoveToCell = map->aproxCanMove(unit, pos1, pos2);
|
||||
if(canUnitMoveToCell == true) {
|
||||
if(pos2 == finalPos) {
|
||||
//on the way
|
||||
ts= tsMoving;
|
||||
|
||||
//store path
|
||||
basicPathFinder->clear();
|
||||
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());
|
||||
|
||||
int pathCount=0;
|
||||
for(int k=i+1; k <= j; k++) {
|
||||
if(pathCount < pathFindRefresh) {
|
||||
basicPathFinder->add(cachedPath[k]);
|
||||
}
|
||||
basicPathFinder->addToLastPathCache(cachedPath[k]);
|
||||
pathCount++;
|
||||
}
|
||||
//store path
|
||||
basicPathFinder->clear();
|
||||
|
||||
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());
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||
char szBuf[4096]="";
|
||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%ld] openPosList.size() [%ld] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
||||
string commandDesc = "none";
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL && command->getCommandType() != NULL) {
|
||||
commandDesc = command->getCommandType()->toString();
|
||||
int pathCount=0;
|
||||
for(int k=i+1; k <= j; k++) {
|
||||
if(k >= cachedPath.size()) {
|
||||
throw runtime_error("k >= cachedPath.size() k = " + intToStr(k) + " cachedPath.size() = " + intToStr(cachedPath.size()));
|
||||
}
|
||||
if(pathCount < pathFindRefresh) {
|
||||
basicPathFinder->add(cachedPath[k]);
|
||||
}
|
||||
basicPathFinder->addToLastPathCache(cachedPath[k]);
|
||||
pathCount++;
|
||||
}
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d",commandDesc.c_str(),unit->getPos().getString().c_str(), targetPos.getString().c_str(),path->getQueueCount());
|
||||
unit->setCurrentUnitTitle(szBuf);
|
||||
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());
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||
char szBuf[4096]="";
|
||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%ld] openPosList.size() [%ld] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
||||
string commandDesc = "none";
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL && command->getCommandType() != NULL) {
|
||||
commandDesc = command->getCommandType()->toString();
|
||||
}
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d",commandDesc.c_str(),unit->getPos().getString().c_str(), targetPos.getString().c_str(),path->getQueueCount());
|
||||
unit->setCurrentUnitTitle(szBuf);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
return ts;
|
||||
//break;
|
||||
}
|
||||
else if(j - i > pathFindRefresh) {
|
||||
//on the way
|
||||
ts= tsMoving;
|
||||
|
||||
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());
|
||||
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());
|
||||
|
||||
return ts;
|
||||
//break;
|
||||
//store path
|
||||
basicPathFinder->clear();
|
||||
|
||||
int pathCount=0;
|
||||
for(int k=i+1; k < cachedPath.size(); k++) {
|
||||
if(k >= cachedPath.size()) {
|
||||
throw runtime_error("#2 k >= cachedPath.size() k = " + intToStr(k) + " cachedPath.size() = " + intToStr(cachedPath.size()));
|
||||
}
|
||||
|
||||
if(pathCount < pathFindRefresh) {
|
||||
basicPathFinder->add(cachedPath[k]);
|
||||
}
|
||||
basicPathFinder->addToLastPathCache(cachedPath[k]);
|
||||
pathCount++;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||
char szBuf[4096]="";
|
||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%ld] openPosList.size() [%ld] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
||||
string commandDesc = "none";
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL && command->getCommandType() != NULL) {
|
||||
commandDesc = command->getCommandType()->toString();
|
||||
}
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d",commandDesc.c_str(),unit->getPos().getString().c_str(), targetPos.getString().c_str(),path->getQueueCount());
|
||||
unit->setCurrentUnitTitle(szBuf);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
else if(j - i > pathFindRefresh) {
|
||||
//on the way
|
||||
ts= tsMoving;
|
||||
|
||||
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());
|
||||
|
||||
//store path
|
||||
basicPathFinder->clear();
|
||||
|
||||
int pathCount=0;
|
||||
for(int k=i+1; k <= cachedPath.size(); k++) {
|
||||
if(pathCount < pathFindRefresh) {
|
||||
basicPathFinder->add(cachedPath[k]);
|
||||
}
|
||||
basicPathFinder->addToLastPathCache(cachedPath[k]);
|
||||
pathCount++;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||
char szBuf[4096]="";
|
||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%ld] openPosList.size() [%ld] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
||||
string commandDesc = "none";
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL && command->getCommandType() != NULL) {
|
||||
commandDesc = command->getCommandType()->toString();
|
||||
}
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d",commandDesc.c_str(),unit->getPos().getString().c_str(), targetPos.getString().c_str(),path->getQueueCount());
|
||||
unit->setCurrentUnitTitle(szBuf);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
return ts;
|
||||
}
|
||||
pos1 = pos2;
|
||||
}
|
||||
|
||||
pos1 = pos2;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -528,38 +554,68 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
|||
closedNodesList[node->heuristic].push_back(node);
|
||||
openPosList[node->pos] = true;
|
||||
|
||||
int failureCount = 0;
|
||||
int cellCount = 0;
|
||||
|
||||
int tryDirection = 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) {
|
||||
processNode(unit, node, finalPos, i, j, nodeLimitReached);
|
||||
if(processNode(unit, node, finalPos, i, j, nodeLimitReached) == false) {
|
||||
failureCount++;
|
||||
}
|
||||
cellCount++;
|
||||
}
|
||||
}
|
||||
// if(failureCount == cellCount && node->pos == unitPos) {
|
||||
// nodeLimitReached = true;
|
||||
// }
|
||||
}
|
||||
else if(tryDirection == 2) {
|
||||
for(int i = -1; i <= 1 && nodeLimitReached == false; ++i) {
|
||||
for(int j = 1; j >= -1 && nodeLimitReached == false; --j) {
|
||||
processNode(unit, node, finalPos, i, j, nodeLimitReached);
|
||||
if(processNode(unit, node, finalPos, i, j, nodeLimitReached) == false) {
|
||||
failureCount++;
|
||||
}
|
||||
cellCount++;
|
||||
}
|
||||
}
|
||||
// if(failureCount == cellCount && node->pos == unitPos) {
|
||||
// nodeLimitReached = true;
|
||||
// }
|
||||
}
|
||||
else if(tryDirection == 1) {
|
||||
for(int i = -1; i <= 1 && nodeLimitReached == false; ++i) {
|
||||
for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) {
|
||||
processNode(unit, node, finalPos, i, j, nodeLimitReached);
|
||||
if(processNode(unit, node, finalPos, i, j, nodeLimitReached) == false) {
|
||||
failureCount++;
|
||||
}
|
||||
cellCount++;
|
||||
}
|
||||
}
|
||||
// if(failureCount == cellCount && node->pos == unitPos) {
|
||||
// nodeLimitReached = true;
|
||||
// }
|
||||
}
|
||||
else {
|
||||
for(int i = 1; i >= -1 && nodeLimitReached == false; --i) {
|
||||
for(int j = 1; j >= -1 && nodeLimitReached == false; --j) {
|
||||
processNode(unit, node, finalPos, i, j, nodeLimitReached);
|
||||
if(processNode(unit, node, finalPos, i, j, nodeLimitReached) == false) {
|
||||
failureCount++;
|
||||
}
|
||||
cellCount++;
|
||||
}
|
||||
}
|
||||
// if(failureCount == cellCount && node->pos == unitPos) {
|
||||
// nodeLimitReached = true;
|
||||
// }
|
||||
}
|
||||
} //while
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),nodeLimitReached,whileLoopCount,nodePoolCount);
|
||||
if(showConsoleDebugInfo && chrono.getMillis() > 2) {
|
||||
printf("Distance for unit [%d - %s] to destination is %.2f took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",unit->getId(),unit->getFullName().c_str(), dist,(long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,nodePoolCount);
|
||||
}
|
||||
|
||||
Node *lastNode= node;
|
||||
|
||||
|
@ -625,11 +681,20 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
|||
|
||||
currNode= firstNode;
|
||||
for(int i=0; currNode->next != NULL; currNode= currNode->next, i++) {
|
||||
if(i < pathFindRefresh) {
|
||||
path->add(currNode->next->pos);
|
||||
Vec2i nodePos = currNode->next->pos;
|
||||
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
|
||||
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
|
||||
}
|
||||
if(basicPathFinder) {
|
||||
basicPathFinder->addToLastPathCache(currNode->next->pos);
|
||||
|
||||
if(i < pathFindRefresh) {
|
||||
path->add(nodePos);
|
||||
}
|
||||
else if(tryLastPathCache == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(tryLastPathCache == true && basicPathFinder) {
|
||||
basicPathFinder->addToLastPathCache(nodePos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -678,7 +743,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
|||
}
|
||||
|
||||
PathFinder::Node *PathFinder::newNode() {
|
||||
if(nodePoolCount < nodePool.size()) {
|
||||
if(nodePoolCount < nodePool.size() && nodePoolCount < useMaxNodeCount) {
|
||||
Node *node= &nodePool[nodePoolCount];
|
||||
node->clear();
|
||||
nodePoolCount++;
|
||||
|
|
|
@ -72,6 +72,7 @@ private:
|
|||
int nodePoolCount;
|
||||
const Map *map;
|
||||
RandomGen random;
|
||||
int useMaxNodeCount;
|
||||
|
||||
public:
|
||||
PathFinder();
|
||||
|
@ -89,7 +90,7 @@ private:
|
|||
|
||||
Node * minHeuristicFastLookup();
|
||||
|
||||
void processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached);
|
||||
bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached);
|
||||
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
|
||||
};
|
||||
|
||||
|
|
|
@ -41,12 +41,14 @@ UnitPathBasic::UnitPathBasic() {
|
|||
this->blockCount = 0;
|
||||
this->pathQueue.clear();
|
||||
this->lastPathCacheQueue.clear();
|
||||
this->map = NULL;
|
||||
}
|
||||
|
||||
UnitPathBasic::~UnitPathBasic() {
|
||||
this->blockCount = 0;
|
||||
this->pathQueue.clear();
|
||||
this->lastPathCacheQueue.clear();
|
||||
this->map = NULL;
|
||||
}
|
||||
|
||||
bool UnitPathBasic::isEmpty() const {
|
||||
|
@ -73,15 +75,36 @@ void UnitPathBasic::incBlockCount() {
|
|||
blockCount++;
|
||||
}
|
||||
|
||||
void UnitPathBasic::add(const Vec2i &path){
|
||||
void UnitPathBasic::add(const Vec2i &path) {
|
||||
if(this->map != NULL) {
|
||||
if(this->map->isInside(path) == false) {
|
||||
throw runtime_error("Invalid map path position = " + path.getString() + " map w x h = " + intToStr(map->getW()) + " " + intToStr(map->getH()));
|
||||
}
|
||||
else if(this->map->isInsideSurface(this->map->toSurfCoords(path)) == false) {
|
||||
throw runtime_error("Invalid map surface path position = " + path.getString() + " map surface w x h = " + intToStr(map->getSurfaceW()) + " " + intToStr(map->getSurfaceH()));
|
||||
}
|
||||
}
|
||||
|
||||
pathQueue.push_back(path);
|
||||
}
|
||||
|
||||
void UnitPathBasic::addToLastPathCache(const Vec2i &path) {
|
||||
if(this->map != NULL) {
|
||||
if(this->map->isInside(path) == false) {
|
||||
throw runtime_error("Invalid map path position = " + path.getString() + " map w x h = " + intToStr(map->getW()) + " " + intToStr(map->getH()));
|
||||
}
|
||||
else if(this->map->isInsideSurface(this->map->toSurfCoords(path)) == false) {
|
||||
throw runtime_error("Invalid map surface path position = " + path.getString() + " map surface w x h = " + intToStr(map->getSurfaceW()) + " " + intToStr(map->getSurfaceH()));
|
||||
}
|
||||
}
|
||||
|
||||
lastPathCacheQueue.push_back(path);
|
||||
}
|
||||
|
||||
Vec2i UnitPathBasic::pop() {
|
||||
if(pathQueue.size() <= 0) {
|
||||
throw runtime_error("pathQueue.size() = " + intToStr(pathQueue.size()));
|
||||
}
|
||||
Vec2i p= pathQueue.front();
|
||||
pathQueue.erase(pathQueue.begin());
|
||||
return p;
|
||||
|
@ -182,7 +205,12 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
|
|||
|
||||
RandomGen random;
|
||||
|
||||
if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) {
|
||||
throw runtime_error("#2 Invalid path position = " + pos.getString());
|
||||
}
|
||||
|
||||
this->unitPath = unitpath;
|
||||
this->unitPath->setMap(map);
|
||||
this->pos=pos;
|
||||
this->type=type;
|
||||
this->faction=faction;
|
||||
|
@ -606,7 +634,11 @@ void Unit::setTarget(const Unit *unit){
|
|||
targetRef= unit;
|
||||
}
|
||||
|
||||
void Unit::setPos(const Vec2i &pos){
|
||||
void Unit::setPos(const Vec2i &pos) {
|
||||
if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) {
|
||||
throw runtime_error("#3 Invalid path position = " + pos.getString());
|
||||
}
|
||||
|
||||
this->lastPos= this->pos;
|
||||
this->pos= pos;
|
||||
this->meetingPos= pos - Vec2i(1);
|
||||
|
@ -617,7 +649,11 @@ void Unit::setPos(const Vec2i &pos){
|
|||
logSynchData(__FILE__,__LINE__);
|
||||
}
|
||||
|
||||
void Unit::setTargetPos(const Vec2i &targetPos){
|
||||
void Unit::setTargetPos(const Vec2i &targetPos) {
|
||||
|
||||
if(map->isInside(targetPos) == false || map->isInsideSurface(map->toSurfCoords(targetPos)) == false) {
|
||||
throw runtime_error("#4 Invalid path position = " + targetPos.getString());
|
||||
}
|
||||
|
||||
Vec2i relPos= targetPos - pos;
|
||||
Vec2f relPosf= Vec2f((float)relPos.x, (float)relPos.y);
|
||||
|
@ -1024,6 +1060,11 @@ void Unit::resetHighlight(){
|
|||
|
||||
const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *targetUnit) const{
|
||||
const CommandType *commandType= NULL;
|
||||
|
||||
if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) {
|
||||
throw runtime_error("#6 Invalid path position = " + pos.getString());
|
||||
}
|
||||
|
||||
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(pos));
|
||||
|
||||
if(type == NULL) {
|
||||
|
@ -1501,6 +1542,10 @@ bool Unit::morph(const MorphCommandType *mct){
|
|||
// ==================== PRIVATE ====================
|
||||
|
||||
float Unit::computeHeight(const Vec2i &pos) const{
|
||||
if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) {
|
||||
throw runtime_error("#7 Invalid path position = " + pos.getString());
|
||||
}
|
||||
|
||||
float height= map->getCell(pos)->getHeight();
|
||||
|
||||
if(currField == fAir) {
|
||||
|
@ -1811,6 +1856,10 @@ void Unit::setTargetVec(const Vec3f &targetVec) {
|
|||
}
|
||||
|
||||
void Unit::setMeetingPos(const Vec2i &meetingPos) {
|
||||
if(map->isInside(meetingPos) == false || map->isInsideSurface(map->toSurfCoords(meetingPos)) == false) {
|
||||
throw runtime_error("#8 Invalid path position = " + meetingPos.getString());
|
||||
}
|
||||
|
||||
this->meetingPos= meetingPos;
|
||||
logSynchData(__FILE__,__LINE__);
|
||||
}
|
||||
|
|
|
@ -120,11 +120,15 @@ public:
|
|||
virtual vector<Vec2i> getQueue() const = 0;
|
||||
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
virtual void setMap(Map *value) = 0;
|
||||
virtual Map * getMap() = 0;
|
||||
};
|
||||
|
||||
class UnitPathBasic : public UnitPathInterface {
|
||||
private:
|
||||
static const int maxBlockCount;
|
||||
Map *map;
|
||||
|
||||
private:
|
||||
int blockCount;
|
||||
|
@ -152,6 +156,9 @@ public:
|
|||
|
||||
virtual vector<Vec2i> getQueue() const { return pathQueue; }
|
||||
|
||||
virtual void setMap(Map *value) { map = value; }
|
||||
virtual Map * getMap() { return map; }
|
||||
|
||||
virtual std::string toString() const;
|
||||
};
|
||||
|
||||
|
@ -167,9 +174,10 @@ private:
|
|||
|
||||
private:
|
||||
int blockCount; /**< number of command updates this path has been blocked */
|
||||
Map *map;
|
||||
|
||||
public:
|
||||
UnitPath() : blockCount(0) {} /**< Construct path object */
|
||||
UnitPath() : blockCount(0), map(NULL) {} /**< Construct path object */
|
||||
virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */
|
||||
virtual bool isEmpty() const {return list<Vec2i>::empty();} /**< is path empty */
|
||||
virtual bool isStuck() const {return false; }
|
||||
|
@ -204,6 +212,9 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
virtual void setMap(Map *value) { map = value; }
|
||||
virtual Map * getMap() { return map; }
|
||||
|
||||
virtual std::string toString() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -129,9 +129,13 @@ int Map::getSurfaceCellArraySize() const {
|
|||
return (surfaceW * surfaceH);
|
||||
}
|
||||
|
||||
SurfaceCell *Map::getSurfaceCell(const Vec2i &sPos) const {
|
||||
return getSurfaceCell(sPos.x, sPos.y);
|
||||
}
|
||||
|
||||
SurfaceCell *Map::getSurfaceCell(int sx, int sy) const {
|
||||
int arrayIndex = sy * surfaceW + sx;
|
||||
if(arrayIndex >= getSurfaceCellArraySize()) {
|
||||
if(arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) {
|
||||
throw runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH));
|
||||
}
|
||||
else if(surfaceCells == NULL) {
|
||||
|
@ -144,9 +148,13 @@ int Map::getCellArraySize() const {
|
|||
return (w * h);
|
||||
}
|
||||
|
||||
Cell *Map::getCell(const Vec2i &pos) const {
|
||||
return getCell(pos.x, pos.y);
|
||||
}
|
||||
|
||||
Cell *Map::getCell(int x, int y) const {
|
||||
int arrayIndex = y * w + x;
|
||||
if(arrayIndex >= getCellArraySize()) {
|
||||
if(arrayIndex < 0 || arrayIndex >= getCellArraySize()) {
|
||||
//abort();
|
||||
throw runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h));
|
||||
}
|
||||
|
@ -565,6 +573,11 @@ bool Map::canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::m
|
|||
|
||||
//checks if a unit can move from between 2 cells using only visible cells (for pathfinding)
|
||||
bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<int, std::map<Field,bool> > > > > *lookupCache) const {
|
||||
if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false ||
|
||||
isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int size= unit->getType()->getSize();
|
||||
int teamIndex= unit->getTeam();
|
||||
Field field= unit->getCurrField();
|
||||
|
@ -632,9 +645,11 @@ bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, s
|
|||
else {
|
||||
for(int i = pos2.x; i < pos2.x + size; ++i) {
|
||||
for(int j = pos2.y; j < pos2.y + size; ++j) {
|
||||
if(isInside(i, j)) {
|
||||
if(getCell(i, j)->getUnit(unit->getCurrField()) != unit) {
|
||||
if(isAproxFreeCell(Vec2i(i, j), field, teamIndex) == false) {
|
||||
|
||||
Vec2i cellPos = Vec2i(i,j);
|
||||
if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) {
|
||||
if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) {
|
||||
if(isAproxFreeCell(cellPos, field, teamIndex) == false) {
|
||||
if(lookupCache != NULL) {
|
||||
(*lookupCache)[pos1][pos2][teamIndex][size][field]=false;
|
||||
}
|
||||
|
@ -665,9 +680,8 @@ bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, s
|
|||
if(lookupCache != NULL) {
|
||||
(*lookupCache)[pos1][pos2][teamIndex][size][field]=true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Vec2i Map::computeRefPos(const Selection *selection) const {
|
||||
|
|
|
@ -183,10 +183,10 @@ public:
|
|||
//get
|
||||
Cell *getCell(int x, int y) const;
|
||||
int getCellArraySize() const;
|
||||
Cell *getCell(const Vec2i &pos) const {return getCell(pos.x, pos.y);}
|
||||
Cell *getCell(const Vec2i &pos) const;
|
||||
int getSurfaceCellArraySize() const;
|
||||
SurfaceCell *getSurfaceCell(int sx, int sy) const;
|
||||
SurfaceCell *getSurfaceCell(const Vec2i &sPos) const {return getSurfaceCell(sPos.x, sPos.y);}
|
||||
SurfaceCell *getSurfaceCell(const Vec2i &sPos) const;
|
||||
int getW() const {return w;}
|
||||
int getH() const {return h;}
|
||||
int getSurfaceW() const {return surfaceW;}
|
||||
|
|
Loading…
Reference in New Issue