mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
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:
parent
257ddb520a
commit
d71af3683a
3 changed files with 32 additions and 17 deletions
|
@ -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--;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue