PDA

View Full Version : House/walls detector



slushpuppy
02-29-2012, 10:17 AM
I was making a harpoon and alkharid smelting script, unfortunately it was my first encounter the rather annoying inaccuracy of using SPS to determine player location-especially when you need to know whether you are properly inside the house and not just at the door for e.g.



function getPolarAngle(o,pt : TPoint) : Extended;
begin
Result := ArcTan2(o.y - pt.y, o.x - pt.x) * 180 / Pi;
end;

function inArray(search : Integer; arr : array of Integer) : Integer;
var
I : Integer;
begin
for I := 0 to High(arr) do
begin
if arr[I] = search then
begin
Result := I;
Exit;
end
end;
Result := -1;
end;

function FindHouseBounds(col,tol : Integer) : TPointArray;
var
tpa,walltpa,players : TPointArray;
atpa : Array of TPointArray;
tmp, foundIndex, I : Integer;
dist1,dist2 : Extended;
MMCTP : TPoint;
degArray : Array of Integer;
knownDegrees : Array[0..360] of Integer;
begin
SetArrayLength(walltpa,1);
SetArrayLength(degArray,1);
writeln(inttostr(Length(walltpa)));
MMCTP := Point( MMCX,MMCY );
players := GetMiniMapDots('p'); //Remove if you don't want to create player filtering.
FindColorsTolerance(tpa,col,MMX1,MMY1,MMX2,MMY2,to l);

SortTPAFrom(tpa,MMCTP);
for I := 0 to High(tpa) do
begin
tmp := floor(getPolarAngle(MMCTP,tpa[I]) / 5); // decrease 5 if splittpawrap isn't capturing bounds properly
foundIndex := inArray(tmp,degArray);
if foundIndex = -1 then
begin
walltpa[Length(walltpa) - 1] := tpa[I];
degArray[Length(degArray) - 1] := tmp;
SetArrayLength(walltpa,GetArrayLength(walltpa) + 1);
SetArrayLength(degArray,GetArrayLength(degArray) + 1);
end else
begin
dist1 := DistBetween(MMCTP,walltpa[foundIndex]);
dist2 := DistBetween(MMCTP,tpa[I]);
if dist2 < dist1 then
walltpa[foundIndex] := tpa[I];
end
end;
writeln(degArray);
SplitTPAWrap(walltpa,5,atpa);
DebugATPABounds(atpa);
Result := walltpa;
end;

Usage:

FindHouseBounds(16118766,25);


Results:
http://i.imgur.com/BEtL6.png

As you can see, it supports pretty individual houses as well as houses stacked next to each other

Go easy on me, this is like my 2nd script for simba D:

masterBB
02-29-2012, 10:33 AM
Very nice rep++

I spaced it a bit to the standards and also added three comments. Could you look at them?
function getPolarAngle(o,pt : TPoint) : Extended;
begin
Result := ArcTan2(o.y - pt.y, o.x - pt.x) * 180 / Pi;
end;

function inArray(search : Integer; arr : array of Integer) : Integer; //I believe this does the same as InIntArray
var
I : Integer;
begin
for I := 0 to High(arr) do
begin
if arr[I] = search then
begin
Result := I;
Exit;
end
end;
Result := -1;
end;

function FindHouseBounds(col,tol : Integer) : TPointArray;
var
tpa,walltpa,players : TPointArray;
atpa : Array of TPointArray;
tmp, foundIndex, I : Integer;
dist1,dist2 : Extended;
MMCTP : TPoint;
degArray : Array of Integer;
knownDegrees : Array[0..360] of Integer;
begin
SetArrayLength(walltpa,1);
SetArrayLength(degArray,1);
writeln(inttostr(Length(walltpa)));
MMCTP := Point( MMCX,MMCY );
players := GetMiniMapDots('p'); //I believe this line is not used
FindColorsTolerance(tpa,col,MMX1,MMY1,MMX2,MMY2,to l);

SortTPAFrom(tpa,MMCTP);
for I := 0 to High(tpa) do
begin
tmp := floor(getPolarAngle(MMCTP,tpa[I]) / 5); //why divided by 5?
foundIndex := inArray(tmp,degArray);
if foundIndex = -1 then
begin
walltpa[Length(walltpa) - 1] := tpa[I];
degArray[Length(degArray) - 1] := tmp;
SetArrayLength(walltpa,GetArrayLength(walltpa) + 1);
SetArrayLength(degArray,GetArrayLength(degArray) + 1);
end else
begin
dist1 := DistBetween(MMCTP,tpa[foundIndex]);
dist2 := DistBetween(MMCTP,tpa[I]);
if dist2 < dist1 then
tpa[foundIndex] := tpa[I];
end
end;
writeln(degArray);
SplitTPAWrap(walltpa,5,atpa);
DebugATPABounds(atpa);
Result := walltpa;
end;

Flight
02-29-2012, 10:52 AM
I like it, nicely done.

slushpuppy
02-29-2012, 10:53 AM
Very nice rep++

I spaced it a bit to the standards and also added three comments. Could you look at them?
function getPolarAngle(o,pt : TPoint) : Extended;
begin
Result := ArcTan2(o.y - pt.y, o.x - pt.x) * 180 / Pi;
end;

function inArray(search : Integer; arr : array of Integer) : Integer; //I believe this does the same as InIntArray
var
I : Integer;
begin
for I := 0 to High(arr) do
begin
if arr[I] = search then
begin
Result := I;
Exit;
end
end;
Result := -1;
end;

function FindHouseBounds(col,tol : Integer) : TPointArray;
var
tpa,walltpa,players : TPointArray;
atpa : Array of TPointArray;
tmp, foundIndex, I : Integer;
dist1,dist2 : Extended;
MMCTP : TPoint;
degArray : Array of Integer;
knownDegrees : Array[0..360] of Integer;
begin
SetArrayLength(walltpa,1);
SetArrayLength(degArray,1);
writeln(inttostr(Length(walltpa)));
MMCTP := Point( MMCX,MMCY );
players := GetMiniMapDots('p'); //I believe this line is not used
FindColorsTolerance(tpa,col,MMX1,MMY1,MMX2,MMY2,to l);

SortTPAFrom(tpa,MMCTP);
for I := 0 to High(tpa) do
begin
tmp := floor(getPolarAngle(MMCTP,tpa[I]) / 5); //why divided by 5?
foundIndex := inArray(tmp,degArray);
if foundIndex = -1 then
begin
walltpa[Length(walltpa) - 1] := tpa[I];
degArray[Length(degArray) - 1] := tmp;
SetArrayLength(walltpa,GetArrayLength(walltpa) + 1);
SetArrayLength(degArray,GetArrayLength(degArray) + 1);
end else
begin
dist1 := DistBetween(MMCTP,tpa[foundIndex]);
dist2 := DistBetween(MMCTP,tpa[I]);
if dist2 < dist1 then
tpa[foundIndex] := tpa[I];
end
end;
writeln(degArray);
SplitTPAWrap(walltpa,5,atpa);
DebugATPABounds(atpa);
Result := walltpa;
end;
O blasted. I didn't know inIntArray Existed at all:blink:

players := GetMiniMapDots('p');
I added that as a precaution, to filter out player dots, as player dots could interfere with the script. However I think I have forgotten to finish that precaution :duh:


//why divided by 5?

This function determines the surrounding walls by doing a 360 degree search for points that match the given color. I found that not having a divisor, the script would overmatch points that are adjacent to the room/house the player is in, especially when there are gaps(such as doors, minimap icon layouts etc).

Also, could I use your formatting to replace my original post?

masterBB
02-29-2012, 10:59 AM
Also, could I use your formatting to replace my original post?

Of course you can. I just placed a few spaces ;). Thanks for answering my questions. This is a really neat piece of code.

Azhar
03-01-2012, 10:22 AM
This guy knows what hes doing, you should app for SRL Member!