[Tutorial] 0AB1: call_scm_function

Hi, I was searching for any tutorial about it but didn't find any which would be made using simple language.
There is one here but I found it difficult to understand when I saw it for the first time.

Why is it useful?
Cleo is limited to 31 variables (+2 timers) which may cause some confusion while making complex scripts. By correct usage of 0AB1 it's possible to make a complex script look clean and organised. Each function has its own "internal variables" and changing them doesn't affect the script where the function is called, that's why it's so useful. By using it you can:
-make calculations using a lot of variables without affecting your base script
-pass a result of your calculations back to your base script
-set something (e.g. your position, your car's position)

Example of use:
Script below is using a function to set maximum speed of the car driven by the player. The function not only sets the maximum speed but also passes his current speed back to the base script. (I advise to copy the following code to your sanny builder and analyse it there, it's going to be more clear because of the colours)
Code:
{$CLEO}
0000: NOP

while true //constantly
wait 0
    if 00DF:   actor $PLAYER_ACTOR driving //check for driving
    then   
    0811: 10@ = actor $PLAYER_ACTOR used_car //store your car to 10@ variable
    0AB1: call_scm_func @set_max_speed 2 carHandle 10@ speedValue 10.0 _returnedSpeedValue 11@ //the code goes now to the ":set_max_speed" label, look there now to see what it does there
    //your first returned parameter from the function which was your current speed (31@) becomes 11@
    0AD1: show_formatted_text_highpriority "your current speed= %f" time 1000 11@ //your current speed is displayed. If you used here 31@ instead of 11@ it wouldn't work because 31@ is function's internal variable
    end
end


:set_max_speed
// your first parameter which is carHandle (10@) becomes 0@
// your second parameter (10.0) becomes 1@
// if you passed any more parameters to this function they would become the following: third-2@, fourth-3@, fifth-4@, sixth-5@ etc...
02E3: 31@ = car 0@ speed //stores current speed to 31@
    if 0025:   31@ > 1@
    then
    04BA: set_car 0@ speed_to 1@
    end
0AB2: ret 1 31@ //31@ which is your current speed is sent back to your base script, now the code jumps to the point where the function has been called

0AB1: call_scm_func @set_max_speed 2 carHandle 10@ speedValue 10.0 _returnedSpeedValue 11@
2 - number of parameters you'd like to pass to the function
10@ 10.0 - parameters you're passing to the function, first one becomes 0@(function's internal variable), second becomes 1@
11@ - parameters you return to your base script by using 0AB2: ret 1 31@

0AB2: ret 1 31@
1 - number of parameters you'd like to return back to the base script
31@ - function's "internal variable" you return back to the base script, it becomes 11@ or any variable you wish



Returning boolean
Function can also return "true"/"false" which means that it can be used as a condition. The script below displays a message if the specified actor is driving.
Code:
{$CLEO}
0000: NOP

while true
wait 0
    if 0AB1: @is_driving 1 $PLAYER_ACTOR
    then
    print "Specified player is driving" 100
    end
end

:is_driving
if 00DF:   actor 0@ driving
then
0485:  return_true
else
059A:  return_false
end
0AB2: ret 0
0485: return_true - causes the function to return true
059A: return_false - causes the function to return false
Note that it's still neccessary to use "0AB2: ret" at the end of the function which returns boolean despite of the true/false opcodes above.

How not to use function returning boolean. (For some reason the "if and" condition is true even if only one of the actors is driving)
Code:
if and
0AB1: @is_driving 1 $PLAYER_ACTOR      //example of incorrect usage
0AB1: @is_driving 1 0@      //example of incorrect usage
0AB1: @is_driving 1 1@      //example of incorrect usage
then

end



Additional tips:
1. Sometimes, for example if someone would like to improve his already made function, he might want to add more parameters to it. That's why I used 31@ instead of 2@ to get the speed of the car. It's better to use higher variable than lower within a function when it's not neccessary. If I used 2@ to get the car speed and later added 3rd parameter I'd have to change 2@ variable to any other to get the speed of the car (or use something like "0085: 31@ = 2@" at the begining of the function but personally I think it's better to avoid that and keep it simple)
2. Adding "_" or "_returned" to the titles of returned parameters (e.g. _carSpeed 11@) is a good way to distinguish which ones are which if you'd like to avoid counting them. It's not an issue with simple functions but it can save time and effort while working with functions which have like 15 or more different parameters.
3. Maximum number of parameters that can be passed to a function is 64 (in cleo 4.3, probably it's the same in cleo 4.1 but I'm not sure).
 
Last edited:

Codex1337

Active member
Joined
Mar 1, 2014
Messages
170
Reaction score
1
Re: 0AB1: call_scm_function

Good job.
Expecting more good tutorials from you :)
 

0B36

Expert
Joined
Jan 6, 2014
Messages
1,324
Reaction score
8
Re: 0AB1: call_scm_function

By 31 variables limit, you can't use 32@, 33@, 34@ and so on, right ?

Edit - 31 doesn't seem to be the limit, I can use 32 and upto 33. But I can't use 34. I'm receiving a Sanny Builder error.

So I searched and found this tutorial - http://gtag.gtagaming.com/forums/index.php?showtopic=310

Very enlightening.
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,126
Solutions
1
Reaction score
158
Re: 0AB1: call_scm_function

[member=11595]Codex1337[/member]
Thanks

[member=8182]0B36[/member]
Yeah, but 32@ and 33@ are timers, if you set any of them to any value (e.g. 32@ = 0) it's going to automatically increase by 1 every millisecond
 

0B36

Expert
Joined
Jan 6, 2014
Messages
1,324
Reaction score
8
Re: 0AB1: call_scm_function

What about additional variables as mentioned in the tutorial I linked ? I guess we can use them as local variables with Deji's opcodes.
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,126
Solutions
1
Reaction score
158
Re: 0AB1: call_scm_function

Hmm look at the last comment of that tutorial. He also posted another thread about it here. I have no idea how it works exactly nor tested it to be honest
 
Joined
Feb 18, 2005
Messages
2,963
Reaction score
267
Re: 0AB1: call_scm_function

Nice tutorial  :urtheman:

About more vars, if you don't wanna bother with cleo memory, use this PLUGIN by 0x.
And in SF just use arrays.

simple example;
Code:
repeat
    wait 40
until samp.Available()
alloc 0@ = 1024


WHILE TRUE
WAIT 0
    0226: 1@ = actor $PLAYER_ACTOR health
    0C0F: array 0@ element 1 = 1@
    04DD: 1@ = actor $PLAYER_ACTOR armour
    0C0F: array 0@ element 2 = 1@
    
    0C0E: 1@ = array 0@ element 1    
    0C0E: 2@ = array 0@ element 2
    
    0AD1: "%d %d" 100 1@ 2@
END

I remember doing a rather big script and only using vars from 0@ to 5@  :me_gusta:
 

Codex1337

Active member
Joined
Mar 1, 2014
Messages
170
Reaction score
1
Re: 0AB1: call_scm_function

Can't we just use these variables? "$PlayerHealth, $POS_Y"
What is the difference between 0[member=21661]S[/member] and $XYZ?
 

0B36

Expert
Joined
Jan 6, 2014
Messages
1,324
Reaction score
8
Re: 0AB1: call_scm_function

Codex1337 link said:
Can't we just use these variables? "$PlayerHealth, $POS_Y"
What is the difference between 0[member=21661]S[/member] and $XYZ?

Yes you can. Variables starting with "$" are termed as global variables; they can be used anywhere in the script, while variables having "@"  are defined as local variables, only to be used inside the script area where they're previously defined.
 
Joined
Feb 18, 2005
Messages
2,963
Reaction score
267
Re: 0AB1: call_scm_function

0B36 link said:
Yes you can. Variables starting with "$" are termed as global variables; they can be used anywhere in the script, while variables having "@"  are defined as local variables, only to be used inside the script area where they're previously defined.

Global means global, so every $ var will be the same in every cleo script. So if you assign a value to $30, and some other non-related script uses the same $30 it will fuck things up. Plus, they don't always work right in 4.1.

Codex1337 link said:
Can't we just use these variables? "$PlayerHealth, $POS_Y"
What is the difference between 0[member=21661]S[/member] and $XYZ?

0@s mean short string, you use it to store short strings(under 8bytes). It will also occupy the next variable.

0@ = 4 bytes
1@s = 8 bytes = 1@, 2@
1@v = 16 bytes = 1@, 2@, 3@, 4@

0@s = 'Codex69'
0@ = 'Code'
1@ = '69'
 

4changesLeft

Well-known member
Joined
Apr 10, 2015
Messages
365
Reaction score
3
RE: 0AB1: call_scm_function

@monday great tutorial, helped me a lot, i have one question tho. Can you use "wait" on a called function? Or it will bypass it just like if you use it on a command?
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,126
Solutions
1
Reaction score
158
RE: 0AB1: call_scm_function

@TehArgis
I have no idea to be honest
 

KamikazeSripterul

Well-known member
Joined
Jun 30, 2019
Messages
353
Reaction score
23
is there a specification of parameters you'd like to pass through depending on your script?
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,126
Solutions
1
Reaction score
158
It depends what the function does. If the function is called "SendTxtMessage", then probably you'd like to pass at least 2 parameters to it (message content + destination number).

The same applies to returned values. If the function is called "GetTickCount" then it should return only one value (otherwise it would cause unnecessary confusion).
 
Top