diff --git a/game/src/main/org/apollo/game/model/entity/path/AStarPathfindingAlgorithm.java b/game/src/main/org/apollo/game/model/entity/path/AStarPathfindingAlgorithm.java
index 5f643f8f..b6609b2e 100644
--- a/game/src/main/org/apollo/game/model/entity/path/AStarPathfindingAlgorithm.java
+++ b/game/src/main/org/apollo/game/model/entity/path/AStarPathfindingAlgorithm.java
@@ -1,140 +1,140 @@
-package org.apollo.game.model.entity.path;
-
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.PriorityQueue;
-import java.util.Queue;
-import java.util.Set;
-
-import org.apollo.game.model.Position;
-import org.apollo.game.model.area.RegionRepository;
-
-/**
- * A {@link PathfindingAlgorithm} that utilises the A* algorithm to find a solution.
- *
- * This implementation utilises a {@link PriorityQueue} of open {@link Node}s, in addition to the usual {@link HashSet}.
- * This allows for logarithmic-time finding of the cheapest element (as opposed to the linear time associated with
- * iterating over the set), whilst still maintaining the constant time contains and remove of the set.
- *
- * This implementation also avoids the linear-time removal from the queue by polling until the first open node is found
- * when identifying the cheapest node.
- *
- * @author Major
- */
-public final class AStarPathfindingAlgorithm extends PathfindingAlgorithm {
-
- /**
- * The heuristic.
- */
- private final Heuristic heuristic;
-
- /**
- * Creates the A* pathfinding algorithm with the specified heuristic.
- *
- * @param repository The {@link RegionRepository}.
- * @param heuristic The heuristic.
- */
- public AStarPathfindingAlgorithm(RegionRepository repository, Heuristic heuristic) {
- super(repository);
- this.heuristic = heuristic;
- }
-
- @Override
- public Deque find(Position origin, Position target) {
- Map nodes = new HashMap<>();
- Node start = new Node(origin), end = new Node(target);
- nodes.put(origin, start);
- nodes.put(target, end);
-
- Set open = new HashSet<>();
- Queue sorted = new PriorityQueue<>();
- open.add(start);
- sorted.add(start);
-
- do {
- Node active = getCheapest(sorted);
- Position position = active.getPosition();
-
- if (position.equals(target)) {
- break;
- }
-
- open.remove(active);
- active.close();
-
- int x = position.getX(), y = position.getY();
- for (int nextX = x - 1; x <= x + 1; nextX++) {
- for (int nextY = y - 1; y <= y + 1; nextY++) {
- if (nextX == x && nextY == y) {
- continue;
- }
-
- Position adjacent = new Position(nextX, nextY);
- if (traversable(adjacent)) {
- Node node = nodes.computeIfAbsent(adjacent, Node::new);
- compare(active, node, open, sorted, heuristic);
- }
- }
- }
- } while (!open.isEmpty());
-
- Deque shortest = new ArrayDeque<>();
- Node active = end;
-
- if (active.hasParent()) {
- Position position = active.getPosition();
-
- while (!origin.equals(position)) {
- shortest.addFirst(position);
- active = active.getParent(); // If the target has a parent then all of the others will.
- position = active.getPosition();
- }
- }
-
- return shortest;
- }
-
- /**
- * Compares the two specified {@link Node}s, adding the other node to the open {@link Set} if the estimation is
- * cheaper than the current cost.
- *
- * @param active The active node.
- * @param other The node to compare the active node against.
- * @param open The set of open nodes.
- * @param sorted The sorted {@link Queue} of nodes.
- * @param heuristic The {@link Heuristic} used to estimate the cost of the node.
- */
- private void compare(Node active, Node other, Set open, Queue sorted, Heuristic heuristic) {
- int cost = active.getCost() + heuristic.estimate(active.getPosition(), other.getPosition());
-
- if (other.getCost() > cost) {
- open.remove(other);
- other.close();
- } else if (other.isOpen() && !open.contains(other)) {
- other.setCost(cost);
- other.setParent(active);
- open.add(other);
- sorted.add(other);
- }
- }
-
- /**
- * Gets the cheapest open {@link Node} from the {@link Queue}.
- *
- * @param nodes The queue of nodes.
- * @return The cheapest node.
- */
- private Node getCheapest(Queue nodes) {
- Node node = nodes.peek();
- while (!node.isOpen()) {
- nodes.poll();
- node = nodes.peek();
- }
-
- return node;
- }
-
+package org.apollo.game.model.entity.path;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apollo.game.model.Position;
+import org.apollo.game.model.area.RegionRepository;
+
+/**
+ * A {@link PathfindingAlgorithm} that utilises the A* algorithm to find a solution.
+ *
+ * This implementation utilises a {@link PriorityQueue} of open {@link Node}s, in addition to the usual {@link HashSet}.
+ * This allows for logarithmic-time finding of the cheapest element (as opposed to the linear time associated with
+ * iterating over the set), whilst still maintaining the constant time contains and remove of the set.
+ *
+ * This implementation also avoids the linear-time removal from the queue by polling until the first open node is found
+ * when identifying the cheapest node.
+ *
+ * @author Major
+ */
+public final class AStarPathfindingAlgorithm extends PathfindingAlgorithm {
+
+ /**
+ * The Heuristic used by this PathfindingAlgorithm.
+ */
+ private final Heuristic heuristic;
+
+ /**
+ * Creates the A* pathfinding algorithm with the specified {@link Heuristic}.
+ *
+ * @param repository The {@link RegionRepository}.
+ * @param heuristic The Heuristic.
+ */
+ public AStarPathfindingAlgorithm(RegionRepository repository, Heuristic heuristic) {
+ super(repository);
+ this.heuristic = heuristic;
+ }
+
+ @Override
+ public Deque find(Position origin, Position target) {
+ Map nodes = new HashMap<>();
+ Node start = new Node(origin), end = new Node(target);
+ nodes.put(origin, start);
+ nodes.put(target, end);
+
+ Set open = new HashSet<>();
+ Queue sorted = new PriorityQueue<>();
+ open.add(start);
+ sorted.add(start);
+
+ do {
+ Node active = getCheapest(sorted);
+ Position position = active.getPosition();
+
+ if (position.equals(target)) {
+ break;
+ }
+
+ open.remove(active);
+ active.close();
+
+ int x = position.getX(), y = position.getY();
+ for (int nextX = x - 1; nextX <= x + 1; nextX++) {
+ for (int nextY = y - 1; nextY <= y + 1; nextY++) {
+ if (nextX == x && nextY == y) {
+ continue;
+ }
+
+ Position adjacent = new Position(nextX, nextY);
+ if (traversable(adjacent)) {
+ Node node = nodes.computeIfAbsent(adjacent, Node::new);
+ compare(active, node, open, sorted, heuristic);
+ }
+ }
+ }
+ } while (!open.isEmpty());
+
+ Deque shortest = new ArrayDeque<>();
+ Node active = end;
+
+ if (active.hasParent()) {
+ Position position = active.getPosition();
+
+ while (!origin.equals(position)) {
+ shortest.addFirst(position);
+ active = active.getParent(); // If the target has a parent then all of the others will.
+ position = active.getPosition();
+ }
+ }
+
+ return shortest;
+ }
+
+ /**
+ * Compares the two specified {@link Node}s, adding the other node to the open {@link Set} if the estimation is
+ * cheaper than the current cost.
+ *
+ * @param active The active node.
+ * @param other The node to compare the active node against.
+ * @param open The set of open nodes.
+ * @param sorted The sorted {@link Queue} of nodes.
+ * @param heuristic The {@link Heuristic} used to estimate the cost of the node.
+ */
+ private void compare(Node active, Node other, Set open, Queue sorted, Heuristic heuristic) {
+ int cost = active.getCost() + heuristic.estimate(active.getPosition(), other.getPosition());
+
+ if (other.getCost() > cost) {
+ open.remove(other);
+ other.close();
+ } else if (other.isOpen() && !open.contains(other)) {
+ other.setCost(cost);
+ other.setParent(active);
+ open.add(other);
+ sorted.add(other);
+ }
+ }
+
+ /**
+ * Gets the cheapest open {@link Node} from the {@link Queue}.
+ *
+ * @param nodes The queue of nodes.
+ * @return The cheapest node.
+ */
+ private Node getCheapest(Queue nodes) {
+ Node node = nodes.peek();
+ while (!node.isOpen()) {
+ nodes.poll();
+ node = nodes.peek();
+ }
+
+ return node;
+ }
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/ChebyshevHeuristic.java b/game/src/main/org/apollo/game/model/entity/path/ChebyshevHeuristic.java
index 33c2cdd9..00e8065f 100644
--- a/game/src/main/org/apollo/game/model/entity/path/ChebyshevHeuristic.java
+++ b/game/src/main/org/apollo/game/model/entity/path/ChebyshevHeuristic.java
@@ -1,19 +1,19 @@
-package org.apollo.game.model.entity.path;
-
-import org.apollo.game.model.Position;
-
-/**
- * The Chebyshev heuristic, ideal for a system that allows for 8-directional movement.
- *
- * @author Major
- */
-final class ChebyshevHeuristic extends Heuristic {
-
- @Override
- public int estimate(Position current, Position goal) {
- int dx = Math.abs(current.getX() - goal.getX());
- int dy = Math.abs(current.getX() - goal.getY());
- return dx >= dy ? dx : dy;
- }
-
+package org.apollo.game.model.entity.path;
+
+import org.apollo.game.model.Position;
+
+/**
+ * The Chebyshev heuristic, ideal for a system that allows for 8-directional movement.
+ *
+ * @author Major
+ */
+final class ChebyshevHeuristic extends Heuristic {
+
+ @Override
+ public int estimate(Position current, Position goal) {
+ int dx = Math.abs(current.getX() - goal.getX());
+ int dy = Math.abs(current.getX() - goal.getY());
+ return dx >= dy ? dx : dy;
+ }
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/Heuristic.java b/game/src/main/org/apollo/game/model/entity/path/Heuristic.java
index f43717fd..468c65bd 100644
--- a/game/src/main/org/apollo/game/model/entity/path/Heuristic.java
+++ b/game/src/main/org/apollo/game/model/entity/path/Heuristic.java
@@ -1,21 +1,21 @@
-package org.apollo.game.model.entity.path;
-
-import org.apollo.game.model.Position;
-
-/**
- * A heuristic used by the A* algorithm.
- *
- * @author Major
- */
-abstract class Heuristic {
-
- /**
- * Estimates the value for this heuristic.
- *
- * @param current The current {@link Position}.
- * @param target The target position.
- * @return The heuristic value.
- */
- public abstract int estimate(Position current, Position target);
-
+package org.apollo.game.model.entity.path;
+
+import org.apollo.game.model.Position;
+
+/**
+ * A heuristic used by the A* algorithm.
+ *
+ * @author Major
+ */
+abstract class Heuristic {
+
+ /**
+ * Estimates the value for this heuristic.
+ *
+ * @param current The current {@link Position}.
+ * @param target The target position.
+ * @return The heuristic value.
+ */
+ public abstract int estimate(Position current, Position target);
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/ManhattanHeuristic.java b/game/src/main/org/apollo/game/model/entity/path/ManhattanHeuristic.java
index c44061b0..67ff7d1f 100644
--- a/game/src/main/org/apollo/game/model/entity/path/ManhattanHeuristic.java
+++ b/game/src/main/org/apollo/game/model/entity/path/ManhattanHeuristic.java
@@ -1,19 +1,19 @@
-package org.apollo.game.model.entity.path;
-
-import org.apollo.game.model.Position;
-
-/**
- * The Manhattan heuristic, ideal for a system that limits movement to 4 directions.
- *
- * @author Major
- */
-final class ManhattanHeuristic extends Heuristic {
-
- @Override
- public int estimate(Position current, Position goal) {
- int dx = Math.abs(current.getX() - goal.getX());
- int dy = Math.abs(current.getX() - goal.getY());
- return dx + dy;
- }
-
+package org.apollo.game.model.entity.path;
+
+import org.apollo.game.model.Position;
+
+/**
+ * The Manhattan heuristic, ideal for a system that limits movement to 4 directions.
+ *
+ * @author Major
+ */
+final class ManhattanHeuristic extends Heuristic {
+
+ @Override
+ public int estimate(Position current, Position goal) {
+ int dx = Math.abs(current.getX() - goal.getX());
+ int dy = Math.abs(current.getX() - goal.getY());
+ return dx + dy;
+ }
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/Node.java b/game/src/main/org/apollo/game/model/entity/path/Node.java
index a5632160..8be1d9ae 100644
--- a/game/src/main/org/apollo/game/model/entity/path/Node.java
+++ b/game/src/main/org/apollo/game/model/entity/path/Node.java
@@ -1,149 +1,155 @@
-package org.apollo.game.model.entity.path;
-
-import java.util.NoSuchElementException;
-import java.util.Optional;
-
-import org.apollo.game.model.Position;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * A node representing a weighted {@link Position}.
- *
- * @author Major
- */
-final class Node {
-
- /**
- * The cost of this node.
- */
- private int cost;
-
- /**
- * Whether or not this node is open.
- */
- private boolean open = true;
-
- /**
- * The parent node of this node.
- */
- private Optional parent = Optional.empty();
-
- /**
- * The point this node represents.
- */
- private final Position position;
-
- /**
- * Creates the node with the specified {@link Position} and cost.
- *
- * @param position The position.
- */
- public Node(Position position) {
- this(position, 0);
- }
-
- /**
- * Creates the node with the specified {@link Position} and cost.
- *
- * @param position The position.
- * @param cost The cost of the node.
- */
- public Node(Position position, int cost) {
- this.position = position;
- this.cost = cost;
- }
-
- /**
- * Closes this node.
- */
- public void close() {
- open = false;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Node) {
- Node other = (Node) obj;
-
- return position.equals(other.position);
- }
-
- return false;
- }
-
- /**
- * Gets the cost of this node.
- *
- * @return The cost.
- */
- public int getCost() {
- return cost;
- }
-
- /**
- * Gets the parent node of this node.
- *
- * @return The parent node.
- * @throws NoSuchElementException If this node does not have a parent.
- */
- public Node getParent() {
- return parent.get();
- }
-
- /**
- * Gets the {@link Position} this node represents.
- *
- * @return The position.
- */
- public Position getPosition() {
- return position;
- }
-
- @Override
- public int hashCode() {
- return position.hashCode();
- }
-
- /**
- * Returns whether or not this node has a parent node.
- *
- * @return {@code true} if this node has a parent node, otherwise {@code false}.
- */
- public boolean hasParent() {
- return parent.isPresent();
- }
-
- /**
- * Returns whether or not this {@link Node} is open.
- *
- * @return {@code true} if this node is open, otherwise {@code false}.
- */
- public boolean isOpen() {
- return open;
- }
-
- /**
- * Sets the cost of this node.
- *
- * @param cost The cost.
- */
- public void setCost(int cost) {
- this.cost = cost;
- }
-
- /**
- * Sets the parent node of this node.
- *
- * @param parent The parent node. May be {@code null}.
- */
- public void setParent(Node parent) {
- this.parent = Optional.ofNullable(parent);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this).add("position", position).add("open", open).add("cost", cost).toString();
- }
-
+package org.apollo.game.model.entity.path;
+
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import org.apollo.game.model.Position;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * A Node representing a weighted {@link Position}.
+ *
+ * @author Major
+ */
+final class Node implements Comparable {
+
+ /**
+ * The cost of this Node.
+ */
+ private int cost;
+
+ /**
+ * Whether or not this Node is open.
+ */
+ private boolean open = true;
+
+ /**
+ * The parent Node of this Node.
+ */
+ private Optional parent = Optional.empty();
+
+ /**
+ * The Position of this Node.
+ */
+ private final Position position;
+
+ /**
+ * Creates the Node with the specified {@link Position} and cost.
+ *
+ * @param position The Position.
+ */
+ public Node(Position position) {
+ this(position, 0);
+ }
+
+ /**
+ * Creates the Node with the specified {@link Position} and cost.
+ *
+ * @param position The Position.
+ * @param cost The cost of the Node.
+ */
+ public Node(Position position, int cost) {
+ this.position = position;
+ this.cost = cost;
+ }
+
+ /**
+ * Closes this Node.
+ */
+ public void close() {
+ open = false;
+ }
+
+ @Override
+ public int compareTo(Node other) {
+ return Integer.compare(cost, other.cost);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Node) {
+ Node other = (Node) obj;
+
+ return position.equals(other.position);
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets the cost of this Node.
+ *
+ * @return The cost.
+ */
+ public int getCost() {
+ return cost;
+ }
+
+ /**
+ * Gets the parent Node of this Node.
+ *
+ * @return The parent Node.
+ * @throws NoSuchElementException If this Node does not have a parent.
+ */
+ public Node getParent() {
+ return parent.get();
+ }
+
+ /**
+ * Gets the {@link Position} this Node represents.
+ *
+ * @return The position.
+ */
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public int hashCode() {
+ return position.hashCode();
+ }
+
+ /**
+ * Returns whether or not this Node has a parent Node.
+ *
+ * @return {@code true} if this Node has a parent Node, otherwise {@code false}.
+ */
+ public boolean hasParent() {
+ return parent.isPresent();
+ }
+
+ /**
+ * Returns whether or not this {@link Node} is open.
+ *
+ * @return {@code true} if this Node is open, otherwise {@code false}.
+ */
+ public boolean isOpen() {
+ return open;
+ }
+
+ /**
+ * Sets the cost of this Node.
+ *
+ * @param cost The cost.
+ */
+ public void setCost(int cost) {
+ this.cost = cost;
+ }
+
+ /**
+ * Sets the parent Node of this Node.
+ *
+ * @param parent The parent Node. May be {@code null}.
+ */
+ public void setParent(Node parent) {
+ this.parent = Optional.ofNullable(parent);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("position", position).add("open", open).add("cost", cost)
+ .toString();
+ }
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/PathfindingAlgorithm.java b/game/src/main/org/apollo/game/model/entity/path/PathfindingAlgorithm.java
index 297e0916..d96007d8 100644
--- a/game/src/main/org/apollo/game/model/entity/path/PathfindingAlgorithm.java
+++ b/game/src/main/org/apollo/game/model/entity/path/PathfindingAlgorithm.java
@@ -1,111 +1,111 @@
-package org.apollo.game.model.entity.path;
-
-import java.util.Deque;
-import java.util.Optional;
-
-import org.apollo.game.model.Direction;
-import org.apollo.game.model.Position;
-import org.apollo.game.model.area.Region;
-import org.apollo.game.model.area.RegionRepository;
-import org.apollo.game.model.entity.EntityType;
-
-import com.google.common.base.Preconditions;
-
-/**
- * An algorithm used to find a path between two {@link Position}s.
- *
- * @author Major
- */
-abstract class PathfindingAlgorithm {
-
- /**
- * The RegionRepository.
- */
- private final RegionRepository repository;
-
- /**
- * Creates the PathfindingAlgorithm.
- *
- * @param repository The {@link RegionRepository}.
- */
- public PathfindingAlgorithm(RegionRepository repository) {
- this.repository = repository;
- }
-
- /**
- * Finds a valid path from the origin {@link Position} to the target one.
- *
- * @param origin The origin Position.
- * @param target The target Position.
- * @return The {@link Deque} containing the Positions to go through.
- */
- public abstract Deque find(Position origin, Position target);
-
- /**
- * Returns whether or not a {@link Position} walking one step in any of the specified {@link Direction}s would lead
- * to is traversable.
- *
- * @param current The current Position.
- * @param directions The Directions that should be checked.
- * @return {@code true} if any of the Directions lead to a traversable tile, otherwise {@code false}.
- */
- protected boolean traversable(Position current, Direction... directions) {
- return traversable(current, Optional.empty(), directions);
- }
-
- /**
- * Returns whether or not a {@link Position} walking one step in any of the specified {@link Direction}s would lead
- * to is traversable.
- *
- * @param current The current Position.
- * @param boundaries The {@link Optional} containing the Position boundaries.
- * @param directions The Directions that should be checked.
- * @return {@code true} if any of the Directions lead to a traversable tile, otherwise {@code false}.
- */
- protected boolean traversable(Position current, Optional boundaries, Direction... directions) {
- Preconditions.checkArgument(directions != null && directions.length > 0, "Directions array cannot be null.");
- int height = current.getHeight();
-
- Position[] positions = boundaries.isPresent() ? boundaries.get() : new Position[0];
-
- for (Direction direction : directions) {
- int x = current.getX(), y = current.getY();
- int value = direction.toInteger();
-
- if (value >= Direction.NORTH_WEST.toInteger() && value <= Direction.NORTH_EAST.toInteger()) {
- y++;
- } else if (value >= Direction.SOUTH_WEST.toInteger() && value <= Direction.SOUTH_EAST.toInteger()) {
- y--;
- }
-
- if (direction == Direction.NORTH_EAST || direction == Direction.EAST || direction == Direction.SOUTH_EAST) {
- x++;
- } else if (direction == Direction.NORTH_WEST || direction == Direction.WEST || direction == Direction.SOUTH_WEST) {
- x--;
- }
-
- Position next = new Position(x, y, height);
- Region region = repository.get(next.getRegionCoordinates());
- if (region.traversable(next, EntityType.NPC, direction) && (positions.length == 0 || inside(next, positions))) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Returns whether or not the specified {@link Position} is inside the specified {@code boundary}.
- *
- * @param position The Position.
- * @param boundary The boundary Positions.
- * @return {@code true} if the specified Position is inside the boundary, {@code false} if not.
- */
- private boolean inside(Position position, Position[] boundary) {
- int x = position.getX(), y = position.getY();
- Position min = boundary[0], max = boundary[1];
-
- return x >= min.getX() && y >= min.getY() && x <= max.getX() && y <= max.getY();
- }
-
+package org.apollo.game.model.entity.path;
+
+import java.util.Deque;
+import java.util.Optional;
+
+import org.apollo.game.model.Direction;
+import org.apollo.game.model.Position;
+import org.apollo.game.model.area.Region;
+import org.apollo.game.model.area.RegionRepository;
+import org.apollo.game.model.entity.EntityType;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * An algorithm used to find a path between two {@link Position}s.
+ *
+ * @author Major
+ */
+abstract class PathfindingAlgorithm {
+
+ /**
+ * The RegionRepository.
+ */
+ private final RegionRepository repository;
+
+ /**
+ * Creates the PathfindingAlgorithm.
+ *
+ * @param repository The {@link RegionRepository}.
+ */
+ public PathfindingAlgorithm(RegionRepository repository) {
+ this.repository = repository;
+ }
+
+ /**
+ * Finds a valid path from the origin {@link Position} to the target one.
+ *
+ * @param origin The origin Position.
+ * @param target The target Position.
+ * @return The {@link Deque} containing the Positions to go through.
+ */
+ public abstract Deque find(Position origin, Position target);
+
+ /**
+ * Returns whether or not a {@link Position} walking one step in any of the specified {@link Direction}s would lead
+ * to is traversable.
+ *
+ * @param current The current Position.
+ * @param directions The Directions that should be checked.
+ * @return {@code true} if any of the Directions lead to a traversable tile, otherwise {@code false}.
+ */
+ protected boolean traversable(Position current, Direction... directions) {
+ return traversable(current, Optional.empty(), directions);
+ }
+
+ /**
+ * Returns whether or not a {@link Position} walking one step in any of the specified {@link Direction}s would lead
+ * to is traversable.
+ *
+ * @param current The current Position.
+ * @param boundaries The {@link Optional} containing the Position boundaries.
+ * @param directions The Directions that should be checked.
+ * @return {@code true} if any of the Directions lead to a traversable tile, otherwise {@code false}.
+ */
+ protected boolean traversable(Position current, Optional boundaries, Direction... directions) {
+ Preconditions.checkArgument(directions != null && directions.length > 0, "Directions array cannot be null.");
+ int height = current.getHeight();
+
+ Position[] positions = boundaries.isPresent() ? boundaries.get() : new Position[0];
+
+ for (Direction direction : directions) {
+ int x = current.getX(), y = current.getY();
+ int value = direction.toInteger();
+
+ if (value >= Direction.NORTH_WEST.toInteger() && value <= Direction.NORTH_EAST.toInteger()) {
+ y++;
+ } else if (value >= Direction.SOUTH_WEST.toInteger() && value <= Direction.SOUTH_EAST.toInteger()) {
+ y--;
+ }
+
+ if (direction == Direction.NORTH_EAST || direction == Direction.EAST || direction == Direction.SOUTH_EAST) {
+ x++;
+ } else if (direction == Direction.NORTH_WEST || direction == Direction.WEST || direction == Direction.SOUTH_WEST) {
+ x--;
+ }
+
+ Position next = new Position(x, y, height);
+ Region region = repository.get(next.getRegionCoordinates());
+ if (region.traversable(next, EntityType.NPC, direction) && (positions.length == 0 || inside(next, positions))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether or not the specified {@link Position} is inside the specified {@code boundary}.
+ *
+ * @param position The Position.
+ * @param boundary The boundary Positions.
+ * @return {@code true} if the specified Position is inside the boundary, {@code false} if not.
+ */
+ private boolean inside(Position position, Position[] boundary) {
+ int x = position.getX(), y = position.getY();
+ Position min = boundary[0], max = boundary[1];
+
+ return x >= min.getX() && y >= min.getY() && x <= max.getX() && y <= max.getY();
+ }
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/SimplePathfindingAlgorithm.java b/game/src/main/org/apollo/game/model/entity/path/SimplePathfindingAlgorithm.java
index d784e451..caf97995 100644
--- a/game/src/main/org/apollo/game/model/entity/path/SimplePathfindingAlgorithm.java
+++ b/game/src/main/org/apollo/game/model/entity/path/SimplePathfindingAlgorithm.java
@@ -1,142 +1,143 @@
-package org.apollo.game.model.entity.path;
-
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Optional;
-
-import org.apollo.game.model.Direction;
-import org.apollo.game.model.Position;
-import org.apollo.game.model.area.RegionRepository;
-
-/**
- * A very simple pathfinding algorithm that simply walks in the direction of the target until it either reaches it or is
- * blocked.
- *
- * @author Major
- */
-public final class SimplePathfindingAlgorithm extends PathfindingAlgorithm {
-
- /**
- * Creates the SimplePathfindingAlgorithm.
- *
- * @param repository The {@link RegionRepository}.
- */
- public SimplePathfindingAlgorithm(RegionRepository repository) {
- super(repository);
- }
-
- /**
- * The Optional containing the boundary Positions.
- */
- private Optional boundaries = Optional.empty();
-
- @Override
- public Deque find(Position origin, Position target) {
- int approximation = (int) (origin.getLongestDelta(target) * 1.5);
- Deque positions = new ArrayDeque<>(approximation);
-
- return addHorizontal(origin, target, positions);
- }
-
- /**
- * Finds a valid path from the origin {@link Position} to the target one.
- *
- * @param origin The origin Position.
- * @param target The target Position.
- * @param boundaries The boundary Positions, which are marking as untraversable.
- * @return The {@link Deque} containing the Positions to go through.
- */
- public Deque find(Position origin, Position target, Position[] boundaries) {
- this.boundaries = Optional.of(boundaries);
- return find(origin, target);
- }
-
- /**
- * Adds the necessary and possible horizontal {@link Position}s to the existing {@link Deque}.
- *
- * This method:
- *
- * - Adds positions horizontally until we are either horizontally aligned with the target, or the next step is not
- * traversable.
- *
- Checks if we are not at the target, and that either of the horizontally-adjacent positions are traversable:
- * if so, we traverse horizontally (see {@link #addHorizontal}); if not, return the current path.
- *
- *
- * @param start The current position.
- * @param target The target position.
- * @param positions The deque of positions.
- * @return The deque of positions containing the path.
- */
- private Deque addHorizontal(Position start, Position target, Deque positions) {
- int x = start.getX(), y = start.getY(), height = start.getHeight();
- int dx = x - target.getX(), dy = y - target.getY();
-
- if (dx > 0) {
- Position current = start;
-
- while (traversable(current, boundaries, Direction.WEST) && dx-- > 0) {
- current = new Position(--x, y, height);
- positions.addLast(current);
- }
- } else if (dx < 0) {
- Position current = start;
-
- while (traversable(current, boundaries, Direction.EAST) && dx++ < 0) {
- current = new Position(++x, y, height);
- positions.addLast(current);
- }
- }
-
- Position last = new Position(x, y, height);
- if (!start.equals(last) && dy != 0 && traversable(last, boundaries, dy > 0 ? Direction.SOUTH : Direction.NORTH)) {
- return addVertical(last, target, positions);
- }
-
- return positions;
- }
-
- /**
- * Adds the necessary and possible vertical {@link Position}s to the existing {@link Deque}.
- *
- * This method:
- *
- * - Adds positions vertically until we are either vertically aligned with the target, or the next step is not
- * traversable.
- *
- Checks if we are not at the target, and that either of the horizontally-adjacent positions are traversable:
- * if so, we traverse horizontally (see {@link #addHorizontal}); if not, return the current path.
- *
- *
- * @param start The current position.
- * @param target The target position.
- * @param positions The deque of positions.
- * @return The deque of positions containing the path.
- */
- private Deque addVertical(Position start, Position target, Deque positions) {
- int x = start.getX(), y = start.getY(), height = start.getHeight();
- int dy = y - target.getY(), dx = x - target.getX();
-
- if (dy > 0) {
- Position current = start;
-
- while (traversable(current, boundaries, Direction.SOUTH) && dy-- > 0) {
- current = new Position(x, --y, height);
- positions.addLast(current);
- }
- } else if (dy < 0) {
- Position current = start;
-
- while (traversable(current, boundaries, Direction.NORTH) && dy++ < 0) {
- current = new Position(x, ++y, height);
- positions.addLast(current);
- }
- }
-
- Position last = new Position(x, y, height);
- if (!last.equals(target) && dx != 0 && traversable(last, boundaries, dx > 0 ? Direction.WEST : Direction.EAST)) {
- return addHorizontal(last, target, positions);
- }
-
- return positions;
- }
-
+package org.apollo.game.model.entity.path;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Optional;
+
+import org.apollo.game.model.Direction;
+import org.apollo.game.model.Position;
+import org.apollo.game.model.area.RegionRepository;
+
+/**
+ * A very simple pathfinding algorithm that simply walks in the direction of the target until it either reaches it or is
+ * blocked.
+ *
+ * @author Major
+ */
+public final class SimplePathfindingAlgorithm extends PathfindingAlgorithm {
+
+ /**
+ * Creates the SimplePathfindingAlgorithm.
+ *
+ * @param repository The {@link RegionRepository}.
+ */
+ public SimplePathfindingAlgorithm(RegionRepository repository) {
+ super(repository);
+ }
+
+ /**
+ * The Optional containing the boundary Positions.
+ */
+ private Optional boundaries = Optional.empty();
+
+ @Override
+ public Deque find(Position origin, Position target) {
+ int approximation = (int) (origin.getLongestDelta(target) * 1.5);
+ Deque positions = new ArrayDeque<>(approximation);
+
+ return addHorizontal(origin, target, positions);
+ }
+
+ /**
+ * Finds a valid path from the origin {@link Position} to the target one.
+ *
+ * @param origin The origin Position.
+ * @param target The target Position.
+ * @param boundaries The boundary Positions, which are marking as untraversable.
+ * @return The {@link Deque} containing the Positions to go through.
+ */
+ public Deque find(Position origin, Position target, Position[] boundaries) {
+ this.boundaries = Optional.of(boundaries);
+ return find(origin, target);
+ }
+
+ /**
+ * Adds the necessary and possible horizontal {@link Position}s to the existing {@link Deque}.
+ *
+ * This method:
+ *
+ * - Adds positions horizontally until we are either horizontally aligned with the target, or the next step is not
+ * traversable.
+ *
- Checks if we are not at the target, and that either of the horizontally-adjacent positions are traversable:
+ * if so, we traverse horizontally (see {@link #addHorizontal}); if not, return the current path.
+ *
+ *
+ * @param start The current position.
+ * @param target The target position.
+ * @param positions The deque of positions.
+ * @return The deque of positions containing the path.
+ */
+ private Deque addHorizontal(Position start, Position target, Deque positions) {
+ int x = start.getX(), y = start.getY(), height = start.getHeight();
+ int dx = x - target.getX(), dy = y - target.getY();
+
+ if (dx > 0) {
+ Position current = start;
+
+ while (traversable(current, boundaries, Direction.WEST) && dx-- > 0) {
+ current = new Position(--x, y, height);
+ positions.addLast(current);
+ }
+ } else if (dx < 0) {
+ Position current = start;
+
+ while (traversable(current, boundaries, Direction.EAST) && dx++ < 0) {
+ current = new Position(++x, y, height);
+ positions.addLast(current);
+ }
+ }
+
+ Position last = new Position(x, y, height);
+ if (!start.equals(last) && dy != 0 && traversable(last, boundaries, dy > 0 ? Direction.SOUTH : Direction.NORTH)) {
+ return addVertical(last, target, positions);
+ }
+
+ return positions;
+ }
+
+ /**
+ * Adds the necessary and possible vertical {@link Position}s to the existing {@link Deque}.
+ *
+ * This method:
+ *
+ * - Adds positions vertically until we are either vertically aligned with the target, or the next step is not
+ * traversable.
+ *
- Checks if we are not at the target, and that either of the horizontally-adjacent positions are traversable:
+ * if so, we traverse horizontally (see {@link #addHorizontal}); if not, return the current path.
+ *
+ *
+ * @param start The current position.
+ * @param target The target position.
+ * @param positions The deque of positions.
+ * @return The deque of positions containing the path.
+ */
+ private Deque addVertical(Position start, Position target, Deque positions) {
+ int x = start.getX(), y = start.getY(), height = start.getHeight();
+ int dy = y - target.getY(), dx = x - target.getX();
+
+ if (dy > 0) {
+ Position current = start;
+
+ while (traversable(current, boundaries, Direction.SOUTH) && dy-- > 0) {
+ current = new Position(x, --y, height);
+ positions.addLast(current);
+ }
+ } else if (dy < 0) {
+ Position current = start;
+
+ while (traversable(current, boundaries, Direction.NORTH) && dy++ < 0) {
+ current = new Position(x, ++y, height);
+ positions.addLast(current);
+ }
+ }
+
+ Position last = new Position(x, y, height);
+ if (!last.equals(target) && dx != 0
+ && traversable(last, boundaries, dx > 0 ? Direction.WEST : Direction.EAST)) {
+ return addHorizontal(last, target, positions);
+ }
+
+ return positions;
+ }
+
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/model/entity/path/package-info.java b/game/src/main/org/apollo/game/model/entity/path/package-info.java
index 2bc5b25b..6358758e 100644
--- a/game/src/main/org/apollo/game/model/entity/path/package-info.java
+++ b/game/src/main/org/apollo/game/model/entity/path/package-info.java
@@ -1,4 +1,4 @@
-/**
- * Contains pathfinding-related classes.
- */
+/**
+ * Contains pathfinding-related classes.
+ */
package org.apollo.game.model.entity.path;
\ No newline at end of file