A to Z Scripting: Looping a script
Looping a script
You may want a script to keep repeating until stopped, for as long as a condition stays true, or for a number of times.
The scripting engine allows up to 10,000 events per frame, so if you're doing something a finite number of times (i.e. checking all entities of a certain type) you can usually do it all in a single frame.
However, if the script should keep running continuously (i.e. for a "No harm" objective) you need to build some kind of wait() event into the script. This avoids that the script tries to run an infinite number of times in a single frame (crash with "runaway loop" error).
Looping with thread
The easiest way to loop is by making the script call itself at the end with "thread". Unlike other methods, this will always repeat the whole script.
Example: "No harm" objective
void looping_script() { if ( $lord_marlow.getHealth() != 100 ) $player1.setObjectiveState(5, OBJ_FAILED); sys.wait(0.5); thread looping_script(); }
Looping with while()
while() lets you loop a script for as long as the condition inside the brackets is true. If it should loop permanently, put a 1 into the brackets (true).
Example: timer for a mover
void mover_timer() { while( $box.isMoving() ) { sys.wait(0.1); float time_moved = time_moved + 0.1; } }
Repeating with for()
for() lets a script repeat for a number of times that can be either pre-determined or variable. It's well-suited for gradually making a change in many small steps (increments).
Example: fading a shader parameter on an entity
void materialise() { float i; //define a float (integer) to keep track of the number of steps for (i=0;i<100;i++) //go from 0 to (one under) 100, one at a time { fade_entity.setShaderParm(5,i); //set shaderParm5 to the current number of steps sys.waitFrame(); //wait one frame until the next step } }
Repeating with do + while()
"Do this script for as long as this condition is met". This one is quite similar to just using while(), the difference is it can begin even if the condition is false at first (the conditional is at the end, not at the beginning).
Example: running a script on every entity of a certain type
//Script by Obsttorte void lamps_toggle() //finds and triggers all electric lamps in the map { light lamp; do //do repeat this... { lamp = sys.getNextEntity("lightType","AIUSE_LIGHTTYPE_ELECTRIC",lamp); //find the next entity which has this spawnarg value if (lamp != $null_entity) sys.trigger(lamp); } while (lamp != $null_entity); //repeat for as long as sys.getNextEntity finds electric lights }
Terminating a running script
Terminating with killthread()
It's possible to manually terminate any script by giving it a (thread) name, and letting another script terminate it.
Example:
void check_health() { sys.threadname("looping_script"); //assign a name to this script or thread if ( $lord_marlow.getHealth() != 100 ) $player1.setObjectiveState(5, OBJ_FAILED); sys.wait(0.5); } void terminate_check_health() { sys.killthread("looping_script"); //terminate the script that was named "looping_script" }
Terminating with return
Alternatively you can terminate a script with simply "return". This causes the script to terminate. Example:
if ( attempts == 3 ) return;
Next / previous article
- Next article: A to Z Scripting: Scripting with...
- Previous article: A to Z Scripting: Conditionals
- Table of contents: A to Z Scripting