Jump to content

Made my first script


Camaro

Recommended Posts

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 by camaro 09
Progress was set as completed (for debugging)
  • Like 3
Link to comment
Share on other sites

Congrats on your first script, good job

As for feed back:

  1. 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
  2. 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.
  3. Your functions like isAtBucketArea don't really add anything, it's just as clear to read milkArea.contains(myPlayer())
  4. You should use configs for quests rather than using your Progress enum and setting after each completed task
  5. You should only sleep if an interaction is successful, for example if (blah.interact()) { sleep }
  6. 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 by Explv
  • Like 3
  • Heart 2
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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:

  1. 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
  2. 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.
  3. Your functions like isAtBucketArea don't really add anything, it's just as clear to read milkArea.contains(myPlayer())
  4. You should use configs for quests rather than using your Progress enum and setting after each completed task
  5. You should only sleep if an interaction is successful, for example if (blah.interact()) { sleep }
  6. 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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...