Jump to content

[Rate My Code] Runecrafting Slave [Essence Runner]


Recommended Posts

Posted

Hi all!

I'm really proud of the overall outcome of this script, because it really pushed my (very limited) knowledge of Java and scripting. Things that I already know to improve would be to implement a tasking system and potencially adding more to the paint, as right now it only has a simple title and a "Run time".

TL;DR version of the script:

  • You are first prompted to enter the username of the account you will be running the essence to. This identifies all kinds of usernames, including ones with spaces in their names (If you don't add specific code for that it'll bug out when you enter a username with a space in it.)
  • Banks in Falador if you don't have Pure essence
  • Walks to Altar
  • Enters Altar
  • Trades the account and waits for the first trade screen. If the trade screen doesn't appear after 10 seconds it trades again. This is in place in case you're running multiple accounts and are busy trading with another one
  • Offers the essence and accepts twice flawlessly and efficiently. Trading takes a maximum of 3 seconds total
  • Leaves the area and banks for more essence

TL;DR of the TL;DR

  • Username
  • Banks
  • Altar
  • Trades
  • Repeat (Apart from username)

Please leave feedback as I know there is most definitely room for improvement and I'm extremely eager to learn! :)

package core;

import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.constants.Banks;
import org.osbot.rs07.api.model.Player;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;
import org.osbot.rs07.utility.ConditionalSleep;

import Utils.MouseCursor;
import Utils.MouseTrail;

import java.awt.*;
import javax.swing.*;
import javax.swing.JOptionPane;


@ScriptManifest(name = "Essence Runner", version = 1, author = "Marcus", logo = "", info = "Runs essence to the Air Altar")


public class Main extends Script {
		
	private MouseTrail trail = new MouseTrail(0, 255, 255, 2000, this);
	private MouseCursor cursor = new MouseCursor(52, 4, Color.green, this);
    private long startTime = System.currentTimeMillis();
    
    private final Area AirAltar = new Area(2989,3295,2982,3289);
    
	JFrame frame = new JFrame("InputDialog Example #1");
	String pName = JOptionPane.showInputDialog(frame, "What's your player name?");
	String pFinal = pName.replace(' ', '\u00A0');
      
    @Override
    public void onStart() throws InterruptedException {      
      }

    @Override
    public int onLoop() throws InterruptedException {

        if (hasEssense()) {
            walkToAltar();
            enterRuins();
            sendRequest();
            offerEss();
            finalTrade();
        } else if (shouldBank()){
        	exitRuins();
            bank();
        } else {
        }
        return 700;
    }

    
    public boolean hasEssense() {
        return (!getBank().isOpen()) &&
        	   (inventory.contains("Pure essence"));
    }
    
    public boolean shouldBank() {
        return (!inventory.contains("Pure essence"));
    }
    
    private void bank() throws InterruptedException {
        if (!Banks.FALADOR_EAST.contains(myPosition())) {
            getWalking().webWalk(Banks.FALADOR_EAST);
        } else if (Banks.FALADOR_EAST != null && (!getBank().isOpen())) {
            getBank().open();
        } else if (!getInventory().isEmptyExcept("Pure essence")) {
            getBank().depositAllExcept("Pure essence");
        } else if (getBank().contains("Pure essence")) {
            getBank().withdraw("Pure essence", 27);
            sleep(random(2,5));
            getBank().close();
            sleep(random(2,5));
			new ConditionalSleep(2000, 600) {
			    @Override
			    public boolean condition() {
			        return ((!getBank().isOpen()) && (inventory.getAmount("Pure essense") == 27));
			    }
			}.sleep();
        } else {
            getWalking().webWalk(Banks.GRAND_EXCHANGE);
        }
    }
        
	public void walkToAltar() throws InterruptedException	{

		RS2Object Ruins = getObjects().closestThatContains("Mysterious ruins");

			if (!AirAltar.contains(myPosition()))	{
				getWalking().webWalk(AirAltar);
				sleep(random(100, 200));
						}
						new ConditionalSleep(2000, 200) {
						    @Override
						    public boolean condition() {
						        return (Ruins != null && Ruins.isVisible());
						    }
						}.sleep();
					  }
	
	public void enterRuins() throws InterruptedException	{

		RS2Object Ruins = getObjects().closestThatContains("Mysterious ruins");
		RS2Object Altar = getObjects().closestThatContains("Altar");

			if (AirAltar.contains(myPosition()))	{
				Ruins.interact("Enter");
				sleep(random(100, 200));
						}
						new ConditionalSleep(2000, 200) {
						    @Override
						    public boolean condition() {
						        return (Altar != null && Altar.isVisible());
						    }
						}.sleep();
					  }
	
	public void exitRuins() throws InterruptedException	{

		RS2Object Portal = getObjects().closestThatContains("Portal");
		RS2Object Ruins = getObjects().closestThatContains("Mysterious ruins");

			if (Portal != null && Portal.isVisible())	{
				Portal.interact("Use");
				sleep(random(100, 200));
						}
						new ConditionalSleep(2000, 200) {
						    @Override
						    public boolean condition() {
						        return (Ruins != null && Ruins.isVisible());
						    }
						}.sleep();
					  }
	
	public void sendRequest() throws InterruptedException	{

		Player player = getPlayers().closest(pFinal);

		
			if (player != null && player.isVisible()) {
			player.interact("trade with");
			sleep(random(2000, 3000));
			new ConditionalSleep(5000, 500) {
                @Override
                public boolean condition() throws InterruptedException {
                    return getTrade().isCurrentlyTrading();
                }
            }.sleep();
        }
    }
	
	public void offerEss() throws InterruptedException	{

	    if (getTrade().isCurrentlyTrading()) {
	    	getTrade().offerAll("Pure essence");
	    	sleep(random(50, 150));
	    	getTrade().acceptTrade();
	    	new ConditionalSleep(10000, 500) {
	                @Override
	                public boolean condition() throws InterruptedException {
	                    return getTrade().isSecondInterfaceOpen();
	                }
	            }.sleep();
	        }
	    }
	
	public void finalTrade() throws InterruptedException	{

	    if (getTrade().isSecondInterfaceOpen()) {
	    	getTrade().acceptTrade();
	    	sleep(random(50, 150));
	    	new ConditionalSleep(10000, 500) {
	                @Override
	                public boolean condition() throws InterruptedException {
	                    return (!getTrade().isSecondInterfaceOpen() && inventory.isEmpty());
	                }
	            }.sleep();
	        }
	    }
	
	
    @Override
    public void onPaint(Graphics2D g) {

        
        g.setColor(new Color(0, 0, 0, 155));
        g.fillRect(5, 258, 200, 80);
        
        g.setColor(new Color(255, 255, 255));
        g.drawRect(5, 258, 200, 80);
        
		trail.paint(g);
		cursor.paint(g);
		
		
        super.onPaint(g);
        g.drawString("Essence Runner", 65, 275);
        g.drawString("Run time: " +String.valueOf(formatTime(System.currentTimeMillis() - startTime)), 15, 295);

    }

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

Posted
9 minutes ago, TheMcPker said:

I would suggest putting more if statements to make sure you are not skipping actions or doing actions when its not supposed to happen. (in the onloop) 

Doesn't the conditional at the end of the statements cover for the lack of ifs in the loop? Or is it better to do both regardless?

Posted
1 hour ago, Naked said:

I'd say 3/10. It's a really solid start, but logically it needs some work. You want to validate that a function should run before calling it. For example, it doesn't make sense to run finalTrade if you're not trading. 

So same question as I made to TheMcPker then, don't the conditionals do that for me, or is it always best to have it in the functions as well? In my code for example, I always start with an IF, and always end with a condition.

  • If I see the player, send the request. Only until I am trading will I do something else
  • If I am trading, offer the essence, and wait until the 2nd trade screen
  • If I am on the 2nd trade screen, accept again, and wait for the screen not to be there
  • If the screen is not there, move and go bank

Doesn't that cover me for having to add validation on the functions? I've tried starting the script on different stages as well, and it always figures out what it has to do next.

Also, when you say validation for the function, you mean on the onLoop, correct?

 

Here's just a piece of what I'm talking about (having IFs and conditionals on everything):

	public void sendRequest() throws InterruptedException	{

		Player player = getPlayers().closest(pFinal);

		
			if (player != null && player.isVisible()) {
			player.interact("trade with");
			sleep(random(2000, 3000));
			new ConditionalSleep(5000, 500) {
                @Override
                public boolean condition() throws InterruptedException {
                    return getTrade().isCurrentlyTrading();
                }
            }.sleep();
        }
    }
	
	public void offerEss() throws InterruptedException	{

	    if (getTrade().isCurrentlyTrading()) {
	    	getTrade().offerAll("Pure essence");
	    	sleep(random(50, 150));
	    	getTrade().acceptTrade();
	    	new ConditionalSleep(10000, 500) {
	                @Override
	                public boolean condition() throws InterruptedException {
	                    return getTrade().isSecondInterfaceOpen();
	                }
	            }.sleep();
	        }
	    }
	
	public void finalTrade() throws InterruptedException	{

	    if (getTrade().isSecondInterfaceOpen()) {
	    	getTrade().acceptTrade();
	    	sleep(random(50, 150));
	    	new ConditionalSleep(10000, 500) {
	                @Override
	                public boolean condition() throws InterruptedException {
	                    return (!getTrade().isSecondInterfaceOpen() && inventory.isEmpty());
	                }
	            }.sleep();
	        }
	    }

 

Posted
22 minutes ago, Lol_marcus said:

So same question as I made to TheMcPker then, don't the conditionals do that for me, or is it always best to have it in the functions as well? In my code for example, I always start with an IF, and always end with a condition.

  • If I see the player, send the request. Only until I am trading will I do something else
  • If I am trading, offer the essence, and wait until the 2nd trade screen
  • If I am on the 2nd trade screen, accept again, and wait for the screen not to be there
  • If the screen is not there, move and go bank

Doesn't that cover me for having to add validation on the functions? I've tried starting the script on different stages as well, and it always figures out what it has to do next.

Also, when you say validation for the function, you mean on the onLoop, correct?

 

Here's just a piece of what I'm talking about (having IFs and conditionals on everything):

It *works*, but it's bad practice. Here's how I suggest writing it:
 

    private final Position ALTAR_POS = new Position(2985,3293,0);

    JFrame frame = new JFrame("InputDialog Example #1");
    String pName = JOptionPane.showInputDialog(frame, "What's your player name?");
    String pFinal = pName.replace(' ', '\u00A0');


    @Override
    public int onLoop() throws InterruptedException {
        if(getTrade().isCurrentlyTrading()){
            if(getTrade().isSecondInterfaceOpen()){
                if(getTrade().acceptTrade()){
                    Sleep.sleepUntil(() -> !getTrade().isCurrentlyTrading(), 5_000);
                }
            }else{
                if(!getTrade().getOurOffers().contains("Pure essence")){
                    if(getTrade().offerAll("Pure essence")){
                        Sleep.sleepUntil(() -> getTrade().getOurOffers().contains("Pure essence"), 5_000);
                    }
                }else{
                    if(getTrade().acceptTrade()){
                        Sleep.sleepUntil(() -> getTrade().isSecondInterfaceOpen(), 5_000);
                    }
                }
            }
        }else if(getInventory().contains("Pure essence")){
            if(portalExists()){
                sendTradeRequest();
            }else{
                walkToAltar();
            }
        }else{
            if(portalExists()){
                exitRuins();
            }else {
                bank();
            }
        }
        return 250;
    }

    private boolean portalExists(){
        return getObjects().closest("Portal") != null;
    }

    private void bank() throws InterruptedException {
        if (!Banks.FALADOR_EAST.contains(myPosition())) {
            getWalking().webWalk(Banks.FALADOR_EAST);
        } else if (!getBank().isOpen()) {
            if(getBank().open()){
                Sleep.sleepUntil(() -> getBank().isOpen(), 5_000);
            }
        } else if(bank.contains("Pure essence")) {
            if(getBank().withdrawAll("Pure essence")){
                Sleep.sleepUntil(() -> getInventory().contains("Pure essence"), 5_000);
            }
        }else{
            getWalking().webWalk(Banks.GRAND_EXCHANGE);
        }
    }

    public void walkToAltar() throws InterruptedException	{
        RS2Object ruins = getObjects().closest("Mysterious ruins");
        if(ruins != null){
            if(ruins.interact("Enter")){
                Sleep.sleepUntil(() -> portalExists(), 5_000);
            }
        }else{
            getWalking().webWalk(ALTAR_POS.getArea(5));
        }
    }

    public void exitRuins() throws InterruptedException	{
        RS2Object portal = getObjects().closest("Portal");
        if(portal != null){
            if(portal.interact("Use")){
                Sleep.sleepUntil(() -> !portalExists(), 5_000);
            }
        }
    }

    public void sendTradeRequest() throws InterruptedException	{
        Player player = getPlayers().closest(pFinal);
        if (player != null) {
            if(player.interact("Trade with")){
                Sleep.sleepUntil(() -> getTrade().isCurrentlyTrading(), 10_000);
            }
        }
    }

I obviously didn't test this, but it should work. No method gets called without validation. It also removed a bunch of possible bottlenecks (for example, if the player isn't visible in your code, it will just sit there. The interactor will adjust the camera so that it is visible.

  • Like 1
Posted
10 minutes ago, Naked said:

It *works*, but it's bad practice. Here's how I suggest writing it:
 


    private final Position ALTAR_POS = new Position(2985,3293,0);

    JFrame frame = new JFrame("InputDialog Example #1");
    String pName = JOptionPane.showInputDialog(frame, "What's your player name?");
    String pFinal = pName.replace(' ', '\u00A0');


    @Override
    public int onLoop() throws InterruptedException {
        if(getTrade().isCurrentlyTrading()){
            if(getTrade().isSecondInterfaceOpen()){
                if(getTrade().acceptTrade()){
                    Sleep.sleepUntil(() -> !getTrade().isCurrentlyTrading(), 5_000);
                }
            }else{
                if(!getTrade().getOurOffers().contains("Pure essence")){
                    if(getTrade().offerAll("Pure essence")){
                        Sleep.sleepUntil(() -> getTrade().getOurOffers().contains("Pure essence"), 5_000);
                    }
                }else{
                    if(getTrade().acceptTrade()){
                        Sleep.sleepUntil(() -> getTrade().isSecondInterfaceOpen(), 5_000);
                    }
                }
            }
        }else if(getInventory().contains("Pure essence")){
            if(portalExists()){
                sendTradeRequest();
            }else{
                walkToAltar();
            }
        }else{
            if(portalExists()){
                exitRuins();
            }else {
                bank();
            }
        }
        return 250;
    }

    private boolean portalExists(){
        return getObjects().closest("Portal") != null;
    }

    private void bank() throws InterruptedException {
        if (!Banks.FALADOR_EAST.contains(myPosition())) {
            getWalking().webWalk(Banks.FALADOR_EAST);
        } else if (!getBank().isOpen()) {
            if(getBank().open()){
                Sleep.sleepUntil(() -> getBank().isOpen(), 5_000);
            }
        } else if(bank.contains("Pure essence")) {
            if(getBank().withdrawAll("Pure essence")){
                Sleep.sleepUntil(() -> getInventory().contains("Pure essence"), 5_000);
            }
        }else{
            getWalking().webWalk(Banks.GRAND_EXCHANGE);
        }
    }

    public void walkToAltar() throws InterruptedException	{
        RS2Object ruins = getObjects().closest("Mysterious ruins");
        if(ruins != null){
            if(ruins.interact("Enter")){
                Sleep.sleepUntil(() -> portalExists(), 5_000);
            }
        }else{
            getWalking().webWalk(ALTAR_POS.getArea(5));
        }
    }

    public void exitRuins() throws InterruptedException	{
        RS2Object portal = getObjects().closest("Portal");
        if(portal != null){
            if(portal.interact("Use")){
                Sleep.sleepUntil(() -> !portalExists(), 5_000);
            }
        }
    }

    public void sendTradeRequest() throws InterruptedException	{
        Player player = getPlayers().closest(pFinal);
        if (player != null) {
            if(player.interact("Trade with")){
                Sleep.sleepUntil(() -> getTrade().isCurrentlyTrading(), 10_000);
            }
        }
    }

I obviously didn't test this, but it should work. No method gets called without validation. It also removed a bunch of possible bottlenecks (for example, if the player isn't visible in your code, it will just sit there. The interactor will adjust the camera so that it is visible.

Thanks for taking the time to write this. :) 

I'll review and improve from it for sure.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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