diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index 882c24f13..3932be1fb 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -27,10 +27,16 @@ BEGIN_PS_NS // anims +enum +{ + kAnimFlag1 = (1 << 2), + kAnimLoop = (1 << 4) +}; + void InitAnims(); void DestroyAnim(DExhumedActor* nAnim); DExhumedActor* BuildAnim(DExhumedActor* actor, int val, int val2, const DVector3& pos, sectortype* pSector, double nScale, int nFlag); - +void UnlinkIgnitedAnim(DExhumedActor* pActor); void FuncAnim(int, int, int, int); void BuildExplosion(DExhumedActor* actor); void BuildSplash(DExhumedActor* actor, sectortype* pSector); diff --git a/source/games/exhumed/src/anims.cpp b/source/games/exhumed/src/anims.cpp index bba736b96..c7ad69a39 100644 --- a/source/games/exhumed/src/anims.cpp +++ b/source/games/exhumed/src/anims.cpp @@ -54,6 +54,36 @@ void InitAnims() nSavePointSeq = SeqOffsets[kSeqItems] + 12; } +/* + Use when deleting an ignited sprite to check if any anims reference it. + Will remove the Anim's loop flag and set the source (the ignited sprite's) sprite reference to -1. + FuncAnim() will then delete the anim on next call for this anim. + + Without this, the anim will hold reference to a sprite which will eventually be reused, but the anim code + will continue to manipulate its hitag value. This can break runlist records for things like LavaDude + limbs that store these in the sprite hitag. + + Specifically needed for IgniteSprite() anims which can become orphaned from the source sprite (e.g a bullet) + when the bullet sprite is deleted. +*/ +void UnlinkIgnitedAnim(DExhumedActor* pActor) +{ + // scan the active anims (that aren't in the 'free' section of AnimsFree[]) + ExhumedStatIterator it(500); + while (auto itActor = it.Next()) + { + if (itActor->spr.statnum == kStatIgnited) + { + // .hitag holds the sprite number of the source 'sprite that's on fire' sprite + if (pActor == itActor->pTarget) + { + itActor->nAction &= ~kAnimLoop; // clear the animation loop flag + itActor->pTarget = nullptr; // set the sprite reference to -1 + } + } + } +} + void DestroyAnim(DExhumedActor* pActor) { if (pActor) diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index 5446915f9..4d1c753ce 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "ns.h" #include "engine.h" #include "exhumed.h" +#include "aistuff.h" #include "sequence.h" #include "names.h" #include "player.h" @@ -603,6 +604,7 @@ void DeleteActor(DExhumedActor* actor) bestTarget = nullptr; } + UnlinkIgnitedAnim(actor); actor->Destroy(); }