From d71af3683a59bab8335a8e6d122d05fba7ba11a2 Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Sat, 24 Feb 2024 19:44:57 -0600 Subject: [PATCH] Clear the path instead of advancing the node when crossing portals. - If an actor crosses back over a portal because they're blocked, it will result in false positives. - Fixed nodes not being targeted for aim direction. --- src/playsim/p_enemy.cpp | 22 +++++++++++++++------- src/playsim/p_map.cpp | 11 ++++++----- wadsrc/static/zscript/actors/actor.zs | 16 +++++++++++----- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index 8c84931f92..0dc3fd0ef5 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -951,13 +951,13 @@ void P_DoNewChaseDir (AActor *actor, double deltax, double deltay) // //============================================================================= -void P_NewChaseDir(AActor * actor) +void DoNewChaseDir(AActor * actor, bool node) { DVector2 delta; actor->strafecount = 0; - if ((actor->flags5&MF5_CHASEGOAL || actor->goal == actor->target) && actor->goal!=NULL) + if ((node || actor->flags5&MF5_CHASEGOAL || actor->goal == actor->target) && actor->goal != nullptr) { delta = actor->Vec2To(actor->goal); } @@ -1096,6 +1096,11 @@ void P_NewChaseDir(AActor * actor) } +void P_NewChaseDir(AActor* actor) +{ + DoNewChaseDir(actor, false); +} + //============================================================================= // // P_RandomChaseDir @@ -2579,7 +2584,11 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi } // [RH] Don't attack if just moving toward goal - if (actor->target == actor->goal || (actor->flags5&MF5_CHASEGOAL && actor->goal != nullptr)) + static const PClass* nodeCls = PClass::FindClass(NAME_PathNode); + bool pnode = (actor->goal && nodeCls->IsAncestorOf(actor->goal->GetClass())); + + if (!pnode && + (actor->target == actor->goal || (actor->flags5&MF5_CHASEGOAL && actor->goal))) { AActor * savedtarget = actor->target; actor->target = actor->goal; @@ -2727,8 +2736,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi if (sight == 0) { - static const PClass* nodeCls = PClass::FindClass(NAME_PathNode); - if (actor->goal && !(actor->goal->flags & MF_AMBUSH) && nodeCls->IsAncestorOf(actor->goal->GetClass())) + if (pnode && !(actor->goal->flags & MF_AMBUSH)) { AActor* temp = actor->target; actor->target = actor->goal; @@ -2766,7 +2774,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi // chase towards player if ((--actor->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_SmartMove(actor) && !(flags & CHF_STOPIFBLOCKED))) { - P_NewChaseDir(actor); + DoNewChaseDir(actor, pnode); } // if the move was illegal, reset it // (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!) @@ -2782,7 +2790,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi } } if (!(flags & CHF_STOPIFBLOCKED)) - P_NewChaseDir(actor); + DoNewChaseDir(actor, pnode); } } else if (dontmove && actor->movecount > 0) actor->movecount--; diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index 57e3b08f07..4728af0119 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -2536,8 +2536,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, // Check for crossed portals - bool portalcrossed; - portalcrossed = false; + bool portalcrossed, nodecall; + nodecall = portalcrossed = false; while (true) { @@ -2582,6 +2582,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, thing->Prev += port->mDisplacement; thing->LinkToWorld(&ctx); P_FindFloorCeiling(thing); + thing->ClearPath(); portalcrossed = true; tm.portalstep = false; tm.pos += port->mDisplacement; @@ -2611,9 +2612,9 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, P_TranslatePortalVXVY(ld, thing->Vel.X, thing->Vel.Y); P_TranslatePortalAngle(ld, thing->Angles.Yaw); thing->LinkToWorld(&ctx); - P_FindFloorCeiling(thing); + P_FindFloorCeiling(thing); + thing->ClearPath(); thing->ClearInterpolation(); - thing->CallReachedNode(thing->goal); portalcrossed = true; tm.portalstep = false; } @@ -2770,7 +2771,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, thing->Sector = thing->Level->PointInSector(thing->Pos()); thing->PrevPortalGroup = thing->Sector->PortalGroup; thing->LinkToWorld(&ctx); - + thing->ClearPath(); P_FindFloorCeiling(thing); } diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 565ddd6434..9c694e38ff 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -802,10 +802,13 @@ class Actor : Thinker native native clearscope bool CanPathfind() const; virtual void ReachedNode(Actor mo) { - if (!mo && !goal) - return; + if (!mo) + { + if (!goal) + return; + mo = goal; + } - mo = goal; let node = PathNode(mo); if (!node || !target || (!bKEEPPATH && CheckSight(target))) { @@ -835,7 +838,7 @@ class Actor : Thinker native if (i >= end) ClearPath(); - + } // Return true to mark the node as ineligible for constructing a path along. @@ -847,12 +850,15 @@ class Actor : Thinker native // STANDSTILL flag is used to require the actor to be bigger instead of smaller. double r = node.Scale.X; double h = node.Scale.Y; + + if (r <= 0.0 && h <= 0.0) + return false; // Perfect fit. if (radius == r && height == h) return false; - if ((0.0 < r && r < radius) || (0.0 < h && h < height)) + if ((r < radius) || (h < height)) return !node.bSTANDSTILL; return false;