SRL Archive - Jr. Member General Help and Discussion

Need help using TPA's to find trees


mxtrix

2013-12-17 01:47:45

Hey guys, I have recently come back to Simba after more than a year and have commenced making a Teak power-cutter. The script is complete however initially I used this to identify the teaks:

not mainscreen.findObject(x, y, [6912650], [5], colorSetting(2, 1, 10), mainscreen.getCenterPoint(), 25, 80, 80, ['Teak'], mainscreen.getBounds(), MOUSE_LEFT)

However it was inaccurate and I wanted to find a more reliable method so I found TPAs. After reading some tutorials throughout the forums I have written a simple procedure to do this- this can be seen below:

Procedure FindTeak;
var
TeakTPA:TPointArray;
ATPA : T2DPointArray;
I, X, Y : Integer;
begin
FindColorsSpiralTolerance(273, 187, TeakTPA, 6647686, 0, 0, 575, 388, 6);
ATPA := TPAToATPEx(TeakTPA, 2, 10);
For I := 0 To High(ATPA) Do
Begin
If MiddleTPAEx(ATPA[I], X, Y) Then
Mouse(x, y, 0, 0);
If (IsMouseOverText(['Teak','eak'],RandomRange(200,300))) Then
Mouse(x, y, 0, 0);
fastClick(MOUSE_LEFT);
Break;
End;
end;

However when compiling I get the error: Exception in Script: Unknown declaration "TPAToATPEx" at line 59, column 12. I am trying to find all of the matching points and group them in rectangles with dimensions of 2x10 pixels (roughly what the trunk of each teak is). Below is a picture of the result from using ACA to test the effectiveness. I understand that the only failsafe present is that where it checks the uptext but I am just trying to get this to work first. I would like the procedure to find all of teak trunks and to click in the centre of the rectangle of the closest 'rectangle' of TPAs to the centre point (which was 273, 187). If anyone could help me it would be greatly appeciated.

[ATTACH=CONFIG]22568[/ATTACH]

Sjoe

2013-12-17 02:02:28

it's TPAToATPAEx

bonsai

2013-12-17 03:49:35

With thin little objects like that you might find the cluster() functions more effective.

ATPA := TeakTPA.cluster(2);

Will put all the pixels within distance two into the subarrays.

Also, for the sorting, mainscreen.playerbox.getMiddle() will return the centerpoint of the player on the screen. That way you don't need to code in constant x,y values.

Good luck with the script!

mxtrix

2013-12-17 10:08:44

Thanks guys. I have managed to play around a bit and get it to work flawlessly. Tomorrow I will finish the script and tidy it up so expect a release in the public section. If anyone was wondering I ended up creating two procedures (one for the initial teak and one for each consecutive one). I ended up creating a second one as it had problems identifying a cut teak from a normal teak . I ended up using TPAToATPAEx instead of TeakTPA.cluster as it found points more near the center of the tree which seemed more human like. I also need to make use of mainscreen.playerbox.getMiddle() but will do that tomorrow also. Here is the code for them:

Procedure FindTeak;
var
TeakTPA:TPointArray;
ATPA : T2DPointArray;
//I, X, Y : Integer; //NEED TO DECALRE AS GLOBAL
begin
FindColorsSpiralTolerance(273, 187, TeakTPA, 6647686, 0, 0, 575, 388, 6);
//ATPA := TeakTPA.cluster(2);
ATPA := TPAToATPAEx(TeakTPA, 4, 54);
For I := 0 To High(ATPA) Do
Begin
If MiddleTPAEx(ATPA[I], X, Y) Then
begin
Mouse(x, y, 0, 0);
end;
If (IsMouseOverText(['Teak','eak'],RandomRange(200,300))) Then
begin
//Mouse(x, y, 0, 0);
fastClick(MOUSE_LEFT);
NextTeak := True;
WriteLn('FindTeak Finished');
Break;
end;
End;
end;

//IF NOTHING IS FOUND ON THE RANDOM SIDE THAN CHECK THE OTHER
Procedure FindNextTeak;
var
TeakTPAN:TPointArray;
ATPAN : T2DPointArray;
//I, X, Y : Integer; //NEED TO DECALRE AS GLOBAL
begin
WriteLn('FindNextTeak Started');
//BX1 and BX2 are the x bounds were the teak trunk will be so we will avoid them
RandomLeftRight := RandomRange(1,2);
if (RandomLeftRight = 1) then
begin
//CLICK TO THE LEFT?
if (not FindColorsSpiralTolerance(273, 187, TeakTPAN, 6647686, 0, 0, BX1, 388, 6)) then
begin
//GOTO OTHER ONE
FindColorsSpiralTolerance(273, 187, TeakTPAN, 6647686, BX2, 0, 575, 388, 6);
end else
begin
WriteLn('Found next teak');
end;
end;
if (RandomLeftRight = 2) then
begin
//CLICK RIGHT
if (not FindColorsSpiralTolerance(273, 187, TeakTPAN, 6647686, BX2, 0, 575, 388, 6)) then
begin
//GOTO OTHER ONE
FindColorsSpiralTolerance(273, 187, TeakTPAN, 6647686, 0, 0, BX1, 388, 6);
end else
begin
WriteLn('Found next teak');
end;
end;
//ATPA := TeakTPA.cluster(2);
ATPAN := TPAToATPAEx(TeakTPAN, 4, 54);
For I := 0 To High(ATPAN) Do
Begin
If MiddleTPAEx(ATPAN[I], X, Y) Then
begin
Mouse(x, y, 0, 0);
end;
If (IsMouseOverText(['Teak','eak'],RandomRange(200,300))) Then
begin
//Mouse(x, y, 0, 0);
fastClick(MOUSE_LEFT);
NextTeak := True;
Break;
end;
end;
end;

The BX1,BX2,BY1 and BY2 variables were created in another procedure I have yet to merge


BX1 := X-40;
BY1 := Y-90;
BX2 := X+40;
BY2 := Y+22;

Sjoe

2013-12-17 11:08:16

From: bonsai
With thin little objects like that you might find the cluster() functions more effective.

ATPA := TeakTPA.cluster(2);

Will put all the pixels within distance two into the subarrays.

Also, for the sorting, mainscreen.playerbox.getMiddle() will return the centerpoint of the player on the screen. That way you don't need to code in constant x,y values.

Good luck with the script!


what about point(mainscreen.playerpoint.x, mainscreen.playerpoint.y);
?

bonsai

2013-12-17 12:22:39

From: Sjoe
what about point(mainscreen.playerpoint.x, mainscreen.playerpoint.y);
?


Yes, you're right. Since he needs X,Y's that would be much simpler.

I forgot Olly added both the point and the box to the library.