package net.scapeemulator.game.model.mob;
import java.util.LinkedList;
import java.util.List;
import net.scapeemulator.game.model.Position;
import net.scapeemulator.game.model.World;
import net.scapeemulator.game.model.pathfinding.TraversalMap;
public enum Direction {
NONE(-1, 0, 0),
NORTH(1, 0, 1),
NORTH_EAST(2, 1, 1),
EAST(4, 1, 0),
SOUTH_EAST(7, 1, -1),
SOUTH(6, 0, -1),
SOUTH_WEST(5, -1, -1),
WEST(3, -1, 0),
NORTH_WEST(0, -1, 1);
private final int intValue;
private final int x;
private final int y;
private Direction(int intValue, int x, int y) {
this.intValue = intValue;
this.x = x;
this.y = y;
}
public Direction getInverted() {
switch (this) {
case NONE:
return NONE;
case NORTH:
return SOUTH;
case NORTH_EAST:
return SOUTH_WEST;
case EAST:
return WEST;
case SOUTH_EAST:
return NORTH_WEST;
case SOUTH:
return NORTH;
case SOUTH_WEST:
return NORTH_EAST;
case WEST:
return EAST;
case NORTH_WEST:
return SOUTH_EAST;
}
throw new RuntimeException();
}
public static List<Position> getNearbyTraversableTiles(Position from, int size) {
TraversalMap traversalMap = World.getWorld().getTraversalMap();
List<Position> positions = new LinkedList<>();
if (traversalMap.isTraversableNorth(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX(), from.getY() + 1, from.getHeight()));
}
if (traversalMap.isTraversableSouth(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX(), from.getY() - 1, from.getHeight()));
}
if (traversalMap.isTraversableEast(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX() + 1, from.getY(), from.getHeight()));
}
if (traversalMap.isTraversableWest(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX() - 1, from.getY(), from.getHeight()));
}
if (traversalMap.isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX() + 1, from.getY() + 1, from.getHeight()));
}
if (traversalMap.isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX() - 1, from.getY() + 1, from.getHeight()));
}
if (traversalMap.isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX() + 1, from.getY() - 1, from.getHeight()));
}
if (traversalMap.isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), size)) {
positions.add(new Position(from.getX() - 1, from.getY() - 1, from.getHeight()));
}
return positions;
}
public static boolean isTraversable(Position from, Direction direction, int size) {
TraversalMap traversalMap = World.getWorld().getTraversalMap();
switch (direction) {
case NORTH:
return traversalMap.isTraversableNorth(from.getHeight(), from.getX(), from.getY(), size);
case SOUTH:
return traversalMap.isTraversableSouth(from.getHeight(), from.getX(), from.getY(), size);
case EAST:
return traversalMap.isTraversableEast(from.getHeight(), from.getX(), from.getY(), size);
case WEST:
return traversalMap.isTraversableWest(from.getHeight(), from.getX(), from.getY(), size);
case NORTH_EAST:
return traversalMap.isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), size);
case NORTH_WEST:
return traversalMap.isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), size);
case SOUTH_EAST:
return traversalMap.isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), size);
case SOUTH_WEST:
return traversalMap.isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), size);
case NONE:
return true;
default:
throw new RuntimeException("unknown type");
}
}
public static boolean projectileClipping(Position from, Position to) {
TraversalMap traversalMap = World.getWorld().getTraversalMap();
Direction direction = between(from, to);
switch (direction) {
case NORTH:
return traversalMap.isTraversableNorth(from.getHeight(), from.getX(), from.getY(), true);
case SOUTH:
return traversalMap.isTraversableSouth(from.getHeight(), from.getX(), from.getY(), true);
case EAST:
return traversalMap.isTraversableEast(from.getHeight(), from.getX(), from.getY(), true);
case WEST:
return traversalMap.isTraversableWest(from.getHeight(), from.getX(), from.getY(), true);
case NORTH_EAST:
return traversalMap.isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), true);
case NORTH_WEST:
return traversalMap.isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), true);
case SOUTH_EAST:
return traversalMap.isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), true);
case SOUTH_WEST:
return traversalMap.isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), true);
case NONE:
return true;
default:
throw new RuntimeException("unknown type");
}
}
public int toInteger() {
return intValue;
}
public static Direction between(Position cur, Position next) {
int deltaX = next.getX() - cur.getX();
int deltaY = next.getY() - cur.getY();
if (deltaY >= 1) {
if (deltaX >= 1) {
return NORTH_EAST;
} else if (deltaX == 0) {
return NORTH;
} else if (deltaX <= -1) {
return NORTH_WEST;
}
} else if (deltaY <= -1) {
if (deltaX >= 1) {
return SOUTH_EAST;
} else if (deltaX == 0) {
return SOUTH;
} else if (deltaX <= -1) {
return SOUTH_WEST;
}
} else if (deltaY == 0) {
if (deltaX >= 1) {
return EAST;
} else if (deltaX == 0) {
return NONE;
} else if (deltaX <= -1) {
return WEST;
}
}
throw new IllegalArgumentException(deltaX + " " + deltaY);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}