SRL Archive - OutDated Tutorials

New Reflection Tutorial (up to date as of Dec 1, 2010)


Cstrike

2010-10-08 23:34:12

Learn how to code for reflection all right here!
This guide alone prints to 34 pages long. Think of the trees…
Up to date as of December 1st, 2010
SVN: http://simbareflection.googlecode.com/svn/trunk/

Use common sense, if this is a half-a-year old, it's probably out of date unless the date above is changed.
Fundamentals are still the same though.
Note this is mainly the basics, if you have advanced questions I still can answer them since I'm a pretty solid at the whole thing.

Also, enjoy the wanky colors and the non-neat format I chose ;)


What you need:
  • Reflection (From Simba, should update in the extensions)
  • The ability to think outside the box in some cases
  • A task that is a pain in the *** to do with color (like walking, finding an NPC is a crowd of things…etc, your mind is the limit)
Yes, you actually can probably do a Dragon Slayer quester with Reflection!!

What coding skills you need:
Red = critical, don't bother with reflection if you don't understand them
Orange = important, but you can get by with some copy pasting
Green = is nice to know


Here we go:
  • SRL basics
  • You need to know how SRL and Simba/SCAR work and flow. If you can't write a normal script like a really basic powerminer (doesn't have to be complex), reflection will probably go over your head. If you can make a basic script that works (one that for example, mines and drops with the occasional failsafe, no banking, no walking, no autocolor…etc) you should be okay [consider yourself beginner]
  • Arrays
  • Reflection is quite dependent on these, without it you will barely even able to do the most simplest thing of walking or finding anything. Should also know what a TPointArray is, and a TIntegerArray is and what a TStringArray is.
  • How to manipulate arrays (for loops…etc)
  • Same as above almost, except if you lack this but know arrays you may be able to do walking If you know this:
     //Let myArray : TIntegerArray;
    for i:=0 to high(myArray) do
    begin
    writeln (inttostr(myArray[i]));
    end;
    If you don't know what is generally going on above (it's a debug procedure for those that don't know), then you're going to struggle.
  • TPoints
  • The concept is important for walking, also important for finding NPC's/objects, but you can get by blindly by copy-pasting someone elses stuff If TP := Point(55, 123);, you should know what number IntToStr(TP.x) will give you… if not, you're going to struggle with walking.
  • 2D arrays
  • Needed for walking long paths that get complex
  • Comfortable with variable conversion
  • Not necessary but if you want to do debugging to find your own interfaces/NPC's…etc, or generally find if something goes wrong– you should have this down (ex: converting NPC names found to a string to debug by writing it with writeln)
  • Know how to make your own procedures and functions
  • You should know how to create functions and procedures with arguments, ex:
    function SquareMyNumber (number : Integer) : Integer;
    begin
    result := number*number;
    end;
If you're missing anything, there are ample guides on all the above subjects in the Scripting Tutorial forums.
Next post will jump right on in. If you're missing some of the above you were warned. You can always ask questions here :), so feel free. I'm just giving you the reality of it.

Debug: When I say this, it means to output data usually by writeln();, so that you can see what the program is doing. Debugging is where you tell the program to output data so you can find bugs. If my definition is wrong then just consider me stupid and deal with how I use this word throughout the tutorial :) ;)

Update log:
[BANANA][LEFT]UPDATE: Nov 28th
I just committed a ton of new features for interfaces, don't bother using the ones I added in this guide.
In addition, you can now use SetupReflection; instead of SetupReflectionEx (true);[/LEFT][/BANANA]

Cstrike

2010-10-08 23:35:15

How to make your script reflection

Just add "SetUpReflectionEx(true);" after SetupSRL;
The boolean argument is whether to continue on if the hooks are up to date.
Basically if false, will log out if the hooks are out of date. You should use true pretty much all the time unless you know what you're doing– since if its false and you're out date, unless youre a java/reflection God… it won't work anyways.


Use this as your basic template
program ReflectionBasic;
{$DEFINE SMART}
{$i srl\srl.scar}
{$i reflection\reflection.simba}

const
{---SMART Setup Constants---}
WORLD = 121;
MEMBERS = false;
SIGNED = true;
{---------------------------}

Procedure DeclarePlayers;
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

With Players[0] Do
Begin
Name := '';
Pass := '';
Nick := '';
Active := True;
Pin := '';
End;
End;

begin
Smart_Members := MEMBERS;
Smart_Server := WORLD;
Smart_Signed := SIGNED;
SetupSRL;
SetUpReflection; // Yeah baby!
DeclarePlayers;
LoginPlayer;
end.

What to do if your hooks are out of date
** Know where Simba/Includes/Reflection/Core/Hooks.simba is located, as this is where you will be pasting new hooks if you do not want to wait for automatic updates from simba.
If they JUST went out of date due to an update that happened 2 hours ago, you're **** out of luck. Sorry, but humans have to update all the various letter based hooks. Takes a while and is a bit irritating.
If you're afraid to go editing, just wait for the reflection update. Depending on how busy people are… may take a few days though.

Steps to update hooks:
1. Go to Reflection –> Reflection Development –> Client Hacking
2. Look for the largest number
3. Open the thread, check the revision number (like #622 for example), and copy the code that looks like a ton of hooks
4. Open up Hooks.simba [see above path I gave you in last paragraph
5. Overwrite EVERYTHING if and only if your reflection hook version number (should be at the top) is less than the number of the thread you copied it from. If you copied number #625 and your version is #623, overwrite. If you copy version #640 and the current version is #640, it will do nothing [usually, minus exceptions or minor updates]

Now they are up to date.
If they still don't work, it means RS was updated and everyone's hooks are out of date. Sorry, just wait.

Using reflection to flawlessly solve randoms!

Just call
R_FindRandoms;
instead of FindNormalRandoms. This will invoke the reflection random solvers. As of October 29th, only 4 randoms remain unsolved, and they will be solved soon. Hopefully by the end of the first week of november, all randoms will be solved and your bots will be UNSTOPPABLE.
If you find an error in any random, report it to the Reflection staff immediately (and if you can, let them on your account so they can find what the error was).

Yes, Mordaut and Maze have been solved. The remaining 4 are not nearly as hard as those two were.
Almost all, if not all of them are solved!

Next post will deal with code.

Cstrike

2010-10-08 23:36:22

Warning: From now on in, some of the scripts I give you may suddenly not work. Reflection is not too well staffed and things go out of date (and so do the hooks). If not, learn the reasoning behind the script and you'll be good. You may even be able to work around the out of date stuff by using intuition and some good thinking.

Everything from here on in is teaching you about:
- how to use reflection scripts
- ideas that you can use them for (these may give you some good ideas!)






=========================================
Read the bolded purple parts below the huge underlined titles to see if it's an area you feel to be worth reading
========================================







Reflection banking

This is the most simple part of reflection. I haven't tried this but the code is really self explanatory. This is mainly boolean functions to see if you're at or using a bank.
The only applications here are quick resources for opening/depositing stuff in a bank.


Example:
R_PinScreen would be used to check if the pin screen is up:


if R_PinScreen then EnterPinProcedureHere;

Really though you should probably try SRL color first, then use this as a fail safe

For getting item ID's for code like this
{*******************************************************************************
function R_DepositAllID(ID : Integer): Boolean;
By: Zyt3x
Description: Deposits all the items with the specified ID
*******************************************************************************}
See later on for getting ITEM ID's from your inventory.


For functions like these:
{*******************************************************************************
Function R_OpenBankBooth(Bank : String): Boolean;
By: ss23 & TheGuyWhoGotOn
Description: Opens the bank using Bank Booth.
*******************************************************************************}
This is for finding a pre-defined bank booth.
Note that here, this procedure is mainly based off of tiles. If you check the code, it will take in places like 'veb', 'varrock east', etc… (your generic places).
If you want to open an obscure bank spot, then you need to go to Object Finding, which will show you how to get a bank location that isn't defined ;)
As per usual, read through the Banking.simba file to see what you can do. Use your knowledge of programming to do the rest.

For example, you could do this:
 if ProcedureHereToCheckIfWereInVarrockWestBank then
begin
if R_OpenBankBooth('vwb') then DepositEverythingProcedureHere
else LogOut;
end;
Despite being a sub-par example, there's an example of what you can do.



Character animations (and NPC animations)

Use this section to check your character or another characters animation.
This is useful for seeing if you're fishing, mining, fighting…etc
How this can be useful for you is if you're fishing somewhere for example, create a loop that only exits upon your character no longer using the fishing animation. Then you know your character has stopped or the fishing location has moved.
This can also be used for NPC's (good for the antirandom for the mime, as it checks his animation number and then you can do stuff from there)


Character animations are numbers, simple as that. If we do something like this
 var anim : Integer;
anim := GetAnimation;
writeln (inttostr(anim)); // Don't really need inttostr I guess
This will output a number.
0 = you standing still doing nothing.
For example, I declared this constant
"FishingAnimation = 618;", since for me at this time, 618 is the animation of fishing. How do I use this?
EDIT: Note, different types of fishing are different numbers, small net uses 621 for example, NEVER assume one number is the same
function AreWeNotFishing : Boolean;
begin
Me := GetMe; // I will explain this later, it basically gets a bunch of information on yourself
if Me.Animation = FishingAnimation then result := false else result := true;
end;

// Then later on in a procedure or loop somewhere...

repeat
wait (500+random(500));
FindNormalRandoms;
until (AreWeNotFishing) // Returns false if we are, but exits upon being true (and based on the procedure above, returns true when we are NOT fishing)


So that is how animations work. Returns a number, and then you read what that number is and what it does, and do what you want with it. Read characters.simba to see more cool functions you can do like:
  • function WaitForAnimation(timeout: integer): boolean;
  • Use logic at how this would work… waits for animation for timeout (milliseconds as an integer)
  • function CharacterAnimating: Boolean;
  • Makes logical sense that "true is similar to yes", so if it returns true, we're doing some animation (unspecific for which though)
  • CharacterMoving: Boolean;
  • True if were walking/running, false if were not

See? Common sense was put into these variables :) It's pretty easy to figure these out…

Cstrike

2010-10-08 23:37:23

Key topic: Getting NPC data (locations, name, position…etc)

Have you thought of anything that has to do with an NPC (Fishing spots are NPCs, rock are NOT NPC's)? This will do anything like finding if its near you, getting its exact location on your main screen…etc. It can even find it's actions or what it can do. Contained here is good debug code to finding any NPC number.
You can do anything pretty much with NPC's. Just think about what you want to do and you can do it (minus impossible things).
Yes, this includes moving our cursor to the NPC that we want as well. Yes, we can target one NPC out of every single one perfectly each time theoretically if you do it right.



To get all the NPC's on the screen (this code will usually always come up unless you know specifically what NPC's youre looking for), you need to call one simple command.

//function GetNPCs: TNPCArray;
var MyNPC : TNPCArray;

MyNPC := GetNPCs // One simple command!

Following this, many will call this function:
//Function SortNPCs(NPCs:array of TNPC):array of TNPC;
MyNPC := SortNPCs(MyNPC);

But to combine them, everyone does this:
MyNPC := SortNPCs(GetNPCs);

Alright, so with that one line of code you called you now have a ton of NPC's (if it doesnt compile, make sure you define it as a variable). Now you want the data right? The data is very similar to how types work.
For example, TP.x gets the x value stored in TP…etc, likewise you call things with a ToStr(MyNPC[index].something);

This code is also by Naike, and I want you to look at what can be done. I won't explain each one, but take a look at what the second parts of MyNPC.ThisThingHere have as their word to get an idea of what you can return.

You can use this code if you want (copy paste it) as a debug to find all the NPC's around you. It finds some off the screen (at max distance of whatever unit 52 is, I don't know it yet… maybe tiles?)

// The big epic debug procedure for finding all those NPC's around you
// By Naike
procedure DoNPC;
begin
Repeat
NPCs := SortNPCs(GetNPCs);
Writeln('--NPCs--');
For I:=0 to high(GetNPCs) do
begin
Writeln('[' + ToStr(I) + ']Name: ' + NPCs[I].Name + '(' + ToStr(NPCs[I].Tile.X) + ', ' + ToStr(NPCs[I].Tile.Y) + ') ID: ' + ToStr(NPCs[I].ID) + ' - Index:' + ToStr(NPCs[I].Index));
Writeln(' Orientation: ' + ToStr(NPCs[I].Orientation) + ' - Level: ' + ToStr(NPCs[I].Level) + ' - Animation:' + ToStr(NPCs[I].Animation) + + ' - HPRatio:' + ToStr(NPCs[I].HPRatio));
Writeln(' Moving:' + ToStr(NPCs[I].Moving) + ' - InFight:' + ToStr(NPCs[I].Fighting) + ' - Interacting:' + ToStr(NPCs[I].Interacting) + ' - Height:' + ToStr(NPCs[I].Height));
Writeln(' Actions:');
For II:=0 to High(NPCs[I].Actions) do
Writeln(' ' + NPCs[I].Actions[II]);
end;
Wait(3000);

ClearDebug;
Until(False);
end;

Notice how it can get actions as well? If you find a fishing spot, and want to fish shark instead of swordfish (since both use 'harpoon'), you can do something like this:

// You NEED to use a for loop with I:=0 since this is an array... remember?
if (ToStr(MyNPC[I].Name = "Fishing spot") then
begin
if (ToStr(MyNPC[0].Actions = "Net") then // Why am I doing index [0]? Because you want to check the first action that returns, we know the first action is going to be either Net or Cage (get this from the debug procedure above, run it if you dont believe me)
begin
// Begin fishing
end;
end;
So what am I doing?
1) Tell computer (did not show the for loop) to go through our NPC array and see if the index results in a name above (remember, the code I pasted above will debug everything, so just run that and find the name of what you want)
2) If it has that name, we want to see if its a shark spot or a lobster spot. We don't want to accidentally fish swords do we? So check the actions, if "net" is first, then you KNOW that there is a harpoon option for shark. If the program sees 'cage' as the first word, it will just ignore it.
This way, we can without even checking the spot, tell if its a place to get shark or not!


When we get better (and learn tiles, which is next (and the most easiest lesson)), we can use functions like this:

// Is your NPC stationary? Like Stiles from karamja?
function GetNPCsAt(T: TTile): TNPCArray;

// This is another good debug procedure
procedure DumpNPCs(NPCs: TNPCArray);
Etc, etc…
Just use your common intuition to get an idea of what the other procedures mean.




Getting Player data and your own character data

Getting other player data is not so useful, but the key part is your own data. This is where you can get your levels, prayer points, HP level in the middle of a fight…etc.

Who wants to hover over your name for the skill experience? Why not just do it in one shot ;)

It's also one simple line!

{*******************************************************************************
function GetMe: TMe;
By: Widget, lordsaturn, Drags111
Description: Returns you
*******************************************************************************}

Just call this:

var MyCharData : TMe;
MyCharData := GetMe;


Now to save time, if you understood the above with NPC's you'll understand this. Naike made this again, he is also God.
Once again, use this as you wish to debug yourself! Call it wherever…
var Me : TMe;
// By Naike
procedure DoTMe;
begin
Repeat
Me := GetMe
Writeln('--Me--');
Writeln('Name: ' + Me.Name + '(' + ToStr(Me.Tile.X) + ', ' + ToStr(Me.Tile.Y) + ') LoginIndex: ' + ToStr(Me.LoginIndex) + ' - Speed:' + ToStr(Me.Speed));
Writeln(' Orientation: ' + ToStr(Me.Orientation) + ' - Combat: ' + ToStr(Me.Level) + ' - Animation:' + ToStr(Me.Animation) + + ' - HPRatio:' + ToStr(Me.HPRatio));
Writeln(' TurnDirection:' + ToStr(Me.TurnDirection) + ' - InFight:' + ToStr(Me.InFight) + ' - Interacting:' + ToStr(Me.Interacting) + ' - Height:' + ToStr(Me.Height));
Writeln(' Levels/Exp:');
For I:=0 to High(Me.Levels) do
Writeln(' Ind[' + ToStr(I) + '] Level:' + ToStr(Me.Levels[I]) + ' Experience: ' + ToStr(Me.Experience[I]));

Writeln('');
Writeln(' Equipment:');
For I:=0 to High(Me.Equipment)do
Writeln(' Ind[' + ToStr(I) + '] ID: ' + ToStr(Me.Equipment[I]));

Wait(3000);
ClearDebug;
Until(False);
end;

One part that sucks is att/def/str/fletch/magic…etc, are all numbers. To find what skill you want, you have to debug what experience it gives you (and what index number), and then that is your constant.
For example, fishing is #10, so if I want an experience debug I will call
writeln (ToStr(Me.Experience[10])); //I chose 10 because 10 is fishing

Also as you see you can get your equipment status. Quite useful, no? You should be an expert on this now so I won't explain each part. Refer here if you need some data (or characters.simba)

Lastly, with the players data you can get, it will return you well… player data. This isn't too useful, but THEROETICALLY you could actually make a viral army (have a list of friends not to attack, and if they're following you and see some other player, they will all attack based on other reflection code. A perfect army under your control). Of course you need like 10 computers for 10 accounts of your own, all which follow your char effectively, but one can dream…


EDIT: The dangers of improperly getting NPC data (causes script termination)
Well there is no real danger, just your script can run fine for 10-20 minutes, and after you leave… it crashes!
How does it crash? Well it just says 'line out of range' and it terminates.
So what is this mistake? I've seen myself and another member on this board do it– it 's a sneaky bugger to catch.

Tell me what's wrong with this code (here's a good practice for you, if you're lazy the answer is farther below)
var NPCs := TNPCArray;
begin
if not LoggedIn then Exit;
NPCs := GetNPCsBy('Fishing spot');
if high(NPCs) > -1 then
begin
for i:=0 to high(GetNPCs) do // This is the line that Simba (or SCAR) would report as the error
begin
if (NPCs[i].Name = 'Fishing spot') then
begin
writeln ('Found fishing spot');
end;
end;
end;
end;

So the code upon inspection to you may look flawless. In fact, it does work. No compiling errors, but think outside the box… it is getting a compiling error. What line is it at? It's at the for loop line. So what is going on there? It goes from 0 to the highest of the NPC's found, how can there be an error?
Now think of reflection at work. Took me a while to figure this out, if you found it out at first than your eyes are better than mine. Notice how the loop goes up from i:=0 to high (GetNPCs)? See the last command? It's getting the NPCs all over again (even though we have already gotten it!)
Therefore if you suddenly have one more NPC on your screen because it wandered in, your loop is going to now search one extra index. i:=0 will go one number higher than your NPCs array that you declared.
For example, if NPCs length is 5, and suddenly an NPC happens to walk in on that ~1 ms that your script is processing NPCs again, it will make your theroetical max 6. When the loop goes through i:=0 to i:=5 (thats a length of 6, remember?), it will search your NPC's (which only has an index of 0 –> 4, which is a length of 5), and searching for a higher index than the max crashes it

So your code should look like this for it to almost never crash:
var NPCs := TNPCArray;
begin
if not LoggedIn then Exit;
NPCs := GetNPCsBy('Fishing spot');
if high(NPCs) > -1 then
begin
for i:=0 to high(NPCs) do // Fixed!
begin
if (NPCs[i].Name = 'Fishing spot') then
begin
writeln ('Found fishing spot');
end;
end;
end;
end;

Always check this.
Do NOT call GetNPCs again in a for loop ever unless you have some really good reason to.

Cstrike

2010-10-08 23:40:09

Key topic: Tiles and walking anywhere (and Core functions)

If you want to do any walking and ensure you will walk that path all the time, this is for you. This will also cover minimap functions (since you can go from tile to the minimap), and will also cover going to the mainscreen.


Basics of Tiles

Runescape is literally tiles. Look on your kitchen floor if you have tiles, and notice how they form (usually) a square adjacent pattern. Runescape is just like that, and they're numbered.
You should understand Cartesian planes here as it will help.



Another in game example for those who are lost:
Source: http://farm1.static.flickr.com/30/55565723_fdbd7638b9.jpg?v=0

Tiles usually have irritating numbers. If I recall correctly, jagex starts their lowest number on the world map at Tile(2807,1567), so your tile will almost surely be larger than this.

Now how do you go about getting the tile that you want? You have two options?
1) Get Sumillion's path maker.
Note, I don't know how much he supports it as he seems to be gone ATM. Works great when you're making long paths but sometimes it can be off by one tile. Not too bad though
2) Debug your own

Here's a code that you can run and it will debug your position:
Note: You may be best to save this file somewhere for easy access in the future
program MyPositionFinder;
{$i SRL/SRL/Misc/SMART.scar}
{$i SRL/SRL.scar}
{$i reflection\reflection.simba}

// I copied this from somewhere, forget where though :(
procedure DeclarePlayers;
begin
NumberOfPlayers(1); // How many players? 1 account = "1', 5 accounts = "5"...
CurrentPlayer := 0; // Start at player "zero" (aka player 1)
Players[0].Name := '';//Your RuneScape UserName
Players[0].Pass := '';//Your RuneScape PassWord
Players[0].Nick := ''; //3-4 letters from name
Players[0].Active:= True;
Players[0].BoxRewards := ['Xp', 'mote', 'ostume', 'oins', 'aphire', 'ssence'];
end;

procedure SetUpSmartStuff;
begin
Smart_Server := 9;
Smart_Members:= False;
Smart_Signed := True;
Smart_SuperDetail := False;
end;

var mt : TTile; // Tile
begin
SetUpSmartStuff;
SetupSRL;
SetupReflectionEx(true);
DeclarePlayers;
LogInPlayer;
MakeCompass ('n');
SetAngle (true);
SetRun (true);
writeln ('2000');
wait (2000);
repeat
cleardebug;
mt := GetMyPos; // Get your global position
writeln (inttostr(mt.x) + '/'+ inttostr(mt.y)); // Output it
wait (1000);
until (false)
end.

So lets break this down so you understand… once again it's one easy line of code!

var MyCurrentTile : TTile; // Call your tile whatever you want, but define it as a "Type Tile"
MyCurrentTile := GetMyPos; // One line ;)
This function GetMyPos stores your current tile in a tile variable. You can also use some other one like GetMyLocPos I think (theres another derivative they kept in the Core.simba, I forget it though), but I like GetMyPos; more since I was brought up learning that ;).

Alright so now what do you do with it? Well you can do whatever you want with it if you know how to use TPoints.

The X number is stored in (assuming were using the variable name MyCurrentTile): MyCurrentTile.x
The Y number is stored in (assuming were using the variable name MyCurrentTile): MyCurrentTile.y
** Remember, if I called the variable LolBoobs, it would be LolBoobs.x …etc, don't think you have to use MyCurrentTile! That's just an arbitrary name I gave the variable

As you can see, you can debug this:
writeln (inttostr(mt.x) + '/'+ inttostr(mt.y)); // Output it
I called the tile mt, and this outputs it for you.

So how do you define a tile on your own if you know it?
Simple :)

var SomeTile : TTile; // Define it as a TTile
begin
SomeTile := Tile(3000,3450); // Make it equal Tile(x,y);
end;
There you go, name it Tile(xvalue,yvalue); MUCH LIKE A TPOINT!
If you understand TPoints, you won't have an issue here. If you're lost, go read a TPoint tutorial who will explain it in more detail. This guide is for reflection only… as someone else will explain TPoints better than I will for now.


How do I make a TTileArray?

Here is how!
var mytilearray : TTileArray;

begin
mytilearray := [Tile(3433,4432), Tile(3323, 4433), Tile (2323, 3434)];
end;


Important: How to use TPoints at first and then turn them into tiles

Why would we want to use TPoints and then convert them? That's an extra step…?

It is very important to use TPoints if youre going to be manipulating them
Reason: You can use the wizzy plugin! You cannot use the plugin with tiles, but you can use all the wizzy plugin with TPoints. If you don't know the power of the wizzy plugin, go read it in a tutorial right now!

But, then we have to reconvert them all?
Use these functions
PointToTile (TP : TPoint) : TTile;
// or
TileToPoint (tile : TTile) : TPoint;

If you know how to use arrays you can manipulate arrays from one to the other easily with a for loop.

Ok now how do I walk with them?
WalkToTile (Tile : TTile;, Randomness : Integer; FlagD : Integer);
Randomness is like the Mouse/MMouse random (which you should know)
FlagD… I honestly forget, I think the D stands for distance, so if you set it to zero, it waits until you get to the flag…

How do I walk big long paths perfectly? WalkToTile keeps screwing up!
WalkToTile does suck at times, and even I can't get it working right, so just use WalkPath;
WalkPath (MyPathOfTTileArray : TTileArray) : Boolean; // Oh yeah, now we can use it in 'if xyz then's!!
This function is utterly awesome. Give it a TTileArray and it will walk it flawlessly. USE THIS. Even if you have one tile, just declare it as a TTA [ttilearray] and USE THIS.


Edit: BTW reflection has R_Flag and R_FFlag. Never used it so I'm unsure if it works or not


Tiles to Minimap and Mainscreen
So you now can walk paths? What if you want to click on the tile on your minimap or mainscreen? What if you want to debug if it's even there?
This will be short, but lets look at some key procedures:
function TileOnMM(Tile: TTile): boolean; 
If you're walking to a key tile, and you want to have a failsafe, use this. If it's not on the minimap, it returns false
if not TileOnMM(Tile(3433,4433)) then Exit;
Not really a shining example, but take it as is.

Here's another good failsafer:
function DistanceFrom(TheTile: TTile): Integer;
Use it like this
 if DistanceFrom(Tile(3433,4343)) > 20 then
begin
writeln ('Too far away, exiting');
Exit;
end;

Lastly, another cool failsafer:
function WaitToMove(Timeout: integer): Boolean;
What if you're walking through a door and it suddenly shuts on you? Good failsafe to logout with.



Getting anything (like NPC location…etc) and finding it on your main screen

You need to understand the Runescape-Z-axis (note, this does not follow real life x,y,z… since y is the vertical height for real life physics, but here in runescape, z is the vertical axis)

So the Z-axis is height. If you specify the height of a tile from the dead center, and want height zero, it will put you on the center of the tile, but on the ground (where Z = 0), but if you want to get it lets say 5 pixels up, I assume the height will be greater (i dont know if height is based on pixels, someone should fill this in) (Z = 5)

Besides my really crap explanation, lets get to some examples.

function TileToMS(tile: TTile; height : integer): TPoint;
,
Input your tile and your height, and the program will create a TPoint of this location. You can now find things on the main screen :)
Play around with the height if you're having trouble.
Want a real life example?
var TP : TPoint;
begin
TP := TileToMS (Tile(3433,4433), 0); // Assuming we're near that tile...
MMouse (TP.x, TP.y, 3, 3);
if GetUpText ('ree') then ChopTree; // This isn't really part of the demonstration, but an example of where you go from here
end;

Of course there are failsafe commands you can use:
Function TileOnMS(TileX, TileY, Height : Integer) : Boolean;

HEIGHT
Height seems to go in pixel format
If you want to play around with height… try so. They have to be huge to get a significant jump.
To give you an example, I feel that a height of 200-300 would be around the NPC's groin area.

If you're having trouble with height, try TileToMS (Tile, 0); <– height of zero


This looks useful:
{*******************************************************************************
function GetTileHeight(tile: TTile) : integer;
By: BenLand100
Description: finds the average height of the global tile provided the tile is in
the current loading area and on a loaded plane.
*******************************************************************************}


Flawless uptext and menu text options
Okay maybe I shouldn't have a section on it, but look at this:

{*******************************************************************************
function R_ChooseOptionMulti(Options : TStringArray) : Boolean;
By: Drags111 - Based off nava2's and Lordsaturns.
Description: Chooses the first found option of "Options" from the Right
Click menu, returns True and Clicks if found, else it will Move the
mouse to a random Coord or select cancel.
*******************************************************************************}



{*******************************************************************************
function R_ChooseOption(Option : String) : Boolean;
By: Drags111
Description: Chooses the option "Option" from the Right Click menu, returns
True and clicks if found, else it will Move the Mouse to a random
Coord or will select cancel.
*******************************************************************************}



{*******************************************************************************
function OptionExists(option: string): Boolean;
By: Drags111
Description: Returns true if an option exists in the choose option menu. Choose
option menu does NOT have to be open.
*******************************************************************************}


///////////////////////////////////////////////////////////////////

{*******************************************************************************
function R_GetUpText: string;
By: Drags111
Description: Gets the UpText (the text in the upper left corner of RS).
*******************************************************************************}



{*******************************************************************************
function R_IsUpTextMulti(UpText: TStringArray): Boolean;
By: Drags111
Description: Returns true if any instance of the UpText is found.
*******************************************************************************}



{*******************************************************************************
function R_IsUpText(UpText: string): Boolean;
By: Drags111
Description: Returns true if UpText is found.
*******************************************************************************}


You can get FLAWLESS uptext!!
Let your mind wander and drool on that one, the functions are really self explanatory (you know GetUpText from SRL? Okay then you know this)

Cstrike

2010-10-08 23:41:56

Key topic: Finding Objects
So you can't click that rock? Can't open that door? Can't climb up that ladder? Want to interact with anything that has a dropdown menu when you right click?
Well read on and you can.



Everything in Runescape has their own ID. This is an object ID, and when you find the ID you can do a lot with it. The cool thing is, each 'state' has it's own ID… making your life easier.
For example, a rock with some iron in it may have an ID of 3849. The rock next to it with iron will probably have an ID like 3857. Each object has it's own ID, so you can't just take one ID from a rock in fally and consider it the same for everywhere.
But this is great, because with object finding you can target one specific thing only. What's even better, is different states have different ID's, so you won't need failsafes as much (but please, DO make them).

Example:
Door open ID: 3434
Door shut ID: 3949

//Pseduo code
if (Door.ID = 3434) then OpenDoor;
if (Door.ID = 3949) then WalkRightOnIn;
Isn't that cool? If its closed, open it, if it returns false (I just added some code in to see if its open), then walk on in ;)
This is great when irritating things stand in your way. Watch now as your bot opens the door, leaving all opponents with their mouth on the floor. They will never stop you now.


//Pseduo code
if (Rock.ID = 4445) then Mine; //4445 is a rock with ore
if (Rock.ID = 43894) then FindNewRock; //43894 is rock 4445 but mined
Well that's cool, we don't even need failsafes for rocks now technically. If it doesn't find an array of ID's that you get on your own (I'll show you how to later) then we know it's been mined.


What about that irritating ladder?
Well I don't need to make code because you get the point.

Object summary:
Objects are made of 3 things. Lets look at this piece of code:

function NewObject(ID, objType: integer; T: TTile): TRSObject;
begin
Result.ID := ID;
Result.objType := objType;
Result.Tile := T;
end;
So when you define some new object, it has to have
1) an ID (some number UNIQUE for each item in runescape)
2) objType (object type), there are only 4 and it's easy to use, I'll explains soon
3) A tile (quite useful for us, just do a TileToMS [MainScreen] and we can pretty much find that object with no problem)

Detail time:
  1. ID
  2. Each item has it's own unique ID. If you want to debug it, open TriBot or RSBot and then turn on the objects debug. This will show you all the ID's in runescape. This way you don't have to use my (or your own made) debugging script for walking around finding them. [*]Object Type
    There are four object types:
    • OBJECT_TYPE_INTERACTABLE = 0;
    • This is the one you're going to use all the time. Interactable objects are things like trees, doors, rocks…etc. If it is an object, I'd say 97% of the time you will be using this. If it's part of a wall then you know it's going to be the next one…etc
    • OBJECT_TYPE_WALLOBJECT = 1;
    • I never have used this [yet], this is probably wall switches. If I ever tackle randoms, this will save our asses in the abyssal random.
    • OBJECT_TYPE_WALLDECOR = 2;
    • I guess a good failsafe? If candle in room during quest and you see candle, then you = on the right track
    • OBJECT_TYPE_FLOORDECOR = 3;
    • Same as above
    [*]Tile
    Self explanatory, you know this now ;) (if not go up a post)

So how do I make code? What is this "Object_type_interactable"? I'm confused at how to use this…

Alright go find your rock, and lets do some code.

Key: When we use functions, they return them as a TRSObject (Type RuneScape Object). Don't worry, they're easy to use. Remember types? Like TPoint.x, TPoint.y, Tile.x…etc? Its the EXACT same, except it is like this:

TRSObjectVariableName.ID = some integer;
TRSObjectVariableName.Tile = stored Tile(x,y);
TRSObjectVariableName.ObjType = numbers 0, 1, 2 or 3


Now a lot of you right now are going "what the hell!? why is TRSObjectVariableName.ObjType = numbers 0, 1, 2 or 3?? How do I know which number to use!?"
Ask yourself which one of these four is it?
  • OBJECT_TYPE_INTERACTABLE = 0;
  • OBJECT_TYPE_WALLOBJECT = 1;
  • OBJECT_TYPE_WALLDECOR = 2;
  • OBJECT_TYPE_FLOORDECOR = 3;

So you found out your trying to do a rock? Well when you get the object, it's going to return:
TRSObjectVariableName.ObjType = 0;
A rock is not a wall object, and doesn't decorate the floor. We can interact with it (like mine) so it's clearly type 0.
But that doesn't really help you too much here, these constants become useful when you're finding an object ;)

So lets get to some code now, I want to find an object!

I want you to do this with the following code:
** If you just want to analyze the code without testing it, I will do that so you don't need to actually log in:
program ObjectFinder;
{$DEFINE SMART}
{$i srl\srl.scar}
{$i reflection\reflection.simba}

const
{---SMART Setup Constants---}
WORLD = 32;
MEMBERS = false;
SIGNED = true;
{---------------------------}

var
NPCs: TNPCArray;
i, ii, x, y: Integer;
FishTP : TPoint;
Me: TMe;

Procedure DeclarePlayers;
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

With Players[0] Do
Begin
Name := '';
Pass := '';
Nick := '';
Active := True;
Integers[0] := 0;
Pin := '';
End;
End;

// Get objects near you
//function GetInteractObjIDAdjacent (Tile : TTile) : Integer;
procedure FindObjNear;
var myObj : TRSObject;
myTile, newTile : TTile;
i : Integer;
begin
if not LoggedIn then exit;
myTile := GetMyPos;
writeln ('[--Objects--]');
newTile := Tile((myTile.x-1),myTile.y);
MyObj := GetObjectAt(newTile, OBJECT_TYPE_INTERACTABLE);
if MyObj.ID > 0 then
begin
writeln ('(W)');
writeln ('ID: '+inttostr(MyObj.ID)+', Tile('+inttostr(MyObj.Tile.x)+','+inttostr(MyObj.Tile.y)+')');
end;

newTile := Tile((myTile.x),myTile.y-1);
MyObj := GetObjectAt(newTile, OBJECT_TYPE_INTERACTABLE);
if MyObj.ID > 0 then
begin
writeln ('(S)');
writeln ('ID: '+inttostr(MyObj.ID)+', Tile('+inttostr(MyObj.Tile.x)+','+inttostr(MyObj.Tile.y)+')');
end;

newTile := Tile((myTile.x+1),myTile.y);
MyObj := GetObjectAt(newTile, OBJECT_TYPE_INTERACTABLE);
if MyObj.ID > 0 then
begin
writeln ('(E)');
writeln ('ID: '+inttostr(MyObj.ID)+', Tile('+inttostr(MyObj.Tile.x)+','+inttostr(MyObj.Tile.y)+')');
end;

newTile := Tile((myTile.x),myTile.y+1);
MyObj := GetObjectAt(newTile, OBJECT_TYPE_INTERACTABLE);
if MyObj.ID > 0 then
begin
writeln ('(N)');
writeln ('ID: '+inttostr(MyObj.ID)+', Tile('+inttostr(MyObj.Tile.x)+','+inttostr(MyObj.Tile.y)+')');
end;
end;



procedure MainLoop;
begin
if not LoggedIn then exit;
SetAngle (true);
MakeCompass ('n');
SetRun (true);
wait (random(500));
repeat
FindObjNear;
wait (1000);
cleardebug;
until (false)
end;

begin
Smart_Members := MEMBERS;
Smart_Server := WORLD;
Smart_Signed := SIGNED;
SetupSRL;
DeclarePlayers;
LoginPlayer;
cleardebug;
MainLoop;
end.

Okay with this, go stand next to your favorite rock, or tree.
THIS IS ASSUMING YOU DON'T WANT TO USE RSBOT/TRIBOT/Any bot TO EASILY GET YOU THE ID.
Yes I made this just for you :)
Only works on the tiles N/S/E/West of your character though, no NE/SE/SW/NW… sorry…


The code declares a TRSObject;, then searches N/S/E/W of you, and debugs what they are. Explore it a bit and get a feel ;)

Got any quick code for me if I know the tile?


var myObject : TRSObject;
myObject := GetInteractableAt (YOUR TILE HERE);
This will get whatever object is at the tile you input.

Okay I know how to get it, but how do I move my mouse to it? That's the most important part!

Be inventive, remember, we know the tile (it has to be on a tile, and we have to get it from a tile…), so call something like this:


TP := TileToMS (TILE_HERE, 1); // Height of 1, if it doesn't work, change the height or check your tile
// Now we have turned the tile into a TPoint on the mainscreen
Mouse (TP.x, TP.y, 2, 2, false);
if R_ChooseOption ('option here') then writeln ('Function carried out');

So there you go.



Now of course we have cool procedures like this:
{*******************************************************************************
function GetObjectByID(ID: Integer; objType, MaxDist: Integer): TRSObject;
By: Drags111
Description: Returns the nearest object with the ID. Sorted from closest
to your character to farthest.
MaxDist: This is the maximum distance from your player you wish to
search. The smaller the number, the faster the search is
completed. The maximum is 52.
*******************************************************************************}
If you know your ID (I gave you 2-3 ways to find it), and know your ObjType, you're set. I don't know what MaxDist is… maybe it's tiles? I doubt it's pixels. Experiment with this.

So lets say you want to find Door ID #4599, but it could be anywhere on the map. Do this:
1) What is my ID?
4599
2) What type is it?
interactable
So I'm going to use the constant value OBJECT_TYPE_INTERACTABLE so when other people read my code they know its interactable
3) Lets just assume 52 for the hell of it

MyObject := GetObjectByID (4599, OBJECT_TYPE_INTERACTABLE, 52);
So why do I use that constant instead of the number 1? Because it's readable code. Always use this unless you have a good reason otherwise.
A good reason could be you putting a variable in there, and debugging from 0 –> 3.


These are the basics, if you're still lost, post here. Check out the Objects.simba file and learn!

Remember:
1) Your object is always defined with a XXX.Tile, XXX.ID, XXX.ObjType
2) You need to know where the object is usually (unless you use a specialized function like above) before you can do stuff with it.



Chat
Chat has everything to do with that box at the bottom. This is mainly for player to player chat, if you want to do NPC to player chat you need to go to the interfaces section, but it wouldn't hurt to read here since some functions are covered.
If you're interested in an autotalker, this is the section for you. All the text players say you can extract and run through your own response machine if you're good enough. This can also get the difference between private messages and in game chat. Cool!


From now on in, it's going to be a bit tighter since I rarely use these (until the next post). I'll tell them as it is, though I'm sure if you read everything up till now and have a good SRL grasp, these won't be a problem.

This is more of a show and tell since these are really self-explanatory if you look at the code

function GetChatMessages(ChatType: string; Visible, NoName: Boolean): TStringArray;
{
Valid ChatType Params:
'chat', 'normal': Normal chat
'pm', 'private': Private messages
'trade': Trade chat
'black', 'message': Black chat messages
'all': All of the above
}

Based on the parameters, you'll see that you just call something like this:

TSA = TStringArray okay?

TSA := GetChatMessages('chat', true, true);
I'm telling the function
a) 'chat' = get the chat box messages only
b) 'Visible = true' I assume this means if it's in the chat box?
c) 'NoName = true' probably don't attach a name to it

Then you invoke your TStringArray reading tools to find out what you want.



NPC chat:
function FindNPCText(text: string): boolean;
By: Drags111
Description: Searches through the known talking interfaces to search for the
inputed text.
This returns true if you find text from that NPC. Quite useful, and so is this:
{*******************************************************************************
function R_ClickToContinue: boolean;
By: Drags111
Description: Does as the name suggests. Clicks the 'click here to continue' crap
*******************************************************************************}
I wish I found this earlier, I kept coding my own "click continue" and it was starting to piss me off.


Well there's more in the chat file, go have a look :)

Lastly before we leave this topic, if you start finding <p=34394> or some number before the text, that's probably java color code. If you want, there is a way to get rid of it through string manipulation. I forget how though… there's a few tricks. I made a post (and so did Bad Boy) in the SRL public help section, if you want… search it with advanced search at the top.


Equipment
If you want to find your ammo amount or see if you're wearing armor, this is the section for you. I personally didn't find much use of this section since most players normally equip their bots with the items and then run a specialized script… but who knows, maybe you're going to make that all in one script and will need to check if the armor is on, or how much ammo you need.

As I said, unfortunately this section isn't nearly as useful as tiles or finding NPC's are. Regardless, awesome failsafes are here.
What if you run out of arrows?

Lets mess around with some basic functions in equipment.simba:

// Use this logic flow
if IsEquippedName('Bronze arrows') and R_GetAmmoCount > 0 then ContinueFiring;

Make sure your ranger not only has a type of arrow, but can fire it.

Remember, you can make a TStringArray and check all types or arrows:
var StuffToFire : TStringArray;
function DoWeHaveAmmo : Boolean;
var i : Integer;
begin
result := false;
StuffToFire := ['Bronze arrows','Iron arrows','Steel arrows','Mithril arrows']; // No one is going to use addy/rune arrows for training, will they?
for i:=0 to high(StuffToFire) do
begin
if IsEquippedName (StuffToFire[i]) then result := true;
end;
if result then writeln ('We have arrows!') else writeln ('We do not have arrows! Oh no!');
end;


Of course though, we always have someone one step ahead of me:
{*******************************************************************************
function IsEquippedNameEx(Names: TStringArray): boolean;
By: Drags111
Description: Returns true if there is an item equipped with one of the Names.
*******************************************************************************}


What about this equipment items set? How can I debug my own names
Well lets look at some definitions…
By the way, this area I'm really weak in. Sorry, I'll do the best I can.

function GetEquipment: TEquipmentSet;   
So this function appears tor return a TEquipmentSet, so we'd have to call:
var MyEqSet : TEquipmentSet;
Call that somewhere. I assume you just run it like this:
var MyEqSet : TEquipmentSet;
MyEqSet := GetEquipment; // Woot, another one line of code
I assume that's enough to be good to go. I haven't tried this yet :(

Now once we have it, the file seems to define it as the following types:

      Result.Items[i].ID  := SmartGetFieldInt(child, hook_interface_GetID);
Result.Items[i].Name := TrimItemName(GetJavaString(textbytes, 255));
Result.Items[i].Count := SmartGetFieldInt(child, hook_interface_GetStack);
Result.Items[i].isAmmo := (Result.Items[i].Count > 1);
Therefore the items probably have something like this to be called:
var MyEqSet : TEquipmentSet;
MyEqSet := GetEquipment;
writeln (ToStr(MyEqSet.Name)); // I haven't run this, experiment with it :)

Unfortunately this area is not to well documented, and I do not see anywhere in the file of the chart that Drags111 mentioned, nor do I see any other function that uses it.
Looks like your innovation will grow if you can learn this. Practice, this will be great for exercising type knowledge! Sorry I can be of no further help.

Gametab
This is for useful things like run energy, stat experience, if you're running or not (and how much energy to rest to), getting skill levels…etc.
If you understand interfaces (the next big topic I will be covering), then this section is not totally necessary. The codes I will show you are more or less specific developed functions rather than something standalone like tiles.


Well if you thought equipment was a letdown, prepare to have your letdown drop to an even lower level.

Just look at the function names and they honestly tell you exactly what they do.

1) procedure R_Rest(MaxEnergy: integer);

2) function R_IsRunning: boolean;

3) function R_IsResting: boolean;

4) function R_GetMMLevels(Which: string): Integer;
This is cool because you can use it like this:
{    
'hitpoints', 'hp': Result := StrToInt(GetInterfaceText(748, 8));
'prayer', 'pp' : Result := StrToInt(GetInterfaceText(749, 4));
'run', 'energy' : Result := StrToInt(GetInterfaceText(750, 5)); }
if R_GetMMLevels('hitpoints') < 100 then RunFromFight;
Great for a fighter script!

Lastly, the best part which I have no clue how to use are skill harvesting stats:
{*******************************************************************************
function R_GetSkillLevel(skill: variant): Integer;
By: Nava2
Description: Gets the Level stored at skill. Skill can be the string or const.
The const is significantly faster.
*******************************************************************************}
I don't quite understand the code or how to use this. Maybe try entering "Fishing" as the skill, or try the number 10. That seems to be the fishing number from previous scripts.
This can be useful for proggys :)

Alright, time to get onto some serious topics again that are important. Check out the next post! Hopefully I'll have interfaces done soon!

Cstrike

2010-10-08 23:43:00

Inventory
All inventory functions are unique in the fact that it's all based around the ID you input. Anything to do with items in your inventory whether it be counting them, moving them, seeing if they're there, or even seeing if the spot is empty or full is all done with the inventory functions. This is great for seeing if your inventory is full with lobsters or runite rocks. It's also awesome how you can specifically target any item without having to do any color finding!

Once again, this will be short because it's relatively simple. You need to know two things:

1) What you'd like to do
2) The item ID

For the item ID, just debug it with RSBot, or search it on the grand exchange and copy the numbers at the end.
Lets say you want air runes and RSBot is broken, do this:

Done! You now have everything you need to proceed with the coding.

Most of the examples are really self explanatory, and if you're able to code SRL at the beginner level, this is probably easy for you:

{*******************************************************************************
function GetInvItemAt(slot: integer): TInvItem;
By: Drags111
Description: Returns a TInvItem from the specific slot [1-25]. If slot is empty,
it returns NullInvItem;
*******************************************************************************}

Pretty simple, slot is probably 1–>28 I think…
If you want to see if an item is there, just do


var
InviItem : TInvItem; // The code tells us it returns a TInvItem!
begin
if (InviItem = NULL_INVITEM) then Writeln ('That spot is empty');
end;

The other ones are much more simple though:

{*******************************************************************************
function R_CountItemName(Name: String): Integer;
By: Drags111
Description: Returns the number of items in your inventory with the Name.
*******************************************************************************}


{*******************************************************************************
procedure R_DropAllItems;
By: Drags111
Description: Drops all items in the inventory.
*******************************************************************************}


{*******************************************************************************
function R_ClickItemID(ID: Integer; Left: Boolean; Action: String): boolean;
By: Drags111
Description: Clicks the first item in the inventory with the ID, and if left is
set to true, Left clicks and performs the action. Otherwise, right
clicks. Ex: R_ClickItemID(123, false, 'Wield');
OR
R_ClickItemID(123, true, ''); //Left clicks (use).
*******************************************************************************}

So it's quite simple, just check Inventory.simba for the commands!


Before we move on, remember that a TInvItem has the following:

    Writeln('Slot: '+ToStr(Items[i].Slot));
Writeln(' Name: '+Items[i].Name);
Writeln(' ID: '+ToStr(Items[i].ID));
Writeln(' Stack Size: '+ToStr(Items[i].ID));
Writeln(' Actions: '+ToStr(Items[i].Actions));
That was borrowed from the DumpCommand (Dump means to dump the data for debugging)

Therefore you can work with all of those, example:

If you are looking for 1k in your inventory of coins, get the items in the inventory, then if Items.Stack > 999, continue on with the function. That pseduocode should give you some idea of what you can do with those :)


Interfaces: A difficult topic made simple
Talking with an NPC? Seeing a new screen pop up like a bank screen, a deposit screen, a random interface thing? What about finding something on the screen that isn't covered above? This is the place for you.
Do not be intimidated by these, they're quite easy. You NEED RSBot for now or you can't really do much. You can actually work around RSBot if you know what you're doing, but most methods crash Simba if you Dump all the interface data. This may be fixed soon, I don't know. RSBot from Powerbot.org is the way to go since it has an interface explorer (and some options that reflection at the moment just doesn't have


Unfortunately… interfaces at the moment are REALLY underdeveloped for amateur users, but I'll clear that up for you. This guide will not only teach you how to use them, but how to make your own hooks for grabbing the data that you want! Cool huh?

I'll be using RSBot here, so go download the newest version, Log In, and run the script "Interface explorer". I'm using RSBot version 2.08, though everything from 1.91 up should have interface explorer. To get it, Go File–> Run Script –> choose Interface Explorer and hit StartScript at the bottom right.



Alright, so we open the interface explorer, and it lists all the interfaces for us:
This is what you see:

To get the interfaces, all you have to do is click on the interface folder and expand it. Inside, click on what component you want and a box will come up on the screen in yellow [very useful] and some data that you can use.


See? That is clearly the run thing.

Notice the texture number? If we click on run, that number will probably change. Therefore if you get the Texture number (code for that later on), and it's not = to a certain number, you can tell what state it is in and then do what you want from there.



What is an Interface, Child and Component?

Interface is the main group that holds all the components together. For example, one interface would hold all the buttons for your stats, another would hold your inventory stuff, another is a banking one, another is your quests…etc

Child is an interface within an interface. This is more for organization. Sometimes jagex does this for banking stuff, the components in the interface folder are general borders and stuff, but a child folder inside will have all the components for items

Components are the stuff you interact with (usually)



So why am I getting random squares? This interface is pointing to nothing!?!?

Guess what? All the interfaces are sort of overlaid, for example:



But now we change over to the log out menu…


Aha! Makes sense :)
See how they're overlaid? Don't be fooled.


So how can you use this?

Lets say we want a failsafe to wait until Interface 165 comes up, we go to Interfaces.Simba and can use:

{*******************************************************************************
function ValidInterface(idx: Integer): Boolean;
By:
Description: Returns true if the interface is valid.
*******************************************************************************}

Here's a great failsafe for you:


MarkTime(t);
repeat
wait (50);
until (ValidInterface(165)) or (TimeFromMark(t) > 15000)
If the interface doesn't come up in 15 seconds, it times out. Otherwise, it proceeds!


Now if you want to get text to see if an interface is up (this is good for Click Here To Continue crap), use this code:

{*******************************************************************************
Function GetInterfaceText(ParentI, ChildI: Integer): String;
By: Method
Description: Returns the Child's text.
*******************************************************************************}
Note that ChildI should be your component number…


Now as you can see it ends here, it's very underdeveloped. What if you want stuff from a Child's component? Like 165, 6, 3?
Zephyrsfury made some code that can do just that, take a look:
function GetComponentText(ParentI, ChildI, CompI: Integer): String;
var
Text, Child, Comp: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Comp := SmartGetFieldArrayObject(Child, hook_interface_GetChildren, compI); //Getting the children components of the Child component
Text := SmartGetFieldObject(Comp, hook_interface_GetText);
Result := GetJavaString(Text, 255);
SmartFreeObject(Text);
SmartFreeObject(Comp);
SmartFreeObject(Child);
end;

Awesome.


What if you want a hook like X or Y, or something on there like Component ID?

Well you have to make your own. Making them is somewhat difficult, and only experts will understand it. Try looking at this code I made for you can see how they all differ between one another. Sorry I'm not actually teaching you this, it's quite advanced. I apologize. The key is knowing what SmartGetField command to use, and what hook you want.
Actually, here are a bunch of ones I made or inherited from others :) ENJOY
function GetComponentID(ParentI, ChildI, CompI: Integer): Integer;
var
Child, Comp: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Comp := SmartGetFieldArrayObject(Child, hook_interface_GetChildren, compI); //Getting the children components of the Child component
Result := SmartGetFieldInt(Comp, hook_interface_GetID);
SmartFreeObject(Comp);
SmartFreeObject(Child);
end;

function GetComponentStack(ParentI, ChildI, CompI: Integer): Integer;
var
Child, Comp: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Comp := SmartGetFieldArrayObject(Child, hook_interface_GetChildren, compI); //Getting the children components of the Child component
Result := SmartGetFieldInt(Comp, hook_interface_GetStack);
SmartFreeObject(Comp);
SmartFreeObject(Child);
end;

function GetComponentX(ParentI, ChildI, CompI: Integer): Integer;
var
Child, Comp: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Comp := SmartGetFieldArrayObject(Child, hook_interface_GetChildren, compI); //Getting the children components of the Child component
Result := SmartGetFieldInt(Comp, hook_interface_GetX);
SmartFreeObject(Comp);
SmartFreeObject(Child);
end;

function GetComponentY(ParentI, ChildI, CompI: Integer): Integer;
var
Child, Comp: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Comp := SmartGetFieldArrayObject(Child, hook_interface_GetChildren, compI); //Getting the children components of the Child component
Result := SmartGetFieldInt(Comp, hook_interface_GetY);
SmartFreeObject(Comp);
SmartFreeObject(Child);
end;

function GetChildID(ParentI, ChildI: Integer): Integer;
var
Child: Integer;
begin
Child := GetInterface(ParentI, ChildI);
Result := SmartGetFieldInt(Child, hook_interface_GetID);
SmartFreeObject(Child);
end;


So thats how interfaces work in a nutshell. If you have any questions or if I forgot anything, please ask.
BTW if your RSBot doesn't accept your clicking, turn the input on at the top right.

Ground items: In the beta phase of development
This is for all the items that are on the ground. This part was broken and sort of still is, only because you have to clear the array at the end. I'll explain:

This won't take too much time since it's sort of underdeveloped AND I have no idea what a node means, so I only really know how to use one command, which is the last two:

Ground items are declared with a
var GIA : TGroundItemArray;
Or TGround item if you please.


If you want to define a ground item, or see what each item has to offer you, this is it:
{*******************************************************************************
function NewGroundItem(id, stack: integer; T: TTile): TGroundItem;
By: Drags111
Description: Returns a new instance of a TGroundItem
*******************************************************************************}
function NewGroundItem(id, stack: integer; T: TTile): TGroundItem;
begin
Result.ID := ID;
Result.Stack := Stack;
Result.Tile := T;
end;

So when we grab a ground item we get the ID (which you saw in the inventory section), the stack (useful), and Tile (even more useful).
We can take the tile and do things like:
if not TileOnMS then // Do TileToMM functions and move near it
if TileOnMS (GroundItem.Tile, 0) then PickUpFunctionHere;

The last one is this:
{*******************************************************************************
function GetItemsNear(T: TTile): TGroundItemArray;
By: Naike
Description: Gets all the items near you. I suggest not going above 2.
1 = 3*3 -> 9 tiles [] [] []
2 = 5*5 -> 25 tiles [] You[] <- GetItemsNear(1)
3 = 7*7 -> 49 tiles [] [] []
and so on..
*******************************************************************************}

Useful if you miss your spot ;)

KEY POINT YOU MUST NOT FORGET!
ALWAYS free your ground item arrays at the end or they will crash your program. Apparently there's some memory leak somewhere, sort of over my head how to fix it.

Therefore just call this:

 YourGroundItemArrayHere := [];
And you're good. Call it AFTER you're done with your GrounditemArray
Hey, maybe in the future you won't even need to use this line of code!

Conclusion:
Subtitle: A Thought provoking discussion of how to think outside the box with reflection: Accomplishing what color just cant realistically


So now we reach the end of our journey, but what can we do now?

Reflection has the ability to do some things color just cannot realistically do. Do not get me wrong, color can pretty much do everything, but try coding Dragon Slayer in color. With a developed reflection you could do it in many lines less than color would, and with more failsafes. The reason is, you can find NPC's no problem, you can get wall items no problem, you can attack monsters and get your HP bar no problem. With color, you need to code a crap load of TPA's. Of course, color wins because reflection breaks when updates come out, but we have some awesome people here who update them.

Ideally you should either go full reflection, or do color with reflection backups. I am biased towards reflection because of the accuracy. With color, if you misclick you could be in for some trouble unless you are an experienced colorist. Of course, when you get to the levels of SRL developers, you can code color usually better than anything, and everything above I have said would be wrong, but for people like you and me who want quick efficient code to do the trick, reflection is for you.

I'm working on a bank solving thing… it's irritatingly huge, but based on ID's you input, it will go into a bank and take out the item you want flawlessly. The reason this beats color is because you only need to call the ID that you want (or ID's), but with color, you have to either use something like MSI that has the pre-determined uptext AND DTM to get it (which consumes memory if someone forgets to free it), or one line of code plucks it out for you and is done.


Places where Reflection holds a high advantage is the ability to sense things far away, or things that are hidden from color.

If you are standing over a rock, color will not be able to find it, but compared to reflection – it KNOWS it's there and will click it. Of course if you suck at coding this can be used against you from a report, but generally you should be fine.

The biggest advantage in reflection is the global Tile system. You can easily walk a HUGE path in 3 lines of code, whereas with color and failsafes it would take possibly hundreds, if not thousands if we want to make a script that will walk from the runite rocks in the wildy to edgeville borders.
Once again, do not get me wrong, color has it's place. I even use color still, but sparingly when I can shrink my code with reflection.
Reflection allows a new dimension of avoiding players. What if you're one of those guys who casts curses on zammy mages? If someone logs in under you and reports you, you're dead. How do you avoid this? You can use color and search uptext every so often, or you can gather any near players with reflection code, and then Log Out almost immediately to ensure you are not reported.

The key is to use both, but you can do either or in both color or reflection. I prefer reflection because of what it can do. If you don't believe me, take a look at my worldwalker I submitted for MSI. It can retrieve you from almost anywhere in (what will be when completed) maybe 1800-2000 lines of code. Imagine how much coding it would take in color to recognize you anywhere in runescape and then retrieve you properly with failsafes? That would be beyond my skill.

If you have any questions, please post. Reflection only, color belongs in the help section, but NEVER forget that you should mix both if you can! One can always back up another, and there are some places where color > reflection!.
Despite this, some of you will end up becoming hooked on reflections, because you don't need to learn the hard stuff like TPA's. Of course, this WILL shoot you in the foot because you need TPA and ATPA knowledge to progress… though people will use Reflection because it's an easy way to do something relatively perfectly with minimal time input.



What are you waiting for? We need a Dragon Slayer solver!

i luffs yeww

2010-10-09 01:00:49

:) Thank you for finally updating this stuff. ^^

Coh3n

2010-10-09 01:44:07

Hey nice job! I can't wait to see when it's done. ;)

Just a suggestion, but you should change the yellow. I can't read it at all on my screen.

Cstrike

2010-10-09 11:32:55

Yellow changed to orange, hopefully more readable ;)


I'm going to do 1 or 2 posts a day and finish this hopefully soon.


In addition I'm also hopefully going to talk to pyroryan and learn more so I can update this in a down to earth tutorial hopefully

pyroryan

2010-10-09 18:56:34

From: cstrike
Yellow changed to orange, hopefully more readable ;)


I'm going to do 1 or 2 posts a day and finish this hopefully soon.


In addition I'm also hopefully going to talk to pyroryan and learn more so I can update this in a down to earth tutorial hopefully


Hopefully you understand interfaces a bit more now. There are still many functions that need to be developed for it before it truly becomes useful.
In regards to the tutorial, nice job! I only skimmed it but its enough to see that this is a masterpiece in reflection tutorials. You touched on each topic enough to achieve understanding, so without a doubt, I could see this becoming a must-read for beginning reflection scripters.

Continuing from our IRC conversation, I see no problems with including interface constants (like the inventory/bank/etc interface)in the reflection svn.
If you still have more questions for me, send them via PMs or we'll run into each other on IRC again.

From: cstrike

If they JUST went out of date due to an update that happened 2 hours ago, you're **** out of luck. Sorry, but humans have to update all the various letter based hooks. Takes a while and is a bit irritating.
If you're afraid to go editing, just wait for the reflection update. Depending on how busy people are… may take a few days though.

If I notice that hooks are outdated when I wake up, I'll usually have most/all of the hooks updated by lunch (depending on when I have school/classes/other stuff/just busy in general). Then I'll inform Naike, who will update the svn asap from there.

Shuttleu

2010-10-09 19:04:27

From: cstrike
**NOTE: Ground items will not be covered, to my knowledge they are out of date
ground items are not out of date, there is a hole in SMART that stops us from using them
as soon as someone can figure out where the hole is, we can fix it up and use ground items

~shut

NCDS

2010-10-09 20:12:15

Nice one cstrike :)

Naike

2010-10-10 08:40:48

I love you.

E: Objects are out of date, not working correctly.
EE: Grats on two squares @ Rep ;)

Cstrike

2010-10-10 14:56:53

From: Naike
E: Objects are out of date, not working correctly.

From: Shuttleu
ground items are not out of date, there is a hole in SMART that stops us from using them
as soon as someone can figure out where the hole is, we can fix it up and use ground items
~shut

D:
If they're out of date and that's the only reason, how do we fix it?
If there is a hole in SMART, who should be the one people go to, whom will fix it? Benland?




New post coming up soon ;)

Naike

2010-10-10 17:32:26

From: Shuttleu
ground items are not out of date, there is a hole in SMART that stops us from using them
as soon as someone can figure out where the hole is, we can fix it up and use ground items

~shut


saywut?

Who told you this?
and what is this hole?

Does BenLand know about this?

Shuttleu

2010-10-10 17:45:13

From: Naike
saywut?

Who told you this?
and what is this hole?

Does BenLand know about this?


by hole i meant memory leak
http://villavu.com/forum/showpost.php?p=727635&postcount=9

~shut

Wyn

2010-10-11 21:51:07

Finally a updated guide. I'm printing this…

Cstrike

2010-10-11 22:11:10

From: wyn10
Finally a updated guide. I'm printing this…


I'm goign to attempt to start a new section soon :)

Wyn

2010-10-11 22:49:23

From: cstrike
I'm goign to attempt to start a new section soon :)


Go go power-ranger.

Cstrike

2010-10-11 22:57:33

From: wyn10
Go go power-ranger.


Section done, power ranger transformed :spongebob:

Wyn

2010-10-12 23:23:15

From: cstrike
Section done, power ranger transformed :spongebob:


Got 19 pages of goodness.

Cstrike

2010-10-13 12:29:51

From: wyn10
Got 19 pages of goodness.


I'm going to work on the next few sections today/now

ALSO I'm adding in something important to teh NPC section which you amy way to see. I'm putting it at the bottom, look for the edit.
EDIT: Chat is done, I may do equipment later today since these topics will be small.

pyroryan

2010-10-14 13:18:48

Question, when you're making the tutorial, do you test every function you include? If you do, then we don't need to test the functions if they're covered in your tutorial :)

Cstrike

2010-10-14 13:43:49

From: pyroryan
Question, when you're making the tutorial, do you test every function you include? If you do, then we don't need to test the functions if they're covered in your tutorial :)


Id say I've tried most of them (minus the ones like chat, or fringe ones that I don't use).

Ones that have this code in them
Procedure DeclarePlayers;
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

With Players[0] Do
Begin
Name := '';
Pass := '';
Nick := '';
Active := True;
Integers[0] := 0;
Pin := '';
End;
End;
Should work because I tested them :)

Cstrike

2010-10-28 21:16:16

I don't double post often but… the guide is FINISHED :D [Plus my last post is almost over 2 weeks old]

Claymore

2010-11-07 13:52:03

Thank you! You have taught me well and now im gonna go back to scripting ^^

Heavenguard

2010-11-25 12:56:43

Beautiful Tutorial bro.

Death12652

2010-12-08 11:14:40

I used your TTile position finder and I keep getting this…


-1/-1

I copied your script and it loads and logs in just fine but after it clears the debug that's what I get. No matter where I go.

Cstrike

2010-12-08 12:21:53

From: death12652
I used your TTile position finder and I keep getting this…


-1/-1

I copied your script and it loads and logs in just fine but after it clears the debug that's what I get. No matter where I go.


In your hooks.simba file, what is your hooks version and latest hookrev number?

Craig`

2010-12-08 12:22:26

Although I don't use Simba this was an interesting read, cheers.


function AreWeNotFishing : Boolean;
begin
Me := GetMe; // I will explain this later, it basically gets a bunch of information on yourself
if Me.Animation = FishingAnimation then result := false else result := true;
end;

// can be changed to..

function AreWeNotFishing : Boolean;
begin
Me := GetMe; // I will explain this later, it basically gets a bunch of information on yourself
Result := not (Me.Animation = FishingAnimation);
// or even Result := not (GetMe.Animation = FishingAnimation);
end;

..no biggie^ though.

~ craig.

lordsaturn

2010-12-08 12:44:20

From: Craig`
Although I don't use Simba this was an interesting read, cheers.


function AreWeNotFishing : Boolean;
begin
Me := GetMe; // I will explain this later, it basically gets a bunch of information on yourself
if Me.Animation = FishingAnimation then result := false else result := true;
end;

// can be changed to..

function AreWeNotFishing : Boolean;
begin
Me := GetMe; // I will explain this later, it basically gets a bunch of information on yourself
Result := not (Me.Animation = FishingAnimation);
// or even Result := not (GetMe.Animation = FishingAnimation);
end;

..no biggie^ though.

~ craig.


can be changed to
function AreWeNotFishing : Boolean;
begin
Result := GetAnimation <> FishingAnimation;
end;

Cstrike

2010-12-08 13:39:08

From: lordsaturn
can be changed to
function AreWeNotFishing : Boolean;
begin
Result := GetAnimation <> FishingAnimation;
end;


Yeah thats my bad, put it in my guide but tried to use the commands so people could see what's going on ;)

Death12652

2010-12-08 18:05:44

My hooksrev number is 2 and the client version number is 632

Cstrike

2010-12-08 18:13:35

From: death12652
My hooksrev number is 2 and the client version number is 632


My file reads:
const
ClientVersion = 633;
HookRev = 2;

Amfortas

2011-02-05 14:20:43

very good tutorial, makes everything clear to me..