The include is broken up into basically two different "categories." For the sake of making this tutorial clear, I will refer to them as "Static" and "Non Static" functions/procedures. For those of you who are not familiar with a java based language, if something is static, it can be accessed throughout the program, without creating an instance of the object type. Now in Lape, we can't directly make a function static or not, but we can use types, and declare as a variable.
Don't worry if that doesn't make sense, it should become quite clear while going through the rest of the tutorial. Another point I would like to make. While talking about the functions in this tutorial, I will at times say that one section only has x number of functions, when it may actually have more in the ".simba." The other functions will be accessed by Reflect.Internals, and only used internally.
Like I mentioned in the Overview, the functions in the include that are considered static can be called and used without creating a variable. This part of the tutorial will be most familiar to people who have scripted with SRL-5 and/or SRL-OSR. Since they used Pascal script, this was the only option when scripting. In order to access any of the static functions, we use the variable named "Reflect." This contains all of the categories for the functions in the include.
For example:
http://i.imgur.com/cVaQOmk.png
http://i.imgur.com/LXRejY5.png
Compass
This section is a pretty self explanatory one, as there are only 3 functions.
Simba Code:
function AngleDeg: Extended;//Returns the Degree of compass in Degrees
function AngleRad: Entended;//Returns the Degree of compass in Radians
procedure Make(Direction: Variant);// Will change compass to specified direction
Map
Another Short section, as the only function is:
Simba Code:
function TileOnMM(Tile: TTile): Boolean;//Returns true if the tile is on the Minimap
Tiles
Tiles.simba contains several very useful functions, which are used in almost every reflection script.
Simba Code:
function DistanceFromTile(Tile: TTile): Integer;//Returns distance(In tiles) from given TTile.
function GetPlane: Integer;//Returns current plane(Floor level)
function GetTileHeight(Tile: TTile);//Returns Height of given TTile.
function InPolygon(Area: TTileArray): Boolean//Returns if we are inside polygon of tiles.
function NearTile(Tile: TTile; Dist: Integer): Boolean;//Returns if we are within Dist from Tile
function TileToMM(Tile:TTile): TPoint//Will return a TPoint Mainscreen coord on the minimap
//given a TTile.
Simba Code:
function TileToMS(Tile: TTile; XOffset: Integer = 0; YOffset:
Integer = 0; ZOffset: Integer = 0): TPoint;
TileToMs is one of the most important functions in the include when it comes to interacting with anything in game. It returns mainscreen coords when given a TTile. This is used whenever we want to interact with npcs, players, objects, ground items, or just Tiles. We are able to add pixel offsets to the function, which are independent of the compass rotation.
Text
The functions involving text, Reflect.Text, Are all the exact same as they are in other SRL color includes, so they should need no explaining.
Simba Code:
function ChooseOption(Option: String): Boolean;
function GetUpText: String;
function IsUpText(UpText: String): Boolean;
function IsUpTextMulti(UpText: TStringArray): Boolean;
Bank
Bank.simba contains both Static and Non Static functions. Opening and closing the bank are done using static functions, as expected. The core functions dealing with the items within the bank are non static functions, but are also referenced via static functions. The list of all functions are:
Simba Code:
procedure TReflectionBank.IsOpen;
procedure TReflectionBank.Close;
function TReflectionBank.ItemCount: Integer;
procedure TReflectBankItemArray.GetAll;
function TReflectBankItem.Find(TheItem: Variant): Boolean;
function TReflectBankItem.Withdraw(Amount: Integer): Boolean;
function TReflectBankItemArray.GetAll: TReflectBankItemArray;
function TReflectBankItemArray.Find(var BankItem:TReflectBankItem, TheItem: Variant): Boolean;
function TReflectBankItemArray.Withdraw(TheItem: Variant; Amount: Integer): Boolean;
Declaring a variable as a TReflectBankItem/TReflectBankItemArray will typically be the best option, as you can gather much more data, but there are times where using a static function will be much cleaner and easier to use.
If you are using reflection to login, and you want to add BankPin support, you should call you bank function like this:
Simba Code:
procedure OpenBank;
begin
//Find/Click on the bank;
Myplayer.EnterPin;
end;
Example of how to use both:
Simba Code:
var Arrow: TReflectBankItem;
begin
if not Reflect.Bank.IsOpen then
Exit;
if Arrow.Find('Iron arrow') then //Case sensitive
begin
if Arrow.Quantity < 100 then
begin
WriteLn('Low on arrows, Quiting!');
TerminateScript;
end;
Arrow.Withdraw(100);
Reflect.Bank.Close;
end;
end.
Simba Code:
begin
if not Reflect.Bank.IsOpen then
Exit;
Reflect.Bank.Withdraw('Iron arrow', 100);//Case sensitive
Reflect.Bank.Close;
end.
So, using the static bank functions, it is much quicker/shorter code in order to withdraw an item, the downside is of course the fact that you can't access any data from the item. Also note that you can get any data from TReflectBankItem that you can from the Item Record.
Chat
The last main section of Static functions for scripter's is Chat.simba. This is another section where functions will be added in at a later date. It will contain all functions regarding game chat within Rs. Currently, the functions are:
Simba Code:
function GetLastMessage: String;//Returns the text of last public chat message
function TReflectionChat.NpcChooseOption(Options: TStringArray): Boolean;//Selects an option from
//an npc chat given an array of string
function TReflectionChat.NpcChooseOption(Option: string): Boolean; overload;//Same as above,
//except it takes a single string
function TReflectionChat.NpcClickToContinue: Boolean;//Clicks continue through all chat
Internals
I will only breifly talk about this section, saving it for the next part of the tutorial, as most scripter's will not need any of the functions within this section. Like I mentioned in the Overview, many functions throughout the include, are labeled as a "Internals" function. While it may be related to the category of the ".simba" it is in, It shouldn't be used by scripter's regularly. While there are many functions within "Internals" I will only mention two in this tutorial.
Simba Code:
function GetSetting(Setting: Integer): Integer;
function GetSettingArray: TIntegerArray;
These two functions could have been in another category, as they can be very useful as a scripting tool, but since they don't do anything useful directly, I decided to keep them in Internals. The best way I can think of to describe the Settings array, are as a integer array of game client variables. A lot of useful values are stored in this array, that change when the in game value change. For example:
Simba Code:
Result := Reflect.Internals.GetSetting(102) > 0;
That is in the function TReflectLocalPlayer.IsPoisoned; If the integer value of the setting array at a index of 102 is any positive value, then we are poisoned. This can get even more precise, as the higher the value, the more poisoned we are (I believe the highest is 25). I won't go into any more examples as I would like for you to go find out neat uses for this set of functions your self! Think: Farming, combat options, ect..
This section is where the bulk of the tutorial will be, as the majority of the include is made up of these Non Static functions. Like previously stated, The term "Non Static", in the sense I am referring to, is any function that can only be accessed through declaring variables. This is done in order to make scripts be able to be written much neater, and in a more object orientated manner. Also, when finished reading this section, it should also make sense why it is done this way.
Memory managment
The latest version's of the include have a vastly different way in which memory is handled in terms of non static objects. Whenever a GetAll/Find method is called on an object, the object
reference of the in game object is stored both with the variable and in the global hook cache. Whenever another GetAll/Find method is called of the same object type, the Hook cache of that
particular object is freed from memory.
So, this means, that aslong as you don't call another GetAll/Find method, the data of the particular object will live with the variable and the Individual .GetBlah functions can be called
on the variables.
Note: Though in some objects(Item, game objects) there are other entries in the record such as _Tile and _Id. Do NOT use any info that is prefixed with a '_', as it is only to
be used internally.
LocalPlayer
I wasn't planning on talking at all about what classes are inherited from what in the RS client or the include, but I feel now as though it will make it easier to understand. Simply put, in java, if a class inherits from another class, it will then contain all methods/fields from the inherited class. So, in the rs client, LocalPlayer, Npcs, and other players all inherit from a class called Actor. So, as you will soon see, LocalPlayer, Npcs, and other players share many of the exact same functions.
With that out of the way, on to LocalPlayer!
In the include, the variables we define are prefixed with: TReflect, so LocalPlayer is: TReflectLocalPlayer; In almost every script you will write, you will want to define a global variable as a TReflectLocalPlayer.
Simba Code:
var
MyPlayer: TReflectLocalPlayer;
So, using MyPlayer, we are able to access all sorts of data and functions regarding our player that are quite useful.
Important Note: This include stores your LocalPlayer reference in a global array in order to handle memory more efficient. If you are using reflection to log your player in, it will take care of this for you. If not, you need to call the following function everytime you start the script/login your player:
This loads the object reference to our player, enabling us to access the data. So, after our player is created, the rest of the functions regarding our player are quite easy to use without much confusion.
Using reflection to login, as long as you Call MyPlayer.Login at the beginning of your script, making sure that your player is created at the beginning, you won't ever have to call MyPlayer.Create;
Declarining you player at the beginning of your scripts is about the same as any othe include:
Simba Code:
var MyPlayer: TReflectLocalPlayer;
MyPlayer.Username := 'UserName';
MyPlayer.Password := 'Password';
MyPlayer.Pin := '3232';
MyPlayer.Active := True;
Then you can just do:
Since I do not feel like typing all of the functions out, here is a screenie of them:
http://i.imgur.com/rXQ24bK.png
Also, for what ever reason, simba's code completion doesn't show inherited functions all the time, so TReflectLocalPlayer, Npcs, and other players
ALL have the following functions:
Simba Code:
function GetSpokenText: String;//Returns current overhead text, if any.
function GetTile: TTile;//Returns current tile/
function GetQueue(Index: Integer = 0): TTile;//Returns tile in walking path
function GetAnimation: Integer;//Returns Animation
function GetHealth: Integer;//Returns top number health (Must be in combat to access)
function GetMaxHealth: Integer;//Returns Bottom number Health(Must also be in combat)
function GetInteractingIndex: Integer;//Returns index of npc/player interacting with
function GetCombatCycle: Integer;//Returns cycle while in combat, == ClientLoop if not
Npcs
So, like just mentioned, since Npcs and LocalPlayer inherit from Actor, npcs will have the same data that I typed out above.
NOTE: Npcs will not have any of the other data that LocalPlayer has, just what was typed out.
So, as expected, we must declare variables:
Simba Code:
var
AllNpcs: TReflectNpcArray;
OurNpc: TReflectNpc;
AllNpcs.GetAll;//Loads all Npcs into 'AllNpcs'
AllNpcs.Get('Guard');// loads all Npcs with name 'Guard into 'AllNpcs'
OurNpc.Find('Guard');//Loads the closest Npc with Name 'Guard' and returns true if found
You must always remember to call whichever one of these functions you are using,
before each and every time you grab data from them, or it will be outdated. For example, here is a simple combat Script.
Simba Code:
program FightTest;
{$DEFINE SMART}
{$i reflection/Reflection.simba}
var
MyPlayer: TReflectLocalPlayer;
procedure FightGuard;
var
Guard: TReflectNpc;
Point: TPoint;
begin
while not MyPlayer.IsUnderAttack do
begin
if Guard.Find('Guard') then
begin
Point := Guard.GetMsPoint;
Reflect.Mouse.Move(Point, 2, 2);
Reflect.Mouse.Click(MOUSE_LEFT);
While MyPlayer.IsMoving do
Wait(50);
end;
end;
end;
begin
Reflect.Setup;
MyPlayer.UserName := 'UN';
MyPlayer.Password := 'Pass';
MyPlayer.Login;
repeat
if MyPlayer.GetHealth < 20 then
//Eat
else
FightGuard;
until(False);
end;
Players
Players refer to any non Npc's including our local player. Currently I only added one function that returns an array of all the players around us. As I haven't scripted anything where I would need this, maybe some other people could chime in and tell me what type of functions in player.simba you would like to see!
Simba Code:
var
Players: TReflectPlayerArray;
begin
Players.GetAll;
end;
Objects
In Rs there are 4 types of in game objects, Interactable(This Include calls Game), Wall Decoration, Floor Decoration, and Boundary.
Game Objects are any mainscreen object that has the option to examine. These are by far the most important objects from a scripter's point of view. Wall Decoration are like pictures, wreaths, candles, ect that are on walls. Floor Decoration are the same as Wall Decoration, just on the floor. Boundary is exactly what it sounds like, anything that forms a boundary in RS, Walls, fences, ect..
Game Objects can be searched by name or ID's, the others must only be searched by ID.
The functions for Objects are set up in the same basic form as Npcs, such that:
Simba Code:
var
AllObjects: TReflectObjectArray;
OurObject: TReflectObject;
begin
AllObjects.GetAll(objGame, 20); //Loads all game objects within 20 tiles
AllObjects.Get(objGame, 'Tree', 20);// Loads all 'Tree's within 20 tiles
OurObject.Find(objGame, 'Tree', 20);//Loads nearest 'Tree' and returns true if found within 20 tiles
end.
Another point I would like to clarify is that the Object Types are no longer constants, but an Enum, so you must use one of the following in your functions:
Simba Code:
type
TObjType = (objNull, objGame, objWallDecoration, objFloorDecoration, objBoundary);
objNull is used internally and will not return any object at all.
Items
This is the final topic to be covered in the 'Non Static functions and it shouldn't be any easier/harder than Npcs/Objects!
There are 3 different types of objects in the include, Ground, Inventory, and bank. All of those extend from the main Item.Simba and contain the same Fields. I will add some of these items and other stuff to my fighting exampleand that should help show more of the includes features as well!
Simba Code:
program FightTest;
{$DEFINE SMART}
{$i reflection/Reflection.simba}
var
MyPlayer: TReflectLocalPlayer;
procedure FightGuard;
var
Guard: TReflectNpc;
Point: TPoint;
begin
while not MyPlayer.IsUnderAttack do
begin
if Guard.Find('Guard') then
begin
Point := Guard.GetMsPoint;
Reflect.Mouse.Move(Point, 2, 2);
Reflect.Mouse.Click(MOUSE_LEFT);
while MyPlayer.IsMoving do
Wait(50);
end;
end;
end;
procedure EatFood;
var
Lobster: TReflectInvItem;
begin
Lobster.Find('Lobster');
Reflect.Mouse.Move(Lobster.GetMSPoint, 2, 2);
Reflect.Mouse.Click(Mouse_Left);
end;
procedure LootItems;
var
TheItems: TReflectGroundItemArray;
I: Integer;
Point: TPoint;
begin
TheItems.GetAll(20);
for I := 0 to High(TheItems) do
begin
Point := TheItems[I].GetMSPoint;
Reflect.Mouse.Move(Point, 2, 2);
Reflect.Mouse.Click(Mouse_Left);
while MyPlayer.IsMoving do
wait(50);
end;
end;
begin
Reflect.Setup;
MyPlayer.UserName := 'UN';
MyPlayer.Password := 'Pass';
MyPlayer.Login;
repeat
if MyPlayer.GetHealth < 20 then
EatFood
else
begin
FightGuard;
LootItems;
end;
until(false);
end.