From 48073a2cd6c0c0e577af92d86ff2a4fcb11f63cd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Aug 2021 14:42:05 +0200 Subject: [PATCH] - sanitized the abuse of using XSPRITE's target field to pass along some info with explosions. This is neither safe nor future proof, so now it uses a separate variable. --- source/games/blood/src/actor.cpp | 5 +++-- source/games/blood/src/bloodactor.h | 4 +++- source/games/blood/src/callback.cpp | 4 +--- source/games/blood/src/loadsave.cpp | 3 ++- source/games/blood/src/nnexts.cpp | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index 33b54bc7e..56e181791 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -5633,6 +5633,7 @@ void actExplodeSprite(DBloodActor* actor) pSprite->type = nType; const EXPLOSION* pExplodeInfo = &explodeInfo[nType]; actor->SetTarget(nullptr); + actor->explosionhackflag = true; pXSprite->data1 = pExplodeInfo->ticks; pXSprite->data2 = pExplodeInfo->quakeEffect; pXSprite->data3 = pExplodeInfo->flashEffect; @@ -5976,9 +5977,9 @@ static void actCheckExplosion() { if (pXSprite->data1 && CheckProximity(pDude, x, y, z, nSector, radius)) { - if (pExplodeInfo->dmg && pXSprite->target_i == 0) + if (pExplodeInfo->dmg && actor->explosionhackflag) { - pXSprite->target_i = 1; + actor->explosionhackflag = false; actDamageSprite(Owner, dudeactor, kDamageFall, (pExplodeInfo->dmg + Random(pExplodeInfo->dmgRng)) << 4); } if (pExplodeInfo->dmgType) ConcussSprite(actor, dudeactor, x, y, z, pExplodeInfo->dmgType); diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 2b0585628..010e2817a 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -97,13 +97,15 @@ public: SPRITEMASS spriteMass; GENDUDEEXTRA genDudeExtra; - int cumulDamage; + int cumulDamage; // this one's transient and does not need to be saved. + bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers. DBloodActor() :index(int(this - base())) { /*assert(index >= 0 && index < kMaxSprites);*/ } DBloodActor& operator=(const DBloodActor& other) = default; void Clear() { + explosionhackflag = false; dudeSlope = 0; dudeExtra = {}; spriteMass = {}; diff --git a/source/games/blood/src/callback.cpp b/source/games/blood/src/callback.cpp index 7cbacbab0..5410c193e 100644 --- a/source/games/blood/src/callback.cpp +++ b/source/games/blood/src/callback.cpp @@ -385,9 +385,7 @@ void FinishHim(DBloodActor* actor, int) // 13 { if (!actor) return; spritetype* pSprite = &actor->s(); - int nXSprite = pSprite->extra; - XSPRITE* pXSprite = &actor->x(); - if (IsPlayerSprite(pSprite) && playerSeqPlaying(&gPlayer[pSprite->type - kDudePlayer1], 16) && pXSprite->target_i == gMe->nSprite) + if (actor->IsPlayerActor() && playerSeqPlaying(&gPlayer[pSprite->type - kDudePlayer1], 16) && actor == gMe->actor()) sndStartSample(3313, -1, 1, 0); } diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 269b40220..0274a2d65 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -482,7 +482,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor& w, DB if (w.hasX()) { arc("dudeslope", w.dudeSlope, def->dudeSlope) - ("dudeextra", w.dudeExtra, def->dudeExtra); + ("dudeextra", w.dudeExtra, def->dudeExtra) + ("explosionflag", w.explosionhackflag, def->explosionhackflag); if (gModernMap) { diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 077523dfe..7d24d681e 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -6995,7 +6995,7 @@ void useTargetChanger(DBloodActor* sourceactor, DBloodActor* actor) if (aiFightDudeCanSeeTarget(actor, pDudeInfo, pMateTargetActor)) { - if (pXMateTarget->target_i < 0) + if (pMateTargetActor->GetTarget() == nullptr) { aiSetTarget(pMateTargetActor, actor); if (pMateTargetActor->IsDudeActor() && !isActive(pMateTargetActor))