Equinox

RSAdvancedPath.java

Sep 30th, 2011
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.50 KB | None | 0 0
  1. import java.util.ArrayList;
  2. import java.util.EnumSet;
  3. import java.util.HashSet;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import java.util.Set;
  7.  
  8. import org.rsbot.script.methods.Calculations;
  9. import org.rsbot.script.methods.Game;
  10. import org.rsbot.script.methods.Objects;
  11. import org.rsbot.script.methods.Players;
  12. import org.rsbot.script.methods.Walking;
  13. import org.rsbot.script.util.Filter;
  14. import org.rsbot.script.wrappers.RSObject;
  15. import org.rsbot.script.wrappers.RSObjectDef;
  16. import org.rsbot.script.wrappers.RSPath.TraversalOption;
  17. import org.rsbot.script.wrappers.RSTile;
  18.  
  19. /**
  20.  * Passes through Gates & obstacles
  21.  *
  22.  * @author Equinox_
  23.  *
  24.  */
  25. public class RSAdvancedPath {
  26.     public static final int WALL_NORTH_WEST = 0x1;
  27.     public static final int WALL_NORTH = 0x2;
  28.     public static final int WALL_NORTH_EAST = 0x4;
  29.     public static final int WALL_EAST = 0x8;
  30.     public static final int WALL_SOUTH_EAST = 0x10;
  31.     public static final int WALL_SOUTH = 0x20;
  32.     public static final int WALL_SOUTH_WEST = 0x40;
  33.     public static final int WALL_WEST = 0x80;
  34.     public static final int BLOCKED = 0x100;
  35.  
  36.     protected RSTile end;
  37.     protected RSTile base;
  38.     protected int[][][] flags;
  39.     protected int[] offX, offY;
  40.     private boolean ended;
  41.     protected RSTile[] tiles;
  42.  
  43.     private final Game game;
  44.     private final Calculations calc;
  45.     private final Walking walking;
  46.     private final Obstacles obstacles;
  47.     private final Players players;
  48.  
  49.     public RSAdvancedPath(Objects objects, Game game, Players players,
  50.         Walking walking, Calculations calc, RSTile end) {
  51.     this.game = game;
  52.     this.walking = walking;
  53.     this.calc = calc;
  54.     this.players = players;
  55.     this.obstacles = new Obstacles(objects, players);
  56.     this.end = end;
  57.     }
  58.  
  59.     /**
  60.      * Traverses the Path
  61.      *
  62.      * @return did traverse
  63.      */
  64.     public boolean traverse() {
  65.     return traverse(EnumSet.of(TraversalOption.HANDLE_RUN,
  66.         TraversalOption.SPACE_ACTIONS));
  67.     }
  68.  
  69.     public boolean traverse(EnumSet<TraversalOption> options) {
  70.     int nIdx = getNextIndex();
  71.     RSTile next = nIdx >= 0 ? tiles[nIdx] : null;
  72.     if (next == null) {
  73.         return false;
  74.     }
  75.     RSObstacle obstacle = obstacles.getObstacleAt(tiles[Math.min(nIdx + 1,
  76.         tiles.length - 1)]);
  77.     if (obstacle != null && obstacle.isOnScreen() && obstacle.canAct()) {
  78.         return obstacle.act();
  79.     } else {
  80.         if (next.equals(getEnd())) {
  81.         if (calc.distanceTo(next) <= 1
  82.             || (ended && players.getMyPlayer().isMoving())
  83.             || next.equals(walking.getDestination())) {
  84.             return false;
  85.         }
  86.         ended = true;
  87.         } else {
  88.         ended = false;
  89.         }
  90.         if (options != null && options.contains(TraversalOption.HANDLE_RUN)
  91.             && !walking.isRunEnabled() && walking.getEnergy() > 50) {
  92.         walking.setRun(true);
  93.         walking.sleep(300);
  94.         }
  95.         if (options != null
  96.             && options.contains(TraversalOption.SPACE_ACTIONS)) {
  97.         RSTile dest = walking.getDestination();
  98.         if (dest != null && players.getMyPlayer().isMoving()
  99.             && calc.distanceTo(dest) > 5
  100.             && calc.distanceBetween(next, dest) < 7) {
  101.             return true;
  102.         }
  103.         }
  104.         return walking.walkTileMM(next, 0, 0);
  105.     }
  106.     }
  107.  
  108.     /**
  109.      * Is this path valid
  110.      */
  111.     public boolean isValid() {
  112.     return getNext() != null
  113.         && !players.getMyPlayer().getLocation().equals(getEnd());
  114.     }
  115.  
  116.     /**
  117.      * Gets the next tile
  118.      */
  119.     public RSTile getNext() {
  120.     int index = getNextIndex();
  121.     if (index >= 0)
  122.         return tiles[index];
  123.     return null;
  124.     }
  125.  
  126.     /**
  127.      * Gets the index of the next tile
  128.      *
  129.      * @return index of the next tile
  130.      */
  131.     public int getNextIndex() {
  132.     if (!recheckPath())
  133.         return -1;
  134.     if (tiles != null)
  135.         for (int i = tiles.length - 1; i >= 0; --i) {
  136.         if (tiles[i] != null)
  137.             if (calc.tileOnMap(tiles[i]))
  138.             return getTileFor(i);
  139.         }
  140.     return -1;
  141.     }
  142.  
  143.     /**
  144.      * Updates the path
  145.      *
  146.      * @return is successful
  147.      */
  148.     private boolean recheckPath() {
  149.     if (!game.getMapBase().equals(base)) {
  150.         int[][] flags = walking.getCollisionFlags(game.getPlane());
  151.         if (flags != null) {
  152.         base = game.getMapBase();
  153.         RSTile start = players.getMyPlayer().getLocation();
  154.         tiles = findPath(start, end);
  155.         if (tiles == null) {
  156.             base = null;
  157.             return false;
  158.         }
  159.         }
  160.     }
  161.     return true;
  162.     }
  163.  
  164.     /**
  165.      * Gets the first reachable tile between your location and the end tile.
  166.      *
  167.      * @param endIndex
  168.      * @return the index
  169.      */
  170.     private int getTileFor(int endIndex) {
  171.     int startIndex = getNearestIndex();
  172.     for (int i = startIndex; i <= endIndex; i++)
  173.         if (obstacles.isObstacleAt(tiles[i]))
  174.         return Math.max(0, i - 1);
  175.     return endIndex;
  176.     }
  177.  
  178.     /**
  179.      * Gets the nearest tile index to your location
  180.      *
  181.      * @return index
  182.      */
  183.     private int getNearestIndex() {
  184.     if (!recheckPath())
  185.         return -1;
  186.     int bIdx = -1;
  187.     double bLen = Integer.MAX_VALUE;
  188.     for (int i = 0; i < tiles.length; i++) {
  189.         double dist = calc.distanceTo(tiles[i]);
  190.         if (dist < bLen) {
  191.         bIdx = i;
  192.         bLen = dist;
  193.         }
  194.     }
  195.     return bIdx;
  196.     }
  197.  
  198.     /**
  199.      * Gets the starting tile
  200.      */
  201.     public RSTile getStart() {
  202.     return tiles != null && tiles.length > 0 ? tiles[0] : null;
  203.     }
  204.  
  205.     /**
  206.      * Gets the ending tile
  207.      */
  208.     public RSTile getEnd() {
  209.     return end;
  210.     }
  211.  
  212.     /**
  213.      * Returns the calculated RSTile array that is currently providing data to
  214.      * this RSAdvancedPath.
  215.      *
  216.      * @return The current RSTile array; or <code>null</code>.
  217.      */
  218.     public RSTile[] getCurrentTiles() {
  219.     return tiles;
  220.     }
  221.  
  222.     protected class Node {
  223.  
  224.     public int x, y, z;
  225.     public Node prev;
  226.     public double g, f;
  227.     public boolean border;
  228.  
  229.     public Node(int x, int y, int z, boolean border) {
  230.         this.border = border;
  231.         this.x = x;
  232.         this.y = y;
  233.         this.z = z;
  234.         g = f = 0;
  235.     }
  236.  
  237.     public Node(int x, int y, int z) {
  238.         this.x = x;
  239.         this.y = y;
  240.         this.z = z;
  241.         g = f = 0;
  242.     }
  243.  
  244.     @Override
  245.     public int hashCode() {
  246.         return (x << 4) | y;
  247.     }
  248.  
  249.     @Override
  250.     public boolean equals(Object o) {
  251.         if (o instanceof Node) {
  252.         Node n = (Node) o;
  253.         return x == n.x && y == n.y && z == n.z;
  254.         }
  255.         return false;
  256.     }
  257.  
  258.     @Override
  259.     public String toString() {
  260.         return "(" + x + "," + y + "," + z + ")";
  261.     }
  262.  
  263.     public RSTile toRSTile(int baseX, int baseY) {
  264.         return new RSTile(x + baseX, y + baseY, z);
  265.     }
  266.  
  267.     }
  268.  
  269.     public RSTile[] findPath(RSTile start, RSTile end) {
  270.     return findPath(start, end, false);
  271.     }
  272.  
  273.     private void updateFlags() {
  274.     flags = new int[4][][];
  275.     offX = new int[4];
  276.     offY = new int[4];
  277.     for (int plane = 0; plane < 4; plane++) {
  278.         flags[plane] = walking.getCollisionFlags(plane);
  279.         RSTile offset = walking.getCollisionOffset(plane);
  280.         offX[plane] = offset.getX();
  281.         offY[plane] = offset.getY();
  282.     }
  283.     }
  284.  
  285.     private RSTile[] findPath(RSTile start, RSTile end, boolean remote) {
  286.     int base_x = base.getX(), base_y = base.getY();
  287.     int curr_x = start.getX() - base_x, curr_y = start.getY() - base_y, curr_z = start
  288.         .getZ();
  289.     int dest_x = end.getX() - base_x, dest_y = end.getY() - base_y, dest_z = end
  290.         .getZ();
  291.  
  292.     // load client data
  293.     updateFlags();
  294.  
  295.     // loaded region only
  296.     if (flags == null || curr_x < 0 || curr_y < 0
  297.         || curr_x >= flags[curr_z].length
  298.         || curr_y >= flags[curr_z].length || dest_x < 0 || dest_y < 0
  299.         || dest_x >= flags[dest_z].length
  300.         || dest_y >= flags[dest_z].length) {
  301.         return null;
  302.     }
  303.  
  304.     // structs
  305.     HashSet<Node> open = new HashSet<Node>();
  306.     HashSet<Node> closed = new HashSet<Node>();
  307.     Node curr = new Node(curr_x, curr_y, curr_z);
  308.     Node dest = new Node(dest_x, dest_y, dest_z);
  309.  
  310.     curr.f = heuristic(curr, dest);
  311.     open.add(curr);
  312.  
  313.     // search
  314.     while (!open.isEmpty()) {
  315.         curr = lowest_f(open);
  316.         if (curr.equals(dest)) {
  317.         // reconstruct from pred tree
  318.         return path(curr, base_x, base_y);
  319.         }
  320.         open.remove(curr);
  321.         closed.add(curr);
  322.         for (Node next : successors(curr)) {
  323.         if (!closed.contains(next)) {
  324.             double t = curr.g + dist(curr, next);
  325.             boolean use_t = false;
  326.             if (!open.contains(next)) {
  327.             open.add(next);
  328.             use_t = true;
  329.             } else if (t < next.g) {
  330.             use_t = true;
  331.             }
  332.             if (use_t) {
  333.             next.prev = curr;
  334.             next.g = t;
  335.             next.f = t + heuristic(next, dest);
  336.             }
  337.         }
  338.         }
  339.     }
  340.  
  341.     // no path
  342.     if (!remote || calc.distanceTo(end) < 10) {
  343.         return null;
  344.     }
  345.     return findPath(start, pull(end));
  346.     }
  347.  
  348.     private RSTile pull(RSTile tile) {
  349.     RSTile p = players.getMyPlayer().getLocation();
  350.     int x = tile.getX(), y = tile.getY();
  351.     if (p.getX() < x) {
  352.         x -= 2;
  353.     } else if (p.getX() > x) {
  354.         x += 2;
  355.     }
  356.     if (p.getY() < y) {
  357.         y -= 2;
  358.     } else if (p.getY() > y) {
  359.         y += 2;
  360.     }
  361.     return new RSTile(x, y);
  362.     }
  363.  
  364.     private double heuristic(Node start, Node end) {
  365.     double dx = start.x - end.x;
  366.     double dy = start.y - end.y;
  367.     double dz = start.z - end.z;
  368.     if (dx < 0) {
  369.         dx = -dx;
  370.     }
  371.     if (dy < 0) {
  372.         dy = -dy;
  373.     }
  374.     if (dz < 0) {
  375.         dz = -dz;
  376.     }
  377.     return dx < dy ? (dz < dy ? dy : dz) : (dz < dx ? dz : dz);
  378.     // double diagonal = dx > dy ? dy : dx;
  379.     // double manhattan = dx + dy;
  380.     // return 1.41421356 * diagonal + (manhattan - 2 * diagonal);
  381.     }
  382.  
  383.     private double dist(Node start, Node end) {
  384.     if (start.x != end.x && start.y != end.y) {
  385.         return 1.41421356;
  386.     } else {
  387.         return 1.0;
  388.     }
  389.     }
  390.  
  391.     private Node lowest_f(Set<Node> open) {
  392.     Node best = null;
  393.     for (Node t : open) {
  394.         if (best == null || t.f < best.f) {
  395.         best = t;
  396.         }
  397.     }
  398.     return best;
  399.     }
  400.  
  401.     private RSTile[] path(Node end, int base_x, int base_y) {
  402.     LinkedList<RSTile> path = new LinkedList<RSTile>();
  403.     Node p = end;
  404.     while (p != null) {
  405.         path.addFirst(p.toRSTile(base_x, base_y));
  406.         p = p.prev;
  407.     }
  408.     return path.toArray(new RSTile[path.size()]);
  409.     }
  410.  
  411.     private List<Node> successors(Node t) {
  412.     LinkedList<Node> tiles = new LinkedList<Node>();
  413.     int x = t.x, y = t.y, z = t.z;
  414.     int f_x = x - offX[z], f_y = y - offY[z];
  415.     int here = flags[z][f_x][f_y];
  416.     int upper = flags.length - 1;
  417.     if (base == null)
  418.         base = game.getMapBase();
  419.     boolean isobstacle = obstacles.isObstacleAt(new RSTile(x + base.getX(),
  420.         y + base.getY(), z));
  421.     if ((f_y > 0
  422.         && ((here & WALL_SOUTH) == 0 || isobstacle || obstacles
  423.             .isObstacleAt(new RSTile(x + base.getX(), y
  424.                 + base.getY() - 1))) && ((flags[z][f_x][f_y - 1] & BLOCKED) == 0))) {
  425.         tiles.add(new Node(x, y - 1, z));
  426.     }
  427.     if ((f_x > 0
  428.         && ((here & WALL_WEST) == 0 || isobstacle || obstacles
  429.             .isObstacleAt(new RSTile(x + base.getX() - 1, y
  430.                 + base.getY()))) && ((flags[z][f_x - 1][f_y] & BLOCKED) == 0))) {
  431.         tiles.add(new Node(x - 1, y, z));
  432.     }
  433.     if ((f_y < upper && ((here & WALL_NORTH) == 0 || isobstacle) && ((flags[z][f_x][f_y + 1] & BLOCKED) == 0))) {
  434.         tiles.add(new Node(x, y + 1, z));
  435.     }
  436.     if ((f_x < upper
  437.         && ((here & WALL_EAST) == 0 || isobstacle || obstacles
  438.             .isObstacleAt(new RSTile(x + base.getX() + 1, y
  439.                 + base.getY()))) && ((flags[z][f_x + 1][f_y] & BLOCKED) == 0))) {
  440.         tiles.add(new Node(x + 1, y, z));
  441.     }
  442.  
  443.     if (f_x > 0 && f_y > 0
  444.         && (here & (WALL_SOUTH_WEST | WALL_SOUTH | WALL_WEST)) == 0
  445.         && (flags[z][f_x - 1][f_y - 1] & BLOCKED) == 0
  446.         && (flags[z][f_x][f_y - 1] & (BLOCKED | WALL_WEST)) == 0
  447.         && (flags[z][f_x - 1][f_y] & (BLOCKED | WALL_SOUTH)) == 0) {
  448.         tiles.add(new Node(x - 1, y - 1, z));
  449.     }
  450.     if (f_x > 0 && f_y < upper
  451.         && (here & (WALL_NORTH_WEST | WALL_NORTH | WALL_WEST)) == 0
  452.         && (flags[z][f_x - 1][f_y + 1] & BLOCKED) == 0
  453.         && (flags[z][f_x][f_y + 1] & (BLOCKED | WALL_WEST)) == 0
  454.         && (flags[z][f_x - 1][f_y] & (BLOCKED | WALL_NORTH)) == 0) {
  455.         tiles.add(new Node(x - 1, y + 1, z));
  456.     }
  457.     if (f_x < upper && f_y > 0
  458.         && (here & (WALL_SOUTH_EAST | WALL_SOUTH | WALL_EAST)) == 0
  459.         && (flags[z][f_x + 1][f_y - 1] & BLOCKED) == 0
  460.         && (flags[z][f_x][f_y - 1] & (BLOCKED | WALL_EAST)) == 0
  461.         && (flags[z][f_x + 1][f_y] & (BLOCKED | WALL_SOUTH)) == 0) {
  462.         tiles.add(new Node(x + 1, y - 1, z));
  463.     }
  464.     if (f_x > 0 && f_y < upper
  465.         && (here & (WALL_NORTH_EAST | WALL_NORTH | WALL_EAST)) == 0
  466.         && (flags[z][f_x + 1][f_y + 1] & BLOCKED) == 0
  467.         && (flags[z][f_x][f_y + 1] & (BLOCKED | WALL_EAST)) == 0
  468.         && (flags[z][f_x + 1][f_y] & (BLOCKED | WALL_NORTH)) == 0) {
  469.         tiles.add(new Node(x + 1, y + 1, z));
  470.     }
  471.  
  472.     return tiles;
  473.     }
  474.  
  475.     public static class Obstacles {
  476.     private final Objects objects;
  477.     private final Players players;
  478.  
  479.     Obstacles(final Objects objects,
  480.         final Players players) {
  481.         this.objects = objects;
  482.         this.players = players;
  483.     }
  484.  
  485.     private final static String[] OBSTACLE_NAMES = { "obstacle", "gate" };
  486.     public final static Filter<RSObject> OBSTACLE_FILTER = new Filter<RSObject>() {
  487.         @Override
  488.         public boolean accept(RSObject o) {
  489.         RSObjectDef def = o.getDef();
  490.         if (def != null && def.getName() != null) {
  491.             for (String s : OBSTACLE_NAMES)
  492.             if (s.trim().equalsIgnoreCase(def.getName().trim()))
  493.                 return true;
  494.         }
  495.         return false;
  496.         }
  497.     };
  498.  
  499.     public boolean isObstacle(RSObject object) {
  500.         return OBSTACLE_FILTER.accept(object);
  501.     }
  502.  
  503.     public RSObstacle[] getAll() {
  504.         List<RSObstacle> obstacles = new ArrayList<RSObstacle>();
  505.         for (RSObject o : objects.getAll(OBSTACLE_FILTER))
  506.         obstacles.add(new RSObstacle(objects, this,players, o.getLocation(),
  507.             "Open"));
  508.         return obstacles.toArray(new RSObstacle[obstacles.size()]);
  509.     }
  510.  
  511.     public RSObstacle getObstacleAt(RSTile tile) {
  512.         RSObstacle obstacle = new RSObstacle(objects, this,players, tile, "Open");
  513.         return obstacle.isObstacle() ? obstacle : null;
  514.     }
  515.  
  516.     public boolean isObstacleAt(RSTile tile) {
  517.         RSObstacle obstacle = getObstacleAt(tile);
  518.         return obstacle != null;
  519.     }
  520.  
  521.     public boolean isActableObstacleAt(RSTile tile) {
  522.         RSObstacle obstacle = getObstacleAt(tile);
  523.         return obstacle != null && obstacle.canAct();
  524.     }
  525.     }
  526.  
  527.     public static class RSObstacle {
  528.     private final RSTile location;
  529.     private String action;
  530.  
  531.     private final Objects objects;
  532.     private final Obstacles obsts;
  533.     private final Players players;
  534.  
  535.     public RSObstacle(Objects objects, Obstacles obsts, Players players,
  536.         RSTile location, String action) {
  537.         this.objects = objects;
  538.         this.obsts = obsts;
  539.         this.players = players;
  540.         this.location = location;
  541.         this.action = action;
  542.     }
  543.  
  544.     public boolean isObstacle() {
  545.         return getObject() != null;
  546.     }
  547.  
  548.     public RSTile getLocation() {
  549.         return location;
  550.     }
  551.  
  552.     public RSObject getObject() {
  553.         RSObject[] objectsA = objects.getAt(location,
  554.             Objects.TYPE_INTERACTABLE | Objects.TYPE_BOUNDARY);
  555.         for (RSObject o : objectsA)
  556.         if (obsts.isObstacle(o))
  557.             return o;
  558.         return null;
  559.     }
  560.  
  561.     public boolean canAct() {
  562.         RSObject obj = getObject();
  563.         if (obj != null) {
  564.         RSObjectDef def = obj.getDef();
  565.         if (def != null && def.getActions() != null) {
  566.             for (String s : def.getActions()) {
  567.             if (s != null && s.contains(action)) {
  568.                 return true;
  569.             }
  570.             }
  571.         }
  572.         }
  573.         return false;
  574.     }
  575.  
  576.     public boolean act() {
  577.         RSObject obstacle = getObject();
  578.         if (obstacle != null) {
  579.         if (obstacle.interact(action))
  580.             for (byte b = 0; b < 50 && !canAct()
  581.                 && players.getMyPlayer().getAnimation() == -1; b++)
  582.             objects.sleep(125);
  583.         return true;
  584.         }
  585.         return false;
  586.     }
  587.  
  588.     public boolean isOnScreen() {
  589.         RSObject obstacle = getObject();
  590.         return obstacle != null && obstacle.isOnScreen();
  591.     }
  592.     }
  593.  
  594. }
  595.  
  596.  
Advertisement
Add Comment
Please, Sign In to add comment