Jump to content

My first ever script


meganide97

Recommended Posts

Hey just wrote my first ever OSbot script after having studied Java for 2 days with no prior experience whatsoever, just wanted to ask for some feedback. It's a very basic mining script that mines Copper ore and then banks, so far it seems to work. :)

Spoiler

package core;

import java.awt.Graphics2D;

import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.constants.Banks;
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;

@ScriptManifest(author = "You", info = "My first script", name = "Miner", version = 0, logo = "")
public class Miner extends Script {

    @Override
    public void onStart() {
        log("Let's get started!");
    }


    @Override
    public int onLoop() throws InterruptedException {
        RS2Object ore = getObjects().closest(7453);
        Area alkharidmine = new Area(3295, 3308, 3303, 3314);
        if (alkharidmine.contains(myPosition())) {
            if (!ore.isVisible()){
                getCamera().toEntity(ore);
            }
            if (ore != null && !inventory.isFull() && !myPlayer().isAnimating()) {
                log("mining rock");
                ore.interact("Mine");
                new ConditionalSleep(500, 750) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        log("sleeping");
                        return myPlayer().isAnimating();
                    }
                }.sleep();
                if (random(0, 50) >= 43) {
                    log("random camera movement");
                    getCamera().moveYaw(random(0, 360));
                    getCamera().movePitch(random(42, 67));
                }
            } else if (inventory.isFull()) {
                log("Inventory is full and we are walking to bank");
                getWalking().webWalk(Banks.AL_KHARID);
                if (Banks.AL_KHARID.contains(myPosition()) && !getBank().open() && inventory.isFull()) {
                    log("we are in bank and inv is full, opening bank");
                    getBank().open();
                    new ConditionalSleep(500, 2000) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return getBank().isOpen();
                        }
                    }.sleep();
                    }else{
                    log("Depositing Ore and walking back to mine");
                    getBank().deposit("Copper ore", 28);
                    getWalking().webWalk(alkharidmine);
                }
                }
            }
            else {
            log("Not in Al-Kharid mine, Walking there");
                getWalking().webWalk(alkharidmine);
            }
        return random(200, 300);
        }


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

        @Override
        public void onPaint (Graphics2D g){
        }
    }

 

What I want to add next is a GUI that lets the user input what kind of ore & location they want to mine in and bank, and also add paint. However I have no idea whatsoever how to this so I will have to study more before doing this. I also read about dividing the script in multiple classes and using the switch command to make it look cleaner so that I wouldn't have to use so many if statements.

 

Will update you guys on the script as I add new stuff. :)

Edit 1: 

- Cleaned up the code a little bit after reading the feedback.

- Added paint (Total runtime, xp gained, lvls gained, total gp made, gp/hour, ore mined, xp/hr.

- Added some antiban (it now randomly hovers the mining skillicon).

- Changed it to mine iron ore instead.

Picture of the bot running: https://i.gyazo.com/87b8d4cf40e87cb4f054b9825d4eae38.png

Updated code:

Spoiler

package core;

import java.awt.Graphics2D;

import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.constants.Banks;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.input.mouse.RectangleDestination;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;
import org.osbot.rs07.utility.ConditionalSleep;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.text.DecimalFormat;

import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;


@ScriptManifest(author = "You", info = "My first script", name = "Miner", version = 0, logo = "")
public final class Miner extends Script {


    //variables for XP per hour
    private int xpPerHour;
    private int totalXpPerHour;

    //Variables for GP made per hour
    private int gpPerHour;
    private int totalGpPerHour;


    //Variables for TOTAL GP MADE
    private int CostofItem;
    private int ItemsMade;
    private double gpGained;
    private double totalGpGained;


    //Variables for levels gained
    private int beginningLVL;
    private int currentLVL;
    private int LVLSgained;


    // Variables for Xp gained
    private int beginningXP;
    private int currentXp;
    private int xpGained;

    //Paint variable declarations
    private long timeBegan;
    private long timeRan;

    @Override
    public final void onStart(){
        timeBegan = System.currentTimeMillis();
        beginningXP = skills.getExperience(Skill.MINING);
        beginningLVL = skills.getStatic(Skill.MINING);
        CostofItem = 169;
        }


    @Override
    public int onLoop() throws InterruptedException {
        RS2Object ore = getObjects().closest(new Area(3294, 3311, 3296, 3308), 7455, 7488);
        Area alkharidmine = new Area(3295, 3308, 3303, 3314);
        RS2Widget skillicon = getWidgets().get(548,49);
        RS2Widget miningicon = getWidgets().get(320,17);
        RS2Widget inventoryicon = getWidgets().get(548, 58);
        if (ore != null && !inventory.isFull() && !myPlayer().isAnimating() && alkharidmine.contains(myPosition())) {
            log("mining rock");
            ore.interact("Mine");
            new ConditionalSleep(3000, 300) {
                @Override
                public boolean condition() throws InterruptedException {
                    log("sleeping");
                    return myPlayer().isAnimating() || !ore.exists(); //we will stop sleeping before the timeout if
                    // player is animating or if the ore is not longer there (someone mined it)
                }
            }.sleep(); //start sleeping
            ItemsMade += 1;
            if (random(0, 50) >= 46) {
                log("random camera movement");
                getCamera().moveYaw(random(0, 360));
                getCamera().movePitch(random(42, 67));
            }
            if (random(0, 100) >=95 && skillicon != null && miningicon != null && inventoryicon != null){
                log("Clicking skillicon");
                skillicon.interact();
                miningicon.hover();
                new ConditionalSleep(2000, 1000) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return !myPlayer().isAnimating();
                    }
                }.sleep();
                inventoryicon.interact();
                new ConditionalSleep(2000, 1000) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return !myPlayer().isAnimating();
                    }
                }.sleep();
            }
        } else if (inventory.isFull()) {
            log("Inventory is full and we are walking to bank");
            getWalking().webWalk(Banks.AL_KHARID);
            if (Banks.AL_KHARID.contains(myPosition()) && !getBank().open()) {
                log("we are in bank and inv is full, opening bank");
                new ConditionalSleep(3000, 500) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return getBank().isOpen(); //we will stop sleeping when bank is open.
                    }
                }.sleep();
            } else {
                log("Depositing Ore and walking back to mine");
                getBank().depositAll();
                getWalking().webWalk(alkharidmine);
            }
        } else if (!alkharidmine.contains(myPosition())) {
        log("Not in Al-Kharid mine, Walking there");
        getWalking().webWalk(alkharidmine);
    }
        return random(200, 300);
        }


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

        @Override
        public void onPaint (Graphics2D g){
        timeRan = System.currentTimeMillis() - this.timeBegan;
        g.drawString("Time ran: " + ft(timeRan), 13, 245);
        g.drawString("XP Gained: " + xpGained, 13, 260);
            g.drawString("LVLS Gained: " + LVLSgained, 13, 275);
        currentXp = skills.getExperience(Skill.MINING);
        xpGained = currentXp - beginningXP;
        currentLVL = skills.getStatic(Skill.MINING);
        LVLSgained = currentLVL - beginningLVL;
        gpGained = ItemsMade * CostofItem;
        totalGpGained = gpGained / 1000;
        DecimalFormat df = new DecimalFormat("#.#"); //rounds to 1 decimal
        g.drawString("Total gp made: " +df.format(totalGpGained) + " k", 13, 290);
        g.drawString("Ore mined: " + ItemsMade, 13,320);
        gpPerHour = (int)(gpGained / ((System.currentTimeMillis() - timeBegan) / 3600000.0D));
        totalGpPerHour = gpPerHour / 1000;
        g.drawString("GP/hour: " + df.format(totalGpPerHour) + " k/hr", 13, 305);
        xpPerHour = (int)(xpGained / ((System.currentTimeMillis() - timeBegan) / 3600000.0D));
        totalXpPerHour = xpPerHour / 1000;
        g.drawString("XP/hour: " + df.format(xpPerHour) + " XP/hr", 13, 335);
        }

//Time ran formatting to Days:Hours:Seconds
    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;
    }
}

 

 

Future updates: 

- Will add a GUI that will let you choose whether you want to powermine or bank, and also lets you choose which ore to mine that supports more locations and not just the Al-Kharid mine.

- Will have to implement some kind of method that gets the GE prices for different ores to calculate the gp/hour.

- For the powermining part, I want it to use shift-click to drop if possible.

Appreciate further feedback, thanks!

 

Edit 2:

- Script now remembers starting position so you can start it from any mine and it will automatically walk to the closest bank.

- Filtered deposit item to bank everything that ends with ore so skillers can have pickaxe in inventory.

 

Edit 3:

- Added a GUI that lets you choose which ores you want to mine (based on color).

- Cleaned up the code a little bit.

Thanks @Vilius for the help!

 

Edit 4:

- Added a powermining checkbox in GUI that supports shift dropping.

- Script is now finished!!! :-)

 

Code:

Spoiler

package miner;
package miner;

import java.awt.Graphics2D;

import org.osbot.rs07.api.Bank;
import org.osbot.rs07.api.Objects;
import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.map.constants.Banks;
import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.model.Item;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.api.ui.Tab;
import org.osbot.rs07.input.mouse.RectangleDestination;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;
import org.osbot.rs07.utility.ConditionalSleep;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.text.DecimalFormat;

import java.text.DecimalFormat;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


@ScriptManifest(author = "Meganide97", info = "Will mine anything anywhere", name = "AIO Miner", version = 0, logo = "http://jambonium.co.uk/wp-content/uploads/2015/10/mining_icon.png")
public final class main extends Script {

    public boolean powerMine = false;


    //preventing script from running when GUI is open
    Object lock = new Object();

    //telling that gui exists
    private gui gui = new gui();

    //String variable that changes ore id depending on the user input in the GUI.
    public Rock ore = Rock.CLAY;

    //variable banks
    private final Area[] BANKS = { Banks.AL_KHARID, Banks.ARDOUGNE_NORTH, Banks.ARDOUGNE_NORTH, Banks.ARDOUGNE_SOUTH, Banks.CAMELOT, Banks.CANIFIS, Banks.CASTLE_WARS, Banks.CATHERBY, Banks.DRAYNOR, Banks.DUEL_ARENA, Banks.EDGEVILLE, Banks.FALADOR_EAST, Banks.FALADOR_WEST, Banks.GRAND_EXCHANGE, Banks.GNOME_STRONGHOLD, Banks.LUMBRIDGE_UPPER, Banks.VARROCK_EAST, Banks.VARROCK_WEST, Banks.YANILLE };

    //walk to closest bank method
    public void walkToClosestBank(){
        getWalking().webWalk(BANKS);
    }

    //saving startposition
    private Position startPos; //start script in right position
    private Area startArea;

    //Paint variable declarations
    private long timeBegan;
    private long timeRan;
    
    @Override
    public final void onStart() throws InterruptedException{
        gui.run(this); //running gui on start
        synchronized(lock){
            lock.wait();
        }
        log("Starting script");
        timeBegan = System.currentTimeMillis();
        getExperienceTracker().start(Skill.MINING);
        startPos = myPlayer().getPosition();
        startArea = myPlayer().getArea(1);
        log("Your starting position is: " + startPos);
        }

    @Override
    public int onLoop() throws InterruptedException {
        RS2Widget miningicon = getWidgets().get(320, 17);
        if (ore != null && !inventory.isFull() && !myPlayer().isAnimating()) {
            ore.getClosestWithOre(getObjects()).ifPresent(rock -> {
                if (startArea.contains(rock))
                    rock.interact("Mine");
            });
            log("mining " + ore);
            new ConditionalSleep(1000, 300) {
                @Override
                public boolean condition() throws InterruptedException {
                    log("sleeping");
                    return myPlayer().isAnimating() || getDialogues().isPendingContinuation(); //we will stop sleeping before the timeout if
                    // player is animating or if the ore is not longer there (someone mined it)
                }
            }.sleep(); //start sleeping
            if (random(0, 50) > 49) {
                log("random camera movement");
                getCamera().moveYaw(random(0, 360));
                getCamera().movePitch(random(42, 67));
            }
            if (random(0, 100) > 99 && miningicon != null) {
                // if (!getTabs().getOpen().equals(Tab.SKILLS)) {
                if (getTabs().open(Tab.SKILLS)) {
                    log("Clicking skillicon");
                    miningicon.hover();
                    sleep(3500);
                    getTabs().open(Tab.INVENTORY);
                    new ConditionalSleep(2000, 1000) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return myPlayer().isAnimating();
                        }
                    }.sleep();
                }
            }
        } else if (inventory.isFull() && powerMine == false) {
            log("Inventory is full and we are walking to bank");
            walkToClosestBank();
            if (!getBank().open()) {
                log("we are in bank and inv is full, opening bank");
                new ConditionalSleep(3000, 500) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        return getBank().isOpen(); //we will stop sleeping when bank is open.
                    }
                }.sleep();
            } else {
                log("Depositing Ore and walking back to startposition");
                getBank().depositAll(i -> i.getName().endsWith("ore"));
                getBank().depositAll("Clay");
                getBank().depositAll("Coal");
                getWalking().webWalk(startPos);
            }
        } else if ( powerMine == true && inventory.isFull() && !getInventory().isItemSelected() && getTabs().open(Tab.INVENTORY)) {
            log("Dropping " + ore );
            if ( getInventory().dropAll(n -> n.getName().endsWith("ore")) );
            if ( getInventory().dropAll("Clay") );
            if ( getInventory().dropAll("Coal") );
        } else if (getInventory().isItemSelected()) {
            log("deselecting " + ore );
            getInventory().deselectItem();
        }
            return random(200, 300);
        }


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

        @Override
        public void onPaint (Graphics2D g){
            timeRan = System.currentTimeMillis() - this.timeBegan;
            g.drawString("Time ran: " + ft(timeRan), 13, 275);
            g.drawString("XP Gained: " + getExperienceTracker().getGainedXP(Skill.MINING), 13, 290);
            g.drawString("XP/hour: " + getExperienceTracker().getGainedXPPerHour(Skill.MINING) + " XP/hr", 13, 305);
            g.drawString("LVLS Gained: " + getExperienceTracker().getGainedLevels(Skill.MINING), 13, 320);
            g.drawString("Time to Lvl: " + ft(getExperienceTracker().getTimeToLevel(Skill.MINING)), 13 , 335);
        }

        //Time ran formatting to Days:Hours:Seconds
        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 meganide97
Added update.
  • Like 2
Link to comment
Share on other sites

Logic needs to be relooked at and worked on

possible nullpointer before you even check if ore is null

banking is poor logic and can be rewritten. You can see an example here: https://github.com/christophernarciso/programming/blob/master/Meire %26 Brito Automation [OSBot.org]/OSBot Scripting Open Source Projects/Scripts/CAccountEvaluator/src/Evaluator.java#L108

Link to comment
Share on other sites

Not bad for 2 days of study.

 

Here are some specifics:

you can get rid of the second call to getBank().open(), because you already called it once in the if statement, it is redundant

get rid of the inventory.isFull() in the same if statement as above, because you already checked it once, so checking it a second time is redundant

the conditionalSleeps that you are using can be broken, the timeout is longer than the sleep delay check (the constructor is ConditionalSleep(int timeout, int sleepTime))

the indentation at the end is confusing, you should probably clean that up (banking has a lot of issues in general)

you called ore.isVisible() before nullchecking ore, so it could throw a null pointer exception

probably some more that I missed

Link to comment
Share on other sites

9 hours ago, D Bolter said:

Congrats on your first script man. May I ask what guides on osbot helped you learn about the API?

Thanks man! I watched some youtube videos and read tutorials here on the forums as well as read snippets of scripts to get an idea how to type the code.

Chris has a discord as well where he teaches you the basics of coding. Here are some links that were very helpful to me:

 

 

 there is a link to the discord ^ up there.

Also I've just started watching these youtube guides which are very helpful: 

Gl man :D

Edited by meganide97
  • Like 1
Link to comment
Share on other sites

1 hour ago, CJ7 said:

Also, I believe this piece of code:


if (!ore.isVisible()){
                getCamera().toEntity(ore);
            }

aside from the possibility of causing nullpointer exceptions is also unnecassesary, since you're calling "ore.interact" after that. Interact also moves the camera! 

Thanks! Removed that line from the code, also as Chris pointed out I did this command before even nullchecking which was a mistake :)

Link to comment
Share on other sites

6 hours ago, dogetrix said:

Not bad for 2 days of study.

 

Here are some specifics:

you can get rid of the second call to getBank().open(), because you already called it once in the if statement, it is redundant

get rid of the inventory.isFull() in the same if statement as above, because you already checked it once, so checking it a second time is redundant

the conditionalSleeps that you are using can be broken, the timeout is longer than the sleep delay check (the constructor is ConditionalSleep(int timeout, int sleepTime))

the indentation at the end is confusing, you should probably clean that up (banking has a lot of issues in general)

you called ore.isVisible() before nullchecking ore, so it could throw a null pointer exception

probably some more that I missed

Thanks for the feedback! Cleaned the code up a little, but what I don't understand is why I should get rid of the call to getBank().open(), if I remove this line it won't open up the bank.

 

Edit: Just tried what you said and it opened up the bank anyway, does the deposit function also open the bank? I'm kinda confused here as to what command decided to open the bank.

Edited by meganide97
Link to comment
Share on other sites

17 minutes ago, Explv said:

Old accounts I created before, I tried running several clients at once but didn't work and I didn't know it was against the rules to have several accounts, however this is the only account I use now that I'm better informed. You can go ahead and remove those accounts, thanks.

9 hours ago, Chris said:

Logic needs to be relooked at and worked on

possible nullpointer before you even check if ore is null

banking is poor logic and can be rewritten. You can see an example here: https://github.com/christophernarciso/programming/blob/master/Meire %26 Brito Automation [OSBot.org]/OSBot Scripting Open Source Projects/Scripts/CAccountEvaluator/src/Evaluator.java#L108

Thanks for the feedback, have cleaned up the code a little will update soon :)

Link to comment
Share on other sites

@meganide97

The bank will still open because of the statement in the if. in the if statement you have !getBank().open(). The open() method tries to open the bank and returns true or false. This means that the bot will try to open the bank while your code is in the if statement. If the bank opens successfully, it will return true and you won't go to that part of your code again. Therefore calling getBank().open() again inside of the if statement is basically pointless

Link to comment
Share on other sites

2 hours ago, dogetrix said:

@meganide97

The bank will still open because of the statement in the if. in the if statement you have !getBank().open(). The open() method tries to open the bank and returns true or false. This means that the bot will try to open the bank while your code is in the if statement. If the bank opens successfully, it will return true and you won't go to that part of your code again. Therefore calling getBank().open() again inside of the if statement is basically pointless

I see now, thank you!

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