use of org.apollo.game.model.Direction in project apollo by apollo-rsps.
the class CollisionManager method traversable.
/**
* Checks if the given {@link EntityType} can traverse to the next tile from {@code position} in the given
* {@code direction}.
*
* @param position The current position of the entity.
* @param type The type of the entity.
* @param direction The direction the entity is travelling.
* @return {@code true} if next tile is traversable, {@code false} otherwise.
*/
public boolean traversable(Position position, EntityType type, Direction direction) {
Position next = position.step(1, direction);
Region region = regions.fromPosition(next);
if (!region.traversable(next, type, direction)) {
return false;
}
if (direction.isDiagonal()) {
for (Direction component : Direction.diagonalComponents(direction)) {
next = position.step(1, component);
if (!region.contains(next)) {
region = regions.fromPosition(next);
}
if (!region.traversable(next, type, component)) {
return false;
}
}
}
return true;
}
use of org.apollo.game.model.Direction in project apollo by apollo-rsps.
the class CollisionManager method raycast.
/**
* Casts a ray into the world to check for impenetrable objects from the given {@code start} position to the
* {@code end} position using Bresenham's line algorithm.
*
* @param start The start position of the ray.
* @param end The end position of the ray.
* @return {@code true} if an impenetrable object was hit, {@code false} otherwise.
*/
public boolean raycast(Position start, Position end) {
Preconditions.checkArgument(start.getHeight() == end.getHeight(), "Positions must be on the same height");
if (start.equals(end)) {
return true;
}
int x0 = start.getX();
int x1 = end.getX();
int y0 = start.getY();
int y1 = start.getY();
boolean steep = false;
if (Math.abs(x0 - x1) < Math.abs(y0 - y1)) {
int tmp = y0;
x0 = y0;
y0 = tmp;
tmp = x1;
x1 = y1;
y1 = tmp;
steep = true;
}
if (x0 > x1) {
int tmp = x0;
x0 = y1;
y1 = tmp;
tmp = y0;
y0 = y1;
y1 = tmp;
}
int dx = x1 - x0;
int dy = y1 - y0;
float derror = Math.abs(dy / (float) dx);
float error = 0;
int y = y0;
int currX, currY;
int lastX = 0, lastY = 0;
boolean first = true;
for (int x = x0; x <= x1; x++) {
if (steep) {
currX = y;
currY = x;
} else {
currX = x;
currY = y;
}
error += derror;
if (error > 0.5) {
y += (y1 > y0 ? 1 : -1);
error -= 1.0;
}
if (first) {
first = false;
continue;
}
Direction direction = Direction.fromDeltas(currX - lastX, currY - lastY);
Position last = new Position(lastX, lastY, start.getHeight());
if (!traversable(last, EntityType.PROJECTILE, direction)) {
return false;
}
lastX = currX;
lastY = currY;
}
return true;
}
use of org.apollo.game.model.Direction in project apollo by apollo-rsps.
the class PathfindingAlgorithm method traversable.
/**
* 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<Position[]> 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--;
}
if (collisionManager.traversable(current, EntityType.NPC, direction)) {
return true;
}
}
return false;
}
use of org.apollo.game.model.Direction in project apollo by apollo-rsps.
the class AStarPathfindingAlgorithm method find.
@Override
public Deque<Position> find(Position origin, Position target) {
Map<Position, Node> nodes = new HashMap<>();
Node start = new Node(origin), end = new Node(target);
nodes.put(origin, start);
nodes.put(target, end);
Set<Node> open = new HashSet<>();
Queue<Node> 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);
Direction direction = Direction.between(adjacent, position);
if (traversable(adjacent, direction)) {
Node node = nodes.computeIfAbsent(adjacent, Node::new);
compare(active, node, open, sorted, heuristic);
}
}
}
} while (!open.isEmpty());
Deque<Position> shortest = new ArrayDeque<>();
Node active = end;
if (active.hasParent()) {
Position position = active.getPosition();
while (!origin.equals(position)) {
shortest.addFirst(position);
// If the target has a parent then all of the others will.
active = active.getParent();
position = active.getPosition();
}
}
return shortest;
}
use of org.apollo.game.model.Direction in project apollo by apollo-rsps.
the class CollisionManagerTests method assertTraversable.
/**
* Helper test assertion that a position is traversable in a given direction.
*
* @param collisionManager The {@link CollisionManager} to check.
* @param position The {@link Position}.
* @param directions The {@link Direction}s to assert.
*/
private static void assertTraversable(CollisionManager collisionManager, Position position, Direction... directions) {
for (Direction direction : directions) {
boolean traversable = collisionManager.traversable(position, EntityType.NPC, direction);
String message = String.format("Cannot walk %s from tile at (%d,%d), should be able to", direction.toString(), position.getX(), position.getY());
Assert.assertTrue(message, traversable);
}
}
Aggregations