premap.c: delete GPSPEED/CYCLERs only after the loop with EVENT_LOADACTOR events

git-svn-id: https://svn.eduke32.com/eduke32@4045 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-09-05 17:37:38 +00:00
parent e402467676
commit 7543ba7226
2 changed files with 24 additions and 7 deletions

View file

@ -106,6 +106,8 @@ enum rendmode_t {
// ... in which case this iterator may be used: // ... in which case this iterator may be used:
#define SPRITES_OF_SECT_SAFE(Sectnum, Iter, Next) Iter=headspritesect[Sectnum]; \ #define SPRITES_OF_SECT_SAFE(Sectnum, Iter, Next) Iter=headspritesect[Sectnum]; \
Iter>=0 && (Next=nextspritesect[Iter], 1); Iter=Next Iter>=0 && (Next=nextspritesect[Iter], 1); Iter=Next
#define SPRITES_OF_STAT_SAFE(Statnum, Iter, Next) Iter=headspritestat[Statnum]; \
Iter>=0 && (Next=nextspritestat[Iter], 1); Iter=Next
#define CLEARLINES2D(Startline, Numlines, Color) \ #define CLEARLINES2D(Startline, Numlines, Color) \
clearbuf((char *)(frameplace + ((Startline)*bytesperline)), (bytesperline*(Numlines))>>2, (Color)) clearbuf((char *)(frameplace + ((Startline)*bytesperline)), (bytesperline*(Numlines))>>2, (Color))

View file

@ -1019,6 +1019,11 @@ static void G_SetupRotfixedSprites(void)
} }
} }
static inline int32_t G_CheckExitSprite(int32_t i)
{
return (sprite[i].lotag == UINT16_MAX && (sprite[i].cstat&16));
}
static inline void prelevel(char g) static inline void prelevel(char g)
{ {
int32_t i, nexti, j, startwall, endwall; int32_t i, nexti, j, startwall, endwall;
@ -1080,16 +1085,15 @@ static inline void prelevel(char g)
} }
} }
i = headspritestat[STAT_DEFAULT]; // NOTE: must be safe loop because callbacks could delete sprites.
while (i >= 0) for (SPRITES_OF_STAT_SAFE(STAT_DEFAULT, i, nexti))
{ {
nexti = nextspritestat[i];
#if !defined LUNATIC #if !defined LUNATIC
A_ResetVars(i); A_ResetVars(i);
A_LoadActor(i); A_LoadActor(i);
#endif #endif
VM_OnEvent(EVENT_LOADACTOR, i, -1, -1, 0); VM_OnEvent(EVENT_LOADACTOR, i, -1, -1, 0);
if (sprite[i].lotag == UINT16_MAX && (sprite[i].cstat&16)) if (G_CheckExitSprite(i))
{ {
g_player[0].ps->exitx = SX; g_player[0].ps->exitx = SX;
g_player[0].ps->exity = SY; g_player[0].ps->exity = SY;
@ -1097,11 +1101,12 @@ static inline void prelevel(char g)
else switch (DYNAMICTILEMAP(PN)) else switch (DYNAMICTILEMAP(PN))
{ {
case GPSPEED__STATIC: case GPSPEED__STATIC:
// DELETE_AFTER_LOADACTOR. Must not change statnum.
sector[SECT].extra = SLT; sector[SECT].extra = SLT;
A_DeleteSprite(i);
break; break;
case CYCLER__STATIC: case CYCLER__STATIC:
// DELETE_AFTER_LOADACTOR. Must not change statnum.
if (g_numCyclers >= MAXCYCLERS) if (g_numCyclers >= MAXCYCLERS)
{ {
Bsprintf(tempbuf,"\nToo many cycling sectors (%d max).",MAXCYCLERS); Bsprintf(tempbuf,"\nToo many cycling sectors (%d max).",MAXCYCLERS);
@ -1114,7 +1119,6 @@ static inline void prelevel(char g)
cyclers[g_numCyclers][4] = SHT; cyclers[g_numCyclers][4] = SHT;
cyclers[g_numCyclers][5] = (SA == 1536); cyclers[g_numCyclers][5] = (SA == 1536);
g_numCyclers++; g_numCyclers++;
A_DeleteSprite(i);
break; break;
case SECTOREFFECTOR__STATIC: case SECTOREFFECTOR__STATIC:
@ -1128,7 +1132,18 @@ static inline void prelevel(char g)
sprite[i].cstat &= ~(1|256); sprite[i].cstat &= ~(1|256);
break; break;
} }
i = nexti; }
// Delete some effector / effector modifier sprites AFTER the loop running
// the LOADACTOR events. DELETE_AFTER_LOADACTOR.
for (SPRITES_OF_STAT_SAFE(STAT_DEFAULT, i, nexti))
if (!G_CheckExitSprite(i))
switch (DYNAMICTILEMAP(PN))
{
case GPSPEED__STATIC:
case CYCLER__STATIC:
A_DeleteSprite(i);
break;
} }
for (i=0; i < MAXSPRITES; i++) for (i=0; i < MAXSPRITES; i++)