From 4848d465e39d04332e68e859876d413c5bfa3fd2 Mon Sep 17 00:00:00 2001 From: Ceikry Date: Thu, 22 Dec 2022 06:20:12 +0000 Subject: [PATCH] Fixed combat pathfinding bug that led to endless NPC "dancing" --- .../core/game/interaction/MovementPulse.java | 21 ++++++++++++++++++- .../game/node/entity/impl/WalkingQueue.java | 7 ++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Server/src/main/java/core/game/interaction/MovementPulse.java b/Server/src/main/java/core/game/interaction/MovementPulse.java index da462af5f..a13a7d047 100644 --- a/Server/src/main/java/core/game/interaction/MovementPulse.java +++ b/Server/src/main/java/core/game/interaction/MovementPulse.java @@ -18,6 +18,7 @@ import core.net.packet.out.ClearMinimapFlag; import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function2; import rs09.game.system.SystemLogger; +import rs09.game.world.GameWorld; import java.util.Deque; @@ -239,9 +240,12 @@ public abstract class MovementPulse extends Pulse { return; } boolean inside = isInsideEntity(mover.getLocation()); +/* This appears to have been a premature optimization that lead to a bug that would cause both entities + to completely stop moving mid-combat/mid-follow-dance/etc if (last != null && last.equals(destination.getLocation()) && !inside) { return; } +*/ Location loc = null; @@ -293,7 +297,22 @@ public abstract class MovementPulse extends Pulse { Path path = Pathfinder.find(mover, loc != null ? loc : destination, true, pathfinder); near = !path.isSuccessful() || path.isMoveNear(); interactLocation = mover.getLocation(); - if (!path.getPoints().isEmpty()) { + boolean canMove = true; + if (destination instanceof NPC || destination instanceof Player) { + Entity e = (Entity) destination; + Location l = e.getLocation(); + Deque npcPath = e.getWalkingQueue().getQueue(); + if (e.getWalkingQueue().hasPath() && e.getProperties().getCombatPulse().isRunning() && e.getProperties().getCombatPulse().getVictim() == mover) + canMove = false; + if (!canMove) { //If we normally shouldn't move, but the NPC's pathfinding is not letting them move, then move. + if (npcPath.size() == 1) { + Point pathElement = npcPath.peek(); + if (pathElement.getX() == l.getX() && pathElement.getY() == l.getY()) + canMove = true; + } + } + } + if (!path.getPoints().isEmpty() && canMove) { Point point = path.getPoints().getLast(); interactLocation = Location.create(point.getX(), point.getY(), mover.getLocation().getZ()); if (forceRun) { diff --git a/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java b/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java index fb8af9fe3..c24e792fd 100644 --- a/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java +++ b/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java @@ -8,6 +8,7 @@ import core.game.world.map.Location; import core.game.world.map.Point; import core.game.world.map.RegionManager; import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks; +import rs09.game.world.GameWorld; import java.util.Deque; import java.util.LinkedList; @@ -348,11 +349,7 @@ public final class WalkingQueue { * @return {@code True} if so. */ public boolean hasPath() { - if (!walkingQueue.isEmpty()) { - Point p = walkingQueue.peek(); - return p.getDirection() != null; - } - return false; + return !walkingQueue.isEmpty(); } /**