Search in sources :

Example 1 with Direction

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;
}
Also used : Position(org.apollo.game.model.Position) Region(org.apollo.game.model.area.Region) Direction(org.apollo.game.model.Direction)

Example 2 with Direction

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;
}
Also used : Position(org.apollo.game.model.Position) Direction(org.apollo.game.model.Direction)

Example 3 with Direction

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;
}
Also used : Position(org.apollo.game.model.Position) Direction(org.apollo.game.model.Direction)

Example 4 with Direction

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;
}
Also used : Position(org.apollo.game.model.Position) HashMap(java.util.HashMap) PriorityQueue(java.util.PriorityQueue) Direction(org.apollo.game.model.Direction) ArrayDeque(java.util.ArrayDeque) HashSet(java.util.HashSet)

Example 5 with Direction

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);
    }
}
Also used : Direction(org.apollo.game.model.Direction)

Aggregations

Direction (org.apollo.game.model.Direction)10 Position (org.apollo.game.model.Position)8 Region (org.apollo.game.model.area.Region)2 MovementSegment (org.apollo.game.sync.seg.MovementSegment)2 TeleportSegment (org.apollo.game.sync.seg.TeleportSegment)2 ArrayDeque (java.util.ArrayDeque)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 PriorityQueue (java.util.PriorityQueue)1 World (org.apollo.game.model.World)1 CollisionManager (org.apollo.game.model.area.collision.CollisionManager)1 DirectionFlag (org.apollo.game.model.area.collision.CollisionUpdate.DirectionFlag)1