SRL Archive - OSR Help

TPA FindObject Problems


VastlySuperior

2012-08-28 13:48:43

Hi

I need some help with my findobject. It finds all the points correctly, but i have two problems.

The first one is that it finds the color, move to the location real quick and then waits about a second and a half before clicking the objects to mine. I don`t understand why it is so slow in clicking the object.

The second problem is that I keep getting this error Repeatedly and I don`t know what to do about it or where to look for the problem. I`m a bit new to TPA`s.

Warning! You passed wrong values to a finder function: xs > xe (359,159). Swapping the values for now.
Warning! You passed wrong values to a finder function: ys > ye (270,70). Swapping the values for now.
We Have Found The Ore

Here is my procedure and function I`m using at the moment to find the ore.

Function FindOre(var x,y:integer) : Boolean;
var
ItemX, ItemY : Integer;
TPA : Array Of TPoint;
ATPA : T2DPointArray;
i : Integer;
PlayerBox, MiningBox: TPointArray;
Begin
PlayerBox := TPAFromBox(IntToBox(240, 140, 275, 195));
x:=MSCX;
y:=MSCY;
FindColorsSpiralTolerance(ItemX, ItemY, TPA, Colour, (MSCX + 100), (MSCY + 100), (MSCX - 100), (MSCY - 100), TolR)
ClearTPAFromTPAWrap(TPA, PlayerBox, {var}TPA);
Begin
ATPA := SplitTPA(TPA, 10);
For i := 0 To High(ATPA) Do
Begin
If MiddleTPAEX(ATPA[i], ItemX, ItemY) then
Begin
MMouse(ItemX, ItemY, 1, 1);
End;
If WaitUptext(Desc, 300) Then
Begin
x := ItemX;
y := ItemY;
Writeln('We Have Found The Ore');
Result := True;
End;
Exit;
End;
End;
End;

procedure Mining; // Mining Operation
var
x, y, RockCounter, FailSafeTime, TempTime: integer;
Begin
Disguise('At The Mining Location. Staring Mining Operation');
WriteLn('At The Mining Location.');
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
Start_Time := GetTimeRunning;
If MineFirstRun then
Begin
MineFirstRun := True;
End else
Begin
MOriginalXP := GetXPBar(2);
OMSkillLevel := GetSkillLevel(SKILL_MINING);
MineFirstRun := True;
End;
If InvFull Then
Begin
MCurrentXP := GetXPBar(1);
MCurrentXP := (MCurrentXP - MOriginalXP);
End_Time := GetTimeRunning;
TotalTime := (End_Time - Start_Time)/1000;
WriteLn('Mining ' + Desc + ' Took ' + IntToStr(TotalTime) + ' Seconds To Complete');
Exit;
End;
SelectRock(OreChoice);
SetLocation;
MakeCompass(Cam);
Wait(200 + Random(100));
SetAngle(SRL_ANGLE_HIGH);
While IsMoving do
Begin
Wait(50);
End;
MarkTime(FailSafeTime);
Repeat
Disguise('Starting Mining For ' + Desc);
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
ToggleXPBar(True);
If (TimeFromMark(FailSafeTime) > (30000 + Random(300))) then
Begin
MCurrentXP := GetXPBar(1);
MCurrentXP := (MCurrentXP - MOriginalXP);
End_Time := GetTimeRunning;
TotalTime := (End_Time - Start_Time)/1000;
WriteLn('Mining ' + Desc + ' Took ' + IntToStr(TotalTime) + ' Seconds To Complete');
Lost;
Exit;
End;
If (FindOre(x, y)) then
Begin
While IsMoving Do
Wait(10);
If IsUptext(Desc) and (not(IsMining)) Then
Begin
Mouse(x, y, 0, 0, True);
MarkTime(RockCounter);
MarkTime(FailSafeTime);
Writeln('Clicked The Ore To Start Mining');
End;
End;
Antiban;
Repeat
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
Until (FindBlackChatMessage('nage')) or (TimeFromMark(RockCounter) > (3700 + Random(300))) and (not(IsMining));

Until (InvFull);
MiningLoads(OreChoice);
MCurrentXP := GetXPBar(1);
MCurrentXP := (MCurrentXP - MOriginalXP);
End_Time := GetTimeRunning;
TotalTime := (End_Time - Start_Time)/1000;
WriteLn('Mining ' + Desc + ' Took ' + IntToStr(TotalTime) + ' Seconds To Complete');
End;


I would appreciate some help with this.

Thanks guys.

CephaXz

2012-08-28 14:03:24

For the error, probably because of this :
FindColorsSpiralTolerance(ItemX, ItemY, TPA, Colour, (MSCX + 100), (MSCY + 100), (MSCX - 100), (MSCY - 100), TolR)

Try changing it to this:

FindColorsSpiralTolerance(ItemX, ItemY, TPA, Colour, (MSCX - 100), (MSCY - 100), (MSCX + 100), (MSCY + 100), TolR)

Second function too complicated to read :p

Runaway

2012-08-28 14:08:59

The wrong value error is because you are declaring the bottom-right corner of the search box before the top-left corner.


Function FindOre(var x, y: Integer) : Boolean;
var
ATPA : T2DPointArray;
TPA, PlayerBox, MiningBox : TPointArray;
ItemX, ItemY, i : Integer;
Begin
PlayerBox := TPAFromBox(IntToBox(240, 140, 275, 195));
//x := MSCX; <- What is the point of this?
//y := MSCY;
FindColorsSpiralTolerance(ItemX, ItemY, TPA, Colour, (MSCX - 100), (MSCY - 100), (MSCX + 100), (MSCY + 100), TolR);
// ^ MSCX - 100 before MSCX + 100, since the top-left is declared before bottom-right
ClearTPAFromTPAWrap(TPA, PlayerBox, {var}TPA);
Begin
ATPA := SplitTPA(TPA, 10);
For i := 0 To High(ATPA) Do
Begin
If MiddleTPAEX(ATPA[i], ItemX, ItemY) then
Begin
MMouse(ItemX, ItemY, 1, 1);
End else
Continue; // No point checking the uptext if the mouse wasn't moved
If WaitUptext(Desc, 300) Then
Begin
x := ItemX;
y := ItemY;
Writeln('We Have Found The Ore');
Result := True;
Exit; // <- Here
End;
//Exit; Move this up to ^
End;
End;
End;

I also added in a few comments on the code ;)

VastlySuperior

2012-08-28 14:34:03

Thanks to both of you for the help with the error I received, That is sorted out now, but I would like to know why it takes about a second before it clicks the rock when finding the location?

Can it have anything to do with the code I use to detect the pixelshift, for if I`m currently in the mining animation?

Here is the code for that as well.

function IsMining: Boolean;                       // True If Mining Animation
var // Credit To Flight
PBox:TBox;
Begin
PBox := IntToBox(245, 130, 285, 195);
Result := (AveragePixelShIft(PBox, 250, 500) > 200);
End;

It was suggested by Flight that it should be > 400, but I did a test on the pixelshift for my character and while standing idle it never goes higher than 150, so I thought if I make it 200 then it will mean that I`m currently in a animation as 400 is really at the end of the range for the mining animation.

I would really like to make this faster.

I took your suggestions Runaway and implemented that also, took out the unnecessary code, as I thought that values will force the search from the center of the screen, that was why I used it.

Solar

2012-08-28 14:46:29

Could you give me simple explanation of what AveragePixelShift does please? I've read the explanation in the include, but what does it mean by pixel shift?
Sorry, I don't mean to derail from your thread, it just doesn't seem like something to create a new one about.

Runaway

2012-08-28 14:55:00

It is most likely the IsMining() check.


Result := (AveragePixelShIft(PBox, 250, 500) > 200);

AveragePixelShift() will check the pixel shift for 500 ms. You also perform an IsMoving and IsUptext check before clicking as well. I would recommend doing this:


function IsMining: Boolean;
var
PBox:TBox;
Begin
PBox := IntToBox(245, 130, 285, 195);
Result := (AveragePixelShIft(PBox, 100, 300) > 200);
// Decrease the WaitPerLoop and MaxWait values
End;

// Either put the IsMoving check here
While IsMoving Do
Wait(50);
// ---^
If (FindOre(x, y)) then
Begin
// IsUptext has already been checked in FindOre so another is unnecessary
If not IsMining Then
Begin
ClickMouse2(mouse_left);
// Or here
While IsMoving Do
Wait(50);
// ---^
MarkTime(RockCounter);
MarkTime(FailSafeTime);
Writeln('Clicked The Ore To Start Mining');
End;
End;

VastlySuperior

2012-08-28 15:26:12

From: Solar
Could you give me simple explanation of what AveragePixelShift does please? I've read the explanation in the include, but what does it mean by pixel shift?
Sorry, I don't mean to derail from your thread, it just doesn't seem like something to create a new one about.


Here Is a good tut on Pixelshift and what it does, basically it helps you determine if your character is busy with a task before doing something else.

@ Runaway. I have changed the procedure as suggested but it seems it made no difference in the timing from when it finds the color to when it clicks on the object. Can it have something to do with the color I use to search for the ore, because I find sometimes when teleporting to the bank and back that when it is at the location where it is supposed to mine it will just stand there doing nothing, that is why I use a 30 second failsafe timer to get out of the situation and start from the beginning and then it works again. The autocolor function reports every time that it finds a color but it will just stand there doing nothing, this does not happens frequently, just sometimes.

I also Use Autocolor ver3 for picking the best color with the tolerance.

Solar

2012-08-28 15:42:51

Thanks, didn't think there would be a tutorial on a single function.

Runaway

2012-08-28 17:14:40

From: VastlySuperior
Here Is a good tut on Pixelshift and what it does, basically it helps you determine if your character is busy with a task before doing something else.

@ Runaway. I have changed the procedure as suggested but it seems it made no difference in the timing from when it finds the color to when it clicks on the object. Can it have something to do with the color I use to search for the ore, because I find sometimes when teleporting to the bank and back that when it is at the location where it is supposed to mine it will just stand there doing nothing, that is why I use a 30 second failsafe timer to get out of the situation and start from the beginning and then it works again. The autocolor function reports every time that it finds a color but it will just stand there doing nothing, this does not happens frequently, just sometimes.

I also Use Autocolor ver3 for picking the best color with the tolerance.


Hmm… try adding this into your IsMining function to see what the average pixel shift is outputting every time it's called:


function IsMining: Boolean;
var
PBox: TBox;
Shift: Integer;
Begin
PBox := IntToBox(245, 130, 285, 195);
Shift := AveragePixelShift(PBox, 100, 300);
Writeln(Shift);
Result := (Shift > 200);
End;

If it's finding the color and moving the mouse, the only thing that could stop it from clicking would be IsMining.

VastlySuperior

2012-08-28 23:50:21

Ok, While Idle, the highest value was 152 and the smallest 52, while mining the biggest value was 670 and smallest 192, So I think 200 is a good value to go with, less false positives that way and it is still sensitive enough to return a quick result.

Or should it be less sensitive? But then it might start clicking on rocks that is further away while still busy mining a rock, which will interrupt the mining and move you away from where you have not finished yet, wasting even more time.

P1ng

2012-08-29 00:15:20

This my own personal IsMining function. Is based on the same principal as yours, only different area. You can see if you have smartgraphics included that this box is perfectly around your player.

function IsMining: Boolean;
begin
SMART_DrawBoxEx(True, False, IntToBox(MSCx - 15, MSCy - 20, MSCx + 15, MSCy + 20), ClWhite);
Result := (PixelShift(IntToBox(MSCx - 15, MSCy - 20, MSCx + 15, MSCy + 20), 500) > 250);
//WriteLn(Result);
end;

Also, feel free to change the number to suit your liking, but from the numbers you gave earlier in the thread 200 sounds like a good go.

CephaXz

2012-08-29 00:19:30

Actually, I would rather check on the color of the rock until its gone. When you fight for a rock with someone else and you lose, you will still have the animation of mining.

Runaway

2012-08-29 00:21:56

From: VastlySuperior
Ok, While Idle, the highest value was 152 and the smallest 52, while mining the biggest value was 670 and smallest 192, So I think 200 is a good value to go with, less false positives that way and it is still sensitive enough to return a quick result.

Or should it be less sensitive? But then it might start clicking on rocks that is further away while still busy mining a rock, which will interrupt the mining and move you away from where you have not finished yet, wasting even more time.


Yeah 200 sounds like it should work well. Maybe a little less (190, 180) could work… but you'll figure out the right amount either way when you test it more :p

Could you post the current code?

VastlySuperior

2012-08-29 00:52:45

From: CephaXz
Actually, I would rather check on the color of the rock until its gone. When you fight for a rock with someone else and you lose, you will still have the animation of mining.


I would really like to know how to do that? Create a box where it clicked and search in the box for the color until not found and then break out of the loop.

@ Runaway, I don`t know if I should release the code as it is at Remington, I know you have a miner for there but Flight asked a few days ago for such a script and I just decided to create it as he is a valued member here and I wanted to give something back to him if it was possible for me to do, I first used findobject to detect the objects but the mouse moved too much all over the screen so I checked out TPA again because I couldn`t get it to work for me but apparently I figured that out now because it works quite well now for me and that is just great.

I don`t know if I should release this in the f2p with banking if it will harm this area at Remington, because in your script, you have to have certain items to make it work, but with mine you don`t need anything as I use the deposito box at port sarim to do the banking.

If you all think it will not harm the area then I will release the whole script to the scripting area, it mines everything at Remington and has the option to powermine as well.

It is working quite stable at the moment, just got a six hour proggy tonight from it for copper and a six hour proggy yesterday for tin.

So what do you guys think, should I release it in the public section?

@ P1ng, thanks for your input, really appreciate that, and is going to test your suggestions as well

P1ng

2012-08-29 01:14:24

I have written a guild miner and it detects the ore vein colour within the lighter rock colour.
If you would like me to send through to you how I do it then just send me a PM.

Alternatively you can try to work it out yourself.
Essentially I make a TBox using GetTPABounds and then check if that ore vein colour is present in that box

VastlySuperior

2012-08-29 01:21:56

From: P1ng
This my own personal IsMining function. Is based on the same principal as yours, only different area. You can see if you have smartgraphics included that this box is perfectly around your player.

function IsMining: Boolean;
begin
SMART_DrawBoxEx(True, False, IntToBox(MSCx - 15, MSCy - 20, MSCx + 15, MSCy + 20), ClWhite);
Result := (PixelShift(IntToBox(MSCx - 15, MSCy - 20, MSCx + 15, MSCy + 20), 500) > 250);
//WriteLn(Result);
end;

Also, feel free to change the number to suit your liking, but from the numbers you gave earlier in the thread 200 sounds like a good go.


This is a really tight squeeze. You say you get good results from this? It works for Angle High but when low it cuts through your character, or do you use other settings for low or do it just not matter?

VastlySuperior

2012-08-29 01:29:06

From: P1ng
I have written a guild miner and it detects the ore vein colour within the lighter rock colour.
If you would like me to send through to you how I do it then just send me a PM.

Alternatively you can try to work it out yourself.
Essentially I make a TBox using GetTPABounds and then check if that ore vein colour is present in that box


TPA`s is still quite new to me but from what I have experienced with this script it outperforms anything else that I have done before and is way more accurate. There is no way I will be using anything else if this works everywhere with any object.

But my main Idea about how to do it was correct as I use the vain in any case to search for the ore when mining, just never crossed my mind to do that instead of the IsMining function to break out of a loop.

But I appreciate the offer P1ng, if I can`t work this out I`ll get back to you.

P1ng

2012-08-29 01:39:15

No problems, the offer stands if you can't figure it out :)

The checks I have in my script (probably a bit of over-kill but can't hurt to be sure):
- Black chat message x2
- Inventory count
- Time
- Pixelshift
- Ore present in rock

VastlySuperior

2012-08-29 05:37:25

From: Runaway
Yeah 200 sounds like it should work well. Maybe a little less (190, 180) could work… but you'll figure out the right amount either way when you test it more :p

Could you post the current code?


You can find the script Here