PDA

View Full Version : Make your own Fletcher script !



Cigue
07-15-2010, 06:13 AM
THERE IS A PARTIALLY COMPLETED FLETCHER AT THE BOTTOM OF THIS TUTORIAL. IF YOU WANT, JUST DOWNLOAD IT AND TRY TO UNDERSTAND IT BY YOURSELF. ANY HELP YOU NEED CAN BE FOUND IN THIS THREAD.


Hi and welcome to my tutorial: how to script your very own bow fletcher! This tutorial will cover many techniques, simple or advanced, but I made sure to choose only simple ones. This tutorial is appropriate for you if you understand the basic idea of a loop, but have difficulties putting together a whole script. That’s okay, because this is baby steps.

If the script shown below doesn't work for you, maybe it's because it's running too fast! Try putting Wait(RandomRange(500,700)); before the functions that fail !

1. Includes

You must always begin your SRL scripts by putting the includes you are going to use! Includes contain the functions you’re going to be using in your script, like Mouse or DeclarePlayers, which are useful if you plan to use your mouse or play RuneScape with that script ;) .

{$i SRL/SRL.scar}

This will include the biggest of the functions contained in SRL. Once you have that, you can use some real functions 
Another interesting to have is SMART. What it does is confine the botting to a window you can minimize or put away, instead of clogging your whole computer. See, as I’m writing this, I’m using SMART to run a bot. Right now.

{$DEFINE SMART}
{$i SRL/SRL.scar}
And that, my friends, is how it’s done.
Next, we are going to tackle the actual instructions going into the script. First, a simple function you must never forget is SetupSRL. Without it, pretty much all of SRL is unusable.
{$DEFINE SMART}
{$i SRL/SRL.scar}

Begin
SetupSRL;
End;

There you have a basic script that you could run, but without much results : it’s got no instructions !

2. DeclarePlayers

This first function we’re going to write is meant to tell the script about the players, how to log them in and some basic info. It goes like this (don’t ask me why, I didn’t make it !).
{$DEFINE SMART}
{$i SRL/SRL.scar}

procedure DeclarePlayers;
begin
HowManyPlayers := 1;//You may change that for any number of players.
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0; //Don't touch
With Players[0] do
begin
Name := '';//RS nickname
Pass := '';//RS password
Nick := '';//3-4 lowercase letters from your nickname
Pin := '';//RS bank pin
Active:= True;
BoxRewards := ['xp', 'lamp', 'imy', 'oins', 'apphire', 'ssence'];//In what order you’d like to get rewards from random events. I chose xp first, then xp lamps, then grimy herbs, you get the idea.
end;
//Notice that you can repeat the entire sequence here, starting from With until end; with different player numbers, if you’re planning to use more than one RS character in your script.
end;

Begin
SetupSRL;
DeclarePlayers;
End.
All this code is useful to functions like LoginPlayer, which we’ll later use to, well, log your player in.

3. LoginPlayer

Yep, you guessed it.
Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
End.
The LoginPlayer function will only work if you have used DeclarePlayers first, because else it wouldn’t know what character to log in.

4. Find location

Okay, we just logged in our character. Now, we’d like to know if we’re anywhere near the right place.
Since this is a Fletcher script, we’ll assume we need to be close to a bank. There’s an excellent way to be sure of that : checking for the bank symbol on the minimap.

This function has two steps. The first one is to set up SymbolAccuracy, which is the variable that decides how accurate must the symbol be. If it’s high, you’ll find it less often but be more sure of it. Under 0.5 accuracy, if there’s a furnace nearby the script could mistake it for a bank !

Let’s set an arbitrary value of 0.6. Next, we’ll need the actual symbol finding : the function goes FindSymbol(var rx, ry: Integer; Name: String). What that means is that you have to give it two integers (rx and ry) and a string of letters (Name). After using FindSymbol, the xr and yr you gave will contain the position of the bank symbol. Not very useful to us, we’re just trying to figure out if it’s there !

We’re going to put all the symbol related stuff in a function called FindBankSymbol.

function FindBankSymbol : Boolean;
var
x, y : integer;
begin
SymbolAccuracy := 0.6;
Result := FindSymbol(x, y, ‘bank’);
end;

Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
FindBankSymbol;
End.

The difference between functions and procedures is that functions give a result, which you can store in a variable and use later, or even use right there as a variable, which is what we’re going to do. FindSymbol() returns a boolean, which can either be true or false. we can use that to our advantage, by writing if FindSymbol() then... The instructions following the then will only be accomplished if the symbol is found (and FindSymbol returns True). If the symbol isn't found (and FindSymbol returns False) then the instructions will not run : it will be like writing "if False then..."

Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
If not FindBankSymbol then
LogOut;
End;

The added instructions will log you out if a bank symbol isn’t found.

5. DTMs

For figuring out what’s in your inventory, the simplest way is looking for DTMs. I recommend that you look up a DTM tutorial before continuing, but I still will try to explain how to use DTMs.

Here, we are going to cover how to make a DTM of a log. The idea is exactly the same for a long bow or short bow.

First, you need SCAR, which I'm sure you can get since you're an intermediate scripter and a big boy/girl :) next, you need to have SCAR and RuneScape open, with the log you're trying to find in plain view (i.e. in your inventory). First, while your item is onscreen, press Print Screen. It's a button just up and right of backspace.

Next, go in SCAR -> Tools -> DTM Editor. A window opens up : go to Edit -> Paste Image. A picture of your screen will show up.

Usually, when picking DTMs, we'll pick one colored point and several points of the black outline of the item. That way, the screen will look for the item color AND outline.

However, we'd like our fletcher to be able to recognize any set of logs, be they normal, oak, willow, yew or even magic. We could either make one DTM for each kind of log (and short bow, and long bow) or simply rely on the outline, so your script will find any type of logs but will not know what color/which kind it is.

So, that's it for the theory. You're going to pick points at random on the black outline of the logs, maybe 10-15. You'll see the points in a list up and right of the Editor.

You'll need to delete all the points that have a different value than 131072 as the last number. It's the only color of any item that won't ever change.

There, you should have a web of components, looking a little like this :

http://img683.imageshack.us/img683/592/itemsc.png

As I didn't have any logs at the moment of the writing, here is a gold bracelet. Notice that the list of numbers on the right all have 131072 as a last parameter.

Once you're positive your DTM looks good, you can go to File -> DTM To String. When you close the editor, you'll notice in SCAR's debug box (the thing at the bottom that holds the message) will have something like this :


DTM := DTMFromString('78DA63D4646160B8C3C8800A98C0244C945 11' +
'DA8E62601356A40359709A8D105AA394F408D1150CD15026A 2C80' +
'6A6E1150630654F380801A13A09A8704D46800590B995054F CFFF' +
'F1F450D00A3350C51');

This is the DTM of the logs you've just made :) Congratulations !

You can do three things with DTMs. The first thing you can do is load them, so the computer knows what it's looking for; then, you can use FindDTM to search for them; finally, you have to free them from your computer's memory so you don't slow it up a lot.

A lot is going to happen here. First, we are going to write a function to load the DTM, which isn't too hard.
Second, we're going to write a function that will tell us if a DTM is found. That, my friends, take some true skill.
The way it is done, a function take some parameters (or none) and returns a result. We want to give it a DTM and we want the result to be if it's found it. The parameters of the function are going to be which DTM we're going to look for, and the result is going to be a Boolean, just like FindSymbol :)

This time, instead of FindSymbol, we are going to use FindDTM(DTM, x, y, x1, y1, x2, y2). This functions has a lot of parameters, does it?
The first parameter, aptly called DTM, is the name of the DTM you want to find. You have to declare it earlier in the function, else FindDTM will NOT work and probably crash your script !

The second two parameters (x and y) are where the location of the DTM will be recorded, if it is found. These are coordinates, by the way.

The last four parameters are the search box for the item. As we are going to look for the item in the inventory, we are going to have to put the limits of the search box on the limits of the inventory. There's a handy way to do that : you can use MIX1, MIY1, MIX2, MIY2. These stand for Main Inventory (limit) X/Y 1/2. Basically, making these the parameters of a box will make a box around your inventory. There are also other versions like MSxx (Main game area limits), MCxx (Main Chat) and MMxx (Mini Map).

We are going to have to check for items in the bank, too. Why not add a parameter to the function that we'll use to decide if the item we're looking for is in the bank or in the inventory?

The third thing we are going to do is FreeDTM(DTMName). It's a function that frees the DTM that you give it from the memory of your computer :)

procedure LoadDTMs;
begin
LogsDTM := DTMFromString('Insert DTM here');
end;

function DTMFinder(DTM : Integer; IsInBank : Boolean) : Boolean;
var
x, y : integer;

begin
if IsInBank then
Result := FindDTM(DTM, x, y, MSX1, MSY1, MSX2, MSY2)
else
Result := FindDTM(DTM, x, y, MIX1, MIY1, MIX2, MIY2);
end;

procedure FreeDTMs;
begin
FreeDTM(LogsDTM);
end;

Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
LoadDTMs;
if DTMFinder(LogsDTM, False) then
Writeln('Found logs in inventory!');
else
LogOut;
If not FindBankSymbol then
LogOut;
FreeDTMs;
End;

6. Error reporting

At this point of the script, a few things could go wrong. What if the bank or logs aren't found?

We are going to add a function solely based to finding out what could go wrong. We'll call it ScriptError, since it's an error in our script :) and we want to be able to read out what happened when an error happens.

Thus, the function will have a string parameter that will hold the information of what goes wrong. The first thing it will do is report to the debug box what went wrong, the second is to log out, the third one is to free your DTMs and the last one is to terminate your script.

procedure ScriptError(ErrorInfo : String);
Begin
Writeln('Error : ' + ErrorInfo);//This will write Error : + whatever you put as a parameter.
LogOut;
FreeDTMs;
TerminateScript;
end;

Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
LoadDTMs;
if DTMFinder(LogsDTM, False) then
Writeln('Found logs in inventory!');
else
ScriptError('Did not find logs');
If not FindBankSymbol then
ScriptError('Did not find bank symbol');
FreeDTMs;
End;

7. Bank opening

We'll need to access a bank, else we know our script won't work. The easiest way to do this is to use OpenBankFast(''). It's a procedure that I haven't found to be completely reliable, however we'll just assume it works for now (I think it does).

We have to tell OpenBankFast which bank we're at. However, switching from player to player, not everyone will want to bank at the same place. We are going to add a variable to declareplayers that players will use to tell the script which bank they're at.



var
x, y, LogsDTM : Integer;

procedure DeclarePlayers;
begin
HowManyPlayers := 1;//You may change that for any number of players.
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0; //Don't touch
With Players[0] do
begin
Name := 'MyCharacterName';//RS nickname
Pass := 'Password';//RS password
Nick := 'Char';//3-4 lowercase letters from your nickname
Pin := '0123';//RS bank pin
Strings[0] := 'veb';//What bank are you at? veb for varrock east, vwb for varrock west, etc.
Active:= True;
BoxRewards := ['xp', 'lamp', 'imy', 'oins', 'apphire', 'ssence'];
end;
end;

function DTMFinder(DTM : Integer; IsInBank : Boolean) : Boolean;
var
x, y : integer;

begin
Result := FindDTM(DTM, x, y, MIX1, MIY1, MIX2, MIY2);
end;

Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
LoadDTMs;
if DTMFinder(LogsDTM, False) then
Writeln('Found logs in inventory!');
else
ScriptError('Did not find logs');
If not FindBankSymbol then
ScriptError('Did not find bank symbol');
If not OpenBankFast(Players[CurrentPlayer].Strings[0]) then
ScriptError('Could not open bank ');
FreeDTMs;
End;

Since we are going to use a lot of x's and y's, I've just put them as global variables : variables that are declared at the start of the script, outside of any function, will work in ANY function. From now on, right after using DTMFinder, you will be able to use the recorded location in any other function ! Notice that I have removed the variables x and y from the DTMFinder function description, else we'd have two variables called the same name and there's no telling how the script might react.

8. Retrieve logs in bank

There's this sweet little function in SRL that goes Withdraw (colon, row, ammount : integer). We want to withdraw 13 logs (if it is not evident to you why, I suggest you go do a little of manual fletching before you go any further). However, we have no clue what the colon and row of the logs might be.

Remember that we just made x and y global? Well, after running a DTMFinder in the bank area, if the log is found it's coordinates will be recorded in x and y. We just need to use a function called MSTPointToBankPoint.

The parameter and result of the function are both TPoints. Horror ! What are these?

They're simply coordinates, an x and a y that you can access easily. For an example, if your variable Coords is a TPoint, then Coords.x is the x value of your TPoint and Coords.y is the y value.

You can make a TPoint from two coordinates by using the Point(x coords, y coords) function.

After using DTMFinder, the coordinates of the Logs are stocked in x, y;
meaning that using Point(x, y) will make a TPoint of the coordinates of the Logs;
meaning that MSTPointToBankPoint(Point(x, y)) will return bank coordinates of the Logs.

Bank coordinates go x = colon, y = row. First row, first colon is (0,0). First row, second colon is (1,0), etc.

We are going to put the bank coordinates in a TPoint variable, which we can then use in a Withdraw function.



procedure GetMaterialsFromBank;
var BankTPoint : TPoint;

begin
If not OpenBankFast(Players[CurrentPlayer].Strings[0]) then
ScriptError('Could not open bank ');
if not DTMFinder(LogsDTM, True) then
ScriptError('Could not find logs in open bank');
BankTPoint := MSTPointToBankPoint(Point(x,y));
Withdraw(BankTPoint.x, BankTPoint.y, 13);
CloseBank;
end;

Begin
SetupSRL;
DeclarePlayers;
LoginPlayer;
LoadDTMs;
if DTMFinder(LogsDTM, False) then
Writeln('Found logs in inventory!');
else
ScriptError('Did not find logs');
If not FindBankSymbol then
ScriptError('Did not find bank symbol');
GetMaterialsFromBank;
FreeDTMs;
End;

And that's all, folks. If you take all the bits and pieces I've wrote so far, you'll have a nice script that will log you in, find and open your bank, then retrieve your logs and close your bank.

9. Repeat the instructions 5-8 with bowstrings.

You've read it right. Make a bowstring DTM, teach your script to find it and withdraw it along with the logs.

10. Find knife

The following takes place after you've withdrawn your logs and bowstrings from bank. You need to make a knife DTM, then find it, then click it. Since it's going to be in your inventory, there's none of that bank TPoint bullsh** (Thank god !) All you're going to use is a function called CoordsToItem(x, y) that will return an item position, and then MouseItem(item position, Leftclick?) to click it.

procedure ClickKnife;
begin
if not DTMFinder(KnifeDTM, False) then
ScriptError('Could not find knife');
MouseItem(CoordsToItem(x, y), True);
end;

TO BE CONTINUED

BraK
07-15-2010, 01:28 PM
Next, we are going to tackle the actual instructions going into the script. First, a simple function you must never forget is SetupSRL. Without it, pretty much all of SRL is unusable.
[SCAR]{$DEFINE SMART}
{$i SRL/SRL.scar}

Begin
SetupSRL;
End; [/ SCAR]

The Tag is broken here you added a space between [/ and SCAR]. You also have almost the same code loginplayer as the previous Scar Tags. it might be easier to read by just showing the main loop or showing the changes you made instead of the whole script. When you get to the later stages it'll be more difficult to read. Due to having to scroll to the bottom of the Scar Tag. Just Some Suggestions but it looks good so far.


begin
setupsrl;
declareplayers;
loginplayer;
end.

Becks
07-15-2010, 02:25 PM
Alright, alright. You got me interested. :) Will take a look at when I get home from work.

ffcfoo
07-20-2010, 03:02 AM
"10. Repeat the instructions 5-9 with bowstrings." btw there is no number 9 xD