1. Retired Developer/Moderator
Join Date
Feb 2006
Posts
381
Mentioned
0 Post(s)
Quoted
1 Post(s)

## Falador Iron Miner and Banker

Happy New Year! Below is my first OSRS SIMBA script which is designed to mine iron ore south of Falador and bank it. I put this together using various tutorials around the site and some very dated memories of SCAR from the early 2000s. I just ran it successfully for ~2 hours across ~20 trips but YMMV. There is very little quality-of-life functionality which is what I plan to focus on next. For now, the script is designed to run using the official OSRS app in the "fixed classic" layout. The pick needs to be equipped, the map should be set to the farthest zoom and highest brightness, and you should be facing north. You can start in either the Falador Bank or at the mining site and the script should do the rest. One notable issue is that the script doesn't handle random events. I thought "Antiban.DismissRandom" was meant to identify and dismiss them but I haven't had any luck (but that could just be my implementation).

Thanks all.

EDIT: Just added a progress report below. There was another player also mining while I was there for this and I continually lost out to him so that slowed everything down on a few runs.

Script has been running for: 1 Hours, 43 Minutes and 4 Seconds
You have completed 13 Trips
You have mined 340 iron ore and gained 11900 mining experience.

Code:
program FaladorIronMinerandBanker; //Written for latest SIMBA 32 bit using OSRS official client in fixed classic layout
{$DEFINE SRL_USE_REMOTEINPUT} {$I SRL-D/OSR.simba} //Using the latest development file from github. Downloaded on 12/30/2022.

const
PPIN = '';
PIXEL_SHIFT = 14;   //% shift within the playerbox to be considered "animating"
RS_WORLD   = 430;         //Desired World (-1 = Random)
IS_MEMBER  = false;       //True if your player is a Member
BankBoothLight = 5600910; //If script can't find bank booth, update color
BankBoothDark = 4416636;  //If script can't find bank booth, update color
RockColor = 2700624;      //If script can't find rock, update color
Version = 'Beta v1.0';     //Beta v1.0 as of 1/1/2023

var
Trips,Mined: Int32;
OreColor: TCTS2Color;
BankPath,BankPath2,MiningPath,MiningPath2: TPointArray;
RSW: TRSWalker;

// Script

procedure declarePlayers(); //Taken from Flight
begin
end;

Procedure SetupAB();
begin
end;

Procedure RunAB(); //Taken from Flight
begin
Antiban.DismissRandom();
if Antiban.DoAntiban() then
if (not RSClient.IsLoggedIn) then
end;

Procedure Setup();
begin
RSClient.Image.Clear(Mainscreen.Bounds);
BankPath := [[3721,3445], [3757, 3400], [3797,3355], [3829,3305], [3833,3204], [3833,3159], [3838,3096],[3836,3040],[3836,3053],[3856,3029]];
BankPath2 := [[3716,3448],[3725,3396],[3745,3351],[3806,3335],[3820,3288],[3829,3245],[3836,3192], [3838,3139],[3838,3092],[3833,3040],[3853,3029]];
MiningPath := [[3836,3060],[3838,3112], [3836,3164],[3836,3209],[3829,3256], [3813,3299],[3790,3335],[3764,3380],[3741,3416],[3716,3448],[3692,3488]];
MiningPath2 := [[3845,3065],[3838,3112],[3849,3168],[3820,3200],[3802,3236],[3788,3285],[3773,3328],[3754,3371],[3732,3416],[3709,3465],[3689,3497]];
RSW.Setup('world');
RSW.FancyMouse:= True;
Trips:= 0;
Mined:= 0;
OreColor:= CTS2(RockColor, 5, 0.2, 0.2);
declarePlayers();
if not RSClient.IsLoggedIn then
begin
MainScreen.setHighestPitch;  //Sets the camera angle to the highest point
end;
SetupAB();
Cleardebug();
Writeln('Starting Falador Iron Miner and Banker ', Version);
end;

// Combination of miss mouse + slowing near the target destination borrowed from Flight
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;

Procedure DoMining; //Credit to Slacky for TPA/ATPA tutorial
var
TPA: TPointArray;
ATPA: T2DPointArray;
i: Int32;
Begin
Writeln('Mining for ore.');
MainScreen.setHighestPitch;
While not Inventory.IsFull() do
begin
RunAB();
if SRL.FindColors(TPA, OreColor, MainScreen.Bounds) then
begin
ATPA:= TPA.Cluster(5);
ATPA.FilterSize(15,90);
ATPA.SortbyIndex(MainScreen.Center);
For i:= 0 to high(ATPA) do
begin
Mouse.HumanMove(ATPA[i].Mean());
Wait(200);
if MainScreen.IsUpText('Mine', 200) then
Mouse.Click(MOUSE_LEFT);
if MainScreen.DidRedClick() then
Break;
end;
Minimap.Waitflag(0);
end;
While SRL.GetPixelShift(MainScreen.GetPlayerBox,500) >= PIXEL_SHIFT do  //Pixel shift concept from Flight
begin
Wait(Random(300,600));
RunAB();
end;
end;
Writeln('Finished mining.');
end;

Procedure WalktoBank();
var
myPos: TPoint;
TimeOut: Int32;
begin
Writeln('Beginning walk to bank.');
RunAB();
if Random(0,10)>5 then
begin
RSW.WalkPath(BankPath, Random(5,8));
Minimap.Waitflag(0);
end else
begin
RSW.WalkPath(BankPath2, Random(5,8));
Minimap.Waitflag(0);
end;
myPos:= RSW.GetMyPos();
begin
TimeOut:= 0;
begin
TimeOut:= TimeOut + 1;
myPos:= RSW.GetMyPos();
if TimeOut > 10 then
Break;
end;
if TimeOut > 10 then
begin
Logout.ClickLogout();
TerminateScript('Failed to reach bank. Terminating script.');
end;
end;
end;

Procedure WalktoMine();
var
myPos: TPoint;
begin
Writeln('Beginning walk to mine.');
RunAB();
myPos:= RSW.GetMyPos();
begin
if Random(0,10)>5 then
begin
RSW.WalkPath(MiningPath, Random(1,3));
Minimap.Waitflag(0);
end else
begin
RSW.WalkPath(MiningPath, Random(1,3));
Minimap.Waitflag(0);
end;
end;
end;

function OpenBankBackup(): Boolean; // Original code borrowed from Flight's fisher
var
i,c: Int32;
ATPA: T2DPointArray;
Finder: TRSObjectFinder;
begin
Finder.ColorClusters += [                // Set object bank booth parameters
CTS2(BankBoothLight, 4, 1.11, 1.12), // Light Brown
CTS2(BankBoothDark, 2, 0.15, 1.05),  // Dark Brown
4];
Finder.Grow:= 2;
Finder.ClusterDistance:= 3;
c:= 0;                                   // Set counter to 0
Repeat
if not Bank.IsOpen then
begin
c:= c + 1;
ATPA := MainScreen.FindObject(Finder);
if (ATPA.Len > 0) then
begin
ATPA.SortByMiddle(Mainscreen.Center);
for i:= 0 to high(ATPA) do
begin
Mouse.HumanMove(ATPA[i].Mean());
Wait(100);
if MainScreen.IsUpText(['Bank Bank', 'Bank booth', 'Bank chest', 'eposit']) then
begin
Mouse.Click(MOUSE_LEFT);
Minimap.Waitflag(0);
Wait(500);
end;
if Bank.IsOpen() then
begin
Result:= True;
Exit(True);
end;
end;
end;
end;
until c > 10;
if Bank.IsOpen then
begin
Result:= True;
Exit(True);
end;
if c > 10 then
begin
Result:= False;
Exit(False);
end;
end;

Procedure DoBanking();
var
BankLocation: T2DPointArray;
i,c: int32;
begin
Writeln('Opening bank.');
RunAB();
MainScreen.setHighestPitch;
Mined:= Mined + Inventory.Count();
Trips:= Trips + 1;
c:= 0;
While Inventory.IsFull do
begin
BankLocation.SortByMiddle(Mainscreen.Center);
For i := 0 to high(BankLocation) do
begin
Mouse.HumanMove(BankLocation[i].Mean());
Wait(100);
if MainScreen.IsUpText('Bank ', 200) then
begin
Mouse.Click(MOUSE_LEFT);
Minimap.Waitflag(0);
Wait(500);
end;
if Bank.IsOpen() then
Break;
end;
if Bank.IsOpen() then
begin
Bank.DepositAll();
if random(0,10) >= 5 then
Bank.ClickCloseButton();
Break;
end;
c:= c + 1;
if c > 5 then
begin
if OpenBankBackup() then
begin
Bank.DepositAll();
if random(0,10) >= 5 then
Bank.ClickCloseButton();
Break;
end else
Logout.ClickLogout();
TerminateScript('Failed to open bank. Terminating script.');
end;
end;
end;

Procedure Reporting();
begin
ClearDebug();
Writeln('Script has been running for: ', SRL.TimeRunning(Time_Formal));
Writeln('You have completed ',IntToStr(Trips),' Trips');
Writeln('You have mined ',IntToStr(Mined),' iron ore and gained ',IntToStr(35*Mined),' mining experience.');
Writeln(' ');
end;

begin
Setup();
DoBanking();
WalktoMine();
Repeat
DoMining();
WalktoBank();
DoBanking();
Reporting();
WalktoMine();
until not RSClient.isloggedin();
end.
Last edited by Renax; 01-02-2023 at 04:53 PM.

2. Cool
I think DismissRandom is iffy at best, would probably need to be called many many times in near succession for it to see that there even is a random somewhere.
We dont really dismiss randoms, ignoring them seems to work out just fine.

In my miner, and in most stuff that is released these days (INeedBot, Flight, Torwent), we all usually rely on MM2MS conversion for cases like this, like the ore it can be stored as a coordinate on the world map, and mapped into the mianscreen as a rectangle.

From the script I linked bellow:
Simba Code:
function TMiner.FindOres(): TRectArray;var  i: Int32;  me,pt: TPoint;begin  me := RSW.GetMyPos();  for i:=0 to High(Self.OreLocations) do begin    pt := RSW.WorldToMM(me, Self.OreLocations[i], Minimap.GetCompassAngle(False));    Result += Minimap.PointToMsRect(pt);  end;end;
This goes along with a function that checks if there is minerals in the ore on the go.

Since this is a miningscript, here's my tiny powerminer (pretty much an experiment), it does things in a quite different way than what we usually do regarding antiban. https://pastebin.com/UgPEqvvT - You might find it interesting. It may have a bug or two. I never really aimed to make a finished product, just playing around while bored with some ideas.
Last edited by slacky; 01-02-2023 at 09:11 PM.

3. Retired Developer/Moderator
Join Date
Feb 2006
Posts
381
Mentioned
0 Post(s)
Quoted
1 Post(s)
Thanks, Slacky. I’ll take a look at the location storing concept.

I see your point on the antiban approach in your powerminer. I want to spend a little time playing and monitor what it looks like when I’m actually performing X skill to see how I can build upon the standard techniques. Is Torwent WASP Scripts? I’ll review some of their stuff for pointers also.

EDIT: While you're here, can you please explain the "Self" syntax I see in a lot of scripts? I'm still getting up to speed with the various types / records that are used.
Last edited by Renax; 01-02-2023 at 03:01 PM.

4. Originally Posted by Renax
Thanks, Slacky. I’ll take a look at the location storing concept.

I see your point on the antiban approach in your powerminer. I want to spend a little time playing and monitor what it looks like when I’m actually performing X skill to see how I can build upon the standard techniques. Is Torwent WASP Scripts? I’ll review some of their stuff for pointers also.

EDIT: While you're here, can you please explain the "Self" syntax I see in a lot of scripts? I'm still getting up to speed with the various types / records that are used.
Yeah, Torwent is the owner of wasp scripts, which is where the somewhat more active devs hangs out these days (in the discord).

As for Self, and the record focused script development, the idea is to have as little as possible be global variables, to avoid namingscheme conflicts, and make reuse somewhat easier, hack to even allow for multiple scripts to be included in one script if one ever wanted to.

Self refers to the instance of the record. So say I make
Simba Code:
type TMiner = record  Foo: Int32;  Bar: Int32;  RSW: RSWalker;  end;var  Miner: TMiner;begin  Miner.RSW.Setup('World');  Miner.Foo := 100;  Miner.Bar := 999;end.

Now can make a procedure that works with that Miner-variable:
Simba Code:
function TMiner.DoStuff(): Boolean;begin  if Self.Foo = 100 then //because the functin was called with "Miner"-variable, self is now "Miner".  begin    WriteLn('yey');    Result := True;  end;end;begin  Miner.DoStuff(); //Think DoStuff(Miner); where in the function the variable for miner is Selfend.
Self is now equal to the "Miner" variable. It's basically an invisible parameter to the function that refers to whatever instance the function was called with.
>>> Miner.DoStuff();

So Miner is passed to the function, as Self. So all it's variables are accessable though the usage of Self. Tbh, you dont have to be explicit about using Self, you can technically, even though I consider this bad practice do:
Simba Code:
function TMiner.DoStuff(): Boolean;begin  if Foo = 100 then //Self is now used implicitly.  begin    WriteLn('yey');    Result := True;  end;end;

Edit: here are some githubs:
https://github.com/ineedbots/srl-osr-scripts
https://github.com/Torwent/wasp-free

Edit2: As for the activity of the forums, which you mentioned in another thread, yes.. it's quite dead. Most sharing and talk happens in discord, in particular the wasp discord. And still, it's not that much scripting, not that many active active devs anymore. The demand is still there though, but the demand has done from "I want a miner" to "I want a complex minigame script" pretty much.
Last edited by slacky; 01-03-2023 at 02:12 AM.

5. Retired Developer/Moderator
Join Date
Feb 2006
Posts
381
Mentioned
0 Post(s)
Quoted
1 Post(s)
Got it. This is starting to become clearer on the second read-through. I appreciate the explanation.

I stumbled on the Discords for wasp/SRL and you're right it looks like there is more activity there. The Sythe forums also look like they still get a decent amount of traffic (of what kind, who knows).

The includes have come such a long way. In just a few days I've got my own little miner running for hours in multiple locations. The team has really done all the leg work in building the infrastructure. I would have thought this would have made scripting more popular now that it's more accessible. But, it could also just be more accessible because I'm not 12 anymore...

I've made some tweaks to the miner I posted, including toying with my own random dimisser and adding support for coal mining in Lumbridge swamp. I want to spend more time with the MM to MS tile concept though. I didn't quite get it on my first attempt and I but I also saw wasp writing about it in one of his discord tutorials so I want to get it right. I also just discovered the ACA/debug tool built into Simba - game changer!

Anyway, thanks again for the tips! I've got plenty to keep busy / learn from. I forgot how fun just building this stuff yourself (or trying to..) can be.