Jump to content

Script Review: Herb Run


hotpoket

Recommended Posts

I started with scripting yesterday, and I was wondering if I could get some feedback on a script I made to see if there are some glaring errors / best practices that I could implement. 

The purpose of the script is to perform a herb run. 

I am aware that this script does not account for dead herbs.

I think the biggest issues are the sleeps, and I implement the while(true) loops and I believe a conditional sleep could be used instead but I haven't been able to implement them.

 

@ScriptManifest(author = "HotPoket", info = "My first script", name = "Herb Running", version = 0, logo = "")
public class Main extends Script {

	private static  Area camelotPatch = new Area(2810,3460,2820, 3470);
	private static Area mortPatch = new Area(3600, 3528, 3605, 3533);
	private static Area ardyPatch = new Area(2668,3376, 2672, 3372);
	private static Area falPatch = new Area(3055, 3313, 3060, 3308);
	private static Area camBank = new Area(2808, 3440, 2810, 3438);
	private static int ardyCloakCharges = 0;
	
	
	
	@Override
	public void onStart() throws InterruptedException {
		
		if (checkSupplies())
		{
			moveToCamelot();
			farmPatch();
			moveToMort();
			farmPatch();
			moveToFal();
			farmPatch();
			moveToArdy();
			farmPatch();
		}
		else
		{
			log("Not enough supplies to perform a herb run");
			stop();
		}
			
	
	}

	@Override
	public int onLoop() throws InterruptedException {		
		
		return random(200, 300);
	}

	@Override
	public void onExit() {
		log("Thanks for running my Tea Thiever!");
	}

	@Override
	public void onPaint(Graphics2D g) {
	}
	
	private boolean checkSupplies() throws InterruptedException
	{
		
	
		if (!getInventory().contains("Rake"))
		{
			log("Rake not found");
			return false;
		}
		if (!getInventory().contains("Seed dibber"))
		{
			log("Seed Dibber Not Found");
			return false;
		}
		if (!getInventory().contains("Spade"))
		{
			log("Spade not found");
			return false;
		}
		
		
		if (getInventory().getAmount("Law rune") < 3 || getInventory().getAmount("Water rune") < 3 && getInventory().getAmount("Air rune") < 8)
		{
			log("Teleport runes not found");
			return false;
		}
		
		if (!getInventory().contains("Ectophial")){
			log("Ectophial not found");
			return false;
		}
		Item [] myItems = getInventory().getItems();
		
		int seedAmount = 0;
		int compostAmount = 0;
		for (Item i : myItems)
		{
			if (i != null && i.getName().contains("seed"))
			{
				seedAmount = i.getAmount();
			}
			if (i!= null && i.getName().contains("post") && !i.isNote())
			{
				compostAmount = (int) getInventory().getAmount(i.getName());
			}
		}
		if (seedAmount < 4)
		{
			log("Seeds not found -- Seed Amount: " + seedAmount);
			return false;
		}
				
				
			return true;
	}
	
	private void noteHerbs() throws InterruptedException
	{
		Item [] myItems = getInventory().getItems();
		for (Item i : myItems)
		{
			
			if (i != null && !i.isNote() && i.getName().contains("Grimy"))
			{
				
				i.interact("Use");
				sleep(2000);
				NPC tl = npcs.closest("Tool Leprechaun");
				tl.interact("Use");
				sleep(2000);
				break;
				
			}
		}
		
	}
	
	private void banking() throws InterruptedException 
	{
		getBank().open();
		long numBuckets = getInventory().getAmount("Bucket");
		if (numBuckets > 0)
		{
			getBank().deposit("Bucket", (int) numBuckets);
		}
		long numCompost = getInventory().getAmount("Ultracompost");
		if (numCompost > 0)
		{
			getBank().depositAll(21483);
		}
		getBank().withdraw(21483, 5);
	}
	
	private void moveToMort() throws InterruptedException 
	{
		getInventory().getItem("Ectophial").interact("Empty");
		sleep(5000);
		walking.webWalk(mortPatch);
	}
	
	private void moveToCamelot() throws InterruptedException
	{
		log("Let's get started!");
		magic.castSpell(Spells.NormalSpells.CAMELOT_TELEPORT);
		sleep(5000);
		
		walking.webWalk(camBank);
		banking();
		walking.webWalk(camelotPatch);

	}
	
	private void moveToArdy() throws InterruptedException 
	{
		log("Moving to Ardy");
		magic.castSpell(Spells.NormalSpells.ARDOUGNE_TELEPORT);
		sleep(5000);
		walking.webWalk(ardyPatch);
	}
	private void moveToFal() throws InterruptedException
	{
		log("Moving to Falador");
		magic.castSpell(Spells.NormalSpells.FALADOR_TELEPORT);
		sleep(5000);
		walking.webWalk(falPatch);
	}
	
	private int whichPatch()
	{
		if (camelotPatch.contains(myPlayer()))
		{
			log("Player is in the CamelotPatch");
			return 8151;
		}
		{
		if	(mortPatch.contains(myPlayer()))
			{
				return 8153;
			}
		if (ardyPatch.contains(myPlayer()))
		{
			log("Player is in the Ardy Patch");
			return 8152;
		}
		if (falPatch.contains(myPlayer()))
		{
			log("Player is in the Falador Patch");
			return 8150;
		}
		
		}
		log("Player is not at a patch -- Closing Script");
		stop();
		return 0;
		
		
	}
	
	private void farmPatch() throws InterruptedException
	{
		
		sleep(6000);
		noteHerbs();
		RS2Object patch = getObjects().closest(whichPatch());
		if (patch != null)
		{
			log("Found patch");
			while (true)
			{
				
				String [] availableActions = patch.getActions();
				if (availableActions[0] != null && availableActions[0].contains("Rake"))
				{
					log("yes");
					
					patch.interact("Rake");
					sleep(10000);
					
				}
				
				
				else
					break;
			}
			
			while (true)
			{
				
				
				String [] availableActions = patch.getActions();
				if (availableActions[0] != null && availableActions[0].contains("Pick"))
				{
					log("yes");
					
					patch.interact("Pick");
					sleep(10000);
					
				}
				
				
				else
					break;
			}
			
			getInventory().dropAll("Weeds");
			sleep(2000);
			patch = getObjects().closest("Herb patch");
			
			Item compost = getInventory().getItem("Ultracompost");
			compost.interact("Use");
			sleep(3000);
			patch.interact("Use");
			sleep(3000);
			Item i = getInventory().getItem("Avantoe seed");
			i.interact("Use");
			sleep(3000);
			patch.interact("Use");
			sleep(3000);
			noteHerbs();
			
			
			
			
		}
	}

	

}

 

Edited by hotpoket
Link to comment
Share on other sites

4 hours ago, hotpoket said:

I started with scripting yesterday, and I was wondering if I could get some feedback on a script I made to see if there are some glaring errors / best practices that I could implement.

Nice first script! some tips though from personal experience:

If you want to do the script the way you have done it, look into this: 

Having a condition check whether a process can be done could help if the script skips one of the functions/tasks you have created, also splitting up each task for small scripts makes them easier to manage

And instead of static sleep times, use conditional sleep 

This just makes your script run better and seem more human like (not to be confused with antiban) 

There are a lot more things you can do but someone else could chip in at some point with more help! A lot of this stuff, you just learn from experience, but so far, you got the basic logic down :)

 

 

  • Like 1
Link to comment
Share on other sites

Hello HotPoket,

I Think its good start. I like the script. As you make more bots your code will get better and you'll learn the Api. 

Things I see

  1. I thinks a bad pratic to do everthing is start. Things like gui , walk to a bank , step up classes and values should go here.
  2. A non looping structure.
  3. Duplicate code.
  4. Things that the api can do but you will learn as you make more bots. Example checkSupplies method.
  5. Error in the amount of runes needed I think you need 4 laws not 3.
  6. conditionsleep Like what Protoprize said.

1. will be fixed by 2. 

2.  The best bots in my opinion are ones that have if else tree that clearly defines were you are in script for something like framing it would be a little harder. But when you get that logic down the bots are bullet proof.  They can be start and stoped any were in the script and finsh the task. 

I think the loop would start like 

if bot-has-items
	if !bot-near-patch || patch-has-herb
          move-to-next // you can find out were you are at in the scrpit by amount of runes buckets of compost left
      else
          farmpatch
else
	get-items

Example my post in with a flax spiner

3. See the code fixes I post.[tpAndMoveToArea]

4.See the code fixes I post. [ checkSupplies, noteHerbs]

5. Just something I saw

Fixes I would make :

package com.bacon.AIO.paint;

import com.bacon.AIO.util.Sleep;
import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.model.Item;
import org.osbot.rs07.api.model.NPC;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.MagicSpell;
import org.osbot.rs07.api.ui.Spells;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

import java.awt.*;

@ScriptManifest(author = "HotPoket", info = "My first script", name = "Herb Running", version = 0, logo = "")
public class Main extends Script {

    private static final Area camelotPatch = new Area(2810, 3460, 2820, 3470);
    private static final Area mortPatch = new Area(3600, 3528, 3605, 3533);
    private static final Area ardyPatch = new Area(2668, 3376, 2672, 3372);
    private static final Area falPatch = new Area(3055, 3313, 3060, 3308);
    private static final Area camBank = new Area(2808, 3440, 2810, 3438);


    @Override
    public void onStart() throws InterruptedException {

		gui maybe?

    }

    @Override
    public int onLoop() throws InterruptedException {
 /*       if (checkSupplies()) {
            moveToCamelot();
            farmPatch();
            moveToMort();
            farmPatch();
            tpAndMoveToArea(Spells.NormalSpells.FALADOR_TELEPORT, falPatch);
            farmPatch();
            tpAndMoveToArea(Spells.NormalSpells.ARDOUGNE_TELEPORT, ardyPatch);
            farmPatch();
        } else {
            log("Not enough supplies to perform a herb run");
            stop();
        }
*/
        This neeeds some looping structure

        if bot-has-items
            if !bot-near-patch || patch-has-herb
                  move-to-next
             else
                  farmpatch
        else
             get-items

        return random(500, 1200);
    }

    private boolean checkSupplies() throws InterruptedException {
        String[] items = new String[]{"Rake", "Seed dibber", "Spade", "Ectophial"};
        String[] runes = new String[]{"Law rune", "Water rune", "Air rune"};

        for (String item : items) {
            if (!getInventory().contains(item)) {
                log(item + " not found");
                return false;
            }
        }

        for (String rune : runes) {
            if (getInventory().getAmount(rune) < 10) {
                log(rune + " not found");
                return false;
            }
        }
        long seedAmount = getInventory().getAmount((x) -> x.getName().contains("seed"));
        long compostAmount = getInventory().getAmount((x) -> x.getName().contains("post"));
        if (seedAmount < 4/* && compostAmount < 4*/) {
            log("Seed or Compost fail" + seedAmount);
            return false;
        }
        return true;
    }

    private void noteHerbs() throws InterruptedException {
        Item myItem = getInventory().getItem((x) -> x.nameContains("Grimy") && !x.isNote());

        myItem.interact("Use");
        if (getInventory().isItemSelected()) {
            NPC tl = npcs.closest("Tool Leprechaun");
            tl.interact("Use");
            Sleep.sleepUntil(() -> !myPlayer().isMoving(), 5000);
        }
    }

    private void banking() throws InterruptedException {
        if (getBank().open()) {
            getBank().depositAll("Bucket");
            getBank().depositAll(21483);
            getBank().withdraw(21483, 5);
        }
    }

    private void moveToMort() throws InterruptedException {
        Position myspot = myPlayer().getPosition();
        getInventory().getItem("Ectophial").interact("Empty");
        Sleep.sleepUntil(() -> !myPlayer().getPosition().equals(myspot), 5000);
        walking.webWalk(mortPatch);
    }

    private void moveToCamelot() throws InterruptedException {
        log("Let's get started!");
        tpAndMoveToArea(Spells.NormalSpells.CAMELOT_TELEPORT,camBank);
        banking();
        walking.webWalk(camelotPatch);
    }

    private void tpAndMoveToArea(MagicSpell spell, Area area) throws InterruptedException {
        Position myspot = myPlayer().getPosition();
        magic.castSpell(spell);
        Sleep.sleepUntil(() -> !myPlayer().getPosition().equals(myspot), 5000);
        walking.webWalk(area);
    }

    private void farmPatch() throws InterruptedException
    {
      if (getInventory().contains((x) -> x.nameContains("Grimy") && !x.isNote())){
          noteHerbs();
      }else {
          RS2Object patch = getObjects().closest(8150,8151,8152,8153);
          if (patch needs to be raked){
              rake
          }else if(inventory has weeds){
              drop weeds
          }else if(patch can be picked){
             pick patch
          }else if(patch is empty and has no weeds and no compost){
             use compost
          }else {
              use use seed
          }

      }

    }

}

 

 

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