May 23, 201510 yr This class uses the recently added instant hop feature to switch worlds. FrostHopper.java Spoiler /** * Tool for instant world hopping * * @author FrostBug */ public class FrostHopper { private final Script parent; public static enum HopMode { NONE(-1), ANY(-1), F2P(1130), P2P(1131); private final int spriteID; private HopMode(int spriteID) { this.spriteID = spriteID; } public int getSpriteID() { return this.spriteID; } } private final static int WIDGET_INDEX_ROOT = 15; private final static int WIDGET_CONTENT_ROOT = 8; private final static int WIDGET_ROOT = 69; private final static int WIDGET_SCROLL = 16; private final static int WIDGET_SCROLL_UP = 4; private final static int WIDGET_SCROLL_DOWN = 5; private final static int WIDGET_WORLD = 0; private final static int WIDGET_WORLDTYPE = 1; private final static int WIDGET_WORLDNUMBER = 2; private final static int WIDGET_PLAYERCOUNT = 4; private final static int WIDGET_WORLDACTIVITY = 5; private final static int WIDGET_OFFSET = 6; private final static int MIN_FRAME_Y = 230; private final static int MAX_FRAME_Y = 416; private final List<Integer> disabled; private HopMode hopMode; private int sourceWorld; private RS2Widget destinationWorld; private int destW; private int attempts; public FrostHopper(Script parent) { this.parent = parent; this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.attempts = 0; this.disabled = Arrays.asList(25, 29, 37, 65, 21, 49); } public void hop(HopMode hopMode) { this.hopMode = hopMode; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.destinationWorld = null; this.destW = -1; this.parent.log("[FrostHopper] Starting quickhop"); this.attempts = 0; } private void finishHop() { parent.log("[FrostHopper] Hopped successfully"); this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.destinationWorld = null; this.destW = -1; this.attempts = 0; } public boolean isHopping() { return this.hopMode != HopMode.NONE; } public int execute() throws InterruptedException { int delay = random(30, 60); if (getCurrentWorld() != getSourceWorld()) { if (destW != getCurrentWorld()) { parent.log("[FrostHopper] ERROR: Incorrect destination world. Hopping again"); this.destinationWorld = null; this.destW = -1; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.attempts = 0; } else { finishHop(); return random(4000, 5000); } } if (parent.getDialogues().isPendingOption() && (!parent.getWidgets().containingText("Switch to World " + destW).isEmpty() || !parent.getWidgets().containingText("World " + destW + " is a High Risk world!").isEmpty())){ if (parent.getDialogues().selectOption("Yes.", "Switch to the High Risk world.")) { delay = random(3000, 4000); } } else if (this.parent.getTabs().getOpen() == Tab.LOGOUT) { if (isQuickhopOpen()) { if (!parent.getWidgets().containingText("Loading...").isEmpty()) { parent.log("Loading worlds.."); return random(1000, 1500); } if (this.destinationWorld == null || attempts >= 3) { attempts = 0; RS2Widget dest = pickWorld(); if (dest != null) { parent.log("[FrostHopper] Hopping to world: " + getWorldNumber(dest)); this.destinationWorld = dest; this.destW = getWorldNumber(dest); } else { parent.log("[FrostHopper] Failed to select world"); } } else { if (isSelectable(this.destinationWorld)) { attempts = 0; parent.log("Interacting with world widget.."); Rectangle rect = this.destinationWorld.getBounds(); rect.translate(0, 2); rect.setSize((int) rect.getWidth(), (int) rect.getHeight() - 4); RectangleDestination dest = new RectangleDestination(parent.getBot(), rect); if (parent.getMouse().move(dest)) { sleep(random(100, 150)); parent.getMouse().click(false); delay = random(800, 1100); } } else { attempts++; scrollToWidget(this.destinationWorld); delay = random(200, 300); } } } else if (openQuickhop()) { delay = random(800, 1200); } } else if (this.parent.getTabs().open(Tab.LOGOUT)) { delay = random(200, 300); } return delay; } private int getWorldWidgetIndex(RS2Widget widget) { int index = 0; for (int i = 300; i < 401; i++) { RS2Widget w = parent.getWidgets().get(WIDGET_ROOT, WIDGET_INDEX_ROOT, i); if (w != null && !w.getHiddenUntilMouseOver()) { if (i == widget.getThirdLevelId()) { return index; } index++; } } return -1; } private boolean isQuickhopOpen() { return parent.getTabs().getOpen() == Tab.LOGOUT && parent.getWidgets().containingText("World Switcher").isEmpty(); } private boolean openQuickhop() { List<RS2Widget> list = parent.getWidgets().containingText("World Switcher"); if (!list.isEmpty()) { return list.get(0).interact(); } return false; } private RS2Widget pickWorld() { List<RS2Widget> list = parent.getWidgets().filter(WIDGET_ROOT, (Filter<RS2Widget>) (RS2Widget w) -> { if (!w.isThirdLevel() || w.getSecondLevelId() != WIDGET_INDEX_ROOT || w.getThirdLevelId() <= 300 || w.getThirdLevelId() > 400 || w.getHiddenUntilMouseOver()) { return false; } int worldNumber = trimWorldNumber(w.getThirdLevelId()); int index = getWorldWidgetIndex(w); RS2Widget world = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_WORLD + (index * WIDGET_OFFSET)); RS2Widget worldType = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_WORLDTYPE + (index * WIDGET_OFFSET)); RS2Widget worldActivity = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_WORLDACTIVITY + (index * WIDGET_OFFSET)); RS2Widget worldCount = parent.getWidgets().get(WIDGET_ROOT, WIDGET_CONTENT_ROOT, WIDGET_PLAYERCOUNT + (index * WIDGET_OFFSET)); String activity = worldActivity.getMessage() == null ? "" : worldActivity.getMessage().toLowerCase(); boolean accessible = world.getTextColor() != 0; boolean notOwn = (worldNumber != getCurrentWorld()); boolean correctType = this.hopMode == HopMode.ANY || (worldType.getSpriteIndex1() == this.hopMode.getSpriteID()); boolean nonPvP = (!activity.contains("pvp")); boolean restricted = disabled.contains(worldNumber); boolean deadman = (activity.contains("deadman")); boolean skill = activity.contains("king of"); boolean full = Integer.parseInt(worldCount.getMessage()) >= 1980; return accessible && notOwn && correctType && nonPvP && !deadman && !restricted && !full && !skill; }); return list.isEmpty() ? null : list.get(random(list.size())); } private int trimWorldNumber(int number) { return (number > 300) ? number - 300 : number; } private int getSourceWorld() { return trimWorldNumber(this.sourceWorld); } private int getCurrentWorld() { return trimWorldNumber(parent.getWorlds().getCurrentWorld()); } private int getWorldNumber(RS2Widget widget) { return trimWorldNumber(widget.getThirdLevelId()); } private void scrollToWidget(RS2Widget widget) { RS2Widget scroll; if (widget.getPosition().getY() < MIN_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL, WIDGET_SCROLL_UP); } else if (widget.getPosition().getY() > MAX_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL, WIDGET_SCROLL_DOWN); } else { parent.log("[FrostHopper] Error determining scroll requirement"); return; } if (scroll != null) { final long startTime = System.currentTimeMillis(); WidgetDestination wDest = new WidgetDestination(parent.getBot(), scroll); parent.getMouse().continualClick(wDest, new Condition() { @Override public boolean evaluate() { return isSelectable(widget) || (System.currentTimeMillis() - startTime) >= 6000; } }); } else { parent.log("[FrostHopper] Cannot find scroll button"); } } private boolean isSelectable(RS2Widget widget) { return widget.getPosition().getY() >= MIN_FRAME_Y && widget.getPosition().getY() <= MAX_FRAME_Y; } } Example usage: Spoiler private FrostHopper hopper; @Override public void onStart() throws InterruptedException { this.hopper = new FrostHopper(this); } @Override public int onLoop() throws InterruptedException { if(this.hopper.isHopping()) { return this.hopper.execute(); } if(runeOresAvailable()) { mineRuneOres(); } else { this.hopper.hop(FrostHopper.HopMode.P2P); } return 1000; } Edited September 27, 20187 yr by FrostBug
May 23, 201510 yr Author Guess I should add that it will pick a random world (excluding PVP worlds) within the provided HopMode
May 23, 201510 yr Guess I should add that it will pick a random world (excluding PVP worlds) within the provided HopMode it was kind of a bit obv if not there would not be a point in having an enum Edited May 23, 201510 yr by josedpay
May 26, 201510 yr Hey I keep having a problem where eventually the hopper with try to join the world I'm already in, and never moves on to try a different option. Did I implement it in my script wrong? Thanks
June 26, 201510 yr This class uses the recently added instant hop feature to switch worlds. FrostHopper.java import java.util.List; import org.osbot.rs07.api.filter.Filter; import org.osbot.rs07.api.ui.RS2Widget; import org.osbot.rs07.api.ui.Tab; import org.osbot.rs07.input.mouse.RectangleDestination; import org.osbot.rs07.input.mouse.WidgetDestination; import static org.osbot.rs07.script.MethodProvider.random; import static org.osbot.rs07.script.MethodProvider.sleep; import org.osbot.rs07.script.Script; import org.osbot.rs07.utility.Condition; /** * Tool for instant world hopping * * @author FrostBug */ public class FrostHopper { private final Script parent; public static enum HopMode { NONE(-1), ANY(-1), F2P(1130), P2P(1131); private final int spriteID; private HopMode(int spriteID) { this.spriteID = spriteID; } public int getSpriteID() { return this.spriteID; } } private final static int WIDGET_ROOT = 69; private final static int WIDGET_SCROLL_ROOT = 113; private final static int WIDGET_SCROLL_UP = 4; private final static int WIDGET_SCROLL_DOWN = 5; private final static int WIDGET_WORLDTYPE = 1; private final static int WIDGET_WORLDNUMBER = 2; private final static int WIDGET_WORLDACTIVITY = 4; private final static int MIN_FRAME_Y = 230; private final static int MAX_FRAME_Y = 416; private HopMode hopMode; private int sourceWorld; private RS2Widget destinationWorld; private int destW; private int attempts; public FrostHopper(Script parent) { this.parent = parent; this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.attempts = 0; } public void hop(HopMode hopMode) { this.hopMode = hopMode; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.destinationWorld = null; this.destW = -1; this.parent.log("[FrostHopper] Starting quickhop"); this.attempts = 0; } private void finishHop() { parent.log("[FrostHopper] Hopped successfully"); this.hopMode = HopMode.NONE; this.sourceWorld = -1; this.destinationWorld = null; this.destW = -1; this.attempts = 0; this.parent.getGeneralUtil().hopped(); } public boolean isHopping() { return this.hopMode != HopMode.NONE; } public int execute() throws InterruptedException { int delay = random(30, 60); if (getCurrentWorld() != getSourceWorld()) { if (destW != getCurrentWorld()) { parent.log("[FrostHopper] ERROR: Incorrect destination world. Hopping again"); this.destinationWorld = null; this.destW = -1; this.sourceWorld = parent.getWorlds().getCurrentWorld(); this.attempts = 0; } else { finishHop(); return random(4000, 5000); } } if (parent.getDialogues().isPendingOption() && !parent.getWidgets().containingText("Switch to World " + destW).isEmpty()) { if (parent.getDialogues().selectOption("Yes.")) { delay = random(3000, 4000); } } else if (this.parent.getTabs().getOpen() == Tab.LOGOUT) { if (isQuickhopOpen()) { if (this.destinationWorld == null || attempts >= 3) { attempts = 0; RS2Widget dest = pickWorld(); if (dest != null) { parent.log("[FrostHopper] Hopping to world: " + getWorldNumber(dest)); this.destinationWorld = dest; this.destW = getWorldNumber(dest); } else { parent.log("[FrostHopper] Failed to select world"); } } else { if (isSelectable(this.destinationWorld)) { attempts = 0; parent.log("Interacting with world widget.."); RectangleDestination dest = new RectangleDestination(parent.getBot(), this.destinationWorld.getRectangle()); if (parent.getMouse().move(dest)) { sleep(random(100, 150)); parent.getMouse().click(false); delay = random(800, 1100); } parent.getMouse().click(false); } else { attempts++; scrollToWidget(this.destinationWorld); delay = random(200, 300); } } } else if (openQuickhop()) { delay = random(800, 1200); } } else if (this.parent.getTabs().open(Tab.LOGOUT)) { delay = random(200, 300); } return delay; } private boolean isQuickhopOpen() { return parent.getTabs().getOpen() == Tab.LOGOUT && parent.getWidgets().containingText("World Switcher").isEmpty(); } private boolean openQuickhop() { List<RS2Widget> list = parent.getWidgets().containingText("World Switcher"); if (!list.isEmpty()) { return list.get(0).interact(); } return false; } private RS2Widget pickWorld() { List<RS2Widget> list = parent.getWidgets().filter(WIDGET_ROOT, (Filter<RS2Widget>) (RS2Widget v) -> { if (v == null) { return false; } boolean secondLevel = v.isSecondLevel(); if (!secondLevel) { //parent.log("DEBUG: IFace is not 2nd level"); return false; } boolean worldNum = v.getChildWidget(WIDGET_WORLDNUMBER) != null && !v.getChildWidget(WIDGET_WORLDNUMBER).getMessage().isEmpty(); if (!worldNum) { //parent.log("DEBUG: Invalid world number"); return false; } boolean activity = v.getChildWidget(WIDGET_WORLDACTIVITY) != null; if (!activity) { //parent.log("DEBUG: Invalid activity field"); return false; } boolean pvp = v.getChildWidget(WIDGET_WORLDACTIVITY).getMessage().toLowerCase().contains("pvp"); if (pvp) { //parent.log("DEBUG: PVP world"); return false; } boolean botMonitor = 86 == getWorldNumber(v); if (botMonitor) { //parent.log("DEBUG: BotMonitor world"); return false; } boolean ownWorld = (getWorldNumber(v) == getSourceWorld()); if (ownWorld) { //parent.log("DEBUG: Own world"); return false; } boolean validMode = (this.hopMode == HopMode.ANY || isCorrectType(v)); if (!validMode) { //parent.log("DEBUG: Incorrect world type"); return false; } return true; }); //parent.log("DEBUG: ----------- WorldPick end"); return list.isEmpty() ? null : list.get(random(list.size())); } private int getSourceWorld() { return (sourceWorld > 300) ? sourceWorld - 300 : sourceWorld; } private int getCurrentWorld() { int w = parent.getWorlds().getCurrentWorld(); return (w > 300) ? w - 300 : w; } private boolean isCorrectType(RS2Widget widget) { RS2Widget type = widget.getChildWidget(WIDGET_WORLDTYPE); return type != null && type.getSpriteIndex1() == this.hopMode.getSpriteID(); } private int getWorldNumber(RS2Widget widget) { int w = Integer.parseInt(widget.getChildWidget(WIDGET_WORLDNUMBER).getMessage()); return (w > 300) ? w - 300 : w; } private void scrollToWidget(RS2Widget widget) { RS2Widget scroll; if (widget.getPosition().getY() < MIN_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL_ROOT, WIDGET_SCROLL_UP); } else if (widget.getPosition().getY() > MAX_FRAME_Y) { scroll = parent.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL_ROOT, WIDGET_SCROLL_DOWN); } else { parent.log("[FrostHopper] Error determining scroll requirement"); return; } if (scroll != null) { final long startTime = System.currentTimeMillis(); WidgetDestination wDest = new WidgetDestination(parent.getBot(), scroll); parent.getMouse().continualClick(wDest, new Condition() { @Override public boolean evaluate() { return isSelectable(widget) || (System.currentTimeMillis() - startTime) >= 6000; } }); } else { parent.log("[FrostHopper] Cannot find scroll button"); } } private boolean isSelectable(RS2Widget widget) { return widget.getPosition().getY() >= MIN_FRAME_Y && widget.getPosition().getY() <= MAX_FRAME_Y; } } Example usage: @ScriptManifest(author = "FrostBug", info = "TestScript", logo = "", name = "Test script", version = 1.0) public class TestScript extends Script { private FrostHopper hopper; @Override public void onStart() throws InterruptedException { this.hopper = new FrostHopper(this); } @Override public int onLoop() throws InterruptedException { if(this.hopper.isHopping()) { return this.hopper.execute(); } if(runeOresAvailable()) { mineRuneOres(); } else { this.hopper.hop(FrostHopper.HopMode.P2P); } return 1000; } } Sometimes can't find the destination world and pretty much the hopper dies, though, sometimes it fixes itself plsfix
June 26, 201510 yr Author Sometimes can't find the destination world and pretty much the hopper dies, though, sometimes it fixes itself plsfix Lrn2 copy/paste sir
November 8, 201510 yr Updated to avoid worlds that you do not have the total level to use Can you also avoid Deadman worlds?
January 17, 201610 yr Author hat random method did you use cant seem to find one. return list.isEmpty() ? null : list.get(random(list.size()));
Create an account or sign in to comment