脚本化触发器、效果、变量与 inline_script

用脚本化触发器/效果、脚本变量和 inline_script 复用脚本

写到第三个事件时,你会发现同一段条件、同一串效果到处复制。群星提供了四种复用手段:

手段位置复用的是
脚本化触发器common/scripted_triggers/一组触发器
脚本化效果common/scripted_effects/一组效果
脚本变量common/scripted_variables/一个数值或字符串常量
inline_scriptcommon/inline_scripts/任意一段脚本文本

脚本化触发器与效果

定义(原版 common/scripted_triggers/00_scripted_triggers.txt 开头的示例):

Clausewitz 脚本
example_trigger = {
	is_country_type = default
	num_communications > 0
}
Clausewitz 脚本
example_effect = {
	add_resource = { energy = -100 }
}

使用时像普通触发器/效果一样写 = yes:

Clausewitz 脚本
trigger = {
	example_trigger = yes
}
immediate = {
	example_effect = yes
}

它们在哪个作用域被调用,内部就在哪个作用域执行。原版的一个真实例子:

Clausewitz 脚本
is_pirate_system = {
	any_fleet_in_system = {
		is_ship_size = pirate_station
	}
}

参数

原版 common/scripted_effects/99_advanced_documentation.txt 详细说明了参数用法。调用时传入 参数名 = 值,定义里用 $参数名$ 取值:

Clausewitz 脚本
# 定义
mymod_give_reward = {
	add_resource = { $RESOURCE$ = $AMOUNT|100$ }
	set_country_flag = mymod_rewarded_$RESOURCE$
}

# 调用
mymod_give_reward = { RESOURCE = energy AMOUNT = 250 }
mymod_give_reward = { RESOURCE = minerals }      # AMOUNT 取默认值 100
  • $AMOUNT|100$ 表示没传时的默认值。
  • 参数可以拼接:mymod_rewarded_$RESOURCE$。

参数还能当开关用,[[参数] ... ] 在传了该参数(且不为 no)时生效,[[!参数] ... ] 相反:

Clausewitz 脚本
example_effect = {
	[[ENERGY]
		add_resource = { energy = $ENERGY$ }
	]
	[[!ENERGY]
		add_resource = { minerals = 100 }
	]
}

example_effect = yes 给 100 矿物,example_effect = { ENERGY = 150 } 给 150 能量币。

注意事项

  • 在脚本化效果/触发器里使用本地化命令要转义:log = "\\[Root.GetName]",否则第二次使用时会出错。
  • 实测 4.5.2 中 scripted_triggers 和 scripted_effects 都是 LIOS:同名定义后读的生效。想覆盖原版的同名定义,文件名要排在原版文件之后(见加载顺序与覆盖规则)。
  • 原版 print_scope_effect / print_scope_trigger 是现成的调试工具,见调试。

脚本变量

以 @ 开头的常量,在 common/scripted_variables/ 中定义的对所有脚本文件全局可用:

Clausewitz 脚本
# common/scripted_variables/mymod_variables.txt
@mymod_signal_reward = 150
Clausewitz 脚本
add_resource = { energy = @mymod_signal_reward }

原版 00_scripted_variables.txt 的注释说明:它们“可以在每个普通脚本文件里被覆盖”,也就是在某个文件顶部写同名的 @变量 只影响这个文件。

  • 实测 scripted_variables 是 FIOS:同名的全局变量先读的生效,后读的报 Variable name … is already taken。
  • 变量名请加模组前缀。

行内数学

@[ ] 里可以写算式,支持 + - * / %、括号和 | |(绝对值),并可直接引用脚本变量(不写 @):

Clausewitz 脚本
add_resource = { energy = @[ mymod_signal_reward * 2 ] }

在脚本化效果/触发器里要写成 @\[ ... ],并且可以和 $参数$ 组合。

inline_script

inline_script 是“文本级的复制粘贴”:游戏把调用处替换成文件内容。它能用在不是触发器、也不是效果的地方,例如建筑的资源表。原版 common/inline_scripts/00_README.txt 的例子:

Clausewitz 脚本
# common/inline_scripts/edicts/upkeep_low.txt
resources = {
	category = edicts
	upkeep = {
		unity = 10
		multiplier = value:edict_size_effect
	}
}
Clausewitz 脚本
fortify_the_border = {
	length = @EdictPerpetual
	icon = "GFX_edict_type_policy"

	inline_script = "edicts/upkeep_low"

	modifier = {
		starbase_upgrade_speed_mult = 0.50
	}
}

规则:

  • 一个文件只放一个 inline_script,文件路径(不含扩展名,相对 common/inline_scripts/)就是它的名字,可用子文件夹组织。
  • 带参数时改用块写法,文件里用 $参数$:
Clausewitz 脚本
inline_script = {
	script = jobs/biologists_add
	AMOUNT = @building_static_jobs
}

(摘自原版 common/buildings/05_research_buildings.txt。)参数值是字符串,用引号包起来甚至可以塞进多条语句。

注意 并不是所有位置都支持 inline_script。若 error.log 提示 inline_script 是 unexpected token 或 encountered before init,说明那里不能用;它也不能用在 examples = { abc test2 } 这样的列表里。

该选哪个?

  1. 只是一组条件 → 脚本化触发器。
  2. 只是一组效果 → 脚本化效果。
  3. 一个会被多处引用的数字 → 脚本变量。
  4. 需要复用的是一段结构(资源表、选项块、整个对象定义)→ inline_script。