diff --git a/source/core/states.cpp b/source/core/states.cpp index 1f5a9e819..c43786936 100644 --- a/source/core/states.cpp +++ b/source/core/states.cpp @@ -41,6 +41,7 @@ #include "templates.h" #include "states.h" #include "texturemanager.h" +#include "codegen.h" // stores indices for symbolic state labels for some old-style DECORATE functions. @@ -699,7 +700,7 @@ void FStateDefinitions::RetargetStatePointers (intptr_t count, const char *targe } else { - statelist[i].State = (FState *)copystring (target); + statelist[i].State = (FState *)FxAlloc.Strdup(target); statelist[i].DefineFlags = SDF_LABEL; } } @@ -800,7 +801,6 @@ FState *FStateDefinitions::ResolveGotoLabel (PClassActor *mytype, char *name) { Printf (TEXTCOLOR_RED "Attempt to get invalid state %s from actor %s.\n", label, type->TypeName.GetChars()); } - delete[] namestart; // free the allocated string buffer return state; } @@ -864,7 +864,7 @@ bool FStateDefinitions::SetGotoLabel(const char *string) // copy the text - this must be resolved later! if (laststate != nullptr) { // Following a state definition: Modify it. - laststate->NextState = (FState*)copystring(string); + laststate->NextState = (FState*)FxAlloc.Strdup(string); laststate->DefineFlags = SDF_LABEL; laststatebeforelabel = nullptr; return true; @@ -874,7 +874,7 @@ bool FStateDefinitions::SetGotoLabel(const char *string) RetargetStates (lastlabel+1, string); if (laststatebeforelabel != nullptr) { - laststatebeforelabel->NextState = (FState*)copystring(string); + laststatebeforelabel->NextState = (FState*)FxAlloc.Strdup(string); laststatebeforelabel->DefineFlags = SDF_LABEL; laststatebeforelabel = nullptr; } diff --git a/source/core/states.h b/source/core/states.h index e52905dd5..88f510ca6 100644 --- a/source/core/states.h +++ b/source/core/states.h @@ -79,6 +79,10 @@ enum EStateFlags { STF_TICADJUST = 1, STF_FULLBRIGHT = 4, // State is fullbright + STF_SPRITESEQMASK = 24, + STF_SPRITESEQNAME = 8, + STF_SPRITESEQINDEX = 16, + STF_SPRITESEQOFFSET = 24, }; enum EStateType : int // this must ensure proper alignment. @@ -161,6 +165,7 @@ struct FDefiningState VMFunction* EnterFunc; // called when entering the state. VMFunction* TickFunc; // called when ticking the state. VMFunction* MoveFunc; // called when moving the actor + FScriptPosition scriptpos; // these are only here so we can use this struct directly in the first stage of transitioning the states in Blood. FDefiningState* NextState; diff --git a/source/core/zcc_compile_raze.cpp b/source/core/zcc_compile_raze.cpp index fe2de0fcc..9d14ef772 100644 --- a/source/core/zcc_compile_raze.cpp +++ b/source/core/zcc_compile_raze.cpp @@ -1025,6 +1025,28 @@ void ZCCRazeCompiler::CompileStates() int numframes = 0; + // first set up the AI states so that regular states can 'goto' to them. + for (auto& defstate : static_cast(c->ClassType())->ActorInfo()->AIStates) + { + statedef.AddStateLabel(defstate.Label.GetChars()); + + FState state; + memset(&state, 0, sizeof(state)); + state.UseFlags = SUF_ACTOR; // AI states are only for actors and nothing else.; + state.sprite = defstate.sprite & 0xfffffff; + if (defstate.sprite & 0x10000000) state.StateFlags = STF_SPRITESEQINDEX; + else if (defstate.sprite & 0x20000000) state.StateFlags = STF_SPRITESEQOFFSET; + else state.StateFlags = STF_SPRITESEQNAME; + state.Tics = defstate.Tics; + //state.? = defstate.Type; // no idea if we will need this. + state.ActionFunc = defstate.ActionFunc; + state.MoveFunc = defstate.MoveFunc; + state.TickFunc = defstate.TickFunc; + state.EnterFunc = defstate.EnterFunc; + statedef.AddStates(&state, "A", defstate.scriptpos); + statedef.SetGotoLabel(defstate.NextStaten.GetChars()); + } + for (auto s : c->States) { int flags; diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index 2aaa991e6..ed3621fd5 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -818,6 +818,7 @@ DEFINE_PROPERTY(aistate, SSIIGGGGs, CoreActor) if (*seq == 0) state.sprite = 0; else if (*seq == '#') state.sprite = (int)strtoull(seq + 1, &endp, 10) | 0x10000000; else if (*seq == '+') state.sprite = (int)strtoull(seq + 1, &endp, 10) | 0x20000000; + else state.sprite = FName(seq).GetIndex(); state.Label = label; state.Type = type;