PDA

View Full Version : Vectors (AeroLib and Reflection)



Immortan
01-10-2016, 03:17 PM
I was just wondering, what's the best way to create a vector (containing coordinates in the world) to mark down a area in RS (With or without using Aerolib)? Also, what would be the best way to detect if a character is within this vector, using whatever suggested method.

I would like to use this for a lot of my potential scripts (miner, fisher, etc).

Kyle
01-10-2016, 03:44 PM
Uh, not sure if you understand what a vector is? It's something with magnitude and direction. Usually used in force type problems/equations.. So I'm not sure what you are asking

Immortan
01-10-2016, 03:52 PM
Uh, not sure if you understand what a vector is? It's something with magnitude and direction. Usually used in force type problems/equations.. So I'm not sure what you are asking

Oh, I am talking about like a list of points that could be used to designate an area in RS. I get that, that's the definition for like physics and math, but I am using the CS definition which states that it is simply an array. Anyways, sorry for the confusion.

Actually, I just realized that I just tried to use both definitions simultaneously, which just caused confusion.

honeyhoney
01-10-2016, 03:55 PM
Oh, I am talking about like a list of points that could be used to designate an area in RS. I get that, that's the definition for like physics and math, but I am using the CS definition which states that it is simply an array.

Uhh... coordinates? :p

If you're not using reflection take a look at RSWalker (https://villavu.com/forum/showthread.php?t=111914) for determining your position on the worldmap.

Reflection has walking built into the include. Explore it here: https://github.com/Elfyyy/OSR-Reflection
You'll likely be most interested in:
https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/internal/Mapwalk.simba
https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/core/renderable/LocalPlayer.simba
https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/core/Tile.simba

Immortan
01-10-2016, 04:04 PM
Uhh... coordinates? :p

If you're not using reflection take a look at RSWalker (https://villavu.com/forum/showthread.php?t=111914) for determining your position on the worldmap.

Reflection has walking built into the include. Explore it here: https://github.com/Elfyyy/OSR-Reflection
You'll likely be most interested in:
https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/internal/Mapwalk.simba
https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/core/renderable/LocalPlayer.simba
https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/core/Tile.simba

This may be something I can use (able to calculate location of character). What I am mainly looking for, is something that can mark say a 4 x 4 location and be able check if the the player entity is within that area, and perhaps some other entities.

honeyhoney
01-10-2016, 04:08 PM
This may be something I can use (able to calculate location of character). What I am mainly looking for, is something that can mark say a 4 x 4 location and be able check if the the player entity is within that area, and perhaps some other entities.

Once you've got the position of your player (ie. the coordinates) you can then calculate whether this position is within an area.

Coordinates are stored as the TPoint data type.
You can define an area using two TPoints (top left of the area, bottom right of the area). This area is stored as a TBox data type.
There is a function in Simba called PointInBox that returns true/false depending on whether the point is within the box.

As I said, to define a TBox you need two TPoints. You can just check the position of your player at both of these points to get these.

Immortan
01-10-2016, 04:13 PM
Once you've got the position of your player (ie. the coordinates) you can then calculate whether this position is within an area.

Coordinates are stored as the TPoint data type.
You can define an area using two TPoints (top left of the area, bottom right of the area). This area is stored as a TBox data type.
There is a function in Simba called PointInBox that returns true/false depending on whether the point is within the box.

As I said, to define a TBox you need two TPoints. You can just check the position of your player at both of these points to get these.

What about irregular shapes? What would be most efficient here? An idea that comes to mind is to just create multiple TBox objects and designate that as the same area, but would this be efficient? I'll look into the libraries anyhow.

honeyhoney
01-10-2016, 04:20 PM
What about irregular shapes? What would be most efficient here? An idea that comes to mind is to just combine TBox objects and designate that as one area, but would this be efficient? I'll look into the libraries anyhow.

Checking if a point is in a polygon is a super interesting problem that a lot of people come up against :)
Give this a read: https://en.wikipedia.org/wiki/Point_in_polygon

Most people tend to stick to TBoxes (including combining a few as you suggested) for their areas. For our purpose you can generally get away with rectangular search areas. Of course the results using a TBox over a polygon are approximate, but again, generally accurate enough for our needs.

Edit: completely forgot about this but as Harrier mentions, take a look at SimbaExt (an include that provides some additional functions) and you can find implementations of the algorithms discussed in the wikipedia article above.


{*
Check if a point is within a polygon/shape by the given outline points (poly)
The points must be in order, as if you would draw a line trough each point.
@note: Ray casting combined with Winding number algorithm
*}
function InPoly(x,y:Integer; const Poly:TPointArray): Boolean; Inline;
var
WN,H,i,j:Integer;
RC:Boolean;
begin
WN := 0;
H := High(poly);
j := H;
RC := False;
for i:=0 to H do begin
if ((Poly[i].x = x) and (Poly[i].y = y)) then
Exit(True);
if ((poly[i].y < y) and (poly[j].y >= y) or (poly[j].y < y) and (poly[i].y >= y)) then
if (poly[i].x+(y-poly[i].y) / (poly[j].y-poly[i].y) * (poly[j].x-poly[i].x) < x) then
RC := Not(RC);
if (poly[i].y <= y) then begin
if (poly[j].y > y) then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) > 0) then
Inc(WN);
end else
if poly[j].y <= y then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) < 0) then
Dec(WN);
j := i;
end;
Result := (WN <> 0) or (rc);
end;


{*
Check if a point is within a polygon/shape by the given outline points (poly)
The points must be in order, as if you would draw a line trough each point.
@note: Ray casting algorithm
*}
function InPolyR(x,y:Integer; const Poly:TPointArray): Boolean; Inline;
var j,i,H: Integer;
begin
H := High(poly);
j := H;
Result := False;
for i:=0 to H do begin
if ((poly[i].y < y) and (poly[j].y >= y) or (poly[j].y < y) and (poly[i].y >= y)) then
if (poly[i].x+(y-poly[i].y) / (poly[j].y-poly[i].y) * (poly[j].x-poly[i].x) < x) then
Result := not(Result);
j := i;
end;
end;


{*
Check if a point is within a polygon/shape by the given outline points (poly)
The points must be in order, as if you would draw a line trough each point.
@note: Winding number algorithm
*}
function InPolyW(x,y:Integer; const Poly:TPointArray): Boolean; Inline;
var
wn,H,i,j:Integer;
begin
wn := 0;
H := High(poly);
j := H;
for i:=0 to H do begin
//if ((Poly[i].x = x) and (Poly[i].y = y)) then
// Exit(True);
if (poly[i].y <= y) then begin
if (poly[j].y > y) then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) > 0) then
Inc(wn);
end else
if poly[j].y <= y then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) < 0) then
Dec(wn);
j := i;
end;
Result := (wn <> 0);
end;
Source: https://github.com/WarPie/SimbaExt/blob/37416bbbc16343a5789c18857450848b5057d297/DLL%20Source/SimbaExt/src/Core/CoreMath.pas

Harrier
01-10-2016, 04:21 PM
What about irregular shapes? What would be most efficient here? An idea that comes to mind is to just create multiple TBox objects and designate that as the same area, but would this be efficient? I'll look into the libraries anyhow.

Look at SimbaEx

Immortan
01-10-2016, 04:32 PM
Checking if a point is in a polygon is a super interesting problem that a lot of people come up against :)
Give this a read: https://en.wikipedia.org/wiki/Point_in_polygon

Most people tend to stick to TBoxes (including combining a few as you suggested) for their areas. For our purpose you can generally get away with rectangular search areas. Of course the results using a TBox over a polygon are approximate, but again, generally accurate enough for our needs.

Alright, I am okay with the idea using 1 or 2 Tbox objects for my areas. I'll stick with this.

honeyhoney
01-10-2016, 04:37 PM
Alright, I am okay with the idea using 1 or 2 Tbox objects for my areas. I'll stick with this.

Keeping it simple is a great way to start. If you find you need more specific search bounds then you can revisit this thread :)

Immortan
01-10-2016, 04:41 PM
Checking if a point is in a polygon is a super interesting problem that a lot of people come up against :)
Give this a read: https://en.wikipedia.org/wiki/Point_in_polygon

Most people tend to stick to TBoxes (including combining a few as you suggested) for their areas. For our purpose you can generally get away with rectangular search areas. Of course the results using a TBox over a polygon are approximate, but again, generally accurate enough for our needs.

Edit: completely forgot about this but as Harrier mentions, take a look at SimbaExt (an include that provides some additional functions) and you can find implementations of the algorithms discussed in the wikipedia article above.


{*
Check if a point is within a polygon/shape by the given outline points (poly)
The points must be in order, as if you would draw a line trough each point.
@note: Ray casting combined with Winding number algorithm
*}
function InPoly(x,y:Integer; const Poly:TPointArray): Boolean; Inline;
var
WN,H,i,j:Integer;
RC:Boolean;
begin
WN := 0;
H := High(poly);
j := H;
RC := False;
for i:=0 to H do begin
if ((Poly[i].x = x) and (Poly[i].y = y)) then
Exit(True);
if ((poly[i].y < y) and (poly[j].y >= y) or (poly[j].y < y) and (poly[i].y >= y)) then
if (poly[i].x+(y-poly[i].y) / (poly[j].y-poly[i].y) * (poly[j].x-poly[i].x) < x) then
RC := Not(RC);
if (poly[i].y <= y) then begin
if (poly[j].y > y) then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) > 0) then
Inc(WN);
end else
if poly[j].y <= y then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) < 0) then
Dec(WN);
j := i;
end;
Result := (WN <> 0) or (rc);
end;


{*
Check if a point is within a polygon/shape by the given outline points (poly)
The points must be in order, as if you would draw a line trough each point.
@note: Ray casting algorithm
*}
function InPolyR(x,y:Integer; const Poly:TPointArray): Boolean; Inline;
var j,i,H: Integer;
begin
H := High(poly);
j := H;
Result := False;
for i:=0 to H do begin
if ((poly[i].y < y) and (poly[j].y >= y) or (poly[j].y < y) and (poly[i].y >= y)) then
if (poly[i].x+(y-poly[i].y) / (poly[j].y-poly[i].y) * (poly[j].x-poly[i].x) < x) then
Result := not(Result);
j := i;
end;
end;


{*
Check if a point is within a polygon/shape by the given outline points (poly)
The points must be in order, as if you would draw a line trough each point.
@note: Winding number algorithm
*}
function InPolyW(x,y:Integer; const Poly:TPointArray): Boolean; Inline;
var
wn,H,i,j:Integer;
begin
wn := 0;
H := High(poly);
j := H;
for i:=0 to H do begin
//if ((Poly[i].x = x) and (Poly[i].y = y)) then
// Exit(True);
if (poly[i].y <= y) then begin
if (poly[j].y > y) then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) > 0) then
Inc(wn);
end else
if poly[j].y <= y then
if (((poly[j].x-poly[i].x)*(y-poly[i].y)-(x-poly[i].x)*(poly[j].y-poly[i].y)) < 0) then
Dec(wn);
j := i;
end;
Result := (wn <> 0);
end;
Source: https://github.com/WarPie/SimbaExt/blob/37416bbbc16343a5789c18857450848b5057d297/DLL%20Source/SimbaExt/src/Core/CoreMath.pas

Thanks for all the info! This seems to be all I need.

Laquisha
01-10-2016, 10:07 PM
Thanks for all the info! This seems to be all I need.

This is already in the reflection include so you don't need any additional code: https://github.com/Elfyyy/OSR-Reflection/blob/master/lib/core/Tile.simba#L90

AFools
01-10-2016, 11:17 PM
There is a cheap and nasty way, not exactly what you asked. it may help or be food for thought.

Reflect.Tiles.DistanceFromTile(Point(3333, 4444)) < 10;

Should you be within less the '10' squares from the target. You can pick a middle point, i have seen polygon used for NPC inside an area, but i'm not sure about the character.

You can always use and statement to attack multiple of these., but at that point it is too complicated and you should probabbly try learn polygons.

the bank
01-11-2016, 03:05 AM
Uh, not sure if you understand what a vector is? It's something with magnitude and direction. Usually used in force type problems/equations.. So I'm not sure what you are asking

I think he's referencing a vector in the way they are used in C++ and some other native languages. Its essentially a List. An array with added functionality.