mirror of
https://github.com/DrBeef/Raze.git
synced 2024-12-11 13:21:39 +00:00
033a73bce0
Down to 350.
248 lines
4.7 KiB
C++
248 lines
4.7 KiB
C++
#pragma once
|
|
|
|
BEGIN_PS_NS
|
|
|
|
class DExhumedActor;
|
|
|
|
enum
|
|
{
|
|
kHitAuxMask = 0x30000,
|
|
kHitAux1 = 0x10000,
|
|
kHitAux2 = 0x20000,
|
|
};
|
|
|
|
// Wrapper around the insane collision info mess from Build.
|
|
struct Collision
|
|
{
|
|
int type;
|
|
int index;
|
|
int exbits;
|
|
int legacyVal; // should be removed later, but needed for converting back for unadjusted code.
|
|
DExhumedActor* actor;
|
|
|
|
Collision() = default;
|
|
explicit Collision(int legacyval) { setFromEngine(legacyval); }
|
|
|
|
// need forward declarations of these.
|
|
int actorIndex(DExhumedActor*);
|
|
DExhumedActor* Actor(int);
|
|
|
|
int setNone()
|
|
{
|
|
type = kHitNone;
|
|
index = -1;
|
|
exbits = 0;
|
|
legacyVal = 0;
|
|
actor = nullptr;
|
|
return kHitNone;
|
|
}
|
|
|
|
int setSector(int num)
|
|
{
|
|
type = kHitSector;
|
|
index = num;
|
|
exbits = 0;
|
|
legacyVal = type | index;
|
|
actor = nullptr;
|
|
return kHitSector;
|
|
}
|
|
int setWall(int num)
|
|
{
|
|
type = kHitWall;
|
|
index = num;
|
|
exbits = 0;
|
|
legacyVal = type | index;
|
|
actor = nullptr;
|
|
return kHitWall;
|
|
}
|
|
int setSprite(DExhumedActor* num)
|
|
{
|
|
type = kHitSprite;
|
|
index = -1;
|
|
exbits = 0;
|
|
legacyVal = type | actorIndex(num);
|
|
actor = num;
|
|
return kHitSprite;
|
|
}
|
|
|
|
int setFromEngine(int value)
|
|
{
|
|
legacyVal = value;
|
|
type = value & kHitTypeMask;
|
|
exbits = value & kHitAuxMask;
|
|
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;
|
|
}
|
|
};
|
|
|
|
class DExhumedActor
|
|
{
|
|
int index;
|
|
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.
|
|
|
|
// for the grenade.
|
|
int nTurn;
|
|
int x;
|
|
int y;
|
|
|
|
|
|
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];
|
|
|
|
inline DExhumedActor* Collision::Actor(int i)
|
|
{
|
|
return &exhumedActors[i];
|
|
}
|
|
|
|
inline int Collision::actorIndex(DExhumedActor* a)
|
|
{
|
|
return a->GetSpriteIndex();
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
inline void ChangeActorSect(DExhumedActor* actor, int stat)
|
|
{
|
|
changespritesect(actor->GetSpriteIndex(), stat);
|
|
}
|
|
|
|
inline void setActorPos(DExhumedActor* actor, vec3_t* pos)
|
|
{
|
|
setsprite(actor->GetSpriteIndex(), pos);
|
|
}
|
|
|
|
inline DExhumedActor* GetActor(const hitdata_t& hitData)
|
|
{
|
|
return hitData.sprite < 0? nullptr : &exhumedActors[hitData.sprite];
|
|
}
|
|
|
|
END_BLD_NS
|