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.
379 lines
8.3 KiB
C++
379 lines
8.3 KiB
C++
#pragma once
|
|
#ifndef __OBSTACLEHPP__
|
|
#define __OBSTACLEHPP__
|
|
|
|
#pragma warning (push)
|
|
#include <map>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
#include <vector>
|
|
#include <list>
|
|
#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<Rect4D> *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<LockData> *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<LockKey,LockKey, bool>
|
|
{
|
|
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<LockKey,MWObject *> *g_Obstacles; // created in AI::Initilizeclass
|
|
// extern stlport::vector<LockData> *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
|