Today BIS added new command triggerTimeoutCurrent that allows you to check the current remaining time of a trigger timeout. This made me look into trigger timeouts, something I haven’t done in previous trigger blog post. So as you have guessed already, today I will focus on timeouts.
When trigger is activated you can delay the onActivationStatement execution simply by setting trigger timeout with setTriggerTimeout command. Once set countdown is over, the statement will run. This made me think about setTimeout command in JavaScript. In JavaScript you can pass a function to this command together with required delay, which in turn sets a timer and delays function execution. Can the same be done in SQF? You betcha!
All we need is to set a trigger with desired timeout to be triggered immediately upon creation. For this it is enough to just set conditionStatement of the trigger to true to make the trigger think it was triggered (triggerActivated though will return true only when onActivationStatement is executed). After we are done with the countdown, we will delete the trigger. So here is a bunch of code for you to explore and play with.
- Function to create and return timeout object:
- Function to return number of seconds left:
- Function to stop timeout in progress (returns true on success):
- Some sample function to call:
- Activate 10 seconds timeout:
- Query remaining time
- Check if timeout is still active
- Stop timeout
Pretty much all you need to create and manage timeouts. This way you can also easily create multiple timeouts since each timeout is a separate trigger object. But what if we want a repeated timeout? In JavaScript such command is called setInterval. Instead of repeatedly creating and deleting the trigger, we are going to create one trigger and keep on activating and deactivating it instead. Look at the code below to see how it is done in case you need to deactivate a trigger with a script in your projects.
- Function to create and return interval object:
- Some example of setting an interval:
Now, the triggers are imprecise in nature. If you want precise intervals use while loops and time check. A trigger will check its timeout once every 0.5 seconds. Because of this there always be up to extra 0 – 0.5 seconds inaccuracy on each timeout, not to mention that when trigger is created it takes up to 0.5 seconds before it even goes live. So if you are setting an interval to let’s say 3 seconds, this literally means: “check interval NOT more than ABOUT once every 3 seconds“. For default 0.5 seconds check you can pass 0 as timeout param.
This inaccuracy could be somewhat negligible at bigger intervals. 0.5 second in 60 seconds interval for example is nothing. So if you need every minute check, it is probably better to create a trigger with 60 seconds timeout than while true loop with sleep 60. Oh and you can remove and query intervals with KK_fnc_clearTimeout and KK_fnc_currentTimeout respectively. Just remember that trigger statements are local, if you want absolute network sync, run timeouts on the server only and broadcast the changes.
Above is a simple countdown I made to demonstrate the new triggerTimeoutCurrent command. But, but, but the triggers are imprecise? Well, while trigger checks on its own timeout every 0.5 seconds there is no reason for us to do the same. We can check the timeout every frame for a better accuracy, thanks to the new command. Here is the code from the video:
Enjoy,
KK
EDIT: Removed redundant code and made neater. Also please note BIS made some changes to trigger functionality since this post, so the code on video now counts down from 9 not 10.