AeroLibrary - Core functionality
Welcome to the introduction to basic types & routines of AeroLib. While getting to know this library and writing scripts may be much different than you're used to, chances are you'll find it much easier to use as opposed to the pascal version of SRL-OSR. So let's jump into it and get acquainted with AL.
TColEx
[AeroLib > core > engine > Color.simba]
TColEx is at the very core of AeroLib, the life blood if you will. This little guy is a package containing a color, color tolerance and the hue & saturation modifiers, which are optional. This type completely replaces normal color-finding routines that you're used to. The basic idea is from Janilabo's TColorSetting work, with the same concept in mind but simplified, automated and Lape-styled.
Code:
Type TColEx = record
Col : Integer;
Tol : Integer;
hMod : Extended;
sMod : Extended;
end;
- Col : The main color you'll be searching for.
- Tol : The tolerance of the color.
- hMod: Hue modifier of a CTS2 (Color tolerance speed 2) based color. (Optional)
- sMod: Saturation modifier of a CTS2 (Color tolerance speed 2) based color. (Optional)
Simba Code:
procedure TColEx.create(_Col, _Tol: Integer; _hMod, _sMod: Extended);
procedure TColEx.create(_Col, _Tol: Integer); overload;
function createCol(_Col, _Tol: Integer; _hMod, _sMod: Extended): TColEx;
function createCol(_Col, _Tol: Integer): TColEx; overload;
These four functions will accomplish the same thing: create & store a TColEx that you can use later. While the first two will be used like this:
Simba Code:
// Define your TColEx
color_White : TColEx;
color_White.create(15660260, 10, 1.26, 0.03); // Automatically becomes a CTS2-based color
or
color_White.create(15660260, 10);
Whereas the other two functions, while accomplishing the same, are used slightly different:
Simba Code:
// Define your TColEx
color_White : TColEx;
color_White := createCol(15660260, 10, 1.26, 0.03); // Automatically becomes a CTS2-based color
or
color_White := createCol(15660260, 10);
Now your color is created & stored and ready to be used.
Simba Code:
function TColEx.findIn(Area: TBox; var Point: TPoint): Boolean;
function TColEx.findIn(Area: TBox): Boolean; overload;
These two functions will tell you if a TColEx is found in an area, defined by a TBox. A helpful hint to keep in mind here is that AeroLib has a few predefined areas, such as:
- AREA_MS (your mainscreen)
- AREA_MM (your minimap)
- AREA_INV (your inventory/all game tabs)
The first function will tell you if the TColEx is found in an area as well as give you the first point at which it's found. The second function will only tell you if it's found in the area or not.
Simba Code:
procedure ColorTest();
var
color_White : TColEx;
foundPnt : TPoint;
begin
color_White.create(15660260, 10, 1.26, 0.03);
if color_White.findIn(AREA_MM, foundPnt) then
writeln('Found white on the minimap at '+toStr(foundPnt));
end;
You'll noticed I used a TColEx that contains a hMod/sMod. Whenever a TColEx containing a hMod and/or sMod is searched for, Simba's CTS is automatically temporarily switched to 2 and when the function has finished its search, the CTS will be returned to whatever it was before hand; you don't have to deal with the switching yourself, or even worry about colors not being found because the CTS was incorrect.
Simba Code:
function TColEx.findAllIn(Area: TBox; var Points: TPointArray): Boolean;
function TColEx.count(Area: TBox): Integer;
function TColEx.findPie(Area: TBox; StartD, EndD, MinR, MaxR: Extended; MidX, MidY: Integer; var Points: TPointArray): Boolean;
TColEx.findAllIn() does the same as above but instead of returning a single point at which the color is found, you'll receive an array of points (TPA) where all of that TColEx is found in your 'Area'.
TColEx.count simply counts the number of pixels of that TColEx found in the 'Area' and results in that total count.
TColEx.findPie finds all the TColEx pixels in a circle. Useful for precise color-finding in areas such as your minimap orbs.
Simba Code:
procedure TColEx.autoCreate(colors: TIntegerArray);
This little procedure will create (& store) a single CTS2-based TColEx for you by merging the colors you provide it. It's based off of ProphesyOfWolf's neat little snippet which I haven't been able to find again. It works the same way as if you were using AutoColor, so keep your array of colors close in tolerance!
Simba Code:
function TColEx.waitFindIn(Area: TBox; waitPerLoop, maxWait: Integer): Boolean;
The same thing as 'waitFindColorIn' but for TColEx. Useful for optimizing scripts or in situations where speed is critical.
TMSObjects
[AeroLib > entities > object > Object.simba]
TMSObjects are MainScreen objects that can be used throughout your script. This simplifies finding objects such as trees, bank booths, NPCs, players and so on. Be warned though, understanding how TMSObjects are detected may be complex for some.
Code:
type TMSObject = record
Name : String;
UpText : TStringArray;
InnerCols : Array of TColEx;
OuterCols : Array of TColEx;
MinCount : Integer;
Height : Integer;
Width : Integer;
SizeTol : Integer;
end;
- Name: The name you assign to your TMSObject (not important)
- UpText: an array of strings to search for when we're looking for the object
- InnerCols: Array of TColEx to search for (most unique colors of the Obj)
- OuterCols: Array of TColEx located near with the InnerCols
- MinCount: Minimum color count (Inner color)
- Height: Size of object (Y axis)
- Width: Size of object (X axis)
- SizeTol: Size tolerance for both height and width
Simba Code:
procedure TMSObject.create(_Name: string; _UpText: TStringArray; _InnerCols, _OuterCols: Array of TColEx; _MinCount, _Height, _Width, _SizeTol: Integer);
procedure TMSObject.create(_Name: string; _UpText: TStringArray; _InnerCols: Array of TColEx; _MinCount, _Height, _Width, _SizeTol: Integer); overload;
procedure TMSObject.create(_Name: string; _UpText: TStringArray; _InnerCols: Array of TColEx; _Height, _Width, _SizeTol: Integer); overload;
procedure TMSObject.create(_Name: string; _UpText: TStringArray; _InnerCols, _OuterCols: Array of TColEx); overload;
procedure TMSObject.create(_Name: string; _UpText: TStringArray; _InnerCols: Array of TColEx); overload;
All of these procedures create your TMSObject, however how accurate you want your object to be found is determined by which of these procedures you use to create it. So let's take a look at how the searching is done so we can better understand how to create an accurate TMSObject.
Simba Code:
function TMSObject.findAll(DistMod: Integer; SortFrom: TPoint; var Pnts: TPointArray): Boolean;
Ok so this function is the basic finder for a TMSObject and all the others will call this one. DistMod is how near at least one pixel of your InnerCol & OuterCol must be from each other to be a possible match. This is only taken into account if you have at least 1 'OuterCol', if not this parameter is not important. SortFrom is pretty straight forward as being the point at which all of your possible TMSObjects are sorted from. Generally this would be Point(MSCX,MSCY) (also predefined in AL as "MSCP") as in most cases we'd want to find the TMSObject that's nearest to our player, assumed to be the middle of the main screen. Pnts is an array of points containing the middle point of every possible TMSObject found.
Since it's possible to search for TMSObjects using dual-colors, AL utilizes bg5's AND_TPA plugin. Confused yet? Let's see a visual example of what's going on.
^ This is the plugin at work, searching for 2 sets of colors that appear within 10 distance of each other. The silver color is marked as white while the wooden color is marked as green, and the wooden color in which is found near (10 distance or less) with a silver color is marked as red.
To create a TMSObject to be found this way could be as simple as this:
Simba Code:
procedure funWithObjs();
var
obj_Chest : TMSObject;
Pnts : TPointArray;
begin // Wooden color // Silver color
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)], [createCol(3956855, 5, 0.19, 1.07)]);
if obj_Chest.findAll(10, MSCP, Pnts) then
writeln('Found a possible '+toStr(length(Pnts))+ 'chests')
else
writeln('Failed to find the chest!');
end;
However calling 'TMSObject.findAll()' will only give you a TPointArray of the middle of every possible result, it does not handle mouse-moving & UpText-checking; this is done in the next function we'll cover but before that let's see how much more accurate AeroLib can be in finding these objects.
While the above is an example of using just an 'InnerCol' as well as an 'OuterCol', we could also create an TMSObject with only an 'InnerCol', which is the equivalent of the most advanced object-finding routines in SRL-OSR. But we can go much further than single and dual-color objects, let's look at size and count filtering.
Let's say we want to find this object using all available information: Inner/OuterCols, MinCount, Height/Width, SizeTol. We would declare this TMSObject like so:
Simba Code:
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)], [createCol(3956855, 5, 0.19, 1.07)], 300, 50, 70, 20);
The last 4 parameters are the additional ones we added: MinCount, Height, Width and SizeTol respectively. Now to successfully find the TMSObject the possible objects must contain more than just those 2 colors but also must have a minimal of 300 in that 'InnerCol' that was found near with the 'OuterCol'. The bounds of that 'InnerCol' must be 50x70 (height/width) with a 20 tolerance to both. For each possible object found that meets all of these requirements a point of the middle of the 'InnerCol' TPA is added to the "Pnts" variable, which we'll receive from the function upon successfully finding at least 1 TMSOjbect.
Hopefully I haven't lost you and you're still up to speed with my explanations. That version of a TMSObject is the most complex, and if you've looked through all of the possible procedures to create a TMSObject you'll see simplified alternatives. Here's some examples:
Simba Code:
// TMSObject containing only an 'InnerCol'
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)]);
// TMSObject containing both an 'InnerCol' and 'OuterCol'
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)], [createCol(3956855, 5, 0.19, 1.07)]);
// TMSObject containing only an 'InnerCol' but also height/width/sizetol
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)], 50, 70, 20);
// TMSObject containing only an 'InnerCol' but also mincount/height/width/sizetol
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)], 300, 50, 70, 20);
// TMSObject containing an 'Inner/Outer Col', mincount/height/width/sizetol
obj_Chest.create('Chest', ['Open Bank chest','Bank chest'], [createCol(7373972, 5, 0.10, 0.96)], [createCol(3956855, 5, 0.19, 1.07)], 300, 50, 70, 20);
So you see the accuracy of finding a TMSObject is determined by how much information about it you provide when creating the TMSObject as opposed to finding it; that part is all handled automatically based on the information stored in the TMSObject.
Ok that's by far the most complex part of this little tutorial, so if you've made it this far and keeping up then it's smooth-sailing from here on out. Next we'll take a look at the remaining functions.
Simba Code:
function TMSObject.find(DistMod: Integer; SortFrom: TPoint; var Pnt: TPoint): Boolean;
function TMSObject.find(var Pnt: TPoint): Boolean; overload;
function TMSObject.find(): Boolean; overload;
These functions will actually take into account the UpText you provided when you created your TMSObject. When one of these functions are called then, if one or more are found, your mouse will move to each of the TMSObjects found and check the UpText for a match. The first function has 3 parameters, 'DistMod' is the distance in which the 2 colors must come to each other. So if you're looking for a rock with a silver vein in it, you'd want the rock color as your 'InnerCol' and the silver vein color as your 'OuterCol' and your 'DistMod' should be quite small (I recommend around 10, which is default). 'SortFrom' is the point in which to start searching from. And last is 'Pnt', the first point at which the TMSObject is found, including the UpText match. The result will be True if the TMSObject was successfully found.
The second function works the same but has 'DistMod' set to 10 as default and 'SortFrom' is set to MSCP (center of the main screen). It will also return the point at which the TMSObject is found, if at all. The third function only results True if found.
Simba Code:
function findMSObjectSimple(Cols: TIntegerArray; UpTextArray: TStringArray): Boolean;
This is a good function for beginners as it will do your object-creating & finding for you, all you have to provide is the color(s) and the uptext of the object you want to find. Do you remember the TColEx.autoCreate() function? That's used here, so remember, if you use multiple colors make sure they're of the same basic color for the auto-color to work accurately.
TItems
[AeroLib > entities > items > Items.simba]
A TItem is a package to store information for an item so you can easily use it throughout your script. It's useful for finding specific items in your inventory, your bank, deposit screens, shop screens, trade screens and even the Grand Exchange screen. This branch of the library comes with many useful functions to save time and space in your script.
Code:
type TItem = record
Name : string;
DTM : integer;
BMP : integer;
BMP_TOL : integer;
Wieldable : boolean;
end;
- Name: A name assigned to your packaged item
- DTM: A stored DTM of the item, used for locating
- BMP: A stored bitmap of the item, used for locating
- BMP_TOL: The tolerance of the TItem's BMP (only if using a BMP)
Defining a TItem is very easy and there's multiple ways to do it. Here's a couple examples:
Simba Code:
procedure itemMadness();
var
item_Coal : TItem;
begin
item_Coal.Name := 'Coal';
item_Coal.DTM := DTMFromString('mggAAAHicY2NgYJjGxMDQAcR9TBD2QiCeBcQcjAwMbEDMD8RiQMwDxCxArKcnD9TFiIG5sIrixhAAAOC3BG4=');
// OR
with item_Coal do
DTM := DTMFromString('mggAAAHicY2NgYJjGxMDQAcR9TBD2QiCeBcQcjAwMbEDMD8RiQMwDxCxArKcnD9TFiIG5sIrixhAAAOC3BG4=');
// OR
with item_Coal do
begin
Name := 'Coal';
BMP := BitmapFromString(WIDTH, HEIGHT, 'YOUR BITMAP STRING GOES HERE');
end;
end;
Now that our TItem is created we can utilize it in our script, but there's one important rule you must always keep in mind when using TItems: Because they're composed of a DTM or Bitmap you must always free the DTM/Bitmap after it's no longer used. A golden rule for using any DTM and/or Bitmap in general is to declare it globally one time at the beginning of your script and free it before the script terminates. This will prevent you from have any memory leaks. Here's an example of correctly defining & freeing TIems:
Simba Code:
program CoalFinder;
{$i AeroLib/AeroLib.Simba}
Var
item_Coal : Titem;
procedure searchForCoal();
begin
if item_Coal.inInventory() then
writeln('Found coal in the inventory')
else
writeln('Did not find coal');
end;
begin
initAL();
with item_Coal do
DTM := DTMFromString('mggAAAHicY2NgYJjGxMDQAcR9TBD2QiCeBcQcjAwMbEDMD8RiQMwDxCxArKcnD9TFiIG5sIrixhAAAOC3BG4=');
searchForCoal();
// other stuff
// script loops
// more stuff
freeDTM(item_Coal.DTM);
end.
...and an example of how not to do it:
Simba Code:
program CoalFinder;
{$i AeroLib/AeroLib.Simba}
procedure searchForCoal();
Var
item_Coal : Titem;
begin
with item_Coal do
DTM := DTMFromString('mggAAAHicY2NgYJjGxMDQAcR9TBD2QiCeBcQcjAwMbEDMD8RiQMwDxCxArKcnD9TFiIG5sIrixhAAAOC3BG4=');
if item_Coal.inInventory() then
writeln('Found coal in the inventory')
else
writeln('Did not find coal');
freeDTM(item_Coal.DTM);
end;
begin
initAL();
searchForCoal();
// other stuff
// script loops
// more stuff
end.
Moving on we'll come to the TItem finding routines.
Simba Code:
function TItem.findIn(Area: TBox; var fPnt: TPoint): Boolean;
Pretty straight forward, if the TItem is found in the specified area (TBox) then the result will be true, along with the point (fPnt) at which the item first appears.
Simba Code:
function TItem.getAmount(ExcludeBank: Boolean): Integer;
function TItem.getAmount(): Integer; overload;
This neat little function will return the amount of the TItem, if it was actually found. If you set 'ExcludeBank' to true then the function will only count the TItem in your inventory. If 'ExcludeBank' is set to false (which is what the second function does) then, if found in the bank, the TItem will be counted (stack amount). Also something to keep in mind is if an item is "stackable", such as coins and bank notes, that will be automatically detected and the function will return the stack amount. However if the item is not stackable then the TItem will be counted for each slot it appears in within the inventory.
Simba Code:
function TItem.getSlots(): TIntegerArray;
function TItem.getSlot(): Integer;
This is simply used to get all of the inventory slots in which the TItem is found, and the second function returns just the first slot to hold the TItem.
Simba Code:
function TItem.interact(action: Variant): Boolean;
A very useful function combining many into one. This is to interact with a TItem, if found, in any action you want: left-click, hover or right-click choose option. Here's some usage examples:
Simba Code:
procedure funWithCoal();
begin
if item_Coal.interact(MOUSE_LEFT) then
writeln('Clicked the coal')
else
writeln('Did not find coal');
if item_Coal.interact('Drop') then
writeln('Dropped the coal')
else
writeln('Did not find coal');
if item_Coal.interact(MOUSE_MOVE) then
if isUpText('Coal') then
writeln('Found coal uptext');
end;
And there you have it folks, a few of the most basic types found in the AeroLibrary. While this tutorial only scratches the surface of what all is available I truly hope it helps you to better understand the include, how it functions and how to take advantage of what it has to offer. If I have the time and willingness I'll write some more tutorials on second-level functionality in the include such as banking, walking and object-interacting. Perhaps even a step-by-step script creation tutorial to get you on your way to scripting.