From 0adf6a52f5bd2f4b5eb20e21dfff03463103ab63 Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Sun, 27 Jan 2019 18:03:04 -0600 Subject: [PATCH] Added CheckReplacee. - Allows defining of what actor is replacing another for information. - If multiple arachnotrons, a modder can attribute them as being a replacer of Arachnotron itself, allowing A_BossDeath and GetReplacee to work with it. --- src/events.cpp | 27 +++++++++++++++++++++++++++ src/events.h | 10 ++++++++++ src/info.cpp | 10 ++++++++++ wadsrc/static/zscript/events.txt | 10 +++++++++- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/events.cpp b/src/events.cpp index 5b1ee9111..9b7926953 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -536,6 +536,14 @@ bool E_CheckReplacement( PClassActor *replacee, PClassActor **replacement ) return final; } +bool E_CheckReplacee(PClassActor **replacee, PClassActor *replacement) +{ + bool final = false; + for (DStaticEventHandler *handler = E_FirstEventHandler; handler; handler = handler->next) + handler->CheckReplacee(replacee, replacement, &final); + return final; +} + void E_NewGame(EventHandlerType handlerType) { bool isStatic = handlerType == EventHandlerType::Global; @@ -627,6 +635,10 @@ DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacee) DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacement) DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, IsFinal) +DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacee) +DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacement) +DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, IsFinal) + DEFINE_ACTION_FUNCTION(DStaticEventHandler, SetOrder) { PARAM_SELF_PROLOGUE(DStaticEventHandler); @@ -1192,6 +1204,21 @@ void DStaticEventHandler::CheckReplacement( PClassActor *replacee, PClassActor * } } +void DStaticEventHandler::CheckReplacee(PClassActor **replacee, PClassActor *replacement, bool *final) +{ + IFVIRTUAL(DStaticEventHandler, CheckReplacee) + { + // don't create excessive DObjects if not going to be processed anyway + if (isEmpty(func)) return; + FReplacedEvent e = { *replacee, replacement, *final }; + VMValue params[2] = { (DStaticEventHandler*)this, &e }; + VMCall(func, params, 2, nullptr, 0); + if (e.Replacee != replacement) // prevent infinite recursion + *replacee = e.Replacee; + *final = e.IsFinal; + } +} + void DStaticEventHandler::NewGame() { IFVIRTUAL(DStaticEventHandler, NewGame) diff --git a/src/events.h b/src/events.h index 91cf37888..dbd408a42 100755 --- a/src/events.h +++ b/src/events.h @@ -81,6 +81,8 @@ void E_Console(int player, FString name, int arg1, int arg2, int arg3, bool manu // called when looking up the replacement for an actor class bool E_CheckReplacement(PClassActor* replacee, PClassActor** replacement); +// called when looking up the replaced for an actor class +bool E_CheckReplacee(PClassActor** replacee, PClassActor* replacement); // called on new game void E_NewGame(EventHandlerType handlerType); @@ -187,6 +189,7 @@ public: // void CheckReplacement(PClassActor* replacee, PClassActor** replacement, bool* final); + void CheckReplacee(PClassActor** replacee, PClassActor* replacement, bool* final); // void NewGame(); @@ -301,4 +304,11 @@ struct FReplaceEvent bool IsFinal; }; +struct FReplacedEvent +{ + PClassActor* Replacee; + PClassActor* Replacement; + bool IsFinal; +}; + #endif diff --git a/src/info.cpp b/src/info.cpp index 761fbe18b..564571719 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -600,6 +600,16 @@ PClassActor *PClassActor::GetReplacee(bool lookskill) } } PClassActor *savedrep = ActorInfo()->Replacee; + // [MC] Same code as CheckReplacement but turned around so modders can indicate + // what monsters spawn from which entity. I.e. instead of a randomspawner + // showing up, one can assign an Arachnotron as the one being replaced + // so functions like CheckReplacee and A_BossDeath can actually work, given + // modders set it up that way. + if (E_CheckReplacee(&savedrep, this)) + { + // [MK] the replacement is final, so don't continue with the chain + return savedrep ? savedrep : this; + } if (savedrep == nullptr && (!lookskill || skillrepname == NAME_None)) { return this; diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt index 4dd256710..19f29c202 100755 --- a/wadsrc/static/zscript/events.txt +++ b/wadsrc/static/zscript/events.txt @@ -300,6 +300,13 @@ struct ReplaceEvent native version("2.4") native bool IsFinal; } +struct ReplacedEvent native version("3.7") +{ + native Class Replacee; + native readonly Class Replacement; + native bool IsFinal; +} + class StaticEventHandler : Object native play version("2.4") { // static event handlers CAN register other static event handlers. @@ -312,7 +319,7 @@ class StaticEventHandler : Object native play version("2.4") virtual void OnUnregister() {} // actual handlers are here -virtual void WorldLoaded(WorldEvent e) {} + virtual void WorldLoaded(WorldEvent e) {} virtual void WorldUnloaded(WorldEvent e) {} virtual void WorldThingSpawned(WorldEvent e) {} virtual void WorldThingDied(WorldEvent e) {} @@ -348,6 +355,7 @@ virtual void WorldLoaded(WorldEvent e) {} // virtual void CheckReplacement(ReplaceEvent e) {} + virtual void CheckReplacee(ReplacedEvent e) {} // virtual void NewGame() {}