- Joined
- Sep 26, 2009
- Messages
- 9,507
When I was making cinematic scripts last year, I was disappointed by the inaccuracies of
I moved to JASS.
What happened then was the precedence-behavior of programming messed everything up in a whole new way. The
I tried learning Anitarf's Cinematic System but I found myself drifting further and further away from the approach I wanted to take with creating the cinematic. I wanted to have a script that looked like it was mine and would be easy for someone to pick up on.
The SleepAction library is the realization of those dreams I had. Now, thanks to a textmacro, it is an easy thing to implement a wait period. The only parts that require thinking are in the parameters passed to the macro.
Example 1:
The first of the parameters is the period you want to wait, which must be a
The textmacro must be within a
Invisible to you while scripting, the textmacro breaks the function in two. A
I find it user-friendly to just name each part a sequencial number (1,2,3...) as you scroll down. The hidden function is a
Hopefully, this script allows you to create cinematics in an environment which is suitable for you!
Example 2:
I can just butter this whole thing up, but there are some real things to consider and to review from what I mentioned already.
A) The textmacro may only be enclosed in a function which
B) The function may not be a method and may not be in the Zinc language.
C) The function must be contained in a scope or a library.
D) Local variables are forgotten after the textmacro line.
E) The textmacro line may not be embedded within a block such as
F) You must input a scope-unique name as a second textmacro parameter.
SleepAction script:
TriggerSleepAction()
, so I moved to fix that problem with Waldbaer's Exact-Timing Cinematic tutorial. Unfortunately, that looked like a mess and was getting tiresome to create the trigger queues for every wait period that I wanted to be exact.I moved to JASS.
What happened then was the precedence-behavior of programming messed everything up in a whole new way. The
TimerStart()
call only compiles functions above it, which made my cinematic script look out-of-order and I was finding it hard to expand on it and to locate a specific section (because everything was in reverse-chronological order).I tried learning Anitarf's Cinematic System but I found myself drifting further and further away from the approach I wanted to take with creating the cinematic. I wanted to have a script that looked like it was mine and would be easy for someone to pick up on.
The SleepAction library is the realization of those dreams I had. Now, thanks to a textmacro, it is an easy thing to implement a wait period. The only parts that require thinking are in the parameters passed to the macro.
Example 1:
JASS:
scope foo initializer bar // requires SleepAction
private function bar takes nothing returns nothing
//! runtextmacro SleepAction("5.5", "1")
call BJDebugMsg("Hello,") // Executed exactly 5 and a half seconds into the game.
//! runtextmacro SleepAction("0.1", "A")
call BJDebugMsg("World!") // Executed exactly 1/10th of a second after the last message.
endfunction
endscope
The first of the parameters is the period you want to wait, which must be a
real
value or variable. Everything below the line of the textmacro will not execute until the *exact moment* the wait period has ended. Not slightly before or slightly after which you get from TriggerSleepAction()
and without disorganizing and/or complicating your script to accomplish something which should not have ever been a complicated process.The textmacro must be within a
scope or library
(pretty much every vJass user does this anyway) and within a vJass function
(not a method
or a Zinc function [Zinc users have anonymous functions to make up for all the features Zinc didn't get]). Note that local
variables are not remembered after the textmacro line, though it is possible to declare new local variables after the line. How it works:Invisible to you while scripting, the textmacro breaks the function in two. A
timer
gets started with the duration you specified and then, using a vJass function interface
combined with TimerData from Vexorian's TimerUtils, the "second part" of the function is executed when the timer expires. For this reason, the second parameter must be a scope-unique sequence of letters and/or numbers and/or underscores as that parameter more or less gives the hidden function a name.I find it user-friendly to just name each part a sequencial number (1,2,3...) as you scroll down. The hidden function is a
private function
which is prefixed with SleepAction_ and, being private
, prefixed with the scope's name as well, with the second parameter's name tacked on at the end of it all.Hopefully, this script allows you to create cinematics in an environment which is suitable for you!
Example 2:
JASS:
scope Scene1 initalizer Init // requires SleepAction
private function Message takes real duration, string msg returns nothing
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, duration, "|cff888888" + msg + "|r")
endfunction
private function Init takes nothing returns nothing
//! runtextmacro SleepAction("0.0", "1")
// Actions below this line happen exactly 0 seconds into the game.
call Message(5.0, "This is an easy method to create cinematics.")
//! runtextmacro SleepAction("5.0", "2")
// Actions below this line happen exactly 5 seconds after the last message.
call Message(7.0, "Using this tool, you can create perfect wait-periods without " + /*
*/"distorting the look and feel of your cinematic scripts.")
//! runtextmacro SleepAction("7.0", "3")
// Actions below this line happen exactly 7 seconds after the last message.
call Message(10.0, "All you have to do is fill in the blanks:\n" + /*
*/"//! runtextmacro SleepAction(\"<Real Duration>\", \"<Scope-Unique Name>\")")
call TriggerSleepAction(10.0)
// Yes, you can safely mix regular TriggerSleepActions in, if you want.
endfunction
endscope
Cons
I can just butter this whole thing up, but there are some real things to consider and to review from what I mentioned already.
A) The textmacro may only be enclosed in a function which
takes nothing returns nothing
.B) The function may not be a method and may not be in the Zinc language.
C) The function must be contained in a scope or a library.
D) Local variables are forgotten after the textmacro line.
E) The textmacro line may not be embedded within a block such as
if/then/else/endif
or loop/endloop
.F) You must input a scope-unique name as a second textmacro parameter.
SleepAction script:
JASS:
library SleepAction requires TimerUtils
function interface SleepActionFunc takes nothing returns nothing
private function Sleep takes nothing returns nothing
local timer t = GetExpiredTimer()
call SleepActionFunc(GetTimerData(t)).execute()
call ReleaseTimer(t)
endfunction
function DoSleepAction takes SleepActionFunc func, real duration returns nothing
local timer t = NewTimer()
call SetTimerData(t, integer(func))
call TimerStart(t, duration, false, function Sleep)
endfunction
//! textmacro SleepAction takes RealSleepDuration, FuncName
globals
private keyword SleepAction_$FuncName$X
endglobals
call DoSleepAction(SleepAction_$FuncName$X, $RealSleepDuration$)
endfunction
private function SleepAction_$FuncName$X takes nothing returns nothing
//! endtextmacro
endlibrary
Last edited: