backIndex

Xelagot action script

Labels and Subs: Gosub, Goto, ResetTo, EscapeTo, Escape. Statements Do and Suspend

EscapeTo and Escape are introduced in X1.exe 2.9999950 and Av99Bot/SrvcXlgBot 1.66

The script is normally executed line by line, starting at the first line and ending at the End statement or at the last line.

The script flow can be re-directed to certain parts of the script: the Labels and the Subs. See the section on Events for handeling unpredictable happenings such as chat, detection of movement, clicks etc... that temporarily interrupt the main script execution.

Labels and Subs are structural elements of a script

Label $label
a label is just that: a label, it has no other function than to mark a place in the script, and can be used to jump to it, the script will resume execution at the line following the label.
Labels may be found:
  1. in the main part of the script, between [Script] and End,
  2. within a sub, between Sub and Return or EndSub,
  3. within an event handler, between Event and EndEvent.
Sub $sub
a Sub is quite different: it has an entry point, the line starting with Sub, and a point of exit, at the Return or EndSub statement. Within a Sub, statements will be executed until the Return or EndSub statement is met, then execution will continue at the line following the one where the Sub was called with the Gosub statement.
Subs and Event handlers may only be placed after the End statement of the main part of the script

In all the examples here, $label and $sub are strings which may only contain letters, numbers and underscores, and must start with a letter. They can be packed in variables, or more often just string literals (no "" needed here). They must exist as Labels or Subs. If a Label is not found, or a Sub does not exist, the script produces an error message on screen (X1.exe) and triggers a LabelNotFound event: the script may trap that event and decide what to do. This can happen if the script uses variables in Goto and Gosub statements to point to labels or subs. See Errors and debugging

Jumps in the execution of the program flow are triggered by five statements: GoSub, Goto, ResetTo, EscapeTo and Escape.

Gosub $sub
is used to call a Sub. The label $sub is the name of the sub, for example, Sub ThisOne can be called with Gosub ThisOne.
Goto $label
is used to jump to a label in the same section of the script. If Goto $label is in the main section, the Label $label must also be in this section; if Goto $label is in the body of an event handler, Label $label must be in there too; and if Goto $label is in a Sub, Label $label must be in the same Sub. If the Label is out of scope, the script produces an error message on screen (X1.exe) and triggers a LabelNotFound event, see Errors and debugging.
For example, if in the main body there is a label called Label donkey, you can use Got donkey in the main body. Two frequent applications of this:
  1. In the main body, Labels and Goto's are frequently used to keep the script going at the same place, while waiting for event to happen:

      OnChatEvent Chat
    Label MainLoop
      Goto MainLoop
     
  2. For loops with a counter:

      %r = 20
      %i = 1
    Label ForOneIn
      IfInt %i > %r Goto ForOneOut
      # some code here...
      Inc %i
    Label ForOneOut

     
If you have been scripting HamBots, you must un-learn your Goto habits: use Goto $label for loops and short jumps within the same section, Gosub $sub for the rest.
ResetTo $label
exits all subs, clears the sub stack, clears the Wait command and resets the script pointer to the line following the specified label. The label must be in the main part of the script. If the Label is out of scope, the script produces an error message on screen (X1.exe) and triggers a LabelNotFound event, see Errors and debugging.
  • When ResetTo is in a Sub called from the main part of the script (or in a Sub called by a Sub called by the main part), it has an inmediate effect.
  • When ResetTo is within an event handler. or in Subs called from the event handler, it has no inmediate effect: it does not affect the execution of subs called by the handler nor resets the script pointer until the moment the event handler has finished processing and exits.
EscapeTo $label
is new (X1.exe 2.9999950, Av99Bot/SrvcXlgBot 1.66). It is very similar to ResetTo, but it always exits inmediately (there is no difference in behaviour when it is in the main section and in the event handlers): it exits all subs, clears the sub stack, clears the Wait command and resets the script pointer to the line following the specified label. The label must be in the main part of the script. If the Label is out of scope, the script produces an error message on screen (X1.exe) and triggers a LabelNotFound event, see Errors and debugging.
Escape
is new (X1.exe 2.9999950, Av99Bot/SrvcXlgBot 1.66), and must be used with care. It will terminate and exit any Sub or Event handler, and reset the pointer at the line in the main body of the script following the one where the main script was interrupted. An interruption, in this context, is a Gosub statement in the main script, or an Event. It is only really useful when used to exit an Event handler, because it will exit it inmediately, even from within a Sub, without resetting the script's main pointer, that is: if the main execution of the script (before it was interrupted by the Event) is still somewhere in a Sub called by the main portion, it will resume execution where it was interrupted (in that Sub, it does not clear the main stack if used in Events). On the other hand, if used outside an Event handler, it clears the main stack and resumes execution at the line following the one where it entered the first Sub on the stack. If not used within an Event or a Sub (if it appears in the main body of the script) it does nothing.

For example, the statement using a literal

Goto MyLabel
requires a label
Label MyLabel

and the statement using a string variable

$Start_param = "StartParameters"
Gosub $Start_param
requires the following structure, after an End statement
End
# none or more subs here, then

Sub StartParameters
   #some code here
EndSub

The following is also possible and legal, the last EndSub closes the Sub. Therefore, the Goto's are also OK here, they 'stay' within the Sub:

End
# none or more subs here, then

Sub StartParameters
  #some code here
  IfInt %r > 3 Goto StartParameters1
  Else IfInt %r > 2 Goto StartParameters2
  Else IfInt %r < 0 EndSub
  #some more code here
EndSub
Label StartParameters1
  # some code here
EndSub
Label StartParameters2
  # some code here
EndSub


STATEMENT DO

This statement has two functions, depending on whether it is followed by arguments or not.

Do on its own, the "empty" Do, forces the script processor to pass control to the main bot program, if issued in the main part of the script or in a sub called from the main part. In an event handler it does nothing. Notice that some other statements have an implicit empty Do, so this statement is rarely needed except after a Suspend statement.

Do $a allows executing a statement stored in a string variable, as if it were part of the script. If $a is an empty string or is not a valid statement, it does nothing.

Example. Supposing you have a list /s_listA of name-value pairs, which contains the following pair:
tea=Gosub ServeTea

If somewhere in your code, you have a string equal to the keyword "Tea", for instance if $a = "Tea", you can use this keyword to go to subroutine ServeTea:

   IfSListGetValue /s_listA $a $b Do $b
is equivalent to
   IfString "Tea" = $a Gosub ServeTea


STATEMENT SUSPEND

Suspend

This is a most dangerous statement. If unwisely used, it can cause the script to take control of the bot and never return to the main program, resulting in an endless loop.

What does it do? If used in the main body or in a Sub called from the main body, Suspend prevents the bot from automatically regaining control at each heartbeat until an empty Do statement or a ResetTo statement is encountered. Many statements force the script to pass control back to the bot. This is necessary: the bot needs to communicate with the universe and world servers, and can only do so by regaining control at each bot heartbeat. Moreover, the other bots in the program must have their turn as well.

On some occasions, you will want to suspend for a short time this behaviour, to speed up script parsing and processing. This might be the case, for instance, if you wish to issue a series of ObjectChange statements, and do not wish the script to pass control back to the bot after each statement (this causes a delay of approximately 0.5 seconds after each of these statements) but prefer to process all these statements first and then return control to the bot so that it sends all these changes to the server in one go. You may then protect your statements in a Suspend .... Do block. Keep in mind that all the code between Suspend and Do will be parsed without giving control back to the bot.

Suspend
# your code here
Do

Using Suspend ... Do wisely can speed up the execution of the script, but you must test your code thoroughly to see that it is really doing what you want it to do: some statements might not work properly after a Suspend statement. Suspend does not work in Event handlers.



backIndex