mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-13 07:57:52 +00:00
- Added a NODELAY state flag. This is only valid for a state immediately following a Spawn label.
When set, the actor will run this state during its first tick. This means Spawn states may now run an action function if you set this flag. Note that this action function is executed during the actor's first tick, which is not the same as when it is spawned. SVN r4240 (trunk)
This commit is contained in:
parent
cc5110575f
commit
0e19a0e330
6 changed files with 65 additions and 21 deletions
|
@ -448,7 +448,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
|
||||||
NextToThink = node->NextThinker;
|
NextToThink = node->NextThinker;
|
||||||
if (node->ObjectFlags & OF_JustSpawned)
|
if (node->ObjectFlags & OF_JustSpawned)
|
||||||
{
|
{
|
||||||
node->ObjectFlags &= ~OF_JustSpawned;
|
// Leave OF_JustSpawn set until after Tick() so the ticker can check it.
|
||||||
if (dest != NULL)
|
if (dest != NULL)
|
||||||
{ // Move thinker from this list to the destination list
|
{ // Move thinker from this list to the destination list
|
||||||
node->Remove();
|
node->Remove();
|
||||||
|
@ -463,7 +463,8 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
|
||||||
|
|
||||||
if (!(node->ObjectFlags & OF_EuthanizeMe))
|
if (!(node->ObjectFlags & OF_EuthanizeMe))
|
||||||
{ // Only tick thinkers not scheduled for destruction
|
{ // Only tick thinkers not scheduled for destruction
|
||||||
node->Tick ();
|
node->Tick();
|
||||||
|
node->ObjectFlags &= ~OF_JustSpawned;
|
||||||
GC::CheckGC();
|
GC::CheckGC();
|
||||||
}
|
}
|
||||||
node = NextToThink;
|
node = NextToThink;
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct FState
|
||||||
BYTE Fullbright:1; // State is fullbright
|
BYTE Fullbright:1; // State is fullbright
|
||||||
BYTE SameFrame:1; // Ignore Frame (except when spawning actor)
|
BYTE SameFrame:1; // Ignore Frame (except when spawning actor)
|
||||||
BYTE Fast:1;
|
BYTE Fast:1;
|
||||||
|
BYTE NoDelay:1; // Spawn states executes its action normally
|
||||||
int ParameterIndex;
|
int ParameterIndex;
|
||||||
|
|
||||||
inline int GetFrame() const
|
inline int GetFrame() const
|
||||||
|
@ -109,6 +110,10 @@ struct FState
|
||||||
{
|
{
|
||||||
return NextState;
|
return NextState;
|
||||||
}
|
}
|
||||||
|
inline bool GetNoDelay() const
|
||||||
|
{
|
||||||
|
return NoDelay;
|
||||||
|
}
|
||||||
inline void SetFrame(BYTE frame)
|
inline void SetFrame(BYTE frame)
|
||||||
{
|
{
|
||||||
Frame = frame - 'A';
|
Frame = frame - 'A';
|
||||||
|
|
|
@ -3496,22 +3496,35 @@ void AActor::Tick ()
|
||||||
}
|
}
|
||||||
|
|
||||||
// cycle through states, calling action functions at transitions
|
// cycle through states, calling action functions at transitions
|
||||||
|
assert (state != NULL);
|
||||||
|
if (ObjectFlags & OF_JustSpawned && state->GetNoDelay())
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
SetState(state);
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
tics++;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tics != -1)
|
if (tics != -1)
|
||||||
{
|
{
|
||||||
// [RH] Use tics <= 0 instead of == 0 so that spawnstates
|
// [RH] Use tics <= 0 instead of == 0 so that spawnstates
|
||||||
// of 0 tics work as expected.
|
// of 0 tics work as expected.
|
||||||
if (tics <= 0)
|
if (tics <= 0)
|
||||||
{
|
{
|
||||||
assert (state != NULL);
|
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!SetState (state->GetNextState()))
|
if (!SetState(state->GetNextState()))
|
||||||
return; // freed itself
|
return; // freed itself
|
||||||
}
|
}
|
||||||
|
|
||||||
tics--;
|
tics--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3983,13 +3996,6 @@ void AActor::PostBeginPlay ()
|
||||||
Renderer->StateChanged(this);
|
Renderer->StateChanged(this);
|
||||||
}
|
}
|
||||||
PrevAngle = angle;
|
PrevAngle = angle;
|
||||||
|
|
||||||
// [BL] Run zero-delay spawn states now so that we don't create a tic later
|
|
||||||
if(tics == 0 && state)
|
|
||||||
{
|
|
||||||
if (!SetState (state->GetNextState()))
|
|
||||||
return; // freed itself
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AActor::MarkPrecacheSounds() const
|
void AActor::MarkPrecacheSounds() const
|
||||||
|
|
|
@ -334,8 +334,8 @@ FStateDefine *FStateDefinitions::FindStateLabelInList(TArray<FStateDefine> & lis
|
||||||
if (create)
|
if (create)
|
||||||
{
|
{
|
||||||
FStateDefine def;
|
FStateDefine def;
|
||||||
def.Label=name;
|
def.Label = name;
|
||||||
def.State=NULL;
|
def.State = NULL;
|
||||||
def.DefineFlags = SDF_NEXT;
|
def.DefineFlags = SDF_NEXT;
|
||||||
return &list[list.Push(def)];
|
return &list[list.Push(def)];
|
||||||
}
|
}
|
||||||
|
@ -351,12 +351,11 @@ FStateDefine *FStateDefinitions::FindStateLabelInList(TArray<FStateDefine> & lis
|
||||||
|
|
||||||
FStateDefine * FStateDefinitions::FindStateAddress(const char *name)
|
FStateDefine * FStateDefinitions::FindStateAddress(const char *name)
|
||||||
{
|
{
|
||||||
FStateDefine * statedef=NULL;
|
FStateDefine *statedef = NULL;
|
||||||
|
|
||||||
TArray<FName> &namelist = MakeStateNameList(name);
|
TArray<FName> &namelist = MakeStateNameList(name);
|
||||||
|
TArray<FStateDefine> *statelist = &StateLabels;
|
||||||
|
|
||||||
TArray<FStateDefine> * statelist = &StateLabels;
|
for(unsigned i = 0; i < namelist.Size(); i++)
|
||||||
for(unsigned i=0;i<namelist.Size();i++)
|
|
||||||
{
|
{
|
||||||
statedef = FindStateLabelInList(*statelist, namelist[i], true);
|
statedef = FindStateLabelInList(*statelist, namelist[i], true);
|
||||||
statelist = &statedef->Children;
|
statelist = &statedef->Children;
|
||||||
|
@ -379,7 +378,7 @@ void FStateDefinitions::SetStateLabel (const char *statename, FState *state, BYT
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Adds a new state to the curremt list
|
// Adds a new state to the current list
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
@ -393,6 +392,24 @@ void FStateDefinitions::AddStateLabel (const char *statename)
|
||||||
lastlabel = index;
|
lastlabel = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Returns the index a state label points to. May only be called before
|
||||||
|
// installing states.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FStateDefinitions::GetStateLabelIndex (FName statename)
|
||||||
|
{
|
||||||
|
FStateDefine *std = FindStateLabelInList(StateLabels, statename, false);
|
||||||
|
if (std == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
assert((size_t)std->State <= StateArray.Size() + 1);
|
||||||
|
return (int)((ptrdiff_t)std->State - 1);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Finds the state associated with the given name
|
// Finds the state associated with the given name
|
||||||
|
@ -863,6 +880,9 @@ bool FStateDefinitions::AddStates(FState *state, const char *framechars)
|
||||||
state->Frame = frame;
|
state->Frame = frame;
|
||||||
state->SameFrame = noframe;
|
state->SameFrame = noframe;
|
||||||
StateArray.Push(*state);
|
StateArray.Push(*state);
|
||||||
|
|
||||||
|
// NODELAY flag is not carried past the first state
|
||||||
|
state->NoDelay = false;
|
||||||
}
|
}
|
||||||
laststate = &StateArray[StateArray.Size() - 1];
|
laststate = &StateArray[StateArray.Size() - 1];
|
||||||
laststatebeforelabel = laststate;
|
laststatebeforelabel = laststate;
|
||||||
|
|
|
@ -91,6 +91,7 @@ public:
|
||||||
|
|
||||||
void SetStateLabel (const char * statename, FState * state, BYTE defflags = SDF_STATE);
|
void SetStateLabel (const char * statename, FState * state, BYTE defflags = SDF_STATE);
|
||||||
void AddStateLabel (const char * statename);
|
void AddStateLabel (const char * statename);
|
||||||
|
int GetStateLabelIndex (FName statename);
|
||||||
void InstallStates(FActorInfo *info, AActor *defaults);
|
void InstallStates(FActorInfo *info, AActor *defaults);
|
||||||
int FinishStates (FActorInfo *actor, AActor *defaults);
|
int FinishStates (FActorInfo *actor, AActor *defaults);
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,18 @@ do_stop:
|
||||||
state.Fast = true;
|
state.Fast = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (sc.Compare("NODELAY"))
|
||||||
|
{
|
||||||
|
if (bag.statedef.GetStateLabelIndex(NAME_Spawn) == bag.statedef.GetStateCount())
|
||||||
|
{
|
||||||
|
state.NoDelay = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc.ScriptMessage("NODELAY may only be used immediately after Spawn:");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (sc.Compare("OFFSET"))
|
if (sc.Compare("OFFSET"))
|
||||||
{
|
{
|
||||||
// specify a weapon offset
|
// specify a weapon offset
|
||||||
|
@ -338,8 +350,7 @@ do_stop:
|
||||||
int paramindex = PrepareStateParameters(&state, numparams, bag.Info->Class);
|
int paramindex = PrepareStateParameters(&state, numparams, bag.Info->Class);
|
||||||
int paramstart = paramindex;
|
int paramstart = paramindex;
|
||||||
bool varargs = params[numparams - 1] == '+';
|
bool varargs = params[numparams - 1] == '+';
|
||||||
int varargcount=0;
|
int varargcount = 0;
|
||||||
|
|
||||||
|
|
||||||
if (varargs)
|
if (varargs)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue