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.
This commit is contained in:
Major Cooke 2024-02-24 19:44:57 -06:00 committed by Rachael Alexanderson
parent 257ddb520a
commit d71af3683a
3 changed files with 32 additions and 17 deletions

View file

@ -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; DVector2 delta;
actor->strafecount = 0; 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); delta = actor->Vec2To(actor->goal);
} }
@ -1096,6 +1096,11 @@ void P_NewChaseDir(AActor * actor)
} }
void P_NewChaseDir(AActor* actor)
{
DoNewChaseDir(actor, false);
}
//============================================================================= //=============================================================================
// //
// P_RandomChaseDir // 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 // [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; AActor * savedtarget = actor->target;
actor->target = actor->goal; actor->target = actor->goal;
@ -2727,8 +2736,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
if (sight == 0) if (sight == 0)
{ {
static const PClass* nodeCls = PClass::FindClass(NAME_PathNode); if (pnode && !(actor->goal->flags & MF_AMBUSH))
if (actor->goal && !(actor->goal->flags & MF_AMBUSH) && nodeCls->IsAncestorOf(actor->goal->GetClass()))
{ {
AActor* temp = actor->target; AActor* temp = actor->target;
actor->target = actor->goal; actor->target = actor->goal;
@ -2766,7 +2774,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
// chase towards player // chase towards player
if ((--actor->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_SmartMove(actor) && !(flags & CHF_STOPIFBLOCKED))) 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 // if the move was illegal, reset it
// (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!) // (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)) if (!(flags & CHF_STOPIFBLOCKED))
P_NewChaseDir(actor); DoNewChaseDir(actor, pnode);
} }
} }
else if (dontmove && actor->movecount > 0) actor->movecount--; else if (dontmove && actor->movecount > 0) actor->movecount--;

View file

@ -2536,8 +2536,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
// Check for crossed portals // Check for crossed portals
bool portalcrossed; bool portalcrossed, nodecall;
portalcrossed = false; nodecall = portalcrossed = false;
while (true) while (true)
{ {
@ -2582,6 +2582,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
thing->Prev += port->mDisplacement; thing->Prev += port->mDisplacement;
thing->LinkToWorld(&ctx); thing->LinkToWorld(&ctx);
P_FindFloorCeiling(thing); P_FindFloorCeiling(thing);
thing->ClearPath();
portalcrossed = true; portalcrossed = true;
tm.portalstep = false; tm.portalstep = false;
tm.pos += port->mDisplacement; tm.pos += port->mDisplacement;
@ -2612,8 +2613,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
P_TranslatePortalAngle(ld, thing->Angles.Yaw); P_TranslatePortalAngle(ld, thing->Angles.Yaw);
thing->LinkToWorld(&ctx); thing->LinkToWorld(&ctx);
P_FindFloorCeiling(thing); P_FindFloorCeiling(thing);
thing->ClearPath();
thing->ClearInterpolation(); thing->ClearInterpolation();
thing->CallReachedNode(thing->goal);
portalcrossed = true; portalcrossed = true;
tm.portalstep = false; tm.portalstep = false;
} }
@ -2770,7 +2771,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
thing->Sector = thing->Level->PointInSector(thing->Pos()); thing->Sector = thing->Level->PointInSector(thing->Pos());
thing->PrevPortalGroup = thing->Sector->PortalGroup; thing->PrevPortalGroup = thing->Sector->PortalGroup;
thing->LinkToWorld(&ctx); thing->LinkToWorld(&ctx);
thing->ClearPath();
P_FindFloorCeiling(thing); P_FindFloorCeiling(thing);
} }

View file

@ -802,10 +802,13 @@ class Actor : Thinker native
native clearscope bool CanPathfind() const; native clearscope bool CanPathfind() const;
virtual void ReachedNode(Actor mo) virtual void ReachedNode(Actor mo)
{ {
if (!mo && !goal) if (!mo)
{
if (!goal)
return; return;
mo = goal; mo = goal;
}
let node = PathNode(mo); let node = PathNode(mo);
if (!node || !target || (!bKEEPPATH && CheckSight(target))) if (!node || !target || (!bKEEPPATH && CheckSight(target)))
{ {
@ -848,11 +851,14 @@ class Actor : Thinker native
double r = node.Scale.X; double r = node.Scale.X;
double h = node.Scale.Y; double h = node.Scale.Y;
if (r <= 0.0 && h <= 0.0)
return false;
// Perfect fit. // Perfect fit.
if (radius == r && height == h) if (radius == r && height == h)
return false; return false;
if ((0.0 < r && r < radius) || (0.0 < h && h < height)) if ((r < radius) || (h < height))
return !node.bSTANDSTILL; return !node.bSTANDSTILL;
return false; return false;