|
@@ -2,9 +2,7 @@
|
|
|
#include "global.h"
|
|
|
#include "CPathfinder.h"
|
|
|
|
|
|
-#define CGI (CGameInfo::mainObj)
|
|
|
-
|
|
|
-CPath * CPathfinder::getPath(int3 &src, int3 &dest)
|
|
|
+CPath * CPathfinder::getPath(int3 &src, int3 &dest, CHeroInstance * hero) //TODO: test it (seems to be finished, but relies on unwritten functions :()
|
|
|
{
|
|
|
if(src.z!=dest.z) //first check
|
|
|
return NULL;
|
|
@@ -16,50 +14,153 @@ CPath * CPathfinder::getPath(int3 &src, int3 &dest)
|
|
|
graph[i].resize(CGI->ac->map.height);
|
|
|
for(int j=0; j<graph[i].size(); ++j)
|
|
|
{
|
|
|
- graph[i][j].accesible = true;
|
|
|
- graph[i][j].dist = -1;
|
|
|
- graph[i][j].theNodeBefore = NULL;
|
|
|
- graph[i][j].x = i;
|
|
|
- graph[i][j].y = j;
|
|
|
+ graph[i][j] = new CPathNode;
|
|
|
+ graph[i][j]->accesible = !CGI->mh->ttiles[i][j][src.z].blocked;
|
|
|
+ graph[i][j]->dist = -1;
|
|
|
+ graph[i][j]->theNodeBefore = NULL;
|
|
|
+ graph[i][j]->visited = false;
|
|
|
+ graph[i][j]->x = i;
|
|
|
+ graph[i][j]->y = j;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- for(int h=0; h<CGI->objh->objInstances.size(); ++h)
|
|
|
+ //graph initialized
|
|
|
+
|
|
|
+ graph[src.x][src.y]->dist = 0;
|
|
|
+
|
|
|
+ std::queue<CPathNode *> mq;
|
|
|
+ mq.push(graph[src.x][src.y]);
|
|
|
+ while(!mq.empty())
|
|
|
{
|
|
|
- if(CGI->objh->objInstances[h]->pos.z == src.z)
|
|
|
+ CPathNode * cp = mq.front();
|
|
|
+ mq.pop();
|
|
|
+ if(cp->x>0)
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x-1][cp->y];
|
|
|
+ if(!dp->visited)
|
|
|
+ {
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y, src.z), hero)))
|
|
|
+ {
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(cp->y>0)
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x][cp->y-1];
|
|
|
+ if(!dp->visited)
|
|
|
+ {
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x, cp->y-1, src.z), hero)))
|
|
|
+ {
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(cp->x>0 && cp->y>0)
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x-1][cp->y-1];
|
|
|
+ if(!dp->visited)
|
|
|
+ {
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y-1, src.z), hero)))
|
|
|
+ {
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y-1, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(cp->x<graph.size()-1)
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x+1][cp->y];
|
|
|
+ if(!dp->visited)
|
|
|
+ {
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y, src.z), hero)))
|
|
|
+ {
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(cp->y<graph[0].size()-1)
|
|
|
{
|
|
|
- unsigned char blockMap[6];
|
|
|
- std::string ourName = CGI->ac->map.defy[CGI->objh->objInstances[h]->defNumber].name;
|
|
|
- std::transform(ourName.begin(), ourName.end(), ourName.begin(), (int(*)(int))toupper);
|
|
|
- for(int y=0; y<CGI->dobjinfo->objs.size(); ++y)
|
|
|
+ CPathNode * dp = graph[cp->x][cp->y+1];
|
|
|
+ if(!dp->visited)
|
|
|
{
|
|
|
- std::string cName = CGI->dobjinfo->objs[y].defName;
|
|
|
- std::transform(cName.begin(), cName.end(), cName.begin(), (int(*)(int))toupper);
|
|
|
- if(cName==ourName)
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x, cp->y+1, src.z), hero)))
|
|
|
{
|
|
|
- for(int u=0; u<6; ++u)
|
|
|
- {
|
|
|
- blockMap[u] = CGI->dobjinfo->objs[y].blockMap[u];
|
|
|
- }
|
|
|
- break;
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x, cp->y+1, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
}
|
|
|
}
|
|
|
- for(int i=0; i<6; ++i)
|
|
|
+ }
|
|
|
+ if(cp->x<graph.size() && cp->y<graph[0].size())
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x+1][cp->y+1];
|
|
|
+ if(!dp->visited)
|
|
|
{
|
|
|
- for(int j=0; j<8; ++j)
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y+1, src.z), hero)))
|
|
|
{
|
|
|
- int cPosX = CGI->objh->objInstances[h]->pos.x - j;
|
|
|
- int cPosY = CGI->objh->objInstances[h]->pos.y - i;
|
|
|
- if(cPosX>0 && cPosY>0)
|
|
|
- {
|
|
|
- graph[cPosX][cPosY].accesible = blockMap[i] & (128 >> j);
|
|
|
- }
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y+1, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(cp->x>0 && cp->y<graph[0].size())
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x-1][cp->y+1];
|
|
|
+ if(!dp->visited)
|
|
|
+ {
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y+1, src.z), hero)))
|
|
|
+ {
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y+1, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(cp->x<graph.size() && cp->y>0)
|
|
|
+ {
|
|
|
+ CPathNode * dp = graph[cp->x+1][cp->y-1];
|
|
|
+ if(!dp->visited)
|
|
|
+ {
|
|
|
+ if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y-1, src.z), hero)))
|
|
|
+ {
|
|
|
+ dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y-1, src.z), hero);
|
|
|
+ dp->theNodeBefore = cp;
|
|
|
+ mq.push(dp);
|
|
|
+ dp->visited = true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- //graph initialized
|
|
|
|
|
|
+ CPathNode * curNode = graph[dest.x][dest.y];
|
|
|
+ CPath * ret = new CPath;
|
|
|
+
|
|
|
+ while(curNode!=graph[src.x][src.y] && curNode != NULL)
|
|
|
+ {
|
|
|
+ ret->nodes.push(*curNode);
|
|
|
+ curNode = curNode->theNodeBefore;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int i=0; i<graph.size(); ++i)
|
|
|
+ {
|
|
|
+ for(int j=0; j<graph[0].size(); ++i)
|
|
|
+ delete graph[i][j];
|
|
|
+ }
|
|
|
|
|
|
- return NULL;
|
|
|
+ return ret;
|
|
|
}
|