Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- *Creates a Mesh-based path, rounds it using Bezier curves, then subdivides the generated *path
- *@author Equinox-
- */
- public class MeshPath {
- public static final Color BLOCK_PATH_COLOR = new Color(0f, 1f, 0f, 1f);
- public static final Color MESH_BORDER = new Color(0.75f, 0.75f, 0.75f,
- 0.75f);
- public static final Color MESH_FILL = new Color(0.5f, 0.5f, 0.5f, 0.75f);
- public static final Color SMOOTH_PATH_COLOR = new Color(0f, 0f, 1f, 1f);
- private List<RSTile> blockPath = new ArrayList<RSTile>();
- private final Calculations calc;
- private boolean end;
- private List<RSTile[]> mesh = new ArrayList<RSTile[]>();
- private final Players players;
- private List<RSTile> smoothPath = new ArrayList<RSTile>();
- private final Walking walking;
- private final Range walkingDistance;
- public MeshPath(Walking walking, Calculations calc, Players players) {
- this(walking, calc, players, new Range(7, 9));
- }
- public MeshPath(Walking walking, Calculations calc, Players players,
- Range walkingDistance) {
- this.walking = walking;
- this.calc = calc;
- this.players = players;
- this.walkingDistance = walkingDistance;
- }
- public MeshPath(Walking walking, Calculations calc, Players players,
- RSTile[][] mesh) {
- this(walking, calc, players);
- setMesh(mesh);
- }
- public MeshPath(Walking walking, Calculations calc, Players players,
- RSTile[][] mesh, Range walkingDistance) {
- this(walking, calc, players, walkingDistance);
- setMesh(mesh);
- }
- public void addLine(RSTile... tiles) {
- if (mesh.size() == 0) {
- mesh.add(tiles);
- return;
- }
- RSTile first = tiles[0];
- RSTile last = tiles[tiles.length - 1];
- RSTile[] oLine = mesh.get(mesh.size() - 1);
- RSTile oFirst = oLine[0];
- RSTile oLast = oLine[oLine.length - 1];
- double straight = calc.distanceBetween(first, oFirst)
- + calc.distanceBetween(last, oLast);
- double crossed = calc.distanceBetween(first, oLast)
- + calc.distanceBetween(last, oFirst);
- if (straight > crossed) {
- mesh.add(tiles);
- return;
- } else {
- RSTile[] reversed = new RSTile[tiles.length];
- for (int i = 0; i < tiles.length; i++)
- reversed[i] = tiles[tiles.length - 1 - i];
- mesh.add(reversed);
- return;
- }
- }
- public void addMesh(RSTile[][] mesh) {
- for (RSTile[] line : mesh)
- addLine(line);
- }
- public void clearPath() {
- blockPath.clear();
- smoothPath.clear();
- }
- public void findPath() {
- findPath(MeshPathType.WEIGHT_CENTER);
- }
- public void findPath(MeshPathType placement) {
- findPath(placement, 0, mesh.size() - 1);
- }
- public void findPath(MeshPathType placement, int start, int end) {
- blockPath.clear();
- for (int i = start; i <= end; i++)
- blockPath.add(getTileOnLine(placement, mesh.get(i)));
- smoothPath = smoothPath(blockPath);
- }
- public RSTile getEnd() {
- if (smoothPath.size() > 0)
- return smoothPath.get(smoothPath.size() - 1);
- else
- return null;
- }
- public RSTile getNext() {
- if (smoothPath.size() > 0) {
- for (int i = smoothPath.size() - 1; i >= 0; i--)
- if (calc.tileOnMap(smoothPath.get(i)))
- return smoothPath.get(i);
- return getTileOnMap(smoothPath.get(0));
- }
- return null;
- }
- public RSTile getTileOnMap(RSTile base) {
- if (calc.tileOnMap(base))
- return base;
- RSTile me = players.getMyPlayer().getLocation();
- int deltaX = base.getX() - me.getX();
- int deltaY = base.getY() - me.getY();
- double dist = calc.distanceBetween(base, me);
- double eX = deltaX / dist, eY = deltaY / dist;
- return new RSTile(me.getX() + (int) (eX * 15), me.getY()
- + (int) (eY * 15));
- }
- public RSTile getStart() {
- if (smoothPath.size() > 0)
- return smoothPath.get(0);
- else
- return null;
- }
- public RSTile getTileInMesh(RSTile tile) {
- if (inMesh(tile))
- return tile;
- double bestDist = Double.MAX_VALUE;
- RSTile nearest = null;
- if (mesh.size() > 1) {
- for (int i = 1; i < mesh.size(); i++) {
- RSTile[] lineA = mesh.get(i - 1);
- RSTile[] lineB = mesh.get(i);
- if (lineA != null)
- for (RSTile t : lineA) {
- double dist = calc.distanceBetween(t, tile);
- if (dist < bestDist) {
- nearest = new RSTile(t.getX(), t.getY());
- bestDist = Double.valueOf(dist);
- }
- }
- if (lineB != null)
- for (RSTile t : lineB) {
- double dist = calc.distanceBetween(t, tile);
- if (dist < bestDist) {
- nearest = new RSTile(t.getX(), t.getY());
- bestDist = Double.valueOf(dist);
- }
- }
- }
- }
- return nearest;
- }
- public RSTile getTileOnLine(MeshPathType placement, RSTile... line) {
- List<RSTile> tiles = getTilesOnLines(line);
- int index = 0;
- switch (placement) {
- case ALL_CENTER:
- index = new Range((int) (tiles.size() * .25d),
- (int) (tiles.size() * 0.75d)).random();
- break;
- case FULL:
- index = new Range(0, tiles.size()).random();
- break;
- case WEIGHT_CENTER:
- index = new Range(0, tiles.size()).random();
- break;
- }
- if (index < 0)
- index = 0;
- if (index >= tiles.size())
- index = tiles.size() - 1;
- if (tiles.size() > 0)
- return tiles.get(index);
- else
- return null;
- }
- public RSTile getTileOnLine(RSTile... line) {
- return getTileOnLine(MeshPathType.WEIGHT_CENTER, line);
- }
- public RSTile[] getTilePath() {
- RSTile[] tiles = new RSTile[smoothPath.size()];
- for (int i = 0; i < tiles.length; i++)
- tiles[i] = new RSTile(smoothPath.get(i).getX(), smoothPath.get(
- i).getY());
- return tiles;
- }
- public List<RSTile> getTilesOnLine(RSTile a, RSTile b) {
- List<RSTile> sublineTiles = new ArrayList<RSTile>();
- int deltaX = b.getX() - a.getX();
- int deltaY = b.getY() - a.getY();
- double dist = calc.distanceBetween(a, b);
- if (dist == 0)
- dist = 1;
- double eX = deltaX / dist, eY = deltaY / dist;
- for (int i = 0; i <= dist; i++)
- sublineTiles.add(new RSTile(a.getX() + (int) (eX * i), a.getY()
- + (int) (eY * i)));
- return sublineTiles;
- }
- public List<RSTile> getTilesOnLines(RSTile... line) {
- List<RSTile> sublineTiles = new ArrayList<RSTile>();
- if (line.length == 1)
- sublineTiles.add(line[0]);
- else
- for (int i = 1; i < line.length; i++) {
- RSTile a = line[i - 1];
- RSTile b = line[i];
- sublineTiles.addAll(getTilesOnLine(a, b));
- }
- return sublineTiles;
- }
- public boolean hasPath() {
- return smoothPath.size() > 0;
- }
- public boolean inMesh(RSTile tile) {
- if (mesh.size() > 1) {
- for (int i = 1; i < mesh.size(); i++) {
- RSTile[] lineA = mesh.get(i - 1);
- RSTile[] lineB = mesh.get(i);
- Polygon poly = new Polygon();
- if (lineA != null)
- for (RSTile t : lineA)
- poly.addPoint(t.getX(), t.getY());
- if (lineB != null)
- for (RSTile t : lineB)
- poly.addPoint(t.getX(), t.getY());
- if (poly.npoints >= 2)
- if (poly.contains(new Point(tile.getX(), tile.getY())))
- return true;
- }
- }
- return false;
- }
- public boolean isValid() {
- return smoothPath.size() > 0 && getNext() != null
- && !players.getMyPlayer().getLocation().equals(getEnd());
- }
- public int meshSize() {
- return mesh.size();
- }
- public void paintAll(Graphics2D g) {
- paintMesh(g);
- paintBlockPath(g);
- paintSmoothPath(g);
- }
- public void paintBlockPath(Graphics2D g) {
- if (blockPath.size() > 1) {
- g.setColor(BLOCK_PATH_COLOR);
- Point a = null;
- for (RSTile t : blockPath) {
- Point b = calc.tileToMinimap(t);
- if (b.x > 0 && b.y > 0)
- g.fillOval(b.x - 2, b.y - 2, 5, 5);
- if (a != null && a.x > 0 && a.y > 0 && b.x > 0 && b.y > 0)
- g.drawLine(a.x, a.y, b.x, b.y);
- a = b;
- }
- }
- }
- public void paintMesh(Graphics2D g) {
- if (mesh.size() > 1) {
- Point[] oldLine = null;
- for (int i = 0; i < mesh.size(); i++) {
- RSTile[] lineB = mesh.get(i);
- Point[] thisLine = new Point[lineB.length];
- Polygon poly = new Polygon();
- boolean onMap = true;
- for (int tile = 0; tile < thisLine.length; tile++) {
- Point p = calc.tileToMinimap(lineB[tile]);
- thisLine[tile] = p;
- poly.addPoint(p.x, p.y);
- if (p.x == -1 || p.y == -1)
- onMap = false;
- }
- if (oldLine != null) {
- for (Point p : oldLine) {
- poly.addPoint(p.x, p.y);
- if (p.x == -1 || p.y == -1)
- onMap = false;
- }
- if (poly.npoints >= 2 && onMap) {
- g.setColor(MESH_BORDER);
- g.draw(poly);
- g.setColor(MESH_FILL);
- g.fill(poly);
- }
- }
- oldLine = thisLine;
- }
- }
- }
- public void paintSmoothPath(Graphics2D g) {
- if (smoothPath.size() > 1) {
- g.setColor(SMOOTH_PATH_COLOR);
- Point a = null;
- for (RSTile t : smoothPath) {
- Point b = calc.tileToMinimap(t);
- if (b.x > 0 && b.y > 0)
- g.fillOval(b.x - 2, b.y - 2, 5, 5);
- if (a != null && a.x > 0 && a.y > 0 && b.x > 0 && b.y > 0)
- g.drawLine(a.x, a.y, b.x, b.y);
- a = b;
- }
- }
- }
- public MeshPath reverse() {
- MeshPath m = new MeshPath(walking, calc, players);
- for (int i = mesh.size() - 1; i >= 0; i--) {
- m.addLine(blockPath.get(i));
- }
- return m;
- }
- public void setMesh(RSTile[][] mesh) {
- this.mesh.clear();
- addMesh(mesh);
- }
- public List<RSTile> smoothPath(List<RSTile> path) {
- List<RSTile> smoothed = new ArrayList<RSTile>();
- if (path.size() >= 3) {
- for (int i = 0; i < path.size(); i++) {
- if (i + 2 < path.size()) {
- RSTile tile1 = path.get(i);
- RSTile tile2 = path.get(i + 1);
- RSTile tile3 = path.get(i + 2);
- if (i == 0)
- smoothed.add(tile1);
- double x2, y2;
- double t = 0.5d;
- x2 = (tile1.getX() + t
- * (-tile1.getX() * 3 + t
- * (3 * tile1.getX() - tile1.getX() * t)))
- + t
- * (3 * tile2.getX() + t
- * (-6 * tile2.getX() + tile2.getX() * 3
- * t))
- + t
- * t
- * (tile2.getX() * 3 - tile2.getX() * 3 * t)
- + tile3.getX() * t * t * t;
- y2 = (tile1.getY() + t
- * (-tile1.getY() * 3 + t
- * (3 * tile1.getY() - tile1.getY() * t)))
- + t
- * (3 * tile2.getY() + t
- * (-6 * tile2.getY() + tile2.getY() * 3
- * t))
- + t
- * t
- * (tile2.getY() * 3 - tile2.getY() * 3 * t)
- + tile3.getY() * t * t * t;
- smoothed.add(getTileInMesh(new RSTile((int) x2,
- (int) y2)));
- } else {
- smoothed.add(path.get(i));
- }
- }
- }
- return smoothed;
- }
- public boolean traverse() {
- return this.traverse(EnumSet.of(TraversalOption.HANDLE_RUN,
- TraversalOption.SPACE_ACTIONS));
- }
- public boolean traverse(EnumSet<TraversalOption> options) {
- RSTile next = getNext();
- if (next == null) {
- return false;
- }
- if (next.equals(getEnd())) {
- if (calc.distanceTo(next) <= 1
- || (end && players.getMyPlayer().isMoving())
- || next.equals(walking.getDestination())) {
- return false;
- }
- end = true;
- } else {
- end = false;
- }
- if (options.contains(TraversalOption.HANDLE_RUN)
- && !walking.isRunEnabled() && walking.getEnergy() > 50) {
- walking.setRun(true);
- }
- if (options.contains(TraversalOption.SPACE_ACTIONS)) {
- RSTile dest = walking.getDestination();
- if (dest != null
- && players.getMyPlayer().isMoving()
- && calc.distanceTo(dest) > 5
- && calc.distanceBetween(next, dest) < walkingDistance
- .random()) {
- return true;
- }
- }
- return walking.walkTileMM(next, 0, 0);
- }
- public int getNearestIndexTo(RSTile t) {
- int len = Integer.MAX_VALUE;
- int bestIndex = -1;
- if (hasPath())
- for (int i = 0; i < smoothPath.size(); i++)
- if (calc.distanceBetween(t, smoothPath.get(i)) < len) {
- bestIndex = i;
- len = calc.distanceTo(t);
- }
- return bestIndex;
- }
- public enum MeshPathType {
- ALL_CENTER, FULL, WEIGHT_CENTER
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment