#pragma once #ifndef __OBSTACLEHPP__ #define __OBSTACLEHPP__ #pragma warning (push) #include #include #include #include #include #pragma warning (pop) #include "mwobject.hpp" #include "rail_move.hpp" namespace MW4AI { class Rect4DHashTable; const int Rect4DTimeDelta = 10; // means 10th of a second extern Rect4DHashTable *g_Rect4DHash,*g_AirRect4DHash; extern Stuff::Scalar g_MaxBuildingHeight; // above the ground extern Stuff::Scalar g_MaxAirHeight; // above the ground, so stay above movers struct Rect4D { static Stuff::MemoryBlockOf *m_EmptyRect; static Rect4D *GetBlankRect (void) { return (Rect4D *) m_EmptyRect->New (); } static void DoneRect (Rect4D *oldrect) { if (oldrect) m_EmptyRect->Delete (oldrect); } // void *operator new (size_t size) {return gos_Malloc (sizeof (Rect4D)); } // void operator delete (void *value,size_t size) { gos_Free (value); } void *operator new (size_t size) {return GetBlankRect (); } void operator delete (void *value,size_t size) { DoneRect ((Rect4D *) value); } Stuff::Scalar left,right,top,bottom; int time; Stuff::Motion3D velocity; Rect4D *next; Rect4D *prev; Entity *who; void Save (MemoryStream *stream) { Verify (!next); // cannot save member of chain Verify (!prev); Verify (!who); *stream << left; *stream << right; *stream << top; *stream << bottom; *stream << time; *stream << velocity; } void Load (MemoryStream *stream) { *stream >> left; *stream >> right; *stream >> top; *stream >> bottom; *stream >> time; *stream >> velocity; } Rect4D (void) { next = NULL; prev = NULL; who = NULL; } Rect4D (Stuff::Scalar p1,Stuff::Scalar p2,Stuff::Scalar p3,Stuff::Scalar p4,int p5,MWObject *p6,const Stuff::Motion3D& p7) { left = p1; top = p2; right = p3; bottom = p4; time = p5; next = NULL; prev = NULL; who = p6; velocity = p7; if (left > right) { Stuff::Scalar temp; temp = left; left = right; right = temp; } if (top > bottom) { Stuff::Scalar temp; temp = top; top = bottom; bottom = temp; } } bool operator== (const Rect4D& p1) const { if (left != p1.left) return false; if (right != p1.right) return false; if (top != p1.top) return false; if (bottom != p1.bottom) return false; if (time != p1.time) return false; return true; } }; class Rect4DHashTable { private: Rect4D **m_List; Rect4D *m_PermList; int m_TopList; int m_CurrentTime; int m_ListSize; void KillHashLine (int i); int FindHashLine (const Rect4D& entry) const { Verify (entry.time >= m_CurrentTime); int deltatime,loc; deltatime = entry.time - m_CurrentTime; if (deltatime >= m_ListSize) return -1; Verify (deltatime < m_ListSize); loc = m_TopList + deltatime; if (loc >= m_ListSize) loc = deltatime - (m_ListSize - m_TopList); Verify (loc>=0); Verify (loc < m_ListSize); return loc; } void IncrementTime (void); void RemovePermRect (Rect4D *current) { Rect4D *temp; temp = current; current = current->next; if (m_PermList == temp) m_PermList = temp->next; if (temp->prev) temp->prev->next = temp->next; if (temp->next) temp->next->prev = temp->prev; delete temp; } public: void KillRectList (void); Rect4DHashTable (int size); ~Rect4DHashTable (void); void AddPermRect (const Rect4D& p1) { Rect4D *arect; // Verify (p1.left >= 0); // Verify (p1.top >= 0); // Verify (p1.bottom < MaxZ); // Verify (p1.right < MaxX); // Verify (p1.left < p1.right); // Verify (p1.top < p1.bottom); arect = new Rect4D (); Verify (arect); *arect = p1; arect->prev = NULL; arect->next = m_PermList; if (m_PermList) m_PermList->prev = arect; m_PermList = arect; } void RemovePermRect (Entity *who); void RemovePermRect (const Rect4D& p1) { Rect4D *current,*temp; current = m_PermList; while (current) { if (current->who == p1.who) { temp = current; current = current->next; if (m_PermList == temp) m_PermList = temp->next; if (temp->prev) temp->prev->next = temp->next; if (temp->next) temp->next->prev = temp->prev; delete temp; return; } current = current->next; } } void AddRect (Rect4D* p1); void RemoveRect (Rect4D *p1) { int loc; if (p1->time < m_CurrentTime) return; Verify (p1); loc = FindHashLine (*p1); if (loc==-1) return; Verify (loc>=0); Verify (loc < m_ListSize); if (m_List[loc] == p1) m_List[loc] = p1->next; if (p1->prev) p1->prev->next = p1->next; if (p1->next) p1->next->prev = p1->prev; p1->next = p1->prev = NULL; // delete p1; } #ifdef _ARMOR void VerifyRectGone (Rect4D *p1); #else void VerifyRectGone (Rect4D *p1) {} #endif void UpdateTime (Stuff::Time curtime); Rect4D *Collide (const Rect4D& p1) const; Rect4D *Collide (const Rect4D* p1) const { return Collide (*p1); } }; struct LockKey { int locx,locz; LockKey (int p1,int p2) { locx = p1; locz = p2; } bool operator== (const LockKey& p1) const { return ((locx == p1.locx) && (locz == p1.locz)); } }; struct LockData { static Stuff::MemoryBlockOf *m_EmptyData; static LockData *GetBlankData (void) { return (LockData *) m_EmptyData->New (); } static void DoneData (LockData *oldrect) { if (oldrect) m_EmptyData->Delete (oldrect); } void *operator new (size_t size) {return GetBlankData (); } void operator delete (void *value,size_t size) { DoneData ((LockData *) value); } int locx,locz; unsigned short olddata; MWObject *who; LockData *next; LockData (void) { locx = -1; locz = -1; olddata = -1; next = NULL; } LockData (int p1,int p2,unsigned short p3) { locx = p1; locz = p2; olddata = p3; who = NULL; next = NULL; } LockData (int p1,int p2,MWObject *p3) { locx = p1; locz = p2; olddata = 0; who = p3; next = NULL; } }; inline bool operator< (const LockKey& p1,const LockKey& p2) { if (p1.locx < p2.locx) return true; if (p1.locz < p2.locz) return true; return false; } struct obstacleptcmp : stlport::binary_function { bool operator()(const LockKey& _X, const LockKey& _Y) const { if (_X.locx < _Y.locx) return true; if (_X.locz < _Y.locz) return true; return false; } }; // extern stlport::map *g_Obstacles; // created in AI::Initilizeclass // extern stlport::vector *g_Obstacles; // created in AI::Initilizeclass MWObject *BlockerLocal (int x,int z); bool AddBlockLocal (int x,int z,MWObject *who); void RemoveBlockLocal (int x,int z,MWObject *who); void InitObstacle (void); void CleanObstacle (void); void SetupPermRects (void); void KillPermRects (void); inline MWObject *Blocker (const Point3D& pt) { int x,z; x = (int) (pt.x); z = (int) (pt.z); x = (int) (x/BLOCK_GRID_RES); z = (int) (z/BLOCK_GRID_RES); return BlockerLocal (x,z); } inline MWObject *Blocker (int x,int z) { x = (x/BLOCK_GRID_RES); z = (z/BLOCK_GRID_RES); return BlockerLocal (x,z); } inline bool AddBlock (const Point3D& pt,MWObject *who) { int x,z; x = (int) (pt.x); z = (int) (pt.z); x = (int) (x/BLOCK_GRID_RES); z = (int) (z/BLOCK_GRID_RES); return AddBlockLocal (x,z,who); } inline bool AddBlock (int x,int z,MWObject *who) { x = (x/BLOCK_GRID_RES); z = (z/BLOCK_GRID_RES); return AddBlockLocal (x,z,who); } inline void RemoveBlock (const Point3D& pt,MWObject *who) { int x,z; x = (int) (pt.x); z = (int) (pt.z); x = (int) (x/BLOCK_GRID_RES); z = (int) (z/BLOCK_GRID_RES); RemoveBlockLocal (x,z,who); } inline void RemoveBlock (int x,int z,MWObject *who) { x = (x/BLOCK_GRID_RES); z = (z/BLOCK_GRID_RES); RemoveBlockLocal (x,z,who); } }; #endif