Примечание:
Сразу говорю, что со Sward of Domocles я взял только идею. В игре этот мод будет выглядеть таким, как с SoD, но для Warband мне пришлось его кардинально переработать. С патрулем из SoD нет ни единого общего скриптика... Кроме того я сделал пару очень важных доработок. Так что что бы про плагиат мне тут не говорили. Целую неделю делал!
Примечание:
Для удобства я выделяю все по данной схеме:
Синий - искомый текст.
Зеленый - добавленный текст.
Красный - замененный текст.
Серый - исходный текст файла.
Итак:
Создание патруля для Warband
1.134, 1.143, 1.153
1. Новая партия
Патруль, который мы собираемся создать, по самой сути не должен быть похож ни на один существующий отряд. По этому для него надо создать новый.
Изменения будем вносить в party_tempates. Итак, дописываем вот тут:
("looter_lair","Kidnappers' Hideout",icon_bandit_lair|carries_goods(2)|pf_is_static|pf_hide_defenders,0,fac_neutral,bandit_personality,[(trp_looter,15,25)]),
("bandit_lair_templates_end","{!}bandit_lair_templates_end",icon_axeman|carries_goods(2)|pf_is_static,0,fac_outlaws,bandit_personality,[(trp_sea_raider,15,50)]),
("leaded_looters","Band of robbers",icon_axeman|carries_goods(8)|pf_quest_party,0,fac_neutral,bandit_personality,[(trp_looter_leader,1,1),(trp_looter,3,3)]),
# patrols +
("player_patrol","Player Partol", icon_gray_knight|pf_always_visible|carries_goods(10), 0, fac_player_supporters_faction, courage_15|aggressiveness_1,[]),
# patrol -
]
Примечание: серый - текст файла, зеленый - то, что мы дописываем.
Итак, что мы сделали:
- Создали новый вид групп с названием "Player Partol" (можно поменять по желанию).
- Дали ему иконку gray_knight (тоже можно поменять на желаемую).
- Сделали его всегда видимым. Как-никак - патруль, как бы информирует наc о своем местонахождении. Если этого не хотите - уберите флаг "pf_always_visible".
- Дали ему немного добра carries_goods(10), что бы бандиты не обходили его стороной, так же, как и любой обычный отряд...
- Самое главное, и где авторы кодя для SoD сделали большую ошибку, мы ставим ему фракцию "fac_player_supporters_faction", а совсем не "fac_player_faction". Иначе наш отряд не сможет нормально воевать и будет нам пользы от него ноль...
- Храбрость ставим на 15, что бы он не убегал, а защищал территорию, где мы его поставили. А агрессию на 1, что бы он не нападал на все, что движется и гонялся за ним по всей карте.
2. Диалоги
Итак, делаем очень важное - "интерфейс" управления нашей группой. Это обычные диалоги с приказами, которые знакомы вам от общения с лордами, если вы маршал...
Итак в dialogs найдем это:
######################################
# GENERIC MEMBER CHAT
######################################
Строки блока "member chat" мы будем заменять. Можете поместить их в комментарий:
##[anyone,"member_chat", [], "Your orders {sir/madam}?", "regular_member_talk",[]],
##[anyone|plyr,"regular_member_talk", [], "Tell me about yourself", "view_regular_char_requested",[]],
##[anyone,"view_regular_char_requested", [], "Aye {sir/madam}. Let me tell you all there is to know about me.", "do_regular_member_view_char",[[change_screen_view_character]]],
##[anyone,"do_regular_member_view_char", [], "Anything else?", "regular_member_talk",[]],
##[anyone|plyr,"regular_member_talk", [], "Nothing. Keep moving.", "close_window",[]],
Как я сказал, вместо этих строк вписываем вот эти нехитрые диалоги:
# patrols +
[anyone,"member_chat", [], "Your orders {sir/madam}?", "regular_member_talk",[]],
[anyone|plyr,"regular_member_talk", [], "Tell me about yourself", "view_regular_char_requested",[]],
[anyone,"view_regular_char_requested", [], "Aye {sir/madam}. Let me tell you all there is to know about me.", "do_regular_member_view_char",[[change_screen_view_character]]],
[anyone,"do_regular_member_view_char", [], "Anything else?", "regular_member_talk",[]],
[anyone|plyr,"regular_member_talk", [], "Make a party.", "plyr_patrol_make",[]],
[anyone,"plyr_patrol_make", [], "As you wish {sir/madam}.", "close_window",
[(store_conversation_troop,":soldier"),
(remove_member_from_party,":soldier"),
(troop_get_slot, ":selected_banner_spr", "trp_player", slot_troop_banner_scene_prop),
(troop_set_slot, ":soldier", slot_troop_banner_scene_prop, ":selected_banner_spr"),
(spawn_around_party,"p_main_party", "pt_player_patrol"),
(troop_set_slot, ":soldier", slot_troop_leaded_party, reg0),
(party_add_leader, reg0, ":soldier"),
(troop_get_slot, ":cur_banner", "trp_player", slot_troop_banner_scene_prop),
(party_set_ai_object, reg0, "p_main_party"),
(party_set_ai_behavior, reg0, ai_bhvr_escort_party),
(gt, ":cur_banner", 0),
(val_sub, ":cur_banner", banner_scene_props_begin),
(val_add, ":cur_banner", banner_map_icons_begin),
(party_set_banner_icon, reg0, ":cur_banner")]],
[anyone|plyr,"regular_member_talk", [], "Nothing. Keep moving.", "close_window",[]],
[party_tpl|pt_player_patrol,"start", [(store_encountered_party,"$temp")], "Yes {sir/madam}?", "plyr_patrol_chat_talk",[(assign, "$g_leave_encounter", 1)]],
[anyone|plyr,"plyr_patrol_chat_talk",[],"I have a new order.", "plyr_patrol_give_order_ask",[]],
# new
[anyone|plyr,"plyr_patrol_chat_talk",[],"Change tactics...", "plyr_patrol_tactic",[]],
[anyone,"plyr_patrol_tactic",[],"What we shall do?", "plyr_patrol_tactic_change",[]],
[anyone|plyr,"plyr_patrol_tactic_change",[],"Proceed as usual.", "plyr_patrol_tactic_change_done",[(party_set_aggressiveness, "$temp", 8),(party_set_courage, "$temp", 8)]],
[anyone|plyr,"plyr_patrol_tactic_change",[],"Attack any enemy.", "plyr_patrol_tactic_change_done",[(party_set_aggressiveness, "$temp", 15),(party_set_courage, "$temp", 15)]],
[anyone|plyr,"plyr_patrol_tactic_change",[],"Attack any enemy, but carefully.", "plyr_patrol_tactic_change_done",[(party_set_aggressiveness, "$temp", 15),(party_set_courage, "$temp", 4)]],
[anyone|plyr,"plyr_patrol_tactic_change",[],"Not attack, but defend yourself if need.", "plyr_patrol_tactic_change_done",[(party_set_aggressiveness, "$temp", 0),(party_set_courage, "$temp", 15)]],
[anyone|plyr,"plyr_patrol_tactic_change",[],"Not engage in any combat.", "plyr_patrol_tactic_change_done",[(party_set_aggressiveness, "$temp", 0),(party_set_courage, "$temp", 4)]],
[anyone,"plyr_patrol_tactic_change_done", [], "We will keep in mind {sir/madam}.", "close_window",[]],
# new
[anyone,"plyr_patrol_give_order_ask", [], "What do you wish {sir/madam}?", "plyr_patrol_give_order",[]],
[anyone|plyr,"plyr_patrol_give_order",[],"Follow me.","plyr_patrol_follow",[]],
[anyone,"plyr_patrol_follow",[],"All right {sir/madam}.","close_window",
[(party_set_ai_object,"$temp","p_main_party"),
(party_set_ai_behavior,"$temp",ai_bhvr_escort_party)]],
[anyone|plyr,"plyr_patrol_give_order",[],"Stay here.","plyr_patrol_stay",[]],
[anyone,"plyr_patrol_stay",[],"All right {sir/madam}.","close_window",
[(party_set_ai_behavior,"$temp",ai_bhvr_travel_to_point),
(party_get_position, pos1, "$temp"),
(party_set_ai_target_position,"$temp",pos1)]],
[anyone|plyr,"plyr_patrol_give_order",[],"Patrol this area.","plyr_patrol_patrol",[]],
[anyone,"plyr_patrol_patrol",[],"All right {sir/madam}.","close_window",
[(party_set_ai_behavior,"$temp",ai_bhvr_patrol_location),
(party_get_position, pos1, "$temp"),
(party_set_ai_target_position,"$temp",pos1),
(party_set_ai_patrol_radius,"$temp",5)]],
[anyone|plyr,"plyr_patrol_give_order", [],"Go to...", "plyr_patrol_give_order_details_ask",[(assign, "$temp_1", spai_holding_center)]],
[anyone|plyr,"plyr_patrol_give_order", [],"Patrol around...", "plyr_patrol_give_order_details_ask",[(assign, "$temp_1", spai_patrolling_around_center)]],
[anyone|plyr,"plyr_patrol_give_order", [],"Forget it.", "plyr_patrol_chat_pre_talk",[]],
[anyone,"plyr_patrol_give_order_details_ask", [],"Where?", "plyr_patrol_give_order_details",[]],
[anyone|plyr|repeat_for_parties, "plyr_patrol_give_order_details",
[(store_repeat_object, ":party_no"),
(assign, ":continue", 0),
(try_begin),
(eq, "$temp_1", spai_holding_center),
(try_begin),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_village),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_castle),
(party_slot_eq, ":party_no", slot_party_type, spt_town),
(assign, ":continue", 1),
(try_end),
(else_try),
(eq, "$temp_1", spai_patrolling_around_center),
(try_begin),
(is_between, ":party_no", centers_begin, centers_end),
(assign, ":continue", 1),
(try_end),
(try_end),
(eq, ":continue", 1),
(neq, ":party_no", "$g_encountered_party"),
(str_store_party_name, s1, ":party_no")],
"{s1}", "plyr_patrol_give_order_details_done",[(store_repeat_object, "$temp_2")]],
[anyone|plyr,"plyr_patrol_give_order_details", [],"Never mind.", "plyr_patrol_give_order_details",[]],
[anyone,"plyr_patrol_give_order_details_done", [],"Of course {sir/madam}!","close_window",
[(try_begin),
(eq,"$temp_1", spai_holding_center),
(party_set_ai_behavior,"$temp",ai_bhvr_travel_to_point),
(party_get_position, pos1, "$temp_2"),
(map_get_land_position_around_position, pos1, pos1,1),
(party_set_ai_target_position,"$temp",pos1),
(try_end),
(try_begin),
(eq,"$temp_1", spai_patrolling_around_center),
(party_set_ai_behavior,"$temp",ai_bhvr_patrol_party),
(party_set_ai_object,"$temp","$temp_2"),
(party_set_ai_patrol_radius ,"$temp",1),
(try_end)]],
[anyone|plyr,"plyr_patrol_chat_talk", [], "Show me your party.", "plyr_patrol_give_troops_end",[]],
[anyone,"plyr_patrol_give_troops_end", [], "Of course {sir/madam}!", "plyr_patrol_chat_pre_talk",[(change_screen_exchange_members,1)]],
[anyone,"plyr_patrol_chat_pre_talk", [], "Anything else?", "plyr_patrol_chat_talk",[]],
[anyone|plyr,"plyr_patrol_chat_talk", [], "Join my party.", "plyr_patrol_chat_rejoin",[]],
[anyone,"plyr_patrol_chat_rejoin", [], "We will do it right now {sir/madam}.", "close_window",[(party_join)]],
[anyone|plyr,"plyr_patrol_chat_talk", [], "Never mind.", "close_window",[]],
# patrols -
Фразы диалогов можете менять, как душе угодно, если вам не нравятся эти... Кириллицу не используйте, в модульке можно исключительно латиницу!
Как можно заметить из диалогов патруль создается так:
В меню партии выбираем воина -> "Говорить" -> "Make a party". В итоге на карте появится отряд с этим воином. Патруль будет уметь:
- Обмениваться войсками с группой игрока;
- Вернуть всех воинов обратно в группу игрока;
- Следовать;
- Стоять;
- Патрулировать;
- Идти в назначенное место (город/замок/деревня);
- Патрулировать назначенное место (город/замок/деревня);
Некоторые примечания:
- При создании патруля он по умолчанию будет следовать за вами. Если вам надо, что бы группа по умолчанию стояла на месте, то в диалоге Make a party. в середине блока операций вместо "ai_bhvr_escort_party" пропишите "ai_bhvr_hold".
- Когда вы приказываете патрулю стоять на месте или идти в указанное место, то патруль всегда (пока не прикажете что-то другое) будет стремится находится в этой точке. То есть даже, если его спугнут враги, то он потом вернется обратно.
Тактика:
Патрулям можно менять тактику. Это всего-лишь изменение агрессивности и храбрости, но оно отлично влияет на действия патруля. Имейте ввиду, тактика - не жесткий приказ. Она лишь указывает патрулям, как бы им стоило поступать, а не приказывает поступать именно так.
Варианты:
- Действовать обычно ("нейтральные" значения)
- Атаковать всех врагов (макс. агрессия и храбрость; атакуют всех врагов, даже тех, кто сильнее патруля)
- Атаковать аккуратно (макс. агрессия, мин. храбрость; атакуют только, если враг слабее патруля)
- Не атаковать, но защищаться (мин. агрессия, макс. храбрость; не атакуют первыми, но не убегают, даже от врагов сильнее патруля)
- Не вступать в бой (мин. агрессия и храбрость; сами не атакуют и убегают, даже от врагов слабее патруля)
Примечания:
Имейте ввиду, что каких-то 5-10 воинов точно не пойдут на 100-150 врагов ни при какой тактике и будут в любом случае убегать.
Тактика не влияет на присоединение патруля на вашу сторону при начале битвы. Патруль присоединится в любом случае.
4. Скрипты
Скрипт всего один - подсчет платы всем патрулям. Подробнее в следующем пункте.
Итак в scripts в самом конце перед закрывающей скобкой:
(eq, ":cur_faction", "fac_player_supporters_faction"),
(val_add, ":number_of_vassals", 1),
(try_end),
(ge, ":number_of_vassals", 3),
(unlock_achievement, ACHIEVEMENT_CONCILIO_CALRADI),
(try_end),
]),
# patrols +
# script_get_all_patrols_wage
# input: none
# output: reg5 = patrol wage
("get_all_patrols_wage",
[(try_begin),
(assign, reg5, 0),
(try_for_parties, ":party"),
(party_get_template_id, ":pt_id", ":party"),
(eq, ":pt_id", "pt_player_patrol"),
(try_begin),
(party_get_num_companion_stacks, ":stacks", ":party"),
(try_for_range, ":stack", 0, ":stacks"),
(party_stack_get_troop_id, ":stack_troop", ":party", ":stack"),
(party_stack_get_size, ":stack_size", ":party", ":stack"),
(call_script, "script_game_get_troop_wage", ":stack_troop", ":party"),
(assign, ":cur_wage", reg0),
(val_mul, ":cur_wage", ":stack_size"),
(val_add, reg5, ":cur_wage"),
(try_end),
(val_mul, reg5, 3), # | 150% ----
(val_div, reg5, 2), # | ---- for patrols
(try_end),
(try_end),
(try_end),
]
),
# patrols +
]
Примечание: Серый - текст файла, зеленый - то, что мы дописываем.
Как видите, патрули получают плату в размере 150%.
По 2 мнимым причинам:
- На пропитание (в отряде игрока ведь кормит игрок);
- Все-таки патруль, работа сложная, рискованная;
И одной объективной причине:
- Что бы не было слишком легко после такого нововведения :p
5. Презентации
Что же нам понадобилось в презентация? Ответ прост - недельная смета! Сейчас мы сделаем замечательный фокус, после которого плата за все патрули будет писаться в одной строчке. По стандарту новая строчка - это новый отряд. А нам ведь не надо стописят строчек, если у нас много патрулей...
Итак, дело сложное. Делаем все очень внимательно!
Первое:
В presentations найти строку:
("budget_report", 0, mesh_load_window,
Нашли? Рано радоваться, нам надо намного ниже.... Теперь ниже этой строки найдите вот это:
(try_for_parties, ":party_no"),
(assign, ":garrison_troop", 0),
Вы должны видеть вот такое:
(gt, ":num_owned_center_values_for_tax_efficiency", ":num_centers_needed_for_efficiency_loss"),
#gt accumulated total is ignored
(val_add, ":num_lines", 1),
(try_end),
(try_for_parties, ":party_no"),
(assign, ":garrison_troop", 0),
(try_begin),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_town),
(party_slot_eq, ":party_no", slot_party_type, spt_castle),
Так вот: зеленая строка говорит нам, что вы нашли не то.
Надо еще раз найти упомянутые выше 2 строчки.
Вы должны найти вот такой блок:
(Синим я выделил искомые строчки)
(position_set_y, pos1, ":cur_y"),
(overlay_set_position, reg1, pos1),
(val_sub, ":cur_y", 27),
(try_end),
(try_for_parties, ":party_no"),
(assign, ":garrison_troop", 0),
(try_begin),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_town),
(party_slot_eq, ":party_no", slot_party_type, spt_castle),
(party_slot_eq, ":party_no", slot_town_lord, "trp_player"),
(assign, ":garrison_troop", 1),
(else_try),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_town),
(party_slot_eq, ":party_no", slot_party_type, spt_castle),
(neg|party_slot_ge, ":party_no", slot_town_lord, 1), #unassigned
(store_faction_of_party, ":center_faction", ":party_no"),
(eq, ":center_faction", "fac_player_supporters_faction"),
(faction_slot_eq, "fac_player_supporters_faction", slot_faction_leader, "trp_player"),
(assign, ":garrison_troop", 1),
(try_end),
(this_or_next|eq, ":party_no", "p_main_party"),
(this_or_next|eq, ":garrison_troop", 1),
(assign, ":total_wage", 0),
(party_get_num_companion_stacks, ":num_stacks", ":party_no"),
(try_for_range, ":i_stack", 0, ":num_stacks"),
(party_stack_get_troop_id, ":stack_troop", ":party_no", ":i_stack"),
(party_stack_get_size, ":stack_size", ":party_no", ":i_stack"),
(call_script, "script_game_get_troop_wage", ":stack_troop", ":party_no"),
(assign, ":cur_wage", reg0),
(val_mul, ":cur_wage", ":stack_size"),
(val_add, ":total_wage", ":cur_wage"),
(try_end),
(try_begin),
(eq, ":garrison_troop", 1),
(val_div, ":total_wage", 2), #Half payment for garrisons
(else_try),
(eq, ":party_no", "p_main_party"),
(store_sub, ":total_payment_ratio", 14, "$g_cur_week_half_daily_wage_payments"), #between 0 and 7
(val_mul, ":total_wage", ":total_payment_ratio"),
(val_div, ":total_wage", 14),
(try_end),
## (gt, ":total_wage", 0),
(val_mul, ":total_wage", -1),
(val_add, ":net_change", ":total_wage"),
(str_store_party_name, s0, ":party_no"),
(try_begin),
(eq, ":party_no", "p_main_party"),
(str_store_string, s0, "str_s0s_party"),
(try_end),
(create_text_overlay, reg1, "str_wages_for_s0", 0),
(position_set_x, pos1, 900),
(position_set_y, pos1, 900),
(overlay_set_size, reg1, pos1),
(position_set_x, pos1, 25),
Проглядите его, в файле вы должны быть именно на это блоке. Именно его мы сейчас будем редактировать.
Что бы не объяснять каждую букву я просто выложу этот же блок со сделанными изменениями. Вы должны у себя сделать такие же изменения. Обратите внимание, что все строки добавлены, т.е. из начального текста не нужно ничего удалять. (position_set_y, pos1, ":cur_y"),
(overlay_set_position, reg1, pos1),
(val_sub, ":cur_y", 27),
(try_end),
(assign, ":patrols_lim", 0), # | patrols
(try_for_parties, ":party_no"),
(assign, ":garrison_troop", 0),
(try_begin),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_town),
(party_slot_eq, ":party_no", slot_party_type, spt_castle),
(party_slot_eq, ":party_no", slot_town_lord, "trp_player"),
(assign, ":garrison_troop", 1),
(else_try),
(this_or_next|party_slot_eq, ":party_no", slot_party_type, spt_town),
(party_slot_eq, ":party_no", slot_party_type, spt_castle),
(neg|party_slot_ge, ":party_no", slot_town_lord, 1), #unassigned
(store_faction_of_party, ":center_faction", ":party_no"),
(eq, ":center_faction", "fac_player_supporters_faction"),
(faction_slot_eq, "fac_player_supporters_faction", slot_faction_leader, "trp_player"),
(assign, ":garrison_troop", 1),
(try_end),
(party_get_template_id, ":pt_id", ":party_no"), # | patrols
(this_or_next|eq, ":party_no", "p_main_party"),
(this_or_next|eq, ":garrison_troop", 1),
(eq, ":pt_id", "pt_player_patrol"), # | patrols
(eq, ":patrols_lim", 0), # | patrols
(assign, ":total_wage", 0),
(party_get_num_companion_stacks, ":num_stacks", ":party_no"),
(try_for_range, ":i_stack", 0, ":num_stacks"),
(party_stack_get_troop_id, ":stack_troop", ":party_no", ":i_stack"),
(party_stack_get_size, ":stack_size", ":party_no", ":i_stack"),
(call_script, "script_game_get_troop_wage", ":stack_troop", ":party_no"),
(assign, ":cur_wage", reg0),
(val_mul, ":cur_wage", ":stack_size"),
(val_add, ":total_wage", ":cur_wage"),
(try_end),
(try_begin),
# patrols +
(eq, ":pt_id", "pt_player_patrol"),
(eq, ":patrols_lim", 0),
(call_script, "script_get_all_patrols_wage"),
(assign, ":total_wage", reg5),
#(val_mul, ":total_wage", 3),
#(val_div, ":total_wage", 2),
(val_add, ":patrols_lim", 1),
(else_try),
# patrols -
(eq, ":garrison_troop", 1),
(val_div, ":total_wage", 2), #Half payment for garrisons
(else_try),
(eq, ":party_no", "p_main_party"),
(store_sub, ":total_payment_ratio", 14, "$g_cur_week_half_daily_wage_payments"), #between 0 and 7
(val_mul, ":total_wage", ":total_payment_ratio"),
(val_div, ":total_wage", 14),
Примечание: Серый - текст файла, зеленый - то, что мы дописываем.
Если у вас все точно, как на примере, значит все ОК!
Ну собственно это все. Компилируем и радуемся.
Если вам понравился это дополнение, попробуйте так же 7. Заставляем ваш эскорт разбивать лагерь вместе с вами (http://rusmnb.ru/index.php?topic=11306)