- refactor the lava dude to use actors.

This commit is contained in:
Christoph Oelckers 2021-10-17 21:06:56 +02:00
parent f12faa9279
commit 77525cecf0
7 changed files with 88 additions and 135 deletions

View file

@ -200,9 +200,8 @@ void DoRegenerates();
// lavadude
void InitLava();
void BuildLava(short nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel);
int BuildLavaLimb(int nSprite, int edx, int ebx);
void BuildLava(DExhumedActor* nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel);
DExhumedActor* BuildLavaLimb(DExhumedActor* nSprite, int edx, int ebx);
void FuncLavaLimb(int, int, int, int);
void FuncLava(int, int, int, int);
@ -285,12 +284,19 @@ void BuildNear(int x, int y, int walldist, int nSector);
int PlotCourseToSprite(int nSprite1, int nSprite2);
inline int PlotCourseToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2)
{
if (nSprite1 == nullptr || nSprite2 == nullptr)
return -1;
return PlotCourseToSprite(nSprite1->GetSpriteIndex(), nSprite2->GetSpriteIndex());
}
void CheckSectorFloor(short nSector, int z, int *x, int *y);
int GetAngleToSprite(int nSprite1, int nSprite2);
int GetWallNormal(short nWall);
int GetUpAngle(short nSprite1, int nVal, short nSprite2, int ecx);
int GetUpAngle(DExhumedActor* nSprite1, int nVal, DExhumedActor* nSprite2, int ecx)
{
return GetUpAngle(nSprite1->GetSpriteIndex(), nVal, nSprite2->GetSpriteIndex(), ecx);
}
void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel);
int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1);
inline Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, int push1)

View file

@ -77,6 +77,7 @@ enum ECounter
{
kCountAnubis,
kCountAnubisDrum,
kCountLava,
kNumCounters
};

View file

@ -108,7 +108,6 @@ uint8_t LoadLevel(MapRecord* map)
ClearAutomap();
InitBubbles();
InitObjects();
InitLava();
InitPushBlocks();
InitSpider();
InitMummy();
@ -558,7 +557,7 @@ void ProcessSpriteTag(short nSprite, short nLotag, short nHitag)
return;
}
BuildLava(nSprite, 0, 0, 0, 0, 0, nChannel);
BuildLava(pActor, 0, 0, 0, 0, 0, nChannel);
return;
}
case 107:

View file

@ -25,41 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
struct Lava
{
short nSprite;
short nRun;
short nAction;
short nTarget;
short nHealth;
short nFrame;
short nIndex;
};
TArray<Lava> LavaList;
FSerializer& Serialize(FSerializer& arc, const char* keyname, Lava& w, Lava* def)
{
if (arc.BeginObject(keyname))
{
arc("health", w.nHealth)
("frame", w.nFrame)
("action", w.nAction)
("sprite", w.nSprite)
("target", w.nTarget)
("run", w.nRun)
("channel", w.nIndex)
.EndObject();
}
return arc;
}
void SerializeLavadude(FSerializer& arc)
{
arc("lavadude", LavaList);
}
static actionSeq LavadudeSeq[] = {
{0, 1},
{0, 1},
@ -72,19 +37,13 @@ static actionSeq LavadudeSeq[] = {
{42, 1}
};
void InitLava()
DExhumedActor* BuildLavaLimb(DExhumedActor* pActor, int move, int ebx)
{
LavaList.Clear();
}
int BuildLavaLimb(int nSprite, int edx, int ebx)
{
auto pSprite = &sprite[nSprite];
auto pSprite = &pActor->s();
short nSector = pSprite->sectnum;
int nLimbSprite = insertsprite(nSector, 118);
assert(nLimbSprite >= 0 && nLimbSprite < kMaxSprites);
auto pLimbSprite = &sprite[nLimbSprite];
auto pLimbActor = insertActor(nSector, 118);
auto pLimbSprite = &pLimbActor->s();
pLimbSprite->x = pSprite->x;
pLimbSprite->y = pSprite->y;
@ -99,7 +58,7 @@ int BuildLavaLimb(int nSprite, int edx, int ebx)
pLimbSprite->yoffset = 0;
pLimbSprite->xrepeat = 90;
pLimbSprite->yrepeat = 90;
pLimbSprite->picnum = (edx & 3) % 3;
pLimbSprite->picnum = (move & 3) % 3;
pLimbSprite->hitag = 0;
pLimbSprite->lotag = runlist_HeadRun() + 1;
pLimbSprite->clipdist = 0;
@ -107,23 +66,23 @@ int BuildLavaLimb(int nSprite, int edx, int ebx)
// GrabTimeSlot(3);
pLimbSprite->extra = -1;
pLimbSprite->owner = runlist_AddRunRec(pLimbSprite->lotag - 1, nLimbSprite, 0x160000);
pLimbSprite->hitag = runlist_AddRunRec(NewRun, nLimbSprite, 0x160000);
pLimbSprite->owner = runlist_AddRunRec(pLimbSprite->lotag - 1, pLimbActor, 0x160000);
pLimbSprite->hitag = runlist_AddRunRec(NewRun, pLimbActor, 0x160000);
return nLimbSprite;
return pLimbActor;
}
void AILavaDudeLimb::Tick(RunListEvent* ev)
{
short nSprite = RunData[ev->nRun].nObjIndex;
assert(nSprite >= 0 && nSprite < kMaxSprites);
auto pSprite = &sprite[nSprite];
auto pActor = ev->pObjActor;
if (!pActor) return;
auto pSprite = &pActor->s();
pSprite->shade += 3;
int nRet = movesprite(nSprite, pSprite->xvel << 12, pSprite->yvel << 12, pSprite->zvel, 2560, -2560, CLIPMASK1);
auto coll = movesprite(pActor, pSprite->xvel << 12, pSprite->yvel << 12, pSprite->zvel, 2560, -2560, CLIPMASK1);
if (nRet || pSprite->shade > 100)
if (coll.type || pSprite->shade > 100)
{
pSprite->xvel = 0;
pSprite->yvel = 0;
@ -133,16 +92,15 @@ void AILavaDudeLimb::Tick(RunListEvent* ev)
runlist_FreeRun(pSprite->lotag - 1);
runlist_SubRunRec(pSprite->hitag);
mydeletesprite(nSprite);
DeleteActor(pActor);
}
}
void AILavaDudeLimb::Draw(RunListEvent* ev)
{
short nSprite = RunData[ev->nRun].nObjIndex;
assert(nSprite >= 0 && nSprite < kMaxSprites);
auto pSprite = &sprite[nSprite];
seq_PlotSequence(ev->nParam, (SeqOffsets[kSeqLavag] + 30) + pSprite->picnum, 0, 1);
auto pActor = ev->pObjActor;
if (!pActor) return;
seq_PlotSequence(ev->nParam, (SeqOffsets[kSeqLavag] + 30) + pActor->s().picnum, 0, 1);
}
void FuncLavaLimb(int nObject, int nMessage, int nDamage, int nRun)
@ -151,29 +109,25 @@ void FuncLavaLimb(int nObject, int nMessage, int nDamage, int nRun)
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void BuildLava(short nSprite, int x, int y, int, short nSector, short nAngle, int nChannel)
void BuildLava(DExhumedActor* pActor, int x, int y, int, short nSector, short nAngle, int nChannel)
{
auto nLava = LavaList.Reserve(1);
auto pActor = &LavaList[nLava];
auto pSprite = &sprite[nSprite];
if (nSprite == -1)
spritetype* pSprite;
if (pActor == nullptr)
{
nSprite = insertsprite(nSector, 118);
pSprite = &sprite[nSprite];
pActor = insertActor(nSector, 118);
pSprite = &pActor->s();
}
else
{
pSprite = &pActor->s();
nSector = pSprite->sectnum;
nAngle = pSprite->ang;
x = pSprite->x;
y = pSprite->y;
changespritestat(nSprite, 118);
ChangeActorStat(pActor, 118);
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
pSprite->x = x;
pSprite->y = y;
pSprite->z = sector[nSector].floorz;
@ -199,22 +153,21 @@ void BuildLava(short nSprite, int x, int y, int, short nSector, short nAngle, in
pActor->nAction = 0;
pActor->nHealth = 4000;
pActor->nSprite = nSprite;
pActor->nTarget = -1;
pActor->nIndex = nChannel;
pActor->pTarget = nullptr;
pActor->nCount = nChannel;
pActor->nFrame = 0;
pActor->nPhase = Counters[kCountLava]++;
pSprite->owner = runlist_AddRunRec(pSprite->lotag - 1, nLava, 0x150000);
pActor->nRun = runlist_AddRunRec(NewRun, nLava, 0x150000);
pSprite->owner = runlist_AddRunRec(pSprite->lotag - 1, pActor, 0x150000);
pActor->nRun = runlist_AddRunRec(NewRun, pActor, 0x150000);
nCreaturesTotal++;
}
void AILavaDude::Draw(RunListEvent* ev)
{
unsigned nLava = RunData[ev->nRun].nObjIndex;
assert(nLava < LavaList.Size());
auto pActor = &LavaList[nLava];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nAction = pActor->nAction;
short nSeq = LavadudeSeq[nAction].a + SeqOffsets[kSeqLavag];
@ -226,13 +179,11 @@ void AILavaDude::Draw(RunListEvent* ev)
void AILavaDude::Damage(RunListEvent* ev)
{
unsigned nLava = RunData[ev->nRun].nObjIndex;
assert(nLava < LavaList.Size());
auto pActor = &LavaList[nLava];
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)
{
@ -253,13 +204,13 @@ void AILavaDude::Damage(RunListEvent* ev)
}
else
{
short nTarget = ev->nParam;
auto pTarget = ev->pOtherActor;
if (nTarget >= 0)
if (pTarget)
{
if (sprite[nTarget].statnum < 199)
if (pTarget->s().statnum < 199)
{
pActor->nTarget = nTarget;
pActor->pTarget = pTarget;
}
}
@ -273,21 +224,19 @@ void AILavaDude::Damage(RunListEvent* ev)
}
}
BuildLavaLimb(nSprite, totalmoves, 64000);
BuildLavaLimb(pActor, totalmoves, 64000);
}
}
void AILavaDude::Tick(RunListEvent* ev)
{
unsigned nLava = RunData[ev->nRun].nObjIndex;
assert(nLava < LavaList.Size());
auto pActor = &LavaList[nLava];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nAction = pActor->nAction;
short nSeq = LavadudeSeq[nAction].a + SeqOffsets[kSeqLavag];
short nSprite = pActor->nSprite;
auto pSprite = &sprite[nSprite];
auto pSprite = &pActor->s();
pSprite->picnum = seq_GetSeqPicnum2(nSeq, pActor->nFrame);
int var_38 = pActor->nFrame;
@ -298,7 +247,7 @@ void AILavaDude::Tick(RunListEvent* ev)
if (nAction)
{
seq_MoveSequence(nSprite, nSeq, var_38);
seq_MoveSequence(pActor, nSeq, var_38);
pActor->nFrame++;
if (pActor->nFrame >= SeqSize[nSeq])
@ -312,14 +261,14 @@ void AILavaDude::Tick(RunListEvent* ev)
}
}
short nTarget = pActor->nTarget;
auto pTarget = pActor->pTarget;
if (nTarget >= 0 && nAction < 4)
if (pTarget && nAction < 4)
{
if (!(sprite[nTarget].cstat & 0x101) || sprite[nTarget].sectnum >= 1024)
if (!(pTarget->s().cstat & 0x101) || pTarget->s().sectnum >= 1024)
{
nTarget = -1;
pActor->nTarget = -1;
pTarget = nullptr;
pActor->pTarget = nullptr;
}
}
@ -327,21 +276,21 @@ void AILavaDude::Tick(RunListEvent* ev)
{
case 0:
{
if ((nLava & 0x1F) == (totalmoves & 0x1F))
if ((pActor->nPhase & 0x1F) == (totalmoves & 0x1F))
{
if (nTarget < 0)
if (pTarget == nullptr)
{
nTarget = FindPlayer(nSprite, 76800);
pTarget = FindPlayer(pActor, 76800);
}
PlotCourseToSprite(nSprite, nTarget);
PlotCourseToSprite(pActor, pTarget);
pSprite->xvel = bcos(pSprite->ang);
pSprite->yvel = bsin(pSprite->ang);
if (nTarget >= 0 && !RandomSize(1))
if (pTarget && !RandomSize(1))
{
pActor->nTarget = nTarget;
pActor->pTarget = pTarget;
pActor->nAction = 2;
pSprite->cstat = 0x101;
pActor->nFrame = 0;
@ -354,11 +303,11 @@ void AILavaDude::Tick(RunListEvent* ev)
int z = pSprite->z;
short nSector = pSprite->sectnum;
int nVal = movesprite(nSprite, pSprite->xvel << 8, pSprite->yvel << 8, 0, 0, 0, CLIPMASK0);
auto coll = movesprite(pActor, pSprite->xvel << 8, pSprite->yvel << 8, 0, 0, 0, CLIPMASK0);
if (nSector != pSprite->sectnum)
{
changespritesect(nSprite, nSector);
ChangeActorSect(pActor, nSector);
pSprite->x = x;
pSprite->y = y;
pSprite->z = z;
@ -369,22 +318,22 @@ void AILavaDude::Tick(RunListEvent* ev)
break;
}
if (!nVal) {
if (coll.type == kHitNone) {
break;
}
if ((nVal & 0xC000) == 0x8000)
if (coll.type == kHitWall)
{
pSprite->ang = (pSprite->ang + ((RandomWord() & 0x3FF) + 1024)) & kAngleMask;
pSprite->xvel = bcos(pSprite->ang);
pSprite->yvel = bsin(pSprite->ang);
break;
}
else if ((nVal & 0xC000) == 0xC000)
else if (coll.type == kHitSprite)
{
if ((nVal & 0x3FFF) == nTarget)
if (coll.actor == pTarget)
{
int nAng = getangle(sprite[nTarget].x - pSprite->x, sprite[nTarget].y - pSprite->y);
int nAng = getangle(pTarget->s().x - pSprite->x, pTarget->s().y - pSprite->y);
if (AngleDiff(pSprite->ang, nAng) < 64)
{
pActor->nAction = 2;
@ -411,7 +360,7 @@ void AILavaDude::Tick(RunListEvent* ev)
pActor->nAction = 3;
pActor->nFrame = 0;
PlotCourseToSprite(nSprite, nTarget);
PlotCourseToSprite(pActor, pTarget);
pSprite->cstat |= 0x101;
}
@ -421,16 +370,16 @@ void AILavaDude::Tick(RunListEvent* ev)
case 3:
{
if ((nFlag & 0x80) && nTarget > -1)
if ((nFlag & 0x80) && pTarget)
{
int nHeight = GetSpriteHeight(nSprite);
GetUpAngle(nSprite, -64000, nTarget, (-(nHeight >> 1)));
int nHeight = GetActorHeight(pActor);
GetUpAngle(pActor, -64000, pTarget, (-(nHeight >> 1)));
BuildBullet(nSprite, 10, bcos(pSprite->ang, 8), bsin(pSprite->ang, 8), -1, pSprite->ang, nTarget + 10000, 1);
BuildBullet(pActor, 10, -1, pSprite->ang, pTarget, 1);
}
else if (var_1C)
{
PlotCourseToSprite(nSprite, nTarget);
PlotCourseToSprite(pActor, pTarget);
pActor->nAction = 7;
pActor->nFrame = 0;
}
@ -453,8 +402,8 @@ void AILavaDude::Tick(RunListEvent* ev)
{
if (nFlag & 0x40)
{
int nLimbSprite = BuildLavaLimb(nSprite, pActor->nFrame, 64000);
D3PlayFX(StaticSound[kSound26], nLimbSprite);
auto pLimbSprite = BuildLavaLimb(pActor, pActor->nFrame, 64000);
D3PlayFX(StaticSound[kSound26], pLimbSprite);
}
if (pActor->nFrame)
@ -464,10 +413,10 @@ void AILavaDude::Tick(RunListEvent* ev)
int ecx = 0;
do
{
BuildLavaLimb(nSprite, ecx, 64000);
BuildLavaLimb(pActor, ecx, 64000);
ecx++;
} while (ecx < 20);
runlist_ChangeChannel(pActor->nIndex, 1);
runlist_ChangeChannel(pActor->nCount, 1);
}
}
else
@ -476,14 +425,14 @@ void AILavaDude::Tick(RunListEvent* ev)
do
{
BuildLavaLimb(nSprite, ecx, 256);
BuildLavaLimb(pActor, ecx, 256);
ecx++;
} while (ecx < 30);
runlist_DoSubRunRec(pSprite->owner);
runlist_FreeRun(pSprite->lotag - 1);
runlist_SubRunRec(pActor->nRun);
mydeletesprite(nSprite);
DeleteActor(pActor);
}
break;

View file

@ -85,7 +85,7 @@ static int osdcmd_spawn(CCmdFuncPtr parm)
else if (!stricmp(c, "mummy")) BuildMummy(-1, initx, inity, sector[initsect].floorz, initsect, inita);
else if (!stricmp(c, "fish")) BuildFish(nullptr, initx, inity, initz + eyelevel[nLocalPlayer], initsect, inita);
else if (!stricmp(c, "lion")) BuildLion(-1, initx, inity, sector[initsect].floorz, initsect, inita);
else if (!stricmp(c, "lava")) BuildLava(-1, 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, "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);

View file

@ -374,7 +374,7 @@ int DestroyTailPart()
for (int i = 0; i < 5; i++)
{
short nHeight = GetSpriteHeight(nSprite);
BuildLavaLimb(nSprite, i, nHeight);
BuildLavaLimb(&exhumedActors[nSprite], i, nHeight);
}
mydeletesprite(nSprite);
@ -1029,7 +1029,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
if (QueenHead.tails < 10) {
for (int i = (10 - QueenHead.tails) * 2; i > 0; i--)
{
BuildLavaLimb(nSprite, i, GetSpriteHeight(nSprite));
BuildLavaLimb(&exhumedActors[nSprite], i, GetSpriteHeight(nSprite));
}
}
}
@ -1047,7 +1047,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
for (i = 0; i < 20; i++)
{
BuildLavaLimb(nSprite, i, GetSpriteHeight(nSprite));
BuildLavaLimb(&exhumedActors[nSprite], i, GetSpriteHeight(nSprite));
}
runlist_SubRunRec(pSprite->owner);

View file

@ -48,7 +48,6 @@ void SerializeSnake(FSerializer& arc);
void SerializeSwitch(FSerializer& arc);
void SerializeView(FSerializer& arc);
void SerializeLavadude(FSerializer& arc);
void SerializeLion(FSerializer& arc);
void SerializeMummy(FSerializer& arc);
void SerializeQueen(FSerializer& arc);
@ -84,7 +83,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
SerializeSwitch(arc);
SerializeView(arc);
SerializeLavadude(arc);
SerializeLion(arc);
SerializeMummy(arc);
SerializeQueen(arc);