raze/source/games/exhumed/src/exhumedactor.h

263 lines
4.7 KiB
C
Raw Normal View History

2021-09-06 21:50:06 +00:00
#pragma once
2021-11-25 20:42:49 +00:00
#include "coreactor.h"
2021-09-06 21:50:06 +00:00
BEGIN_PS_NS
class DExhumedActor;
enum
{
kHitAuxMask = 0x30000,
kHitAux1 = 0x10000,
kHitAux2 = 0x20000,
};
2021-09-06 21:50:06 +00:00
// Wrapper around the insane collision info mess from Build.
struct Collision
{
int type;
int index;
int exbits;
2021-09-06 21:50:06 +00:00
int legacyVal; // should be removed later, but needed for converting back for unadjusted code.
DExhumedActor* actor;
Collision() = default;
explicit Collision(int legacyval) { setFromEngine(legacyval); }
2021-09-06 21:50:06 +00:00
// need forward declarations of these.
int actorIndex(DExhumedActor*);
DExhumedActor* Actor(int);
int setNone()
{
type = kHitNone;
index = -1;
exbits = 0;
2021-09-06 21:50:06 +00:00
legacyVal = 0;
actor = nullptr;
return kHitNone;
}
int setSector(int num)
{
type = kHitSector;
index = num;
exbits = 0;
2021-09-06 21:50:06 +00:00
legacyVal = type | index;
actor = nullptr;
return kHitSector;
}
int setWall(int num)
{
type = kHitWall;
index = num;
exbits = 0;
2021-09-06 21:50:06 +00:00
legacyVal = type | index;
actor = nullptr;
return kHitWall;
}
int setSprite(DExhumedActor* num)
{
type = kHitSprite;
index = -1;
exbits = 0;
2021-09-06 21:50:06 +00:00
legacyVal = type | actorIndex(num);
actor = num;
return kHitSprite;
}
int setFromEngine(int value)
{
legacyVal = value;
type = value & kHitTypeMask;
exbits = value & kHitAuxMask;
2021-09-06 21:50:06 +00:00
if (type == 0) { index = -1; actor = nullptr; }
else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; }
else { index = -1; actor = Actor(value & kHitIndexMask); }
return type;
}
2021-11-22 21:20:53 +00:00
walltype* wall()
{
return &::wall[index];
}
sectortype* sector()
{
return &::sector[index];
}
2021-09-06 21:50:06 +00:00
};
class DExhumedActor : public DCoreActor
2021-09-06 21:50:06 +00:00
{
DExhumedActor* base();
public:
DExhumedActor* pTarget;
int16_t nPhase;
int16_t nHealth;
int16_t nFrame;
int16_t nAction;
int16_t nCount;
int16_t nRun;
union { int16_t nIndex; int16_t nAngle; }; // angle is for wasp.
union { int16_t nIndex2; int16_t nAngle2; }; // index2 is for scorpion, angle2 is for wasp.
union { int16_t nChannel; int16_t nVel; }; // channel is for scorpion, vel is for wasp.
union { int16_t nDamage; int16_t nAction2; }; // nAction2 is for the queen.
2021-09-06 21:50:06 +00:00
// for the grenade.
int nTurn;
int x;
int y;
DExhumedActor()
{
index = (int(this - base()));
}
2021-09-06 21:50:06 +00:00
DExhumedActor& operator=(const DExhumedActor& other) = default;
void Clear()
{
}
};
extern DExhumedActor exhumedActors[MAXSPRITES];
inline DExhumedActor* Collision::Actor(int i)
{
return &exhumedActors[i];
}
inline int Collision::actorIndex(DExhumedActor* a)
{
return a->GetSpriteIndex();
}
2021-09-06 21:50:06 +00:00
inline DExhumedActor* DExhumedActor::base() { return exhumedActors; }
// Iterator wrappers that return an actor pointer, not an index.
class ExhumedStatIterator : public StatIterator
{
public:
ExhumedStatIterator(int stat) : StatIterator(stat)
{
}
DExhumedActor* Next()
{
int n = NextIndex();
return n >= 0 ? &exhumedActors[n] : nullptr;
}
DExhumedActor* Peek()
{
int n = PeekIndex();
return n >= 0 ? &exhumedActors[n] : nullptr;
}
};
class ExhumedSectIterator : public SectIterator
{
public:
ExhumedSectIterator(int stat) : SectIterator(stat)
{
}
2021-11-22 17:51:22 +00:00
ExhumedSectIterator(sectortype* stat) : SectIterator(stat)
{
}
2021-09-06 21:50:06 +00:00
DExhumedActor* Next()
{
int n = NextIndex();
return n >= 0 ? &exhumedActors[n] : nullptr;
}
DExhumedActor* Peek()
{
int n = PeekIndex();
return n >= 0 ? &exhumedActors[n] : nullptr;
}
};
// An iterator to iterate over all sprites.
class ExhumedSpriteIterator
{
ExhumedStatIterator it;
int stat = 0;
public:
ExhumedSpriteIterator() : it(0) {}
DExhumedActor* 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 ExhumedLinearSpriteIterator
{
int index = 0;
public:
void Reset()
{
index = 0;
}
DExhumedActor* Next()
{
while (index < MAXSPRITES)
{
auto p = &exhumedActors[index++];
if (p->s().statnum != MAXSTATUS) return p;
}
return nullptr;
}
};
inline FSerializer& Serialize(FSerializer& arc, const char* keyname, DExhumedActor*& w, DExhumedActor** def)
{
int index = w? int(w - exhumedActors) : -1;
Serialize(arc, keyname, index, nullptr);
if (arc.isReading()) w = index == -1? nullptr : &exhumedActors[index];
return arc;
}
inline void ChangeActorStat(DExhumedActor* actor, int stat)
{
changespritestat(actor->GetSpriteIndex(), stat);
}
2021-11-22 20:03:10 +00:00
inline void ChangeActorSect(DExhumedActor* actor, sectortype* stat)
{
changespritesect(actor->GetSpriteIndex(), sector.IndexOf(stat));
}
2021-09-06 21:50:06 +00:00
inline void setActorPos(DExhumedActor* actor, vec3_t* pos)
{
setsprite(actor->GetSpriteIndex(), pos);
}
inline DExhumedActor* GetActor(const hitdata_t& hitData)
{
2021-10-27 18:51:41 +00:00
return hitData.sprite < 0? nullptr : &exhumedActors[hitData.sprite];
}
2021-09-06 21:50:06 +00:00
END_BLD_NS