From 25de6fe4c506ee97ade540516370d4f39f67e171 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Oct 2021 23:03:09 +0200 Subject: [PATCH] - converted FuncRex to a class. --- source/games/exhumed/src/aistuff.h | 7 + source/games/exhumed/src/rex.cpp | 597 +++++++++++++++-------------- 2 files changed, 311 insertions(+), 293 deletions(-) diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index bfa3fc91383..87e72f7f97c 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -601,6 +601,13 @@ struct AIRat : public ExhumedAI void RadialDamage(RunListEvent* ev) override; }; +struct AIRex : 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); diff --git a/source/games/exhumed/src/rex.cpp b/source/games/exhumed/src/rex.cpp index 88e14708150..b2b95c28a86 100644 --- a/source/games/exhumed/src/rex.cpp +++ b/source/games/exhumed/src/rex.cpp @@ -80,12 +80,12 @@ void InitRexs() void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, int nChannel) { int nRex = RexList.Reserve(1); - auto pSprite = &sprite[nSprite]; + auto pSprite = &sprite[nSprite]; if (nSprite == -1) { nSprite = insertsprite(nSector, 119); - pSprite = &sprite[nSprite]; + pSprite = &sprite[nSprite]; } else { @@ -122,7 +122,7 @@ void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, i RexList[nRex].nAction = 0; RexList[nRex].nHealth = 4000; - RexList[nRex].nFrame = 0; + RexList[nRex].nFrame = 0; RexList[nRex].nSprite = nSprite; RexList[nRex].nTarget = -1; RexList[nRex].nCount = 0; @@ -137,361 +137,372 @@ void BuildRex(short nSprite, int x, int y, int z, short nSector, short nAngle, i nCreaturesTotal++; } -void FuncRex(int nObject, int nMessage, int nDamage, int nRun) +void AIRex::RadialDamage(RunListEvent* ev) { - short nRex = RunData[nRun].nVal; + short nRex = RunData[ev->nRun].nVal; assert(nRex >= 0 && nRex < (int)RexList.Size()); short nAction = RexList[nRex].nAction; short nSprite = RexList[nRex].nSprite; - auto pSprite = &sprite[nSprite]; - bool bVal = false; + if (nAction == 5) + { + ev->nDamage = runlist_CheckRadialDamage(nSprite); + } + Damage(ev); +} + +void AIRex::Damage(RunListEvent* ev) +{ + short nRex = RunData[ev->nRun].nVal; + assert(nRex >= 0 && nRex < (int)RexList.Size()); + + short nAction = RexList[nRex].nAction; + short nSprite = RexList[nRex].nSprite; + auto pSprite = &sprite[nSprite]; - switch (nMessage) + if (ev->nDamage) { - default: + short nTarget = ev->nIndex; + if (nTarget >= 0 && sprite[nTarget].statnum == 100) { - Printf("unknown msg %d for Rex\n", nMessage); - return; + RexList[nRex].nTarget = nTarget; } - case 0xA0000: + if (RexList[nRex].nAction == 5 && RexList[nRex].nHealth > 0) { - if (nAction == 5) + RexList[nRex].nHealth -= dmgAdjust(ev->nDamage); + + if (RexList[nRex].nHealth <= 0) { - nDamage = runlist_CheckRadialDamage(nSprite); + pSprite->xvel = 0; + pSprite->yvel = 0; + pSprite->zvel = 0; + pSprite->cstat &= 0xFEFE; + + RexList[nRex].nHealth = 0; + + nCreaturesKilled++; + + if (nAction < 6) + { + RexList[nRex].nAction = 6; + RexList[nRex].nFrame = 0; + } } - // fall through to case 0x80000 - fallthrough__; } + } +} + +void AIRex::Draw(RunListEvent* ev) +{ + short nRex = RunData[ev->nRun].nVal; + assert(nRex >= 0 && nRex < (int)RexList.Size()); + + short nAction = RexList[nRex].nAction; + + seq_PlotSequence(ev->nIndex, SeqOffsets[kSeqRex] + RexSeq[nAction].a, RexList[nRex].nFrame, RexSeq[nAction].b); + return; +} + +void AIRex::Tick(RunListEvent* ev) +{ + short nRex = RunData[ev->nRun].nVal; + assert(nRex >= 0 && nRex < (int)RexList.Size()); + + short nAction = RexList[nRex].nAction; + short nSprite = RexList[nRex].nSprite; + auto pSprite = &sprite[nSprite]; + + bool bVal = false; + + Gravity(nSprite); + + int nSeq = SeqOffsets[kSeqRex] + RexSeq[nAction].a; + + pSprite->picnum = seq_GetSeqPicnum2(nSeq, RexList[nRex].nFrame); + + int ecx = 2; + + if (nAction != 2) { + ecx = 1; + } + + // moves the mouth open and closed as it's idle? + while (--ecx != -1) + { + seq_MoveSequence(nSprite, nSeq, RexList[nRex].nFrame); + + RexList[nRex].nFrame++; + if (RexList[nRex].nFrame >= SeqSize[nSeq]) + { + RexList[nRex].nFrame = 0; + bVal = true; + } + } + + int nFlag = FrameFlag[SeqBase[nSeq] + RexList[nRex].nFrame]; + + short nTarget = RexList[nRex].nTarget; - case 0x80000: + switch (nAction) + { + default: + return; + + case 0: + { + if (!RexList[nRex].nCount) { - if (nDamage) + if ((nRex & 0x1F) == (totalmoves & 0x1F)) { - short nTarget = nObject; - if (nTarget >= 0 && sprite[nTarget].statnum == 100) + if (nTarget < 0) { - RexList[nRex].nTarget = nTarget; + short nAngle = pSprite->ang; // make backup of this variable + RexList[nRex].nTarget = FindPlayer(nSprite, 60); + pSprite->ang = nAngle; } - - if (RexList[nRex].nAction == 5 && RexList[nRex].nHealth > 0) + else { - RexList[nRex].nHealth -= dmgAdjust(nDamage); - - if (RexList[nRex].nHealth <= 0) - { - pSprite->xvel = 0; - pSprite->yvel = 0; - pSprite->zvel = 0; - pSprite->cstat &= 0xFEFE; - - RexList[nRex].nHealth = 0; - - nCreaturesKilled++; - - if (nAction < 6) - { - RexList[nRex].nAction = 6; - RexList[nRex].nFrame = 0; - } - } + RexList[nRex].nCount = 60; } } - return; } - - case 0x90000: + else { - seq_PlotSequence(nObject, SeqOffsets[kSeqRex] + RexSeq[nAction].a, RexList[nRex].nFrame, RexSeq[nAction].b); - return; - } + RexList[nRex].nCount--; + if (RexList[nRex].nCount <= 0) + { + RexList[nRex].nAction = 1; + RexList[nRex].nFrame = 0; - case 0x20000: - { - Gravity(nSprite); + pSprite->xvel = bcos(pSprite->ang, -2); + pSprite->yvel = bsin(pSprite->ang, -2); - int nSeq = SeqOffsets[kSeqRex] + RexSeq[nAction].a; + D3PlayFX(StaticSound[kSound48], nSprite); - pSprite->picnum = seq_GetSeqPicnum2(nSeq, RexList[nRex].nFrame); + RexList[nRex].nCount = 30; + } + } - int ecx = 2; + return; + } - if (nAction != 2) { - ecx = 1; - } + case 1: + { + if (RexList[nRex].nCount > 0) + { + RexList[nRex].nCount--; + } - // moves the mouth open and closed as it's idle? - while (--ecx != -1) + if ((nRex & 0x0F) == (totalmoves & 0x0F)) + { + if (!RandomSize(1)) { - seq_MoveSequence(nSprite, nSeq, RexList[nRex].nFrame); - - RexList[nRex].nFrame++; - if (RexList[nRex].nFrame >= SeqSize[nSeq]) + RexList[nRex].nAction = 5; + RexList[nRex].nFrame = 0; + pSprite->xvel = 0; + pSprite->yvel = 0; + return; + } + else + { + if (((PlotCourseToSprite(nSprite, nTarget) >> 8) >= 60) || RexList[nRex].nCount > 0) + { + int nAngle = pSprite->ang & 0xFFF8; + pSprite->xvel = bcos(nAngle, -2); + pSprite->yvel = bsin(nAngle, -2); + } + else { + RexList[nRex].nAction = 2; + RexList[nRex].nCount = 240; + D3PlayFX(StaticSound[kSound48], nSprite); RexList[nRex].nFrame = 0; - bVal = true; + return; } } + } - int nFlag = FrameFlag[SeqBase[nSeq] + RexList[nRex].nFrame]; - - short nTarget = RexList[nRex].nTarget; + int nMov = MoveCreatureWithCaution(nSprite); - switch (nAction) + switch ((nMov & 0xC000)) + { + case 0xC000: + { + if ((nMov & 0x3FFF) == nTarget) { - default: - return; - - case 0: - { - if (!RexList[nRex].nCount) - { - if ((nRex & 0x1F) == (totalmoves & 0x1F)) - { - if (nTarget < 0) - { - short nAngle = pSprite->ang; // make backup of this variable - RexList[nRex].nTarget = FindPlayer(nSprite, 60); - pSprite->ang = nAngle; - } - else - { - RexList[nRex].nCount = 60; - } - } - } - else - { - RexList[nRex].nCount--; - if (RexList[nRex].nCount <= 0) - { - RexList[nRex].nAction = 1; - RexList[nRex].nFrame = 0; + PlotCourseToSprite(nSprite, nTarget); + RexList[nRex].nAction = 4; + RexList[nRex].nFrame = 0; + break; + } + fallthrough__; + } + case 0x8000: + { + pSprite->ang = (pSprite->ang + 256) & kAngleMask; + pSprite->xvel = bcos(pSprite->ang, -2); + pSprite->yvel = bsin(pSprite->ang, -2); + RexList[nRex].nAction = 1; + RexList[nRex].nFrame = 0; + nAction = 1; + break; + } + } - pSprite->xvel = bcos(pSprite->ang, -2); - pSprite->yvel = bsin(pSprite->ang, -2); + break; + } - D3PlayFX(StaticSound[kSound48], nSprite); + case 2: + { + RexList[nRex].nCount--; + if (RexList[nRex].nCount > 0) + { + PlotCourseToSprite(nSprite, nTarget); - RexList[nRex].nCount = 30; - } - } + pSprite->xvel = bcos(pSprite->ang, -1); + pSprite->yvel = bsin(pSprite->ang, -1); - return; - } + int nMov = MoveCreatureWithCaution(nSprite); - case 1: - { - if (RexList[nRex].nCount > 0) - { - RexList[nRex].nCount--; - } + switch (nMov & 0xC000) + { + case 0x8000: + { + SetQuake(nSprite, 25); + RexList[nRex].nCount = 60; + + pSprite->ang = (pSprite->ang + 256) & kAngleMask; + pSprite->xvel = bcos(pSprite->ang, -2); + pSprite->yvel = bsin(pSprite->ang, -2); + RexList[nRex].nAction = 1; + RexList[nRex].nFrame = 0; + nAction = 1; + break; + } + case 0xC000: + { + RexList[nRex].nAction = 3; + RexList[nRex].nFrame = 0; - if ((nRex & 0x0F) == (totalmoves & 0x0F)) - { - if (!RandomSize(1)) - { - RexList[nRex].nAction = 5; - RexList[nRex].nFrame = 0; - pSprite->xvel = 0; - pSprite->yvel = 0; - return; - } - else - { - if (((PlotCourseToSprite(nSprite, nTarget) >> 8) >= 60) || RexList[nRex].nCount > 0) - { - int nAngle = pSprite->ang & 0xFFF8; - pSprite->xvel = bcos(nAngle, -2); - pSprite->yvel = bsin(nAngle, -2); - } - else - { - RexList[nRex].nAction = 2; - RexList[nRex].nCount = 240; - D3PlayFX(StaticSound[kSound48], nSprite); - RexList[nRex].nFrame = 0; - return; - } - } - } + short nSprite2 = nMov & 0x3FFF; - int nMov = MoveCreatureWithCaution(nSprite); + if (sprite[nSprite2].statnum && sprite[nSprite2].statnum < 107) + { + short nAngle = pSprite->ang; - switch ((nMov & 0xC000)) - { - case 0xC000: - { - if ((nMov & 0x3FFF) == nTarget) - { - PlotCourseToSprite(nSprite, nTarget); - RexList[nRex].nAction = 4; - RexList[nRex].nFrame = 0; - break; - } - fallthrough__; - } - case 0x8000: - { - pSprite->ang = (pSprite->ang + 256) & kAngleMask; - pSprite->xvel = bcos(pSprite->ang, -2); - pSprite->yvel = bsin(pSprite->ang, -2); - RexList[nRex].nAction = 1; - RexList[nRex].nFrame = 0; - nAction = 1; - break; - } - } + runlist_DamageEnemy(nSprite2, nSprite, 15); - break; - } + int xVel = bcos(nAngle) * 15; + int yVel = bsin(nAngle) * 15; - case 2: - { - RexList[nRex].nCount--; - if (RexList[nRex].nCount > 0) + if (sprite[nSprite2].statnum == 100) { - PlotCourseToSprite(nSprite, nTarget); - - pSprite->xvel = bcos(pSprite->ang, -1); - pSprite->yvel = bsin(pSprite->ang, -1); - - int nMov = MoveCreatureWithCaution(nSprite); - - switch (nMov & 0xC000) - { - case 0x8000: - { - SetQuake(nSprite, 25); - RexList[nRex].nCount = 60; - - pSprite->ang = (pSprite->ang + 256) & kAngleMask; - pSprite->xvel = bcos(pSprite->ang, -2); - pSprite->yvel = bsin(pSprite->ang, -2); - RexList[nRex].nAction = 1; - RexList[nRex].nFrame = 0; - nAction = 1; - break; - } - case 0xC000: - { - RexList[nRex].nAction = 3; - RexList[nRex].nFrame = 0; - - short nSprite2 = nMov & 0x3FFF; - - if (sprite[nSprite2].statnum && sprite[nSprite2].statnum < 107) - { - short nAngle = pSprite->ang; - - runlist_DamageEnemy(nSprite2, nSprite, 15); - - int xVel = bcos(nAngle) * 15; - int yVel = bsin(nAngle) * 15; - - if (sprite[nSprite2].statnum == 100) - { - short nPlayer = GetPlayerFromSprite(nSprite2); - nXDamage[nPlayer] += (xVel << 4); - nYDamage[nPlayer] += (yVel << 4); - sprite[nSprite2].zvel = -3584; - } - else - { - sprite[nSprite2].xvel += (xVel >> 3); - sprite[nSprite2].yvel += (yVel >> 3); - sprite[nSprite2].zvel = -2880; - } - } - - RexList[nRex].nCount >>= 2; - return; - } - } + short nPlayer = GetPlayerFromSprite(nSprite2); + nXDamage[nPlayer] += (xVel << 4); + nYDamage[nPlayer] += (yVel << 4); + sprite[nSprite2].zvel = -3584; } else { - RexList[nRex].nAction = 1; - RexList[nRex].nFrame = 0; - RexList[nRex].nCount = 90; + sprite[nSprite2].xvel += (xVel >> 3); + sprite[nSprite2].yvel += (yVel >> 3); + sprite[nSprite2].zvel = -2880; } - - return; } - case 3: - { - if (bVal) - { - RexList[nRex].nAction = 2; - } - return; - } - - case 4: - { - if (nTarget != -1) - { - if (PlotCourseToSprite(nSprite, nTarget) < 768) - { - if (nFlag & 0x80) - { - runlist_DamageEnemy(nTarget, nSprite, 15); - } - - break; - } - } + RexList[nRex].nCount >>= 2; + return; + } + } + } + else + { + RexList[nRex].nAction = 1; + RexList[nRex].nFrame = 0; + RexList[nRex].nCount = 90; + } - RexList[nRex].nAction = 1; - break; - } + return; + } - case 5: - { - if (bVal) - { - RexList[nRex].nAction = 1; - RexList[nRex].nCount = 15; - } - return; - } + case 3: + { + if (bVal) + { + RexList[nRex].nAction = 2; + } + return; + } - case 6: + case 4: + { + if (nTarget != -1) + { + if (PlotCourseToSprite(nSprite, nTarget) < 768) + { + if (nFlag & 0x80) { - if (bVal) - { - RexList[nRex].nAction = 7; - RexList[nRex].nFrame = 0; - runlist_ChangeChannel(RexList[nRex].nChannel, 1); - } - return; + runlist_DamageEnemy(nTarget, nSprite, 15); } - case 7: - { - pSprite->cstat &= 0xFEFE; - return; - } + break; } + } - // break-ed - if (nAction > 0) - { - if ((nTarget != -1) && (!(sprite[nTarget].cstat & 0x101))) - { - RexList[nRex].nAction = 0; - RexList[nRex].nFrame = 0; - RexList[nRex].nCount = 0; - RexList[nRex].nTarget = -1; - pSprite->xvel = 0; - pSprite->yvel = 0; - } - } - return; + RexList[nRex].nAction = 1; + break; + } + + case 5: + { + if (bVal) + { + RexList[nRex].nAction = 1; + RexList[nRex].nCount = 15; + } + return; + } + + case 6: + { + if (bVal) + { + RexList[nRex].nAction = 7; + RexList[nRex].nFrame = 0; + runlist_ChangeChannel(RexList[nRex].nChannel, 1); + } + return; + } + + case 7: + { + pSprite->cstat &= 0xFEFE; + return; + } + } + + // break-ed + if (nAction > 0) + { + if ((nTarget != -1) && (!(sprite[nTarget].cstat & 0x101))) + { + RexList[nRex].nAction = 0; + RexList[nRex].nFrame = 0; + RexList[nRex].nCount = 0; + RexList[nRex].nTarget = -1; + pSprite->xvel = 0; + pSprite->yvel = 0; } } + return; +} + + +void FuncRex(int nObject, int nMessage, int nDamage, int nRun) +{ + AIRex ai; + runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun); } END_PS_NS