2011-05-13 04:24:42 -04:00
|
|
|
package org.moparscape.msc.gs.model;
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-05-13 04:24:42 -04:00
|
|
|
import org.moparscape.msc.gs.Instance;
|
2012-01-07 16:11:45 -05:00
|
|
|
import org.moparscape.msc.gs.model.landscape.TileValue;
|
2011-04-27 01:44:26 -04:00
|
|
|
|
|
|
|
public class PathHandler {
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* World instance
|
|
|
|
*/
|
|
|
|
private static final World world = Instance.getWorld();
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* The waypoint in the path we are currently at
|
|
|
|
*/
|
|
|
|
private int curWaypoint;
|
|
|
|
/**
|
|
|
|
* The mob that this path belongs to
|
|
|
|
*/
|
|
|
|
private Mob mob;
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* The path we are walking
|
|
|
|
*/
|
|
|
|
private Path path;
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* Constructs a new PathHandler belonging to the given Mob
|
|
|
|
*/
|
|
|
|
public PathHandler(Mob m) {
|
|
|
|
mob = m;
|
|
|
|
resetPath();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* Are we are the start of the path?
|
|
|
|
*/
|
|
|
|
protected boolean atStart() {
|
|
|
|
return mob.getX() == path.getStartX() && mob.getY() == path.getStartY();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* Checks if we are at the given waypoint
|
|
|
|
*/
|
|
|
|
protected boolean atWaypoint(int waypoint) {
|
|
|
|
return path.getWaypointX(waypoint) == mob.getX()
|
|
|
|
&& path.getWaypointY(waypoint) == mob.getY();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
private int[] cancelCoords() {
|
|
|
|
resetPath();
|
|
|
|
return new int[] { -1, -1 };
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
2011-06-25 01:44:53 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
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;
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
// 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();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
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
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
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
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
// 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();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
// If only one direction is blocked, but it blocks both tiles
|
|
|
|
if ((myXBlocked && newXBlocked) || (myYBlocked && newYBlocked)) {
|
|
|
|
return cancelCoords();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
return coords;
|
|
|
|
} catch (Exception e) {
|
|
|
|
return cancelCoords();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
private boolean isBlocking(byte val, byte bit) {
|
|
|
|
if (path.isNoClip())
|
|
|
|
return false;
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
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;
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
2011-06-25 01:44:53 -04:00
|
|
|
|
|
|
|
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);
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
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();
|
2011-04-27 01:44:26 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* Resets the path (stops movement)
|
|
|
|
*/
|
|
|
|
protected void resetPath() {
|
|
|
|
path = null;
|
|
|
|
curWaypoint = -1;
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
2011-06-25 01:44:53 -04:00
|
|
|
|
|
|
|
//
|
|
|
|
/**
|
|
|
|
* 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]));
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* 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));
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* Sets us on the given path
|
|
|
|
*/
|
|
|
|
public void setPath(Path path) {
|
|
|
|
curWaypoint = -1;
|
|
|
|
this.path = path;
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
|
2011-06-25 01:44:53 -04:00
|
|
|
/**
|
|
|
|
* Updates the point in the path to the next one assuming we are not
|
|
|
|
* finished
|
|
|
|
*/
|
|
|
|
public void updatePosition() {
|
|
|
|
if (!finishedPath()) {
|
|
|
|
setNextPosition();
|
|
|
|
}
|
2011-04-27 01:44:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|