diff --git a/src/g_level.cpp b/src/g_level.cpp index 3fb8089d7..9d1bd9270 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1486,12 +1486,32 @@ int FLevelLocals::FinishTravel () // //========================================================================== +FLevelLocals::FLevelLocals() : Behaviors(this), tagManager(this) +{ + // Make sure that these point to the right data all the time. + // This will be needed for as long as it takes to completely separate global UI state from per-level play state. + for (int i = 0; i < MAXPLAYERS; i++) + { + Players[i] = &players[i]; + } + localEventManager = new EventManager; +} + +FLevelLocals::~FLevelLocals() +{ + if (localEventManager) delete localEventManager; +} + +//========================================================================== +// +// +//========================================================================== + void FLevelLocals::Init() { P_InitParticles(this); P_ClearParticles(this); BaseBlendA = 0.0f; // Remove underwater blend effect, if any - localEventManager = new EventManager; gravity = sv_gravity * 35/TICRATE; aircontrol = sv_aircontrol; @@ -2129,8 +2149,11 @@ void FLevelLocals::Mark() GC::Mark(BotInfo.firstthing); GC::Mark(BotInfo.body1); GC::Mark(BotInfo.body2); - GC::Mark(localEventManager->FirstEventHandler); - GC::Mark(localEventManager->LastEventHandler); + if (localEventManager) + { + GC::Mark(localEventManager->FirstEventHandler); + GC::Mark(localEventManager->LastEventHandler); + } Thinkers.MarkRoots(); canvasTextureInfo.Mark(); for (auto &c : CorpseQueue) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 7594fb19a..cf09617d0 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -106,15 +106,8 @@ struct FLevelLocals { void *level; void *Level; // bug catchers. - FLevelLocals() : Behaviors(this), tagManager(this) - { - // Make sure that these point to the right data all the time. - // This will be needed for as long as it takes to completely separate global UI state from per-level play state. - for (int i = 0; i < MAXPLAYERS; i++) - { - Players[i] = &players[i]; - } - } + FLevelLocals(); + ~FLevelLocals(); friend class MapLoader; diff --git a/src/gamedata/info.cpp b/src/gamedata/info.cpp index 1086200b2..f06e56b46 100644 --- a/src/gamedata/info.cpp +++ b/src/gamedata/info.cpp @@ -536,9 +536,11 @@ PClassActor *PClassActor::GetReplacement(FLevelLocals *Level, bool lookskill) lookskill = false; skillrepname = NAME_None; } } - // [MK] ZScript replacement through Event Handlers, has priority over others + // [MK] ZScript replacement through Event Handlers, has priority over others. PClassActor *Replacement = ActorInfo()->Replacement; - if (Level->localEventManager->CheckReplacement(this,&Replacement) ) + // Level can be null when initializing dynamic lights. + // Since they only want to check for DehackedPickups this code should be skipped for them. + if (Level && Level->localEventManager->CheckReplacement(this,&Replacement) ) { // [MK] the replacement is final, so don't continue with the chain return Replacement ? Replacement : this; @@ -561,7 +563,7 @@ PClassActor *PClassActor::GetReplacement(FLevelLocals *Level, bool lookskill) } // Now handle DECORATE replacement chain // Skill replacements are not recursive, contrarily to DECORATE replacements - rep = rep->GetReplacement(false); + rep = rep->GetReplacement(Level, false); // Reset the temporarily NULLed field ActorInfo()->Replacement = oldrep; return rep; @@ -615,7 +617,7 @@ PClassActor *PClassActor::GetReplacee(FLevelLocals *Level, bool lookskill) { rep = PClass::FindActor(skillrepname); } - rep = rep->GetReplacee(false); + rep = rep->GetReplacee(Level, false); ActorInfo()->Replacee = savedrep; return rep; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 1cebab78d..8aeca7b8b 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -338,8 +338,7 @@ void FLevelLocals::ClearLevelData() Scrolls.Clear(); if (automap) automap->Destroy(); Behaviors.UnloadModules(); - delete localEventManager; - localEventManager = nullptr; + localEventManager->Shutdown(); } //========================================================================== diff --git a/src/r_data/a_dynlightdata.cpp b/src/r_data/a_dynlightdata.cpp index e6ed0c10b..1d8564a45 100644 --- a/src/r_data/a_dynlightdata.cpp +++ b/src/r_data/a_dynlightdata.cpp @@ -46,7 +46,7 @@ inline PClassActor * GetRealType(PClassActor * ti) { - PClassActor *rep = ti->GetReplacement(false); + PClassActor *rep = ti->GetReplacement(nullptr, false); if (rep != ti && rep != NULL && rep->IsDescendantOf(NAME_DehackedPickup)) { return rep; diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index 96e63c037..653bc2d98 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -2846,7 +2846,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency) // // //========================================================================== -DEFINE_GLOBAL(currentVMLevel, level); +DEFINE_GLOBAL_NAMED(currentVMLevel, level) DEFINE_FIELD(FLevelLocals, sectors) DEFINE_FIELD(FLevelLocals, lines) DEFINE_FIELD(FLevelLocals, sides) diff --git a/src/version.h b/src/version.h index 3387ae54a..1336b47c6 100644 --- a/src/version.h +++ b/src/version.h @@ -87,11 +87,11 @@ const char *GetVersionString(); #define SAVEGAME_EXT "zds" // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 4555 +#define MINSAVEVER 4556 // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4555 +#define SAVEVER 4556 // This is so that derivates can use the same savegame versions without worrying about engine compatibility #define GAMESIG "GZDOOM"