bugfix for nig's issue
This commit is contained in:
parent
22b230a5b3
commit
0f5f4c0792
|
@ -566,348 +566,6 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
|
|
||||||
// ==================== PRIVATE ====================
|
// ==================== PRIVATE ====================
|
||||||
|
|
||||||
bool PathFinder::addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded, bool bypassChecks) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
*newNodeAdded=NULL;
|
|
||||||
//Vec2i sucPos= node->pos + Vec2i(i, j);
|
|
||||||
if(bypassChecks == true ||
|
|
||||||
(canUnitMoveSoon(unit, node->pos, sucPos) == true && openPos(sucPos, factions[unit->getFactionIndex()]) == false)) {
|
|
||||||
//if node is not open and canMove then generate another node
|
|
||||||
Node *sucNode= newNode(factions[unit->getFactionIndex()],maxNodeCount);
|
|
||||||
if(sucNode != NULL) {
|
|
||||||
sucNode->pos= sucPos;
|
|
||||||
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
|
|
||||||
sucNode->prev= node;
|
|
||||||
sucNode->next= NULL;
|
|
||||||
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
|
|
||||||
|
|
||||||
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
||||||
MutexSafeWrapper safeMutex(factionMutex,mutexOwnerId);
|
|
||||||
|
|
||||||
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
|
|
||||||
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
|
|
||||||
}
|
|
||||||
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
|
|
||||||
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
|
|
||||||
|
|
||||||
*newNodeAdded=sucNode;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodeLimitReached= true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
direction PathFinder::directionOfMove(Vec2i to, Vec2i from) const {
|
|
||||||
if (from.x == to.x) {
|
|
||||||
if (from.y == to.y)
|
|
||||||
return 0;
|
|
||||||
else if (from.y < to.y)
|
|
||||||
return 4;
|
|
||||||
else // from.y > to.y
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (from.x < to.x) {
|
|
||||||
if (from.y == to.y)
|
|
||||||
return 2;
|
|
||||||
else if (from.y < to.y)
|
|
||||||
return 3;
|
|
||||||
else // from.y > to.y
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else { // from.x > to.x
|
|
||||||
if (from.y == to.y)
|
|
||||||
return 6;
|
|
||||||
else if (from.y < to.y)
|
|
||||||
return 5;
|
|
||||||
else // from.y > to.y
|
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
direction PathFinder::directionWeCameFrom(Vec2i node, Vec2i nodeFrom) const {
|
|
||||||
direction result = NO_DIRECTION;
|
|
||||||
if(nodeFrom.x >= 0 && nodeFrom.y >= 0) {
|
|
||||||
result = directionOfMove(node, nodeFrom);
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("directionWeCameFrom node [%s] nodeFrom [%s] result = %d\n",node.getString().c_str(),nodeFrom.getString().c_str(),result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this coordinate contained within the map bounds?
|
|
||||||
bool PathFinder::contained(Vec2i c) {
|
|
||||||
return (map->isInside(c) == true && map->isInsideSurface(map->toSurfCoords(c)) == true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this coordinate within the map bounds, and also walkable?
|
|
||||||
bool PathFinder::isEnterable(Vec2i coord) {
|
|
||||||
//node node = getIndex (astar->bounds, coord);
|
|
||||||
//return contained(coord) && astar->grid[node];
|
|
||||||
return contained(coord);
|
|
||||||
}
|
|
||||||
// the coordinate one tile in the given direction
|
|
||||||
Vec2i PathFinder::adjustInDirection(Vec2i c, int dir) {
|
|
||||||
// we want to implement "rotation" - that is, for instance, we can
|
|
||||||
// subtract 2 from the direction "north" and get "east"
|
|
||||||
// C's modulo operator doesn't quite behave the right way to do this,
|
|
||||||
// but for our purposes this kluge should be good enough
|
|
||||||
switch ((dir + 65536) % 8) {
|
|
||||||
case 0: return Vec2i(c.x, c.y - 1);
|
|
||||||
case 1: return Vec2i(c.x + 1, c.y - 1);
|
|
||||||
case 2: return Vec2i(c.x + 1, c.y );
|
|
||||||
case 3: return Vec2i(c.x + 1, c.y + 1);
|
|
||||||
case 4: return Vec2i(c.x, c.y + 1);
|
|
||||||
case 5: return Vec2i(c.x - 1, c.y + 1);
|
|
||||||
case 6: return Vec2i(c.x - 1, c.y);
|
|
||||||
case 7: return Vec2i(c.x - 1, c.y - 1);
|
|
||||||
}
|
|
||||||
return Vec2i( -1, -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PathFinder::directionIsDiagonal(direction dir) const {
|
|
||||||
return (dir % 2) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// logical implication operator
|
|
||||||
bool PathFinder::implies(bool a, bool b) const {
|
|
||||||
return a ? b : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
directionset PathFinder::addDirectionToSet(directionset dirs, direction dir) const {
|
|
||||||
return dirs | 1 << dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
directionset PathFinder::forcedNeighbours(Vec2i coord,direction dir) {
|
|
||||||
if (dir == NO_DIRECTION)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
directionset dirs = 0;
|
|
||||||
#define ENTERABLE(n) isEnterable(adjustInDirection(coord, (dir + (n)) % 8))
|
|
||||||
if (directionIsDiagonal(dir)) {
|
|
||||||
if (!implies (ENTERABLE (6), ENTERABLE (5)))
|
|
||||||
dirs = addDirectionToSet (dirs, (dir + 6) % 8);
|
|
||||||
if (!implies (ENTERABLE (2), ENTERABLE (3)))
|
|
||||||
dirs = addDirectionToSet (dirs, (dir + 2) % 8);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!implies (ENTERABLE (7), ENTERABLE (6)))
|
|
||||||
dirs = addDirectionToSet (dirs, (dir + 7) % 8);
|
|
||||||
if (!implies (ENTERABLE (1), ENTERABLE (2)))
|
|
||||||
dirs = addDirectionToSet (dirs, (dir + 1) % 8);
|
|
||||||
}
|
|
||||||
#undef ENTERABLE
|
|
||||||
return dirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
directionset PathFinder::naturalNeighbours(direction dir) const {
|
|
||||||
if (dir == NO_DIRECTION)
|
|
||||||
return 255;
|
|
||||||
|
|
||||||
directionset dirs = 0;
|
|
||||||
dirs = addDirectionToSet (dirs, dir);
|
|
||||||
if (directionIsDiagonal (dir)) {
|
|
||||||
dirs = addDirectionToSet (dirs, (dir + 1) % 8);
|
|
||||||
dirs = addDirectionToSet (dirs, (dir + 7) % 8);
|
|
||||||
}
|
|
||||||
return dirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return and remove a direction from the set
|
|
||||||
// returns NO_DIRECTION if the set was empty
|
|
||||||
direction PathFinder::nextDirectionInSet(directionset *dirs) const {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
char bit = 1 << i;
|
|
||||||
if (*dirs & bit) {
|
|
||||||
*dirs ^= bit;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NO_DIRECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// directly translated from "algorithm 2" in the paper
|
|
||||||
Vec2i PathFinder::jump(Vec2i dest, direction dir, Vec2i start,std::vector<Vec2i> &path, int pathLength) {
|
|
||||||
Vec2i coord = adjustInDirection(start, dir);
|
|
||||||
//printf("jump dir [%u] start [%s] coord [%s] dest [%s]\n",dir,start.getString().c_str(),coord.getString().c_str(),dest.getString().c_str());
|
|
||||||
|
|
||||||
if (!isEnterable(coord))
|
|
||||||
return Vec2i(-1,-1);
|
|
||||||
|
|
||||||
if(path.size() > max(300,pathLength*2)) {
|
|
||||||
//if(path.size() > 2000) {
|
|
||||||
//printf("path.size() > pathLength [%d]\n",pathLength);
|
|
||||||
//return Vec2i(-1,-1);
|
|
||||||
return coord;
|
|
||||||
}
|
|
||||||
path.push_back(coord);
|
|
||||||
|
|
||||||
//int node = getIndex (astar->bounds, coord);
|
|
||||||
if (coord == dest || forcedNeighbours(coord, dir)) {
|
|
||||||
//path.push_back(coord);
|
|
||||||
//printf("jump #1 = %d [%d]\n",(int)path.size(),pathLength);
|
|
||||||
return coord;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(directionIsDiagonal(dir)) {
|
|
||||||
Vec2i next = jump(dest, (dir + 7) % 8, coord,path,pathLength);
|
|
||||||
if (next.x >= 0) {
|
|
||||||
//path.push_back(coord);
|
|
||||||
//printf("jump #2 = %d [%d]\n",(int)path.size(),pathLength);
|
|
||||||
return coord;
|
|
||||||
}
|
|
||||||
next = jump(dest, (dir + 1) % 8, coord, path,pathLength);
|
|
||||||
if (next.x >= 0) {
|
|
||||||
//path.push_back(coord);
|
|
||||||
//printf("jump #3 = %d [%d]\n",(int)path.size(),pathLength);
|
|
||||||
return coord;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//else {
|
|
||||||
//path.push_back(coord);
|
|
||||||
//}
|
|
||||||
return jump(dest, dir, coord, path,pathLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PathFinder::astarJPS(std::map<Vec2i,Vec2i> cameFrom, Node *& node,
|
|
||||||
const Vec2i & finalPos, std::map<Vec2i,bool> closedNodes,
|
|
||||||
std::map<std::pair<Vec2i,Vec2i> ,bool> canAddNode, Unit *& unit,
|
|
||||||
bool & nodeLimitReached, int & maxNodeCount) {
|
|
||||||
Vec2i cameFromPos(-1, -1);
|
|
||||||
if(cameFrom.find(node->pos) != cameFrom.end()) {
|
|
||||||
cameFromPos = cameFrom[node->pos];
|
|
||||||
}
|
|
||||||
direction from = directionWeCameFrom(node->pos, cameFromPos);
|
|
||||||
directionset dirs = forcedNeighbours(node->pos, from) | naturalNeighbours(from);
|
|
||||||
bool canAddEntirePath = false;
|
|
||||||
bool foundQuickRoute = false;
|
|
||||||
for (int dir = nextDirectionInSet(&dirs); dir != NO_DIRECTION; dir = nextDirectionInSet(&dirs)) {
|
|
||||||
//for (int dir = 0; dir < 8; dir++) {
|
|
||||||
std::vector<Vec2i> path;
|
|
||||||
Vec2i newNode = jump(finalPos, dir, node->pos,path,(int)node->pos.dist(finalPos));
|
|
||||||
//Vec2i newNode = adjustInDirection(node->pos, dir);
|
|
||||||
|
|
||||||
//printf("examine node from [%u][%u] - current node [%s] next possible node [%s]\n",from,dirs,node->pos.getString().c_str(),newNode.getString().c_str());
|
|
||||||
|
|
||||||
//coord_t newCoord = getCoord (bounds, newNode);
|
|
||||||
|
|
||||||
// this'll also bail out if jump() returned -1
|
|
||||||
if (!contained(newNode))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(closedNodes.find(newNode) != closedNodes.end())
|
|
||||||
continue;
|
|
||||||
//if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
|
|
||||||
|
|
||||||
//addToOpenSet (&astar, newNode, node);
|
|
||||||
//printf("JPS #2 node->pos [%s] newNode [%s] path.size() [%d] pos [%s]\n",node->pos.getString().c_str(),newNode.getString().c_str(),(int)path.size(),path[0].getString().c_str());
|
|
||||||
|
|
||||||
Vec2i newPath = path[0];
|
|
||||||
|
|
||||||
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, newPath);
|
|
||||||
//bool posOpen = (openPos(newPath, factions[unit->getFactionIndex()]) == false);
|
|
||||||
//bool isFreeCell = map->isFreeCell(newPath,unit->getType()->getField());
|
|
||||||
|
|
||||||
if(canAddNode.find(make_pair(node->pos,newPath)) == canAddNode.end()) {
|
|
||||||
Node *newNode=NULL;
|
|
||||||
if(addToOpenSet(unit, node, finalPos, newPath, nodeLimitReached, maxNodeCount,&newNode,false) == true) {
|
|
||||||
//cameFrom = node->pos;
|
|
||||||
cameFrom[newPath]=node->pos;
|
|
||||||
foundQuickRoute = true;
|
|
||||||
|
|
||||||
if(path.size() > 1 && path[path.size()-1] == finalPos) {
|
|
||||||
canAddEntirePath = true;
|
|
||||||
for(unsigned int x = 1; x < path.size(); ++x) {
|
|
||||||
Vec2i futureNode = path[x];
|
|
||||||
|
|
||||||
bool canUnitMoveToCell = canUnitMoveSoon(unit, newNode->pos, futureNode);
|
|
||||||
if(canUnitMoveToCell != true || openPos(futureNode, factions[unit->getFactionIndex()]) == true) {
|
|
||||||
canAddEntirePath = false;
|
|
||||||
canAddNode[make_pair(node->pos,futureNode)]=false;
|
|
||||||
//printf("COULD NOT ADD ENTIRE PATH! canUnitMoveToCell = %d\n",canUnitMoveToCell);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(canAddEntirePath == true) {
|
|
||||||
//printf("add node - ENTIRE PATH!\n");
|
|
||||||
|
|
||||||
for(unsigned int x = 1; x < path.size(); ++x) {
|
|
||||||
Vec2i futureNode = path[x];
|
|
||||||
|
|
||||||
Node *newNode2=NULL;
|
|
||||||
addToOpenSet(unit, newNode, finalPos, futureNode, nodeLimitReached, maxNodeCount,&newNode2, true);
|
|
||||||
newNode=newNode2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Node *result = factions[unit->getFactionIndex()].openNodesList.begin()->second[0];
|
|
||||||
//if(result->pos == finalPos || result->exploredCell == false) {
|
|
||||||
// printf("Will break out of pathfinding now!\n");
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//printf("add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//printf("COULD NOT add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
|
|
||||||
canAddNode[make_pair(node->pos,newPath)]=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(canAddEntirePath == true) {
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
if(foundQuickRoute == false) {
|
|
||||||
for (int dir = 0; dir < 8; dir++) {
|
|
||||||
Vec2i newNode = adjustInDirection(node->pos, dir);
|
|
||||||
|
|
||||||
//printf("examine node from [%u][%u] - current node [%s] next possible node [%s]\n",from,dirs,node->pos.getString().c_str(),newNode.getString().c_str());
|
|
||||||
|
|
||||||
//coord_t newCoord = getCoord (bounds, newNode);
|
|
||||||
|
|
||||||
// this'll also bail out if jump() returned -1
|
|
||||||
if (!contained(newNode))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(closedNodes.find(newNode) != closedNodes.end())
|
|
||||||
continue;
|
|
||||||
//if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
|
|
||||||
|
|
||||||
//addToOpenSet (&astar, newNode, node);
|
|
||||||
//printf("JPS #3 node->pos [%s] newNode [%s]\n",node->pos.getString().c_str(),newNode.getString().c_str());
|
|
||||||
|
|
||||||
Vec2i newPath = newNode;
|
|
||||||
|
|
||||||
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, newPath);
|
|
||||||
//bool posOpen = (openPos(newPath, factions[unit->getFactionIndex()]) == false);
|
|
||||||
//bool isFreeCell = map->isFreeCell(newPath,unit->getType()->getField());
|
|
||||||
|
|
||||||
if(canAddNode.find(make_pair(node->pos,newPath)) == canAddNode.end()) {
|
|
||||||
Node *newNode=NULL;
|
|
||||||
if(addToOpenSet(unit, node, finalPos, newPath, nodeLimitReached, maxNodeCount,&newNode, false) == true) {
|
|
||||||
//cameFrom = node->pos;
|
|
||||||
cameFrom[newPath]=node->pos;
|
|
||||||
//foundQuickRoute = true;
|
|
||||||
|
|
||||||
//printf("#2 add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//printf("#2 COULD NOT add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
|
|
||||||
canAddNode[make_pair(node->pos,newPath)]=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//route a unit using A* algorithm
|
//route a unit using A* algorithm
|
||||||
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout,
|
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout,
|
||||||
int frameIndex, int maxNodeCount, uint32 *searched_node_count) {
|
int frameIndex, int maxNodeCount, uint32 *searched_node_count) {
|
||||||
|
@ -1385,9 +1043,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
int whileLoopCount = 0;
|
int whileLoopCount = 0;
|
||||||
if(nodeLimitReached == false) {
|
if(nodeLimitReached == false) {
|
||||||
codeLocation = "32";
|
codeLocation = "32";
|
||||||
//printf("\n\n\n====== START AStar-JPS Pathfinder start [%s] end [%s]\n",unitPos.getString().c_str(),finalPos.getString().c_str());
|
|
||||||
|
|
||||||
const bool tryJPSPathfinder = false;
|
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
|
||||||
char szBuf[8096]="";
|
char szBuf[8096]="";
|
||||||
|
@ -1397,7 +1052,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
}
|
}
|
||||||
|
|
||||||
doAStarPathSearch(nodeLimitReached, whileLoopCount, unitFactionIndex,
|
doAStarPathSearch(nodeLimitReached, whileLoopCount, unitFactionIndex,
|
||||||
pathFound, node, finalPos, tryJPSPathfinder,
|
pathFound, node, finalPos,
|
||||||
closedNodes, cameFrom, canAddNode, unit, maxNodeCount,frameIndex);
|
closedNodes, cameFrom, canAddNode, unit, maxNodeCount,frameIndex);
|
||||||
|
|
||||||
codeLocation = "33";
|
codeLocation = "33";
|
||||||
|
|
|
@ -280,72 +280,36 @@ private:
|
||||||
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
|
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
|
||||||
int getPathFindExtendRefreshNodeCount(int factionIndex);
|
int getPathFindExtendRefreshNodeCount(int factionIndex);
|
||||||
|
|
||||||
|
|
||||||
void astarJPS(std::map<Vec2i,Vec2i> cameFrom, Node *& node,
|
|
||||||
const Vec2i & finalPos, std::map<Vec2i,bool> closedNodes,
|
|
||||||
std::map<std::pair<Vec2i,Vec2i> ,bool> canAddNode, Unit *& unit,
|
|
||||||
bool & nodeLimitReached, int & maxNodeCount);
|
|
||||||
|
|
||||||
bool contained(Vec2i c);
|
|
||||||
direction directionOfMove(Vec2i to, Vec2i from) const;
|
|
||||||
direction directionWeCameFrom(Vec2i node, Vec2i nodeFrom) const;
|
|
||||||
bool isEnterable(Vec2i coord);
|
|
||||||
Vec2i adjustInDirection(Vec2i c, int dir);
|
|
||||||
bool directionIsDiagonal(direction dir) const;
|
|
||||||
directionset forcedNeighbours(Vec2i coord,direction dir);
|
|
||||||
bool implies(bool a, bool b) const;
|
|
||||||
directionset addDirectionToSet(directionset dirs, direction dir) const;
|
|
||||||
directionset naturalNeighbours(direction dir) const;
|
|
||||||
direction nextDirectionInSet(directionset *dirs) const;
|
|
||||||
Vec2i jump(Vec2i dest, direction dir, Vec2i start,std::vector<Vec2i> &path,int pathLength);
|
|
||||||
bool addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded,bool bypassChecks);
|
|
||||||
|
|
||||||
//bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2);
|
|
||||||
inline bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) {
|
inline bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) {
|
||||||
//bool result = true;
|
|
||||||
|
|
||||||
// std::map<int,std::map<Field,BadUnitNodeList> > &badCellList = factions[unit->getFactionIndex()].badCellList;
|
|
||||||
// if(badCellList.find(unit->getType()->getSize()) != badCellList.end()) {
|
|
||||||
// std::map<Field,BadUnitNodeList> &badFieldList = badCellList[unit->getType()->getSize()];
|
|
||||||
// if(badFieldList.find(unit->getCurrField()) != badFieldList.end()) {
|
|
||||||
// BadUnitNodeList &badList = badFieldList[unit->getCurrField()];
|
|
||||||
// if(badList.isPosBad(pos1,pos2) == true) {
|
|
||||||
// result = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if(result == true) {
|
|
||||||
// //bool canUnitMoveToCell = map->canMove(unit, unitPos, pos);
|
|
||||||
// //bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos);
|
|
||||||
// result = map->aproxCanMoveSoon(unit, pos1, pos2);
|
|
||||||
// if(result == false) {
|
|
||||||
// badCellList[unit->getType()->getSize()][unit->getCurrField()].badPosList[pos1][pos2]=false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool result = map->aproxCanMoveSoon(unit, pos1, pos2);
|
bool result = map->aproxCanMoveSoon(unit, pos1, pos2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void doAStarPathSearch(bool & nodeLimitReached, int & whileLoopCount,
|
inline void doAStarPathSearch(bool & nodeLimitReached, int & whileLoopCount,
|
||||||
int & unitFactionIndex, bool & pathFound, Node *& node, const Vec2i & finalPos,
|
int & unitFactionIndex, bool & pathFound, Node *& node, const Vec2i & finalPos,
|
||||||
const bool tryJPSPathfinder, std::map<Vec2i,bool> closedNodes,
|
std::map<Vec2i,bool> closedNodes,
|
||||||
std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> ,
|
std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> ,
|
||||||
bool> canAddNode, Unit *& unit, int & maxNodeCount, int curFrameIndex) {
|
bool> canAddNode, Unit *& unit, int & maxNodeCount, int curFrameIndex) {
|
||||||
|
|
||||||
//Chrono chrono;
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
MutexSafeWrapper safeMutexFaction(factionMutex,mutexOwnerId);
|
||||||
//chrono.start();
|
|
||||||
|
|
||||||
FactionState &factionState = factions[unitFactionIndex];
|
FactionState &factionState = factions[unitFactionIndex];
|
||||||
|
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
|
|
||||||
while(nodeLimitReached == false) {
|
while(nodeLimitReached == false) {
|
||||||
whileLoopCount++;
|
whileLoopCount++;
|
||||||
|
|
||||||
|
safeMutexFaction.Lock();
|
||||||
if(factionState.openNodesList.empty() == true) {
|
if(factionState.openNodesList.empty() == true) {
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
pathFound = false;
|
pathFound = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node = minHeuristicFastLookup(factionState);
|
node = minHeuristicFastLookup(factionState);
|
||||||
if(node->pos == finalPos || node->exploredCell == false) {
|
if(node->pos == finalPos || node->exploredCell == false) {
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
pathFound = true;
|
pathFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -367,71 +331,70 @@ private:
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if(tryJPSPathfinder == true) {
|
|
||||||
closedNodes[node->pos] = true;
|
|
||||||
}
|
|
||||||
if(factionState.closedNodesList.find(node->heuristic) == factionState.closedNodesList.end()) {
|
if(factionState.closedNodesList.find(node->heuristic) == factionState.closedNodesList.end()) {
|
||||||
factionState.closedNodesList[node->heuristic].clear();
|
factionState.closedNodesList[node->heuristic].clear();
|
||||||
//factionState.closedNodesList[node->heuristic].reserve(PathFinder::pathFindNodesMax);
|
//factionState.closedNodesList[node->heuristic].reserve(PathFinder::pathFindNodesMax);
|
||||||
}
|
}
|
||||||
factionState.closedNodesList[node->heuristic].push_back(node);
|
factionState.closedNodesList[node->heuristic].push_back(node);
|
||||||
factionState.openPosList[node->pos] = true;
|
factionState.openPosList[node->pos] = true;
|
||||||
if(tryJPSPathfinder == true) {
|
safeMutexFaction.ReleaseLock(true);
|
||||||
astarJPS(cameFrom, node, finalPos, closedNodes, canAddNode, unit, nodeLimitReached, maxNodeCount);
|
|
||||||
|
int failureCount = 0;
|
||||||
|
int cellCount = 0;
|
||||||
|
|
||||||
|
safeMutexFaction.Lock();
|
||||||
|
int tryDirection = factionState.random.randRange(0, 3);
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
|
|
||||||
|
if(tryDirection == 3) {
|
||||||
|
for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
|
||||||
|
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
|
||||||
|
safeMutexFaction.Lock();
|
||||||
|
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
|
||||||
|
failureCount++;
|
||||||
|
}
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
|
cellCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(tryDirection == 2) {
|
||||||
|
for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
|
||||||
|
for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
|
||||||
|
safeMutexFaction.Lock();
|
||||||
|
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
|
||||||
|
failureCount++;
|
||||||
|
}
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
|
cellCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(tryDirection == 1) {
|
||||||
|
for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
|
||||||
|
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
|
||||||
|
safeMutexFaction.Lock();
|
||||||
|
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
|
||||||
|
failureCount++;
|
||||||
|
}
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
|
cellCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int failureCount = 0;
|
for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
|
||||||
int cellCount = 0;
|
for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
|
||||||
int tryDirection = factionState.random.randRange(0, 3);
|
safeMutexFaction.Lock();
|
||||||
|
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
|
||||||
if(tryDirection == 3) {
|
failureCount++;
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
|
safeMutexFaction.ReleaseLock(true);
|
||||||
|
cellCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//!!!
|
|
||||||
//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,factionState.nodePoolCount);
|
|
||||||
//if(chrono.getMillis() > 1) {
|
|
||||||
//printf("AStar for unit [%d - %s] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d curFrameIndex = %d travel distance = %f\n",unit->getId(),unit->getFullName().c_str(), (long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,factionState.nodePoolCount,curFrameIndex,unit->getPos().dist(finalPos));
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue