SRL Archive - First Scripts

[blog] Ratzer


Sir R. M8gic1an

2011-11-10 11:03:03

Ok, so this is far from my first script, but it is my first script in a long time. So I personally need to clear some rust, and thought I might write about it, and the blogging section is gone, so I found either this or the writing section to be appropriate.

Now this is the first time I'd work on a full-scale fighting script, and I'm going to attempt to kill ratz under varrock, a feat I've attempted before, but unfortunately got me banned due to lousy programming. I'll be walking through the very basics to some of the advanced here.

So the first thing I did was grab a basic script set up, and run that to make sure I had everything setup correctly.

program Ratzer;
{$DEFINE SMART}
{$i SRL/SRL.scar}


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

Players[0].Name :=''; // Copy and paste to add more players
Players[0].Pass :='';
Players[0].Nick :=''; //Used for random events
Players[0].Active:=True;
end;

begin
Smart_Server := 1;
SetupSRL;
DeclarePlayers;
LoginPlayer;
end.

Smart loads up, my player logs in. Perfect, everything is correctly set up with my Simba and etc. IF it didn't happen so, it'd probably be a problem with my java settings, or one of the many other common set up problems.

First thing I noticed was that my graphics were on high definition. I manually changed those to minimum, although I do remember SRL has a function to do so. Next thing I noticed was that my angle on the player is too low. So next thing I do is I'll be adding SetAngle(true) to my script. This will higher the camera's viewpoint.

Okay so now, first things first, I wanna kill rats. Therefore I need the rats' colors. I'm using AutoColorAid2 to grab the colors for my rats. I've placed my character at the rat pits, popped up ACA2, and 'Refreshed from Client'.

I set my ColorToleranceSpeed (CTS) settings to 2, as I find that color finding algorithm to be more effective than CTS 1. I grabbed some colors from the rats' head, body and tail. I notice it catches a bit onto some armour, but the amount is not comparable to the rat, so that should be ok, considering that we can later filter color count.

The result I get is: See Picture
From: ACA2, Rats

BestColor = 6646383
Tol = 13;
Hue = 0.33
Sat = 0.23


Now as I'm lazy and currently just laying the foundations for the script, I'll use ACAs finding function (for now), but I will later make my own. ACAs function looks like this:

function FindObject(var fx, fy: Integer): Boolean;
var
arP: TPointArray;
ararP: T2DPointArray;
tmpCTS, i, arL: Integer;
P: TPoint;
begin
tmpCTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(0.33, 0.23);

if not(FindColorsTolerance(arP, 6646383, MSX1, MSY1, MSX2, MSY2, 13)) then
begin
Writeln('Failed to find the color, no object found.');
ColorToleranceSpeed(tmpCTS);
SetColorSpeed2Modifiers(0.2, 0.2);
Exit;
end;

SortTPAFrom(arP, Point(MSCX, MSCY));
ararP := SplitTPAEx(arP, 20, 20);
arL := High(ararP);

for i := 0 to arL do
begin
P := MiddleTPA(ararP[i]);
MMouse(P.x, P.y, 5, 5);
Wait(100 + Random(100));
if (IsUpText('iant')) then
begin;
Result := True;
Break;
end;
end;

ColorToleranceSpeed(tmpCTS);
SetColorSpeed2Modifiers(0.2, 0.2);

if (i = arL + 1) then
begin
Writeln('FindObject could not find object.');
Exit;
end;

GetMousePos(fx, fy);
end;

I renamed it to FindRat. When I re-write this function I'll include a color count, I'll use SplitTPA instead of SplitTPAEx (due to the diff algorithms) and I'll use ColorMouse, a function I made, instead of SRLs MMouse.

Very well, time to find and kill my first Rat.

Procedure Fight;
var
x, y: integer;
begin
FindRat(x, y);
end;

//Added procedure Fight to Mainloop
Notice: The function from ACA2 would not click - I modified it so it would click.

Okay, tested and it worked. I successfully attacked a rat. Yay for me. Next thing I want to do is gather colors for the drops. I'm ranging so it's extremely important for me that I pickup my arrows.

I got the colors for the bottom end and the stick. ACA recognizes the arrows quite effectively.
From: ACA2, Arrows

Color = 729430;
HSL Tol = 14;
Hue = 0.28;
Sat = 0.19;

From: ACA2, Bones

Color = 10395826;
HSL Tol = 24;
Hue = 0.07;
Sat = 0.39;

From: ACA2, Meat

Color = 729430;
HSL Tol = 9;
Hue = 0.01;
Sat = 0.02;


I gathered the colors both on MS and on inventory as some sort of cross-referencing failsafe. The bones are somewhat troublesome as they also identify as raw rat meat. This might turn out to be a problem later, but hopefully not… perhaps this will be the first time I actually use the NotColors/BadColors algorithm.

Posting, need to pee. - mission accomplished.

The fighting cycle is pretty simple, on its simplest level:
- Find Target
- Attack
- WaitForDeath
- - (Eat)
- Pickup Loot

so a quick Mockup:

Procedure Fight;
var
x, y: integer;
begin
if FindRat(x,y) then
begin
repeat
wait(500+random(500));
if GetHP < 50 then
if not Eat then
RunAndRest;
until(not srl_InFight)
PickupLoot('All');
end;
end;

Seems pretty simple, no? To add some bones to the skeleton,

//Gets HP lvl from MM; Function renamed to spare string and shorten code
Function GetHP: integer;
var
color: string;
begin
Result := GetMMLevels('hp', color);
end;

//Function will look for cooked rat meat in inventory and eat it
//mockup
Function Eat: boolean;
begin
Result := False;
end;

//Function runs away from battlefield and rests until HP is restored
Function RunAndRest: boolean;
begin
Result := RunAway('w', true, 2, 100);

if not SetRest then
writeln('trouble resting')
else
repeat
wait(5000);
until(GetHP > 100)

Result := GetHP >= 100;
end;

//Function picks up loot
Function PickupLoot(which: string):boolean;
var
color, tol, arL, i: integer;
h, s: extended;
uptext: string;
TPA: TPointArray;
ATPA: T2DPointArray;
P: TPoint;
begin
writeln('Looting, ' + which);

if (lowercase(which) = 'arrows')and(Players[CurrentPlayer].Skill <> 'range') then
exit;

case lowercase(which) of
'all':
Result := PickupLoot('bones') and
PickupLoot('meat') and
PickupLoot('arrows');
'bones':
begin
color := 10395826;
Tol := 24;
h := 0.07;
s := 0.39;
uptext := 'ones';
end;

'meat':
begin
color := 729430;
Tol := 9;
h := 0.01;
s := 0.02;
uptext := 'eat';
end;

'arrows':
begin
color := 729430;
Tol := 14;
h := 0.28;
s := 0.19;
uptext := 'rrows';
end;
end;


ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(h, s);

Result := FindColorsSpiralTolerance(MSCX, MSCY, TPA, color, MSX1, MSY1, MSX2, MSY2, Tol);

if not Result then
begin
ColorToleranceSpeed(1);
SetColorSpeed2Modifiers(0.2, 0.2);
exit;
end;

ATPA := SplitTPAEx(TPA, 20, 20);
arL := High(ATPA);

for i := 0 to arL do
begin
P := MiddleTPA(ATPA[i]);
if ColorMouse(P.x, P.Y,color, tol, uptext) then
begin
Result := True;
writeln(which + ' looted');
Break;
end;
end;

if not lowercase(which) = 'arrows' then
begin
InvC := InvCount;
Result := WaitInvMinCount(InvC + 1, 5000);
end else
wait(3000 + random(2000));

ColorToleranceSpeed(1);
SetColorSpeed2Modifiers(0.2, 0.2);

end;


{test log
With the mockup as it is, and a loop on fighting, I am finding this:

1. SRLs inFight relies on your HP bar, which takes a while to disappear
-- Track Enemy Rat, track their HP bar and determine InFight from there (as well)
2. Clicking on rats already under attack
-- Checking for HP Bar Above Rat, exclude these from TPA
-- Checking for 'already under attack' text
3. When running away, gate might be closed
4. Bones Uptext does not show up under meat or other

^^ Your own HP bar will never appear if you kill too quickly at a range
^^ Fix: WaitFunc(@srl_InFight)
^^ Scripts is frenetically clicking on rats, until one of them comes and attacks you
^^ Fix: WaitFunc(@srl_InFight)
}
~RM

footballjds

2011-11-10 11:09:15

I like how you're breaking down every single function/procedure.
You gonna do this through the entire script writing process? :)
It will be great learning material!

Sir R. M8gic1an

2011-11-10 11:19:57

Yeh, that's pretty much my plan. More in the making.

-RM

Harry

2011-11-10 11:25:50

Looks pretty neat! Good luck on your script.

Just curious, why are you not coding this into MSI? Or is that a future plan with it?

Sir R. M8gic1an

2011-11-10 11:55:18

From: Harry
Looks pretty neat! Good luck on your script.

Just curious, why are you not coding this into MSI? Or is that a future plan with it?


That is a future plan. Due to it being a new skill and my rustiness, I decided to write it out first until I've got its kinks figured out. Getting it into MSI will probably pretty much be copy paste of some of the main code.

~RM

Flight

2011-11-10 12:13:19

You said you were going to eventually include a 'count color' in your FindRat function, which functions will be used for that? Also, you're for sure "srl_InFight" still works? (I'm not saying it doesn't, never even tried it)

WT-Fakawi

2011-11-10 12:18:54

Now here is a great initiative!

Unasked and Unwanted Suggestions:
You might wanna open the XP and calculate a full hit.
You might wanna add a sliced fullhitbar bitmap 56*1 for definitive detection.

  FullHitBar := BitmapFromString(56, 1, 'meJxjYrdmYMhhYGgCIkaGLgw0iZl' +        
'hFjJiYVgIR6wMq+CIg2EjDO3EhTgZDgARhIFHGQZazcRuDQB2WiWA');
SetBitmapName(FullHitBar,'FullHitBar');

And check for legits and drops around :) But, bweh, you know about this :)

Sir R. M8gic1an

2011-11-10 12:41:13

From: Flight
You said you were going to eventually include a 'count color' in your FindRat function, which functions will be used for that? Also, you're for sure "srl_InFight" still works? (I'm not saying it doesn't, never even tried it)


Count Color is very simple. After doing FindColorsTolerance, all you need to do is Lenght(TPA), and that'll return the amount of color points found on the rat.

The count will just be if abs(AverageCount - Length(TPA)) < 50 then Result := true;
That checks that what we found is not just some random piece of armour. (but it might turn out to be more trouble than its worth.

Yes, srl_InFight still works;

From: Fawk

Now here is a great initiative!

Unasked and Unwanted Suggestions:
You might wanna open the XP and calculate a full hit.
You might wanna add a sliced fullhitbar bitmap 56*1 for definitive detection.

FullHitBar := BitmapFromString(56, 1, 'meJxjYrdmYMhhYGgCIkaGLgw0iZl' +
'hFjJiYVgIR6wMq+CIg2EjDO3EhTgZDgARhIFHGQZazcRuDQB2WiWA');
SetBitmapName(FullHitBar,'FullHitBar');

And check for legits and drops around :) But, bweh, you know about this :)


Cheers Fawk, nice suggestions :)

e: added basic looting to the script, will write on it tomorrow; That's it for the day

~RM

Sir R. M8gic1an

2011-11-11 13:05:37

So, second day in and I'm already feeling that bliss of absent mindedly watch my character play runescape. It's great. While your characters whiles away killing some rats, you are not paying close attention to the hits you make or whatever else. You are inside the machine, checking the oil and the engine.

As a sidenote, I thought that to develop the fighting cycle I'd be better off using a mellee character, due to the extra defense, and not wasting arrows that are not yet my priority.

So last night as I left my script to stew, I knew I'd need a better way of dealing with my items. I took the obvious approach, which makes the script more structured and goes some way to joining up with MSI. An ItemLoader.

function LoadItem(which: string; var color, tol: integer; var hue, sat: extended; var uptext: string): boolean;
begin
case lowercase(which) of
'rat':
begin
color := 6251868;
Tol := 15;
hue := 2.41;
sat := 0.20;
uptext := 'iant';
Result := true;
end;

'bones':
begin
color := 10395826;
Tol := 24;
hue := 0.07;
sat := 0.39;
uptext := 'ones';
Result := true;
end;

'raw meat':
begin
color := 1321874;
Tol := 14;
hue := 0.14;
sat := 0.11;
uptext := 'meat';
Result := true;
end;

'meat':
begin
color := 1982064;
Tol := 6;
hue := 0.34;
sat := 3.16;
uptext := 'eat';
Result := true;
end;

'arrows':
begin
color := 729430;
Tol := 14;
hue := 0.28;
sat := 0.19;
uptext := 'rrows';
Result := true;
end;
end;
end;

This allowed me to shorten my PickupLoot function by a mile.

Function PickupLoot(which: string):boolean;
var
color, tol, arL, i, invC: integer;
h, s: extended;
uptext: string;
TPA: TPointArray;
ATPA: T2DPointArray;
P: TPoint;
begin
if srl_InFight then exit;
Gametab(tab_inv);
writeln('Looting, ' + which);

if (lowercase(which) = 'arrows')and(Players[CurrentPlayer].Skill <> 'range') then
exit;


if lowercase(which) = 'all' then
begin
PickupLoot('raw meat');
PickupLoot('bones');
PickupLoot('arrows');
Result:= true; //needs criteria
end;

LoadItem(which, color, tol, h, s, uptext);

ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(h, s);

Result := FindColorsSpiralTolerance(MSCX, MSCY, TPA, color, MSX1, MSY1, MSX2, MSY2, Tol);

if not Result then
begin
writeln('no colors found');
ColorToleranceSpeed(1);
SetColorSpeed2Modifiers(0.2, 0.2);
exit;
end;

ATPA := SplitTPAEx(TPA, 20, 20);
arL := High(ATPA);

for i := 0 to arL do
begin
P := MiddleTPA(ATPA[i]);
if ColorMouse(P.x, P.Y,color, tol, uptext) then
begin
Result := True;
Break;
end;
end;

if not (lowercase(which) = 'arrows') then
begin
InvC := InvCount;
Result := WaitInvMinCount(InvC + 1, 5000);
end else
wait(3000 + random(2000));

if not Result then
writeln('Objects did''nt match')
else begin
writeln(which + ' looted');
wait(1500+random(1500));
end;

ColorToleranceSpeed(1);
SetColorSpeed2Modifiers(0.2, 0.2);

end;

Now the PickupLoot function also waits until you actually have the loot before looking for some more. This had been an initial issue, and it went looking for the loot all over the place. This function still needs some work. When looting bones it needs to check the options rather than just the uptext.
The line that makes it wait for the loot is this one:

Result := WaitInvMinCount(InvC + 1, 5000);

it waits until InvCount is increased by one.

Now, to be able to absent mindedly watch the script run…. I needed to be able to eat. So that's the next thing I took care of. For now its just a simple color search, but for the moment it will do. Another problem it had, was that it was working on hardwired HP - I've now changed that to %

Function Eat: boolean;
var
cHP, MyHP, color, tol, x, y, i: integer;
h, s: extended;
uptext: string;
begin
cHP := GetHP;
MyHP := Players[CurrentPlayer].Level[SKILL_HP];

if round(cHP / MyHP)> 3 then
begin
Result := true;
exit;
end;

writeln('Eating');
Gametab(tab_inv);
LoadItem('meat', color, tol, h, s, uptext);

ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(h, s);
Result := FindColorTolerance(x, y, color, MIX1, MIY1, MIX2, MIY2, tol);

if Result then
Result := ColorMouse(x,y, color, tol, uptext)
else
writeln('couldnt find meat');

if Result then
begin
Result := false;
repeat
wait(300+random(200));
Result := GetHP > cHP;
inc(i);
if i > 20 then break;
until(Result)
end;

ColorToleranceSpeed(1);
SetColorSpeed2Modifiers(0.20, 0.20);

end;

Do notice Gametab(tab_inv) - an essential to make this function work. We need to be sure the inventory tab is open. And also notice that Eat checks for HP - so I've removed some of the HP checks elsewhere.

And that's it for now. I still need to add the 'Someone else i fighting that' check. Then I'll need to take care of getting the character to equip fighting equipment. I'll need to make the character be able to cook until it has an inventory of 80% bones - bones are a huge profit and that is what this script will be making a profit on. I'll need to get the bank walk and walk-back sorted. Might use SPS for that. Might use something else.

~RM

MagicMushroomKillaMMK

2011-11-11 14:11:25

I got banned using a miner I made on my level 137………. I didn't even get to finish writing the script. BAD.

footballjds

2011-11-11 15:24:35

From: justin102030
I got banned using a miner I made on my level 137………. I didn't even get to finish writing the script. BAD.


This is EXTREMELY off topic. :redface:
Could you create a new thread. This seems like something i'd want more info on :)

Kyle Undefined

2011-11-11 18:48:34

Awesome progress and blog! I love reading it, keep it up!

Kajutsky

2011-11-11 21:57:49

good luck sir

bevardis

2011-11-12 09:49:20

First script and Rasta Magician just don't go together : D

Swatarianess

2011-11-15 06:49:56

Thanks helped my find out how to Find then click on a color, had got stuck on making mouse move to a color for like 2hrs >.< lol thanks so much