- 好友
- 2
- 在线时间
- 0 小时
- 最后登录
- 2025-3-24
随仆

- UID
- 3713555
- 第纳尔
- 115
- 精华
- 0
- 互助
- 0
- 荣誉
- 1
- 贡献
- 0
- 魅力
- 202
- 注册时间
- 2024-11-10
 鲜花( 7)  鸡蛋( 0)
|
本帖最后由 AntiN0m1 于 2024-12-28 18:54 编辑
大家是否遇到过这种情况:单刷时每招一个NPC就让他出去宣传或收集情报,回来了再把他送出去。时间久了就会发现,执行完任务归队的NPC总是任务列表最后的三四个人,其他人就没回来过。你再想让排在前面的人去做宣传,或者想等一个特定的NPC归队先给他练级,只能先把后面的NPC留在队里几天。
造成这种情况的原因是什么呢?我们先看一个每小时1次的简单触发器,在module_simple_triggers.py中找到以下代码:
- #NPC changes begin
- #Resolve one issue each hour
- (1,
- [
- (str_store_string, s51, "str_no_trigger_noted"),
- # Rejoining party
- (try_begin),
- (gt, "$npc_to_rejoin_party", 0), ##有NPC要归队
- (eq, "$g_infinite_camping", 0), ##不在无限露营
- (try_begin), ##NPC可以归队的条件
- (neg|main_party_has_troop, "$npc_to_rejoin_party"), ##玩家队伍没有该NPC
- (neq, "$g_player_is_captive", 1), ##玩家不是俘虏
- (str_store_string, s51, "str_triggered_by_npc_to_rejoin_party"),
- (assign, "$npc_map_talk_context", slot_troop_days_on_mission),
- (start_map_conversation, "$npc_to_rejoin_party", -1), ##触发归队对话
- (else_try), ##NPC暂不能归队
- (troop_set_slot, "$npc_to_rejoin_party", slot_troop_current_mission, npc_mission_rejoin_when_possible),
- (assign, "$npc_to_rejoin_party", 0),
- (try_end),
- # Here do NPC that is quitting
- (else_try),
- #略
- #略
- #略
- ]),
复制代码
|
可以看到,在# Rejoining party这一段控制着NPC的归队。有一个关键的全局变量$npc_to_rejoin_party,这是准备归队的NPC的id。
触发归队对话后,在module_dialogs.py里会有(assign, "$npc_to_rejoin_party", 0)将其清零。我们需要找到它是在哪设置的。
打开module_triggers.py找到以下冷却时间为1天的触发器:
- #Process morale and determine personality clashes
- (0, 0, 24,[],
- [
- #略
- #略
- #略
- (try_for_range, ":npc", companions_begin, companions_end), ##循环所有NPC
- ###Reset meeting variables
- #略
- #略
- #略
- #Check for quitting
- (try_begin),
- (main_party_has_troop, ":npc"),
- #略
- #略
- #略
- #main party does not have troop, and the troop is a companion ##同伴NPC不在玩家部队
- (else_try),
- (neg|main_party_has_troop, ":npc"),
- (eq, ":occupation", slto_player_companion),
- (troop_get_slot, ":days_on_mission", ":npc", slot_troop_days_on_mission),
- (try_begin), ##任务天数大于0时,天数减1。影响天数的好像不止这一处。
- (gt, ":days_on_mission", 0),
- (val_sub, ":days_on_mission", 1),
- (troop_set_slot, ":npc", slot_troop_days_on_mission, ":days_on_mission"),
- (else_try), ##任务天数等于0。任务天数刚变成0的那天NPC是不会回来的,方法1会自然修复这一问题。
- (troop_slot_ge, ":npc", slot_troop_current_mission, 1),
- #If the hero can join ##判断NPC能否归队
- (this_or_next|neg|troop_slot_eq, ":npc", slot_troop_current_mission, npc_mission_rejoin_when_possible),
- (hero_can_join, ":npc"),
- (assign, "$npc_to_rejoin_party", ":npc"), ##设置归队NPC的id,罪魁祸首
- (try_end),
- (try_end),
- (try_end),
- ]),
复制代码
|
可以看到,每循环一个NPC,如果他能归队,就会把$npc_to_rejoin_party设置成他,如此以来id越靠后的NPC就会优先归队。又因为触发器每天只触发1次,所以NPC一多,前面的人还没回来,后面的人就又回来了。
原因找到了,现在该如何解决呢?自然会想到记录NPC离队的顺序,我选择用部队记录,把NPC按顺序加入一个记录部队,归队时让记录部队的第一个NPC回来然后删掉。具体实现方法我给出2种。
方法1:
第一步:在module_parties.py里创建一个记录部队,以那些用于计算的部队为模板,如"temp_casualties",和它们放在一起,也就是"zendar"的上面:
("npcs_on_missions","{!}npcs_on_missions",pf_disabled, no_menu, pt_none, fac_neutral,0,ai_bhvr_hold,0,(1,1),[]),
第二步:在NPC外出执行任务时把他加入记录部队,这个在原版战团中比较简单,只在module_dialogs.py中有3处:
1.宣传统治权:[anyone,"member_kingsupport_4", [略],
2.收集情报:[anyone,"member_intelgathering_4", [略],
3.派遣使者:[anyone|plyr, "minister_diplomatic_dispatch_confirm",[], "Yes, do that", "minister_pretalk",[略],
只需要在[略]中找到:
(remove_member_from_party, <代表NPC的id的变量>, "p_main_party"),
在下面加上以下一句即可:
(party_add_members, "p_npcs_on_missions", <代表NPC的id的变量>, 1),
这种方法略显繁琐,而且每个mod可能不同。你如果不喜欢可以看方法2。
第三步:设置$npc_to_rejoin_party。在module_triggers.py的那段代码中作如下修改:
- (try_begin),
- (gt, ":days_on_mission", 0),
- (val_sub, ":days_on_mission", 1),
- (troop_set_slot, ":npc", slot_troop_days_on_mission, ":days_on_mission"),
- # (else_try), ##注释掉原方法
- # (troop_slot_ge, ":npc", slot_troop_current_mission, 1),
- # #If the hero can join
- # (this_or_next|neg|troop_slot_eq, ":npc", slot_troop_current_mission, npc_mission_rejoin_when_possible),
- # (hero_can_join, ":npc"),
- # (assign, "$npc_to_rejoin_party", ":npc"),
- (try_end),
- (try_end),
- (try_end),
- #在所有NPC的循环之外加上:
- ###(((方法1
- (party_get_num_companion_stacks, ":num_stacks", "p_npcs_on_missions"),
- (try_for_range, ":cur_stack", 0, ":num_stacks"), ##循环记录部队的兵种
- (party_stack_get_troop_id, ":npc", "p_npcs_on_missions", ":cur_stack"),
- ##判断NPC能否归队
- (troop_slot_eq, ":npc", slot_troop_days_on_mission, 0),
- (troop_slot_ge, ":npc", slot_troop_current_mission, 1),
- (this_or_next|neg|troop_slot_eq, ":npc", slot_troop_current_mission, npc_mission_rejoin_when_possible),
- (hero_can_join, ":npc"),
- (assign, "$npc_to_rejoin_party", ":npc"),
- (assign, ":num_stacks", 0), ##跳出循环
- (try_end),
- ###)))
- ]),
复制代码
|
第四步:在NPC触发归队对话的时候从记录部队把他删掉。在module_simple_triggers.py的那段代码中插入###(((方法1)))这一句:
- (assign, "$npc_map_talk_context", slot_troop_days_on_mission),
- (party_remove_members, "p_npcs_on_missions", "$npc_to_rejoin_party", 1), ###(((方法1)))
- (start_map_conversation, "$npc_to_rejoin_party", -1),
复制代码
|
方法2:
第一步:与方法1相同,作为区别名字改一下:
("npcs_days_on_mission_0","{!}npcs_days_on_mission_0",pf_disabled, no_menu, pt_none, fac_neutral,0,ai_bhvr_hold,0,(1,1),[]),
第二步:在任务天数减为0时将NPC加入记录部队,然后设置$npc_to_rejoin_party。在module_triggers.py的那段代码中作如下修改:
- (try_begin),
- (gt, ":days_on_mission", 0),
- (val_sub, ":days_on_mission", 1),
- (troop_set_slot, ":npc", slot_troop_days_on_mission, ":days_on_mission"),
- # (else_try), ##注释掉原方法
- # (troop_slot_ge, ":npc", slot_troop_current_mission, 1),
- # #If the hero can join
- # (this_or_next|neg|troop_slot_eq, ":npc", slot_troop_current_mission, npc_mission_rejoin_when_possible),
- # (hero_can_join, ":npc"),
- # (assign, "$npc_to_rejoin_party", ":npc"),
- ###(((方法2,将任务天数为0的NPC加入记录部队
- (else_try),
- (assign, ":add_num", 1),
- (party_get_num_companion_stacks, ":num_stacks", "p_npcs_days_on_mission_0"),
- (try_for_range, ":cur_stack", 0, ":num_stacks"), ##判断记录部队中有没有此NPC,若有则不加入
- (party_stack_get_troop_id, ":cur_stack_id", "p_npcs_days_on_mission_0", ":cur_stack"),
- (eq, ":npc", ":cur_stack_id"),
- (assign, ":add_num", 0),
- (assign, ":num_stacks", 0),
- (try_end),
- (eq, ":add_num", 1),
- (party_add_members, "p_npcs_days_on_mission_0", ":npc", ":add_num"),
- ###)))
- (try_end),
- (try_end),
- (try_end),
- #在所有NPC的循环之外加上:
- ###(((方法2
- (party_get_num_companion_stacks, ":num_stacks", "p_npcs_days_on_mission_0"),
- (try_for_range, ":cur_stack", 0, ":num_stacks"), ##循环记录部队的兵种
- (party_stack_get_troop_id, ":npc", "p_npcs_days_on_mission_0", ":cur_stack"),
- ##判断NPC能否归队
- (troop_slot_eq, ":npc", slot_troop_days_on_mission, 0), ##可以删除此行
- (troop_slot_ge, ":npc", slot_troop_current_mission, 1),
- (this_or_next|neg|troop_slot_eq, ":npc", slot_troop_current_mission, npc_mission_rejoin_when_possible),
- (hero_can_join, ":npc"),
- (assign, "$npc_to_rejoin_party", ":npc"),
- (assign, ":num_stacks", 0), ##跳出循环
- (try_end),
- ###)))
- ]),
复制代码
|
第三步:与方法1第四步相同。在module_simple_triggers.py的那段代码中插入###(((方法2)))这一句:
- (assign, "$npc_map_talk_context", slot_troop_days_on_mission),
- (party_remove_members, "p_npcs_days_on_mission_0", "$npc_to_rejoin_party", 1), ###(((方法2)))
- (start_map_conversation, "$npc_to_rejoin_party", -1),
复制代码
|
总结:
方法1可以严格区分任意NPC离队的顺序,但有点繁琐,适合强迫症。方法2不能区分任务天数在同一天减为0的NPC顺序,会将其按照id正序排列。但两者在实战中几乎没有区别,都能达到目的。我更推荐方法2,改的地方少,方便查错。
对于不开源的mod,方法2似乎可以用于魔球修改,我不太了解,欢迎熟悉魔球的大佬补充。
|
|