mirror of
https://github.com/ZDoom/Raze.git
synced 2025-03-13 20:42:11 +00:00
- initialize actorArray for all games.
- the foundation for an actor aware backend.
This commit is contained in:
parent
52c80f187a
commit
9380819e4e
13 changed files with 189 additions and 74 deletions
|
@ -383,22 +383,9 @@ inline void getzrange(int x, int y, int z, int16_t sectnum, int32_t* ceilz, int3
|
|||
getzrange(&v, sectnum, ceilz, ceilhit, florz, florhit, walldist, cliptype);
|
||||
}
|
||||
extern vec2_t hitscangoal;
|
||||
int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
|
||||
hitdata_t *hitinfo, uint32_t cliptype) ATTRIBUTE((nonnull(1,6)));
|
||||
inline int hitscan(int x, int y, int z, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
|
||||
short* hitsect, short* hitwall, short* hitspr, int* hitx, int* hity, int* hitz, uint32_t cliptype)
|
||||
{
|
||||
vec3_t v{ x,y,z };
|
||||
hitdata_t hd{};
|
||||
int res = hitscan(&v, sectnum, vx, vy, vz, &hd, cliptype);
|
||||
if (hitsect) *hitsect = hd.sect;
|
||||
if (hitwall) *hitwall = hd.wall;
|
||||
if (hitspr) *hitspr = hd.sprite;
|
||||
*hitx = hd.pos.x;
|
||||
*hity = hd.pos.y;
|
||||
*hitz = hd.pos.z ;
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t hitscan_(const vec3_t* sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
|
||||
hitdata_t* hitinfo, uint32_t cliptype) ATTRIBUTE((nonnull(1, 6)));
|
||||
|
||||
void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange,
|
||||
int16_t *neartagsector, int16_t *neartagwall, int16_t *neartagsprite,
|
||||
|
@ -560,8 +547,6 @@ int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ,
|
|||
int32_t lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY,
|
||||
int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ);
|
||||
|
||||
int32_t rayintersect(int32_t x1, int32_t y1, int32_t z1, int32_t vx, int32_t vy, int32_t vz, int32_t x3,
|
||||
int32_t y3, int32_t x4, int32_t y4, int32_t *intx, int32_t *inty, int32_t *intz);
|
||||
int32_t insertsprite(int16_t sectnum, int16_t statnum);
|
||||
int32_t deletesprite(int16_t spritenum);
|
||||
|
||||
|
|
|
@ -1259,7 +1259,7 @@ static int32_t hitscan_trysector(const vec3_t *sv, usectorptr_t sec, hitdata_t *
|
|||
//
|
||||
// hitscan
|
||||
//
|
||||
int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
|
||||
int32_t hitscan_(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
|
||||
hitdata_t *hit, uint32_t cliptype)
|
||||
{
|
||||
int32_t x1, y1=0, z1=0, x2, y2, intx, inty, intz;
|
||||
|
|
|
@ -564,12 +564,6 @@ int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
|
|||
return t;
|
||||
}
|
||||
|
||||
int32_t rayintersect(int32_t x1, int32_t y1, int32_t z1, int32_t vx, int32_t vy, int32_t vz, int32_t x3,
|
||||
int32_t y3, int32_t x4, int32_t y4, int32_t *intx, int32_t *inty, int32_t *intz)
|
||||
{
|
||||
return (rintersect(x1, y1, z1, vx, vy, vz, x3, y3, x4, y4, intx, inty, intz) != -1);
|
||||
}
|
||||
|
||||
//
|
||||
// multi-pskies
|
||||
//
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "buildtypes.h"
|
||||
#include "build.h"
|
||||
#include "iterators.h"
|
||||
|
||||
class DCoreActor
|
||||
{
|
||||
|
@ -11,30 +12,32 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
spritetype& s()
|
||||
spritetype& s() const
|
||||
{
|
||||
return sprite[index];
|
||||
}
|
||||
|
||||
int GetIndex()
|
||||
int GetIndex() const
|
||||
{
|
||||
// For error printing only! This is only identical with the sprite index for items spawned at map start.
|
||||
return s().time;
|
||||
}
|
||||
|
||||
int GetSpriteIndex()
|
||||
int GetSpriteIndex() const
|
||||
{
|
||||
// this is only here to mark places that need changing later! It will be removed once the sprite array goes.
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sectortype* sector()
|
||||
sectortype* sector() const
|
||||
{
|
||||
return s().sector();
|
||||
}
|
||||
|
||||
bool insector() const
|
||||
{
|
||||
return s().insector();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -50,6 +53,7 @@ extern TArray<walltype> wall;
|
|||
enum EHitBits
|
||||
{
|
||||
kHitNone = 0,
|
||||
kHitTypeHitscan = 1, // hitscan results are not exclusive
|
||||
kHitTypeMask = 0xC000,
|
||||
kHitTypeMaskSW = 0x1C000, // SW has one more relevant bit
|
||||
kHitIndexMask = 0x3FFF,
|
||||
|
@ -63,16 +67,13 @@ enum EHitBits
|
|||
|
||||
// This serves as input/output for all functions dealing with collisions, hits, etc.
|
||||
// Not all utilities use all variables.
|
||||
template<class TActor>
|
||||
struct HitInfoBase
|
||||
{
|
||||
static_assert(std::is_convertible_v<TActor*, DCoreActor*>, "Actor class for Collision needs to inherit from DCoreActor");
|
||||
|
||||
int type;
|
||||
vec3_t hitpos;
|
||||
sectortype* hitSector;
|
||||
walltype* hitWall;
|
||||
TActor* hitActor;
|
||||
DCoreActor* hitActor;
|
||||
|
||||
HitInfoBase() = default;
|
||||
explicit HitInfoBase(int legacyval) { setFromEngine(legacyval); }
|
||||
|
@ -109,11 +110,11 @@ struct HitInfoBase
|
|||
{
|
||||
*this = {};
|
||||
type = kHitSprite;
|
||||
hitActor = static_cast<TActor*>(actorArray[num]);
|
||||
hitActor = actorArray[num];
|
||||
return kHitSprite;
|
||||
}
|
||||
|
||||
int setSprite(TActor* num)
|
||||
int setSprite(DCoreActor* num)
|
||||
{
|
||||
*this = {};
|
||||
type = kHitSprite;
|
||||
|
@ -139,3 +140,132 @@ struct HitInfoBase
|
|||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Iterator wrappers that return an actor pointer, not an index.
|
||||
template<class TActor>
|
||||
class TStatIterator : public StatIterator
|
||||
{
|
||||
public:
|
||||
TStatIterator(int stat) : StatIterator(stat)
|
||||
{
|
||||
}
|
||||
|
||||
TActor* Next()
|
||||
{
|
||||
int n = NextIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
}
|
||||
|
||||
TActor* Peek()
|
||||
{
|
||||
int n = PeekIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template<class TActor>
|
||||
class TSectIterator : public SectIterator
|
||||
{
|
||||
public:
|
||||
TSectIterator(int stat) : SectIterator(stat)
|
||||
{
|
||||
}
|
||||
|
||||
TSectIterator(sectortype* stat) : SectIterator(stat)
|
||||
{
|
||||
}
|
||||
|
||||
TActor* Next()
|
||||
{
|
||||
int n = NextIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
}
|
||||
|
||||
TActor* Peek()
|
||||
{
|
||||
int n = PeekIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// An iterator to iterate over all sprites.
|
||||
template<class TActor>
|
||||
class TSpriteIterator
|
||||
{
|
||||
TStatIterator<TActor> it;
|
||||
int stat = 0;
|
||||
|
||||
public:
|
||||
TSpriteIterator() : it(0) {}
|
||||
|
||||
TActor* Next()
|
||||
{
|
||||
while (stat < MAXSTATUS)
|
||||
{
|
||||
auto ac = it.Next();
|
||||
if (ac) return ac;
|
||||
stat++;
|
||||
if (stat < MAXSTATUS) it.Reset(stat);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// For iterating linearly over map spawned sprites. Will later only be valid on map load
|
||||
template<class TActor>
|
||||
class TLinearSpriteIterator
|
||||
{
|
||||
int index = 0;
|
||||
public:
|
||||
|
||||
void Reset()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
TActor* Next()
|
||||
{
|
||||
while (index < MAXSPRITES)
|
||||
{
|
||||
auto p = static_cast<TActor*>(actorArray[index++]);
|
||||
if (p->s().statnum != MAXSTATUS) return p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
[[deprecated]]
|
||||
inline int hitscan(const vec3_t* sv, int sectnum, int vx, int vy, int vz, hitdata_t* hitinfo, unsigned cliptype)
|
||||
{
|
||||
return hitscan_(sv, sectnum, vx, vy, vz, hitinfo, cliptype);
|
||||
}
|
||||
|
||||
[[deprecated]]
|
||||
inline int hitscan(int x, int y, int z, int sectnum, int vx, int vy, int vz,
|
||||
short* hitsect, short* hitwall, short* hitspr, int* hitx, int* hity, int* hitz, uint32_t cliptype)
|
||||
{
|
||||
vec3_t v{ x,y,z };
|
||||
hitdata_t hd{};
|
||||
int res = hitscan_(&v, sectnum, vx, vy, vz, &hd, cliptype);
|
||||
if (hitsect) *hitsect = hd.sect;
|
||||
if (hitwall) *hitwall = hd.wall;
|
||||
if (hitspr) *hitspr = hd.sprite;
|
||||
*hitx = hd.pos.x;
|
||||
*hity = hd.pos.y;
|
||||
*hitz = hd.pos.z;
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& direction, HitInfoBase& hitinfo, unsigned cliptype)
|
||||
{
|
||||
hitdata_t hd{};
|
||||
int res = hitscan_(&start, sector.IndexOf(startsect), direction.x, direction.y, direction.z, &hd, cliptype);
|
||||
hitinfo.hitpos = hd.pos;
|
||||
hitinfo.hitSector = hd.sect == -1? nullptr : §or[hd.sect];
|
||||
hitinfo.hitWall = hd.wall == -1? nullptr : &wall[hd.wall];
|
||||
hitinfo.hitActor = hd.sprite == -1? nullptr : actorArray[hd.sprite];
|
||||
hitinfo.type = kHitTypeHitscan;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "gamefuncs.h"
|
||||
#include "gamestruct.h"
|
||||
#include "intvec.h"
|
||||
#include "coreactor.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -243,6 +243,15 @@ extern DBloodActor bloodActors[kMaxSprites];
|
|||
|
||||
inline DBloodActor* DBloodActor::base() { return bloodActors; }
|
||||
|
||||
// subclasses to add a game specific actor() method
|
||||
struct HitInfo : public HitInfoBase
|
||||
{
|
||||
DBloodActor* actor() const
|
||||
{
|
||||
return static_cast<DBloodActor*>(hitActor);
|
||||
}
|
||||
};
|
||||
|
||||
// Iterator wrappers that return an actor pointer, not an index.
|
||||
class BloodStatIterator : public StatIterator
|
||||
{
|
||||
|
|
|
@ -354,6 +354,8 @@ int HitScan(DBloodActor *actor, int z, int dx, int dy, int dz, unsigned int nMas
|
|||
{
|
||||
hitscangoal.x = hitscangoal.y = 0x1ffffff;
|
||||
}
|
||||
// HitInfo hitData;
|
||||
// hitscan({ x, y, z }, pSprite->sector(), { dx, dy, dz << 4 }, hitData, nMask);
|
||||
vec3_t pos = { x, y, z };
|
||||
hitdata_t hitData;
|
||||
hitData.pos.z = gHitInfo.hitz;
|
||||
|
|
|
@ -285,6 +285,11 @@ int GameInterface::GetCurrentSkill()
|
|||
|
||||
void GameInterface::app_init()
|
||||
{
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
actorArray[i] = &hittype[i];
|
||||
}
|
||||
|
||||
if (isRR()) C_SetNotifyFontScale(0.5);
|
||||
ud.god = 0;
|
||||
ud.m_respawn_items = 0;
|
||||
|
|
|
@ -21,7 +21,7 @@ struct STATUSBARTYPE
|
|||
bool gotweapon[MAX_WEAPONS];
|
||||
};
|
||||
|
||||
struct DDukeActor
|
||||
struct DDukeActor : public DCoreActor
|
||||
{
|
||||
uint8_t cgg;
|
||||
uint8_t spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'.
|
||||
|
@ -45,7 +45,10 @@ struct DDukeActor
|
|||
|
||||
static DDukeActor* array(); // this is necessary to allow define inline functions referencing the global array inside the definition itself.
|
||||
|
||||
DDukeActor() : s(&sprite[this - array()]) {}
|
||||
DDukeActor() : s(&sprite[this - array()])
|
||||
{
|
||||
index = int(this - array());
|
||||
}
|
||||
DDukeActor(const DDukeActor& other) = delete; // we also do not want to allow copies.
|
||||
DDukeActor& operator=(const DDukeActor& other) = delete;
|
||||
void clear()
|
||||
|
@ -58,7 +61,6 @@ struct DDukeActor
|
|||
floorz = ceilingz = lastvx = lastvy = aflags = saved_ammo = 0;
|
||||
memset(temp_data, 0, sizeof(temp_data));
|
||||
}
|
||||
int GetSpriteIndex() const { return int(this - array()); }
|
||||
|
||||
// This once was stored in the owner field of the sprite
|
||||
inline DDukeActor* GetOwner()
|
||||
|
@ -96,18 +98,6 @@ struct DDukeActor
|
|||
// only valid for real players - just here to abstract yvel.
|
||||
return s->yvel;
|
||||
}
|
||||
|
||||
sectortype* sector() const
|
||||
{
|
||||
return s->sector();
|
||||
}
|
||||
|
||||
bool insector() const
|
||||
{
|
||||
return s->insector();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
extern DDukeActor hittype[MAXSPRITES + 1];
|
||||
inline DDukeActor* DDukeActor::array() { return hittype; }
|
||||
|
|
|
@ -464,6 +464,11 @@ static void SetTileNames()
|
|||
|
||||
void GameInterface::app_init()
|
||||
{
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
actorArray[i] = &exhumedActors[i];
|
||||
}
|
||||
|
||||
#if 0
|
||||
help_disabled = true;
|
||||
#endif
|
||||
|
|
|
@ -89,9 +89,8 @@ struct Collision
|
|||
}
|
||||
};
|
||||
|
||||
class DExhumedActor
|
||||
class DExhumedActor : public DCoreActor
|
||||
{
|
||||
int index;
|
||||
DExhumedActor* base();
|
||||
|
||||
public:
|
||||
|
@ -115,16 +114,15 @@ public:
|
|||
int y;
|
||||
|
||||
|
||||
DExhumedActor() :index(int(this - base())) {}
|
||||
DExhumedActor()
|
||||
{
|
||||
index = (int(this - base()));
|
||||
}
|
||||
DExhumedActor& operator=(const DExhumedActor& other) = default;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
}
|
||||
|
||||
spritetype& s() { return sprite[index]; }
|
||||
int GetIndex() { return index; } // should only be for error reporting or for masking to a slot index
|
||||
int GetSpriteIndex() { return index; } // this is only here to mark places that need changing later!
|
||||
};
|
||||
|
||||
extern DExhumedActor exhumedActors[MAXSPRITES];
|
||||
|
|
|
@ -178,6 +178,11 @@ void GameInterface::LoadGameTextures()
|
|||
|
||||
void GameInterface::app_init()
|
||||
{
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
actorArray[i] = &swActors[i];
|
||||
}
|
||||
|
||||
GameTicRate = TICS_PER_SEC / synctics;
|
||||
InitCheats();
|
||||
automapping = 1;
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
BEGIN_SW_NS
|
||||
|
||||
|
||||
class DSWActor
|
||||
class DSWActor : public DCoreActor
|
||||
{
|
||||
int index;
|
||||
DSWActor* base();
|
||||
|
||||
public:
|
||||
|
@ -16,7 +15,10 @@ public:
|
|||
USER user;
|
||||
walltype* tempwall; // transient, to replace a hack using a 16 bit sprite field.
|
||||
|
||||
DSWActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ }
|
||||
DSWActor()
|
||||
{
|
||||
index = (int(this - base()));
|
||||
}
|
||||
DSWActor& operator=(const DSWActor& other) = default;
|
||||
|
||||
void Clear()
|
||||
|
@ -26,7 +28,6 @@ public:
|
|||
bool hasU() { return hasUser; }
|
||||
|
||||
|
||||
spritetype& s() { return sprite[index]; }
|
||||
USER* u() { return &user; }
|
||||
USER* allocUser()
|
||||
{
|
||||
|
@ -39,16 +40,6 @@ public:
|
|||
hasUser = false;
|
||||
user.Clear();
|
||||
}
|
||||
|
||||
int GetIndex()
|
||||
{
|
||||
return s().time;
|
||||
}
|
||||
|
||||
int GetSpriteIndex() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
extern DSWActor swActors[MAXSPRITES];
|
||||
|
|
Loading…
Reference in a new issue