From e543c704392dc6b231d8f3fe9080fb2ec3af77f8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 3 Dec 2021 21:36:32 +0100 Subject: [PATCH] - replacement of BloodLinearSpriteIterator Preparation for eliminating sprite[]. This array can later be created by the actual spawn function. --- source/core/coreactor.h | 11 +++++++++++ source/games/blood/src/actor.cpp | 4 ++-- source/games/blood/src/actor.h | 2 +- source/games/blood/src/blood.cpp | 29 +++++++++++++++++++++-------- source/games/blood/src/eventq.cpp | 13 ++++++------- source/games/blood/src/eventq.h | 2 +- source/games/blood/src/misc.h | 2 +- source/games/blood/src/nnexts.cpp | 12 +++++------- source/games/blood/src/nnexts.h | 2 +- source/games/blood/src/triggers.cpp | 16 ++++++---------- source/games/blood/src/triggers.h | 2 +- source/games/blood/src/warp.cpp | 8 +++++--- 12 files changed, 61 insertions(+), 42 deletions(-) diff --git a/source/core/coreactor.h b/source/core/coreactor.h index 37826d7dd..756d956c9 100644 --- a/source/core/coreactor.h +++ b/source/core/coreactor.h @@ -12,6 +12,11 @@ protected: public: + bool exists() const + { + return (unsigned)s().statnum < MAXSTATUS; + } + spritetype& s() const { return sprite[index]; @@ -263,6 +268,12 @@ public: } return nullptr; } + + void Reset() + { + stat = 0; + it.Reset(0); + } }; // For iterating linearly over map spawned sprites. Will later only be valid on map load diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index cd3726215..810e9ec92 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -2517,11 +2517,11 @@ static void actInitDudes() // //--------------------------------------------------------------------------- -void actInit() +void actInit(TArray& actors) { #ifdef NOONE_EXTENSIONS if (!gModernMap) nnExtResetGlobals(); - else nnExtInitModernStuff(); + else nnExtInitModernStuff(actors); #endif BloodStatIterator it(kStatItem); diff --git a/source/games/blood/src/actor.h b/source/games/blood/src/actor.h index 534ed6095..39d7c4eab 100644 --- a/source/games/blood/src/actor.h +++ b/source/games/blood/src/actor.h @@ -209,7 +209,7 @@ void sub_3888C(int, int); void TreeToGibCallback(int, int); bool IsUnderwaterSector(sectortype* pSector); -void actInit(); +void actInit(TArray& actors); int actWallBounceVector(int *x, int *y, walltype* pWall, int a4); int actFloorBounceVector(int *x, int *y, int *z, sectortype* pSector, int a5); void actRadiusDamage(DBloodActor* source, int x, int y, int z, sectortype* pSector, int nDist, int a7, int a8, DAMAGE_TYPE a9, int a10, int a11); diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index 218809613..46d28019d 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -119,12 +119,25 @@ void StartLevel(MapRecord* level, bool newgame) gSecretMgr.Clear(); automapping = 1; - int modernTypesErased = 0; - BloodLinearSpriteIterator it; - while (auto actor = it.Next()) + + // Here is where later the actors must be spawned. + + // get a sorted list of all actors as we need to run some init code in spawn order. (iterating bloodActors would actually do, but that won't last forever) + TArray actorlist; + BloodSpriteIterator sit; + while (auto act = sit.Next()) { + actorlist.Push(act); + } + std::sort(actorlist.begin(), actorlist.end(), [](DBloodActor* a, DBloodActor* b) { return a->GetIndex() < b->GetIndex(); }); + + + int modernTypesErased = 0; + for(unsigned i = 0; i < actorlist.Size(); i++) + { + auto actor = actorlist[i]; spritetype* pSprite = &actor->s(); - if (pSprite->statnum < kMaxStatus && actor->hasX()) + if (actor->exists() && actor->hasX()) { XSPRITE* pXSprite = &actor->x(); @@ -175,9 +188,9 @@ void StartLevel(MapRecord* level, bool newgame) #endif } InitSectorFX(); - warpInit(); - actInit(); - evInit(); + warpInit(actorlist); + actInit(actorlist); + evInit(actorlist); for (int i = connecthead; i >= 0; i = connectpoint2[i]) { if (newgame) @@ -207,7 +220,7 @@ void StartLevel(MapRecord* level, bool newgame) } PreloadCache(); InitMirrors(); - trInit(); + trInit(actorlist); if (!gMe->packSlots[1].isActive) // if diving suit is not active, turn off reverb sound effect sfxSetReverb(0); ambInit(); diff --git a/source/games/blood/src/eventq.cpp b/source/games/blood/src/eventq.cpp index 09fb30814..0d2faa294 100644 --- a/source/games/blood/src/eventq.cpp +++ b/source/games/blood/src/eventq.cpp @@ -272,7 +272,7 @@ static void createBucketHeads() // //--------------------------------------------------------------------------- -void evInit() +void evInit(TArray& actors) { int nCount = 0; @@ -300,16 +300,15 @@ void evInit() } } - BloodLinearSpriteIterator it; - while (auto actor = it.Next()) + for (auto actor : actors) { - if (actor->hasX() && actor->x().rxID > 0) + if (actor->exists() && actor->hasX() && actor->x().rxID > 0) { - assert(nCount < kChannelMax); + assert(nCount < kChannelMax); rxBucket[nCount] = EventObject(actor); - nCount++; - } + nCount++; } + } SortRXBucket(nCount); bucketCount = nCount; createBucketHeads(); diff --git a/source/games/blood/src/eventq.h b/source/games/blood/src/eventq.h index 537ede51d..51a6130b6 100644 --- a/source/games/blood/src/eventq.h +++ b/source/games/blood/src/eventq.h @@ -239,7 +239,7 @@ struct EVENT } }; -void evInit(void); +void evInit(TArray& actors); void evPostActor(DBloodActor*, unsigned int nDelta, COMMAND_ID command); void evPostActor(DBloodActor*, unsigned int nDelta, CALLBACK_ID callback); diff --git a/source/games/blood/src/misc.h b/source/games/blood/src/misc.h index 6f0c9de4b..3f46746a8 100644 --- a/source/games/blood/src/misc.h +++ b/source/games/blood/src/misc.h @@ -65,7 +65,7 @@ struct ZONE { }; extern ZONE gStartZone[8]; -void warpInit(void); +void warpInit(TArray& actors); int CheckLink(DBloodActor *pSprite); int CheckLink(int *x, int *y, int *z, sectortype** pSector); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 677444d7d..002fb69b6 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -516,7 +516,7 @@ void nnExtResetGlobals() // //--------------------------------------------------------------------------- -void nnExtInitModernStuff() +void nnExtInitModernStuff(TArray& actors) { nnExtResetGlobals(); @@ -536,10 +536,9 @@ void nnExtInitModernStuff() } } - BloodLinearSpriteIterator it; - while (auto actor = it.Next()) + for (auto actor : actors) { - if (!actor->hasX()) continue; + if (!actor->exists() || !actor->hasX()) continue; XSPRITE* pXSprite = &actor->x(); spritetype* pSprite = &actor->s(); @@ -816,10 +815,9 @@ void nnExtInitModernStuff() int count = 0; TRCONDITION* pCond = &gCondition[gTrackingCondsCount]; - BloodLinearSpriteIterator it; - while (auto iactor2 = it.Next()) + for (auto iactor2 : actors) { - if (!iactor2->hasX() || iactor2->x().txID != pXSprite->rxID || iactor2 == iactor) + if (!iactor->exists() || !iactor2->hasX() || iactor2->x().txID != pXSprite->rxID || iactor2 == iactor) continue; XSPRITE* pXSpr = &iactor2->x(); diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index dabd874d3..c22ac5fea 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -287,7 +287,7 @@ extern AISTATE genPatrolStates[kPatrolStateSize]; // - FUNCTIONS ------------------------------------------------------------------ bool nnExtEraseModernStuff(DBloodActor* actor); -void nnExtInitModernStuff(); +void nnExtInitModernStuff(TArray& actors); void nnExtProcessSuperSprites(void); bool nnExtIsImmune(DBloodActor* pSprite, int dmgType, int minScale = 16); int nnExtRandom(int a, int b); diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index fb129bf49..aca907a62 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -1967,7 +1967,7 @@ void trProcessBusy(void) void InitGenerator(DBloodActor*); -void trInit(void) +void trInit(TArray& actors) { gBusy.Clear(); for(auto& wal : walls()) @@ -1976,15 +1976,12 @@ void trInit(void) wal.baseWall.x = wal.x; wal.baseWall.y = wal.y; } - BloodLinearSpriteIterator it; - while (auto actor = it.Next()) + for(auto actor : actors) { + if (!actor->exists()) continue; auto spr = &actor->s(); - if (spr->statnum < kStatFree) - { - spr->inittype = spr->type; - actor->basePoint = spr->pos; - } + spr->inittype = spr->type; + actor->basePoint = spr->pos; } for(auto& wal : walls()) { @@ -2069,8 +2066,7 @@ void trInit(void) } } - it.Reset(); - while (auto actor = it.Next()) + for (auto actor : actors) { auto pSprite = &actor->s(); if (pSprite->statnum < kStatFree && actor->hasX()) diff --git a/source/games/blood/src/triggers.h b/source/games/blood/src/triggers.h index dcb5c3ec3..bd6ea7273 100644 --- a/source/games/blood/src/triggers.h +++ b/source/games/blood/src/triggers.h @@ -58,7 +58,7 @@ void trMessageWall(walltype* pWall, const EVENT& event); void trTriggerSprite(DBloodActor* actor, int command); void trMessageSprite(DBloodActor* actor, EVENT event); void trProcessBusy(void); -void trInit(void); +void trInit(TArray& actors); void trTextOver(int nId); bool SetSpriteState(DBloodActor* actor, int nState); bool SetWallState(walltype* pWall, int nState); diff --git a/source/games/blood/src/warp.cpp b/source/games/blood/src/warp.cpp index 4f3f7bcb2..65811b239 100644 --- a/source/games/blood/src/warp.cpp +++ b/source/games/blood/src/warp.cpp @@ -55,14 +55,16 @@ void validateLinks() } } -void warpInit(void) + +void warpInit(TArray& actors) { #ifdef NOONE_EXTENSIONS int team1 = 0; int team2 = 0; gTeamsSpawnUsed = false; // increment if team start positions specified. #endif - BloodLinearSpriteIterator it; - while (auto actor = it.Next()) + + for(auto actor : actors) { + if (!actor->exists()) continue; spritetype* pSprite = &actor->s(); if (actor->hasX()) { XSPRITE *pXSprite = &actor->x();