SRL Archive - OSR Help

Best way to Find a Fairy ring EOC


King

2013-04-02 23:31:14

Ive tried TPA ect, and Im not getting it accurate enough, also tried DTMS and rotating them ?: Ideas, I need to find this

accurately and reliably

@Ashaman88
@Sin
@Flight

Any ideas?

tealc

2013-04-02 23:34:00

ATPA's with a decent amount of math/filtering

edit: try messing with these functions http://villavu.com/forum/showthread.php?t=49067

King

2013-04-02 23:36:20

From: tealc
ATPA's with a decent amount of math/filtering


I was thinking that I could maybe search for the top of the Fairy ring buds, filter it from the mainscreen and make that a ATPA and the search that ATPA for a certain amount of the color in the very middle of the ring..

Ashaman88

2013-04-02 23:39:48

Dtms would be a no no here… I would try different tpas/atpas functions and such. Can you get the ring on ms reliably?

King

2013-04-02 23:43:28

From: Ashaman88
Dtms would be a no no here… I would try different tpas/atpas functions and such. Can you get the ring on ms reliably?


I can get the ring on the MS almost everytime, if not, then a simple camera rotation will make sure it is always visible, Im going to try playing with ATPAS/TPAS more, Ill post results and possibly a function to find them!

Flight

2013-04-02 23:44:06

I've a question: where in this ring do you click to interact with it? Will any one of the rings work? Or can you also click in the middle, not on a ring at all, and still interact with it?

King

2013-04-02 23:45:59

From: Flight
I've a question: where in this ring do you click to interact with it? Will any one of the rings work? Or can you also click in the middle, not on a ring at all, and still interact with it?


You have to click on or inside the very middle ring to interact with it, all the other areas are just for show :P

Flight

2013-04-02 23:50:18

From: SRLKing
You have to click on or inside the very middle ring to interact with it, all the other areas are just for show :P


Good good. If that's the case I'll use my newest object-finding functions from Herb-Farmer to find rings. It's quite intelligent how it works. Give me a little while and I'll play around with it.

King

2013-04-02 23:57:01

From: Flight
Good good. If that's the case I'll use my newest object-finding functions from Herb-Farmer to find rings. It's quite intelligent how it works. Give me a little while and I'll play around with it.


Okay, Im off to bed :P

midnight here, I would love to see how it works/learn from it (I cant use it as Im applying with this script and want to write it all myself :P) However I can always benefit from reading your work :spot:

Flight

2013-04-03 00:58:16

Ok here it is. It's shaved down from the original version used to find patches in my Herb-Farmer but I tested it at all angles, the middle of the fairy rings was found every time.


{$I SRL/SRL.Simba}

//By Flight for shape-related finding routines. Useful for dynamic box/circle objects
Function FoundBoxfromTPA(Pnt: TPoint; Pnts: TPointArray; Tol,Offset: Integer; var Box: TBox): Boolean;
var
i: Integer;
lPnts: TPointArray;
pV1,pV2,pV3,pV4: Boolean;
begin
Result := False;

//Check low X axis
lPnts := TPABetweenPoints(Point(Pnt.X-Tol,Pnt.Y), Point(Pnt.X-Offset,Pnt.Y), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV1 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV1 then
begin
Box.X1 := lPnts[i].X;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

//Check high X axis
lPnts := TPABetweenPoints(Point(Pnt.X+Tol,Pnt.Y), Point(Pnt.X+Offset,Pnt.Y), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV2 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV2 then
begin
Box.X2 := lPnts[i].X;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

//Check low Y axis
lPnts := TPABetweenPoints(Point(Pnt.X,Pnt.Y-Tol), Point(Pnt.X,Pnt.Y-Offset), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV3 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV3 then
begin
Box.Y1 := lPnts[i].Y;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

//Check high Y axis
lPnts := TPABetweenPoints(Point(Pnt.X,Pnt.Y+Tol), Point(Pnt.X,Pnt.Y+Offset), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV4 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV4 then
begin
Box.Y2 := lPnts[i].Y;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

Result := ((Box.X2 > 0) and (Box.Y2 > 0));
end;

Function FoundRing(var Pnt: TPoint): Boolean;
var
RingBox,pBox: TBox;
CTS,i: Integer;
rPntsB: T2DPointArray;
rPnts1,mPnts: TPointArray;
begin
if not LoggedIn then
Exit;

CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);

SetColorSpeed2Modifiers(0.11, 4.59);
FindColorsSpiralTolerance(MSCX, MSCY, rPnts1, 14408945, MSX1, MSY1, MSX2, MSY2, 7);
ColorToleranceSpeed(CTS);
SetColorSpeed2Modifiers(0.2, 0.2);

if (Length(rPnts1) < 30) then
Exit;

SortTPAFrom(rPnts1, Point(MSCX,MSCY));
ClearDoubleTPA(rPnts1);

//TPAtoATPAExWrap(rPnts1, 74, 70, rPntsB);
SplitTPAExWrap(rPnts1, 74, 70, rPntsB);
SortATPAFromFirstPoint(rPntsB, Point(MSX1,MSCY));
SortATPASize(rPntsB, True);

for i:=0 to High(rPntsB) do
begin
pBox := GetTPABounds(rPntsB[i]);
SetArrayLength(mPnts, Length(mPnts)+1);
mPnts[High(mPnts)] := MiddleTPA(rPntsB[i]);
end;

for i:=0 to High(mPnts) do
begin
Result := FoundBoxfromTPA(mPnts[i], rPnts1, 70, 10, RingBox);
if Result then
begin
Pnt := MiddleBox(RingBox);
Break;
end;
end;
end;

Var
thePnt: TPoint;

begin
SetupSRL;
if FoundRing(thePnt) then
MMouse(thePnt.X, thePnt.Y, 3, 3);
end.

King

2013-04-03 01:01:40

From: Flight
Ok here it is. It's shaved down from the original version used to find patches in my Herb-Farmer but I tested it at all angles, the middle of the fairy rings was found every time.


{$I SRL/SRL.Simba}

//By Flight for shape-related finding routines. Useful for dynamic box/circle objects
Function FoundBoxfromTPA(Pnt: TPoint; Pnts: TPointArray; Tol,Offset: Integer; var Box: TBox): Boolean;
var
i: Integer;
lPnts: TPointArray;
pV1,pV2,pV3,pV4: Boolean;
begin
Result := False;

//Check low X axis
lPnts := TPABetweenPoints(Point(Pnt.X-Tol,Pnt.Y), Point(Pnt.X-Offset,Pnt.Y), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV1 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV1 then
begin
Box.X1 := lPnts[i].X;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

//Check high X axis
lPnts := TPABetweenPoints(Point(Pnt.X+Tol,Pnt.Y), Point(Pnt.X+Offset,Pnt.Y), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV2 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV2 then
begin
Box.X2 := lPnts[i].X;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

//Check low Y axis
lPnts := TPABetweenPoints(Point(Pnt.X,Pnt.Y-Tol), Point(Pnt.X,Pnt.Y-Offset), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV3 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV3 then
begin
Box.Y1 := lPnts[i].Y;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

//Check high Y axis
lPnts := TPABetweenPoints(Point(Pnt.X,Pnt.Y+Tol), Point(Pnt.X,Pnt.Y+Offset), 5, 0);
SortTPAFrom(lPnts, Pnt);
for i:=0 to High(lPnts) do
begin
pV4 := NearbyPointInArray(lPnts[i], 5, Pnts);
if pV4 then
begin
Box.Y2 := lPnts[i].Y;
break;
end;
if (i=High(lPnts)) then
Exit;
end;

Result := ((Box.X2 > 0) and (Box.Y2 > 0));
end;

Function FoundRing(var Pnt: TPoint): Boolean;
var
RingBox,pBox: TBox;
CTS,i: Integer;
rPntsB: T2DPointArray;
rPnts1,mPnts: TPointArray;
begin
if not LoggedIn then
Exit;

CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);

SetColorSpeed2Modifiers(0.11, 4.59);
FindColorsSpiralTolerance(MSCX, MSCY, rPnts1, 14408945, MSX1, MSY1, MSX2, MSY2, 7);
ColorToleranceSpeed(CTS);
SetColorSpeed2Modifiers(0.2, 0.2);

if (Length(rPnts1) < 30) then
Exit;

SortTPAFrom(rPnts1, Point(MSCX,MSCY));
ClearDoubleTPA(rPnts1);

//TPAtoATPAExWrap(rPnts1, 74, 70, rPntsB);
SplitTPAExWrap(rPnts1, 74, 70, rPntsB);
SortATPAFromFirstPoint(rPntsB, Point(MSX1,MSCY));
SortATPASize(rPntsB, True);

for i:=0 to High(rPntsB) do
begin
pBox := GetTPABounds(rPntsB[i]);
SetArrayLength(mPnts, Length(mPnts)+1);
mPnts[High(mPnts)] := MiddleTPA(rPntsB[i]);
end;

for i:=0 to High(mPnts) do
begin
Result := FoundBoxfromTPA(mPnts[i], rPnts1, 70, 10, RingBox);
if Result then
begin
Pnt := MiddleBox(RingBox);
Break;
end;
end;
end;

Var
thePnt: TPoint;

begin
SetupSRL;
if FoundRing(thePnt) then
MMouse(thePnt.X, thePnt.Y, 3, 3);
end.


o.0 That is a beautiful function, I am definitely going to read over this some more and hopefully use something like this in my script, I love how it checks the highs and lows, I think I might be able to modify my current one to check the area bit more like yours and have it be good(: Thanks flight! Can't rep, need to spread it around ;(

superuser

2013-04-03 05:18:21

You can also use my surfaces system to accurately find the ring from any angle.

Here's the script (you can download the include from the link):

program surfaces_fairyring;

{$DEFINE SMART}

{$i srl\srl.simba}
{$i srl\srl\misc\SmartGraphics.simba}

{$i su_surfaces.simba}

var
obj_fairyring: TSurfaceObject;

procedure Init();
begin
SetupSRL();
SMART_ClearMS();

CreateSurfaceParts(obj_fairyring, 2);

with obj_fairyring do begin
parts[0].c := 4817795;
parts[0].hm := 0.03;
parts[0].sm := 0.09;
parts[0].t := 12;
parts[0].minw := 50;
parts[0].maxw := 160;
parts[0].minh := 50;
parts[0].maxh := 160;
parts[0].step := 32;
parts[0].max_distance := 999;

parts[1].c := 14213871;
parts[1].hm := 0.91
parts[1].sm := 3.94;
parts[1].t := 8;
parts[1].filter := @SurfaceFilterClosest; // We want to have the closest fairy ring next to us.
parts[1].minw := 10;
parts[1].maxw := parts[0].maxw;
parts[1].minh := 10;
parts[1].maxh := parts[0].maxh;
parts[1].step := 32;
parts[1].max_distance := parts[0].max_distance;

name := 'Fairy ring';
uptext := 'Fairy';
filter := @SurfaceFilterClosest;
end;
end;

begin
Init();

if FindSurfaceObject(obj_fairyring, MSX1, MSY1, MSX2, MSY2) then begin
WriteLn('Found fairy ring at ' + IntToStr(obj_fairyring.p.x) + ', ' + IntToStr(obj_fairyring.p.y));
end;
end.

Here's a few screenshots of it at action:


King

2013-04-05 11:27:34

From: superuser
You can also use my surfaces system to accurately find the ring from any angle.

Here's the script (you can download the include from the link):

program surfaces_fairyring;

{$DEFINE SMART}

{$i srl\srl.simba}
{$i srl\srl\misc\SmartGraphics.simba}

{$i su_surfaces.simba}

var
obj_fairyring: TSurfaceObject;

procedure Init();
begin
SetupSRL();
SMART_ClearMS();

CreateSurfaceParts(obj_fairyring, 2);

with obj_fairyring do begin
parts[0].c := 4817795;
parts[0].hm := 0.03;
parts[0].sm := 0.09;
parts[0].t := 12;
parts[0].minw := 50;
parts[0].maxw := 160;
parts[0].minh := 50;
parts[0].maxh := 160;
parts[0].step := 32;
parts[0].max_distance := 999;

parts[1].c := 14213871;
parts[1].hm := 0.91
parts[1].sm := 3.94;
parts[1].t := 8;
parts[1].filter := @SurfaceFilterClosest; // We want to have the closest fairy ring next to us.
parts[1].minw := 10;
parts[1].maxw := parts[0].maxw;
parts[1].minh := 10;
parts[1].maxh := parts[0].maxh;
parts[1].step := 32;
parts[1].max_distance := parts[0].max_distance;

name := 'Fairy ring';
uptext := 'Fairy';
filter := @SurfaceFilterClosest;
end;
end;

begin
Init();

if FindSurfaceObject(obj_fairyring, MSX1, MSY1, MSX2, MSY2) then begin
WriteLn('Found fairy ring at ' + IntToStr(obj_fairyring.p.x) + ', ' + IntToStr(obj_fairyring.p.y));
end;
end.

Here's a few screenshots of it at action:




I think I will be using this, all credit to you of course(:

superuser

2013-04-05 12:52:46

From: SRLKing
I think I will be using this, all credit to you of course(:


Please, be my guest :)

King

2013-04-05 13:01:35

From: superuser
Please, be my guest :)


I really hope you can get this put in the offical SRL includes, it is absolutely amazing how accurate I was able to get it, works with people in the ring, fairies and the other creatures over it as well. I really think you should talk to a admin/someone who can get this pulled in the official SRL include as it is extremely useful and provides almost a reflection like way of identifying objects. So a huge thanks to you<3