- converted FuncMummy into a class

This commit is contained in:
Christoph Oelckers 2021-10-15 22:02:06 +02:00
parent 008825fe32
commit 3bda4d5b07
2 changed files with 339 additions and 323 deletions

View file

@ -505,6 +505,14 @@ struct AICreatureChunk : public ExhumedAI
virtual void Tick(RunListEvent* ev) override;
};
struct AIMummy : public ExhumedAI
{
void Tick(RunListEvent* ev) override;
void Damage(RunListEvent* ev) override;
void Draw(RunListEvent* ev) override;
void RadialDamage(RunListEvent* ev) override;
};
void runlist_DispatchEvent(ExhumedAI* ai, int nObject, int nMessage, int nDamage, int nRun);

View file

@ -173,363 +173,371 @@ void CheckMummyRevive(short nMummy)
}
}
void FuncMummy(int nObject, int nMessage, int nDamage, int nRun)
void AIMummy::Tick(RunListEvent* ev)
{
short nMummy = RunData[nRun].nVal;
short nMummy = RunData[ev->nRun].nVal;
assert(nMummy >= 0 && nMummy < kMaxMummies);
short nTarget = UpdateEnemy(&MummyList[nMummy].nTarget);
short nSprite = MummyList[nMummy].nSprite;
auto pSprite = &sprite[nSprite];
auto pSprite = &sprite[nSprite];
short nAction = MummyList[nMummy].nAction;
switch (nMessage)
Gravity(nSprite);
int nSeq = SeqOffsets[kSeqMummy] + MummySeq[nAction].a;
pSprite->picnum = seq_GetSeqPicnum2(nSeq, MummyList[nMummy].nFrame);
short nFrame = SeqBase[nSeq] + MummyList[nMummy].nFrame;
short nFrameFlag = FrameFlag[nFrame];
seq_MoveSequence(nSprite, nSeq, MummyList[nMummy].nFrame);
bool bVal = false;
MummyList[nMummy].nFrame++;
if (MummyList[nMummy].nFrame >= SeqSize[nSeq])
{
default:
MummyList[nMummy].nFrame = 0;
bVal = true;
}
if (nTarget != -1 && nAction < 4)
{
if ((!sprite[nTarget].cstat) && nAction)
{
DebugOut("unknown msg %d for Mummy\n", nMessage);
break;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel = 0;
}
}
int nMov = MoveCreatureWithCaution(nSprite);
if (nAction > 7)
return;
switch (nAction)
{
case 0:
{
if ((MummyList[nMummy].nIndex & 0x1F) == (totalmoves & 0x1F))
{
pSprite->cstat = 0x101;
if (nTarget < 0)
{
int nTarget = FindPlayer(nSprite, 100);
if (nTarget >= 0)
{
D3PlayFX(StaticSound[kSound7], nSprite);
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nTarget = nTarget;
MummyList[nMummy].nAction = 1;
MummyList[nMummy].nCount = 90;
pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2);
}
}
}
return;
}
case 1:
{
if (MummyList[nMummy].nCount > 0)
{
MummyList[nMummy].nCount--;
}
case 0x20000:
if ((MummyList[nMummy].nIndex & 0x1F) == (totalmoves & 0x1F))
{
Gravity(nSprite);
pSprite->cstat = 0x101;
int nSeq = SeqOffsets[kSeqMummy] + MummySeq[nAction].a;
PlotCourseToSprite(nSprite, nTarget);
pSprite->picnum = seq_GetSeqPicnum2(nSeq, MummyList[nMummy].nFrame);
short nFrame = SeqBase[nSeq] + MummyList[nMummy].nFrame;
short nFrameFlag = FrameFlag[nFrame];
seq_MoveSequence(nSprite, nSeq, MummyList[nMummy].nFrame);
bool bVal = false;
MummyList[nMummy].nFrame++;
if (MummyList[nMummy].nFrame >= SeqSize[nSeq])
if (MummyList[nMummy].nAction == 1)
{
MummyList[nMummy].nFrame = 0;
bVal = true;
}
if (nTarget != -1 && nAction < 4)
{
if ((!sprite[nTarget].cstat) && nAction)
if (RandomBit())
{
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel = 0;
}
}
int nMov = MoveCreatureWithCaution(nSprite);
if (nAction > 7)
return;
switch (nAction)
{
case 0:
{
if ((MummyList[nMummy].nIndex & 0x1F) == (totalmoves & 0x1F))
if (cansee(pSprite->x, pSprite->y, pSprite->z - GetSpriteHeight(nSprite), pSprite->sectnum,
sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z - GetSpriteHeight(nTarget), sprite[nTarget].sectnum))
{
pSprite->cstat = 0x101;
if (nTarget < 0)
{
int nTarget = FindPlayer(nSprite, 100);
if (nTarget >= 0)
{
D3PlayFX(StaticSound[kSound7], nSprite);
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nTarget = nTarget;
MummyList[nMummy].nAction = 1;
MummyList[nMummy].nCount = 90;
pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2);
}
}
}
return;
}
case 1:
{
if (MummyList[nMummy].nCount > 0)
{
MummyList[nMummy].nCount--;
}
if ((MummyList[nMummy].nIndex & 0x1F) == (totalmoves & 0x1F))
{
pSprite->cstat = 0x101;
PlotCourseToSprite(nSprite, nTarget);
if (MummyList[nMummy].nAction == 1)
{
if (RandomBit())
{
if (cansee(pSprite->x, pSprite->y, pSprite->z - GetSpriteHeight(nSprite), pSprite->sectnum,
sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z - GetSpriteHeight(nTarget), sprite[nTarget].sectnum))
{
MummyList[nMummy].nAction = 3;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel = 0;
return;
}
}
}
}
// loc_2B5A8
if (!MummyList[nMummy].nFrame)
{
pSprite->xvel = bcos(pSprite->ang, -1);
pSprite->yvel = bsin(pSprite->ang, -1);
}
if (pSprite->xvel || pSprite->yvel)
{
if (pSprite->xvel > 0)
{
pSprite->xvel -= 1024;
if (pSprite->xvel < 0) {
pSprite->xvel = 0;
}
}
else if (pSprite->xvel < 0)
{
pSprite->xvel += 1024;
if (pSprite->xvel > 0) {
pSprite->xvel = 0;
}
}
if (pSprite->yvel > 0)
{
pSprite->yvel -= 1024;
if (pSprite->yvel < 0) {
pSprite->yvel = 0;
}
}
else if (pSprite->yvel < 0)
{
pSprite->yvel += 1024;
if (pSprite->yvel > 0) {
pSprite->yvel = 0;
}
}
}
if (nMov)
{
switch (nMov & 0xC000)
{
case 0x8000:
{
pSprite->ang = (pSprite->ang + ((RandomWord() & 0x3FF) + 1024)) & kAngleMask;
pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2);
return;
}
case 0xC000:
{
if ((nMov & 0x3FFF) == nTarget)
{
int nAngle = getangle(sprite[nTarget].x - pSprite->x, sprite[nTarget].y - pSprite->y);
if (AngleDiff(pSprite->ang, nAngle) < 64)
{
MummyList[nMummy].nAction = 2;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel = 0;
}
}
return;
}
}
}
break;
}
case 2:
{
if (nTarget == -1)
{
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nAction = 3;
MummyList[nMummy].nFrame = 0;
}
else
{
if (PlotCourseToSprite(nSprite, nTarget) >= 1024)
{
MummyList[nMummy].nAction = 1;
MummyList[nMummy].nFrame = 0;
}
else if (nFrameFlag & 0x80)
{
runlist_DamageEnemy(nTarget, nSprite, 5);
}
}
return;
}
case 3:
{
if (bVal)
{
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nCount = 100;
MummyList[nMummy].nTarget = -1;
return;
}
else if (nFrameFlag & 0x80)
{
SetQuake(nSprite, 100);
// low 16 bits of returned var contains the sprite index, the high 16 the bullet number
int nBullet = BuildBullet(nSprite, 9, 0, 0, -15360, pSprite->ang, nTarget + 10000, 1);
CheckMummyRevive(nMummy);
if (nBullet > -1)
{
if (!RandomSize(3))
{
// FIXME CHECKME - nBullet & 0xFFFF can be -1. Original code doesn't handle this??
SetBulletEnemy(FixedToInt(nBullet), nTarget); // isolate the bullet number (shift off the sprite index)
sprite[nBullet & 0xFFFF].pal = 5;
}
}
}
return;
}
case 4:
{
if (bVal)
{
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nAction = 5;
}
return;
}
case 5:
{
MummyList[nMummy].nFrame = 0;
return;
}
case 6:
{
if (bVal)
{
pSprite->cstat = 0x101;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nHealth = 300;
MummyList[nMummy].nTarget = -1;
nCreaturesTotal++;
}
return;
}
case 7:
{
if (nMov & 0x20000)
{
pSprite->xvel >>= 1;
pSprite->yvel >>= 1;
}
if (bVal)
{
pSprite->xvel = 0;
pSprite->yvel = 0;
pSprite->cstat = 0x101;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nTarget = -1;
return;
}
}
}
}
return;
// loc_2B5A8
if (!MummyList[nMummy].nFrame)
{
pSprite->xvel = bcos(pSprite->ang, -1);
pSprite->yvel = bsin(pSprite->ang, -1);
}
if (pSprite->xvel || pSprite->yvel)
{
if (pSprite->xvel > 0)
{
pSprite->xvel -= 1024;
if (pSprite->xvel < 0) {
pSprite->xvel = 0;
}
}
else if (pSprite->xvel < 0)
{
pSprite->xvel += 1024;
if (pSprite->xvel > 0) {
pSprite->xvel = 0;
}
}
return;
}
case 0x90000:
{
seq_PlotSequence(nObject, SeqOffsets[kSeqMummy] + MummySeq[nAction].a, MummyList[nMummy].nFrame, MummySeq[nAction].b);
return;
}
case 0xA0000:
{
if (MummyList[nMummy].nHealth <= 0)
return;
nDamage = runlist_CheckRadialDamage(nSprite);
// fall through to 0x80000
fallthrough__;
}
case 0x80000:
{
if (nDamage <= 0)
return;
if (MummyList[nMummy].nHealth <= 0) {
return;
}
MummyList[nMummy].nHealth -= dmgAdjust(nDamage);
if (MummyList[nMummy].nHealth <= 0)
if (pSprite->yvel > 0)
{
MummyList[nMummy].nHealth = 0;
pSprite->cstat &= 0xFEFE;
nCreaturesKilled++;
DropMagic(nSprite);
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nAction = 4;
pSprite->xvel = 0;
pSprite->yvel = 0;
pSprite->zvel = 0;
pSprite->z = sector[pSprite->sectnum].floorz;
}
else
{
if (!RandomSize(2))
{
MummyList[nMummy].nAction = 7;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel -= 1024;
if (pSprite->yvel < 0) {
pSprite->yvel = 0;
}
}
else if (pSprite->yvel < 0)
{
pSprite->yvel += 1024;
if (pSprite->yvel > 0) {
pSprite->yvel = 0;
}
}
}
if (nMov)
{
switch (nMov & 0xC000)
{
case 0x8000:
{
pSprite->ang = (pSprite->ang + ((RandomWord() & 0x3FF) + 1024)) & kAngleMask;
pSprite->xvel = bcos(pSprite->ang, -2);
pSprite->yvel = bsin(pSprite->ang, -2);
return;
}
case 0xC000:
{
if ((nMov & 0x3FFF) == nTarget)
{
int nAngle = getangle(sprite[nTarget].x - pSprite->x, sprite[nTarget].y - pSprite->y);
if (AngleDiff(pSprite->ang, nAngle) < 64)
{
MummyList[nMummy].nAction = 2;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel = 0;
}
}
return;
}
}
}
break;
}
case 2:
{
if (nTarget == -1)
{
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nFrame = 0;
}
else
{
if (PlotCourseToSprite(nSprite, nTarget) >= 1024)
{
MummyList[nMummy].nAction = 1;
MummyList[nMummy].nFrame = 0;
}
else if (nFrameFlag & 0x80)
{
runlist_DamageEnemy(nTarget, nSprite, 5);
}
}
return;
}
case 3:
{
if (bVal)
{
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nCount = 100;
MummyList[nMummy].nTarget = -1;
return;
}
else if (nFrameFlag & 0x80)
{
SetQuake(nSprite, 100);
// low 16 bits of returned var contains the sprite index, the high 16 the bullet number
int nBullet = BuildBullet(nSprite, 9, 0, 0, -15360, pSprite->ang, nTarget + 10000, 1);
CheckMummyRevive(nMummy);
if (nBullet > -1)
{
if (!RandomSize(3))
{
// FIXME CHECKME - nBullet & 0xFFFF can be -1. Original code doesn't handle this??
SetBulletEnemy(FixedToInt(nBullet), nTarget); // isolate the bullet number (shift off the sprite index)
sprite[nBullet & 0xFFFF].pal = 5;
}
}
}
return;
}
case 4:
{
if (bVal)
{
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nAction = 5;
}
return;
}
case 5:
{
MummyList[nMummy].nFrame = 0;
return;
}
case 6:
{
if (bVal)
{
pSprite->cstat = 0x101;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nHealth = 300;
MummyList[nMummy].nTarget = -1;
nCreaturesTotal++;
}
return;
}
case 7:
{
if (nMov & 0x20000)
{
pSprite->xvel >>= 1;
pSprite->yvel >>= 1;
}
if (bVal)
{
pSprite->xvel = 0;
pSprite->yvel = 0;
pSprite->cstat = 0x101;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nTarget = -1;
}
return;
}
}
}
void AIMummy::Draw(RunListEvent* ev)
{
short nMummy = RunData[ev->nRun].nVal;
assert(nMummy >= 0 && nMummy < kMaxMummies);
short nAction = MummyList[nMummy].nAction;
seq_PlotSequence(ev->nIndex, SeqOffsets[kSeqMummy] + MummySeq[nAction].a, MummyList[nMummy].nFrame, MummySeq[nAction].b);
return;
}
void AIMummy::RadialDamage(RunListEvent* ev)
{
short nMummy = RunData[ev->nRun].nVal;
assert(nMummy >= 0 && nMummy < kMaxMummies);
short nSprite = MummyList[nMummy].nSprite;
auto pSprite = &sprite[nSprite];
if (MummyList[nMummy].nHealth <= 0)
return;
ev->nDamage = runlist_CheckRadialDamage(nSprite);
Damage(ev);
}
void AIMummy::Damage(RunListEvent* ev)
{
short nMummy = RunData[ev->nRun].nVal;
assert(nMummy >= 0 && nMummy < kMaxMummies);
short nSprite = MummyList[nMummy].nSprite;
auto pSprite = &sprite[nSprite];
if (ev->nDamage <= 0)
return;
if (MummyList[nMummy].nHealth <= 0) {
return;
}
MummyList[nMummy].nHealth -= dmgAdjust(ev->nDamage);
if (MummyList[nMummy].nHealth <= 0)
{
MummyList[nMummy].nHealth = 0;
pSprite->cstat &= 0xFEFE;
nCreaturesKilled++;
DropMagic(nSprite);
MummyList[nMummy].nFrame = 0;
MummyList[nMummy].nAction = 4;
pSprite->xvel = 0;
pSprite->yvel = 0;
pSprite->zvel = 0;
pSprite->z = sector[pSprite->sectnum].floorz;
}
else
{
if (!RandomSize(2))
{
MummyList[nMummy].nAction = 7;
MummyList[nMummy].nFrame = 0;
pSprite->xvel = 0;
pSprite->yvel = 0;
}
}
return;
}
void FuncMummy(int nObject, int nMessage, int nDamage, int nRun)
{
AIMummy ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
END_PS_NS