From 457f7c31c3e481d08d640c36427bfe5daeb3624b Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Mon, 27 Sep 2021 19:40:57 +0200 Subject: [PATCH] Allow WorldUnloaded events to know the next map name (if any). --- src/events.cpp | 8 +++++--- src/events.h | 5 +++-- src/g_level.cpp | 6 +++--- wadsrc/static/zscript/events.zs | 2 ++ 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/events.cpp b/src/events.cpp index 623d22203..a9362e03b 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -294,11 +294,11 @@ void EventManager::WorldLoaded() } } -void EventManager::WorldUnloaded() +void EventManager::WorldUnloaded(const FString& nextmap) { for (DStaticEventHandler* handler = LastEventHandler; handler; handler = handler->prev) { - handler->WorldUnloaded(); + handler->WorldUnloaded(nextmap); } } @@ -629,6 +629,7 @@ DEFINE_FIELD_X(RenderEvent, FRenderEvent, Camera); DEFINE_FIELD_X(WorldEvent, FWorldEvent, IsSaveGame); DEFINE_FIELD_X(WorldEvent, FWorldEvent, IsReopen); +DEFINE_FIELD_X(WorldEvent, FWorldEvent, NextMap); DEFINE_FIELD_X(WorldEvent, FWorldEvent, Thing); DEFINE_FIELD_X(WorldEvent, FWorldEvent, Inflictor); DEFINE_FIELD_X(WorldEvent, FWorldEvent, Damage); @@ -769,13 +770,14 @@ void DStaticEventHandler::WorldLoaded() } } -void DStaticEventHandler::WorldUnloaded() +void DStaticEventHandler::WorldUnloaded(const FString& nextmap) { IFVIRTUAL(DStaticEventHandler, WorldUnloaded) { // don't create excessive DObjects if not going to be processed anyway if (isEmpty(func)) return; FWorldEvent e = owner->SetupWorldEvent(); + e.NextMap = nextmap; VMValue params[2] = { (DStaticEventHandler*)this, &e }; VMCall(func, params, 2, nullptr, 0); } diff --git a/src/events.h b/src/events.h index 86e8e941e..f5ad75d88 100755 --- a/src/events.h +++ b/src/events.h @@ -78,7 +78,7 @@ public: // void WorldLoaded(); - void WorldUnloaded(); + void WorldUnloaded(const FString& nextmap); void WorldThingSpawned(AActor* actor); void WorldThingDied(AActor* actor, AActor* inflictor); void WorldThingGround(AActor* actor, FState* st); @@ -144,6 +144,7 @@ struct FWorldEvent // for loaded/unloaded bool IsSaveGame = false; bool IsReopen = false; + FString NextMap; // for thingspawned, thingdied, thingdestroyed AActor* Thing = nullptr; // for thingdied AActor* Inflictor = nullptr; // can be null - for damagemobj @@ -232,7 +233,7 @@ struct EventManager // called right after the map has loaded (approximately same time as OPEN ACS scripts) void WorldLoaded(); // called when the map is about to unload (approximately same time as UNLOADING ACS scripts) - void WorldUnloaded(); + void WorldUnloaded(const FString& nextmap); // called around PostBeginPlay of each actor. void WorldThingSpawned(AActor* actor); // called after AActor::Die of each actor. diff --git a/src/g_level.cpp b/src/g_level.cpp index 6468dd29d..5247c4968 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -468,7 +468,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) // did we have any level before? if (primaryLevel->info != nullptr) - staticEventManager.WorldUnloaded(); + staticEventManager.WorldUnloaded(FString()); // [MK] don't pass the new map, as it's not a level transition if (!savegamerestore) { @@ -701,10 +701,10 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int inflags, for (auto Level : AllLevels()) { // Todo: This must be exolicitly sandboxed! - Level->localEventManager->WorldUnloaded(); + Level->localEventManager->WorldUnloaded(nextlevel); } // [ZZ] unsafe world unload (changemap != map) - staticEventManager.WorldUnloaded(); + staticEventManager.WorldUnloaded(nextlevel); unloading = false; STAT_ChangeLevel(nextlevel, this); diff --git a/wadsrc/static/zscript/events.zs b/wadsrc/static/zscript/events.zs index 6db6fb1e2..7492ea2b0 100644 --- a/wadsrc/static/zscript/events.zs +++ b/wadsrc/static/zscript/events.zs @@ -15,6 +15,8 @@ struct WorldEvent native play version("2.4") native readonly bool IsSaveGame; // this will be true if we are re-entering the hub level. native readonly bool IsReopen; + // for unloaded, name of next map (if any) + native readonly String NextMap; // for thingspawned/thingdied/thingdestroyed/thingground native readonly Actor Thing; // for thingdied. can be null