mirror of
https://github.com/ZDoom/Raze.git
synced 2025-06-02 02:01:31 +00:00
- Added GC support to Exhumed
This commit is contained in:
parent
138690d34e
commit
8dde6a3074
36 changed files with 308 additions and 196 deletions
|
@ -65,6 +65,7 @@ TArray<DCoreActor*> checked;
|
||||||
|
|
||||||
static bool ValidateStatList(int statnum)
|
static bool ValidateStatList(int statnum)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
checked.Clear();
|
checked.Clear();
|
||||||
for (auto entry = statList[statnum].firstEntry; entry; entry = entry->nextStat)
|
for (auto entry = statList[statnum].firstEntry; entry; entry = entry->nextStat)
|
||||||
{
|
{
|
||||||
|
@ -75,6 +76,7 @@ static bool ValidateStatList(int statnum)
|
||||||
assert(entry->prevStat == nullptr || entry->prevStat->nextStat == entry);
|
assert(entry->prevStat == nullptr || entry->prevStat->nextStat == entry);
|
||||||
assert(entry->nextStat == nullptr || entry->nextStat->prevStat == entry);
|
assert(entry->nextStat == nullptr || entry->nextStat->prevStat == entry);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +199,7 @@ int ChangeActorStat(DCoreActor* actor, int statnum, bool tail)
|
||||||
|
|
||||||
static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr)
|
static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
assert(sect);
|
assert(sect);
|
||||||
checked.Clear();
|
checked.Clear();
|
||||||
assert(sect->firstEntry == nullptr || sect->firstEntry->prevSect == nullptr);
|
assert(sect->firstEntry == nullptr || sect->firstEntry->prevSect == nullptr);
|
||||||
|
@ -211,6 +214,7 @@ static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr)
|
||||||
assert(entry->prevSect == nullptr || entry->prevSect->nextSect == entry);
|
assert(entry->prevSect == nullptr || entry->prevSect->nextSect == entry);
|
||||||
assert(entry->nextSect == nullptr || entry->nextSect->prevSect == entry);
|
assert(entry->nextSect == nullptr || entry->nextSect->prevSect == entry);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,8 +334,6 @@ static void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail)
|
||||||
void ChangeActorSect(DCoreActor* actor, sectortype* sect, bool tail)
|
void ChangeActorSect(DCoreActor* actor, sectortype* sect, bool tail)
|
||||||
{
|
{
|
||||||
if (sect == nullptr) return;
|
if (sect == nullptr) return;
|
||||||
auto old_sect = actor->link_sector;
|
|
||||||
assert(actor->s().insector());
|
|
||||||
RemoveActorSect(actor);
|
RemoveActorSect(actor);
|
||||||
InsertActorSect(actor, sect, tail);
|
InsertActorSect(actor, sect, tail);
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ void FuncLion(int, int, int, int);
|
||||||
// 16 bytes
|
// 16 bytes
|
||||||
struct BlockInfo
|
struct BlockInfo
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int field_8;
|
int field_8;
|
||||||
|
@ -206,8 +206,8 @@ struct BlockInfo
|
||||||
extern BlockInfo sBlockInfo[];
|
extern BlockInfo sBlockInfo[];
|
||||||
|
|
||||||
extern Collision hiHit;
|
extern Collision hiHit;
|
||||||
extern DExhumedActor* nChunkSprite[];
|
extern TObjPtr<DExhumedActor*> nChunkSprite[];
|
||||||
extern DExhumedActor* nBodySprite[];
|
extern TObjPtr<DExhumedActor*> nBodySprite[];
|
||||||
|
|
||||||
signed int lsqrt(int a1);
|
signed int lsqrt(int a1);
|
||||||
void MoveThings();
|
void MoveThings();
|
||||||
|
@ -259,7 +259,7 @@ extern int bTorch;
|
||||||
extern int nSmokeSparks;
|
extern int nSmokeSparks;
|
||||||
extern int nDronePitch;
|
extern int nDronePitch;
|
||||||
extern int lFinaleStart;
|
extern int lFinaleStart;
|
||||||
extern DExhumedActor* pFinaleSpr;
|
extern TObjPtr<DExhumedActor*> pFinaleSpr;
|
||||||
|
|
||||||
void InitObjects();
|
void InitObjects();
|
||||||
void InitElev();
|
void InitElev();
|
||||||
|
@ -305,8 +305,8 @@ void FuncQueen(int, int, int, int);
|
||||||
|
|
||||||
struct RA
|
struct RA
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
DExhumedActor* pTarget;
|
TObjPtr<DExhumedActor*> pTarget;
|
||||||
|
|
||||||
int16_t nAction;
|
int16_t nAction;
|
||||||
int16_t nFrame;
|
int16_t nFrame;
|
||||||
|
@ -352,7 +352,7 @@ struct RunStruct
|
||||||
{
|
{
|
||||||
int nAIType; // todo later: replace this with an AI pointer
|
int nAIType; // todo later: replace this with an AI pointer
|
||||||
int nObjIndex; // If object is a non-actor / not refactored yet.
|
int nObjIndex; // If object is a non-actor / not refactored yet.
|
||||||
DExhumedActor* pObjActor; // If object is an actor
|
TObjPtr<DExhumedActor*> pObjActor; // If object is an actor
|
||||||
int next;
|
int next;
|
||||||
int prev;
|
int prev;
|
||||||
};
|
};
|
||||||
|
@ -715,8 +715,8 @@ enum { kSnakeSprites = 8 }; // or rename to kSnakeParts?
|
||||||
// 32bytes
|
// 32bytes
|
||||||
struct Snake
|
struct Snake
|
||||||
{
|
{
|
||||||
DExhumedActor* pEnemy; // nRun
|
TObjPtr<DExhumedActor*> pEnemy; // nRun
|
||||||
DExhumedActor* pSprites[kSnakeSprites];
|
TObjPtr<DExhumedActor*> pSprites[kSnakeSprites];
|
||||||
|
|
||||||
int16_t nCountdown;
|
int16_t nCountdown;
|
||||||
int16_t nRun;
|
int16_t nRun;
|
||||||
|
|
|
@ -28,7 +28,6 @@ BEGIN_PS_NS
|
||||||
int nMagicSeq = -1;
|
int nMagicSeq = -1;
|
||||||
int nPreMagicSeq = -1;
|
int nPreMagicSeq = -1;
|
||||||
int nSavePointSeq = -1;
|
int nSavePointSeq = -1;
|
||||||
//FreeListArray<Anim, kMaxAnims> AnimList;
|
|
||||||
|
|
||||||
|
|
||||||
void SerializeAnim(FSerializer& arc)
|
void SerializeAnim(FSerializer& arc)
|
||||||
|
@ -138,7 +137,7 @@ void AIAnim::Tick(RunListEvent* ev)
|
||||||
|
|
||||||
if (pSprite->statnum == kStatIgnited)
|
if (pSprite->statnum == kStatIgnited)
|
||||||
{
|
{
|
||||||
auto pIgniter = pActor->pTarget;
|
DExhumedActor* pIgniter = pActor->pTarget;
|
||||||
|
|
||||||
if (pIgniter)
|
if (pIgniter)
|
||||||
{
|
{
|
||||||
|
|
|
@ -136,7 +136,7 @@ void AIAnubis::Tick(RunListEvent* ev)
|
||||||
bVal = true;
|
bVal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTarget = ap->pTarget;
|
DExhumedActor* pTarget = ap->pTarget;
|
||||||
|
|
||||||
int nFrame = SeqBase[nSeq] + ap->nFrame;
|
int nFrame = SeqBase[nSeq] + ap->nFrame;
|
||||||
int nFlag = FrameFlag[nFrame];
|
int nFlag = FrameFlag[nFrame];
|
||||||
|
|
|
@ -34,8 +34,8 @@ enum { kMaxBullets = 500 };
|
||||||
// 32 bytes
|
// 32 bytes
|
||||||
struct Bullet
|
struct Bullet
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
DExhumedActor* pEnemy;
|
TObjPtr<DExhumedActor*> pEnemy;
|
||||||
|
|
||||||
int16_t nSeq;
|
int16_t nSeq;
|
||||||
int16_t nFrame;
|
int16_t nFrame;
|
||||||
|
@ -56,6 +56,16 @@ FreeListArray<Bullet, kMaxBullets> BulletList;
|
||||||
int lasthitz, lasthitx, lasthity;
|
int lasthitz, lasthitx, lasthity;
|
||||||
sectortype* lasthitsect;
|
sectortype* lasthitsect;
|
||||||
|
|
||||||
|
size_t MarkBullets()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < kMaxBullets; i++)
|
||||||
|
{
|
||||||
|
GC::Mark(BulletList[i].pActor);
|
||||||
|
GC::Mark(BulletList[i].pEnemy);
|
||||||
|
}
|
||||||
|
return 2 * kMaxBullets;
|
||||||
|
}
|
||||||
|
|
||||||
int nRadialBullet = 0;
|
int nRadialBullet = 0;
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, Bullet& w, Bullet* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, Bullet& w, Bullet* def)
|
||||||
|
@ -138,7 +148,7 @@ int GrabBullet()
|
||||||
|
|
||||||
void DestroyBullet(int nBullet)
|
void DestroyBullet(int nBullet)
|
||||||
{
|
{
|
||||||
auto pActor = BulletList[nBullet].pActor;
|
DExhumedActor* pActor = BulletList[nBullet].pActor;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
runlist_DoSubRunRec(BulletList[nBullet].nRunRec);
|
runlist_DoSubRunRec(BulletList[nBullet].nRunRec);
|
||||||
|
@ -223,7 +233,7 @@ void BulletHitsSprite(Bullet *pBullet, DExhumedActor* pBulletActor, DExhumedActo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pActor = pBullet->pActor;
|
DExhumedActor* pActor = pBullet->pActor;
|
||||||
spritetype *pSprite = &pActor->s();
|
spritetype *pSprite = &pActor->s();
|
||||||
|
|
||||||
if (nStat == kStatAnubisDrum)
|
if (nStat == kStatAnubisDrum)
|
||||||
|
@ -307,7 +317,7 @@ int MoveBullet(int nBullet)
|
||||||
int nType = pBullet->nType;
|
int nType = pBullet->nType;
|
||||||
bulletInfo *pBulletInfo = &BulletInfo[nType];
|
bulletInfo *pBulletInfo = &BulletInfo[nType];
|
||||||
|
|
||||||
auto pActor = BulletList[nBullet].pActor;
|
DExhumedActor* pActor = BulletList[nBullet].pActor;
|
||||||
spritetype *pSprite = &pActor->s();
|
spritetype *pSprite = &pActor->s();
|
||||||
|
|
||||||
int x = pSprite->x;
|
int x = pSprite->x;
|
||||||
|
@ -322,7 +332,7 @@ int MoveBullet(int nBullet)
|
||||||
|
|
||||||
if (pBullet->field_10 < 30000)
|
if (pBullet->field_10 < 30000)
|
||||||
{
|
{
|
||||||
auto pEnemyActor = BulletList[nBullet].pEnemy;
|
DExhumedActor* pEnemyActor = BulletList[nBullet].pEnemy;
|
||||||
if (pEnemyActor)
|
if (pEnemyActor)
|
||||||
{
|
{
|
||||||
if (!(pEnemyActor->s().cstat & 0x101))
|
if (!(pEnemyActor->s().cstat & 0x101))
|
||||||
|
@ -494,7 +504,8 @@ HITSPRITE:
|
||||||
nDamage *= 2;
|
nDamage *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
runlist_DamageEnemy(EnergyBlocks[pHitWall->nextSector()->extra], pActor, nDamage);
|
DExhumedActor* eb = EnergyBlocks[pHitWall->nextSector()->extra];
|
||||||
|
if (eb) runlist_DamageEnemy(eb, pActor, nDamage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -821,7 +832,7 @@ void AIBullet::Tick(RunListEvent* ev)
|
||||||
assert(nBullet >= 0 && nBullet < kMaxBullets);
|
assert(nBullet >= 0 && nBullet < kMaxBullets);
|
||||||
|
|
||||||
int nSeq = SeqOffsets[BulletList[nBullet].nSeq];
|
int nSeq = SeqOffsets[BulletList[nBullet].nSeq];
|
||||||
auto pActor = BulletList[nBullet].pActor;
|
DExhumedActor* pActor = BulletList[nBullet].pActor;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
int nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].nFrame];
|
int nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].nFrame];
|
||||||
|
|
|
@ -60,10 +60,8 @@ extern int16_t inita;
|
||||||
extern sectortype* initsectp;
|
extern sectortype* initsectp;
|
||||||
|
|
||||||
extern int nCurChunkNum;
|
extern int nCurChunkNum;
|
||||||
extern DExhumedActor* nBodyGunSprite[50];
|
|
||||||
extern int movefifoend;
|
extern int movefifoend;
|
||||||
extern int movefifopos;
|
extern int movefifopos;
|
||||||
extern int nCurBodyGunNum;
|
|
||||||
|
|
||||||
// all static counters combined in an array for easier maintenance.
|
// all static counters combined in an array for easier maintenance.
|
||||||
enum ECounter
|
enum ECounter
|
||||||
|
|
|
@ -52,11 +52,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
|
TObjPtr<DExhumedActor*> bestTarget;
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DExhumedActor, false, true)
|
IMPLEMENT_CLASS(DExhumedActor, false, true)
|
||||||
IMPLEMENT_POINTERS_START(DExhumedActor)
|
IMPLEMENT_POINTERS_START(DExhumedActor)
|
||||||
IMPLEMENT_POINTER(pTarget)
|
IMPLEMENT_POINTER(pTarget)
|
||||||
IMPLEMENT_POINTERS_END
|
IMPLEMENT_POINTERS_END
|
||||||
|
|
||||||
|
size_t MarkMove();
|
||||||
|
size_t MarkBullets();
|
||||||
|
size_t MarkInput();
|
||||||
|
size_t MarkItems();
|
||||||
|
size_t MarkLighting();
|
||||||
|
size_t MarkObjects();
|
||||||
|
size_t MarkPlayers();
|
||||||
|
size_t MarkQueen();
|
||||||
|
size_t MarkRa();
|
||||||
|
size_t MarkSnake();
|
||||||
|
size_t MarkRunlist();
|
||||||
|
|
||||||
|
|
||||||
|
static void markgcroots()
|
||||||
|
{
|
||||||
|
size_t num = MarkMove();
|
||||||
|
num += MarkBullets();
|
||||||
|
num += MarkInput();
|
||||||
|
num += MarkItems();
|
||||||
|
num += MarkLighting();
|
||||||
|
num += MarkObjects();
|
||||||
|
num += MarkPlayers();
|
||||||
|
num += MarkQueen();
|
||||||
|
num += MarkRa();
|
||||||
|
num += MarkSnake();
|
||||||
|
num += MarkRunlist();
|
||||||
|
|
||||||
|
GC::Mark(bestTarget);
|
||||||
|
GC::Mark(pSpiritSprite);
|
||||||
|
num += 2;
|
||||||
|
|
||||||
|
Printf("%d objects marked\n", num);
|
||||||
|
}
|
||||||
|
|
||||||
static MapRecord* NextMap;
|
static MapRecord* NextMap;
|
||||||
|
|
||||||
void uploadCinemaPalettes();
|
void uploadCinemaPalettes();
|
||||||
|
@ -138,7 +174,6 @@ bool bInDemo = false;
|
||||||
bool bSlipMode = false;
|
bool bSlipMode = false;
|
||||||
bool bDoFlashes = true;
|
bool bDoFlashes = true;
|
||||||
|
|
||||||
DExhumedActor* bestTarget;
|
|
||||||
|
|
||||||
int nStartLevel;
|
int nStartLevel;
|
||||||
int nTimeLimit;
|
int nTimeLimit;
|
||||||
|
@ -468,6 +503,8 @@ static void SetTileNames()
|
||||||
void GameInterface::app_init()
|
void GameInterface::app_init()
|
||||||
{
|
{
|
||||||
SetupActors(RUNTIME_CLASS(DExhumedActor));
|
SetupActors(RUNTIME_CLASS(DExhumedActor));
|
||||||
|
GC::AddMarkerFunc(markgcroots);
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
help_disabled = true;
|
help_disabled = true;
|
||||||
|
|
|
@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
#include "names.h"
|
#include "names.h"
|
||||||
#include "exhumedactor.h"
|
#include "exhumedactor.h"
|
||||||
|
#include "serialize_obj.h"
|
||||||
|
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ extern int nEnergyTowers;
|
||||||
|
|
||||||
extern int nEnergyChan;
|
extern int nEnergyChan;
|
||||||
|
|
||||||
extern DExhumedActor* pSpiritSprite;
|
extern TObjPtr<DExhumedActor*> pSpiritSprite;
|
||||||
|
|
||||||
extern bool bInDemo;
|
extern bool bInDemo;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ class DExhumedActor : public DCoreActor
|
||||||
HAS_OBJECT_POINTERS
|
HAS_OBJECT_POINTERS
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DExhumedActor* pTarget;
|
TObjPtr<DExhumedActor*> pTarget;
|
||||||
|
|
||||||
int16_t nPhase;
|
int16_t nPhase;
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,7 @@ void AIFish::Tick(RunListEvent* ev)
|
||||||
pActor->nFrame = 0;
|
pActor->nFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTargetActor = pActor->pTarget;
|
DExhumedActor* pTargetActor = pActor->pTarget;
|
||||||
|
|
||||||
switch (nAction)
|
switch (nAction)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ void ThrowGrenade(int nPlayer, int, int, int ecx, int push1)
|
||||||
if (PlayerList[nPlayer].pPlayerGrenade == nullptr)
|
if (PlayerList[nPlayer].pPlayerGrenade == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto pActor = PlayerList[nPlayer].pPlayerGrenade;
|
DExhumedActor* pActor = PlayerList[nPlayer].pPlayerGrenade;
|
||||||
auto pGrenadeSprite = &pActor->s();
|
auto pGrenadeSprite = &pActor->s();
|
||||||
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
||||||
auto pPlayerSprite = &pPlayerActor->s();
|
auto pPlayerSprite = &pPlayerActor->s();
|
||||||
|
|
|
@ -807,7 +807,7 @@ loc_flag:
|
||||||
DExhumedActor* target = nullptr;
|
DExhumedActor* target = nullptr;
|
||||||
if (sPlayerInput[nPlayer].pTarget != nullptr && Autoaim(nPlayer))
|
if (sPlayerInput[nPlayer].pTarget != nullptr && Autoaim(nPlayer))
|
||||||
{
|
{
|
||||||
auto t = sPlayerInput[nPlayer].pTarget;
|
DExhumedActor* t = sPlayerInput[nPlayer].pTarget;
|
||||||
// only autoaim if target is in front of the player.
|
// only autoaim if target is in front of the player.
|
||||||
auto pTargetSprite = &t->s();
|
auto pTargetSprite = &t->s();
|
||||||
assert(pTargetSprite->sector());
|
assert(pTargetSprite->sector());
|
||||||
|
|
|
@ -45,12 +45,9 @@ sectortype* initsectp;
|
||||||
|
|
||||||
int nCurChunkNum = 0;
|
int nCurChunkNum = 0;
|
||||||
|
|
||||||
DExhumedActor* nBodyGunSprite[50];
|
|
||||||
int movefifoend;
|
int movefifoend;
|
||||||
int movefifopos;
|
int movefifopos;
|
||||||
|
|
||||||
int nCurBodyGunNum;
|
|
||||||
|
|
||||||
int Counters[kNumCounters];
|
int Counters[kNumCounters];
|
||||||
|
|
||||||
|
|
||||||
|
@ -846,8 +843,6 @@ void SerializeInit(FSerializer& arc)
|
||||||
("inita", inita)
|
("inita", inita)
|
||||||
("initsect", initsectp)
|
("initsect", initsectp)
|
||||||
("curchunk", nCurChunkNum)
|
("curchunk", nCurChunkNum)
|
||||||
.Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite))
|
|
||||||
("curbodygun", nCurBodyGunNum)
|
|
||||||
.Array("counters", Counters, kNumCounters)
|
.Array("counters", Counters, kNumCounters)
|
||||||
.EndObject();
|
.EndObject();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,15 @@ BEGIN_PS_NS
|
||||||
|
|
||||||
PlayerInput sPlayerInput[kMaxPlayers];
|
PlayerInput sPlayerInput[kMaxPlayers];
|
||||||
|
|
||||||
|
size_t MarkInput()
|
||||||
|
{
|
||||||
|
for (auto& p : sPlayerInput)
|
||||||
|
{
|
||||||
|
GC::Mark(p.pTarget);
|
||||||
|
}
|
||||||
|
return kMaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
void ClearSpaceBar(int nPlayer)
|
void ClearSpaceBar(int nPlayer)
|
||||||
{
|
{
|
||||||
sPlayerInput[nPlayer].actions &= SB_OPEN;
|
sPlayerInput[nPlayer].actions &= SB_OPEN;
|
||||||
|
|
|
@ -32,7 +32,7 @@ enum {
|
||||||
// 32 bytes
|
// 32 bytes
|
||||||
struct PlayerInput
|
struct PlayerInput
|
||||||
{
|
{
|
||||||
DExhumedActor* pTarget;
|
TObjPtr<DExhumedActor*> pTarget;
|
||||||
int xVel;
|
int xVel;
|
||||||
int yVel;
|
int yVel;
|
||||||
uint16_t buttons;
|
uint16_t buttons;
|
||||||
|
|
|
@ -98,9 +98,15 @@ AnimInfo nItemAnimInfo[] = {
|
||||||
|
|
||||||
const int16_t nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 };
|
const int16_t nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 };
|
||||||
|
|
||||||
TArray<DExhumedActor*> Regenerates;
|
TArray<DExhumedActor*> Regenerates; // must handle read barriers manually!
|
||||||
int nMagicCount;
|
int nMagicCount;
|
||||||
|
|
||||||
|
size_t MarkItems()
|
||||||
|
{
|
||||||
|
GC::MarkArray(Regenerates);
|
||||||
|
return Regenerates.Size();
|
||||||
|
}
|
||||||
|
|
||||||
void SerializeItems(FSerializer& arc)
|
void SerializeItems(FSerializer& arc)
|
||||||
{
|
{
|
||||||
if (arc.BeginObject("items"))
|
if (arc.BeginObject("items"))
|
||||||
|
@ -395,7 +401,7 @@ void DoRegenerates()
|
||||||
{
|
{
|
||||||
for(unsigned i = 0; i < Regenerates.Size(); i++)
|
for(unsigned i = 0; i < Regenerates.Size(); i++)
|
||||||
{
|
{
|
||||||
auto pActor = Regenerates[i];
|
DExhumedActor* pActor = GC::ReadBarrier(Regenerates[i]);
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
if (pSprite->extra > 0)
|
if (pSprite->extra > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -255,7 +255,7 @@ void AILavaDude::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTarget = pActor->pTarget;
|
DExhumedActor* pTarget = pActor->pTarget;
|
||||||
|
|
||||||
if (pTarget && nAction < 4)
|
if (pTarget && nAction < 4)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct Flash
|
||||||
{
|
{
|
||||||
walltype* pWall;
|
walltype* pWall;
|
||||||
sectortype* pSector;
|
sectortype* pSector;
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
};
|
};
|
||||||
int next;
|
int next;
|
||||||
int8_t nType;
|
int8_t nType;
|
||||||
|
@ -100,6 +100,15 @@ int nGlowCount;
|
||||||
int bDoFlicks = 0;
|
int bDoFlicks = 0;
|
||||||
int bDoGlows = 0;
|
int bDoGlows = 0;
|
||||||
|
|
||||||
|
size_t MarkLighting()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < kMaxFlashes; i++)
|
||||||
|
{
|
||||||
|
auto& f = sFlash[i];
|
||||||
|
if (f.nType & 4) GC::Mark(f.pActor);
|
||||||
|
}
|
||||||
|
return kMaxFlashes;
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, Flash& w, Flash* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, Flash& w, Flash* def)
|
||||||
{
|
{
|
||||||
|
@ -442,12 +451,10 @@ void UndoFlashes()
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
auto ac = pFlash->pActor;
|
DExhumedActor* ac = pFlash->pActor;
|
||||||
if (!ac) continue;
|
if (ac && ac->spr.pal >= 7)
|
||||||
auto sp = &ac->s();
|
|
||||||
if (sp->pal >= 7)
|
|
||||||
{
|
{
|
||||||
pShade = &sp->shade;
|
pShade = &ac->spr.shade;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto loc_1868A;
|
goto loc_1868A;
|
||||||
|
@ -505,12 +512,11 @@ void UndoFlashes()
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
auto ac = pFlash->pActor;
|
DExhumedActor* ac = pFlash->pActor;
|
||||||
auto sp = &ac->s();
|
if (ac && ac->spr.pal >= 7)
|
||||||
if (sp->pal >= 7)
|
|
||||||
{
|
{
|
||||||
sp->pal -= 7;
|
ac->spr.pal -= 7;
|
||||||
sp->shade = pFlash->shade;
|
ac->spr.shade = pFlash->shade;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -222,7 +222,7 @@ void AILion::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
||||||
auto pTarget = pActor->pTarget;
|
DExhumedActor* pTarget = pActor->pTarget;
|
||||||
|
|
||||||
auto nMov = MoveCreatureWithCaution(pActor);
|
auto nMov = MoveCreatureWithCaution(pActor);
|
||||||
|
|
||||||
|
|
|
@ -35,21 +35,33 @@ int nPushBlocks;
|
||||||
// TODO - moveme?
|
// TODO - moveme?
|
||||||
sectortype* overridesect;
|
sectortype* overridesect;
|
||||||
|
|
||||||
DExhumedActor* nBodySprite[50];
|
enum
|
||||||
|
{
|
||||||
|
kMaxPushBlocks = 100,
|
||||||
|
kMaxMoveChunks = 75
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TObjPtr<DExhumedActor*> nBodySprite[50];
|
||||||
|
TObjPtr<DExhumedActor*> nChunkSprite[kMaxMoveChunks];
|
||||||
|
BlockInfo sBlockInfo[kMaxPushBlocks];
|
||||||
|
TObjPtr<DExhumedActor*> nBodyGunSprite[50];
|
||||||
|
int nCurBodyGunNum;
|
||||||
|
|
||||||
int sprceiling, sprfloor;
|
int sprceiling, sprfloor;
|
||||||
Collision loHit, hiHit;
|
Collision loHit, hiHit;
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kMaxPushBlocks = 100,
|
|
||||||
kMaxMoveChunks = 75
|
|
||||||
};
|
|
||||||
|
|
||||||
// think this belongs in init.c?
|
// think this belongs in init.c?
|
||||||
BlockInfo sBlockInfo[kMaxPushBlocks];
|
|
||||||
|
|
||||||
DExhumedActor *nChunkSprite[kMaxMoveChunks];
|
|
||||||
|
size_t MarkMove()
|
||||||
|
{
|
||||||
|
GC::MarkArray(nBodySprite, 50);
|
||||||
|
GC::MarkArray(nChunkSprite, kMaxMoveChunks);
|
||||||
|
for(int i = 0; i < nPushBlocks; i++)
|
||||||
|
GC::Mark(sBlockInfo[i].pActor);
|
||||||
|
return 50 + kMaxMoveChunks + nPushBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, BlockInfo* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, BlockInfo* def)
|
||||||
{
|
{
|
||||||
|
@ -73,7 +85,9 @@ void SerializeMove(FSerializer& arc)
|
||||||
("chunkcount", nCurChunkNum)
|
("chunkcount", nCurChunkNum)
|
||||||
.Array("chunks", nChunkSprite, kMaxMoveChunks)
|
.Array("chunks", nChunkSprite, kMaxMoveChunks)
|
||||||
("overridesect", overridesect)
|
("overridesect", overridesect)
|
||||||
.Array("bodysprite", nBodySprite, 50)
|
.Array("bodysprite", nBodySprite, countof(nBodySprite))
|
||||||
|
("curbodygun", nCurBodyGunNum)
|
||||||
|
.Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite))
|
||||||
.EndObject();
|
.EndObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1281,7 +1295,7 @@ void InitChunks()
|
||||||
|
|
||||||
DExhumedActor* GrabBodyGunSprite()
|
DExhumedActor* GrabBodyGunSprite()
|
||||||
{
|
{
|
||||||
auto pActor = nBodyGunSprite[nCurBodyGunNum];
|
DExhumedActor* pActor = nBodyGunSprite[nCurBodyGunNum];
|
||||||
spritetype* pSprite;
|
spritetype* pSprite;
|
||||||
if (pActor == nullptr)
|
if (pActor == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1346,7 +1360,7 @@ DExhumedActor* GrabBody()
|
||||||
|
|
||||||
DExhumedActor* GrabChunkSprite()
|
DExhumedActor* GrabChunkSprite()
|
||||||
{
|
{
|
||||||
auto pActor = nChunkSprite[nCurChunkNum];
|
DExhumedActor* pActor = nChunkSprite[nCurChunkNum];
|
||||||
|
|
||||||
if (pActor == nullptr)
|
if (pActor == nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,9 @@ void AIMummy::Tick(RunListEvent* ev)
|
||||||
auto pActor = ev->pObjActor;
|
auto pActor = ev->pObjActor;
|
||||||
if (!pActor) return;
|
if (!pActor) return;
|
||||||
|
|
||||||
auto pTarget = UpdateEnemy(&pActor->pTarget);
|
DExhumedActor* targ = pActor->pTarget;
|
||||||
|
auto pTarget = UpdateEnemy(&targ);
|
||||||
|
pActor->pTarget = targ;
|
||||||
|
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
int nAction = pActor->nAction;
|
int nAction = pActor->nAction;
|
||||||
|
|
|
@ -67,14 +67,14 @@ struct Bob
|
||||||
|
|
||||||
struct Drip
|
struct Drip
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
int16_t nCount;
|
int16_t nCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 56 bytes
|
// 56 bytes
|
||||||
struct Elev
|
struct Elev
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
sectortype* pSector;
|
sectortype* pSector;
|
||||||
int16_t nFlags;
|
int16_t nFlags;
|
||||||
int16_t nChannel;
|
int16_t nChannel;
|
||||||
|
@ -110,7 +110,7 @@ struct wallFace
|
||||||
|
|
||||||
struct slideData
|
struct slideData
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
int16_t nChannel;
|
int16_t nChannel;
|
||||||
int16_t nStart;
|
int16_t nStart;
|
||||||
int16_t nRunRec;
|
int16_t nRunRec;
|
||||||
|
@ -142,7 +142,7 @@ struct Point
|
||||||
|
|
||||||
struct Trap
|
struct Trap
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
walltype* pWall1;
|
walltype* pWall1;
|
||||||
walltype* pWall2;
|
walltype* pWall2;
|
||||||
|
|
||||||
|
@ -167,11 +167,22 @@ TArray<slideData> SlideData;
|
||||||
TArray<wallFace> WallFace;
|
TArray<wallFace> WallFace;
|
||||||
TArray<Drip> sDrip;
|
TArray<Drip> sDrip;
|
||||||
TArray<DExhumedActor*> EnergyBlocks;
|
TArray<DExhumedActor*> EnergyBlocks;
|
||||||
|
TObjPtr<DExhumedActor*> pFinaleSpr;
|
||||||
|
|
||||||
|
size_t MarkObjects()
|
||||||
|
{
|
||||||
|
GC::Mark(pFinaleSpr);
|
||||||
|
for (auto& d : sDrip) GC::Mark(d.pActor);
|
||||||
|
for (auto& d : sTrap) GC::Mark(d.pActor);
|
||||||
|
for (auto& d : Elevator) GC::Mark(d.pActor);
|
||||||
|
for (auto& d : SlideData) GC::Mark(d.pActor);
|
||||||
|
GC::MarkArray(EnergyBlocks);
|
||||||
|
return 1 + sDrip.Size() + sTrap.Size() + Elevator.Size() + SlideData.Size();
|
||||||
|
}
|
||||||
|
|
||||||
int lFinaleStart;
|
int lFinaleStart;
|
||||||
|
|
||||||
int nFinaleStage;
|
int nFinaleStage;
|
||||||
DExhumedActor* pFinaleSpr;
|
|
||||||
|
|
||||||
int nDronePitch = 0;
|
int nDronePitch = 0;
|
||||||
int nSmokeSparks = 0;
|
int nSmokeSparks = 0;
|
||||||
|
@ -751,7 +762,7 @@ void AIElev::Tick(RunListEvent* ev)
|
||||||
assert(nChannel >= 0 && nChannel < kMaxChannels);
|
assert(nChannel >= 0 && nChannel < kMaxChannels);
|
||||||
|
|
||||||
auto pSector =Elevator[nElev].pSector;
|
auto pSector =Elevator[nElev].pSector;
|
||||||
auto pElevSpr = Elevator[nElev].pActor;
|
DExhumedActor* pElevSpr = Elevator[nElev].pActor;
|
||||||
|
|
||||||
int ebp = 0; // initialise to *something*
|
int ebp = 0; // initialise to *something*
|
||||||
|
|
||||||
|
@ -1274,7 +1285,8 @@ void AITrap::ProcessChannel(RunListEvent* ev)
|
||||||
void AITrap::Tick(RunListEvent* ev)
|
void AITrap::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nTrap = RunData[ev->nRun].nObjIndex;
|
int nTrap = RunData[ev->nRun].nObjIndex;
|
||||||
auto pActor = sTrap[nTrap].pActor;
|
DExhumedActor* pActor = sTrap[nTrap].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
if (sTrap[nTrap].nState >= 0)
|
if (sTrap[nTrap].nState >= 0)
|
||||||
|
@ -2120,7 +2132,8 @@ void DoDrips()
|
||||||
sDrip[i].nCount--;
|
sDrip[i].nCount--;
|
||||||
if (sDrip[i].nCount <= 0)
|
if (sDrip[i].nCount <= 0)
|
||||||
{
|
{
|
||||||
auto pActor = sDrip[i].pActor;
|
DExhumedActor* pActor = sDrip[i].pActor;
|
||||||
|
if (!pActor) continue;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
int nSeqOffset = SeqOffsets[kSeqDrips];
|
int nSeqOffset = SeqOffsets[kSeqDrips];
|
||||||
|
|
|
@ -77,7 +77,7 @@ int nLocalPlayer = 0;
|
||||||
|
|
||||||
Player PlayerList[kMaxPlayers];
|
Player PlayerList[kMaxPlayers];
|
||||||
|
|
||||||
DExhumedActor* nNetStartSprite[kMaxPlayers] = { };
|
TObjPtr<DExhumedActor*> nNetStartSprite[kMaxPlayers] = { };
|
||||||
|
|
||||||
int nStandHeight;
|
int nStandHeight;
|
||||||
|
|
||||||
|
@ -87,6 +87,20 @@ int PlayerCount;
|
||||||
int nNetStartSprites;
|
int nNetStartSprites;
|
||||||
int nCurStartSprite;
|
int nCurStartSprite;
|
||||||
|
|
||||||
|
|
||||||
|
size_t MarkPlayers()
|
||||||
|
{
|
||||||
|
for (auto& p : PlayerList)
|
||||||
|
{
|
||||||
|
GC::Mark(p.pActor);
|
||||||
|
GC::Mark(p.pDoppleSprite);
|
||||||
|
GC::Mark(p.pPlayerFloorSprite);
|
||||||
|
GC::Mark(p.pPlayerGrenade);
|
||||||
|
}
|
||||||
|
GC::MarkArray(nNetStartSprite, kMaxPlayers);
|
||||||
|
return 5 * kMaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
void SetSavePoint(int nPlayer, int x, int y, int z, sectortype* pSector, int nAngle)
|
void SetSavePoint(int nPlayer, int x, int y, int z, sectortype* pSector, int nAngle)
|
||||||
{
|
{
|
||||||
PlayerList[nPlayer].sPlayerSave.x = x;
|
PlayerList[nPlayer].sPlayerSave.x = x;
|
||||||
|
@ -206,7 +220,7 @@ void RestartPlayer(int nPlayer)
|
||||||
{
|
{
|
||||||
auto plr = &PlayerList[nPlayer];
|
auto plr = &PlayerList[nPlayer];
|
||||||
auto pActor = plr->Actor();
|
auto pActor = plr->Actor();
|
||||||
auto pDopSprite = plr->pDoppleSprite;
|
DExhumedActor* pDopSprite = plr->pDoppleSprite;
|
||||||
|
|
||||||
DExhumedActor* floorsprt;
|
DExhumedActor* floorsprt;
|
||||||
|
|
||||||
|
@ -220,7 +234,7 @@ void RestartPlayer(int nPlayer)
|
||||||
|
|
||||||
plr->pActor = nullptr;
|
plr->pActor = nullptr;
|
||||||
|
|
||||||
auto pFloorSprite = plr->pPlayerFloorSprite;
|
DExhumedActor* pFloorSprite = plr->pPlayerFloorSprite;
|
||||||
if (pFloorSprite != nullptr) {
|
if (pFloorSprite != nullptr) {
|
||||||
DeleteActor(pFloorSprite);
|
DeleteActor(pFloorSprite);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +259,7 @@ void RestartPlayer(int nPlayer)
|
||||||
|
|
||||||
if (nTotalPlayers > 1)
|
if (nTotalPlayers > 1)
|
||||||
{
|
{
|
||||||
auto nNStartSprite = nNetStartSprite[nCurStartSprite];
|
DExhumedActor* nNStartSprite = nNetStartSprite[nCurStartSprite];
|
||||||
auto nstspr = &nNStartSprite->s();
|
auto nstspr = &nNStartSprite->s();
|
||||||
nCurStartSprite++;
|
nCurStartSprite++;
|
||||||
|
|
||||||
|
@ -548,7 +562,7 @@ int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount)
|
||||||
|
|
||||||
void SetPlayerMummified(int nPlayer, int bIsMummified)
|
void SetPlayerMummified(int nPlayer, int bIsMummified)
|
||||||
{
|
{
|
||||||
auto pActor = PlayerList[nPlayer].pActor;
|
DExhumedActor* pActor = PlayerList[nPlayer].pActor;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
pSprite->yvel = 0;
|
pSprite->yvel = 0;
|
||||||
|
@ -633,13 +647,13 @@ void AIPlayer::Damage(RunListEvent* ev)
|
||||||
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
||||||
int nAction = PlayerList[nPlayer].nAction;
|
int nAction = PlayerList[nPlayer].nAction;
|
||||||
auto pPlayerSprite = &pPlayerActor->s();
|
auto pPlayerSprite = &pPlayerActor->s();
|
||||||
auto pDopple = PlayerList[nPlayer].pDoppleSprite;
|
DExhumedActor* pDopple = PlayerList[nPlayer].pDoppleSprite;
|
||||||
|
|
||||||
if (!nDamage) {
|
if (!nDamage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DExhumedActor* pActor2 = (!ev->isRadialEvent()) ? ev->pOtherActor : ev->pRadialActor->pTarget;
|
DExhumedActor* pActor2 = (!ev->isRadialEvent()) ? ev->pOtherActor : ev->pRadialActor->pTarget.Get();
|
||||||
|
|
||||||
// ok continue case 0x80000 as normal, loc_1C57C
|
// ok continue case 0x80000 as normal, loc_1C57C
|
||||||
if (!PlayerList[nPlayer].nHealth) {
|
if (!PlayerList[nPlayer].nHealth) {
|
||||||
|
@ -744,7 +758,7 @@ void AIPlayer::Tick(RunListEvent* ev)
|
||||||
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
||||||
auto pPlayerSprite = &pPlayerActor->s();
|
auto pPlayerSprite = &pPlayerActor->s();
|
||||||
|
|
||||||
auto pDopple = PlayerList[nPlayer].pDoppleSprite;
|
DExhumedActor* pDopple = PlayerList[nPlayer].pDoppleSprite;
|
||||||
|
|
||||||
int nAction = PlayerList[nPlayer].nAction;
|
int nAction = PlayerList[nPlayer].nAction;
|
||||||
int nActionB = PlayerList[nPlayer].nAction;
|
int nActionB = PlayerList[nPlayer].nAction;
|
||||||
|
@ -803,7 +817,7 @@ void AIPlayer::Tick(RunListEvent* ev)
|
||||||
if (PlayerList[nPlayer].nInvisible == 0)
|
if (PlayerList[nPlayer].nInvisible == 0)
|
||||||
{
|
{
|
||||||
pPlayerSprite->cstat &= 0x7FFF; // set visible
|
pPlayerSprite->cstat &= 0x7FFF; // set visible
|
||||||
auto pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite;
|
DExhumedActor* pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite;
|
||||||
|
|
||||||
if (pFloorSprite != nullptr) {
|
if (pFloorSprite != nullptr) {
|
||||||
pFloorSprite->s().cstat &= 0x7FFF; // set visible
|
pFloorSprite->s().cstat &= 0x7FFF; // set visible
|
||||||
|
@ -1049,7 +1063,7 @@ void AIPlayer::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
PlayerList[nPlayer].nPlayerPushSound = 1;
|
PlayerList[nPlayer].nPlayerPushSound = 1;
|
||||||
int nBlock = PlayerList[nPlayer].pPlayerPushSect->extra;
|
int nBlock = PlayerList[nPlayer].pPlayerPushSect->extra;
|
||||||
auto pBlockActor = sBlockInfo[nBlock].pActor;
|
DExhumedActor* pBlockActor = sBlockInfo[nBlock].pActor;
|
||||||
|
|
||||||
D3PlayFX(StaticSound[kSound23], pBlockActor, 0x4000);
|
D3PlayFX(StaticSound[kSound23], pBlockActor, 0x4000);
|
||||||
}
|
}
|
||||||
|
@ -1274,7 +1288,7 @@ sectdone:
|
||||||
}
|
}
|
||||||
|
|
||||||
// loc_1B1EB
|
// loc_1B1EB
|
||||||
auto pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite;
|
DExhumedActor* pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite;
|
||||||
if (nTotalPlayers > 1 && pFloorActor)
|
if (nTotalPlayers > 1 && pFloorActor)
|
||||||
{
|
{
|
||||||
auto pFloorSprite = &pFloorActor->s();
|
auto pFloorSprite = &pFloorActor->s();
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct PlayerSave
|
||||||
struct Player
|
struct Player
|
||||||
{
|
{
|
||||||
DExhumedActor* Actor() { return pActor; }
|
DExhumedActor* Actor() { return pActor; }
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
int16_t nHealth;
|
int16_t nHealth;
|
||||||
int16_t nLives;
|
int16_t nLives;
|
||||||
int16_t nDouble;
|
int16_t nDouble;
|
||||||
|
@ -108,9 +108,9 @@ struct Player
|
||||||
int ototalvel;
|
int ototalvel;
|
||||||
int totalvel;
|
int totalvel;
|
||||||
int16_t eyelevel, oeyelevel;
|
int16_t eyelevel, oeyelevel;
|
||||||
DExhumedActor* pPlayerGrenade;
|
TObjPtr<DExhumedActor*> pPlayerGrenade;
|
||||||
DExhumedActor* pPlayerFloorSprite;
|
TObjPtr<DExhumedActor*> pPlayerFloorSprite;
|
||||||
DExhumedActor* pDoppleSprite;
|
TObjPtr<DExhumedActor*> pDoppleSprite;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ extern Player PlayerList[kMaxPlayers];
|
||||||
|
|
||||||
extern int obobangle, bobangle;
|
extern int obobangle, bobangle;
|
||||||
|
|
||||||
extern DExhumedActor* nNetStartSprite[kMaxPlayers];
|
extern TObjPtr<DExhumedActor*> nNetStartSprite[kMaxPlayers];
|
||||||
extern int nNetStartSprites;
|
extern int nNetStartSprites;
|
||||||
extern int nCurStartSprite;
|
extern int nCurStartSprite;
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ static actionSeq EggSeq[] = {
|
||||||
|
|
||||||
struct Queen
|
struct Queen
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
DExhumedActor* pTarget;
|
TObjPtr<DExhumedActor*> pTarget;
|
||||||
int16_t nHealth;
|
int16_t nHealth;
|
||||||
int16_t nFrame;
|
int16_t nFrame;
|
||||||
int16_t nAction;
|
int16_t nAction;
|
||||||
|
@ -83,8 +83,8 @@ struct Queen
|
||||||
|
|
||||||
struct Egg
|
struct Egg
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
DExhumedActor* pTarget;
|
TObjPtr<DExhumedActor*> pTarget;
|
||||||
int16_t nHealth;
|
int16_t nHealth;
|
||||||
int16_t nFrame;
|
int16_t nFrame;
|
||||||
int16_t nAction;
|
int16_t nAction;
|
||||||
|
@ -94,8 +94,8 @@ struct Egg
|
||||||
|
|
||||||
struct Head
|
struct Head
|
||||||
{
|
{
|
||||||
DExhumedActor* pActor;
|
TObjPtr<DExhumedActor*> pActor;
|
||||||
DExhumedActor* pTarget;
|
TObjPtr<DExhumedActor*> pTarget;
|
||||||
int16_t nHealth;
|
int16_t nHealth;
|
||||||
int16_t nFrame;
|
int16_t nFrame;
|
||||||
int16_t nAction;
|
int16_t nAction;
|
||||||
|
@ -112,7 +112,7 @@ int nQHead = 0;
|
||||||
int nHeadVel;
|
int nHeadVel;
|
||||||
int nVelShift;
|
int nVelShift;
|
||||||
|
|
||||||
DExhumedActor* tailspr[kMaxTails];
|
TObjPtr<DExhumedActor*> tailspr[kMaxTails];
|
||||||
|
|
||||||
|
|
||||||
Queen QueenList[kMaxQueens];
|
Queen QueenList[kMaxQueens];
|
||||||
|
@ -124,6 +124,21 @@ int MoveQZ[25];
|
||||||
sectortype* MoveQS[25];
|
sectortype* MoveQS[25];
|
||||||
int16_t MoveQA[25];
|
int16_t MoveQA[25];
|
||||||
|
|
||||||
|
|
||||||
|
size_t MarkQueen()
|
||||||
|
{
|
||||||
|
GC::Mark(QueenList[0].pActor);
|
||||||
|
GC::Mark(QueenList[0].pTarget);
|
||||||
|
GC::Mark(QueenHead.pActor);
|
||||||
|
GC::Mark(QueenHead.pTarget);
|
||||||
|
for (int i = 0; i < kMaxEggs; i++)
|
||||||
|
{
|
||||||
|
GC::Mark(QueenEgg[i].pActor);
|
||||||
|
GC::Mark(QueenEgg[i].pTarget);
|
||||||
|
}
|
||||||
|
return 4 + 2 * kMaxEggs;
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, Queen& w, Queen* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, Queen& w, Queen* def)
|
||||||
{
|
{
|
||||||
if (arc.BeginObject(keyname))
|
if (arc.BeginObject(keyname))
|
||||||
|
@ -229,7 +244,8 @@ void BlowChunks(DExhumedActor* pActor)
|
||||||
|
|
||||||
void DestroyEgg(int nEgg)
|
void DestroyEgg(int nEgg)
|
||||||
{
|
{
|
||||||
auto pActor = QueenEgg[nEgg].pActor;
|
DExhumedActor* pActor = QueenEgg[nEgg].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
if (QueenEgg[nEgg].nAction != 4)
|
if (QueenEgg[nEgg].nAction != 4)
|
||||||
|
@ -360,7 +376,8 @@ int DestroyTailPart()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pActor = tailspr[--QueenHead.nIndex2];
|
DExhumedActor* pActor = tailspr[--QueenHead.nIndex2];
|
||||||
|
if (!pActor) return 0;
|
||||||
|
|
||||||
BlowChunks(pActor);
|
BlowChunks(pActor);
|
||||||
BuildExplosion(pActor);
|
BuildExplosion(pActor);
|
||||||
|
@ -430,7 +447,8 @@ void BuildQueenEgg(int nQueen, int nVal)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pActor = QueenList[nQueen].pActor;
|
DExhumedActor* pActor = QueenList[nQueen].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
int x = pSprite->x;
|
int x = pSprite->x;
|
||||||
|
@ -500,7 +518,8 @@ void AIQueenEgg::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nEgg = RunData[ev->nRun].nObjIndex;
|
int nEgg = RunData[ev->nRun].nObjIndex;
|
||||||
Egg* pEgg = &QueenEgg[nEgg];
|
Egg* pEgg = &QueenEgg[nEgg];
|
||||||
auto pActor = pEgg->pActor;
|
DExhumedActor* pActor = pEgg->pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
int nAction = pEgg->nAction;
|
int nAction = pEgg->nAction;
|
||||||
|
|
||||||
|
@ -533,7 +552,9 @@ void AIQueenEgg::Tick(RunListEvent* ev)
|
||||||
bVal = true;
|
bVal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pTarget = UpdateEnemy(&pEgg->pActor);
|
DExhumedActor* enemy = pEgg->pActor;
|
||||||
|
pTarget = UpdateEnemy(&enemy);
|
||||||
|
pEgg->pActor = enemy;
|
||||||
pEgg->pTarget = pTarget;
|
pEgg->pTarget = pTarget;
|
||||||
|
|
||||||
if (pTarget && (pTarget->s().cstat & 0x101) == 0)
|
if (pTarget && (pTarget->s().cstat & 0x101) == 0)
|
||||||
|
@ -655,7 +676,8 @@ void AIQueenEgg::RadialDamage(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nEgg = RunData[ev->nRun].nObjIndex;
|
int nEgg = RunData[ev->nRun].nObjIndex;
|
||||||
Egg* pEgg = &QueenEgg[nEgg];
|
Egg* pEgg = &QueenEgg[nEgg];
|
||||||
auto pActor = pEgg->pActor;
|
DExhumedActor* pActor = pEgg->pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
auto pRadial = &ev->pRadialActor->s();
|
auto pRadial = &ev->pRadialActor->s();
|
||||||
|
|
||||||
|
@ -690,7 +712,8 @@ void AIQueenEgg::Draw(RunListEvent* ev)
|
||||||
|
|
||||||
void BuildQueenHead(int nQueen)
|
void BuildQueenHead(int nQueen)
|
||||||
{
|
{
|
||||||
auto pActor = QueenList[nQueen].pActor;
|
DExhumedActor* pActor = QueenList[nQueen].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
int x = pSprite->x;
|
int x = pSprite->x;
|
||||||
|
@ -742,7 +765,8 @@ void BuildQueenHead(int nQueen)
|
||||||
|
|
||||||
void AIQueenHead::Tick(RunListEvent* ev)
|
void AIQueenHead::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
auto pActor = QueenHead.pActor;
|
DExhumedActor* pActor = QueenHead.pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
int nAction = QueenHead.nAction;
|
int nAction = QueenHead.nAction;
|
||||||
|
@ -766,7 +790,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
|
||||||
var_14 = 1;
|
var_14 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTarget = QueenHead.pTarget;
|
DExhumedActor* pTarget = QueenHead.pTarget;
|
||||||
|
|
||||||
if (pTarget)
|
if (pTarget)
|
||||||
{
|
{
|
||||||
|
@ -930,7 +954,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto headSect = MoveQS[nHd];
|
auto headSect = MoveQS[nHd];
|
||||||
auto pTActor = tailspr[i];
|
DExhumedActor* pTActor = tailspr[i];
|
||||||
if (pTActor)
|
if (pTActor)
|
||||||
{
|
{
|
||||||
auto pTSprite = &pTActor->s();
|
auto pTSprite = &pTActor->s();
|
||||||
|
@ -1041,7 +1065,8 @@ void AIQueenHead::RadialDamage(RunListEvent* ev)
|
||||||
|
|
||||||
void AIQueenHead::Damage(RunListEvent* ev)
|
void AIQueenHead::Damage(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
auto pActor = QueenHead.pActor;
|
DExhumedActor* pActor = QueenHead.pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
if (QueenHead.nHealth > 0 && ev->nDamage != 0)
|
if (QueenHead.nHealth > 0 && ev->nDamage != 0)
|
||||||
|
@ -1176,11 +1201,12 @@ void AIQueen::Tick(RunListEvent* ev)
|
||||||
int nQueen = RunData[ev->nRun].nObjIndex;
|
int nQueen = RunData[ev->nRun].nObjIndex;
|
||||||
assert(nQueen >= 0 && nQueen < kMaxQueens);
|
assert(nQueen >= 0 && nQueen < kMaxQueens);
|
||||||
|
|
||||||
auto pActor = QueenList[nQueen].pActor;
|
DExhumedActor* pActor = QueenList[nQueen].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
int nAction = QueenList[nQueen].nAction;
|
int nAction = QueenList[nQueen].nAction;
|
||||||
int si = QueenList[nQueen].nAction2;
|
int si = QueenList[nQueen].nAction2;
|
||||||
auto pTarget = QueenList[nQueen].pTarget;
|
DExhumedActor* pTarget = QueenList[nQueen].pTarget;
|
||||||
|
|
||||||
bool bVal = false;
|
bool bVal = false;
|
||||||
|
|
||||||
|
@ -1435,7 +1461,8 @@ void AIQueen::RadialDamage(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nQueen = RunData[ev->nRun].nObjIndex;
|
int nQueen = RunData[ev->nRun].nObjIndex;
|
||||||
assert(nQueen >= 0 && nQueen < kMaxQueens);
|
assert(nQueen >= 0 && nQueen < kMaxQueens);
|
||||||
auto pActor = QueenList[nQueen].pActor;
|
DExhumedActor* pActor = QueenList[nQueen].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
auto pRadial = &ev->pRadialActor->s();
|
auto pRadial = &ev->pRadialActor->s();
|
||||||
|
|
||||||
|
@ -1451,7 +1478,8 @@ void AIQueen::Damage(RunListEvent* ev)
|
||||||
int nQueen = RunData[ev->nRun].nObjIndex;
|
int nQueen = RunData[ev->nRun].nObjIndex;
|
||||||
assert(nQueen >= 0 && nQueen < kMaxQueens);
|
assert(nQueen >= 0 && nQueen < kMaxQueens);
|
||||||
|
|
||||||
auto pActor = QueenList[nQueen].pActor;
|
DExhumedActor* pActor = QueenList[nQueen].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
int si = QueenList[nQueen].nAction2;
|
int si = QueenList[nQueen].nAction2;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,16 @@ static actionSeq RaSeq[] = {
|
||||||
{2, 0}
|
{2, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
size_t MarkRa()
|
||||||
|
{
|
||||||
|
for (auto& r : Ra)
|
||||||
|
{
|
||||||
|
GC::Mark(r.pActor);
|
||||||
|
GC::Mark(r.pTarget);
|
||||||
|
}
|
||||||
|
return 2 * kMaxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, RA& w, RA* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, RA& w, RA* def)
|
||||||
{
|
{
|
||||||
if (arc.BeginObject(keyname))
|
if (arc.BeginObject(keyname))
|
||||||
|
@ -62,7 +72,8 @@ void SerializeRa(FSerializer& arc)
|
||||||
void FreeRa(int nPlayer)
|
void FreeRa(int nPlayer)
|
||||||
{
|
{
|
||||||
int nRun = Ra[nPlayer].nRun;
|
int nRun = Ra[nPlayer].nRun;
|
||||||
auto pActor = Ra[nPlayer].pActor;
|
DExhumedActor* pActor = Ra[nPlayer].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
runlist_SubRunRec(nRun);
|
runlist_SubRunRec(nRun);
|
||||||
|
@ -70,6 +81,7 @@ void FreeRa(int nPlayer)
|
||||||
runlist_FreeRun(pSprite->lotag - 1);
|
runlist_FreeRun(pSprite->lotag - 1);
|
||||||
|
|
||||||
DeleteActor(pActor);
|
DeleteActor(pActor);
|
||||||
|
Ra[nPlayer] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildRa(int nPlayer)
|
void BuildRa(int nPlayer)
|
||||||
|
@ -112,8 +124,9 @@ void InitRa()
|
||||||
|
|
||||||
void MoveRaToEnemy(int nPlayer)
|
void MoveRaToEnemy(int nPlayer)
|
||||||
{
|
{
|
||||||
auto pTarget = Ra[nPlayer].pTarget;
|
DExhumedActor* pTarget = Ra[nPlayer].pTarget;
|
||||||
auto pActor = Ra[nPlayer].pActor;
|
DExhumedActor* pActor = Ra[nPlayer].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
int nAction = Ra[nPlayer].nAction;
|
int nAction = Ra[nPlayer].nAction;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
|
@ -171,7 +184,8 @@ void AIRa::Tick(RunListEvent* ev)
|
||||||
int nCurrentWeapon = PlayerList[nPlayer].nCurrentWeapon;
|
int nCurrentWeapon = PlayerList[nPlayer].nCurrentWeapon;
|
||||||
|
|
||||||
int nSeq = SeqOffsets[kSeqEyeHit] + RaSeq[Ra[nPlayer].nAction].a;
|
int nSeq = SeqOffsets[kSeqEyeHit] + RaSeq[Ra[nPlayer].nAction].a;
|
||||||
auto pActor = Ra[nPlayer].pActor;
|
DExhumedActor* pActor = Ra[nPlayer].pActor;
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
bool bVal = false;
|
bool bVal = false;
|
||||||
|
|
|
@ -57,7 +57,7 @@ int word_964EC = 10;
|
||||||
|
|
||||||
int nSpiritRepeatX;
|
int nSpiritRepeatX;
|
||||||
int nSpiritRepeatY;
|
int nSpiritRepeatY;
|
||||||
DExhumedActor* pSpiritSprite;
|
TObjPtr<DExhumedActor*> pSpiritSprite;
|
||||||
int nPixelsToShow;
|
int nPixelsToShow;
|
||||||
int nTalkTime = 0;
|
int nTalkTime = 0;
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ DExhumedActor* FindFood(DExhumedActor* pActor)
|
||||||
|
|
||||||
if (nChunkTotal)
|
if (nChunkTotal)
|
||||||
{
|
{
|
||||||
auto pActor2 = nChunkSprite[RandomSize(7) % nChunkTotal];
|
DExhumedActor* pActor2 = nChunkSprite[RandomSize(7) % nChunkTotal];
|
||||||
if (pActor2 != nullptr)
|
if (pActor2 != nullptr)
|
||||||
{
|
{
|
||||||
auto pSprite2 = &pActor2->s();
|
auto pSprite2 = &pActor2->s();
|
||||||
|
@ -152,7 +152,7 @@ DExhumedActor* FindFood(DExhumedActor* pActor)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pActor2 = nBodySprite[RandomSize(7) % nBodyTotal];
|
DExhumedActor* pActor2 = nBodySprite[RandomSize(7) % nBodyTotal];
|
||||||
if (pActor2 != nullptr)
|
if (pActor2 != nullptr)
|
||||||
{
|
{
|
||||||
auto pSprite2 = &pActor2->s();
|
auto pSprite2 = &pActor2->s();
|
||||||
|
@ -224,7 +224,7 @@ void AIRat::Tick(RunListEvent* ev)
|
||||||
pActor->nFrame = 0;
|
pActor->nFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTarget = pActor->pTarget;
|
DExhumedActor* pTarget = pActor->pTarget;
|
||||||
|
|
||||||
Gravity(pActor);
|
Gravity(pActor);
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ void AIRex::Tick(RunListEvent* ev)
|
||||||
|
|
||||||
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
||||||
|
|
||||||
auto pTarget = pActor->pTarget;
|
DExhumedActor* pTarget = pActor->pTarget;
|
||||||
|
|
||||||
switch (nAction)
|
switch (nAction)
|
||||||
{
|
{
|
||||||
|
|
|
@ -206,7 +206,7 @@ void AIRoach::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
||||||
auto pTarget = pActor->pTarget;
|
DExhumedActor* pTarget = pActor->pTarget;
|
||||||
|
|
||||||
if (nAction > 5) {
|
if (nAction > 5) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -48,6 +48,16 @@ RunChannel sRunChannels[kMaxChannels];
|
||||||
FreeListArray<RunStruct, kMaxRuns> RunData;
|
FreeListArray<RunStruct, kMaxRuns> RunData;
|
||||||
|
|
||||||
|
|
||||||
|
size_t MarkRunlist()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < kMaxRuns; i++) // only way to catch everything. :(
|
||||||
|
{
|
||||||
|
GC::Mark(RunData[i].pObjActor);
|
||||||
|
}
|
||||||
|
return kMaxRuns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunStruct* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunStruct* def)
|
||||||
{
|
{
|
||||||
if (arc.BeginObject(keyname))
|
if (arc.BeginObject(keyname))
|
||||||
|
@ -55,8 +65,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunS
|
||||||
arc("ref", w.nAIType)
|
arc("ref", w.nAIType)
|
||||||
("val", w.nObjIndex)
|
("val", w.nObjIndex)
|
||||||
("actor", w.pObjActor)
|
("actor", w.pObjActor)
|
||||||
("_4", w.next)
|
("next", w.next)
|
||||||
("_6", w.prev)
|
("prev", w.prev)
|
||||||
.EndObject();
|
.EndObject();
|
||||||
}
|
}
|
||||||
return arc;
|
return arc;
|
||||||
|
@ -490,7 +500,6 @@ void runlist_ReadyChannel(int eax)
|
||||||
|
|
||||||
void runlist_ProcessChannels()
|
void runlist_ProcessChannels()
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
int v0;
|
int v0;
|
||||||
int v1;
|
int v1;
|
||||||
int v5;
|
int v5;
|
||||||
|
@ -542,63 +551,6 @@ void runlist_ProcessChannels()
|
||||||
ChannelList = v1;
|
ChannelList = v1;
|
||||||
} while (v1 != -1);
|
} while (v1 != -1);
|
||||||
|
|
||||||
#else
|
|
||||||
int edi = -1;
|
|
||||||
int esi = edi;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int nChannel = ChannelList;
|
|
||||||
if (nChannel < 0)
|
|
||||||
{
|
|
||||||
ChannelList = esi;
|
|
||||||
if (esi != -1)
|
|
||||||
{
|
|
||||||
edi = -1;
|
|
||||||
esi = edi;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int b = sRunChannels[nChannel].b;
|
|
||||||
int d = sRunChannels[nChannel].d;
|
|
||||||
|
|
||||||
if (d & 2)
|
|
||||||
{
|
|
||||||
sRunChannels[nChannel].d = d ^ 2;
|
|
||||||
runlist_SignalRun(sRunChannels[nChannel].a, ChannelList, &ExhumedAI::ProcessChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d & 1)
|
|
||||||
{
|
|
||||||
sRunChannels[nChannel].d = d ^ 1;
|
|
||||||
runlist_SignalRun(sRunChannels[nChannel].a, 0, &ExhumedAI::Process);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sRunChannels[nChannel].d == 0)
|
|
||||||
{
|
|
||||||
sRunChannels[ChannelList].b = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (esi == -1)
|
|
||||||
{
|
|
||||||
esi = ChannelList;
|
|
||||||
edi = esi;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sRunChannels[edi].b = ChannelList;
|
|
||||||
edi = ChannelList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ChannelList = b;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int runlist_FindChannel(int ax)
|
int runlist_FindChannel(int ax)
|
||||||
|
|
|
@ -156,7 +156,7 @@ void AISoul::Tick(RunListEvent* ev)
|
||||||
auto coll = movesprite(pActor, bcos(pSprite->ang) * nVel, bsin(pSprite->ang) * nVel, pSprite->zvel, 5120, 0, CLIPMASK0);
|
auto coll = movesprite(pActor, bcos(pSprite->ang) * nVel, bsin(pSprite->ang) * nVel, pSprite->zvel, 5120, 0, CLIPMASK0);
|
||||||
if (coll.exbits & 0x10000)
|
if (coll.exbits & 0x10000)
|
||||||
{
|
{
|
||||||
auto pSet = pActor->pTarget;
|
DExhumedActor* pSet = pActor->pTarget;
|
||||||
if (!pSet) return;
|
if (!pSet) return;
|
||||||
auto pSetSprite = &pSet->s();
|
auto pSetSprite = &pSet->s();
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ void AISet::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
|
||||||
auto pTarget = pActor->pTarget;
|
DExhumedActor* pTarget = pActor->pTarget;
|
||||||
|
|
||||||
if (pTarget && nAction < 10)
|
if (pTarget && nAction < 10)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,16 @@ FreeListArray<Snake, kMaxSnakes> SnakeList;
|
||||||
|
|
||||||
int16_t nPlayerSnake[kMaxPlayers];
|
int16_t nPlayerSnake[kMaxPlayers];
|
||||||
|
|
||||||
|
size_t MarkSnake()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < kMaxSnakes; i++)
|
||||||
|
{
|
||||||
|
GC::Mark(SnakeList[i].pEnemy);
|
||||||
|
GC::MarkArray(SnakeList[i].pSprites, kSnakeSprites);
|
||||||
|
}
|
||||||
|
return kMaxSnakes * (1 + kSnakeSprites);
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, Snake& w, Snake* def)
|
FSerializer& Serialize(FSerializer& arc, const char* keyname, Snake& w, Snake* def)
|
||||||
{
|
{
|
||||||
if (arc.BeginObject(keyname))
|
if (arc.BeginObject(keyname))
|
||||||
|
@ -74,7 +84,8 @@ void DestroySnake(int nSnake)
|
||||||
|
|
||||||
for (int i = 0; i < kSnakeSprites; i++)
|
for (int i = 0; i < kSnakeSprites; i++)
|
||||||
{
|
{
|
||||||
auto pSnake = SnakeList[nSnake].pSprites[i];
|
DExhumedActor* pSnake = SnakeList[nSnake].pSprites[i];
|
||||||
|
if (!pSnake) continue;
|
||||||
auto pSprite = &pSnake->s();
|
auto pSprite = &pSnake->s();
|
||||||
|
|
||||||
runlist_DoSubRunRec(pSprite->lotag - 1);
|
runlist_DoSubRunRec(pSprite->lotag - 1);
|
||||||
|
@ -101,7 +112,7 @@ void ExplodeSnakeSprite(DExhumedActor* pActor, int nPlayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// take a copy of this, to revert after call to runlist_RadialDamageEnemy()
|
// take a copy of this, to revert after call to runlist_RadialDamageEnemy()
|
||||||
auto nOwner = pActor->pTarget;
|
DExhumedActor* nOwner = pActor->pTarget;
|
||||||
pActor->pTarget = PlayerList[nPlayer].pActor;
|
pActor->pTarget = PlayerList[nPlayer].pActor;
|
||||||
|
|
||||||
runlist_RadialDamageEnemy(pActor, nDamage, BulletInfo[kWeaponStaff].nRadius);
|
runlist_RadialDamageEnemy(pActor, nDamage, BulletInfo[kWeaponStaff].nRadius);
|
||||||
|
@ -256,7 +267,8 @@ DExhumedActor* FindSnakeEnemy(int nSnake)
|
||||||
int nPlayer = SnakeList[nSnake].nSnakePlayer;
|
int nPlayer = SnakeList[nSnake].nSnakePlayer;
|
||||||
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
auto pPlayerActor = PlayerList[nPlayer].Actor();
|
||||||
|
|
||||||
auto pActor = SnakeList[nSnake].pSprites[0]; // CHECKME
|
DExhumedActor* pActor = SnakeList[nSnake].pSprites[0]; // CHECKME
|
||||||
|
if (!pActor) return nullptr;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
int nAngle = pSprite->ang;
|
int nAngle = pSprite->ang;
|
||||||
|
@ -307,12 +319,13 @@ void AISnake::Tick(RunListEvent* ev)
|
||||||
int nSnake = RunData[ev->nRun].nObjIndex;
|
int nSnake = RunData[ev->nRun].nObjIndex;
|
||||||
assert(nSnake >= 0 && nSnake < kMaxSnakes);
|
assert(nSnake >= 0 && nSnake < kMaxSnakes);
|
||||||
|
|
||||||
auto pActor = SnakeList[nSnake].pSprites[0];
|
DExhumedActor* pActor = SnakeList[nSnake].pSprites[0];
|
||||||
|
if (!pActor) return;
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
seq_MoveSequence(pActor, SeqOffsets[kSeqSnakehed], 0);
|
seq_MoveSequence(pActor, SeqOffsets[kSeqSnakehed], 0);
|
||||||
|
|
||||||
auto pEnemySprite = SnakeList[nSnake].pEnemy;
|
DExhumedActor* pEnemySprite = SnakeList[nSnake].pEnemy;
|
||||||
|
|
||||||
Collision nMov;
|
Collision nMov;
|
||||||
int zVal;
|
int zVal;
|
||||||
|
@ -374,7 +387,8 @@ void AISnake::Tick(RunListEvent* ev)
|
||||||
|
|
||||||
for (int i = 7; i > 0; i--)
|
for (int i = 7; i > 0; i--)
|
||||||
{
|
{
|
||||||
auto pActor2 = SnakeList[nSnake].pSprites[i];
|
DExhumedActor* pActor2 = SnakeList[nSnake].pSprites[i];
|
||||||
|
if (!pActor2) continue;
|
||||||
auto pSprite2 = &pActor2->s();
|
auto pSprite2 = &pActor2->s();
|
||||||
|
|
||||||
pSprite2->ang = nAngle;
|
pSprite2->ang = nAngle;
|
||||||
|
|
|
@ -127,7 +127,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTarget = spp->pTarget;
|
DExhumedActor* pTarget = spp->pTarget;
|
||||||
|
|
||||||
if (pTarget == nullptr || pTarget->s().cstat & 0x101)
|
if (pTarget == nullptr || pTarget->s().cstat & 0x101)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,9 +59,6 @@ bool bCamera = false;
|
||||||
|
|
||||||
int viewz;
|
int viewz;
|
||||||
|
|
||||||
DExhumedActor* pEnemy;
|
|
||||||
|
|
||||||
int nEnemyPal = 0;
|
|
||||||
|
|
||||||
// We cannot drag these through the entire event system... :(
|
// We cannot drag these through the entire event system... :(
|
||||||
tspritetype* mytsprite;
|
tspritetype* mytsprite;
|
||||||
|
@ -198,6 +195,8 @@ static TextOverlay subtitleOverlay;
|
||||||
|
|
||||||
void DrawView(double smoothRatio, bool sceneonly)
|
void DrawView(double smoothRatio, bool sceneonly)
|
||||||
{
|
{
|
||||||
|
DExhumedActor* pEnemy = nullptr;
|
||||||
|
int nEnemyPal = -1;
|
||||||
int playerX;
|
int playerX;
|
||||||
int playerY;
|
int playerY;
|
||||||
int playerZ;
|
int playerZ;
|
||||||
|
@ -218,7 +217,7 @@ void DrawView(double smoothRatio, bool sceneonly)
|
||||||
|
|
||||||
if (nSnakeCam >= 0 && !sceneonly)
|
if (nSnakeCam >= 0 && !sceneonly)
|
||||||
{
|
{
|
||||||
auto pActor = SnakeList[nSnakeCam].pSprites[0];
|
DExhumedActor* pActor = SnakeList[nSnakeCam].pSprites[0];
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
playerX = pSprite->x;
|
playerX = pSprite->x;
|
||||||
|
@ -497,8 +496,6 @@ void SerializeView(FSerializer& arc)
|
||||||
("camerapan", nCamerapan)
|
("camerapan", nCamerapan)
|
||||||
("camera", bCamera)
|
("camera", bCamera)
|
||||||
("viewz", viewz)
|
("viewz", viewz)
|
||||||
("enemy", pEnemy)
|
|
||||||
("enemypal", nEnemyPal)
|
|
||||||
.Array("vertpan", dVertPan, countof(dVertPan))
|
.Array("vertpan", dVertPan, countof(dVertPan))
|
||||||
.Array("quake", nQuake, countof(nQuake))
|
.Array("quake", nQuake, countof(nQuake))
|
||||||
.EndObject();
|
.EndObject();
|
||||||
|
|
|
@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
extern bool bSubTitles;
|
extern bool bSubTitles;
|
||||||
extern DExhumedActor* bestTarget;
|
extern TObjPtr<DExhumedActor*> bestTarget;
|
||||||
extern bool bCamera;
|
extern bool bCamera;
|
||||||
|
|
||||||
void DrawStatusBar();
|
void DrawStatusBar();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue