SRL Archive - Help and Support

TPA help?


Camaro'

2012-02-22 12:25:43


function FindWallBox(Click : Boolean): Boolean;
var
TPA: TPointArray;
ATPA: T2DPointArray;
I, X, Y: Integer;

TB : TBox;
begin
FindColorsTolerance(TPA, 15854581, MMX1, MMY1, MMX2, MMY2, 12);
ATPA := SplitTPAEx(TPA, 14, 19);
SortATPAFrom(ATPA, Point(MMCX, MMCY));
DebugATPABounds(ATPA);
for I := 0 to High(ATPA) do
begin
MiddleTPAEx(ATPA[i], X, Y);
TB := GetTPABounds(ATPA[i]);
writeln('w = '+tostr(tb.x2-tb.x1)+', h='+tostr(tb.y2-tb.y1)+'');
if (TB.x2 - TB.X1) < 25 then
continue;
if (TB.Y2 - TB.Y1) < 40 then
Continue;
if (PointInBox(Point(MMCX, MMCY), tb)) then
begin
Result := True;
if (Click) then
begin
Mouse(x, y, 5, 5, True);
FFlag(0);
end;
Writeln('True');
Exit;
end;
end;
end;

What i'm trying to do is detect if we are in a box (white walls on MM) but a lot of the time it its detecting things that aren't completely closed boxes. It works most of the time, but some times it will detect other things (like multiple walls close together that isn't a complete box). Can anyone give me some pointers on how I could go about writing this. Thanks.


This shows a false positive it gave me.

edit: I'm not even sure if thats debug from this function, but regardless, this function has given similar debug :)

masterBB

2012-02-22 12:36:50

I once draw it on a bitmap and then used floodfill on it, it is slow but 100% accurate.

Camaro'

2012-02-22 12:38:04

Can you explain a bit more in depth, I'm so sorry.


There is an example of it not working…
edit: I'm not even sure if thats debug from this function, but regardless, this function has given similar debug :)

masterBB

2012-02-22 12:45:38

Uhm well, you got a ATPA right? That ATPA contains a few TPAs, each of them containing one to a few walls.

You take a bitmap the size of the minimap .
Draw the TPA on it.
Use floodfill starting in the middle, since that is where the player is.
And check if it reaches the borders of the minimap, if it does then you aren't in a box.

Camaro'

2012-02-22 12:47:27

That is so genius :)

I'm going to do this. I will reply back when i have results! Thank you so much !!

masterBB

2012-02-22 12:51:04

http://villavu.com/forum/showthread.php?t=65266

not the same problem but it does got the same solution. Nava even posted some pseudocode (by that time I already made my own :) ). I'm still looking for my old code as it was in a plugin, and pretty fast.

Camaro'

2012-02-22 12:51:53

How slow do you think it would be without a plugin?

masterBB

2012-02-22 12:53:49

It's was more than a half year ago, but I believe in simba on my very very old laptop is was like 1-2 seconds. But that wasn't optimal.

Camaro'

2012-02-22 12:55:48

That's not to bad.

I never really worked with like drawing bitmaps, but I'll give it a go.

kingarabian

2012-02-22 13:57:13

I'll give it a go once i'm home.

n3ss3s

2012-02-22 16:50:47

Use SplitTPA with something like 3 dist on the wall color points, it'll exclude the one thats further away… Bitmap/Floodfill crap is obsolete here

masterBB

2012-02-22 18:29:30

But that wouldn't work on this situation:


kingarabian

2012-02-22 18:41:47

From: n3ss3s
Use SplitTPA with something like 3 dist on the wall color points, it'll exclude the one thats further away… Bitmap/Floodfill crap is obsolete here


You know how much times we tried splitting?

Edit: And Floodfill seems to be too much of a hassle for this situation.

n3ss3s

2012-02-22 20:01:31

From: kingarabian
You know how much times we tried splitting?

Edit: And Floodfill seems to be too much of a hassle for this situation.


u tried it wrong

Sin

2012-02-22 20:03:58

Dat awkward moment when you feel so stupid when reading posts of geniuses T_T

kingarabian

2012-02-22 20:15:14

From: n3ss3s
u tried it wrong


Elaborate please!

The situation with the small graveyard is that it does show as a closed square on the minimap.

Edit: I spy Bonfield :D!

Camaro'

2012-02-22 23:44:00

From: n3ss3s
Use SplitTPA with something like 3 dist on the wall color points, it'll exclude the one thats further away… Bitmap/Floodfill crap is obsolete here


ATPA := SplitTPA(TPA, 3);

If there is a player dot on the wall then that will mess that up..


masterBB

2012-02-23 04:08:07

I can write the floodfill function when I'm back from school. It doesn't matter if you will using it, just as proof of concept.

kingarabian

2012-02-23 04:49:58

From: masterBB
I can write the floodfill function when I'm back from school. It doesn't matter if you will using it, just as proof of concept.


Much appreciated.

I was looking at Nava2's code and it was a bit confusing. Just add some extra documentation please!


Thanks!

Camaro'

2012-02-23 11:47:13

From: masterBB
I can write the floodfill function when I'm back from school. It doesn't matter if you will using it, just as proof of concept.


Yeah please, In the mean time I am going to attempt to write one today. Last I tried, I made a bitmap of the minimap

I just wrote this now, didn't feel like opening simba.


var Col : integer;

FindColorsTolerance(TPA, 123456, MMX1, MMY1, MMX2, MMY2, 12);
col := Createbitmap(mmx2-mmx1, mmy2-mmy1);
drawTPABitmap(col, tpa, clRed);


This gave me :

Error: Exception: The Points you passed to DrawATPA exceed the bitmap's bounds at line 20


but I just realized I need this code

for i := High(TPA) downto 0 do // make all pts relative to origin at 1 left and up from (MMX1, MMY1)
tpa[i] := Point(tpa[i].x+1-MMX1, tpa[i].y+1-MMY1);

masterBB

2012-02-23 11:56:36

It works like this 2- 5 = 3, but the actual width is 2,3,4 and 5. So just use mmx2-mmx1+1

Also, far from finished but to give you the idea what I'm working on:
program FloodFill_ProofOfConcept;

const //I don't use full capital const.
AmountOfLines = 10;
AmountOfSquares = 4;
MaxLineLength = 35;
MinLineLength = 26;

MiniMapWidth = 154;
MiniMapCenterX = 77;
MiniMapCenterY = 77;

var
points:TPointArray;
bitmap:integer;

{
The following functions are used in setting up, they are not accounted in the
benchmarks cause your don't use them.
}

function GetWhiteLine:TPointArray;
var
lineLength:Integer;
Hor:Boolean;
i,x,y:Integer;
begin
lineLength := RandomRange(MinLineLength,MaxLineLength);
setLength(Result,lineLength);

Hor := Random(2) = 1;

x := random(MiniMapWidth);
y := random(MiniMapWidth);

for i := 0 to lineLength-1 do
begin
x := x + 1 * Integer(Hor);
y := y + 1 * Integer(not(Hor));
Result[i] := Point(x,y);
end;
end;

function GetWhiteSquare:TPointArray;
var
x,y,i,j:Integer;
width,height:Integer;
p:TPoint;
begin
x := random(MiniMapWidth);
y := random(MiniMapWidth);

width := RandomRange(MinLineLength,MaxLineLength);
height := RandomRange(MinLineLength,MaxLineLength);

setLength(Result, (width)*2 + (height)*2);

for i := 0 to width-1 do
begin
Result[i] := Point(x+i,y);
Result[i+width] := Point(x+i,y+height);
end;

for i := 0 to height-1 do
begin
Result[i+(width*2)] := Point(x,y+i);
Result[i+height+(width*2)] := Point(x+width,y+i);
end;
end;

function GetRandomWhiteLines:TPointArray;
var
i:Integer;
begin
for i := 0 to AmountOfLines do
Result := CombineTPA(Result,GetWhiteLine);

for i := 0 to AmountOfSquares do
Result := CombineTPA(Result,GetWhiteSquare);
end;

{
The following function uses the FloodFillTPA method
}
function InBoxByFloodFillTPA(TPA:TPointArray):Boolean;
var
i:Integer;
box:TBox;
ATPA:T2DPointArray;
TPA2:TPointArray;
begin
wait(200);
box.X1 := 0;
box.Y1 := 0;
box.X2 := MiniMapWidth+1;
box.Y2 := MiniMapWidth+1;
TPA2 := ReturnPointsNotInTPA(TPA,box); //Sometimes returns: Error: Exception:
//Invalid pointer operation
ATPA := FloodFillTPA(TPA2);

for i := 0 to High(ATPA) do
if PointInTPA(Point(MinimapCenterX,MiniMapCenterY),ATPA[i]) then
begin
Result := PointInTPA(Point(0,0),ATPA[i]);
DrawTPABitmap(bitmap,ATPA[i],clRed);
DrawBitmapDebugImg(bitmap);
end;
end;

begin
//Set up
points := GetRandomWhiteLines;
FilterPointsDist(points,0,MiniMapWidth/2,MiniMapCenterX,MinimapCenterY);
bitmap := CreateBitmap(MiniMapWidth+2,MiniMapWidth+2);
DrawTPABitmap(bitmap,points,clWhite);

//Debug
DisplayDebugImgWindow(MiniMapWidth+2,MiniMapWidth+2);
DrawBitmapDebugImg(bitmap);

//FloodFillTPA
writeln('Are your free to run around? : ' + ToStr(InBoxByFloodFillTPA(points)));

FreeBitmap(bitmap);
end.

edit:
Got to go, maybe I find some hours in the evening to work on it.

Camaro'

2012-02-23 12:38:42

Combining your code, and fixing up my code. I got a function that debugs everything as we want it ( I suppose ).

If there is an enclosed box, it will flood only inside the box, or else it does the whole minimap.


I need two things though, for starters we need it so if there is a small gap in the box, we need it to fill that gap.

Like if the wall is not closed fully.

masterBB

2012-02-23 13:16:30

With the method I posted it isn't possible.

Camaro'

2012-02-23 13:19:36

Here is what I have ATM:

http://pastebin.com/gW5Smdxi

or


var
bitmap:integer;
const
MiniMapWidth = 154;
MiniMapCenterX = 77;
MiniMapCenterY = 77;

function InBoxByFloodFillTPA(TPA:TPointArray):Boolean;
var
i:Integer;
box:TBox;
ATPA:T2DPointArray;
TPA2:TPointArray;
begin
wait(200);
box.X1 := 0;
box.Y1 := 0;
box.X2 := MiniMapWidth+1;
box.Y2 := MiniMapWidth+1;
TPA2 := ReturnPointsNotInTPA(TPA,box); //Sometimes returns: Error: Exception:
//Invalid pointer operation
ATPA := FloodFillTPA(TPA2);

for i := 0 to High(ATPA) do
if PointInTPA(Point(MinimapCenterX,MiniMapCenterY),ATPA[i]) then
begin
Result := PointInTPA(Point(0,0),ATPA[i]);
DrawTPABitmap(bitmap,ATPA[i],clRed);
DrawBitmapDebugImg(bitmap);
end;
end;

function InGraveFlood: Boolean;
var TPA,tpa2,tpa3,tpa4: TPointArray;
i: Integer;
begin

FindColorsTolerance(TPA, 16185593 , MMX1, MMY1, MMX2, MMY2, 25); //wall
FindColorsTolerance(TPA2, 460262 , MMX1, MMY1, MMX2, MMY2, 25); //red door
FindColorsTolerance(TPA4, 255472, MMX1, MMY1, MMX2, MMY2, 25); //yellow npc
tpa := combineTPA(Tpa,tpa2);
tpa := combineTPA(tpa4, tpa);
for i := High(TPA) downto 0 do // make all pts relative to origin at 1 left and up from (MMX1, MMY1)
tpa[i] := Point(tpa[i].x+1-MMX1, tpa[i].y+1-MMY1);


FilterPointsDist(TPA,0,MiniMapWidth/2,MiniMapCenterX,MiniMapCenterY);
writeln('length '+tostr(length(Tpa))+'');
bitmap := CreateBitmap(MiniMapWidth+2,MiniMapWidth+2);

DrawTPABitmap(bitmap,tpa,clWhite);


writeln(inboxbyfloodfilltpa(tpa));
//Debug
DisplayDebugImgWindow(MiniMapWidth+2,MiniMapWidth+2);
DrawBitmapDebugImg(bitmap);

freebitmap(bitmap);

end;



For some reason it stopped drawing the red fill just recently, I don't know why. Oh and I'm testing this else where from before, but it shouldn't matter.

I put those extra tpa's in there to fill up any extra spots missing in the box (although runescape sometimes automatically makes the box incomplete.)

masterBB

2012-02-23 13:25:05

You should remove wait(200); cause I only placed it there when it was running in a loop.

Could look into it this evening. Will pm you before I start.

Camaro'

2012-02-23 13:25:55

Yeah I'm going to now, Just not quite sure on why the fill stopped filling (lol).

I think it happened after i added the npc tpa but I'm not sure.

Edit:


Is there any way to fix that? Those gaps aren't usually there, they just appear at random times.

Edit: Script I am using I posted on page 1.

masterBB

2012-02-23 13:35:20

I have an idea. Put a rectangle inside it. enlarge it till it hits the white walls. If the size of the space is x, it is in the room? Also why didn't you used a SPS like bitmap of the area above it?

Camaro'

2012-02-23 13:37:02

I'm going to attempt that, and you mean use something similar to SPS?

I don't know, I never really used SPS before.

masterBB

2012-02-23 14:01:13

Would make it so much easier… Well it was fun ^^, I really need that master cup :P

Camaro'

2012-02-23 14:09:25

From: masterBB
Would make it so much easier… Well it was fun ^^, I really need that master cup :P


Yeah, It works most of the time with what you said with some changes.

masterBB

2012-02-25 15:42:52

How did this work out?

Camaro'

2012-02-25 16:26:21

I couldn't get anything reliable enough.

Home

2012-02-25 16:51:59

[QUOTE=Camaro';942102]I couldn't get anything reliable enough.

I would go with SplitTPA and use some other functions to Remove TPA's from TPA (Distance, Other Colors, Size) It should do the trick.


~Home

Camaro'

2012-02-25 17:37:43

From: Home
I would go with SplitTPA and use some other functions to Remove TPA's from TPA (Distance, Other Colors, Size) It should do the trick.


~Home


I used a lot on my old function. Still gave me false positives.

I'd hate to use SPS for this, but seems to be my only chose.

masterBB

2012-02-25 22:41:04

SPS is nothing more than taking the map as a bitmap, split it in several smaller bitmaps, search for those and based on there positions retrieve your position. You can achieve much better results with (d)dtms and hand made bitmaps. I was aware that the floodfill function would probably be overkill, but I like to experiment with it.

Camaro'

2012-02-26 01:46:22

From: masterBB
SPS is nothing more than taking the map as a bitmap, split it in several smaller bitmaps, search for those and based on there positions retrieve your position. You can achieve much better results with (d)dtms and hand made bitmaps. I was aware that the floodfill function would probably be overkill, but I like to experiment with it.


Yeah I know, I may try making a few bitmaps later and see how they work out.

n3ss3s

2012-02-26 14:39:39

I might be wrong but I'm 99% sure that the player dots either don't have 16777215 at all or only one dot, so you could exclude non-wall points by checking if they don't have a second 16777215-white connected to them…

Camaro'

2012-02-26 14:45:57

Well 16777215 isn't always the wall color, but from what I gathered from your post is that the whatever the wall color is, it can appear no more then once in any player dot. Or am I misunderstanding something?

n3ss3s

2012-02-26 16:20:18

Well that's just a guess but I'm 99.99% sure that there is a const color (16777215) that appears in the white dots only once, and I thought (guess they changed it or..?) that it's the only wall color

Camaro'

2012-02-26 17:57:55

Yeah the wall color changes now.