呼叫剧本段落功能(SubRoutine)的使用
SubRoutine 是指、在剧本中的某处「呼叫」其他剧本段落的功能。SubRoutine呼叫出的剧本段落在执行完后、就会返回原来的剧本。
这和宏(Macro) ( → 宏(Macro)的使用 ) 的功能类似、但 SubRoutine 一般用于执行比较复杂的操作、而 Macro 则相对简单一些。(例如, Macro 中禁止使用标签)
SubRoutine 的基本使用方法
SubRoutine 功能,要求呼叫的剧本段必须是以 标签(Label)作为开头的。而段落结束,需要返回原来的剧本,则是以 return 指令作为结束符号的。要进行呼叫,请使用 call 指令。
请看以下的例子。
[waittime=200]
*start|开始
[cm]
要呼叫其他的剧本了哦。[l][r]
[calltarget=*subroutine]
呼叫完毕,返回原来的地方了。
[s]
*subroutine
我是被呼叫的剧本段,而这就是subroutine功能了。[l][r]
点鼠标就会回到原来的地方了。[l][r]
[return]
那么、执行这个例子的时候、「要呼叫其他的剧本了哦。」的消息后,会显示的是「我是被呼叫的剧本段。」、「点鼠标就会回到原来的地方了。」对话后点鼠标、会显示「呼叫完毕,返回原来的地方了。」。
也就是说、call 指令执行后,除了跳转到呼叫的剧本段以外、也会将之前的剧本位置进行记录、而使用 return 指令后、就会返回之前记录的位置了 ( 这种自动记录被称为「Call Stack」)。
在以上的例子里、*subroutine
到 [return]
之间的段落,就是「subroutine」了。
在一个 subroutine 段落中,还可以继续呼叫其他的 subroutine 。这种呼叫可以一层一层地积累 ( return 之前再进行 call ) ,没有呼叫层数的限制。(提示:就算是这样,多层套叠很容易导致出错。可能的话,请尽量用jump而不用call。)
另外,除了「使用选项分歧」的场合之类需要用 [cm] 消除文字外,假如不是保存标签 (带有 | 的标签) ,呼叫出的段落标签后面不带 [cm] 也无所谓的。(提示:不用理会这句,[cm] 能不用尽量不用。)
Call Stack 记录的内容包括:剧本档名、最近的标签名、以及 call 指令距离该标签的行数、而并不是记录 call 指令的具体内容。请注意:假如在 debug 之类的情况下,改变了剧本档,可能会导致返回的时候,无法回到正确的位置。
另外,请尽量不要将 subroutine 的开头标签当作存储标记 (带有 | 的标签) 用,在 subroutine 中,也不要创建存储标记比较好。
subroutine 相关的注意事项
在某个剧本段落中,使用 call 呼叫自身的话,就会陷入死循环。
call 与 return 没有一一对应的话、Call Stack 就会不断积累、有可能会造成 return 之后不是返回预期的标签的错误、请千万注意。
此外还有、请小心如下的例子
*subroutine
・・・
[ifexp="f.flag1"][jumptarget=*otherplaces1][endif]
[ifexp="f.flag2"][jumptarget=*otherplaces2][endif]
・・・
[return]
*otherplaces1
・・・
[return]
*otherplaces2
;这段落里没有return指令・・・
这是 subroutine 段落中,又跳转到其他地方的情况。假如是跳转到 otherplaces1 的情况、由于有 return 的标记,保持了 call 〜 return 的平衡。但是、假如跳转到了 otherplaces2 、段落里没有 return 指令出现、这个 subroutine 就变成了「无法返回」的状态。也就是说、call 〜 return 的平衡没有维持。
如果、执行完毕后不想返回原来的呼叫处、而是想要返回其他的地方、return 指令也拥有 storage 和 target 属性、利用它们可以返回到任意位置。