- 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
void InitRexs();
void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel);
void BuildRex(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel);
void FuncRex(int, int, int, int);
// roach

View file

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

View file

@ -92,7 +92,6 @@ uint8_t LoadLevel(MapRecord* map)
PlayClock = 0;
memset(Counters, 0, sizeof(Counters));
InitRexs();
InitSets();
InitQueens();
InitRoachs();
@ -565,7 +564,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag)
return;
}
BuildRex(nSprite, 0, 0, 0, 0, 0, nChannel);
BuildRex(pActor, 0, 0, 0, 0, 0, nChannel);
return;
}
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, "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, "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, "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);

View file

@ -26,20 +26,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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[] = {
{29, 0},
{0, 0},
@ -51,53 +37,24 @@ static actionSeq RexSeq[] = {
{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)
("frame", w.nFrame)
("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];
pActor = insertActor(nSector, 119);
pSprite = &pActor->s();
}
else
{
changespritestat(nSprite, 119);
pSprite = &pActor->s();
x = pSprite->x;
y = pSprite->y;
z = sector[pSprite->sectnum].floorz;
nAngle = pSprite->ang;
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
ChangeActorStat(pActor, 119);
}
pSprite->x = x;
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->nHealth = 4000;
pActor->nFrame = 0;
pActor->nSprite = nSprite;
pActor->nTarget = -1;
pActor->pTarget = nullptr;
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.
runlist_AddRunRec(NewRun, nRex, 0x180000);
runlist_AddRunRec(NewRun, pActor, 0x180000);
nCreaturesTotal++;
}
void AIRex::RadialDamage(RunListEvent* ev)
{
short nRex = RunData[ev->nRun].nObjIndex;
assert(nRex >= 0 && nRex < (int)RexList.Size());
auto pActor = &RexList[nRex];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nAction = pActor->nAction;
short nSprite = pActor->nSprite;
if (nAction == 5)
{
ev->nDamage = runlist_CheckRadialDamage(nSprite);
ev->nDamage = runlist_CheckRadialDamage(pActor);
}
Damage(ev);
}
void AIRex::Damage(RunListEvent* ev)
{
short nRex = RunData[ev->nRun].nObjIndex;
assert(nRex >= 0 && nRex < (int)RexList.Size());
auto pActor = &RexList[nRex];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nAction = pActor->nAction;
short nSprite = pActor->nSprite;
auto pSprite = &sprite[nSprite];
auto pSprite = &pActor->s();
if (ev->nDamage)
{
short nTarget = ev->nParam;
if (nTarget >= 0 && sprite[nTarget].statnum == 100)
auto pTarget = ev->pOtherActor;
if (pTarget && pTarget->s().statnum == 100)
{
pActor->nTarget = nTarget;
pActor->pTarget = pTarget;
}
if (pActor->nAction == 5 && pActor->nHealth > 0)
@ -199,9 +152,8 @@ void AIRex::Damage(RunListEvent* ev)
void AIRex::Draw(RunListEvent* ev)
{
short nRex = RunData[ev->nRun].nObjIndex;
assert(nRex >= 0 && nRex < (int)RexList.Size());
auto pActor = &RexList[nRex];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nAction = pActor->nAction;
@ -211,17 +163,15 @@ void AIRex::Draw(RunListEvent* ev)
void AIRex::Tick(RunListEvent* ev)
{
short nRex = RunData[ev->nRun].nObjIndex;
assert(nRex >= 0 && nRex < (int)RexList.Size());
auto pActor = &RexList[nRex];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nAction = pActor->nAction;
short nSprite = pActor->nSprite;
auto pSprite = &sprite[nSprite];
auto pSprite = &pActor->s();
bool bVal = false;
Gravity(nSprite);
Gravity(pActor);
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?
while (--ecx != -1)
{
seq_MoveSequence(nSprite, nSeq, pActor->nFrame);
seq_MoveSequence(pActor, nSeq, pActor->nFrame);
pActor->nFrame++;
if (pActor->nFrame >= SeqSize[nSeq])
@ -248,7 +198,7 @@ void AIRex::Tick(RunListEvent* ev)
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
short nTarget = pActor->nTarget;
auto pTarget = pActor->pTarget;
switch (nAction)
{
@ -259,12 +209,12 @@ void AIRex::Tick(RunListEvent* ev)
{
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
pActor->nTarget = FindPlayer(nSprite, 60);
pActor->pTarget = FindPlayer(pActor, 60);
pSprite->ang = nAngle;
}
else
@ -284,7 +234,7 @@ void AIRex::Tick(RunListEvent* ev)
pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2);
D3PlayFX(StaticSound[kSound48], nSprite);
D3PlayFX(StaticSound[kSound48], pActor);
pActor->nCount = 30;
}
@ -300,7 +250,7 @@ void AIRex::Tick(RunListEvent* ev)
pActor->nCount--;
}
if ((nRex & 0x0F) == (totalmoves & 0x0F))
if ((pActor->nPhase & 0x0F) == (totalmoves & 0x0F))
{
if (!RandomSize(1))
{
@ -312,7 +262,7 @@ void AIRex::Tick(RunListEvent* ev)
}
else
{
if (((PlotCourseToSprite(nSprite, nTarget) >> 8) >= 60) || pActor->nCount > 0)
if (((PlotCourseToSprite(pActor, pTarget) >> 8) >= 60) || pActor->nCount > 0)
{
int nAngle = pSprite->ang & 0xFFF8;
pSprite->xvel = bcos(nAngle, -2);
@ -322,29 +272,29 @@ void AIRex::Tick(RunListEvent* ev)
{
pActor->nAction = 2;
pActor->nCount = 240;
D3PlayFX(StaticSound[kSound48], nSprite);
D3PlayFX(StaticSound[kSound48], pActor);
pActor->nFrame = 0;
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->nFrame = 0;
break;
}
fallthrough__;
[[fallthrough]];
}
case 0x8000:
case kHitWall:
{
pSprite->ang = (pSprite->ang + 256) & kAngleMask;
pSprite->xvel = bcos(pSprite->ang, -2);
@ -364,18 +314,18 @@ void AIRex::Tick(RunListEvent* ev)
pActor->nCount--;
if (pActor->nCount > 0)
{
PlotCourseToSprite(nSprite, nTarget);
PlotCourseToSprite(pActor, pTarget);
pSprite->xvel = bcos(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;
pSprite->ang = (pSprite->ang + 256) & kAngleMask;
@ -386,34 +336,34 @@ void AIRex::Tick(RunListEvent* ev)
nAction = 1;
break;
}
case 0xC000:
case kHitSprite:
{
pActor->nAction = 3;
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;
runlist_DamageEnemy(nSprite2, nSprite, 15);
runlist_DamageEnemy(nMov.actor, pActor, 15);
int xVel = bcos(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);
nYDamage[nPlayer] += (yVel << 4);
sprite[nSprite2].zvel = -3584;
pSprite2->zvel = -3584;
}
else
{
sprite[nSprite2].xvel += (xVel >> 3);
sprite[nSprite2].yvel += (yVel >> 3);
sprite[nSprite2].zvel = -2880;
pSprite2->xvel += (xVel >> 3);
pSprite2->yvel += (yVel >> 3);
pSprite2->zvel = -2880;
}
}
@ -443,13 +393,13 @@ void AIRex::Tick(RunListEvent* ev)
case 4:
{
if (nTarget != -1)
if (pTarget != nullptr)
{
if (PlotCourseToSprite(nSprite, nTarget) < 768)
if (PlotCourseToSprite(pActor, pTarget) < 768)
{
if (nFlag & 0x80)
{
runlist_DamageEnemy(nTarget, nSprite, 15);
runlist_DamageEnemy(pTarget, pActor, 15);
}
break;
@ -476,7 +426,7 @@ void AIRex::Tick(RunListEvent* ev)
{
pActor->nAction = 7;
pActor->nFrame = 0;
runlist_ChangeChannel(pActor->nChannel, 1);
runlist_ChangeChannel(pActor->nRun, 1);
}
return;
}
@ -491,12 +441,12 @@ void AIRex::Tick(RunListEvent* ev)
// break-ed
if (nAction > 0)
{
if ((nTarget != -1) && (!(sprite[nTarget].cstat & 0x101)))
if ((pTarget != nullptr) && (!(pTarget->s().cstat & 0x101)))
{
pActor->nAction = 0;
pActor->nFrame = 0;
pActor->nCount = 0;
pActor->nTarget = -1;
pActor->pTarget = nullptr;
pSprite->xvel = 0;
pSprite->yvel = 0;
}

View file

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