Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

First Script Issues, Wont enter Mining State

Featured Replies

Hey guys,

 

I'm just toying around with OSBot's API and Java in general trying to get a feel for everything. I don't have a huge amount of experience coding, only in MATLAB. I wrote this script last night with the help of Apaec's tutorial, however, it won't interact with the rocks. It drops perfectly fine, it just won't mine. On the paint, it is almost always on the "dropping" status until I manually override and mine, at which point it changes to "sleeping" as opposed to mining.
 

All in all, I'm very confused and I'd love a second set of eyes to help my chase down my problem smile.png

Sincerely,

 

-Omni.

import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

import java.awt.*;
import java.util.concurrent.TimeUnit;

@ScriptManifest(author = "Omni", info = "Iron Powerminer", name = "Omni Miner", version = 1.0, logo = "")

public class OmniMiner extends Script {

	private int [] targetRock = {13458, 13456};
	private int oreMined = 0;
	private long timeBegan;
    private long timeRan;
    
    // DEBUG STATUS
    
    public static String status;
    
    // Paint Variables
	private final Color color1 = new Color(0, 102, 102);
	private final Color color2 = new Color(0, 0, 0);
	private final BasicStroke stroke1 = new BasicStroke(1);
	private final Font font1 = new Font("Arial", 1, 14);
	private final Font font2 = new Font("Arial", 1, 10);
	
	@Override
	public void onStart() {
		log("Omni Miner has begun. Please report any bugs to me via the forums");
		status = "script starting";
        timeBegan = System.currentTimeMillis();
	}

	private enum State {
		MINE, DROP, SLEEP
	};

	private State getState() {
		Entity rock = objects.closest(targetRock);
		// Dropping state
		if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269))
			return State.DROP;
		// Check if mining already
		if (myPlayer().isAnimating())
			return State.SLEEP;
				// Mining State
		if (rock != null && !myPlayer().isAnimating())
			return State.MINE;
			return State.SLEEP;

	}

	@Override
	public int onLoop() throws InterruptedException {
		switch (getState()) {
		case MINE:
			Entity rock = objects.closest(targetRock);
			if (!inventory.isEmpty() && !myPlayer().isAnimating()) {
				rock.interact("Mine");
			status = "Mining";
			}
			break;
		case DROP:
			inventory.dropAllExcept(1265, 1269);
			status = "Dropping";
			sleep(random(200,300));
			break;
		case SLEEP:
			sleep(random(200, 300));
			status = "Sleeping";
			break;
		}
		return random(200, 300);
	}

	@Override
	public void onExit() {
		log("Thanks for running Omni Miner.");
	}

	@Override
	public void onPaint(Graphics2D g) {
	    timeRan = System.currentTimeMillis() - this.timeBegan;
        g.setColor(color1);
        g.fillRect(7, 458, 325, 16);
        g.setColor(color2);
        g.setStroke(stroke1);
        g.drawRect(7, 458, 325, 16);
        g.setColor(color1);
        g.fillRect(325, 345, 170, 129);
        g.setColor(color2);
        g.drawRect(325, 345, 170, 129);
        g.setFont(font1);
        g.drawString("Omni Miner V 1.01" , 329, 362);
        g.setFont(font2);
        g.drawString("Time Running: " + ft(timeRan), 329, 375);
        g.setFont(font2);
        g.drawString("Experience Gained:", 329, 387);
        g.setFont(font2);
        g.drawString("Ores mined: ", 329, 399);
        g.setFont(font2);
        g.drawString("Status: " + status, 329, 411);

	}

    private String ft(long duration) {
    	
            String res = "";
            long days = TimeUnit.MILLISECONDS.toDays(duration);
            long hours = TimeUnit.MILLISECONDS.toHours(duration) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
            long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
            long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
            if (days == 0)
            {
                    res = (hours + ":" + minutes + ":" + seconds);
            }
            else
            {
                    res = (days + ":" + hours + ":" + minutes + ":" + seconds);
            }
            return res;
            
    }
} 

 

Hey guys,

 

I'm just toying around with OSBot's API and Java in general trying to get a feel for everything. I don't have a huge amount of experience coding, only in MATLAB. I wrote this script last night with the help of Apaec's tutorial, however, it won't interact with the rocks. It drops perfectly fine, it just won't mine. On the paint, it is almost always on the "dropping" status until I manually override and mine, at which point it changes to "sleeping" as opposed to mining.

 

All in all, I'm very confused and I'd love a second set of eyes to help my chase down my problem smile.png

Sincerely,

 

-Omni.

 

instead of 

!inventory.isEmptyExcept(1269)

use

inventory.isFull()

And for

if (rock != null && !myPlayer().isAnimating())
			return State.MINE;
			return State.SLEEP;

You cant return two states at once.  Just use MINE in that one

 

Add sleep in case MINE if its spamclicking

 

Edited by RickyD

  • Author

instead of 

!inventory.isEmptyExcept(1269)

use

inventory.isFull()

And for

if (rock != null && !myPlayer().isAnimating())
			return State.MINE;
			return State.SLEEP;

You cant return two states at once.  Just use MINE in that one

 

Add sleep in case MINE if its spamclicking

I really appreciate you taking the time to help me. I made the changes you suggested, however, the Mine case still isn't running for whatever reason. I don't suppose you have any other ideas? If not, thanks for all your help anyway.

 

My getState is now:

	private State getState() {
		Entity rock = objects.closest(targetRock);
		// Dropping state
		if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269))
			return State.DROP;
		// Check if mining already
		if (myPlayer().isAnimating())
			return State.SLEEP;
				// Mining State
		if (rock != null && !myPlayer().isAnimating())
			return State.MINE;
		else 
			return State.SLEEP;
	}

I put an else return State.Sleep in there because it was throwing me an error telling me it wanted a return null after return State.Mine without it. 


private State getState() {

Entity rock = objects.closest(targetRock);

// Dropping state

if(inventory.isFull()){

return State.DROP;

}else{

if(myPlayer().isAnimating()){

return State.SLEEP;

}else{

if(rock != null){

return State.MINE;

}else{

return State.SLEEP;

}

}

}

}

Edited by RickyD

  • Author
private State getState() {
		Entity rock = objects.closest(targetRock);
		// Dropping state
		 
	 if(inventory.isFull()){
		 return State.DROP;
	 }else{
		 if(myPlayer().isAnimating()){
			 return State.SLEEP;
		 }else{
			 if(rock != null){
				return State.MINE;
			 }else{
				 return State.SLEEP;
			 }
		 }
	 }
	}

That fixed it up perfectly, thank you very much. I'll keep toying around with it to get it perfect but I really appreciate the help :)

  • Author

The inventory doesn't always have to be full to drop

On that note, if I change the dropping method from is.Full to .isEmptyExcept, the script breaks again. It gets stuck in the 'dropping' status and doesn't mine still. Even when I change it to is.Full, it mines a full inventory successfully and drops the full load, but then doesn't resume.

 

Also, one (hopefully) last question for anyone reading: Is there a limit radius command in OSBot? I'm mining in the middle of two rocks and I want it to wait if those two are exhausted until they respawn. Instead, it runs off to a very nearby rock, but it takes longer than waiting. Is there a command similar to "Entity rock = objects.closest" that is sort of a "Entity rock = objects.within2tiles"

 

Do you have any advise about that? I honestly can't see where I've gone wrong. This is my updated code.

import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

import java.awt.*;
import java.util.concurrent.TimeUnit;

@ScriptManifest(author = "Omni", info = "Iron Powerminer", name = "Omni Miner", version = 1.0, logo = "")

public class OmniMiner extends Script {

	private int [] targetRock = {13710};
    private long timeBegan;
    private long timeRan;
    private int xpGained;
    private int xpPerHour;
    private int currentXP;
    private int currentLevel;
    private int beginningXP;
    private double nextLevelXP;
    private long timeTNL;
    private double xpTillNextLevel;
    private int OreMined = 0;
    
    final int[] XP_TABLE = {
                0, 0, 83, 174, 276, 388, 512, 650, 801, 969, 1154,
        1358, 1584, 1833, 2107, 2411, 2746, 3115, 3523, 3973, 4470, 5018,
        5624, 6291, 7028, 7842, 8740, 9730, 10824, 12031, 13363, 14833,
        16456, 18247, 20224, 22406, 24815, 27473, 30408, 33648, 37224,
        41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014, 91721,
        101333, 111945, 123660, 136594, 150872, 166636, 184040, 203254,
        224466, 247886, 273742, 302288, 333804, 368599, 407015, 449428,
        496254, 547953, 605032, 668051, 737627, 814445, 899257, 992895,
        1096278, 1210421, 1336443, 1475581, 1629200, 1798808, 1986068,
        2192818, 2421087, 2673114, 2951373, 3258594, 3597792, 3972294,
        4385776, 4842295, 5346332, 5902831, 6517253, 7195629, 7944614,
        8771558, 9684577, 10692629, 11805606, 13034431, 200000000
        };
    
    // DEBUG STATUS
    
    public static String status;
    
    // Paint Variables
	private final Color color1 = new Color(0, 102, 102);
	private final Color color2 = new Color(0, 0, 0);
	private final BasicStroke stroke1 = new BasicStroke(1);
	private final Font font1 = new Font("Arial", 1, 14);
	private final Font font2 = new Font("Arial", 1, 10);
	
	@Override
	public void onStart() {
		log("Omni Miner has begun. Please report any bugs to me via the forums");
		status = "script starting";
        timeBegan = System.currentTimeMillis();
        beginningXP = skills.getExperience(Skill.MINING);
        timeTNL = 0;
	}

	private enum State {
		MINE, DROP, SLEEP
	};

	private State getState() {
		Entity rock = objects.closest(targetRock);
		// Dropping state
	 if(!inventory.isEmptyExcept(1269)){
		 return State.DROP;
	 }else{
		 if(myPlayer().isAnimating()){
			 return State.SLEEP;
		 }else{
			 if(rock != null){
				return State.MINE;
			 }else{
				 return State.SLEEP;
			 }
		 }
	 }
	}
	@Override
	public int onLoop() throws InterruptedException {
		switch (getState()) {
		case MINE:
			Entity rock = objects.closest(targetRock);
			if ((!inventory.isEmpty()) && !myPlayer().isAnimating()) {
				rock.interact("Mine");
			status = "Mining";
			sleep(random(4000,4500));
			}
			break;
		case DROP:
			inventory.dropAllExcept(1265, 1269);
			status = "Dropping";
			sleep(random(200,300));
			break;
		case SLEEP:
			sleep(random(200, 300));
			status = "Sleeping";
			break;
		}
		return random(200, 300);
	}

	@Override
	public void onExit() {
		log("Thanks for running Omni Miner.");
	}
	
	@Override
	public void onPaint(Graphics2D g) {
		currentXP = skills.getExperience(Skill.MINING);
        currentLevel = skills.getStatic(Skill.MINING);
		xpGained = currentXP - beginningXP; 
        xpPerHour = (int)( xpGained / ((System.currentTimeMillis() - this.timeBegan) / 3600000.0D));
        nextLevelXP = XP_TABLE[currentLevel + 1];
        xpTillNextLevel = nextLevelXP - currentXP;
        OreMined = xpGained / 35;
        if (xpGained >= 1)
        {
                timeTNL = (long) ((xpTillNextLevel / xpPerHour) * 3600000);
        }
	    timeRan = System.currentTimeMillis() - this.timeBegan;
        g.setColor(color1);
        g.fillRect(7, 458, 325, 16);
        g.setColor(color2);
        g.setStroke(stroke1);
        g.drawRect(7, 458, 325, 16);
        g.setColor(color1);
        g.fillRect(325, 345, 170, 129);
        g.setColor(color2);
        g.drawRect(325, 345, 170, 129);
        g.setFont(font1);
        g.drawString("Omni Miner V 1.0" , 329, 362);
        g.setFont(font2);
        g.drawString("Time Running: " + ft(timeRan), 329, 375);
        g.setFont(font2);
        g.drawString("Experience Gained: " + xpGained, 329, 387);
        g.setFont(font2);
        g.drawString("TTL: " + ft(timeTNL), 329,399);
        g.setFont(font2);
        g.drawString("Ores mined: " + OreMined, 329, 411);
        g.setFont(font2);
        g.drawString("Status: " + status, 329, 423);

	}

    private String ft(long duration) {
    	
            String res = "";
            long days = TimeUnit.MILLISECONDS.toDays(duration);
            long hours = TimeUnit.MILLISECONDS.toHours(duration) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
            long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
            long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
            if (days == 0)
            {
                    res = (hours + ":" + minutes + ":" + seconds);
            }
            else
            {
                    res = (days + ":" + hours + ":" + minutes + ":" + seconds);
            }
            return res;
            
    }
} 

Edited by omni4life

Rather than manually typing out the experience table, you can use the formula Jagex uses to calculate it dynamically.
 
Here's a little snippit if you want to use it in the future:
public static int[] createTable(int level) {
    int[] table = new int[level];
    for(int i=1, b=0; i < level; b += i + 300 * Math.pow(2, i / 7d), table[i] = i == 99? 200000000 : b/4, i++); 
    return table;
}

 

  • Author

 

Rather than manually typing out the experience table, you can use the formula Jagex uses to calculate it dynamically.
 
Here's a little snippit if you want to use it in the future:
public static int[] createTable(int level) {
    int[] table = new int[level];
    for(int i=1, b=0; i < level; b += i + 300 * Math.pow(2, i / 7d), table[i] = i == 99? 200000000 : b/4, i++); 
    return table;
}

 

Thanks heaps, I'll use that to neaten it up smile.png. I don't suppose you have any ideas regarding why it isn't executing properly? Sometimes it also gets stuck on 'starting script' status and doesn't proceed until I manually mine an ore at which point, it stops mining and is stuck in the 'dropping' state.

 

The strange thing is, I think it may be tied to my paint. Prior to its addition, it actually all worked okay so perhaps I inadvertently tweaked something.

Edited by omni4life

private State getState() {
		Entity rock = objects.closest(targetRock);
		// Dropping state
		 
	 if(inventory.isFull()){
		 return State.DROP;
	 }else{
		 if(myPlayer().isAnimating()){
			 return State.SLEEP;
		 }else{
			 if(rock != null){
				return State.MINE;
			 }else{
				 return State.SLEEP;
			 }
		 }
	 }
	}

 

You could also return State.DROP when there aren't any rocks available.

  • Author

You could also return State.DROP when there aren't any rocks available.

I'd actually quite like to implement that, is there a way to limit the Entity = objects.clostest and set it within a limit of two tiles. I found in the API Entity Area(int x1, int y1, int x2, int y2), would I utilise that and set a square that contains the two rocks that I want to target? I'm not totally sure how to utilise it so I'd love any input anyone has. 

I'd actually quite like to implement that, is there a way to limit the Entity = objects.clostest and set it within a limit of two tiles. I found in the API Entity Area(int x1, int y1, int x2, int y2), would I utilise that and set a square that contains the two rocks that I want to target? I'm not totally sure how to utilise it so I'd love any input anyone has. 

 

I saw you use object.closest but I think the correct way is to do getObjects().closest.

 

You can also use the Objects object to find the rocks in an area with this.

getObjects().closest(new Area(x1, y1, x2, y2), ids);

You could also just use .closest like you already do and check if the distance is more than the maximum that you want.

 

Edit:

Same for inventory, use getInventory().

 

I would also recommend to always use brackets with your if statements.

	private State getState() {
		Entity rock = objects.closest(targetRock);
		// Dropping state
		if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269)) {
			return State.DROP;
		}
		// Check if mining already
		if (myPlayer().isAnimating()) {
			return State.SLEEP;
		}
		// Mining State
		if (rock != null && !myPlayer().isAnimating()) {
			return State.MINE;
		}
		
		return State.SLEEP;
	}

Edited by Merccy

  • Author

I saw you use object.closest but I think the correct way is to do getObjects().closest.

You can also use the Objects object to find the rocks in an area with this.

getObjects().closest(new Area(x1, y1, x2, y2), ids);
You could also just use .closest like you already do and check if the distance is more than the maximum that you want.

Edit:

Same for inventory, use getInventory().

I would also recommend to always use brackets with your if statements.

private State getState() {		Entity rock = objects.closest(targetRock);		// Dropping state		if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269)) {			return State.DROP;		}		// Check if mining already		if (myPlayer().isAnimating()) {			return State.SLEEP;		}		// Mining State		if (rock != null && !myPlayer().isAnimating()) {			return State.MINE;		}				return State.SLEEP;	}

I'll definitely toy around with that and your dropping during null ore idea tomorrow when I get home. I really appreciate you and everyone else taking the time to answer simple questions for me, it's hugely helpful in wrapping my head around Java and the api

I'd actually quite like to implement that, is there a way to limit the Entity = objects.clostest and set it within a limit of two tiles. I found in the API Entity Area(int x1, int y1, int x2, int y2), would I utilise that and set a square that contains the two rocks that I want to target? I'm not totally sure how to utilise it so I'd love any input anyone has. 

 

 

in onLoop you could do something like:

Position myPosition = new Position(myPlayer().getPosition());

Area myRadius = new Area(new Position(myPosition.getX()+2, myPosition.getY()+2,0), new Position(myPosition.getX()-2, myPosition.getY()-2,0));

the "myRadius" creates a square radius around you.  I'm not sure how a mining script works so you have to figure out where you'd want to logically ask if a there are only null rocks in "myRadius"   

if(myRadius.contains(NULLROCK.getPosition)){
   //all the rocks here are NULL, dropping inventory...
}

Edited by RickyD

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.