SRL Archive - Outdated Tutorials

[#29] SRL user-defined procedures!


EvilChicken!

2008-12-09 11:15:02

SRL user-defined procedures!



With the release of revision #29, SRL now has a new feature available; user-definable procedures. Simply explained, they consist of an array of procedure variables which are called within various common SRL procedures and functions. It is nothing complicated at all, this is how the procedure variables are declared:

var
srl_Procs: array [0..8] of procedure();

The main purpose of these, as you'll find more about in this tutorial, is to assign your procedures of preferral, to these procedure variables. These assigned procedures will then be called whenever certain SRL functions which call these procedures, are called. For example, if a procedure is assigned to srl_Procs[SRL_AntiBan], that procedure will be called whenever Flag or FFlag is called. This might be useful for i.e. doing antiban actions while waiting for the flag to disappear of the minimap.

Before you continue reading, you might want to take a look inside the globals.scar include (found in Includes/SRL/core folder). Once you open the include, scroll down to where you see all the SRL_On(…) constants. Here, you'll see which procedure variables that currently are available.

const
srl_AntiBan = 0; { Your AntiBan procedure to be called during various SRL functions and procedures. (Flag, FFlag) }
srl_OnFindMod = 1; { After a player or Jagex mod is detected talking in the chat box. }
srl_OnFindDead = 2; { After the text 'Oh dear you are dead' is detected. }
srl_OnFindFight = 3; { After detecting a fighting random. }
srl_OnFindTrade = 4; { After the trade has been attempted (either success or failure). }
srl_OnNextPlayer = 5; { While the players are logged out and before CurrentPlayer changes. }
srl_OnSendStats = 6; { After SRL Script Stats are sent to the server. }
srl_OnRandomCall = 7; { Called in FindNormalRandoms, FindInventoryRandoms, FindNonInventoryRandoms. (NOT ONLY WHEN RANDOMS ARE DETECTED). }
srl_OnFindRandom = 8; { After a random event is detected. (FNR, FIR, FNIR, FT) }

At the time of me writing this, the procedure array consists of 9 procedure variables. All of them have self-explanatory names and are clearly stating upon which situations they are called. In addition, the comments should help you understand every single one of them. But - remember that these constants only are integers which represent the position of the procedure that the constant represents, in the [0..8] array of procedures.

Regarding that, let's take this constant as an example:

const
srl_OnFindRandom = 8;

That constant has an assigned value of 8, meaning that calling SRL_Procs[srl_OnFindRandom] would be the same as calling SRL_Procs[8] (Keep that in mind, we'll get right back to that.)

Inside AntiRandoms.scar, where all the random detecting functions are, we currently have four procedures/functions that use the above mentioned constant. Whenever one of the procedures in that include (FindNormalRandoms, FindInventoryRandoms, FindNonInventoryRanoms, FindTalk) detects a random event in RuneScape, something like this gets executed:


if (srl_Procs[srl_OnFindRandom] <> nil) then
srl_Procs[srl_OnFindRandom]();

Two lines. So simple, yet so awesome. The first line, if (SRL_Procs[SRL_OnFindRandom] <> nil) then, checks whether the procedure SRL_Procs[SRL_OnFindRandom] variable is assigned to an actual procedure. Earlier above, our constant example "SRL_OnFindRandom" is declared as nothing more than an integer constant, yes? That makes the two lines above be the same as simply checking whether SRL_Procs[0] points to a procedure. So, basically - if a procedure has been assigned to SRL_Procs[SRL_OnFindRandom], this line returns true.

And, the next line ofcourse calls the procedure assigned to the procedure variable, if it points to a procedure.

Assigning a procedure to one of the procedure variables is really easy, it's almost like assigning normal variables! Just do like this:

srl_Procs[srl_OnFindRandom] := @AfterRandom;

I told you it was easy!
In the example line above, we assign srl_Procs[srl_OnFindRandom] to a procedure named AfterRandom; which should be declared in your script somewhere above where you actually assign it to a srl_Proc. Just don't remember to add a "@" before the procedure's name, as this is crucial for SCAR to interpret it correctly. Also, the procedure must NOT have any parameters!
And that's all there is to it, now AfterRandom will be called every single time a random is found!

Now with a full script example!

program SRLprocvarsexample;
{.include SRL/SRL.scar}

procedure LOL;
begin
WriteLn('Yay?');
end;

begin
SetUpSRL;
srl_Procs[0] := @LOL; { Here, we assign the SRL_Procs[0] variable (declared in Globals.scar) to procedure LOL;. }
if (SRL_Procs[0] <> nil) then { Not really needed in this exact case, but just an example on
how to check if a procedure variable actually is assigned to a procedure. }
SRL_Procs[0](); { Here, we finally call the procedure assigned to the variable. }
end.

So, what is this system really good for?
It has countless possibilities, the limit here is your mind.
For example, why not do some quick antiban while waiting for the flag to dissapear? Switch gametabs, or something else less time consuming. And, what do you want to happen whenever you detect a RS moderator or if your player dies? While we're at it, why not switch worlds on NextPlayer or do something time consuming (like a GetPage) while the player is logged out?

The possibilities are endless, use your imagination!

This marks the end of this short tutorial. I hope you didn't mind reading it despite that it is in a slightly bad state. (Which I plan to improve on after I get some feedback.) Please give me and ideas or comments for what parts I explained wrongly or poorly, and any ideas, comments or tips are welcome! :)

As a final notice, I highly recommend you to check out globals.scar to get better understanding of this feature. If there were any part that were hard to understand in this "tutorial", please let me know.


Happy scripting ^^
- EC!

The_Shermanator

2008-12-09 11:27:19

Ahh looks very cool, Its crazy how you devs come up with this stuff.
Goodjob on this! Can't wait to use it!

-The_Shermanator

Wizzup?

2008-12-09 11:28:23

Nice. :)

Magiic

2008-12-09 12:02:14

really nice :P, it's awesome

Blumblebee

2008-12-09 16:42:22

wow this is hawt. + rep.

Lee Lok Hin

2008-12-09 17:15:18

Mention that the procedure must be a procedure with no parameters?

NiCbaZ

2008-12-09 19:10:48

This look's nice but i don't really undertand..

Switch gametabs, or something else less time consuming. And, what do you want to happen whenever you detect a RS moderator or if your player dies? While we're at it, why not switch worlds on NextPlayer or do something time consuming (like a GetPage) while the player is logged out?



But couldn't you just do..

While FlagPresent do
AntiBan;

If FindMod then
Switchworlds.

etc, you can do all that stuff anyway?

EvilChicken!

2008-12-10 19:09:52

From: Wizzup?
Nice. :)


From: The_Shermanator
Ahh looks very cool, Its crazy how you devs come up with this stuff.
Goodjob on this! Can't wait to use it!

-The_Shermanator


From: sandos
really nice :P, it's awesome


From: Blumblebee
wow this is hawt. + rep.


Thanks to all of you!
And, Blum, thanks for the rep+ ^^

And, please do let me know if I missed something or made something unclear - or if you have any suggestions for anything I could add/improve.

From: Lee Lok Hin
Mention that the procedure must be a procedure with no parameters?


Whoops, forgot to add that. Thanks!

From: NiCbaZ
This look's nice but i don't really undertand..




But couldn't you just do..

While FlagPresent do
AntiBan;

If FindMod then
Switchworlds.

etc, you can do all that stuff anyway?


This system simply makes things easier, especially the "OnFindRandom" and such.

And, your FlagPresent example, would you want that implemented in your script every single time you call (F)Flag? No. That's why you simply assign a procedure to it, and you only have to do it once.

NiCbaZ

2008-12-10 19:57:04

Yes i undertand now, Thank you.

Nose Smasher

2008-12-16 00:55:53

Awesome, jus read bout these in the thread bout rev 29 and 30 ;) Good job, not much more you can put in tut, peeps jus gotta play wit it for them selves :p I'll have fun wit these :p

Thanks :)

Naike

2009-01-10 18:47:16

Call it gravedig, but i had to Thank you for this tut.
Really nice work Ec!.

mastaraymond

2009-01-11 06:00:50

From: N1ke!
Call it gravedig, but i had to Thank you for this tut.
Really nice work Ec!.

afaik, you cannot gravedig tutorials.

Wizzup?

2009-01-11 06:25:19

From: N1ke!
Call it gravedig, but i had to Thank you for this tut.
Really nice work Ec!.


I think this is SRL's latest feature, how is it a gravedig? ;)

Sir R. M8gic1an

2009-07-12 01:16:50

testing something

~RM

Da 0wner

2009-07-12 01:30:17

Can you please add ThreadSafeCall to this? So we can have parameters.

bullzeye95

2009-07-12 01:43:01

From: Da 0wner
Can you please add ThreadSafeCall to this? So we can have parameters.


Parameters would be a nightmare IMO. How would it know what parameters to pass? I guess you could have a whole other array of TVaraintArrays to pass, but that would be messy. You'd have to edit an array, maybe multiple times just to pass a couple parameters. If you really want to pass parameters, you could just create a no-parameter procedure and have it call the main one with parameters. The other downside to it is, AFAIK, parameters passed via ThreadSafeCall cannot be passed by reference (or at least edited).

Of course you may have a reason/solution I didn't think of?

Da 0wner

2009-07-12 04:26:33

program New;

type
TProc = record
Name : string;
Params : TVariantArray;
end;

var
srl_Procs: array [0..8] of TProc;

function TestProc1(s : string; i : integer) : string;
begin
result := 'TheResult';
Writeln(s);
Writeln(IntToStr(i));
end;

function CallProc(Index : integer) : string;
begin
try
result := ThreadSafeCall(srl_Procs[Index].Name, srl_Procs[Index].Params);
except end;
end;

procedure SetParams(Index : integer; Params : TVariantArray);
begin
srl_Procs[Index].Params := Params;
end;

begin
srl_Procs[0].Name := 'TestProc1';
SetParams(0, ['hello', 1337]);
Writeln(callProc(0));
end.

:).

ZephyrsFury

2009-07-12 06:53:38

From: Da 0wner
program New;

type
TProc = record
Name : string;
Params : TVariantArray;
end;

var
srl_Procs: array [0..8] of TProc;

function TestProc1(s : string; i : integer) : string;
begin
result := 'TheResult';
Writeln(s);
Writeln(IntToStr(i));
end;

function CallProc(Index : integer) : string;
begin
try
result := ThreadSafeCall(srl_Procs[Index].Name, srl_Procs[Index].Params);
except end;
end;

procedure SetParams(Index : integer; Params : TVariantArray);
begin
srl_Procs[Index].Params := Params;
end;

begin
srl_Procs[0].Name := 'TestProc1';
SetParams(0, ['hello', 1337]);
Writeln(callProc(0));
end.

:).

Interesting, very interesting….

Da 0wner

2009-07-12 06:56:11

Seems more powerful than the current system :D.

mastaraymond

2009-07-12 14:53:14

From: Da 0wner
Seems more powerful than the current system :D.

But it's quite useless, afaik? Name an event where you need parameters to be added..

Da 0wner

2009-07-12 15:11:38

Maybe getting what random is currently active or something.

You can be imaginative. I'm not really sure, but I don't see why it shouldn't be added. It adds more flexibility.

Freddy1990

2009-07-13 05:00:21

Using ThreadSafeCall to do this is a really bad idea because it synchronizes the script thread with the main thread… And the functions in SCAR are written to run in a separated thread, so synchronizing some of them would not be wise, however, I can probably add a CallProc function to SCAR instead which doesn't synchronize threads, of course it can't be used for forms then simply because it wouldn't be thread-safe then. For forms you'd still need ThreadSafeCall.

Da 0wner

2009-07-13 05:04:50

Sure, CallProc would be nice in 3.22 or 3.21a or whatever :p.

Hold my suggestion for this until Freddy releases a new SCAR with CallProc.

Freddy1990

2009-07-13 05:29:46

From: Da 0wner
Sure, CallProc would be nice in 3.22 or 3.21a or whatever :p.

Hold my suggestion for this until Freddy releases a new SCAR with CallProc.


I've added CallProc to SCAR, it's available from #7 in the SCAR Pre-release SVN.

Da 0wner

2009-07-13 05:38:35

Oh, thanks <3 :).

Wizzup?

2010-07-31 18:49:40

I just wanted to bump this as this is still very useful. I don't think it is used by many scripts?

EvilChicken!

2010-07-31 19:15:04

From: Wizzup?
I just wanted to bump this as this is still very useful. I don't think it is used by many scripts?


Thanks for bumping, even I myself had forgotten about this.
Sadly enough, it never seemed to get popular enough amongst people. It was quickly forgotten since nobody initially applied it to their scripts, so no examples were even set to inspire others to do likewise. Nowadays most people do not even know it exists..

I wonder if there are some ways of encouraging people to use them more often?

i luffs yeww

2010-07-31 19:29:27

:) You could always make a script using them.

Frement

2010-07-31 19:50:29

From: EvilChicken!
Thanks for bumping, even I myself had forgotten about this.
Sadly enough, it never seemed to get popular enough amongst people. It was quickly forgotten since nobody initially applied it to their scripts, so no examples were even set to inspire others to do likewise. Nowadays most people do not even know it exists..

I wonder if there are some ways of encouraging people to use them more often?


I wonder if there is some way to encourage people in making scripts :)

Heavenguard

2010-07-31 20:08:28

Omg this is soo awesome. Amazing. +rep 2, going to start incorporating into my scripts right away lol. Great job to anyone who was involved, amazing job.

Cigue

2010-07-31 23:01:07

From: Frement
I wonder if there is some way to encourage people in making scripts :)


I don't know, do you mean like a competition? :)

Heavenguard

2010-07-31 23:09:02

[offtopic] I wish that SRL had a certain holiday or season were users are inspired to just make a script [no matter how stupid or bad it may be]… it would be pretty friendly, and then we could do things with those scripts as a festivity or something. It would be fun lol, and on a more positive level, it would inspire those who never scripted that much, to start scripting again.

HarryJames

2011-05-08 11:49:09

Bump.
This is very helpful for scripting imo.

Gu3st...

2011-05-08 11:56:39

What is there to bump?

This has been in SRL since Rev #29 (Not open-dev rev #29, but SRL rev #29)

HarryJames

2011-05-08 12:06:18

Well 0, 7 and 8 have been of use to me, and I'm gong to definately use 0 and 8 in my woodcutter.

Coh3n

2011-05-08 21:44:56

From: Zyt3x
What is there to bump?

This has been in SRL since Rev #29 (Not open-dev rev #29, but SRL rev #29)

Just to remind/tell people what's in SRL I guess.

Yago

2011-05-08 21:50:23

I actually had no idea about this … I was wondering what srl_proc meant and stuff

Gu3st...

2011-05-09 03:29:52

Can I request a srl_onLoggedIn constant? :)

BraK

2011-05-09 05:37:28

Lol I forgot about most of these :redface: Glad for the bump.

~BraK

Simtoon

2011-05-09 06:40:07

The font is so big.