Jump to content

[Rate My Code] Runecrafting Slave [Essence Runner]


Lol_marcus

Recommended Posts

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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

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.

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