So it seems to be a reoccurring pattern that everyone's first script is a simple wood cutter. So here is my attempt.
All critique is appreciated.
import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;
import java.awt.*;
import java.text.DecimalFormat;
@ScriptManifest(author = "Exponential", info = "A simple tree cutting script", name = "Chop Drop Repeat", version = 1.0, logo = "<==>")
public class Main extends Script {
private long startTime;
private int startXP;
private int gainedXP;
private int startLevel;
private int currentLevel;
private double XPPerHour;
/* To reduce paint refresh rate */
private int paintCount = 10;
/* Formatting output to paint */
private DecimalFormat df = new DecimalFormat("#.#");
@Override
public void onStart() {
log("Welcome to Exponential's Chop Drop Repeat");
startTime = System.currentTimeMillis();
startXP = skills.getExperience(Skill.WOODCUTTING);
startLevel = skills.getStatic(Skill.WOODCUTTING);
}
/**
* Represents the states within the script
*/
private enum State {
CHOP, DROP, WAIT
}
private State getState() {
if (inventory.isFull()) {
return State.DROP;
}
if (myPlayer().isAnimating()) {
return State.WAIT;
}
/* Current targets willow trees */
Entity tree = objects.closest("Willow");
if (tree != null) {
return State.CHOP;
}
return State.WAIT;
}
@Override
public int onLoop() throws InterruptedException {
switch (getState()) {
case CHOP:
Entity tree = objects.closest("Willow");
/* Check if there is a tree, and we're not running
* towards it already. */
if (tree != null && !myPlayer().isMoving()) {
if (tree.isVisible()) {
tree.interact("Chop down");
} else {
camera.toEntity(tree);
}
}
break;
case DROP:
/* Axe must be wielded, else it will be dropped */
inventory.dropAll();
if (getInventory().isItemSelected()) getMouse().click(false);
break;
case WAIT:
break;
}
return random(700, 900);
}
@Override
public void onExit() {
log("Thanks for running the script");
log("You ran the script for " + ((System.currentTimeMillis() - startTime)/1000) + "seconds.");
}
@Override
public void onPaint(Graphics2D g) {
g.setColor(Color.WHITE);
long runTime = System.currentTimeMillis() - startTime;
g.drawString("Runtime - " + timeConversion(runTime), 20, 50);
g.drawString("WC Level: (" + currentLevel + ") + " + (currentLevel - startLevel), 20, 70);
gainedXP = (skills.getExperience(Skill.WOODCUTTING) - startXP);
currentLevel = skills.getStatic(Skill.WOODCUTTING);
g.drawString("XP gained: " + gainedXP, 20, 90);
/* Not necessary to update this every tick*/
paintCount++;
if (paintCount % 10 == 0) {
XPPerHour = ((3600.0 / runTime) * gainedXP);
XPPerHour = Double.valueOf(df.format(XPPerHour));
/* Prevents this int getting to large */
if (paintCount > 9000) paintCount = 0;
}
g.drawString("XP/hour: " + XPPerHour + "K", 20, 110);
double perHour = XPPerHour * 1000;
int nextLevelXP = skills.getExperienceForLevel(currentLevel + 1);
int reqToLevel = nextLevelXP - (startXP + gainedXP);
g.drawString("XP to level: " + reqToLevel, 20, 130);
double ratio = reqToLevel/perHour;
long timeTo = (long) (ratio * 60.0 * 60.0 * 1000);
g.drawString("Time to level: " + timeConversion(timeTo), 20, 150);
}
/**
* Converts the millis time to a readable h:m:s format
*
* @param runTime current runtime in millis
*
* @return h:m:s string
*/
private String timeConversion(long runTime) {
int totalSeconds = (int)runTime/1000;
int seconds = totalSeconds % 60;
int totalMinutes = totalSeconds / 60;
int minutes = totalMinutes % 60;
int hours = totalMinutes / 60;
return hours + ":" + minutes + ":" + seconds;
}
}
I added the line:
if (getInventory().isItemSelected()) getMouse().click(false);
to try and prevent a bug from happening when the bot selects a log, but doesn't drop it, and then fails to continue dropping any more logs as the item is still selected. Any ideas?