package org.moparscape.msc.gs.model; import org.moparscape.msc.gs.Instance; import org.moparscape.msc.gs.model.landscape.TileValue; public class PathHandler { /** * World instance */ private static final World world = Instance.getWorld(); /** * Attempts to create a path to the given coordinates */ public static Path makePath(int startX, int startY, int x1, int y1, int x2, int y2, boolean flag) { return null; } /** * The waypoint in the path we are currently at */ private int curWaypoint; /** * The mob that this path belongs to */ private Mob mob; /** * The path we are walking */ private Path path; /** * Constructs a new PathHandler belonging to the given Mob */ public PathHandler(Mob m) { mob = m; resetPath(); } /** * Are we are the start of the path? */ protected boolean atStart() { return mob.getX() == path.getStartX() && mob.getY() == path.getStartY(); } /** * Checks if we are at the given waypoint */ protected boolean atWaypoint(int waypoint) { return path.getWaypointX(waypoint) == mob.getX() && path.getWaypointY(waypoint) == mob.getY(); } private int[] cancelCoords() { resetPath(); return new int[] { -1, -1 }; } /** * Checks if we have reached the end of our path */ public boolean finishedPath() { if (path == null) { return true; } if (path.length() > 0) { return atWaypoint(path.length() - 1); } else { return atStart(); } } /** * Gets the next coordinate in the right direction */ protected int[] getNextCoords(int startX, int destX, int startY, int destY) { try { int[] coords = { startX, startY }; boolean myXBlocked = false, myYBlocked = false, newXBlocked = false, newYBlocked = false; if (startX > destX) { myXBlocked = isBlocking(startX - 1, startY, 8); // Check right // tiles left // wall coords[0] = startX - 1; } else if (startX < destX) { myXBlocked = isBlocking(startX + 1, startY, 2); // Check left // tiles right // wall coords[0] = startX + 1; } if (startY > destY) { myYBlocked = isBlocking(startX, startY - 1, 4); // Check top // tiles bottom // wall coords[1] = startY - 1; } else if (startY < destY) { myYBlocked = isBlocking(startX, startY + 1, 1); // Check bottom // tiles top // wall coords[1] = startY + 1; } // If both directions are blocked OR we are going straight and the // direction is blocked if ((myXBlocked && myYBlocked) || (myXBlocked && startY == destY) || (myYBlocked && startX == destX)) { return cancelCoords(); } if (coords[0] > startX) { newXBlocked = isBlocking(coords[0], coords[1], 2); // Check dest // tiles // right // wall } else if (coords[0] < startX) { newXBlocked = isBlocking(coords[0], coords[1], 8); // Check dest // tiles // left wall } if (coords[1] > startY) { newYBlocked = isBlocking(coords[0], coords[1], 1); // Check dest // tiles top // wall } else if (coords[1] < startY) { newYBlocked = isBlocking(coords[0], coords[1], 4); // Check dest // tiles // bottom // wall } // If both directions are blocked OR we are going straight and the // direction is blocked if ((newXBlocked && newYBlocked) || (newXBlocked && startY == coords[1]) || (myYBlocked && startX == coords[0])) { return cancelCoords(); } // If only one direction is blocked, but it blocks both tiles if ((myXBlocked && newXBlocked) || (myYBlocked && newYBlocked)) { return cancelCoords(); } return coords; } catch (Exception e) { return cancelCoords(); } } private boolean isBlocking(byte val, byte bit) { if (path.isNoClip()) return false; if ((val & bit) != 0) { // There is a wall in the way return true; } if ((val & 16) != 0) { // There is a diagonal wall here: \ return true; } if ((val & 32) != 0) { // There is a diagonal wall here: / return true; } if ((val & 64) != 0) { // This tile is unwalkable return true; } return false; } private boolean isBlocking(int x, int y, int bit) { if (path.isNoClip()) return false; if (mob instanceof Player) { Player p = (Player) mob; if (p.isMod()) return false; } TileValue t = world.getTileValue(x, y); return isBlocking(t.mapValue, (byte) bit) || isBlocking(t.objectValue, (byte) bit) || isMobBlocking(x, y); } private boolean isMobBlocking(int x, int y) { // ActiveTile t = world.getTile(x, y); // if (mob instanceof Player) { // if (t.hasNpcs()) { // for (Npc n : t.getNpcs()) { // if (n.getDef().isAggressive() && !n.getLocation().inWilderness()) // return true; // } // } // } // if (mob instanceof Npc) { // Npc n = (Npc) mob; // if (n.getChasing() != null) // if (t.hasPlayers() && t.getPlayers().contains(n.getChasing())) // if (x == n.getChasing().getX() && y == n.getChasing().getY()) // return false; // if (t.hasNpcs() || (t.hasPlayers() && n.getChasing() != null)) // return true; // } // t.cleanItself(); return false; } /** * Resets the path (stops movement) */ protected void resetPath() { path = null; curWaypoint = -1; } // /** * Updates our position to the next in the path */ protected void setNextPosition() { int[] newCoords = { -1, -1 }; if (curWaypoint == -1) { if (atStart()) { curWaypoint = 0; } else { newCoords = getNextCoords(mob.getX(), path.getStartX(), mob.getY(), path.getStartY()); } } if (curWaypoint > -1) { if (atWaypoint(curWaypoint)) { curWaypoint++; } if (curWaypoint < path.length()) { newCoords = getNextCoords(mob.getX(), path.getWaypointX(curWaypoint), mob.getY(), path.getWaypointY(curWaypoint)); } else { resetPath(); } } if (newCoords[0] > -1 && newCoords[1] > -1) { mob.setLocation(Point.location(newCoords[0], newCoords[1])); } } /** * Creates a new path and sets us walking it */ public void setPath(int startX, int startY, byte[] waypointXoffsets, byte[] waypointYoffsets) { setPath(new Path(startX, startY, waypointXoffsets, waypointYoffsets)); } /** * Sets us on the given path */ public void setPath(Path path) { curWaypoint = -1; this.path = path; } /** * Updates the point in the path to the next one assuming we are not * finished */ public void updatePosition() { if (!finishedPath()) { setNextPosition(); } } }