- initialize actorArray for all games.

- the foundation for an actor aware backend.
This commit is contained in:
Christoph Oelckers 2021-11-25 22:33:55 +01:00
parent 52c80f187a
commit 9380819e4e
13 changed files with 189 additions and 74 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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
//

View file

@ -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 : &sector[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;
}

View file

@ -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"
//---------------------------------------------------------------------------
//

View file

@ -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
{

View file

@ -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;

View file

@ -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;

View file

@ -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; }

View file

@ -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

View file

@ -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];

View file

@ -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;

View file

@ -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];