OSP Code Campaign Field army - Separated player warband

Users who are viewing this thread

Hello.

I just wanted to share the script i made. This script will allow the player to send one of his troops to form a new parties (Field army) and act like patrol but with lord-like option so they can be tasked to follow you, patrol, there, go there, stay there, etc.

I made this script because i thought it will be more fun if you want to role-play to become a solo monarch without a lord serving but also wanted to have some form of war parties that can be tasked anything.

I made this script using some diplomacy patrol script i modified to act like indepedent war parties like described above.

This script will make new friendly parties under your command with "fac_player_faction" in faction slot.
here the script:

module_script.py
Code:
#script_fa_send_party
  #Input:
  #Output:
  ("fa_send_party",
  [
    (store_script_param, ":start_party", 1),
    (store_script_param, ":soldier", 2),
    (store_script_param, ":player_fac", 3),

	(spawn_around_party, ":start_party","pt_player_field_army"),
    (assign,":spawned_party",reg0),
    (party_set_faction, ":spawned_party", ":player_fac"),
    (party_set_slot, ":spawned_party", slot_party_type, spt_player_field_army),
    (str_store_party_name, s5, ":start_party"),
    (party_set_name, ":spawned_party", "@{s5} Field Army"),
	
	(party_add_members, ":spawned_party",":soldier",1),

    (party_set_ai_behavior, ":spawned_party", ai_bhvr_escort_party),

  ]),

#and Jrider diplomacy patrol identifier script - if you don't already have it

# Jrider -
   
   #identify party as patrol
#input: party
#output: reg0
#0 yes, 1 no
      
   ("cf_is_patrol",
      [
         (store_script_param, ":cur_party", 1),
         (assign,reg0,0),
         (store_faction_of_party,":cur_faction",":cur_party"),
         (eq, ":cur_faction", "fac_player_faction"),
         (party_stack_get_troop_id,":cur_troop",":cur_party",0),
         (neq,":cur_troop","trp_player"),
         (try_for_range,":num",companions_begin,heroes_end),
           (eq,":cur_troop",":num"),
           (assign, reg0,1),
         (try_end),
      ]
   ),
   
#find all patrols and count them
#input: none
#output: reg0
#amount of existing patrols

   ("check_for_patrols",
      [
         (assign,":num",0),
         (try_for_parties,":cur_party"),
           (call_script, "script_cf_is_patrol",":cur_party"),
           (eq,reg0,0),
           (val_add,":num",1),
         (try_end),
         (assign,reg0,":num"),
      ]
   ),
   
#enforce patrol party size limit
#it is assumed that the party prisoner limit equals zero
#except for npc prisoners

#input: party, mode
#mode 0: delete all troops w/o doing anything else
#mode 1: all deleted troops are being added to the player party

#output: none (it uses reg0, but the information is useless outside of this script and its recursive brother)
   
   ("cf_fix_party_size",
      [
         (store_script_param, ":cur_party", 1),
         (store_script_param, ":mode", 2),
         (call_script, "script_cf_is_patrol",":cur_party"),
         (try_begin),
           (eq,reg0,0),
           (call_script,"script_game_get_party_companion_limit",3),
           (call_script,"script_cf_fix_party_size_recursive",":cur_party",":mode"),

           (assign,":bool",0),
           (party_get_num_prisoner_stacks, ":num_stacks",":cur_party"),
           (try_for_range_backwards,":index",0,":num_stacks"),
             (party_prisoner_stack_get_troop_id,":cur_troop",":cur_party",":index"),
             (party_prisoner_stack_get_size,":cur_size",":cur_party",":index"),
            (try_for_range,":num",companions_begin,heroes_end),
               (eq,":cur_troop",":num"),
              (assign,":bool",1),
            (try_end),
            (try_begin),
              (neq,":bool",1),
               (party_remove_prisoners,":cur_party",":cur_troop",":cur_size"),
            (try_end),
           (try_end),
         (try_end),
      ]
   ),

#a while do loop for cf_fix_party_size
#don't use it outside of the previous script
   
   ("cf_fix_party_size_recursive", #I am not exactly happy about the recursive
      [
         (store_script_param, ":cur_party", 1),
         (store_script_param, ":mode", 2),
         (assign,":reg0_backup",reg0),
         (store_party_size_wo_prisoners,":num",":cur_party"),
         (try_begin),
           (gt,":num",reg0),
           (neq,0,reg0),
           (store_sub,":delta",":num",reg0),
           (party_get_num_companion_stacks,":num_stacks",":cur_party"),
           (assign, ":to_del_stack",0),
           (assign, ":checker", 100),
           (try_for_range,":index",0,":num_stacks"),
             (party_stack_get_troop_id,":cur_troop",":cur_party",":index"),
             (store_character_level,":cur_level",":cur_troop"),
             (le,":cur_level",":checker"),
             (assign,":checker",":cur_level"),
             (assign,":to_del_stack",":index"),
           (try_end),
           (party_stack_get_size,":num_troop",":cur_party",":to_del_stack"),
           (party_stack_get_troop_id,":cur_troop",":cur_party",":to_del_stack"),
           (try_begin),
             (le,":num_troop",":delta"),
             (assign, ":delta", ":num_troop"),
           (try_end),
           (party_remove_members,":cur_party",":cur_troop",":delta"),
           (try_begin),
             (eq,":mode",1),
             (party_add_members,"p_main_party",":cur_troop",":delta"),
           (try_end),
           (assign,reg0,":reg0_backup"),
           (call_script,"script_cf_fix_party_size_recursive",":cur_party",":mode"),
         (try_end),
      ]
   ),

module_dialog.py (in GENERIC MEMBER CHAT, bellow "Tell me about yourself" option)
Code:
##field army begin +  
  [anyone|plyr,"regular_member_talk", [], "Lead a field army", "fa_check",[]],
  [anyone|plyr, "fa_check", [
							(call_script, "script_check_for_patrols"),
							(store_faction_of_party, "$fa_fac", "trp_player"),
							(store_skill_level,":max_amount",skl_leadership,"trp_player"),
							(troop_get_slot, ":renown", "trp_player", slot_troop_renown),
							(val_div, ":renown", 100), #Ammount of required renown to able to send war parties
							(val_add, ":max_amount",":renown"),
							(try_for_range,":num",walled_centers_begin,walled_centers_end),
                             (party_slot_eq, ":num", slot_town_lord, "trp_player"),
							 (val_add,":max_amount",1),
							(try_end),
							(gt,":max_amount",reg0),
							],"Very well.","close_window",[
                                             (store_conversation_troop,":soldier"),
                                             (remove_member_from_party,":soldier"),
											 (try_begin),
												(eq, "$fa_fac", "fac_player_faction"),
												(call_script, "script_fa_send_party", "p_main_party", ":soldier", "fac_player_faction"),
											 (else_try),
												(call_script, "script_fa_send_party", "p_main_party", ":soldier", "$players_kingdom"),
											 (try_end),
											 #(call_script, "script_fa_send_party", "p_main_party", ":soldier", "fac_player_faction"),#"fac_player_faction" "$players_kingdom"
                                             #(spawn_around_party,"p_main_party","pt_player_field_army"),
                                             #(party_set_slot, reg(0), slot_party_type, spt_field_army),
                                             #(party_add_members,reg(0),":soldier",1),
                                             #(party_set_ai_behavior,reg(0),ai_bhvr_escort_party),
                                             ]],
  [anyone,"fa_check", [],"I am sorry {sir/madam}, but we don't think that you capable to sendind more field army.","member_chat",[]],
	
   [anyone,"start",
   [
   (store_encountered_party,"$temp"),
   (party_slot_eq, "$temp", slot_party_type, spt_player_field_army),
   (party_slot_eq, "$temp", fa_slot_party_mission, "trp_player"),
   #(store_faction_of_party, ":cur_faction", "$temp"),
   #(eq,":cur_faction","fac_player_faction"),
                    ],
   "Yes?", "fa_chat_talk",[(assign, "$g_leave_encounter", 1)]],
  
  
 [anyone|plyr,"fa_chat_talk",[],"I have a new task for you.", "fa_give_order_ask",[]],

  [anyone,"fa_give_order_ask", [],
   "Yes {Sir/Madam}?", "fa_give_order",[]],
   
  [anyone|plyr,"fa_give_order",[],"Follow me","fa_follow",[]],
  [anyone,"fa_follow",[],"All right","close_window",[
                                       (party_set_ai_object,"$temp","p_main_party"),
                                       (party_set_ai_behavior,"$temp",ai_bhvr_escort_party),
                                       ]],
  [anyone|plyr,"fa_give_order",[],"Stay here","fa_stay",[]],
  [anyone,"fa_stay",[],"All right","close_window",[
                                       (party_set_ai_behavior,"$temp",ai_bhvr_hold),
                                       (party_get_position, pos1, "$temp"),
                                       (party_set_ai_target_position,"$temp",pos1),
                                       ]],
  [anyone|plyr,"fa_give_order",[],"Patrol this area","fa_patrol",[]],
  [anyone,"fa_patrol",[],"All right","close_window",[
                                       (party_set_ai_behavior,"$temp",ai_bhvr_patrol_location),
                                       (party_get_position, pos1, "$temp"),
                                       (party_set_ai_target_position,"$temp",pos1),
                                       ]],
  
  [anyone|plyr,"fa_give_order", [],"Go to...", "fa_give_order_details_ask",[(assign, "$temp_1", spai_holding_center),]],
  [anyone|plyr,"fa_give_order", [],"Patrol around...", "fa_give_order_details_ask",[(assign, "$temp_1", spai_patrolling_around_center),]],
  [anyone|plyr,"fa_give_order", [],"Forget it.", "fa_chat_pre_talk",[]],
  

  [anyone,"fa_give_order_details_ask", [],
   "Where?", "fa_give_order_details",[]],
  
  [anyone|plyr|repeat_for_parties, "fa_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_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}", "fa_give_order_details_done",
   [
     (store_repeat_object, "$temp_2"),
     ]],
    
  [anyone,"fa_give_order_details_done", [],"Okay","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,"fa_chat_talk", [], "I want to give you troops.", "fa_give_troops",[(call_script,"script_game_get_party_companion_limit",3),(display_message, "@allowed party size {reg0}"),(change_screen_give_members),]],
  [anyone,"fa_give_troops", [], "Yes...", "fa_give_troops_end",[]],
  [anyone,"fa_give_troops_end", [], "There we go.", "fa_chat_pre_talk",[
                                                         (store_encountered_party,":cur_party"),
                                                         (call_script,"script_cf_fix_party_size",":cur_party",1),
                                                         ]],
  [anyone,"fa_chat_pre_talk", [], "Anything else?", "fa_chat_talk",[]],
  
  [anyone|plyr,"fa_chat_talk", [], "I want to you to join me again.", "fa_chat_rejoin",[]],
  [anyone,"fa_chat_rejoin", [(party_can_join)], "Yes {sir/madam}.", "close_window",[(party_join),]],
  [anyone,"fa_chat_rejoin", [(neg|party_can_join)], "We can't join you, you don't have enough capacity","fa_chat_talk",[]],
 
  [anyone|plyr,"fa_chat_talk", [], "Nevermind", "close_window",[]],
##field army end +

module_simple_trigger.py (in diplomacy below patrol wages script, in native just after the last script)
Code:
# Field Army Wages
  (24 * 7,
   [

    (try_for_parties, ":party_no"),
      (party_slot_eq,":party_no", slot_party_type, spt_player_field_army),



      #(party_get_slot, ":ai_state", ":party_no", slot_party_ai_state),
      #(eq, ":ai_state", spai_patrolling_around_center),

      (try_begin),
		(party_slot_eq, ":party_no", fa_slot_party_mission, "trp_player"),
        (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", 0),
          (val_mul, reg0, ":stack_size"),
          (val_add, ":total_wage", reg0),
        (try_end),
        (store_troop_gold, ":gold", "trp_player"),
        (try_begin),
          (lt, ":gold", ":total_wage"),
          #(party_get_slot, ":target_party", ":party_no", slot_party_ai_object),
          #(str_store_party_name, s6, ":target_party"),
          (display_log_message, "@Your field army disbanded because you can't pay their wages!", 0xFF0000),
          (remove_party, ":party_no"),
        (try_end),
      (try_end),
    (try_end),
    ]),

module_presentation.py (in diplomacy below second patrol wages presentation in search, native after line 12780)
Code:
##Field Army Start +
		(assign, ":fa_troop", 0),
        (try_begin),
          (party_slot_eq, ":party_no",slot_party_type, spt_player_field_army),
          (party_slot_eq, ":party_no", fa_slot_party_mission, "trp_player"),
          (assign, ":fa_troop", 1),
        (try_end),
        (this_or_next|eq, ":fa_troop", 1),
		##Field Army End +

also in module_script.py (in script_let_nearby_parties_join_current_battle, before
"(this_or_next|eq, ":dont_add_friends_other_than_accompanying", 0)," )
Code:
#fa begin
		  (store_faction_of_party, ":faction_no", ":party_no"),
		  (assign, ":fa_true", 0),
		  (try_begin),
			#(party_slot_eq, ":party_no", slot_party_ai_state, spai_accompanying_army),            
            #(party_slot_eq, ":party_no", slot_party_ai_object, "p_main_party"),
			(eq, ":faction_no", "fac_player_faction"),#"fac_player_faction" "$players_kingdom"
            (assign, ":fa_true", 1),
		  (else_try),
			(eq, ":faction_no", "$players_kingdom"),#"fac_player_faction" "$players_kingdom"
            (assign, ":fa_true", 2),
		  (try_end),
		  
		  (try_begin),
			(eq, ":fa_true", 1),
			
			(party_quick_attach_to_current_battle, ":party_no", 0),
			(str_store_party_name, s1, ":party_no"),
			(display_message, "str_s1_joined_battle_friend"),
		  (else_try),
			(eq, ":fa_true", 2),
			
			(party_quick_attach_to_current_battle, ":party_no", 0),
			(str_store_party_name, s1, ":party_no"),
			(display_message, "str_s1_joined_battle_friend"),
		  (try_end),
		  
		  #fa end

module_constant.py (in diplomacy, below spt_patrol and dplmc_slot_party_mission_diplomacy )
Code:
#...Below dplmc_slot_party_mission_diplomacy...
fa_slot_party_mission						  = 301

#...Below spt_patrol...
spt_player_field_army  						  = 22

module_party_template.py (in diplomacy after routed_enemies)
Code:
# Field Army
  ("player_field_army","Field Army",icon_gray_knight,0,fac_player_faction,fieldarmy_personality,[]),

#...You can change their personality to soldier or anthing...

header_parties.py (if you want to use my custom personality if not change personality in party_templates to soldier_pesonality)
Code:
fieldarmy_personality = aggressiveness_8 | courage_15 #Optional
hold_personality = aggressiveness_0 | courage_15 #Optional

EDIT:

Credit:

-Waihti, zParsifal, Jrider: Diplomacy mod source (https://forums.taleworlds.com/index.php/topic,116424.0.html#post_mods)

EDIT2: Thanks Dj_FRedy for noticing the error in wages script when it suppose to take the gold straight from player inventory but instead take it from money in chamberlain.
 
Hey, Neolemon, I wonder if it wouldn't be better to check the gold directly from the player's inventory, or track if the player has a center and a chamberlain, since otherwise, he wouldn't be able to access the treasure and the party would always dissolve.
I mean this operation: (store_troop_gold, ":gold", "trp_household_possessions"),
 
Dj_FRedy said:
Hey, Neolemon, I wonder if it wouldn't be better to check the gold directly from the player's inventory, or track if the player has a center and a chamberlain, since otherwise, he wouldn't be able to access the treasure and the party would always dissolve.
I mean this operation: (store_troop_gold, ":gold", "trp_household_possessions"),

Oh god!  :facepalm:. Yes i'm sorry, didn't notice if trp_household_posessions, isn't exist in native, i thought it would be go to player inventory directly, since i follow the original patrol wages script.

Thanks! i'll edit it soon
 
(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),
          ##Field Army Start +
(assign, ":fa_troop", 0),
        (try_begin),
          (party_slot_eq, ":party_no",slot_party_type, spt_player_field_army),
          (party_slot_eq, ":party_no", fa_slot_party_mission, "trp_player"),
          (assign, ":fa_troop", 1),
        (try_end),
        (this_or_next|eq, ":fa_troop", 1),
##Field Army End +
(else_try), 


Have i pasted a piece of code in correct way?
 
Its a nice addition, it would be great to make them expensive since they warband(hehe) leader not only needs money to pay his men, he also needs it to buy food...etc
Also adding a condition that you need a certain level of leadership to control certain number of bands, meaning having high level leadership can be more useful. also I think allowing npc lords be able to deploy warbands would be great as well depending on the lord's leadership level, will help small kingdoms have another way to defend themselves or even when invading, it opens a lot of new ways of attacking and defending.

thanks again for the work!
 
Um… I wonder that as for the last three spoilers, is it the same way to add them in native?since only [diplomacy] was mentioned there.
 
Back
Top Bottom