等等,先别提刀!我需要先解释一下原因。你们可能曾读过Tinto Talks#85-模组制作或是已经开始尝试制作EU5的模组了!
EU5中,我们的脚本语言得到了一次重大更新,开发了数据库接入模式。这个功能允许你决定一段脚本要如何与已存在的(游戏中的或是其他模组中的)脚本共同作用,通过一系列新的关键字。
这一功能将加入Victoria 3。也因此,新版本更新后,你将需要根据强制要求的新语法调整你的模组。
如果各位没有了解过这个功能,让我举例说明这一个系统:
首先,假设我现在想调整征召农兵这一法律,以体现乡村民众利益集团的精神与力量。我可以在该法律的键值前使用INJECT关键字,该关键字可以将脚本内容插入现有的法律中,而非取代它。
你可能发现了,将修正插入现有的内容会计算为加法。加入原有内容中有+25%威望的修正,你又inject了一个+50%威望的修正,那么最终结果会是+75%威望。
新的关键字一共有六种,为了方便,我将它们全部列于此处:
# code
INJECT:key#此模式下,代码将尝试添加进已有内容。若不存在对应key,则报错。
REPLACE:key#此模式下,代码会替换掉已有内容。若不存在对应key,则报错。
TRY_INJECT:key#此模式等同于INJECT,但若不存在对应key,不会报错。
TRY_REPLACE:key#此模式等同于REPLACE,但若不存在对应key,不会报错。
INJECT_OR_CREATE:key#此模式等同于INJECT,但若不存在对应key,会创建新的内容。
REPLACE_OR_CREATE:key#此模式等同于REPLACE,但若不存在对应key,会创建新的内容。
# code end
使用正确的关键字能够避免许多兼容性问题,也能更容易与现有的模组进行兼容性适配——如果你和同行们热烈的交流的话。
请注意,您必须明确调用这些关键字。代码不允许隐式替换,所以如果您有时间,记得更新一下代码!
以下是这个新系统生效的数据库:
# spoiler
acceptance_statuses
ai_strategies
amendments
battle_conditions
building_groups
buildings
buy_packages
character_interactions
character_templates
character_traits
cohesion_levels
combat_unit_groups
combat_unit_types
combat_unit_experience_levels
commander_orders
company_charter_types
company_types
country_creation
country_definitions
country_formation
country_ranks
country_types
culture_graphics
cultures
decisions
decrees
diplomatic_actions
diplomatic_catalyst_categories
diplomatic_catalysts
diplomatic_plays
discrimination_trait_groups
discrimination_traits
dna_data
dynamic_company_names
dynamic_country_names
dynamic_country_map_colors
dynamic_treaty_names
technology
flag_definitions
game_concepts
geographic_regions
goods
government_types
harvest_condition_types
ideologies
institutions
interest_group_traits
interest_groups
journal_entry_groups
journal_entries
law_groups
laws
legitimacy_levels
liberty_desire_levels
military_formation_flags
mobilization_option_groups
mobilization_options
objective_subgoal_categories
objective_subgoals
objectives
parties
political_lobby_appeasement (factor)
political_lobby_appeasement (reason)
political_lobbies
political_movement_categories
political_movement_pop_support
political_movements
pop_needs
pop_types
power_bloc_coa_pieces
power_bloc_identities
power_bloc_map_textures
power_bloc_names
power_bloc_principle_groups
power_bloc_principles
prestige_goods
production_method_groups
production_methods
proposal_types
religions
social_classes
social_hierarchies
map_data/state_regions
state_traits
strategic_regions
subject_types
terrain_manipulators
terrain
themes
tutorial_lessons
tutorial_lesson_chains
labels
war_goal_types
alert_groups
alert_types
commander_ranks
scripted_buttons
scripted_progress_bars
treaty_articles
gfx/map/city_data/city_building_vfx
gfx/map/fleet_dioramas
gfx/map/fleet_entities
gfx/map/army_dioramas
gfx/map/front_entities
state_regions
sound/persistent_objects
music
notifications
modifier_type_definitions
ethnicities
script_values
scripted_guis
scripted_lists
scripted_modifiers
gui_animations
achievements
modifier_icons
gfx/portraits/accessories
gfx/portraits/portrait_modifiers
# spoiler end
建筑组清理
说到会导致模组损坏的事情:
首先是,我们重命名了一系列建筑,在版本更新后你应该可以很快确认这些变化,并通过大规模替换解决问题。此前,有一些建筑键值明明不规范,我们决定让一切更一致。
其次是,地区资源现在按照建筑类型操作,而非建筑组。让我们举例说明,在map_data/state_regions中,定义发生了以下变化:
新写法:
# code
arable_resources = { "building_wheat_farm" }
capped_resources = {
building_fishing_wharf = 4
}
resource = {
type = "building_oil_rig"
undiscovered_amount = 40
}
# code end
旧写法:
# code
arable_resources = { "bg_wheat_farms" }
capped_resources = {
bg_fishing = 4
}
resource = {
type = "bg_oil_extraction"
undiscovered_amount = 40
}
# code end
此改动意图消灭那些仅在资源定义中被用到的建筑组。现在,每种农场不再属于各自的建筑组,而是属于一个bg_staple_crops建筑组。被移除的建筑组仍被记录在数据库中,但已不再被使用,并将在1.13版本被彻底移除。我们也增加了临时方案,当你输入建筑组时,代码会尝试读取建筑组的默认建筑类型。该临时方案也将在1.13版本删除,所以我们依然推荐更新你的模组。
可模组化战争目标
无论如何,我们要进行下一个主题了:脚本化战争目标类型!
我们清楚这是你们中的许多人很久以来一直期待的东西。我十分高兴的宣布,实现了。我们新建了一个数据库,存放在common/war_goal_types文件夹中。
当更新上线后,我们此前的战争目标都将被放在这个文件夹中。不过需要说明的是,很多原版的行为都是由代码编写的的,所以在进行修改时一定要加倍小心。
# code
some_war_goal = {
icon = "gfx/interface/icons/war_goals/icon.dds"
### List of Kinds
# annex_country
# ban_slavery
# Will convert to law commitment treaty article for slavery banned
# colonization_rights
# conquer_state
# contain_threat
# enforce_treaty_article
# force_nationalization
# foreign_investment_rights
# Will convert to investment rights treaty article
# humiliation
# increase_autonomy
# independence
# join_power_bloc
# leave_power_bloc
# liberate_country
# liberate_subject
# make_dominion
# make_protectorate
# make_tributary
# open_market
# reduce_autonomy
# regime_change
# return_state
# revoke_all_claims
# revoke_claim
# secession
# take_treaty_port
# Will convert to treaty port treaty article
# transfer_subject
# unification
# unification_leadership
# custom
# No predefined effect. In case you only want to execute the on_enforced effect, but nothing else.
kind = war_goal_kind # The Kind of the war goal defines the code-side predefined package of behavior that war goal will have, primarily defining what effect the war goal has when executed.
### List of settings
# require_target_be_part_of_war
# Target country has to be in the war, can't target neutral countries
# can_add_for_other_country
# Allows adding the goal for other participating countries
# annexes_entire_state
# Flag for if the goal is expected to always annex the entire target state. This is used to calculate conflicts with other goals
# annexes_entire_country
# Flag for if the goal is expected to always annex the entire target state. This is used to calculate conflicts with other goals
# country_creation
# Flag for if the goal creates a new country
# overlord_is_stakeholder
# Flag for if the stakeholder of the war goal should be the overlord rather than the target country itself
# can_target_decentralized
# If the war goal can target decentralized countries
# has_other_stakeholder
# If the war goal has a different stakeholder than the target itself
# turns_into_subject
# If the war goal turns the target country into a subject. For conflict resolution purposes
# skip_build_list
# If the war goal should be available to be picked in the diplomatic play or not
# targets_enemy_subject
# If the war goal should target an enemy subject specifically rather than all enemies in the war goal
# targets_enemy_claims
# If the war goal should target the claims of a country, rather than the country itself
# requires_interest
# If the war goal requires you to have an interest in the relevant strategic zone
# debug
# No effect, used for code debug purposes.
# validate_subject_relation
# Validation behavior that checks if the resulting subject relation of this war goal is valid
# validate_formation_candidate_self
# Validation check to make sure the goal holder is a formation candidate
# validate_formation_candidate_target
# Validation check to make sure the goal target is a formation candidate
# validate_sole_formation_candidate
# Validation check to make sure the goal holder is the only formation candidate
# validate_target_not_treaty_port
# Validation check to make sure the target state is not a treaty port
# validate_join_power_bloc
# Special validation for join power bloc war goal kind
# validate_colonization_rights
# Special validation for colonization rights war goal kind
# validate_force_nationalization
# Special validation for force nationalization war goal kind
# validate_foreign_investment_rights
# Special validation for investment rights war goal kind
# validate_regime_change
# Special validation for regime change war goal kind
# validate_contain_threat
# Special validation for contain threat war goal kind
# validate_revoke_claims
# Special validation for revoke claims war goal kind
# validate_increase_autonomy
# Special validation for increase autonomy war goal kind
# validate_take_treaty_port
# Special validation for take treaty port war goal kind
# validate_independence
# Special validation for independence war goal kind
# validate_conflicts_war_goals_holder
# Validate conflicts with war goals of the same type from holder
# validate_conflicts_war_goals_all
# Validate conflicts with war goals of the same type from all participating countries
# validate_conflicts_conquer_state
# Validate conflicts with war goals that conquer states (i.e. that have the conflicts_with_annex_state)
# validate_conflicts_annex_country
# Validate conflicts with war goals that annex countries (i.e. that have the conflicts_with_annex_country)
# validate_conflicts_make_subject
# Validate conflicts with war goals that make new subjects (i.e. that have the conflicts_with_make_subject)
# validate_conflicts_existing_subject
# Validate conflicts with war goals that make new subjects (i.e. that have the conflicts_with_make_subject)
# conflicts_with_make_subject
# Marks the war goal as potentially conflicting with make subject war goals
# conflicts_with_country_creation
# Marks the war goal as potentially conflicting with country creation war goals
# conflicts_with_annex_country
# Marks the war goal as potentially conflicting with annex country war goals
# conflicts_with_annex_state
# Marks the war goal as potentially conflicting with annex state war goals
# conflicts_with_existing_subject
# Marks the war goal as potentially conflicting with existing subject war goals
settings = { # Settings further customize how the war goal is treated in different checks. A war goal can only have one kind, but multiple settings.
setting_1
setting_2
}
execution_priority = 80
### List of Contestion Types
# control_target_state
# control_target_country_capital
# control_any_target_country_state
# control_any_target_incorporated_state
# control_own_state
# control_own_capital
# control_all_own_states
# control_all_target_country_claims
# control_any_releasable_state
contestion_type = control_type
## Target Type
#What kind of entity the war goal primarily "targets". This primarily defines how the game generates potential alternatives for each war goal type when selecting one from the diplomatic play panel. Most war goal kinds will require a specific target type to work well and can't be changed (i.e. Conquer State can't have a Treaty Article target type). This field primarily allows you to have custom war goals target different entities.
### List of Target Types
# Country
# Loops over enemy countries to generate war goal alternatives
# State
# Loops over states belonging to enemy countries
# Treaty Article
# Loops over article types and then enemy countries
target_type = target_type
possible = {
# trigger to determine if a goal with its target data is listed when selecting a war goal in the diplo play panel
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
}
valid = {
# trigger in addition to some basic validation code-side
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
}
maneuvers = {
# script value
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
value = 10
}
infamy = {
# script value
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
value = 15
}
on_enforced = {
# script effect on top of the predefined code effect
# scopes: root = holder, creator_country, diplomatic_play, target_country, target_state, stakeholder, target_region, article_options
}
}
# code end
无上下文日志条目
无上下文日志条目,或称“全局日志条目”,是一种新的日志条目标记类型。在我们谈到这个功能的有趣之处之前,我还是不得不先遗憾的警告大家,本次更新将使模组损坏。
你需要为你的日志条目组(common/journal_entry_groups)设置context来修复模组。你需要为每个日志条目组添加一行代码“context = none/country”。在多数情况下,如果你的日志条目绑定在国家上,那么此处就应该输入country,而如果输入为none,那么意味着这个日志是一个全局日志条目。
全局日志条目的撰写方式与其他日志条目类似,不过拥有一系列新的触发器与效果,以满足其同时被多个国家分享的需要。总的来说,这应该很容易理解,但它是一个非常酷且令人兴奋的功能,我们今后会经常使用,希望你们也会喜欢!
下面是一个全局日志条目的例子:
# code
# Sample JE for global journal entries
je_global_test = {
icon = "gfx/interface/icons/event_icons/event_map.dds"
group = je_group_global_test
is_shown_when_inactive = {
always = no
#always = yes
}
modifiers_while_active = {
lippe_crisis_ongoing
}
scripted_button = je_global_test_button
scripted_button = je_global_test_button_2
should_be_involved = {
OR = {
country_rank >= rank_value:great_power
country_definition = cd:LIP
country_definition = cd:SCM
}
}
should_show_when_not_involved = {
OR = {
country_rank >= rank_value:major_power
country_definition = cd:LIP
country_definition = cd:SCM
}
}
possible = {
always = no
}
complete = {
any_country = {
count < 1
OR = {
country_definition = cd:LIP
country_definition = cd:SCM
}
}
}
fail = {
any_country = {
count > 2
OR = {
country_definition = cd:LIP
country_definition = cd:SCM
}
}
}
immediate_all_involved = {
if = {
limit = { exists = c:LIP }
change_relations = { country = c:LIP value = -10 }
}
if = {
limit = { exists = c:SCM }
change_relations = { country = c:SCM value = -10 }
}
}
on_become_involved_after_activation = {
if = {
limit = { exists = c:LIP }
change_relations = { country = c:LIP value = -10 }
}
if = {
limit = { exists = c:SCM }
change_relations = { country = c:SCM value = -10 }
}
}
on_no_longer_involved = {
if = {
limit = { exists = c:LIP }
change_relations = { country = c:LIP value = 10 }
}
if = {
limit = { exists = c:SCM }
change_relations = { country = c:SCM value = 10 }
}
}
on_complete_all_involved = {
add_modifier = { name = lippe_crisis_averted years = 10 }
}
on_fail_all_involved = {
add_modifier = { name = lippe_crisis years = 10 }
}
on_timeout_all_involved = {
add_modifier = { name = lippe_crisis years = 10 }
}
on_weekly_pulse = {
effect = {
scope:journal_entry = {
every_scope_je_involved = {
limit = {
NOR = {
country_rank >= rank_value:great_power
country_definition = cd:LIP
country_definition = cd:SCM
}
}
scope:journal_entry = { remove_involved_country = prev }
}
}
scope:journal_entry = { remove_involved_country = c:FRA }
scope:journal_entry = { add_involved_country = c:ARG }
}
}
weight = 1000
timeout = 1825
should_be_pinned_by_default = yes
}
# code end
地理区域
另一个新功能是地理区域,它是可以被任意定义且固定的脚本列表,可以被任何触发器或是检查引用。
地理区域的添加非常简单,你只需要在common/geographic_regions文件夹创建一个文件,然后把列表写进去就好。
其完整定义如下:
# code
geographic_region_key = {
# All state/strategic regions are added together to form a geographic region
# the key to access this in script lists i.e <any/..>_<state/...>_in_europe
short_key = "europe"
# The Strategic Regions this geographic region encompasses
strategic_regions = { sr:<key> sr:<key> sr:<key> }
# The State Regions this geographic region encompasses
state_regions = { <STATE_REGION> <STATE_REGION> }
}
# code end
区域性生产方式
与地理区域紧密相连的新功能区域性生产方式向大家问好。该功能允许你定义一种生产方式,该生产方式仅对世界的一部分生效。这种方式其实类似于一种“建筑变体”,比如潮湿咖啡种植带?
文化性自定义姓名顺序
现在,你可以通过一个文化数据库中的标记定义名字的展示顺序。默认情况下,显示方式被定义为first_last,但你也可以把它设置为last_first,意味着你可以把姓氏放在前面,把名字放在后面。
我们已将此系统应用于世界各地我们认为适用的文化。老实说,你们当中有多少人知道匈牙利语传统上也是把姓放在前面?(月姬:致敬传奇模组汉语圈与匈牙利文化姓前名后。)
控制台
控制台按钮也面貌一新,许多常用命令和作弊码的按钮也得到了快捷按钮。
眼尖的玩家可能还发现了新的Inspect Country按钮,点击该按钮会为当前选中/观察的国家打开脚本运行器窗口。你也可以通过控制台指令打开观察器,例如,“inspect_country GBR”会打开英国的窗口。
受CK3启发,我们也在其他地方添加了一些debug按钮,如右键杀死一个所选角色。仅仅是为了测试目的哦!
我们计划在未来添加更多这类按钮。
假修正
在漫长的等待过后,我们加入了定义仅脚本修正的功能——或者叫假修正更容易让人理解。在common/modifier_type_definitions中的文件定义修正时,你可以添加一个“script_only = yes”标记,将修正标记为假修正。这么做可以抑制报错,拯救你的C盘。
法律修正案
上一篇开发日志中介绍的法律修正案功能也是完全可模组化的!你可以在common/amendments数据库中自定义新的修正案,随后通过新的效果添加至法律中。
我还是要把示例放在下方:
# code
amendment_test = {
parent = law_peasant_levies # optional reference to a law that dictates what stances IGs and movements have toward this amendment
allowed_laws = { # list of laws that the amendment can be added to
law_professional_army
law_national_militia
law_mass_conscription
law_census_voting
}
modifier = {}
tax_modifier_very_low = {}
tax_modifier_low = {}
tax_modifier_medium = {}
tax_modifier_high = {}
tax_modifier_very_high = {}
possible = {
always = yes
}
can_repeal = {
always = yes
}
ai_will_revoke = {
always = yes
}
}
# The effect:
# add_amendment
# Adds an amendment to the scoped law.
add_amendment = {
type = amendment_example
sponsor = interest_group
cooldown = 120 # months
timeout = 240 # months (optional, 0 = none)
}
**Supported Scopes**: law
# code end
结语
回过头一看,确实挺多的,但其实还没结束!如往常一样,我们还新增了一系列新的触发器、新的修正类型、效果,并对模组制作进行了小型改进。不过考虑到篇幅问题,我还是决定把剩下的部分留到更新日志时再说。
再次感谢大家一直以来的支持,也感谢大家创作的令人惊叹的模组!:)
本周四,你们将看到下一篇开发日志。日志将讲述西班牙在1.12版本与在Iberian Twilight中得到的更新。不见不散!
作者: z363046305 时间: 昨天 19:56
又在修底层代码啊 (, 下载次数: 0)