SRL Archive - SRL Snippets

TPA/ATPA Obj finding with multiple color


riwu

2012-10-27 10:33:36

I've just made this base for an Oak Dungeon Door script that i'm currently working on. This is a generic function that some might find useful so i'm posting it here. Just made it though and haven't tested so might have some errors. The reason why the function don't return the point in which the object is at (like what most obj finding function does) is because your mouse is already at the obj when the result is true! So just start clicking!

type
ObjRecord = record
Color, Tol: TIntegerArray;
HMod,SMod: TExtendedArray;
UpText: TStringArray;
MinL, Split: Integer;
end;

function FObj(Obj: ObjRecord): Boolean;
var
ATPA: T2DPointArray;
i, l, x, y: Integer;
playerTPA, TPA: TPointArray;
begin
ColorToleranceSpeed(2);
l:= High(Obj.Color);
SetLength(ATPA, l + 1);

for i:=0 to l do
begin
SetColorSpeed2Modifiers(Obj.HMod[i], Obj.SMod[i]);
FindColorsTolerance(ATPA[i], Obj.Color[i], MSX1, MSY1, MSX2, MSY2, Obj.Tol[i]);
end;

ColorToleranceSpeed(1);

MergeATPAWrap(ATPA, TPA);
TPAFromBoxWrap(IntToBox(247, 156, 271, 186), playerTPA);
ClearTPAFromTPAWrap(TPA, playerTPA, TPA);

if Length(TPA) < Obj.MinL then
Exit;

SplitTPAWrap(TPA, Obj.Split, ATPA);
SortATPAFromMidPoint(ATPA, Point(MSCX, MSCY));

for i:=0 to High(ATPA) do
if Length(ATPA[i]) > Obj.MinL then
begin
MiddleTPAEx(ATPA[i], x, y);
MMouse(x, y, 2, 2);
if WaitUpTextMulti(Obj.UpText, 618) then
begin
// if DEBUG_MODE then
writeln('Found Obj: ' + ToStr(Obj));
Result:= True;
Exit;
end;
end;
end;

Suggestions are appreciated.

And btw i reused some variables (eg. i, ATPA), this shouldn't affect functionality but is it good practice?

slushpuppy

2012-10-27 11:05:04

You should add a check for whether 2 colors are within a certain proximity because it just seems you are just grouping colors together without checking relations between the two

There is a pre-existing function to do such things:
FindObjTPAMulti

Also you may want to take a look at:

http://villavu.com/forum/showthread.php?t=81393&highlight=duck


or

Snippet from my own beefybill script

function findCompositeColors(maxDist : Integer ;colors : TIntegerArray; tols : TIntegerArray) : array of TPointArray;
var
I,Y,Z,found2Index,foundCount : Integer;
tol : extended;
tpa,tpa2 : TPointArray;
tp1,tp2 : TPoint;
points : array of TPointArray;
colorList : TIntegerArray;
begin
SetArrayLength(points, Length(colors));
foundCount := 0;
FindObjTPAMulti(
for I := 0 to High(colors) do
if FindColorsSpiralTolerance(MSCX,MSCY,tpa,colors[I],MSX1,MSY1,MSX2,MSY2,tols[I]) then
begin

Inc(foundCount);
tpa2 := CombineTPA(tpa2,tpa);
{points[I] := SplitTPA(tpa,maxDist);
DebugATPABounds(points[I]); }

end;
// debugtpa(tpa2,'');
if foundCount = Length(colors) then
begin
points := splittpa(tpa2,maxDist);
//DebugATPAbounds(points);
for I := 0 to high(points) do
begin
colorList := GetColors(points[I]);
foundCount := 0;
for Y := 0 to high(colors) do
begin
tol := sqr(tols[Y]);
for Z := 0 to high(colorList) do
begin
if GetTol(colors[Y],colorList[Z]) <= tol then
begin
Inc(foundCount);
break;
end;
end;
end;
if foundCount = Length(colors) then
begin
SetArrayLength(Result,Length(Result) + 1);
Result[High(Result)] := points[I];
end;
end;
end;
end;

litoris

2012-10-27 12:32:26

This is kinda useless, beginner5 had some function that I assume the guy above me linked to. One got committed, it joins close points from two TPAs. I use it in all my scripts, and I'm using a record in a similar fashion to you here in my WIP script to contain the needed info.

riwu

2012-10-27 19:47:32

From: slushpuppy
You should add a check for whether 2 colors are within a certain proximity because it just seems you are just grouping colors together without checking relations between the two

There is a pre-existing function to do such things:
FindObjTPAMulti

Also you may want to take a look at:

http://villavu.com/forum/showthread.php?t=81393&highlight=duck


or

Snippet from my own beefybill script


Huh how am i grouping colors far apart if i use SplitTPA? (and i don't see how your code checks for point proximity either, other than using SplitTPA)

And when it comes to TPA, i've yet to find any pre-existing functions in include that satisfies my needs completely. (both in obj finding and tpa walking) For instance, the function you provided: FindObjTPAMulti: does not support CTS 2, uses first point grouping (TPAtoATPA) instead of SplitTPA, does not clear my player array…
Both your function and the link you provided does not seem to have any CTS 2/3 at all, which is crucial sometimes.

IMO TPA is just too flexible such that it's hard to standardize these procedures and add to include, which is why i'm not suggesting to commit this. This is posted under SRL Snippets if you haven't realize :p


EDIT: encountered a problem: how do i get the record name? (other than creating an extra variable in the record)
Like writeln(DemonButler) will return the whole record of it, how do i make it write just 'DemonButler'?

slushpuppy

2012-10-27 22:24:49

From: riwu
Huh how am i grouping colors far apart if i use SplitTPA? (and i don't see how your code checks for point proximity either, other than using SplitTPA)

And when it comes to TPA, i've yet to find any pre-existing functions in include that satisfies my needs completely. (both in obj finding and tpa walking) For instance, the function you provided: FindObjTPAMulti: does not support CTS 2, uses first point grouping (TPAtoATPA) instead of SplitTPA, does not clear my player array…
Both your function and the link you provided does not seem to have any CTS 2/3 at all, which is crucial sometimes.

IMO TPA is just too flexible such that it's hard to standardize these procedures and add to include, which is why i'm not suggesting to commit this. This is posted under SRL Snippets if you haven't realize :p


EDIT: encountered a problem: how do i get the record name? (other than creating an extra variable in the record)
Like writeln(DemonButler) will return the whole record of it, how do i make it write just 'DemonButler'?


After I split my tpa, I still check for existence of 2 or more colors in each subtpa hence proxmity check- look at the code after //DebugATPAbounds(points);

While in your snippet, after grouping them together, you essentially went straight to the mouse uptext block without checking whether each tpa contains all the colors

Having C2 color finding is good, it might seem unnecessary given that you are searching for multiple colors-hence narrowing the field in which false positives might occurs

riwu

2012-10-27 22:47:41

From: slushpuppy
After I split my tpa, I still check for existence of 2 or more colors in each subtpa hence proxmity check- look at the code after //DebugATPAbounds(points);

While in your snippet, after grouping them together, you essentially went straight to the mouse uptext block without checking whether each tpa contains all the colors

Having C2 color finding is good, it might seem unnecessary given that you are searching for multiple colors-hence narrowing the field in which false positives might occurs

Oh, in my case it's not necessarily that the tpa cluster contains all the color.

For instance in my waterfiend script, i combine the tpa of the blue color and white color of the water rune, but sometimes other loots may cover the blue color. So as long as their combined length is higher than a certain length i would consider it a hit so i'll move mouse over to check.

So it all depends on whether you want to ensure that the tpa cluster contains all the colors in the array. And since mine don't, CTS 2 would be very useful in improving the accuracy.

slushpuppy

2012-10-28 04:24:15

From: riwu
Oh, in my case it's not necessarily that the tpa cluster contains all the color.

For instance in my waterfiend script, i combine the tpa of the blue color and white color of the water rune, but sometimes other loots may cover the blue color. So as long as their combined length is higher than a certain length i would consider it a hit so i'll move mouse over to check.

So it all depends on whether you want to ensure that the tpa cluster contains all the colors in the array. And since mine don't, CTS 2 would be very useful in improving the accuracy.


That seems like a roundabout way to solve a problem, as you can just search for the grey outline of the rune body, and not deal with the blue at all

riwu

2012-10-28 05:01:18

From: slushpuppy
That seems like a roundabout way to solve a problem, as you can just search for the grey outline of the rune body, and not deal with the blue at all

It's a water rune on mainscreen. I don't think mainscreen items lie on ground so perfectly.

slushpuppy

2012-10-28 05:23:29

From: riwu
It's a water rune on mainscreen. I don't think mainscreen items lie on ground so perfectly.


You missed my point. You shouldn't be concerned about the blue portion of the rune as the grey body will always be visible-regardless whether mainscreen items lie on the ground so perfectly or there is another item ontop of the rune.

Enslaved

2012-10-28 05:28:13

From: slushpuppy
You missed my point. You shouldn't be concerned about the blue portion of the rune as the grey body will always be visible-regardless whether mainscreen items lie on the ground so perfectly or there is another item ontop of the rune.
easy to mix up, you would need a few failsafes to stop it picking junk up

riwu

2012-10-28 06:03:20

From: slushpuppy
You missed my point. You shouldn't be concerned about the blue portion of the rune as the grey body will always be visible-regardless whether mainscreen items lie on the ground so perfectly or there is another item ontop of the rune.



Looking closer…

Which 'grey outline' would you suggest to check? :p

I think you are just arguing for the sake of arguing. Please don't hold grudge against people just because they didn't vote yes on your app. Forget injuries, never forget kindness, and you will live a happier life :)

Enslaved

2012-10-28 06:44:26

this one might work

Enslaved

2012-10-28 06:48:50

From: riwu

EDIT: encountered a problem: how do i get the record name? (other than creating an extra variable in the record)
Like writeln(DemonButler) will return the whole record of it, how do i make it write just 'DemonButler'?


Sorry for the double post, dont know how to quote in an edit,


[Main]Lol, is that a slushpuppy quote?[/Main]

Olly

2012-10-28 10:32:00

From: Enslaved
this one might work


That will not work, ground items have some crazy tolerance on them. Try it yourself log out a few times etc :p

Enslaved

2012-10-28 10:34:27

ok my bad, just trying to give it a go thats all :(