From 063239d7b9e6164095366b70cb11a31ac389a5c0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 21 Nov 2024 01:56:44 +0600 Subject: [PATCH] Add WorldRailgunPreFired for railgun attacks Add AttackLineFlags for WorldHitscanPreFired Indentation fixes in event.zs --- src/events.cpp | 57 +++++++++++++++++++++++++++++++-- src/events.h | 6 ++++ src/playsim/p_map.cpp | 2 +- wadsrc/static/zscript/events.zs | 21 ++++++------ 4 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/events.cpp b/src/events.cpp index 2f7b12091d..88f0a2f821 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -719,6 +719,27 @@ bool EventManager::WorldHitscanPreFired(AActor* actor, DAngle angle, double dist return ret; } +bool EventManager::WorldRailgunPreFired(FName damageType, PClassActor* pufftype, FRailParams* param) +{ + auto actor = param->source; + + // don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever. + if (actor->ObjectFlags & OF_EuthanizeMe) + return false; + + bool ret = false; + + if (ShouldCallStatic(true)) ret = staticEventManager.WorldRailgunPreFired(damageType, pufftype, param); + + if (!ret) + { + for (DStaticEventHandler* handler = FirstEventHandler; handler && ret == false; handler = handler->next) + ret = handler->WorldRailgunPreFired(damageType, pufftype, param); + } + + return ret; +} + void EventManager::WorldHitscanFired(AActor* actor, const DVector3& AttackPos, const DVector3& DamagePosition, AActor* Inflictor, int flags) { // don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever. @@ -1064,6 +1085,8 @@ DEFINE_FIELD_X(WorldEvent, FWorldEvent, AttackOffsetForward); DEFINE_FIELD_X(WorldEvent, FWorldEvent, AttackOffsetSide); DEFINE_FIELD_X(WorldEvent, FWorldEvent, AttackZ); DEFINE_FIELD_X(WorldEvent, FWorldEvent, AttackPuffType); +DEFINE_FIELD_X(WorldEvent, FWorldEvent, RailParams); +DEFINE_FIELD_X(WorldEvent, FWorldEvent, AttackLineFlags); DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, PlayerNumber); DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, IsReturn); @@ -1784,7 +1807,37 @@ bool DStaticEventHandler::WorldHitscanPreFired(AActor* actor, DAngle angle, doub e.AttackOffsetForward = offsetforward; e.AttackOffsetSide = offsetside; e.AttackZ = sz; - e.DamageFlags = flags; + e.AttackLineFlags = flags; + int processed; + VMReturn results[1] = { &processed }; + VMValue params[2] = { (DStaticEventHandler*)this, &e }; + VMCall(func, params, 2, results, 1); + return !!processed; + } + + return false; +} + +bool DStaticEventHandler::WorldRailgunPreFired(FName damageType, PClassActor* pufftype, FRailParams* param) +{ + IFVIRTUAL(DStaticEventHandler, WorldRailgunPreFired) + { + // don't create excessive DObjects if not going to be processed anyway + if (isEmpty(func)) return false; + FWorldEvent e = owner->SetupWorldEvent(); + e.Thing = param->source; + e.AttackPuffType = pufftype; + e.DamageType = damageType; + e.Damage = param->damage; + e.AttackOffsetForward = 0; + e.AttackOffsetSide = param->offset_xy; + e.AttackDistance = param->distance; + e.AttackZ = param->offset_z; + e.AttackAngle = e.Thing->Angles.Yaw + param->angleoffset; + e.AttackPitch = e.Thing->Angles.Pitch + param->pitchoffset; + e.RailParams = *param; + e.RailParams.puff = pufftype; + int processed; VMReturn results[1] = { &processed }; VMValue params[2] = { (DStaticEventHandler*)this, &e }; @@ -1806,7 +1859,7 @@ void DStaticEventHandler::WorldHitscanFired(AActor* actor, const DVector3& Attac e.AttackPos = AttackPos; e.DamagePosition = DamagePosition; e.Inflictor = Inflictor; - e.DamageFlags = flags; + e.AttackLineFlags = flags; VMValue params[2] = { (DStaticEventHandler*)this, &e }; VMCall(func, params, 2, nullptr, 0); } diff --git a/src/events.h b/src/events.h index c3d05d4853..8a30bdfed4 100644 --- a/src/events.h +++ b/src/events.h @@ -4,6 +4,7 @@ #include "dobject.h" #include "serializer.h" #include "d_event.h" +#include "p_local.h" #include "sbar.h" #include "info.h" #include "vm.h" @@ -312,6 +313,7 @@ public: void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle); void WorldThingDestroyed(AActor* actor); bool WorldHitscanPreFired(AActor* actor, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, double sz, double offsetforward, double offsetside); + bool WorldRailgunPreFired(FName damageType, PClassActor* pufftype, FRailParams* param); void WorldHitscanFired(AActor* actor, const DVector3& AttackPos, const DVector3& DamagePosition, AActor* Inflictor, int flags); void WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate); void WorldLineActivated(line_t* line, AActor* actor, int activationType); @@ -403,6 +405,8 @@ struct FWorldEvent double AttackOffsetSide = 0; double AttackZ = 0; PClassActor* AttackPuffType = nullptr; + FRailParams RailParams; + int AttackLineFlags = 0; }; struct FPlayerEvent @@ -481,6 +485,8 @@ struct EventManager bool WorldHitscanPreFired(AActor* actor, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, double sz, double offsetforward, double offsetside); // called when a hitscan attack has been fired void WorldHitscanFired(AActor* actor, const DVector3& AttackPos, const DVector3& DamagePosition, AActor* Inflictor, int flags); + // called when a railgun attack has been fired (can be overridden to block it) + bool WorldRailgunPreFired(FName damageType, PClassActor* pufftype, FRailParams* param); // called inside AActor::Grind just before the corpse is destroyed void WorldThingGround(AActor* actor, FState* st); // called after AActor::Revive. diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index 7da6ba5152..f4f85c8ba1 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -5416,7 +5416,7 @@ void P_RailAttack(FRailParams *p) // disabled because not complete yet. flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? TRACE_ReportPortals : TRACE_PCross | TRACE_Impact | TRACE_ReportPortals; - if (source->Level->localEventManager->WorldHitscanPreFired(source, source->Angles.Yaw + p->angleoffset, p->distance, source->Angles.Pitch + p->pitchoffset, p->damage, damagetype, puffclass, flags, p->offset_z, 0, p->offset_xy)) + if (source->Level->localEventManager->WorldRailgunPreFired(damagetype, puffclass, p)) { return; } diff --git a/wadsrc/static/zscript/events.zs b/wadsrc/static/zscript/events.zs index 72cf23a51a..cc83ad28ae 100644 --- a/wadsrc/static/zscript/events.zs +++ b/wadsrc/static/zscript/events.zs @@ -97,14 +97,16 @@ struct WorldEvent native play version("2.4") native readonly bool DamageIsRadius; native int NewDamage; native readonly State CrushedState; - native readonly double AttackAngle; - native readonly double AttackPitch; - native readonly double AttackDistance; - native readonly vector3 AttackPos; - native readonly double AttackOffsetForward; - native readonly double AttackOffsetSide; - native readonly double AttackZ; - native readonly class AttackPuffType; + native readonly int AttackLineFlags; + native readonly double AttackAngle; + native readonly double AttackPitch; + native readonly double AttackDistance; + native readonly vector3 AttackPos; + native readonly double AttackOffsetForward; + native readonly double AttackOffsetSide; + native readonly double AttackZ; + native readonly class AttackPuffType; + native readonly FRailParams RailParams; } struct PlayerEvent native play version("2.4") @@ -163,7 +165,8 @@ class StaticEventHandler : Object native play version("2.4") virtual void WorldThingRevived(WorldEvent e) {} virtual void WorldThingDamaged(WorldEvent e) {} virtual void WorldThingDestroyed(WorldEvent e) {} - virtual bool WorldHitscanPreFired(WorldEvent e) { return false; } + virtual bool WorldHitscanPreFired(WorldEvent e) { return false; } + virtual bool WorldRailgunPreFired(WorldEvent e) { return false; } virtual void WorldHitscanFired(WorldEvent e) {} virtual void WorldLinePreActivated(WorldEvent e) {} virtual void WorldLineActivated(WorldEvent e) {}