本帖最后由 rubik 于 2018-1-22 22:14 编辑
很多人可能都发现了一个现象,领主战败之后,不管是哪国的,不管战败地点离自己的主城远还是近,都是同一个时刻回城。我的MOD里,这一点表现得尤其明显,领主回城多半会从城里取兵,取兵信息一下就刷屏了,各国领主的取兵信息都有。其他MOD领主回城都不取兵,较难发现,但领主同时逃回自己主城是一个不以MOD为转移的事实。原因就在module_simple_triggers.py里的下面这个触发器,时间设定上很粗糙,就是每48小时检测一次,只要同时满足两个条件(没有被俘,没有带队)的领主,到了检测的时间点,就会在这个时间点全部刷到各自的主城里面。 很显然,在家门口战败,和不远万里深入敌后战败,战败时间相差不大,在同一个检测周期内的话,所有战败领主都会是在同一个时刻逃回各自的主城,这非常不合理,对守土的一方也非常不公平。
# Respawn hero party after kingdom hero is released from captivity.
(48,
[
(try_for_range, ":troop_no", active_npcs_begin, active_npcs_end),
(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_kingdom_hero),
(str_store_troop_name, s1, ":troop_no"),
(neg|troop_slot_ge, ":troop_no", slot_troop_prisoner_of_party, 0),
(neg|troop_slot_ge, ":troop_no", slot_troop_leaded_party, 1),
(store_troop_faction, ":cur_faction", ":troop_no"),
(try_begin),
(eq, ":cur_faction", "fac_outlaws"), #Do nothing
(else_try),
(try_begin),
(eq, "$cheat_mode", 2),
(str_store_troop_name, s4, ":troop_no"),
(display_message, "str_debug__attempting_to_spawn_s4"),
(try_end),
(call_script, "script_cf_select_random_walled_center_with_faction_and_owner_priority_no_siege", ":cur_faction", ":troop_no"),#Can fail
(assign, ":center_no", reg0),
(try_begin),
(eq, "$cheat_mode", 2),
(str_store_party_name, s7, ":center_no"),
(str_store_troop_name, s0, ":troop_no"),
(display_message, "str_debug__s0_is_spawning_around_party__s7"),
(try_end),
(call_script, "script_create_kingdom_hero_party", ":troop_no", ":center_no"),
(try_begin),
(eq, "$g_there_is_no_avaliable_centers", 0),
(party_attach_to_party, "$pout_party", ":center_no"),
(try_end),
#new
#(troop_get_slot, ":party_no", ":troop_no", slot_troop_leaded_party),
#(call_script, "script_npc_decision_checklist_party_ai", ":troop_no"), #This handles AI for both marshal and other parties
#(call_script, "script_party_set_ai_state", ":party_no", reg0, reg1),
#new end
(troop_get_slot, ":party_no", ":troop_no", slot_troop_leaded_party),
(call_script, "script_party_set_ai_state", ":party_no", spai_holding_center, ":center_no"),
(else_try),
(neg|faction_slot_eq, ":cur_faction", slot_faction_state, sfs_active),
(try_begin),
(is_between, ":troop_no", kings_begin, kings_end),
(troop_set_slot, ":troop_no", slot_troop_change_to_faction, "fac_commoners"),
(else_try),
(store_random_in_range, ":random_no", 0, 100),
(lt, ":random_no", 10),
(call_script, "script_cf_get_random_active_faction_except_player_faction_and_faction", ":cur_faction"),
(troop_set_slot, ":troop_no", slot_troop_change_to_faction, reg0),
(try_end),
(try_end),
(try_end),
]),
所以我引入了一个机制,每隔4个小时,寻找一下所有领主的下落,有下落的话,就重新记录一遍领主出现在大地图上的时间和位置。 如果领主战败了,或者从监狱逃跑,或者被敌人释放,领主就会从大地图上消失,失踪了。这种情况下,领主在地图上的时间和位置就不会更新了,失踪之前记录下的时间和位置就是领主最后一次出现在在大地图上的时间和位置。 然后就可以根据领主失踪前的位置和领主主城的位置,来计算回城需要的时间,再加上失踪的时刻,就是领主最终回城的时刻。每4小时检测一次,如果当前时刻小于领主最终回城的时刻,那么就算领主满足那两个条件(没有被俘,没有带队)也不会刷出,还需要再等4个小时,再次检测,直到当前时刻大于领主回城的时刻,领主才会刷出。
整体的代码结构都修改了,那我就直接贴整段修改后的代码,用的时候直接整段替换。黑色加粗的地方是重点的地方。
# Respawn hero party after kingdom hero is released from captivity.
## CC
(4,
[
(try_for_range, ":troop_no", active_npcs_begin, active_npcs_end),
(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_kingdom_hero),
(str_store_troop_name, s1, ":troop_no"),
(try_begin), # can find troop's position
(this_or_next|troop_slot_ge, ":troop_no", slot_troop_leaded_party, 1),
(troop_slot_ge, ":troop_no", slot_troop_prisoner_of_party, 0),
(try_begin),
(troop_get_slot, ":party_no", ":troop_no", slot_troop_leaded_party),
(ge, ":party_no", 1),
(assign, ":relevant_party", ":party_no"),
(else_try),
(troop_get_slot, ":cur_prisoner_of_party", ":troop_no", slot_troop_prisoner_of_party),
(ge, ":cur_prisoner_of_party", 0),
(assign, ":relevant_party", ":cur_prisoner_of_party"),
(try_end),
# record last_position_game_hours and last_position_closest_center
(store_current_hours, ":last_position_hours"),
(troop_set_slot, ":troop_no", slot_troop_last_position_game_hours, ":last_position_hours"),
(call_script, "script_get_closest_center", ":relevant_party"),
(assign, ":closest_center_no", reg0),
(troop_set_slot, ":troop_no", slot_troop_last_position_closest_center, ":closest_center_no"),
(else_try),
(neg|troop_slot_ge, ":troop_no", slot_troop_prisoner_of_party, 0),
(neg|troop_slot_ge, ":troop_no", slot_troop_leaded_party, 1),
(store_troop_faction, ":cur_faction", ":troop_no"),
(try_begin),
(eq, ":cur_faction", "fac_outlaws"), #Do nothing
(else_try),
(try_begin),
(eq, "$cheat_mode", 2),
(str_store_troop_name, s4, ":troop_no"),
(display_message, "str_debug__attempting_to_spawn_s4"),
(try_end),
(call_script, "script_cf_select_random_walled_center_with_faction_and_owner_priority_no_siege", ":cur_faction", ":troop_no"),#Can fail
(assign, ":center_no", reg0),
(try_begin),
(eq, "$cheat_mode", 2),
(str_store_party_name, s7, ":center_no"),
(str_store_troop_name, s0, ":troop_no"),
(display_message, "str_debug__s0_is_spawning_around_party__s7"),
(try_end),
(try_begin),
(store_current_hours, ":cur_hours"),
(troop_get_slot, ":last_position_closest_center", ":troop_no", slot_troop_last_position_closest_center),
(troop_get_slot, ":last_position_hours", ":troop_no", slot_troop_last_position_game_hours),
(store_distance_to_party_from_party, ":distance_troop_to_move", ":last_position_closest_center", ":center_no"),
(store_div, ":need_hours", ":distance_troop_to_move", 4),
(store_add, ":next_respawn_hours", ":last_position_hours", ":need_hours"),
(ge, ":cur_hours", ":next_respawn_hours"),
(call_script, "script_create_kingdom_hero_party", ":troop_no", ":center_no"),
(try_begin),
(eq, "$g_there_is_no_avaliable_centers", 0),
(party_attach_to_party, "$pout_party", ":center_no"),
(try_end),
#new
#(troop_get_slot, ":party_no", ":troop_no", slot_troop_leaded_party),
#(call_script, "script_npc_decision_checklist_party_ai", ":troop_no"), #This handles AI for both marshal and other parties
#(call_script, "script_party_set_ai_state", ":party_no", reg0, reg1),
#new end
(troop_get_slot, ":party_no", ":troop_no", slot_troop_leaded_party),
(call_script, "script_party_set_ai_state", ":party_no", spai_holding_center, ":center_no"),
(try_end),
(else_try),
(neg|faction_slot_eq, ":cur_faction", slot_faction_state, sfs_active),
(try_begin),
(is_between, ":troop_no", kings_begin, kings_end),
(troop_set_slot, ":troop_no", slot_troop_change_to_faction, "fac_commoners"),
(else_try),
(store_random_in_range, ":random_no", 0, 100),
(lt, ":random_no", 10),
(call_script, "script_cf_get_random_active_faction_except_player_faction_and_faction", ":cur_faction"),
(troop_set_slot, ":troop_no", slot_troop_change_to_faction, reg0),
(try_end),
(try_end),
(try_end),
(try_end),
]),
## CC
其中用到了两个新slot,需要在module_constants.py里面进行定义。
slot_troop_last_position_closest_center = 406
slot_troop_last_position_game_hours = 407
这是我MOD里的数值,具体的视自己MOD的情况而定。首先slot编号不能和已经存在的关于troop的slot冲突,其次slot的编号尽量小,这样可以使得存档更小,也使得MOD运行更流畅。
这样修改之后就合理多了。战败回城或从监狱放出或者逃走是根据距离来的,同一阵营,偏远主城的领主回城晚,前线主城的领主回城早。侵略者战败回城晚,守土者战败回城早,有利于守土者。那种大地图对角线,战败后回城的领主,可能一个星期才能回城,这比原版48小时,也就是两天要长得多。而就在城门口被击败的领主,最多4个小时就转身回城。按平均距离算,多数领主是在十几个小时回城,比原版最长48小时要短,战争节奏更加紧凑。
4个小时检测一次,间隔是比较合适的。每1小时检测一次,虽然更准,但是会消耗更多资源。检测时间间隔太长,距离相差比较大的可能都是同一时间回城,就没有区分度了。 再加上只是获取的领主失踪前,离他最近的哪一个center,而不是领主本身的位置坐标,换句话说就是获取的一个近似位置,所以这个机制也只是贴近真实,也只需要是贴近真实,不需要完全真实。
@Eason_hdy
|