From 9942a598668556f4dfbff77fbcf9ca185bcad511 Mon Sep 17 00:00:00 2001
From: ZZYZX <zzyzx@virtual>
Date: Tue, 31 Jan 2017 04:11:09 +0200
Subject: [PATCH] Almost forgot (x2): thing revived world event

---
 src/events.cpp                   | 24 ++++++++++++++++++++++++
 src/events.h                     |  3 +++
 src/p_mobj.cpp                   |  3 +++
 wadsrc/static/zscript/events.txt |  1 +
 4 files changed, 31 insertions(+)

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);