Skip to content

Instantly share code, notes, and snippets.

@dayjaby
Last active October 23, 2019 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dayjaby/4a065aa825745c4c43f8c24d998ec989 to your computer and use it in GitHub Desktop.
Save dayjaby/4a065aa825745c4c43f8c24d998ec989 to your computer and use it in GitHub Desktop.
package scripts;
import org.powerbot.script.*;
import org.powerbot.script.rt4.ClientContext;
import org.powerbot.script.rt4.*;
import scripts.utils.agility.Obstacle;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
@Script.Manifest(
name = "Fally Agility", properties = "author=andyroo; topic=1298690; client=4;",
description = "v 2.2 - Completes Falador agility course"
)
/**
* Changelog
*
* Fally Agility
* v 2.2
* Random camera angle for starting obstacle (wall)
* Paint proggy
*
*/
public class FaladorAgility extends PollingScript<ClientContext> implements PaintListener {
/***********************************
* Constants
***********************************/
private static final Tile START_TILE = new Tile(3036, 3340, 0);
private static final Area[] fallyAreas = {
// Falador
new Area(new Tile(3000, 3300, 0), new Tile(3100, 3400, 0)),
new Area(new Tile(3035, 3344, 3), new Tile(3041, 3341, 3)),
new Area(new Tile(3052, 3341, 3), new Tile(3044, 3350, 3)),
new Area(new Tile(3047, 3357, 3), new Tile(3051, 3359, 3)),
new Area(new Tile(3044, 3361, 3), new Tile(3049, 3368, 3)),
new Area(new Tile(3042, 3365, 3), new Tile(3033, 3360, 3)),
new Area(new Tile(3025, 3351, 3), new Tile(3030, 3355, 3)),
new Area(new Tile(3008, 3352, 3), new Tile(3022, 3359, 3)),
new Area(new Tile(3015, 3342, 3), new Tile(3023, 3350, 3)),
new Area(new Tile(3010, 3343, 3), new Tile(3015, 3347, 3)),
new Area(new Tile(3008, 3334, 3), new Tile(3014, 3343, 3)),
new Area(new Tile(3010, 3330, 3), new Tile(3018, 3335, 3)),
new Area(new Tile(3018, 3331, 3), new Tile(3025, 3336, 3)),
// Canifis
new Area(new Tile(3471,3464,0), new Tile(3511,3504,0)),
new Area(new Tile(3504,3491,2),new Tile(3508,3498,2)),
new Area(new Tile(3503,3504,2), new Tile(3497,3506,2)),
new Area(new Tile(3486,3498,2),new Tile(3493,3505,2)),
new Area(new Tile(3474,3491,3),new Tile(3480,3500,3)),
new Area(new Tile(3477,3480,2),new Tile(3484,3487,2)),
new Area(new Tile(3488,3468,3),new Tile(3504,3479,3)),
new Area(new Tile(3509,3474,2),new Tile(3515,3483,2))
};
private static final int MARK_ID = 11849;
private static final Obstacle[] FALLY_OBSTACLES = {
// Falador
new Obstacle(10833, Obstacle.Type.ROUGH_WALL, 360, 50, new int[]{16, 96, -192, -68, 100, 140}),
new Obstacle(10834, Obstacle.Type.TIGHTROPE, 300, 67, new int[]{64, 120, 28, 68, 44, 128}),
new Obstacle(10836, Obstacle.Type.HANDHOLDS, 0, 100, new int[]{-28, 28, -12, 60, 60, 120}),
new Obstacle(11161, Obstacle.Type.GAP, 0, 100),
new Obstacle(11360, Obstacle.Type.GAP, 0, 100),
new Obstacle(11361, Obstacle.Type.TIGHTROPE, 33, 100, new int[]{-68, 4, 0, 76, -4, 72}),
new Obstacle(11364, Obstacle.Type.TIGHTROPE, 90, 100, new int[]{0, 60, -68, 8, 44, 116}),
new Obstacle(11365, Obstacle.Type.GAP, 90, 100),
new Obstacle(11366, Obstacle.Type.LEDGE, 90, 100),
new Obstacle(11367, Obstacle.Type.LEDGE, 90, 100),
new Obstacle(11368, Obstacle.Type.LEDGE, 130, 70),
new Obstacle(11370, Obstacle.Type.LEDGE, 180, 100),
new Obstacle(11371, Obstacle.Type.EDGE, 180, 100),
// Canifis
new Obstacle(10819, Obstacle.Type.TALL_TREE, 0, 90, new int[]{168, 204, -200, 0, -32, 32}),
new Obstacle(10820, Obstacle.Type.GAP, 0, 40),
new Obstacle(10821, Obstacle.Type.GAP, 90, 40),
new Obstacle(10828, Obstacle.Type.GAP, 90, 40),
new Obstacle(10822, Obstacle.Type.GAP, 180, 40),
new Obstacle(10831, Obstacle.Type.POLE_VAULT, 180, 70), // Vault
new Obstacle(10823, Obstacle.Type.GAP, 270, 40),
new Obstacle(10832, Obstacle.Type.GAP, 0, 40)
};
/******************************************************************************************/
private long startTime;
private int startXP;
private int startMarkCount;
private int currentMarkCount;
private int currentXP;
private static String version = "2.2";
private State currentState;
private Area currentArea;
private Location location;
private int obstacleNum;
private int energyThreshold;
private static final int GUI_X = 350;
private static final int GUI_Y = 339;
private static final int GUI_WIDTH = 519;
private static final int GUI_HEIGHT = 138;
private static final List<Integer> doNotAlch = Arrays.asList(995,561,MARK_ID);
/******************************************************************************************/
// output time elapsed from ms to hh:mm:ss
public static String getTimeElapsed(long ms) {
long sec, min, hr;
sec = (ms / 1000) % 60;
min = ((ms / 1000) / 60) % 60;
hr = ((ms / 1000) / 60) / 60;
return String.format("%02d:%02d:%02d", hr, min, sec);
}
public void updateInfo() {
if(ctx.game.tab() == Game.Tab.INVENTORY) {
if (ctx.inventory.select().id(MARK_ID).peek().valid())
currentMarkCount = ctx.inventory.select().id(MARK_ID).poll().stackSize();
else
currentMarkCount = 0;
}
currentXP = ctx.skills.experience(Constants.SKILLS_AGILITY);
}
public void repaint(Graphics graphics) {
int x = GUI_X;
int y = GUI_Y;
graphics.setColor(new Color(0, 0, 0));
graphics.fillRect(x, y, GUI_WIDTH - GUI_X, GUI_HEIGHT);
graphics.setColor(new Color(255, 255, 255));
x += 10;
graphics.drawString("Version: " + version, x, y += 15);
graphics.drawString(getTimeElapsed(System.currentTimeMillis() - startTime), x, y += 15);
graphics.drawString("XP Gained: " + Integer.toString(currentXP - startXP), x, y += 15);
graphics.drawString("Marks collected: " + Integer.toString(currentMarkCount - startMarkCount), x, y += 15);
}
public void start() {
ctx.camera.pitch(true);
energyThreshold = Random.nextInt(30, 60);
if(ctx.inventory.select().id(MARK_ID).peek().valid())
startMarkCount = ctx.inventory.poll().stackSize();
else startMarkCount = 0;
startXP = ctx.skills.experience(Constants.SKILLS_AGILITY);
updateInfo();
startTime = System.currentTimeMillis();
}
public void stop() {
updateInfo();
String totalTime = getTimeElapsed(System.currentTimeMillis() - startTime);
log.info(version);
log.info("Time run: " + totalTime);
log.info("XP Gained: " + Integer.toString(currentXP - startXP));
log.info("Marks collected: " + Integer.toString(currentMarkCount - startMarkCount));
}
// check for marks of grace
private boolean markCheck() {
final GroundItem mark = ctx.groundItems.select(10).id(MARK_ID).poll();
if(!mark.valid())
return true;
if (currentArea != null && currentArea.contains(mark.tile())) {
log.info("mark found");
if (mark.inViewport()) {
final int beforeCount;
if(ctx.inventory.select().id(MARK_ID).peek().valid()) {
beforeCount = ctx.inventory.poll().stackSize();
}
else beforeCount = 0;
if(mark.click("Take", Game.Crosshair.ACTION)) {
log.info("Attempt to pick up mark");
return Condition.wait(new Callable<Boolean>() {
public Boolean call() throws Exception {
return ctx.inventory.select().id(MARK_ID).poll().stackSize() > beforeCount && !mark.valid();
}
}, 300, 10);
}
} else if (mark.valid()) {
log.info("walk to mark");
ctx.movement.step(mark.tile());
}
}
else return true; // mark is in different area
return false;
}
private void waitObstacle() {
final Area previousArea = currentArea;
final int nextObstacle = (obstacleNum+1) % FALLY_OBSTACLES.length;
ctx.magic.cast(Magic.Spell.HIGH_ALCHEMY);
Condition.wait(new Callable<Boolean>() {
public Boolean call() throws Exception {
log.info("Waiting for next state");
state();
turnCamera(FALLY_OBSTACLES[nextObstacle]);
return !currentArea.equals(previousArea) && ctx.players.local().animation()==-1 && !ctx.players.local().inMotion();
}
}, Random.nextInt(220,300), 25);
updateInfo();
ctx.inventory.select().select(new Filter<Item>() {
@Override
public boolean accept(Item item) {
return !doNotAlch.contains(item.id());
}
}).poll().interact("Cast");
}
private void waitMovement() {
Condition.wait(new Callable<Boolean>() {
public Boolean call() throws Exception {
Player me = ctx.players.local();
//log.info("waiting to stop moving");
return !me.inMotion();
}
}, 250, 8);
}
public void poll() {
boolean obstacleFound = false;
currentState = state();
markCheck();
updateInfo();
switch (currentState) {
case INVALID: {
Condition.sleep();
}
break;
case RUN_TOGGLE: {
ctx.movement.running(true);
energyThreshold = Random.nextInt(30, 60);
Condition.wait(new Callable<Boolean>() {
public Boolean call() throws Exception {
return ctx.movement.running();
}
}, 250, 4);
}
break;
case OBSTACLE: {
GameObject obstacleObject = null;
Obstacle obstacleInfo = FALLY_OBSTACLES[obstacleNum];
if (location == Location.FALADOR)
obstacleObject = ctx.objects.select(10).id(obstacleInfo.id()).poll();
if (obstacleObject == null) {
log.info("Obstacle not found");
break;
}
if (obstacleObject.valid()) {
if (interactObstacle(obstacleObject, obstacleInfo)) {
obstacleFound = true;
} else {
turnCamera(obstacleInfo);
log.info("Move to obstacle " + obstacleNum);
final Tile obstacleTile = obstacleObject.tile();
ctx.movement.step(obstacleTile);
Condition.wait(new Callable<Boolean>() {
public Boolean call() throws Exception {
return obstacleTile.distanceTo(ctx.players.local()) < 3;
}
}, 250, 6);
}
} else if(obstacleNum==0) {
ctx.movement.step(START_TILE);
} else if(obstacleNum==19) {
ctx.movement.step(new Tile(3501,3476,3));
} else if(obstacleNum==13) {
ctx.movement.step(new Tile(3507,3488,0));
}
}
break;
default:
break;
}
if (obstacleFound) {
waitObstacle();
}
}
private boolean interactObstacle(GameObject obstacleObject, Obstacle obstacleInfo) {
if(!obstacleObject.inViewport()) return false;
log.info("Obstacle " + obstacleNum + " found");
if (obstacleInfo.bounds() != null) {
obstacleObject.bounds(obstacleInfo.bounds());
}
return obstacleObject.click(obstacleInfo.action(), Game.Crosshair.ACTION);
}
private void turnCamera(Obstacle obstacleInfo) {
if(Math.abs((ctx.camera.yaw()+720-obstacleInfo.angle()) % 360) > 20) {
ctx.camera.angle(Random.nextInt(obstacleInfo.angle()-15,obstacleInfo.angle()+15));
}
if(Math.abs(ctx.camera.pitch()-obstacleInfo.pitch()) > 20) {
ctx.camera.pitch(Random.nextInt(obstacleInfo.pitch()-15,obstacleInfo.pitch()+15));
}
}
private State state() {
if (!ctx.game.loggedIn()) {
return State.INVALID;
}
Player me = ctx.players.local();
if (!ctx.movement.running() && (ctx.movement.energyLevel() > energyThreshold)) {
log.info("Toggle run");
return State.RUN_TOGGLE;
}
obstacleNum = -1;
for (int i = 0; i < fallyAreas.length; i++) {
if (fallyAreas[i].contains(me.tile())) {
log.info("Obstacle " + i);
obstacleNum = i;
currentArea = fallyAreas[i];
location = Location.FALADOR;
break;
}
}
if (obstacleNum != -1) {
return State.OBSTACLE;
}
return State.INVALID;
}
private enum State {
RUN_TOGGLE, OBSTACLE, INVALID
}
private enum Location {
FALADOR
}
}
package scripts.utils.agility;
public class Obstacle {
public enum Type {
TIGHTROPE, HANDHOLDS, GAP, LEDGE, ROUGH_WALL, EDGE, TALL_TREE, POLE_VAULT
}
private int id;
private Type type;
private int[] bounds;
private int angle;
private int pitch;
public Obstacle(int id, Type type, int angle, int pitch) {
this.id = id;
this.type = type;
this.angle = angle;
this.pitch = pitch;
}
public Obstacle(int id, Type type, int angle, int pitch, int[] bounds) {
this(id,type,angle,pitch);
this.bounds = bounds;
}
public Obstacle(Obstacle o) {
this(o.id,o.type,o.angle,o.pitch,o.bounds);
}
public int id() {
return id;
}
public Type type() {
return type;
}
public int angle() { return angle; }
public int pitch() { return pitch; }
public int[] bounds() {
return bounds;
}
public String action() {
if (type == Type.TIGHTROPE || type == Type.HANDHOLDS)
return "Cross";
else if (type == Type.GAP || type == Type.LEDGE || type == Type.EDGE)
return "Jump";
else if (type == Type.ROUGH_WALL || type == Type.TALL_TREE)
return "Climb";
else if (type == Type.POLE_VAULT)
return "Vault";
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment