Building a simple Port Sarim chopper & banker
Resources used
Simba 1400+
SRL-F
ACA (Built into Simba)
Step 1: Defining the script
Going into this tutorial I'll assume you have some basic knowledge about writing scripts using Simba. I'll keep things as simple in this script as possible with plenty of documentation, however should any part not make sense please feel free to post any questions you may have. With that being said, off we go. Start by opening Simba and pasting the following chunk of code:
Simba Code:
program PortSarimChopper;
{$DEFINE SRL_USE_REMOTEINPUT} // Allows us to use the OEM client without taking over mouse & keyboard
{$I SRL-F/OSR.simba} // We'll need the SRL-F include
Type TTreeType = (Willow);
Const
(* Script settings *)
TREETYPE = Willow; // Type of tree to chop (only Willow supported currently)
PERCSHIFT = 16; // Percent pixelshift to be considered 'chopping'
MAXRUNTIME = 75; // Max run time in minutes
(* Player settings *)
PNAME = ''; // Player name
PPASS = ''; // Player password
PPIN = ''; // Player pin (not needed here as we use the deositbox)
(*
Here we add a new type of variable called a 'TTree'
Inside the TTree we'll store useful information
that we can apply to multiple types of trees
*)
Type
TTree = record
XP : Int32;
WalkTile: TPoint;
Color : TCTS2Color;
Log : TRSItem;
Tiles : TPointArray;
end;
(*
Our base record for the script, containing
global variables to be used throughout.
*)
TScript = record
LogCount : Int32;
Tree : TTree;
PrevTile,
BankTile : TPoint;
BankPath,
TreePath : TPointArray;
TreeZones : T2DPointArray;
MiscItems : TRSItemArray;
RSW : TRSWalker;
ShutdownTime: Int64;
end;
(*
Create a single instance of a 'TScript', call it 'Bot'.
*)
Var
Bot: TScript;
As you can see I've denotations for every block of code in the example, and I'll continue to do so throughout the tutorial. In a nutshell what's going on here is importing SRL-F, which is just my personal version of Olly's SRL-OSR, as well as defining that the script will utilize the very powerful and handy feature called RemoteInput. This allows us to bot using the official OSRS client and does not take over your mouse and keyboard. It's just about as safe as you can possibly bot without Simba taking control of you PC (unless using a VM, ect...). Aside from that we define the script settings as well as global variables to be used throughout.
Step 2: Adding useful/critical components
Here we'll add some useful functions such as customized mouse movements, progress reporting and anti-ban setup.
Simba Code:
(*
Just a neater version of writing debug messages.
*)
procedure TScript.WriteMsg(Message: String);
begin
WriteLn('[Bot]: ', Message);
end;
(*
Always declare your players.
*)
procedure TScript.DeclarePlayers();
begin
Login.AddPlayer(PNAME, PPASS, PPIN, []);
end;
(*
Print out a report of your in-game progress.
Makes use of SRL-F's built-in 'ProgressReport' procedure.
*)
procedure TScript.Report();
var
XpGained:Int32;
begin
XpGained := Max(1,(Self.LogCount*Self.Tree.XP));
(* Let's clean up Simba's output section before printing another progress report *)
ClearDebug();
(* See progreports.simba (Includes/SRL-F/utils/progreports.simba) for reference *)
ProgressReport(RESULT_REPORTBOX, 'Port Sarim Chopper', 'Flight', '1.00',
['Runtime', 'Logs chopped', 'XP gained', 'Until shutdown'],
[SRL.MsToTime(GetTimeRunning, Time_Short),
ToStr(Self.LogCount, '(', Round(Self.LogCount / (GetTimeRunning()/1000/60/60)),' / hr)'),
ToStr(Round(XpGained,2),'(', Round(XpGained / (GetTimeRunning()/1000/60/60)),' / hr)'),
SRL.MsToTime(Self.ShutdownTime-GetTimeRunning, Time_Short)]);
end;
(* Some homegrown anti-ban *)
procedure TMouse.RandomMovement();
var
S: Int32;
begin
S := Self.Speed;
Self.Speed := 4;
Self.Move(Box(Mouse.Position, 75, 75), True, );
Self.Speed := S;
end;
procedure TScript.DoLoseFocus();
begin
Antiban.LoseFocus(SRL.NormalRange(3700,500));
end;
(* Setup our antiban *)
procedure TScript.SetupAntiban();
begin
Antiban.Skills += ERSSKILL.WOODCUTTING;
// Interval Antiban method
Antiban.AddTask(ONE_SECOND*10, @Mouse.RandomMovement);
Antiban.AddTask(ONE_MINUTE*2, @Self.DoLoseFocus);
Antiban.AddTask(ONE_MINUTE*4, @Antiban.HoverMSPlayers);
Antiban.AddTask(ONE_MINUTE*7, @Antiban.RandomRotate);
Antiban.AddTask(ONE_MINUTE*9, @Antiban.HoverSkills);
Antiban.AddBreak(ONE_MINUTE*18, ONE_SECOND*40, 0.2, 0.0);
end;
procedure TScript.DoAB();
begin
Antiban.DismissRandom();
if Antiban.DoAntiban() then
if (not RSClient.IsLoggedIn) then
Login.LoginPlayer();
end;
(* Combination of miss mouse + slowing near the target destination *)
procedure TMouse.HumanMove(Point: TPoint);
var
mPt: TPoint;
S: Int32;
Miss: Double;
Range: Int64;
begin
S := Self.Speed;
Range := Trunc(Power(Self.Position().DistanceTo(Point), 0.80)); // how much possible range to miss
Miss := SRL.SkewedRand(0.9, 0.1, 1.5); // Where miss will happen. 1 = destination (P).
mPt.X := Trunc((1-Miss)*Self.Position().X + Miss*Point.X);
mPt.Y := Trunc((1-Miss)*Self.Position().Y + Miss*Point.Y);
mPt.X += SRL.NormalRange(-Range, Range);
mPt.Y += SRL.NormalRange(-Range, Range);
Self.Move(mPt);
Self.Speed := round(S*0.85);
Self.Move(Point);
Self.Speed := S;
end;
If it's hard to read the denotation within that code block just copy & paste it into Simba to make it a bit easier to read.
Step 3: Finding & interacting with objects
Here we have the actual finding of mainscreen objects, in this case willow trees and the depositbox at Port Sarim. You'll notice both accomplish the same task but are done differently. It's simply to demonstrate different ways to go about accomplishing tasks.
Simba Code:
(* Function to gather all available trees of our tree type *)
function TScript.AllAvailableTrees(): TPointArray;
var
TPA: TPointArray;
ATPA: T2DPointArray;
Finder: TRSObjectFinder;
begin
// Uses SRL-OSR's built-in color-finding
// See examples in Includes/SRL-F/docs/images
Finder.Colors += Self.Tree.Color; // Load our tree type's color into the finder
Finder.Grow := 4;
Finder.ClusterDistance := 4;
ATPA := MainScreen.FindObject(Finder); // Finder will spit out a T2DPointArray of any found trees as 'ATPA'
if ATPA.Len < 1 then Exit; // No colors found
for TPA in ATPA do
Result += TPA.Mean(); // For each TPA within the ATPA we'll extract the mean and add it to the result
Result.Sort([Mainscreen.GetPlayerBox.Middle.X, Mainscreen.GetPlayerBox.Y2]); // Now sort the result from our player
end;
(*
Finding the depositbox. By this point you should already
understand how this works.
*)
function TScript.FindDepositBox(): Boolean;
var
TPA: TPointArray;
ATPA: T2DPointArray;
Finder: TRSObjectFinder;
begin
Finder.Colors += CTS2(6189178, 7, 0.06, 0.56);
Finder.Grow := 1;
Finder.ClusterDistance := 3;
ATPA := MainScreen.FindObject(Finder);
if (ATPA.Len > 0) then
begin
ATPA.SortByMiddle(Mainscreen.Center);
for TPA in ATPA do
begin
Mouse.HumanMove(TPA.Mean()); // Right away move the mouse to each TPA mean and check for uptext
if MainScreen.IsUpText(['eposit']) then // Found it, exit and return 'True'
Exit(True);
end;
end;
end;
You can see here that TScript.AllAvailableTrees() will (hopefully) spit out a TPA of all located willow trees whereas TScript.FindDepositBox() right away moves the mouse until the correct uptext is found.
Step 4: Chopping a tree
Alright, we have a function to find those willow trees on the mainscreen, now let's build a procedure that calls that finder and actually chops the tree. While we're at it, let's create a loop that waits while we're still chopping. Here's one way to accomplish this:
Simba Code:
procedure TScript.ChopTree();
var
i,XP: Int32;
T: TCountdown;
Trees: TPointArray;
begin
// Failsafe...
if DepositBox.IsOpen then
begin
DepositBox.Close();
Exit;
end;
// We're > 25 distance from the tree's 'WalkTile', so let's webwalk back
if RSW.GetMyPos().DistanceTo(Self.Tree.WalkTile) >= 25 then
begin
Self.WriteMsg('Returning to initial spot');
Minimap.EnableRun();
RSW.WebWalk(Self.Tree.WalkTile);
Exit;
end;
// Get all trees of our treetype, stored as a TPA
Trees := Self.AllAvailableTrees();
// So we don't spam move the mouse, let's limit the attempts to a max of 3 movements
for i:=0 to min(3, high(Trees)) do
begin
Mouse.HumanMove(Trees[i]);
if MainScreen.IsUpText('Chop down', 75) then // Found the desired uptext, let's break the loop now
break;
end;
// Never found the uptext, perhars we're too far away
// Webwalk back to the tree's WalkTile
if (not MainScreen.IsUpText('Chop down')) then
begin
Self.WriteMsg('No trees found, returning to initial spot');
RSW.WebWalk(Self.Tree.WalkTile);
Exit;
end;
Mouse.Click(MOUSE_LEFT);
if (not MainScreen.DidRedClick) then Exit;
// Record the value in the XP bar before we begin chopping
XP := XPBar.Read();
// Wait while the player is walking towards the tree
if Minimap.HasFlag(500) then
if WaitUntil(Minimap.IsPlayerMoving(300), 75, 1000) then
Minimap.WaitPlayerMoving(300, 6000);
// Start a countdown timer between 1.6 and 1.8 seconds, begin chopping loop
T.Init(SRL.NormalRange(1600,1800));
// Repeating loop while 'T' is still counting down
while (not T.IsFinished) do
begin
if (not RSClient.IsLoggedIn) then Exit;
if Inventory.IsFull() then break;
if Chat.ClickContinue(False) then
T.Restart;
// The XP bar reads higher than the previous record
// So restart T timer and re-record the our XP bar as XP
if XPBar.Read() > XP then
begin
XP := XPBar.Read();
T.Restart();
end;
// If there's a percent pixelshift (PERCSHIFT) within our player's box
// restart the T timer
if (SRL.PercentShift(MainScreen.GetPlayerBox(), 500) >= PERCSHIFT) then
T.Restart();
Self.DoAB(); // Let's do some anti-ban while chopping
Wait(60,120); // Slow down the loop 60-120ms so we're not chewing up CPU usage
end;
Wait(130, 850);
if SRL.Dice(15) then // 15% chance of rotating the camera
case SRL.Dice(50) of // 50/50 chance to rotate left or rght by 20-70 degrees
True: Minimap.SetCompassAngle(Minimap.GetCompassAngle() - random(20, 70));
False: Minimap.SetCompassAngle(Minimap.GetCompassAngle() + random(20, 70));
end;
end;
Script logic is key to an efficient and reliable script, and you can take my word for it when I say I've run into nearly every possible scenario that can go wrong. Learn from my mistakes and make use of failsafes when at all possible. For this section the logic is:
- Make sure the depositbox screen is not open, if so close it and exit
- Check our position, if we're too far from the trees web-walk back
- Gather all visible trees, mouse each one (max 4 attempts) until our uptext is found
- Click the tree
- Wait until we've stopped walking
- Wait while chop
Step 5: Deposit the logs
By this point we find the trees and chop 'em until we've a full inventory. So we need a build a method to walk to the depositbox, find & open it, deposit our logs (as well as misc. items such as bird nests). I also find that after handling banking in any script is an appropriate time to do a progress report, so we'll do that here as well.
Simba Code:
(* Deposit the logs *)
procedure TScript.DepositLogs();
var
i: Int32;
begin
if (not RSClient.IsLoggedIn) then Exit;
if (not DepositBox.IsOpen()) then // Is the depositbox already open?
if RSW.GetMyPos().DistanceTo(Self.BankTile) >= 15 then
begin
Self.WriteMsg('Walking to the deposit box');
Minimap.DisableRun();
RSW.WebWalk(Self.BankTile);
Exit;
end;
if (not Self.FindDepositBox()) then Exit;
if MainScreen.IsUpText(['eposit']) then
begin
Inc(Self.LogCount, Inventory.CountItem(Self.Tree.Log)); // Count the logs and save it to our 'LogCount' variable
Mouse.Click(MOUSE_LEFT);
if (not MainScreen.DidRedClick) then Exit;
Minimap.WaitPlayerMoving(200, 3000);
// Wait until the depositbox is open within 4.1 seconds, at an interval of 75ms
if (not WaitUntil(DepositBox.IsOpen(), 75, 4100)) then Exit;
end;
Wait(35, 450);
DepositBox.DepositItem([Self.Tree.Log, DEPOSITBOX_DEPOSIT_ALL], True); // Deposit all of 'Log' TItem, using quantity buttons
Wait(35, 750);
for i:=0 to high(Self.MiscItems) do // Deposit any other misc item (can be defined in TScript.Init()), such as birdnests
if DepositBox.FindItem(Self.MiscItems[i]) then
begin
DepositBox.DepositItem([Self.MiscItems[i], DEPOSITBOX_DEPOSIT_ALL], True);
Wait(35, 250);
end;
DepositBox.Close();
if (not WaitUntil((not DepositBox.IsOpen()), 75, 4100)) then DepositBox.Close(); // Try again?
Wait(175,350);
Self.Report(); // This is a good time to print out a progress report
if (getTimeRunning() > Self.ShutdownTime) then // Check if the script has been running for more than 'MAXRUNTIME'
begin
Logout.ClickLogout(); // If so, logout and terminate the script
TerminateScript('Time to shutdown');
Exit;
end;
end;
No need to include a bit to walk our player back to the trees, if you remember from our TScript.ChopTree() procedure above this is already handled.
Step 6: Initiate and run the script
We're almost there! At this point we just need to define all the variables of the script, do our set-ups and create a main repeating loop the script will run off of.
Simba Code:
(* Our script's main repeating loop *)
procedure TScript.Run();
begin
while RSClient.IsLoggedIn do // While we're logged in do...
begin
if Inventory.IsFull() then // Full inventory, so go deposit logs
Self.DepositLogs()
else
Self.ChopTree(); // Not a full inventory, so chop some trees
Self.DoAB(); // Check if it's a good time to initiate some anti-ban
if (getTimeRunning() > Self.ShutdownTime) then // Time to shutdown?
begin
Logout.ClickLogout();
TerminateScript('Time to shutdown');
Exit;
end;
end;
Self.WriteMsg('Not logged in'); // No info given, so stay logged out
end;
(* Setup our script & variables *)
procedure TScript.Init();
begin
with Self do
begin
DeclarePlayers(); // Don't forget to do this!
SetupAntiban();
RSW.Setup('world'); // Must setup RSWalker as well
RSW.ScreenWalk := False; // True for walking via the mainscreen
RSW.EnableRunAtEnergy := 85; // At 85+ run energy, auto-enable running
MM2MS.ZoomLevel := Options.GetZoomLevel(); // Done just once per session to get zoom level. Needed for MMtoMS conversion
Mouse.Speed := 20; // Mouse speed, 20 seems nice
BankTile := [3995,3508]; // MM tile to walk to for the depositbox
end;
case lowercase(ToStr(TREETYPE)) of // Load tree variables based on the 'TREETYPE'
'willow': // Self-explanatory...
with Self.Tree do
begin
XP := 67;
WalkTile := [4043, 3436];
Color := CTS2(4161909, 1, 0.10, 0.71);
Log := 'Willow logs';
end;
end;
// Setup shutdown time, which is MAXRUNTIME X 60000 (1 minute), with a random +/- 10%
Self.ShutdownTime := (MAXRUNTIME * 60000) + Random(- (MAXRUNTIME * 6000), (MAXRUNTIME * 6000));
end;
You can easily decipher the logic of the script's main loop here:
- While we're logged in...
- If the inventory is full, deposit logs
- If the inventory is not fll, chop trees
- If it's time to shut down, logout and terminate the script
- Perform anti-ban
Aside from that we also do our setup, including defining our script's variables.
Step 7: Putting it all together
We have everything we need for this simple chopping script, now all that's left to do is tell Simba to load the TScript (defined as "Bot") and run it.
Simba Code:
begin
RSClient.Image.Clear(Mainscreen.Bounds); // Always a good idea to clear the RSClient's image, just in case
Bot.Init(); // Setup Bot (our TScript)
Bot.Run(); // Lights, camera, action!
end.
And everything put together:
Simba Code:
program PortSarimChopper;
{$DEFINE SRL_USE_REMOTEINPUT} // Allows us to use the OEM client without taking over mouse & keyboard
{$I SRL-F/OSR.simba} // We'll need the SRL-F include
Type TTreeType = (Willow);
Const
(* Script settings *)
TREETYPE = Willow; // Type of tree to chop (only Willow supported currently)
PERCSHIFT = 16; // Percent pixelshift to be considered 'chopping'
MAXRUNTIME = 75; // Max run time in minutes
(* Player settings *)
PNAME = ''; // Player name
PPASS = ''; // Player password
PPIN = ''; // Player pin (not needed here as we use the deositbox)
(*
Here we add a new type of variable called a 'TTree'
Inside the TTree we'll store useful information
that we can apply to multiple types of trees
*)
Type
TTree = record
XP : Int32;
WalkTile: TPoint;
Color : TCTS2Color;
Log : TRSItem;
Tiles : TPointArray;
end;
(*
Our base record for the script, containing
global variables to be used throughout.
*)
TScript = record
LogCount : Int32;
Tree : TTree;
PrevTile,
BankTile : TPoint;
BankPath,
TreePath : TPointArray;
TreeZones : T2DPointArray;
MiscItems : TRSItemArray;
RSW : TRSWalker;
ShutdownTime: Int64;
end;
(*
Create a single instance of a 'TScript', call it 'Bot'.
*)
Var
Bot: TScript;
(*
Just a neater version of writing debug messages.
*)
procedure TScript.WriteMsg(Message: String);
begin
WriteLn('[Bot]: ', Message);
end;
(*
Always declare your players.
*)
procedure TScript.DeclarePlayers();
begin
Login.AddPlayer(PNAME, PPASS, PPIN, []);
end;
(*
Print out a report of your in-game progress.
Makes use of SRL-F's built-in 'ProgressReport' procedure.
*)
procedure TScript.Report();
var
XpGained:Int32;
begin
XpGained := Max(1,(Self.LogCount*Self.Tree.XP));
(* Let's clean up Simba's output section before printing another progress report *)
ClearDebug();
(* See progreports.simba (Includes/SRL-F/utils/progreports.simba) for reference *)
ProgressReport(RESULT_REPORTBOX, 'Port Sarim Chopper', 'Flight', '1.00',
['Runtime', 'Logs chopped', 'XP gained', 'Until shutdown'],
[SRL.MsToTime(GetTimeRunning, Time_Short),
ToStr(Self.LogCount, '(', Round(Self.LogCount / (GetTimeRunning()/1000/60/60)),' / hr)'),
ToStr(Round(XpGained,2),'(', Round(XpGained / (GetTimeRunning()/1000/60/60)),' / hr)'),
SRL.MsToTime(Self.ShutdownTime-GetTimeRunning, Time_Short)]);
end;
(* Some homegrown anti-ban *)
procedure TMouse.RandomMovement();
var
S: Int32;
begin
S := Self.Speed;
Self.Speed := 4;
Self.Move(Box(Mouse.Position, 75, 75), True, );
Self.Speed := S;
end;
procedure TScript.DoLoseFocus();
begin
Antiban.LoseFocus(SRL.NormalRange(3700,500));
end;
(* Setup our antiban *)
procedure TScript.SetupAntiban();
begin
Antiban.Skills += ERSSKILL.WOODCUTTING;
// Interval Antiban method
Antiban.AddTask(ONE_SECOND*10, @Mouse.RandomMovement);
Antiban.AddTask(ONE_MINUTE*2, @Self.DoLoseFocus);
Antiban.AddTask(ONE_MINUTE*4, @Antiban.HoverMSPlayers);
Antiban.AddTask(ONE_MINUTE*7, @Antiban.RandomRotate);
Antiban.AddTask(ONE_MINUTE*9, @Antiban.HoverSkills);
Antiban.AddBreak(ONE_MINUTE*18, ONE_SECOND*40, 0.2, 0.0);
end;
procedure TScript.DoAB();
begin
Antiban.DismissRandom();
if Antiban.DoAntiban() then
if (not RSClient.IsLoggedIn) then
Login.LoginPlayer();
end;
(* Combination of miss mouse + slowing near the target destination *)
procedure TMouse.HumanMove(Point: TPoint);
var
mPt: TPoint;
S: Int32;
Miss: Double;
Range: Int64;
begin
S := Self.Speed;
Range := Trunc(Power(Self.Position().DistanceTo(Point), 0.80)); // how much possible range to miss
Miss := SRL.SkewedRand(0.9, 0.1, 1.5); // Where miss will happen. 1 = destination (P).
mPt.X := Trunc((1-Miss)*Self.Position().X + Miss*Point.X);
mPt.Y := Trunc((1-Miss)*Self.Position().Y + Miss*Point.Y);
mPt.X += SRL.NormalRange(-Range, Range);
mPt.Y += SRL.NormalRange(-Range, Range);
Self.Move(mPt);
Self.Speed := round(S*0.85);
Self.Move(Point);
Self.Speed := S;
end;
(* Function to gather all available trees of our tree type *)
function TScript.AllAvailableTrees(): TPointArray;
var
TPA: TPointArray;
ATPA: T2DPointArray;
Finder: TRSObjectFinder;
begin
// Uses SRL-OSR's built-in color-finding
// See examples in Includes/SRL-F/docs/images
Finder.Colors += Self.Tree.Color; // Load our tree type's color into the finder
Finder.Grow := 4;
Finder.ClusterDistance := 4;
ATPA := MainScreen.FindObject(Finder); // Finder will spit out a T2DPointArray of any found trees as 'ATPA'
if ATPA.Len < 1 then Exit; // No colors found
for TPA in ATPA do
Result += TPA.Mean(); // For each TPA within the ATPA we'll extract the mean and add it to the result
Result.Sort([Mainscreen.GetPlayerBox.Middle.X, Mainscreen.GetPlayerBox.Y2]); // Now sort the result from our player
end;
(*
Finding the depositbox. By this point you should already
understand how this works.
*)
function TScript.FindDepositBox(): Boolean;
var
TPA: TPointArray;
ATPA: T2DPointArray;
Finder: TRSObjectFinder;
begin
Finder.Colors += CTS2(6189178, 7, 0.06, 0.56);
Finder.Grow := 1;
Finder.ClusterDistance := 3;
ATPA := MainScreen.FindObject(Finder);
if (ATPA.Len > 0) then
begin
ATPA.SortByMiddle(Mainscreen.Center);
for TPA in ATPA do
begin
Mouse.HumanMove(TPA.Mean()); // Right away move the mouse to each TPA mean and check for uptext
if MainScreen.IsUpText(['eposit']) then // Found it, exit and return 'True'
Exit(True);
end;
end;
end;
procedure TScript.ChopTree();
var
i,XP: Int32;
T: TCountdown;
Trees: TPointArray;
begin
// Failsafe...
if DepositBox.IsOpen then
begin
DepositBox.Close();
Exit;
end;
// We're > 25 distance from the tree's 'WalkTile', so let's webwalk back
if RSW.GetMyPos().DistanceTo(Self.Tree.WalkTile) >= 25 then
begin
Self.WriteMsg('Returning to initial spot');
Minimap.EnableRun();
RSW.WebWalk(Self.Tree.WalkTile);
Exit;
end;
// Get all trees of our treetype, stored as a TPA
Trees := Self.AllAvailableTrees();
// So we don't spam move the mouse, let's limit the attempts to a max of 4 movements
for i:=0 to min(3, high(Trees)) do
begin
Mouse.HumanMove(Trees[i]);
if MainScreen.IsUpText('Chop down', 75) then // Found the desired uptext, let's break the loop now
break;
end;
// Never found the uptext, perhars we're too far away
// Webwalk back to the tree's WalkTile
if (not MainScreen.IsUpText('Chop down')) then
begin
Self.WriteMsg('No trees found, returning to initial spot');
RSW.WebWalk(Self.Tree.WalkTile);
Exit;
end;
Mouse.Click(MOUSE_LEFT);
if (not MainScreen.DidRedClick) then Exit;
// Record the value in the XP bar before we begin chopping
XP := XPBar.Read();
// Wait while the player is walking towards the tree
if Minimap.HasFlag(500) then
if WaitUntil(Minimap.IsPlayerMoving(300), 75, 1000) then
Minimap.WaitPlayerMoving(300, 6000);
// Start a countdown timer between 1.6 and 1.8 seconds, begin chopping loop
T.Init(SRL.NormalRange(1600,1800));
// Repeating loop while 'T' is still counting down
while (not T.IsFinished) do
begin
if (not RSClient.IsLoggedIn) then Exit;
if Inventory.IsFull() then break;
if Chat.ClickContinue(False) then
T.Restart;
// The XP bar reads higher than the previous record
// So restart T timer and re-record the our XP bar as XP
if XPBar.Read() > XP then
begin
XP := XPBar.Read();
T.Restart();
end;
// If there's a percent pixelshift (PERCSHIFT) within our player's box
// restart the T timer
if (SRL.PercentShift(MainScreen.GetPlayerBox(), 500) >= PERCSHIFT) then
T.Restart();
Self.DoAB(); // Let's do some anti-ban while chopping
Wait(60,120); // Slow down the loop 60-120ms so we're not chewing up CPU usage
end;
Wait(130, 850);
if SRL.Dice(15) then // 15% chance of rotating the camera
case SRL.Dice(50) of // 50/50 chance to rotate left or rght by 20-70 degrees
True: Minimap.SetCompassAngle(Minimap.GetCompassAngle() - random(20, 70));
False: Minimap.SetCompassAngle(Minimap.GetCompassAngle() + random(20, 70));
end;
end;
(* Deposit the logs *)
procedure TScript.DepositLogs();
var
i: Int32;
begin
if (not RSClient.IsLoggedIn) then Exit;
if (not DepositBox.IsOpen()) then // Is the depositbox already open?
if RSW.GetMyPos().DistanceTo(Self.BankTile) >= 15 then
begin
Self.WriteMsg('Walking to the deposit box');
Minimap.DisableRun();
RSW.WebWalk(Self.BankTile);
Exit;
end;
if (not Self.FindDepositBox()) then Exit;
if MainScreen.IsUpText(['eposit']) then
begin
Inc(Self.LogCount, Inventory.CountItem(Self.Tree.Log)); // Count the logs and save it to our 'LogCount' variable
Mouse.Click(MOUSE_LEFT);
if (not MainScreen.DidRedClick) then Exit;
Minimap.WaitPlayerMoving(200, 3000);
// Wait until the depositbox is open within 4.1 seconds, at an interval of 75ms
if (not WaitUntil(DepositBox.IsOpen(), 75, 4100)) then Exit;
end;
Wait(35, 450);
DepositBox.DepositItem([Self.Tree.Log, DEPOSITBOX_DEPOSIT_ALL], True); // Deposit all of 'Log' TItem, using quantity buttons
Wait(35, 750);
for i:=0 to high(Self.MiscItems) do // Deposit any other misc item (can be defined in TScript.Init()), such as birdnests
if DepositBox.FindItem(Self.MiscItems[i]) then
begin
DepositBox.DepositItem([Self.MiscItems[i], DEPOSITBOX_DEPOSIT_ALL], True);
Wait(35, 250);
end;
DepositBox.Close();
if (not WaitUntil((not DepositBox.IsOpen()), 75, 4100)) then DepositBox.Close(); // Try again?
Wait(175,350);
Self.Report(); // This is a good time to print out a progress report
if (getTimeRunning() > Self.ShutdownTime) then // Check if the script has been running for more than 'MAXRUNTIME'
begin
Logout.ClickLogout(); // If so, logout and terminate the script
TerminateScript('Time to shutdown');
Exit;
end;
end;
(* Our script's main repeating loop *)
procedure TScript.Run();
begin
while RSClient.IsLoggedIn do // While we're logged in do...
begin
if Inventory.IsFull() then // Full inventory, so go deposit logs
Self.DepositLogs()
else
Self.ChopTree(); // Not a full inventory, so chop some trees
Self.DoAB(); // Check if it's a good time to initiate some anti-ban
if (getTimeRunning() > Self.ShutdownTime) then // Time to shutdown?
begin
Logout.ClickLogout();
TerminateScript('Time to shutdown');
Exit;
end;
end;
Self.WriteMsg('Not logged in'); // No info given, so stay logged out
end;
(* Setup our script & variables *)
procedure TScript.Init();
begin
with Self do
begin
DeclarePlayers(); // Don't forget to do this!
SetupAntiban();
RSW.Setup('world'); // Must setup RSWalker as well
RSW.ScreenWalk := False; // True for walking via the mainscreen
RSW.EnableRunAtEnergy := 85; // At 85+ run energy, auto-enable running
MM2MS.ZoomLevel := Options.GetZoomLevel(); // Done just once per session to get zoom level. Needed for MMtoMS conversion
Mouse.Speed := 20; // Mouse speed, 20 seems nice
BankTile := [3995,3508]; // MM tile to walk to for the depositbox
end;
case lowercase(ToStr(TREETYPE)) of // Load tree variables based on the 'TREETYPE'
'willow': // Self-explanatory...
with Self.Tree do
begin
XP := 67;
WalkTile := [4043, 3436];
Color := CTS2(4161909, 1, 0.10, 0.71);
Log := 'Willow logs';
end;
end;
// Setup shutdown time, which is MAXRUNTIME X 60000 (1 minute), with a random +/- 10%
Self.ShutdownTime := (MAXRUNTIME * 60000) + Random(- (MAXRUNTIME * 6000), (MAXRUNTIME * 6000));
end;
begin
RSClient.Image.Clear(Mainscreen.Bounds); // Always a good idea to clear the RSClient's image, just in case
Bot.Init(); // Setup Bot (our TScript)
Bot.Run(); // Lights, camera, action!
end.
This tutorial was just intended to cover some of the basics, and keep in mind this just one of near limitless ways to structure a script. It's not the way to do it, just my way. If you'd like some more examples of SRL-OSR scripts I invite you to SRL-OSR's test scripts (includes/SRL-F/tests). Please do feel free to posts questions or comments and I'll try to help to the best of my ablity.