SRL Archive - OSR Help

Some more help simplifying lengthy procedures? Can't quite get it from tutorials :/


rotchy1

2013-06-05 07:19:24

Theres a few procedures/functions that I've been trying to simply and or make more efficient that I've listed below. I've been reading some tut's on them and not quite getting it well enoguh to impliment it so could someone give me a little advice on them? Thanks!

So basically I'm trying to use a Case function to simplify this failsafe walking procedure that will execute if SPS fails at walknig to the chicken pen in Lumbridge from the Lumbridge Lodestone.

This is the procedure I'm trying to simplify:

procedure ChickenWalkFailsafe;
var
T: Integer;
begin
TeleHome;
repeat
MarkTime(T);
Writeln('RadialWalk1');
RadialWalkTolerance(5594207, 76, 80, 70, -1, 0, 34);
wait(RandomRange(1000,1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('error 9');
Logout;
TerminateScript;
end;
until (VinesFound = True);
repeat
MarkTime(T);
Writeln('RadialWalk2');
RadialWalkTolerance(5594207, 45, 55, 55, - 1, 0, 34);
if TimeFromMark(T) > 30000 then
begin
Writeln('error 10');
Logout;
TerminateScript;
end;
until (LightPostFound = True);
repeat
MarkTime(T);
Writeln('RadialWalk3');
RadialWalkTolerance(5594207, 330, 350, 75, - 1, 0, 34);
if TimeFromMark(T) > 30000 then
begin
Writeln('error 11');
Logout;
TerminateScript;
end;
until (StumpFound = True);
repeat
MarkTime(T);
Writeln('RadialWalk4');
RadialWalkTolerance(5594207, 330, 350, 80, - 1, 0, 34);
if TimeFromMark(T) > 30000 then
begin
Writeln('error 12');
Logout;
TerminateScript;
end;
until (BlueFlagFound = True);
repeat
MarkTime(T);
Writeln('RadialWalk5');
RadialWalkTolerance(5594207, 350, 359, 20, - 1, 0, 34);
if TimeFromMark(T) > 30000 then
begin
Writeln('error 13');
Logout;
TerminateScript;
end;
until (RockFound = True);
repeat
MarkTime(T);
Writeln('RadialWalk6');
RadialWalkTolerance(5594207, 300, 355, 70, - 1, 0, 34);
if TimeFromMark(T) > 30000 then
begin
Writeln('error 14');
Logout;
TerminateScript;
end;
until (HayandGrainFound = True);
repeat
MarkTime(T);
Writeln('RadialWalk7');
RadialWalkTolerance(5594207, 350, 352, 63, - 1, 0, 34);
if TimeFromMark(T) > 30000 then
begin
Writeln('error 15');
Logout;
TerminateScript;
end;
until (WheelBarrelPlantFound = True);
Wait(RandomRange(1500,2000));
end;


This next procedure I've already been helped (ALOT) by Kasi, by speeding it up and making it more human like, but now I would like to possibly make it right click another pile of of "loot" while it is walking to one so that all it has to do once it picks up the first pile is choose option "Take" on the second pile and hopefully speed it up and make it even more human like? If I could I would also like to add a feature that allows it to choose Option "Take feather" if that is an option, however if not, then choose option "Take Raw Chicken". And one more question, is it possible to have it Choose option "Take Feather" and then click the same pile of loot and Choose option "Take Raw Chicken" and then again click the same pile and Choose option "Take Bones". Since the price of bones is 66% that of the price of Raw Chicken currently, I feel this may add to the GP/Hour of the script?

Here is the code for this function (again credits mainly go to Kasi for teaching me how to split the TPA and for rewriting this function)

Function FindRaw : Boolean;  //Credits to Kasi for making this procedure
//and at the same time teaching how to split
//TPAs to reduce the amount of total points
//and find the point closest to player first.
//This makes the script look much more human
//like and increased the speed a good bit. I
//really appreciate it!
var
I, T, TimesFailed : integer;
RawTPA : TPointArray;
Raw2DTPA : T2DPointArray;
TB : TBox;
begin
FindNormalRandoms;
SetColorToleranceSpeed(2);
SetToleranceSpeed2Modifiers(0.20, 0.44);
FindColorsTolerance(RawTPA, 9213099, MSX1, MSY1, MSX2, MSY2, 19);
SetColorToleranceSpeed(1);
SetToleranceSpeed2Modifiers(0.02, 0.02);
SplitTPAExWrap(RawTPA, 10, 10, Raw2DTPA);
SetLength(RawTPA, 0);
for I := 0 to High(Raw2DTPA) do
begin
TB := GetTPABounds(Raw2DTPA[I]);
if ((iAbs(TB.X1 - TB.X2) > 8) and (iAbs(TB.Y1 - TB.Y2) > 8) and
(iAbs(TB.X1 - TB.X2) < 15) and (iAbs(TB.Y1 - TB.Y2) < 15))
then
CombineTPAWrap(RawTPA, [MiddleTPA(Raw2DTPA[I])], RawTPA);
end;
SortTPAFrom(RawTPA, Point(MSCx, MSCy));
MarkTime(T);
for i := 0 to High(RawTPA) do
begin
MMouse(RawTPA[I].x, RawTPA[I].y, 2, 2);
if waituptext('aw ch', 100) and RBoolEx(2) then
begin
ClickMouse2(mouse_Left);
Result := WaitNotMoving(True);
Break;
end else
begin
if waituptext('aw ch', 500) then
begin
ClickMouse2(Mouse_Right);
if WaitOption('hicken', 600) then
begin
WaitNotMoving(true);
Result := True;
Break;
end;
end else
begin
if TimeFromMark(T) > 3000 then
begin
Inc(TimesFailed);
if TimesFailed >= 3 then
begin
KillChicken;
AntiBan;
TimesFailed := 0;
end;
end;
if TimeFromMark(T) > 30000 then
begin
Logout;
TerminateScript;
end;
end;
end;
end;
end;

This next procedure is the procedure I made for finding the gate and checking to make sure it is open, however sometimes the player runs just a hair to far north so that the gate is just off the screen and it continues to search for about 30 seconds and then proceeds directly to finding the loot. In this case I'm trying to implement a failsafe where if it cannot find the gate it walks back a step and then searches again. Currently I tried having it repeat the WalkToChickens procedure if it goes for 30 seconds without finding the gate, but it never does this, instead proceeds directly to finding loot? Did I implement my failsafe incorrectly?

Heres the procedure for this:

procedure OpenGateIfClosed; //Checks if the gate is open or closed by
//hovering the gate and checking uptext, if
//gate is open it will tell us and proceed, if
//gate is closed it will open and tell us that
//it opened it and then proceed.

var MMx, MMy, T: Integer;
MainScreenPointConverted: TPoint;

begin
MarkTime(T);
WaitNotMoving(true);
FindColorSpiral(MMx, MMy, (197874 or 3951706), MMCX, MMCY, MMCX + 25, MMCY + 25);
MainScreenPointConverted := MMToMS(Point(MMx, MMy));
FindObj(MMx, MMy, 'ate', 3951706, 7);
MMouse(MMx, MMy, 0, 0);
GetUpText;
if WaitUptext('pen', RandomRange(400,650)) then
begin
ClickMouse2(1);
wait(RandomRange(3000,4500));
end;
if TimeFromMark(T) > 30000 then
begin
WalkToChickens;
end
else
begin
AntiBan;
end;
end;

Any help here is appreciated, I know I've asked alot so an answer to each obviously isn't expected, but even just a little would be awesome! Thanks Guys!

Rich

2013-06-05 07:46:14

EDIT: I've been really stupid. Ignore this post. Sorry :/

rotchy1

2013-06-05 08:25:15

From: Rich
EDIT: I've been really stupid. Ignore this post. Sorry :/


I Find myself saying this alot too, no worries :)

Rich

2013-06-05 08:39:27

Got there in the end. For the first one try this:
procedure ChickenWalkFailsafe;
var
T, I : Integer;
sRadial, eRadial, xMod : TIntegerArray;
UntilWhat : array of function() : Boolean;

begin
TeleHome;
sRadial:= [76, 45, 330, 330, 350, 300, 350];
eRadial:= [80, 55, 350, 350, 359, 355, 352];
xMod:= [70, 55, 75, 80, 20, 70, 63];
UntilWhat[0]:= @VinesFound; UntilWhat[1]:= @LightPostFound; UntilWhat[2]:= @StumpFound
UntilWhat[3]:= @BlueFlagFound; UntilWhat[4]:= @RockFound; UntilWhat[5]:= @HayandGrainFound;
for I:= 0 to High(sRadial) do
repeat
MarkTime(T);
Writeln('RadialWalk' + IntToStr(I + 1));
RadialWalkTolerance(5594207, sRadial, eRadial, xMod, -1, 0, 34);
wait(RandomRange(1000, 1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('Error ' + IntToStr(I + 9));
Logout;
TerminateScript;
end;
until (UntilWhat[I]());
Wait(RandomRange(1500, 2000));
end;
For some reason it wouldn't let me declare the functions as a single array, so had to do it like that. It looks messy, I know, but I didn't really fancy taking up 6 lines. Hopefully it works :)

Enslaved

2013-06-05 08:58:50



function FindColorsSpiralMulti(Sx, Sy: Integer; Colors, Tolerance: TIntegerArray; X1, Y1, X2, Y2: Integer): TPointArray;
var
i: Integer;
ATPA: T2DPointArray;
CombTPA: TPointArray;
begin
if (High(Colors) <> High(Tolerance)) then
begin
Writeln('Invalid number of parameters');
TerminateScript;
end;
for i := 0 to High(Colors) do
begin
SetLength(ATPA, i + 1);
FindColorsSpiralTolerance(Sx, Sy, ATPA[i], Colors[i], x1, y1, x2, y2, Tolerance[i]);
end;
CombTPA := MergeATPA(ATPA);
SortTPAFrom(CombTPA, Point(sx, sy));
Result := CombTPA;
end;

function OpenGateIfClosed: Boolean;
var
MMx, MMy, T, i: Integer;
MSPC: TPoint;
TPA: TPointArray;
begin
MarkTime(T);
while True do
begin
FFlag(0);
TPA := FindColorsSpiralMulti(MMCX + 10, MMCY + 10, [197874, 3951706], [10, 10], MMX1, MMY1, MMX2, MMY2);
MSPC := MMToMS(TPA[0]);
MMouse(MSPC.x, MSPC.y, 3, 3);
ClickMouse2(True);
if FindObj(MMx, MMy, 'ate', 3951706, 7) then //FindOBj automatically moves the mouse to the point when checking for uptext
begin
if WaitUptext('pen', RandomRange(400, 650)) then
begin
ClickMouse2(True);
wait(200);//static wait is fine as it is followed by a dynamic wait, this basically waits for the flag to appear.
FFlag(0);
Break;
end;
end;
Inc(i);
if (i = 5) or (TimeFromMark(T) > 30000) then
Exit;
end;
AntiBan;
Result := True;
end;

procedure Main;
begin
if not OpenGateIfClosed then
WalkToChickens;
end;

I changed a few things, when you use ( A or B) it is using a bitwise operator and passing the result of the query as the colour… … do not ever use OR unless you know how to fully utilize them or using it for basic boolean logic.

Try to break everything down into functions that you can call. The general rule of thumb is only to stick the same thing in a procedure if it is closely related. Take my example of the colour finding function, it is separated from the rest of the procedure as it is a rather common function and not confined to that single procedure.

rotchy1

2013-06-05 09:05:47

From: Rich
Got there in the end. For the first one try this:
procedure ChickenWalkFailsafe;
var
T, I : Integer;
sRadial, eRadial, xMod : TIntegerArray;
UntilWhat : array of function() : Boolean;

begin
TeleHome;
sRadial:= [76, 45, 330, 330, 350, 300, 350];
eRadial:= [80, 55, 350, 350, 359, 355, 352];
xMod:= [70, 55, 75, 80, 20, 70, 63];
UntilWhat[0]:= @VinesFound; UntilWhat[1]:= @LightPostFound; UntilWhat[2]:= @StumpFound
UntilWhat[3]:= @BlueFlagFound; UntilWhat[4]:= @RockFound; UntilWhat[5]:= @HayandGrainFound;
for I:= 0 to High(sRadial) do
repeat
MarkTime(T);
Writeln('RadialWalk' + IntToStr(I + 1));
RadialWalkTolerance(5594207, sRadial, eRadial, xMod, -1, 0, 34);
wait(RandomRange(1000, 1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('Error ' + IntToStr(I + 9));
Logout;
TerminateScript;
end;
until (UntilWhat[I]());
Wait(RandomRange(1500, 2000));
end;
For some reason it wouldn't let me declare the functions as a single array, so had to do it like that. It looks messy, I know, but I didn't really fancy taking up 6 lines. Hopefully it works :)


wow, that actually made sense, so from I:=0 to High it will use the values you declared, and I didn't even know you could declare 'UntilWhat'

Very Helpful thankyou :)!

Rich

2013-06-05 09:12:14

From: rotchy1
wow, that actually made sense, so from I:=0 to High it will use the values you declared, and I didn't even know you could declare 'UntilWhat'

Very Helpful thankyou :)!
That's alright, no worries. I don't think many people know about function pointers as they're seldom used, but they're very handy. If you fancy a read, check out this guide: http://villavu.com/forum/showthread.php?t=102800

rotchy1

2013-06-05 09:13:46

From: Enslaved


function FindColorsSpiralMulti(Sx, Sy: Integer; Colors, Tolerance: TIntegerArray; X1, Y1, X2, Y2: Integer): TPointArray;
var
i: Integer;
ATPA: T2DPointArray;
CombTPA: TPointArray;
begin
if (High(Colors) <> High(Tolerance)) then
begin
Writeln('Invalid number of parameters');
TerminateScript;
end;
for i := 0 to High(Colors) do
begin
SetLength(ATPA, i + 1);
FindColorsSpiralTolerance(Sx, Sy, ATPA[i], Colors[i], x1, y1, x2, y2, Tolerance[i]);
end;
CombTPA := MergeATPA(ATPA);
SortTPAFrom(CombTPA, Point(sx, sy));
Result := CombTPA;
end;

function OpenGateIfClosed: Boolean;
var
MMx, MMy, T, i: Integer;
MSPC: TPoint;
TPA: TPointArray;
begin
MarkTime(T);
while True do
begin
FFlag(0);
TPA := FindColorsSpiralMulti(MMCX + 10, MMCY + 10, [197874, 3951706], [10, 10], MMX1, MMY1, MMX2, MMY2);
MSPC := MMToMS(TPA[0]);
MMouse(MSPC.x, MSPC.y, 3, 3);
ClickMouse2(True);
if FindObj(MMx, MMy, 'ate', 3951706, 7) then //FindOBj automatically moves the mouse to the point when checking for uptext
begin
if WaitUptext('pen', RandomRange(400, 650)) then
begin
ClickMouse2(True);
wait(200);//static wait is fine as it is followed by a dynamic wait, this basically waits for the flag to appear.
FFlag(0);
Break;
end;
end;
Inc(i);
if (i = 5) or (TimeFromMark(T) > 30000) then
Exit;
end;
AntiBan;
Result := True;
end;

procedure Main;
begin
if not OpenGateIfClosed then
WalkToChickens;
end;

I changed a few things, when you use ( A or B) it is using a bitwise operator and passing the result of the query as the colour… … do not ever use OR unless you know how to fully utilize them or using it for basic boolean logic.

Try to break everything down into functions that you can call. The general rule of thumb is only to stick the same thing in a procedure if it is closely related. Take my example of the colour finding function, it is separated from the rest of the procedure as it is a rather common function and not confined to that single procedure.


Thanks for the info, it makes sense how you broke it down into simpler steps that can be called within the actual OpenGateIfClosed function. I really appreciate the help!

rotchy1

2013-06-05 09:15:35

From: Rich
That's alright, no worries. I don't think many people know about function pointers as they're seldom used, but they're very handy. If you fancy a read, check out this guide: http://villavu.com/forum/showthread.php?t=102800


Ill open the tab for later :)

Enslaved

2013-06-05 09:16:00

slight edit to @Rich's Fix

procedure ChickenWalkFailsafe;
var
T, I : Integer;
sRadial, eRadial, xMod : TIntegerArray;
UntilWhat : array of function : Boolean; //does not need brackets after function as you are not passing args

begin
TeleHome;
sRadial:= [76, 45, 330, 330, 350, 300, 350];
eRadial:= [80, 55, 350, 350, 359, 355, 352];
xMod:= [70, 55, 75, 80, 20, 70, 63];
UntilWhat[0]:= @VinesFound; UntilWhat[1]:= @LightPostFound; UntilWhat[2]:= @StumpFound
UntilWhat[3]:= @BlueFlagFound; UntilWhat[4]:= @RockFound; UntilWhat[5]:= @HayandGrainFound;
for I:= 0 to High(sRadial) do
repeat
MarkTime(T);
Writeln('RadialWalk' + IntToStr(I + 1));
RadialWalkTolerance(5594207, sRadial, eRadial, xMod[I], -1, 0, 34); //Rich, you forgot to add the subitem :)
wait(RandomRange(1000, 1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('Error ' + IntToStr(I + 9));
Logout;
TerminateScript;
end;
until (UntilWhat[I]());
Wait(RandomRange(1500, 2000));
end;

Rich

2013-06-05 09:20:33

You need to keep the parenthesis even if there are no variables. Good shout on the arrays though, but you missed a couple ;)

procedure ChickenWalkFailsafe;
var
T, I : Integer;
sRadial, eRadial, xMod : TIntegerArray;
UntilWhat : array of function() : Boolean;

begin
TeleHome;
sRadial:= [76, 45, 330, 330, 350, 300, 350];
eRadial:= [80, 55, 350, 350, 359, 355, 352];
xMod:= [70, 55, 75, 80, 20, 70, 63];
UntilWhat[0]:= @VinesFound; UntilWhat[1]:= @LightPostFound; UntilWhat[2]:= @StumpFound
UntilWhat[3]:= @BlueFlagFound; UntilWhat[4]:= @RockFound; UntilWhat[5]:= @HayandGrainFound;
for I:= 0 to High(sRadial) do
repeat
MarkTime(T);
Writeln('RadialWalk' + IntToStr(I + 1));
RadialWalkTolerance(5594207, sRadial[I], eRadial[I], xMod[I], -1, 0, 34);
wait(RandomRange(1000, 1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('Error ' + IntToStr(I + 9));
Logout;
TerminateScript;
end;
until (UntilWhat[I]());
Wait(RandomRange(1500, 2000));
end;

rotchy1

2013-06-05 09:29:50

From: Enslaved
slight edit to @Rich's Fix

procedure ChickenWalkFailsafe;
var
T, I : Integer;
sRadial, eRadial, xMod : TIntegerArray;
UntilWhat : array of function : Boolean; //does not need brackets after function as you are not passing args

begin
TeleHome;
sRadial:= [76, 45, 330, 330, 350, 300, 350];
eRadial:= [80, 55, 350, 350, 359, 355, 352];
xMod:= [70, 55, 75, 80, 20, 70, 63];
UntilWhat[0]:= @VinesFound; UntilWhat[1]:= @LightPostFound; UntilWhat[2]:= @StumpFound
UntilWhat[3]:= @BlueFlagFound; UntilWhat[4]:= @RockFound; UntilWhat[5]:= @HayandGrainFound;
for I:= 0 to High(sRadial) do
repeat
MarkTime(T);
Writeln('RadialWalk' + IntToStr(I + 1));
RadialWalkTolerance(5594207, sRadial, eRadial, xMod[I], -1, 0, 34); //Rich, you forgot to add the subitem :)
wait(RandomRange(1000, 1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('Error ' + IntToStr(I + 9));
Logout;
TerminateScript;
end;
until (UntilWhat[I]());
Wait(RandomRange(1500, 2000));
end;


I caught the Subitems when I compiled, but I couldn't help but laugh when I was reading your comments….My name is Rich as well and I was wondering how in the hell you knew my actual name…then I realized Rich's is username is, well "Rich" of course :P

Enslaved

2013-06-05 10:09:27

From: Rich
You need to keep the parenthesis even if there are no variables. Good shout on the arrays though, but you missed a couple ;)

procedure ChickenWalkFailsafe;
var
T, I : Integer;
sRadial, eRadial, xMod : TIntegerArray;
UntilWhat : array of function() : Boolean;

begin
TeleHome;
sRadial:= [76, 45, 330, 330, 350, 300, 350];
eRadial:= [80, 55, 350, 350, 359, 355, 352];
xMod:= [70, 55, 75, 80, 20, 70, 63];
UntilWhat[0]:= @VinesFound; UntilWhat[1]:= @LightPostFound; UntilWhat[2]:= @StumpFound
UntilWhat[3]:= @BlueFlagFound; UntilWhat[4]:= @RockFound; UntilWhat[5]:= @HayandGrainFound;
for I:= 0 to High(sRadial) do
repeat
MarkTime(T);
Writeln('RadialWalk' + IntToStr(I + 1));
RadialWalkTolerance(5594207, sRadial[I], eRadial[I], xMod[I], -1, 0, 34);
wait(RandomRange(1000, 1500));
if TimeFromMark(T) > 30000 then
begin
Writeln('Error ' + IntToStr(I + 9));
Logout;
TerminateScript;
end;
until (UntilWhat[I]());
Wait(RandomRange(1500, 2000));
end;

Ahh my bad lol, was just trying to fix the compile errors and declared those 2 as variants