SRL Archive - Reflection Tutorials

Making a oak “cut 'n bank' script


masterBB

2009-08-03 00:16:57

Reflection tutorial:
Making a oak “cut 'n bank” script


Update: 18-2

In this tutorial I'm going to teach you about reflection. And making an Oak woodcutter + banker east of varrock.

Including:
  • How to find objects(trees)
  • Walking
  • How to bank
Requirements:
  • Basic scar knowledge
  • Scar
  • SRL
  • Reflection

*Note:
I will not help you with installing any of these, please just use one of the other tutorials on the web


I: Basic knowledge

What is reflection? What is the difference between reflection and normal Scar color-finding? If you know the answers on these questions than you can skip this part of the tutorial.

Reflection reads the variables from runescape with SMART. So we don't have to use on-screen information anymore. Those vars tell us wich trees are full grown and wich trees are tree stumps. It tells us where we are. And it tels us where the bank is.

Al those things are easy to do by functions comming with reflection, compare it with SRL. Those functions work with runescapes tile system. Ever noticed that the RS world has been made from squares? Well all those squares have a x and an y value, useable for walking and tree finding. And some of those tiles also contains a number, from now on refered as the “Object ID”.

II: First step

This is exactly the same as with the most Scar scripts! Except ofcourse the reflection include:)

Program Wcer;

{.include srl/srl/misc/smart.scar}
{.include srl/srl.scar}
{.include reflection/reflection.simba}

procedure DeclarePlayers;
begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

Players[0].Name := ''; // your username
Players[0].Pass := ''; // your password
Players[0].Nick := ''; // 3-4 letters of your username
Players[0].Active := True; //Use this player or not?
End;

procedure MainLoop;
begin
if(not(LoggedIn))then
LoginPlayer;
repeat
until(false);
end;

begin
Smart_Signed := true;
Smart_Server := 34;
Smart_SuperDetail := false;
SetupSRL;
SetupReflection;
DeclarePlayers;
MainLoop;
end.

III: Getting info

If I use a Tile point, I get that point by replacing the MainLoop procedure by this:
procedure MainLoop;
var
Mypos:Tpoint;
begin
if(not(LoggedIn))then
LoginPlayer;
repeat
wait(500);
MyPos := getMyPos;
writeln('x = ' + IntToStr(MyPos.x) + 'y = ' + IntToStr(MyPos.y) );
until(false);
end;
What does this do?
-This returns every 500 ms you position.
Reflection function used:
-getMyPos;
What does getMyPos do?
-It returns you players position in a Tpoint.
*Note: A Tpoint is a var with 2 values (x and y).


If you know the tile of a object, like a tree, than you can get the Object ID by replacing the MainLoop procedure by this:

procedure mainloop;
var
thatObjectID:Integer;
begin
thatObjectID := GetObjectAt(Point(3168,3421),0).ID; //3168,3421 is the location of the most west Oak Tree
writeln('Object ID:'+ InttoStr(thatObjectID));
end;

What does this do?
-This returns the Object ID of a certain tile
Reflection function used:
-GetObjectAt(Point(x,y),type).ID;
What does GetObjectAt do?
- What do types exist?
0 = Interactable objects, 2 = wall decor
-It returns the objects ID in a Integer
*Note: A tree stump has a different ID than an full grown tree


Next thing is Animation, every action has a certain animation. For example; woodcutting, fishing, mining. But also for every item used during that animation; rune hatchet, iron hatchet-harpoon, net-rune pickaxe, iron pickaxe. In this script I will use the animation of cutting trees with the rune hatchet, as this is the most used axe(animation number: 867). And here is the code

procedure mainloop;
var
myAni:Integer;
begin
myAni := GetAnimation;
writeln('my animation = '+ InttoStr(myAni));
end;

What does this do?
-This returns the animation number
Reflection function used:
-GetAnimation;
What does getMyPos do?
-It returns the animation in a Integer
*Note: every tool has a different animation number

IV: Chopping the trees

I got the folowing information:
  • Oak tree Object ID: 1281
  • Oak tree 1 coordinates: 3168,3421
  • Oak tree 2 coordinates: 3162,3417
  • woodcutting + rune axe animation: 867
  • no animation: -1

The new Code:
  • procedure cutTrees
  • function ChopTree:Boolean
  • a new line in MainLoop: cutTrees;

This code also contains a new reflection command; TileToMS(Point(x,y),height):Tpoint. *tile to mainscreen coordinates.
This function transforms a tile to mainscreen coordinates. The height variable will not be used in this tutorial. I just use 10.

Walking through the code of procedure cutTrees.
It starts with setting up the camera settings to the best angle and direction.
If it finds a tree and clicked on it(chopTree) then……
-It waits till you are cutting trees(animation is 867)
-It waits till you are done(animation = -1)
And repeats if you inventory is not full

Walking through the code of function ChopTree.
It checks if Oak 1 is not already cutted
if not then…
–It gets its position on you screen by using the TileToMS function
-And clicks on it
-Result = true

if Oak 1 is a tree stump…
-It checks if Oak 2 is not already cutted
-if not then…
–it repeats the process from Oak1

if both trees are tree stumps then….
-Result = false

Walking and Banking

The next part of this tutorial is about walking and banking. Banking is very easy because there is a banking function in the reflection library; R_OpenBankBooth('');. Where you just have to put in wich bank to use, in this case 'vwb'.

Walking is a litlle bit harder, but it's still easier to use and more acurate than radial walk. I use the folowing code for it: WalkToTile();. Wich walks to a certain point and waits till it's there.

For this I will add two functions; LoadPath(i:integer) and WalkPath(i:integer). Where i is the difference between walking to the spot and walking to the bank. I =0 is walking to the bank and I= 1 is walking to the spot.

function LoadPath(i:Integer): TPointArray;
begin
if(i = 0) then
begin
SetLength(Result, 2);
Result[0] := Point(3173, 3429);
Result[1] := Point(3182, 3436);
end;
if(i = 1) then
begin
SetLength(Result, 2);
Result[0] := Point(3173, 3429);
Result[1] := Point(3165, 3419);
end;
end;

Procedure WalkThePath(i:integer);
Var
p: Integer;
Path: TPointArray;
Begin
if(not(LoggedI n))then
begin
Exit;
end;
Path := LoadPath(i);
for p := 0 to High(Path) do
Begin
WalkToTile(Path[p], 0, 0);
wait(300+random(100));
end;
Wait(500+Random(300));
end;

LoadPath is a function that returns the path how it has to walk. So Path := LoadPath(i). For example if you walk to the bank, Path := LoadPath(0). Path[0] will be 3173, 3429 and Path[1] will be 3182, 3436.

After the Path is loaded a for-loop walks to those tiles. WalkToTile clicks on the minimap and it waits until you are there.

Complete

Program New;
{.include srl/srl/misc/smart.scar}
{.include srl/srl.scar}
{.include reflection/reflection.simba}

Procedure DeclarePlayers;
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

Players[0].Name := ''; // your username
Players[0].Pass := ''; // your password
Players[0].Nick := ''; // 3-4 letters of your username
Players[0].Active := True; //Use this player or not?
End;

Procedure SetupScript;
Begin
DeclarePlayers;
If (not (LoggedIn)) Then LoginPlayer;
End;

function LoadPath(i:Integer): TPointArray;
begin
if(i = 0) then
begin
SetLength(Result, 2);
Result[0] := Point(3173, 3429);
Result[1] := Point(3182, 3436);
end;
if(i = 1) then
begin
SetLength(Result, 2);
Result[0] := Point(3173, 3429);
Result[1] := Point(3165, 3419);
end;
end;

Procedure WalkThePath(i:integer);
Var
p: Integer;
Path: TPointArray;
Begin
if(not(LoggedIn))then
begin
Exit;
end;
Path := LoadPath(i);
for p := 0 to High(Path) do
Begin
WalkToTile(Path[p], 0, 0);
wait(300+random(100));
end;
Wait(500+Random(300));
end;

Function ChopTree: Boolean;
Var
x, y, treeID: Integer;
MSPoint: TPoint;
Begin
treeID := GetObjectAt(Point(3168, 3421),0).ID;
If (treeID = 1281) Then
Begin
MSPoint := TileToMS(Point(3168, 3421), 10);
MMouse(MSPoint.x, MSPoint.y, 10, 5);
wait(100 + Random(30));
getMousePos(x, y);
Mouse(x, y, 0, 0, True);
Result := True;
End Else
Begin
treeID := GetObjectAt(Point(3162, 3417),0).ID;
If (treeID = 1281) Then
Begin
MSPoint := TileToMS(Point(3162, 3417), 10);
MMouse(MSPoint.x, MSPoint.y, 10, 5);
wait(100 + Random(30));
getMousePos(x, y);
Mouse(x, y, 0, 0, True);
Result := True;
End;
End;
End;

Procedure CutTrees;
Begin
R_MakeCompass('S');
SetAngle(True);
Repeat
If (ChopTree) Then
Begin
Repeat
wait(100 + Random(200));
If (GetAnimation = 867) Then
Begin
Break;
End;
Until (False);
Repeat
wait(200 + Random(50));
Until (GetAnimation = -1);
End;
Until (InvFull);
WalkThePath(0);
wait(500+random(200));
R_OpenBankBooth('vwb');
wait(500+random(200));
WalkThePath(1);
End;

Procedure MainLoop;
Begin
If (not (LoggedIn)) Then LoginPlayer;
Repeat
cutTrees;
Until (False);
End;

Begin
Smart_Signed := True;
Smart_Server := 34;
Smart_SuperDetail := False;
SetupSRL;
SetupReflection;
SetupScript;
MainLoop;
End.

Done?

NO!
  • It doesn't deposit logs
  • no antirandoms (can be done by: R_FindRandoms;)
  • no antiban
  • no progie

I didn't add them because they are the same as with normal Scar or SRL.

Creditz: rogeruk for fixing my standards:)

kyleisntwild

2009-08-07 06:55:19

This actually was helpful :) ty sir

rogeruk

2009-08-07 16:28:15

Program New;
{.include srl/srl/misc/smart.scar}
{.include srl/srl.scar}
{.include srl/srl/reflection/reflection.scar}

Procedure DeclarePlayers;
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

Players[0].Name := ''; // your username
Players[0].Pass := ''; // your password
Players[0].Nick := ''; // 3-4 letters of your username
Players[0].Active := True; //Use this player or not?
End;

Procedure SetupScript;
Begin
DeclarePlayers;
If (not (LoggedIn)) Then LoginPlayer;
End;

Function ChopTree: Boolean;
Var
x, y, IDthing: Integer;
MSPoint: TPoint;
Begin
IDthing := GetObjectAt(3168, 3421).objType;
If (IDthing = 1281) Then
Begin
MSPoint := TileToMS(Point(3168, 3421), 10);
MMouse(MSPoint.x, MSPoint.y, 10, 5);
wait(100 + Random(30));
getMousePos(x, y);
Mouse(x, y, 0, 0, True);
Result := True;
End Else
Begin
IDthing := GetObjectAt(3162, 3417).objType;
If (IDthing = 1281) Then
Begin
MSPoint := TileToMS(Point(3162, 3417), 10);
MMouse(MSPoint.x, MSPoint.y, 10, 5);
wait(100 + Random(30));
getMousePos(x, y);
Mouse(x, y, 0, 0, True);
Result := True;
End;
End;
End;

Procedure CutTrees;
Begin
R_MakeCompass('S');
SetAngle(True);
Repeat
If (ChopTree) Then
Begin
Repeat
wait(100 + Random(200));
If (GetAnimation = 867) Then
Begin
Break;
End;
Until (False);
Repeat
wait(200 + Random(50));
Until (GetAnimation = -1);
End;
Until (InvFull);
End;

Procedure MainLoop;
Begin
If (not (LoggedIn)) Then LoginPlayer;
Repeat
cutTrees;
Until (False);
End;

Begin
Smart_Signed := True;
Smart_Server := 34;
Smart_SuperDetail := False;
SetupSRL;
SetupReflection;
SetupScript;
MainLoop;
End.

Standards Fixed.

IDthing

You shouldnt name these like that. They should be named in relevance to what it is. IDThing?. OakID? TreeID?

masterBB

2009-08-07 17:30:32

From: kyleisntwild
This actually was helpful :) ty sir


Thanks for reading my tutorial, any suggestions how to improve it?

From: rogeruk

Standards Fixed.

You shouldnt name these like that. They should be named in relevance to what it is. IDThing?. OakID? TreeID?


Thanks for fixing my standards, added by the tutorial. I replaced IDthing with TreeID.

rep++

Smarter Child

2009-08-07 20:22:54

You are talented, why don't you release a reflection script. :)

darkmind63

2009-08-09 15:58:42

i know this guy personally, he always messes up his standards and has a tendency to give confusing names to important variables.
But other than that great tutorial

ian.

2009-08-09 17:36:32

From: rogeruk
Program New;
{.include srl/srl/misc/smart.scar}
{.include srl/srl.scar}
{.include srl/srl/reflection/reflection.scar}

Procedure DeclarePlayers;
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

Players[0].Name := ''; // your username
Players[0].Pass := ''; // your password
Players[0].Nick := ''; // 3-4 letters of your username
Players[0].Active := True; //Use this player or not?
End;

Procedure SetupScript;
Begin
DeclarePlayers;
If (not (LoggedIn)) Then LoginPlayer;
End;

Function ChopTree: Boolean;
Var
x, y, IDthing: Integer;
MSPoint: TPoint;
Begin
IDthing := GetObjectAt(3168, 3421).objType;
If (IDthing = 1281) Then
Begin
MSPoint := TileToMS(Point(3168, 3421), 10);
MMouse(MSPoint.x, MSPoint.y, 10, 5);
wait(100 + Random(30));
getMousePos(x, y);
Mouse(x, y, 0, 0, True);
Result := True;
End Else
Begin
IDthing := GetObjectAt(3162, 3417).objType;
If (IDthing = 1281) Then
Begin
MSPoint := TileToMS(Point(3162, 3417), 10);
MMouse(MSPoint.x, MSPoint.y, 10, 5);
wait(100 + Random(30));
getMousePos(x, y);
Mouse(x, y, 0, 0, True);
Result := True;
End;
End;
End;

Procedure CutTrees;
Begin
R_MakeCompass('S');
SetAngle(True);
Repeat
If (ChopTree) Then
Begin
Repeat
wait(100 + Random(200));
If (GetAnimation = 867) Then
Begin
Break;
End;
Until (False);
Repeat
wait(200 + Random(50));
Until (GetAnimation = -1);
End;
Until (InvFull);
End;

Procedure MainLoop;
Begin
If (not (LoggedIn)) Then LoginPlayer;
Repeat
cutTrees;
Until (False);
End;

Begin
Smart_Signed := True;
Smart_Server := 34;
Smart_SuperDetail := False;
SetupSRL;
SetupReflection;
SetupScript;
MainLoop;
End.

Standards Fixed.


You shouldnt name these like that. They should be named in relevance to what it is. IDThing?. OakID? TreeID?


Those aren't entirely correct standards.

Nice to see you're trying to help out, masterBB! :) Keep it up! ^^

PatDuffy

2011-02-10 16:39:56

I found this tutorial extremely helpful in piecing together all of the information I'm attempting to learn. Other tutorials just focus on one aspect of scripting, without informing the reader on how to put it all together. This one went through the step-by-step process on how I should develop a new script, including Reflection(something I am new to).

Just a few things about your grammar in the tutorial

*Note: A tree stump got a different ID as an full grown tree


and

*Note: every tool got a different animation number


I'm fairly sure they both should be "has" instead of "got". and instead of "as" it should be "than".

masterBB

2011-02-10 16:43:22

Thank you, since my main language is not English I sometimes make mistakes. But I now see what I did wrong. Will fix it.

Echo_

2011-02-16 14:33:02

Old ass thread bro.

masterBB

2011-02-16 14:34:36

Code is already updated, will upload it tomorrow. I decide what is an old thread.

tofurocks

2011-02-17 16:57:45

Thanks this tutorial is awesome :)
I didn't know how much reflection integration SRL had :O

masterBB

2011-02-18 05:44:37

Thanks, but now the code is updated. This tutorial is more useful now. Though only the geObjectAt was outdated.

tofurocks

2011-02-21 23:07:31

So GetObjectAt is a reflection function?
If so, should it not be R_GetObjectAt?
Makes it a lot clearer when browsing the includes.

masterBB

2011-02-23 10:00:27

{*******************************************************************************
function GetObjectAt(T: TTile; objType: Integer): TRSObject;
By: Drags111
Description: Returns the object at the specified tile, with the type of objType.
*******************************************************************************}
function GetObjectAt(T: TTile; objType: Integer): TRSObject;
var
objFuncts: array [0..3] of function(T: TTile):TRSObject;
begin
Result := NULL_RSOBJECT;

objFuncts[0] := @GetInteractableAt; objFuncts[1] := @GetWallObjectAt;
objFuncts[2] := @GetWallDecorAt; objFuncts[3] := @GetFloorDecorAt;

Result := objFuncts[objType](T);
end;

Maybe I use a different include as you do?

tofurocks

2011-02-23 19:36:13

I was just talking about the name, nevermind.

Emu

2011-10-03 06:26:53

Hi, thanks for the tutorial its a real help!

One slight problem though…
 procedure PathFind;
var
MyPos:Tpoint;
begin
if(not(LoggedIn))then
LoginPlayer;
repeat
wait(500);
MyPos := getMyPos;
writeln('x = ' + IntToStr(MyPos.x) + 'y = ' + IntToStr(MyPos.y) );
until(false);
end;

This code returns


Compiling failed.
[Error] (17:12): Unknown identifier 'getMyPos' at line 16

This is the full code if it helps.


program DeclarePlayers;
{$i srl/srl/misc/smart.scar} // This is how we include SMART; it HAS to be included BEFORE SRL!
{$i srl/srl.scar}
{$I Reflection/Reflection.simba}
var x, y:integer;


procedure PathFind;
var
MyPos:Tpoint;
begin
if(not(LoggedIn))then
LoginPlayer;
repeat
wait(500);
MyPos := getMyPos;
writeln('x = ' + IntToStr(MyPos.x) + 'y = ' + IntToStr(MyPos.y) );
until(false);
end;






procedure DeclarePlayers;
begin
HowManyPlayers := 1; // This is set to the total amount of players (more on multiplayer later ;)), for now, just keep it set as 1
NumberOfPlayers(HowManyPlayers); // This is a procedure in SRL which sets up player arrays (also, more on that later), this will always be the same
CurrentPlayer := 0; // This is the player to start with; the first player will always be 0 (you'll find out when you learn all about arrays)

Players[0].Name := edit'; // Username
Players[0].Pass := 'edit'; // Password
Players[0].Nick := 'Dras'; // 3-4 lowercase letters from username; used for random event detection
Players[0].Active := True; // Set to true if you want to use Player 0
Players[0].Pin := ''; // Leave blank if the player doesn't have a bank pin
end;

begin
// These 4 lines HAVE to be set BEFORE you call SetupSRL;
Smart_Server := 152;
Smart_Members := False;
Smart_Signed := True;
Smart_SuperDetail := False;

ClearDebug;
SetupSRL;
SetupReflection;
DeclarePlayers; // Calls the procedure, you can't forget this!
LoginPlayer; // You want your player to login, right?
wait(6000+random(2000));
PathFind;
end.

Just wondering if you can help me out, thanks.

Flight

2011-10-03 06:48:56

Yeah this tutorial is based on Reflection 1. The current reflection, that you're using, is R2. Between the two versions there's not much difference, just alot of slight name changes, mostly adding "R_" in front of functions/procedures. Instead of "getMyPos" use "R_GetMyPos".

Emu

2011-10-04 02:00:07

Oh ok, Thanks again!