Added CheckReplacement to event handlers, a function inspired by its namesake in Unreal's Mutator class.
Performs runtime replacement of actor classes. Takes priority over the "replaces" keyword in both DECORATE and ZScript.
This commit is contained in:
parent
7d40edd6ac
commit
e18b17217f
4 changed files with 51 additions and 1 deletions
|
|
@ -38,6 +38,7 @@
|
|||
#include "actor.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "d_net.h"
|
||||
#include "info.h"
|
||||
|
||||
DStaticEventHandler* E_FirstEventHandler = nullptr;
|
||||
DStaticEventHandler* E_LastEventHandler = nullptr;
|
||||
|
|
@ -506,6 +507,12 @@ bool E_CheckRequireMouse()
|
|||
return false;
|
||||
}
|
||||
|
||||
void E_CheckReplacement( PClassActor *replacee, PClassActor **replacement )
|
||||
{
|
||||
for (DStaticEventHandler *handler = E_FirstEventHandler; handler; handler = handler->next)
|
||||
handler->CheckReplacement(replacee,replacement);
|
||||
}
|
||||
|
||||
// normal event loopers (non-special, argument-less)
|
||||
DEFINE_EVENT_LOOPER(RenderFrame)
|
||||
DEFINE_EVENT_LOOPER(WorldLightning)
|
||||
|
|
@ -571,6 +578,9 @@ DEFINE_FIELD_X(ConsoleEvent, FConsoleEvent, Name)
|
|||
DEFINE_FIELD_X(ConsoleEvent, FConsoleEvent, Args)
|
||||
DEFINE_FIELD_X(ConsoleEvent, FConsoleEvent, IsManual)
|
||||
|
||||
DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacee)
|
||||
DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacement)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DStaticEventHandler, SetOrder)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DStaticEventHandler);
|
||||
|
|
@ -653,6 +663,8 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, PostUiTick);
|
|||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, ConsoleProcess);
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, NetworkProcess);
|
||||
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, CheckReplacement);
|
||||
|
||||
// ===========================================
|
||||
//
|
||||
// Event handlers
|
||||
|
|
@ -1123,6 +1135,21 @@ void DStaticEventHandler::ConsoleProcess(int player, FString name, int arg1, int
|
|||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::CheckReplacement( PClassActor *replacee, PClassActor **replacement )
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, CheckReplacement)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_CheckReplacement_VMPtr)
|
||||
return;
|
||||
FReplaceEvent e = { replacee, *replacement };
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, &e };
|
||||
VMCall(func, params, 2, nullptr, 0);
|
||||
if ( e.Replacement != replacee ) // prevent infinite recursion
|
||||
*replacement = e.Replacement;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DStaticEventHandler::OnDestroy()
|
||||
{
|
||||
|
|
|
|||
12
src/events.h
12
src/events.h
|
|
@ -69,6 +69,9 @@ bool E_Responder(const event_t* ev); // splits events into InputProcess and UiPr
|
|||
// this executes on console/net events.
|
||||
void E_Console(int player, FString name, int arg1, int arg2, int arg3, bool manual);
|
||||
|
||||
// called when looking up the replacement for an actor class
|
||||
void E_CheckReplacement(PClassActor* replacee, PClassActor** replacement);
|
||||
|
||||
// send networked event. unified function.
|
||||
bool E_SendNetworkEvent(FString name, int arg1, int arg2, int arg3, bool manual);
|
||||
|
||||
|
|
@ -166,6 +169,9 @@ public:
|
|||
|
||||
//
|
||||
void ConsoleProcess(int player, FString name, int arg1, int arg2, int arg3, bool manual);
|
||||
|
||||
//
|
||||
void CheckReplacement(PClassActor* replacee, PClassActor** replacement);
|
||||
};
|
||||
class DEventHandler : public DStaticEventHandler
|
||||
{
|
||||
|
|
@ -262,4 +268,10 @@ struct FConsoleEvent
|
|||
bool IsManual;
|
||||
};
|
||||
|
||||
struct FReplaceEvent
|
||||
{
|
||||
PClassActor* Replacee;
|
||||
PClassActor* Replacement;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -425,7 +425,9 @@ PClassActor *PClassActor::GetReplacement(bool lookskill)
|
|||
lookskill = false; skillrepname = NAME_None;
|
||||
}
|
||||
}
|
||||
auto Replacement = ActorInfo()->Replacement;
|
||||
// [MK] ZScript replacement through Event Handlers, has priority over others
|
||||
PClassActor *Replacement = ActorInfo()->Replacement;
|
||||
E_CheckReplacement(this,&Replacement);
|
||||
if (Replacement == nullptr && (!lookskill || skillrepname == NAME_None))
|
||||
{
|
||||
return this;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue