From 0fc490bf4030b92eefdf002c02b302674ae620d2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Oct 2021 21:07:33 +0200 Subject: [PATCH] - converted FuncAnubis into a class. --- source/games/exhumed/src/aistuff.h | 7 + source/games/exhumed/src/anubis.cpp | 575 ++++++++++++++-------------- 2 files changed, 294 insertions(+), 288 deletions(-) diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index 2d0b0f7b2cb..e6cf0aebb5e 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -438,6 +438,13 @@ struct AIAnim : public ExhumedAI void Draw(RunListEvent* ev) override; }; +struct AIAnubis : public ExhumedAI +{ + void Tick(RunListEvent* ev) override; + void Draw(RunListEvent* ev) override; + void RadialDamage(RunListEvent* ev) override; + void Damage(RunListEvent* ev) override; +}; void runlist_DispatchEvent(ExhumedAI* ai, int nObject, int nMessage, int nDamage, int nRun); diff --git a/source/games/exhumed/src/anubis.cpp b/source/games/exhumed/src/anubis.cpp index ef13c72d662..6a420517149 100644 --- a/source/games/exhumed/src/anubis.cpp +++ b/source/games/exhumed/src/anubis.cpp @@ -155,351 +155,350 @@ void BuildAnubis(int nSprite, int x, int y, int z, int nSector, int nAngle, uint nCreaturesTotal++; } -void FuncAnubis(int nObject, int nMessage, int nDamage, int nRun) +void AIAnubis::Tick(RunListEvent* ev) { - int nAnubis = RunData[nRun].nVal; + int nAnubis = ev->RunValue(); auto ap = &AnubisList[nAnubis]; - assert(nAnubis >= 0 && nAnubis < (int)AnubisList.Size()); - int nSprite = ap->nSprite; auto sp = &sprite[nSprite]; - short nAction = ap->nAction; + int nAction = ap->nAction; bool bVal = false; - switch (nMessage) - { - default: - { - DebugOut("unknown msg %d for Anubis\n", nMessage); - return; - } + if (nAction < 11) { + Gravity(nSprite); + } - case 0x20000: - { - if (nAction < 11) { - Gravity(nSprite); - } + short nSeq = SeqOffsets[kSeqAnubis] + AnubisSeq[nAction].a; - short nSeq = SeqOffsets[kSeqAnubis] + AnubisSeq[nAction].a; + seq_MoveSequence(nSprite, nSeq, ap->nFrame); - seq_MoveSequence(nSprite, nSeq, ap->nFrame); + sp->picnum = seq_GetSeqPicnum2(nSeq, ap->nFrame); - sp->picnum = seq_GetSeqPicnum2(nSeq, ap->nFrame); + ap->nFrame++; + if (ap->nFrame >= SeqSize[nSeq]) + { + ap->nFrame = 0; + bVal = true; + } - ap->nFrame++; - if (ap->nFrame >= SeqSize[nSeq]) - { - ap->nFrame = 0; - bVal = true; - } + short nTarget = ap->nTarget; + auto pTarget = nTarget < 0 ? nullptr : &sprite[nTarget]; - short nTarget = ap->nTarget; - auto pTarget = nTarget < 0? nullptr : &sprite[nTarget]; + short nFrame = SeqBase[nSeq] + ap->nFrame; + short nFlag = FrameFlag[nFrame]; - short nFrame = SeqBase[nSeq] + ap->nFrame; - short nFlag = FrameFlag[nFrame]; + int nMov = 0; - int nMov = 0; + if (nAction > 0 && nAction < 11) { + nMov = MoveCreatureWithCaution(nSprite); + } - if (nAction > 0 && nAction < 11) { - nMov = MoveCreatureWithCaution(nSprite); + switch (nAction) + { + case 0: + { + if ((nAnubis & 0x1F) == (totalmoves & 0x1F)) + { + if (nTarget < 0) { + nTarget = FindPlayer(nSprite, 100); } - switch (nAction) + if (nTarget >= 0) { - case 0: - { - if ((nAnubis & 0x1F) == (totalmoves & 0x1F)) - { - if (nTarget < 0) { - nTarget = FindPlayer(nSprite, 100); - } - - if (nTarget >= 0) - { - D3PlayFX(StaticSound[kSound8], nSprite); - ap->nAction = 1; - ap->nFrame = 0; - ap->nTarget = nTarget; - - sp->xvel = bcos(sp->ang, -2); - sp->yvel = bsin(sp->ang, -2); - } - } - return; - } - case 1: - { - if ((nAnubis & 0x1F) == (totalmoves & 0x1F)) - { - PlotCourseToSprite(nSprite, nTarget); - - int nAngle = sp->ang & 0xFFF8; - sp->xvel = bcos(nAngle, -2); - sp->yvel = bsin(nAngle, -2); - } - - switch (nMov & 0xC000) - { - case 0xC000: - { - if ((nMov & 0x3FFF) == nTarget) - { - int nAng = getangle(pTarget->x - sp->x, pTarget->y - sp->y); - int nAngDiff = AngleDiff(sp->ang, nAng); - - if (nAngDiff < 64) - { - ap->nAction = 2; - ap->nFrame = 0; - } - break; - } - // else we fall through to 0x8000 - fallthrough__; - } - case 0x8000: - { - sp->ang = (sp->ang + 256) & kAngleMask; - sp->xvel = bcos(sp->ang, -2); - sp->yvel = bsin(sp->ang, -2); - break; - } - - default: - { - if (ap->nCount) - { - ap->nCount--; - } - else - { - ap->nCount = 60; - - if (nTarget > -1) // NOTE: nTarget can be -1. this check wasn't in original code. TODO: demo compatiblity? - { - if (cansee(sp->x, sp->y, sp->z - GetSpriteHeight(nSprite), sp->sectnum, - pTarget->x, pTarget->y, pTarget->z - GetSpriteHeight(nTarget), pTarget->sectnum)) - { - sp->xvel = 0; - sp->yvel = 0; - sp->ang = GetMyAngle(pTarget->x - sp->x, pTarget->y - sp->y); - - ap->nAction = 3; - ap->nFrame = 0; - } - } - } - break; - } - } - break; - } - case 2: - { - if (nTarget == -1) - { - ap->nAction = 0; - ap->nCount = 50; - } - else - { - if (PlotCourseToSprite(nSprite, nTarget) >= 768) - { - ap->nAction = 1; - } - else - { - if (nFlag & 0x80) - { - runlist_DamageEnemy(nTarget, nSprite, 7); - } - } - } + D3PlayFX(StaticSound[kSound8], nSprite); + ap->nAction = 1; + ap->nFrame = 0; + ap->nTarget = nTarget; - break; - } - case 3: - { - if (bVal) - { - ap->nAction = 1; + sp->xvel = bcos(sp->ang, -2); + sp->yvel = bsin(sp->ang, -2); + } + } + return; + } + case 1: + { + if ((nAnubis & 0x1F) == (totalmoves & 0x1F)) + { + PlotCourseToSprite(nSprite, nTarget); - sp->xvel = bcos(sp->ang, -2); - sp->yvel = bsin(sp->ang, -2); - ap->nFrame = 0; - } - else - { - // loc_25718: - if (nFlag & 0x80) - { - BuildBullet(nSprite, 8, 0, 0, -1, sp->ang, nTarget + 10000, 1); - } - } + int nAngle = sp->ang & 0xFFF8; + sp->xvel = bcos(nAngle, -2); + sp->yvel = bsin(nAngle, -2); + } - return; - } - case 4: - case 5: - { - sp->xvel = 0; - sp->yvel = 0; + switch (nMov & 0xC000) + { + case 0xC000: + { + if ((nMov & 0x3FFF) == nTarget) + { + int nAng = getangle(pTarget->x - sp->x, pTarget->y - sp->y); + int nAngDiff = AngleDiff(sp->ang, nAng); - if (bVal) - { - ap->nAction = 1; - ap->nFrame = 0; - } - return; - } - case 6: - case 7: - case 8: - case 9: - case 10: + if (nAngDiff < 64) { - if (bVal) - { - ap->nAction = (RandomSize(3) % 5) + 6; - ap->nFrame = 0; - } - return; + ap->nAction = 2; + ap->nFrame = 0; } - case 11: - case 12: + break; + } + // else we fall through to 0x8000 + fallthrough__; + } + case 0x8000: + { + sp->ang = (sp->ang + 256) & kAngleMask; + sp->xvel = bcos(sp->ang, -2); + sp->yvel = bsin(sp->ang, -2); + break; + } + + default: + { + if (ap->nCount) + { + ap->nCount--; + } + else + { + ap->nCount = 60; + + if (nTarget > -1) // NOTE: nTarget can be -1. this check wasn't in original code. TODO: demo compatiblity? { - if (bVal) + if (cansee(sp->x, sp->y, sp->z - GetSpriteHeight(nSprite), sp->sectnum, + pTarget->x, pTarget->y, pTarget->z - GetSpriteHeight(nTarget), pTarget->sectnum)) { - ap->nAction = nAction + 2; - ap->nFrame = 0; - sp->xvel = 0; sp->yvel = 0; + sp->ang = GetMyAngle(pTarget->x - sp->x, pTarget->y - sp->y); + + ap->nAction = 3; + ap->nFrame = 0; } - return; - } - case 13: - case 14: - { - sp->cstat &= 0xFEFE; - return; } - - default: - return; } - - // loc_2564C: - if (nAction && nTarget != -1) + break; + } + } + break; + } + case 2: + { + if (nTarget == -1) + { + ap->nAction = 0; + ap->nCount = 50; + } + else + { + if (PlotCourseToSprite(nSprite, nTarget) >= 768) { - if (!(pTarget->cstat & 0x101)) + ap->nAction = 1; + } + else + { + if (nFlag & 0x80) { - ap->nAction = 0; - ap->nFrame = 0; - ap->nCount = 100; - ap->nTarget = -1; - - sp->xvel = 0; - sp->yvel = 0; + runlist_DamageEnemy(nTarget, nSprite, 7); } } - - return; } - case 0x90000: + break; + } + case 3: + { + if (bVal) { - seq_PlotSequence(nObject, SeqOffsets[kSeqAnubis] + AnubisSeq[nAction].a, ap->nFrame, AnubisSeq[nAction].b); - break; - } + ap->nAction = 1; - case 0xA0000: // fall through to next case + sp->xvel = bcos(sp->ang, -2); + sp->yvel = bsin(sp->ang, -2); + ap->nFrame = 0; + } + else { - if (nAction >= 11) { - return; + // loc_25718: + if (nFlag & 0x80) + { + BuildBullet(nSprite, 8, 0, 0, -1, sp->ang, nTarget + 10000, 1); } + } - nDamage = runlist_CheckRadialDamage(nSprite); - fallthrough__; + return; + } + case 4: + case 5: + { + sp->xvel = 0; + sp->yvel = 0; + + if (bVal) + { + ap->nAction = 1; + ap->nFrame = 0; } - case 0x80000: + return; + } + case 6: + case 7: + case 8: + case 9: + case 10: + { + if (bVal) { - if (nDamage) - { - if (ap->nHealth <= 0) - return; + ap->nAction = (RandomSize(3) % 5) + 6; + ap->nFrame = 0; + } + return; + } + case 11: + case 12: + { + if (bVal) + { + ap->nAction = nAction + 2; + ap->nFrame = 0; - ap->nHealth -= dmgAdjust(nDamage); + sp->xvel = 0; + sp->yvel = 0; + } + return; + } + case 13: + case 14: + { + sp->cstat &= 0xFEFE; + return; + } - if (ap->nHealth > 0) - { - int nTarget = nObject; + default: + return; + } - // loc_258D6: - if (nTarget < 0) { - return; - } - auto pTarget = &sprite[nTarget]; + // loc_2564C: + if (nAction && nTarget != -1) + { + if (!(pTarget->cstat & 0x101)) + { + ap->nAction = 0; + ap->nFrame = 0; + ap->nCount = 100; + ap->nTarget = -1; - if (pTarget->statnum == 100 || pTarget->statnum < 199) - { - if (!RandomSize(5)) { - ap->nTarget = nTarget; - } - } + sp->xvel = 0; + sp->yvel = 0; + } + } - if (RandomSize(1)) - { - if (nAction >= 6 && nAction <= 10) - { - int nDrumSprite = insertsprite(sp->sectnum, kStatAnubisDrum); - auto pDrumSprite = &sprite[nDrumSprite]; - - pDrumSprite->x = sp->x; - pDrumSprite->y = sp->y; - pDrumSprite->z = sector[pDrumSprite->sectnum].floorz; - pDrumSprite->xrepeat = 40; - pDrumSprite->yrepeat = 40; - pDrumSprite->shade = -64; - - BuildObject(nDrumSprite, 2, 0); - } - - ap->nAction = 4; - ap->nFrame = 0; - } - else - { - // loc_259B5: - D3PlayFX(StaticSound[kSound39], nSprite); - } - } - else - { - // he ded. - sp->xvel = 0; - sp->yvel = 0; - sp->zvel = 0; - sp->z = sector[sp->sectnum].floorz; - sp->cstat &= 0xFEFE; + return; +} - ap->nHealth = 0; +void AIAnubis::Draw(RunListEvent* ev) +{ + auto ap = &AnubisList[ev->RunValue()]; + seq_PlotSequence(ev->nIndex, SeqOffsets[kSeqAnubis] + AnubisSeq[ap->nAction].a, ap->nFrame, AnubisSeq[ap->nAction].b); +} - nCreaturesKilled++; +void AIAnubis::RadialDamage(RunListEvent* ev) +{ + auto ap = &AnubisList[ev->RunValue()]; + if (ap->nAction < 11) + { + ev->nDamage = runlist_CheckRadialDamage(ap->nSprite); + Damage(ev); + } +} - if (nAction < 11) - { - DropMagic(nSprite); - ap->nAction = (nMessage == 0xA0000) + 11; - ap->nFrame = 0; - } +void AIAnubis::Damage(RunListEvent* ev) +{ + auto ap = &AnubisList[ev->RunValue()]; + int nSprite = ap->nSprite; + auto sp = &sprite[nSprite]; + int nAction = ap->nAction; + int nDamage = ev->nDamage; + + if (nDamage) + { + if (ap->nHealth <= 0) + return; + + ap->nHealth -= dmgAdjust(nDamage); + + if (ap->nHealth > 0) + { + int nTarget = ev->nIndex; + + // loc_258D6: + if (nTarget < 0) { + return; + } + auto pTarget = &sprite[nTarget]; + + if (pTarget->statnum == 100 || pTarget->statnum < 199) + { + if (!RandomSize(5)) { + ap->nTarget = nTarget; } } - return; + if (RandomSize(1)) + { + if (nAction >= 6 && nAction <= 10) + { + int nDrumSprite = insertsprite(sp->sectnum, kStatAnubisDrum); + auto pDrumSprite = &sprite[nDrumSprite]; + + pDrumSprite->x = sp->x; + pDrumSprite->y = sp->y; + pDrumSprite->z = sector[pDrumSprite->sectnum].floorz; + pDrumSprite->xrepeat = 40; + pDrumSprite->yrepeat = 40; + pDrumSprite->shade = -64; + + BuildObject(nDrumSprite, 2, 0); + } + + ap->nAction = 4; + ap->nFrame = 0; + } + else + { + // loc_259B5: + D3PlayFX(StaticSound[kSound39], nSprite); + } } + else + { + // he ded. + sp->xvel = 0; + sp->yvel = 0; + sp->zvel = 0; + sp->z = sector[sp->sectnum].floorz; + sp->cstat &= 0xFEFE; + + ap->nHealth = 0; + + nCreaturesKilled++; + + if (nAction < 11) + { + DropMagic(nSprite); + ap->nAction = (ev->nMessage == EMessageType::RadialDamage) + 11; + ap->nFrame = 0; + } } + } } + + +void FuncAnubis(int nObject, int nMessage, int nDamage, int nRun) +{ + AIAnubis ai; + runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); +} + END_PS_NS