Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
728 lines
15 KiB
C++
728 lines
15 KiB
C++
#pragma warning (disable:4786)
|
|
#include <utils\utils.h>
|
|
#include "map.hpp"
|
|
#include "move.hpp"
|
|
#include "movezone.hpp"
|
|
#include <map>
|
|
|
|
CMapCell g_MapCells[MAPCELLCOUNT][MAPCELLCOUNT];
|
|
|
|
std::map<int,float> pathmapzone[MAPCELLCOUNT][MAPCELLCOUNT][2]; // index is for the topleft cell of each src,dest pair the 2 is for the offset table-2
|
|
|
|
bool SetWeight (int sx,int sy,int offset,int areaentry,int areaexit,float newweight)
|
|
{
|
|
int ix,iy,io;
|
|
int index;
|
|
int temp;
|
|
std::map<int,float>::iterator iter;
|
|
|
|
ix = sx;
|
|
iy = sy;
|
|
io = offset;
|
|
|
|
switch (offsetzone[offset][2])
|
|
{
|
|
case 0:
|
|
ix--;
|
|
temp = areaentry;
|
|
areaentry = areaexit;
|
|
areaexit = temp;
|
|
break;
|
|
case 1:
|
|
iy--;
|
|
temp = areaentry;
|
|
areaentry = areaexit;
|
|
areaexit = temp;
|
|
break;
|
|
case 2:
|
|
io-=2;
|
|
break;
|
|
case 3:
|
|
io-=2;
|
|
break;
|
|
}
|
|
assert (ix>=0);
|
|
assert (ix<MAPCELLCOUNT);
|
|
assert (iy>=0);
|
|
assert (iy<MAPCELLCOUNT);
|
|
assert (io>=0);
|
|
assert (io<2);
|
|
|
|
index = areaentry<<4;
|
|
index += areaexit;
|
|
|
|
iter = pathmapzone[ix][iy][io].find (index);
|
|
if (iter == pathmapzone[ix][iy][io].end ())
|
|
{
|
|
pathmapzone[ix][iy][io][index] = newweight;
|
|
return true;
|
|
}
|
|
if ((*iter).second > newweight)
|
|
{
|
|
pathmapzone[ix][iy][io][index] = newweight;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
float GetWeight (int sx,int sy,int dx,int dy,int areaentry,int areaexit)
|
|
{
|
|
if (abs (sx-dx))
|
|
{
|
|
if (sx > dx)
|
|
return GetWeight (sx,sy,0,areaentry,areaexit);
|
|
else
|
|
return GetWeight (sx,sy,2,areaentry,areaexit);
|
|
}
|
|
else if (abs(sy-dy))
|
|
{
|
|
if (sy > dy)
|
|
return GetWeight (sx,sy,1,areaentry,areaexit);
|
|
else
|
|
return GetWeight (sx,sy,3,areaentry,areaexit);
|
|
}
|
|
assert (false);
|
|
return -1.0;
|
|
}
|
|
|
|
float GetWeight (int sx,int sy,int offset,int areaentry,int areaexit)
|
|
{
|
|
int ix,iy,io;
|
|
int index;
|
|
int temp;
|
|
std::map<int,float>::iterator iter;
|
|
|
|
ix = sx;
|
|
iy = sy;
|
|
io = offset;
|
|
|
|
switch (offsetzone[offset][2])
|
|
{
|
|
case 0:
|
|
ix--;
|
|
temp = areaentry;
|
|
areaentry = areaexit;
|
|
areaexit = temp;
|
|
break;
|
|
case 1:
|
|
iy--;
|
|
temp = areaentry;
|
|
areaentry = areaexit;
|
|
areaexit = temp;
|
|
break;
|
|
case 2:
|
|
io-=2;
|
|
break;
|
|
case 3:
|
|
io-=2;
|
|
break;
|
|
}
|
|
if (ix<0)
|
|
return -1;
|
|
if (ix>=MAPCELLCOUNT)
|
|
return -1;
|
|
if (iy<0)
|
|
return -1;
|
|
if (iy>=MAPCELLCOUNT)
|
|
return -1;
|
|
assert (io>=0);
|
|
assert (io<2);
|
|
index = areaentry<<4;
|
|
index += areaexit;
|
|
iter = pathmapzone[ix][iy][io].find (index);
|
|
if (iter == pathmapzone[ix][iy][io].end ())
|
|
{
|
|
return -1.0;
|
|
}
|
|
return (*iter).second;
|
|
}
|
|
|
|
void InitMoveZoneData (void)
|
|
{
|
|
int curx,cury;
|
|
int x,y;
|
|
for (y=0,cury = 0;y<MAPCELLCOUNT;y++,cury+=(MAPCELLSIZE-1))
|
|
for (x=0,curx=0;x<MAPCELLCOUNT;x++,curx+=(MAPCELLSIZE-1))
|
|
{
|
|
int left,right,top,bottom;
|
|
|
|
left = clamp<int> (0,curx,MAPSIZE-1);
|
|
right = clamp<int> (0,left+MAPCELLSIZE-1,MAPSIZE-1);
|
|
top = clamp<int> (0,cury,MAPSIZE-1);
|
|
bottom = clamp<int> (0,top+MAPCELLSIZE-1,MAPSIZE-1);
|
|
|
|
g_MapCells[x][y].SetSize (left,top,right,bottom);
|
|
}
|
|
for (y=0;y<MAPCELLCOUNT;y++)
|
|
for (x=0;x<MAPCELLCOUNT;x++)
|
|
{
|
|
g_MapCells[x][y].CalcWeight ();
|
|
g_MapCells[x][y].CalcInterior ();
|
|
g_MapCells[x][y].CalcEdges ();
|
|
}
|
|
}
|
|
|
|
CMapCell::CMapCell (void)
|
|
{
|
|
m_WeightAverage = 0;
|
|
m_PassAverage = 0;
|
|
}
|
|
|
|
|
|
CMapCell::~CMapCell (void)
|
|
{
|
|
}
|
|
|
|
void CMapCell::CalcWeight (void)
|
|
{
|
|
int midx,midy,count;
|
|
|
|
m_PassAverage = 0;
|
|
m_WeightAverage = 0;
|
|
count = 0;
|
|
for (midx = m_Left;midx<=m_Right;midx++)
|
|
{
|
|
for (midy=m_Top;midy<=m_Bottom;midy++)
|
|
{
|
|
count++;
|
|
m_WeightAverage+=g_Map[midx][midy].weight;
|
|
if (g_Map[midx][midy].passable)
|
|
{
|
|
m_PassAverage++;
|
|
}
|
|
}
|
|
}
|
|
m_PassAverage /= count;
|
|
m_WeightAverage /= count;
|
|
}
|
|
|
|
void CMapCell::CalcEdges (void)
|
|
{
|
|
int x,y;
|
|
for (x=m_Left;x<=m_Right;x++)
|
|
{
|
|
m_AreaData[m_Areas[x-m_Left][0]].flags |= TOPEDGEMASK;
|
|
m_AreaData[m_Areas[x-m_Left][MAPCELLSIZE-1]].flags |= BOTTOMEDGEMASK;
|
|
}
|
|
for (y=m_Top;y<=m_Bottom;y++)
|
|
{
|
|
m_AreaData[m_Areas[0][y-m_Top]].flags |= LEFTEDGEMASK;
|
|
m_AreaData[m_Areas[MAPCELLSIZE-1][y-m_Top]].flags |= RIGHTEDGEMASK;
|
|
}
|
|
}
|
|
|
|
void CMapCell::CalcArea (int sx,int sy,int id,int info)
|
|
{
|
|
if (sx < 0)
|
|
return;
|
|
if (sy<0)
|
|
return;
|
|
if (sx>=MAPCELLSIZE)
|
|
return;
|
|
if (sy>=MAPCELLSIZE)
|
|
return;
|
|
|
|
if ((m_Areas[sx][sy] == 0) && (SquareInfo (sx+m_Left,sy+m_Top)==info))
|
|
{
|
|
m_Areas[sx][sy] = id;
|
|
CalcArea (sx-1,sy,id,info);
|
|
CalcArea (sx+1,sy,id,info);
|
|
CalcArea (sx,sy-1,id,info);
|
|
CalcArea (sx,sy+1,id,info);
|
|
}
|
|
}
|
|
|
|
void CMapCell::CalcInterior (void)
|
|
{
|
|
int x,y,id;
|
|
float count[MAXAREAS];
|
|
|
|
for (x=0;x<MAPCELLSIZE;x++)
|
|
{
|
|
for (y=0;y<MAPCELLSIZE;y++)
|
|
{
|
|
m_Areas[x][y] = 0;
|
|
}
|
|
}
|
|
id = 1;
|
|
for (x=0;x<MAPCELLSIZE;x++)
|
|
{
|
|
for (y=0;y<MAPCELLSIZE;y++)
|
|
{
|
|
if (m_Areas[x][y])
|
|
continue;
|
|
assert (id<MAXAREAS);
|
|
m_AreaData[id].info = SquareInfo (x+m_Left,y+m_Top);
|
|
if (Passable (x+m_Left,y+m_Top))
|
|
m_AreaData[id].passable = 1;
|
|
else
|
|
m_AreaData[id].passable = 0;
|
|
CalcArea (x,y,id++,SquareInfo (x+m_Left,y+m_Top));
|
|
}
|
|
}
|
|
memset (count,0,sizeof(int)*MAXAREAS);
|
|
for (id=0;id<MAXAREAS;id++)
|
|
m_AreaData[id].weight = 0;
|
|
for (x=0;x<MAPCELLSIZE;x++)
|
|
{
|
|
for (y=0;y<MAPCELLSIZE;y++)
|
|
{
|
|
m_AreaData[m_Areas[x][y]].weight += g_Map[x+m_Left][y+m_Top].weight;
|
|
count[m_Areas[x][y]]++;
|
|
}
|
|
}
|
|
for (id=1;id<MAXAREAS;id++)
|
|
{
|
|
if (count[id] != 0)
|
|
m_AreaData[id].weight /= count[id];
|
|
}
|
|
}
|
|
|
|
void CMapCell::RenderEdges (CDIBSurface& dest,int dx)
|
|
{
|
|
int x,y;
|
|
|
|
for (x=m_Left;x<=m_Right;x++)
|
|
{
|
|
dest.Fill (dx+x*DRAWCELLSIZE,m_Top*DRAWCELLSIZE,dx+(x+1)*DRAWCELLSIZE,(m_Top+1)*DRAWCELLSIZE,RGB (0,255,0));
|
|
dest.Fill (dx+x*DRAWCELLSIZE,m_Bottom*DRAWCELLSIZE,dx+(x+1)*DRAWCELLSIZE,(m_Bottom+1)*DRAWCELLSIZE,RGB (0,255,0));
|
|
}
|
|
for (y=m_Top;y<=m_Bottom;y++)
|
|
{
|
|
dest.Fill (dx+m_Left*DRAWCELLSIZE,y*DRAWCELLSIZE,dx+(m_Left+1)*DRAWCELLSIZE,(y+1)*DRAWCELLSIZE,RGB (0,255,0));
|
|
dest.Fill (dx+m_Right*DRAWCELLSIZE,y*DRAWCELLSIZE,dx+(m_Right+1)*DRAWCELLSIZE,(y+1)*DRAWCELLSIZE,RGB (0,255,0));
|
|
}
|
|
}
|
|
|
|
FixedHeap<CALCZONEELEMENT> CALCZONEELEMENT::m_EmptyCalcZoneElement(1);
|
|
|
|
void CALCZONEELEMENT::operator =(FibHeapNode& RHS)
|
|
{
|
|
CALCZONEELEMENT& fred = (CALCZONEELEMENT&) RHS;
|
|
|
|
sx = fred.sx;
|
|
sy = fred.sy;
|
|
dx = fred.dx;
|
|
dy = fred.dy;
|
|
sarea = fred.sarea;
|
|
darea = fred.darea;
|
|
dir = fred.dir;
|
|
}
|
|
|
|
bool CALCZONEELEMENT::operator ==(FibHeapNode& RHS)
|
|
{
|
|
CALCZONEELEMENT& fred = (CALCZONEELEMENT&) RHS;
|
|
if (sx != fred.sx)
|
|
return false;
|
|
if (sy != fred.sy)
|
|
return false;
|
|
|
|
if (dx != fred.dx)
|
|
return false;
|
|
if (dy != fred.dy)
|
|
return false;
|
|
|
|
if (sarea != fred.sarea)
|
|
return false;
|
|
if (darea != fred.darea)
|
|
return false;
|
|
if (dir != fred.dir)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool CALCZONEELEMENT::operator <(FibHeapNode& RHS)
|
|
{
|
|
CALCZONEELEMENT& fred = (CALCZONEELEMENT&) RHS;
|
|
|
|
float sw,dw;
|
|
|
|
sw = GetWeight (sx,sy,dx,dy,sarea,darea);
|
|
dw = GetWeight (fred.sx,fred.sy,fred.dx,fred.dy,fred.sarea,fred.darea);
|
|
if (sw < dw)
|
|
return true;
|
|
if (dw < sw)
|
|
return false;
|
|
|
|
if (fred.sx < sx)
|
|
return false;
|
|
if (sx < fred.sx)
|
|
return true;
|
|
if (fred.dx < dx)
|
|
return false;
|
|
if (dx < fred.dx)
|
|
return true;
|
|
|
|
if (fred.sy < sy)
|
|
return false;
|
|
if (sy < fred.sy)
|
|
return true;
|
|
if (fred.dy < dy)
|
|
return false;
|
|
if (dy < fred.dy)
|
|
return true;
|
|
|
|
if (sarea < fred.sarea)
|
|
return true;
|
|
if (darea < fred.darea)
|
|
return true;
|
|
|
|
if (dir < fred.dir)
|
|
return true;
|
|
|
|
return true;
|
|
}
|
|
|
|
float GetOneCostZone (int sx,int sy,int offset,int areaentry,int areaexit,int newarea)
|
|
{
|
|
float toret;
|
|
int dx,dy;
|
|
|
|
dx = sx + offsetzone[offset][0];
|
|
dy = sy + offsetzone[offset][1];
|
|
|
|
if (dx<0)
|
|
return -1.0;
|
|
if (dy<0)
|
|
return -1.0;
|
|
if (dx>=MAPCELLCOUNT)
|
|
return -1.0;
|
|
if (dy>=MAPCELLCOUNT)
|
|
return -1.0;
|
|
|
|
if (areaentry == areaexit)
|
|
{
|
|
if (!g_MapCells[sx][sy].AreaData (areaentry).passable)
|
|
return -1.0;
|
|
toret = g_MapCells[sx][sy].AreaData (areaentry).weight;
|
|
}
|
|
else
|
|
{
|
|
if (!g_MapCells[sx][sy].AreaData (areaentry).passable)
|
|
return -1.0;
|
|
if (!g_MapCells[sx][sy].AreaData (areaexit).passable)
|
|
return -1.0;
|
|
toret = g_MapCells[sx][sy].AreaData (areaentry).weight/2.0 + g_MapCells[sx][sy].AreaData (areaexit).weight/2.0;
|
|
}
|
|
//TODO: add support for connection of areas within the zone
|
|
#if 0
|
|
int x,y;
|
|
bool flag;
|
|
switch (offsetzone[offset][2])
|
|
{
|
|
case 0:
|
|
for (y=0;y<MAPCELLSIZE;y++)
|
|
{
|
|
if (g_Map)
|
|
{
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
if (offsetzone[offset][3] != 4) // just and area change, no new zone
|
|
{
|
|
if (!g_MapCells[dx][dy].AreaData (newarea).passable)
|
|
return -1.0;
|
|
toret += g_MapCells[dx][dy].AreaData (newarea).weight;
|
|
toret *= 0.5;
|
|
}
|
|
|
|
|
|
return toret;
|
|
}
|
|
|
|
float PathCostGuessZone (int sx,int sy,int dx,int dy)
|
|
{
|
|
int t1,t2;
|
|
|
|
t1 = dx - sx;
|
|
t2 = dy - dx;
|
|
|
|
__asm
|
|
{
|
|
mov eax,t1
|
|
cdq
|
|
xor eax,edx
|
|
sub eax,edx
|
|
mov t1,eax
|
|
mov eax,t2
|
|
cdq
|
|
xor eax,edx
|
|
sub eax,edx
|
|
mov t2,eax
|
|
}
|
|
// return t1+t2;
|
|
|
|
return t2 < t1 ? (t1+(t2>>1)) : (t2+(t1>>1));
|
|
}
|
|
|
|
CPoint GlobalToCellIndex (CPoint src)
|
|
{
|
|
int i;
|
|
CPoint toret(-1,-1);
|
|
|
|
for (i=0;i<MAPCELLCOUNT;i++)
|
|
{
|
|
if (src.x >= g_MapCells[i][0].Left () && src.x <= g_MapCells[i][0].Right())
|
|
{
|
|
toret.x = i;
|
|
break;
|
|
}
|
|
}
|
|
for (i=0;i<MAPCELLCOUNT;i++)
|
|
{
|
|
if (src.y >= g_MapCells[0][i].Top () && src.y <= g_MapCells[0][i].Bottom())
|
|
{
|
|
toret.y = i;
|
|
break;
|
|
}
|
|
}
|
|
return toret;
|
|
}
|
|
|
|
void FindLowerEdge (int dx,int dy,int endarea,int& sx,int& sy,int& curarea,int& dir,int startx,int starty,int startarea)
|
|
{
|
|
int i,j;
|
|
float cost;
|
|
float minvalue;
|
|
|
|
minvalue = FLT_MAX;
|
|
|
|
for (j=1;j<MAXAREAS;j++)
|
|
{
|
|
for (i=0;i<OFFSIZEZONE;i++)
|
|
{
|
|
cost = GetWeight (dx,dy,i,j,endarea);
|
|
if (cost != -1)
|
|
{
|
|
if ((startx == dx+offsetzone[i][0]) && (starty == dy+offsetzone[i][1]) && (startarea == j))
|
|
{
|
|
sx = startx;
|
|
sy = starty;
|
|
curarea = j;
|
|
dir = (offsetzone[i][2]+2)& 0x03;
|
|
return;
|
|
}
|
|
if (cost<minvalue)
|
|
{
|
|
minvalue = cost;
|
|
sx = dx + offsetzone[i][0];
|
|
sy = dy + offsetzone[i][1];
|
|
curarea = j;
|
|
dir = (offsetzone[i][2]+2) & 0x03;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AddCalcElements (FibHeap& calc,int sx,int sy,int area,float startweight)
|
|
{
|
|
int i,j,temparea;
|
|
int x,y;
|
|
float cost;
|
|
CALCZONEELEMENT *temp;
|
|
|
|
AREADATA& tempdata = g_MapCells[sx][sy].AreaData (area);
|
|
if (tempdata.left_connect)
|
|
{
|
|
i = sx-1;
|
|
j = sy;
|
|
if (i>=0)
|
|
{
|
|
for (y=0;y<MAPCELLSIZE;y++)
|
|
{
|
|
if (g_MapCells[sx][sy].m_Areas[0][y] == area)
|
|
{
|
|
temparea = g_MapCells[i][j].m_Areas[MAPCELLSIZE-1][y];
|
|
cost = GetOneCostZone (sx,sy,0,area,area,temparea);
|
|
assert (cost != -1);
|
|
cost += startweight;
|
|
if (SetWeight (sx,sy,0,area,temparea,cost))
|
|
{
|
|
temp = new CALCZONEELEMENT (sx,sy,i,j,area,temparea,LEFTEDGE);
|
|
calc.Insert (temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (tempdata.top_connect)
|
|
{
|
|
i = sx;
|
|
j = sy-1;
|
|
if (j>=0)
|
|
{
|
|
for (x=0;x<MAPCELLSIZE;x++)
|
|
{
|
|
if (g_MapCells[sx][sy].m_Areas[x][0] == area)
|
|
{
|
|
temparea = g_MapCells[i][j].m_Areas[x][MAPCELLSIZE-1];
|
|
cost = GetOneCostZone (sx,sy,1,area,area,temparea);
|
|
assert (cost != -1);
|
|
cost += startweight;
|
|
if (SetWeight (sx,sy,1,area,temparea,cost))
|
|
{
|
|
temp = new CALCZONEELEMENT (sx,sy,i,j,area,temparea,TOPEDGE);
|
|
calc.Insert (temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tempdata.right_connect)
|
|
{
|
|
i = sx+1;
|
|
j = sy;
|
|
if (i<MAPCELLCOUNT)
|
|
{
|
|
for (y=0;y<MAPCELLSIZE;y++)
|
|
{
|
|
if (g_MapCells[sx][sy].m_Areas[MAPCELLSIZE-1][y] == area)
|
|
{
|
|
temparea = g_MapCells[i][j].m_Areas[0][y];
|
|
cost = GetOneCostZone (sx,sy,2,area,area,temparea);
|
|
assert (cost != -1);
|
|
cost += startweight;
|
|
if (SetWeight (sx,sy,2,area,temparea,cost))
|
|
{
|
|
temp = new CALCZONEELEMENT (sx,sy,i,j,area,temparea,RIGHTEDGE);
|
|
calc.Insert (temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (tempdata.bottom_connect)
|
|
{
|
|
i = sx;
|
|
j = sy+1;
|
|
if (j<MAPCELLCOUNT)
|
|
{
|
|
for (x=0;x<MAPCELLSIZE;x++)
|
|
{
|
|
if (g_MapCells[sx][sy].m_Areas[x][MAPCELLSIZE-1] == area)
|
|
{
|
|
temparea = g_MapCells[i][j].m_Areas[x][0];
|
|
cost = GetOneCostZone (sx,sy,3,area,area,temparea);
|
|
assert (cost != -1);
|
|
cost += startweight;
|
|
if (SetWeight (sx,sy,3,area,temparea,cost))
|
|
{
|
|
temp = new CALCZONEELEMENT (sx,sy,i,j,area,temparea,BOTTOMEDGE);
|
|
calc.Insert (temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CalcPathZone (std::stack<PATHZONEELEMENT> *dest,CPoint gstart,CPoint gend)
|
|
{
|
|
int curarea,endarea,startarea;
|
|
int i,j,k;
|
|
FibHeap calc;
|
|
CALCZONEELEMENT *temp;
|
|
CPoint start,end;
|
|
|
|
assert (gstart.x>=0);
|
|
assert (gstart.x<MAPSIZE);
|
|
assert (gstart.y>=0);
|
|
assert (gstart.y<MAPSIZE);
|
|
|
|
start = GlobalToCellIndex (gstart);
|
|
end = GlobalToCellIndex (gend);
|
|
|
|
|
|
assert (start.x != -1);
|
|
assert (start.y != -1);
|
|
assert (end.x != -1);
|
|
assert (end.y != -1);
|
|
if (start == end)
|
|
{
|
|
// TODO: need to update if start and end zones are the same yet can't get there
|
|
dest->push (PATHZONEELEMENT (start.x,start.y,end.x,end.y,g_MapCells[start.x][start.y].AreaGlobal (gstart.x,gstart.y),g_MapCells[end.x][end.y].AreaGlobal (gend.x,gend.y),-1));
|
|
return true;
|
|
}
|
|
|
|
|
|
int x=-1,y=-1;
|
|
bool done;
|
|
|
|
while (!dest->empty ())
|
|
dest->pop ();
|
|
|
|
for (i=0;i<MAPCELLSIZE;i++)
|
|
for (j=0;j<MAPCELLSIZE;j++)
|
|
for (k=0;k<OFFSIZEZONE;k++)
|
|
{
|
|
pathmapzone[i][j][k].clear ();
|
|
}
|
|
|
|
endarea = g_MapCells[end.x][end.y].AreaGlobal (gend.x,gend.y);
|
|
|
|
curarea = g_MapCells[start.x][start.y].AreaGlobal (gstart.x,gstart.y);
|
|
startarea = curarea;
|
|
AREADATA& tempdata = g_MapCells[start.x][start.y].AreaData (curarea);
|
|
|
|
AddCalcElements (calc,start.x,start.y,curarea,0);
|
|
|
|
done = false;
|
|
while (!done)
|
|
{
|
|
temp = (CALCZONEELEMENT *) calc.ExtractMin ();
|
|
if (temp == NULL)
|
|
break;
|
|
|
|
if ((temp->dx == end.x) && (temp->dy == end.y) && (temp->darea == endarea))
|
|
done = true;
|
|
else
|
|
AddCalcElements (calc,temp->dx,temp->dy,temp->darea,GetWeight (temp->sx,temp->sy,temp->dx,temp->dy,temp->sarea,temp->darea));
|
|
|
|
delete temp;
|
|
}
|
|
|
|
while (temp = (CALCZONEELEMENT *) calc.ExtractMin ())
|
|
delete temp;
|
|
|
|
if (!done)
|
|
return false;
|
|
|
|
done = false;
|
|
int curx,cury;
|
|
|
|
curx = end.x;
|
|
cury = end.y;
|
|
curarea = endarea;
|
|
|
|
|
|
while (!done)
|
|
{
|
|
int dx,dy,darea,dir;
|
|
FindLowerEdge (curx,cury,curarea,dx,dy,darea,dir,start.x,start.y,startarea);
|
|
dest->push (PATHZONEELEMENT (dx,dy,curx,cury,darea,curarea,dir));
|
|
curx = dx;
|
|
cury = dy;
|
|
curarea = darea;
|
|
if ((curx == start.x) && (cury == start.y) && (curarea == startarea))
|
|
{
|
|
done = true;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|