vsun Posted December 1, 2021 Share Posted December 1, 2021 I've been interested in writing a bot for a while but doing 2000 laps of the Ape Atoll course is what finally broke me. Here's the completed script I wrote for doing the course. It'll only work if you run it at the start or end tile of an obstacle. I tried to add code to get back on the course if the player went off, but I ran into a bunch of issues navigating to the start/end tiles and gave up. Please let me know about any Java best practices I missed and how I can improve/clean this up since it's my first script. import com.epicbot.api.shared.APIContext; import com.epicbot.api.shared.GameType; import com.epicbot.api.shared.entity.ItemWidget; import com.epicbot.api.shared.entity.SceneObject; import com.epicbot.api.shared.methods.*; import com.epicbot.api.shared.model.Tile; import com.epicbot.api.shared.script.LoopScript; import com.epicbot.api.shared.script.ScriptManifest; import com.epicbot.api.shared.util.Random; import com.epicbot.api.shared.util.paint.frame.PaintFrame; import com.epicbot.api.shared.util.time.Time; import java.awt.*; @ScriptManifest(name = "ApeAtollAgility", gameType = GameType.OS) public class ApeAtollAgility extends LoopScript { private long startTime; private int laps; private int originalExperience; private ICameraAPI camera() { return getAPIContext().camera(); } private IInventoryAPI inventory() { return getAPIContext().inventory(); } private ILocalPlayerAPI localPlayer() { return getAPIContext().localPlayer(); } private IMouseAPI mouse() { return getAPIContext().mouse(); } private IObjectsAPI objects() { return getAPIContext().objects(); } private IWebWalkingAPI webWalking() { return getAPIContext().webWalking(); } private IWalkingAPI walking() { return getAPIContext().walking(); } private final String[] COURSE = { "Stepping stone", "Tropical tree", "Monkeybars", "Skull slope", "Rope", "Tropical tree" }; private final String[] ACTIONS = { "Jump-to", "Climb", "Swing Across", "Climb-up", "Swing", "Climb-down" }; private final Tile[] STARTS = { new Tile(2755, 2742, 0), new Tile(2753, 2742, 0), new Tile(2752, 2742, 2), new Tile(2747, 2741, 0), new Tile(2751, 2731, 0), new Tile(2758, 2734, 0) }; private final Tile[] ENDS = { new Tile(2753, 2742, 0), new Tile(2753, 2742, 2), new Tile(2747, 2741, 0), new Tile(2742, 2741, 0), new Tile(2756, 2731, 0), new Tile(2770, 2747, 0) }; private int missed = 0; private boolean isIdle() { return !localPlayer().isAnimating() && !localPlayer().isMoving(); } private boolean isOnTile(Tile t) { Tile currTile = localPlayer().getLocation(); return currTile.equals(t); } private boolean needStaminaDose() { return walking().getRunEnergy() < Math.random() * 40 && !localPlayer().isStaminaActive(); } private ItemWidget findStaminaDose() { String fmt = "Stamina potion(%d)"; for (int i = 1; i <= 4; i++) { ItemWidget stam = inventory().getItem(String.format(fmt, i)); if (stam != null) { return stam; } } return null; } private boolean shouldExit() { if (!getAPIContext().client().isLoggedIn()) { return false; } return findStaminaDose() == null && walking().getRunEnergy() < 20; } private void doHumanWait() { double p = Math.random(); if (p < 0.01) { int secs = Random.nextInt(90, 150); getLogger().info(String.format("Long sleeping for %d seconds", secs)); mouse().moveOffScreen(); Time.sleep(secs * 1000); } else if (p < 0.04) { int secs = Random.nextInt(10, 20); getLogger().info(String.format("Sleeping for %d seconds", secs)); mouse().moveOffScreen(); Time.sleep(secs * 1000); } } private int findCurrentStep(Tile t) { for (int i = 0; i < STARTS.length; i++) { Tile s = STARTS[i]; if (t.equals(s)) { return i; } } for (int i = 0; i < ENDS.length; i++) { Tile e = ENDS[i]; if (t.equals(e)) { return (i + 1) % ENDS.length; } } return -1; } private boolean doCourseStep() throws Exception { Tile curr = localPlayer().getLocation(); int i = findCurrentStep(curr); if (i == -1) { if (missed >= 10) { throw new Exception("Missed too many obstacles"); } // usually only logs on the stepping stone since it "wakes" when on the stone getLogger().info("Did not find current step"); missed++; return false; } missed = 0; String name = COURSE[i]; String action = ACTIONS[i]; Tile s = STARTS[i]; Tile e = ENDS[i]; getLogger().info(String.format("%s %s: %d", action, name, i)); SceneObject obstacle = objects().query().named(name).results().nearest(); if (obstacle == null) { // if we don't see it, move to the start walking().walkOnMap(s); Time.sleep(4000, () -> isOnTile(s) && isIdle()); } else { // if we see it, do the action on it if (obstacle.interact(action)) { doHumanWait(); Time.sleep(3000, () -> isOnTile(e) && isIdle()); } } if (i == COURSE.length - 1) { laps++; } // Time.sleep(100); return isOnTile(e); } private String convertToHHMMSS(long ms) { int total = (int) (ms / 1000); int h = total / 3600; int m = (total % 3600) / 60; int s = total % 60; return String.format("%02d:%02d:%02d", h, m, s); } private int getExpGained() { return getAPIContext().skills().agility().getExperience() - originalExperience; } @Override protected int loop() { if (shouldExit()) { return -1; } if (!isIdle()) { Time.sleep(600, () -> isIdle()); } else if (needStaminaDose()) { ItemWidget stam = findStaminaDose(); if (stam != null) { stam.interact("Drink"); } } else { try { doCourseStep(); } catch (Exception e) { getLogger().error(e.toString()); return -1; } } return 690; } @Override public boolean onStart(String... strings) { if (!getAPIContext().client().isLoggedIn()) { return false; } startTime = System.currentTimeMillis(); laps = 0; originalExperience = getAPIContext().skills().agility().getExperience(); getLogger().info("Starting script"); ICameraAPI cam = camera(); cam.setPitch(98, false); cam.setYawDeg(0, false); return true; } @Override protected void onPaint(Graphics2D g, APIContext ctx) { if (!getAPIContext().client().isLoggedIn()) { Time.sleep(15000, () -> getAPIContext().client().isLoggedIn()); } long totalMillis = System.currentTimeMillis() - startTime; PaintFrame frame = new PaintFrame(); frame.setTitle("Stats"); frame.addLine("Time elapsed: ", convertToHHMMSS(totalMillis)); frame.addLine("Total laps: ", laps); frame.addLine("Exp gained: ", getExpGained()); frame.draw(g, 0, 90, ctx); } } 2 Quote Link to comment Share on other sites More sharing options...
Sellout Posted December 3, 2021 Share Posted December 3, 2021 Nice 😄 Quote Link to comment Share on other sites More sharing options...
alex_unique_modifi Posted July 27, 2022 Share Posted July 27, 2022 lmao. desperate times calls for desperate measures Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.