2020-12-02 11:46:44 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-11-25 20:42:49 +00:00
|
|
|
#include "coreactor.h"
|
|
|
|
|
2020-12-02 11:46:44 +00:00
|
|
|
BEGIN_BLD_NS
|
|
|
|
|
2021-09-02 18:23:51 +00:00
|
|
|
class DBloodActor;
|
|
|
|
|
|
|
|
struct SPRITEHIT
|
|
|
|
{
|
2021-12-05 19:55:19 +00:00
|
|
|
// These must use read barriers as they can live longer and need proper GC maintenance.
|
2021-09-02 18:23:51 +00:00
|
|
|
Collision hit, ceilhit, florhit;
|
|
|
|
};
|
|
|
|
|
2021-11-25 20:42:49 +00:00
|
|
|
class DBloodActor : public DCoreActor
|
2020-12-02 11:46:44 +00:00
|
|
|
{
|
2021-12-05 19:55:19 +00:00
|
|
|
DECLARE_CLASS(DBloodActor, DCoreActor)
|
|
|
|
HAS_OBJECT_POINTERS
|
2020-12-02 11:46:44 +00:00
|
|
|
|
|
|
|
public:
|
2021-05-05 08:12:31 +00:00
|
|
|
int dudeSlope;
|
2021-12-30 10:15:27 +00:00
|
|
|
vec3_t vel;
|
2021-09-05 08:09:59 +00:00
|
|
|
bool hasx;
|
2021-12-22 08:49:00 +00:00
|
|
|
XSPRITE xspr;
|
2021-08-29 17:09:29 +00:00
|
|
|
SPRITEHIT hit;
|
2020-12-04 22:21:42 +00:00
|
|
|
DUDEEXTRA dudeExtra;
|
2021-09-01 19:53:33 +00:00
|
|
|
SPRITEMASS spriteMass;
|
2021-08-29 07:27:03 +00:00
|
|
|
GENDUDEEXTRA genDudeExtra;
|
2021-12-05 22:56:35 +00:00
|
|
|
TObjPtr<DBloodActor*> prevmarker; // needed by the nnext marker code. This originally hijacked targetX in XSPRITE
|
|
|
|
TObjPtr<DBloodActor*> ownerActor; // was previously stored in the sprite's owner field.
|
2022-08-10 22:13:36 +00:00
|
|
|
DVector3 basePoint;
|
2021-11-23 18:37:38 +00:00
|
|
|
EventObject condition[2];
|
2021-09-05 08:09:59 +00:00
|
|
|
bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers.
|
2021-09-01 19:53:33 +00:00
|
|
|
|
2021-08-28 13:43:34 +00:00
|
|
|
// transient data (not written to savegame)
|
|
|
|
int cumulDamage;
|
2021-09-05 10:35:13 +00:00
|
|
|
bool interpolated;
|
2020-11-07 15:26:14 +00:00
|
|
|
|
2021-12-05 19:55:19 +00:00
|
|
|
DBloodActor() = default;
|
2021-12-05 08:20:41 +00:00
|
|
|
void Serialize(FSerializer& arc) override;
|
2021-12-05 19:55:19 +00:00
|
|
|
size_t PropagateMark() override;
|
2021-12-05 08:20:41 +00:00
|
|
|
|
2021-09-05 08:09:59 +00:00
|
|
|
bool hasX() { return hasx; }
|
|
|
|
void addX() { hasx = true; }
|
|
|
|
|
2020-12-02 19:22:13 +00:00
|
|
|
void SetOwner(DBloodActor* own)
|
|
|
|
{
|
2021-11-19 20:19:18 +00:00
|
|
|
ownerActor = own;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DBloodActor* GetOwner()
|
|
|
|
{
|
2021-11-19 20:19:18 +00:00
|
|
|
return ownerActor;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
2020-12-03 17:00:07 +00:00
|
|
|
void SetTarget(DBloodActor* own)
|
|
|
|
{
|
2021-12-23 14:55:27 +00:00
|
|
|
xspr.target = own;
|
2020-12-03 17:00:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DBloodActor* GetTarget()
|
|
|
|
{
|
2021-12-23 14:55:27 +00:00
|
|
|
return xspr.target;
|
2020-12-03 17:00:07 +00:00
|
|
|
}
|
|
|
|
|
2021-05-05 08:12:31 +00:00
|
|
|
bool ValidateTarget(const char* func)
|
|
|
|
{
|
|
|
|
if (GetTarget() == nullptr)
|
|
|
|
{
|
|
|
|
Printf(PRINT_HIGH | PRINT_NOTIFY, "%s: invalid target in calling actor\n", func);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-12-03 19:30:30 +00:00
|
|
|
void SetBurnSource(DBloodActor* own)
|
|
|
|
{
|
2021-12-23 14:55:27 +00:00
|
|
|
xspr.burnSource = own;
|
2020-12-03 19:30:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DBloodActor* GetBurnSource()
|
|
|
|
{
|
2021-12-23 14:55:27 +00:00
|
|
|
return xspr.burnSource;
|
2020-12-03 19:30:30 +00:00
|
|
|
}
|
|
|
|
|
2020-12-02 23:30:19 +00:00
|
|
|
void SetSpecialOwner() // nnext hackery
|
|
|
|
{
|
2021-11-19 20:19:18 +00:00
|
|
|
ownerActor = nullptr;
|
2022-05-23 22:30:41 +00:00
|
|
|
spr.intowner = kMagicOwner;
|
2020-12-02 23:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GetSpecialOwner()
|
|
|
|
{
|
2022-05-23 22:30:41 +00:00
|
|
|
return ownerActor == nullptr && (spr.intowner == kMagicOwner);
|
2020-12-02 23:30:19 +00:00
|
|
|
}
|
|
|
|
|
2020-12-02 19:22:13 +00:00
|
|
|
bool IsPlayerActor()
|
|
|
|
{
|
2021-12-25 17:37:58 +00:00
|
|
|
return spr.type >= kDudePlayer1 && spr.type <= kDudePlayer8;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsDudeActor()
|
|
|
|
{
|
2021-12-25 17:37:58 +00:00
|
|
|
return spr.type >= kDudeBase && spr.type < kDudeMax;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsItemActor()
|
|
|
|
{
|
2021-12-25 17:37:58 +00:00
|
|
|
return spr.type >= kItemBase && spr.type < kItemMax;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsWeaponActor()
|
|
|
|
{
|
2021-12-25 17:37:58 +00:00
|
|
|
return spr.type >= kItemWeaponBase && spr.type < kItemWeaponMax;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsAmmoActor()
|
|
|
|
{
|
2021-12-25 17:37:58 +00:00
|
|
|
return spr.type >= kItemAmmoBase && spr.type < kItemAmmoMax;
|
2020-12-02 19:22:13 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 19:03:42 +00:00
|
|
|
bool isActive()
|
2020-12-03 19:30:30 +00:00
|
|
|
{
|
|
|
|
if (!hasX())
|
|
|
|
return false;
|
|
|
|
|
2021-12-29 19:03:42 +00:00
|
|
|
switch (xspr.aiState->stateType)
|
2020-12-03 19:30:30 +00:00
|
|
|
{
|
|
|
|
case kAiStateIdle:
|
|
|
|
case kAiStateGenIdle:
|
|
|
|
case kAiStateSearch:
|
|
|
|
case kAiStateMove:
|
|
|
|
case kAiStateOther:
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2020-12-02 11:46:44 +00:00
|
|
|
};
|
|
|
|
|
2021-11-25 23:08:59 +00:00
|
|
|
// subclassed to add a game specific actor() method
|
2021-11-25 21:33:55 +00:00
|
|
|
|
2021-11-25 22:28:28 +00:00
|
|
|
extern HitInfo gHitInfo;
|
|
|
|
|
|
|
|
|
2020-12-02 16:10:00 +00:00
|
|
|
// Iterator wrappers that return an actor pointer, not an index.
|
2021-08-29 18:47:51 +00:00
|
|
|
|
2021-11-26 20:13:19 +00:00
|
|
|
using BloodStatIterator = TStatIterator<DBloodActor>;
|
|
|
|
using BloodSectIterator = TSectIterator<DBloodActor>;
|
|
|
|
using BloodSpriteIterator = TSpriteIterator<DBloodActor>;
|
2021-08-29 18:47:51 +00:00
|
|
|
|
2020-12-02 22:39:38 +00:00
|
|
|
inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
|
|
|
|
{
|
2021-12-22 19:55:58 +00:00
|
|
|
GetSpriteExtents(&actor->spr, top, bottom);
|
2020-12-02 22:39:38 +00:00
|
|
|
}
|
|
|
|
|
2021-12-22 14:40:15 +00:00
|
|
|
inline bool CheckSector(const BitArray& bits, DBloodActor* act)
|
|
|
|
{
|
2021-12-30 15:39:43 +00:00
|
|
|
return bits[act->sectno()];
|
2021-12-22 14:40:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-22 15:33:03 +00:00
|
|
|
inline bool IsTargetTeammate(DBloodActor* pSource, DBloodActor* pTarget)
|
|
|
|
{
|
|
|
|
if (!pSource->IsPlayerActor())
|
|
|
|
return false;
|
|
|
|
PLAYER* pSourcePlayer = &gPlayer[pSource->spr.type - kDudePlayer1];
|
|
|
|
return IsTargetTeammate(pSourcePlayer, pTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-02 11:46:44 +00:00
|
|
|
END_BLD_NS
|