i pro leechin'
07-22-2008, 11:21 AM
http://img154.imageshack.us/img154/8119/tuts4nubsaq4.png
Table of Contents
Chp 1. Basic things you should know. (My first script).
Chp.2. Standards.
Chp.3. FailSafes
Chp.4. MultiPlayer
Chp.5. Bitmaps
Chp.6. Dtms
Chp.7. Anti Ban
Chp.8. Anti Randoms
Chp.9. Walking
Chp.10. TPAs/Tboxes
Basic things EVERYONE should know
Okay, so welcome. You’ve made your first step to become a scripter, or even an srl member. Which is no easy task to do. But if you are able to read, and understand all of the below then you’ll get in easy. Just don’t be surprised if they think your script has been stolen when it’s too good though! *coughs*.
Okay, so first I’ll just talk about the basics of scar. Open up scar, and you will be greeted with :
program New;
begin
end.
So, nothing complex. The program ‘New’; is the name of the program, this can be ANYTHING you want, ie,
program ProMiner;
But remember it must contain no spaces. The:
Begin
End.
Is your main loop, this means the core of your script will be between these begins and end. That is ‘begin’ core st00f ere ‘end.’ This however, does not mean you must write 5000 lines of code between this begin and end. We can add functions, and procedures elsewhere to the script. More on that later.
Okay, also notice that to add ‘comments’ to your script you can either use
Begin // This would be a comment, after the 2 slash, this will not be counted in the script!
Procedure; // Therefore this would be a procedure using a hawt comment. Try to notice the semi-colon placed after procedure.
End. //Please note the full stop, as this is important.
Okay, so I’ve decided for our very first script we shall write a nice simple script which will serve no purpose other than this tutorial. This will be a simple debug spammer :D Which will double up as a proggie I suppose. A proggie is a progress report, which will display the details of the script as it has been running.
As before the layout of a brand new scar page is
program New;
begin
end.
So we should space out this to make it easier on our eyes:
program RandomScript; //As you can see I’ve named this program.
Begin
end.
Now, we shall use the mainloop to call a procedure. A procedure is basically, a section of a script which can be called upon many times. This is how one would be declared:
Procedure Name;
Begin
End; // Notice the semi colon,
//as all procedures and function
// will have this at the end, while the main loop will finish with a fullstop.
So as we’re writing some sort of progresss report, we should use the procedure
Writeln(s :string);
This will write the debug.
Wtf, how do I use that pl0x
Somehow, I knew you would ask that. Let’s break it down
Name(); // This will always be all you call apon srl functions or procedures which contain user imput.
//So let’s take writeln
Writeln(); // In our procedure we will use this, then we look at the inside of the writeln procedure
// as it is ‘s :string’ this means that writeln requires a string, Which is a sequence of characters and numbers
// which will be contained within quotation marks.
//Therefore we should use
Writeln(‘String’);
If we were to use this in our main loop, in our debug menu, String would occur once the script has been ran.
So placing this into our procedure of
procedure hello; // Called the procedure Hello
begin
Writeln('lol'); // Change ‘lol’ to Anything you so desire.
end;
This would mean our script would look like :
program script;
procedure hello;
begin
Writeln('lol');
end;
begin
End.
But, when you anxiously ran the script, you noticed that it infact did not put ‘lol’ into the debug , Oh noez, I heard you cry. This can be easily solved, and explained. We haven’t called it in our main loop!. Now I bet you feel silly for that huh?! XD
This would mean our script will look like this :
program script;
procedure hello;
begin
Writeln('lol');
end;
begin
hello;
End.
Yay, great.
Now to improve on this, simply writing ‘lol’ to debug, ain’t gonna help no onez. Pretend we wanted to make a progress report for a simple miner, this would require us to add the variable ‘OresMined’, in order to keep track of what we have mined! Just because we’re a beginner, we’ll also add a constant of the ore name. Below is how they are declared.
Variable :
program Variable;
var
OresMined : Integer; // And integer is just a whole number, ie, doesn't contain a decimal point :P
begin
end.
Constant :
program Constant;
Const
OreType = 'Coal'; // Notice it is a string
begin
end.
And together it is simply:
Var
OresMined : Integer;
Const
OreType = ‘Coal’;
Now, back to our script after we have added the Varibale and constant to our script, we would hopefully want to write the amount of OresMined, and the OreType :
program script;
Var
OresMined : Integer;
Const
OreType = 'Coal';
procedure hello;
begin
Writeln('You have mined ' + IntToStr(OresMined) + ' ores.');// Notice IntToStr, as i explained earlier
// writeln requires a string to write to debug. IntToStr, turns the variable, OresMined
// (which is an Int(eger), into a string. The '+' sign concatenates the information together.
Writeln('You also decided to mine ' + OreType); // Notice as OreType is already a string!
// Nothing is required to convert it into a string =)
end;
begin
hello;
End.
This will output:
You have mined 0 ores.
You also decided to mine Coal
Wahey. I should really tell you how to add to the value of the OresMined, and you can do so by doing:
OresMined := 300;
More on that later.
Okay, so nice and simple. For the purpose of the script we will add a loop. A loop just… Loops ! We can make one by doing
Repeat
Procedures;
Until(false);
Obviously, until ‘false’ is a bad, bad idea. But since this is only our first script I will correct this later!
We shall now add this into our script. Notice the ‘wait’ function.
program script;
Var
OresMined : Integer;
Const
OreType = 'Coal';
procedure hello;
begin
Oresmined := 300;
Writeln('You have mined ' + IntToStr(OresMined) + ' ores.');// Notice IntToStr, as i explained earlier
// writeln requires a string to write to debug. IntToStr, turns the variable
// OresMined, (which is an Int(eger), into a string. The '+' sign concatenates the information together.
Writeln('You also decided to mine ' + OreType); // Notice as OreType is already a string!
//Nothing is required to convert it into a string =)
end;
begin
repeat
wait(1000+random(200)); // This will first wait 1 second, or 1000 miliseconds
// then a random 0.2 seconds.
//This isn't required, but it's good practice.
hello;
until(false);
End.
This will continually spam your debug menu. So we will make use of these functions to add spice to our script.
inc(TotalProggies); // This adds one to our total progress reports
ClearDebug; // Deletes the current debug text ;o!
TimeRunning; // This is an srl function, therefore we will need to include the srl :0
Before I show you the finished product, to use TimeRunning, I said this requires the SRL. Look below on how to do so :
program SRL;
{.include SRL/SRL.Scar} // Will always occur underneath Program
Begin
end.
This would leave our final script as :
program script;
{.include SRL/SRL.Scar}
Var
OresMined,TotalProggies : Integer;
Const
OreType = 'Coal';
procedure hello;
begin
inc(TotalProggies); // This adds one to our total progress reports
ClearDebug; // Deletes the current debug text ;o!
Writeln('We have spammed j00 debug '+ inttostr(TotalProggies) + ' times.');
WriteLn(TimeRunning);
Writeln('You have mined ' + IntToStr(OresMined) + ' ores.');// Notice IntToStr, as i explained earlier
// writeln requires a string to write to debug. IntToStr, turns the variable, OresMined
//(which is an Int(eger), into a string. The '+' sign concatenates the information together.
Writeln('You also decided to mine ' + OreType); // Notice as OreType is already a string!
// Nothing is required to convert it into a string =)
end;
begin
repeat
wait(1000+random(200)); // This will first wait 1 second, or 1000 miliseconds
// then a random 0.2 seconds.
//This isn't required, but it's good practice.
hello;
until(false);
End.
Nice and easy =)!
Standards
I was forced to ask how to write this section, as it’s a part of scripting which is usually neglected, yet highly appreciated if done correctly.
A wise man called 3garrett3 once said, however,
“Don’t have sucky standards,
Or a one armed hooker named Steve will get you.”
Follow these wise words, and you will do well.
--------
Say you have completed a nice little procedure, but you can’t make heads or tails out of the errors it’s giving to you when you try to compile, must likely it’s your standards. Although poor standards won’t make a difference when compiling, it’s more helpful to the scripter to know exactly what’s happening, and more importantly to others.
You should know these key words
Indenting : You can achieve this by using the Tab key:
http://img367.imageshack.us/img367/8247/tabxn5.png
Backspacing This can be achieved by using shift + tab, this will be the opposite of indenting.
Global vars [/i] Global vars, not specifically standards, but these are the vars declared at the start ie :
Program New; var x,y;
Global vars should only be used when needed, such as dtms. In such cases Dtm’s should be declared as
var dtmTrout:integer;
[u]Local vars These are declared locally in a procedure / function such as
procedure Jesus;
Var
I : integer;
Begin
End;
------
Okay, now onto the actual standards.
Begin statements will occur on their own line, and the end statement will occur on the same line, even when nesting occurs. Example:
Begin
If(condition) then
If(condition) then
Begin
Writeln(‘lol’);
End;
End;
Do not use two or more statements on a single line
Use semi-colons at the ends of lines
Use spaces after commas, and Mathematical related signs
Jesus := (a + b) * (j + c) * 4;
With more ‘stuff’ that would be:
program New;
var
g:extended;
begin
g:= (pow(300,12) * (30 + 30));
writeln(floattostr(g));
end.
Don’t use spaces after parenthesis. Look at above example.
Try to name functions, vars, procedures relevantly. Ie -> dtmTrout, FindTheTrout.
Routine names should always contain capital letters at the beginning.
Procedure Jesus;
After var, there should be indentation when declaing vars
[scar]
Var
Nesting
Nesting is …
If(condition) then
If(condition) then
If(condition) then
Begin
Result:=10;
Exit;
End
Basically this is nesting :P My English is bad so I can’t put it in words sadly, but that is nesting, It’s used a lot in autocolouring etc etc:
{************************************************* ******************************
function FindWaterColor: Integer;
By: Tarajunky
Description: Autodetects Water Color on Minimap
************************************************** *****************************}
function FindWaterColor: Integer;
var
GC, a, l, TestColor, Red, Green, Blue : integer;
var
P:array of Tpoint;
begin
GC := 12095356;
Flag;
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 60);
l:=GetArrayLength(P);
for a:= 0 to l-1 do
begin
if rs_OnMinimap(P[a].x,P[a].y) then
begin
TestColor := GetColor(P[a].x,P[a].y);
if SimilarColors(TestColor,GC,50) then
begin
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Blue - Green, 5, 10) then // Notice LOTS of nesting, Rwar!
if InRange(Green - Red, 18, 26) then
if InRange(Blue - Red, 55, 72) then
if GetColor(P[a].x + 2, P[a].y + 2) = TestColor then
if GetColor(P[a].x + 1, P[a].y + 1) = TestColor then
if GetColor(P[a].x, P[a].y + 2) = TestColor then
if GetColor(P[a].x + 2, P[a].y) = TestColor then
if GetColor(P[a].x, P[a].y + 1) = TestColor then
if GetColor(P[a].x + 1, P[a].y) = TestColor then
if GetColor(P[a].x + 2, P[a].y + 1) = TestColor then
if GetColor(P[a].x + 1, P[a].y + 2) = TestColor then
begin
Result := TestColor;
WaterColor := TestColor;
WriteLn('WaterColor = ' + IntToStr(TestColor));
Exit;
end;
end;
end;
end;
WriteLn('Could not find Water Color!');
Result := 0;
end;
Fail Safes
What’s a failsafe?
Breaking out of Endless loops.
Other methods of doing the same thing, if one fails.
For the first on the list.
Breaking out of Endless loops
In our first script, we used
Repeat
Something;
Until(false);
Well this is EXTREMELY bad :P!
Okay, pretend we had this script :
begin
repeat
MineOres;
Until(false);
End.
So, seems okay at first sight. It’ll just endless MineOres, yea? That’s exactly why it fails. What if there’s lag, causing you to log out. What if there’s a system update. Etc etc. Take a look at this example also
Begin
Repeat
Wait(30+random(70))
Until(GetColor(400,400)=255);
End.
So it will wait until… Let’s pretend a random screen or something, I dunno :P!
So how do you Improve this?
There are lots of different ways of doing so.
Simple break functions, such as If not logged in.
Counter
Marktime
If statements
Check if logged in
This is the easiest most reliable in my opinion.
Procedure Bob;
Begin
if not LoggedIn then exit;
wait(300000);
end;
As you can see it will simply exist the procedure if you are not logged in, which is extremely useful.
It’d be useful to note this also
If not LoggedIn then Break; // Break from loops etc
Counters
Okay, counters rely on vars, and checking the amount of times a loop has occurred. For instance, if we had the Random screen opening example:
Var
I : integer; // We declare the var I, to count the amount of loops, it’s already set as one.
Begin
Repeat
Inc(I); // Adds one to Var I
Wait(30+random(70))
Until(GetColor(400,400)=255) or (I > 10); // Will break out of the loop after 10 loops
End.
Mark Time
This involves the usage of
MarkTime(Time);
TimeFromMark(Time);
Extremely easy to use:
procedure WaitForWindow;
var
MarkedTime: integer;
begin
if not LoggedIn then exit;
MarkTime(MarkedTime);
repeat
wait(30+random(30));
until(GetColor(400,400)=255) or (TimeFromMark(MarkedTime) > 10000); // Checks if time from mark is more than 10 seconds
end;
If statements
Obviously these are extremely useful, say you have decided to do
Procedure GetPick;
begin
FindDtm(Pick, x, y, MIX1,MIY1,MIX2,MIY2);
mouse(x, y, 5, 5, true);
wait(300);
end;
Firstly, this assuming the dtm has not been found. It will not store the x,y cords for us to use, therefore x,y = 0. Then it will click 0,0 with a randomness of 5,5. So, we firstly won’t have clicked the pick, assuming that we have one and the dtm just failed. Then it will click the corner of rs = BAN.
We can easily solve this by adding the if statement :
Procedure GetPick;
begin
if( FindDtm(Pick, x, y, MIX1,MIY1,MIX2,MIY2)) then // This is how If statements are declared If….. Then
begin // We want to execute an entire chunk of code not just one line. One line would suffice, but for the purposes of this.
mouse(x, y, 5, 5, true);
writeln(‘Pick found’);
wait(300);
end;
end;
This says, IF, the dtm is found. Execute whatever we needed (Clicking and waiting);
MultiPlayer
Multiplayer is extremely useful, and easy. This allows…Multiple users to perform tasks 24/7 without ban, usually :p
NextPlayer
Extremely useful,
NextPlayer ( True ) - This will switch players and will leave the current player active.
NextPlayer ( False ) - This will switch players and will switch the current player to not active.
We may have all seen this before:
procedure Declareplayers;
begin
NumberOfPlayers(2); // Players
CurrentPlayer := 0;
Players[0].Name := 'Username'; // Player Name
Players[0].Pass := ''; // Player Pass
Players[0].Nick := 'ame';
Players[0].Active := true; // Is this player active? (True / False)
end;
But you’ve never wondered how to get different characters? That’s when Nextplayer comes in use, ie, say in your script you’ve got
If(not(radialwalk….)) then
NextPlayer(False);
This will allow the next player to become active, leaving the current as false. This is extremely usefull for tracking the amount of ores a player has mined ie:
Procedure mining;
Begin
If(MinedOre) then // Checks if mined ore = true
Players[CurrentPlayer].Integers[0]; // Will add 1 to the current player array, we assume for this demonstration this was infact our mining Integer :P
End;
This should also be added to our main loop :
begin
SetupSRL;
ActivateClient;
DeclarePlayers;
repeat
repeat
Mining;
Dropping;
until (Loads >= LoadsToDo) or (not LoggedIn)
NextPlayer(Players[CurrentPlayer].Active);
until (False);
end.
Bitmaps
Bitmaps
Bitmaps are useful for item finding, including for inventory and banking. Not so much useful for Main screen things however. A bitmap is basically just a graphic image which is composed of dots, or pixels.
With that in mind, let’s get started.
Firstly, you should screen shot your Runescape client, then you should crop the image to only show the object which you want to find. In this case I have cropped it to show only a tinderbox. (If you don’t know how to crop with MsPaint, then give up).
http://img166.imageshack.us/img166/2470/firstpe0.png
In order to make it more accurate, we want scar to not search for colours, so we shall make the background black.
http://img166.imageshack.us/img166/8107/2ndup8.png
Once this has been done, we should copy the image. Next, open scar. Select:
http://img179.imageshack.us/img179/3273/scarko4.png
Wait(50);
Then,
http://img440.imageshack.us/img440/1986/scar2wx4.png
Press okay. Then your debug menu should be filled with something like :
Tinderbox := BitmapFromString(33, 35, 'beNrtVltvEkEYnUWELWJ' +
'CDPJs+mR8aNCkMcYLs7gV2kBZENptU+zMAsIGKbctUkSyIWjV qA/G' +
'H+zZTqX4oOHSPpgwOSHLZc6Z73yXgZDlWq4Zl3SGK1z02ZOYG k0lt' +
'y6RE4T0lp+GgjGVblCa0zQtmoiqdEEr8ns7u9l0LpOieqbI8q 8Lhw' +
'AeGNXxOUKA7iL8xqt9AJzVcqFWKdXflPEAQCKva0JCVSLzsdf Mksl' +
'568i0GlWg06q1DBNvzRIHP3T1dBahzScBQlCBs2vxfrc96B3j tWvV' +
'K0UnBEQE/sMDPZPVMqnEWa5nLaqmTCzbTWwPsW0yHJwQq2w1cPKCW' +
'eQiBbAIClGqzFe0Q9fJ19Php9FgZL8j3eNep+lYdGTCN8YVPX njIO' +
'3nOX9p7yZ0YdocUdikLfhx/l7rgh8Wbas+4OWmTwiRbhvfQiWxFZt' +
'JwtVrCn6koNsoIC+oonhkxYFb/kNFI/3fKrMWqt1/C2A7DcvPH5/j' +
'XCWycqGiyLARZQAoTvdNaxdjPIoWdhPi86yHvdJ9MlahE0KIi BJZ2' +
'/Q1GrzTKhESDN0OTj3WqjgVOjp8zxO+43m67hUYC01GBIhMrcqu 6S' +
'UCLscobERbQeVh2Ps3FfrA4RedshrwTW9UMHANRYt0Yy+RXZA Yq0y' +
'ahiyjU/Ab9CBC9l0ns0hIP79/Rt066aaqCGQyFhQYnESlFdkG2hz8' +
'+7vZORrQtqWR7SKMVxg3jHSRJY3tOKPUapiGwVmRow0pje9o8 ZyDF' +
'/PNWKd07Z5oENHjcMaZjSUO8zGdGFOQiwUuPgluyB7ycfhe9Agk WI' +
'XDfJBjhsOfxW/VH99OA0QSF4SYrqoSwqy43GsUh/zywcY8cYaJVad' +
'rd6/6z8ByLde/l/Jo7b+P4RdywhvG');
Congratulations on creating a bitmap.
Searching for a bitmap
There are many functions for searching for a bitmap. But we should obviously declare the Bitmap as local, for this example.
procedure TinderboxExample;
var
Tinderbox : Integer;
begin
Tinderbox := BitmapFromString(33, 35, 'beNrtVltvEkEYnUWELWJ' +
'CDPJs+mR8aNCkMcYLs7gV2kBZENptU+zMAsIGKbctUkSyIWjV qA/G' +
'H+zZTqX4oOHSPpgwOSHLZc6Z73yXgZDlWq4Zl3SGK1z02ZOYG k0lt' +
'y6RE4T0lp+GgjGVblCa0zQtmoiqdEEr8ns7u9l0LpOieqbI8q 8Lhw' +
'AeGNXxOUKA7iL8xqt9AJzVcqFWKdXflPEAQCKva0JCVSLzsdf Mksl' +
'568i0GlWg06q1DBNvzRIHP3T1dBahzScBQlCBs2vxfrc96B3j tWvV' +
'K0UnBEQE/sMDPZPVMqnEWa5nLaqmTCzbTWwPsW0yHJwQq2w1cPKCW' +
'eQiBbAIClGqzFe0Q9fJ19Php9FgZL8j3eNep+lYdGTCN8YVPX njIO' +
'3nOX9p7yZ0YdocUdikLfhx/l7rgh8Wbas+4OWmTwiRbhvfQiWxFZt' +
'JwtVrCn6koNsoIC+oonhkxYFb/kNFI/3fKrMWqt1/C2A7DcvPH5/j' +
'XCWycqGiyLARZQAoTvdNaxdjPIoWdhPi86yHvdJ9MlahE0KIi BJZ2' +
'/Q1GrzTKhESDN0OTj3WqjgVOjp8zxO+43m67hUYC01GBIhMrcqu 6S' +
'UCLscobERbQeVh2Ps3FfrA4RedshrwTW9UMHANRYt0Yy+RXZA Yq0y' +
'ahiyjU/Ab9CBC9l0ns0hIP79/Rt066aaqCGQyFhQYnESlFdkG2hz8' +
'+7vZORrQtqWR7SKMVxg3jHSRJY3tOKPUapiGwVmRow0pje9o8 ZyDF' +
'/PNWKd07Z5oENHjcMaZjSUO8zGdGFOQiwUuPgluyB7ycfhe9Agk WI' +
'XDfJBjhsOfxW/VH99OA0QSF4SYrqoSwqy43GsUh/zywcY8cYaJVad' +
'rd6/6z8ByLde/l/Jo7b+P4RdywhvG');
if(FindBitmap(x, y, Tinderbox))then // if found... -.-
begin
Mouse(x, y, 1, 1, true);
end;
freebitmap(Tinderbox); // Always remember to do so.
end;
Also remember to free bitmaps, as it will stop memory leaks.
Take a look at :
function FindBitmap(bitmap: Integer; var x, y: Integer): Boolean;
Search for the bitmap in client window. If found coordinates are returned in x,y. bitmap contains handle to bitmap generated by LoadBitmap.
function FindBitmapIn(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer): Boolean;
Search for the bitmap in coordinates specified by x1, y1, x2, y2. bitmap contains handle to bitmap generated by LoadBitmap.
function FindBitmapToleranceIn(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer; tolerance: Integer): Boolean;
Works like FindBitmapIn but with a tolerance parameter for finding any similar colored bitmap.
Tolerance is used to find a colored bitmap in range of the bitmap you are looking for.
The greater color range you want, the higher the tolerance parameter should be.
function
FindBitmapSpiral(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer): Boolean;
Search for the bitmap in coordinates specified by x1, y1, x2, y2 starting from x, y. bitmap contains handle to bitmap generated by LoadBitmap.
function FindBitmapSpiralTolerance(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer; Tolerance: Integer): Boolean;
Works like FindBitmapSpiral but with a tolerance parameter for finding any similar colored bitmap.
Tolerance is used to find a colored bitmap in range of the bitmap you are looking for.
The greater color range you want, the higher the tolerance parameter should be.
function
FindBitmapMaskTolerance(mask: Integer; var x, y: Integer; x1, y1, x2, y2: Integer; Tolerance, ContourTolerance: Integer): Boolean;
Essentially it works like FindBitmapIn except it identifies using the masks/shape of an object in the bitmap.
Masks are specified by the colors black and white.
ContourTolerance is the minimal tolerance for color difference between shape of a mask and the background in a bitmap,
It makes sure the shape differs from the background.
<-- sample mask for finding letter A in any color.
^ Found by pressing f1 in scar
DTM’s
Everyone at point should be able to include the usage of DTM’s in their script. DTM, being the acryonym for: Dormed Template mesh.
DTM’s are useful for item finding. For instance, if we wanted to check if we have a log in our inventory, we’d simply do
if findDTM(DtmOfLog,x,y,MIX1,MIY1,MIX2,MIY2)) then result:=true;
Sounds easy enough huh? But how would someone go about making a DTM? Easy! Scar has enabled us to create DTM’s easily, and Jagex has helped us also by making the outlines of objects a constant colour. How nice!
Due to using the example of a log earlier, I’ve decided to make a dtm of … Trout (Thanks drizzt). This might be useful in a cooking situation where you’re waiting to see if the last spot in your inventory, is infact a cooked trout.
First, you should attempt to open up the handy-dandy dtm editor in scar:
http://img507.imageshack.us/img507/9967/firstmv6.png
Once you have achieved this, a picture such as this should appear (assuming you’re logged in, and have the item in the first place).
http://img521.imageshack.us/img521/3986/23741615ps6.png
Now, select a main point, this is the point of x,y which is returned if a dtm is successfully found! (If you look closely there is a red dot)
http://img75.imageshack.us/img75/3237/51295337ds3.png
You should now go ahead and select this as your mainpoint, and select a tolerance of 10-20.
http://img149.imageshack.us/img149/3972/44385883rn6.png
You should now attempt to click on 5-10 places which are black on the object, use the large picture in the top left if you are unsure. Be sure to check if the point is infact black also! (The color should be : 65536, if not delete the subpoint and select another).
http://img172.imageshack.us/img172/9107/56319321zs3.png
Your trout / item should now look like :
http://img509.imageshack.us/img509/710/44305557wq2.png
Now, go to File > Save > And name it however you like.
Close and reopen the dtm editor, which should be showing runescape and your inventory and do :
http://img378.imageshack.us/img378/7627/71533675ck6.png
Select the saved file, and assuming you have done your dtm correctly you should get the message:
Yay? :\ If not repeat the steps, or tell me if I’ve said something wrong, ahhh!
Now all you need to do is click File > DTM to text. And in your Scar message box something like this should appear:
http://img172.imageshack.us/img172/4696/22299983ur9.png
But sir, how do we test for dtms?
Simply put, I dunno. I’ll refer you to my clever owl.
http://img59.imageshack.us/img59/6598/owlloleu7.png
Obviously the dtm should be declared, for instance this script example
program New;
{.include SRL/SRL.Scar}
var
x, y, troutdtm: integer;
procedure Dtm;
begin
Trout := DTMFromString('78DA633CC0C4C0B09F9101197415E733700 16' +
'99828E356A09A13A86A60B270353B806AF611507306A86613 116A' +
'7610507310A8E6307E350079140A92');
end;
begin
setupsrl;
dtm;
if(FindDtm(trout,x,y,MIX1,MIY1,MIX2,MIY2)) then
mmouse(x,y,5,5);
freedtm(trout);
end.
Although this doesn’t fill the first intention of finding if the last slot of our invent Is a dtm of a cooked trout, this is why we can always change
if(FindDtm(trout,x,y,MIX1,MIY1,MIX2,MIY2)) then
Into..
if(FindDtm(trout,x,y,689,430,723,460)) then
Of course I’ll explain a better method later, but for now this is the best you can do :P!
This is the end of the tutorial for dtms goodluck =)
Anti Ban
Antiban, is EXTREMELY easy, but is sometimes over looked. Antiban, is basically, human dumbness :D. This includes things such as waiting long lengths of times, boredom, misclicking etc etc. In most cases Antiban is called by using a procedure, with a case. Look at the example below:
Procedure ProAntiban;
begin
if(not(LoggedIn))then
Exit;
case Random(11) of // Picks a random number for the case 0-11
0,1,2,3 : begin // If the number is 0-3 then will begin this.
HoverSkill('Random', false); //Hovers a random skill
wait(2000+Random(500)); //Will wait 2-2.5 secs.
end;
end;
Before we go on I advice to look at : Srl/Core/Antiban.scar
Okay, now basically we should add more options to the case, from selecting random functions, or procedures from Antiban.scar I have come up with:
Procedure ProAntiban;
begin
if not LoggedIn then Exit;
case 6+random(10) of //Will alow antiban to sometimes never occur
0 : HoverSkill('Random', false);
1: PickUpMouse;
2: AlmostLogOut;
3: BoredHuman;
4,5: begin
MakeCompass('N');
wait(10+random(5));
MakeCompass('S');
wait(10+random(5));
MakeCompass('N');
end;
end;
wait(30+random(30);
end;
Obviously this can be improved on, a lot :P
So you’d plunk this procedure in random places in your script, ie, if it was a mining script, during mining, or whilst waiting for an ore respawn =)
Another thing I like to add in my scripts, is a lot of difference while waiting, in most scripts you’ll see:
Wait(30+random(70));
This sadly does not cut it for me, at all! Firstly that’s a lot of writing, secondly, after 5-10 hours of running a script you’ll most likely have reached all the difference in waits you can, 30-100 :P ie, jagex will know you’re botting. So I came up with sWait, which I feel is far more… ‘Random’ =)
function sWait(number: integer): boolean;
var
i, j, k, l: integer;
begin
j := (number + 10);
k := random(3) + 1; // if random = 0 / 0 = fail, so + 1.
l := random(4) + 1;
for i := 1 to k do
j := j + (j / l);
wait(j);
end;
It’s not even complex, but it is extremely useful, as in the longrun, I write less, and also it will be improved antiban :O zomg, and can reach from a small number to an extremely big number some times ;o. Used like so,
sWait(100);
Other things to add, as I mentioned before, would be to incoperate human dumbness. Ie, forgetfulness. Take a look at this,
function MightRun(Percent, Chance: Integer; where: boolean): Boolean;
var
Energy: Integer;
C0lor: string;
begin
if (not (LoggedIn)) then
Exit;
Energy := GetMMLevels('run', C0lor);
if Energy > Percent then
begin
case Random(Chance) of
1, 2, 3:
begin
gametab(11);
wait(500 + random(500));
SetRun(where);
end;
end;
end;
end;
This is extremely useful while running, and how humans ‘forget’ to run true / false.
Anti Randoms
Adding Anti Randoms to your script is EXTREMELY easy. You don’t even need to write advanced functions thanks to SRL, this is how you should use it :
FindNormalRandoms
If you’ve ever seen FindFastRandoms, don’t ever use this, lol. It’s an extremely old now not needed function / procedure (Can’t remember). Antirandoms is extremely easy, but ‘noobs’ get confused about it. I don’t understand why, but there you go. Sorry about this being so short, lol :S.
Places to call this would be after Bone burying, dropping ores, after eating food and closing windows (banks, shops). Try not to check for Randoms during walking… Because I’ve forgotten how to do so =\
Walking
Radial Walking
Understanding Radial Walking is extremely easy. It relies on a colour, a radius and a limit of degrees. This is the function :
RadialWalk(TheColor: Integer; StartRadial, EndRadial: Integer; Radius: Integer; Xmod, Ymod: Integer): Boolean;
The only ‘complicated’ bit of this may be the start, and end radial. The colour, and Xmod, Ymod are easily explained so I’ll tell you about that after the Start and End Radials.
Okay, to explain this I’ll have to give an example of when you might be able to use it. Assume you need to get out of lumby, you would radial walk the road colour, in order to get to the bridge or something.
http://img392.imageshack.us/img392/2718/firstys5.png
So in the picture below, familiar Lumbridge. Now, imagine a compass over it.
http://img292.imageshack.us/img292/4425/2ndjw7.png
Okay, as you can clearly see we’d need to choose A starting and ending of points between North and South, or, 0-180 degrees. Now, placing slightly more accurate degrees over this:
http://img388.imageshack.us/img388/4171/3rdjf5.png
Okay, so assume we picked a starting radial of 45 degrees, and an ending radial of 90 degrees, It would scan like this:
http://img292.imageshack.us/img292/5780/fifthvl4.png
Basically, it’s ‘trial and error’, although we know we need between points x-y, it might not always work as we plan.
If all this is confusing to you, and you don’t know how radials work then, do not fear there is always Yakman’s RadialWalkerAid:
program RadialWalkerAid;
{
RADIAL WALKER AID by YAKMAN
This is a utility which helps people use Radial Walk.
There are Four Functions of this script.
The first function shows the Radial and Radius of a point
when you move the mouse over the MiniMap. It will also show the Radial
with 360 added, so it can be used for walking upwards.
For Example, when you move the mouse above the center, it will show
a radial of 0 and a radius of around 40.
The second function Draws the Path which RadialWalk takes when you input
the StartRadial, EndRadial, Radius and press the 'Show Path' Button
For Example, if you put StartRadial=90 EndRadial=180 and Radius=50
it will draw a arc in the lower right 50 pixels from the center
moving inwards until it reaches the center.
Both these Functions can have their color changed using the DropDown
Menu, the choises are Red, Blue and Green.
Pressing the 'Clear Box' button will remove all the marks and leave
an empty minimap.
The first Function can be Disabled by UnChecking the 'Drawing Radial'
checkbox.
The thrid function is used by clicking the 'Capture From Client' button
it copys the area from the RS Minimap and displays it on the form.
This can be used now with the first and second functions.
The fourth function is activated by checking the Dynamic Capture
checkbox, it means that the script will capture the client minimap
repeatedly, the frame rate is decided by the drop-down menu
labeled 'DCapture Frame Rate'.
Enjoy!
Yakman.
Before i released this, i sent it to a few people
they all found it VERY useful and a good piece of work
(it also looks really cool when you make it draw the path)
'omg that is soooooooooo
cooooooooooooooool'
Sumilion
'wow, thats great!'
Freddy1990
'WOWAWAWEWA'
WT-Fakawi
}
const
DebugAll = False; //If you really want to see the script working
//Nothing Below needs to be edited
var
bmpBlank_Map:integer;
working:boolean;
//this global boolean shows if radial path is begin drawn
var
bmpCapture:integer;
Capture:TCanvas;
Captured:boolean;
FoundRS:boolean;
var
i,StartRadial,EndRadial,Color,Radius:integer;
//radial path drawing globals
var
frmDesign : TForm;
Label1 : TLabel; //form variables
Label2 : TLabel;
Label3 : TLabel;
Label4 : TLabel;
Label5 : TLabel;
Label6 : TLabel;
Label7 : TLabel;
Label8 : TLabel;
Label9 : TLabel;
Label10 : TLabel;
Button1 : TButton;
Button2 : TButton;
ComboBox1 : TComboBox;
ComboBox2 : TComboBox;
CheckBox2 : TCheckBox;
CheckBox1 : TCheckBox;
Button3 : TButton;
Button4 : TButton;
Button5 : TButton;
Edit1 : TEdit;
Edit2 : TEdit;
Edit3 : TEdit;
Memo1 : TMemo;
Timer2 : TTimer;
Timer3 : TTimer;
//constants, dont change these unless RS updates
const
FormX = 190; //where to copy to the form
FormY = 92;
const
ClientX = 551; //where to copy from the clint
ClientY = 9;
const
Height = 151; //dimentions
Width = 152;
const
CenterX = 266; //center of the form image
CenterY = 168;
procedure ClearMap;
begin
if(captured)then
SafeCopyCanvas(capture,frmDesign.canvas,0,0,Width, Height,FormX,FormY,FormX+Width,FormY+Height)
else
SafeCopyCanvas(getbitmapcanvas(bmpBlank_Map),frmDe sign.canvas,0,0,Width,Height,FormX,FormY,FormX+Wid th,FormY+Height);
end;
procedure DrawBlankMap(sender:TObject);
begin
frmDesign.RePaint;
end;
function Distance(x1, y1, x2, y2: Integer): Integer;
// By PPLSUQBAWLZ edit BenLand100
begin
Result := Round(Sqrt(Sqr(x1 - x2) + Sqr(y1 - y2)));
end;
function FindRadial(x,y,radius:integer):integer;
var x1,y1,r:integer; //this finds the radial at your mouse by
begin //checking every radial of the radius and seeing if your
if(working)then exit; //mouse is close to there
for r:=0 to 360 do
begin
x1:= Round(Radius*Sin(r * pi / 180))+CenterX;
y1:= Round(-Radius*Cos(r * pi / 180))+CenterY;
if(DebugAll)then
frmDesign.Canvas.Pixels[x1,y1] := 16777215;
if(Distance(x1,y1,x,y)<=1)then
begin
result:=r;
exit;
end;
end;
writeln('Failed to get radial');
end;
procedure DrawRadial(x,y,Thecolor:integer);
var Radius,Radial:integer;
begin
if(working)then exit;
Radius := Distance(CenterX,CenterY,x,y);
Radial := FindRadial(x,y,Radius);
if(not DebugAll)then
ClearMap;
frmDesign.Canvas.Pen.Color := TheColor;
frmDesign.Canvas.MoveTo(CenterX,CenterY);
frmDesign.Canvas.LineTo(x,y);
Label1.Caption := 'Radial = '+inttostr(Radial);
Label2.Caption := 'Radius = '+inttostr(Radius);
Label10.Caption := 'Radial + 360 = '+inttostr(Radial+360);
end;
procedure SafeDrawRadial(x,y,color:integer);
var t:TVariantArray;
begin
t:= [x,y,color];
ThreadSafeCall('DrawRadial',t);
end;
//event called when the mouse if moved
procedure MouseMove(Sender:TObject;Shirt:TShiftState;x,y:int eger);
var fillcolor:integer;
begin
if(working)then exit;
if(DebugAll)then
writeln('Mouse Move Event - Mouse at '+inttostr(x)+','+inttostr(y));
if(not CheckBox1.Checked)then exit;
if(not ((x>FormX)and(x<FormX+Width-6)and(y>FormY)and(y<FormY+Height)))then exit;
case ComboBox1.Text of
'Red':fillcolor:=255;
'Blue':fillcolor:=16711680;
'Green':fillcolor:=65280;
end
SafeDrawRadial(x,y,fillcolor);
end;
//event called by Timer3
procedure DrawRadialStep(sender:TObject);
var x1,y1:integer;
begin //draws on step of the radial path, then changes global variables
Working:=true; //for the next time it is called
case ComboBox1.Text of
'Red':color:=255;
'Blue':color:=16711680;
'Green':color:=65280;
end
x1:= Round(Radius * Sin(i*pi/180))+CenterX;
y1:= Round(Radius * Cos(i*pi/180))+CenterY;
frmDesign.Canvas.Pixels[x1,y1]:=Color;
if(DebugAll)then
writeln('x1 = '+inttostr(x1)+' y1='+inttostr(y1));
if(i=EndRadial)then
begin
i:=StartRadial;
Radius:=Radius-4;
end;
if(Radius<=1)then
begin
Timer3.Enabled := False;
working:=false;
Button3.Caption:='Show Path';
exit;
end;
if(StartRadial < EndRadial)then
i:=i+1
else
i:=i-1;
if(DebugAll)then
writeln('i='+inttostr(i)+' radius='+inttostr(radius)+' sr='+inttostr(startradial)+' er='+inttostr(endradial));
end;
//called by pressing Button3
procedure OnRadialPath(Sender:TObject);
begin
if(not Working)then
begin
try
StartRadial:=StrToInt(Edit1.text);
EndRadial:=StrToInt(Edit2.Text);
Radius:=StrToInt(Edit3.text);
except
edit1.text:='0';
edit2.text:='0';
edit3.text:='0';
if(DebugAll)then
writeln('Numbers Only!');
end
ClearMap;
if(Radius > 80)then exit;
StartRadial:= StartRadial + 180;
EndRadial:= EndRadial + 180;//all this because SCAR's sin uses radians
StartRadial := 360 - StartRadial;
EndRadial := 360 - EndRadial;
case ComboBox1.Text of
'Red':color:=255;
'Blue':color:=16711680;
'Green':color:=65280;
end
i:=StartRadial
Timer3.Enabled:=True;
Button3.Caption:='Stop';
end
else
begin
Timer3.Enabled:= False;
Button3.Caption:='Show Path';
working:=false;
end
end;
//called by clicking the mouse
procedure MouseDown(Sender:TObject;Button:TMouseButton;Shift :TShiftState;X,Y:Integer);
begin
if(working)then exit;
if(not ((x>FormX)and(x<FormX+Width-6)and(y>FormY)and(y<FormY+Height)))then exit;
CheckBox1.Checked:=not CheckBox1.Checked;
end; //simply freezes the radial display
procedure Paint(Sender:TObject);
begin
ClearMap;
end;
procedure PrintProc(sender:TObject);
var sRadial,eRadial,Radius:integer;
begin
if(working)then exit;
try
sRadial:=StrToInt(Edit1.Text);
eRadial:=StrToInt(Edit2.Text);
Radius:=StrToInt(Edit3.Text);
except
edit1.text:='0';
edit2.text:='0';
edit3.text:='0';
if(DebugAll)then
writeln('Numbers Only!');
end
Memo1.Lines.Add('');
Memo1.Lines.Add('RadialWalk( {TheColor} , '+inttostr(sRadial)+', '+inttostr(eRadial)+', '+inttostr(Radius)+', {Xmod}, {Ymod});');
Memo1.Lines.Add('RadialRoadWalk(RoadColor, '+inttostr(sRadial)+', '+inttostr(eRadial)+', '+inttostr(Radius)+', {Xmod}, {Ymod});');
end;
procedure FindClient;
begin //finds the RS window by size
if(working)then exit;
if(FindWindowBySize(766,504))then
label8.caption:='RS Handle = '+Inttostr(GetClientWindowHandle)
else
label8.caption:='RS Handle = 0';
end;
procedure CaptureFromClient;
begin
try //frees an older bitmap if it exists
FreeBitmap(bmpCapture);
except
//there was no older bitmap to free
end
bmpCapture:=BitmapFromString(Width,Height,'');
Capture:=GetBitmapCanvas(bmpCapture);
if(not FoundRS)then
FindClient;
if(Label8.Caption = 'RS Handle = 0')then
exit;
try
SafeCopyCanvas(GetClientCanvas,Capture,ClientX,Cli entY,ClientX+Width,ClientY+height,0,0,Width,Height );
SafeCopyCanvas(Capture,frmDesign.canvas,0,0,Width, Height,FormX,FormY,FormX+Width,FormY+Height);
except
CheckBox2.Checked:=false;
end
Captured:=true;
end;
//called by pressing button
procedure ClientCapture(sender:TObject);
begin
CaptureFromClient;
end;
//called by Timer2
procedure DynamicCapture(sender:TObject);
begin
if(working)then exit;
CaptureFromClient;
end;
//called by changing CheckBox2
procedure StartDCapture(sender:TObject);
begin
if(working)then exit;
if(CheckBox2.Checked)then
begin
Timer2.Interval:= StrToInt(ComboBox2.Text);
Timer2.Enabled:= True;
end
else
begin
Timer2.Enabled:= False;
end
end;
//called by pressing button
procedure FindRS(sender:TObject);
begin
if(working)then exit;
FindClient;
end;
procedure Form;
begin //constructs the form
frmDesign.Left := 267;
frmDesign.Top := 154;
frmDesign.BorderIcons := ;
frmDesign.BorderStyle := bsSingle;
frmDesign.Caption := 'Radial Walking Aid - Yakman';
frmDesign.ClientHeight := 387;
frmDesign.ClientWidth := 519;
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.PixelsPerInch := 96;
frmDesign.OnMouseMove:= @MouseMove;
frmDesign.OnPaint:= @Paint;
frmDesign.OnMouseDown:=@MouseDown;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 48;
Label1.Top := 40;
Label1.Width := 48;
Label1.Height := 13;
Label1.Caption := 'Radial = ';
Label2 := TLabel.Create(frmDesign);
Label2.Parent := frmDesign;
Label2.Left := 48;
Label2.Top := 88;
Label2.Width := 48;
Label2.Height := 13;
Label2.Caption := 'Radius = ';
Label3 := TLabel.Create(frmDesign);
Label3.Parent := frmDesign;
Label3.Left := 64;
Label3.Top := 256;
Label3.Width := 55;
Label3.Height := 13;
Label3.Caption := 'Start Radial';
Label4 := TLabel.Create(frmDesign);
Label4.Parent := frmDesign;
Label4.Left := 64;
Label4.Top := 288;
Label4.Width := 52;
Label4.Height := 13;
Label4.Caption := 'End Radial';
Label5 := TLabel.Create(frmDesign);
Label5.Parent := frmDesign;
Label5.Left := 64;
Label5.Top := 320;
Label5.Width := 33;
Label5.Height := 13;
Label5.Caption := 'Radius';
Label6 := TLabel.Create(frmDesign);
Label6.Parent := frmDesign;
Label6.Left := 192;
Label6.Top := 16;
Label6.Width := 265;
Label6.Height := 13;
Label6.Caption := 'Move Your Mouse Over the MiniMap To Display Radials';
Label7 := TLabel.Create(frmDesign);
Label7.Parent := frmDesign;
Label7.Left := 168;
Label7.Top := 40;
Label7.Width := 332;
Label7.Height := 13;
Label7.Caption :=
'Input '#39'StartRadial'#39' '#39'EndRadial'#39' and '#39'Radius'#39' to Display RadialWa' +
'lk Path';
Label8 := TLabel.Create(frmDesign);
Label8.Parent := frmDesign;
Label8.Left := 376;
Label8.Top := 168;
Label8.Width := 64;
Label8.Height := 13;
Label8.Caption := 'RS Handle = 0';
Label9 := TLabel.Create(frmDesign);
Label9.Parent := frmDesign;
Label9.Left := 376;
Label9.Top := 240;
Label9.Width := 103;
Label9.Height := 13;
Label9.Caption := 'DCapture Frame Rate';
Label10 := TLabel.Create(frmDesign);
Label10.Parent := frmDesign;
Label10.Left := 24;
Label10.Top := 64;
Label10.Width := 72;
Label10.Height := 13;
Label10.Caption := 'Radial + 360 = ';
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 16;
Button1.Top := 344;
Button1.Width := 100;
Button1.Height := 25;
Button1.Caption := 'Print Procedure';
Button1.TabOrder := 15;
Button1.OnClick:= @PrintProc;
Button1.OnMouseDown:=@MouseDown;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 16;
Button2.Top := 112;
Button2.Width := 118;
Button2.Height := 25;
Button2.Caption := 'Clear Map';
Button2.TabOrder := 8;
Button2.OnClick := @DrawBlankMap;
Button2.OnMouseDown:=@MouseDown;
Button3 := TButton.Create(frmDesign);
Button3.Parent := frmDesign;
Button3.Left := 16;
Button3.Top := 208;
Button3.Width := 75;
Button3.Height := 25;
Button3.Caption := 'Show Path';
Button3.TabOrder := 11;
Button3.OnClick:= @OnRadialPath;
Button3.OnMouseDown:=@MouseDown;
Button4 := TButton.Create(frmDesign);
Button4.Parent := frmDesign;
Button4.Left := 376;
Button4.Top := 104;
Button4.Width := 106;
Button4.Height := 25;
Button4.Caption := 'Capture From Client';
Button4.TabOrder := 16;
Button4.OnClick := @ClientCapture;
Button5 := TButton.Create(frmDesign);
Button5.Parent := frmDesign;
Button5.Left := 376;
Button5.Top := 136;
Button5.Width := 75;
Button5.Height := 25;
Button5.Caption := 'Find RS';
Button5.TabOrder := 17;
Button5.OnClick := @FindRS;
ComboBox1 := TComboBox.Create(frmDesign);
ComboBox1.Parent := frmDesign;
ComboBox1.Left := 16;
ComboBox1.Top := 144;
ComboBox1.Width := 118;
ComboBox1.Height := 21;
ComboBox1.ItemHeight := 13;
ComboBox1.TabOrder := 9;
ComboBox1.Text := 'Red';
ComboBox1.Items.Add('Red');
ComboBox1.Items.Add('Blue');
ComboBox1.Items.Add('Green');
CheckBox1 := TCheckBox.Create(frmDesign);
CheckBox1.Parent := frmDesign;
CheckBox1.Left := 16;
CheckBox1.Top := 176;
CheckBox1.Width := 97;
CheckBox1.Height := 17;
CheckBox1.Caption := 'Drawing Radial';
CheckBox1.TabOrder := 10;
CheckBox1.Checked:=True;
CheckBox1.OnMouseDown:=@MouseDown;
Edit1 := TEdit.Create(frmDesign);
Edit1.Parent := frmDesign;
Edit1.Left := 16;
Edit1.Top := 248;
Edit1.Width := 39;
Edit1.Height := 21;
Edit1.TabOrder := 12;
Edit1.Text := '0';
Edit1.OnMouseDown:=@MouseDown;
Edit2 := TEdit.Create(frmDesign);
Edit2.Parent := frmDesign;
Edit2.Left := 16;
Edit2.Top := 280;
Edit2.Width := 39;
Edit2.Height := 21;
Edit2.TabOrder := 13;
Edit2.Text := '0';
Edit2.OnMouseDown:=@MouseDown;
Edit3 := TEdit.Create(frmDesign);
Edit3.Parent := frmDesign;
Edit3.Left := 16;
Edit3.Top := 312;
Edit3.Width := 39;
Edit3.Height := 21;
Edit3.TabOrder := 14;
Edit3.Text := '0';
Edit3.OnMouseDown:=@MouseDown;
CheckBox2 := TCheckBox.Create(frmDesign);
CheckBox2.Parent := frmDesign;
CheckBox2.Left := 376;
CheckBox2.Top := 264;
CheckBox2.Width := 111;
CheckBox2.Height := 17;
CheckBox2.Caption := 'Dynamic Capture';
CheckBox2.TabOrder := 18;
CheckBox2.OnClick := @StartDCapture;
ComboBox2 := TComboBox.Create(frmDesign);
ComboBox2.Parent := frmDesign;
ComboBox2.Left := 376;
ComboBox2.Top := 216;
ComboBox2.Width := 87;
ComboBox2.Height := 21;
ComboBox2.ItemHeight := 13;
ComboBox2.TabOrder := 19;
ComboBox2.Text := '500';
ComboBox2.Items.Add('10');
ComboBox2.Items.Add('100');
ComboBox2.Items.Add('250');
ComboBox2.Items.Add('500');
ComboBox2.Items.Add('1000');
Timer3 := TTimer.Create(frmDesign);
Timer3.Interval:=2;
Timer3.Enabled:=False;
Timer3.OnTimer := @DrawRadialStep;
Timer2 := TTimer.Create(frmDesign);
Timer2.Interval := 10;
Timer2.Enabled:= False;
Timer2.OnTimer := @DynamicCapture;
Memo1 := TMemo.Create(frmDesign);
Memo1.Parent := frmDesign;
Memo1.Left := 152;
Memo1.Top := 296;
Memo1.Width := 185;
Memo1.Height := 68;
Memo1.ScrollBars := ssBoth;
Memo1.TabOrder := 20;
frmDesign.ShowModal;
end;
procedure SafeForm;
var T:TVariantArray;
begin
ThreadSafeCall('Form',t);
end;
procedure LoadBMP;
begin //loads the bitmap of the blank map
Writeln('Loading Bitmap');
bmpBlank_Map := BitmapFromString(152, 151, 'beNrtnf1vleU' +
'Zx8Ep6nRkcUoCQuZ4SQMUJi8OsAULZaz0LaGtGlpehMpbBZS2 hHcz' +
'aNUx7SJKpCEMReJmZCRmbD+4uMUf5g9LlpksMVli/MV/Y7/sU7704' +
'uJ+zikOaXuect25cvKc06fl9Pmc7/e6rvu+n1K1eEv1ZKKzcVr/rj' +
'lv76s+0rmpvbVuYfn02bOmFIslC2eub6zktNbm6trVTzbUVPJ I1FQ' +
'tJvwrFs11FQTnN9ev4sBe7Nhaf2L/c6d6XySOdjT5OLy9bs+GlS11' +
'A++wbfmkJJrL709i3C2N7M/hh+uaJLG5toz307291r9D/9S/frav+' +
'28fv/XPv15QfHr5VOfOFl2Bra2rOaiuWECsXDZfoafLn5jLlZ83e2' +
'rByz5r+mQeOYHrTzw+dxpnWrS1VO9sWaa32tNWBsqujtYtz6w uhpJ' +
'/izcjiKJjBI2jXoemgPIiB3pR5/P4QnuTCJ48tiO5DlwuLhrXc+Oi' +
'B4iC7MYN2/D/SkGgfLR4h3BJ2BH+lQv9PYaSg97D2/it1zdVwpHgg' +
'MtiHBOU2YsviHx1TdUiToajiFs8v7EOlASSNFVykcGU/WDwE65DvK' +
'qsLEePLDlBTze0rBVBHvUr64DPtsenWDtrgmJY2d0aUz7/Xo8cJyj' +
'//LuTECQ4eOP4bq4bPiZJEhIClxQ6hlJPhUn4FLySSHjF0nJehNH r' +
'vfuI3c+vA6VoJii5/kYQFfOUd+KVaJEVY5YjHyS+8dDeNgSYEOTjz' +
'WWBGpcrwTeuZEYxoPLbrLsS/Kao8typg/yaJCyCPMJFUAglZCVMuI' +
'gUIUagNBnqRcJL+K2+Y8TF868TXR3PFkTJRwtknKyECI5dmxo KQvT' +
'ZMAvRjBQj8hoEqAhKgLpERnBcCQ9PU5dLNElGBWnyi5Oq+MWx ViKh' +
'qZAWzF2lSnksj+DToxE8e7pXBN8788qHr/6if8+8I52bCWh6lHAke' +
'AP8E95Lr9npYOgNeIj+0YIPAO/fZCiCmJInWIIC/PbyFE1C2kzc1T' +
'63uggEHqt60qMkY8pmfRjBBCIEL1/8DQSPNkzd8tMfNsyf8vrxPSc' +
'OPu9RDiTxQXeVpRsyy4kqvRJtyj/tUefAjncudgoRtOuQL3zZoUSQ' +
'pVlQm6BUcU5AUyWlIF6j2VhpSdBnQ++lQLxypu2NTY9B8KkZD xHNk' +
'x4803cgQeklKQewEsVHQY5qOnQ+ctbHzxeiY4ngTWlS+fgPsD wWJU' +
'LQaEIWv7oBZVPlujUFSlnCICJDNCiIOx76/oGJ98HRo1Su5ILTg1i' +
'WNKsc0OZVVWbtXYnyGtP6VUlFys+xSmaMERyaJuZj5ZynKWEC lOBY' +
'KczUkQhTKClKBXF/1cMmQwi+dvddv7/37k//eF4cCUlSKE2SsnEvS' +
'cuS1zPmja29r0gH3nbjtDFPcAiaBW0WcFwiIJ4+2QVQHnk6kM UGVS' +
'mshvK9I782JZoMIfjOPd8D4l/uv+fimeOERymOfJDEkfdQ2FqNoyt' +
'KsRGTIcfIMDHScXfMuGnSlMdyuc72dROgvO6xjZW+joUmtc2l sy+R' +
'E7HTx6dPRomSIQQVl979lTiauypL8gOBePnlSlikHG+sduwAG frpN' +
'd72HSXDmwpTUwfZOtbSZUGP5UBpkepUhY3sFCUaROJPH75pKJ MsSY' +
'qEI1WrOHqUSbeIISQzbHz87kwZDi1MdZrZWVnwoUcBVR3ra0i J0Tt' +
'qAjHhKJRWuIojqtR8eMLRnr7Q3uR7Q++ld6YMbyFjKl2C0gLL pSXh' +
'8qq8kRgLOuqOKfcScEwkmXCUHhOOBROiekPvpUGwmDBBmfVY2 FmuJ' +
'FAHRnfi6N6L73RaZkzECMGvFtzz1dan/vX5lYSj0YTjZ2c2g1K+uq' +
'ZqUTJRY1Nt4sh7C4g3Rbl21VxD2VK3OOuxXNJzpw4SQokeZaq VC36' +
'MqZIZTYxA/Kz8rv/+/WMCjv/49AO6D6F898GJBBDVRXqOVE3iqD5R' +
'M97ZhBhe+v96bBYlKfJCfw8BSjief20jPWPWVAfEuPUpIP779 P5iY' +
'mxrqRZH+ap6GeOoNt/3+CHD71L8JCh5aqqEI8mxKMerpkoUS45wBN' +
'AXF/f6/CiO6nrkpQHxdqHMVj6oEo40HXBsX/FoUY5XQxyzxSrsIPj' +
'lpUPWPyo/mhI5SErTQHN7UWoF0/SozrEYx2LN4/rGSsQIR5vPwVf9' +
'GmJAHA6UvojV+texA7vEkTpHMwCeY++jEwpy9KtX33zSR37Uj B9ip' +
'AZWYRNKHBmU2vND30GdY/Wq+g5D+fQP7hbKgmKUqf7n899+9EqTWg' +
'x6Ul+dRk4csdYSPZ7ve47+URzNWi2EMsmM4khfg6N+faUXVYq jNYk' +
'BcYRV2bW7lRTZv2eelTqaXE1QZsUItUSMA7MKgxB9nxgXf1hV aWUP' +
'1qotHGattmLFoyK7GYBPAkpUhaNZd78lIyAO6+iuuC87RSBrf X/LN' +
'Fu0MpQWBlFiJA+e7euGI5K0XVLJOlRAHG6UftWSUgeO6j5Mku auFn' +
'6HFdKjraBMxVFtKdNqp4A4KiiJgevftQWUH7xY5t1VmzrE0SD imeB' +
'TrzHgn/Wr6DhsvihqmxHm6KfTlSjJkud6ngWlekk81vbnECpsPETd' +
'SIIe5aiH9rZFWhz1RDmwLbZrC3H64FoSpVQplMqVtBh4JlWN7 HQAm' +
'YMYjjq6KCHoE+XubU8Txzt+jir71k2lEzGUCBCCmg/XlmPVNtZoaN' +
'4mII5uorTJgW0b6oWSjtLTRInI8Fq/X7+qpmoxvhotf+m66/Y6UBL' +
'72mt+2b4UlAROazM2WmHU1I01GgGxNDtKCVM00eaZl35mN76t XDaf' +
'R7s9M9JiCbqr7qL1C1vNdcvbmqvbBhekFJp/03JJzL+VpiSzy5Qnj' +
'+1YsXSO3YKaOGqIsZTd1VYn1RiePtllmxg9YpU3AbFka1cvSd 1fII' +
'i2RhxizFHB43dn2a0ZIcYcSdLuyPMctSk9VqZyN8Pj9ahbv+1 pzN7' +
'kVJImRh5DjPnKkoRVrV6MkRlzJ8nrez+iZ8yzJLVcFT3jWJKk bgwJ' +
'MY6FaqdxWlQ4+eJoGz8Ia0Bsk39coryMV1dPSKzV/2GNuD454ri5t' +
'qynrUzWSr1qphoXJ4+SFMow1bHBMdrGsWGttu4flyWnKOFIhK mODW' +
'uNSjU4xiidFCmOcUHyniKD49iw1uAYHGOUToq8CnF8XI28owy OwTF' +
'GcIwxDBxjBMcYJcExLkKMGDFixIgRI0aMGDFixIgRI0aMGDFi xIgR' +
'I0aMGDFixCg0xscunVyPwX0dwTE/khufknL7c4JjjkdwDI4xgmOM4' +
'BijIEf9mcdBjsUiRklD7GkrC45jgGP/rjnfgmOMHHDUH5cLjrnmeP' +
'nlSvQ4pCRjlDpElDgkxxj54Hh4e91HrzStqZhRxFpj5IPj2/uq4bh' +
'y2fxCeoyRG45A/OzM5pqqxUgSlBsXPTBIMDjmyVSBSLQ2VzuOMfJX' +
'qYrjC+0D1tq2fFJwzCNHQcRaj3Ruql39ZEgy16YKxzeO78ZaV e0Ex' +
'9xVOF9c3AtHStbTJ7vaW+tkrYEyRxA315ZBUBz3bFh57tRBUu SNVW' +
'uMfLSNQCRQJRwv9Pf0Ht4W1pqv8WbtvRIjQZYUR6x1a+vq6oo FIcm' +
'8QITdl5cOERJj9/ba908fIGStSxbODI55EaM44q7iiBhJkbLW5U/M' +
'jWonR2JUhbNrUwMc6TvgaFVrWGvpc8RLE1MVR0nySOcmrFXVT qAsW' +
'Yg9bWVejIJI4KhwJEXyGNaaCzF+faVXmXHLM6sFEaeFI5KEox rJFU' +
'vLVe0EytLMjEAkEOPOlmUGkQCiUiQoYUr3IUnqvxKIq1dqZao 4Soz' +
'gSzhKkqd6X2yuq4AjktR/2BooSwci7L75pI/wYhRH1TnIkECSRMfW' +
'enHU/1Af7loiEAFHTgQiYtQETsJREFXtqJGkZIWjSXLtqrmBshTKG' +
'4nxbF+3F6M4Hu1oMl+1qlXW+sSCcv3P5iHJ0ilvkCTHavw9xx P7nz' +
'OOqnZUtSJJUK6pWhQoS8dRCTX+MlJzVBOjt1ZkqwkBcTSU4a6 jWKM' +
'WLG+8GClQRRB2aiRBqR0CcESVeCxM1U4GylGsUeWovrzxmVEc gaiQ' +
'JInOnS0rlpaLoy1NhruOYo2qdQ1zVGsbEaOQJRyVJTlAhqDkE Y7ai' +
'IW7xra6EYO4vqnyi4t7LS3C1EM0MaJEUmHCkZC1amUZa62uWI AkCZ' +
'iqowRooBz1tGhzqkAkoGkEuzpavbVy7K1VuwWioxzhbrFgWlQ gRgh' +
'intIjqTDLka8iTFlrQ00lHKEJ0821ZdGGjExtY/OoBcVInDy2Q4oj' +
'0GPH1npBTDjaMpZS5MDtA1WLNH8ulN0V98VlH6aW36fFghAhB TsfA' +
'DIxWorUhIBZqzha4RooRwBiskycOKp6DT0qkFvCMWutSpFUPh wsWT' +
'hT7kpwEChvI0Sbt/nDuWPaeJPUqAbR7JRQy49z+nrVdx9Ee2udWSv' +
'HKmI9ylDlbYEINYNoW1KLpUUVNtKjJMnTebNneIiWJbWyzGlm rXAk' +
'KHvgaDVPoPzuELXl5qYFKkHXr0ZDGvQcZ02frJJVpY5x5Kuqd jTXy' +
'iMQKYoAClli7Yq5YbAjCRFH1QS4TFUT45Yop075EYCyevTLH5 oQgC' +
'AcOVlkkaRHSQTK7wIRO4VgsQI1SYviiMfqmMfJj0xUyWochdI 27XA' +
'AMjWSXpJ60SYHAuUt9IlJYVNMiT4t2lqGrRor8FX0lczO+aqV EDj6' +
'R+ock+QQKIPm0ARt+6JvMYaASFoUCJtNlRgNJS/KIW0JMrv8wbejU' +
'M7RHB02C0qA6hWhtPkBX/mMvzoCXAIR57S5U1Cq2R8aoubfNAWn2V' +
'QrVk1rmnATtSxHuas1klbtENr+IZQcaLnZIiqfmzaJNu02BMR De9u' +
'MlJU3vlIVYq1rAIKS1QgmcwJ29wcctfyBJAm+UYWrofQ1T3hs MS9V' +
'qEksVtUYRMPka1QcVaYqxJzD8fqmyoXl08mA2RTplz/MWiVJuasKV' +
'6lSiTKLMrpLtfnaQowYtRt8iNI0gSgjTThKj0aZk4FI65EtdV Ao7G' +
'StnM/3mpECXRw1kU5IqprB44MRwkxkiPp0c41uA5eXJov7BdekvBg' +
'TU7XlDN3zOPOxSQ8/9OCShTMTJSYrIIS2KCtLcuwlaTUPHMW3pW6x' +
'zajfmRkTghCxu7/tDqmCe6X8FjjEpUmYBKIvbzi40N+j0mXXpgZEB' +
'MGfTHtk3uypPjkmczu2A0T+yXeRHOGIZiVJy5L6kmbw+NK6Nd dp0v' +
'PeIcI0GRpEL8OCEC20IOULVFOitfxqNPQHAfTnj3TlsVa6SLh 4Mcp' +
'XfdVqK5LSHScQuiHdUHIgSQoloR13clpQiuarqycQY5UgVagn yLFK' +
'Gq+7LES81FoM9RdCqStvS1SCaOWNFhM1cYokSZHoKFvnWD/iN3toT' +
'gBGQmmFq6nSehOh1IIXTmvCHHs0E4L2mHQWifoSiNCRW3o7zc 7e6A' +
'SYIiJkKI44KmKc/MhELrXKm2Su1W9t1bS5rYCoAbEsaTM8kqQ4FqQ' +
'plGODpieoEEHt/V7fWJncU1MQImXkt4HozdbuH9dKIsmRoNSBrJWs' +
'2R7EOGpF0lc7hM24+t5EKK0iElBt9cFmDaWnmSOgwieCSoUWP JWRZ' +
'rcNZwlqAnxogglHDtQ+CKICMRL4KscFW8ikkeQn6NsBR4thgE ynCi' +
'2OJBx1JsJUxjSO/bvmEHmRp/Dxbi+/XAkyhRH0RuqRZTnKS3V7VLY' +
'0zc6EW7fIi/qjHAaRY8Q4e9YUOGZbj+xKln6gtY3KkgJkJZASZUNN' +
'pbEzmubDmkRau2qu1T9CaUBLUJ4mQBB4ggpesaXDBFbSViRVD UpU5' +
'Wm5z9Kfqhq9wjm6Gw4KPi1CTZed/Dhv9gwkqY0BN5Wk9l+JV6I76y' +
'WlVv8lcVRdpCpX/sz74btImgKa0PRAR4Wp/dPCx7uCl4UIase+tfY' +
'FBZiFqC3EslMtZIiaadOXpmKt17l6Pi2aHmk6CF7hUbOsfE6K cTRJ' +
'0rPo2y0VasbVNyA+S5oY1c6or1HNrP3q6Jfz6Tfltx5oYrnDz dT/K' +
'/ZOPD4LEbQlp8Q2k4mapKrx0zXZKRrrFkXQNOtrG2+qNf8DGPMB Pw' +
'==');
writeln('Bitmap Loaded');
end;
procedure SetSelfWindowState(State:TWindowState);
begin
GetSelf.WindowState :=State;
end; //sets the SCAR main form window state
procedure SafeSetSelfWindowState(State:TWindowState);
var t:TVariantArray;
begin
t:= [state];
ThreadSafeCall('SetSelfWindowState',t);
end;
begin
ClearDebug;
writeln('Successfully compiled');
LoadBMP;
if(not DebugAll)then
SafeSetSelfWindowState(wsMinimized);
frmDesign:= CreateForm; //this is already thread safe
SafeForm;
SafeSetSelfWindowState(wsNormal);
FreeBitmap(bmpBlank_Map);
try
FreeBitmap(bmpCapture);
except
end
end.
Xmod Ymod
Srl’s definition of Xmod and Ymod is:
XMod, YMod: deviation from MouseFindFlag. -2 to 2.
Pretty much this is the Randomness of the point it will click. It’s best to use -2,1 etc, so it doesn’t appear off the map.
Radius
The radius is just the length of the search line, it is best to use a radius of 20-72.
I’ll add more on this if you don’t understand. In a case like lumbridge 72 would be fine, but if we were continually using in a script perhaps we should have the radius as
Radius := 50+random(22);
Or any other radius will work.
The Color
This is the easiest part of the function, yey ^_^
If you take a look at autocolor, In srl, you’ll notice these colors which are extremely useful for radial walking.
// » function FindWaterColor: Integer; | by Tarajunky fixed by BobboHobbo
// » function FindRoadColor: Integer; | by Tarajunky
// » function FindVarrockRoadColor: Integer; | by Tarajunky
// » function FindFallyRoadColor: Integer; | by Tarajunky
// » function FindLumbyRoadColor: Integer; | by ZephyrsFury
// » function FindRockColor: Integer; | by Tarajunky
// » function FindStoneColor: Integer; | by Tarajunky
// » function FindDirtRoadColor: Integer; | by ZephyrsFury
// » function FindBridgeColor: Integer; | by Tarajunky
// » function FindLadderColor: Integer; | by Tarajunky
// > function FindSandColor: Integer; | by Tarajunk
Basically pick the color which you want. So In this case with getting out of lumbridge, we obvious would use FindLumbyRoadColor, and thus select this and place it into our function as you will see below.
Putting it all together
Okay so we’ve decided that we should be using:
A color of FindLumbyRoadColor
A starting radial of 45 degrees
An Ending Radial of 90 degrees
And the radius should be 50
We also decided the xmod, and ymod to be -2,1
Once placed into the function:
RadialRoadWalk(FindLumbyRoadColor, 45, 90, 0, -2, 1);
But say we wanted lots of walking, (bad example), we could use nesting, and if statements like so;
program New;
{.include SRL/srl.scar}
begin
Setupsrl;
ActivateClient;
Wait(300);
if(RadialRoadWalk(FindLumbyRoadColor, 45, 90, 72, -2, 1)) then
if(RadialRoadWalk(FindLumbyRoadColor,70,120,72,-2,-1)) then
writeln('Yay, where ever the heck i planned to go, worked!'); // Somewhere over the bridge ;o
end.
Obviously we would need to add failsafes ! More on that later.
Symbol Finding
Symbol finding is extremely useful, yet sometimes unreliable. This is more noticeable when attempting to bank sadly, as the white dots overlap the symbol sometimes making it unfindable.
Symbols can be used for failsafes, location checking, and as actual walking.
I shall pretend that you are making a smithing script in lumby, which ties in with the whole radial walking example. Say we have just radial walked from lumby up near the furnace, and we want to get in the building / near the furnace :
Therefore using:
FindSymbol(x,y,’Symbol name’);
Where x,y is the Coords of the symbol, and the symbol name… Being one of these :
{************************************************* ******************************
Valid Arguments are:
- agility - furnace - quest
- altar - gem stall - rare trees, tree
- anvil - guide - sandpit
- apothecary - hair dresser - saw mill
- archery shop - herbalist - scimitar shop
- arrow - house - shield
- axe shop - hunter store - shop, store
- bar - hunter training - short cut
- candle shop - jewelery - silk stall
- churn - kebab shop - silver stall
- clothes shop - mace shop - slayer master
- cookery shop - magic shop - spice stall
- cookery, cook - makeover mage - spinning wheel, spin
- crafing shop - mill - staff shop
- dungeon - minigame - summoning store
- farming shop - mining shop - sword shop
- farming spot - pet shop - training dummy
- fishing shop, fish store - platebody shop - underground
- fishing spot, fish - plateskirt shop - water source, water
- food shop - portal (to player owned houses) - weave
- fur trader - pottery, pot - windmill
************************************************** *****************************}
So, That means we just need to Do,
FindSymbol(x,y, ‘furance’);
Pretty easy, but we of course need to make an if statement, to see if this is true!
If(FindSymbol(x,y, ‘Furance’)) then
With this we then add the clicking to it:
If(FindSymbol(x,y, ‘Furance’)) then
Begin
Wait(30+random(70));
Mouse(x,y,5,5,true); // If you remember from earlier, 5,5 is the randomness. And true is a normal left click.
Flag();
End;
This will Check if the symbol has been found, then will wait, then click it. This is useful for a failsafe also! Say you have been attempting to find the Furance, you can check to see how fair away you are from the furnace using ‘distance’, and if the distance is further than it should be it shall try to correct this.
If(FindSymbol(x,y, ‘Furnace’)) then
if Distance(mmcx, mmcy, x, y) >= 10 then
begin
wait(30+random(30));
writeln(‘Correcting user’s placement’);
mouse(x,y,5,5)
Flag();
End;
Another use for Finding symbol would be when radial walking long distances:
// Never use this, it’s just an example :P! It can be an endless loop
repeat
RadialWalk(FindLumbyRoadColor, 12, 50, 30+random(30), -2, 1);
until(FindSymbol(x,y,'furance'));
So, Symbol Finding is pretty useful =)!
[CENTER][b]TPA and Tboxes
For my first tutorial, of many, I have decided to explain and discuss Tpa’s. Many of you are most likely under the illusion that TPA’s are impossible to incoperate into a script, and to be used effectively by anyone unless you’re a genius. But after munk explained that this is SIMPLY not true, and that any idiot can make effective use of TPA I decided that I should write a tutorial on it, disproving the usual thoughts aboutTPA.
Now, let me explain the basics.
What are Tpa’s?
A TPA is just what you think it is…. Uh …
A TPA is just a bunch of data stored in an array. To be specific, it’s a collection of Tpoints in an array, hence : TPointArrays.
I shall explain this in two parts.
Tpoints
A tpoint contains 2 bits of data, the x and y co-ordinates of a point. You may notice the x,y points of something when you’ve been selecting a colour and noticed it displayed a x and y point.
An Array
The array is just multible Tpoints, ie, numerous x and y co-ordinates placed into an array.
Simple.
Effectively using the TPA
This is how to declare a basic Tpoint:
Var
TpointName: tpoint;
This will create the variable tpointname and declare is as a tpoint.
To actually add data to this var you would use something like:
Procedure TPA;
Var
TheTpa: TPointArray; // Declare the tpa like discussed before
Begin
SetArrayLength(TheTpa, 1); // Remember that 1 tpa contains both x and y
TheTpa[0].x := 30; // Arrays always start 0,1,2,3 etc etc :
TheTpa[0].y := 30;
Writeln('TheTpa[0].x = '+IntToStr(theTpa[0].x)+ ' TheTpa[0].y = '+IntToStr(TheTpa[0].y)+'.');
End;
This would of course give the output off :
TPA[0].x = 30 TPA[0].y = 30.
The use of something like this could be Mmousing the X and Y co-ordinates of the tpoint.
Adding more points to the TPA
Of course manually inputting x and y co-ordinates would be pointless. There are many methods of adding data to a Tpoint Array. Most commonly used would be these two :
FindColorsSpiralTolerance(x,y : Integer; var Points :TPointArray; color, xs,ys,ye : integer; Tolerance : Integer);
The above is most common for minimap related object finding such as finding Npcs, as it will spiral outwards of the minimap.
The second used would be
FinndColorsTolerance(var Points : TPointArray; Color, xs, ys, xe , ye , Tolerance : Integer): Boolean;
Same idea as SpiralTolerance.
These are both extremely useful, as this will be out data which we will then sort out. As this will find the x and y co-ordinates of the colour’s with tolerance, we will have to sort through ‘a lot’ of data. We can do this by using T2DPointArrays. This is just An array, inside an array. An example of this would be
TheTPA[0][0].x := 30;
TheTPA[0][0].y := 30;
These are declared as such :
Variable: T2DPointArray;
Okay, you may be thinking. Great, this seems easy so far. And it is! But actually using these methods are slightly tricky at first, but here would be an example of using both TpointArrays, and the T2DPointArrays in order to find mainscreen objects.
function MineRock (RockColor,Tolerance : Integer) : boolean;
Var
tx, ty : Integer;
TPA : Array Of TPoint;
t2d : T2DPointArray;
I : Integer;
Begin
FindColorsSpiralTolerance(tx, ty, TPA, RockColor, MSX1, MSY1, MSX2-100, MSY2-100, Tolerance); // First store the color’s x y’s into t points
t2d:=TPAtoATPAEx(tpa,2,10); // Splits the TPA to boxes with sidelengths W and H and results
if length(t2d) = 0 then exit; // Self explanatory, will exit if length is 0. Length of array is the amount of data in it
for i:=0 to high(t2d) do // This will start from 0, and then go to the highest t2darray data
begin
if middleTPAex(t2d[i],tx,ty) then // stores the coordinates of the middle of the TPointArray a to X & Y.
Wait(30+random(20));
mmouse(tx,ty,5,5); // Move the mouse to the temp tx,ty cords.
if (pos('ine', rs_GetUpText) > 0) then // Check if the uptext is ‘Mine’
begin // If so :
GetMousePos(x, y);
Wait(50+random(300));
mouse(x, y, 5, 5, true);
Wait(100+random(300)));
result := true; //Make the result true
exit;
end;
end;
end;
Pretty easy I hope! Basically it did this:
* Stored the color tolerance points starting from center, this means as we loop through our data it should be the closest to center, which should be us :P
* Changed the Tpoints into t2dpointarrays
*Checked if the t2d contained any data, if not exit
*Stored the middle tpoints into x,y points (tx,ty)
*Mmoused the data, checking if uptext was ‘ine’ if so, click
This is how effective TPA CAN be.
Tboxes
In short this is a collection of 2, x and y points from 2 Tpoints. This image will help explain.
http://img234.imageshack.us/img234/4688/tboxexamplegm5.png
Uses of Tboxes
• Item searching through points, such as Srl’s InvBox, where you can easily search for Dtms etc etc.
• Finding data in certain points
Example
Function GetNPCPlace(Box: TBox): Tpoint;
Var
//i: integer;
npcs: TpointArray;
splitnpcs: T2dPointArray;
begin
findColorsTolerance(npcs,195836,Box.x1,Box.y1,Box. x2,Box.y2,3);
if length(npcs) > 1 then
begin
Splitnpcs := TPAtoATPAEx(npcs,20,20);
SortATPAsize(SplitNpcs,true);
result := MiddleTPA(SplitNpcs[0]);
end;
end;
End of TPA
In summary if you followed through (lol >.<) you should understand the basics of tpa and should be able to effectively use them. You should always check out:
SRL\Misc\WizzyPlugin.scar
Just to see all the functions:
procedure tSwap(var a, b: TPoint);
Description:
Swaps the two TPoints.
procedure tpaSwap(var a, b: TPointArray);
Description:
Swaps the two TPointArrays.
procedure SwapE(var a, b: Extended);
Description:
Swaps the two Extended values.
procedure RAaSTPAEx(var a: TPointArray; const w, h: Integer);
Description:
Leaves one point per box with side lengths W and H to the TPA.
procedure RAaSTPA(var a: TPointArray; const Dist: Integer);
Description:
Leaves one point per box with the side length Dist.
function NearbyPointInArrayEx(const P: TPoint; w, h:Integer; a: TPointArray): Boolean;
Description:
Returns true if the point P is near a point in the TPA a with the
max X and Y distances W and H.
function NearbyPointInArray(const P: TPoint; Dist:Integer; a: TPointArray): Boolean;
Description:
Returns true if the point P is near a point in the TPA a with the
max distance Dist.
function ReArrangeandShortenArrayEx(a: TPointArray; w, h: Integer): TPointArray;
Description:
Results the TPointArray a with one point per box with side lengths
W and H left.
function ReArrangeandShortenArray(a: TPointArray; Dist: Integer): TPointArray;
Description:
Results the TPointArray a with one point per box with side length
Dist left.
function TPAtoATPAEx(TPA: TPointArray; w, h: Integer): T2DPointArray;
Description:
Splits the TPA to boxes with sidelengths W and H and results
them as a T2DPointArray.
function TPAtoATPA(TPA: TPointArray; Dist: Integer): T2DPointArray;
Description:
Splits the TPA to boxes with sidelength Dist and results
them as a T2DPointArray.
procedure SortTPAFrom(var a: TPointArray; const From: TPoint);
Description:
Sorts the TPointArray a from the point From.
Closest one to the point is [0], second closest is [1] etc.
procedure SortATPAFrom(var a: T2DPointArray; const From: TPoint);
Description:
Sorts the T2DPointArray a from the point From.
procedure SortATPAFromFirstPoint(var a: T2DPointArray; const From: TPoint);
Description:
Sorts the T2DPointArray a from the point From.
procedure InvertTPA(var a: TPointArray);
Description:
Inverts / Reverts the TPointArray a.
procedure InvertATPA(var a: T2DPointArray);
Description:
Inverts / Reverts the T2DPointArray a.
function MiddleTPAEx(TPA: TPointArray; var x, y: Integer): Boolean;
Description:
Stores the coordinates of the middle of the TPointArray a to X & Y.
function MiddleTPA(tpa: TPointArray): TPoint;
Description:
Returns the middle of the TPointArray tpa.
procedure SortATPASize(var a: T2DPointArray; const BigFirst: Boolean);
Description:
Sorts the T2DPointArray a from either largest or smallest, by the
amount of points in the TPAs.
function CombineTPA(Ar1, Ar2: TPointArray): TPointArray;
Description:
Combines the TPointArrays Ar1 and Ar2, and results the combination.
function CombineIntArray(Ar1, Ar2: TIntegerArray): TIntegerArray;
Description:
Combines the TIntegerArrays Ar1 and Ar2, and results the
combination.
function InIntArrayEx(a: TIntegerArray; var Where: Integer; const Number: Integer): Boolean;
Description:
Returns true if the integer Number was found in the integer array
a, and stores the index to Where.
function InIntArray(a: TIntegerArray; Number: Integer): Boolean;
Description:
Returns true if the integer Number was found in the integer array a.
procedure ClearSameIntegers(var a: TIntegerArray);
Description:
Clears the duplicates in the integer array a.
procedure ClearSameIntegersAndTPA(var a: TIntegerArray; var p: TPointArray);
Description:
Clears the duplicates in the integer array a and the TPointArray p.
function SplitTPAEx(arr: TPointArray; w, h: Integer): T2DPointArray;
Description:
Splits the points with max X and Y distances W and H to their
own TPointArrays.
function SplitTPA(arr: TPointArray; Dist: Integer): T2DPointArray;
Description:
Splits the points with max distance Dist to their own TPointArrays.
Dist 1 puts the points that are next to eachother to their own arrays.
procedure FilterPointsPie(var Points: TPointArray; const SD, ED, MinR, MaxR: Extended; Mx, My: Integer);
Description:
Removes the points in the TPointArray Points that are not within
the degrees SD (StartDegree) and ED (EndDegree) and the distances
MinR (MinRadius) and MaxR (MaxRadius) from the origin (Mx, My).
function RemoveDistTPointArray(x, y, dist: Integer; ThePoints: TPointArray; RemoveHigher: Boolean): TPointArray;
Description:
Removes the points that are inside or outside the distance Dist
from the point (x, y) from the TPointArray ThePoints.
function GetTPABounds(TPA: TPointArray): TBox;
Description:
Returns the boundaries of the TPA as a TBox.
function FindTPAinTPA(SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
Description:
Looks for the TPA SearchTPA in the TPA TotalTPA and returns
the matched points to the TPA Matches. Returns true if there were atleast one
match(es).
function FindTextTPAinTPA(Height: Integer; SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
Description:
Read the description of FindTPAinTPA. Additional Height parameter.
function FindGapsTPA(TPA: TPointArray; MinPixels: Integer): T2DPointArray;
Description:
Finds the possible gaps in the TPointArray TPA and results the
gaps as a T2DPointArray. Considers as a gap if the gap length is >= MinPixels.
Only horizontal, sorry folks.
Function CreateTPAFromBMP(BmpDC: HDC): TPointArray;
Description:
Creates a TPointArray of the bitmap dc BmpDC.
Use GetBitmapDC to get the dc.
procedure SortCircleWise(var tpa: TPointArray; mx, my, Deg: Integer; SortUp: Boolean);
Description:
Sorts all points in tpa by distance from degree (Deg) and distance from
mx and my. Sortup will return closest distance to mx and my first.
Distance will be sorted first (RadialWalk style).
procedure LinearSort(var tpa: TPointArray; mx, my, Deg: Integer; SortUp: Boolean);
Description:
Sorts all points in tpa by distance from degree (Deg) and distance from
mx and my. Sortup will return closest distance to mx and my first.
Degree will be sorted first (LinearWalk style).
Function MergeATPA(ATPA: T2DPointArray): TPointArray;
Description:
Merges the TPointArrays of the T2DPointArray ATPA in to one TPA.
Table of Contents
Chp 1. Basic things you should know. (My first script).
Chp.2. Standards.
Chp.3. FailSafes
Chp.4. MultiPlayer
Chp.5. Bitmaps
Chp.6. Dtms
Chp.7. Anti Ban
Chp.8. Anti Randoms
Chp.9. Walking
Chp.10. TPAs/Tboxes
Basic things EVERYONE should know
Okay, so welcome. You’ve made your first step to become a scripter, or even an srl member. Which is no easy task to do. But if you are able to read, and understand all of the below then you’ll get in easy. Just don’t be surprised if they think your script has been stolen when it’s too good though! *coughs*.
Okay, so first I’ll just talk about the basics of scar. Open up scar, and you will be greeted with :
program New;
begin
end.
So, nothing complex. The program ‘New’; is the name of the program, this can be ANYTHING you want, ie,
program ProMiner;
But remember it must contain no spaces. The:
Begin
End.
Is your main loop, this means the core of your script will be between these begins and end. That is ‘begin’ core st00f ere ‘end.’ This however, does not mean you must write 5000 lines of code between this begin and end. We can add functions, and procedures elsewhere to the script. More on that later.
Okay, also notice that to add ‘comments’ to your script you can either use
Begin // This would be a comment, after the 2 slash, this will not be counted in the script!
Procedure; // Therefore this would be a procedure using a hawt comment. Try to notice the semi-colon placed after procedure.
End. //Please note the full stop, as this is important.
Okay, so I’ve decided for our very first script we shall write a nice simple script which will serve no purpose other than this tutorial. This will be a simple debug spammer :D Which will double up as a proggie I suppose. A proggie is a progress report, which will display the details of the script as it has been running.
As before the layout of a brand new scar page is
program New;
begin
end.
So we should space out this to make it easier on our eyes:
program RandomScript; //As you can see I’ve named this program.
Begin
end.
Now, we shall use the mainloop to call a procedure. A procedure is basically, a section of a script which can be called upon many times. This is how one would be declared:
Procedure Name;
Begin
End; // Notice the semi colon,
//as all procedures and function
// will have this at the end, while the main loop will finish with a fullstop.
So as we’re writing some sort of progresss report, we should use the procedure
Writeln(s :string);
This will write the debug.
Wtf, how do I use that pl0x
Somehow, I knew you would ask that. Let’s break it down
Name(); // This will always be all you call apon srl functions or procedures which contain user imput.
//So let’s take writeln
Writeln(); // In our procedure we will use this, then we look at the inside of the writeln procedure
// as it is ‘s :string’ this means that writeln requires a string, Which is a sequence of characters and numbers
// which will be contained within quotation marks.
//Therefore we should use
Writeln(‘String’);
If we were to use this in our main loop, in our debug menu, String would occur once the script has been ran.
So placing this into our procedure of
procedure hello; // Called the procedure Hello
begin
Writeln('lol'); // Change ‘lol’ to Anything you so desire.
end;
This would mean our script would look like :
program script;
procedure hello;
begin
Writeln('lol');
end;
begin
End.
But, when you anxiously ran the script, you noticed that it infact did not put ‘lol’ into the debug , Oh noez, I heard you cry. This can be easily solved, and explained. We haven’t called it in our main loop!. Now I bet you feel silly for that huh?! XD
This would mean our script will look like this :
program script;
procedure hello;
begin
Writeln('lol');
end;
begin
hello;
End.
Yay, great.
Now to improve on this, simply writing ‘lol’ to debug, ain’t gonna help no onez. Pretend we wanted to make a progress report for a simple miner, this would require us to add the variable ‘OresMined’, in order to keep track of what we have mined! Just because we’re a beginner, we’ll also add a constant of the ore name. Below is how they are declared.
Variable :
program Variable;
var
OresMined : Integer; // And integer is just a whole number, ie, doesn't contain a decimal point :P
begin
end.
Constant :
program Constant;
Const
OreType = 'Coal'; // Notice it is a string
begin
end.
And together it is simply:
Var
OresMined : Integer;
Const
OreType = ‘Coal’;
Now, back to our script after we have added the Varibale and constant to our script, we would hopefully want to write the amount of OresMined, and the OreType :
program script;
Var
OresMined : Integer;
Const
OreType = 'Coal';
procedure hello;
begin
Writeln('You have mined ' + IntToStr(OresMined) + ' ores.');// Notice IntToStr, as i explained earlier
// writeln requires a string to write to debug. IntToStr, turns the variable, OresMined
// (which is an Int(eger), into a string. The '+' sign concatenates the information together.
Writeln('You also decided to mine ' + OreType); // Notice as OreType is already a string!
// Nothing is required to convert it into a string =)
end;
begin
hello;
End.
This will output:
You have mined 0 ores.
You also decided to mine Coal
Wahey. I should really tell you how to add to the value of the OresMined, and you can do so by doing:
OresMined := 300;
More on that later.
Okay, so nice and simple. For the purpose of the script we will add a loop. A loop just… Loops ! We can make one by doing
Repeat
Procedures;
Until(false);
Obviously, until ‘false’ is a bad, bad idea. But since this is only our first script I will correct this later!
We shall now add this into our script. Notice the ‘wait’ function.
program script;
Var
OresMined : Integer;
Const
OreType = 'Coal';
procedure hello;
begin
Oresmined := 300;
Writeln('You have mined ' + IntToStr(OresMined) + ' ores.');// Notice IntToStr, as i explained earlier
// writeln requires a string to write to debug. IntToStr, turns the variable
// OresMined, (which is an Int(eger), into a string. The '+' sign concatenates the information together.
Writeln('You also decided to mine ' + OreType); // Notice as OreType is already a string!
//Nothing is required to convert it into a string =)
end;
begin
repeat
wait(1000+random(200)); // This will first wait 1 second, or 1000 miliseconds
// then a random 0.2 seconds.
//This isn't required, but it's good practice.
hello;
until(false);
End.
This will continually spam your debug menu. So we will make use of these functions to add spice to our script.
inc(TotalProggies); // This adds one to our total progress reports
ClearDebug; // Deletes the current debug text ;o!
TimeRunning; // This is an srl function, therefore we will need to include the srl :0
Before I show you the finished product, to use TimeRunning, I said this requires the SRL. Look below on how to do so :
program SRL;
{.include SRL/SRL.Scar} // Will always occur underneath Program
Begin
end.
This would leave our final script as :
program script;
{.include SRL/SRL.Scar}
Var
OresMined,TotalProggies : Integer;
Const
OreType = 'Coal';
procedure hello;
begin
inc(TotalProggies); // This adds one to our total progress reports
ClearDebug; // Deletes the current debug text ;o!
Writeln('We have spammed j00 debug '+ inttostr(TotalProggies) + ' times.');
WriteLn(TimeRunning);
Writeln('You have mined ' + IntToStr(OresMined) + ' ores.');// Notice IntToStr, as i explained earlier
// writeln requires a string to write to debug. IntToStr, turns the variable, OresMined
//(which is an Int(eger), into a string. The '+' sign concatenates the information together.
Writeln('You also decided to mine ' + OreType); // Notice as OreType is already a string!
// Nothing is required to convert it into a string =)
end;
begin
repeat
wait(1000+random(200)); // This will first wait 1 second, or 1000 miliseconds
// then a random 0.2 seconds.
//This isn't required, but it's good practice.
hello;
until(false);
End.
Nice and easy =)!
Standards
I was forced to ask how to write this section, as it’s a part of scripting which is usually neglected, yet highly appreciated if done correctly.
A wise man called 3garrett3 once said, however,
“Don’t have sucky standards,
Or a one armed hooker named Steve will get you.”
Follow these wise words, and you will do well.
--------
Say you have completed a nice little procedure, but you can’t make heads or tails out of the errors it’s giving to you when you try to compile, must likely it’s your standards. Although poor standards won’t make a difference when compiling, it’s more helpful to the scripter to know exactly what’s happening, and more importantly to others.
You should know these key words
Indenting : You can achieve this by using the Tab key:
http://img367.imageshack.us/img367/8247/tabxn5.png
Backspacing This can be achieved by using shift + tab, this will be the opposite of indenting.
Global vars [/i] Global vars, not specifically standards, but these are the vars declared at the start ie :
Program New; var x,y;
Global vars should only be used when needed, such as dtms. In such cases Dtm’s should be declared as
var dtmTrout:integer;
[u]Local vars These are declared locally in a procedure / function such as
procedure Jesus;
Var
I : integer;
Begin
End;
------
Okay, now onto the actual standards.
Begin statements will occur on their own line, and the end statement will occur on the same line, even when nesting occurs. Example:
Begin
If(condition) then
If(condition) then
Begin
Writeln(‘lol’);
End;
End;
Do not use two or more statements on a single line
Use semi-colons at the ends of lines
Use spaces after commas, and Mathematical related signs
Jesus := (a + b) * (j + c) * 4;
With more ‘stuff’ that would be:
program New;
var
g:extended;
begin
g:= (pow(300,12) * (30 + 30));
writeln(floattostr(g));
end.
Don’t use spaces after parenthesis. Look at above example.
Try to name functions, vars, procedures relevantly. Ie -> dtmTrout, FindTheTrout.
Routine names should always contain capital letters at the beginning.
Procedure Jesus;
After var, there should be indentation when declaing vars
[scar]
Var
Nesting
Nesting is …
If(condition) then
If(condition) then
If(condition) then
Begin
Result:=10;
Exit;
End
Basically this is nesting :P My English is bad so I can’t put it in words sadly, but that is nesting, It’s used a lot in autocolouring etc etc:
{************************************************* ******************************
function FindWaterColor: Integer;
By: Tarajunky
Description: Autodetects Water Color on Minimap
************************************************** *****************************}
function FindWaterColor: Integer;
var
GC, a, l, TestColor, Red, Green, Blue : integer;
var
P:array of Tpoint;
begin
GC := 12095356;
Flag;
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 60);
l:=GetArrayLength(P);
for a:= 0 to l-1 do
begin
if rs_OnMinimap(P[a].x,P[a].y) then
begin
TestColor := GetColor(P[a].x,P[a].y);
if SimilarColors(TestColor,GC,50) then
begin
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Blue - Green, 5, 10) then // Notice LOTS of nesting, Rwar!
if InRange(Green - Red, 18, 26) then
if InRange(Blue - Red, 55, 72) then
if GetColor(P[a].x + 2, P[a].y + 2) = TestColor then
if GetColor(P[a].x + 1, P[a].y + 1) = TestColor then
if GetColor(P[a].x, P[a].y + 2) = TestColor then
if GetColor(P[a].x + 2, P[a].y) = TestColor then
if GetColor(P[a].x, P[a].y + 1) = TestColor then
if GetColor(P[a].x + 1, P[a].y) = TestColor then
if GetColor(P[a].x + 2, P[a].y + 1) = TestColor then
if GetColor(P[a].x + 1, P[a].y + 2) = TestColor then
begin
Result := TestColor;
WaterColor := TestColor;
WriteLn('WaterColor = ' + IntToStr(TestColor));
Exit;
end;
end;
end;
end;
WriteLn('Could not find Water Color!');
Result := 0;
end;
Fail Safes
What’s a failsafe?
Breaking out of Endless loops.
Other methods of doing the same thing, if one fails.
For the first on the list.
Breaking out of Endless loops
In our first script, we used
Repeat
Something;
Until(false);
Well this is EXTREMELY bad :P!
Okay, pretend we had this script :
begin
repeat
MineOres;
Until(false);
End.
So, seems okay at first sight. It’ll just endless MineOres, yea? That’s exactly why it fails. What if there’s lag, causing you to log out. What if there’s a system update. Etc etc. Take a look at this example also
Begin
Repeat
Wait(30+random(70))
Until(GetColor(400,400)=255);
End.
So it will wait until… Let’s pretend a random screen or something, I dunno :P!
So how do you Improve this?
There are lots of different ways of doing so.
Simple break functions, such as If not logged in.
Counter
Marktime
If statements
Check if logged in
This is the easiest most reliable in my opinion.
Procedure Bob;
Begin
if not LoggedIn then exit;
wait(300000);
end;
As you can see it will simply exist the procedure if you are not logged in, which is extremely useful.
It’d be useful to note this also
If not LoggedIn then Break; // Break from loops etc
Counters
Okay, counters rely on vars, and checking the amount of times a loop has occurred. For instance, if we had the Random screen opening example:
Var
I : integer; // We declare the var I, to count the amount of loops, it’s already set as one.
Begin
Repeat
Inc(I); // Adds one to Var I
Wait(30+random(70))
Until(GetColor(400,400)=255) or (I > 10); // Will break out of the loop after 10 loops
End.
Mark Time
This involves the usage of
MarkTime(Time);
TimeFromMark(Time);
Extremely easy to use:
procedure WaitForWindow;
var
MarkedTime: integer;
begin
if not LoggedIn then exit;
MarkTime(MarkedTime);
repeat
wait(30+random(30));
until(GetColor(400,400)=255) or (TimeFromMark(MarkedTime) > 10000); // Checks if time from mark is more than 10 seconds
end;
If statements
Obviously these are extremely useful, say you have decided to do
Procedure GetPick;
begin
FindDtm(Pick, x, y, MIX1,MIY1,MIX2,MIY2);
mouse(x, y, 5, 5, true);
wait(300);
end;
Firstly, this assuming the dtm has not been found. It will not store the x,y cords for us to use, therefore x,y = 0. Then it will click 0,0 with a randomness of 5,5. So, we firstly won’t have clicked the pick, assuming that we have one and the dtm just failed. Then it will click the corner of rs = BAN.
We can easily solve this by adding the if statement :
Procedure GetPick;
begin
if( FindDtm(Pick, x, y, MIX1,MIY1,MIX2,MIY2)) then // This is how If statements are declared If….. Then
begin // We want to execute an entire chunk of code not just one line. One line would suffice, but for the purposes of this.
mouse(x, y, 5, 5, true);
writeln(‘Pick found’);
wait(300);
end;
end;
This says, IF, the dtm is found. Execute whatever we needed (Clicking and waiting);
MultiPlayer
Multiplayer is extremely useful, and easy. This allows…Multiple users to perform tasks 24/7 without ban, usually :p
NextPlayer
Extremely useful,
NextPlayer ( True ) - This will switch players and will leave the current player active.
NextPlayer ( False ) - This will switch players and will switch the current player to not active.
We may have all seen this before:
procedure Declareplayers;
begin
NumberOfPlayers(2); // Players
CurrentPlayer := 0;
Players[0].Name := 'Username'; // Player Name
Players[0].Pass := ''; // Player Pass
Players[0].Nick := 'ame';
Players[0].Active := true; // Is this player active? (True / False)
end;
But you’ve never wondered how to get different characters? That’s when Nextplayer comes in use, ie, say in your script you’ve got
If(not(radialwalk….)) then
NextPlayer(False);
This will allow the next player to become active, leaving the current as false. This is extremely usefull for tracking the amount of ores a player has mined ie:
Procedure mining;
Begin
If(MinedOre) then // Checks if mined ore = true
Players[CurrentPlayer].Integers[0]; // Will add 1 to the current player array, we assume for this demonstration this was infact our mining Integer :P
End;
This should also be added to our main loop :
begin
SetupSRL;
ActivateClient;
DeclarePlayers;
repeat
repeat
Mining;
Dropping;
until (Loads >= LoadsToDo) or (not LoggedIn)
NextPlayer(Players[CurrentPlayer].Active);
until (False);
end.
Bitmaps
Bitmaps
Bitmaps are useful for item finding, including for inventory and banking. Not so much useful for Main screen things however. A bitmap is basically just a graphic image which is composed of dots, or pixels.
With that in mind, let’s get started.
Firstly, you should screen shot your Runescape client, then you should crop the image to only show the object which you want to find. In this case I have cropped it to show only a tinderbox. (If you don’t know how to crop with MsPaint, then give up).
http://img166.imageshack.us/img166/2470/firstpe0.png
In order to make it more accurate, we want scar to not search for colours, so we shall make the background black.
http://img166.imageshack.us/img166/8107/2ndup8.png
Once this has been done, we should copy the image. Next, open scar. Select:
http://img179.imageshack.us/img179/3273/scarko4.png
Wait(50);
Then,
http://img440.imageshack.us/img440/1986/scar2wx4.png
Press okay. Then your debug menu should be filled with something like :
Tinderbox := BitmapFromString(33, 35, 'beNrtVltvEkEYnUWELWJ' +
'CDPJs+mR8aNCkMcYLs7gV2kBZENptU+zMAsIGKbctUkSyIWjV qA/G' +
'H+zZTqX4oOHSPpgwOSHLZc6Z73yXgZDlWq4Zl3SGK1z02ZOYG k0lt' +
'y6RE4T0lp+GgjGVblCa0zQtmoiqdEEr8ns7u9l0LpOieqbI8q 8Lhw' +
'AeGNXxOUKA7iL8xqt9AJzVcqFWKdXflPEAQCKva0JCVSLzsdf Mksl' +
'568i0GlWg06q1DBNvzRIHP3T1dBahzScBQlCBs2vxfrc96B3j tWvV' +
'K0UnBEQE/sMDPZPVMqnEWa5nLaqmTCzbTWwPsW0yHJwQq2w1cPKCW' +
'eQiBbAIClGqzFe0Q9fJ19Php9FgZL8j3eNep+lYdGTCN8YVPX njIO' +
'3nOX9p7yZ0YdocUdikLfhx/l7rgh8Wbas+4OWmTwiRbhvfQiWxFZt' +
'JwtVrCn6koNsoIC+oonhkxYFb/kNFI/3fKrMWqt1/C2A7DcvPH5/j' +
'XCWycqGiyLARZQAoTvdNaxdjPIoWdhPi86yHvdJ9MlahE0KIi BJZ2' +
'/Q1GrzTKhESDN0OTj3WqjgVOjp8zxO+43m67hUYC01GBIhMrcqu 6S' +
'UCLscobERbQeVh2Ps3FfrA4RedshrwTW9UMHANRYt0Yy+RXZA Yq0y' +
'ahiyjU/Ab9CBC9l0ns0hIP79/Rt066aaqCGQyFhQYnESlFdkG2hz8' +
'+7vZORrQtqWR7SKMVxg3jHSRJY3tOKPUapiGwVmRow0pje9o8 ZyDF' +
'/PNWKd07Z5oENHjcMaZjSUO8zGdGFOQiwUuPgluyB7ycfhe9Agk WI' +
'XDfJBjhsOfxW/VH99OA0QSF4SYrqoSwqy43GsUh/zywcY8cYaJVad' +
'rd6/6z8ByLde/l/Jo7b+P4RdywhvG');
Congratulations on creating a bitmap.
Searching for a bitmap
There are many functions for searching for a bitmap. But we should obviously declare the Bitmap as local, for this example.
procedure TinderboxExample;
var
Tinderbox : Integer;
begin
Tinderbox := BitmapFromString(33, 35, 'beNrtVltvEkEYnUWELWJ' +
'CDPJs+mR8aNCkMcYLs7gV2kBZENptU+zMAsIGKbctUkSyIWjV qA/G' +
'H+zZTqX4oOHSPpgwOSHLZc6Z73yXgZDlWq4Zl3SGK1z02ZOYG k0lt' +
'y6RE4T0lp+GgjGVblCa0zQtmoiqdEEr8ns7u9l0LpOieqbI8q 8Lhw' +
'AeGNXxOUKA7iL8xqt9AJzVcqFWKdXflPEAQCKva0JCVSLzsdf Mksl' +
'568i0GlWg06q1DBNvzRIHP3T1dBahzScBQlCBs2vxfrc96B3j tWvV' +
'K0UnBEQE/sMDPZPVMqnEWa5nLaqmTCzbTWwPsW0yHJwQq2w1cPKCW' +
'eQiBbAIClGqzFe0Q9fJ19Php9FgZL8j3eNep+lYdGTCN8YVPX njIO' +
'3nOX9p7yZ0YdocUdikLfhx/l7rgh8Wbas+4OWmTwiRbhvfQiWxFZt' +
'JwtVrCn6koNsoIC+oonhkxYFb/kNFI/3fKrMWqt1/C2A7DcvPH5/j' +
'XCWycqGiyLARZQAoTvdNaxdjPIoWdhPi86yHvdJ9MlahE0KIi BJZ2' +
'/Q1GrzTKhESDN0OTj3WqjgVOjp8zxO+43m67hUYC01GBIhMrcqu 6S' +
'UCLscobERbQeVh2Ps3FfrA4RedshrwTW9UMHANRYt0Yy+RXZA Yq0y' +
'ahiyjU/Ab9CBC9l0ns0hIP79/Rt066aaqCGQyFhQYnESlFdkG2hz8' +
'+7vZORrQtqWR7SKMVxg3jHSRJY3tOKPUapiGwVmRow0pje9o8 ZyDF' +
'/PNWKd07Z5oENHjcMaZjSUO8zGdGFOQiwUuPgluyB7ycfhe9Agk WI' +
'XDfJBjhsOfxW/VH99OA0QSF4SYrqoSwqy43GsUh/zywcY8cYaJVad' +
'rd6/6z8ByLde/l/Jo7b+P4RdywhvG');
if(FindBitmap(x, y, Tinderbox))then // if found... -.-
begin
Mouse(x, y, 1, 1, true);
end;
freebitmap(Tinderbox); // Always remember to do so.
end;
Also remember to free bitmaps, as it will stop memory leaks.
Take a look at :
function FindBitmap(bitmap: Integer; var x, y: Integer): Boolean;
Search for the bitmap in client window. If found coordinates are returned in x,y. bitmap contains handle to bitmap generated by LoadBitmap.
function FindBitmapIn(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer): Boolean;
Search for the bitmap in coordinates specified by x1, y1, x2, y2. bitmap contains handle to bitmap generated by LoadBitmap.
function FindBitmapToleranceIn(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer; tolerance: Integer): Boolean;
Works like FindBitmapIn but with a tolerance parameter for finding any similar colored bitmap.
Tolerance is used to find a colored bitmap in range of the bitmap you are looking for.
The greater color range you want, the higher the tolerance parameter should be.
function
FindBitmapSpiral(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer): Boolean;
Search for the bitmap in coordinates specified by x1, y1, x2, y2 starting from x, y. bitmap contains handle to bitmap generated by LoadBitmap.
function FindBitmapSpiralTolerance(bitmap: Integer; var x, y: Integer; x1, y1, x2, y2: Integer; Tolerance: Integer): Boolean;
Works like FindBitmapSpiral but with a tolerance parameter for finding any similar colored bitmap.
Tolerance is used to find a colored bitmap in range of the bitmap you are looking for.
The greater color range you want, the higher the tolerance parameter should be.
function
FindBitmapMaskTolerance(mask: Integer; var x, y: Integer; x1, y1, x2, y2: Integer; Tolerance, ContourTolerance: Integer): Boolean;
Essentially it works like FindBitmapIn except it identifies using the masks/shape of an object in the bitmap.
Masks are specified by the colors black and white.
ContourTolerance is the minimal tolerance for color difference between shape of a mask and the background in a bitmap,
It makes sure the shape differs from the background.
<-- sample mask for finding letter A in any color.
^ Found by pressing f1 in scar
DTM’s
Everyone at point should be able to include the usage of DTM’s in their script. DTM, being the acryonym for: Dormed Template mesh.
DTM’s are useful for item finding. For instance, if we wanted to check if we have a log in our inventory, we’d simply do
if findDTM(DtmOfLog,x,y,MIX1,MIY1,MIX2,MIY2)) then result:=true;
Sounds easy enough huh? But how would someone go about making a DTM? Easy! Scar has enabled us to create DTM’s easily, and Jagex has helped us also by making the outlines of objects a constant colour. How nice!
Due to using the example of a log earlier, I’ve decided to make a dtm of … Trout (Thanks drizzt). This might be useful in a cooking situation where you’re waiting to see if the last spot in your inventory, is infact a cooked trout.
First, you should attempt to open up the handy-dandy dtm editor in scar:
http://img507.imageshack.us/img507/9967/firstmv6.png
Once you have achieved this, a picture such as this should appear (assuming you’re logged in, and have the item in the first place).
http://img521.imageshack.us/img521/3986/23741615ps6.png
Now, select a main point, this is the point of x,y which is returned if a dtm is successfully found! (If you look closely there is a red dot)
http://img75.imageshack.us/img75/3237/51295337ds3.png
You should now go ahead and select this as your mainpoint, and select a tolerance of 10-20.
http://img149.imageshack.us/img149/3972/44385883rn6.png
You should now attempt to click on 5-10 places which are black on the object, use the large picture in the top left if you are unsure. Be sure to check if the point is infact black also! (The color should be : 65536, if not delete the subpoint and select another).
http://img172.imageshack.us/img172/9107/56319321zs3.png
Your trout / item should now look like :
http://img509.imageshack.us/img509/710/44305557wq2.png
Now, go to File > Save > And name it however you like.
Close and reopen the dtm editor, which should be showing runescape and your inventory and do :
http://img378.imageshack.us/img378/7627/71533675ck6.png
Select the saved file, and assuming you have done your dtm correctly you should get the message:
Yay? :\ If not repeat the steps, or tell me if I’ve said something wrong, ahhh!
Now all you need to do is click File > DTM to text. And in your Scar message box something like this should appear:
http://img172.imageshack.us/img172/4696/22299983ur9.png
But sir, how do we test for dtms?
Simply put, I dunno. I’ll refer you to my clever owl.
http://img59.imageshack.us/img59/6598/owlloleu7.png
Obviously the dtm should be declared, for instance this script example
program New;
{.include SRL/SRL.Scar}
var
x, y, troutdtm: integer;
procedure Dtm;
begin
Trout := DTMFromString('78DA633CC0C4C0B09F9101197415E733700 16' +
'99828E356A09A13A86A60B270353B806AF611507306A86613 116A' +
'7610507310A8E6307E350079140A92');
end;
begin
setupsrl;
dtm;
if(FindDtm(trout,x,y,MIX1,MIY1,MIX2,MIY2)) then
mmouse(x,y,5,5);
freedtm(trout);
end.
Although this doesn’t fill the first intention of finding if the last slot of our invent Is a dtm of a cooked trout, this is why we can always change
if(FindDtm(trout,x,y,MIX1,MIY1,MIX2,MIY2)) then
Into..
if(FindDtm(trout,x,y,689,430,723,460)) then
Of course I’ll explain a better method later, but for now this is the best you can do :P!
This is the end of the tutorial for dtms goodluck =)
Anti Ban
Antiban, is EXTREMELY easy, but is sometimes over looked. Antiban, is basically, human dumbness :D. This includes things such as waiting long lengths of times, boredom, misclicking etc etc. In most cases Antiban is called by using a procedure, with a case. Look at the example below:
Procedure ProAntiban;
begin
if(not(LoggedIn))then
Exit;
case Random(11) of // Picks a random number for the case 0-11
0,1,2,3 : begin // If the number is 0-3 then will begin this.
HoverSkill('Random', false); //Hovers a random skill
wait(2000+Random(500)); //Will wait 2-2.5 secs.
end;
end;
Before we go on I advice to look at : Srl/Core/Antiban.scar
Okay, now basically we should add more options to the case, from selecting random functions, or procedures from Antiban.scar I have come up with:
Procedure ProAntiban;
begin
if not LoggedIn then Exit;
case 6+random(10) of //Will alow antiban to sometimes never occur
0 : HoverSkill('Random', false);
1: PickUpMouse;
2: AlmostLogOut;
3: BoredHuman;
4,5: begin
MakeCompass('N');
wait(10+random(5));
MakeCompass('S');
wait(10+random(5));
MakeCompass('N');
end;
end;
wait(30+random(30);
end;
Obviously this can be improved on, a lot :P
So you’d plunk this procedure in random places in your script, ie, if it was a mining script, during mining, or whilst waiting for an ore respawn =)
Another thing I like to add in my scripts, is a lot of difference while waiting, in most scripts you’ll see:
Wait(30+random(70));
This sadly does not cut it for me, at all! Firstly that’s a lot of writing, secondly, after 5-10 hours of running a script you’ll most likely have reached all the difference in waits you can, 30-100 :P ie, jagex will know you’re botting. So I came up with sWait, which I feel is far more… ‘Random’ =)
function sWait(number: integer): boolean;
var
i, j, k, l: integer;
begin
j := (number + 10);
k := random(3) + 1; // if random = 0 / 0 = fail, so + 1.
l := random(4) + 1;
for i := 1 to k do
j := j + (j / l);
wait(j);
end;
It’s not even complex, but it is extremely useful, as in the longrun, I write less, and also it will be improved antiban :O zomg, and can reach from a small number to an extremely big number some times ;o. Used like so,
sWait(100);
Other things to add, as I mentioned before, would be to incoperate human dumbness. Ie, forgetfulness. Take a look at this,
function MightRun(Percent, Chance: Integer; where: boolean): Boolean;
var
Energy: Integer;
C0lor: string;
begin
if (not (LoggedIn)) then
Exit;
Energy := GetMMLevels('run', C0lor);
if Energy > Percent then
begin
case Random(Chance) of
1, 2, 3:
begin
gametab(11);
wait(500 + random(500));
SetRun(where);
end;
end;
end;
end;
This is extremely useful while running, and how humans ‘forget’ to run true / false.
Anti Randoms
Adding Anti Randoms to your script is EXTREMELY easy. You don’t even need to write advanced functions thanks to SRL, this is how you should use it :
FindNormalRandoms
If you’ve ever seen FindFastRandoms, don’t ever use this, lol. It’s an extremely old now not needed function / procedure (Can’t remember). Antirandoms is extremely easy, but ‘noobs’ get confused about it. I don’t understand why, but there you go. Sorry about this being so short, lol :S.
Places to call this would be after Bone burying, dropping ores, after eating food and closing windows (banks, shops). Try not to check for Randoms during walking… Because I’ve forgotten how to do so =\
Walking
Radial Walking
Understanding Radial Walking is extremely easy. It relies on a colour, a radius and a limit of degrees. This is the function :
RadialWalk(TheColor: Integer; StartRadial, EndRadial: Integer; Radius: Integer; Xmod, Ymod: Integer): Boolean;
The only ‘complicated’ bit of this may be the start, and end radial. The colour, and Xmod, Ymod are easily explained so I’ll tell you about that after the Start and End Radials.
Okay, to explain this I’ll have to give an example of when you might be able to use it. Assume you need to get out of lumby, you would radial walk the road colour, in order to get to the bridge or something.
http://img392.imageshack.us/img392/2718/firstys5.png
So in the picture below, familiar Lumbridge. Now, imagine a compass over it.
http://img292.imageshack.us/img292/4425/2ndjw7.png
Okay, as you can clearly see we’d need to choose A starting and ending of points between North and South, or, 0-180 degrees. Now, placing slightly more accurate degrees over this:
http://img388.imageshack.us/img388/4171/3rdjf5.png
Okay, so assume we picked a starting radial of 45 degrees, and an ending radial of 90 degrees, It would scan like this:
http://img292.imageshack.us/img292/5780/fifthvl4.png
Basically, it’s ‘trial and error’, although we know we need between points x-y, it might not always work as we plan.
If all this is confusing to you, and you don’t know how radials work then, do not fear there is always Yakman’s RadialWalkerAid:
program RadialWalkerAid;
{
RADIAL WALKER AID by YAKMAN
This is a utility which helps people use Radial Walk.
There are Four Functions of this script.
The first function shows the Radial and Radius of a point
when you move the mouse over the MiniMap. It will also show the Radial
with 360 added, so it can be used for walking upwards.
For Example, when you move the mouse above the center, it will show
a radial of 0 and a radius of around 40.
The second function Draws the Path which RadialWalk takes when you input
the StartRadial, EndRadial, Radius and press the 'Show Path' Button
For Example, if you put StartRadial=90 EndRadial=180 and Radius=50
it will draw a arc in the lower right 50 pixels from the center
moving inwards until it reaches the center.
Both these Functions can have their color changed using the DropDown
Menu, the choises are Red, Blue and Green.
Pressing the 'Clear Box' button will remove all the marks and leave
an empty minimap.
The first Function can be Disabled by UnChecking the 'Drawing Radial'
checkbox.
The thrid function is used by clicking the 'Capture From Client' button
it copys the area from the RS Minimap and displays it on the form.
This can be used now with the first and second functions.
The fourth function is activated by checking the Dynamic Capture
checkbox, it means that the script will capture the client minimap
repeatedly, the frame rate is decided by the drop-down menu
labeled 'DCapture Frame Rate'.
Enjoy!
Yakman.
Before i released this, i sent it to a few people
they all found it VERY useful and a good piece of work
(it also looks really cool when you make it draw the path)
'omg that is soooooooooo
cooooooooooooooool'
Sumilion
'wow, thats great!'
Freddy1990
'WOWAWAWEWA'
WT-Fakawi
}
const
DebugAll = False; //If you really want to see the script working
//Nothing Below needs to be edited
var
bmpBlank_Map:integer;
working:boolean;
//this global boolean shows if radial path is begin drawn
var
bmpCapture:integer;
Capture:TCanvas;
Captured:boolean;
FoundRS:boolean;
var
i,StartRadial,EndRadial,Color,Radius:integer;
//radial path drawing globals
var
frmDesign : TForm;
Label1 : TLabel; //form variables
Label2 : TLabel;
Label3 : TLabel;
Label4 : TLabel;
Label5 : TLabel;
Label6 : TLabel;
Label7 : TLabel;
Label8 : TLabel;
Label9 : TLabel;
Label10 : TLabel;
Button1 : TButton;
Button2 : TButton;
ComboBox1 : TComboBox;
ComboBox2 : TComboBox;
CheckBox2 : TCheckBox;
CheckBox1 : TCheckBox;
Button3 : TButton;
Button4 : TButton;
Button5 : TButton;
Edit1 : TEdit;
Edit2 : TEdit;
Edit3 : TEdit;
Memo1 : TMemo;
Timer2 : TTimer;
Timer3 : TTimer;
//constants, dont change these unless RS updates
const
FormX = 190; //where to copy to the form
FormY = 92;
const
ClientX = 551; //where to copy from the clint
ClientY = 9;
const
Height = 151; //dimentions
Width = 152;
const
CenterX = 266; //center of the form image
CenterY = 168;
procedure ClearMap;
begin
if(captured)then
SafeCopyCanvas(capture,frmDesign.canvas,0,0,Width, Height,FormX,FormY,FormX+Width,FormY+Height)
else
SafeCopyCanvas(getbitmapcanvas(bmpBlank_Map),frmDe sign.canvas,0,0,Width,Height,FormX,FormY,FormX+Wid th,FormY+Height);
end;
procedure DrawBlankMap(sender:TObject);
begin
frmDesign.RePaint;
end;
function Distance(x1, y1, x2, y2: Integer): Integer;
// By PPLSUQBAWLZ edit BenLand100
begin
Result := Round(Sqrt(Sqr(x1 - x2) + Sqr(y1 - y2)));
end;
function FindRadial(x,y,radius:integer):integer;
var x1,y1,r:integer; //this finds the radial at your mouse by
begin //checking every radial of the radius and seeing if your
if(working)then exit; //mouse is close to there
for r:=0 to 360 do
begin
x1:= Round(Radius*Sin(r * pi / 180))+CenterX;
y1:= Round(-Radius*Cos(r * pi / 180))+CenterY;
if(DebugAll)then
frmDesign.Canvas.Pixels[x1,y1] := 16777215;
if(Distance(x1,y1,x,y)<=1)then
begin
result:=r;
exit;
end;
end;
writeln('Failed to get radial');
end;
procedure DrawRadial(x,y,Thecolor:integer);
var Radius,Radial:integer;
begin
if(working)then exit;
Radius := Distance(CenterX,CenterY,x,y);
Radial := FindRadial(x,y,Radius);
if(not DebugAll)then
ClearMap;
frmDesign.Canvas.Pen.Color := TheColor;
frmDesign.Canvas.MoveTo(CenterX,CenterY);
frmDesign.Canvas.LineTo(x,y);
Label1.Caption := 'Radial = '+inttostr(Radial);
Label2.Caption := 'Radius = '+inttostr(Radius);
Label10.Caption := 'Radial + 360 = '+inttostr(Radial+360);
end;
procedure SafeDrawRadial(x,y,color:integer);
var t:TVariantArray;
begin
t:= [x,y,color];
ThreadSafeCall('DrawRadial',t);
end;
//event called when the mouse if moved
procedure MouseMove(Sender:TObject;Shirt:TShiftState;x,y:int eger);
var fillcolor:integer;
begin
if(working)then exit;
if(DebugAll)then
writeln('Mouse Move Event - Mouse at '+inttostr(x)+','+inttostr(y));
if(not CheckBox1.Checked)then exit;
if(not ((x>FormX)and(x<FormX+Width-6)and(y>FormY)and(y<FormY+Height)))then exit;
case ComboBox1.Text of
'Red':fillcolor:=255;
'Blue':fillcolor:=16711680;
'Green':fillcolor:=65280;
end
SafeDrawRadial(x,y,fillcolor);
end;
//event called by Timer3
procedure DrawRadialStep(sender:TObject);
var x1,y1:integer;
begin //draws on step of the radial path, then changes global variables
Working:=true; //for the next time it is called
case ComboBox1.Text of
'Red':color:=255;
'Blue':color:=16711680;
'Green':color:=65280;
end
x1:= Round(Radius * Sin(i*pi/180))+CenterX;
y1:= Round(Radius * Cos(i*pi/180))+CenterY;
frmDesign.Canvas.Pixels[x1,y1]:=Color;
if(DebugAll)then
writeln('x1 = '+inttostr(x1)+' y1='+inttostr(y1));
if(i=EndRadial)then
begin
i:=StartRadial;
Radius:=Radius-4;
end;
if(Radius<=1)then
begin
Timer3.Enabled := False;
working:=false;
Button3.Caption:='Show Path';
exit;
end;
if(StartRadial < EndRadial)then
i:=i+1
else
i:=i-1;
if(DebugAll)then
writeln('i='+inttostr(i)+' radius='+inttostr(radius)+' sr='+inttostr(startradial)+' er='+inttostr(endradial));
end;
//called by pressing Button3
procedure OnRadialPath(Sender:TObject);
begin
if(not Working)then
begin
try
StartRadial:=StrToInt(Edit1.text);
EndRadial:=StrToInt(Edit2.Text);
Radius:=StrToInt(Edit3.text);
except
edit1.text:='0';
edit2.text:='0';
edit3.text:='0';
if(DebugAll)then
writeln('Numbers Only!');
end
ClearMap;
if(Radius > 80)then exit;
StartRadial:= StartRadial + 180;
EndRadial:= EndRadial + 180;//all this because SCAR's sin uses radians
StartRadial := 360 - StartRadial;
EndRadial := 360 - EndRadial;
case ComboBox1.Text of
'Red':color:=255;
'Blue':color:=16711680;
'Green':color:=65280;
end
i:=StartRadial
Timer3.Enabled:=True;
Button3.Caption:='Stop';
end
else
begin
Timer3.Enabled:= False;
Button3.Caption:='Show Path';
working:=false;
end
end;
//called by clicking the mouse
procedure MouseDown(Sender:TObject;Button:TMouseButton;Shift :TShiftState;X,Y:Integer);
begin
if(working)then exit;
if(not ((x>FormX)and(x<FormX+Width-6)and(y>FormY)and(y<FormY+Height)))then exit;
CheckBox1.Checked:=not CheckBox1.Checked;
end; //simply freezes the radial display
procedure Paint(Sender:TObject);
begin
ClearMap;
end;
procedure PrintProc(sender:TObject);
var sRadial,eRadial,Radius:integer;
begin
if(working)then exit;
try
sRadial:=StrToInt(Edit1.Text);
eRadial:=StrToInt(Edit2.Text);
Radius:=StrToInt(Edit3.Text);
except
edit1.text:='0';
edit2.text:='0';
edit3.text:='0';
if(DebugAll)then
writeln('Numbers Only!');
end
Memo1.Lines.Add('');
Memo1.Lines.Add('RadialWalk( {TheColor} , '+inttostr(sRadial)+', '+inttostr(eRadial)+', '+inttostr(Radius)+', {Xmod}, {Ymod});');
Memo1.Lines.Add('RadialRoadWalk(RoadColor, '+inttostr(sRadial)+', '+inttostr(eRadial)+', '+inttostr(Radius)+', {Xmod}, {Ymod});');
end;
procedure FindClient;
begin //finds the RS window by size
if(working)then exit;
if(FindWindowBySize(766,504))then
label8.caption:='RS Handle = '+Inttostr(GetClientWindowHandle)
else
label8.caption:='RS Handle = 0';
end;
procedure CaptureFromClient;
begin
try //frees an older bitmap if it exists
FreeBitmap(bmpCapture);
except
//there was no older bitmap to free
end
bmpCapture:=BitmapFromString(Width,Height,'');
Capture:=GetBitmapCanvas(bmpCapture);
if(not FoundRS)then
FindClient;
if(Label8.Caption = 'RS Handle = 0')then
exit;
try
SafeCopyCanvas(GetClientCanvas,Capture,ClientX,Cli entY,ClientX+Width,ClientY+height,0,0,Width,Height );
SafeCopyCanvas(Capture,frmDesign.canvas,0,0,Width, Height,FormX,FormY,FormX+Width,FormY+Height);
except
CheckBox2.Checked:=false;
end
Captured:=true;
end;
//called by pressing button
procedure ClientCapture(sender:TObject);
begin
CaptureFromClient;
end;
//called by Timer2
procedure DynamicCapture(sender:TObject);
begin
if(working)then exit;
CaptureFromClient;
end;
//called by changing CheckBox2
procedure StartDCapture(sender:TObject);
begin
if(working)then exit;
if(CheckBox2.Checked)then
begin
Timer2.Interval:= StrToInt(ComboBox2.Text);
Timer2.Enabled:= True;
end
else
begin
Timer2.Enabled:= False;
end
end;
//called by pressing button
procedure FindRS(sender:TObject);
begin
if(working)then exit;
FindClient;
end;
procedure Form;
begin //constructs the form
frmDesign.Left := 267;
frmDesign.Top := 154;
frmDesign.BorderIcons := ;
frmDesign.BorderStyle := bsSingle;
frmDesign.Caption := 'Radial Walking Aid - Yakman';
frmDesign.ClientHeight := 387;
frmDesign.ClientWidth := 519;
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.PixelsPerInch := 96;
frmDesign.OnMouseMove:= @MouseMove;
frmDesign.OnPaint:= @Paint;
frmDesign.OnMouseDown:=@MouseDown;
Label1 := TLabel.Create(frmDesign);
Label1.Parent := frmDesign;
Label1.Left := 48;
Label1.Top := 40;
Label1.Width := 48;
Label1.Height := 13;
Label1.Caption := 'Radial = ';
Label2 := TLabel.Create(frmDesign);
Label2.Parent := frmDesign;
Label2.Left := 48;
Label2.Top := 88;
Label2.Width := 48;
Label2.Height := 13;
Label2.Caption := 'Radius = ';
Label3 := TLabel.Create(frmDesign);
Label3.Parent := frmDesign;
Label3.Left := 64;
Label3.Top := 256;
Label3.Width := 55;
Label3.Height := 13;
Label3.Caption := 'Start Radial';
Label4 := TLabel.Create(frmDesign);
Label4.Parent := frmDesign;
Label4.Left := 64;
Label4.Top := 288;
Label4.Width := 52;
Label4.Height := 13;
Label4.Caption := 'End Radial';
Label5 := TLabel.Create(frmDesign);
Label5.Parent := frmDesign;
Label5.Left := 64;
Label5.Top := 320;
Label5.Width := 33;
Label5.Height := 13;
Label5.Caption := 'Radius';
Label6 := TLabel.Create(frmDesign);
Label6.Parent := frmDesign;
Label6.Left := 192;
Label6.Top := 16;
Label6.Width := 265;
Label6.Height := 13;
Label6.Caption := 'Move Your Mouse Over the MiniMap To Display Radials';
Label7 := TLabel.Create(frmDesign);
Label7.Parent := frmDesign;
Label7.Left := 168;
Label7.Top := 40;
Label7.Width := 332;
Label7.Height := 13;
Label7.Caption :=
'Input '#39'StartRadial'#39' '#39'EndRadial'#39' and '#39'Radius'#39' to Display RadialWa' +
'lk Path';
Label8 := TLabel.Create(frmDesign);
Label8.Parent := frmDesign;
Label8.Left := 376;
Label8.Top := 168;
Label8.Width := 64;
Label8.Height := 13;
Label8.Caption := 'RS Handle = 0';
Label9 := TLabel.Create(frmDesign);
Label9.Parent := frmDesign;
Label9.Left := 376;
Label9.Top := 240;
Label9.Width := 103;
Label9.Height := 13;
Label9.Caption := 'DCapture Frame Rate';
Label10 := TLabel.Create(frmDesign);
Label10.Parent := frmDesign;
Label10.Left := 24;
Label10.Top := 64;
Label10.Width := 72;
Label10.Height := 13;
Label10.Caption := 'Radial + 360 = ';
Button1 := TButton.Create(frmDesign);
Button1.Parent := frmDesign;
Button1.Left := 16;
Button1.Top := 344;
Button1.Width := 100;
Button1.Height := 25;
Button1.Caption := 'Print Procedure';
Button1.TabOrder := 15;
Button1.OnClick:= @PrintProc;
Button1.OnMouseDown:=@MouseDown;
Button2 := TButton.Create(frmDesign);
Button2.Parent := frmDesign;
Button2.Left := 16;
Button2.Top := 112;
Button2.Width := 118;
Button2.Height := 25;
Button2.Caption := 'Clear Map';
Button2.TabOrder := 8;
Button2.OnClick := @DrawBlankMap;
Button2.OnMouseDown:=@MouseDown;
Button3 := TButton.Create(frmDesign);
Button3.Parent := frmDesign;
Button3.Left := 16;
Button3.Top := 208;
Button3.Width := 75;
Button3.Height := 25;
Button3.Caption := 'Show Path';
Button3.TabOrder := 11;
Button3.OnClick:= @OnRadialPath;
Button3.OnMouseDown:=@MouseDown;
Button4 := TButton.Create(frmDesign);
Button4.Parent := frmDesign;
Button4.Left := 376;
Button4.Top := 104;
Button4.Width := 106;
Button4.Height := 25;
Button4.Caption := 'Capture From Client';
Button4.TabOrder := 16;
Button4.OnClick := @ClientCapture;
Button5 := TButton.Create(frmDesign);
Button5.Parent := frmDesign;
Button5.Left := 376;
Button5.Top := 136;
Button5.Width := 75;
Button5.Height := 25;
Button5.Caption := 'Find RS';
Button5.TabOrder := 17;
Button5.OnClick := @FindRS;
ComboBox1 := TComboBox.Create(frmDesign);
ComboBox1.Parent := frmDesign;
ComboBox1.Left := 16;
ComboBox1.Top := 144;
ComboBox1.Width := 118;
ComboBox1.Height := 21;
ComboBox1.ItemHeight := 13;
ComboBox1.TabOrder := 9;
ComboBox1.Text := 'Red';
ComboBox1.Items.Add('Red');
ComboBox1.Items.Add('Blue');
ComboBox1.Items.Add('Green');
CheckBox1 := TCheckBox.Create(frmDesign);
CheckBox1.Parent := frmDesign;
CheckBox1.Left := 16;
CheckBox1.Top := 176;
CheckBox1.Width := 97;
CheckBox1.Height := 17;
CheckBox1.Caption := 'Drawing Radial';
CheckBox1.TabOrder := 10;
CheckBox1.Checked:=True;
CheckBox1.OnMouseDown:=@MouseDown;
Edit1 := TEdit.Create(frmDesign);
Edit1.Parent := frmDesign;
Edit1.Left := 16;
Edit1.Top := 248;
Edit1.Width := 39;
Edit1.Height := 21;
Edit1.TabOrder := 12;
Edit1.Text := '0';
Edit1.OnMouseDown:=@MouseDown;
Edit2 := TEdit.Create(frmDesign);
Edit2.Parent := frmDesign;
Edit2.Left := 16;
Edit2.Top := 280;
Edit2.Width := 39;
Edit2.Height := 21;
Edit2.TabOrder := 13;
Edit2.Text := '0';
Edit2.OnMouseDown:=@MouseDown;
Edit3 := TEdit.Create(frmDesign);
Edit3.Parent := frmDesign;
Edit3.Left := 16;
Edit3.Top := 312;
Edit3.Width := 39;
Edit3.Height := 21;
Edit3.TabOrder := 14;
Edit3.Text := '0';
Edit3.OnMouseDown:=@MouseDown;
CheckBox2 := TCheckBox.Create(frmDesign);
CheckBox2.Parent := frmDesign;
CheckBox2.Left := 376;
CheckBox2.Top := 264;
CheckBox2.Width := 111;
CheckBox2.Height := 17;
CheckBox2.Caption := 'Dynamic Capture';
CheckBox2.TabOrder := 18;
CheckBox2.OnClick := @StartDCapture;
ComboBox2 := TComboBox.Create(frmDesign);
ComboBox2.Parent := frmDesign;
ComboBox2.Left := 376;
ComboBox2.Top := 216;
ComboBox2.Width := 87;
ComboBox2.Height := 21;
ComboBox2.ItemHeight := 13;
ComboBox2.TabOrder := 19;
ComboBox2.Text := '500';
ComboBox2.Items.Add('10');
ComboBox2.Items.Add('100');
ComboBox2.Items.Add('250');
ComboBox2.Items.Add('500');
ComboBox2.Items.Add('1000');
Timer3 := TTimer.Create(frmDesign);
Timer3.Interval:=2;
Timer3.Enabled:=False;
Timer3.OnTimer := @DrawRadialStep;
Timer2 := TTimer.Create(frmDesign);
Timer2.Interval := 10;
Timer2.Enabled:= False;
Timer2.OnTimer := @DynamicCapture;
Memo1 := TMemo.Create(frmDesign);
Memo1.Parent := frmDesign;
Memo1.Left := 152;
Memo1.Top := 296;
Memo1.Width := 185;
Memo1.Height := 68;
Memo1.ScrollBars := ssBoth;
Memo1.TabOrder := 20;
frmDesign.ShowModal;
end;
procedure SafeForm;
var T:TVariantArray;
begin
ThreadSafeCall('Form',t);
end;
procedure LoadBMP;
begin //loads the bitmap of the blank map
Writeln('Loading Bitmap');
bmpBlank_Map := BitmapFromString(152, 151, 'beNrtnf1vleU' +
'Zx8Ep6nRkcUoCQuZ4SQMUJi8OsAULZaz0LaGtGlpehMpbBZS2 hHcz' +
'aNUx7SJKpCEMReJmZCRmbD+4uMUf5g9LlpksMVli/MV/Y7/sU7704' +
'uJ+zikOaXuect25cvKc06fl9Pmc7/e6rvu+n1K1eEv1ZKKzcVr/rj' +
'lv76s+0rmpvbVuYfn02bOmFIslC2eub6zktNbm6trVTzbUVPJ I1FQ' +
'tJvwrFs11FQTnN9ev4sBe7Nhaf2L/c6d6XySOdjT5OLy9bs+GlS11' +
'A++wbfmkJJrL709i3C2N7M/hh+uaJLG5toz307291r9D/9S/frav+' +
'28fv/XPv15QfHr5VOfOFl2Bra2rOaiuWECsXDZfoafLn5jLlZ83e2' +
'rByz5r+mQeOYHrTzw+dxpnWrS1VO9sWaa32tNWBsqujtYtz6w uhpJ' +
'/izcjiKJjBI2jXoemgPIiB3pR5/P4QnuTCJ48tiO5DlwuLhrXc+Oi' +
'B4iC7MYN2/D/SkGgfLR4h3BJ2BH+lQv9PYaSg97D2/it1zdVwpHgg' +
'MtiHBOU2YsviHx1TdUiToajiFs8v7EOlASSNFVykcGU/WDwE65DvK' +
'qsLEePLDlBTze0rBVBHvUr64DPtsenWDtrgmJY2d0aUz7/Xo8cJyj' +
'//LuTECQ4eOP4bq4bPiZJEhIClxQ6hlJPhUn4FLySSHjF0nJehNH r' +
'vfuI3c+vA6VoJii5/kYQFfOUd+KVaJEVY5YjHyS+8dDeNgSYEOTjz' +
'WWBGpcrwTeuZEYxoPLbrLsS/Kao8typg/yaJCyCPMJFUAglZCVMuI' +
'gUIUagNBnqRcJL+K2+Y8TF868TXR3PFkTJRwtknKyECI5dmxo KQvT' +
'ZMAvRjBQj8hoEqAhKgLpERnBcCQ9PU5dLNElGBWnyi5Oq+MWx ViKh' +
'qZAWzF2lSnksj+DToxE8e7pXBN8788qHr/6if8+8I52bCWh6lHAke' +
'AP8E95Lr9npYOgNeIj+0YIPAO/fZCiCmJInWIIC/PbyFE1C2kzc1T' +
'63uggEHqt60qMkY8pmfRjBBCIEL1/8DQSPNkzd8tMfNsyf8vrxPSc' +
'OPu9RDiTxQXeVpRsyy4kqvRJtyj/tUefAjncudgoRtOuQL3zZoUSQ' +
'pVlQm6BUcU5AUyWlIF6j2VhpSdBnQ++lQLxypu2NTY9B8KkZD xHNk' +
'x4803cgQeklKQewEsVHQY5qOnQ+ctbHzxeiY4ngTWlS+fgPsD wWJU' +
'LQaEIWv7oBZVPlujUFSlnCICJDNCiIOx76/oGJ98HRo1Su5ILTg1i' +
'WNKsc0OZVVWbtXYnyGtP6VUlFys+xSmaMERyaJuZj5ZynKWEC lOBY' +
'KczUkQhTKClKBXF/1cMmQwi+dvddv7/37k//eF4cCUlSKE2SsnEvS' +
'cuS1zPmja29r0gH3nbjtDFPcAiaBW0WcFwiIJ4+2QVQHnk6kM UGVS' +
'mshvK9I782JZoMIfjOPd8D4l/uv+fimeOERymOfJDEkfdQ2FqNoyt' +
'KsRGTIcfIMDHScXfMuGnSlMdyuc72dROgvO6xjZW+joUmtc2l sy+R' +
'E7HTx6dPRomSIQQVl979lTiauypL8gOBePnlSlikHG+sduwAG frpN' +
'd72HSXDmwpTUwfZOtbSZUGP5UBpkepUhY3sFCUaROJPH75pKJ MsSY' +
'qEI1WrOHqUSbeIISQzbHz87kwZDi1MdZrZWVnwoUcBVR3ra0i J0Tt' +
'qAjHhKJRWuIojqtR8eMLRnr7Q3uR7Q++ld6YMbyFjKl2C0gLL pSXh' +
'8qq8kRgLOuqOKfcScEwkmXCUHhOOBROiekPvpUGwmDBBmfVY2 FmuJ' +
'FAHRnfi6N6L73RaZkzECMGvFtzz1dan/vX5lYSj0YTjZ2c2g1K+uq' +
'ZqUTJRY1Nt4sh7C4g3Rbl21VxD2VK3OOuxXNJzpw4SQokeZaq VC36' +
'MqZIZTYxA/Kz8rv/+/WMCjv/49AO6D6F898GJBBDVRXqOVE3iqD5R' +
'M97ZhBhe+v96bBYlKfJCfw8BSjief20jPWPWVAfEuPUpIP779 P5iY' +
'mxrqRZH+ap6GeOoNt/3+CHD71L8JCh5aqqEI8mxKMerpkoUS45wBN' +
'AXF/f6/CiO6nrkpQHxdqHMVj6oEo40HXBsX/FoUY5XQxyzxSrsIPj' +
'lpUPWPyo/mhI5SErTQHN7UWoF0/SozrEYx2LN4/rGSsQIR5vPwVf9' +
'GmJAHA6UvojV+texA7vEkTpHMwCeY++jEwpy9KtX33zSR37Uj B9ip' +
'AZWYRNKHBmU2vND30GdY/Wq+g5D+fQP7hbKgmKUqf7n899+9EqTWg' +
'x6Ul+dRk4csdYSPZ7ve47+URzNWi2EMsmM4khfg6N+faUXVYq jNYk' +
'BcYRV2bW7lRTZv2eelTqaXE1QZsUItUSMA7MKgxB9nxgXf1hV aWUP' +
'1qotHGattmLFoyK7GYBPAkpUhaNZd78lIyAO6+iuuC87RSBrf X/LN' +
'Fu0MpQWBlFiJA+e7euGI5K0XVLJOlRAHG6UftWSUgeO6j5Mku auFn' +
'6HFdKjraBMxVFtKdNqp4A4KiiJgevftQWUH7xY5t1VmzrE0SD imeB' +
'TrzHgn/Wr6DhsvihqmxHm6KfTlSjJkud6ngWlekk81vbnECpsPETd' +
'SIIe5aiH9rZFWhz1RDmwLbZrC3H64FoSpVQplMqVtBh4JlWN7 HQAm' +
'YMYjjq6KCHoE+XubU8Txzt+jir71k2lEzGUCBCCmg/XlmPVNtZoaN' +
'4mII5uorTJgW0b6oWSjtLTRInI8Fq/X7+qpmoxvhotf+m66/Y6UBL' +
'72mt+2b4UlAROazM2WmHU1I01GgGxNDtKCVM00eaZl35mN76t XDaf' +
'R7s9M9JiCbqr7qL1C1vNdcvbmqvbBhekFJp/03JJzL+VpiSzy5Qnj' +
'+1YsXSO3YKaOGqIsZTd1VYn1RiePtllmxg9YpU3AbFka1cvSd 1fII' +
'i2RhxizFHB43dn2a0ZIcYcSdLuyPMctSk9VqZyN8Pj9ahbv+1 pzN7' +
'kVJImRh5DjPnKkoRVrV6MkRlzJ8nrez+iZ8yzJLVcFT3jWJKk bgwJ' +
'MY6FaqdxWlQ4+eJoGz8Ia0Bsk39coryMV1dPSKzV/2GNuD454ri5t' +
'qynrUzWSr1qphoXJ4+SFMow1bHBMdrGsWGttu4flyWnKOFIhK mODW' +
'uNSjU4xiidFCmOcUHyniKD49iw1uAYHGOUToq8CnF8XI28owy OwTF' +
'GcIwxDBxjBMcYJcExLkKMGDFixIgRI0aMGDFixIgRI0aMGDFi xIgR' +
'I0aMGDFixCg0xscunVyPwX0dwTE/khufknL7c4JjjkdwDI4xgmOM4' +
'BijIEf9mcdBjsUiRklD7GkrC45jgGP/rjnfgmOMHHDUH5cLjrnmeP' +
'nlSvQ4pCRjlDpElDgkxxj54Hh4e91HrzStqZhRxFpj5IPj2/uq4bh' +
'y2fxCeoyRG45A/OzM5pqqxUgSlBsXPTBIMDjmyVSBSLQ2VzuOMfJX' +
'qYrjC+0D1tq2fFJwzCNHQcRaj3Ruql39ZEgy16YKxzeO78ZaV e0Ex' +
'9xVOF9c3AtHStbTJ7vaW+tkrYEyRxA315ZBUBz3bFh57tRBUu SNVW' +
'uMfLSNQCRQJRwv9Pf0Ht4W1pqv8WbtvRIjQZYUR6x1a+vq6oo FIcm' +
'8QITdl5cOERJj9/ba908fIGStSxbODI55EaM44q7iiBhJkbLW5U/M' +
'jWonR2JUhbNrUwMc6TvgaFVrWGvpc8RLE1MVR0nySOcmrFXVT qAsW' +
'Yg9bWVejIJI4KhwJEXyGNaaCzF+faVXmXHLM6sFEaeFI5KEox rJFU' +
'vLVe0EytLMjEAkEOPOlmUGkQCiUiQoYUr3IUnqvxKIq1dqZao 4Soz' +
'gSzhKkqd6X2yuq4AjktR/2BooSwci7L75pI/wYhRH1TnIkECSRMfW' +
'enHU/1Af7loiEAFHTgQiYtQETsJREFXtqJGkZIWjSXLtqrmBshTKG' +
'4nxbF+3F6M4Hu1oMl+1qlXW+sSCcv3P5iHJ0ilvkCTHavw9xx P7nz' +
'OOqnZUtSJJUK6pWhQoS8dRCTX+MlJzVBOjt1ZkqwkBcTSU4a6 jWKM' +
'WLG+8GClQRRB2aiRBqR0CcESVeCxM1U4GylGsUeWovrzxmVEc gaiQ' +
'JInOnS0rlpaLoy1NhruOYo2qdQ1zVGsbEaOQJRyVJTlAhqDkE Y7ai' +
'IW7xra6EYO4vqnyi4t7LS3C1EM0MaJEUmHCkZC1amUZa62uWI AkCZ' +
'iqowRooBz1tGhzqkAkoGkEuzpavbVy7K1VuwWioxzhbrFgWlQ gRgh' +
'intIjqTDLka8iTFlrQ00lHKEJ0821ZdGGjExtY/OoBcVInDy2Q4oj' +
'0GPH1npBTDjaMpZS5MDtA1WLNH8ulN0V98VlH6aW36fFghAhB TsfA' +
'DIxWorUhIBZqzha4RooRwBiskycOKp6DT0qkFvCMWutSpFUPh wsWT' +
'hT7kpwEChvI0Sbt/nDuWPaeJPUqAbR7JRQy49z+nrVdx9Ee2udWSv' +
'HKmI9ylDlbYEINYNoW1KLpUUVNtKjJMnTebNneIiWJbWyzGlm rXAk' +
'KHvgaDVPoPzuELXl5qYFKkHXr0ZDGvQcZ02frJJVpY5x5Kuqd jTXy' +
'iMQKYoAClli7Yq5YbAjCRFH1QS4TFUT45Yop075EYCyevTLH5 oQgC' +
'AcOVlkkaRHSQTK7wIRO4VgsQI1SYviiMfqmMfJj0xUyWochdI 27XA' +
'AMjWSXpJ60SYHAuUt9IlJYVNMiT4t2lqGrRor8FX0lczO+aqV EDj6' +
'R+ock+QQKIPm0ARt+6JvMYaASFoUCJtNlRgNJS/KIW0JMrv8wbejU' +
'M7RHB02C0qA6hWhtPkBX/mMvzoCXAIR57S5U1Cq2R8aoubfNAWn2V' +
'QrVk1rmnATtSxHuas1klbtENr+IZQcaLnZIiqfmzaJNu02BMR De9u' +
'MlJU3vlIVYq1rAIKS1QgmcwJ29wcctfyBJAm+UYWrofQ1T3hs MS9V' +
'qEksVtUYRMPka1QcVaYqxJzD8fqmyoXl08mA2RTplz/MWiVJuasKV' +
'6lSiTKLMrpLtfnaQowYtRt8iNI0gSgjTThKj0aZk4FI65EtdV Ao7G' +
'StnM/3mpECXRw1kU5IqprB44MRwkxkiPp0c41uA5eXJov7BdekvBg' +
'TU7XlDN3zOPOxSQ8/9OCShTMTJSYrIIS2KCtLcuwlaTUPHMW3pW6x' +
'zajfmRkTghCxu7/tDqmCe6X8FjjEpUmYBKIvbzi40N+j0mXXpgZEB' +
'MGfTHtk3uypPjkmczu2A0T+yXeRHOGIZiVJy5L6kmbw+NK6Nd dp0v' +
'PeIcI0GRpEL8OCEC20IOULVFOitfxqNPQHAfTnj3TlsVa6SLh 4Mcp' +
'XfdVqK5LSHScQuiHdUHIgSQoloR13clpQiuarqycQY5UgVagn yLFK' +
'Gq+7LES81FoM9RdCqStvS1SCaOWNFhM1cYokSZHoKFvnWD/iN3toT' +
'gBGQmmFq6nSehOh1IIXTmvCHHs0E4L2mHQWifoSiNCRW3o7zc 7e6A' +
'SYIiJkKI44KmKc/MhELrXKm2Su1W9t1bS5rYCoAbEsaTM8kqQ4FqQ' +
'plGODpieoEEHt/V7fWJncU1MQImXkt4HozdbuH9dKIsmRoNSBrJWs' +
'2R7EOGpF0lc7hM24+t5EKK0iElBt9cFmDaWnmSOgwieCSoUWP JWRZ' +
'rcNZwlqAnxogglHDtQ+CKICMRL4KscFW8ikkeQn6NsBR4thgE ynCi' +
'2OJBx1JsJUxjSO/bvmEHmRp/Dxbi+/XAkyhRH0RuqRZTnKS3V7VLY' +
'0zc6EW7fIi/qjHAaRY8Q4e9YUOGZbj+xKln6gtY3KkgJkJZASZUNN' +
'pbEzmubDmkRau2qu1T9CaUBLUJ4mQBB4ggpesaXDBFbSViRVD UpU5' +
'Wm5z9Kfqhq9wjm6Gw4KPi1CTZed/Dhv9gwkqY0BN5Wk9l+JV6I76y' +
'WlVv8lcVRdpCpX/sz74btImgKa0PRAR4Wp/dPCx7uCl4UIase+tfY' +
'FBZiFqC3EslMtZIiaadOXpmKt17l6Pi2aHmk6CF7hUbOsfE6K cTRJ' +
'0rPo2y0VasbVNyA+S5oY1c6or1HNrP3q6Jfz6Tfltx5oYrnDz dT/K' +
'/ZOPD4LEbQlp8Q2k4mapKrx0zXZKRrrFkXQNOtrG2+qNf8DGPMB Pw' +
'==');
writeln('Bitmap Loaded');
end;
procedure SetSelfWindowState(State:TWindowState);
begin
GetSelf.WindowState :=State;
end; //sets the SCAR main form window state
procedure SafeSetSelfWindowState(State:TWindowState);
var t:TVariantArray;
begin
t:= [state];
ThreadSafeCall('SetSelfWindowState',t);
end;
begin
ClearDebug;
writeln('Successfully compiled');
LoadBMP;
if(not DebugAll)then
SafeSetSelfWindowState(wsMinimized);
frmDesign:= CreateForm; //this is already thread safe
SafeForm;
SafeSetSelfWindowState(wsNormal);
FreeBitmap(bmpBlank_Map);
try
FreeBitmap(bmpCapture);
except
end
end.
Xmod Ymod
Srl’s definition of Xmod and Ymod is:
XMod, YMod: deviation from MouseFindFlag. -2 to 2.
Pretty much this is the Randomness of the point it will click. It’s best to use -2,1 etc, so it doesn’t appear off the map.
Radius
The radius is just the length of the search line, it is best to use a radius of 20-72.
I’ll add more on this if you don’t understand. In a case like lumbridge 72 would be fine, but if we were continually using in a script perhaps we should have the radius as
Radius := 50+random(22);
Or any other radius will work.
The Color
This is the easiest part of the function, yey ^_^
If you take a look at autocolor, In srl, you’ll notice these colors which are extremely useful for radial walking.
// » function FindWaterColor: Integer; | by Tarajunky fixed by BobboHobbo
// » function FindRoadColor: Integer; | by Tarajunky
// » function FindVarrockRoadColor: Integer; | by Tarajunky
// » function FindFallyRoadColor: Integer; | by Tarajunky
// » function FindLumbyRoadColor: Integer; | by ZephyrsFury
// » function FindRockColor: Integer; | by Tarajunky
// » function FindStoneColor: Integer; | by Tarajunky
// » function FindDirtRoadColor: Integer; | by ZephyrsFury
// » function FindBridgeColor: Integer; | by Tarajunky
// » function FindLadderColor: Integer; | by Tarajunky
// > function FindSandColor: Integer; | by Tarajunk
Basically pick the color which you want. So In this case with getting out of lumbridge, we obvious would use FindLumbyRoadColor, and thus select this and place it into our function as you will see below.
Putting it all together
Okay so we’ve decided that we should be using:
A color of FindLumbyRoadColor
A starting radial of 45 degrees
An Ending Radial of 90 degrees
And the radius should be 50
We also decided the xmod, and ymod to be -2,1
Once placed into the function:
RadialRoadWalk(FindLumbyRoadColor, 45, 90, 0, -2, 1);
But say we wanted lots of walking, (bad example), we could use nesting, and if statements like so;
program New;
{.include SRL/srl.scar}
begin
Setupsrl;
ActivateClient;
Wait(300);
if(RadialRoadWalk(FindLumbyRoadColor, 45, 90, 72, -2, 1)) then
if(RadialRoadWalk(FindLumbyRoadColor,70,120,72,-2,-1)) then
writeln('Yay, where ever the heck i planned to go, worked!'); // Somewhere over the bridge ;o
end.
Obviously we would need to add failsafes ! More on that later.
Symbol Finding
Symbol finding is extremely useful, yet sometimes unreliable. This is more noticeable when attempting to bank sadly, as the white dots overlap the symbol sometimes making it unfindable.
Symbols can be used for failsafes, location checking, and as actual walking.
I shall pretend that you are making a smithing script in lumby, which ties in with the whole radial walking example. Say we have just radial walked from lumby up near the furnace, and we want to get in the building / near the furnace :
Therefore using:
FindSymbol(x,y,’Symbol name’);
Where x,y is the Coords of the symbol, and the symbol name… Being one of these :
{************************************************* ******************************
Valid Arguments are:
- agility - furnace - quest
- altar - gem stall - rare trees, tree
- anvil - guide - sandpit
- apothecary - hair dresser - saw mill
- archery shop - herbalist - scimitar shop
- arrow - house - shield
- axe shop - hunter store - shop, store
- bar - hunter training - short cut
- candle shop - jewelery - silk stall
- churn - kebab shop - silver stall
- clothes shop - mace shop - slayer master
- cookery shop - magic shop - spice stall
- cookery, cook - makeover mage - spinning wheel, spin
- crafing shop - mill - staff shop
- dungeon - minigame - summoning store
- farming shop - mining shop - sword shop
- farming spot - pet shop - training dummy
- fishing shop, fish store - platebody shop - underground
- fishing spot, fish - plateskirt shop - water source, water
- food shop - portal (to player owned houses) - weave
- fur trader - pottery, pot - windmill
************************************************** *****************************}
So, That means we just need to Do,
FindSymbol(x,y, ‘furance’);
Pretty easy, but we of course need to make an if statement, to see if this is true!
If(FindSymbol(x,y, ‘Furance’)) then
With this we then add the clicking to it:
If(FindSymbol(x,y, ‘Furance’)) then
Begin
Wait(30+random(70));
Mouse(x,y,5,5,true); // If you remember from earlier, 5,5 is the randomness. And true is a normal left click.
Flag();
End;
This will Check if the symbol has been found, then will wait, then click it. This is useful for a failsafe also! Say you have been attempting to find the Furance, you can check to see how fair away you are from the furnace using ‘distance’, and if the distance is further than it should be it shall try to correct this.
If(FindSymbol(x,y, ‘Furnace’)) then
if Distance(mmcx, mmcy, x, y) >= 10 then
begin
wait(30+random(30));
writeln(‘Correcting user’s placement’);
mouse(x,y,5,5)
Flag();
End;
Another use for Finding symbol would be when radial walking long distances:
// Never use this, it’s just an example :P! It can be an endless loop
repeat
RadialWalk(FindLumbyRoadColor, 12, 50, 30+random(30), -2, 1);
until(FindSymbol(x,y,'furance'));
So, Symbol Finding is pretty useful =)!
[CENTER][b]TPA and Tboxes
For my first tutorial, of many, I have decided to explain and discuss Tpa’s. Many of you are most likely under the illusion that TPA’s are impossible to incoperate into a script, and to be used effectively by anyone unless you’re a genius. But after munk explained that this is SIMPLY not true, and that any idiot can make effective use of TPA I decided that I should write a tutorial on it, disproving the usual thoughts aboutTPA.
Now, let me explain the basics.
What are Tpa’s?
A TPA is just what you think it is…. Uh …
A TPA is just a bunch of data stored in an array. To be specific, it’s a collection of Tpoints in an array, hence : TPointArrays.
I shall explain this in two parts.
Tpoints
A tpoint contains 2 bits of data, the x and y co-ordinates of a point. You may notice the x,y points of something when you’ve been selecting a colour and noticed it displayed a x and y point.
An Array
The array is just multible Tpoints, ie, numerous x and y co-ordinates placed into an array.
Simple.
Effectively using the TPA
This is how to declare a basic Tpoint:
Var
TpointName: tpoint;
This will create the variable tpointname and declare is as a tpoint.
To actually add data to this var you would use something like:
Procedure TPA;
Var
TheTpa: TPointArray; // Declare the tpa like discussed before
Begin
SetArrayLength(TheTpa, 1); // Remember that 1 tpa contains both x and y
TheTpa[0].x := 30; // Arrays always start 0,1,2,3 etc etc :
TheTpa[0].y := 30;
Writeln('TheTpa[0].x = '+IntToStr(theTpa[0].x)+ ' TheTpa[0].y = '+IntToStr(TheTpa[0].y)+'.');
End;
This would of course give the output off :
TPA[0].x = 30 TPA[0].y = 30.
The use of something like this could be Mmousing the X and Y co-ordinates of the tpoint.
Adding more points to the TPA
Of course manually inputting x and y co-ordinates would be pointless. There are many methods of adding data to a Tpoint Array. Most commonly used would be these two :
FindColorsSpiralTolerance(x,y : Integer; var Points :TPointArray; color, xs,ys,ye : integer; Tolerance : Integer);
The above is most common for minimap related object finding such as finding Npcs, as it will spiral outwards of the minimap.
The second used would be
FinndColorsTolerance(var Points : TPointArray; Color, xs, ys, xe , ye , Tolerance : Integer): Boolean;
Same idea as SpiralTolerance.
These are both extremely useful, as this will be out data which we will then sort out. As this will find the x and y co-ordinates of the colour’s with tolerance, we will have to sort through ‘a lot’ of data. We can do this by using T2DPointArrays. This is just An array, inside an array. An example of this would be
TheTPA[0][0].x := 30;
TheTPA[0][0].y := 30;
These are declared as such :
Variable: T2DPointArray;
Okay, you may be thinking. Great, this seems easy so far. And it is! But actually using these methods are slightly tricky at first, but here would be an example of using both TpointArrays, and the T2DPointArrays in order to find mainscreen objects.
function MineRock (RockColor,Tolerance : Integer) : boolean;
Var
tx, ty : Integer;
TPA : Array Of TPoint;
t2d : T2DPointArray;
I : Integer;
Begin
FindColorsSpiralTolerance(tx, ty, TPA, RockColor, MSX1, MSY1, MSX2-100, MSY2-100, Tolerance); // First store the color’s x y’s into t points
t2d:=TPAtoATPAEx(tpa,2,10); // Splits the TPA to boxes with sidelengths W and H and results
if length(t2d) = 0 then exit; // Self explanatory, will exit if length is 0. Length of array is the amount of data in it
for i:=0 to high(t2d) do // This will start from 0, and then go to the highest t2darray data
begin
if middleTPAex(t2d[i],tx,ty) then // stores the coordinates of the middle of the TPointArray a to X & Y.
Wait(30+random(20));
mmouse(tx,ty,5,5); // Move the mouse to the temp tx,ty cords.
if (pos('ine', rs_GetUpText) > 0) then // Check if the uptext is ‘Mine’
begin // If so :
GetMousePos(x, y);
Wait(50+random(300));
mouse(x, y, 5, 5, true);
Wait(100+random(300)));
result := true; //Make the result true
exit;
end;
end;
end;
Pretty easy I hope! Basically it did this:
* Stored the color tolerance points starting from center, this means as we loop through our data it should be the closest to center, which should be us :P
* Changed the Tpoints into t2dpointarrays
*Checked if the t2d contained any data, if not exit
*Stored the middle tpoints into x,y points (tx,ty)
*Mmoused the data, checking if uptext was ‘ine’ if so, click
This is how effective TPA CAN be.
Tboxes
In short this is a collection of 2, x and y points from 2 Tpoints. This image will help explain.
http://img234.imageshack.us/img234/4688/tboxexamplegm5.png
Uses of Tboxes
• Item searching through points, such as Srl’s InvBox, where you can easily search for Dtms etc etc.
• Finding data in certain points
Example
Function GetNPCPlace(Box: TBox): Tpoint;
Var
//i: integer;
npcs: TpointArray;
splitnpcs: T2dPointArray;
begin
findColorsTolerance(npcs,195836,Box.x1,Box.y1,Box. x2,Box.y2,3);
if length(npcs) > 1 then
begin
Splitnpcs := TPAtoATPAEx(npcs,20,20);
SortATPAsize(SplitNpcs,true);
result := MiddleTPA(SplitNpcs[0]);
end;
end;
End of TPA
In summary if you followed through (lol >.<) you should understand the basics of tpa and should be able to effectively use them. You should always check out:
SRL\Misc\WizzyPlugin.scar
Just to see all the functions:
procedure tSwap(var a, b: TPoint);
Description:
Swaps the two TPoints.
procedure tpaSwap(var a, b: TPointArray);
Description:
Swaps the two TPointArrays.
procedure SwapE(var a, b: Extended);
Description:
Swaps the two Extended values.
procedure RAaSTPAEx(var a: TPointArray; const w, h: Integer);
Description:
Leaves one point per box with side lengths W and H to the TPA.
procedure RAaSTPA(var a: TPointArray; const Dist: Integer);
Description:
Leaves one point per box with the side length Dist.
function NearbyPointInArrayEx(const P: TPoint; w, h:Integer; a: TPointArray): Boolean;
Description:
Returns true if the point P is near a point in the TPA a with the
max X and Y distances W and H.
function NearbyPointInArray(const P: TPoint; Dist:Integer; a: TPointArray): Boolean;
Description:
Returns true if the point P is near a point in the TPA a with the
max distance Dist.
function ReArrangeandShortenArrayEx(a: TPointArray; w, h: Integer): TPointArray;
Description:
Results the TPointArray a with one point per box with side lengths
W and H left.
function ReArrangeandShortenArray(a: TPointArray; Dist: Integer): TPointArray;
Description:
Results the TPointArray a with one point per box with side length
Dist left.
function TPAtoATPAEx(TPA: TPointArray; w, h: Integer): T2DPointArray;
Description:
Splits the TPA to boxes with sidelengths W and H and results
them as a T2DPointArray.
function TPAtoATPA(TPA: TPointArray; Dist: Integer): T2DPointArray;
Description:
Splits the TPA to boxes with sidelength Dist and results
them as a T2DPointArray.
procedure SortTPAFrom(var a: TPointArray; const From: TPoint);
Description:
Sorts the TPointArray a from the point From.
Closest one to the point is [0], second closest is [1] etc.
procedure SortATPAFrom(var a: T2DPointArray; const From: TPoint);
Description:
Sorts the T2DPointArray a from the point From.
procedure SortATPAFromFirstPoint(var a: T2DPointArray; const From: TPoint);
Description:
Sorts the T2DPointArray a from the point From.
procedure InvertTPA(var a: TPointArray);
Description:
Inverts / Reverts the TPointArray a.
procedure InvertATPA(var a: T2DPointArray);
Description:
Inverts / Reverts the T2DPointArray a.
function MiddleTPAEx(TPA: TPointArray; var x, y: Integer): Boolean;
Description:
Stores the coordinates of the middle of the TPointArray a to X & Y.
function MiddleTPA(tpa: TPointArray): TPoint;
Description:
Returns the middle of the TPointArray tpa.
procedure SortATPASize(var a: T2DPointArray; const BigFirst: Boolean);
Description:
Sorts the T2DPointArray a from either largest or smallest, by the
amount of points in the TPAs.
function CombineTPA(Ar1, Ar2: TPointArray): TPointArray;
Description:
Combines the TPointArrays Ar1 and Ar2, and results the combination.
function CombineIntArray(Ar1, Ar2: TIntegerArray): TIntegerArray;
Description:
Combines the TIntegerArrays Ar1 and Ar2, and results the
combination.
function InIntArrayEx(a: TIntegerArray; var Where: Integer; const Number: Integer): Boolean;
Description:
Returns true if the integer Number was found in the integer array
a, and stores the index to Where.
function InIntArray(a: TIntegerArray; Number: Integer): Boolean;
Description:
Returns true if the integer Number was found in the integer array a.
procedure ClearSameIntegers(var a: TIntegerArray);
Description:
Clears the duplicates in the integer array a.
procedure ClearSameIntegersAndTPA(var a: TIntegerArray; var p: TPointArray);
Description:
Clears the duplicates in the integer array a and the TPointArray p.
function SplitTPAEx(arr: TPointArray; w, h: Integer): T2DPointArray;
Description:
Splits the points with max X and Y distances W and H to their
own TPointArrays.
function SplitTPA(arr: TPointArray; Dist: Integer): T2DPointArray;
Description:
Splits the points with max distance Dist to their own TPointArrays.
Dist 1 puts the points that are next to eachother to their own arrays.
procedure FilterPointsPie(var Points: TPointArray; const SD, ED, MinR, MaxR: Extended; Mx, My: Integer);
Description:
Removes the points in the TPointArray Points that are not within
the degrees SD (StartDegree) and ED (EndDegree) and the distances
MinR (MinRadius) and MaxR (MaxRadius) from the origin (Mx, My).
function RemoveDistTPointArray(x, y, dist: Integer; ThePoints: TPointArray; RemoveHigher: Boolean): TPointArray;
Description:
Removes the points that are inside or outside the distance Dist
from the point (x, y) from the TPointArray ThePoints.
function GetTPABounds(TPA: TPointArray): TBox;
Description:
Returns the boundaries of the TPA as a TBox.
function FindTPAinTPA(SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
Description:
Looks for the TPA SearchTPA in the TPA TotalTPA and returns
the matched points to the TPA Matches. Returns true if there were atleast one
match(es).
function FindTextTPAinTPA(Height: Integer; SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
Description:
Read the description of FindTPAinTPA. Additional Height parameter.
function FindGapsTPA(TPA: TPointArray; MinPixels: Integer): T2DPointArray;
Description:
Finds the possible gaps in the TPointArray TPA and results the
gaps as a T2DPointArray. Considers as a gap if the gap length is >= MinPixels.
Only horizontal, sorry folks.
Function CreateTPAFromBMP(BmpDC: HDC): TPointArray;
Description:
Creates a TPointArray of the bitmap dc BmpDC.
Use GetBitmapDC to get the dc.
procedure SortCircleWise(var tpa: TPointArray; mx, my, Deg: Integer; SortUp: Boolean);
Description:
Sorts all points in tpa by distance from degree (Deg) and distance from
mx and my. Sortup will return closest distance to mx and my first.
Distance will be sorted first (RadialWalk style).
procedure LinearSort(var tpa: TPointArray; mx, my, Deg: Integer; SortUp: Boolean);
Description:
Sorts all points in tpa by distance from degree (Deg) and distance from
mx and my. Sortup will return closest distance to mx and my first.
Degree will be sorted first (LinearWalk style).
Function MergeATPA(ATPA: T2DPointArray): TPointArray;
Description:
Merges the TPointArrays of the T2DPointArray ATPA in to one TPA.