diff --git a/src/events.cpp b/src/events.cpp index bba4d180d..68088a307 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -250,6 +250,15 @@ void E_WorldThingDied(AActor* actor, AActor* inflictor) handler->WorldThingDied(actor, inflictor); } +void E_WorldThingRevived(AActor* actor) +{ + // don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever. + if (actor->ObjectFlags & OF_EuthanizeMe) + return; + for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) + handler->WorldThingRevived(actor); +} + void E_WorldThingDestroyed(AActor* actor) { // don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever. @@ -399,6 +408,7 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLoaded) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied) +DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingRevived) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick) @@ -475,6 +485,20 @@ void DStaticEventHandler::WorldThingDied(AActor* actor, AActor* inflictor) } } +void DStaticEventHandler::WorldThingRevived(AActor* actor) +{ + IFVIRTUAL(DStaticEventHandler, WorldThingRevived) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_WorldThingRevived_VMPtr) + return; + DWorldEvent* e = E_SetupWorldEvent(); + e->Thing = actor; + VMValue params[2] = { (DStaticEventHandler*)this, e }; + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); + } +} + void DStaticEventHandler::WorldThingDestroyed(AActor* actor) { IFVIRTUAL(DStaticEventHandler, WorldThingDestroyed) diff --git a/src/events.h b/src/events.h index b5bd76bff..0bebcfc88 100755 --- a/src/events.h +++ b/src/events.h @@ -29,6 +29,8 @@ void E_WorldUnloadedUnsafe(); void E_WorldThingSpawned(AActor* actor); // called after AActor::Die of each actor. void E_WorldThingDied(AActor* actor, AActor* inflictor); +// called after AActor::Revive. +void E_WorldThingRevived(AActor* actor); // called before AActor::Destroy of each actor. void E_WorldThingDestroyed(AActor* actor); // same as ACS SCRIPT_Lightning @@ -86,6 +88,7 @@ public: virtual void WorldUnloaded(); virtual void WorldThingSpawned(AActor*); virtual void WorldThingDied(AActor*, AActor*); + virtual void WorldThingRevived(AActor*); virtual void WorldThingDestroyed(AActor*); virtual void WorldLightning(); virtual void WorldTick(); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e45ca0b5f..f22f63937 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7472,6 +7472,9 @@ void AActor::Revive() { level.total_monsters++; } + + // [ZZ] resurrect hook + E_WorldThingRevived(this); } int AActor::GetGibHealth() const diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt index 179bf8ea6..cedee667a 100755 --- a/wadsrc/static/zscript/events.txt +++ b/wadsrc/static/zscript/events.txt @@ -36,6 +36,7 @@ class StaticEventHandler : Object native virtual native void WorldUnloaded(WorldEvent e); virtual native void WorldThingSpawned(WorldEvent e); virtual native void WorldThingDied(WorldEvent e); + virtual native void WorldThingRevived(WorldEvent e); virtual native void WorldThingDestroyed(WorldEvent e); virtual native void WorldLightning(WorldEvent e); // for the sake of completeness. virtual native void WorldTick(WorldEvent e);