import java.util.HashMap; import java.util.Map; /** * Kills pirates at the Brimhaven pub. * Uncerts lobster or swordfish certs for food. *

* Required: * Start script at the pub or near the certer. * Inventory: sleeping bag, lobster or swordfish certs. *

* Optional Parameters: * --min-hits <#> (default 50) * -f,--fightmode (default Strength) *

* Notes: * --min-hits is the hits to flee combat at. *

* * @Author Chomp */ public class AA_DeadmansChest extends AA_Script { private static final Coordinate COORDINATE_CERTER = new Coordinate(445, 680); private static final Coordinate COORDINATE_SLEEP = new Coordinate(452, 696); private static final int[] ITEM_IDS_LOOT = new int[]{1277, 1092, 526, 527, 42, 40, 41, 31, 33, 34, 11, 10}; private static final int[] ITEM_IDS_STACKABLE = new int[]{10, 11, 31, 33, 34, 40, 41, 42}; private static final int NPC_ID_SETH = 267; private static final int NPC_ID_PIRATE = 264; private static final int NPC_XP_PIRATE = 82; private static final int ITEM_ID_HALF_KEY_TEETH = 526; private static final int ITEM_ID_HALF_KEY_LOOP = 527; private static final int MAXIMUM_FATIGUE = 99; private static final int MINIMUM_COMBAT_LVL_NON_AGGRO = 61; private final Map spawnMap = new HashMap<>(); private final int[] loot = new int[3]; private Cert cert; private Coordinate nextRespawn; private long startTime; private double initialCombatXp; private long timeout; private int playerX; private int playerY; private int healThreshold; private int minimumHits = 50; private boolean uncerting; private boolean aggro; public AA_DeadmansChest(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 "--min-hits": minimumHits = Integer.parseInt(args[++i]); break; case "-f": case "--fightmode": combatStyle = CombatStyle.valueOf(args[++i].toUpperCase()); break; default: throw new IllegalArgumentException("Error: malformed parameters. Try again ..."); } } } if (!hasInventoryItem(ITEM_ID_SLEEPING_BAG)) { throw new IllegalStateException("Sleeping bag missing from inventory."); } for (final Cert cert : Cert.VALUES) { if (hasInventoryItem(cert.id)) { this.cert = cert; break; } } if (cert == null) { throw new IllegalStateException("Certs missing from inventory."); } System.out.printf("[%s] Using %ss and %s combat style.%n", this, getItemNameId(cert.id), combatStyle); setCombatStyle(combatStyle.getIndex()); initialCombatXp = getTotalCombatXp(); healThreshold = getBaseHits() - cert.healAmount; uncerting = !hasInventoryItem(cert.foodId); aggro = bot.getPlayerCombatLevel(bot.getPlayer()) < MINIMUM_COMBAT_LVL_NON_AGGRO; startTime = System.currentTimeMillis(); } @Override public int main() { playerX = getX(); playerY = getY(); if (bot.getCombatStyle() != combatStyle.getIndex()) setCombatStyle(combatStyle.getIndex()); return uncerting ? uncert() : kill(); } @Override public void onServerMessage(final String message) { if (message.startsWith("eat", 4) || message.endsWith("shut") || message.endsWith("open")) { timeout = System.currentTimeMillis() + TIMEOUT_ONE_TICK; } else if (message.equals("You don't have that many certificates")) { exit("Out of certificates"); } else { super.onServerMessage(message); } } private int uncert() { if (isNearCerter()) { if (hasInventoryItem(cert.foodId)) { uncerting = false; return 0; } return talkToCerter(); } if (Area.TAVERN.contains(playerX, playerY)) { return exitTavern(); } return walkToCerter(); } private int kill() { if (inCombat()) { if (getCurrentHits() < minimumHits) { walkTo(playerX, playerY); return SLEEP_ONE_TICK; } return 0; } if (getCurrentHits() <= healThreshold) { final int foodIndex = getInventoryIndex(cert.foodId); if (foodIndex == -1) { uncerting = true; return 0; } return eat(foodIndex); } if (!Area.TAVERN.contains(playerX, playerY)) { return enterTavern(); } if (!isDoorClosed()) { return closeDoor(); } final int teethIndex = getInventoryIndex(ITEM_ID_HALF_KEY_TEETH); if (teethIndex != -1) { final int loopIndex = getInventoryIndex(ITEM_ID_HALF_KEY_LOOP); if (loopIndex != -1) { useItemWithItem(teethIndex, loopIndex); return SLEEP_ONE_TICK; } } updateLoot(); if (loot[0] != -1) { if (!isInventoryFull() || canPickUpStackableLoot()) { pickupItem(loot[0], loot[1], loot[2]); return SLEEP_ONE_TICK; } final int foodIndex = getInventoryIndex(cert.foodId); if (foodIndex != -1) { return eat(foodIndex); } } if (getFatigue() >= MAXIMUM_FATIGUE) { if (aggro && (playerX != COORDINATE_SLEEP.getX() || playerY != COORDINATE_SLEEP.getY())) { walkTo(COORDINATE_SLEEP.getX(), COORDINATE_SLEEP.getY()); return SLEEP_ONE_TICK; } return sleep(); } final int pirateIndex = getNearestPirateIndex(); if (pirateIndex != -1) { attackNpc(pirateIndex); return SLEEP_ONE_TICK; } if (nextRespawn != null && (playerX != nextRespawn.getX() || playerY != nextRespawn.getY())) { walkTo(nextRespawn.getX(), nextRespawn.getY()); return SLEEP_ONE_TICK; } return 0; } private boolean isNearCerter() { return playerY <= COORDINATE_CERTER.getY(); } private int talkToCerter() { final String certAmount = Cert.getCertAmount(getInventoryEmptyCount()); if (certAmount == null) { return exit("Out of inventory space."); } if (isQuestMenu()) { int index; if ((index = getQuestMenuIndex("I have some certificates to trade in")) != -1 || (index = getQuestMenuIndex(cert.name)) != -1 || (index = getQuestMenuIndex(certAmount)) != -1) { answer(index); timeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS; } return 0; } if (System.currentTimeMillis() <= timeout) { return 0; } final int[] certer = getNpcByIdNotTalk(NPC_ID_SETH); if (certer[0] == -1) { return 0; } talkToNpc(certer[0]); timeout = System.currentTimeMillis() + TIMEOUT_TWO_SECONDS; return 0; } private int exitTavern() { if (isDoorClosed()) { if (inCombat()) { walkTo(Object.TAVERN_DOOR.coordinate.getX(), Object.TAVERN_DOOR.coordinate.getY()); return SLEEP_ONE_TICK; } return openDoor(); } walkTo(Object.TAVERN_DOOR.coordinate.getX() - 1, Object.TAVERN_DOOR.coordinate.getY()); return SLEEP_ONE_TICK; } private int walkToCerter() { if (getCurrentHits() > minimumHits && !isDoorClosed() && isNearDoor()) { if (inCombat()) { walkTo(Object.TAVERN_DOOR.coordinate.getX() - 1, Object.TAVERN_DOOR.coordinate.getY()); return SLEEP_ONE_TICK; } return closeDoor(); } walkTo(COORDINATE_CERTER.getX(), COORDINATE_CERTER.getY()); return SLEEP_ONE_TICK; } private int eat(final int foodIndex) { if (System.currentTimeMillis() <= timeout) { return 0; } useItem(foodIndex); timeout = System.currentTimeMillis() + TIMEOUT_THREE_SECONDS; return 0; } private int enterTavern() { final int doorX = Object.TAVERN_DOOR.coordinate.getX(); final int doorY = Object.TAVERN_DOOR.coordinate.getY(); if (inCombat() || distanceTo(doorX, doorY) > 1) { walkTo(doorX - 1, doorY); return SLEEP_ONE_TICK; } if (isDoorClosed()) { return openDoor(); } walkTo(doorX, doorY); return SLEEP_ONE_TICK; } private boolean isDoorClosed() { return getWallObjectIdFromCoords(Object.TAVERN_DOOR.coordinate.getX(), Object.TAVERN_DOOR.coordinate.getY()) == Object.TAVERN_DOOR.id; } private int closeDoor() { if (System.currentTimeMillis() <= timeout) { return 0; } atWallObject2(Object.TAVERN_DOOR.coordinate.getX(), Object.TAVERN_DOOR.coordinate.getY()); timeout = System.currentTimeMillis() + TIMEOUT_TWO_SECONDS; return 0; } private void updateLoot() { loot[0] = -1; for (final int itemId : ITEM_IDS_LOOT) { for (int index = 0; index < getGroundItemCount(); index++) { final int groundItemId = getGroundItemId(index); if (groundItemId != itemId) { continue; } final int groundItemX = getItemX(index); final int groundItemY = getItemY(index); if (!Area.TAVERN.contains(groundItemX, groundItemY)) { continue; } loot[0] = groundItemId; loot[1] = groundItemX; loot[2] = groundItemY; return; } } } private boolean canPickUpStackableLoot() { return inArray(ITEM_IDS_STACKABLE, loot[0]) && hasInventoryItem(loot[0]); } private int getNearestPirateIndex() { int pirateIndex = -1; int currentDistance = Integer.MAX_VALUE; for (int index = 0; index < bot.getNpcCount(); index++) { final java.lang.Object npc = bot.getNpc(index); if (bot.getNpcId(npc) != NPC_ID_PIRATE || bot.isMobInCombat(npc)) { continue; } final int npcX = bot.getMobLocalX(npc) + bot.getAreaX(); final int npcY = bot.getMobLocalY(npc) + bot.getAreaY(); if (!Area.TAVERN.contains(npcX, npcY)) { continue; } final int distance = distanceTo(npcX, npcY, playerX, playerY); if (distance >= currentDistance) { continue; } pirateIndex = index; currentDistance = distance; } return pirateIndex; } public int getQuestMenuIndex(final String option) { final String[] openMenyItems = questMenuOptions(); for (int index = 0; index < questMenuCount(); index++) { if (openMenyItems[index].equals(option)) { return index; } } return -1; } private int openDoor() { if (System.currentTimeMillis() <= timeout) { return 0; } atWallObject(Object.TAVERN_DOOR.coordinate.getX(), Object.TAVERN_DOOR.coordinate.getY()); timeout = System.currentTimeMillis() + TIMEOUT_TWO_SECONDS; return 0; } private boolean isNearDoor() { return distanceTo(Object.TAVERN_DOOR.coordinate.getX(), Object.TAVERN_DOOR.coordinate.getY()) <= 1; } @Override public void paint() { int y = PAINT_OFFSET_Y; drawString("@yel@Deadman's Chest", 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); final int kills = (int) xpGained / NPC_XP_PIRATE; drawString(String.format("@yel@Kills: @whi@%d @cya@(@whi@%s per@cya@/@whi@hr@cya@)", kills, toUnitsPerHour(kills, startTime)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0); if (nextRespawn != null) { drawString(String.format("@yel@Next spawn: @cya@(@whi@%d@cya@, @whi@%d@cya@)", nextRespawn.getX(), nextRespawn.getY()), PAINT_OFFSET_X, y + PAINT_OFFSET_Y_INCREMENT, 1, 0); } } @Override public void onNpcSpawned(final java.lang.Object npc) { if (bot.getNpcId(npc) != NPC_ID_PIRATE) { return; } final int npcX = bot.getMobLocalX(npc) + bot.getAreaX(); final int npcY = bot.getMobLocalY(npc) + bot.getAreaY(); if (!Area.TAVERN.contains(npcX, npcY)) { return; } final int serverIndex = bot.getMobServerIndex(npc); final Spawn spawn = spawnMap.get(serverIndex); if (spawn != null) { spawn.getCoordinate().set(npcX, npcY); spawn.setTimestamp(System.currentTimeMillis()); } else { spawnMap.put(serverIndex, new Spawn(new Coordinate(npcX, npcY), System.currentTimeMillis())); } nextRespawn = spawnMap.isEmpty() ? null : spawnMap.values().stream().sorted().findFirst().get().getCoordinate(); } private enum Cert { LOBSTER(533, 373, 12, "Lobster"), SWORDFISH(535, 370, 14, "Swordfish"); private static final Cert[] VALUES = Cert.values(); private final int id; private final int foodId; private final int healAmount; private final String name; Cert(final int id, final int foodId, final int healAmount, final String name) { this.id = id; this.foodId = foodId; this.healAmount = healAmount; this.name = name; } private static String getCertAmount(final int inventorySpaces) { final int amount = inventorySpaces / 5; switch (amount) { case 0: return null; case 1: return "One"; case 2: return "two"; case 3: return "Three"; case 4: return "four"; default: return "five"; } } } private enum Area implements RSArea { TAVERN(new Coordinate(449, 696), new Coordinate(454, 706)), BRIMHAVEN(new Coordinate(444, 694), new Coordinate(459, 709)); private final Coordinate lowerBoundingCoordinate; private final Coordinate upperBoundingCoordinate; Area(final Coordinate lowerBoundingCoordinate, final Coordinate upperBoundingCoordinate) { this.lowerBoundingCoordinate = lowerBoundingCoordinate; this.upperBoundingCoordinate = upperBoundingCoordinate; } public Coordinate getLowerBoundingCoordinate() { return lowerBoundingCoordinate; } public Coordinate getUpperBoundingCoordinate() { return upperBoundingCoordinate; } } private enum Object implements RSObject { TAVERN_DOOR(2, new Coordinate(449, 699)); private final int id; private final Coordinate coordinate; Object(final int id, final Coordinate coordinate) { this.id = id; this.coordinate = coordinate; } public int getId() { return id; } public Coordinate getCoordinate() { return coordinate; } } }