From 0656916bf2a9169488beee17392c7c912af8faaf Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sat, 24 Mar 2018 15:59:20 +0100 Subject: [PATCH] Add WorldLinePreActivated to override line activation, as a counterpart to WorldLineActivated. --- src/events.cpp | 25 +++++++++++++++++++++++++ src/events.h | 6 +++++- src/p_spec.cpp | 5 +++++ wadsrc/static/zscript/events.txt | 4 +++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/events.cpp b/src/events.cpp index 8b6d1e9ec..7ef72b0db 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -413,6 +413,12 @@ void E_WorldThingDestroyed(AActor* actor) handler->WorldThingDestroyed(actor); } +void E_WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate) +{ + for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) + handler->WorldLinePreActivated(line, actor, shouldactivate); +} + void E_WorldLineActivated(line_t* line, AActor* actor) { for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) @@ -548,6 +554,7 @@ DEFINE_FIELD_X(WorldEvent, FWorldEvent, DamageType); DEFINE_FIELD_X(WorldEvent, FWorldEvent, DamageFlags); DEFINE_FIELD_X(WorldEvent, FWorldEvent, DamageAngle); DEFINE_FIELD_X(WorldEvent, FWorldEvent, ActivatedLine); +DEFINE_FIELD_X(WorldEvent, FWorldEvent, ShouldActivate); DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, PlayerNumber); DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, IsReturn); @@ -634,6 +641,7 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingRevived) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDamaged) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed) +DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLinePreActivated) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLineActivated) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick) @@ -796,6 +804,23 @@ void DStaticEventHandler::WorldThingDestroyed(AActor* actor) } } +void DStaticEventHandler::WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate) +{ + IFVIRTUAL(DStaticEventHandler, WorldLinePreActivated) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_WorldLinePreActivated_VMPtr) + return; + FWorldEvent e = E_SetupWorldEvent(); + e.Thing = actor; + e.ActivatedLine = line; + e.ShouldActivate = *shouldactivate; + VMValue params[2] = { (DStaticEventHandler*)this, &e }; + VMCall(func, params, 2, nullptr, 0); + *shouldactivate = e.ShouldActivate; + } +} + void DStaticEventHandler::WorldLineActivated(line_t* line, AActor* actor) { IFVIRTUAL(DStaticEventHandler, WorldLineActivated) diff --git a/src/events.h b/src/events.h index bdc35d4aa..547ab4829 100755 --- a/src/events.h +++ b/src/events.h @@ -40,6 +40,8 @@ void E_WorldThingRevived(AActor* actor); void E_WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle); // called before AActor::Destroy of each actor. void E_WorldThingDestroyed(AActor* actor); +// called in P_ActivateLine before executing special, set shouldactivate to false to prevent activation. +void E_WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate); // called in P_ActivateLine after successful special execution. void E_WorldLineActivated(line_t* line, AActor* actor); // same as ACS SCRIPT_Lightning @@ -141,6 +143,7 @@ public: void WorldThingRevived(AActor*); void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle); void WorldThingDestroyed(AActor*); + void WorldLinePreActivated(line_t*, AActor*, bool*); void WorldLineActivated(line_t*, AActor*); void WorldLightning(); void WorldTick(); @@ -198,8 +201,9 @@ struct FWorldEvent FName DamageType; int DamageFlags = 0; DAngle DamageAngle; - // for lineactivated + // for line(pre)activated line_t* ActivatedLine = nullptr; + bool ShouldActivate = true; }; struct FPlayerEvent diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 36d1bb11c..2d7d3ddc0 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -189,6 +189,11 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe return false; } + // [MK] Use WorldLinePreActivated to decide if activation should continue + bool shouldactivate = true; + E_WorldLinePreActivated(line, mo, &shouldactivate); + if ( !shouldactivate ) return false; + bool remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false; diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt index 16e88f9a6..1aa2e3b59 100755 --- a/wadsrc/static/zscript/events.txt +++ b/wadsrc/static/zscript/events.txt @@ -25,8 +25,9 @@ struct WorldEvent native play version("2.4") native readonly Name DamageType; native readonly EDmgFlags DamageFlags; native readonly double DamageAngle; - // for lineactivated + // for line(pre)activated native readonly Line ActivatedLine; + native bool ShouldActivate; } struct PlayerEvent native play version("2.4") @@ -302,6 +303,7 @@ class StaticEventHandler : Object native play version("2.4") virtual native void WorldThingRevived(WorldEvent e); virtual native void WorldThingDamaged(WorldEvent e); virtual native void WorldThingDestroyed(WorldEvent e); + virtual native void WorldLinePreActivated(WorldEvent e); virtual native void WorldLineActivated(WorldEvent e); virtual native void WorldLightning(WorldEvent e); // for the sake of completeness. virtual native void WorldTick();