Files
firestorm/Gameleap/code/mw4/Code/MW4/obstacle.hpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

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