import org.rsbot.event.listeners.PaintListener; import org.rsbot.script.Script; import org.rsbot.script.ScriptManifest; import org.rsbot.script.methods.Game; import org.rsbot.script.methods.Objects; import org.rsbot.script.methods.Skills; import org.rsbot.script.util.Timer; import org.rsbot.script.wrappers.*; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.net.URL; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; @ScriptManifest(authors = {"Mike_"}, keywords = {"Mike","Agility","Ape Atoll"}, name = "Monkey Agility", description = "", version = 2.02) public class MonkeyAgility extends Script implements PaintListener { Obstacle pause, tree, bars, slope, swing, rope, pineapple, step; int last = -1; String debug; Obstacle[] course; Timer runTime; Timer changeStateTimer; Timer failsafeTimer; RSObject next; Image bg; int startingXp = 0, startingLevel = 0, xp = 0, level = 0; double perc = 0; public void onRepaint(Graphics graphics) { try { Graphics2D g = (Graphics2D) graphics; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Font f = new Font("Arial", Font.PLAIN, 12); FontMetrics fm = g.getFontMetrics(f); g.setFont(f); g.setColor(new Color(0, 0, 0, 100)); double hours = (double) runTime.getElapsed() / 1000 / 60 / 60; int gained = skills.getCurrentExp(Skills.AGILITY) - startingXp; int level = skills.getCurrentLevel(Skills.AGILITY); int laps = gained/580; if (hours == 0.0) return; double perHour = (gained / hours); String[][] msg = { {"Time: ", runTime.toElapsedString()}, {"Agility: ", format(gained) + "xp"}, {"", format((int) perHour) + "xp/hr"}, {"Laps: ", format(laps)}, {"", format((int)(laps/hours))+"/hr"}, }; g.setColor(new Color(0, 0, 0, 60)); for (int i = 0; i < 5; i++) { RoundRectangle2D box = new RoundRectangle2D.Double(20 + i * 1.5, 40 + i * 1.5, 150, 142, 10, 10); g.fill(box); } g.drawImage(bg, 20, 40, null); int y = 60; String title = "Monkey Agility"; int logoX = (150 - fm.stringWidth(title)) / 2 + 20; g.setColor(Color.BLACK); g.drawString(title, logoX + 1, y + 1); g.setColor(new Color(255, 205, 0)); g.drawString(title, logoX, y); f = new Font("Verdana", Font.PLAIN, 11); fm = g.getFontMetrics(f); g.setFont(f); int longest = -1; for (String[] s : msg) if (fm.stringWidth(s[0]) > longest) longest = fm.stringWidth(s[0]); y += 3; for (String[] s : msg) { y += 15; g.setColor(Color.BLACK); g.drawString(s[0], 31, y + 1); g.setColor(new Color(255, 205, 0)); g.drawString(s[0], 30, y); g.setColor(new Color(0, 0, 0, 90)); RoundRectangle2D box = new RoundRectangle2D.Double(30 + longest, y - 10, fm.stringWidth(s[1]) + 9, 13, 5, 5); g.fill(box); g.setColor(Color.BLACK); g.drawString(s[1], 35 + longest, y + 1); g.setColor(new Color(255, 205, 0)); g.drawString(s[1], 34 + longest, y); } y += 12; double perc = (double) skills.getPercentToNextLevel(Skills.AGILITY) / 100; g.setColor(new Color(0, 0, 0, 120)); RoundRectangle2D box = new RoundRectangle2D.Double(33, y, 125, 15, 5, 5); g.fill(box); g.setColor(new Color(179, 126, 63)); box = new RoundRectangle2D.Double(35, y + 2, 121 * perc + 1, 9, 3, 3); g.fill(box); g.setColor(new Color(128, 80, 37)); box = new RoundRectangle2D.Double(36, y + 3, 121 * perc, 9, 3, 3); g.fill(box); if (perHour == 0) return; double time = skills.getExpToNextLevel(Skills.AGILITY) / perHour; //I should kill myself for this abomination in these this and the next line. String timeLeft = (int) Math.floor(time) + ":" + String.format("%02d", (int) ((time * 60) % 60)) + " until " + (level + 1); int timeLeftX = (125 - fm.stringWidth(timeLeft)) / 2 + 33; g.setColor(new Color(119, 72, 33)); box = new RoundRectangle2D.Double(36, y + 3, 121 * perc, 9, 3, 3); g.draw(box); g.setColor(new Color(0, 0, 0)); g.drawString(timeLeft, timeLeftX + 1, y + 13); g.setColor(new Color(255, 205, 0)); g.drawString(timeLeft, timeLeftX, y + 12); } catch (Exception e) { e.printStackTrace(); } } public void onServerMessage(String s) { } public void build() { pause = new Obstacle() { @Override boolean isCurrent() { return game.getPlane() == 0 && getMyPlayer().getLocation().equals(new RSTile(2754, 2742)); } @Override String actionName() { return "Walking over step... PAUSE!"; //To change body of implemented methods use File | Settings | File Templates. } @Override RSObject get() { return objects.getNearest(12570); //To change body of implemented methods use File | Settings | File Templates. } boolean overcome() { return false; } }; tree = new Obstacle() { @Override boolean isCurrent() { return game.getPlane() == 0 && (getMyPlayer().getLocation().equals(new RSTile(2753, 2742)) || getMyPlayer().getLocation().equals(new RSTile(2752, 2742))); } @Override String actionName() { return "Climb Tropical tree"; //To change body of implemented methods use File | Settings | File Templates. } @Override RSObject get() { return objects.getNearest(12570); //To change body of implemented methods use File | Settings | File Templates. } }; bars = new Obstacle() { @Override boolean isCurrent() { int x = getMyPlayer().getLocation().getX(); int y = getMyPlayer().getLocation().getY(); return game.getPlane() == 2 && x <= 2754 && y <= 2742 && x >= 2752 && y >= 2741; } @Override String actionName() { return "Swing Across Monkeybars"; } @Override RSObject get() { return objects.getNearest(12573); } }; slope = new Obstacle() { @Override boolean isCurrent() { int x = getMyPlayer().getLocation().getX(); int y = getMyPlayer().getLocation().getY(); RSTile dest = walking.getDestination(); return y==2741 && x<=2748 && (x>=2746 || (getMyPlayer().isMoving() && x>=2744)); } @Override String actionName() { return "Climb-up Skull slope"; } @Override RSObject get() { RSObject[] o = objects.getAt(new RSTile(2746, 2741),Objects.TYPE_FLOOR_DECORATION); if (o.length > 0) return o[0]; return null; } }; swing = new Obstacle() { @Override boolean isCurrent() { return getMyPlayer().getLocation().getX() <= 2752; } @Override String actionName() { return "Swing Rope"; } @Override RSObject get() { return objects.getTopAt(new RSTile(2752,2731)); } @Override RSTile walkTile() { return new RSTile(2751,2731); } }; rope = new Obstacle() { @Override boolean isCurrent() { return getMyPlayer().getLocation().getY() <= 2737; } @Override String actionName() { return "Climb-down Tropical tree"; } @Override RSObject get() { return objects.getNearest(12618); } }; pineapple = new Obstacle() { @Override boolean isCurrent() { RSObject[] o = objects.getAt(new RSTile(2754, 2742), Objects.TYPE_FLOOR_DECORATION); RSObject stone = null; if (o.length > 0) stone = o[0]; if (level < 75 && 28 - inventory.getCount() > 4) { RSObject p = objects.getTopAt(new RSTile(2776, 2749)); if (p!=null && calc.distanceTo(p) < calc.distanceTo(stone)) return true; } return false; } @Override String actionName() { return "Pick Pineapple Plant"; //To change body of implemented methods use File | Settings | File Templates. } @Override RSObject get() { return objects.getTopAt(new RSTile(2776, 2749)); } }; step = new Obstacle() { @Override boolean isCurrent() { return true; } @Override String actionName() { return "Jump-to Stepping stone"; } @Override RSObject get() { RSObject[] o = objects.getAt(new RSTile(2754, 2742), Objects.TYPE_FLOOR_DECORATION); RSObject stone = null; if (o.length > 0) stone = o[0]; return stone; } @Override RSTile walkTile() { return new RSTile(2755,2742); } }; course = new Obstacle[]{pause, tree, bars, slope, swing, rope, pineapple, step}; } public RSItem getItem(String name) { RSItem[] inv = inventory.getItems(); for(RSItem item:inv) { if(item.getName().equalsIgnoreCase(name)) return item; } return null; } @Override public int loop() { if (!failsafeTimer.isRunning()) return -1; if (!game.isLoggedIn() || game.isWelcomeScreen()) return random(50, 100); if (startingXp == 0) { startingXp = skills.getCurrentExp(Skills.AGILITY); startingLevel = skills.getCurrentLevel(Skills.AGILITY); } xp = skills.getCurrentExp(Skills.AGILITY); level = skills.getCurrentLevel(Skills.AGILITY); perc = skills.getPercentToNextLevel(Skills.AGILITY); try { game.openTab(Game.TAB_INVENTORY); RSItem greegree = getItem("Monkey greegree"); if(greegree!=null) greegree.doAction("Use"); if (changeStateTimer != null && (getMyPlayer().isMoving() || getMyPlayer().getAnimation() != -1)) changeStateTimer = new Timer(3000); if (changeStateTimer == null) { if (getMyPlayer().getAnimation() != -1) return random(50, 100); if (getMyPlayer().isMoving()) { RSTile dest = walking.getDestination(); RSObject a = course[last].get(); if(a==null || dest==null || calc.distanceBetween(dest,a.getLocation())<2) if (course[last] == slope) return random(50, 100); if (dest != null && calc.distanceTo(dest) > 5 && calc.distanceTo(dest) < 18) return random(50, 100); if (dest == null) return random(50, 100); } } if (changeStateTimer != null) { int current = -1; for (int i = 0; i < course.length; i++) { if (course[i].isCurrent()) { current = i; break; } } if (current != last || !changeStateTimer.isRunning()) { changeStateTimer = null; last = current; } } if (changeStateTimer != null) { debug = "busy"; return random(50, 100); } if (menu.contains("->") || menu.contains("Use Knife")) menu.doAction("Cancel"); if (inventory.contains(2114) && 28 - inventory.getCount() >= 4) { RSComponent slice = interfaces.getComponent(140, 2); RSComponent slice2 = interfaces.getComponent(513, 72); if (slice2 != null) { if (slice2.doAction("Make All")) return random(900, 1200); else return random(50, 100); } if (slice != null) if (slice.doAction("Continue")) return random(900, 1200); else return random(50, 100); RSItem knife = inventory.getItem(946); RSItem pineapple=inventory.getItem(2114); if (inventory.useItem(knife,pineapple)) { return random(900, 1200); } } for (int i = 0; i < course.length; i++) { if (course[i].isCurrent()) { last = i; debug = course[i].actionName(); if (course[i].overcome()) { failsafeTimer = new Timer(120000); changeStateTimer = new Timer(3000); return random(600, 1200); } RSObject obs = course[i].get(); if (obs == null || obs.isOnScreen()) return random(50, 100); RSTile t = obs.getLocation(); if(!obs.isOnScreen() && calc.distanceTo(t)<5) camera.turnToObject(obs); if(calc.distanceTo(t)>=5 || random(0,50)==5) if(walkPath(fixPath(course[i].walkTile()))) { if(!obs.isOnScreen()) { sleep(random(0,300)); camera.turnToObject(obs); } return random(600, 1200); } } } } catch (Exception e) { e.printStackTrace(); } return random(50, 100); } public int hp() { return combat.getLifePoints(); } @Override public boolean onStart() { runTime = new Timer(Integer.MAX_VALUE); try { bg = ImageIO.read(new URL("http://i.imgur.com/JdK5N.png")); } catch (Exception e) { e.printStackTrace(); } failsafeTimer = new Timer(120000); build(); return true; } public RSTile[] fixPath(RSTile t) { int startX = getMyPlayer().getLocation().getX(); int startY = getMyPlayer().getLocation().getY(); int destinationX = t.getX(); int destinationY = t.getY(); double dx, dy; ArrayList list = new ArrayList(); list.add(new RSTile(startX, startY)); while (Math.hypot(destinationY - startY, destinationX - startX) > 8) { dx = destinationX - startX; dy = destinationY - startY; int gamble = random(5, 7); while (Math.hypot(dx, dy) > gamble) { dx *= .95; dy *= .95; } startX += (int) dx; startY += (int) dy; list.add(new RSTile(startX, startY)); } list.add(new RSTile(destinationX, destinationY)); return list.toArray(new RSTile[list.size()]); } public boolean walkPath(RSTile[] path) { if (path == null || path.length == 0) { throw new IllegalArgumentException("path can not be null or empty"); } if (walking.getEnergy() > random(30, 99)) { walking.setRun(true); } RSTile last = null; for (RSTile aPath : path) { if (calc.distanceTo(aPath)<=15) { last = aPath; } } return last != null && walking.walkTileMM(new RSTile(last.getX() + random(-2, 3), last.getY() + random(-2, 3))); } public String format(int num) { DecimalFormat df = new DecimalFormat(); DecimalFormatSymbols dfs = new DecimalFormatSymbols(); dfs.setGroupingSeparator(','); df.setDecimalFormatSymbols(dfs); return df.format(num); } public boolean modelContains(RSModel m, Point p) { if (m == null || p == null) return false; Polygon[] poly = m.getTriangles(); if (poly.length < 1) return false; for (Polygon t : poly) if (t.contains(p)) return true; return false; } public boolean doAction(RSObject o, String s) { return o!= null && ((!modelContains(o.getModel(),mouse.getLocation()) && o.doAction(s)) || (menu.contains(s) && menu.doAction(s))); } abstract class Obstacle { abstract boolean isCurrent(); boolean overcome() { eat(); for(int i=0;i<5;i++) { RSObject o = get(); next=o; if (o != null) { if(doAction(o,actionName()) && menu.contains(actionName())) return true; } } return false; } void eat() { int hp = hp(); int eatTo = random(200, 300); if (hp < 100) while (hp() < eatTo && inventory.contains(2118)) { hp += 20; RSItem food = inventory.getItem(2118); if(food!=null && food.doAction("Eat")) sleep(random(1200, 1300)); } } RSTile walkTile() { RSObject o = get(); if(o==null) return null; return o.getLocation(); } abstract String actionName(); abstract RSObject get(); } }