#ifndef __MOVEZONEHPP__ #define __MOVEZONEHPP__ #include #include const int OFFSIZEZONE = 4; const int offsetzone[OFFSIZEZONE][3] = { // third number is the direction l,t,r,b 0,1,2,3 {-1,0,0}, {0,-1,1}, {1,0,2}, {0,1,3} }; const int LEFTEDGEMASK=0x01; const int TOPEDGEMASK=0x02; const int RIGHTEDGEMASK=0x04; const int BOTTOMEDGEMASK=0x08; const int LEFTEDGE = 0; const int TOPEDGE = 1; const int RIGHTEDGE = 2; const int BOTTOMEDGE = 3; struct AREADATA { union { struct { unsigned left_connect:1; unsigned top_connect:1; unsigned right_connect:1; unsigned bottom_connect:1; unsigned passable:1; }; unsigned char flags; }; int info; float weight; bool operator< (const AREADATA& p1) const { return flags < p1.flags; } bool operator== (const AREADATA& p1) const { return flags == p1.flags; } bool operator!= (const AREADATA& p1) const { return flags != p1.flags; } }; struct PATHZONEELEMENT { int sx,sy; // cell id int dx,dy; // cell id int sarea,darea; // sarea is the start area for the edge, darea is the area for the edge on the other cell // sarea may not be the area that you entered the cell on int dir; bool operator< (const PATHZONEELEMENT& p1) const; bool operator== (const PATHZONEELEMENT& p1) const; PATHZONEELEMENT (int nsx,int nsy,int ndx,int ndy,int nsarea,int ndarea,int ndir) {sx=nsx;sy=nsy;dx=ndx;dy=ndy;sarea=nsarea;darea=ndarea;dir=ndir;} PATHZONEELEMENT (void) { sx = -1; sy = -1; dx = -1; dy = -1; sarea = 0;darea = 0;dir = -1;} }; const int MAPCELLSIZE = 16; const int DRAWCELLSIZE=2; bool SetWeight (int sx,int sy,int offset,int areaentry,int areaexit,float newweight); // offset is the index into the offsetzone table float GetWeight (int sx,int sy,int offset,int areaentry,int areaexit); // offset is the index into the offsetzone table float GetWeight (int sx,int sy,int dx,int dy,int areaentry,int areaexit); // offset is the index into the offsetzone table void FindLowerEdge (int dx,int dy,int endarea,int& sx,int& sy,int& curarea,int& dir,int startx,int starty,int startarea); // will get the lowest connection from dx,dy to sx,sy // used to find path in reverse order // will return startx,starty,startarea if there is a choice for this connection CPoint GlobalToCellIndex (CPoint src); bool CalcPathZone (std::stack *dest,CPoint start,CPoint end); // in the zone float GetOneCostZone (int sx,int sy,int offset,int areaentry,int areaexit,int newarea); // offset is the index into the offsetzone table float PathCostGuessZone (int sx,int sy,int dx,int dy); void InitMoveZoneData (void); bool AddCalcElements (FibHeap& calc,int sx,int sy,int area,float startweight); class CALCZONEELEMENT : public FibHeapNode { private: static FixedHeap m_EmptyCalcZoneElement; public: int sx,sy; int dx,dy; int sarea,darea; int dir; CALCZONEELEMENT (int nsx,int nsy,int ndx,int ndy,int nsarea,int ndarea,int ndir) {sx=nsx;sy=nsy;dx=ndx;dy=ndy;sarea=nsarea;darea=ndarea;dir = ndir;} CALCZONEELEMENT (void) { sx = -1; sy = -1; dx = -1; dy = -1; sarea = 0;darea = 0;dir = -1;} virtual void operator =(FibHeapNode& RHS); virtual bool operator ==(FibHeapNode& RHS); virtual bool operator <(FibHeapNode& RHS); // static CALCELEMENT *GetBlankElement (void) { return (CALCELEMENT *) m_EmptyCalcElement.Alloc (); } // static void DoneElement (CALCELEMENT *oldelem) { m_EmptyCalcElement.Free (oldelem); } // void *operator new (size_t size) {return GetBlankElement (); } // void operator delete (void *value,size_t size) { DoneElement ((CALCELEMENT *) value); } }; //const int MAPCELLCOUNT = ((MAPSIZE/(MAPCELLSIZE-1))+((MAPSIZE%(MAPCELLSIZE-1))?1:0)); const int MAPCELLCOUNT = 17; const int MAXAREAS=16; class CMapCell { friend float GetOneCostZone (int sx,int sy,int offset,int areaentry,int areaexit,int newarea); // offset is the index into the offsetzone table friend bool CalcPathZone (std::stack *dest,CPoint start,CPoint end); // in the zone friend bool AddCalcElements (FibHeap& calc,int sx,int sy,int area,float startweight); private: int m_Left,m_Right,m_Bottom,m_Top; float m_WeightAverage; float m_PassAverage; int m_Areas[MAPCELLSIZE][MAPCELLSIZE]; AREADATA m_AreaData[MAXAREAS]; // first four bits are edge connection data l,t,r,b 0,1,2,3 void CalcArea (int sx,int sy,int id,int info); public: CMapCell (void); ~CMapCell (void); /* void Left (int value) { m_Left = value; } void Right (int value) { m_Right = value; } void Top (int value) { m_Top = value; } void Bottom (int value) { m_Bottom = value; } */ int Left (void) { return m_Left; } int Right (void) { return m_Right; } int Top (void) { return m_Top; } int Bottom (void) { return m_Bottom; } float AverageWeight (void) { return m_WeightAverage; } int AreaGlobal (int globalx,int globaly) // takes global coordinates { return m_Areas[globalx-m_Left][globaly-m_Top]; } int AreaLocal (int localx,int localy) // takes coordinates local to this cell { return m_Areas[localx][localy]; } AREADATA AreaData (int area) { return m_AreaData[area]; } void CalcWeight (void); void CalcEdges (void); void CalcInterior (void); void SetSize (int left,int top,int right,int bottom) { assert (left>=0); assert (left=0); assert (right=0); assert (top=0); assert (bottom