From b9f6120380c4bac347ab9c7470048ce321db5ef6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 5 May 2021 10:12:31 +0200 Subject: [PATCH] - handle target validations in AI functions properly. Now they will all print the function name along with the message and not rely on assert abuse. --- source/games/blood/src/aibat.cpp | 6 ++-- source/games/blood/src/aibeast.cpp | 7 +++-- source/games/blood/src/aiboneel.cpp | 29 +++++++++---------- source/games/blood/src/aiburn.cpp | 1 - source/games/blood/src/aicaleb.cpp | 4 +-- source/games/blood/src/aicerber.cpp | 6 +--- source/games/blood/src/aicult.cpp | 5 ++-- source/games/blood/src/aigarg.cpp | 7 ++--- source/games/blood/src/aighost.cpp | 7 ++--- source/games/blood/src/aigilbst.cpp | 7 +++-- source/games/blood/src/aihand.cpp | 3 +- source/games/blood/src/aihound.cpp | 11 +------- source/games/blood/src/aiinnoc.cpp | 2 +- source/games/blood/src/aipod.cpp | 11 +------- source/games/blood/src/airat.cpp | 3 +- source/games/blood/src/aispid.cpp | 7 ++--- source/games/blood/src/aitchern.cpp | 7 ++--- source/games/blood/src/aizomba.cpp | 5 ++-- source/games/blood/src/aizombf.cpp | 4 ++- source/games/blood/src/bloodactor.h | 44 ++++++++++++++++++----------- 20 files changed, 80 insertions(+), 96 deletions(-) diff --git a/source/games/blood/src/aibat.cpp b/source/games/blood/src/aibat.cpp index 2a4223cb7..20ce2289b 100644 --- a/source/games/blood/src/aibat.cpp +++ b/source/games/blood/src/aibat.cpp @@ -66,6 +66,7 @@ void batBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype *pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); @@ -74,7 +75,6 @@ void batBiteSeqCallback(int, DBloodActor* actor) DUDEINFO *pDudeInfoT = getDudeInfo(pTarget->type); int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2; int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2; - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); actFireVector(actor, 0, 0, dx, dy, height2-height, kVectorBatBite); } @@ -167,7 +167,7 @@ static void batThinkPonder(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -275,7 +275,7 @@ static void batThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aibeast.cpp b/source/games/blood/src/aibeast.cpp index 401a23fe9..032c41d0a 100644 --- a/source/games/blood/src/aibeast.cpp +++ b/source/games/blood/src/aibeast.cpp @@ -67,6 +67,7 @@ void SlashSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype *pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); @@ -238,7 +239,7 @@ static void beastThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -408,7 +409,7 @@ static void beastThinkSwimChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -512,6 +513,7 @@ static void sub_62AE0(DBloodActor* actor) auto pSprite = &actor->s(); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int z = pSprite->z + getDudeInfo(pSprite->type)->eyeHeight; int z2 = pTarget->z + getDudeInfo(pTarget->type)->eyeHeight; @@ -549,6 +551,7 @@ static void sub_62D7C(DBloodActor* actor) int nSprite = pSprite->index; assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int z = pSprite->z + getDudeInfo(pSprite->type)->eyeHeight; int z2 = pTarget->z + getDudeInfo(pTarget->type)->eyeHeight; diff --git a/source/games/blood/src/aiboneel.cpp b/source/games/blood/src/aiboneel.cpp index 8a1443e54..791bfb0fd 100644 --- a/source/games/blood/src/aiboneel.cpp +++ b/source/games/blood/src/aiboneel.cpp @@ -65,6 +65,20 @@ void eelBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype *pSprite = &actor->s(); + + /* + * workaround for + * pXSprite->target >= 0 && pXSprite->target < kMaxSprites in file NBlood/source/blood/src/aiboneel.cpp at line 86 + * The value of pXSprite->target is -1. + * copied from lines 177:181 + * resolves this case, but may cause other issues? + */ + if (actor->GetTarget() == nullptr) + { + aiNewState(actor, &eelSearch); + return; + } + spritetype *pTarget = &sprite[pXSprite->target_i]; int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); @@ -73,19 +87,6 @@ void eelBiteSeqCallback(int, DBloodActor* actor) DUDEINFO *pDudeInfoT = getDudeInfo(pTarget->type); int height = (pSprite->yrepeat*pDudeInfo->eyeHeight)<<2; int height2 = (pTarget->yrepeat*pDudeInfoT->eyeHeight)<<2; - /* - * workaround for - * pXSprite->target >= 0 && pXSprite->target < kMaxSprites in file NBlood/source/blood/src/aiboneel.cpp at line 86 - * The value of pXSprite->target is -1. - * copied from lines 177:181 - * resolves this case, but may cause other issues? - */ - if (actor->GetTarget() == nullptr) - { - aiNewState(actor, &eelSearch); - return; - } - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); actFireVector(actor, 0, 0, dx, dy, height2-height, kVectorBoneelBite); } @@ -180,7 +181,6 @@ static void eelThinkPonder(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -288,7 +288,6 @@ static void eelThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aiburn.cpp b/source/games/blood/src/aiburn.cpp index 529ed5e54..e6e24a76f 100644 --- a/source/games/blood/src/aiburn.cpp +++ b/source/games/blood/src/aiburn.cpp @@ -162,7 +162,6 @@ static void burnThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aicaleb.cpp b/source/games/blood/src/aicaleb.cpp index a160781a5..9034ec1e9 100644 --- a/source/games/blood/src/aicaleb.cpp +++ b/source/games/blood/src/aicaleb.cpp @@ -137,7 +137,6 @@ static void calebThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -273,7 +272,6 @@ static void calebThinkSwimChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -354,6 +352,7 @@ static void sub_65F44(DBloodActor* actor) int nSprite = pSprite->index; assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int z = pSprite->z + getDudeInfo(pSprite->type)->eyeHeight; int z2 = pTarget->z + getDudeInfo(pTarget->type)->eyeHeight; @@ -391,6 +390,7 @@ static void sub_661E0(DBloodActor* actor) int nSprite = pSprite->index; assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int z = pSprite->z + getDudeInfo(pSprite->type)->eyeHeight; int z2 = pTarget->z + getDudeInfo(pTarget->type)->eyeHeight; diff --git a/source/games/blood/src/aicerber.cpp b/source/games/blood/src/aicerber.cpp index 5c5c4b643..694ef1219 100644 --- a/source/games/blood/src/aicerber.cpp +++ b/source/games/blood/src/aicerber.cpp @@ -67,11 +67,7 @@ void cerberusBiteSeqCallback(int, DBloodActor* actor) Printf(PRINT_HIGH, "pSprite->type >= kDudeBase && pSprite->type < kDudeMax"); return; } - ///assert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target >= 0 && pXSprite->target < kMaxSprites"); - return; - } + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int dz = pTarget->z-pSprite->z; actFireVector(actor, 350, -100, dx, dy, dz, kVectorCerberusHack); diff --git a/source/games/blood/src/aicult.cpp b/source/games/blood/src/aicult.cpp index c41f0c6d8..41b2567d5 100644 --- a/source/games/blood/src/aicult.cpp +++ b/source/games/blood/src/aicult.cpp @@ -136,7 +136,7 @@ void cultThrowSeqCallback(int, DBloodActor* actor) nMissile = kThingArmedTNTBundle; char v4 = Chance(0x6000); sfxPlay3DSound(pSprite, 455, -1, 0); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); int dx = pTarget->x - pSprite->x; @@ -173,7 +173,7 @@ void sub_68230(int, DBloodActor* actor) if (gGameOptions.nDifficulty > 2) nMissile = kThingArmedTNTBundle; sfxPlay3DSound(pSprite, 455, -1, 0); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); int dx = pTarget->x - pSprite->x; @@ -252,7 +252,6 @@ static void cultThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aigarg.cpp b/source/games/blood/src/aigarg.cpp index ab6e8d322..f1f872547 100644 --- a/source/games/blood/src/aigarg.cpp +++ b/source/games/blood/src/aigarg.cpp @@ -81,6 +81,7 @@ void SlashFSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO *pDudeInfoT = getDudeInfo(pTarget->type); @@ -110,6 +111,7 @@ void BlastSSeqCallback(int, DBloodActor* actor) XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); wrand(); // ??? + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int height = (pSprite->yrepeat*getDudeInfo(pSprite->type)->eyeHeight) << 2; int dx = pXSprite->targetX-pSprite->x; @@ -366,11 +368,6 @@ static void gargThinkChase(DBloodActor* actor) return; } DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - ///assert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target >= 0 && pXSprite->target < kMaxSprites"); - return; - } spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aighost.cpp b/source/games/blood/src/aighost.cpp index d0fa239a1..5f9d77c89 100644 --- a/source/games/blood/src/aighost.cpp +++ b/source/games/blood/src/aighost.cpp @@ -65,6 +65,7 @@ void ghostSlashSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO *pDudeInfoT = getDudeInfo(pTarget->type); @@ -93,6 +94,7 @@ void ghostBlastSeqCallback(int, DBloodActor* actor) XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); wrand(); // ??? + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int height = (pSprite->yrepeat*getDudeInfo(pSprite->type)->eyeHeight) << 2; int dx = pXSprite->targetX-pSprite->x; @@ -344,11 +346,6 @@ static void ghostThinkChase(DBloodActor* actor) return; } DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - ///assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites"); - return; - } spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aigilbst.cpp b/source/games/blood/src/aigilbst.cpp index 24c9bc1d8..8bd7ebfb7 100644 --- a/source/games/blood/src/aigilbst.cpp +++ b/source/games/blood/src/aigilbst.cpp @@ -62,6 +62,7 @@ void GillBiteSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); @@ -128,7 +129,7 @@ static void gillThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -260,7 +261,7 @@ static void gillThinkSwimChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -345,6 +346,7 @@ static void sub_6CD74(DBloodActor* actor) auto pSprite = &actor->s(); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int z = pSprite->z + getDudeInfo(pSprite->type)->eyeHeight; int z2 = pTarget->z + getDudeInfo(pTarget->type)->eyeHeight; @@ -381,6 +383,7 @@ static void sub_6D03C(DBloodActor* actor) auto pSprite = &actor->s(); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; int z = pSprite->z + getDudeInfo(pSprite->type)->eyeHeight; int z2 = pTarget->z + getDudeInfo(pTarget->type)->eyeHeight; diff --git a/source/games/blood/src/aihand.cpp b/source/games/blood/src/aihand.cpp index 42e0eae14..10c4af8ba 100644 --- a/source/games/blood/src/aihand.cpp +++ b/source/games/blood/src/aihand.cpp @@ -46,6 +46,7 @@ void HandJumpSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; if (IsPlayerSprite(pTarget)) { @@ -93,7 +94,7 @@ static void handThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aihound.cpp b/source/games/blood/src/aihound.cpp index 4ec349ec4..ca827ec16 100644 --- a/source/games/blood/src/aihound.cpp +++ b/source/games/blood/src/aihound.cpp @@ -55,11 +55,7 @@ void houndBiteSeqCallback(int, DBloodActor* actor) return; } - ///assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites"); - return; - } + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; #ifdef NOONE_EXTENSIONS if (IsPlayerSprite(pTarget) || gModernMap) // allow to hit non-player targets @@ -120,11 +116,6 @@ static void houndThinkChase(DBloodActor* actor) return; } DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - ///assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites"); - return; - } spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aiinnoc.cpp b/source/games/blood/src/aiinnoc.cpp index 34c978f38..36db8f211 100644 --- a/source/games/blood/src/aiinnoc.cpp +++ b/source/games/blood/src/aiinnoc.cpp @@ -76,7 +76,7 @@ static void innocThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aipod.cpp b/source/games/blood/src/aipod.cpp index 5a6f5329e..3e17473c9 100644 --- a/source/games/blood/src/aipod.cpp +++ b/source/games/blood/src/aipod.cpp @@ -73,11 +73,7 @@ void podAttack(int, DBloodActor* actor) spritetype *pTarget = &sprite[pXSprite->target_i]; - ///assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); - if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) { - Printf(PRINT_HIGH, "pSprite->type >= kDudeBase && pSprite->type < kDudeMax"); - return; - } + if (!actor->ValidateTarget(__FUNCTION__)) return; DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); int x = pTarget->x-pSprite->x; int y = pTarget->y-pSprite->y; @@ -201,11 +197,6 @@ static void aiPodChase(DBloodActor* actor) return; } DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - ///assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites"); - return; - } spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/airat.cpp b/source/games/blood/src/airat.cpp index 9c5f4dddd..0f1687b4c 100644 --- a/source/games/blood/src/airat.cpp +++ b/source/games/blood/src/airat.cpp @@ -49,7 +49,7 @@ void ratBiteSeqCallback(int, DBloodActor* actor) int dx = CosScale16(pSprite->ang); int dy = SinScale16(pSprite->ang); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; if (IsPlayerSprite(pTarget)) actFireVector(actor, 0, 0, dx, dy, pTarget->z-pSprite->z, kVectorRatBite); @@ -90,7 +90,6 @@ static void ratThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aispid.cpp b/source/games/blood/src/aispid.cpp index 9ce72a8bf..e51d5aa78 100644 --- a/source/games/blood/src/aispid.cpp +++ b/source/games/blood/src/aispid.cpp @@ -73,7 +73,7 @@ void SpidBiteSeqCallback(int, DBloodActor* actor) dy += Random2(2000); int dz = Random2(2000); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; if (IsPlayerSprite(pTarget)) { @@ -122,7 +122,7 @@ void SpidJumpSeqCallback(int, DBloodActor* actor) dy += Random2(200); int dz = Random2(200); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; if (IsPlayerSprite(pTarget)) { dz += pTarget->z-pSprite->z; @@ -144,7 +144,7 @@ void SpidBirthSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; DUDEEXTRA_at6_u1 *pDudeExtraE = &actor->dudeExtra.at6.u1; int dx = pXSprite->targetX-pSprite->x; @@ -207,7 +207,6 @@ static void spidThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aitchern.cpp b/source/games/blood/src/aitchern.cpp index b9b87d3d7..482ce45b8 100644 --- a/source/games/blood/src/aitchern.cpp +++ b/source/games/blood/src/aitchern.cpp @@ -50,6 +50,7 @@ void sub_71A90(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int nTarget = pTarget->index; @@ -317,11 +318,7 @@ static void sub_72934(DBloodActor* actor) return; } DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - ///assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); - if (!(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites)) { - Printf(PRINT_HIGH, "pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites"); - return; - } + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aizomba.cpp b/source/games/blood/src/aizomba.cpp index b06bcd7d1..48b9c9d9b 100644 --- a/source/games/blood/src/aizomba.cpp +++ b/source/games/blood/src/aizomba.cpp @@ -63,6 +63,7 @@ void HackSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO *pDudeInfoT = getDudeInfo(pTarget->type); @@ -118,7 +119,7 @@ static void zombaThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; @@ -170,7 +171,7 @@ static void zombaThinkPonder(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/aizombf.cpp b/source/games/blood/src/aizombf.cpp index 1e5997e8f..268de4a8f 100644 --- a/source/games/blood/src/aizombf.cpp +++ b/source/games/blood/src/aizombf.cpp @@ -52,6 +52,7 @@ void zombfHackSeqCallback(int, DBloodActor* actor) spritetype* pSprite = &actor->s(); if (pSprite->type != kDudeZombieButcher) return; + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); int height = (pDudeInfo->eyeHeight*pSprite->yrepeat); @@ -64,6 +65,7 @@ void PukeSeqCallback(int, DBloodActor* actor) { XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); DUDEINFO *pDudeInfoT = getDudeInfo(pTarget->type); @@ -119,7 +121,7 @@ static void zombfThinkChase(DBloodActor* actor) } assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type); - assert(pXSprite->target_i >= 0 && pXSprite->target_i < kMaxSprites); + if (!actor->ValidateTarget(__FUNCTION__)) return; spritetype *pTarget = &sprite[pXSprite->target_i]; XSPRITE *pXTarget = &xsprite[pTarget->extra]; int dx = pTarget->x-pSprite->x; diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 8bc073a56..b363bb7aa 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -11,45 +11,45 @@ extern int cumulDamage[kMaxXSprites]; class DBloodActor { int index; - DBloodActor* base(); + DBloodActor* base(); public: - int dudeSlope; + int dudeSlope; DUDEEXTRA dudeExtra; - DBloodActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ } - DBloodActor& operator=(const DBloodActor& other) = default; - + DBloodActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ } + DBloodActor& operator=(const DBloodActor& other) = default; + void Clear() { dudeSlope = 0; dudeExtra = {}; } - bool hasX() { return sprite[index].extra > 0; } + bool hasX() { return sprite[index].extra > 0; } void addX() { if (s().extra == -1) dbInsertXSprite(s().index); } spritetype& s() { return sprite[index]; } XSPRITE& x() { return xsprite[sprite[index].extra]; } // calling this does not validate the xsprite! - SPRITEHIT& hit() { return gSpriteHit[sprite[index].extra]; } - int& xvel() { return Blood::xvel[index]; } - int& yvel() { return Blood::yvel[index]; } - int& zvel() { return Blood::zvel[index]; } + SPRITEHIT& hit() { return gSpriteHit[sprite[index].extra]; } + int& xvel() { return Blood::xvel[index]; } + int& yvel() { return Blood::yvel[index]; } + int& zvel() { return Blood::zvel[index]; } - int& cumulDamage() { return Blood::cumulDamage[sprite[index].extra]; } - SPRITEMASS& spriteMass() { return gSpriteMass[sprite[index].extra]; } - GENDUDEEXTRA& genDudeExtra() { return Blood::gGenDudeExtra[index]; } - POINT3D& basePoint() { return Blood::baseSprite[index]; } + int& cumulDamage() { return Blood::cumulDamage[sprite[index].extra]; } + SPRITEMASS& spriteMass() { return gSpriteMass[sprite[index].extra]; } + GENDUDEEXTRA& genDudeExtra() { return Blood::gGenDudeExtra[index]; } + POINT3D& basePoint() { return Blood::baseSprite[index]; } void SetOwner(DBloodActor* own) { - s().owner = own? own->s().index : -1; + s().owner = own ? own->s().index : -1; } DBloodActor* GetOwner() { - if (s().owner == -1 || s().owner == kMaxSprites-1) return nullptr; + if (s().owner == -1 || s().owner == kMaxSprites - 1) return nullptr; return base() + s().owner; } @@ -60,10 +60,20 @@ public: DBloodActor* GetTarget() { - if (x().target_i == -1 || x().target_i == kMaxSprites - 1) return nullptr; + if (x().target_i <= -1 || x().target_i == kMaxSprites - 1) return nullptr; return base() + x().target_i; } + bool ValidateTarget(const char* func) + { + if (GetTarget() == nullptr) + { + Printf(PRINT_HIGH | PRINT_NOTIFY, "%s: invalid target in calling actor\n", func); + return false; + } + return true; + } + void SetBurnSource(DBloodActor* own) { x().burnSource = own ? own->s().index : -1;