#pragma once #ifndef __RAILMOVEHPP__ #define __RAILMOVEHPP__ #include "mw4.hpp" #include "adept\applicationtask.hpp" #include "aiutils.hpp" #include "vehicle.hpp" #include #include "quadtree.hpp" #pragma warning(push) #include #include #pragma warning (pop) // Editor specific code //#ifdef GAMEEDITOR #include //#endif //#include "utils\utils.h" //-------------------------------------------------------------------- Stuff::Scalar GetMapY(Stuff::Scalar x, Stuff::Scalar z); namespace MW4AI { extern HGOSHEAP g_AIHeap,g_MoverAIHeap,g_CombatAIHeap,g_RailHeap; typedef void (*WorkCallBack) (float); extern Stuff::Scalar MinZ, MaxZ, MinX, MaxX; extern bool twofalse[2],twotrue[2]; extern int twomax[2]; class CRailNode; class CRailLink; class CRailGraph; class CMoveGrid; class CAirMoveGrid; class CPathRequest; class CGridPath; class CRailPath; class CMoveRectList; struct OBRect; const int MAXLINKS=10000; const int MAXNODES=2000; const int MINLINKCALC = 10; const int MAXLINKCALC = 15; const int LINKDIST = 300; const int BLOCK_GRID_SIZE = 128; const int BLOCK_GRID_RES = 10; // meters per cell const int MACROBLOCK_GRID_RES = 80; // meters per cell const int MACROBLOCK_GRID_SIZE = 1280 / MACROBLOCK_GRID_RES; const int BLOCK_TO_MACROBLOCK = (MACROBLOCK_GRID_RES / BLOCK_GRID_RES); const int AIR_BLOCK_GRID_SIZE = 64; const int AIR_BLOCK_GRID_RES = 20; // meters per cell const int GRIDMOVE_FAIL_THRESHOLD = 250; // number of cells to visit before failure to find path const int GRIDMOVE_MAX_CHECK_THRESHOLD = 5000; // mapquery project has a copy of these also. const unsigned char AIRPASS_FLAG = 0x01; // true if air units cannot pass const unsigned short LEGPASS_FLAG = 0x0001; // true if legged units cannot use const unsigned short HOVERPASS_FLAG = 0x0002; // true if hover units cannot use const unsigned short TRACKPASS_FLAG = 0x0004; // true if track units cannot use const unsigned short WHEELPASS_FLAG = 0x0008; // true if wheel units cannot use const unsigned short WATERPASS_FLAG = 0x0010; // true if water units cannot use const unsigned short JUMPPASS_FLAG = 0x0020; // true if cannot jump through const unsigned short MOVEPASSNOW_FLAG = 0x0040; // if a vehicle has this cell blocked now const unsigned short BRIDGE_FLAG = 0x0080; // true if this cell is a bridge cell const unsigned short WATER1_FLAG = 0x0100; // with water 2 for four levels of water const unsigned short WATER2_FLAG = 0x0200; // no, shallow, medium, deep const unsigned short STEEP1_FLAG = 0x0400; // with steep 2 for steepness of slope for descending, going up uses blocked flags const unsigned short STEEP2_FLAG = 0x0800; // mech down, track down, wheel down, hover down const unsigned short SLOPEDIR1_FLAG = 0x1000; // quanta of slope direction const unsigned short SLOPEDIR2_FLAG = 0x2000; const unsigned short SLOPEDIR3_FLAG = 0x4000; const int HOVERDOWN_SLOPE = 0; const int WHEELDOWN_SLOPE = 1; const int TRACKDOWN_SLOPE = 2; const int LEGDOWN_SLOPE = 3; const int STEEP_MASK = 0x0c00; const int STEEP_SHIFT = 10; const int NO_WATER = 0; const int SHALLOW_WATER = 1; const int MEDIUM_WATER = 2; const int DEEP_WATER = 3; const int WATER_MASK = 0x0300; const int WATER_SHIFT = 8; const int SLOPEDIR_MASK = 0x7000; const int SLOPEDIR_SHIFT = 12; const int UPSLOPE_STRAIGHT_COST = 14; const int UPSLOPE_DIAG_COST = 21; const int STRAIGHT_COST = 10; const int DIAG_COST = 15; const int DOWNSLOPE_STRAIGHT_COST = 13; const int DOWNSLOPE_DIAG_COST = 19; // const float LEGUP_SLOPE_THRESHOLD = 0.707f; //cos (45 deg) // const float LEGDOWN_SLOPE_THRESHOLD = 0.5f; //cos (60 deg) // const float TRACKUP_SLOPE_THRESHOLD = 0.819f; //cos (35 deg) // const float TRACKDOWN_SLOPE_THRESHOLD = 0.707f; //cos (45 deg) // const float WHEELUP_SLOPE_THRESHOLD = 0.906f; //cos (25 deg) // const float WHEELDOWN_SLOPE_THRESHOLD = 0.819f; //cos (35 deg) // const float HOVERUP_SLOPE_THRESHOLD = 0.965f; //cos (15 deg) // const float HOVERDOWN_SLOPE_THRESHOLD = 0.906f; //cos (25 deg) const unsigned short BLOCKED_FLAGS = 0x003f; // for all blocked flags //-------------------------------------------------------------------- // note: these two areas of const's must match const int JUMPFLAG = 0x0001; const int TRACKFLAG = 0x0002; const int FLYFLAG = 0x0004; const int WHEELFLAG = 0x0008; const int LEGFLAG = 0x0010; const int HOVERFLAG = 0x0020; const int HELIFLAG = 0x0040; const int WATERFLAG = 0x0100; const int BRIDGEFLAG = 0x0080; // implied from data so not listed as index const int JUMPINDEX = 0; const int TRACKINDEX = 1; const int FLYINDEX = 2; const int WHEELINDEX = 3; const int LEGINDEX = 4; const int HOVERINDEX = 5; const int HELIINDEX = 6; const int BRIDGEINDEX = 7; const int WATERINDEX = 8; const int NUM_MOVE_TYPES = 9; struct gridpoint { int x,y; gridpoint (int p1,int p2); gridpoint (float p1,float p2); }; void FillCircle (stlport::vector& points,Stuff::Point3D center,Stuff::Scalar rad); //-------------------------------------------------------------------- typedef CRailNode *CRailNodePtr; typedef CRailLink *CRailLinkPtr; class CRailLink { friend class CRailGraph; private: unsigned int m_ID; CRailNode *m_Loc[2]; unsigned int m_LocID[2]; float m_Weight[NUM_MOVE_TYPES][2]; float m_CalcedWeight[NUM_MOVE_TYPES][2]; int m_Bridge; // id of bridge object int m_UsageFlags[2]; void ID (unsigned int id) { m_ID = id; } ~CRailLink(); public: // would you believe that all this is to just draw a single line? static void ConstructLinkObjectStream(int id,Stuff::MemoryStream *stream,Stuff::NotationFile *model_file); void DumpNotationFile (Stuff::NotationFile *file); CRailLink (Stuff::MemoryStream *stream,CRailGraph *parent); CRailLink (void); CRailLink (CRailNode *loc1,CRailNode *loc2,float weight[NUM_MOVE_TYPES][2],bool jump[2] = twofalse,bool track[2]=twofalse,bool fly[2]=twofalse,bool wheel[2]=twofalse,bool leg[2]=twotrue,bool hover[2] =twofalse,bool heli[2] = twofalse); CRailLink (CRailNode *loc1,CRailNode *loc2,float weight[NUM_MOVE_TYPES][2],int moveflags[2] = twomax); int Bridge (void) const { return m_Bridge; } void Bridge (int id) { m_Bridge = id; } void DestroyBridge (void); float Weight (int type,CRailNode *src) const; float LowestWeight (int usage,int &type,CRailNode *src) const; bool Jump (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & JUMPFLAG; else return m_UsageFlags[1] & JUMPFLAG; #pragma warning (default:4800) } bool Tracked (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & TRACKFLAG; else return m_UsageFlags[1] & TRACKFLAG; #pragma warning (default:4800) } bool Flyer (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & FLYFLAG; else return m_UsageFlags[1] & FLYFLAG; #pragma warning (default:4800) } bool Wheeled (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & WHEELFLAG; else return m_UsageFlags[1] & WHEELFLAG; #pragma warning (default:4800) } bool Legged (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & LEGFLAG; else return m_UsageFlags[1] & LEGFLAG; #pragma warning (default:4800) } bool Hover (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & TRACKFLAG; else return m_UsageFlags[1] & HOVERFLAG; #pragma warning (default:4800) } bool Heli (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & HELIFLAG; else return m_UsageFlags[1] & HELIFLAG; #pragma warning (default:4800) } bool Water (CRailNode *src) const { #pragma warning (disable :4800) if (m_Loc[0] == src) return m_UsageFlags[0] & WATERFLAG; else return m_UsageFlags[1] & WATERFLAG; #pragma warning (default:4800) } void Weight (float amount,int which,CRailNode *src,bool calc=false); void Jump (bool p1,CRailNode *src); void Tracked (bool p1,CRailNode *src); void Flyer (bool p1,CRailNode *src); void Wheeled (bool p1,CRailNode *src); void Legged (bool p1,CRailNode *src); void Hover (bool p1,CRailNode *src); void Heli (bool p1,CRailNode *src); unsigned int ID (void) const { return m_ID; } const CRailNode *Location (unsigned int id) const; unsigned int LocID (unsigned int id) const; CRailNode *OtherLocation (const CRailNode *temp); CRailNode *Location (int id); void TestInstance (void) const {} }; class CRailNode { friend class CRailGraph; private: struct RailSubNode { Stuff::Point3D location; RailSubNode (void) { location = Stuff::Point3D (0,0,0); } RailSubNode (const Stuff::Point3D& loc) { location = loc; } RailSubNode (Stuff::Scalar p1,Stuff::Scalar p2,Stuff::Scalar p3); RailSubNode (const RailSubNode& p1) { location = p1.location; } RailSubNode& operator= (const RailSubNode& p1); }; unsigned int m_ID; bool m_Dirty; bool m_DistanceValid; Stuff::Point3D m_Location; stlport::vector m_Links; stlport::vector m_SubNodes; stlport::vector m_EditorDistance; // only allocated in the editor float m_PathWeight; // used in the path finding code weight to get to this node float m_PathEstimate; // used in the path finding code weight from this node to the dest int m_PathType; // used in the path finding code type of movement to get to this node Stuff::Scalar m_Radius,m_RadiusSquared,m_MaxRadius,m_SubNodeRadiusMult; void SubNodeRadiusMult(Stuff::Scalar mult) { m_SubNodeRadiusMult = mult;} void ID (unsigned int id) { m_ID = id; } ~CRailNode (void); public: // Draw a circle for the radius static void ConstructNodeObjectStream(int id,Stuff::MemoryStream *stream,Stuff::NotationFile *model_file); void DumpNotationFile (Stuff::NotationFile *file); CRailNode (const Stuff::Point3D& loc,Stuff::Scalar rad); CRailNode (Stuff::MemoryStream *stream,CRailGraph *parent); CRailLink *LinkTo (CRailNode *dest); float LinkLength (CRailLink *link); // only length for non intersecting parts, negative if overlap with abs = to dist center to center bool PtInNode (const Stuff::Point3D& pt); Stuff::Point3D Location (void) const { return m_Location; } void Location (const Stuff::Point3D& newloc); unsigned int ID (void) const { return m_ID; } Stuff::Scalar Radius (void) const { return m_Radius; } Stuff::Scalar RadiusSquared (void) const { return m_RadiusSquared; } void Radius (Stuff::Scalar newrad); void SetRadiusToMax (void); void CheckRadius(); int NumLinks (void) const { return m_Links.size (); } CRailLink *Link (unsigned int id) const; void ClearLinks (void); RailSubNode SubNode (unsigned int id); RailSubNode SubNode (CRailLink *link); unsigned int LinkID (unsigned int index); void AddLink (CRailLink *link); void DeleteLink (CRailLink *link); float EditorDistance (CRailNode *dest) const; float EditorDistance (unsigned int id) const; // Path finding support float PathWeight (void) const { return m_PathWeight; } float PathEstimate (void) const { return m_PathEstimate; } int PathType (void) const { return m_PathType; } bool PathWeight (float newvalue,float estimate,int type); // true if changed void ClearPathWeight (float newvalue,float newestimate,int type); void TestInstance (void) const {} }; struct NodeDist { CRailNode *src; CRailNode *dest; NodeDist (void) { src = dest = NULL; } NodeDist (const NodeDist& p1) { src = p1.src; dest = p1.dest; } NodeDist (CRailNode *p1,CRailNode *p2) { src = p1; dest = p2; } }; struct raildistcmp : binary_function { bool operator()(const NodeDist& _X, const NodeDist& _Y) const {return _X.src->EditorDistance (_X.dest) < _Y.src->EditorDistance (_Y.dest); } }; class CRailSquare { public: Stuff::Scalar height; BYTE material; Stuff::Normal3D normal; int waterlevel; int objectid; int bridge; // id of bridge object bool walkthruflag; Stuff::Scalar objectheight; CRailSquare (void); void Construct (Stuff::Scalar x,Stuff::Scalar z); }; class CRailWorkGrid { protected: QuadTree m_QuadTree; bool workarray[2048][2048]; stlport::vector > m_Grid; float CheckSquare (int cx,int cy,int movetype); void MarkBuilding (Stuff::ExtentBox& box,int id,bool bridge,CMoveGrid *movegrid,CAirMoveGrid *airmovegrid,bool walkthruflag); public: CRailWorkGrid (void); void Construct (WorkCallBack callback,float maxpercent,CMoveGrid *movegrid,CAirMoveGrid *airmovegrid); Stuff::Scalar CalcWeight (Stuff::Point3D src, Stuff::Point3D dest,int movetype); Stuff::Scalar MaterialMode (int x,int y,int movetype); Stuff::Scalar CalcRadius (const Stuff::Point3D& center,Stuff::Scalar maxrad); bool BuildingAt (const Stuff::Point3D&); Stuff::Scalar Slope (const Stuff::Point3D& loc); Stuff::Scalar Slope (int x,int y); int CalcBridgeLink (Stuff::Point3D src, Stuff::Point3D dest); bool AnalyzeNode (QuadTreeNode *node); }; class CAirMoveGrid { private: DWORD m_Width,m_Height; // in meters unsigned char **m_Data; // two dimensional array for width and height. AIR_PASS_FLAG flags at top DWORD m_AllocWidth,m_AllocHeight; public: CAirMoveGrid (Stuff::MemoryStream *stream); CAirMoveGrid (void); ~CAirMoveGrid (void) { Destroy (); } void Destroy (void); void SaveData (const char *filename); static void ConstructStream (Stuff::MemoryStream *stream,const char *filename); void Construct (int width,int height); void Clear (void); void Passable (Stuff::Scalar x,Stuff::Scalar z,unsigned char canpass,bool override = false); // in meters void PassableLocal (int x,int z,unsigned char canpass,bool override=false); // in local unsigned char Passable (Stuff::Scalar x,Stuff::Scalar z) const; // in meters unsigned char PassableLocal (int x,int z) const; // in local }; class CMoveGrid { private: DWORD m_Width,m_Height; // in meters unsigned short *m_Data; // two dimensional array for width and height. PASS_FLAG flags at top // unsigned short **m_Data; // two dimensional array for width and height. PASS_FLAG flags at top unsigned char **m_MacroData; // 40 meter grid for whether a cell is open, same size in width and height at m_Data // 0 is totatlly open 1 is some form of blocking DWORD m_AllocWidth,m_AllocHeight; DWORD m_MacroAllocWidth,m_MacroAllocHeight; static void ConvertOldStyle (Stuff::MemoryStream *stream,DWORD *data,DWORD filesize); static void ConvertOldStyle2 (Stuff::MemoryStream *stream,DWORD *data,DWORD filesize); void CreateMacroData (void); void DeleteMacroData (void); public: CMoveGrid (Stuff::MemoryStream *stream); CMoveGrid (void); ~CMoveGrid (void) { Destroy (); } void Destroy (void); void SaveData (const char *filename); static bool ConstructStream (Stuff::MemoryStream *stream,const char *filename); void Construct (int width,int height); void Clear (void); void Passable (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass); // in meters void PassableLocal (int x,int z,unsigned short canpass); // in local void PassableOverride (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass); // in meters void PassableLocalOverride (int x,int z,unsigned short canpass); // in local unsigned short Passable (Stuff::Scalar x,Stuff::Scalar z) const; // in meters unsigned short PassableLocal (int x,int z) const; // in local unsigned char MacroPassable (Stuff::Scalar x,Stuff::Scalar z) const; // in meters unsigned char MacroPassableLocal (int x,int z) const; // in local }; typedef CRailNode *CRailNodePtr; typedef Adept::Receiver__ClassData CRailGraph__ClassData; typedef Adept::Receiver__Message CRailGraph__Message; class CRailGraph : public Adept::Receiver { private: stlport::vector m_Links; stlport::vector m_Nodes; stlport::vector m_BlockedLinks; bool m_Dirty; CRailWorkGrid *m_WorkGrid; CMoveGrid *m_MoveGrid; CAirMoveGrid *m_AirMoveGrid; int m_WorkGridRefCount; CMoveRectList *m_RectList; void CalcEditorDistances (void); void AnalyzePaths (void); void AddBridgeLinks (void); int CalcBridgeLink (Stuff::Point3D src, Stuff::Point3D dest); bool TestBridge (int id,int node1,int node2); bool LinkWeight (CRailLink *link); public: typedef CRailGraph__ClassData ClassData; typedef CRailGraph__Message Message; bool BridgeNear (Stuff::Point3D& start,Stuff::Point3D& end); bool m_SaveLineElementMemory; Stuff::Point3D PullPointElement (Stuff::Point3D& start,Stuff::Point3D& end,int usage); Stuff::Point3D PullPointElementMask (Stuff::Point3D& start,Stuff::Point3D& end,int mask); bool PointOpen (Stuff::Scalar x,Stuff::Scalar y,int pass); unsigned short Passable (Stuff::Scalar x,Stuff::Scalar z) const; unsigned short PassableLocal (int x,int z) const; // in local void Passable (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass); // in meters void PassableLocal (int x,int z,unsigned short canpass); // in local void PassableOverride (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass); // in meters void PassableLocalOverride (int x,int z,unsigned short canpass); // in local unsigned char MacroPassable (Stuff::Scalar x,Stuff::Scalar z) const; // in meters unsigned char MacroPassableLocal (int x,int z) const; // in local unsigned char AirPassable (Stuff::Scalar x,Stuff::Scalar z) const; unsigned char AirPassableLocal (int x,int z) const; // in local void AirPassable (Stuff::Scalar x,Stuff::Scalar z,unsigned char canpass,bool override = false); // in meters void AirPassableLocal (int x,int z,unsigned char canpass,bool override=false); // in local CRailGraph (ClassData *class_data); CRailGraph (ClassData *class_data,Stuff::MemoryStream *stream); ~CRailGraph (void); void CreateGrid (WorkCallBack callback,float maxpercent); void KillGrid (void); void ClearLinks (int *start,int numnodes); void ClearLinks (void); static ClassData *DefaultData; static void ConstructGraphObjectStream(Stuff::MemoryStream *stream,Stuff::NotationFile *model_file); bool QuickCheck (int x1,int y1,int x2,int y2,unsigned short mask,bool widthvalid=true); bool AirQuickCheck (int x1,int y1,int x2,int y2); bool MoveTo (int x,int y,int dir,int mask); // in local coordinates dir is from mask list int UpDownTo (int x,int y,int dir,int mask); // in local coordinates dir is from mask list static void InitializeClass(); static void TerminateClass(); void BlockLink (int node1,int node2); void RemoveBlock (int node); int AddNode (CRailNode *node); int AddLink (CRailLink *link); int AddLink (unsigned int n1,unsigned int n2,float weight[NUM_MOVE_TYPES][2],int moveflags[2] = twomax); int AddLink (CRailNode *n1,CRailNode *n2,float weight[NUM_MOVE_TYPES][2],int moveflags[2] = twomax); void ClearPathFlags (void); CRailNode *FindClosestNode (const Stuff::Point3D& loc,bool strict=true,CRailNode *firstcheck = NULL); void FindBestNode (const Stuff::Point3D& start,const Stuff::Point3D& end,bool strict,CRailNodePtr& startnode,CRailNodePtr& endnode); float Connect (CRailNode *src,CRailNode *dest,int usagetype) const; int Connect (CRailNode *src,CRailNode *dest) const; int NumNodes(void) const { return m_Nodes.size(); } int NumLinks(void) const { return m_Links.size(); } int CountNodes(void) const; int CountLinks(void) const; CRailLink *Link (unsigned int id); CRailNode *Node (unsigned int id); void DeleteNode (unsigned int id); void DeleteLink (unsigned int id); void DeleteLink (unsigned int node1,unsigned int node2); void TestInstance (void) const; const CMoveRectList *RectList (void) const { return m_RectList; } // editor support void DumpNotationFile (Stuff::NotationFile *file,const char *passfile,const char *rectfile,const char *airpassfile); void CalcLinks (int min = MINLINKCALC,int max = MAXLINKCALC,int range = LINKDIST,WorkCallBack callback = NULL); void CalcLinks (int *start,int numnodes,int min = MINLINKCALC,int max = MAXLINKCALC,int range = LINKDIST,WorkCallBack callback= NULL); void UpdateNodes (WorkCallBack callback,float percentstart); void CreateBasicNodes (int number,WorkCallBack callback); void CreateRectData (WorkCallBack callback); Stuff::Scalar m_SubNodeRadiusMult; }; struct railnodecmp : binary_function { bool operator()(const CRailNode *_X, const CRailNode *_Y) const { float c1,c2; c1 = _X->PathWeight () + _X->PathEstimate (); c2 = _Y->PathWeight () + _Y->PathEstimate (); return c1 < c2; } }; class CRailPath { public: struct NodePathElement { CRailLink *link; CRailNode *destnode; int usage; NodePathElement (void) { link = NULL; destnode = NULL; usage = 0; } NodePathElement (CRailLink *p1,CRailNode *p2,int p3) { link = p1; destnode = p2; usage = p3; } void Save (MemoryStream *stream); void Load (MemoryStream *stream); }; struct PathElement { Stuff::Point3D loc; int usage; bool onrail; int linkid; PathElement (void); PathElement (const Stuff::Point3D& p1,int p2,bool p3,int p4); bool operator== (const PathElement& p1); void Save (MemoryStream *stream); void Load (MemoryStream *stream); }; private: Stuff::Point3D m_Start; Stuff::Point3D m_End; Stuff::Point3D m_HeadPoint; MechWarrior4::MoverAI *m_AI; int m_UsageAllowed; CRailNode *m_StartNode,*m_EndNode; CRailGraph *m_Graph; CPathRequest *m_SubPathRequest; bool m_Calced; bool m_Strict; bool m_TenMeterAllowed; bool m_QuickPath; bool m_NearLastFrame; stlport::vector m_NodePath; stlport::vector m_Path; int m_InNodePath; stlport::vector::iterator m_InPath; CGridPath *m_SubPath; bool NewSubPath (const Stuff::Point3D& loc); float CostGuess (CRailNode *src); //------------------- // following support public: enum PATHSTATES { RAIL_START_PATH, RAIL_MOVE_NO_RAIL, RAIL_NEXT_STEP, RAIL_HEAD_EXIT_SUB, RAIL_MOVE_RAIL, RAIL_MOVE_ENDPOINT, RAIL_MOVE_WAITING, // waiting for a subpath calc to end RAIL_FINISH }; private: PATHSTATES m_State; void CalcOutVec (Stuff::Point3D& outvec); void ConvertNodeToPath (void); void ReverseList (void); void DumpPath (void); void CreatePathRequests (void); bool PointBehind (const Stuff::Point3D& loc,const Stuff::Point3D& dest); void AddStartPoint (Stuff::Point3D& loc,bool& startbrid,stlport::vector::iterator& iter); void AddBridgeToPath (stlport::vector::iterator iter,Stuff::Point3D& loc,const OBRect *bridge,bool startbrid); void AddPointToPath (stlport::vector::iterator iter,Stuff::Point3D& loc); void AddJumpPoint (stlport::vector::iterator iter,Stuff::Point3D& loc); void AddEndPoint (Stuff::Point3D& loc); void HandleOneNodePath (void); public: CRailPath (CRailGraph *graph,const Stuff::Point3D& start,const Stuff::Point3D& end,bool strict,MechWarrior4::MoverAI *ai,bool tenmeter); CRailPath (CRailGraph *graph,CRailNode *start,CRailNode *end,MechWarrior4::MoverAI *ai,bool tenmeter); CRailPath (CRailGraph *graph,MechWarrior4::MoverAI *ai); ~CRailPath (void); void Save (MemoryStream *stream); void Load (MemoryStream *stream); bool Calced (void) const { return m_Calced; } bool QuickPath (void) const { return m_QuickPath; } void Reverify (int usage); bool JumpSoon (void) const; void CalcPath (int usage); int CurLink (void) const; Stuff::Point3D CurrentPoint (void) const; // next link in path Stuff::Point3D NextPoint (void) const; // next link in path bool Next (const Stuff::Point3D& loc); Stuff::Point3D Heading (void) const { return CurrentPoint (); } PATHSTATES State (void) const { return m_State; } void Tick (const Stuff::Point3D& loc,Stuff::Time till,Stuff::Scalar speed,Stuff::Point3D& outvec,bool& jump,bool& prejump); void TestInstance (void) const {Verify (m_State>=RAIL_START_PATH); Verify (m_State <=RAIL_FINISH);} Stuff::Point3D Start (void) const { return m_Start; } Stuff::Point3D End (void) const { return m_End; } void UpdateSrcDest (CRailNode *src,CRailNode *dest); void UpdateSrcDest (const Stuff::Point3D& src,const Stuff::Point3D& dest); void PointList (stlport::vector& dest); }; class CGridPath { friend struct gridpathcmp; public: struct GridPathElement { int locX,locY; GridPathElement (void) { locX = 0; locY = 0;} GridPathElement (int p1,int p2) { locX = p1; locY = p2; } bool operator== (const GridPathElement& p1) { return (p1.locX == locX) && (p1.locY == locY); } }; struct DirElement { int locX,locY; DirElement (void) { locX = -1; locY = -1;} DirElement (int p1,int p2) { locX = p1; locY = p2; } }; bool DirPathValid() const { return (m_InDirPath != m_DirList.end()); } private: stlport::vector::iterator m_InDirPath; stlport::vector m_DirList; int m_StartX,m_StartY,m_EndX,m_EndY; bool m_Calced; bool m_Working; bool m_QuickValid; bool m_TenMeterAllowed; int m_WorkCount; unsigned short m_Mask; CRailGraph *m_Graph; my_heap calc; static CGridPath *m_WorkingPath; static int m_BlockOriginX,m_BlockOriginY; static unsigned int m_BlockGrid[BLOCK_GRID_SIZE][BLOCK_GRID_SIZE][2]; // lower number is current cost, upper is estimate static unsigned int Cost (int sx,int sy); static unsigned int Estimate (int sx,int sy); static bool Cost (int sx,int sy,unsigned int cost,unsigned int estimate); static unsigned int Cost (const GridPathElement& p1) { return Cost (p1.locX,p1.locY); } static unsigned int Estimate (const GridPathElement& p1) { return Estimate (p1.locX,p1.locY); } static bool Cost (const GridPathElement& p1,unsigned int cost,unsigned int estimate) { return Cost (p1.locX,p1.locY,cost,estimate); } int CostGuess (int sx,int sy); int AdjustCost (int cx,int cy); // will adjust the cost based on locality to blocked terrain void ReverseList (void); // bool QuickCheck (int x1,int y1,int x2,int y2); void ConstructQuickPath (void); void DumpPath (void); void SmoothList (void); void SmoothListHelper (stlport::vector& vec,int s,int e); void Calc30Path (void); void Calc10Path (void); void StartCalcPath (void); void ContinueCalcPath (void); public: virtual void Save (MemoryStream *stream); virtual void Load (MemoryStream *stream); CGridPath (CRailGraph *graph); CGridPath (CRailGraph *graph,unsigned short mask,int sx,int sy,int dx,int dy,bool tenmeter); CGridPath (CRailGraph *graph,unsigned short mask,Stuff::Scalar sx,Stuff::Scalar sy,Stuff::Scalar dx,Stuff::Scalar dy,bool tenmeter); ~CGridPath (void); void DoCalcPath (void); bool Working (void) { return m_Working; } bool Calced (void) const { return m_Calced; } bool QuickValid (void) const { return m_QuickValid; } bool Next (void); // true if path still exists Stuff::Point3D NextPoint (void) const; // next link in path bool OneFromEnd (void) const; // at end is also good Stuff::Point3D CurrentPoint (void) const; // int size (void) // { return m_Path.size (); } DirElement direlement (int index); int dirsize (void) { return m_DirList.size (); } void UpdateSrcDest (int sx,int sy,int dx,int dy); void UpdateSrcDest (Stuff::Scalar sx,Stuff::Scalar sy,Stuff::Scalar dx,Stuff::Scalar dy); void PointList (stlport::vector& dest); Stuff::Point3D End (void) { return Point3D ((Scalar) m_EndX,0.0f,(Scalar) m_EndY); } }; struct gridpathcmp : binary_function { bool operator()(const CGridPath::GridPathElement& _X, const CGridPath::GridPathElement& _Y) const { int c1,c2; c1 = CGridPath::Cost (_X) + CGridPath::Estimate (_X); c2 = CGridPath::Cost (_Y) + CGridPath::Estimate (_Y); return c1Location(); m_RailLinkPointData[0].y += 0.5f; m_RailLinkPointData[1] = m_Loc[1]->Location(); m_RailLinkPointData[1].y += 0.5f; } */ } #include "rail_move.inl" #endif