- all Blood stat iterators ported.

This commit is contained in:
Christoph Oelckers 2020-10-15 17:15:45 +02:00
parent 33164694b9
commit eb78b88598
20 changed files with 248 additions and 126 deletions

View file

@ -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)

View file

@ -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]);
}

View file

@ -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)

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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);

View file

@ -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];

View file

@ -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];

View file

@ -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)

View file

@ -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;
}

View file

@ -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);

View file

@ -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) {

View file

@ -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)

View file

@ -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)

View file

@ -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));

View file

@ -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)

View file

@ -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_

67
source/core/iterators.h Normal file
View file

@ -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;
}
};