FrostHopper is cool and all but i needed this for a specific project and thought i would share. Credits to @@FrostBug
EDIT: Added interrupt to whole method not just scrolling. derp
/**
* Simplified version of FrostHopper by FrostBug on OSBot.
* Hops to a specific world with an interrupt condition when scrolling worlds.
* Credits: FrostBug
*
* @author House
*/
public class HHopper {
private final static int WIDGET_INDEX_ROOT = 14;
private final static int WIDGET_ROOT = 69;
private final static int WIDGET_SCROLL = 15;
private final static int WIDGET_SCROLL_UP = 4;
private final static int WIDGET_SCROLL_DOWN = 5;
private final static int MIN_FRAME_Y = 230;
private final static int MAX_FRAME_Y = 416;
private final int NOT_LOADING_STATE = 30;
Script script;
public HHopper(Script script) {
this.script = script;
}
public boolean hop(int world, BooleanSupplier condition) {
if(condition.getAsBoolean())
return false;
if (script.getClient().getLoginStateValue() != NOT_LOADING_STATE)
return false;
if (trimWorldNumber(script.getWorlds().getCurrentWorld()) == world)
return true;
if (script.getTabs().getOpen().equals(Tab.LOGOUT)) {
if (isQuickhopOpen()) {
if (loadingWorlds())
return false;
RS2Widget worldWidget = getWorld(world);
if (worldWidget == null)
return false;
if (isSelectable(worldWidget)) {
Rectangle rect = worldWidget.getRectangle();
rect.translate(0, 2);
rect.setSize((int) rect.getWidth(), (int) rect.getHeight() - 4);
RectangleDestination dest = new RectangleDestination(script.getBot(), rect);
if (script.getMouse().click(dest, false))
return false;
} else
scrollToWidget(worldWidget, condition);
} else
openQuickhop();
} else
script.getTabs().open(Tab.LOGOUT);
return false;
}
private boolean scrollToWidget(RS2Widget widget, BooleanSupplier condition) {
RS2Widget scroll;
if (widget.getPosition().getY() < MIN_FRAME_Y) {
scroll = script.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL, WIDGET_SCROLL_UP);
} else if (widget.getPosition().getY() > MAX_FRAME_Y) {
scroll = script.getWidgets().get(WIDGET_ROOT, WIDGET_SCROLL, WIDGET_SCROLL_DOWN);
} else {
return false;
}
if (scroll != null) {
final long startTime = System.currentTimeMillis();
WidgetDestination wDest = new WidgetDestination(script.getBot(), scroll);
script.getMouse().continualClick(wDest, new Condition() {
@[member=Override]
public boolean evaluate() {
return isSelectable(widget) || (System.currentTimeMillis() - startTime) >= 6000 || condition.getAsBoolean();
}
});
}
return true;
}
private boolean isSelectable(RS2Widget widget) {
return widget.getPosition().getY() >= MIN_FRAME_Y && widget.getPosition().getY() <= MAX_FRAME_Y;
}
private RS2Widget getWorld(int world) {
@SuppressWarnings("unchecked")
RS2Widget worldWidget = script.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());
return worldNumber == world;
}).get(0);
return worldWidget;
}
private int trimWorldNumber(int number) {
return (number > 300) ? number - 300 : number;
}
public boolean loadingWorlds() {
return !script.getWidgets().containingText("Loading...").isEmpty();
}
private boolean isQuickhopOpen() {
return script.getTabs().getOpen() == Tab.LOGOUT && script.getWidgets().containingText("World Switcher").isEmpty();
}
private boolean openQuickhop() {
List<RS2Widget> list = script.getWidgets().containingText("World Switcher");
if (!list.isEmpty()) {
return list.get(0).interact();
}
return false;
}
}
Usage:
hHopper.hop(86, () -> false);