From bb862098ea4ae72b21f9ea0c2a8d8c7a83aa2357 Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Sun, 27 Sep 2020 16:15:58 -0500 Subject: [PATCH] Added CanCrossLine virtual for actors. - Called last after all other line checks occur. Returning false means the actor cannot cross that line. --- src/playsim/p_map.cpp | 39 +++++++++++++++++++++++++++ wadsrc/static/zscript/actors/actor.zs | 6 +++++ 2 files changed, 45 insertions(+) diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index 1dd5d55781..5d0017bffa 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -155,6 +155,38 @@ bool P_CanCollideWith(AActor *tmthing, AActor *thing) return true; } +//========================================================================== +// +// CanCrossLine +// +// Checks if an actor can cross a line after all checks are processed. +// If false, the line blocks them. +//========================================================================== + +bool P_CanCrossLine(AActor *mo, line_t *line, int side) +{ + static unsigned VIndex = ~0u; + if (VIndex == ~0u) + { + VIndex = GetVirtualIndex(RUNTIME_CLASS(AActor), "CanCrossLine"); + assert(VIndex != ~0u); + } + + VMValue params[4] = { mo, line, side, false }; + VMReturn ret; + int retval; + ret.IntAt(&retval); + + auto clss = mo->GetClass(); + VMFunction *func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr; + if (func != nullptr) + { + VMCall(func, params, 4, &ret, 1); + return retval; + } + return true; +} + //========================================================================== // // FindRefPoint @@ -953,6 +985,13 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec } } + if (!P_CanCrossLine(tm.thing, ld, P_PointOnLineSide(cres.Position, ld))) + { + if (wasfit) + tm.thing->BlockingLine = ld; + + return false; + } // If the floor planes on both sides match we should recalculate open.bottom at the actual position we are checking // This is to avoid bumpy movement when crossing a linedef with the same slope on both sides. // This should never narrow down the opening, though, only widen it. diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 96d60b7616..2972055989 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -501,6 +501,12 @@ class Actor : Thinker native return true; } + // Called by PIT_CheckLine to check if an actor can cross a line. + virtual bool CanCrossLine(Line crossing, int side) + { + return true; + } + // Called by revival/resurrection to check if one can resurrect the other. // "other" can be null when not passive. virtual bool CanResurrect(Actor other, bool passive)