raze/source/games/sw/src/swactor.h

252 lines
4.2 KiB
C
Raw Normal View History

#pragma once
// included by game.h
BEGIN_SW_NS
class DSWActor
{
int index;
DSWActor* base();
public:
2021-11-19 23:18:23 +00:00
bool hasUser;
USER user;
DSWActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ }
DSWActor& operator=(const DSWActor& other) = default;
void Clear()
{
clearUser();
}
2021-11-19 23:18:23 +00:00
bool hasU() { return hasUser; }
spritetype& s() { return sprite[index]; }
2021-11-19 23:18:23 +00:00
USER* u() { return &user; }
USER* allocUser()
{
2021-11-19 23:18:23 +00:00
hasUser = true;
return u();
}
2021-11-01 22:26:13 +00:00
void clearUser()
{
2021-11-19 23:18:23 +00:00
hasUser = false;
user.Clear();
2021-11-01 22:26:13 +00:00
}
2021-11-01 16:54:18 +00:00
int GetIndex()
{
return s().time;
}
int GetSpriteIndex() const
{
return index;
}
};
extern DSWActor swActors[MAXSPRITES];
inline DSWActor* DSWActor::base() { return swActors; }
// Iterator wrappers that return an actor pointer, not an index.
class SWStatIterator : public StatIterator
{
public:
SWStatIterator(int stat) : StatIterator(stat)
{
}
DSWActor* Next()
{
int n = NextIndex();
return n >= 0 ? &swActors[n] : nullptr;
}
DSWActor* Peek()
{
int n = PeekIndex();
return n >= 0 ? &swActors[n] : nullptr;
}
};
class SWSectIterator : public SectIterator
{
public:
SWSectIterator(int stat) : SectIterator(stat)
{
}
SWSectIterator(sectortype* stat) : SectIterator(stat)
{
}
DSWActor* Next()
{
int n = NextIndex();
return n >= 0 ? &swActors[n] : nullptr;
}
DSWActor* Peek()
{
int n = PeekIndex();
return n >= 0 ? &swActors[n] : nullptr;
}
};
// An iterator to iterate over all sprites.
class SWSpriteIterator
{
SWStatIterator it;
int stat = 0;
public:
SWSpriteIterator() : it(0) {}
DSWActor* 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.
class SWLinearSpriteIterator
{
int index = 0;
public:
void Reset()
{
index = 0;
}
DSWActor* Next()
{
while (index < MAXSPRITES)
{
auto p = &swActors[index++];
if (p->s().statnum != MAXSTATUS) return p;
}
return nullptr;
}
};
enum EHitBitsSW
{
kHitTypeMaskSW = 0x1C000,
kHitSky = 0x10000, // SW only
};
2021-10-31 09:54:34 +00:00
inline int Collision::setNone()
{
2021-10-31 09:54:34 +00:00
type = kHitNone;
index = -1;
legacyVal = 0;
actor = nullptr;
return kHitNone;
}
2021-10-31 09:54:34 +00:00
inline int Collision::setSector(int num)
{
type = kHitSector;
index = num;
legacyVal = type | index;
actor = nullptr;
return kHitSector;
}
inline int Collision::setWall(int num)
{
type = kHitWall;
index = num;
legacyVal = type | index;
actor = nullptr;
return kHitWall;
}
inline int Collision::setSprite(DSWActor* num)
{
type = kHitSprite;
index = -1;
legacyVal = type | int(num - swActors);
actor = num;
return kHitSprite;
}
int Collision::setSky() { setNone(); type = kHitSky; return kHitSky; }
2021-10-31 09:54:34 +00:00
inline int Collision::setFromEngine(int value)
{
legacyVal = value;
type = value & kHitTypeMaskSW;
if (type == 0) { index = -1; actor = nullptr; }
else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; }
else { index = -1; actor = &swActors[value & kHitIndexMask]; }
return type;
}
2021-11-03 23:23:05 +00:00
struct HITINFO {
DSWActor* hitactor;
2021-11-24 15:49:53 +00:00
int hitsect;
int hitwall;
2021-11-03 23:23:05 +00:00
short hitsprite;
vec3_t pos;
void clearObj()
{
pos = {};
2021-11-24 15:49:53 +00:00
hitsect = hitwall = -1;
2021-11-03 23:23:05 +00:00
hitsprite = -1;
hitactor = nullptr;
}
void set(hitdata_t* hit)
{
2021-11-24 15:49:53 +00:00
hitsect = hit->sect;
hitwall = hit->wall;
2021-11-03 23:23:05 +00:00
hitsprite = hit->sprite;
hitactor = hit->sprite >= 0 ? &swActors[hit->sprite] : nullptr;
pos = hit->pos;
}
2021-11-24 15:49:53 +00:00
2021-11-24 15:55:24 +00:00
walltype* wall() const { return hitwall == -1? nullptr : &::wall[hitwall]; }
sectortype* sector() const { return hitsect == -1 ? nullptr : &::sector[hitsect]; }
2021-11-03 23:23:05 +00:00
};
inline FSerializer& Serialize(FSerializer& arc, const char* keyname, DSWActor*& w, DSWActor** def)
{
int index = w? int(w - swActors) : -1;
Serialize(arc, keyname, index, nullptr);
if (arc.isReading()) w = index == -1? nullptr : &swActors[index];
return arc;
}
inline void ChangeActorSect(DSWActor* actor, int sect)
{
changespritesect(actor->GetSpriteIndex(), sect);
}
inline int SetActorZ(DSWActor* actor, const vec3_t* newpos)
{
return setspritez(actor->GetSpriteIndex(), newpos);
}
2021-11-04 23:00:47 +00:00
inline int SetActor(DSWActor* actor, const vec3_t* newpos)
{
return setsprite(actor->GetSpriteIndex(), newpos);
}
END_SW_NS