Vic3 mod 制作教程 第二章 上下文和Scope(文本版)
大家好啊, 今天给大家说说vic3的mod制作教程。
上一章说到,新版引擎对Scope和Event Target有很强的约束,但是相信看这视频的基本没人能弄清楚什么是Scope和Event target,更不用说什么是上下文
上下文是重要的概念,可以指示等于号左边的类型,通过这种指示可以得到右边应该填什么值,可以不可以后接大括号
而Scope就是在=后接大括号对应的环境,很多语句要在判断完上下文后再判断Scope的类型,才能推定要填什么
所以,我们就从Scope和上下文说起
# 第一节 上下文
## 第一小节 上下文概述
上下文是我自己捏造的名词,所以我直接用用中文说明,上下文其实就是左边的单词加上大括号里面的东西,简单说明就是代码运行的环境。
从使用位置来看,上下文可以分为P社写死的上下文和可以重复利用的上下文;从类型上看,上下文可以分成effect,trigger,modifier和其他参数,可以重复利用的上下文一般只有前三者。
所以本节以外的上下文都是专门指用来说P社写死的上下文,而可以重复利用的上下文则会被称呼为effect,trigger或者modifier。
分辨是否写死的上下文比较简单,写死的上下文除了其他参数外,等于号后面均为大括号,而可以重复利用的既有大括号又可以不带大括号
## 第二小节 不同的上下文类型
effect的上下文是瞬间发生的效果,通常以on_xxx.when_xxx,immediate之类的瞬时名词命名,自然跟着的都应该是。
trigger的上下文是一组布尔判定,如果没有指定NOR,NOT和OR,默认的上下文都是所有内部trigger的和,也就是AND,通常以is_xxx,enable,trigger命名
modfier则是一个用英文都说不利索的被滥用到极致的名词,Timed modifier可以是modifier,modifier_type可以是modifier,给定的modifier上下文也叫modifier
modifier_type是最基本的modifier,可以粗略翻译为”增益“,它们采用给定的格式对指定的Scope产生持续性的特定的加成。虽然定义它们的文件夹叫做`modifier_types`,但是由于它们对应的Event target 叫做`modifier`,且它们在界面代码也是这样称呼,因此本教程将会采用`modifier`描述这一类“modifier”
Timed modifier是modifier_type的集合,在Hoi4里面是被称为idea,它们定义了Timed modifier的名称,内部modifiere的持续时间等,还可以被effect调用。虽然定义它们的文件夹叫做`modifiers`,但是因为P社的文档已经全部把它们写成了`timed modifier`,本教程将会采用`timed modifier`描述这一类“modifier”
给定的modifier上下文,本教程已经约定称呼其为“modifier的上下文”,它们一般都位于一些持续性的名词上,更有可能直接就叫modifier,和Timed modifier相同,也是modifier的集合,只是不能被effect调用
还有一些“modifier”是类似权重的东西,这种只能自己判断,一般这种不包含`modifier`
## 第三小节 使用的稍微概述
关于effect,trigger的用法,完整的用法可以参阅wiki,或者在控制台使用`script_docs`自行生成文档,但是如果不能掌握Scope和Event target,你根本无法正确使用
此外,无论是effect,trigger都需要符合文档给出的名称,或者在Scripted_effect和Scripted_trigger定义出全新的effect函数和trigger函数,否则它们不会运行,如果在拆解他人mod的时候发现了陌生的effect和trigger,它们很有可能就是mod作者在Scripted_effect和Scripted_trigger定义出来的
# 第二节 认识Scope和Event Target
Scope则是游戏里面的内容,Scope就是作用域,就是文本代码(无论是effect,trigger,还是modifier)作用的输入输出类型,而Event_target就是一组输入Scope,得出不一定同一类型的Scpoe的输出的关键词
## 三个特殊Scope
在详细说明Scope之前,需要要说明三个特殊Scope:root,this和prev
root是最底层的scope,在不声明任何scope的时候,作用的对象就是root。
root的类型一般预先声明,比如如果确定一个事件是state_event, 那么这个root的类型就是state,对象就是发生该事件的state
然而,有一些代码会强行把root强行转换成其他的类型,这点是需要留意的
this是当前的scope,就是位于等号右侧大括号里的输入类型,在一些需要用到当前Scope作为输入的文本代码,可以用this代替
prev是上一层的scope,是等于号左侧的单词在大括号里的的输入类型,但是不是任何时候都能够使用prev
## Scope的输入和输出
然后就可以说明Scope的输入和输出是怎么回事了
Scope一般作为输入,让文本代码在Scope里运行,注意看文档或者wiki里的`Supported Scopes`,这些就是需要输入的Scope的类型,所以运行这些代码需要把Scope设置为对应的类型
有一些`Supported Scopes`是none,那么就需要按照情况来判断
而作为输出的时候,一般位于等号的右边,就是文档或者Wiki里面写的`Supported Targets`,直接写对应的Scope就可以了,当然,一般需要配合Event target来声明这个Scope
## Event target
Event target 可以使用点连接,也可以写在大括号里,这取决于是否可以直接声明这个scope
从Event_target的文档看,Event_target有以下几个属性:`Input Scopes`,`Output Scopes`,`Requires Data`,`Global Link`
`Input Scope`就是输入的Scope, 比如`c:USA.religion`的输入就是`c:USA`,翻阅文档,显然,`religion`支持`country` Scope作为输入,因此这是合法输入,而如果使用`s:STATE_IOWA.religion`则是非法输入,当然说不定没准什么时候P社来一次更新就支持`state` Scope了,所以文档需要时常更新
`Output Scopes`就是输出的Scope,一般给定什么就是什么,除了有value或者bool输出的`modifier:`和根据输入给出type的`type`
`Requires Data`就是是否需要判断有额外的参数输入,参数的输入需要是在冒号后面提供,比如`modifier:country_subsidies_all`就是给定了modifier的名字`country_subsidies_all`作为额外参数来得到指定的modifier的,更为人知晓的则是`s:STATE_IOWA`,给定`STATE_IOWA`作为名字获取衣阿华州的`state_region` Scope
如果要进一步获取美国的衣阿华州,则需要结合.的连接和:的提供参数,使用`region_state`转化为`state scope`,而翻阅文档可得,`region_state`也是`Requires Data`,所以我们给定国家的名称,也就是`s:STATE_IOWA.region_state:USA`就可以获得美国的衣阿华州
`Global Link`就是前面不需要Scope输入,可以不带点`modifier:country_subsidies_all`和`s:STATE_IOWA`对应的`modifier:`和`s:`都是不需要Scope输入的所以可以直接不带点,而`s:STATE_IOWA.region_state:USA`的 `.region_state:`需要Scope输入,所以前面需要带点
Scope还能通过`save_scope_as = <string>`命名为可以在事件链中使用的Event target的`scope`,通过`scope:<string>`调用, 但是只能在一个事件链中存储
另一种存储就是通过存变量实现,这种就要留到下一章再说了
# 我们现在学会了上下文和Scope
现在, 下课
哇袄