RSGoldMine RuneScape Gold RuneScapeGoldMarkt RuneScape Gold OSRS Gold Probemas RuneChat RuneScape Games to win Coins and Gold
Sign in to follow this  
Chris

Tutorial 4 (Four) - Converting to "Task Script", and adding a paint

Recommended Posts

Chris   

Converting to "Task Script", and adding a paint

 

You’ve just got your first script set up, well done! I have had some comments saying that the previous script had problems and was attacking whilst it was already fighting, that’s ok. This is just a tutorial and we will address things like this as we go on. I will cover that at the end of this tutorial.

 

In this tutorial we are going to cover converting our script to “Task Script”. Creating a Task script helps you modular

 

Step One - Converting to “Task Script”

So, “Task Script” is a way of breaking the scripts logic down into tasks. For example, we might have a task that handles fighting, and one that handles healing. Or Fighting, and banking. You can put this in one class and just use a lot of if/else statements but you’ll end up with lots of lines and if you get a bug you’ll be lost for where to look. Additionally, when we get good at scripting our banking class for example may be so generalised that it would work with all of our scripts - so we could then re-use our banking class in another script rather than rewriting it everytime we create a new script.

 

Sadly, the first thing to do is to copy/paste some code. Below is the class for “Task”. Please create a new java class within the “tutorial” package, and name this Task. Once you have done that, follow the link below and copy this code into the class.

 

https://gist.github.com/ChrisBPB/51dee268f7e7ae10b6174fa2f1270f46

 

See image for reference: https://i.imgur.com/wX8HOMt.png

 

In the image above please read the following:

  1. Arrow labeled 1 is pointing to us extending a class named ClientAccessor. This class, as the name suggests, is a class that will allow us to Access Client methods. As you remember from a previous tutorial, when we extend something we essentially copy its template and have to copy its methods too. In this example we only have to copy the constructor. In this example the constructor is the method named Task(ClientContext ctx). The constructor is essentially the method we call when we want to create an object of that class type. So if we want to create a Task, we have to call that constructor. The constructor is requiring us to pass ctx, and as we learnt - ctx gives us access to all the useful methods we need.
  2. Arrow labeled 2 is pointing to our ctx parameter in the constructor however we covered that in the paragraph above.
  3. Arrow 3 is pointing to our method titled activate(), this will determine what activates this object. This essentially is our if statement.
  4. Arrow 4 is pointing to execute. If the activate condition completes (returns true) then our execute will be executed, so this is where the majority of our code goes.

 

We can not close that class, we do not need to look at it again.

 

 

Please now create a new class called Fight, again in the tutorial package. This class is going to be a Task to handle our fighting. As such, we need to use our Task class as a template, we do this by extending it. Please extend Task. You may notice as you did that it did not generate any import statement, this is because Task is in the same package, so it already knows where it is.

 

See image for reference: https://i.imgur.com/k8Ks2H5.png

 

Now, we see errors. This is because our Task class has 3 methods that we have not copied yet, remember? Click on the error and press alt+enter to fix it. We need to “implement the methods” and then we need to do that again as we need to “create a constructor”.

 

See images for reference: https://i.imgur.com/X5vddNQ.png https://i.imgur.com/SzUhQrt.png https://i.imgur.com/XdD8sDI.png

 

 

Awesome. So now, we want to activate this when we want to fight, but we already have our code for this from our previous tutorial.

 

See image for reference: https://i.imgur.com/pkAraZc.png

 

So, we want to check if our health bar is not visible, and that our health is over 35%. We already have the code, but it’s in 2 lines. If we refer back to the last tutorial, we can remember than AND is written as &&, and join these together. It’s as simple as that!

 

See image for reference: https://i.imgur.com/ncl03V9.png

 

Now, we need to copy the code relevant to actually fighting over so our execute() method can cause us to fight.

 

See image for reference: https://i.imgur.com/drGkl53.png

 

So after copying the above across you should end up with a Fight class that looks like this:

 

See image for reference: https://i.imgur.com/TfqPa3d.png

 

 

Hopefully you are following along, there is not much I can really explain here as we already wrote this together and went through it in the last tutorial. We are just moving it over to a new class.

 

So our activate has became our if, and our execute has became our code to find and attack a cow. We can now delete all of our code inside poll() from our CowKiller class.

 

See image for reference: https://i.imgur.com/L0LnKuA.png

 

But we aren’t done yet! We have our task, and we have our script class, but they aren’t linked. There is no reference to Task or Fight within our CowKiller.java file. This is because we need to tell it how to use Tasks.

 

So, the idea is that we want to split our script up into as many tasks as possible, at the moment we only have Fight, but let’s just imagine we have Fight and Bank. It knows when to activate, and it knows what to do when it activates, so all we have to do is actually check if it’s activate or not. To do this we must create a List of our Tasks, we do this where we put our Cow IDs earlier, it goes here because we need access to this constantly, not just at the start.

 

We are going to use an ArrayList, which is a datatype that holds multiple other data types. We previously covered Arrays, which are basically very simply ArrayLists. So to create an ArrayList what we do is the same as any other data type, we do ArrayList tasks = new ArrayList(). However we much specify what the ArrayList will be holding (Task), we do this with diamonds. So it becomes ArrayList<Task> tasks = new ArrayList<Task>(); If you typed this out fully without using an import suggestion you will now need to click alt+enter on ArrayList to fix the error.

 

See image for reference: https://i.imgur.com/MW1iPhT.png

 

So, we discussed briefly earlier the different between an Object and a Class. An object is something that was created from a class, and this is what we have to do with out Fight class, as it is actually useless as a class but not as an object.

 

To do this, within our start() method we must create a new variable of type Fight named fight, if you remember we also must past ctx to its constructor - the constructor is the method called when we create this object.

 

See image for reference: https://i.imgur.com/AqDb48m.png

 

Now, we need to add this fight task to our list, this is as simple as tasks.add(fight);. This add() method is provided to us automatically by the ArrayList, which is one of the many advantages it has over a simple array.

 

See image for reference: https://i.imgur.com/8ibxDqC.png

 

If our banking task was ready we would also add that below, but it isn’t. So our list of tasks is ready! Within our poll() now (poll remember is the meat of our script, it’s where everything happens). We need to check every task in our list, and see if it’s activated or not. To do this, we use a “loop”. A loop is just something that repeats itself. We will be using a for loop, this may look complicated but it isn’t.

 

See image for reference: https://i.imgur.com/5gGvQxT.png

 

If the above was written in plain English, it would read as follows: “for every task, give me a copy of it called t”. So now we can just see is t is activate, and if so .. execute!

 

See image for reference: https://i.imgur.com/le5a5Ml.png

 

You have now finished creating your “Task Script”, you can add whatever tasks you want so easily.

 

 

Step 2 - Creating a Paint

Honestly, another relatively simple task with little coding. RSBot creates a Paint class for us, called PaintListener. All we have to do is .. implement it! You may be thinking, ok so we extend PaintListener. Actually, this is not correct. We do literally implement it, as below:

 

See image for reference: https://i.imgur.com/wcqVykc.png

 

This will cause an error that we fix with alt+enter

 

See image for reference: https://i.imgur.com/68b1Uqt.png

 

And this will finally generate the following method

 

See image for reference: https://i.imgur.com/CxG8XRo.png

 

In Java we will be drawing onto our screen using basic shapes, lines, and text. It is drawn in the order you write them out, so if you draw a black box and a smaller red box, the red box is on top. But if you draw a small red box and then a big black box - you won’t see the red as it is under the black one. To draw a shape we do the following steps

  1. Step the colour to draw in
  2. Tell it where to draw
  3. Tell it how big to draw

 

To draw a black rectangle would look like this

g.setColor(new Color(0, 0, 0, 180));
g.fillRect(0, 0, 150, 100);

 

This sets the colour to black (RGB) the 180 is A (rgba) which is alpha for transparency. 255 is solid, 0 is invisible. Then it says fillRect() (draw a coloured in rectangle) at 0,0 with a size os 150x100px.

 

How do we know where and how big to draw, you ask? To figure this out we head over to RSBot, and click View->Mouse Position.

 

See image for reference: https://i.imgur.com/22Uwyhm.png 

 

This will draw (in green) our mouse coordinates at the top left of our screen.

 

See image for reference: https://i.imgur.com/LYOVtvb.png 

 

So, move the mouse to the top left of where you want to draw (0,0 is the top left corner of the game screen) and then take a note of the coordinates. I want to draw at the top left so I note 0,0. I now move the mouse to where I want the top right corner to be, for me this is 100 across. I then repeat for where I want the bottom left corner to be, for me this is 150 down. So, I begin at 0,0 and move 100 across and 150 down. My fillRect will be (0,0,100,150). It’s important that you understand I am not putting 100 and 150 because that’s where I want the corners in terms of coordinates, but in terms of how many pixels away from 0,0 I want them. 100 is the width of my rectangle, 150 is the height.

 

Let’s see the code and what it would look like

 

See images for reference: https://i.imgur.com/fftjoTy.png https://i.imgur.com/sLAjUHy.png

 

Now, I want to add a border to make it stand out. I could either draw a slightly bigger rectangle behind this one so that the edges poke out, or I could use drawRect(). drawRect works in the same way at fillRect(), however it draws an outline rather than a filled in rectangle. So all we need to do is change the colour to white and the rest is the same!

 

See image for reference: https://i.imgur.com/exTlN5b.png

 

Finally, let’s add some text. To draw text is the same steps. We set the colour, and then we tell it where to draw. We could optionally set the font and the size.

 

You already know how to set the colour, but actually as we are writing in white we don’t have to because it’s still white from before. So, all we need to do is decide what to write, and where. For this we use the graphics.drawString() method, we tell it what to write and where i.e graphics.drawString(“Cow Killer”, 0,0) would draw it at the top left, however this would look messy so I will use 20,20.

 

See image for reference: https://i.imgur.com/5nuJBta.png

 

Let’s see how it looks.

 

See image for reference: https://i.imgur.com/vIgk3ht.png

 

We will expand on the paint in a future tutorial, but with these 3 steps you can make any paint you want really. Showing the time is just some maths logic, exp gained uses ctx.skills.experience and some maths and logic (check exp at start and subtract it from current exp). You can also see here for the Java official API documentation (all the stuff graphics has to offer): https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics.html

 

 

Step Three - Fixing our error in the script

Some of you mentioned that the script was attacking multiple cows at once, I covered this in a forum response however I will write it here for you all.

 

haven't really ran this script for long periods of time but logically it should not attack something if it is already fighting something, this is because we do not fight unless healthBarVisible()==false - it is possible that this alone is not a good enough check, you could change this to something like

 

See image for reference: https://i.imgur.com/CMxbDed.png

 

This, although untested, should work because it says if our healthbar is not visible AND if we are interacting with a nil npc then let's fight

 

 

 

The RSBot api is nullsafe, what this means is that to prevent errors it will never return null. Null is essentially the same as nothing. So what it does instead is returns essentially an invalid or empty version of an NPC. This is why we use .equals(ctx.npcs.nil()) instead of == null. ctx.npcs.nil() will return (or give) us a one of these invalid npcs so we can compare to it.

 

 

 

Further, we use .equals(ctx.npcs.nil()) over == ctx.npcs.nil() because we are comparing an Object. An object basically means we are comparing something that is not a primitive datatype. A primitive datatype, without getting too in depth, is basically the most basic of datatypes. They include essentially any form of number (such as int), boolean (true/false), and char (single character or letter). Strangely it does not include Strings so if we wanted to compare "chris" to something is would be "chris".equals("chris") NOT "chris"=="chris".

 

EDIT: That above is not working, sorry! I have left it in as it does teach you about some things - but you actually need to use !ctx.players.local().interacting().valid() rather than .equals(ctx.npcs.nil())

 

 

Fin

 

Well done, you finished this tutorial. The next one is hopefully a bit more fun. But these are important steps you will need to take for every script you write, so we do need to get them out of the way. Please do leave any questions.

 

 

Share this post


Link to post
Chris   
4 hours ago, Christian0662 said:

Great tutorial! When will your next tutorial come out?

 

I hope to write the next today or tomorrow 

Share this post


Link to post
Chris   
12 hours ago, Christian0662 said:

Great tutorial! When will your next tutorial come out?

 

 

On 4/6/2020 at 10:52 PM, radicalrobby said:

❤️ Thanks Brotha! You are an inspiration!

I have added an edit to this, it's not too important but is required for the script to work. It's near the bottom, i highlighted it in red.

Share this post


Link to post
whitguy   

you are the best! also please ignore my question on the last portion of the tutorial. you answered it at the end of this one. Thank again!

Share this post


Link to post
Chris   
1 hour ago, whitguy said:

you are the best! also please ignore my question on the last portion of the tutorial. you answered it at the end of this one. Thank again!

no problem!

Share this post


Link to post

 

Thank you for your contribution and the time to help other people. Could you make an example of how to take 2 items from the bank to the inventory, mix them and return them to the bank?

Share this post


Link to post

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.

Sign in to follow this