脚本语法与作用域
脚本基本写法、触发器与效果、this/root/from/prev
基本语法
群星的脚本(Paradox 称为 Clausewitz 脚本)只有几种元素:
# 井号后面是注释
key = value # 赋值
key = { ... } # 块
num_communications > 1 # 比较:> < >= <=
is_ai = no # 布尔值用 yes / no
name = "country.50.a" # 字符串,含空格或特殊字符时加引号
value = @tier1unityreward # @ 开头是脚本变量- 缩进和换行没有语法意义,但请保持与原版一致的 Tab 缩进,方便排查括号。
- 大括号必须配对。少一个
}会让后面整个文件解析错乱,error.log里会出现一串看似无关的错误。 - 键名区分大小写的情况很多,照抄原版最安全。
触发器与效果
脚本里的语句分两类,不能混用:
| 触发器(trigger) | 效果(effect) | |
|---|---|---|
| 作用 | 检查条件,返回真/假 | 改变游戏状态 |
| 例子 | is_ai = no、has_country_flag = x、num_communications > 1 | set_country_flag = x、add_resource = { energy = 100 } |
| 出现的块 | trigger、limit、potential、allow、pre_triggers | immediate、option、after、effect |
触发器块里的多条语句默认是“全部成立”(AND)。逻辑运算用大写:
trigger = {
is_ai = no
OR = {
has_country_flag = story1
num_communications > 1
}
NOT = { has_country_flag = starting_event }
NOR = {
has_ethic = ethic_gestalt_consciousness
is_nomadic = yes
}
}还有 AND、NAND(AND 取反)、calc_true_if(满足其中若干条)等。
效果里需要条件分支时用 if / else_if / else,条件写在 limit 里:
immediate = {
if = {
limit = { has_country_flag = story1 }
country_event = { id = country.1 }
}
else = {
country_event = { id = country.258 days = 180 }
}
}(摘自原版 events/country_events_1.txt 的 country.258。)
另外两个常用的效果包装:hidden_effect = { ... } 让里面的效果不显示在提示框里;custom_tooltip = <本地化键> 在提示框里显示一段自定义文字。
作用域(scope)
每条触发器和效果都在某个作用域里执行,也就是“针对哪个对象”:国家、行星、舰队、领袖、星系……例如 add_resource 只能在国家作用域用,is_planet_class 只能在行星作用域用。
切换作用域就是写一个“作用域名 = { }”的块:
owner = { # 从当前对象切到它的所有者(国家)
add_resource = { energy = 100 }
}
capital_scope = { # 从国家切到首都
save_event_target_as = capital
}也可以用点号连续切换,例如 root.owner.capital_scope。
注意 4.5 把“殖民地”(colony)作为单独的作用域:
capital_scope的输出是 colony,carrier从殖民地回到承载它的行星;与之对应,原版大量行星相关事件使用carrier_event。以script_documentation\scopes.log中的 Supported Scopes / Output Scope 为准。
特殊作用域
| 关键字 | 含义(摘自 4.5 的 scopes.log) |
|---|---|
this | 当前作用域 |
root | 这一段脚本最初的作用域,例如 country_event 里的那个国家 |
prev | 上一次切换前的作用域;prevprev 再往前一层 |
from | 上一个事件的 root,或由 on_action 预设的 FROM;fromfrom 再往前一层 |
prev 的经典例子:
owner = {
capital_scope = {
is_owned_by = prev # prev 指 owner,这条恒为真
}
}from 在 on_action 里的含义由该 on_action 决定,原版 common/on_actions/00_on_actions.txt 的注释会写明,例如 on_war_beginning 是 Root = Country、From = War(见 on_actions)。
事件目标
需要在之后的事件里再次引用某个对象时,用 save_event_target_as 保存,用 event_target:名字 取回:
capital_scope = { save_event_target_as = capital }
random_system = {
limit = {
distance = {
source = event_target:capital
use_bypasses = no
min_jumps = 2
max_jumps = 6
}
}
save_event_target_as = probe_system_1
}(改写自原版 country.1 事件。)事件目标在同一条未中断的事件链中有效。
遍历:any / every / random / count
对一组对象做检查或执行效果,用前缀 + 列表名:
| 前缀 | 类型 | 含义 |
|---|---|---|
any_ | 触发器 | 其中任意一个满足条件 |
count_ | 触发器 | 满足条件的个数 |
every_ | 效果 | 对每一个满足 limit 的执行 |
random_ | 效果 | 随机挑一个满足 limit 的执行 |
ordered_ | 效果 | 按指定排序挑一个执行 |
every_owned_colony = {
limit = { is_capital = no }
add_modifier = { modifier = my_mod_bonus days = 360 }
}注意 4.5 的文档把
every_owned_planet/any_owned_planet等标记为 “Deprecated; use owned_colony instead”。照抄老教程前,先在effects.log/triggers.log里查一下。