From 5a74e79b929ddf1fb156c22d7a8b58d5e7397272 Mon Sep 17 00:00:00 2001 From: Boondorl <59555366+Boondorl@users.noreply.github.com> Date: Thu, 19 Jan 2023 19:58:04 -0500 Subject: [PATCH] Added bounce virtual --- src/playsim/actor.h | 5 +++++ src/playsim/p_map.cpp | 17 +++++++++++++++++ src/playsim/p_mobj.cpp | 26 ++++++++++++++++++++++++++ wadsrc/static/zscript/actors/actor.zs | 6 ++++++ 4 files changed, 54 insertions(+) diff --git a/src/playsim/actor.h b/src/playsim/actor.h index eea647477..6ebb7f1cd 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -850,6 +850,11 @@ public: // (virtual on the script side only) int SpecialMissileHit (AActor *victim); + // Called when bouncing to allow for custom behavior. + // Returns -1 for normal behavior, 0 to stop, and 1 to keep going. + // (virtual on the script side only) + int SpecialBounceHit(AActor* bounceMobj, line_t* bounceLine, secplane_t* bouncePlane); + // Returns true if it's okay to switch target to "other" after being attacked by it. bool CallOkayToSwitchTarget(AActor *other); bool OkayToSwitchTarget (AActor *other); diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index c9a0052f2..797feb8e7 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -3518,6 +3518,16 @@ bool FSlide::BounceWall(AActor *mo) } line = bestslideline; + if (mo->flags & MF_MISSILE) + { + switch (mo->SpecialBounceHit(nullptr, line, nullptr)) + { + case 1: return true; + case 0: return false; + default: break; + } + } + if (line->special == Line_Horizon || ((mo->BounceFlags & BOUNCE_NotOnSky) && line->hitSkyWall(mo))) { mo->SeeSound = mo->BounceSound = NO_SOUND; // it might make a sound otherwise @@ -3608,6 +3618,13 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) case 0: return false; default: break; } + + switch (mo->SpecialBounceHit(BlockingMobj, nullptr, nullptr)) + { + case 1: return true; + case 0: return false; + default: break; + } } //Don't go through all of this if the actor is reflective and wants things to pass through them. diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 1596989d0..bc0b85961 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -1546,6 +1546,17 @@ void AActor::PlayBounceSound(bool onfloor) bool AActor::FloorBounceMissile (secplane_t &plane) { + if (flags & MF_MISSILE) + { + switch (SpecialBounceHit(nullptr, nullptr, &plane)) + { + // This one is backwards for some reason... + case 1: return false; + case 0: return true; + default: break; + } + } + // [ZZ] if bouncing missile hits a damageable sector(plane), it dies if (P_ProjectileHitPlane(this, -1) && bouncecount > 0) { @@ -3197,6 +3208,21 @@ int AActor::SpecialMissileHit (AActor *victim) else return -1; } +// This virtual method only exists on the script side. +int AActor::SpecialBounceHit(AActor* bounceMobj, line_t* bounceLine, secplane_t* bouncePlane) +{ + IFVIRTUAL(AActor, SpecialBounceHit) + { + VMValue params[4] = { (DObject*)this, bounceMobj, bounceLine, bouncePlane }; + VMReturn ret; + int retval; + ret.IntAt(&retval); + VMCall(func, params, 4, &ret, 1); + return retval; + } + else return -1; +} + bool AActor::AdjustReflectionAngle (AActor *thing, DAngle &angle) { if (flags2 & MF2_DONTREFLECT) return true; diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 2601b7698..4e8e5977c 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -543,6 +543,12 @@ class Actor : Thinker native return -1; } + // This is called when a missile bounces off something. + virtual int SpecialBounceHit(Actor bounceMobj, Line bounceLine, SecPlane bouncePlane) + { + return -1; + } + // Called when the player presses 'use' and an actor is found, except if the // UseSpecial flag is set. Use level.ExecuteSpecial to call action specials // instead.