diff --git a/source/blood/src/actor.cpp b/source/blood/src/actor.cpp index 118111cbb..000fcbfc9 100644 --- a/source/blood/src/actor.cpp +++ b/source/blood/src/actor.cpp @@ -5471,7 +5471,7 @@ void actProcessSprites(void) StatIterator it1(kStatDude); while ((nSprite2 = it1.NextIndex()) >= 0) { - nNextSprite = nextspritestat[nSprite2]; + nNextSprite = it1.PeekIndex(); spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite2->flags&32) continue; @@ -5936,7 +5936,7 @@ void actProcessSprites(void) StatIterator it1(kStatDude); while ((nSprite2 = it1.NextIndex()) >= 0) { - nNextSprite = nextspritestat[nSprite2]; + nNextSprite = it1.PeekIndex(); spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite2->flags&32) diff --git a/source/blood/src/ai.cpp b/source/blood/src/ai.cpp index 6943c70bd..4e4277cd4 100644 --- a/source/blood/src/ai.cpp +++ b/source/blood/src/ai.cpp @@ -1418,7 +1418,10 @@ void sub_5F15C(spritetype *pSprite, XSPRITE *pXSprite) gAffectedSectors[0] = 0; gAffectedXWalls[0] = 0; GetClosestSpriteSectors(pSprite->sectnum, pSprite->x, pSprite->y, 400, gAffectedSectors, va4, gAffectedXWalls); - for (int nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; int dx = pSprite2->x-pSprite->x; @@ -1439,7 +1442,10 @@ void sub_5F15C(spritetype *pSprite, XSPRITE *pXSprite) } void aiProcessDudes(void) { - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { spritetype *pSprite = &sprite[nSprite]; if (pSprite->flags & 32) continue; int nXSprite = pSprite->extra; @@ -1491,7 +1497,9 @@ void aiProcessDudes(void) { void aiInit(void) { - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) { aiInitSprite(&sprite[nSprite]); } diff --git a/source/blood/src/aibeast.cpp b/source/blood/src/aibeast.cpp index aa995db52..180148be6 100644 --- a/source/blood/src/aibeast.cpp +++ b/source/blood/src/aibeast.cpp @@ -125,7 +125,9 @@ static void StompSeqCallback(int, int nXSprite) v4 = 0; } vc <<= 4; - for (int nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it1(kStatDude); + while ((nSprite2 = it1.NextIndex()) >= 0) { if (nSprite != nSprite2 || v4) { @@ -161,7 +163,8 @@ static void StompSeqCallback(int, int nXSprite) } } } - for (int nSprite2 = headspritestat[kStatThing]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + it1.Reset(kStatThing); + while ((nSprite2 = it1.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite2->flags&32) diff --git a/source/blood/src/aicerber.cpp b/source/blood/src/aicerber.cpp index 38736fb0d..99394d1f3 100644 --- a/source/blood/src/aicerber.cpp +++ b/source/blood/src/aicerber.cpp @@ -118,7 +118,9 @@ static void cerberusBurnSeqCallback(int, int nXSprite) aim.dy = SinScale16(pSprite->ang); aim.dz = gDudeSlope[nXSprite]; int nClosest = 0x7fffffff; - for (short nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite == pSprite2 || !(pSprite2->flags&8)) @@ -202,7 +204,9 @@ static void cerberusBurnSeqCallback2(int, int nXSprite) aim.dz = gDudeSlope[nXSprite]; az = 0; int nClosest = 0x7fffffff; - for (short nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite == pSprite2 || !(pSprite2->flags&8)) diff --git a/source/blood/src/aigarg.cpp b/source/blood/src/aigarg.cpp index 08a8d42aa..e30693a33 100644 --- a/source/blood/src/aigarg.cpp +++ b/source/blood/src/aigarg.cpp @@ -147,7 +147,9 @@ static void BlastSSeqCallback(int, int nXSprite) aim.dy = SinScale16(pSprite->ang); aim.dz = gDudeSlope[nXSprite]; int nClosest = 0x7fffffff; - for (short nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite == pSprite2 || !(pSprite2->flags&8)) diff --git a/source/blood/src/aighost.cpp b/source/blood/src/aighost.cpp index 6530f0976..7b1d4f96c 100644 --- a/source/blood/src/aighost.cpp +++ b/source/blood/src/aighost.cpp @@ -130,7 +130,9 @@ static void ghostBlastSeqCallback(int, int nXSprite) aim.dy = SinScale16(pSprite->ang); aim.dz = gDudeSlope[nXSprite]; int nClosest = 0x7fffffff; - for (short nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite == pSprite2 || !(pSprite2->flags&8)) diff --git a/source/blood/src/aitchern.cpp b/source/blood/src/aitchern.cpp index 7bfd95717..f9a8d7359 100644 --- a/source/blood/src/aitchern.cpp +++ b/source/blood/src/aitchern.cpp @@ -102,7 +102,9 @@ static void sub_71BD4(int, int nXSprite) aim.dy = SinScale16(pSprite->ang); aim.dz = gDudeSlope[nXSprite]; int nClosest = 0x7fffffff; - for (short nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite == pSprite2 || !(pSprite2->flags&8)) @@ -180,7 +182,9 @@ static void sub_720AC(int, int nXSprite) aim.dz = gDudeSlope[nXSprite]; int nClosest = 0x7fffffff; az = 0; - for (short nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nextspritestat[nSprite2]) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { spritetype *pSprite2 = &sprite[nSprite2]; if (pSprite == pSprite2 || !(pSprite2->flags&8)) diff --git a/source/blood/src/aiunicult.cpp b/source/blood/src/aiunicult.cpp index eacf8df42..735649d73 100644 --- a/source/blood/src/aiunicult.cpp +++ b/source/blood/src/aiunicult.cpp @@ -1194,7 +1194,10 @@ spritetype* leechIsDropped(spritetype* pSprite) { } void removeDudeStuff(spritetype* pSprite) { - for (short nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatThing); + while ((nSprite = it.NextIndex()) >= 0) + { if (sprite[nSprite].owner != pSprite->index) continue; switch (sprite[nSprite].type) { case kThingArmedProxBomb: @@ -1209,7 +1212,9 @@ void removeDudeStuff(spritetype* pSprite) { } } - for (short nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + it.Reset(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { if (sprite[nSprite].owner != pSprite->index) continue; actDamageSprite(sprite[nSprite].owner, &sprite[nSprite], (DAMAGE_TYPE) 0, 65535); } @@ -2126,7 +2131,10 @@ bool genDudePrepare(spritetype* pSprite, int propId) { case kGenDudePropertyLeech: pExtra->nLifeLeech = -1; if (pSprite->owner != kMaxSprites - 1) { - for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatThing); + while ((nSprite = it.NextIndex()) >= 0) + { if (sprite[nSprite].owner == pSprite->index && sprite[nSprite].type == kModernThingEnemyLifeLeech) { pExtra->nLifeLeech = nSprite; break; @@ -2137,8 +2145,12 @@ bool genDudePrepare(spritetype* pSprite, int propId) { fallthrough__; case kGenDudePropertySlaves: + { pExtra->slaveCount = 0; memset(pExtra->slave, -1, sizeof(pExtra->slave)); - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { if (sprite[nSprite].owner != pSprite->index) continue; else if (!IsDudeSprite(&sprite[nSprite]) || !xspriRangeIsFine(sprite[nSprite].extra) || xsprite[sprite[nSprite].extra].health <= 0) { sprite[nSprite].owner = -1; @@ -2151,7 +2163,7 @@ bool genDudePrepare(spritetype* pSprite, int propId) { } if (propId) break; fallthrough__; - + } case kGenDudePropertySpriteSize: { if (seqGetStatus(3, pSprite->extra) == -1) seqSpawn(pXSprite->data2 + pXSprite->aiState->seqId, 3, pSprite->extra, -1); diff --git a/source/blood/src/asound.cpp b/source/blood/src/asound.cpp index 6813b0e0f..81e29b1ce 100644 --- a/source/blood/src/asound.cpp +++ b/source/blood/src/asound.cpp @@ -52,7 +52,9 @@ void ambProcess(void) { if (!SoundEnabled()) return; - for (int nSprite = headspritestat[kStatAmbience]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatAmbience); + while ((nSprite = it.NextIndex()) >= 0) { spritetype *pSprite = &sprite[nSprite]; if (pSprite->owner < 0 || pSprite->owner >= kMaxAmbChannel) @@ -114,7 +116,10 @@ void ambInit(void) { ambKillAll(); memset(ambChannels, 0, sizeof(ambChannels)); - for (int nSprite = headspritestat[kStatAmbience]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatAmbience); + while ((nSprite = it.NextIndex()) >= 0) + { if (sprite[nSprite].extra <= 0 || sprite[nSprite].extra >= kMaxXSprites) continue; XSPRITE *pXSprite = &xsprite[sprite[nSprite].extra]; diff --git a/source/blood/src/callback.cpp b/source/blood/src/callback.cpp index 18e7d5a19..f4e6ef445 100644 --- a/source/blood/src/callback.cpp +++ b/source/blood/src/callback.cpp @@ -639,10 +639,11 @@ void DropVoodooCb(int nSprite) // unused evPost(nSprite, 3, 0, kCallbackRemove); return; } - int nSprite2, nNextSprite; - for (nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nNextSprite) + int nSprite2; + StatIterator it(kStatDude); + while ((nSprite2 = it.NextIndex()) >= 0) { - nNextSprite = nextspritestat[nSprite2]; + int nNextSprite = it.PeekIndex(); if (nOwner == nSprite2) continue; spritetype *pSprite2 = &sprite[nSprite2]; diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index 5fcf556ec..15f9c7a71 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -219,7 +219,9 @@ void CKillMgr::AddKill(spritetype* pSprite) void CKillMgr::CountTotalKills(void) { TotalKills = 0; - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) { spritetype* pSprite = &sprite[nSprite]; if (pSprite->type < kDudeBase || pSprite->type >= kDudeMax) diff --git a/source/blood/src/eventq.cpp b/source/blood/src/eventq.cpp index 086a565ad..95c1951f7 100644 --- a/source/blood/src/eventq.cpp +++ b/source/blood/src/eventq.cpp @@ -405,7 +405,10 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command) case kChannelRemoteBomb5: case kChannelRemoteBomb6: case kChannelRemoteBomb7: - for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + { + int nSprite; + StatIterator it(kStatThing); + while ((nSprite = it.NextIndex()) >= 0) { spritetype* pSprite = &sprite[nSprite]; if (pSprite->flags & 32) @@ -419,9 +422,13 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command) } } return; + } case kChannelTeamAFlagCaptured: case kChannelTeamBFlagCaptured: - for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + { + int nSprite; + StatIterator it(kStatItem); + while ((nSprite = it.NextIndex()) >= 0) { spritetype* pSprite = &sprite[nSprite]; if (pSprite->flags & 32) @@ -435,6 +442,7 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command) } } return; + } default: break; } diff --git a/source/blood/src/fx.cpp b/source/blood/src/fx.cpp index 00220fe09..7ff522439 100644 --- a/source/blood/src/fx.cpp +++ b/source/blood/src/fx.cpp @@ -168,9 +168,10 @@ spritetype * CFX::fxSpawn(FX_ID nFx, int nSector, int x, int y, int z, unsigned FXDATA *pFX = &gFXData[nFx]; if (gStatCount[1] == 512) { - int nSprite = headspritestat[kStatFX];; - while ((sprite[nSprite].flags & 32) && nSprite != -1) - nSprite = nextspritestat[nSprite]; + StatIterator it(kStatFX); + int nSprite = it.NextIndex(); + while (nSprite != -1 && (sprite[nSprite].flags & 32)) + nSprite = it.NextIndex(); if (nSprite == -1) return NULL; sub_73FB0(nSprite); @@ -204,7 +205,9 @@ spritetype * CFX::fxSpawn(FX_ID nFx, int nSector, int x, int y, int z, unsigned void CFX::fxProcess(void) { - for (int nSprite = headspritestat[kStatFX]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatFX); + while ((nSprite = it.NextIndex()) >= 0) { spritetype *pSprite = &sprite[nSprite]; viewBackupSpriteLoc(nSprite, pSprite); diff --git a/source/blood/src/nnexts.cpp b/source/blood/src/nnexts.cpp index eb04eff56..9a44742f7 100644 --- a/source/blood/src/nnexts.cpp +++ b/source/blood/src/nnexts.cpp @@ -389,16 +389,20 @@ void nnExtInitModernStuff(bool bSaveLoad) { pXSprite->Proximity = true; break; case kDudeModernCustom: + { if (pXSprite->txID <= 0) break; - for (int nSprite = headspritestat[kStatDude], found = 0; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite, found = 0; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { XSPRITE* pXSpr = &xsprite[sprite[nSprite].extra]; if (pXSpr->rxID != pXSprite->txID) continue; else if (found) I_Error("\nCustom dude (TX ID %d):\nOnly one incarnation allowed per channel!", pXSprite->txID); changespritestat(nSprite, kStatInactive); - nSprite = headspritestat[kStatDude]; found++; } break; + } case kDudePodMother: case kDudeTentacleMother: pXSprite->state = 1; @@ -406,9 +410,10 @@ void nnExtInitModernStuff(bool bSaveLoad) { case kModernPlayerControl: switch (pXSprite->command) { case kCmdLink: + { if (pXSprite->data1 < 1 || pXSprite->data1 >= kMaxPlayers) I_Error("\nPlayer Control (SPRITE #%d):\nPlayer out of a range (data1 = %d)", pSprite->index, pXSprite->data1); - + //if (numplayers < pXSprite->data1) //I_Error("\nPlayer Control (SPRITE #%d):\n There is no player #%d", pSprite->index, pXSprite->data1); @@ -419,7 +424,10 @@ void nnExtInitModernStuff(bool bSaveLoad) { I_Error("\nPlayer Control (SPRITE #%d):\nTX ID should be in range of %d and %d!", pSprite->index, kChannelUser, kChannelMax); // only one linker per player allowed - for (int nSprite = headspritestat[kStatModernPlayerLinker]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatModernPlayerLinker); + while ((nSprite = it.NextIndex()) >= 0) + { XSPRITE* pXCtrl = &xsprite[sprite[nSprite].extra]; if (pXSprite->data1 == pXCtrl->data1) I_Error("\nPlayer Control (SPRITE #%d):\nPlayer %d already linked with different player control sprite #%d!", pSprite->index, pXSprite->data1, nSprite); @@ -428,6 +436,7 @@ void nnExtInitModernStuff(bool bSaveLoad) { pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; changespritestat(pSprite->index, kStatModernPlayerLinker); break; + } case 67: // play qav animation if (pXSprite->txID && !pXSprite->waitTime) pXSprite->waitTime = 1; changespritestat(pSprite->index, kStatModernQavScene); @@ -532,18 +541,19 @@ void nnExtInitModernStuff(bool bSaveLoad) { } } + int i; if (!bSaveLoad) { // let's try to find "else" and "else if" of conditions here spritetype* pCond = NULL; XSPRITE* pXCond = NULL; bool found = false; int rx = 0; int sum1 = 0; int sum2 = 0; - for (int i = headspritestat[kStatModernCondition]; i >= 0;) { + for (i = StatIterator::First(kStatModernCondition); i >= 0;) { pCond = &sprite[i]; pXCond = &xsprite[pCond->extra]; sum1 = pXCond->locked + pXCond->busyTime + pXCond->waitTime + pXCond->data1; if (!found) rx = pXCond->rxID; - for (int a = i; a >= 0; a = nextspritestat[a], found = false) { + for (int a = i; a >= 0; a = StatIterator::NextFor(a), found = false) { spritetype* pCond2 = &sprite[a]; XSPRITE* pXCond2 = &xsprite[pCond2->extra]; sum2 = pXCond2->locked + pXCond2->busyTime + pXCond2->waitTime + pXCond2->data1; @@ -558,13 +568,15 @@ void nnExtInitModernStuff(bool bSaveLoad) { } - if (!found) i = nextspritestat[i]; + if (!found) i = StatIterator::NextFor(i); } } // collect objects for tracking conditions - for (int i = headspritestat[kStatModernCondition]; i >= 0; i = nextspritestat[i]) { + StatIterator it(kStatModernCondition); + while ((i = it.NextIndex()) >= 0) + { spritetype* pSprite = &sprite[i]; XSPRITE* pXSprite = &xsprite[pSprite->extra]; if (pXSprite->busyTime <= 0) continue; @@ -791,8 +803,10 @@ void nnExtProcessSuperSprites() { if (!pXProxSpr->DudeLockout) { - for (int nAffected = headspritestat[kStatDude]; nAffected >= 0; nAffected = nextspritestat[nAffected]) { - + int nAffected; + StatIterator it(kStatDude); + while ((nAffected = it.NextIndex()) >= 0) + { if ((sprite[nAffected].flags & 32) || xsprite[sprite[nAffected].extra].health <= 0) continue; else if (CheckProximity(&sprite[nAffected], x, y, z, sectnum, 96)) { trTriggerSprite(index, pXProxSpr, kCmdSpriteProximity); @@ -2834,16 +2848,6 @@ bool condCheckWall(XSPRITE* pXCond, int cmpOp, bool PUSH) { if (!sectRangeIsFine(var = sectorofwall(pWall->nextwall))) return false; else if (PUSH) condPush(pXCond, OBJ_SECTOR, var); return true; - /*case 57: // someone touching this wall? - for (int i = headspritestat[kStatDude]; i >= 0; i = nextspritestat[i]) { - if (!xspriRangeIsFine(sprite[i].extra) || (gSpriteHit[sprite[i].extra].hit & 0xc000) != 0x8000) continue; - else if ((gSpriteHit[sprite[i].extra].hit & 0x3fff) != objIndex) continue; - else if (PUSH) { - condPush(pXCond, OBJ_SPRITE, i); - return true; - } - } - return false;*/ } } @@ -3103,7 +3107,10 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { } return retn; case 45: // this sprite is a target of some dude? - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { if (pSpr->index == nSprite) continue; spritetype* pDude = &sprite[nSprite]; @@ -3160,17 +3167,22 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) { else if (PUSH && spriRangeIsFine(pXSpr->burnSource)) condPush(pXCond, OBJ_SPRITE, pXSpr->burnSource); return true; case 66: // any flares stuck in this sprite? - for (int nSprite = headspritestat[kStatFlare]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + { + int nSprite; + StatIterator it(kStatFlare); + while ((nSprite = it.NextIndex()) >= 0) + { spritetype* pFlare = &sprite[nSprite]; if (!xspriRangeIsFine(pFlare->extra) || (pFlare->flags & kHitagFree)) continue; - + XSPRITE* pXFlare = &xsprite[pFlare->extra]; if (!spriRangeIsFine(pXFlare->target) || pXFlare->target != objIndex) continue; else if (PUSH) condPush(pXCond, OBJ_SPRITE, nSprite); return true; } return false; + } case 70: return condCmp(getSpriteMassBySize(pSpr), arg1, arg2, cmpOp); // mass of the sprite in a range? } @@ -3207,8 +3219,10 @@ void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) { int newSerial = condSerialize(objType, newIndex); // then update serials - for (int nSpr = headspritestat[kStatModernCondition]; nSpr >= 0; nSpr = nextspritestat[nSpr]) { - + int nSpr; + StatIterator it(kStatModernCondition); + while ((nSpr = it.NextIndex()) >= 0) + { XSPRITE* pXCond = &xsprite[sprite[nSpr].extra]; if (pXCond->targetX == oldSerial) pXCond->targetX = newSerial; if (pXCond->targetY == oldSerial) pXCond->targetY = newSerial; @@ -3383,7 +3397,10 @@ void modernTypeTrigger(int destObjType, int destObjIndex, EVENT event) { spritetype* aiFightGetTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode) { DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); XSPRITE* pXSprite = &xsprite[pSprite->extra]; spritetype* pTarget = NULL; XSPRITE* pXTarget = NULL; spritetype* cTarget = NULL; - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { pTarget = &sprite[nSprite]; pXTarget = &xsprite[pTarget->extra]; if (!aiFightDudeCanSeeTarget(pXSprite, pDudeInfo, pTarget)) continue; @@ -3498,7 +3515,10 @@ void aiFightActivateDudes(int rx) { // this function sets target to -1 for all dudes that hunting for nSprite void aiFightFreeTargets(int nSprite) { - for (int nTarget = headspritestat[kStatDude]; nTarget >= 0; nTarget = nextspritestat[nTarget]) { + int nTarget; + StatIterator it(kStatDude); + while ((nTarget = it.NextIndex()) >= 0) + { if (!IsDudeSprite(&sprite[nTarget]) || sprite[nTarget].extra < 0) continue; else if (xsprite[sprite[nTarget].extra].target == nSprite) aiSetTarget(&xsprite[sprite[nTarget].extra], sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z); @@ -3521,7 +3541,10 @@ void aiFightFreeAllTargets(XSPRITE* pXSource) { bool aiFightDudeIsAffected(XSPRITE* pXDude) { if (pXDude->rxID <= 0 || pXDude->locked == 1) return false; - for (int nSprite = headspritestat[kStatModernDudeTargetChanger]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatModernDudeTargetChanger); + while ((nSprite = it.NextIndex()) >= 0) + { XSPRITE* pXSprite = (sprite[nSprite].extra >= 0) ? &xsprite[sprite[nSprite].extra] : NULL; if (pXSprite == NULL || pXSprite->txID <= 0 || pXSprite->state != 1) continue; for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) { @@ -3564,7 +3587,10 @@ void aiFightAlarmDudesInSight(spritetype* pSprite, int max) { spritetype* pDude = NULL; XSPRITE* pXDude = NULL; XSPRITE* pXSprite = &xsprite[pSprite->extra]; DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { pDude = &sprite[nSprite]; if (pDude->index == pSprite->index || !IsDudeSprite(pDude) || pDude->extra < 0) continue; @@ -4243,7 +4269,10 @@ int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) { void useRandomItemGen(spritetype* pSource, XSPRITE* pXSource) { // let's first search for previously dropped items and remove it if (pXSource->dropMsg > 0) { - for (short nItem = headspritestat[kStatItem]; nItem >= 0; nItem = nextspritestat[nItem]) { + int nItem; + StatIterator it(kStatItem); + while ((nItem = it.NextIndex()) >= 0) + { spritetype* pItem = &sprite[nItem]; if ((unsigned int)pItem->type == pXSource->dropMsg && pItem->x == pSource->x && pItem->y == pSource->y && pItem->z == pSource->z) { gFX.fxSpawn((FX_ID)29, pSource->sectnum, pSource->x, pSource->y, pSource->z, 0); @@ -4630,8 +4659,10 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) { if ((pXSprite->target < 0 || pPlayer != NULL) && (gFrameClock & 32) != 0) { // try find first target that dude can see - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { - + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) + { pTarget = &sprite[nSprite]; pXTarget = &xsprite[pTarget->extra]; if (pXTarget->target == pSprite->index) { diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index eeedcfb36..644246522 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -787,7 +787,10 @@ void playerStart(int nPlayer, int bNewLevel) // assign or update player's sprite index for conditions if (gModernMap) { - for (int nSprite = headspritestat[kStatModernPlayerLinker]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { + int nSprite; + StatIterator it(kStatModernPlayerLinker); + while ((nSprite = it.NextIndex()) >= 0) + { XSPRITE* pXCtrl = &xsprite[sprite[nSprite].extra]; if (pXCtrl->data1 == pPlayer->nPlayer + 1) { int nSpriteOld = pXCtrl->sysData1; @@ -888,7 +891,9 @@ void playerInit(int nPlayer, unsigned int a2) char sub_3A158(PLAYER *a1, spritetype *a2) { - for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatThing); + while ((nSprite = it.NextIndex()) >= 0) { if (a2 && a2->index == nSprite) continue; @@ -1198,7 +1203,10 @@ void CheckPickUp(PLAYER *pPlayer) int z = pSprite->z; int nSector = pSprite->sectnum; int nNextSprite; - for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nNextSprite) { + int nSprite; + StatIterator it(kStatItem); + while ((nSprite = it.NextIndex()) >= 0) + { spritetype *pItem = &sprite[nSprite]; nNextSprite = nextspritestat[nSprite]; if (pItem->flags&32) diff --git a/source/blood/src/triggers.cpp b/source/blood/src/triggers.cpp index 4c5574c64..1f6b29108 100644 --- a/source/blood/src/triggers.cpp +++ b/source/blood/src/triggers.cpp @@ -1528,7 +1528,8 @@ void OperatePath(unsigned int nSector, XSECTOR *pXSector, EVENT event) spritetype *pSprite2 = &sprite[pXSector->marker0]; XSPRITE *pXSprite2 = &xsprite[pSprite2->extra]; int nId = pXSprite2->data2; - for (nSprite = headspritestat[kStatPathMarker]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + StatIterator it(kStatMarker); + while ((nSprite = it.NextIndex()) >= 0) { pSprite = &sprite[nSprite]; if (pSprite->type == kMarkerPath) @@ -1681,7 +1682,8 @@ void InitPath(unsigned int nSector, XSECTOR *pXSector) XSPRITE *pXSprite; assert(nSector < (unsigned int)numsectors); int nId = pXSector->data; - for (nSprite = headspritestat[kStatPathMarker]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + StatIterator it(kStatMarker); + while ((nSprite = it.NextIndex()) >= 0) { pSprite = &sprite[nSprite]; if (pSprite->type == kMarkerPath) diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 8937d353b..4fec258ce 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -847,9 +847,11 @@ void viewDrawScreen(bool sceneonly) deliriumTurn = 0; deliriumPitch = 0; } - int nSprite = headspritestat[kStatExplosion]; int unk = 0; - while (nSprite >= 0) + + int nSprite; + StatIterator it(kStatExplosion); + while ((nSprite = it.NextIndex()) >= 0) { spritetype* pSprite = &sprite[nSprite]; int nXSprite = pSprite->extra; @@ -859,10 +861,10 @@ void viewDrawScreen(bool sceneonly) { unk += pXSprite->data3 * 32; } - nSprite = nextspritestat[nSprite]; } - nSprite = headspritestat[kStatProjectile]; - while (nSprite >= 0) { + it.Reset(kStatProjectile); + while ((nSprite = it.NextIndex()) >= 0) + { spritetype* pSprite = &sprite[nSprite]; switch (pSprite->type) { case kMissileFlareRegular: @@ -872,7 +874,6 @@ void viewDrawScreen(bool sceneonly) if (TestBitString(gotsector, pSprite->sectnum)) unk += 256; break; } - nSprite = nextspritestat[nSprite]; } g_visibility = (int32_t)(ClipLow(gVisibility - 32 * gView->visibility - unk, 0)); cA += q16ang(interpolateangfix16(IntToFixed(deliriumTurnO), IntToFixed(deliriumTurn), gInterpolate)); diff --git a/source/blood/src/weapon.cpp b/source/blood/src/weapon.cpp index a60d4c91b..da6b6ba7b 100644 --- a/source/blood/src/weapon.cpp +++ b/source/blood/src/weapon.cpp @@ -307,7 +307,6 @@ WEAPONTRACK gWeaponTrack[] = { void UpdateAimVector(PLAYER * pPlayer) { - short nSprite; spritetype *pSprite; assert(pPlayer != NULL); spritetype *pPSprite = pPlayer->pSprite; @@ -324,7 +323,9 @@ void UpdateAimVector(PLAYER * pPlayer) if (cl_autoaim == 1 || (cl_autoaim == 2 && !pWeaponTrack->bIsProjectile) || pPlayer->curWeapon == 10 || pPlayer->curWeapon == 9) { int nClosest = 0x7fffffff; - for (nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) { pSprite = &sprite[nSprite]; if (pSprite == pPSprite) @@ -382,7 +383,9 @@ void UpdateAimVector(PLAYER * pPlayer) } if (pWeaponTrack->atc > 0) { - for (nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatThing); + while ((nSprite = it.NextIndex()) >= 0) { pSprite = &sprite[nSprite]; if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pPlayer, pSprite)) @@ -2508,7 +2511,9 @@ void sub_51340(spritetype *pMissile, int a2) actHitcodeToData(a2, &gHitInfo, &v24, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (a2 == 3 && v24 >= 0 && sprite[v24].statnum == kStatDude) v4 = 0; - for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + int nSprite; + StatIterator it(kStatDude); + while ((nSprite = it.NextIndex()) >= 0) { if (nSprite != nOwner || v4) { @@ -2526,7 +2531,8 @@ void sub_51340(spritetype *pMissile, int a2) } } } - for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) + it.Reset(kStatThing); + while ((nSprite = it.NextIndex()) >= 0) { spritetype *pSprite = &sprite[nSprite]; if (pSprite->flags&32) diff --git a/source/build/include/build.h b/source/build/include/build.h index 8709b9682..6c3c82a6f 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -921,53 +921,6 @@ extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum) extern void(*PolymostProcessVoxels_Callback)(void); #endif - -class StatIterator -{ - int next; -public: - StatIterator(int stat) - { - assert(stat >= 0 && stat < MAXSTATUS); - next = headspritestat[stat]; - } - - void Reset(int stat) - { - assert(stat >= 0 && stat < MAXSTATUS); - next = headspritestat[stat]; - } - - int NextIndex() - { - int n = next; - next = nextspritestat[next]; - return n; - } -}; - -class SectIterator -{ - int next; -public: - SectIterator(int stat) - { - assert(stat >= 0 && stat < MAXSECTORS); - next = headspritesect[stat]; - } - - void Reset(int stat) - { - assert(stat >= 0 && stat < MAXSECTORS); - next = headspritesect[stat]; - } - - int NextIndex() - { - int n = next; - next = nextspritesect[next]; - return n; - } -}; +#include "iterators.h" #endif // build_h_ diff --git a/source/core/iterators.h b/source/core/iterators.h new file mode 100644 index 000000000..7519048ce --- /dev/null +++ b/source/core/iterators.h @@ -0,0 +1,67 @@ +#pragma once + + +class StatIterator +{ + int next; +public: + StatIterator(int stat) + { + assert(stat >= 0 && stat < MAXSTATUS); + next = headspritestat[stat]; + } + + void Reset(int stat) + { + assert(stat >= 0 && stat < MAXSTATUS); + next = headspritestat[stat]; + } + + int NextIndex() + { + int n = next; + next = nextspritestat[next]; + return n; + } + + int PeekIndex() + { + return next; + } + + + // These are only used by one particularly screwy loop in Blood's nnexts.cpp. + static int First(int stat) + { + return headspritestat[stat]; + } + + static int NextFor(int spr) + { + return nextspritestat[spr]; + } +}; + +class SectIterator +{ + int next; +public: + SectIterator(int stat) + { + assert(stat >= 0 && stat < MAXSECTORS); + next = headspritesect[stat]; + } + + void Reset(int stat) + { + assert(stat >= 0 && stat < MAXSECTORS); + next = headspritesect[stat]; + } + + int NextIndex() + { + int n = next; + next = nextspritesect[next]; + return n; + } +};