Jump to content

First Script Issues, Wont enter Mining State


omni4life

Recommended Posts

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;
            
    }
} 
Link to comment
Share on other sites

 

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
Link to comment
Share on other sites

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. 

Link to comment
Share on other sites


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
  • Like 1
Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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;
}

 

  • Like 1
Link to comment
Share on other sites

 

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
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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. 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
  • Like 1
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...