diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h index 80a9d665c8f..cca53ede304 100644 --- a/source/games/exhumed/src/exhumed.h +++ b/source/games/exhumed/src/exhumed.h @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "screenjob.h" #include "gamestruct.h" #include "names.h" +#include "exhumedactor.h" BEGIN_PS_NS diff --git a/source/games/exhumed/src/exhumedactor.h b/source/games/exhumed/src/exhumedactor.h new file mode 100644 index 00000000000..7f1339dbbe8 --- /dev/null +++ b/source/games/exhumed/src/exhumedactor.h @@ -0,0 +1,220 @@ +#pragma once + +BEGIN_PS_NS + +void mydeletesprite(int nSprite); + +class DExhumedActor; + +// Wrapper around the insane collision info mess from Build. +struct Collision +{ + int type; + int index; + int legacyVal; // should be removed later, but needed for converting back for unadjusted code. + DExhumedActor* actor; + + Collision() = default; + Collision(int legacyval) { setFromEngine(legacyval); } + + // need forward declarations of these. + int actorIndex(DExhumedActor*); + DExhumedActor* Actor(int); + + int setNone() + { + type = kHitNone; + index = -1; + legacyVal = 0; + actor = nullptr; + return kHitNone; + } + + int setSector(int num) + { + type = kHitSector; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitSector; + } + int setWall(int num) + { + type = kHitWall; + index = num; + legacyVal = type | index; + actor = nullptr; + return kHitWall; + } + int setSprite(DExhumedActor* num) + { + type = kHitSprite; + index = -1; + legacyVal = type | actorIndex(num); + actor = num; + return kHitSprite; + } + + int setFromEngine(int value) + { + legacyVal = value; + type = value & kHitTypeMask; + 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() :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! + + /* + void SetOwner(DExhumedActor* own) + { + s().owner = own ? own->GetSpriteIndex() : -1; + } + + DExhumedActor* GetOwner() + { + if (s().owner == -1 || s().owner == MAXSPRITES - 1) return nullptr; + return base() + s().owner; + } + */ +}; + +extern DExhumedActor exhumedActors[MAXSPRITES]; + +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 void DeleteSprite(DExhumedActor* nSprite) +{ + if (nSprite) mydeletesprite(nSprite->GetSpriteIndex()); +} + +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); +} + +END_BLD_NS