/** * Kills Darkwizards and collects runes/coins at the Dark Wizard Tower. * Start at the tower with sleeping bag in inventory. *
* Optional Parameter:
* --no-doors (Disables closing doors)
* -f,--fightmode
*
* @Author Chomp
*/
public class AA_DarkWizardTower extends AA_Script {
private static final int[] NPC_IDS_DARK_WIZARD = new int[]{57, 60};
private static final int[] ITEM_IDS_LOOT = new int[]{10, 31, 32, 33, 34, 35, 36, 38, 40, 41, 42, 46, 619};
private static final int MAXIMUM_FATIGUE = 99;
private final int[] groundItem = new int[4];
private long startTime;
private double initialCombatXp;
private long doorTimeout;
private long ladderTimeout;
private int playerX;
private int playerY;
private boolean checkTopFloor;
private boolean doors = true;
public AA_DarkWizardTower(final Extension extension) {
super(extension);
}
@Override
public void init(final String parameters) {
if (!parameters.isEmpty()) {
final String[] args = parameters.split(" ");
for (int i = 0; i < args.length; i++) {
switch (args[i].toLowerCase()) {
case "-f":
case "--fightmode":
combatStyle = CombatStyle.valueOf(args[++i].toUpperCase());
break;
case "--no-doors":
doors = false;
break;
default:
throw new IllegalArgumentException("Error: malformed parameters. Try again ...");
}
}
}
if (!hasInventoryItem(ITEM_ID_SLEEPING_BAG)) {
throw new IllegalStateException("Sleeping bag missing from inventory.");
}
setCombatStyle(combatStyle.getIndex());
initialCombatXp = getTotalCombatXp();
startTime = System.currentTimeMillis();
}
@Override
public int main() {
if (bot.getCombatStyle() != combatStyle.getIndex()) setCombatStyle(combatStyle.getIndex());
if (inCombat()) {
return 0;
}
if (getFatigue() >= MAXIMUM_FATIGUE) {
return sleep();
}
playerX = getX();
playerY = getY();
return Floor.F2.contains(playerX, playerY) || Floor.F3.contains(playerX, playerY) ?
handleF2F3() :
handleF1();
}
@Override
public void onServerMessage(final String message) {
if (message.endsWith("ladder")) {
ladderTimeout = System.currentTimeMillis() + TIMEOUT_ONE_TICK;
} else if (message.endsWith("open") || message.endsWith("shut")) {
doorTimeout = System.currentTimeMillis() + TIMEOUT_ONE_TICK;
} else {
super.onServerMessage(message);
}
}
private int handleF2F3() {
final int[] wizard = getNpcById(NPC_IDS_DARK_WIZARD);
if (wizard[0] != -1) {
attackNpc(wizard[0]);
return SLEEP_ONE_TICK;
}
updateGroundItem(false);
if (groundItem[0] != -1) {
pickupItem(groundItem[3], groundItem[1], groundItem[2]);
return SLEEP_ONE_TICK;
}
return nextFloor();
}
private int handleF1() {
final int[] wizard = getNpcById(NPC_IDS_DARK_WIZARD);
if (wizard[0] != -1) {
if (Floor.F1.contains(playerX, playerY) != Floor.F1.contains(wizard[1], wizard[2])) {
final Door door = getNearestDoorTo(wizard[1], wizard[2]);
final int doorX = door.coordinate.getX();
final int doorY = door.coordinate.getY();
if (getWallObjectIdFromCoords(doorX, doorY) == door.id) {
if (System.currentTimeMillis() <= doorTimeout) {
return 0;
}
atWallObject(doorX, doorY);
doorTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS;
return 0;
}
}
attackNpc(wizard[0]);
return SLEEP_ONE_TICK;
}
updateGroundItem(true);
if (groundItem[0] != -1) {
pickupItem(groundItem[3], groundItem[1], groundItem[2]);
return SLEEP_ONE_TICK;
}
if (!Floor.F1.contains(playerX, playerY)) {
return enterF1();
}
if (doors) {
for (final Door door : Door.DOORS) {
final int doorX = door.coordinate.getX();
final int doorY = door.coordinate.getY();
if (getWallObjectIdFromCoords(doorX, doorY) != door.id) {
if (System.currentTimeMillis() <= doorTimeout) {
return 0;
}
atWallObject2(doorX, doorY);
doorTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS;
return 0;
}
}
}
return nextFloor();
}
private void updateGroundItem(final boolean bottomFloor) {
groundItem[0] = -1;
int currentDistance = Integer.MAX_VALUE;
for (int index = 0; index < getGroundItemCount(); index++) {
final int groundItemId = getGroundItemId(index);
if (!inArray(ITEM_IDS_LOOT, groundItemId)) {
continue;
}
final int groundItemX = getItemX(index);
final int groundItemY = getItemY(index);
if (bottomFloor && !Floor.F1.contains(groundItemX, groundItemY)) {
continue;
}
final int distance = distanceTo(groundItemX, groundItemY);
if (distance < currentDistance) {
groundItem[0] = index;
groundItem[1] = groundItemX;
groundItem[2] = groundItemY;
groundItem[3] = groundItemId;
currentDistance = distance;
}
}
}
private int nextFloor() {
if (System.currentTimeMillis() <= ladderTimeout) {
return 0;
}
if (Floor.F1.contains(playerX, playerY)) {
checkTopFloor = true;
atObject(Ladder.F1_UP.coordinate.getX(),
Ladder.F1_UP.coordinate.getY());
} else if (Floor.F2.contains(playerX, playerY)) {
if (checkTopFloor) {
atObject(Ladder.F2_UP.coordinate.getX(),
Ladder.F2_UP.coordinate.getY());
} else {
atObject(Ladder.F2_DOWN.coordinate.getX(),
Ladder.F2_DOWN.coordinate.getY());
}
} else if (Floor.F3.contains(playerX, playerY)) {
checkTopFloor = false;
atObject(Ladder.F3_DOWN.coordinate.getX(),
Ladder.F3_DOWN.coordinate.getY());
} else {
return SLEEP_ONE_TICK;
}
ladderTimeout = System.currentTimeMillis() + TIMEOUT_TWO_SECONDS;
return 0;
}
private Door getNearestDoorTo(final int x, final int y) {
Door closestDoor = null;
int currentDistance = Integer.MAX_VALUE;
for (final Door door : Door.DOORS) {
final int distance = distanceTo(x, y, door.coordinate.getX(), door.coordinate.getY());
if (distance < currentDistance) {
currentDistance = distance;
closestDoor = door;
}
}
return closestDoor;
}
private int enterF1() {
final Door door = getNearestDoorTo(playerX, playerY);
final int doorX = door.coordinate.getX();
final int doorY = door.coordinate.getY();
if (getWallObjectIdFromCoords(doorX, doorY) != door.id) {
walkTo(doorX, doorY);
return SLEEP_ONE_TICK;
}
if (System.currentTimeMillis() <= doorTimeout) {
return 0;
}
atWallObject(doorX, doorY);
doorTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS;
return 0;
}
@Override
public void paint() {
int y = PAINT_OFFSET_Y;
drawString("@yel@Dark Wizard Tower", PAINT_OFFSET_X, y, 1, 0);
drawString(String.format("@yel@Runtime: @whi@%s", toDuration(startTime)),
PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0);
final double xpGained = getTotalCombatXp() - initialCombatXp;
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);
}
private enum Floor implements RSArea {
F1(new Coordinate(360, 568), new Coordinate(363, 573)) {
public boolean contains(final int x, final int y) {
return super.contains(x, y) || ((x == 364 || x == 359) && y > 568 && y < 573);
}
},
F2(new Coordinate(360, 1512), new Coordinate(363, 1517)) {
public boolean contains(final int x, final int y) {
return super.contains(x, y) || ((x == 359 || x == 364) && y > 1513 && y < 1516);
}
},
F3(new Coordinate(360, 2457), new Coordinate(364, 2460));
private final Coordinate lowerBoundingCoordinate;
private final Coordinate upperBoundingCoordinate;
Floor(final Coordinate lowerBoundingCoordinate, final Coordinate upperBoundingCoordinate) {
this.lowerBoundingCoordinate = lowerBoundingCoordinate;
this.upperBoundingCoordinate = upperBoundingCoordinate;
}
public Coordinate getLowerBoundingCoordinate() {
return lowerBoundingCoordinate;
}
public Coordinate getUpperBoundingCoordinate() {
return upperBoundingCoordinate;
}
}
private enum Ladder implements RSObject {
F1_UP(5, new Coordinate(360, 570)),
F2_DOWN(6, new Coordinate(360, 1514)),
F2_UP(5, new Coordinate(363, 1514)),
F3_DOWN(6, new Coordinate(363, 2458));
private final int id;
private final Coordinate coordinate;
Ladder(final int id, final Coordinate coordinate) {
this.id = id;
this.coordinate = coordinate;
}
public int getId() {
return id;
}
public Coordinate getCoordinate() {
return coordinate;
}
}
private enum Door implements RSObject {
NE(2, new Coordinate(360, 568)),
NW(2, new Coordinate(364, 569)),
SE(2, new Coordinate(359, 572)),
SW(2, new Coordinate(363, 573));
private static final Door[] DOORS = Door.values();
private final int id;
private final Coordinate coordinate;
Door(final int id, final Coordinate coordinate) {
this.id = id;
this.coordinate = coordinate;
}
public int getId() {
return id;
}
public Coordinate getCoordinate() {
return coordinate;
}
}
}