- added BloodSpriteIterator and BloodLinearSpriteIterator to get rid of explicit loops over the sprite array.

This commit is contained in:
Christoph Oelckers 2021-08-29 20:47:51 +02:00
parent 484d016172
commit b2de1e5209
4 changed files with 59 additions and 33 deletions

View file

@ -7457,16 +7457,6 @@ void HITINFO::set(hitdata_t* hit)
} }
void aiSetTarget_(XSPRITE* pXSprite, int nTarget)
{
aiSetTarget(&bloodActors[pXSprite->reference], &bloodActors[nTarget]);
}
void aiSetTarget_(XSPRITE* pXSprite, int x, int y, int z)
{
aiSetTarget(&bloodActors[pXSprite->reference], x, y, z);
}
char SetSpriteState(DBloodActor* actor, int nState) char SetSpriteState(DBloodActor* actor, int nState)
{ {
return SetSpriteState(actor->GetIndex(), &actor->x(), nState); return SetSpriteState(actor->GetIndex(), &actor->x(), nState);

View file

@ -96,7 +96,4 @@ void aiInit(void);
void aiInitSprite(DBloodActor* pSprite); void aiInitSprite(DBloodActor* pSprite);
bool CanMove(DBloodActor* pSprite, int a2, int nAngle, int nRange); bool CanMove(DBloodActor* pSprite, int a2, int nAngle, int nRange);
void aiSetTarget_(XSPRITE* pXSprite, int x, int y, int z);
void aiSetTarget_(XSPRITE* pXSprite, int nTarget);
END_BLD_NS END_BLD_NS

View file

@ -269,6 +269,47 @@ public:
} }
}; };
// An iterator to iterate over all sprites.
class BloodSpriteIterator
{
BloodStatIterator it;
int stat = kStatDecoration;
public:
BloodSpriteIterator() : it(kStatDecoration) {}
DBloodActor* Next()
{
while (stat < kStatFree)
{
auto ac = it.Next();
if (ac) return ac;
stat++;
if (stat < kStatFree) it.Reset(stat);
}
return nullptr;
}
};
// For iterating linearly over map spawned sprites.
class BloodLinearSpriteIterator
{
int index = 0;
public:
DBloodActor* Next()
{
while (index < MAXSPRITES)
{
auto p = &bloodActors[index++];
if (p->s().statnum != kStatFree) return p;
}
return nullptr;
}
};
inline int DeleteSprite(DBloodActor* nSprite) inline int DeleteSprite(DBloodActor* nSprite)
{ {
if (nSprite) return DeleteSprite(nSprite->s().index); if (nSprite) return DeleteSprite(nSprite->s().index);

View file

@ -545,10 +545,10 @@ void nnExtInitModernStuff(bool bSaveLoad)
} }
} }
for (int i = 0; i < kMaxXSprites; i++) BloodLinearSpriteIterator it;
while (auto actor = it.Next())
{ {
auto actor = &bloodActors[i]; if (!actor->hasX()) continue;
if (actor->s().statnum == kStatFree || !actor->hasX()) continue;
XSPRITE* pXSprite = &actor->x(); XSPRITE* pXSprite = &actor->x();
spritetype* pSprite = &actor->s(); spritetype* pSprite = &actor->s();
@ -842,8 +842,8 @@ void nnExtInitModernStuff(bool bSaveLoad)
} }
// collect objects for tracking conditions // collect objects for tracking conditions
BloodStatIterator it(kStatModernCondition); BloodStatIterator it2(kStatModernCondition);
while (auto iactor = it.Next()) while (auto iactor = it2.Next())
{ {
spritetype* pSprite = &iactor->s(); spritetype* pSprite = &iactor->s();
XSPRITE* pXSprite = &iactor->x(); XSPRITE* pXSprite = &iactor->x();
@ -855,14 +855,14 @@ void nnExtInitModernStuff(bool bSaveLoad)
int count = 0; int count = 0;
TRCONDITION* pCond = &gCondition[gTrackingCondsCount]; TRCONDITION* pCond = &gCondition[gTrackingCondsCount];
for (int i = 0; i < kMaxXSprites; i++) BloodLinearSpriteIterator it;
while (auto iactor2 = it.Next())
{ {
auto actor = &bloodActors[i]; if (!iactor2->hasX() || iactor2->x().txID != pXSprite->rxID || iactor2 == iactor)
if (actor->s().statnum == kStatFree || !actor->hasX() || actor->x().txID != pXSprite->rxID || actor == iactor)
continue; continue;
XSPRITE* pXSpr = &actor->x(); XSPRITE* pXSpr = &iactor2->x();
spritetype* pSpr = &actor->s(); spritetype* pSpr = &iactor2->s();
int index = pXSpr->reference; int cmd = pXSpr->command; int index = pXSpr->reference; int cmd = pXSpr->command;
switch (pSpr->type) { switch (pSpr->type) {
case kSwitchToggle: // exceptions case kSwitchToggle: // exceptions
@ -884,8 +884,8 @@ void nnExtInitModernStuff(bool bSaveLoad)
pCond->obj[count].type = OBJ_SPRITE; pCond->obj[count].type = OBJ_SPRITE;
pCond->obj[count].index_ = 0; pCond->obj[count].index_ = 0;
pCond->obj[count].actor = &bloodActors[index]; pCond->obj[count].actor = iactor2;
pCond->obj[count++].cmd = cmd; pCond->obj[count++].cmd = (uint8_t)pXSpr->command;
} }
for (int i = 0; i < kMaxXSectors; i++) for (int i = 0; i < kMaxXSectors; i++)
@ -4678,11 +4678,9 @@ bool condCheckSprite(DBloodActor* aCond, int cmpOp, bool PUSH)
if (actorvar == nullptr) if (actorvar == nullptr)
{ {
// check if something is touching this sprite // check if something is touching this sprite
for (int i = kMaxXSprites - 1, idx = i; i > 0; idx = xsprite[--i].reference) BloodSpriteIterator it;
while (auto iactor = it.Next())
{ {
if (idx < 0) continue;
auto iactor = &bloodActors[idx];
if (iactor->s().flags & kHitagRespawn) continue; if (iactor->s().flags & kHitagRespawn) continue;
auto& hit = iactor->hit; auto& hit = iactor->hit;
switch (arg3) switch (arg3)
@ -6152,7 +6150,7 @@ void seqTxSendCmdAll(DBloodActor* source, DBloodActor* actor, COMMAND_ID cmd, bo
{ {
for (int i = 0; i <= 3; i++) for (int i = 0; i <= 3; i++)
{ {
pXSource->txID = GetDataVal(&bloodActors[pXSource->reference], i); pXSource->txID = GetDataVal(source, i);
if (pXSource->txID <= 0 || pXSource->txID >= kChannelUserMax) continue; if (pXSource->txID <= 0 || pXSource->txID >= kChannelUserMax) continue;
else if (!modernSend) evSendActor(actor, pXSource->txID, cmd); else if (!modernSend) evSendActor(actor, pXSource->txID, cmd);
else modernTypeSendCommand(actor, pXSource->txID, cmd); else modernTypeSendCommand(actor, pXSource->txID, cmd);
@ -9124,10 +9122,10 @@ bool incDecGoalValueIsReached(DBloodActor* actor)
void seqSpawnerOffSameTx(DBloodActor* actor) void seqSpawnerOffSameTx(DBloodActor* actor)
{ {
auto pXSource = &actor->x(); auto pXSource = &actor->x();
for (int i = 0; i < kMaxXSprites; i++) BloodSpriteIterator it;
while (auto iactor = it.Next())
{ {
auto iactor = &bloodActors[i]; if (iactor->s().type != kModernSeqSpawner || !iactor->hasX() || iactor == actor) continue;
if (iactor->s().statnum == kStatFree || iactor->s().type != kModernSeqSpawner || !iactor->hasX() || iactor == actor) continue;
XSPRITE* pXSprite = &iactor->x(); XSPRITE* pXSprite = &iactor->x();
if (pXSprite->txID == pXSource->txID && pXSprite->state == 1) if (pXSprite->txID == pXSource->txID && pXSprite->state == 1)
{ {