FUNCTION (FU)
RECEIVER
Used to create a separate section of code that can be accessed from more than one place and thus reused. A function is called by using the function receiver. The function trigger then defines the start of the function code.
If you want a script to occur when a function is activated, use a function TRIGGER
NEW FU RECEIVER SYNTAX. See
below
!!FU#:XXXX; |
Function receiver - transfers control to ERM code following
function trigger) # = 1 to 30000. |
!!FU#:XXXX; |
Local function receiver - transfers control to ERM code following
local function trigger) See below # = -1 to -100. |
OPTIONS
C$;![]() |
Check for wrong y vars usage May be used without parameters, like !!FU:C1; $=0 - enables run time check $=1 - disable run time check (default if just !!FU:C) It will check only if you try to set a y var outside of a function body (execution time), for this is the main case of the problem (reading is not a problem at all if it worked correct). By default the checking is disabled. This is most logical to use as an instruction and may be useful when testing scripts. Very simple usage. Example: ************ ZVSE !#FU:C; !#TM1:S1/999/1/1; set TM1 for red !?TM1; !!VRy1:S1; !!FU123:P; !?FU123; !!VRy1:S2; ************ Here when the timer section is executed, you will get a message that y var is set outside of the function body. |
D$/$/$... up to 16#s. ![]() |
Call the function at opposite side. Syntax is the same as for FU:P Now during a battle you may pass the values of v vars to the other side and call functions at the other side. Say, you run a user dependent script (like stack splitting). The script runs at one side because it runs as a reaction to a human action (mouse click). So all that you change at this side will not be changed on the other side. Now you can pass all changed values to the other side not running a script there. Example. On the one side you run a mouse event driven script: ... !!VRv1234:S999; On the other side v1234 will still keep the old value. To fix it use: ... !!VRv1234:S999; !!IP:V1234/1234; The last command will immediately send the value of v1234 to the other side. Now to the second part of the problem. Say you use some specific command that has some effects on the battlefield (say you cast a spell with ERM). Again, if it is done only at one side, there will be a problem because it is not done on the other side. Now you may use a distant call for those cases. This means that you call a function but it runs not at this local PC but at a distant one (the opponent's PC). Up to 16 x parameters are transferred. Example. On one side you have: ... !!BMv10:Mi/y5/5; To make it run correctly you should make some changes: ... !!BMv10:Mi/y5/5; !!FU12345:Dv10/i/y5/5; !?FU12345; !!BMx1:Mx2/x3/x4; That is all. How it works. FU:D immediately transfer all x parameters to the other side and makes a call of FU1234 there. So BMv10:M... command runs at one PC and BMx1:M... at the other PC. If you pass all in the right order, you will see the same effect at both sides. Note that you can pass some vars with IP:V command and then call FU:D to pass more than 16 x parameters to the other side. Now, an example that you can check (tested): *********** ZVSE !?BG0; !!IF:M^Hi!^; !!VRv99:S99; !!VRv100:S100; !!VRv101:S101; !!IP:V99/100; !!FU123:D1/2/3/4/5; !?FU123; !!IF:M^V99=%V99, V100=%V100, V101=%V101, X1=%X1, X2=%X2, X3=%X3, X4=%X4, X5=%X5^; *********** You will see "Hi!" message at any action of a stack, then you will see a message "V99=99, V100=100, V101=0, X1=1, X2=2, X3=3, X4=4, X5=5" at the other PC. Then you get "Hi!" at the other PC. If you continue, you may notice that the next time the message will be: "V99=99, V100=100, V101=101, X1=1, X2=2, X3=3, X4=4, X5=5". So v101 is changed. This is because first you send v99 and v100 through the network and call a function that shows a message (and this is why v101 is 0). But then the BG0 trigger will work out at the defender's side and v101 will be set to 101. This example is only an example because in the script: !?BG0; !!IF:M^Hi!^; !!VRv99:S99; !!VRv100:S100; !!VRv101:S101; will work fine (identical) at both sides. But if you run a script as a reaction to a human related event (mouse click generally), you need to think how to transfer changes to the other side. |
E;
E0; |
Exit the current function immediately May be used in instructions: !#FU:#; though not sure how this is going to work. Need tests. You can use this command to avoid re-entering the function. Example It was: !?FU123; ... !!VRv10:S0 T10; [get random value] !?FU123&v10<5; [continue only if random value <5] ... Now you can do it this way: !?FU123; ... !!VRv10:S0 T10; [get random value] !!FU&v10>=5:E; [exit the function only if random value >=5] [continue only if random value <5] ... The plus of this technology is that you have the same set of y and other local vars and you can use it in triggers also. Another example (complete): *************** ZVSE !?LE3/4/0; [all is attached to local event] !!IF:M^L0-0^; !!FU123:P; !!IF:M^L0-1^; !!FU:E; [leave] !!IF:M^L0-2^; !?FU123; !!IF:M^L1-0^; !!FU124:P; !!IF:M^L1-1^; !!FU:E; [leave] !!IF:M^L1-2^; !?FU124; !!IF:M^L2-0^; !!FU125:P; !!IF:M^L2-1^; !!IF:M^L2-1a^; !?FU125; !!IF:M^L3-0^; !!FU126:P; !!IF:M^L3-1^; !!FU:E; [leave] !!IF:M^L3-2^; !?FU126; !!IF:M^L4-0^; !!IF:M^L4-1^; !!FU:E; [leave] !!IF:M^L4-2^; *************** You will get the next messages: L0-0 L1-0 L2-0 L3-0 L4-0 L4-1 L3-1 L2-1 L2-1a L1-1 L0-1 |
E#; Extended syntax |
Go-to statement |
P$/$/$... up to 16#s. |
Call the function |
X#/?$; |
Get type of argument x# |
Declarations and Instruction usage
If you call a function with an instruction, the function must be declared
*before* the instruction.
So, for example, if you want to call function 100 at the
start of a map, you can put in the instruction !#FU100:P;
but it won't work if the function trigger follows the instruction. Instead, the
function trigger (and code within it) must be first.
So:
ZVSE
!?FU100;
!!IF:M^This is function 100.^;
!#FU100:P;
The above will work but if !#FU100:P; would have been put
first (right after ZVSE), it wouldn't work. You wouldn't get an error message
but the function wouldn't execute.
Usage
of a variable in a function receiver
You can use a variable in a function receiver. So you
could put, for example, !!FUv10:P; and the function called (if it exists) would
be the function number *currently* stored in v10.
Function Examples:
Example:
!?FU1;
!!IF:M^Here we are before. %X1 %X16^;
!!VRx1:+1;
!!FU2:Px1;
!!IF:M^Here we are after. %X1 %X16^;
To call a function use a receiver FU# (#=1...1000)
Example:
!!FU1:P5;
This calls the function above with one parameter (5)
Local Variable in functions:
In functions you have local variables (up to 100).
To get access to local variables use y# (#=1...100) syntax.
You can set/check/get these vars. Every call creates a unique set of local variables that all equal to zero at entrance.
So all operation with local variable take place inside a function only.
You can make recursive calls.
Another example:
!!FU1:Pi/102/v10/35;
means that in the body of the function we have:
!?FU1; x1=i, x2=102, x3=v10, x4=35 others x5...x16 are undefined
!!IF:M^x1=%X1, x2=%X2^;
Then if you call a function with other parameters, x1...x16
variables in a body of a function will have corresponding values.
!!FU1:P10/20; will show "x1=10, x2=20"
!!VRv5:S33;
!!FU1:Pv5/0; will show "x1=33, x2=0"
Y variables y1...y100 are local variables. You can use them inside
functions for any purpose. All functions have their OWN y variable
set, even if you call recursively one function. When you go out of a
function a previous set of y vars is restored.
!!FU1:P; call FU1
!?FU1; y1 is undefined (=0)
!!VRy1:S1; y1=1
!!FU2:P; call FU2
!!IF:M^y1=%Y1^; "y1=1" (y1 take its original value 1 that was before
calling FU2)
!?FU2; y1 is undefined (=0)
!!VRy1:S2; y1=2
!!IF:M^y1=%Y1^; "y1=2"
Can we make a generic function where I terra transform a big
square?
But I still recommend to pass all arguments to the function like this:
!!FU#:Px1/y1/x2/y2/level/type/subtype;
This is a call:
!!FU20000:P5/15/7/28/0/2/50; x1=5,y1=15,x2=7,y2=28,level=0,type=2,subtype=50
Function:
!?FU20000; transform an area
!!DO20001/0/144/1:Px1/x2/x3/x4/x5/x6/x7;
!?FU20001&x16>=x1/x16<=x3; transform a column
!!DO20002/0/144/1:Px16/x2/x4/x5/x6/x7;
!?FU20002&x16>=x2/x16<=x3; Transform one square
!!VRv1:Sx1; X coordinate
!!VRv2:Sx16; Y coordinate
!!VRv3:Sx4; level
!!TR1:Tx5/x6/d/d/d/d/d/d; start retain type
A function is an entry point as a trigger and a body as receivers.
The trigger is !?FU# (#=1...1000)
Receivers are any receivers.
Example:
!?FU1;
!!IF:M^Here we are before. %X1 %X16^;
!!VRx1:+1;
!!FU2:Px1;
!!IF:M^Here we are after. %X1 %X16^;
To call a function use a receiver !!FU# (#=1...1000)
It has only one command: P
P$/$/$... up to 16 #s.
Example:
!!FU1:P5;
This calls the function above with one parameter (5)
To get access to parameters use x# (#=1...16) syntax.
They may be used everywhere when f...t variables.
When you make a next call to another function (see example) all parameters that are not set will be inherited.
In functions you have local variables (up to 100).
To get access to local variables use y# (#=1...100) syntax.
You can set/check/get these variables. Every call creates a unique set of local variables that all equal to zero at entrance.
So all operation with local variables take place inside a function only.
You can make recursive calls.
You can add a code (receivers) to already exist triggers using the same triggers two or more times.
Example:
!?FU1;
!!... receivers 1
...
!?FU1;
!!... receivers 2
...
!!FU1:...
Last call execute all receivers 1 and then all receivers 2 at the same context.
Example:
!!IFv10:S5;
!!SG4/3/0:M1/v10; set sign message to string var z[v10] or z5
!!SG4/3/0:M1/?z10; get current sign message to z10 string var