Improve NoDelay reliability.

- Instead of tying NoDelay behavior to OF_JustSpawned, use a new actor
  flag, MF7_HANDLENODELAY. This only gets cleared once it has actually
  been checked by Tick(). This is necessary because freeze mode delays the
  initial run of Tick() past the initial spawn, so OF_JustSpawned will no
  longer be set when it does the initial tick.
- Delay NoDelay processing if an actor is spawned dormant. Actors spawned
  dormant have Deactivate() called before they tick, so MF7_HANDLENODELAY
  will remain set as long as an actor is dormant. This allows the NoDelay
  handling to occur as expected once it is activated.
This commit is contained in:
Randy Heit 2013-09-17 20:44:13 -05:00
parent a3e74bb39f
commit e021fba5e1
4 changed files with 20 additions and 14 deletions

View file

@ -334,11 +334,12 @@ enum
MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup.
MF6_RELATIVETOFLOOR = 0x80000000, // [RC] Make flying actors be affected by lifts.
// --- mobj.flags6 ---
// --- mobj.flags7 ---
MF7_NEVERTARGET = 0x00000001, // can not be targetted at all, even if monster friendliness is considered.
MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO)
MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings.
MF7_HANDLENODELAY = 0x00000008, // respect NoDelay state flag
// --- mobj.renderflags ---

View file

@ -473,7 +473,7 @@ public:
// use this method.
virtual size_t PointerSubstitution (DObject *old, DObject *notOld);
static size_t StaticPointerSubstitution (DObject *old, DObject *notOld);
PClass *GetClass() const
{
if (Class == NULL)

View file

@ -457,7 +457,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
node->PostBeginPlay();
}
else if (dest != NULL)
{ // Move thinker from this list to the destination list
{
I_Error("There is a thinker in the fresh list that has already ticked.\n");
}

View file

@ -3525,19 +3525,23 @@ void AActor::Tick ()
Destroy();
return;
}
if (ObjectFlags & OF_JustSpawned && state->GetNoDelay())
if ((flags7 & MF7_HANDLENODELAY) && !(flags2 & MF2_DORMANT))
{
// For immediately spawned objects with the NoDelay flag set for their
// Spawn state, explicitly set the current state so that it calls its
// action and chains 0-tic states.
int starttics = tics;
if (!SetState(state))
return; // freed itself
// If the initial state had a duration of 0 tics, let the next state run
// normally. Otherwise, increment tics by 1 so that we don't double up ticks.
if (starttics > 0 && tics >= 0)
flags7 &= ~MF7_HANDLENODELAY;
if (state->GetNoDelay())
{
tics++;
// For immediately spawned objects with the NoDelay flag set for their
// Spawn state, explicitly set the current state so that it calls its
// action and chains 0-tic states.
int starttics = tics;
if (!SetState(state))
return; // freed itself
// If the initial state had a duration of 0 tics, let the next state run
// normally. Otherwise, increment tics by 1 so that we don't double up ticks.
else if (starttics > 0 && tics >= 0)
{
tics++;
}
}
}
// cycle through states, calling action functions at transitions
@ -4024,6 +4028,7 @@ void AActor::PostBeginPlay ()
Renderer->StateChanged(this);
}
PrevAngle = angle;
flags7 |= MF7_HANDLENODELAY;
}
void AActor::MarkPrecacheSounds() const