import java.util.HashMap; import java.util.Map; /** * A script for using a cannon. * Inventory: Sleeping Bag, Cballs, Cannon parts *
*
* @author Chomp
*/
public class AA_Cannon extends AA_Script {
private static final int MAXIMUM_FATIGUE = 95;
private Coordinate idleCoord;
private Coordinate cannonCoord;
private double initialRangedXp;
private long startTime;
private long searchTimeout;
private long setUpTimeout;
private int cannonballIndex;
private int initialCannonballCount;
private boolean idle;
public AA_Cannon(final Extension ex) {
super(ex);
}
@Override
public void init(final String parameters) {
if (!isLoggedIn()) {
throw new IllegalStateException("Must start script logged in.");
}
if (getInventoryIndex(ITEM_ID_SLEEPING_BAG) != 0) {
throw new IllegalStateException("Sleeping bag missing from 1st inventory slot.");
}
cannonballIndex = getInventoryIndex(MultiCannon.ITEM_ID_CANNON_BALL);
if (cannonballIndex != 1) {
throw new IllegalStateException("Cannon balls missing from 2nd inventory slot.");
}
initialCannonballCount = getInventoryStack(cannonballIndex);
cannonCoord = new Coordinate(getX(), getY());
initialRangedXp = getAccurateXpForLevel(Skill.RANGED.getIndex());
startTime = System.currentTimeMillis();
}
@Override
public int main() {
if (getFatigue() >= MAXIMUM_FATIGUE) {
final int index = getInventoryIndex(ITEM_ID_SLEEPING_BAG);
if (index == -1) {
System.err.println("Sleeping bag missing from inventory.");
stopScript();
return 0;
}
useItem(index);
return SLEEP_ONE_SECOND;
}
if (idle) {
return idle();
}
if (inCombat() || System.currentTimeMillis() <= searchTimeout) {
return 0;
}
if (getX() != cannonCoord.getX() || getY() != cannonCoord.getY()) {
walkTo(cannonCoord.getX(), cannonCoord.getY());
return SLEEP_ONE_TICK;
}
final int objectId = getObjectIdFromCoords(cannonCoord.getX(), cannonCoord.getY());
if (objectId == -1) {
if (System.currentTimeMillis() <= setUpTimeout) {
return 0;
}
if (outOfCannonBalls()) {
System.err.println("Out of cannonballs.");
stopScript();
return 0;
}
final int baseIndex = getInventoryIndex(MultiCannon.FULL.nextPartId);
if (baseIndex == -1) {
System.err.println("Lost cannon base.");
stopScript();
return 0;
}
useItem(baseIndex);
setUpTimeout = System.currentTimeMillis() + 1000L;
return 0;
}
final MultiCannon multiCannon = MultiCannon.byId(objectId);
switch (multiCannon) {
case FULL:
if (outOfCannonBalls()) {
atObject2(cannonCoord.getX(), cannonCoord.getY());
return 2000;
}
atObject(cannonCoord.getX(), cannonCoord.getY());
searchTimeout = System.currentTimeMillis() + 2000L;
return 0;
case BASE:
case STAND:
case BARRELS:
final int nextPartIndex = getInventoryIndex(multiCannon.nextPartId);
if (nextPartIndex != -1) {
useItemOnObject(nextPartIndex, cannonCoord.getX(), cannonCoord.getY());
} else {
atObject(cannonCoord.getX(), cannonCoord.getY());
}
return SLEEP_ONE_SECOND;
default:
System.err.println("An object is obstructing cannon placement.");
stopScript();
return 0;
}
}
@Override
public void onServerMessage(final String message) {
if (message.endsWith("targets")) {
searchTimeout = System.currentTimeMillis() + 1000L;
} else if (message.endsWith("ammo") || message.endsWith("target")) {
searchTimeout = 0L;
} else if (message.endsWith("ground")) {
setUpTimeout = System.currentTimeMillis() + 3000L;
} else if (message.endsWith("area")) {
idleCoord = getWalkableCoordinate();
idle = true;
} else {
super.onServerMessage(message);
}
}
private int idle() {
if (idleCoord == null || getX() != cannonCoord.getX() || getY() != cannonCoord.getY()) {
idle = false;
return 0;
}
walkTo(idleCoord.getX(), idleCoord.getY());
return SLEEP_ONE_TICK;
}
private boolean outOfCannonBalls() {
return getInventoryCount() <= cannonballIndex ||
getInventoryId(cannonballIndex) != MultiCannon.ITEM_ID_CANNON_BALL;
}
@Override
public void paint() {
int y = PAINT_OFFSET_Y;
bot.drawString("@yel@Cannon", PAINT_OFFSET_X, y, 1, 0);
bot.drawString(String.format("@yel@Runtime: @whi@%s", toDuration(startTime)),
PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0);
final double xpGained = getAccurateXpForLevel(Skill.RANGED.getIndex()) - initialRangedXp;
bot.drawString(String.format("@yel@Xp: @whi@%s @cya@(@whi@%s xp@cya@/@whi@hr@cya@)",
DECIMAL_FORMAT.format(xpGained), toUnitsPerHour((int) xpGained, startTime)),
PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT * 2, 1, 0);
final int remaining = getInventoryStack(cannonballIndex);
final int used = initialCannonballCount - remaining;
bot.drawString(String.format("@yel@Cballs: @whi@%d @cya@(@whi@%s balls@cya@/@whi@hr@cya@)",
used, toUnitsPerHour(used, startTime)),
PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0);
bot.drawString(String.format("@yel@Remaining: @whi@%d", remaining),
PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT * 2, 1, 0);
bot.drawString(String.format("@yel@Time remaining: @whi@%s", toTimeToCompletion(used, remaining, startTime)),
PAINT_OFFSET_X, y + PAINT_OFFSET_Y_INCREMENT, 1, 0);
}
private enum MultiCannon {
FULL(943, 1032),
BASE(946, 1033),
STAND(947, 1034),
BARRELS(948, 1035);
private static final Map