肖像模组制作

本页面所适用的版本可能已经过时,最后更新于2.8
(重定向自Portrait modding



The character screen

肖像是通过叠加基本元素的层来构建的:背景、通用头部、面部元素(脸颊、头发、鼻子等)、衣服、帽子等。

这些基本元素中的每一个都有多个变体或框架。

框架的选择基于以下几点:

  • 角色的DNA,
  • 角色的某些Property(也就是triggers)

儿童是一个例外,因为它们是使用单个图像创建的,因此儿童看起来很相似。

特性

有两种特征:DNA和属性。两者都是字母串(变量值可能为零)。

他们可以通过控制台命令charinfo来查看。

DNA

DNA是由父母遗传的11个字母组成的字符串,出生后不会改变。

对于已经成为历史的角色,他们的DNA被设置在角色历史:

125501 = {
	name="Temujin" # AKA: Genghis Khan
	dynasty=11100
	dna="bfimkolbecc"
	(...)
}

否则,随机生成的角色将获得随机的DNA字符串,这些字符串将保存在游戏存档中。

Index Used for
d0 脖子
d1 下巴
d2 嘴巴
d3 鼻子
d4 脸颊
d5 不使用的变量
d6 眼睛
d7 耳朵
d8 发色
d9 瞳色
d10 不使用的变量

所以成吉思汗角色代码中的 dna = "bfimkolbecc" 意味着:

  • 脖子使用图像b (mongol_male_neck_1.dds中的第二个图标)
  • 下巴使用图像f(mongol_male_chin_1.dds中的第六个图标)
  • 嘴巴使用图像i(mongol_male_mouth_1.dds中的第九个图标)
  • 鼻子使用图像m(mongol_male_nose_1.dds中的第13个图标)
  • 以此类推...

如果dds文件中的图像块数量小于字母对应的数字, 它就会循环计数。比如,下巴对应的dds文件只有4个图标,那么a和e都代表第一个图标。

Property

属性在ck2中由一个14位的字符串组成。如果字符串不够长,结尾会加上0。

只有头发(p1)和胡子(p4)可以在游戏里通过Customization Pack修改。其他的值来自portrait_properties.txt

  • p0: 背景
  • p1: 头发
  • p2: 基本的脑袋
  • p3: 衣服
  • p4: 胡子
  • p5: 头盔
  • p6: 是否在监狱
  • p7: 伤疤图层1
  • p8: 红色的点
  • p9: Boils
  • p10: 是否盲人
  • p11: 是否玩家
  • p12: 面具
  • p13: 眼罩
  • p14: 中式化妆图层
  • p15: 中式化妆图层2
  • p16: 中国皇帝的珠宝
  • p17: 永生
  • p18: 特殊王冠-后
  • p19: 特殊王冠
  • p20: 雀斑
  • p21: 体格
  • p22: 苍白的
  • p23: 黑眼圈
  • p24: 兔唇
  • p25: 伤疤图层2
  • p26: 伤疤图层3
  • p27: 溅血
  • p28: 纹身
  • p29: 土著出征前的脸部化妆
  • p30: 恶魔之子
  • p31: 法兰克文化男性叠加图层
  • p32: 法兰克文化女性叠加图层
  • p33: 法兰克文化女性叠底图层和头发

可以用下面的方式添加新的Property:

  • 定义一个包含sprite的.gfx文件,以GFX_custom为例。
spriteType = {
	name = "GFX_custom"
	texturefile = "gfx\\characters\\shared\\new_property.dds"
	noOfFrames = 2
	norefcount = yes
	can_be_lowres = yes
}
  • 在portrait_properties.txt配置p18 (property的数量是从这里动态确定的):
# p18
18 = {
	0 = {
		factor = 50
	}
	1 = {
		factor = 50
	}
}
  • 在portraits.gfx中叠加图层: "GFX_custom:p18"

渲染

基于玩家的实验,以下是对游戏中肖像渲染工作原理的描述。记住,其中一部分的逻辑仍然由Portrait Builder重新实施,这用来作为游戏外的渲染检查工具。

孩子

对于孩子的portraits:

  1. 直接在 /interface/portraits/* 查找 PORTRAIT_<culturegfx>_child_<sex>
    • <culturegfx> 是graphical_culture用来定义角色所属的文化或者文化组。
    • <sex> 决定是男是女。

封建制度政府

游戏渲染封建封建制度政府中成人肖像如下:

  1. 直接在/interface/portraits/portrait.gfx (或者其他/interface/*下面的portraitType) 寻找PORTRAIT_<culturegfx>_<sex><_period><age>,
    • <culturegfx>graphical_culture 用来定义角色所属的文化或者文化组。(common/cultures/00_cultures.txt)
    • <sex>决定是男是女。
    • <age>是一个int类型(整数值)r: 0代表年轻(16 <= age < 30), 1代表中年 (30 <= age < 50), 2代表暮年(age >= 50)
    • <_period> 在值为_early时说明早于950年。_late 时说明晚于1250年。其他情况下为空值。(注意:真实的时间放在defines下面的EARLY_PORTRAIT_AND_UNIT_BEFORE_YEAR和LATE_PORTRAIT_AND_UNIT_AFTER_YEAR定义中)
  2. 如果没有匹配的portraitType,将会尝试寻找某些默认值:no date, no age,返回值中寻找graphical_cultures列表里面的种族。寻找来自父母文化组的种族特点(注意不是文化,种族是先天的,文化后天可以改)。万不得已会将变量的值变为westerngfx。
  3. 如果没有匹配的portraitType,将会按照顺序使用图层,每个图层被定义在 GFX_TYPE:[d|p]INDEX:
    1. 在spriteTypes(/interface/portraits/portrait_sprites.gfx或者其他 /interface/*下的spriteType)寻找 GFX_TYPE 然后读取dds文件的图标序号N
    2. 解析要使用的dds图标:
      • 如果字符串的值为d, 在DNA字符串的INDEX位置查找,转换数字后对N进行取模的运算(运算符mod)。
      • 如果字符串的值为p, 解析值的INDEX属性。这定义于/interface/portrait_properties.txt。选择基于加权随机,但将自动选择评估结果>=100的第一个结果。
  4. 为种族定义肤色,在common/graphicalculturetypes/graphicalculturetype.txt,因此这也可以"管理"到混血儿。

神权制度政府

该制度政府下的人物肖像渲染类似封建制度政府,但头饰和服装层除外。

  1. 寻找角色的宗教定义,然后直接查找dds文件里的图标目录。 (portrait_properties.txt不起作用):
    • religious_clothing_head: 用于宗教头饰图层的dds图标文件。
    • religious_clothing_priest: 用于其他宗教下祭祀的dds图标文件。
  2. GFX_religious_male_clothes下的dds图标目录是硬编码的, 比如GFX_religious_male_headgear。这些文件用来替换掉portrait.gfx中的定义。

共和制政府

该制度政府下的人物肖像渲染类似封建制度政府,但头饰和服装层除外。 GFX_merchant_male_clothes下的dds图标目录是硬编码的, 比如GFX_merchant_male_headgear。这些文件用来替换掉portrait.gfx中的定义。


衣物覆盖

2.7版本添加了一种新机制,可以根据规则覆盖服装层。

ck2中唯一的代码翻译位于dlc072.zip下的 \interface\portraits\society_clothes.gfx

完整数组代码的结构如下所示:

portraitType = {
	name = "PORTRAIT_<override_type>_clothing_male"

	weight = {
		additive_modifier = {
			value = 10000
			# Conditions (in portrait scope) for modifier to apply
		}
	}

	layer = { # GFX_empty can be used to disable a layer
		"GFX_xxx_male_clothing_behind:c0"
		"GFX_xxx_male_headgear_behind:c1"
		"GFX_xxx_male_clothing_front:c2"
		"GFX_xxx_male_headgear_mid:c3"
		"GFX_xxx_male_clothing_infront:c4"
		"GFX_xxx_male_headgear_front:c5"
	}

	allow_property_values = {
		<property_index> = {
			<frame_index> = {
				# Conditions (in portrait scope) for frame to be used
			}
		}
	}
}

注意:

  • c0到c7是根据"文化目录"来渲染衣物的图层的(通常是由p3和p5定义):
    • c0 =衣物-后
    • c1 =头饰-后
    • c2 =衣物
    • c3 =头饰-中
    • c4 =衣物-前
    • c5 =头饰
    • c6 =头发后面的头饰图层
    • c7 =头饰与头发图层

注意:通过模组你不能添加一个动态的额外文化图标目录。

  • layerallow_property_values 可以像portrait_properties.txt用类似的方式选择p3 (衣物) 和p5 (头饰) 下覆盖衣物对应dds文件下的图标。

Portrait scope

A new scope is used, which is a sort of limited version of a character scope, with conditions prefixed with portrait_.

变量名 变量类型 ck2是否可用 变量说明 代码示例
portrait_age child/oldage 角色的年龄在portrait threshold阈值判断下来说是孩子,年轻,中年还是一个老年人。由于阈值是可配置的,因此这里没有直接硬编码数值。 portrait_age > child

portrait_age < oldage

portrait_is_female bool 角色是否为女性 portrait_is_female = yes
portrait_has_trait trait 该外貌变量下角色是否有特性 portrait_has_trait = vaishnavist_hindu
portrait_religion religion X [Seen in the .exe - to be tested]
portrait_culture culture 角色的文化 portrait_culture = greek
portrait_culture_group culture_group 字面意思:文化组 portrait_culture_group = latin
portrait_gfx_culture ? X [Seen in the .exe - to be tested]
portrait_government government X Whether character has the specified government. Seems to only work on landed characters.
portrait_tier tier portrait_tier = king
portrait_title_tier ? X [Seen in the .exe - to be tested]
portrait_society society portrait_society = monastic_order_benedictine
portrait_society_rank int Character rank if member of a society portrait_society_rank = 1
portrait_clothing bool 警告: portrait_clothing = no 似乎不起作用. portrait_clothing = yes
portrait_offmap offmap_power 该角色是否为中国皇帝 portrait_offmap = offmap_china
portrait_is_patrician bool X 角色是否在一个商人共和国,他们的雇主是贵族,还是有共和国政府的形式。 portrait_is_patrician = yes
portrait_in_command bool X 该角色是否带领军队 portrait_in_command = yes

自定义种族

通过在肖像类型层中创建新资产和/或混合现有的ck2或DLC资产,可以创建新的种族。

例如,一个customgfx种族和norsegfx的脸和byzantinegfx的衣服。

新的资产

主条目:Graphics modding

如果你从头创建一个图像sprite,你需要

  • 在文件夹gfx/characters/中创造两个文件夹(gothic_male和gothic_female) 来存放sprite (例如:有12个图标的gothic_male_clothes.dds)
  • 在文件夹interface/创造一个portraits_gothic_spritetypes.gfx文件,文件下要有每个图像sprite都有一个条目:
spriteTypes = {
  spriteType = {
    name = "GFX_gothic_male_clothes"
    texturefile = "gfx\\characters\\gothic_male\\gothic_male_clothes.dds"
    noOfFrames = 12
    norefcount = yes
    can_be_lowres = yes
  }
  ...
}

DLC资产

重复使用DLC资产比创建新资产更容易,但因为DLC资产本身不能捆绑到模组中。[2] 没有DLC的用户将不会拥有这些资产(例如the Norse Portraits DLC) ,没有DLC的用户会见到没有渲染脑袋但是渲染衣服的gothicgfx。

如果定义了哥特式风格的一些portraitTypes,游戏就会渲染它们。即使这些层涉及未知资产,也不能正确显示。 将会在一旦对应的portraitType没有创立,其他种族的graphical_cultures列表的返回值(或者默认渲染的westerngfx)将会进行渲染。

这种问题包含以下几种状况:

  1. 将portraitTypes的定义捆绑在主mod之外的子mod中。这样的话玩家就会:
    • 如果没有所需DLC,只能让子mod工作。
    • 如果没有所需DLC,会看到候选返回值下种族外貌。
  2. 为了不使用DLC资产的种族提供后备的portraitTypes。玩家需要下载额外返回值下的portraitTypes然后再没有所需DLC情况下使用。

新的种族

如果要定义一个新的gothicgfx种族,请按照以下步骤

  • 在主要mod文件夹common/graphicalculturetypes/ 下建立一个新的txt文件并加入以下代码:
gothicgfx = {
  skin_tone = 0
}
  • 在主要mod文件夹common/cultures/00_cultures.txt 的文件中,修改或者添加一种新的哥特文化组的culture然后添加以下代码:
graphical_cultures = { gothicgfx occitangfx }

注意:如果开了子mod,那么重要的是,列表中的最后一个culturefx是ck2的类型之一(occitangfx、muslimgfx、byzantinegfx、westerngfx)。如果它是westerngfx,则可以省略它,因为它是默认值,或者用作3层种族。如果要候选返回值的portraitTypes,则不需要这样做。

  • 在子modI(或者主要mod,根据情况选择)文件夹下 interface/添加一个新的portraits_gothic.gfx文件,并且使用以下的数组结构。 (代码从ck2的另一个文件下portraits.gfx复制过来):
spriteTypes = {
  spriteType = {
    name = "PORTRAIT_gothicgfx_child_male"
  }
  spriteType = {
    name = "PORTRAIT_gothicgfx_child_female"
  }
  portraitType = {
    name = "PORTRAIT_gothicgfx_male"
  }
  portraitType = {
    name = "PORTRAIT_gothicgfx_male1"
  }
  portraitType = {
    name = "PORTRAIT_gothicgfx_male2"
  }
  portraitType = {
    name = "PORTRAIT_gothicgfx_female"
  }
  portraitType = {
    name = "PORTRAIT_gothicgfx_female1"
  }
  portraitType = {
    name = "PORTRAIT_gothicgfx_female2"
  }
}
  • 对于每个portraitType,给每个图层(自定义的、ck2本体的或者DLC的spriteType)匹配正确的sprite
portraitType = {
  name = "PORTRAIT_gothicgfx_female"
  effectFile = "gfx/FX/portrait.lua"
  layer = { # GFX_TYPE:[d|p]INDEX:COLOR_LINK:DONT_REFRESH_IF_VALID:CULTURE_INDEX
    "GFX_character_background:p0"
    "GFX_byzantine_female_clothes_behind:p3:c0"
    "GFX_byzantine_female_headgear_behind:p5:c1"
    "GFX_norse_female_hair_behind:p1:h:y"
    "GFX_norse_female_base:p2"
    "GFX_norse_female_neck:d0"
    "GFX_norse_female_mouth:d2"
    "GFX_norse_female_nose:d3"
    "GFX_norse_female_chin:d1"
    "GFX_norse_female_cheeks:d4"
    "GFX_norse_female_eyes:d6"
    "GFX_norse_female_eyes2:d6:e"
    "GFX_character_scars:p7:y"
    "GFX_character_reddots:p8"
    "GFX_character_boils:p9"
    "GFX_character_blinded_eyes:p10"
    "GFX_norse_female_ear:d7"			
    "GFX_byzantine_female_clothes:p3:c2"
    "GFX_empty:p5:c3"
    "GFX_norse_female_hair:p1:h:y"
    "GFX_empty:p3:c4"
    "GFX_byzantine_female_headgear:p5:c5"
    "GFX_character_imprisoned:p6"
    "GFX_player_overlay:p11"
}

静态的portraits

要显示静态预渲染肖像,有几种技术:

杂项层

使用杂项层(例如blinded_eyes),添加一个预先渲染的portrait图标[3]

  • 把这个图层放到portraits.gfx列表的最后面
  • 在portrait_sprites.gfx里添加新的图标 (ex: GFX_character_blinded_eyes)
  • 编辑sprite(比如blinded_eyes.dds)然后添加额外图标
  • 在portrait_properties.txt中为每个图层对应属性的dds图标添加一个条目(比如: p10盲人), 基于独特特征或角色flag的触发器
# p10 blinded
10 = {
	0 = {
		factor = 100
		modifier = {
			factor = 0
			trait = blinded
		}
		modifier = {
			factor = 0
			#Either a character flag or a unique trait.
		}
	}
	
	1 =  {
		factor = 100
		modifier = {
			factor = 0
			NOT = {
				trait = blinded
			}
		}
		modifier = {
			factor = 0
			#Either a character flag or a unique trait.
		}

	}
	2 =  {
		factor = 100
		modifier = {
			factor = 0
			NOT = {
				#Either a character flag or a unique trait.
			}
		}
	}
}

遮挡flag

在角色历史中使用occluded = yes。可用于默罕默德(先知). 最大的限制是,每个occluded = yes的角色会拥有相同的portrait。这使用单个的图标材质,而且在Muhammad.tga中硬编码

spriteType = {
  name = "GFX_Muhammad"
  texturefile = "gfx\\characters\\Muhammad.tga"
  noOfFrames = 1
  norefcount = yes
}

自定义种族

使用自定义种族,然后将之设定在角色历史中。或者通过 set_graphical_culture 事件命令 因为命令需要文化作为参数,所以还必须定义自定义文化。 此外,种族在出生时从父母中的一方随机继承。 所以需要一些on_action事件来控制。

步骤如下:

  • common/cultures/ 创建一个自定义文化
special = {
  graphical_cultures = { specialgfx }
  ...
}
  • interface/ 为自定义种族定义一个portrait, 然后需要一个基于p2 property的图标
spriteType = {
  name = "GFX_special"
  texturefile = "gfx\\characters\\special.tga"
  noOfFrames = 1
  norefcount = yes
}

portraitType = {
  name = "PORTRAIT_specialgfx_male"
  effectFile = "gfx/FX/portrait.lua"
  layer = { # GFX_TYPE:[d|p]INDEX:COLOR_LINK:DONT_REFRESH_IF_VALID:CULTURE_INDEX
    "GFX_character_background:p0"
    "GFX_special:p2"
    "GFX_character_imprisoned:p6"
  }
  hair_color = { { 10 10 10 } { 50 50 50 } { 255 255 255 } } #Must be included.
  eye_color = {	{ 255 255 255} } # Leaving these out will crash the game.
}

portraitType = {
  name = "PORTRAIT_specialgfx_female"
  ... #The rest is same as above. Both *_male and *_female portraitType are required, even for static portraits.
}
  • 使用 set_graphical_culture = special 命令和 graphical_culture = specialgfx 在事件中进行控制

External links

See also

References