模组:对话
← 目录
这个页面解释了游戏如何存储对话文本,它的格式,以及游戏如何解析它。它将会是一个提供给模组制造者的高级指南。
算法
游戏按如下方式寻找对话:
- 事件对话读取自相应的事件命令(参见模组:事件数据)。
- 针对地点的对话读取自 StringsFromCSFiles
<location>.cs 。 - 其他角色对话读取自针对相应角色的文件。
- 如果没有找到合适的对话,游戏会回退到 StringsFromCSFiles 文件的硬编码对话(尤其是那些前缀为 NPC.cs 的对话)。
预定义值
游戏在部分对话键中使用如下预定义值。本节主要供下文参考,必要之处可链接至本节。
一星期的各天
- Mon
- Tue
- Wed
- Thu
- Fri
- Sat
- Sun
季节
- spring
- summer
- fall
- winter
第一年/其后
某些情况下游戏使用“第一年/其后”值用于对话条件。此类型有两种可能的取值:
| 值 | 含义 |
|---|---|
| 1 | 发生于第 1 年。 |
| 2 | 发生于第 2 年及其后的所有年份。 |
数据
这些对话文本存储在四组文件中。
角色文件目录:Characters\Dialogue文件
Characters\Dialogue\*.xnb 包含了大部分角色对话里 (一个文件夹对应一个角色). 游戏将从下面的一部分内容中选择对话,依照这里排列好的指令顺序来读取对话。
*指越往下的对话格式,读取优先度会比上面的对话还要低。*
特殊对话
以下是一些针对特定情况的预设键(Key):
- 请注意是使用左侧英文键名
| 键格式(key format) | 描述(description) |
|---|---|
| breakUp | NPC 被赠与枯萎的花束分手时的反应。 |
| divorced | 与离婚的配偶对话时的反应。 |
| DumpsterDiveComment | NPC 撞见玩家翻垃圾桶时的对话。默认为基于 NPC 年龄的通用对话。 |
| GreenRain | 第一年绿雨期间的对话。 |
| GreenRain_2 | 第二年及其后绿雨期间的对话。 |
| HitBySlingshot | 被玩家用弹弓射击时显示的对话。默认为通用对话。 |
<location>_Entry
|
NPC 进入指定地点 <location> 时有50%的几率头上浮现出此对话气泡。此对话条目可以包含多重选项,以 / 分割;游戏会从中随机抽取一个。例子: SeedShop_Entry: "嗨,皮埃尔!/现在,我需要的是.../啊!看起来真不错!/今晚准备做我的特制酱料!/皮埃尔!今天的新品是什么?/皮埃尔!今天要一起出门玩吗?"说明:不要将此键与#对话气泡混淆。 |
| Resort Resort_Bar Resort_Chair Resort_Dance Resort_Entering Resort_Leaving Resort_Shore Resort_Towel Resort_Umbrella Resort_Wander |
NPC 游览姜岛度假村时的各种对话。 |
| SpouseFarmhouseClutter | NPC 配偶在农舍中无法寻路到厨房站立点时显示的对话。 |
| SpouseGiftJealous | 玩家给约会的 NPC 送礼后,其 NPC 配偶的嫉妒对话。如果配偶与约会对象性别相同,则前者有 20~40% 的概率嫉妒(除非是后者的生日)。可以在对话中使用 {0} 代表受礼 NPC 的名字,用 {1} 代表礼物的名称。 |
| Spouse_MonstersInHouse | 当 NPC 配偶在农舍中且附近有怪物时显示。 |
| SpouseStardrop | 当您从配偶那里获得星之果实时显示。 |
| WipedMemory | 当您使用记忆之黑暗神殿擦除离婚了的 NPC 的记忆后,第一次与他们交谈时显示。 |
物品对话
下述键适用于给 NPC 物品。
| 键格式 | 描述 |
|---|---|
AcceptBirthdayGift_<id>AcceptBirthdayGift_ <tag>AcceptBirthdayGift_ <taste>_<context tag>AcceptBirthdayGift_ <taste>AcceptBirthdayGift_Negative AcceptBirthdayGift_Positive AcceptBirthdayGift |
当玩家赠送生日礼物时显示。若忽略,默认为适用于所有 NPC 的通用对话。这些键会覆盖 AcceptGift_<id> 和 AcceptGift_<tag>,即使 AcceptBirthdayGift 键的针对性更低。
游戏按如下顺序检查对话键,并使用第一个匹配的键:
|
| AcceptBouquet | NPC 收到玩家的花束时显示。默认为通用对话。 |
AcceptGift_<id>AcceptGift_ <tag>AcceptGift_ <taste>_<context tag>AcceptGift_ <taste>AcceptGift |
NPC 收到玩家的非生日礼物时显示。若忽略,默认为 Data/NPCGiftTastes 中的对话。
游戏按如下顺序检查对话键,并使用第一个匹配的键:
|
| MovieInvitation | NPC 受邀观影的反应。若未定义,则 NPC 会采用来自 Strings\Characters.xnb 的通用台词,具体取决于 NPC 的礼貌程度。 |
| RejectBouquet_NotDatable RejectBouquet_NpcAlreadyMarried RejectBouquet_AlreadyAccepted_Engaged RejectBouquet_AlreadyAccepted_Married RejectBouquet_AlreadyAccepted RejectBouquet_Divorced RejectBouquet_VeryLowHearts RejectBouquet_LowHearts RejectBouquet |
NPC 拒绝花束时显示的对话。
如果可能,会采用更有针对性的对话:
若没有设置针对性对话,游戏会使用 RejectBouquet 对话(若设置),否则默认为每种情况的通用对话。 |
| RejectGift_Divorced | 当 NPC 因为与您离婚而拒绝礼物时显示。 |
RejectItem_<id>RejectItem_ <tag>
|
若设置,则 NPC 会拒绝所有匹配的物品,并显示此对话。可以使用物品 ID(例如 RejectItem_(O)128)或上下文标签(例如 RejectItem_category_fish)来匹配物品。这可用于屏蔽送礼、电影票、花束等。然而对于任务或特别任务物品无效。 说明:这些对话键的优先级高于接受礼物对话键,即使拒绝键针对上下文标签(针对性更低)而接受键针对物品 ID(针对性更高)。这意味着您无法先使用拒绝键来拒绝一组物品(例如,通过 category_gem 拒绝所有宝石),然后再用接受键来接受这组物品中的特例。如果确实需要这样做,请为物品组中每个需要被拒绝的物品单独设置拒绝键。 |
| RejectMermaidPendant_AlreadyAccepted_Engaged RejectMermaidPendant_AlreadyAccepted_Married RejectMermaidPendant_AlreadyAccepted RejectMermaidPendant_Divorced |
NPC 拒绝美人鱼吊坠时的对话。
若未设置针对性对话,则游戏会使用 RejectMermaidPendant 对话(若设置),否则默认为每种情况的通用对话。 |
| samp>RejectMovieTicket_AlreadyInvitedBySomeoneElse RejectMovieTicket_AlreadyWatchedThisWeek RejectMovieTicket_Divorced RejectMovieTicket_DontWantToSeeThatMovie RejectMovieTicket |
NPC 拒绝电影票的对话。
如果可能,会采用更有针对性的对话:
若未设置针对性对话,则游戏会使用 RejectMovieTicket 对话(若设置),否则默认为每种情况的通用对话。 |
| RejectRoommateProposal_AlreadyAccepted RejectRoommateProposal_NpcWithSomeoneElse RejectRoommateProposal_PlayerWithSomeoneElse RejectRoommateProposal_LowFriendship RejectRoommateProposal_SmallHouse RejectRoommateProposal |
(可选)NPC 拒绝室友提议,因为玩家不符合特定条件:
若未设置针对性对话,则游戏会使用 RejectRoommateProposal 对话(若设置),否则默认为每种情况的通用对话。 |
地点对话
上述对话均匹配失败后,将检查地点对话。
变体:
- 每个键都可添加季节名称作为前缀(可选),例如 springMountain_47_23。
游戏会按如下顺序检查变体:<season><key> 和 <key>。为求简洁,不再单独列出这些变体。
不同于日常对话,地点对话只要满足触发条件即可无限触发,这里的触发条件包括处在特定地点。地点对话不会从 NPC 的对话列表中移除对话,而是在 NPC 处于特定地点时覆盖这些对话。
注意:NPC 必须设置礼物喜好才能使用地点对话,即使其 CanSocialize 字段为 false(不可社交)。
| 键格式 | 描述 |
|---|---|
<location>_<x>_<y>
|
NPC 站在地点 <location> 的地块坐标 <x>, <y> 处显示的对话。示例:Mountain_47_23: "我是被和平和安静吸引而来的。" |
<location>_<dayName>
|
在指定的星期几,在指定地点的对话。 示例:Saloon_Fri: "今晚的生意很不错。我很高兴。" |
<location><hearts>
|
与该 NPC 有至少 <hearts> 心友谊时,在指定地点的对话。其中 <hearts>需要填写2的倍数。 检查的优先级为 10、8、6、4、2(不填任何数字则为0,其他取值无法识别)。示例:Saloon8: "嗨,@。见到你真高兴!在这儿,你永远是受欢迎的。" |
<location>
|
当NPC身处在指定地点,就会触发指定地点的对话。 示例:Saloon: "在这里,我终于能放松一下,聊聊天了。"
|
节日对话
| 键格式 | 描述 |
|---|---|
| Fair_Judging | 用于星露谷展览会,刘易斯检查展览时的对话。若忽略,则 NPC 会使用其常规的节日对话。
若仅设置此字段而未设置 Fair_Judged* 字段,则评价结束后 NPC 仍会重复此对话。 |
| Fair_Judged_PlayerLost_PurpleShorts Fair_Judged_PlayerLost_Skipped Fair_Judged_PlayerLost Fair_Judged_PlayerWon Fair_Judged |
用于星露谷展览会,刘易斯检查展览后的对话。
游戏按如下顺序检查对话键,并使用第一个匹配的键:
|
| FlowerDance_Accept_Roommate FlowerDance_Accept_Spouse FlowerDance_Accept |
花舞节 NPC 同意共舞的对话。游戏会优先选取 _Roommate(室友)或 _Spouse(配偶)变体键(若适用),否则会检查常规键。若忽略,默认为通用对话。 |
| FlowerDance_Decline |
花舞节 NPC 拒绝共舞的对话。(若其已同意与他人共舞,则会采用一个不同的对话。)
danceRejection 是弃用的旧版名称(仍能使用,以向后兼容)。 |
| WinterStar_GiveGift_Before_Roommate WinterStar_GiveGift_Before_Spouse WinterStar_GiveGift_Before WinterStar_GiveGift_After_Roommate WinterStar_GiveGift_After_Spouse WinterStar_GiveGift_After |
冬日星盛宴 NPC 赠与玩家礼物之前/之后(以玩家打开礼物为界)的对话。游戏会优先使用 _Roommate(室友)或 _Spouse(配偶)变体键(若适用),否则会检查常规键。若忽略,默认为通用对话。若忽略,则使用适用于所有 NPC 的通用对话。 |
WinterStar_ReceiveGift_<id>WinterStar_ReceiveGift_ <tag>WinterStar_ReceiveGift |
冬日星盛宴 NPC 收到玩家礼物的对话。可以针对特定物品 ID(例如 WinterStar_ReceiveGift_(O)128)、上下文标签(例如 WinterStar_ReceiveGift_category_fish)或任意物品(例如 WinterStar_ReceiveGift)。若忽略,默认为适用于所有 NPC 的通用对话。 |
雨天对话
Characters\Dialogue\rainy.xnb文件里每一个NPC都有对应的一个对话。如果你的情况是:还未结婚或者离婚、当天是雨天、并且上述的对话条件没有达成,你将会有50%几率读取这个雨天对话。*由于是50%,所以你可能会触发平时的对话然后说出“今天天气真好”这种诡异的对话……*
雨天对话需要使用content的EditData来添加在游戏里,以下为麻薯君的例子:
{
"Action": "EditData",
"Target": "Characters/Dialogue/rainy",
"Entries": {
"Mochi":"下雨啦!$1#$e#农作物不用浇水真是太棒了!$1#$b#不过我已经有了洒水器,所以无论是晴天雨天都没关系。#$e#所以你的洒水器都有了吗?$1"
}
},
{
"Action": "EditData",
"Target": "Characters/Dialogue/rainy",
"Entries": {
"Mochi":"下雨了你却没有避雨吗?#$b#你也是辛苦了。$8#$b#你过来我这里吧。#$b#着凉了可不好。$1"
},
"When": {
"Hearts:Mochi": "4, 5, 6, 7"
}
},
{
"Action": "EditData",
"Target": "Characters/Dialogue/rainy",
"Entries": {
"Mochi":"你看看你!#$b#不带伞还淋湿了全身上下。$6#$b#我帮你擦擦头发。$1#$b#%麻薯君拿出毛巾帮你擦干头发#$b#嗯,擦干了!$1#$e#喝点咖啡吧!$1[395]#$e#快喝吧!$1"
},
"When": {
"Hearts:Mochi": "8, 9, 10"
}
}
通用对话
上述对话均匹配失败后,将按如下顺序检查通用对话:
<season>_<key>_inlaw_<spouse><season>_<key><key>_inlaw_<spouse><key>
解释:<season> 是季节名称(例如 spring_14);_inlaw_<spouse> 判定玩家是否已与指定 NPC 结婚,无论讲话的 NPC 是否与 <spouse> 指定的 NPC 有亲属关系(例如 Sat_inlaw_Abigail);而 <key> 取下述格式之一:
| 键格式 | 描述 |
|---|---|
<1到28日><dayOfMonth>
|
在第一年每个月的指定天数显示的对话。 警告:此键仅适用于第一年的特性不同于其他各键,且经常误导毫无防备的开发者!一般情况下,您可能实际想要的是 <dayOfMonth>_*。示例:10: "你看了昨晚的比赛吗?#$b#等等,你有电视机吗……?" |
<1到28日>_<1或2年><dayOfMonth>_<firstOrLaterYear>
|
在第一年/其后每个月的指定天数显示的对话。填的是“1”的话,第一年以后(即第二、三年)不会再触发;“2”则第一年以后触发。 示例:2_1: "我丈夫肯特是位士兵,在海外服役。因此他现在不在。#$b#他服役完了后一定会安全归来的!!!#$e#需要什么吗?" |
<1到28日>_*<dayOfMonth>_*
|
在每一年每个月的指定天数显示的对话。 示例:18_*: "我待在这里会尽量保持安静的。假如镇上的人听到下水道里传来我奇怪的声音……" |
<星期几><几心>_<1或2年><dayOfWeek><hearts>_<firstOrLaterYear>
|
需同时满足:当天是星期几符合 <dayOfWeek>,与 NPC 的友谊至少为 <hearts> 心,当年是第一年/其后。其中 <hearts> 按 10、8、6、4、2 的顺序依次被检查(其他取值无法识别)。示例:Thu2_2: "我父亲回来了。你见到他了吗?#$b#很高兴他平安归来。" |
<星期几><几心><dayOfWeek><hearts>
|
需同时满足:当天是星期几符合 <dayOfWeek>,与 NPC 的友谊至少为 <hearts> 心。其中 <hearts> 按 10、8、6、4、2 的顺序依次被检查(其他取值无法识别)。示例:Sun4: "嘿,@。#$e#今天过得怎么样?" |
<星期几>_<1或2年><dayOfWeek>_<firstOrLaterYear>
|
需同时满足:当天是星期几符合 <dayOfWeek>,当年是第一年/其后。示例:Sat_1: "爸爸就要回来啦!#$b#不知他有没有给我买玩具回来呢。$u" |
<星期几><dayOfWeek>
|
当天是星期几符合 <dayOfWeek>。示例:Mon: "哦,嘿。你是在休息吗?" |
特定NPC
| NPC | 键格式 | 描述 |
|---|---|---|
| 吉尔 | ComeBackLater Snoring |
没有完成新的冒险任务时继而的对话。ComeBackLater 会出现依次,随后的每次对话都是 Snoring。 |
备用方案
在大多数情况下,如果游戏无法寻找一个 NPC 所需的字符串,其会默认使用Strings\StringsFromCSFiles.xnb中的NPC.cs.4061(英语为 "Hi.")。
雨天对话
Characters\Dialogue\rainy.xnb文件里每一个NPC都有对应的一个对话。如果你的情况是:还未结婚或者离婚、当天是雨天、并且上述的对话条件没有达成,你将会有50%几率读取这个雨天对话。*由于是50%,所以可能会触发平时的对话然后说出“今天天气真好”这种诡异的对话……*
雨天对话需要使用content的EditData来添加在游戏里,以下为模组作者麻薯君(贴吧@你的麻糬君丫)的例子:
展开例子
{
"Action": "EditData",
"Target": "Characters/Dialogue/rainy",
"Entries": {
"Mochi":"下雨啦!$1#$e#农作物不用浇水真是太棒了!$1#$b#不过我已经有了洒水器,所以无论是晴天雨天都没关系。#$e#所以你的洒水器都有了吗?$1"
}
},
{
"Action": "EditData",
"Target": "Characters/Dialogue/rainy",
"Entries": {
"Mochi":"下雨了你却没有避雨吗?#$b#你也是辛苦了。$8#$b#你过来我这里吧。#$b#着凉了可不好。$1"
},
"When": {
"Hearts:Mochi": "4, 5, 6, 7"
}
},
{
"Action": "EditData",
"Target": "Characters/Dialogue/rainy",
"Entries": {
"Mochi":"你看看你!#$b#不带伞还淋湿了全身上下。$6#$b#我帮你擦擦头发。$1#$b#%麻薯君拿出毛巾帮你擦干头发#$b#嗯,擦干了!$1#$e#喝点咖啡吧!$1[395]#$e#快喝吧!$1"
},
"When": {
"Hearts:Mochi": "8, 9, 10"
}
}
婚后对话
Characters\Dialogue\MarriageDialogue.xnb 包含了所有配偶的对话完本,每个 NPC 也可以拥有其独立的对话文件(可选),例如 Characters\Dialogue\MarriageDialogueAbigail.xnb。游戏查询一个对话键时,会优先使用 NPC 独立文件中的键(若存在),否则会使用通用文件中的键,若仍不存在,则使用默认文本(通常为空白)。
每个对话键都有下述格式之一:
| 键格式 | 描述 |
|---|---|
<季节>_<1到28日><season>_<day>
|
一天开始时的对话,具体采用哪句取决于键中的<season> 和 <day> 。示例:fall_1: "这香味很明显……蘑菇、腐烂的树叶、南瓜。秋天到了。很美好不是吗?" |
露台_<配偶>patio_ <spouse>
|
NPC 站在室外露台(在出货箱初始位置上方的平台刷新时)时显示的对话。 |
<天气>_<白天或晚上>_<随机><weather>_<dayOrNight>_<random>
|
婚后日常对话。<weather>可以填充Rainy或者Indoor,前者是下雨天的情况,后者是除雨天以外的天气。 <dayOrNight>可以填充Night或者Day,前者是游戏时间为下午6点以后会触发的对话,后者为下午6点以前触发。<random>可以填写的内容是0,1,2,3,4,所以你会有五个对话且随机触发。例子: Rainy_Night_3: "每当夜幕降临,我很喜欢把家里的灯光调暗一点,然后好好地聆听那份寂静……$8" 这里有一段由于编者无法理解是否需要删掉的似乎是隶属于这条键的键,放在这里<weather>_Day_<random>一天开始时的对话,基于 <weather>(雨天采用 Rainy,否则采用 Indoor,即便配偶不在室内)和 <random>(随机取 0 到 4)。若游戏选择的随机数 <random> 不存在对应的对话,则会使用默认文本。Rainy_Night_ <random>雨天晚 6 时之后农舍中的日常对话。其中 <random> 为 0~5 的随机数(含端点)或 NPC 名字,每个条目被选中的概率相等。若游戏选择的随机数 <random> 不存在对应的对话,则会使用默认文本。Indoor_Night_ <random>非雨天晚 6 时之后农舍中的日常对话。其中 <random> 为 0~4 的随机数(含端点)或 NPC 名字,每个条目被选中的概率相等。若游戏选择的随机数 <random> 不存在对应的对话,则会使用默认文本。 |
好玩/快乐/有趣离去_<配偶名字>funLeave_ <spouse>
|
NPC离开农舍时的对话(除了使用硬编码的 marriageJob 日程键)。 |
工作离去_<配偶>jobLeave_ <spouse>
|
NPC离开农舍去工作的对话。仅适用于玛鲁、潘妮和哈维。 |
好玩/快乐/有趣回家_<配偶名字>funReturn_ <spouse>
|
配偶在下午 1 时后回到农舍、到达目标位置之前时的对话,只限星期一触发 (给任何NPC)或者星期五(如果不是玛鲁/哈维/潘妮)(除非存在硬编码的 marriageJob 日程键)。 示例:funReturn_Abigail: "嘿!你过得好吗?我过得挺好。散散步让人精神清爽。$h" |
工作回家_<配偶>jobReturn_ <spouse>
|
配偶(仅限玛鲁、潘妮和哈维)在下午 1 时后下班回到农舍、到达目标位置之前的对话(当NPC行动使用硬编码的 marriageJob 日程键时)。 示例:jobReturn_Penny: "#$c .5#晚上好。我今天很不错,多谢关心!你怎么样?$h#$e#今天贾斯和文森特很不乖啊。我到现在都像上了发条一样……" |
<season>_<spouse>
|
有 9 心以上友谊时,每天有 5% 概率触发此对话。 Example: fall_Abigail: "我是在你身上闻到南瓜的味道了吗?可能我是在做梦吧……$h" |
Outdoor_<spouse>
|
在农场上有 20% 概率触发此对话。 示例:Outdoor_Abigail: "我就在这逛逛,可以吗?#$e#这儿有许多有趣的虫子和小东西。*轻笑*$h" |
Outdoor_<random>
|
在农场上有 80% 概率触发此对话。<random> 是介于 0~4 的数,以备随机抽取。示例:Outdoor_3: "我们拥有一个山洞,这太酷了!简直让我梦想成真了。$h" |
spouseRoom_<spouse>
|
配偶在配偶房间中的对话。 示例:spouseRoom_Abigail: "#$c .5#我提前起床给小大卫喂了吃的。今早他很有活力。#$e#我希望你不会介意豚鼠的味道。" |
OneKid_<random>
|
有 1 个孩子时,配偶站在厨房中显示的对话。<random> 是介于 0~4 的数,以备随机抽取。示例:OneKid_1: "不知道%kid1将来会不会像你一样成为农夫呢?" |
TwoKids_<random>
|
有 2 个孩子时,配偶站在厨房中显示的对话。<random> 是介于 0~4 的数,以备随机抽取。示例:TwoKids_2: "我梦到%kid2将成为一名著名的怪物猎人。我已经在考虑做一套小装备了。" |
NoBed_<random>
|
前一晚没有可用的床时的对话。<random> 是介于 0~3 的数,以备随机抽取。Example: NoBed_3: "我们的床怎么了……?$s" |
<感情>_<随机><affection>_<random>
|
农舍中午 11 时到晚 6 时,或一天开始时但没有选中其他对话时显示的对话。其中 <affection> 取值方法如下:若好感度低于 9 心,则随机抽取 Bad 或 Neutral;若恰为 10 心,则 50% 概率取 Good,若恰为 11 心则此概率为 87.5% ,若为 12 心及以上则为 99.4% ;否则取 Neutral。其中 <random> 是介于 0~9 的数,以备随机抽取。.示例: Good_5: "我只是在欣赏你送我的美人鱼吊坠……我会一直戴着它,直到生命的尽头。$l" |
室友对话
游戏的婚姻逻辑允许与 NPC(包括自定义 NPC)成为室友,不单是科罗布斯。
下述对话键适用于他们搬入之前:
| 内容文件 | 键 | 效果 |
|---|---|---|
| Strings/StringsFromCSFiles | <NPC name>_EngagedRoommate
|
接受室友提议的对话。 ⚠ 如果您未指定 Data/EngagementDialogue: <NPC name>Roommate0 ,这些键会被忽略。示例:虚空幽灵吊坠!你是怎么……?$3#$b#哦,不得了。$7#$b#@……嗯,只要你愿意,我可以和你一起住。但我们得对所有人保密。#$b#过几天我就去你家……可以吗?$h |
| Strings/Characters | MovieInvite_NoTheater | 拒绝室友提议的对话,因为当前玩家不满足要求(即,最小友谊值 + 农舍等级,且没有室友/配偶)。拒绝观影邀请也是此对话。 |
| Data/EngagementDialogue | <NPC name>Roommate0<NPC name>Roommate1
|
接受室友提议后、搬入农舍之前的常规对话。其中 Roommate0 变体总是用于 NPC 接受提议的当天;在其后的若干天中,NPC 会随机抽取 Roommate0 或 Roommate1。如果 Roommate0 变体被定义,则必须同时定义 Roommate1 以免出错。
|
搬入后的对话:
| 内容文件 | 键 | 效果 |
|---|---|---|
Characters/Dialogue/MarriageDialogue<NPC name>Roommate
|
全部 | 等价于 Characters/Dialogue/MarriageDialogue<NPC name>,但仅限该 NPC 是室友的情况。若素材文件存在,则会完全取代配偶版本的文件;否则默认使用配偶版本的素材文件。
|
| Characters/Dialogue/MarriageDialogue | *Roommate | 包含 Roommate 后缀的键会被优先使用(若存在)。(仅限于此文件,而不是 MarriageDialogue<NPC name> 文件。)
|
| Data/Festivals/* | <NPC name>_roommate
|
NPC 成为室友后,在节日期间的常规对话。若此键没有被定义,则会使用 <NPC name>_spouse 代替。
|
对于其他 NPC:
| 内容文件 | 键 | 效果 |
|---|---|---|
| Characters/Dialogue/* | *_roommate_* | 等价于 通用对话 中的 *_inlaw_* 中缀,不过是对于室友的情形。若未定义,则会回退到没有中缀的对话(而不会转而使用 *_inlaw_* 中缀)。 |
数据文件目录:Data\*
订婚对话
类似于雨天对话,Data\EngagementDialogue.xnb 包含形如 <NPC>0 和 <NPC>1 的对话,用于已订婚但还未结婚的状态;对于室友,则为已接受邀请但尚未搬入的状态。
事件文件
Data\Events\*.xnb 包含事件脚本,包括任何事件中的对话(参见模组:事件数据)。
额外对话
Data\ExtraDialogue.xnb 收录了一些字符串,其中某些针对于特定 NPC :
| 键格式 | 描述 |
|---|---|
| PurchasedItem_* | 在向商店售出一种可食用物品后,非儿童的小镇 NPC 可能随机说出此对话。这些键是硬编码的,因此无法自行添加具有类似效果的键。
对于有数字中缀的键(例如 PurchasedItem_5_Cooking),数字中缀会按如下方式被选择:
|
| Town_DumpsterDiveComment_Child Town_DumpsterDiveComment_Teen Town_DumpsterDiveComment_Adult Town_DumpsterDiveComment_Linus |
NPC 撞见玩家翻垃圾桶时的对话,基于年龄。莱纳斯有独立的对话,但其他 NPC 没有。 |
SummitEvent_Dialogue3_<spouse>
|
在顶峰完美过场动画之前,你的配偶 NPC 会说话。 |
电影院对话
NPC 对电影的反应存储在 Data\MoviesReactions.xnb,其组织方式与其他对话文件颇为不同。参见模组:电影院数据以了解更多。
动画描述
Data\animationDescriptions.xnb包含了简短的动画描述,以配合行程上所显示的动作。(说明:行程有两种方式可以显示对话/描述,一种是行程对话scheduledialogue,另外的就是动画描述animationDescriptions,如果你想要NPC在行程里有显示动画和对话,需要额外给animation加上描述才能同时拥有动画和对话,行程对话在动画时是无法显示的,这点请各位注意一下。)
字符串文件:Strings\*文件
Strings\StringsFromCSFiles.xnb包含了各种各样的预设对话。这个文件里有着预设好的对话、大部分NPC共同使用的对话(例如NPC会说一个与其相关的其他角色喜欢/讨厌什么东西)、硬核事件(例如婚礼的致辞)等等。
这个文件的条目格式为"<key>": "对话字符串" "<key>": "dialogue string",它可以是任意的特殊标识符。这些键必须完全匹配游戏里所需要的键,但这些键只是游戏专属的特殊标识符— 即使这些键看起来就像<file name>.<line number>,这最初只是用于分配IDs的,并且这些IDs没有任何意义或者作用。(甚至它也不需要匹配当前的文件名或行号)。*通俗地讲,其实就是StringsFromCSFiles这个文件里的对话全部都是无法被我们添加进入游戏代码里,最多只能通过某些小手段把dialogue string改成你想要的句子*
动画描述
Strings\animationDescriptions.xnb 包含少数与日程节点搭配对话。不要与 Data\animationDescriptions.xnb 混淆,后者包含动画的数据,而非描述动画的字符串。
角色
Strings\Characters.xnb 杂录了一些对话,其中一些针对特定 NPC :
| 键格式 | 描述 |
|---|---|
MovieInvite_Spouse_<NPC name>
|
NPC 与当前玩家婚后接受电影票的对话。若缺省,默认为 MovieInvite_Invited_* 键。 |
MovieInvite_Invited_<NPC name>MovieInvite_Invited_ <manner>MovieInvite_Invited_ <socialAnxiety>MovieInvite_Invited_ <optimism>MovieInvite_Invited_ <age>MovieInvite_Invited |
NPC 接受电影票的对话。NPC 会使用此有序列表中第一个匹配的键。
其中 |
| Phone_* | 使用电话呼叫店主 NPC 的对话。这些键是硬编码的,因此具有相同格式的新键会被忽略。 |
事件
Strings\Events.xnb 包含与事件和节日相关的对话,某些针对特定 NPC 。
对话气泡
Strings\SpeechBubbles.xnb 包含一些由对话气泡显示的对话,在玩家进入指定地点时显示。这与 Characters\Dialogue\*.xnb 文件的 <location>_Entry 字段不同,后者在 NPC 进入指定地点时显示。这些键是硬编码的,因此具有相同格式的新键会被忽略。
来自CS文件的字符串
Strings\StringsFromCSFiles.xnb 杂录了一些字符串,例如多个角色共享的对话、硬编码事件(如婚礼)的对话等。
此文件中的条目形如 "<key>": "dialogue string",其中 key 为任意的唯一标识符。这些字符串的键名必须精确匹配游戏期望接受的键名;尽管大多数键形如 <file name>.<line number>,这种命名方式也仅仅是一种惯例,起初用于分配 ID,并没有实际含义或效果(甚至无需匹配当前的 C# 文件名或代码行数)。
在大多数情况下,如果游戏无法寻找一个 NPC 所需的字符串,其会默认使用 NPC.cs.4061(英语为 "Hi.")。
此文件中存储的一些其他实用的针对 NPC 的字符串如下所示:
| 键格式 | 描述 |
|---|---|
<NPC name>_AfterWedding
|
与 NPC 举行婚礼后的当天,在农场上与其的对话。 |
<NPC name>_Engaged<NPC name>_EngagedRoommate
|
NPC 接受订婚物品(例如原版的美人鱼吊坠或虚空幽灵吊坠)后,在“接受/拒绝”检查完毕后。 |
格式
对话内容可以包含标记(token)和命令,它们用于控制对话框、改变文本(例如,根据性别切换字符串)、注入值等。Dialogue 类负责解析这些标记和命令。
性别判断
| 语法 | 描述 |
|---|---|
| ${male^female}$ ${male^female^non-binary}$ |
根据玩家的性别更改文本。非二元值仅在模组覆盖玩家性别时使用,因为游戏内的 UI 仅允许男性和女性选项。
该语法在大多数其他命令或解析之前应用的,因此可以在 ^ 可能有不同含义的情况下安全使用(例如邮件文本)。您也可以用 ¦ 代替 ^ ,在这种情况下,任何 ^ 字符都将保持原样。 示例: |
特殊标记
| 字符 | 描述 |
|---|---|
| # | 分割一个对话字符串中的两条命令。 |
| { | TODO. 意为 "breakSpecialCharacter" 。 |
| % | 将对话框转换为通用文本框。 示例: "%阿比盖尔正沉醉在她的音乐里。"
|
| * | 意为 "quickResponseDelineator"(快捷问答定界符)。会在代码中转换为 #$b#。用在 $y(对话快捷问答)中,以达成 #$b# 的效果。您可以使用双重星号 ** 用于转义文本星号。 |
||
|
>意为 "multipleDialogueDelineator"(多重对话定界符)。可用于任何按季/按周循环的对话。使用此定界符可以在同一对话键下设立多组对话,按游玩的周数轮番出现。 示例: "Tue6": "这句话会在第一年春季和秋季出现||这句话会在第一年夏季出现||这句话会在第一年秋季出现"
|
| ^ | (已弃用)大多数代码应当使用上文中提及的较新的 ${...} 语法,后者受支持更广泛。
性别开关字符。此字符前的文本会呈现给男性玩家,后的文本会呈现给女性玩家。 |
肖像命令
这些命令设置当前台词对应的对话框肖像。若不存在肖像命令,则使用普通肖像。
肖像按从上到下、从左到右的顺序,从 $0 开始编号。最先的 6 幅肖像是标准的,可用数字(例如 $2)或唯一别名(例如 $s)表示之。任何潜在的配偶和许多其他角色都有这 6 幅肖像,但这并非完全统一的;例如卡洛琳就只有 4 幅。
| 数字 | 别名 | 描述 |
|---|---|---|
| $0 | $neutral | 默认/一般的表情。 |
| $1 | $h | 开心的表情。 |
| $2 | $s | 伤心的表情。 |
| $3 | $u | 特殊肖像。对每个 NPC 的含义各不相同:没好气(阿比盖尔),手持橄榄球(亚历克斯),生气(卡洛琳),恶心(州长),以此类推。 |
| $4 | $l | 脸红/喜欢的表情。 |
| $5 | $a | 生气的表情 |
$<id>
|
上述 6 幅肖像之外的肖像。根据id的数字切换对应位置的表情。这些肖像ID顺序从左到右,从上到下并以$0开始计算。全部角色都有固定6个基础表情: $0 (默认/一般), $1 (开心), $2 (伤心), $3 (特殊), $4 (脸红/喜欢), and $5 (生气)。可以为角色创造自制表情以用在对话或者事件剧情里。 注意: $1不能放在对话的最前面,因为会和以下的指令冲突(参考下面的$1)。 |
对话命令
本页面的内容需要酌情看待,当前没有人测试过绝大多数命令被同时使用的情况,但多命令同时在一个键内使用是可行的。当前请尽量避免多命令同时使用。
| 命令 | 描述 |
|---|---|
action <action>
|
运行一个触发动作字符串,例如 $action AddMoney 500 向当前玩家添加 |
| $b | 表示对话中的停顿,需要玩家点击才能使下面的内容载入新对话框。(这里举个明显可以看到差别的例子,那就是对话框右下方或者人物肖像的左下方,会出现向下的箭头。) |
$c <概率>#<内容1>#<内容2>$c <probability>#<text1>#<text2>
|
以<probability>(使用小数形式表示百分数,介于 0~1)的概率显示<text1>的对话内容;如果未判定到<text1>的内容,将显示<text2>的对话内容。比如:$c 0.9代表以 90% 概率显示<text1>,剩余的10%概率则会显示<text2>。 注意: 替代器命令(在下方可见)不能在<text1>正常运行。这个命令并不需要是对话字符串中的第一个命令,可以放在一段对话的后面,但需要用$b隔开,否则会呈现出$e的中断效果,此时可以再次与角色交互,此时对话内容仍然存在,可以继续播放且对话命令会运行)。该命令的触发概率与游戏内的运气无关。(警告:由于与游戏内概率无关,且星露谷物语的概率并不是类似于抽卡游戏的有保底机制的伪随机,所以如果要使用这个随机对话指令,最好不要将触发概率设置的过小。) 在内容1和内容2中使用 $b似乎会出现BUG,当前不建议同时使用。:bug当前的详细呈现在文本中使用如“#$c 0.5 #文本1 #文本2 #$b#文本3”格式文本时,呈现的效果是角色随机说出文本1或文本2后对话被中断,再次交互后说出文本3。
如果是“#$c 0.5 #文本1 #$b# 文本3 #文本2 #$b#文本4”则会说出文本1或文本3,此时对话被中断,再次交互后说出“#文本2 #$b#文本4。”
两个特性前者触发机制不明,后者似乎是游戏吧#$b#前的分割命令的#识别为了命令的#内容2前的#。
|
$d <世界状态ID>#<文本1>|<文本2>$d <state id>#<text1>|<text2>
|
"根据世界状态而显示的对话"(dialogueDependingOnWorldState)
|
| $e | 结束当前对话,并且关闭对话框使玩家可以恢复行动。$e 之后的对话只有与 NPC 再次互动才能触发。这里举个明显可以看到差别的例子,那就是对话框右下方或者人物肖像的左下方,会出现中间有X的小方格,并且你可以看到对话框缩小并消失。) |
| $k | 未完成的指令。代表"对话杀死"(dialogueKill)。(貌似至今为止是没有看过作者使用,看看未来有没有被赋予意义) |
$p <回答ID>#<达成ID的内容>|<未达成ID时的内容>$p <response ID>#<match text>|<no-match text>
|
p代表"对话的先决条件"(dialoguePrerequisite)。根据玩家之前对问题的回答所对应的ID而显示不同的文本。如果之前玩家选择的回答和这个<response ID>是一样的,那么<match text>将会被显示;相反的,如果没有选择到对应ID,<no-match text>就会被显示. 这些对话内容是使用#这个符号分开不同内容。可以使用#来搞出多个内容(虽然目前我只看到两个内容,不知道三个以上的内容是否存在)。这并不需要是对话字符串中的第一个命令,可以放在一段对话的后面,但需要用$b隔开,否则会呈现出$e的中断效果))。
您可以检查多个回答 ID 。例如,下面的代码在玩家选择回答 17、18 或 Apple 时显示第一条对话: You can check multiple response IDs. For example, this will show the first dialogue if the player chose dialogue answer 17, 18, or Apple: $p 17|18|Apple#你是不是认为什么都不会发生?$u|也许祸乱人间的邪恶鬼魂就会出现啦! |
$q <response IDs> <fallback>#<text>
|
显示包含指定问题文本的对话框(问答对话指令的前缀)。若 <response IDs>(一个以 / 分割的列表)包含玩家已给出的任何回答,则直接跳过此问题(以及随后的台词),且 <fallback> 会被追加到 $q 命令前。而 <fallback> 对话一般使用 $p 命令以根据玩家作出的回答调整文本。说明:对话问题必须使用唯一的 ID ,这点与事件类似。除此之外,如果你上一次已经回答过这个问答,<fallback>可以搭配$p指令来制作下一次遇到这个问题时会说的话。注意: 问答ID需要是独一无二的,和事件一样,以防止和其他NPC的问答ID冲突而导致对话被跳过。可以参照模组:事件数据以得到更多资讯参见事件数据页面以了解更多。
|
$query <query>#<状态存在>|<状态不存在>$query <query>#<if true>|<if false>
|
根据 <query> 提供的游戏状态查询显示不同文本。示例:
"Mon": "$query !PLAYER_VISITED_LOCATION Current Mine#你知道山上有一座废弃的矿井吗?据说里面全是怪物!|我听说你去了山上的老矿洞!#你找到什么好吃的了吗?"
|
$r <回答ID> <增加多少好感度> <反应>[对其他NPC的好感影响]#<答案1的内容>$r <response ID> <friendship> <reaction>[observerfriendship]#<answer text>
|
为 $q 问题对话制定一条答复。其中 <answer text> 是要显示的文本。<response ID> 为回答 ID ,以备之后引用(多个回答可以共用同一 ID)。<friendship> 定义了选择此回答引起的友谊值变化,可以为正数或负数。<reaction> 是该 NPC 对应的 Content\Characters\Dialogue\*.xnb 素材文件中的键名,用于定义选择此回答后 NPC 作出的反应。[observerfriendship] 是一个下划线(_)分隔的字符串。若指定此参数,则影响玩家与另一个 NPC 的友谊值。其格式为 friend_NPCID_Integer , 例如 "friend_George_-20" 或 "friend_Penny_40" 。
|
$t <对话主题ID> [持续时长] $t <topic ID> [day length]
|
添加一个对话主题,为期 [day length] 天(默认 4 天)。
|
$v <事件ID> [前提未满足是否忽略] [玩家已观看时是否忽略]$v <event id> [check preconditions] [skip if seen]
|
立即开启一个事件,并结束当前对话,且满足如下条件:
若事件未成功播放,则对话会跳到下一段台词。 例如, 说明:此命令仅在对话的最前端处有效。如果此命令前面存在任何对话或其他命令,都会导致此命令无法触发,且将事件命令作为对话文本直接输出。 |
$y '<问题>_<回复>' $y ' <answer>_<reply>'
|
意为“对话快捷问答”;这是问答更便捷的形式。它的工作方式类似于 $q , 但问题和答案同时出现在一个对话框中。它不能设置可用于 "dialoguePrerequisite"($p,对话前提)的回答 ID 。它不能设置友谊值变化。它可以重复触发。它无需作为对话中的第一条命令,只要是它之前的命令以 #$e# 或 #$b# 结尾。它可以拥有 2 个以上的回答。 (注意:你只能放置在对话字符串的最后一个,否则你的问题、回答和反应都会混乱。可以尝试复制坏例子的那个对话并且粘贴到任意一个NPC的对话文本中,然后进入游戏测试会发生什么) 例子1: Penny: "$y '要来份早饭吗?_是的,谢谢。_好,给你。_不了,我感觉很好。_那额外的就给我吃啦!'" 例子2: Sun4: "嗨,@先生。^嗨,@小姐。#$b#今天天气不错……#$b#$y '要来我家吃饭吗?_当然。_那就那么说定了!_抱歉,我今天很忙。_没关系,下次再来吧'" 坏例子: Sun4: "嗨,@先生。^嗨,@小姐。#$b#今天天气不错……#$b#$y '要来我家吃饭吗?_当然。_那就那么说定了!_抱歉,我今天很忙。_没关系,下次再来吧'#$e#今天要招待什么料理呢~" |
$1 <信件ID>#<第一次看到的内容> #$e# <第N次以后的内容>$1 <letter ID>#<1st-time text> #$e# <nth-time text>
|
注意:命令中的1是数字1而不是字母l.创建一段玩家(至多)只能看一次的对话台词。只有当 <letter ID> 未被标记,<1st-time text> 才会显示(且随后立即标记 <letter ID>)。相反的, <nth-time text>将被触发。此处 <letter ID> 不应取真实信件的 ID(因为该信件并不会被送出),但可被事件或其他对话台词引用。
|
| %fork | 设置 specialEventVariable1 变量,以备 fork 命令检查。主要用于对事件中的 $q 问题作出反应。详见 事件指令。 |
%revealtaste:<NPCID>:<物体ID>%revealtaste: <NPC name>:<item ID><NPC><object ID> |
在社交菜单中显示指定角色对指定物体的礼物喜好。例如,%revealtaste:Lewis:(O)258 会更新刘易斯的礼物日志,以显示他对蓝莓的喜好。此命令必须出现在对话框中的最前方可生效(即在任何 #$b# 换行之前,但 #$e# 换行是允许的)。 第二种形式已弃用,且仅适用于非限定性数值型物品 ID 。 |
[<id> + ]
|
给予玩家一个来自当前括号内的物品。例如:"我一整个下午都在幻想着大海,因此我决定做些海味尝尝。[(O)198 (O)202 (O)727 (O)MossSoup]$h"
以上对话会随机选择 198(烤鱼)、202(炸鱿鱼)、727(海鲜杂烩汤)或 MossSoup(苔藓汤)中的一件物品送给玩家。 每个值既可以是完整的限定性物品 ID(例如:[(O)198]),也可以是舍弃前缀的非限定性物品 ID(例如:[198],这种情况下会默认前缀为 (O)) |
问答例子
为理解 $q、$r 和 $p 的工作机制,最好结合具体的例子。
展开例子
请留意下述可读性较高的代码:
summer_Fri:
"我觉得我明天会去海滩!
#$q 305/306 beachquestion_followup#你想要跟我来吗?
#$r 305 15 beachquestion_yes#当然,我很乐意!
#$r 306 0 beachquestion_sorry#呃,抱歉,我已经有约了……
#$r 306 -10 beachquestion_no#不了,谢谢。
",
"beachquestion_yes": "很好!一言为定。$h",
"beachquestion_sorry": "哦。真糟糕。好吧。$6",
"beachquestion_no": "哦。呃。抱歉。$s",
"beachquestion_followup":
"$p 305
#明天肯定肯有意思!$h
|嗯……不知道能不能找个人陪我一起去……$s
",
summer_Sat:
"这时节的海滩真漂亮……
#$p 305
#多谢你今天陪我来!$h
|哦,嗨@, 最近过得怎么样?
",
上述对话在夏季星期五触发。NPC 开始会说:“我觉得我明天会去海滩!”
然后提出一个问题:
#$q 305/306 beachquestion_followup#你想要跟我来吗?
$q 开启这个问题。305/306 用于检查问题先前是否已经回答过,如已回答,则显示对话键 beachquestion_followup。(注意可以按照您喜爱的方式命名对话键以提高可读性。)
接下来是玩家可以给出的回答。您可以添加任意数量的 $r 命令;此处示例中有 3 个:
#$r 305 15 beachquestion_yes#当然,我很乐意!
#$r 306 0 beachquestion_sorry#呃,抱歉,我已经有约了……
#$r 306 -10 beachquestion_no#不了,谢谢。
如果您接受了邀请(第 1 个选项),游戏会把您对此问题的回答记作 ID 305 。之后,您与说话人的友谊值会增加 15 点。beachquestion_yes 是一个对话键,用于指示当您选择了此回答时,NPC 接下来的反应。
如果您拒绝了邀请(第 2、3 个选项),游戏会把您对此问题的回答记作 ID 306。根据您作出的回答,与说话人的友谊值会不变(0 点),或者减少(-10 点)。然后说话人使用对话键 beachquestion_sorry 或 beachquestion_no 来继续对话。
现在我们需要对每种回答制定对话键,以描述 NPC 听到此回答后的反应:
"beachquestion_yes": "很好!一言为定。$h",
"beachquestion_sorry": "哦。真糟糕。好吧。$6",
"beachquestion_no": "哦。呃。抱歉。$s",
"beachquestion_followup":
"$p 305
#明天肯定肯有意思!$h
|嗯……不知道能不能找个人陪我一起去……$s
",
此处需要留意的是 beachquestion_followup 。如果玩家再次与该 NPC 对话,$q 305/306 会发现该问题已经被回答过,因此会直接跳转到 followup 键。
$p 305 开启一个“可变”反应,意为:“如果玩家接受了邀请,说第一段台词,否则说第二段台词”。如果玩家接受了邀请,则 NPC 的反应很开心。否则,TA 会念叨需要另找个同伴。
第 2 天也有一个可变的反应:
summer_Sat:
"这时节的海滩真漂亮……
#$p 305
#多谢你今天陪我来!$h
|哦,嗨@, 最近过得怎么样?
",
和前文相同,第一句台词(这时节的海滩真漂亮……)在玩家与该 NPC 交谈时总会显示,但下一句台词取决于玩家前一天是否接受了邀约。
如下是另一个例子,摘自海莉的对话文件。注意此处的代码可读性较低,但不影响读取:
summer_Sat: "农场的活好像很无聊的样子……#$q 42/43 summer_Sat_old#一天都干什么呢?#$r 42 10 summer_Sat_12#护理植物#$r 42 10 summer_Sat_12#探索山洞#$r 43 -10 summer_Sat_13#在房子里面转#$r 42 10 summer_Sat_12#挖宝藏" #!String
summer_Sat_old: "#$p 43#嘿,你最好别在我房间里偷偷摸摸的!!$a|不过我估计你没准能练出个好身材。" #!String
summer_Sat_12: "嗯……听起来是个大工程。" #!String
summer_Sat_13: "什么?你最好别有这个想法!$a" #!String
第一次启动此对话时,回答 42 和 43 都没有被回答过(因为这些回答 ID 专属于此问题),因此海莉会说:“农场的活好像很无聊的样子……一天都干什么呢?”玩家可以选择如下回答:
- 护理植物
- 探索山洞
- 在房子里面转
- 挖宝藏
第 3 个回答,$r 43 -10 summer_Sat_13#在房子里面转,会设置回答 ID 43 ,减少海莉 10 点好感,并引发对话 summer_Sat_13(海莉:“什么?你最好别有这个想法!”)。所有其他回答都会设置回答 ID 42 ,增加海莉 10 点好感,并引发对话 summer_Sat_12(“嗯……听起来是个大工程。”)。
下一次再启动此对话 summer_Sat 时,$q 给出的某一回答 ID 已被设置(42 或 43)。因此,$q 问题和之后的内容都被忽略,而 summer_Sat_old 对话取代了前者。新对话通过 $p 命令,根据您先前作出的回答来调整海莉的对话。如果先前回答的是“在房子里面转”,则使用竖线 | 前的文本,因此海莉会说“农场的活好像很无聊的样子……嘿,你最好别在我房间里偷偷摸摸的!!”。如果回答 43 未被设置(由此推出回答 42 必定被设置),则使用竖线|后的文本,因此海莉会说“农场的活好像很无聊的样子……不过我估计你没准能练出个好身材。”
同样的例子,和上一条例子的区别是语言描述相比上一个更为口语化,可以参照两者进行同时理解
请留意下述可读性较高的代码:
summer_Fri:
"我想我明天会去海滩玩!
#$q 305/306 beachquestion_followup#你想要跟我来吗?
#$r 305 15 beachquestion_yes#当然,我超喜欢!
#$r 306 0 beachquestion_sorry#噢,对不起,我已经和别人约好了……
#$r 306 -10 beachquestion_no#不用了,谢谢。
",
beachquestion_yes: "好耶!是约会!$h",
beachquestion_sorry: "淦,好吧。$6",
beachquestion_no: "哦,呃,我很抱歉。$s",
beachquestion_followup:
"$p 305
#明天一定可以玩得很开心!$h
|哎,要是有个人能陪我,那该有多好……$s
",
summer_Sat:
"每年这个时候的海滩都很赞……
#$p 305
#谢谢你今天陪我来这里。$h
|哦,你好,@,今天过得怎么样?
",
以上对话在夏季的任何星期五触发。NPC的对话开头总是触发: "我想我明天会去海滩玩!"
之后,ta会开始问你问题
#$q 305/306 beachquestion_followup#你想要跟我来吗?
$q 开始提问。 305/306检查这个问题是否在以前触发过,如果有就会直接把你的对话送到beachquestion_followup这个对话键。(你可以随意你的对话键以方便你找到/知道/运作/检查)
之后,就是玩家可以回答的答案。你可以增加多少个 $r都没问题;这里,我们则是三个:
#$r 305 15 beachquestion_yes#当然,我超喜欢!
#$r 306 0 beachquestion_sorry#噢,对不起,我已经和别人约好了……
#$r 306 -10 beachquestion_no#不用了,谢谢。
如果你表示同意(指第一个回答),游戏将会记录 ID 305作为你回答问题的答案。之后,你和那个角色的好感度增加了15点数。 beachquestion_yes就会被触发并延续刚刚问答对话。
如果你表示拒绝(指第二和第三个回答)游戏将会记录ID 306 作为你回答问题的答案,然后根据你选择的回答保持不变,0或者减少好感,-10。之后会读取beachquestion_sorry或者beachquestion_no来继续你的对话。
现在我们需要给对话键加上反应:
beachquestion_yes: "好耶!是约会!$h",
beachquestion_sorry: "淦,好吧。$6",
beachquestion_no: "哦,呃,我很抱歉。$s",
beachquestion_followup:
"$p 305
#明天一定可以玩得很开心!$h
|哎,要是有个人能陪我,那该有多好……$s
",
这里需要注意的是beachquestion_followup。当玩家再一次触发这个对话时,$q 305/306会被检测以判定是开始问问题或者直接读取这个对话。
$p 305开启了一个变量反应,意思是"如果玩家选择的是同意,那么会触发前者的对话。相反则触发后者的对话"。如果玩家回答的是同意,那个NPC会表现开心。相反,ta会说ta需要找人陪ta一起去。
这里隔天会触发另外一个变量反应:
summer_Sat:
"每年这个时候的海滩都很赞……
#$p 305
#谢谢你今天陪我来这里。$h
|哦,你好,@,今天过得怎么样?
",
依旧是第一行,每一次玩家与NPC对话的第一句都会是(每年这个时候……),但是下一行是根据昨天玩家所选择的答案来显示出对应对话内容。
这里是另一个从海莉的对话文件里拿出来的例子。注意一下,即使脚本格式很难读懂,但游戏能够同时处理这两种格式。
summer_Sat: "农场的活好像很无聊的样子……#$q 42/43 summer_Sat_old#一天都干什么呢?#$r 42 10 summer_Sat_12#护理植物#$r 42 10 summer_Sat_12#探索山洞#$r 43 -10 summer_Sat_13#在你的房间里面转#$r 42 10 summer_Sat_12#挖宝藏" #!String
summer_Sat_old: "#$p 43#嘿,你最好别在我房间里偷偷摸摸的!!$a|不过我估计你没准能练出个好身材。" #!String
summer_Sat_12: "嗯……听起来是个大工程。" #!String
summer_Sat_13: "什么?你最好别有这个想法!$a" #!String
第一回触发的summer_Sat,将会触发42或者43的反应(因为这个问题是唯一有它们作为回答的问题),所以海莉会说 "农场的活好像很无聊的样子……一天都干什么呢?" 玩家可以选择以下其中一个回答:
- 护理植物
- 探索山洞
- 在你的房间里面转
- 挖宝藏
第三个回答,$r 43 -10 summer_Sat_13#在你的房间里面转,回答被记录为ID 43,减少10点海莉的好感度并且触发这个对话summer_Sat_13 (海莉说 "什么?你最好别有这个想法!")。其他回答则被记录为ID 42,增加10点海莉的好感度并且触发这个对话summer_Sat_12 ("嗯……听起来是个大工程。").
summer_Sat,将给出$q命令中列出的一个回答ID(42或43)。因此,$q和以后的内容被废弃,并且对话summer_Sat_old会代替这个空缺的位置。这个新对话使用了$p指令来改变海莉的对话,根据你上次回答ID是43或者是42来触发对应对话。如果你之前回答的是"在你的房间里面转",在这个符号|之前的对话会被触发,所以海莉将会说"农场的活好像很无聊的样子……嘿,你最好别在我房间里偷偷摸摸的!!" 如果不是ID 43被记录(在这个情况下,你一定是给出反应42的ID,打个比方,上次问答对话所选择的三个里其中一个回答),在这个符号|之后的对话会被触发,所以海莉反而会说 "农场的活好像很无聊的样子……不过我估计你没准能练出个好身材。"替换命令
替换命令会被替换为对应的字符串。请注意,在信件中,只有 @ 命令有效。
| 命令 | 描述 |
|---|---|
| @ | 玩家名字。 示例: 你好 @!
|
| %adj | 随机形容词(来自 StringsFromCSFiles.xnb) |
| %noun | 随机名词(来自 StringsFromCSFiles.xnb) |
| %place | 随机地点名(来自 StringsFromCSFiles.xnb) |
| %spouse | 玩家配偶的名字。 |
| %name | 随机生成的名字。 |
| %firstnameletter | 玩家名字的前半部分(向下取值),在英文中,如果玩家的名字是 Natalie ,则使用 "Nat" (游戏语言非英语时,运作方式未知)。 |
| %time | 当前游戏当天的时间。 |
| %band | 山姆和塞巴斯蒂安的乐队名称。 |
| %book | 艾利欧特的书名。 |
| %pet | 玩家宠物的名字。 |
| %farm | 农场名。 |
| %favorite | 玩家最爱的东西。 |
| %kid1 | 玩家第一个孩子的名字。 |
| %kid2 | 玩家第二个孩子的名字。 |
回答ID
回应ID标识了玩家在回应问题对话时所选择的答案。在某些情况下,一个问题里面可能会有多个答案具有相同ID的情况(比如各种各样的"yes"),或者每个问题都使用一样的ID(在这种情况下,ID只是显示玩家已经回答或者还没回答的问题)。
任何模组里都可以使用自填ID,不过这里提供了原版游戏IDs,以1.3.36为准:
- 对话
NPC 问题 回答 阿比盖尔 Sun2
@你觉得我们死后会变成什么样?17: 我不知道。
18: 我们会变成鬼魂。
17: 我们会上天堂。
18: 我们的能量体会进入灵界。
17: 什么都不会发生。我们就是不存在了而已。阿比盖尔 summer_Sun
好吧……假设你得到了一个带薪假期。你会去哪儿?25: 海滩
26: 漆黑的山洞
26: 古老茂密的森林
25: 乔家购物广场阿比盖尔 fall_Sun
我想给我的头发重新染个色……你觉得什么颜色好?27: 染成黑色吧。
27: 不妨试试金色吧?
27: 粉红怎么样?
28: 我喜欢你现在的样子!阿比盖尔 winter_Sun
我画了两幅画。你觉得怎么样?29: 我喜欢丛林海岛和老虎这一幅。
30: 我喜欢拿着战斧的兽人这一幅。
29: 我哪幅都不喜欢。亚历克斯 Wed
我还想叫你一起投投球,但你好像不怎么喜欢运动。^如果你不是女孩子,我就约你打球了。6: 我站在旁边看就好了。
5: 我想和你打球!
5: (愤怒)你到底是什么意思?亚历克斯 summer_Wed
你觉得我能成为职业选手吗?52: 你一定会成为运动场上的传奇
52: 可能吧,你毕竟练习了那么久
53: 别做梦了,你还是老老实实去做推销员吧亚历克斯 fall_Wed
你觉得女孩子会喜欢我的发型吗?^你觉得我的发型怎么样?54: 看起来挺时尚的。
55: 像头上长了蘑菇一样。克林特 Mon
你一定猜不到我的曾祖父以前是一名……9: 铁匠。
9: 一个糊涂的小丑
9: 一个尖酸刻薄的混蛋。海莉 summer_Sat
一天都干什么呢?42: 护理植物
42: 探索山洞
43: 在房子里面转
42: 挖宝藏海莉 fall_Sat
*唉*……你觉得我今天做点什么好呢?44: 水彩画
44: 阅读杂志
44: 安安静静的呆着(原文翻译:快停止成为一个自私的爱哭鬼)莉亚 Mon
所以你为什么要做一个农夫呢?21: 我想要赚很多很多的钱。
22: 住在这里比住在城市里要更“真实”。
211132: 为了追随爷爷的脚步。
22: 我想要逃离我原来的生活。玛鲁 Sun
你在农场工作得开心吗?3: 开心。
4: 不开心。玛鲁 summer_Thu
我下了决心,以后一定要自己做个机器人出来。35: 对你来说,应该是小菜一碟。
36: 你可别眼高手低了
35: 听起来应该挺难的吧潘妮 Mon4
但果然还是不要总想着消极的一面吧?7: 没错。还是保持乐观比较好哦!
8: 还是现实一点比较好吧。山姆 Wed
嘿……你觉得我的新歌该是什么主题的?20: 耕种、挖矿和砍柴。
8820: 海中之城。
8821: 火车。
19: 随便吧。反正都是难听死的。赛巴斯 Fri2
那么你是如何打发空闲时间的?15: 继续耕种
16: 漫画书
15: 采购
15: 运动赛巴斯 fall_Fri
你平时读书吗, @?62: 嗯。看些经典名著。
63: 只看科幻与奇幻作品。
62: 我喜欢言情作品。
63: 不,我不看书的。
- 事件
事件 问题 回答 阿比盖尔四心事件 @!你怎么站在雨里啊?$7 32: 我在干活儿
32: 我在享受这种天气
32: 我还想问你呢阿比盖尔六心事件 你以前用过剑对么? 847951: 没错,我觉得很刺激!
847951: 是的,但只是自卫而已
847951: 没错,但是太危险了。你不应该冒险。
847951: 没有阿比盖尔十心事件 *吸气*$s 776589: 发生了什么?
776589: 你还好吗?阿比盖尔十心事件 我可能没有自己想象的那么勇敢……$8 34: 和我在一起,你就安全了。
34: 我也害怕。
34: 你哭得就像个三岁小孩儿。别说了。亚历克斯五心事件 我真没用……$s 57: 才不是。你明明是个天才!
57: 我们都有自己的长处和短处。
57: 没用?对,总结得很精辟。克林特三心事件 你有什么秘诀吗?^你能给我一些建议吗? 211: 靠你的能力和魅力打动女性
211: 做些疯狂的事情,让别人猜不透你
211: 表现得正常一点儿……做你自己就好
211: 把女人当男人一样对待德米特里厄斯六心事件 你觉得西红柿算什么? 59: 蔬菜
59: 水果艾利欧特二心事件 问个问题……你喜欢什么样的书, @? 958699: 悬念
958700: 浪漫
958701: 科幻艾利欧特四心事件 等等。让我们举杯庆祝一下!为了…… 28376: 鹈鹕镇!
28376: 我们的友谊!
28376: 我们的健康!
28376: 你的命运!艾米丽六心事件 所以……*喘气*……你感觉怎么样?$h 213: 这太奇妙了!
213: 真尴尬……
213: (保持沉默并缓缓鼓掌)艾芙琳四心事件 您觉得如何? 51: 很美味!
51: 就像在嚼冰球格斯四心事件 @,你有什么事儿吗? 207: 你现在就得把赊的账给结了!
208: 酒吧在经济上有些困难海莉二心事件 那是因为上周是我打扫的!$a 46: 少废话,赶紧打扫!
45: 海莉,何不每周固定打扫一次呢?
46: 艾米丽,这次就去打扫吧。海莉四心事件 话说……你挺有劲的,对吧? 47: 是
47: 不是海莉六心事件 这东西现在已经买不到了……$s 48: 别担心,我给你买个新的!
48: 太遗憾了……哈维二心事件 @你觉得乔治该怎么做? 84: 乔治应该听从哈维医生的建议。
85: 乔治知道怎么做对他的身体最好。哈维四心事件 嗯……你的心跳有点儿快。$u 86: 我有点紧张。
86: 我刚才在农场里干活,现在还没喘过来气。
86: 你真的是医生吗?我的心跳很正常!肯特三心事件 (跟肯特聊聊)$s 215: 这事怪乔迪……她本该知道的!
215: 我知道你内心很痛苦……但这也不能怨你老婆啊。
215: (撒谎)这事怪我……是我说要吃爆米花的。莉亚四心事件 我是不是太自私了 @?$s 83: 不,你只是做了必须做的事情。
83: 不,是你的前任太蠢了。
83: 不,但你其实应该待在城里。
83: 对,有那么一点儿。
83: 对,但人不为己天诛地灭。刘易斯六心事件 @……你什么都听到了,是么?$s 200: 是的……但是我会保密的。
201: 是的……我要告诉大家。玛鲁二心事件 我说的没错吧, @? 15933: (什么也不说)
15933: 其实,你爸刚刚可神秘了。玛鲁四心事件 @我应该怎么办? 38: 从地板上铲起来就好。他不会发现的。
39: 告诉哈维是我的错。
38: 告诉哈维,这纯属意外。玛鲁六心事件 你看到的是什么? 40: 一颗美丽的星球。
40: 一片漆黑的深渊。玛鲁八心事件 真是对不起。$8 41: 没关系,根本不疼的。
41: 抱歉就对了。简直疼死人了!玛鲁十心事件 那么,你觉得怎么样呢, @? 18981: 我认为你的发明很厉害。
18981: 我很失望……你不该让那机器人成为你的奴隶的。
18981: 看来你爸对我们在一起是没意见咯?
18981: (盯着玛鲁,什么也不说)玛鲁十心事件 你会那么说,肯定有原因……$a 18982: 玛丽尔达就是一台设计用来模仿人类的机器。
18982: 我刚才是在开玩笑。玛丽尔达应该享有自由的权力。
18982: 我会让她去农场里工作。潘妮二心事件 @?你看到了? 71: 没错,你做的很好,潘妮。
71: 你应该不管他的,现在他倒恼羞成怒了。
71: 我就散个步,不用管我。潘妮六心事件 ……怎么样? 72: (说谎)嗯嗯!真好吃!
73: 呃……我能把剩下的带走吗?
73: 真是特别的味道……你是怎么把它做得那么耐人寻味的?皮埃尔六心事件 发誓你不会把这事儿告诉任何人。 50: 我会为你保守秘密的。
50: 这事儿应该让你太太知道。罗宾六心事件 你有没有用木头做过东西呢, @? 66: 有
66: 没有山姆二心事件 说, @…… 你喜欢什么样的音乐? 76: 令人愉悦的流行乐。
77: 实验性质的硬摇滚。
78: 极富能量的舞曲。
79: 气氛活跃的乡村音乐。山姆四心事件 ……告诉她吧, @。$s 80: 山姆把零食递给我的时候掉到了地上。
80: 山姆把零食递给我的时候被我弄掉了。
81: 山姆故意弄掉的。他觉得这样很好玩。
对话主题
一个对话主题(conversation topic)是一个临时标识,可供事件前提和游戏状态查询检查,还用于触发一次性 NPC 对话(如果有相应的对话键)。当对话主题处于活跃状态时,其存储在 Farmer.activeDialogueEvents 中;失效后,则移动到 Farmer.previousActiveDialogueEvents 。
因为对话主题是临时的,故可用于控制事件之间的间隔:例如,如果您添加了一个对话主题,则可以要求一个事件前提只有当该对话主题不活跃时才能满足。因此,必须等待该对话主题结束后才能观看那个事件。
开启一个对话主题有很多种方式:
- 使用
addConversationTopic事件命令; - 使用
AddConversationTopic触发动作; - 使用
$t对话命令; - 使用
%item conversationTopic信件命令; - 在 C# 代码中,调用
Farmer.activeDialogueEvents.TryAdd(string, int)
默认情况下对话主题将持续 4 天,但上述的所有方法都支持自定义持续时间(可选)。
对话主题记忆
在对话主题的常规活动时间以外,游戏也记录了对话主题开启的时间,并在对话主题开启一段时间后触发附加的对话主题。这些附加主题总是与原对话主题保持一致,只是在末尾添加了 _memory_<time> 后缀(请注意,游戏检查 "_memory_" 关键字以控制其行为,因此尽量在自定义对话主题中避免此关键字)。
如下是这些附加主题的键名以及其出现的时间。所有的附加主题都持续 4 天。
| id | 在原主题启动后多少天出现 |
|---|---|
<key>_memory_oneday
|
1 |
<key>_memory_oneweek
|
7 |
<key>_memory_twoweeks
|
14 |
<key>_memory_fourweeks
|
28 |
<key>_memory_eightweeks
|
56 |
<key>_memory_oneyear
|
104 |
注意 _memory_oneyear 的名称并非笔误,它确实延后 104 天出现,这少于通常意义上的一年(112 天)。
通用主题
当玩家达成特定条件时,游戏会自动触发如下的对话主题。这些主题会自动涵盖模组添加的内容,因此(举例而言)任何模组添加的事件都会生成 eventSeen_ 主题,任何 NPC 与玩家结婚后都会生成 married_ 主题,以此类推。这与对话主题记忆搭配使用,可以灵活地调度事件、协调 NPC 行为,而无需额外的工作量。
所有这些对话主题持续 4 天。
| id | 触发条件 |
|---|---|
achievement_<id>
|
玩家第一次达成指定成就。 |
cropMatured_<object id>
|
玩家第一次收获指定类型的作物。 |
dating_<npc internal name>
|
玩家第一次约会指定 NPC(仅适用于玩家给予的花束被接受的情形;其他改变与该 NPC 关系的方法不被认可)。 |
divorced_<npc internal name>
|
玩家第一次与指定 NPC 离婚(仅适用于玩家使用镇长的庄园登记册的情形;不适用于室友)。 |
eventSeen_<id>
|
玩家第一次观看指定事件。 |
firstVisit_<location name>
|
玩家第一次进入指定地点。 |
fishCaught_<id>
|
玩家第一次抓到指定的鱼。 |
houseUpgrade_<level>
|
玩家升级农舍至指定等级(例如 2)。 |
married_<npc internal name>
|
玩家第一次与指定 NPC 结婚(仅适用于观看婚礼事件的情形;其他改变与该 NPC 关系的方法不被认可)。 |
mineArea_<area>
|
玩家第一次进入指定矿井区域(整数)。其中 0 代表 1~10 层,10 代表 11~39 层,40 代表 40~79 层,80 代表 80~120 层,121 代表骷髅洞穴层,77377 代表采石场矿井层。(FIXME: 矿井层数 == -1 时可能存在其他值) |
purchasedAnimal_<type>
|
玩家第一次购买指定类型动物。 |
questComplete_<id>
|
玩家第一次完成指定任务。 |
roommates_<npc internal name>
|
玩家第一次与指定 NPC 成为室友。 |
structureBuilt_<type>
|
玩家第一次建造指定农场建筑。 |
特殊主题
这些主题用于特定的事件,且其键名中不适用任何变量。
| id | 持续时间 | 触发条件 |
|---|---|---|
| 收集包 | ||
| cc_Begin | 4 天 | 第一次阅读社区中心的祝尼魔卷轴后,在法师的过场动画期间设置。 |
| cc_Complete | 4 天 | 社区中心竣工(不适用于 Joja 路线)。 |
| cc_Boulder | 7 天 | 深山闪闪发光的巨石已移除,社区中心或 Joja 路线均可。 |
| cc_Bridge | 7 天 | 采石场桥梁已修复,社区中心或 Joja 路线均可。 |
| cc_Bus | 7 天 | 公交车已修复,社区中心或 Joja 路线均可。 |
| cc_Greenhouse | 3 天 | 温室已修复,仅适用于社区中心路线,不适用于 Joja 路线。 |
| cc_Minecart | 7 天 | 矿车修复,社区中心或 Joja 路线均可。 |
| joja_Begin | 7 天 | 玩家第一次打开Joja社区发展申请书。 |
| movieTheater | 3 天 | 电影院竣工。 |
| 配偶事件 | ||
| elliottGone | 6 天 | 艾利欧特 14 心事件。 |
| ElliottGone1 ElliottGone2 ElliottGone3 ElliottGone4 ElliottGone5 ElliottGone6 ElliottGone7 |
同一天 | 艾利欧特的 14 心事件的一部分。事件启动时,设置第 1 个标识;而后,每收到艾利欧特的一封信,就设置一个标识。 |
| emilyFiber | 2 天 | 艾米丽的 14 心事件的一部分。完成任务后设置此主题。 |
| haleyCakewalk1 haleyCakewalk2 |
同一天 | 海莉的 14 心事件。 |
| leahPaint | 同一天 | 莉亚的 14 心事件开启。 |
| pennyRedecorating | 2 天 | 潘妮的 14 心事件的一部分。 |
| samJob1 samJob2 |
2 天 | 山姆的 14 心事件的一部分。 |
| samJob3 | 3 天 | 山姆的 14 心事件的一部分。 |
| sebastianFrog | 同一天 | 塞巴斯蒂安的 14 心事件开启。 |
| sebastianFrog2 | 6 天 | 塞巴斯蒂安的 14 心事件的一部分。 |
| shaneSaloon1 shaneSaloon2 |
同一天 | 谢恩的 14 心事件的一部分。 |
| 其他事件 | ||
| gotPet | 4 天 | 玩家接受玛妮带来的第一只宠物。 |
| dumped_Guys dumped_Girls |
7 天 | 发生群体 10 心事件后(例如,参见阿比盖尔#群体10心事件)。 |
| secondChance_Girls secondChance_Guys |
14 天 | 发生群体 10 心事件后(例如,参见阿比盖尔#群体10心事件)。 |
| GreenRainFinished | 2 天 | 第 1 年绿雨后。 |
| dating | 4 天 | 玩家第一次约会某个 NPC 时。 |
| married | 4 天 | 玩家第一次结婚时。 |
| married_twice | 4 天 | 玩家第二次结婚时。 |
| divorced_once | 4 天 | 玩家第一次离婚时。 |
| divorced_twice | 4 天 | 玩家第二次离婚时。 |
| LeoDeparture | 同一天 | 雷欧搬家(在岛屿码头事件发生后)。 |
| pamHouseUpgrade | 4 天 | 设置在潘姆家修复事件之后,并且当时玩家选择承认自己是赞助者。 |
| pamHouseUpgradeAnonymous | 4 天 | 设置在潘姆家修复事件之后,并且当时玩家选择保密自己的身份。 |
| willyCrabs | 4 天 | 威利的 6 心事件后。 |
| wonEggHunt | 4 天 | 玩家第一次在复活节寻找彩蛋中夺冠。 |
| wonGrange | 4 天 | 玩家第一次在星露谷展览会上夺冠。 |
| wonIceFishing | 4 天 | 玩家第一次在冰雪节钓鱼比赛中夺冠。 |
| 其他 | ||
| Introduction | 6 天 | 农夫被创建(例如,新建存档,或第一次加入联机游戏)。 |
| FullCrabPond | 14 天 | 鱼塘第一次有 10 只螃蟹。 |
可使用的NPC对话模板
为了便于模组制作者制作,这里提供由麻薯君(贴吧@你的麻糬君丫)整理过的一般对话模板和贴吧@萌新不萌新-整理过的婚后对话模板。
之前的编者给出的使用模板时的提示
- 如果你使用的是上面对话模板的"give_flowersA"和"give_flowersB",你还需要额外去下载Canon-Friendly Dialogue Expansion for All Friend-able Characters来运行这个对话,唯一缺点就是如果有其他NPC模组是没有这些对话,会陷入死循环。*
用点小聪明,你可以让每个NPC做出不同的反应,而不是使用常规的预设对话。打个比方,你可以使用CP模组Content Patcher来改变NPC.cs.3962 和NPC.cs.3963 (送花交往对话反应),与NPC.cs.3980 (送吊坠求婚对话反应):
{
"Action": "EditData",
"Target": "Strings/StringsFromCSFiles",
"Entries": {
"NPC.cs.3962": "$q 10001 give_flowersA#?!...#$r 10001 0 give_flowersA# [送出花束]",
"NPC.cs.3963": "$q 10001 give_flowersB#?!...#$r 10001 0 give_flowersB# [送出花束]",
"NPC.cs.3980": "$q 10001 give_pendant#?!...#$r 10001 0 give_pendant# 你愿意和我结婚吗?"
}
}
以这个为例子,每一个NPC会从角色对话文件里的give_flowersA, give_flowersB, 和 give_pendant 读取对应的反应对话. (看看以下格式的信息可以了解更多的语法)记得要把全部可婚NPC都要加上,否则会有BUG。例子,你可以给海莉加上这个:
{
"Action": "EditData",
"Target": "Characters/Dialogue/Haley",
"Entries": {
"give_flowersA": "噢,这花束真漂亮。$1#$b#...什么?你想要成为我的男朋友?$8^...什么?你想要成为我的女朋友?$8#$b#....我以为我们已经在一起了。$1",
"give_flowersB": "哦哦哦,@! 我愿意成为你人生中的真命天子。$1",
"give_pendant": ".....$8#$b#@,我不知道我现在该说什么……$8#$b#...$7#$b#好...我接受了...$4#$b#我等不及要告诉镇长这个消息了... 我想全部计划得花上3天就能准备好。$1"
}
}
这个可以添加其他通用对话,你甚至可以通过已经回答问题的IDs来避免“送花束”的重复问答。*原文直译不太行,我来解释一下,使用$q指令的问答对话会有对应的ID,比如上面使用的是$q 10001(作为问题ID)和$r 10001(作为回答ID),回答后的回答ID会被游戏存档记录,所以也有可能会导致向其他NPC求婚时会出现BUG。总结一下就是,建议使用这个对话格式而不是上面有问答ID的*
对话模板
{
//特殊对话
"Introduction": "",//介绍
"danceRejection": "",//有人邀请或者好感没到的拒绝跳舞对话
"divorced": "",//分手之后的对话
"breakUp": "",//离婚之后的对话
"dumped_girls": "",//触发修罗场(女之后的对话
"secondChance_girls": "",修罗场7天后的原谅对话
"dumped_guys": "",//同上(男修罗场
"secondChance_guys": "",//同上(男修罗场
"stardrop_gift": "",//14心配偶送星之果实对话
"give_flowersA": "",//送花的对话
"give_flowersB": "",//同上,为版本2
"give_pendant": "",//求婚
"rejectNPCA": "",//交往被拒绝
"rejectNPCB": "",//同上,为版本2
"reject_two_heartA": "",//同上,二心以上
"reject_two_heartB": "",//同上,二心以上,为版本2
"reject_four_heartA": "",//同上,四心以上
"reject_four_heartB": "",//同上,四心以上,为版本2
"engageA": "",//与别人订婚时求婚
"engageB": "",//同上,为版本2
"marriedA": "",//与别人结婚后求婚
"marriedB": "",//同上,为版本2
"refusal_knownA": "",不可攻略的角色被求婚的对话
"refusal_knownB": "",//同上,为版本2
"refusal_botherA": "",不可攻略的角色被求婚的对话(不要问我差别,我也不懂
"refusal_botherB": "",//同上,为版本2
"refusal_no_heartsA": "",不可攻略的角色被求婚的对话(为0心
"refusal_no_heartsB": "",//同上,为版本2
//节日对话
"spring_1": "",//新年
"spring_12":"",//蛋蛋节前一天
"Spring_23":"",//花舞节前一天
"summer_10":"",//宴会前一天
"summer_27":"",//月光水母前一天
"fall_15":"",//展览会前一天
"fall_26":"",//万灵节前一天
"winter_7":"",//冰雪节前一天
"winter_24":"",//冬日星节日前一天
//春季和一般对话
"Mon":"",
"Mon2":"",
"Mon4":"",
"Mon6":"",
"Mon8":"",
"Mon10":"",
"Tue":"",
"Tue2":"",
"Tue4":"",
"Tue6":"",
"Tue8":"",
"Tue10":"",
"Wed":"",
"Wed2":"",
"Wed4":"",
"Wed6":"",
"Wed8":"",
"Wed10":"",
"Thu":"",
"Thu2":"",
"Thu4":"",
"Thu8":"",
"Thu10":"",
"Fri":"",
"Fri2":"",
"Fri4":"",
"Fri6":"",
"Fri8":"",
"Fri10":"",
"Sat":"",
"Sat2":"",
"Sat4":"",
"Sat6":"",
"Sat8":"",
"Sat10":"",
"Sun":"",
"Sun2":"",
"Sun4":"",
"Sun6":"",
"Sun8":"",
"Sun10":"",
//夏季对话~
"summer_Mon":"",
"summer_Mon2":"",
"summer_Mon4":"",
"summer_Mon6":"",
"summer_Mon8":"",
"summer_Mon10":"",
"summer_Tue":"",
"summer_Tue2":"",
"summer_Tue4":"",
"summer_Tue6":"",
"summer_Tue8":"",
"summer_Tue10":"",
"summer_Wed":"",
"summer_Wed2":"",
"summer_Wed4":"",
"summer_Wed6":"",
"summer_Wed8":"",
"summer_Wed10":"",
"summer_Thu":"",
"summer_Thu2":"",
"summer_Thu4":"",
"summer_Thu6":"",
"summer_Thu8":"",
"summer_Thu10":"",
"summer_Fri":"",
"summer_Fri2":"",
"summer_Fri4":"",
"summer_Fri6":"",
"summer_Fri8":"",
"summer_Fri10":"",
"summer_Sat":"",
"summer_Sat2":"",
"summer_Sat4":"",
"summer_Sat6":"",
"summer_Sat8":"",
"summer_Sat10":"",
"summer_Sun":"",
"summer_Sun2":"",
"summer_Sun4":"",
"summer_Sun6":"",
"summer_Sun8":"",
"summer_Sun10":"",
//秋季对话~
"fall_Mon":"",
"fall_Mon2":"",
"fall_Mon4":"",
"fall_Mon6":"",
"fall_Mon8":"*",
"fall_Mon10":"",
"fall_Tue":"",
"fall_Tue2":"",
"fall_Tue4":"",
"fall_Tue6":"",
"fall_Tue8":"",
"fall_Tue10":"",
"fall_Wed":"",
"fall_Wed2":"",
"fall_Wed4":"",
"fall_Wed6":"",
"fall_Wed8":"",
"fall_Wed10":"",
"fall_Thu":"",
"fall_Thu2":"",
"fall_Thu4":"",
"fall_Thu6":"",
"fall_Thu8":"",
"fall_Thu10":"",
"fall_Fri":"",
"fall_Fri2":"",
"fall_Fri4":"",
"fall_Fri6":"",
"fall_Fri8":"",
"fall_Fri10":"",
"fall_Sat":"",
"fall_Sat2":"",
"fall_Sat4":"",
"fall_Sat6":"",
"fall_Sat8":"",
"fall_Sat10":"",
"fall_Sun":"",
"fall_Sun2":"",
"fall_Sun4":"",
"fall_Sun6":"",
"fall_Sun8":"",
"fall_Sun10":"",
//冬季对话
"winter_Mon":"",
"winter_Mon2":"",
"winter_Mon4":"",
"winter_Mon6":"",
"winter_Mon8":"",
"winter_Mon10":"",
"winter_Tue":"",
"winter_Tue2":"",
"winter_Tue4":"",
"winter_Tue6":"",
"winter_Tue8":"",
"winter_Tue10":"",
"winter_Wed":"",
"winter_Wed2":"",
"winter_Wed4":"",
"winter_Wed6":"",
"winter_Wed8":"",
"winter_Wed10":"",
"winter_Thu":"",
"winter_Thu2":"",
"winter_Thu4":"",
"winter_Thu6":"",
"winter_Thu8":"",
"winter_Thu10":"",
"winter_Fri":"",
"winter_Fri2":"",
"winter_Fri4":"",
"winter_Fri6":"",
"winter_Fri8":"",
"winter_Fri10":"",
"winter_Sat":"",
"winter_Sat2":"",
"winter_Sat4":"",
"winter_Sat6":"",
"winter_Sat8":"",
"winter_Sat10":"",
"wintar_Sun":"",
"winter_Sun2":"",
"winter_Sun4":"",
"winter_Sun6":"",
"winter_Sun8":"",
"winter_Sun10":"",
}
婚后对话模板
//文中所有ABCD替换为当前制作的模组角色的id
{
"Rainy_Day_0": "",//下雨天白天
"Rainy_Day_1": "",
"Rainy_Day_2": "",
"Rainy_Day_3": "",
"Rainy_Day_4": "",
"Rainy_Night_0": "",//下雨天晚上
"Rainy_Night_1": "",
"Rainy_Night_2": "",
"Rainy_Night_3": "",
"Rainy_Night_4": "",
"Indoor_Day_0": "",//室内白天
"Indoor_Day_1": "",
"Indoor_Day_2": "",
"Indoor_Day_3": "",
"Indoor_Day_4": "",
"Indoor_Night_0": "",//室内晚上
"Indoor_Night_1": "",
"Indoor_Night_2": "",
"Indoor_Night_3": "",
"Indoor_Night_4": "",
"Outdoor_0": "",//门口
"Outdoor_1": "",
"Outdoor_2": "",
"Outdoor_3": "",
"Outdoor_4": "",
"OneKid_0": "%kid1",//第一个孩子
"OneKid_1": "",
"OneKid_2": "",
"OneKid_3": "",
"OneKid_4": "",
"TwoKids_0": "%kid2",//第二个孩子
"TwoKids_1": "",
"TwoKids_2": "",
"TwoKids_3": "",
"TwoKids_4": "",
"Good_0": "",//高心几率对话
"Good_1": "",
"Good_2": "",
"Good_3": "",
"Good_4": "",
"Neutral_0": "",
"Neutral_1": "",
"Neutral_2": "",
"Neutral_3": "",
"Neutral_4": "",
"Bad_0": ".",//低心几率触发
"Bad_1": "",
"Bad_2": "",
"Bad_3": "",
"Bad_4": "",
"spring_1": "",//每年春1对话
"spring_12": "",//复活节前一天对话
"spring_23": "",//花舞节前一天对话
"summer_1": "",//每年夏1对话
"summer_10": "",//夏威夷宴会前一天对话
"summer_28": "",//水母节当天对话
"fall_1": "",//每年秋1对话
"fall_15": "",//展览会前一天对话
"fall_26": "",//万灵节当天对话
"winter_1": "",//每年冬1对话
"winter_7": "",//冰雪节前一天对话
"winter_23": "",//冬日星前一天对话
"winter_28": "",//当年最后一天对话
"patio_ABCD": "",//在外面天井的对话
"spouseRoom_ABCD": "",//在配偶房的对话}
对于C#模组
Dialogue类
一系列 NPC 对话都表示为 Dialogue 实例。一些常用的字段/方法如下:
| 成员 | 用法 |
|---|---|
| dialogues | 待显示的“对话台词”。每个列表项都会显示在相同的对话框中(但不一定仅包含一句话)。
每条对话都可以包含待显示的文本,副作用(显示对话时运行的代码),或兼而有之。若一个列表项具有副作用,则会在对话框显示此条目后运行此副作用。若此列表项没有文本,则游戏先运行其副作用,然后跳到下一个列表项。 |
| speaker | 讲话的 NPC(若适用)。 |
| CurrentEmotion | 当前台词的肖像命令。 |
| TranslationKey | 当前台词的翻译键(若适用)。 |
| getCurrentDialogue() | 获取经过格式处理的、当前待显示的对话文本。 |
| getPortraitIndex() | NPC 肖像贴图集的索引,用于显示当前台词的肖像。 |
| isOnFinalDialogue() | 当前台词是否为当前对话中最后一条有文本的台词。 |
| isDialogueFinished() | 是否所有台词都已出现。 |
| convertToDwarvish() | 将当前对话台词替换为矮人语(玩家获得矮人语教程之前看不懂矮人的语言)。 |
Dialogue 类也提供了一些静态方法用于处理对话。一些主要的方法包括:
| 方法 | 用法 |
|---|---|
| TryGetDialogue(…) | 根据指定 NPC 和翻译键创建对话,若翻译键不存在,返回 null 。
这一般用于实现备用对话,例如: Dialogue? dialogue =
Dialogue.TryGetDialogue(npc, $"Charaxters\\Dialogue\\{npc.Name}:SomeKey_{relationship}")
?? Dialogue.TryGetDialogue(npc, "Charaxters\\Dialogue\\{npc.Name}:SomeKey");
注意此方法在某种意义上是低阶的。在大多数情况下,您应当使用等价的 NPC.TryGetDialogue 方法从 NPC 对话文件中读取对话。示例: Dialogue? dialogue =
npc.TryGetDialogue($"SomeKey_{relationship}")
?? npc.TryGetDialogue("SomeKey");
|
| FromTranslation(…) | 根据指定 NPC 和翻译键创建对话。这类似于 TryGetDialogue,但无效的翻译键会按原样显示。 |
| GetFallbackForError() | 发生错误无法加载适当的对话时,获取备用对话。这一般是 "..." 变体,但与具体语言有关。 |
| applyGenderSwitchBlocks(…) | 处理一段文本中的性别文本。根据设计,这可用于任何文本,不仅是对话文本。您可以使用当前玩家的性别,也可指定性别。
示例: string text = Dialogue.applyGenderSwitchBlocks("Hello ${lad^lass}$!"); // results in "Hello lad!" or "Hello lass!"
|
| convertToDwarvish(text) | 将文本翻译为矮人语(玩家获得矮人语教程之前看不懂矮人的语言)。 |
DialogueBox类
DialogueBox 是显示对话框时的菜单。一般而言用于 NPC 对话,但也用于某些非 NPC 对话。
部分常用字段包括:
| 字段 | 用法 |
|---|---|
| characterDialogue | 当前对话是标准 NPC 对话的情况下,此字段存储欲显示的 [[#Dialogue类|Dialogue 实例]]。 |
| dialogues | 当前对话是自定义对话的情况下,此字段存储待显示的对话台词。 |
| isPortraitBox() | 对话框是否有肖像。 |
对于 NPC 对话,您可以使用 MenuChanged 事件以检测是否出现了特定对话。示例:
private void OnMenuChanged(object sender, MenuChangedEventArgs e)
{
bool isAbigailDanceRejection =
e.NewMenu is DialogueBox dialogueBox
&& dialogueBox.characterDialogue is {} dialogue
&& dialogue.speaker?.Name == "Abigail"
&& dialogue.TranslationKey == "Characters\\Dialogue\\Abigail:danceRejection";
}
}}

沪公网安备 31011002002714 号