/** * Fish, cook, and cert at the Fishing Guild. *

* Required: * Start script at the fishing guild with sleeping bag, fishing tool, and cooking gauntlets (optional). *

* Required Parameter: * -f,--fish *

* Optional Parameters: * -c,--cook * -r,--receiver *

* Notes: * A player matching the name of the receiver parameter can say "Trade" in chat to have certs traded to him/her. *

* * @Author Chomp */ public class AA_FishingGuild extends AA_Script { private static final int MAXIMUM_FATIGUE = 99; private static final int REQUIRED_FISH_COUNT_TO_CERT = 25; private Fish fish; private State state; private long startTime; private String receiver = ""; private double initialFishingXp; private double initialCookingXp; private long clickTimeout; private long tradeRequestTimeout; private long optionMenuTimeout; private int playerX; private int playerY; private int fishCerted; private int fishCaught; private int fishCooked; private int fishBurnt; private boolean idle; private boolean trading; private boolean cooking; public AA_FishingGuild(final Extension extension) { super(extension); } @Override public void init(final String parameters) { if (parameters.isEmpty()) printInstructions(); final String[] args = parameters.split(" "); for (int i = 0; i < args.length; i++) { switch (args[i].toLowerCase()) { case "-f": case "--fish": fish = Fish.valueOf(args[++i].toUpperCase()); break; case "-c": case "--cook": cooking = true; break; case "-r": case "--receiver": receiver = args[++i]; break; default: throw new IllegalArgumentException("Error: malformed parameters. Try again ..."); } } if (fish == null) { throw new IllegalStateException("Missing fish parameter."); } if (!hasInventoryItem(ITEM_ID_SLEEPING_BAG)) { throw new IllegalStateException("Sleeping bag missing from inventory."); } if (!hasInventoryItem(fish.toolId)) { throw new IllegalStateException(String.format("%s missing from inventory.", getItemNameId(fish.toolId))); } state = State.FISH; initialFishingXp = getAccurateXpForLevel(Skill.FISHING.getIndex()); initialCookingXp = getAccurateXpForLevel(Skill.COOKING.getIndex()); startTime = System.currentTimeMillis(); } @Override public int main() { playerX = getX(); playerY = getY(); if (trading) { return trade(); } switch (state) { case FISH: return fish(); case COOK: return cook(); case CERT: return cert(); default: return exit("Invalid script state."); } } @Override public void onServerMessage(final String message) { if (message.startsWith("fail", 4)) { clickTimeout = 0; } else if (message.startsWith("catch", 4)) { fishCaught++; clickTimeout = 0; } else if (message.startsWith("burn", 17)) { fishBurnt++; clickTimeout = 0; } else if (message.endsWith("cooked")) { fishCooked++; clickTimeout = 0; } else if (message.endsWith("certificates")) { fishCerted += REQUIRED_FISH_COUNT_TO_CERT; } else if (message.endsWith("area")) { idle = true; } else if (message.startsWith("Trade") || message.endsWith("trade")) { clickTimeout = 0L; optionMenuTimeout = 0L; tradeRequestTimeout = 0L; trading = false; } else { super.onServerMessage(message); } } private int trade() { final int[] player = getPlayerByName(receiver); if (player[0] == -1) { trading = false; return 0; } final int inventoryIndex = getInventoryIndex(fish.certIds); if (inventoryIndex == -1) { trading = false; return 0; } if (isInTradeConfirm()) { if (bot.hasLocalConfirmedTrade()) { return 0; } confirmTrade(); return SLEEP_ONE_TICK; } if (isInTradeOffer()) { if (getLocalTradeItemCount() == 0) { if (System.currentTimeMillis() <= clickTimeout) { return 0; } offerItemTrade(inventoryIndex, getInventoryStack(inventoryIndex)); clickTimeout = System.currentTimeMillis() + TIMEOUT_ONE_SECOND; return 0; } if (bot.hasLocalAcceptedTrade()) { return 0; } acceptTrade(); return SLEEP_ONE_TICK; } if (distanceTo(player[1], player[2]) > 1) { walkTo(player[1], player[2]); return SLEEP_ONE_TICK; } if (System.currentTimeMillis() <= tradeRequestTimeout) { return 0; } sendTradeRequest(getPlayerPID(player[0])); tradeRequestTimeout = System.currentTimeMillis() + TIMEOUT_TEN_SECONDS; return 0; } private int fish() { if (Area.DOCKS.contains(playerX, playerY)) { if (idle) { if (playerY == fish.coordinate.getY() + 2) { idle = false; return 0; } walkTo(fish.coordinate.getX() - 1, fish.coordinate.getY() + 2); return SLEEP_ONE_TICK; } if (getInventoryCount() == MAX_INV_SIZE) { state = cooking ? State.COOK : State.CERT; return 0; } if (getFatigue() >= MAXIMUM_FATIGUE) { return sleep(); } if (System.currentTimeMillis() <= clickTimeout) { return 0; } final Coordinate fishCoordinate = fish.coordinate; if (playerX != fishCoordinate.getX() - 1 || playerY != fishCoordinate.getY() + 1) { walkTo(fishCoordinate.getX() - 1, fishCoordinate.getY() + 1); return SLEEP_ONE_TICK; } useObject2(fishCoordinate.getX(), fishCoordinate.getY()); clickTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS; return 0; } if (Area.RANGE_HOUSE.contains(playerX, playerY) && getWallObjectIdFromCoords(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()) == Object.RANGE_DOOR.id) { atWallObject(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()); return SLEEP_ONE_SECOND; } if (Area.CERT_HOUSE.contains(playerX, playerY) && getWallObjectIdFromCoords(Object.CERT_DOOR.coordinate.getX(), Object.CERT_DOOR.coordinate.getY()) == Object.CERT_DOOR.id) { atWallObject(Object.CERT_DOOR.coordinate.getX(), Object.CERT_DOOR.coordinate.getY()); return SLEEP_ONE_SECOND; } walkTo(fish.coordinate.getX() - 1, fish.coordinate.getY() + 1); if (getFatigue() != 0 && isWalking()) { return sleep(); } return SLEEP_ONE_TICK; } private int cook() { if (Area.RANGE_HOUSE.contains(playerX, playerY)) { final int burntIndex = getInventoryIndex(fish.burntId); if (burntIndex != -1) { dropItem(burntIndex); return SLEEP_ONE_TICK; } if (getFatigue() >= MAXIMUM_FATIGUE) { return sleep(); } if (System.currentTimeMillis() <= clickTimeout) { return 0; } final int rawIndex = getInventoryIndex(fish.rawId); if (rawIndex != -1) { final Coordinate range = Object.RANGE.getCoordinate(); if (playerX != range.getX() + 1 || playerY != range.getY()) { walkTo(range.getX() + 1, range.getY()); return SLEEP_ONE_TICK; } useWithObject(rawIndex, range.getX(), range.getY()); clickTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS; return 0; } state = getInventoryCount(fish.cookedId) >= REQUIRED_FISH_COUNT_TO_CERT ? State.CERT : State.FISH; return 0; } if (distanceTo(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()) <= 1) { if (getWallObjectIdFromCoords(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()) == Object.RANGE_DOOR.id) { atWallObject(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()); return SLEEP_ONE_SECOND; } walkTo(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()); return SLEEP_ONE_TICK; } walkTo(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY() - 1); if (getFatigue() != 0 && isWalking()) { return sleep(); } return SLEEP_ONE_TICK; } private int cert() { if (Area.CERT_HOUSE.contains(playerX, playerY)) { final int itemId = cooking ? fish.cookedId : fish.rawId; if (getInventoryCount(itemId) < REQUIRED_FISH_COUNT_TO_CERT) { state = State.FISH; return 0; } if (isQuestMenu()) { int menuIndex; if ((menuIndex = getMenuIndex("I have some fish to trade in")) != -1 || (menuIndex = getMenuIndex(cooking ? fish.cookedCertName : fish.rawCertName)) != -1 || (menuIndex = getMenuIndex("Twentyfive")) != -1 ) { answer(menuIndex); optionMenuTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS; return 0; } return SLEEP_ONE_SECOND; } if (System.currentTimeMillis() <= optionMenuTimeout) { return 0; } final int[] certer = getNpcByIdNotTalk(fish.certerId); if (certer[0] == -1) { return 0; } talkToNpc(certer[0]); optionMenuTimeout = System.currentTimeMillis() + TIMEOUT_FIVE_SECONDS; return 0; } if (Area.RANGE_HOUSE.contains(playerX, playerY) && getWallObjectIdFromCoords(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()) == Object.RANGE_DOOR.id) { atWallObject(Object.RANGE_DOOR.coordinate.getX(), Object.RANGE_DOOR.coordinate.getY()); return SLEEP_ONE_SECOND; } if (distanceTo(Object.CERT_DOOR.coordinate.getX(), Object.CERT_DOOR.coordinate.getY()) <= 1) { if (getWallObjectIdFromCoords(Object.CERT_DOOR.coordinate.getX(), Object.CERT_DOOR.coordinate.getY()) == Object.CERT_DOOR.id) { atWallObject(Object.CERT_DOOR.coordinate.getX(), Object.CERT_DOOR.coordinate.getY()); return SLEEP_ONE_SECOND; } walkTo(Object.CERT_DOOR.coordinate.getX(), Object.CERT_DOOR.coordinate.getY()); return SLEEP_ONE_TICK; } walkTo(Object.CERT_DOOR.coordinate.getX() - 1, Object.CERT_DOOR.coordinate.getY()); if (getFatigue() != 0 && isWalking()) { return sleep(); } return SLEEP_ONE_TICK; } @Override public void paint() { int y = PAINT_OFFSET_Y; drawString("@yel@Fishing Guild", PAINT_OFFSET_X, y, 1, 0); drawString(String.format("@yel@Catching: @gr1@%s", fish.cookedCertName), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0); drawString(String.format("@yel@Runtime: @whi@%s", toDuration(startTime)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0); final double fishingXpGained = getAccurateXpForLevel(Skill.FISHING.getIndex()) - initialFishingXp; drawString(String.format("@cya@Fishing Xp: @whi@%s @cya@(@whi@%s xp@cya@/@whi@hr@cya@)", DECIMAL_FORMAT.format(fishingXpGained), toUnitsPerHour((int) fishingXpGained, startTime)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT * 2, 1, 0); drawString(String.format("@cya@Fish Caught: @whi@%s @cya@(@whi@%s fish@cya@/@whi@hr@cya@)", DECIMAL_FORMAT.format(fishCaught), toUnitsPerHour(fishCaught, startTime)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0); if (cooking) { final double cookingXpGained = getAccurateXpForLevel(Skill.COOKING.getIndex()) - initialCookingXp; drawString(String.format("@or1@Cooking Xp: @whi@%s @or1@(@whi@%s xp@or1@/@whi@hr@or1@)", DECIMAL_FORMAT.format(cookingXpGained), toUnitsPerHour((int) cookingXpGained, startTime)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT * 2, 1, 0); drawString(String.format("@or1@Fish Cooked: @whi@%s", DECIMAL_FORMAT.format(fishCooked)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0); if (fishBurnt > 0) { drawString(String.format("@or1@Fish Burnt: @whi@%s", DECIMAL_FORMAT.format(fishBurnt)), PAINT_OFFSET_X, y += PAINT_OFFSET_Y_INCREMENT, 1, 0); } } drawString(String.format("@gre@Fish Certed: @whi@%s", DECIMAL_FORMAT.format(fishCerted)), PAINT_OFFSET_X, y + PAINT_OFFSET_Y_INCREMENT * 2, 1, 0); } @Override public void onChatMessage(final String message, final String playerName, final boolean moderator, final boolean administrator) { if (receiver.isEmpty()) { return; } if (playerName.equals(receiver) && message.equals("Trade")) { trading = true; } } private enum State { FISH, COOK, CERT } private enum Fish { LOBSTER(372, 373, 374, 375, 369, new int[]{533, 534}, "Raw Lobster", "Lobster", new Coordinate(596, 501)), SHARK(545, 546, 547, 379, 370, new int[]{630, 631}, "Raw Shark", "Shark", new Coordinate(593, 501)); private final int rawId; private final int cookedId; private final int burntId; private final int toolId; private final int certerId; private final int[] certIds; private final String rawCertName; private final String cookedCertName; private final Coordinate coordinate; Fish(final int rawId, final int cookedId, final int burntId, final int toolId, final int certerId, final int[] certIds, final String rawCertName, final String cookedCertName, final Coordinate coordinate) { this.rawId = rawId; this.cookedId = cookedId; this.burntId = burntId; this.toolId = toolId; this.certerId = certerId; this.certIds = certIds; this.rawCertName = rawCertName; this.cookedCertName = cookedCertName; this.coordinate = coordinate; } } private enum Area implements RSArea { DOCKS(new Coordinate(586, 496), new Coordinate(598, 513)), RANGE_HOUSE(new Coordinate(583, 519), new Coordinate(588, 523)), CERT_HOUSE(new Coordinate(602, 500), new Coordinate(605, 505)) { @Override public boolean contains(final int x, final int y) { return super.contains(x, y) || (x >= 603 && x <= 605 && y == 506); } }; 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 { CERT_DOOR(2, new Coordinate(603, 506)), RANGE_DOOR(2, new Coordinate(586, 519)), RANGE(11, new Coordinate(583, 520)); 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; } } }