mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Implemented WorldThingDied (calls at the same point as SCRIPT_Kill); Added Inflictor parameter for WorldThingDied.
This commit is contained in:
parent
27c8140c46
commit
71f62af6db
4 changed files with 94 additions and 0 deletions
|
@ -239,8 +239,27 @@ void E_WorldThingSpawned(AActor* actor)
|
|||
handler->WorldThingSpawned(actor);
|
||||
}
|
||||
|
||||
void E_WorldThingDied(AActor* actor, AActor* inflictor)
|
||||
{
|
||||
// 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->WorldThingDied(actor, inflictor);
|
||||
}
|
||||
|
||||
void E_WorldThingDestroyed(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->WorldThingDestroyed(actor);
|
||||
}
|
||||
|
||||
// normal event loopers (non-special, argument-less)
|
||||
DEFINE_EVENT_LOOPER(RenderFrame)
|
||||
DEFINE_EVENT_LOOPER(WorldLightning)
|
||||
|
||||
// declarations
|
||||
IMPLEMENT_CLASS(DStaticEventHandler, false, false);
|
||||
|
@ -258,6 +277,7 @@ DEFINE_FIELD_X(RenderEvent, DRenderEvent, Camera);
|
|||
|
||||
DEFINE_FIELD_X(WorldEvent, DWorldEvent, IsSaveGame);
|
||||
DEFINE_FIELD_X(WorldEvent, DWorldEvent, Thing);
|
||||
DEFINE_FIELD_X(WorldEvent, DWorldEvent, Inflictor);
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DEventHandler, Create)
|
||||
|
@ -375,14 +395,24 @@ DEFINE_ACTION_FUNCTION(DStaticEventHandler, Unregister)
|
|||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLoaded)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
|
||||
|
||||
// ===========================================
|
||||
//
|
||||
// Event handlers
|
||||
//
|
||||
// ===========================================
|
||||
|
||||
static DWorldEvent* E_SetupWorldEvent()
|
||||
{
|
||||
static DWorldEvent* e = nullptr;
|
||||
if (!e) e = (DWorldEvent*)RUNTIME_CLASS(DWorldEvent)->CreateNew();
|
||||
e->IsSaveGame = savegamerestore;
|
||||
e->Thing = nullptr;
|
||||
e->Inflictor = nullptr;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -426,6 +456,48 @@ void DStaticEventHandler::WorldThingSpawned(AActor* actor)
|
|||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::WorldThingDied(AActor* actor, AActor* inflictor)
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldThingDied)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_WorldThingDied_VMPtr)
|
||||
return;
|
||||
DWorldEvent* e = E_SetupWorldEvent();
|
||||
e->Thing = actor;
|
||||
e->Inflictor = inflictor;
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, e };
|
||||
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::WorldThingDestroyed(AActor* actor)
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldThingDestroyed)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_WorldThingDestroyed_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::WorldLightning()
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldLightning)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_WorldLightning_VMPtr)
|
||||
return;
|
||||
DWorldEvent* e = E_SetupWorldEvent();
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, e };
|
||||
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static DRenderEvent* E_SetupRenderEvent()
|
||||
{
|
||||
static DRenderEvent* e = nullptr;
|
||||
|
|
13
src/events.h
13
src/events.h
|
@ -27,6 +27,12 @@ void E_WorldLoadedUnsafe();
|
|||
void E_WorldUnloadedUnsafe();
|
||||
// called around PostBeginPlay of each actor.
|
||||
void E_WorldThingSpawned(AActor* actor);
|
||||
// called after AActor::Die of each actor.
|
||||
void E_WorldThingDied(AActor* actor, AActor* inflictor);
|
||||
// called before AActor::Destroy of each actor.
|
||||
void E_WorldThingDestroyed(AActor* actor);
|
||||
// same as ACS SCRIPT_Lightning
|
||||
void E_WorldLightning();
|
||||
// called on each render frame once.
|
||||
void E_RenderFrame();
|
||||
|
||||
|
@ -77,6 +83,9 @@ public:
|
|||
virtual void WorldLoaded();
|
||||
virtual void WorldUnloaded();
|
||||
virtual void WorldThingSpawned(AActor*);
|
||||
virtual void WorldThingDied(AActor*, AActor*);
|
||||
virtual void WorldThingDestroyed(AActor*);
|
||||
virtual void WorldLightning();
|
||||
virtual void RenderFrame();
|
||||
};
|
||||
class DEventHandler : public DStaticEventHandler
|
||||
|
@ -141,11 +150,14 @@ public:
|
|||
bool IsSaveGame;
|
||||
// for thingspawned, thingdied, thingdestroyed
|
||||
AActor* Thing;
|
||||
// for thingdied
|
||||
AActor* Inflictor; // can be null
|
||||
|
||||
DWorldEvent()
|
||||
{
|
||||
IsSaveGame = false;
|
||||
Thing = nullptr;
|
||||
Inflictor = nullptr;
|
||||
}
|
||||
|
||||
void Serialize(FSerializer& arc) override
|
||||
|
@ -153,6 +165,7 @@ public:
|
|||
Super::Serialize(arc);
|
||||
arc("IsSaveGame", IsSaveGame);
|
||||
arc("Thing", Thing);
|
||||
arc("Inflictor", Inflictor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "a_morph.h"
|
||||
#include "virtual.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
static FRandom pr_obituary ("Obituary");
|
||||
static FRandom pr_botrespawn ("BotRespawn");
|
||||
|
@ -384,6 +385,9 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
target = source;
|
||||
}
|
||||
|
||||
// [ZZ] Fire WorldThingDied script hook.
|
||||
E_WorldThingDied(this, inflictor);
|
||||
|
||||
// [JM] Fire KILL type scripts for actor. Not needed for players, since they have the "DEATH" script type.
|
||||
if (!player && !(flags7 & MF7_NOKILLSCRIPTS) && ((flags7 & MF7_USEKILLSCRIPTS) || gameinfo.forcekillscripts))
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@ class WorldEvent : BaseEvent native
|
|||
native readonly bool IsSaveGame;
|
||||
// for thingspawned/thingdied/thingdestroyed
|
||||
native readonly Actor Thing;
|
||||
// for thingdied. can be null
|
||||
native readonly Actor Inflictor;
|
||||
}
|
||||
|
||||
class StaticEventHandler : Object native
|
||||
|
@ -33,6 +35,9 @@ class StaticEventHandler : Object native
|
|||
virtual native void WorldLoaded(WorldEvent e);
|
||||
virtual native void WorldUnloaded(WorldEvent e);
|
||||
virtual native void WorldThingSpawned(WorldEvent e);
|
||||
virtual native void WorldThingDied(WorldEvent e);
|
||||
virtual native void WorldThingDestroyed(WorldEvent e);
|
||||
virtual native void WorldLightning(WorldEvent e); // for the sake of completeness.
|
||||
|
||||
virtual native void RenderFrame(RenderEvent e);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue