Jump to content

737 Cook's Assistant


737

Recommended Posts

737 Cook's Assistant

 

Description

Does the Cook's assistant quest then stops. Can be started at any point. No inventory or bank required.


Screens shots:
cooksassistantscreenshot.png.b662cdd87e989719bb888b5e610fbee5.png
cooksassistantscreenshot2.png.0716fca6d5b7823a80adb60f2a17d445.png

Script:

Spoiler


import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.model.GroundItem;
import org.osbot.rs07.api.model.NPC;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.Message;
import org.osbot.rs07.api.ui.Tab;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;
import org.osbot.rs07.utility.ConditionalSleep;

import java.awt.*;

@ScriptManifest(
        author = "737",
        info = "Does the Cook's Assistant Quest",
        logo = "",
        name = "737 Cook's Assistant",
        version = 1
)
public class CooksAssistant extends Script {

    private final Area AREA_LUMBRIDGE_KITCHEN = new Area(3208, 3212, 3210, 3213);
    private final Area AREA_FIND_EGG = new Area(3228, 3296, 3231, 3300);
    private final Area AREA_FIND_BUCKET = new Area(3226, 3290, 3229, 3291);
    private final Area AREA_FIND_COW = new Area(3253, 3275, 3256, 3277);
    private final Area AREA_WHEAT_FIELD = new Area(3160, 3294, 3162, 3297);
    private final Area AREA_FLOUR_BIN = new Area(3166, 3305, 3167, 3305);

    private final Position POSITION_HOPPER = new Position(3166, 3308, 2);

    private final String ITEM_BUCKET = "Bucket";
    private final String ITEM_BUCKET_MILK = "Bucket of milk";
    private final String ITEM_POT = "Pot";
    private final String ITEM_POT_FLOUR = "Pot of flour";
    private final String ITEM_EGG = "Egg";
    private final String ITEM_WHEAT = "Grain";

    private final String ACTION_TAKE = "Take";
    private final String ACTION_MILK = "Milk";
    private final String ACTION_PICK = "Pick";
    private final String ACTION_FILL = "Fill";
    private final String ACTION_OPERATE = "Operate";
    private final String ACTION_EMPTY = "Empty";
    private final String ACTION_TALK = "Talk-to";

    private final String OBJECT_COW = "Dairy Cow";
    private final String OBJECT_WHEAT = "Wheat";
    private final String OBJECT_HOPPER = "Hopper";
    private final String OBJECT_HOPPER_CONTROLS = "Hopper Controls";
    private final String OBJECT_FLOUR_BIN = "Flour Bin";

    private final String NPC_COOK = "Cook";

    private final String MESSAGE_GAME_HOPPER_FILLED = "You put the grain in the hopper";
    private final String MESSAGE_GAME_HOPPER_FILLED2 = "There is already grain in the hopper";
    private final String MESSAGE_GAME_HOPPER_OPERATE = "The grain slides down";
    private final String MESSAGE_GAME_HOPPER_EMPTIED = "You fill a pot with the last of the flour";

    private final int CONFIG_QUEST = 29;

    private final String[] DIALOGUE_OPTIONS_START_QUEST =
            {
                    "What's wrong?",
                    "Yes.",
                    "I'm always happy to help a cook in distress.",
                    "Actually, I know where to find this stuff."
            };

    private final String WIDGET_START_QUEST = "Start the Cook\'s Assistant quest?";

    private int baseSleepMs = 75;
    private String status = "loading...";
    private boolean hopperFilled = false;
    private boolean wheatProcessed = false;
    private long startTime;
    private boolean handInStarted = false;

    @Override
    public void onStart() {
        startTime = System.currentTimeMillis();
        baseSleepMs = random(50, 75);
    }

    @Override
    public int onLoop() throws InterruptedException {
        if (!getTabs().getOpen().equals(Tab.INVENTORY)) {
            getTabs().open(Tab.INVENTORY);
        }

        if (configs.get(CONFIG_QUEST) == 0) //quest not started
        {
            status = "Starting Quest";
            startQuest();
        } else if (configs.get(CONFIG_QUEST) == 2) {
            logger.info("Quest Complete. Stopping.");
            stop();
        } else if (handInStarted
                || (getInventory().contains(ITEM_BUCKET_MILK))
                && getInventory().contains(ITEM_BUCKET_MILK)
                && getInventory().contains(ITEM_BUCKET_MILK)) {
            status = "Handing in";
            handInStarted = true;
            completeQuest();
        } else if (!getInventory().contains(ITEM_POT_FLOUR)) {
            status = "Obtaining a pot of flour";
            getPotOfFlour();
        } else if (!getInventory().contains(ITEM_EGG)) {
            status = "Obtaining an Egg";
            fetchGroundItem(ITEM_EGG, AREA_FIND_EGG);
        } else if (!getInventory().contains(ITEM_BUCKET_MILK)) {
            status = "Obtaining a Bucket of Milk";
            getBucketOfMilk();
        }

        rSleep();
        return 0;
    }

    @Override
    public void onMessage(Message message) {
        if (message.getType() == Message.MessageType.GAME || message.getType() == Message.MessageType.FILTERED) {
            if (message.getMessage().contains(MESSAGE_GAME_HOPPER_FILLED)
                    || message.getMessage().contains(MESSAGE_GAME_HOPPER_FILLED2)) {
                logger.info("Hopper was filled.");
                hopperFilled = true;
                return;
            }

            if (message.getMessage().contains(MESSAGE_GAME_HOPPER_OPERATE)) {
                logger.info("Wheat was processed.");
                hopperFilled = false;
                wheatProcessed = true;
                return;
            }

            if (message.getMessage().contains(MESSAGE_GAME_HOPPER_EMPTIED)) {
                wheatProcessed = false;
                return;
            }
        }
    }

    @Override
    public void onPaint(Graphics2D g) {
        Color color = new Color(0, 255, 0, 150);
        g.setColor(color);
        g.fillRect(5, 20, 510, 100);

        g.setColor(Color.red);
        Font fontTitle = new Font("Consolas", Font.BOLD, 16);
        Font font = new Font("Consolas", Font.PLAIN, 16);

        g.setFont(fontTitle);
        g.drawString("737 Cook's Assistant v1.0", 20, 40);
        g.setFont(font);
        g.drawString("Status: " + status, 20, 60);
        g.drawString("Time Elapsed: " + formatTime(System.currentTimeMillis() - startTime), 20, 80);

        Point mP = getMouse().getPosition();

        g.drawLine(mP.x - 5, mP.y + 5, mP.x + 5, mP.y - 5);
        g.drawLine(mP.x + 5, mP.y + 5, mP.x - 5, mP.y - 5);
    }

    public void startQuest() throws InterruptedException {
        if (!dialogues.inDialogue()) {
            talkToNPC(NPC_COOK, AREA_LUMBRIDGE_KITCHEN);
            return;
        }

        handleDialogue(DIALOGUE_OPTIONS_START_QUEST);
    }

    public void completeQuest() throws InterruptedException {
        if (!dialogues.inDialogue()) {
            talkToNPC(NPC_COOK, AREA_LUMBRIDGE_KITCHEN);
            return;
        }

        handleDialogue(null); //no dialogue options for hand in
    }

    public void handleDialogue(String[] dialogueOptions) throws InterruptedException {
        //to make this method generic we need to modify the quest confirmation check
        boolean questConfirmationDialogueAvailable = !getWidgets().containingText(WIDGET_START_QUEST).isEmpty();

        if (questConfirmationDialogueAvailable) {
            getKeyboard().typeString("1");
            return;
        }

        if (dialogues.isPendingContinuation()) {
            dialogues.clickContinue();
            sleep(random(1000, 3000));
            return;
        }

        for (String dialogue : dialogueOptions) {
            if (dialogueExists(dialogue)) {
                dialogues.selectOption(dialogue);
                sleep(random(1000, 3000));
                return;
            }
        }

        //if we get lost in the dialogue somehow
        getWalking().walk(new Position(myPosition().getX() + 1, myPosition().getY(), myPosition().getZ()));
    }

    public boolean dialogueExists(String dialogueText) {
        return getWidgets().containingText(dialogueText) != null;
    }

    public void talkToNPC(String npcName, Area npcArea) throws InterruptedException {
        if (!npcArea.contains(myPosition())) {
            getWalking().webWalk(npcArea);
            return;
        }

        NPC npc = getNpcs().closest(npcName);

        if (npc != null && npc.isVisible()) {
            if(npc.isVisible()){
                npc.interact(ACTION_TALK);
                new ConditionalSleep(10000) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return dialogues.inDialogue();
                    }
                }.sleep();
            }
            else
            {
                getCamera().toEntity(npc);
            }

        }
    }

    public void getPotOfFlour() throws InterruptedException {
        if (!getInventory().contains(ITEM_POT)) {
            fetchGroundItem(ITEM_POT, AREA_LUMBRIDGE_KITCHEN);
            return;
        }

        if (!getInventory().contains(ITEM_WHEAT) && !hopperFilled && !wheatProcessed) {
            interactObject(OBJECT_WHEAT, ACTION_PICK, AREA_WHEAT_FIELD,
                    new ConditionalSleep(10000) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return getInventory().contains(ITEM_WHEAT);
                        }
                    });
            return;
        }

        if (getInventory().contains(ITEM_WHEAT)) {
            interactObject(OBJECT_HOPPER, ACTION_FILL, POSITION_HOPPER,
                    new ConditionalSleep(10000) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return hopperFilled;
                        }
                    });
            return;
        }

        if (hopperFilled) {
            interactObject(OBJECT_HOPPER_CONTROLS, ACTION_OPERATE, POSITION_HOPPER,
                    new ConditionalSleep(10000) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return wheatProcessed;
                        }
                    });
            return;
        }

        if (wheatProcessed) {
            interactObject(OBJECT_FLOUR_BIN, ACTION_EMPTY, AREA_FLOUR_BIN,
                    new ConditionalSleep(10000) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return getInventory().contains(ITEM_POT_FLOUR);
                        }
                    });
            return;
        }
    }

    public void getBucketOfMilk() throws InterruptedException {
        if (!getInventory().contains(ITEM_BUCKET)) {
            fetchGroundItem(ITEM_BUCKET, AREA_FIND_BUCKET);
            return;
        }

        interactObject(OBJECT_COW, ACTION_MILK, AREA_FIND_COW,
                new ConditionalSleep(10000) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return (getInventory().contains(ITEM_BUCKET_MILK));
                    }
                });
    }

    public void interactObject(String objectName,
                               String objectAction,
                               Area objectArea,
                               ConditionalSleep sleep) throws InterruptedException {
        interactObject(objectName, objectAction, objectArea.getRandomPosition(), sleep);
    }

    public void interactObject(String objectName,
                               String objectAction,
                               Position position,
                               ConditionalSleep sleep) throws InterruptedException {
        if (myPosition().distance(position) > 3 || myPosition().getZ() != position.getZ()) {
            getWalking().webWalk(position);
            return;
        }

        RS2Object object = getObjects().closest(objectName);

        if (object != null) {
            if (object.isVisible()) {
                object.interact(objectAction);
                sleep.sleep();
            } else {
                getCamera().toEntity(object);
            }
            return;

        }

    }

    public void fetchGroundItem(String itemName, Area area) throws InterruptedException {
        if (!area.contains(myPosition())) {
            getWalking().webWalk(area);
            return;
        }

        GroundItem groundItem = getGroundItems().closest(itemName);

        if (groundItem != null) {
            if (groundItem.isVisible()) {
                groundItem.interact(ACTION_TAKE);
                new ConditionalSleep(10000) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return (getInventory().contains(itemName));
                    }
                }.sleep();
                return;
            } else {
                getCamera().toEntity(groundItem);
            }

        }

    }

    public void rSleep() throws InterruptedException {
        sleep(baseSleepMs + random(0, 25));
    }


    public final String formatTime(final long ms) {
        long s = ms / 1000, m = s / 60, h = m / 60;
        s %= 60;
        m %= 60;
        h %= 24;
        return String.format("%02d:%02d:%02d", h, m, s);
    }
}

 


This is my first script. I made it for fun.

Potentially I will continue writing scripts. Maybe more quests, maybe something else.

I would appreciate any feedback. I come from a .NET background so my Java is so-so. Also if there are any OSbot best practices I'm not following please let me know.

Thanks

Edited by 737
update script
  • Like 1
Link to comment
Share on other sites

On 4/2/2024 at 10:52 AM, TheCongregation said:

That's really cool, I like how you've adapted it so that it's self sufficient for the quest. 

If you wanna collab i'd be happy to help make more quests with you perhaps something challenging like The Knight's Sword. 

I've updated this on the forum.

I may have interest in collaborating on projects in the future but am currently taking a break. Burnt out at my job. Brain is tired.

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...