- refactor rex to use actors.

This commit is contained in:
Christoph Oelckers 2021-10-18 00:28:59 +02:00
parent 1cf616c7ba
commit f0f0ca020b
6 changed files with 69 additions and 122 deletions

View file

@ -411,8 +411,7 @@ void FuncRat(int a, int, int b, int nRun);
// rex // rex
void InitRexs(); void BuildRex(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel);
void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel);
void FuncRex(int, int, int, int); void FuncRex(int, int, int, int);
// roach // roach

View file

@ -80,6 +80,7 @@ enum ECounter
kCountLava, kCountLava,
kCountLion, kCountLion,
kCountMummy, kCountMummy,
kCountRex,
kNumCounters kNumCounters
}; };

View file

@ -92,7 +92,6 @@ uint8_t LoadLevel(MapRecord* map)
PlayClock = 0; PlayClock = 0;
memset(Counters, 0, sizeof(Counters)); memset(Counters, 0, sizeof(Counters));
InitRexs();
InitSets(); InitSets();
InitQueens(); InitQueens();
InitRoachs(); InitRoachs();
@ -565,7 +564,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag)
return; return;
} }
BuildRex(nSprite, 0, 0, 0, 0, 0, nChannel); BuildRex(pActor, 0, 0, 0, 0, 0, nChannel);
return; return;
} }
case 106: case 106:

View file

@ -86,7 +86,7 @@ static int osdcmd_spawn(CCmdFuncPtr parm)
else if (!stricmp(c, "fish")) BuildFish(nullptr, initx, inity, initz + eyelevel[nLocalPlayer], initsect, inita); else if (!stricmp(c, "fish")) BuildFish(nullptr, initx, inity, initz + eyelevel[nLocalPlayer], initsect, inita);
else if (!stricmp(c, "lion")) BuildLion(nullptr, initx, inity, sector[initsect].floorz, initsect, inita); else if (!stricmp(c, "lion")) BuildLion(nullptr, initx, inity, sector[initsect].floorz, initsect, inita);
else if (!stricmp(c, "lava")) BuildLava(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); else if (!stricmp(c, "lava")) BuildLava(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount);
else if (!stricmp(c, "rex")) BuildRex(-1, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); else if (!stricmp(c, "rex")) BuildRex(nullptr, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount);
else if (!stricmp(c, "set")) BuildSet(-1, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); else if (!stricmp(c, "set")) BuildSet(-1, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount);
else if (!stricmp(c, "queen")) BuildQueen(-1, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount); else if (!stricmp(c, "queen")) BuildQueen(-1, initx, inity, sector[initsect].floorz, initsect, inita, nNetPlayerCount);
else if (!stricmp(c, "roach")) BuildRoach(0, -1, initx, inity, sector[initsect].floorz, initsect, inita); else if (!stricmp(c, "roach")) BuildRoach(0, -1, initx, inity, sector[initsect].floorz, initsect, inita);

View file

@ -26,20 +26,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS BEGIN_PS_NS
struct Rex
{
short nHealth;
short nFrame;
short nAction;
short nSprite;
short nTarget;
short nCount;
short nChannel;
};
TArray<Rex> RexList;
static actionSeq RexSeq[] = { static actionSeq RexSeq[] = {
{29, 0}, {29, 0},
{0, 0}, {0, 0},
@ -51,53 +37,24 @@ static actionSeq RexSeq[] = {
{28, 1} {28, 1}
}; };
FSerializer& Serialize(FSerializer& arc, const char* keyname, Rex& w, Rex* def) void BuildRex(DExhumedActor* pActor, int x, int y, int z, short nSector, short nAngle, int nChannel)
{ {
if (arc.BeginObject(keyname)) spritetype* pSprite;
if (pActor == nullptr)
{ {
arc("health", w.nHealth) pActor = insertActor(nSector, 119);
("frame", w.nFrame) pSprite = &pActor->s();
("action", w.nAction)
("sprite", w.nSprite)
("target", w.nTarget)
("count", w.nCount)
("channel", w.nChannel)
.EndObject();
}
return arc;
}
void SerializeRex(FSerializer& arc)
{
arc("rex", RexList);
}
void InitRexs()
{
RexList.Clear();
}
void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel)
{
int nRex = RexList.Reserve(1);
auto pActor = &RexList[nRex];
auto pSprite = &sprite[nSprite];
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 119);
pSprite = &sprite[nSprite];
} }
else else
{ {
changespritestat(nSprite, 119); pSprite = &pActor->s();
x = pSprite->x; x = pSprite->x;
y = pSprite->y; y = pSprite->y;
z = sector[pSprite->sectnum].floorz; z = sector[pSprite->sectnum].floorz;
nAngle = pSprite->ang; nAngle = pSprite->ang;
}
assert(nSprite >= 0 && nSprite < kMaxSprites); ChangeActorStat(pActor, 119);
}
pSprite->x = x; pSprite->x = x;
pSprite->y = y; pSprite->y = y;
@ -124,52 +81,48 @@ void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, i
pActor->nAction = 0; pActor->nAction = 0;
pActor->nHealth = 4000; pActor->nHealth = 4000;
pActor->nFrame = 0; pActor->nFrame = 0;
pActor->nSprite = nSprite; pActor->pTarget = nullptr;
pActor->nTarget = -1;
pActor->nCount = 0; pActor->nCount = 0;
pActor->nPhase = Counters[kCountRex]++;
pActor->nChannel = nChannel; pActor->nRun = nChannel;
pSprite->owner = runlist_AddRunRec(pSprite->lotag - 1, nRex, 0x180000); pSprite->owner = runlist_AddRunRec(pSprite->lotag - 1, pActor, 0x180000);
// this isn't stored anywhere. // this isn't stored anywhere.
runlist_AddRunRec(NewRun, nRex, 0x180000); runlist_AddRunRec(NewRun, pActor, 0x180000);
nCreaturesTotal++; nCreaturesTotal++;
} }
void AIRex::RadialDamage(RunListEvent* ev) void AIRex::RadialDamage(RunListEvent* ev)
{ {
short nRex = RunData[ev->nRun].nObjIndex; auto pActor = ev->pObjActor;
assert(nRex >= 0 && nRex < (int)RexList.Size()); if (!pActor) return;
auto pActor = &RexList[nRex];
short nAction = pActor->nAction; short nAction = pActor->nAction;
short nSprite = pActor->nSprite;
if (nAction == 5) if (nAction == 5)
{ {
ev->nDamage = runlist_CheckRadialDamage(nSprite); ev->nDamage = runlist_CheckRadialDamage(pActor);
} }
Damage(ev); Damage(ev);
} }
void AIRex::Damage(RunListEvent* ev) void AIRex::Damage(RunListEvent* ev)
{ {
short nRex = RunData[ev->nRun].nObjIndex; auto pActor = ev->pObjActor;
assert(nRex >= 0 && nRex < (int)RexList.Size()); if (!pActor) return;
auto pActor = &RexList[nRex];
short nAction = pActor->nAction; short nAction = pActor->nAction;
short nSprite = pActor->nSprite; auto pSprite = &pActor->s();
auto pSprite = &sprite[nSprite];
if (ev->nDamage) if (ev->nDamage)
{ {
short nTarget = ev->nParam; auto pTarget = ev->pOtherActor;
if (nTarget >= 0 && sprite[nTarget].statnum == 100) if (pTarget && pTarget->s().statnum == 100)
{ {
pActor->nTarget = nTarget; pActor->pTarget = pTarget;
} }
if (pActor->nAction == 5 && pActor->nHealth > 0) if (pActor->nAction == 5 && pActor->nHealth > 0)
@ -199,9 +152,8 @@ void AIRex::Damage(RunListEvent* ev)
void AIRex::Draw(RunListEvent* ev) void AIRex::Draw(RunListEvent* ev)
{ {
short nRex = RunData[ev->nRun].nObjIndex; auto pActor = ev->pObjActor;
assert(nRex >= 0 && nRex < (int)RexList.Size()); if (!pActor) return;
auto pActor = &RexList[nRex];
short nAction = pActor->nAction; short nAction = pActor->nAction;
@ -211,17 +163,15 @@ void AIRex::Draw(RunListEvent* ev)
void AIRex::Tick(RunListEvent* ev) void AIRex::Tick(RunListEvent* ev)
{ {
short nRex = RunData[ev->nRun].nObjIndex; auto pActor = ev->pObjActor;
assert(nRex >= 0 && nRex < (int)RexList.Size()); if (!pActor) return;
auto pActor = &RexList[nRex];
short nAction = pActor->nAction; short nAction = pActor->nAction;
short nSprite = pActor->nSprite; auto pSprite = &pActor->s();
auto pSprite = &sprite[nSprite];
bool bVal = false; bool bVal = false;
Gravity(nSprite); Gravity(pActor);
int nSeq = SeqOffsets[kSeqRex] + RexSeq[nAction].a; int nSeq = SeqOffsets[kSeqRex] + RexSeq[nAction].a;
@ -236,7 +186,7 @@ void AIRex::Tick(RunListEvent* ev)
// moves the mouth open and closed as it's idle? // moves the mouth open and closed as it's idle?
while (--ecx != -1) while (--ecx != -1)
{ {
seq_MoveSequence(nSprite, nSeq, pActor->nFrame); seq_MoveSequence(pActor, nSeq, pActor->nFrame);
pActor->nFrame++; pActor->nFrame++;
if (pActor->nFrame >= SeqSize[nSeq]) if (pActor->nFrame >= SeqSize[nSeq])
@ -248,7 +198,7 @@ void AIRex::Tick(RunListEvent* ev)
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
short nTarget = pActor->nTarget; auto pTarget = pActor->pTarget;
switch (nAction) switch (nAction)
{ {
@ -259,12 +209,12 @@ void AIRex::Tick(RunListEvent* ev)
{ {
if (!pActor->nCount) if (!pActor->nCount)
{ {
if ((nRex & 0x1F) == (totalmoves & 0x1F)) if ((pActor->nPhase & 0x1F) == (totalmoves & 0x1F))
{ {
if (nTarget < 0) if (pTarget == nullptr)
{ {
short nAngle = pSprite->ang; // make backup of this variable short nAngle = pSprite->ang; // make backup of this variable
pActor->nTarget = FindPlayer(nSprite, 60); pActor->pTarget = FindPlayer(pActor, 60);
pSprite->ang = nAngle; pSprite->ang = nAngle;
} }
else else
@ -284,7 +234,7 @@ void AIRex::Tick(RunListEvent* ev)
pSprite->xvel = bcos(pSprite->ang, -2); pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2); pSprite->yvel = bsin(pSprite->ang, -2);
D3PlayFX(StaticSound[kSound48], nSprite); D3PlayFX(StaticSound[kSound48], pActor);
pActor->nCount = 30; pActor->nCount = 30;
} }
@ -300,7 +250,7 @@ void AIRex::Tick(RunListEvent* ev)
pActor->nCount--; pActor->nCount--;
} }
if ((nRex & 0x0F) == (totalmoves & 0x0F)) if ((pActor->nPhase & 0x0F) == (totalmoves & 0x0F))
{ {
if (!RandomSize(1)) if (!RandomSize(1))
{ {
@ -312,7 +262,7 @@ void AIRex::Tick(RunListEvent* ev)
} }
else else
{ {
if (((PlotCourseToSprite(nSprite, nTarget) >> 8) >= 60) || pActor->nCount > 0) if (((PlotCourseToSprite(pActor, pTarget) >> 8) >= 60) || pActor->nCount > 0)
{ {
int nAngle = pSprite->ang & 0xFFF8; int nAngle = pSprite->ang & 0xFFF8;
pSprite->xvel = bcos(nAngle, -2); pSprite->xvel = bcos(nAngle, -2);
@ -322,29 +272,29 @@ void AIRex::Tick(RunListEvent* ev)
{ {
pActor->nAction = 2; pActor->nAction = 2;
pActor->nCount = 240; pActor->nCount = 240;
D3PlayFX(StaticSound[kSound48], nSprite); D3PlayFX(StaticSound[kSound48], pActor);
pActor->nFrame = 0; pActor->nFrame = 0;
return; return;
} }
} }
} }
int nMov = MoveCreatureWithCaution(nSprite); auto nMov = MoveCreatureWithCaution(pActor);
switch ((nMov & 0xC000)) switch (nMov.type)
{ {
case 0xC000: case kHitSprite:
{ {
if ((nMov & 0x3FFF) == nTarget) if (nMov.actor == pTarget)
{ {
PlotCourseToSprite(nSprite, nTarget); PlotCourseToSprite(pActor, pTarget);
pActor->nAction = 4; pActor->nAction = 4;
pActor->nFrame = 0; pActor->nFrame = 0;
break; break;
} }
fallthrough__; [[fallthrough]];
} }
case 0x8000: case kHitWall:
{ {
pSprite->ang = (pSprite->ang + 256) & kAngleMask; pSprite->ang = (pSprite->ang + 256) & kAngleMask;
pSprite->xvel = bcos(pSprite->ang, -2); pSprite->xvel = bcos(pSprite->ang, -2);
@ -364,18 +314,18 @@ void AIRex::Tick(RunListEvent* ev)
pActor->nCount--; pActor->nCount--;
if (pActor->nCount > 0) if (pActor->nCount > 0)
{ {
PlotCourseToSprite(nSprite, nTarget); PlotCourseToSprite(pActor, pTarget);
pSprite->xvel = bcos(pSprite->ang, -1); pSprite->xvel = bcos(pSprite->ang, -1);
pSprite->yvel = bsin(pSprite->ang, -1); pSprite->yvel = bsin(pSprite->ang, -1);
int nMov = MoveCreatureWithCaution(nSprite); auto nMov = MoveCreatureWithCaution(pActor);
switch (nMov & 0xC000) switch (nMov.type)
{ {
case 0x8000: case kHitWall:
{ {
SetQuake(nSprite, 25); SetQuake(pActor, 25);
pActor->nCount = 60; pActor->nCount = 60;
pSprite->ang = (pSprite->ang + 256) & kAngleMask; pSprite->ang = (pSprite->ang + 256) & kAngleMask;
@ -386,34 +336,34 @@ void AIRex::Tick(RunListEvent* ev)
nAction = 1; nAction = 1;
break; break;
} }
case 0xC000: case kHitSprite:
{ {
pActor->nAction = 3; pActor->nAction = 3;
pActor->nFrame = 0; pActor->nFrame = 0;
short nSprite2 = nMov & 0x3FFF; auto pSprite2 = &nMov.actor->s();
if (sprite[nSprite2].statnum && sprite[nSprite2].statnum < 107) if (pSprite2->statnum && pSprite2->statnum < 107)
{ {
short nAngle = pSprite->ang; short nAngle = pSprite->ang;
runlist_DamageEnemy(nSprite2, nSprite, 15); runlist_DamageEnemy(nMov.actor, pActor, 15);
int xVel = bcos(nAngle) * 15; int xVel = bcos(nAngle) * 15;
int yVel = bsin(nAngle) * 15; int yVel = bsin(nAngle) * 15;
if (sprite[nSprite2].statnum == 100) if (pSprite2->statnum == 100)
{ {
short nPlayer = GetPlayerFromSprite(nSprite2); auto nPlayer = GetPlayerFromActor(nMov.actor);
nXDamage[nPlayer] += (xVel << 4); nXDamage[nPlayer] += (xVel << 4);
nYDamage[nPlayer] += (yVel << 4); nYDamage[nPlayer] += (yVel << 4);
sprite[nSprite2].zvel = -3584; pSprite2->zvel = -3584;
} }
else else
{ {
sprite[nSprite2].xvel += (xVel >> 3); pSprite2->xvel += (xVel >> 3);
sprite[nSprite2].yvel += (yVel >> 3); pSprite2->yvel += (yVel >> 3);
sprite[nSprite2].zvel = -2880; pSprite2->zvel = -2880;
} }
} }
@ -443,13 +393,13 @@ void AIRex::Tick(RunListEvent* ev)
case 4: case 4:
{ {
if (nTarget != -1) if (pTarget != nullptr)
{ {
if (PlotCourseToSprite(nSprite, nTarget) < 768) if (PlotCourseToSprite(pActor, pTarget) < 768)
{ {
if (nFlag & 0x80) if (nFlag & 0x80)
{ {
runlist_DamageEnemy(nTarget, nSprite, 15); runlist_DamageEnemy(pTarget, pActor, 15);
} }
break; break;
@ -476,7 +426,7 @@ void AIRex::Tick(RunListEvent* ev)
{ {
pActor->nAction = 7; pActor->nAction = 7;
pActor->nFrame = 0; pActor->nFrame = 0;
runlist_ChangeChannel(pActor->nChannel, 1); runlist_ChangeChannel(pActor->nRun, 1);
} }
return; return;
} }
@ -491,12 +441,12 @@ void AIRex::Tick(RunListEvent* ev)
// break-ed // break-ed
if (nAction > 0) if (nAction > 0)
{ {
if ((nTarget != -1) && (!(sprite[nTarget].cstat & 0x101))) if ((pTarget != nullptr) && (!(pTarget->s().cstat & 0x101)))
{ {
pActor->nAction = 0; pActor->nAction = 0;
pActor->nFrame = 0; pActor->nFrame = 0;
pActor->nCount = 0; pActor->nCount = 0;
pActor->nTarget = -1; pActor->pTarget = nullptr;
pSprite->xvel = 0; pSprite->xvel = 0;
pSprite->yvel = 0; pSprite->yvel = 0;
} }

View file

@ -50,7 +50,6 @@ void SerializeView(FSerializer& arc);
void SerializeQueen(FSerializer& arc); void SerializeQueen(FSerializer& arc);
void SerializeRat(FSerializer& arc); void SerializeRat(FSerializer& arc);
void SerializeRex(FSerializer& arc);
void SerializeRoach(FSerializer& arc); void SerializeRoach(FSerializer& arc);
void SerializeScorpion(FSerializer& arc); void SerializeScorpion(FSerializer& arc);
void SerializeSet(FSerializer& arc); void SerializeSet(FSerializer& arc);
@ -83,7 +82,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
SerializeQueen(arc); SerializeQueen(arc);
SerializeRat(arc); SerializeRat(arc);
SerializeRex(arc);
SerializeRoach(arc); SerializeRoach(arc);
SerializeScorpion(arc); SerializeScorpion(arc);
SerializeSet(arc); SerializeSet(arc);