Camaro Posted December 9, 2018 Share Posted December 9, 2018 (edited) Hi, just finished up my first script, looking for feedback on how I can improve. It completes Cooks Assistant and also the baking break achievement diary. Should be able to start from any point in the quest. Big shout-out to @The Viking for his Timing class! Also @Explv for the area map, extremely helpful. import org.osbot.rs07.api.model.NPC; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.api.ui.RS2Widget; import org.osbot.rs07.script.MethodProvider; public class Helper { private MethodProvider provider; public Helper(MethodProvider p) { provider = p; } public RS2Widget cooksAssistant() { return provider.getWidgets().get(399, 9, 1); } public RS2Widget progressPage() { return provider.getWidgets().get(119, 3); } public RS2Widget dialogBoxCook() { return provider.getWidgets().get(231, 2); } public RS2Widget dialogBoxMe() { return provider.getWidgets().get(217, 2); } public RS2Widget optionOne() { return provider.getWidgets().get(219, 1, 1); } public RS2Widget lineMilk() { return provider.getWidgets().get(119, 7); } public RS2Widget lineFlour() { return provider.getWidgets().get(119, 8); } public RS2Widget lineEgg() { return provider.getWidgets().get(119, 9); } public RS2Widget lumbyDiary() { return provider.getWidgets().get(259, 10, 83); } public RS2Widget achievementDiary() { return provider.getWidgets().get(399, 3); } public RS2Widget cookBreadAchievement() { return provider.getWidgets().get(119, 18); } public RS2Widget breadOption() { return provider.getWidgets().get(270, 14, 29); } public NPC cook() { return provider.getNpcs().closest(4626); } public RS2Object cow() { return provider.getObjects().closest(8689); } public RS2Object wheat() { return provider.getObjects().closest("Wheat"); } public RS2Object hopper() { return provider.getObjects().closest("Hopper"); } public RS2Object lever() { return provider.getObjects().closest("Hopper controls"); } public RS2Object flourBin() { return provider.getObjects().closest("Flour bin"); } public RS2Object range() { return provider.getObjects().closest("Cooking range"); } public RS2Object sink() { return provider.getObjects().closest("Sink"); } } import org.osbot.rs07.api.Quests; import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.api.ui.*; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; @ScriptManifest(info = "Cooks assistant", version = 1.0, logo = "", name = "Cooks assistant", author = "Matt") public class Main extends Script { enum Progress { unsure, needToStart, needToGetMilk, needToGetFlour, needToGetEgg, needToGiveMilk, needToGiveFlour, needToGiveEgg, needToTalk, doDiary, bakeBread, completed } enum FlourProgress { getGrain, putInHopper, pullLever, getFlour } public Progress progress = null; public FlourProgress flourProgress = null; public GroundItem tempitem = null; public int tempint = 0; public Helper helper = null; public final Area startArea = new Area(3205, 3217, 3212, 3212); public final Area bucketArea = new Area(3211, 9624, 3216, 9620); public final Area eggArea = new Area(3227, 3301, 3233, 3296); public final Area milkArea = new Area( new int[][]{ { 3251, 3278 }, { 3251, 3274 }, { 3254, 3271 }, { 3256, 3271 }, { 3256, 3278 } } ); public final Area flourArea = new Area( new int[][]{ { 3157, 3295 }, { 3162, 3290 }, { 3164, 3292 }, { 3164, 3295 } } ); public final Area hopperArea = new Area( new int[][]{ { 3166, 3311 }, { 3168, 3311 }, { 3171, 3308 }, { 3171, 3306 }, { 3168, 3303 }, { 3166, 3303 }, { 3163, 3306 }, { 3163, 3308 } } ); public boolean isAtStart() { return startArea.contains(myPlayer()); } public boolean isAtBucketArea() { return bucketArea.contains(myPlayer()); } public boolean isAtEggArea() { return eggArea.contains(myPlayer()); } public boolean isAtMilkArea() { return milkArea.contains(myPlayer()); } public boolean isAtFlourArea() { return flourArea.contains(myPlayer()); } public boolean isAtHopperArea(int plane) { return hopperArea.setPlane(plane).contains(myPlayer()); } public boolean isReady(int pots, int buckets, int eggs) { return inventory.getAmount("Pot") >= pots && inventory.getAmount("Bucket") >= buckets && inventory.getAmount("Egg") >= eggs; } public void getPot() { if (!isAtStart()) { walking.webWalk(startArea); } else if ((tempitem = getGroundItems().closest("Pot")) != null) { tempint = getInventory().getEmptySlotCount(); tempitem.interact("Take"); Timing.waitCondition(() -> getInventory().getEmptySlotCount() < tempint, 3000); } } public void getBucket() { if (!isAtBucketArea()) { walking.webWalk(bucketArea); } else if ((tempitem = getGroundItems().closest("Bucket")) != null) { tempint = getInventory().getEmptySlotCount(); tempitem.interact("Take"); Timing.waitCondition(() -> getInventory().getEmptySlotCount() < tempint, 3000); } } public void getEgg() { if (!isAtEggArea()) { walking.webWalk(eggArea); } else if ((tempitem = getGroundItems().closest("Egg")) != null) { tempint = getInventory().getEmptySlotCount(); tempitem.interact("Take"); Timing.waitCondition(() -> getInventory().getEmptySlotCount() < tempint, 3000); } } public void getMilk() { if (!isReady(0, (int)(1 - inventory.getAmount("Bucket of milk")), 0)) { getSupplies(0, (int)(1 - inventory.getAmount("Bucket of milk")), 0); } else if (!isAtMilkArea()) { walking.webWalk(milkArea); } else if (helper.cow() != null) { tempint = (int) inventory.getAmount("Bucket of milk"); helper.cow().interact("Milk"); Timing.waitCondition(() -> inventory.getAmount("Bucket of milk") > tempint, 10000); } } public void getFlour(int count) { if (!isReady((int)(count - inventory.getAmount("Pot of flour")), 0, 0)) { getSupplies((int)(count - inventory.getAmount("Pot of flour")), 0, 0); } else if (flourProgress == null) { flourProgress = FlourProgress.getGrain; } switch (flourProgress) { case getGrain: if (inventory.getAmount("Grain") >= count - inventory.getAmount("Pot of flour")) { flourProgress = FlourProgress.putInHopper; } else if (!isAtFlourArea()) { walking.webWalk(flourArea); } else if (helper.wheat() != null) { tempint = (int) inventory.getAmount("Grain"); helper.wheat().interact("Pick"); Timing.waitCondition(() -> inventory.getAmount("Grain") > tempint, 3000); } break; case putInHopper: if (!isAtHopperArea(2)) { walking.webWalk(hopperArea.setPlane(2)); } else if (helper.hopper() != null && inventory.getItem("Grain").interact("Use")) { tempint = (int) inventory.getAmount("Grain"); helper.hopper().interact("Use"); Timing.waitCondition(() -> inventory.getAmount("Grain") < tempint && !myPlayer().isAnimating(), 5000); Timing.waitCondition(() -> false, 2000); flourProgress = FlourProgress.pullLever; } break; case pullLever: if (!isAtHopperArea(2)) { walking.webWalk(hopperArea.setPlane(2)); } else if (helper.lever() != null && helper.lever().interact("Operate")) { Timing.waitCondition(() -> !myPlayer().isMoving() && myPlayer().isAnimating(), 3000); flourProgress = FlourProgress.getFlour; } break; case getFlour: if (!isAtHopperArea(0)) { walking.webWalk(hopperArea.setPlane(0)); } else if (helper.flourBin() != null) { tempint = (int) inventory.getAmount("Pot of flour"); helper.flourBin().interact("Empty"); Timing.waitCondition(() -> inventory.getAmount("Pot of flour") > tempint, 3000); flourProgress = null; } break; } } public void getSupplies(int pots, int buckets, int eggs) { log("getting supplies"); if (inventory.getAmount("Pot") < pots) { getPot(); } else if (inventory.getAmount("Bucket") < buckets) { getBucket(); } else if (inventory.getAmount("Egg") < eggs) { getEgg(); } } @Override public void onStart() throws InterruptedException { log("Starting"); progress = Progress.unsure; helper = new Helper(this); } @Override public int onLoop() throws InterruptedException { log(progress); switch (progress) { case unsure: if (getQuests().isComplete(Quests.Quest.COOKS_ASSISTANT)) { progress = Progress.doDiary; } else if (!getQuests().isStarted(Quests.Quest.COOKS_ASSISTANT) && !getQuests().isComplete(Quests.Quest.COOKS_ASSISTANT)) { progress = Progress.needToStart; } else if (!getTabs().isOpen(Tab.QUEST) && getTabs().open(Tab.QUEST)) { Timing.waitCondition(() -> getTabs().isOpen(Tab.QUEST), 2000); } else if (helper.progressPage() == null) { helper.cooksAssistant().interact("Read Journal:"); Timing.waitCondition(() -> helper.progressPage() != null, 2000); } else if (helper.lineMilk() != null && helper.lineMilk().getMessage().contains("I need to find")) { progress = Progress.needToGetMilk; } else if (helper.lineMilk() != null && helper.lineMilk().getMessage().contains("give to the cook")) { progress = inventory.getAmount("Bucket of milk") < 2 ? Progress.needToGetMilk : Progress.needToGiveMilk; } else if (helper.lineFlour() != null && helper.lineFlour().getMessage().contains("I need to find")) { progress = Progress.needToGetFlour; } else if (helper.lineFlour() != null && helper.lineFlour().getMessage().contains("give to the cook")) { progress = inventory.getAmount("Pot of flour") < 2 ? Progress.needToGetFlour : Progress.needToGiveFlour; } else if (helper.lineEgg() != null && helper.lineEgg().getMessage().contains("I need to find")) { progress = Progress.needToGetEgg; } else if (helper.lineEgg() != null && helper.lineEgg().getMessage().contains("give to the cook")) { progress = Progress.needToGiveEgg; } else if (helper.lineMilk() != null && helper.lineFlour() != null && helper.lineEgg() != null && helper.lineMilk().getMessage().contains("I have given") && helper.lineFlour().getMessage().contains("I have given") && helper.lineEgg().getMessage().contains("I have given")) { progress = Progress.needToTalk; } break; case needToStart: if (!isAtStart()) { walking.webWalk(startArea); } else if (!getDialogues().inDialogue() && helper.cook() != null) { helper.cook().interact("Talk-to"); Timing.waitCondition(() -> getDialogues().inDialogue(), 3000); } else if ((helper.dialogBoxCook() != null && helper.dialogBoxCook().getMessage().equals("Cook")) || (helper.dialogBoxMe() != null && helper.dialogBoxMe().getMessage().equals(myPlayer().getName()))) { getKeyboard().pressKey(32); } else if (helper.optionOne() != null && helper.optionOne().getMessage().equals("What's wrong?")) { getDialogues().selectOption("What's wrong?"); } else if (helper.optionOne() != null && helper.optionOne().getMessage().equals("I'm always happy to help a cook in distress.")) { getDialogues().selectOption("I'm always happy to help a cook in distress."); Timing.waitCondition(() -> getQuests().isStarted(Quests.Quest.COOKS_ASSISTANT), 2000); progress = Progress.needToGetMilk; } break; case needToGetMilk: if (inventory.getAmount("Bucket of milk") < 2) { getMilk(); } else { progress = Progress.needToGiveMilk; } break; case needToGiveMilk: if (inventory.getAmount("Bucket of milk") < 2) { progress = Progress.unsure; } else if (!isAtStart()) { walking.webWalk(startArea); } else if (!getDialogues().inDialogue() && helper.cook() != null) { helper.cook().interact("Talk-to"); } else if ((helper.dialogBoxCook() != null && helper.dialogBoxCook().getMessage().equals("Cook")) || (helper.dialogBoxMe() != null && helper.dialogBoxMe().getMessage().equals(myPlayer().getName()))) { getKeyboard().pressKey(32); } break; case needToGetFlour: if (inventory.getAmount("Pot of flour") < 2) { getFlour(2); } else { progress = Progress.needToGiveFlour; } break; case needToGiveFlour: if (inventory.getAmount("Pot of flour") < 2) { progress = Progress.unsure; } else if (!isAtStart()) { walking.webWalk(startArea); } else if (!getDialogues().inDialogue() && helper.cook() != null) { helper.cook().interact("Talk-to"); } else if ((helper.dialogBoxCook() != null && helper.dialogBoxCook().getMessage().equals("Cook")) || (helper.dialogBoxMe() != null && helper.dialogBoxMe().getMessage().equals(myPlayer().getName()))) { getKeyboard().pressKey(32); } break; case needToGetEgg: if (!isReady(0, 0, 1)) { getEgg(); } else { progress = Progress.needToGiveEgg; } break; case needToGiveEgg: if (!getInventory().contains("Egg")) { progress = Progress.unsure; } else if (!isAtStart()) { walking.webWalk(startArea); } else if (!getDialogues().inDialogue() && helper.cook() != null) { helper.cook().interact("Talk-to"); } else if ((helper.dialogBoxCook() != null && helper.dialogBoxCook().getMessage().equals("Cook")) || (helper.dialogBoxMe() != null && helper.dialogBoxMe().getMessage().equals(myPlayer().getName()))) { getKeyboard().pressKey(32); } break; case needToTalk: if (getQuests().isComplete(Quests.Quest.COOKS_ASSISTANT)) { progress = Progress.doDiary; } else if (!isAtStart()) { walking.webWalk(startArea); } else if (!getDialogues().inDialogue() && helper.cook() != null) { helper.cook().interact("Talk-to"); } else if ((helper.dialogBoxCook() != null && helper.dialogBoxCook().getMessage().equals("Cook")) || (helper.dialogBoxMe() != null && helper.dialogBoxMe().getMessage().equals(myPlayer().getName()))) { getKeyboard().pressKey(32); } break; case doDiary: if (!getWorlds().isMembersWorld()) { log("Not on members world, cannot complete achievement diary"); progress = Progress.completed; } else if (helper.progressPage() == null && !getTabs().isOpen(Tab.QUEST) && getTabs().open(Tab.QUEST)) { Timing.waitCondition(() -> getTabs().isOpen(Tab.QUEST), 2000); } else if (helper.progressPage() == null && helper.lumbyDiary() == null && helper.achievementDiary() != null) { helper.achievementDiary().interact("View Achievement Diaries"); } else if (helper.progressPage() == null) { helper.lumbyDiary().interact("Open Lumbridge & Draynor Journal"); Timing.waitCondition(() -> helper.progressPage() != null, 2000); } else if (helper.cookBreadAchievement() != null) { progress = helper.cookBreadAchievement().getMessage().contains("<str>") ? Progress.completed : Progress.bakeBread; } break; case bakeBread: if (!getInventory().contains("Bread dough") && !getInventory().contains("Bucket of water") && !getInventory().contains("Bucket")) { getSupplies(0, 1, 0); } else if (!getInventory().contains("Bread dough") && !getInventory().contains("Pot of flour")) { getFlour(1); } else if (!isAtStart()) { walking.webWalk(startArea); } else if (!getInventory().contains("Bread dough") && !getInventory().contains("Bucket of water") && helper.sink() != null) { inventory.getItem("Bucket").interact("Use"); tempint = (int) inventory.getAmount("Bucket"); helper.sink().interact("Use"); Timing.waitCondition(() -> inventory.getAmount("Bucket") < tempint, 5000); } else if (!getInventory().contains("Bread dough") && helper.breadOption() == null) { inventory.getItem("Bucket of water").interact("Use"); tempint = (int) inventory.getAmount("Bread dough"); inventory.getItem("Pot of flour").interact("Use"); Timing.waitCondition(() -> helper.breadOption() != null, 2000); } else if (!getInventory().contains("Bread dough") && helper.breadOption() != null) { helper.breadOption().interact("Make"); } else if (!getInventory().contains("Break") && helper.range() != null && !helper.range().isVisible()) { walking.walk(new Area(3210, 3216, 3211, 3215)); } else if (!getInventory().contains("Break") && helper.range() != null) { inventory.getItem("Bread dough").interact("Use"); tempint = (int) inventory.getAmount("Bread"); helper.range().interact("Use"); if (Timing.waitCondition(() -> inventory.getAmount("Bread") > tempint, 7000)) { progress = Progress.completed; } } break; case completed: log(getWidgets().get(119, 6).getMessage()); log("Completed quest"); stop(false); break; } return 600; } } Edited December 15, 2018 by camaro 09 Progress was set as completed (for debugging) 3 Quote Link to comment Share on other sites More sharing options...
Explv Posted December 9, 2018 Share Posted December 9, 2018 (edited) Congrats on your first script, good job As for feed back: That Helper class should not exist, it doesn't add any benefit. You should just make the getWidgets() and getObjects() calls in the "Main" class Don't use IDs for widgets, the IDs can change and then your script will break. You should find the widgets based on text, actions etc. Your functions like isAtBucketArea don't really add anything, it's just as clear to read milkArea.contains(myPlayer()) You should use configs for quests rather than using your Progress enum and setting after each completed task You should only sleep if an interaction is successful, for example if (blah.interact()) { sleep } tempitem variable should be removed, just create a local variable when required If you follow the above advice your script will be far more succinct and maintainable. Edited December 9, 2018 by Explv 3 2 Quote Link to comment Share on other sites More sharing options...
Rare scripts Posted December 9, 2018 Share Posted December 9, 2018 Looks good, congrats on ur first script! Quote Link to comment Share on other sites More sharing options...
Perryy Posted December 10, 2018 Share Posted December 10, 2018 Congratulations bro! Quote Link to comment Share on other sites More sharing options...
JS3 Posted December 12, 2018 Share Posted December 12, 2018 Nice job on the first script! Keep it up!! Quote Link to comment Share on other sites More sharing options...
Mephisto Posted December 12, 2018 Share Posted December 12, 2018 Congrats on your first script! Quote Link to comment Share on other sites More sharing options...
liverare Posted December 12, 2018 Share Posted December 12, 2018 You could check to see if you've already completed the quest onStart and terminate the script if it is. If the quest is incomplete and in progress, then you could go through the quest journal and figure out what's still outstanding, store them as variables and referencing them as opposed to re-open the widget to check manually for each step. Quote Link to comment Share on other sites More sharing options...
Camaro Posted December 15, 2018 Author Share Posted December 15, 2018 On 12/12/2018 at 12:24 PM, liverare said: You could check to see if you've already completed the quest onStart and terminate the script if it is. If the quest is incomplete and in progress, then you could go through the quest journal and figure out what's still outstanding, store them as variables and referencing them as opposed to re-open the widget to check manually for each step. Already does this in the first conditional in the unsure case of the switch! And yes, setting variables after looking at the page for the first time would be better. On 12/9/2018 at 2:42 PM, Explv said: Congrats on your first script, good job As for feed back: That Helper class should not exist, it doesn't add any benefit. You should just make the getWidgets() and getObjects() calls in the "Main" class Don't use IDs for widgets, the IDs can change and then your script will break. You should find the widgets based on text, actions etc. Your functions like isAtBucketArea don't really add anything, it's just as clear to read milkArea.contains(myPlayer()) You should use configs for quests rather than using your Progress enum and setting after each completed task You should only sleep if an interaction is successful, for example if (blah.interact()) { sleep } tempitem variable should be removed, just create a local variable when required If you follow the above advice your script will be far more succinct and maintainable. Thanks a ton! Didnt even know about configs, thats very useful. Quote Link to comment Share on other sites More sharing options...