SRL Archive - RS3 Help

Help making a better way to find a moving NPC


arclight

2014-11-03 22:42:46

Okay, so, for my Kyatt Summoning Script, I was wondering if there is a better way than what I currently do to find the banker. Here is the code for that method:
function findBankerAndClick(button : integer = mouse_Left) : boolean;
var
x, y, index, tries: integer;
TPA, copyTPA, checkTPA : TPointArray;
ATPA : T2DPointArray;
begin
for tries := 0 to 6 do
begin
findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
ATPA := TPA.toATPA(10,10);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
//can't see banker, try to click minimap
if(length(ATPA) = 0) then
begin
minimap.clickCompass;
findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
ATPA := TPA.toATPA(10,10);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
end;
if(length(ATPA) = 0) then
exit(false);
for(index := 0) to (high(ATPA)) do
begin
mouse(MiddleTPA(ATPA[index]), MOUSE_MOVE);
findColorsSpiralTolerance(x, y, checkTPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
copyTPA := TPA;
//checking if he moved
if((length(copyTPA.clearTPAFrom(checkTPA)) > (0.5 * length(TPA)))) then
begin
//probably moved, going to have to be careful
if(button = mouse_Right) then
begin
fastClick(button);
wait(gaussRangeInt(250, 500));
if(chooseOption.optionsExist(['Bank '])) then
exit(true);
end else
begin
//technically could click someone's familar or something for a false
//positive, but at least we probably see the banker, I think
if(didClick(true)) then
exit(true);
end;
index := high(ATPA);
wait(gaussRangeInt(250, 500));
end else if(isMouseOverText(['Bank '], 250)) then
begin
fastClick(button);
exit(true);
end;
end;
end;
writeln('totally failed at getting that banker');
exit(false);
end;

Basically it finds TPAs for the banker, makes ATPAs out of it, moves mouse to location, find TPAs again and compares it to original if the mouse over text starts with bank, and proceeds based off that knowledge. The compare step just sees if the TPAs are 50% different at least. Is there a better way to solve this problem? I would assume people would have heavily explored it already.

sidenote: I should probably use break rather than invalidating the for loop index, but I didn't remember if that was a feature of LAPE or not.

TomTuff

2014-11-03 22:58:58

Just only mouse to the first TPA in the array and check the hover text. If it doesn't did him then search again. Make your Colors only detect the banker.

This is for the guy by fight caves right?

arclight

2014-11-03 23:12:49

From: TomTuff
Just only mouse to the first TPA in the array and check the hover text. If it doesn't did him then search again. Make your Colors only detect the banker.

This is for the guy by fight caves right?


Ya. I already check for the hover over text, but he was moving before it clicked, which is why I added the failsafe.

TomTuff

2014-11-03 23:14:27

Yeah take that check out entirely and just do what I said (only mouse to ATPA[0] and if you don't find him exit false and try again)

Check out bonsais tutorial for finding hard to read objects. That should work perfectly. Also try temporarily boosting mosespeed to 30 or so.

arclight

2014-11-03 23:39:35

The problem isn't in initially finding him (only time I get false positives is if people wear the distinctive color of the banker) , but make sure he is still there when I click, forgot to add the check back in on the checking for the mouse over though. I probably should just not check the TPAs again and just do the check to see if I actually clicked him each time. So, like this:

function findBankerAndClick(button : integer = mouse_Left) : boolean;
var
x, y, index, tries: integer;
TPA: TPointArray;
ATPA : T2DPointArray;
begin
for tries := 0 to 6 do
begin
findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
ATPA := TPA.toATPA(10,10);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
//can't see banker, try to click minimap
if(length(ATPA) = 0) then
begin
minimap.clickCompass;
findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
ATPA := TPA.toATPA(10,10);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
end;
if(length(ATPA) = 0) then
exit(false);
for(index := 0) to (high(ATPA)) do
begin
mouse(MiddleTPA(ATPA[index]), MOUSE_MOVE);
if(isMouseOverText(['Bank '], 250)) then
begin
if(button = mouse_Right) then
begin
fastClick(button);
wait(gaussRangeInt(250, 500));
if(chooseOption.optionsExist(['Bank '])) then
exit(true);
end else
begin
//technically could click someone's familar or something for a false
//positive, but at least we probably see the banker, I think
if(didClick(true)) then
exit(true);
end;
break;
end;
end;
end;
writeln('totally failed at getting that banker');
exit(false);
end

I should mention my solution to not finding the banker is reteleporting and hoping for the best, so that is a fairly costly move.

TomTuff

2014-11-04 00:56:48

From: arclight
The problem isn't in initially finding him (only time I get false positives is if people wear the distinctive color of the banker) , but make sure he is still there when I click, forgot to add the check back in on the checking for the mouse over though. I probably should just not check the TPAs again and just do the check to see if I actually clicked him each time. So, like this:

function findBankerAndClick(button : integer = mouse_Left) : boolean;
var
x, y, index, tries: integer;
TPA: TPointArray;
ATPA : T2DPointArray;
begin
for tries := 0 to 6 do
begin
findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
ATPA := TPA.toATPA(10,10);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
//can't see banker, try to click minimap
if(length(ATPA) = 0) then
begin
minimap.clickCompass;
findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24));
ATPA := TPA.toATPA(10,10);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
end;
if(length(ATPA) = 0) then
exit(false);
for(index := 0) to (high(ATPA)) do
begin
mouse(MiddleTPA(ATPA[index]), MOUSE_MOVE);
if(isMouseOverText(['Bank '], 250)) then
begin
if(button = mouse_Right) then
begin
fastClick(button);
wait(gaussRangeInt(250, 500));
if(chooseOption.optionsExist(['Bank '])) then
exit(true);
end else
begin
//technically could click someone's familar or something for a false
//positive, but at least we probably see the banker, I think
if(didClick(true)) then
exit(true);
end;
break;
end;
end;
end;
writeln('totally failed at getting that banker');
exit(false);
end

I should mention my solution to not finding the banker is reteleporting and hoping for the best, so that is a fairly costly move.



Ok, I'm home now, so I can help you out some.

I don't like the way you've implemented the "tries" looping. I think that it is good form to have functions such as findBankerAndClick do only that, and handle any sort of fail safes such as numerous tries or camera rotating outside of the function itself.

Anyways, here's what I came up with. It works 100% of the time for me.

function openMejJalBank(fast: boolean = false): boolean;
var
ATPA: T2DPointArray;
TPA: TPointArray;
P: TPoint;
i, button: Integer;
begin
if bankScreen.isOpen() then
Exit(True);

if not findColorsSpiralTolerance(P.x, P.y, TPA, 2268349, mainscreen.getBounds, 8, colorSetting(2, 0.22, 2.24)) then
Exit(False);

ATPA := TPA.split(4, 4);
ATPA.filterBetween(0, 30);

if Length(ATPA) = 0 then
Exit(False);

ATPA.sortFromMidPoint(mainscreen.getCenterPoint);

//smartImage.clear;
//smartImage.debugATPA(ATPA);

case fast of
True: button := mouse_Left;
False: button := mouse_Right;
end;

mouseBox(ATPA[0].getBounds, MOUSE_MOVE);
if isMouseOverText(['Mej']) then
begin
fastClick(button);
if fast then
exit(bankScreen.isOpen(200));
if chooseOption.select(['Bank']) then
Exit(bankScreen.isOpen(200));
end;
end;

arclight

2014-11-04 01:52:50

Alright, using a bit of your ideas to move the failsafes out of the function:

function findBankerAndClick(button : integer = mouse_Left) : boolean;
var
x, y, index, tries: integer;
TPA : TPointArray;
ATPA : T2DPointArray;
begin
if(not findColorsSpiralTolerance(x, y, TPA, 2268349, mainScreen.getBounds, 8, colorSetting(2, 0.22, 2.24))) then
exit(false);

ATPA := TPA.split(5,5);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
mouse(MiddleTPA(ATPA[0]), MOUSE_MOVE);
if(isMouseOverText(['Bank'], 250)) then
begin
if(button = mouse_Right) then
begin
fastClick(button);
if(chooseOption.select(['Bank'])) then
exit(bankScreen.isOpen(gaussRangeInt(1500, 2000)));
end else
begin
fastClick(button);
exit(bankScreen.isOpen(gaussRangeInt(1500, 2000)));
end;
end;
exit(false);
end;

function attemptFun(func : function(p : integer) : boolean; attempts, param : integer) : boolean;
var
index : integer;
begin
for index := 0 to attempts do
begin
if(func(param)) then
exit(true);
end;
exit(false);
end;

function bank : boolean;
var
button : integer;
begin
AntiBan;
actionBar.clickSlot(1);
Wait(gaussRangeInt(500,1000));
conversationBox.selectOption(3);
Wait(gaussRangeInt(3000,4000));
case random(1,10) of
1..7 : button := mouse_Left;
7..10 : button := mouse_Right;
end;
if(not attemptFun(@findBankerAndClick, 2, button)) then
begin
minimap.clickCompass;
if(not attemptFun(@findBankerAndClick, 2, button)) then
TerminateScript;
end;
wait(gaussRangeInt(500,1000));
bankScreen.clickButton(players[CurrentPlayer].integers[1]);
wait(gaussRangeInt(1000,2500));
if(not(tabBackpack.count = 28)) then
begin
writeln('backpack a little empty, ending');
TerminateScript;
end;
end;

I gave it two attempts before trying the minimap to avoid have the weird time when it is clicks right when he is walking by.

Incurable

2014-11-04 02:58:32

I haven't read everything, but is there any reason why you can't just use:


mouseSpeed := gaussRangeInt(28, 36);

… to make sure that you click the Banker, then lower it again afterwards?

Lipcot

2014-11-04 10:59:46

From: Incurable
I haven't read everything, but is there any reason why you can't just use:


mouseSpeed := gaussRangeInt(28, 36);

… to make sure that you click the Banker, then lower it again afterwards?


i was here to say the exact same thing. i've used mousespeed := 30 + random(5) for fight scripts and never got banned sooo, you could try that

plus, you could also try lowering the time on the mouseovertext, like to 100 ms, so at the moment the mouse is over the banker, it will click almost instantly. you could also make a loop that tries many times, i would even use ATPA, just TPA and coordinates, since it will be a faster process and it leaves less time for the banker to move