PYTHON SCRIPT/SCHEME EXCHANGE

Users who are viewing this thread

Dj_FRedy said:
mm I see that this modification was updated for Warband 1.143, since then new slots have been added, 146 and 147, in vanilla or Diplomacy, are already in use ...

Thanks for noticing that Dj_FRedy, I'll try assigning different numbers to those two slots!


Geoffrey Ashe said:
Okay here it goes, the sources of the NNY mod. I hope they are getting used:

Explanation how to the read/insert the code
filename
#######

this file is meant, till another one is mentioned.


code1
#----------------------------------------------------------------------------------
code2
#----------------------------------------------------------------------------------
code3

code 2 is new and is supposed t o be inserted between code1 and code3 (they are mentioned to find where exactly the code is supposed to go)


#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#--#-

Desperation between each code piece

Bandit bribery
module_dialog.py
################

    ], "{s5}", "close_window",[encounter_attack]],
#----------------------------------------------------------------------------------
[anyone|plyr,"bandit_meet", [], "I spare your life if you join me", "bandit_recruit",[]],

[anyone,"bandit_recruit", [
(store_random_in_range,":rand",0,20),
(gt,"$player_honor",":rand"),
], "A {boy/girl} like you, who could do no misdeeds? Heck no. We will slit your throat for your impudence!","close_window",[encounter_attack]],#needs dialog rewrite

[anyone,"bandit_recruit",[
(store_encountered_party,":party"),
(store_party_size,":size",":party"),
(store_mul,":size",":size",50),
(assign, reg0, ":size"),
],"we consider your offer for {reg0} denars","bandit_recruit_2",[]],

[anyone|plyr,"bandit_recruit_2",
[
        (store_troop_gold, ":gold", "trp_player"),
        (ge, ":gold", reg0),
(party_can_join),
],"Okay","close_window",
[
(troop_remove_gold, "trp_player", reg0),
(party_join),
(assign, "$g_leave_encounter", 1)
]],

 
[anyone|plyr,"bandit_recruit_2",[],"Nevermind","bandit_meet",[]],
#----------------------------------------------------------------------------------
  [anyone|plyr,"bandit_meet", [], "Never mind, I have no business with you.", "close_window",[(assign, "$g_leave_encounter", 1)]],

I also made some adjustments to this script...
I think that the actual payment part of the script was somehow messed up so I fixed that issue first.
I also added some consequences for recruiting bandits, like morale and honour loss and aristocratic NPC complaints.
The morale impact is the same as the one used for recruiting prisoners (-4 morale per man) and the impact also depends on selected campaign AI difficulty.

Follow the same code placement as the one in Geoffrey Ashe's original version:

Code:
# BANDIT BRIBE BEGIN
   [anyone|plyr,"bandit_meet", [], "I'll spare your life if you join me.", "bandit_recruit",[]],
   
   [anyone,"bandit_recruit", [
      (store_random_in_range,":rand",0,20),
      (gt,"$player_honor",":rand"),
   ], "A {boy/girl} like you, who could do no misdeeds? Heck no. We will slit your throat for your impudence!","close_window",[encounter_attack]],
         
   [anyone,"bandit_recruit",[
      (store_encountered_party,":party"),
      (store_party_size,":size",":party"),
      (store_mul,":size_bribe",":size",50),
      (assign, reg0, ":size_bribe"),
   ],"We'll consider your offer for {reg0} denars.","bandit_recruit_2",[]],
   
   [anyone|plyr,"bandit_recruit_2",
   [
        (store_troop_gold, ":gold", "trp_player"),
        (ge, ":gold", reg0),
      (party_can_join),
   ],"Very well.","close_window",
   [
      (store_encountered_party,":party"),
      (store_party_size,":size",":party"),
      (store_mul,":size_bribe",":size",50),
      (assign, reg0, ":size_bribe"),
      (troop_remove_gold, "trp_player", reg0),
      (play_sound, "snd_money_paid"),
      # change base morale reduction based on difficulty:
      (game_get_reduce_campaign_ai, ":reduce"),
      (val_sub, ":reduce", 4),
      (store_mul, ":morale_change", ":reduce", ":size"),
      (call_script, "script_change_player_party_morale", ":morale_change"),
      (party_join),
      (assign, "$g_leave_encounter", 1),
      (call_script, "script_change_player_honor", -1),
      (call_script, "script_objectionable_action", tmt_aristocratic, "str_pay_bandits"),

   ]],
               
   [anyone|plyr,"bandit_recruit_2",[],"Forget about it.","bandit_meet",[]],
# BANDIT BRIBE END

As and optional part, you can also find the used companion complaint lines ("script_objectionable_action", tmt_aristocratic, "str_pay_bandits") and edit them so they're more to you liking.
I like to make them a bit more vague since they're used as a response for paying off the bandits to leave you alone in Native.
Which means that your aristocratic companion will refer to recruiting bandits as "Bla bla such cowardice, bla never truly feared by his men bla bla."
I just tend to replace "such cowardice" with "such actions" and "truly feared" with "truly respected".
But even if you leave them the way they are in Native it's acceptable.

And yeah, I'm pretty new at this so feel free to suggest any adjustments that would make the code less messy.
 
Hey guys, I edited the script for calculating the score for each lord when it's time for the king to hand out fiefs. Instead of heavily relying on renown, which inevitably leads the king and a few other super-lords to control everything, this script heavily relies on how many fiefs the lord owns, what kind of fief it is, and also HEAVILY penalizes the faction leader unless they themselves are landless. It also tries to give out walled centers equitably, so if a lord doesn't have a walled center and a walled center is up for grabs, it favors them over lords that already have a walled center. Also, it makes a lord's relationship with his king more important because it slightly influences the score for all lords, whereas previously the script only handled a human player's relationship with their king. It also decreases bonus to score for being the one to capture the fief, so marshals don't grab all the land. tl;dr it makes faction leaders a hell of a lot more reasonable and a lot less selfish when distributing fiefs. So far it works, I infinite camped for an ingame year and most of the faction leaders only had 1 town, maybe 1 or 2 castles here and there, and when the king's last fief was taken, they assigned themselves a new one. Pretty neat, huh? :grin:

Code:
# script_calculate_troop_score_for_center
  # Input: arg1 = troop_no, arg2 = center_no
  # Output: reg0 = score
  ("calculate_troop_score_for_center",
   [(store_script_param, ":troop_no", 1),
    (store_script_param, ":center_no", 2),
    (assign, ":num_center_points", 1),
	(assign, ":num_centers_owned", 0),
	(assign, ":num_walled_centers_owned", 0),
	(store_faction_of_troop, ":troop_faction", ":troop_no"),
	(faction_get_slot, ":faction_leader", ":troop_faction", slot_faction_leader),
    (try_for_range, ":cur_center", centers_begin, centers_end),
      (assign, ":center_owned", 0),
      (try_begin),
        (eq, ":troop_no", "trp_player"),
        (party_slot_eq, ":cur_center", slot_town_lord, stl_reserved_for_player),
        (assign, ":center_owned", 1),
      (try_end),
      (this_or_next|party_slot_eq, ":cur_center", slot_town_lord, ":troop_no"),
		(eq, ":center_owned", 1),
      (try_begin), # town
        (party_slot_eq, ":cur_center", slot_party_type, spt_town),
        (val_add, ":num_center_points", 20), # (used to be 3) center pts greatly increased for towns to avoid emergence of "super-lords" that control multiple towns and get ultra rich
		(val_add, ":num_centers_owned", 1),
		(val_add, ":num_walled_centers_owned", 1),
      (else_try), # castle
        (party_slot_eq, ":cur_center", slot_party_type, spt_castle),
        (val_add, ":num_center_points", 8), # used to be 2
		(val_add, ":num_centers_owned", 1),
		(val_add, ":num_walled_centers_owned", 1),
      (else_try), # village
        (val_add, ":num_center_points", 2), # used to be 1
		(val_add, ":num_centers_owned", 1),
      (try_end),
    (try_end),
    (troop_get_slot, ":troop_renown", ":troop_no", slot_troop_renown), # all of these checks are mutually exclusive, whichever one applies first, gets applied and no more
	(try_begin), # increase score for lords with no walled centers if fief is a castle
	  (eq, ":num_walled_centers_owned", 0),
	  (party_slot_eq, ":cur_center", slot_party_type, spt_castle),
	  (store_add, ":score", ":troop_renown", 1000), # castles get more renown boost over towns (wouldn't want to give a town to some random lord with little renown)
	(else_try), # very slightly increase score for lords with no walled centers if fief is a town
	  (eq, ":num_walled_centers_owned", 0),
	  (party_slot_eq, ":cur_center", slot_party_type, spt_town),
	  (store_add, ":score", ":troop_renown", 600), # walled center checks come before landless check to ensure walled centers are distributed equitably
	(else_try), # massively increase score for landless lords
	  (eq, ":num_centers_owned", 0),
	  (store_add, ":score", ":troop_renown", 2000), # landless check comes before faction leader check so if faction leader is fiefless it's almost certain they will give fief to themselves
	(else_try), # reduce score for faction leaders to prevent fief hogging
	  (eq, ":troop_no", ":faction_leader"),
	  (store_sub, ":score", ":troop_renown", 300), # faction leaders generally get ~1000 renown so this makes them less selfish (no more King Harlaus has decided to grant Sargoth to King Harlaus when there's 2 fiefless lords)
	(else_try), # landed lords still get a bonus
	  (store_add, ":score", ":troop_renown", 500),
    (try_end),
	(try_begin), # divide faction leader's score by 2 to make them even less selfish
	  (eq, ":troop_no", ":faction_leader"),
	  (val_div, ":score", 2),
    (try_end),
    (val_div, ":score", ":num_center_points"),
	(try_begin),
	  (ge, ":num_centers_owned", 1), # avoid dividing by 0
	  (val_div, ":score", ":num_centers_owned"), # new - divide score even further by flat number of centers owned to discourage lords hoarding villages and encourage equal distribution of fiefs
	(try_end),
    (store_random_in_range, ":random", 75, 100), # changed from 50-100 to 75-100 to make it more deterministic
	(try_begin), # don't get relation with self if faction leader
	  (neq, ":troop_no", ":faction_leader"),
	  (call_script, "script_troop_get_relation_with_troop", ":troop_no", ":faction_leader"),
	  (assign, ":leader_relation", reg0),
	  (val_mul, ":leader_relation", 1), # of course, faction leaders are human, so they will tend to give fiefs to lords they like and keep them from lords they dislike
	  (val_div, ":leader_relation", 10), # only 10% of relation with faction leader influences score to avoid faction leaders picking favorites and to let them give fiefs to unfriendly lords to build back relations
      (val_add, ":random", ":leader_relation"),
    (try_end),
    (val_mul, ":score", ":random"),
    (try_begin), # boost score if lord captured the center
      (party_slot_eq, ":center_no", slot_center_last_taken_by_troop, ":troop_no"),
      (val_mul, ":score", 12), # +20% score, down from +50% to prevent marshal from getting all the land
      (val_div, ":score", 10),
    (try_end),
    #(try_begin), # deprecated, relation with faction leader applied to ALL lords in above script
    #  (eq, ":troop_no", "trp_player"),
    #  (faction_get_slot, ":faction_leader", "$players_kingdom"),
    #  (call_script, "script_troop_get_player_relation", ":faction_leader"),
    #  (assign, ":leader_relation", reg0),
    #  #(troop_get_slot, ":leader_relation", ":faction_leader", slot_troop_player_relation),
    #  (val_mul, ":leader_relation", 2),
    #  (val_add, ":score", ":leader_relation"),
    #(try_end),
    (assign, reg0, ":score"),
    ]),
# You don't have to copy the examples, but it could help!
# Example: Swadia captures a castle (+8 center pts)
# King Harlaus has Praven and 2 villages (+24 center pts) and 1000 renown
# Count Ryis has a castle and a village (+10 center pts) and 600 renown AND captured the castle
# Count Grainwad has a village (+2 center pts) and 200 renown
#
## CALCULATIONS ##
# King Harlaus has a walled center, taking him to the -300 renown penalty for faction leaders
# Count Ryis has a walled center, taking him to the base +500 renown bonus
# Count Grainwad has no walled centers, and it's a castle, so he gets +1000 renown
# King Harlaus has 700 score, Count Ryis has 1100 score, Count Grainwad has 1200 score
#
# King Harlaus is the faction leader, so we divide his score by 2 (700/2=350 score)
# King Harlaus now has 350 score, Count Ryis has 1100 score, Count Grainwad has 1200 score
#
# Divide scores by center points (350/24=14.58) (1100/10=110) (1200/2=600)
# King Harlaus has 14.58 score, Count Ryis has 110 score, Count Grainwad has 600 score
#
# Divide scores by centers owned (14.58/3=4.86) (110/2=55) (600/1=600)
# King Harlaus has 4.86 score, Count Ryis has 55 score, Count Grainwad has 600 score
#
# Let's say Count Ryis has +20 relation with King Harlaus
# Let's say Count Grainwad has -50 relation with King Harlaus
#
# Count Grainwad's random score multiplier ranges from 0.7x to 0.95x
# Count Ryis's random score multiplier ranges from 0.77x to 1.02x
# King Harlaus's random score multiplier ranges from 0.75x to 1.00x because he's the faction leader so no changes
#
# Now we get the score ranges
# King Harlaus: 3.645-4.86
# Count Ryis: 42.35-56.1
# Count Grainwad: 420-570
#
# However, Count Ryis captured the castle, which multiplies his total score by 1.2x
# King Harlaus: 3.645-4.86
# Count Ryis: 50.82-67.32
# Count Grainwad: 420-570
#
# If these 3 were the only lords in the kingdom of Swadia, it's almost certain - no, absolutely certain, because it's proven by maths, that Count Grainwad would be granted the castle. It's fair, don't you think?

The above script also goes well with the one I edited for give_center_to_lord. It changes how much relations change between a king and a lord when the king gives the lord a fief depending on what type of fief it is. I've long detested how giving a village gave the same amount of relations as a town, and this changes that! Also, other lords will change their relations with their king more dramatically than before from a fief assignment to counterbalance the increase in relations per fief and to promote internal cliques.

Code:
# script_give_center_to_lord
  # Input: arg1 = center_no, arg2 = lord_troop, arg3 = add_garrison_to_center
  ("give_center_to_lord",
    [
      (store_script_param, ":center_no", 1),
      (store_script_param, ":lord_troop_id", 2), #-1 only in the case of a player deferring ownership of a center
      (store_script_param, ":add_garrison", 3),

	  (try_begin),
	    (eq, "$cheat_mode", 1),
		(ge, ":lord_troop_id", 0),
		(str_store_party_name, s4, ":center_no"),
		(str_store_troop_name, s5, ":lord_troop_id"),
		(display_message, "@{!}DEBUG -- {s4} awarded to {s5}"),
	  (try_end),
	  
	  (try_begin),
	    (eq, ":lord_troop_id", "trp_player"),
	    (unlock_achievement, ACHIEVEMENT_ROYALITY_PAYMENT),
	    
	    (assign, ":number_of_fiefs_player_have", 1),
	    (try_for_range, ":cur_center", centers_begin, centers_end),
	      (neq, ":cur_center", ":center_no"),
	      (party_slot_eq, ":cur_center", slot_town_lord, "trp_player"),
	      (val_add, ":number_of_fiefs_player_have", 1),
	    (try_end),
	    
	    (ge, ":number_of_fiefs_player_have", 5),
	    (unlock_achievement, ACHIEVEMENT_MEDIEVAL_EMLAK),	    
	  (try_end),
	  
      (party_get_slot, ":old_lord_troop_id", ":center_no", slot_town_lord),
      
	  (try_begin), #This script is ONLY called with lord_troop_id = -1 when it is the player faction 
	    (eq, ":lord_troop_id", -1),
	    (assign, ":lord_troop_faction", "fac_player_supporters_faction"),
        (party_set_banner_icon, ":center_no", 0),#Removing banner
		
      (else_try),	
	    (eq, ":lord_troop_id", "trp_player"),
	    (assign, ":lord_troop_faction", "$players_kingdom"), #was changed on Apr 27 from fac_plyr_sup_fac

      (else_try),	  
		(store_troop_faction, ":lord_troop_faction", ":lord_troop_id"),
	  (try_end),	
	  (faction_get_slot, ":faction_leader", ":lord_troop_faction", slot_faction_leader),

	  (try_begin),
	    (eq, ":faction_leader", "trp_player"),

        (try_begin),
            (troop_get_type, ":is_female", "trp_player"),
            (eq, ":is_female", 1),
            (unlock_achievement, ACHIEVEMENT_QUEEN),
        (try_end),
	  (try_end),
	  
	  (try_begin),
		(eq, ":faction_leader", ":old_lord_troop_id"),
		(call_script, "script_add_log_entry", logent_liege_grants_fief_to_vassal, ":faction_leader", ":center_no", ":lord_troop_id", ":lord_troop_faction"),
        (troop_set_slot, ":lord_troop_id", slot_troop_promised_fief, 0),		
	  (try_end),

      (try_begin),
	    (eq, ":lord_troop_id", -1), #Lord troop ID -1 is only used when a player is deferring assignment of a fief
        (party_set_faction, ":center_no", "$players_kingdom"),
	  (else_try),
        (eq, ":lord_troop_id", "trp_player"),
        (gt, "$players_kingdom", 0),
        (party_set_faction, ":center_no", "$players_kingdom"),
      (else_try),
        (eq, ":lord_troop_id", "trp_player"),
        (neg|is_between, "$players_kingdom", kingdoms_begin, kingdoms_end),
        (party_set_faction, ":center_no", "fac_player_supporters_faction"),
      (else_try),
        (party_set_faction, ":center_no", ":lord_troop_faction"),
      (try_end),
      (party_set_slot, ":center_no", slot_town_lord, ":lord_troop_id"),

      (try_begin),
        (party_slot_eq, ":center_no", slot_party_type, spt_village),
        (party_get_slot, ":farmer_party_no", ":center_no", slot_village_farmer_party),
        (gt, ":farmer_party_no", 0),
        (party_is_active, ":farmer_party_no"),
        (store_faction_of_party, ":center_faction", ":center_no"),
        (party_set_faction, ":farmer_party_no", ":center_faction"),
      (try_end),

    (try_begin),
        (this_or_next|party_slot_eq, ":center_no", slot_party_type, spt_town),
			(party_slot_eq, ":center_no", slot_party_type, spt_castle),
		(gt, ":lord_troop_id", -1),
		
#normal_banner_begin
        (troop_get_slot, ":cur_banner", ":lord_troop_id", slot_troop_banner_scene_prop),
        (gt, ":cur_banner", 0),
        (val_sub, ":cur_banner", banner_scene_props_begin),
        (val_add, ":cur_banner", banner_map_icons_begin),
        (party_set_banner_icon, ":center_no", ":cur_banner"),
# custom_banner_begin
#        (troop_get_slot, ":flag_icon", ":lord_troop_id", slot_troop_custom_banner_map_flag_type),
#        (ge, ":flag_icon", 0),
#        (val_add, ":flag_icon", custom_banner_map_icons_begin),
#        (party_set_banner_icon, ":center_no", ":flag_icon"),
    (try_end),

#    (try_begin),
#		(eq, 1, 0),
 #       (eq, ":lord_troop_id", "trp_player"),
 #       (neq, ":old_lord_troop_id", "trp_player"),
 #       (party_get_slot, ":center_relation", ":center_no", slot_center_player_relation),
 #       (is_between, ":center_relation", -4, 5),
 #       (call_script, "script_change_player_relation_with_center", ":center_no", 5),
 #       (gt, ":old_lord_troop_id", 0),
 #       (call_script, "script_change_player_relation_with_troop", ":old_lord_troop_id", -25),
 #   (try_end),
	(try_begin),
		(gt, ":lord_troop_id", -1),
		(call_script, "script_update_troop_notes", ":lord_troop_id"),
	(try_end),
	
    (call_script, "script_update_center_notes", ":center_no"),
    
    (try_begin),
      (gt, ":lord_troop_faction", 0),
      (call_script, "script_update_faction_notes", ":lord_troop_faction"),
    (try_end),  
    
    (try_begin),
        (ge, ":old_lord_troop_id", 0),
        (call_script, "script_update_troop_notes", ":old_lord_troop_id"),
        (store_troop_faction, ":old_lord_troop_faction", ":old_lord_troop_id"),
        (call_script, "script_update_faction_notes", ":old_lord_troop_faction"),
    (try_end),

    (try_begin),
        (eq, ":add_garrison", 1),
        (this_or_next|party_slot_eq, ":center_no", slot_party_type, spt_town),
			(party_slot_eq, ":center_no", slot_party_type, spt_castle),
        (assign, ":garrison_strength", 3), 
        (try_begin),
          (party_slot_eq, ":center_no", slot_party_type, spt_town),
          (assign, ":garrison_strength", 9),
        (try_end),
        (try_for_range, ":unused", 0, ":garrison_strength"),
          (call_script, "script_cf_reinforce_party", ":center_no"),
        (try_end),
        ## ADD some XP initially
        (try_for_range, ":unused", 0, 7),
          (store_mul, ":xp_range_min", 150, ":garrison_strength"),
          (store_mul, ":xp_range_max", 200, ":garrison_strength"),
          (store_random_in_range, ":xp", ":xp_range_min", ":xp_range_max"),
          (party_upgrade_with_xp, ":center_no", ":xp", 0),
        (try_end),
    (try_end),

	(faction_get_slot, ":faction_leader", ":lord_troop_faction", slot_faction_leader),
	(store_current_hours, ":hours"),
	
	#the next block handles gratitude, objections and jealousies; BELOW THIS PART ARE THE MAIN CHANGES I MADE TO THE SCRIPT
	(try_begin),
	  	(gt, ":hours", 0),
		(gt, ":lord_troop_id", 0), # lord_troop_id is the lord being granted the center
		# change gratitude based on fief type
	    (try_begin), # town
		  (party_slot_eq, ":center_no", slot_party_type, spt_town),
		  (call_script, "script_troop_change_relation_with_troop", ":lord_troop_id", ":faction_leader", 50),
		  (val_add, "$total_promotion_changes", 50), # total_promotion_changes measures how popular a fief deferment is within a faction 
	    (else_try), # castle
		  (party_slot_eq, ":center_no", slot_party_type, spt_castle),
		  (call_script, "script_troop_change_relation_with_troop", ":lord_troop_id", ":faction_leader", 30),
		  (val_add, "$total_promotion_changes", 30),
	    (else_try), # village
		  (call_script, "script_troop_change_relation_with_troop", ":lord_troop_id", ":faction_leader", 10),
		  (val_add, "$total_promotion_changes", 10), 
	  (try_end),
		
		#smaller factions are more dramatically influenced by internal jealousies
		#Disabled as of NOV 2010
#		(try_begin),
#			(neg|faction_slot_ge, ":lord_troop_faction", slot_faction_number_of_parties, 4),
#			(assign, ":faction_size_multiplier", 6),
#		(else_try),
#			(neg|faction_slot_ge, ":lord_troop_faction", slot_faction_number_of_parties, 8),
#			(assign, ":faction_size_multiplier", 5),
#		(else_try),
#			(neg|faction_slot_ge, ":lord_troop_faction", slot_faction_number_of_parties, 16),
#			(assign, ":faction_size_multiplier", 4),
#		(else_try),
#			(neg|faction_slot_ge, ":lord_troop_faction", slot_faction_number_of_parties, 32),
#			(assign, ":faction_size_multiplier", 3),
#		(else_try),	
#			(assign, ":faction_size_multiplier", 2),
#		(try_end),
		
		#factional politics -- each lord in the faction adjusts his relation according to the relation with the lord receiving the faction
		(try_for_range, ":other_lord", active_npcs_begin, active_npcs_end),
			(troop_slot_eq, ":other_lord", slot_troop_occupation, slto_kingdom_hero),
			(neq, ":other_lord", ":lord_troop_id"),
			
		    (store_troop_faction, ":other_troop_faction", ":other_lord"),
		    (eq, ":lord_troop_faction", ":other_troop_faction"),

		    (neq, ":other_lord", ":faction_leader"),
			
	        (call_script, "script_troop_get_relation_with_troop", ":other_lord", ":lord_troop_id"),
			(assign, ":relation_with_troop", reg0),

			#relation reduction = relation/4 minus 2. So,0 = -2, 8 = 0, 16 = +2, 24 = +4
		    (store_div, ":relation_with_liege_change", ":relation_with_troop", 4), #changed from 8
		    (val_sub, ":relation_with_liege_change", 2), # add some base ingratitude because center could've gone to self

		    (val_clamp, ":relation_with_liege_change", -10, 10),
			
			(try_begin),
				#upstanding and goodnatured lords will not lose relation unless they actively dislike the other lord and lose less relation even if center is given to disliked lord
				(this_or_next|troop_slot_eq, ":other_lord", slot_lord_reputation_type, lrep_upstanding),
					(troop_slot_eq, ":other_lord", slot_lord_reputation_type, lrep_goodnatured),
				(try_begin), # relation is at least 1 and liege relation change is negative
				  (ge, ":relation_with_troop", 0),
				  (lt, ":relation_with_liege_change", 0),
				  (val_max, ":relation_with_liege_change", 0),
				(try_end),
				(try_begin),
				  (lt, ":relation_with_liege_change", 0),
			  	  (val_mul, ":relation_with_liege_change", 2), # -33% relation loss
				  (val_div, ":relation_with_liege_change", 3),
				(try_end),
			(else_try),
				#penalty is increased for lords who have the more unpleasant reputation types
				(this_or_next|troop_slot_eq, ":other_lord", slot_lord_reputation_type, lrep_selfrighteous),
				(this_or_next|troop_slot_eq, ":other_lord", slot_lord_reputation_type, lrep_debauched),
					(troop_slot_eq, ":other_lord", slot_lord_reputation_type, lrep_quarrelsome),
				(lt, ":relation_with_liege_change", 0),
				(val_mul, ":relation_with_liege_change", 3), # +33% relation loss
				(val_div, ":relation_with_liege_change", 2),
			(try_end),

			
		    (neq, ":relation_with_liege_change", 0),
			#removed Nov 2010
#		  	(val_mul, ":relation_reduction", ":faction_size_multiplier"),
#		  	(val_div, ":relation_reduction", 2),
			#removed Nov 2010
			
			(try_begin),
				(troop_slot_eq, ":other_lord", slot_troop_stance_on_faction_issue, ":lord_troop_id"),
				(val_add, ":relation_with_liege_change", 1),
				(val_max, ":relation_with_liege_change", 1),
			(try_end),
			
 	        (call_script, "script_troop_change_relation_with_troop", ":other_lord", ":faction_leader", ":relation_with_liege_change"),
			(val_add, "$total_promotion_changes", ":relation_with_liege_change"),
			
		    (try_begin),
				(this_or_next|le, ":relation_with_liege_change", -8), #changed from -4 because clamp was changed from (-5 to +3) to (-10 to +10)
				(this_or_next|troop_slot_eq, ":other_lord", slot_troop_promised_fief, 1), #1 is any fief
					(troop_slot_eq, ":other_lord", slot_troop_promised_fief, ":center_no"), # Lord will feel cheated if fief was promised to them or given to someone they hate
				(call_script, "script_add_log_entry", logent_troop_feels_cheated_by_troop_over_land, ":other_lord", ":center_no", ":lord_troop_id", ":lord_troop_faction"),
		    (try_end),
		  
		(try_end),
	(try_end),
	
	#Villages from another faction will also be transferred along with a fortress
    (try_begin),
		(is_between, ":center_no", walled_centers_begin, walled_centers_end),
        (try_for_range, ":cur_village", villages_begin, villages_end),
			(party_slot_eq, ":cur_village", slot_village_bound_center, ":center_no"),
			(store_faction_of_party, ":cur_village_faction", ":cur_village"),
			(neq, ":cur_village_faction", ":lord_troop_faction"),
			
			(call_script, "script_give_center_to_lord", ":cur_village", ":lord_troop_id", 0),
        (try_end),
    (try_end),       
  ]),
 
Change the item(itm_arquebus) and constants "is_between"(thunder_braves_begin, thunder_braves_end) to the troops range you wish, same as "trp_thunder_brave", change it to your troop.
its basically a dialog to give a specific item to one of the troops you putted in the constants range, remove the talked troop and item, and add the new unit, you can expand it or modify to your needs(the "trp_thunder_brave"  is a custom troop, not connected to the troop trees in my case)-

Code:
# TheSwan Thunder braves begin
  [anyone|plyr,"regular_member_talk", [(player_has_item, "itm_arquebus"), (is_between,"$g_talk_troop",thunder_braves_begin, thunder_braves_end),], "I got some of those invaders fire thunders, take it, it will serve you well in battle.", "thunder_braves1",[]],
  [anyone|plyr, "thunder_braves2", [], "Here you can have it.", "close_window", [(party_remove_members,"p_main_party","$g_talk_troop", 1), (party_add_members, "p_main_party", "trp_thunder_brave", 1), (troop_remove_item, "trp_player", "itm_arquebus")]],
  [anyone|plyr, "thunder_braves2", [], "I change my mind.", "close_window", []],
  [anyone, "thunder_braves1", [], "Thank you, {sir/madam}.", "thunder_braves2", []],
# TheSwan Thunder braves end


In that code its basically giving that troop a gun(if you have it in your inventory), the custom troop there  (trp_thunder_brave) is similar troop to the talked troop you about to remove, only with a gun(can be any different gear you wish) so its kind of evolving you can say, this should be changed according to your desire
 
Dj_FRedy said:
Tired of crossing the hall so there's no interesting character to talk to?
Something similar happened to me and I wrote this script, feel free to use it.
To insert in menu "town" with the string {s16}
Code:
			#Who's in the hall? {s16} + Dj_FRedy
			(call_script, "script_whos_in_the_hall", "$current_town"),
			#Who's in the hall? - Dj_FRedy

Nice script. You have also to add {s16} to the town heading, I guess.
Code:
(
    "town",mnf_enable_hot_keys|mnf_scale_picture,
    "{s10} {s14}^{s11}{s12}{s13} {s16}",
    "none",
In Diplomacy it looks like that

20191012104713_1.jpg
 
Hello @Crysix
Of course you say well, 'some things'. This isn't much use if you don't provide 'fire arrows', or any particle code, which I think would be the most interesting thing to offer the rest of the modders. On the other hand, I would personally set the triggers in the corresponding mission templates, instead of making calls every 0.1 seconds constantly.
Also tell you that g_lco' are global corresponding to an @Lav's modification, you should specify it, not everyone has such a modification added, although it would be easy to explain where to define the variables within the system.
I hope I haven't been too punctilious with my comment.
 
Hey Dj_FRedy, the fire arrow item\model can be found in varied mods, for example there is in the-12th- mod, you can set the trigger where ever you want yes, but in simple triggers it work just fine, and yes i forgot its Lav global variables and addition.
 
Hello everyone,

I would like to share code that reduces enemy lords escape chance after defeat by 5% depending on each point given to prisoner management. Code has been approved by Dj_FRedy, so I share with you guys.  :party:

In Script "cf_check_hero_can_escape_from_player" search (lt, ":rand", hero_escape_after_defeat_chance), and replace with below.
Code:
	### BEGIN + REDUCING CHANCE OF LORD ESCAPE
		# (lt, ":rand", hero_escape_after_defeat_chance),
		(assign, ":escape_chance", 70),
		(try_begin),
			(store_skill_level, ":level", "skl_prisoner_management", "trp_player"),
			(val_mul, ":level", 5), # reducing 5%
			(val_sub, ":escape_chance", ":level"),
		(try_end),
		(lt, ":rand", ":escape_chance"),
	### END - REDUCING CHANCE OF LORD ESCAPE

Feel free to use and improve it.

Kind regards,
 
To be a lord in Calradia is not easy, although the high rank and privileges there are many dangerous and risks the lords put in order to serve their kingdom and ruler.

So to respect their efforts here is a code to pay them weekly, this code can be improved and values can be changed to meet your needs and will.

Start with the module_game_menus.py:
Add the small block(action_lords_weekly_payment) below the "action_walk_around"  from camp action,
Code:
 ("camp_action",0,
   "Choose an action:",
   "none",
   [
     ],
    [
      ("camp_recruit_prisoners",
       [(troops_can_join, 1),
        (store_current_hours, ":cur_time"),
        (val_sub, ":cur_time", 24),
        (gt, ":cur_time", "$g_prisoner_recruit_last_time"),
        (try_begin),
          (gt, "$g_prisoner_recruit_last_time", 0),
          (assign, "$g_prisoner_recruit_troop_id", 0),
          (assign, "$g_prisoner_recruit_size", 0),
          (assign, "$g_prisoner_recruit_last_time", 0),
        (try_end),
        ], "Recruit some of your prisoners to your party.",
       [(jump_to_menu, "mnu_camp_recruit_prisoners"),
        ],
       ),
      ("action_walk_around",[],"Walk around.",
       [(set_jump_mission,"mt_ai_training"),
        (call_script, "script_setup_random_scene"),
     (change_screen_mission)
        ]
       ),

("action_lords_weekly_payment",[(faction_slot_eq, "fac_player_supporters_faction", slot_faction_state, sfs_active)],"Set lords weekly payment.",
       [(jump_to_menu, "mnu_lords_weekly_payment"),
	    ]),

Now add this menu anywhere in module_game_menus.py:
Code:
  ("lords_weekly_payment",0,
   "Choose the weekly paymet of your lords.^{s24}^Current payment for each lord is {s2}",
   "none",
   [
       (assign, ":num_lords", 0),
       (try_for_parties, ":cur_party"),
       (store_faction_of_party, ":cur_faction", ":cur_party"),
       (eq, ":cur_faction", "fac_player_supporters_faction"),

       (try_begin),
       (party_slot_eq, ":cur_party", slot_party_type, spt_kingdom_hero_party),
       (val_add, ":num_lords", 1),
       (try_end),
       (try_end),

       (assign, reg60, ":num_lords"),
       (str_store_string, s24, "@Our kingdom currently have ({reg60}) lords."),

       (try_begin),
       (eq, "$lord_payment", 1),
       (str_store_string, s2, "@Very low(125 denars), -3 renown, -2 right to rule, -1 honor."),
       (else_try),
       (eq, "$lord_payment", 2),
       (str_store_string, s2, "@Low(200 denars), -2 renown, -1 right to rule."),
       (else_try),
       (eq, "$lord_payment", 3),
       (str_store_string, s2, "@Average(325 denars)."),
       (else_try),
       (eq, "$lord_payment", 4),
       (str_store_string, s2, "@High(450 denars), +2 renown, +2 right to rule."),
       (else_try),
       (eq, "$lord_payment", 5),
       (str_store_string, s2, "@Very high(600 denars), +2 renown, +2 right to rule, +1 honor."),
       (try_end),
       (try_end),
   ],
    [
      ("lords_weekly_payment1",[],"Very low weekly payment.",
       [
           (assign, "$lord_payment", 1),
        ]),
       ("lords_weekly_payment2", [], "Low weekly payment.",
        [
            (assign, "$lord_payment", 2),
        ]),
       ("lords_weekly_payment3", [], "Average weekly payment.",
        [
            (assign, "$lord_payment", 3),
        ]),
       ("lords_weekly_payment4", [], "High weekly payment.",
        [
            (assign, "$lord_payment", 4),
        ]),
       ("lords_weekly_payment5", [], "Very high weekly payment.",
        [
            (assign, "$lord_payment", 5),
        ]),

      ("camp_action_4",[],"Back to camp menu.",
       [(jump_to_menu, "mnu_camp"),
        ]
       ),
      ]
  ),

Last thing with the menus just assign the lord payment to 3(average), add to the first menu in the game "start_game_0",
Code:
 (assign, "$lord_payment", 3),

In the module_scripts.py just assign the the "$lord_payment" as global variable"(assign, "$lord_payment", 0),":
Code:
  ("lco_initialize_presentation",
        [

            (presentation_set_duration, 999999),
            (try_begin),
                (eq, "$g_lco_initialized", 0),
                (assign, "$g_lco_activate_troop", 0), # By default, we do not make a particular troop active
                (assign, "$g_lco_active_hero", 0),    # We show the first hero by default
                (assign, "$g_lco_page", 0),           # We show the first page by default
                (assign, "$g_lco_operation", 0),      # No special action by default
                (assign, "$g_lco_target", 0),         # No action target by default
                (assign, "$g_lco_auto_horses", 1),    # Horses are auto-equipped by default
                (assign, "$g_lco_auto_armors", 1),    # Same
                (assign, "$g_lco_auto_shields", 1),   # Same
                (assign, "$g_lco_include_companions", 1),
                (assign, "$g_lco_include_lords", 0),
                (assign, "$g_lco_include_regulars", 0),
                # BugFix V1.1. Do not overwrite $g_lco_garbage_troop on first run if it's already initialized.
                (try_begin),
                    (lt, "$g_lco_garbage_troop", 3),
                    (assign, "$g_lco_garbage_troop", lco_garbage), # This troop will be used for discarding items or looting, and it's inventory will be purged on exit
                (try_end),
                (assign, "$g_lco_initialized", 1),
                # BugFix V1.2. Hardcoded xp-to-level conversion table has been removed
            (try_end),

            # GLOBAL VARIABLES INITIALIZATION
            (assign, "$lord_payment", 0),              ###########>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>add this
            (assign, "$g_lco_heroes", 0),             # Total number of heroes in the party, excluding player
            (assign, "$g_lco_inv_slots", 0),          # Total number of slots in the player's inventory
            (assign, "$g_lco_dragging", 0),           # Currently not dragging anything
            (assign, "$g_lco_dragging_from", 0),      # Troop ID of dragged item current owner
            (assign, "$g_lco_dragging_from_slot", 0), # Slot ID of dragged item current owner
            (assign, "$g_lco_drag_item", -1),         # Item type currently being dragged
            (assign, "$g_lco_drag_modifier", 0),      # Modifier of item currently being dragged
lco_initialize_presentation(g_lco)' are global corresponding to an Lav's modification- https://forums.taleworlds.com/index.php/topic,189930.msg4545726.html#msg4545726

Last thing to add is the trigger in module_simple_triggers.py add this:
Code:
    (24 * 7,  #lords_weekly_payment
     [
         #check if the player kingdom is active and get the total number of lords in the player kingdom.
         (faction_slot_eq, "fac_player_supporters_faction", slot_faction_state, sfs_active),
         (assign, ":num_lords", 0),
         (try_for_parties, ":cur_party"),
         (store_faction_of_party, ":cur_faction", ":cur_party"),
         (try_begin),
         (eq, ":cur_faction", "fac_player_supporters_faction"),
         (party_slot_eq, ":cur_party", slot_party_type, spt_kingdom_hero_party),
         (val_add, ":num_lords", 1),
         (assign, reg60, ":num_lords"),
         (try_end),

         #check payment ranks that called from the camp action menu(default is 3, Average).
         (try_begin), # Very low.
         (eq, "$lord_payment", 1),
         (assign, ":payment_very_low", 125),
         (assign, reg61, ":payment_very_low"),
         (else_try), # Low.
         (eq, "$lord_payment", 2),
         (assign, ":payment_low", 200),
         (assign, reg61, ":payment_low"),
         (else_try), # Average.
         (eq, "$lord_payment", 3),
         (assign, ":payment_average", 325),
         (assign, reg61, ":payment_average"),
         (else_try), # High.
         (eq, "$lord_payment", 4),
         (assign, ":payment_high", 450),
         (assign, reg61, ":payment_high"),
         (else_try), # Very High.
         (eq, "$lord_payment", 5),
         (assign, ":payment_very_high", 600),
         (assign, reg61, ":payment_very_high"),
         (try_end),
         (try_end),
         #set the checked variables to their values.
         (try_begin),
         (eq, "$lord_payment", 1),
         (store_mul, ":payment_final", ":num_lords", ":payment_very_low"), # ":num_lords"= current faction lords, ":payment_very_low"(125), Current lords*125=":payment_final".
         (assign, ":renown", -3),
         (assign, ":right_to_rule", -2),
         (assign, ":honor", -1),
         (else_try),
         (eq, "$lord_payment", 2),
         (store_mul, ":payment_final", ":num_lords", ":payment_low"), # ":num_lords"= current faction lords, ":payment_low"(200), Current lords*200=":payment_final".
         (assign, ":renown", -2),
         (assign, ":right_to_rule", -1),
         (assign, ":honor", 0),
         (else_try),
         (eq, "$lord_payment", 3),
         (store_mul, ":payment_final", ":num_lords", ":payment_average"), # ":num_lords"= current faction lords, ":payment_average"(325), Current lords*325=":payment_final".
         (assign, ":renown", 0),
         (assign, ":right_to_rule", 0),
         (assign, ":honor", 0),
         (else_try),
         (eq, "$lord_payment", 4),
         (store_mul, ":payment_final", ":num_lords", ":payment_high"), # ":num_lords"= current faction lords, ":payment_high"(450), Current lords*450=":payment_final".
         (assign, ":renown", 2),
         (assign, ":right_to_rule", 2),
         (else_try),
         (eq, "$lord_payment", 5),
         (store_mul, ":payment_final", ":num_lords", ":payment_very_high"), # ":num_lords"= current faction lords, ":payment_very_high"(600), Current lords*600=":payment_final".
         (assign, ":renown", 3),
         (assign, ":right_to_rule", 2),
         (assign, ":honor", 1),
         (try_end),
         (try_end),
         (assign, reg62, ":payment_final"),

          #execute the values, first check the player treasury, if there is enough gold for the payment take from there(if not go to the next check) and the rank effects to the player(renown,right to rule,honor).
         (try_begin),
         (store_troop_gold, ":household_gold", "trp_household_possessions"),
         (lt, ":payment_final", ":household_gold"),
         (display_message,"@Our kingdom currently have ({reg60}) lords and each lord payment is ({reg61} denars) their weekly cost is ({reg62} denars).",0xFFD800),
         (troop_remove_gold, "trp_household_possessions", ":payment_final"),
         (call_script, "script_change_troop_renown", "trp_player", ":renown"),
         (call_script, "script_change_player_right_to_rule", ":right_to_rule"),
         (call_script, "script_change_player_honor", ":honor"),
        #execute the values, second check the player personal gold, if there is enough gold for the payment take from there and the rank effects to the player(renown,right to rule,honor).
         (else_try),
         (store_troop_gold, ":player_gold", "trp_player"),
         (lt, ":payment_final", ":player_gold"),
         (display_message,"@Our kingdom currently have ({reg60}) lords and each lord payment is ({reg61} denars) their weekly cost is ({reg62} denars).",0xFFD800),
         (troop_remove_gold, "trp_player", ":payment_final"),
         (call_script, "script_change_troop_renown", "trp_player", ":renown"),
         (call_script, "script_change_player_right_to_rule", ":right_to_rule"),
         (call_script, "script_change_player_honor", ":honor"),
         # execute the values, third check, in this point the treasury and the player dont have enough gold for the payment, not taking any gold from the player but decreasing the player relation with all his lords by 1.
         (else_try),
         (store_sub, ":difference", ":payment_final", ":player_gold"),
         (assign, reg63, ":difference"),
         (display_message,"@Our kingdom currently have ({reg60}) lords and each lord payment is ({reg61} denars) their weekly cost is ({reg62} denars), you needed more ({reg63} denars) to pay your lords.",0xFF0000),
         (display_message,"@The relation with all your lords decreased by 1.",0xFF0000),
         (try_for_range, ":lord", lords_begin, lords_end),
         (troop_slot_eq, ":lord", slot_troop_occupation, slto_kingdom_hero),
         (store_faction_of_troop, ":troop_faction", ":lord"),
         (eq, ":troop_faction", "$players_kingdom"),
         (set_show_messages, 0), # to avoid a lot of red lines in the left side of the screen.
         (call_script, "script_troop_change_relation_with_troop", ":lord", "trp_player", -1),
         (set_show_messages, 1),
         (try_end),
         (try_end),
     ]),
 
TheSwanFlamingArrows-
Updated.

This will let the agents to swap from normal arrows to flaming arrows or vice versa in the battlefield\any other mission with a key click,
The flaming arrows have more damage but slow reload and less accuracy than normal arrows,
The flaming arrows fire and smoke that will hit the target wont be sticky, so if it hit a horse it may be smoke in the air for a very short time,

Link to the custom sounds, textures and mesh will be at the end.

*This will swap the normal arrows(itm_arrow) to the flaming arrows, so make sure the archers have itm_arrow for this to effect them, or change it to any other arrow item(adjust according to your mod, this use native arrows).
*Only work for the ally agents, can be done small tweaks to make it also effect the agents from the enemy team, or any other operation that effect the enemy team use.
*Adding the grenade script.

First sounds, add those in module_sounds.py:
Code:
    ("order_arrow_fire", sf_2d | sf_priority_10 | sf_vol_10, ["Group_State_Flaming_On_2.wav"]),
    ("order_arrow_normal", sf_2d | sf_priority_10 | sf_vol_10, ["Group_State_Flaming_Off_1.wav"]),

Add the "script_create_explosion" in the module_scripts.py:
Code:
#script_create_explosion
  #Input: grenadier, damage min, damage max, explosion radius,
  #Output: none
  #NOTE: If creating an explosion outside of weapon triggers, store the location in pos1
  ("create_explosion", [

     (store_script_param, ":grenadier", 1),
     (store_script_param, ":damageMin", 2),
     (store_script_param, ":damageMax", 3),
     (store_script_param, ":radius", 4),
       (particle_system_burst,"psys_pistol_smoke",pos1,5),
        (particle_system_burst,"psys_fireplace_fire_small",pos1,60),
          (try_for_agents,":target"),

            (agent_is_alive, ":target"),
            (agent_is_active, ":target"),
            (agent_get_team, ":grenadiers_team", ":grenadier"),
            (agent_get_team, ":targets_team", ":target"),
            (teams_are_enemies, ":grenadiers_team", ":targets_team"),

            (agent_get_position,pos2,":target"),
            (get_distance_between_positions,":dist",pos1,pos2),
       (try_begin),
               (lt,":dist", ":radius"),
               (store_agent_hit_points,":hp",":target",10),
      (store_random_in_range,":dmg", ":damageMin", ":damageMax"),
      (val_sub,":hp",":dmg"),
      (try_begin),
       (lt, ":hp", 0),
        #if you want to play a custom animation for explosive deaths, put it here.
        #(agent_set_animation, ":target", "anim_explosion_death"),
       (try_end),
      (agent_deliver_damage_to_agent,":grenadier",":target", ":dmg"),
       (try_end),
        (try_end)
  ]),

Add the flaming arrows items in the module_items.py:
Code:
#(if you dont want them in the market just remove the "itp_merchandise")
#normal arrows.
["flaming_arrows", "Flaming Arrows", [("arrow", 0), ("huojian_fly", ixmesh_flying_ammo),("quiver", ixmesh_carry)],
itp_type_arrows | itp_merchandise | itp_default_ammo, itcf_carry_quiver_back, 72,
weight(4) | difficulty(0) | spd_rtng(85) | shoot_speed(30) | thrust_damage(1, blunt) | max_ammo(30) | weapon_length(
     95), imodbits_missile, [(ti_on_missile_hit, [
    (store_trigger_param_1, ":grenadier"),
    # GRENADE STATS
    (assign, ":damageMin", 60),
    (assign, ":damageMax", 100),
    (assign, ":radius", 125),
    (call_script, "script_create_explosion", ":grenadier", ":damageMin", ":damageMax", ":radius"),])]],

#khergit arrows.
["flaming_khergit_arrows", "Flaming Khergit Arrows",
[("arrow_b", 0), ("huojian_fly", ixmesh_flying_ammo), ("quiver_b", ixmesh_carry)],itp_type_arrows | itp_merchandise | itp_default_ammo, itcf_carry_quiver_back_right, 410,weight(4) | difficulty(0) | spd_rtng(85) | shoot_speed(30) | thrust_damage(6, blunt) | max_ammo(34) | weapon_length(95), imodbits_missile, [(ti_on_missile_hit, [
    (store_trigger_param_1, ":grenadier"),
    # GRENADE STATS
    (assign, ":damageMin", 60),
    (assign, ":damageMax", 100),
    (assign, ":radius", 125),
    (call_script, "script_create_explosion", ":grenadier", ":damageMin", ":damageMax", ":radius"),
])]],

#barbed arrows.
["flaming_barbed_arrows", "Flaming Barbed Arrows",
[("barbed_arrow", 0), ("huojian_fly", ixmesh_flying_ammo), ("quiver_d", ixmesh_carry)],
itp_type_arrows | itp_merchandise | itp_default_ammo, itcf_carry_quiver_back_right, 72,
weight(4) | difficulty(0) | spd_rtng(85) | shoot_speed(30) | thrust_damage(1, blunt) | max_ammo(
     30) | weapon_length(
     95), imodbits_missile, [(ti_on_missile_hit, [
    (store_trigger_param_1, ":grenadier"),
    # GRENADE STATS
    (assign, ":damageMin", 60),
    (assign, ":damageMax", 100),
    (assign, ":radius", 125),
    (call_script, "script_create_explosion", ":grenadier", ":damageMin", ":damageMax", ":radius"),
])]],

#bodkin arrows.
["flaming_bodkin_arrows", "Flaming Bodkin Arrows", [("piercing_arrow", 0), ("huojian_fly", ixmesh_flying_ammo), ("quiver_c", ixmesh_carry)],
itp_type_arrows | itp_merchandise | itp_default_ammo, itcf_carry_quiver_back_right, 72,
weight(4) | difficulty(0) | spd_rtng(85) | shoot_speed(30) | thrust_damage(1, blunt) | max_ammo(
     30) | weapon_length(
     95), imodbits_missile, [(ti_on_missile_hit, [
    (store_trigger_param_1, ":grenadier"),
    # GRENADE STATS
    (assign, ":damageMin", 60),
    (assign, ":damageMax", 100),
    (assign, ":radius", 125),
    (call_script, "script_create_explosion", ":grenadier", ":damageMin", ":damageMax", ":radius"),
])]],


Add at the top of module_mission_templates.py:
Code:
the_swan_flaming_arrows_use_fire = (
   0.0, 0, 0, [], [

       (try_begin),
       (key_clicked, key_t), #change to any key you want
       (try_for_agents, ":cur_agent"),
       (get_player_agent_no, ":player"),
       (agent_get_team, ":player_team", ":player"),
       (agent_is_alive, ":cur_agent"),
       (agent_is_human, ":cur_agent"),
       (agent_is_non_player, ":cur_agent"),
       (agent_get_team, ":cur_team", ":cur_agent"),
       (eq, ":cur_team", ":player_team"),
(agent_get_ammo, ":destination", ":cur_agent", 1),
       (try_begin),
       (agent_has_item_equipped, ":cur_agent", "itm_arrows"),
  (agent_unequip_item, ":cur_agent", "itm_arrows"),
       (agent_equip_item, ":cur_agent", "itm_flaming_arrows"),
  (agent_set_wielded_item, ":cur_agent", "itm_flaming_arrows"),
(agent_set_ammo, ":cur_agent", "itm_flaming_arrows",":destination"),
       (else_try),
       (agent_has_item_equipped, ":cur_agent", "itm_barbed_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_barbed_arrows"),
       (agent_equip_item, ":cur_agent", "itm_flaming_barbed_arrows"),
  (agent_set_wielded_item, ":cur_agent", "itm_flaming_barbed_arrows"),
(agent_set_ammo, ":cur_agent", "itm_flaming_barbed_arrows",":destination"),
       (else_try),
       (agent_has_item_equipped, ":cur_agent", "itm_bodkin_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_bodkin_arrows"),
       (agent_equip_item, ":cur_agent", "itm_flaming_bodkin_arrows"),
  (agent_set_wielded_item, ":cur_agent", "itm_flaming_bodkin_arrows"),
(agent_set_ammo, ":cur_agent", "itm_flaming_bodkin_arrows",":destination"),
       (else_try),
       (agent_has_item_equipped, ":cur_agent", "itm_khergit_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_khergit_arrows"),
       (agent_equip_item, ":cur_agent", "itm_flaming_khergit_arrows"),
  (agent_set_wielded_item, ":cur_agent", "itm_flaming_khergit_arrows"),
(agent_set_ammo, ":cur_agent", "itm_flaming_khergit_arrows",":destination"),
       (end_try),
       (agent_set_ranged_damage_modifier, ":cur_agent", 165), #adjust fire arrow wielding agent stats according to your liking
       (agent_set_accuracy_modifier, ":cur_agent", 85), #adjust fire arrow wielding agent stats according to your liking
       (agent_set_reload_speed_modifier, ":cur_agent", 70), #adjust fire arrow wielding agent stats according to your liking
       (end_try),
       (display_message, "@Units, use fire!"),
       (agent_play_sound, ":player", "snd_order_arrow_fire"),
   ])
the_swan_flaming_arrows_extinguish_flames = (
   0.0, 0, 0, [], [
  (try_begin),
       (key_clicked, key_u), #get clicked key to active
       (try_for_agents, ":cur_agent"),
       (get_player_agent_no, ":player"),
       (agent_get_team, ":player_team", ":player"),
       (agent_is_alive, ":cur_agent"),
       (agent_is_human, ":cur_agent"),
       (agent_is_non_player, ":cur_agent"),
       (agent_get_class, ":agent_class", ":cur_agent"),
(neq, ":agent_class", grc_infantry), #not infnatry
       (agent_get_team, ":cur_team", ":cur_agent"),
       (eq, ":cur_team", ":player_team"),
       #  (agent_get_class, ":agent_class", ":cur_agent"),
       (agent_get_ammo, ":destination", ":cur_agent", 1),
       (try_begin),
       (agent_has_item_equipped, ":cur_agent", "itm_flaming_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_flaming_arrows"),
       (agent_equip_item, ":cur_agent", "itm_arrows"),
       (agent_set_wielded_item, ":cur_agent", "itm_arrows"),
       (agent_set_ammo, ":cur_agent", "itm_arrows", ":destination"),
       (else_try),
       (agent_has_item_equipped, ":cur_agent", "itm_flaming_barbed_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_flaming_barbed_arrows"),
       (agent_equip_item, ":cur_agent", "itm_barbed_arrows"),
       (agent_set_wielded_item, ":cur_agent", "itm_barbed_arrows"),
       (agent_set_ammo, ":cur_agent", "itm_barbed_arrows", ":destination"),
       (else_try),
       (agent_has_item_equipped, ":cur_agent", "itm_flaming_bodkin_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_flaming_bodkin_arrows"),
       (agent_equip_item, ":cur_agent", "itm_bodkin_arrows"),
       (agent_set_wielded_item, ":cur_agent", "itm_bodkin_arrows"),
       (agent_set_ammo, ":cur_agent", "itm_bodkin_arrows", ":destination"),
       (else_try),
       (agent_has_item_equipped, ":cur_agent", "itm_flaming_khergit_arrows"),
       (agent_unequip_item, ":cur_agent", "itm_flaming_khergit_arrows"),
       (agent_equip_item, ":cur_agent", "itm_khergit_arrows"),
       (agent_set_wielded_item, ":cur_agent", "itm_khergit_arrows"),
       (agent_set_ammo, ":cur_agent", "itm_khergit_arrows", ":destination"),
       (end_try),

       (agent_set_ranged_damage_modifier, ":cur_agent", 100),
       (agent_set_accuracy_modifier, ":cur_agent", 100),
       (agent_set_reload_speed_modifier, ":cur_agent", 100),
       (end_try),
       (display_message, "@Units, extinguish flames."),
       (agent_play_sound, ":player", "snd_order_arrow_normal"),
   ])

Final thing is to add those to any mission you want this to be available:
Code:
the_swan_flaming_arrows_use_fire,
the_swan_flaming_arrows_extinguish_flames,
(technically anywhere with "common_battle_tab_press,")

Link to the custom sounds, textures and mesh: https://www.dropbox.com/s/nutv3r6r5ebsij1/TheSwanFlamingArrows.rar?dl=0
 
Last edited:
I got a script which makes it so that farmer parties spawn with localized low-level troops, so a group of villagers from an originally Swadian village will get a few Swadian recruits and militia regardless of whoever controls the attached town/castle. It's mostly been taken from the script that spawns kingdom caravan parties, but it works well enough. If you want to edit the kinds of troops that spawn in the reinforcement templates, go to module_party_templates.py, anyways, here it is:
DMYwdgn.png

It's running on a modded game, but it still works, you can't do this with just morgh's editor (it has 6 slots i believe)
Code:
# script_create_village_farmer_party
  # Input: arg1 = village_no
  # Output: reg0 = party_no
  ("create_village_farmer_party",
   [(store_script_param, ":village_no", 1),
    (party_get_slot, ":town_no", ":village_no", slot_village_market_town),
    (store_faction_of_party, ":party_faction", ":town_no"),
    (faction_get_slot, ":reinforcements_a", ":party_faction", slot_faction_reinforcements_a), # get template from owner faction just in case something screws up
##    (faction_get_slot, ":reinforcements_b", ":party_faction", slot_faction_reinforcements_b), # you can insert stronger units if you want, a is weakest, b is medium, c is strongest
##    (faction_get_slot, ":reinforcements_c", ":party_faction", slot_faction_reinforcements_c),
	
#    (store_faction_of_party, ":town_faction", ":town_no"),
#    (try_begin),
#		(neq, ":town_faction", ":party_faction"),
#		(assign, ":town_no", -1),
#		(assign, ":score_to_beat", 9999),
#		(try_for_range, ":other_town", towns_begin, towns_end),
#			(store_faction_of_party, ":other_town_faction", ":town_no"),
#			(store_relation, ":relation", ":other_town_faction", ":party_faction"),
#			(ge, ":relation", 0),
			
#			(store_distance_to_party_from_party, ":distance", ":village_no", ":other_town"),
#			(lt, ":distance", ":score_to_beat"),
#			(assign, ":town_no", ":other_town"),
#			(assign, ":score_to_beat", ":distance"),
#		(try_end),
#	(try_end),
	
	(try_begin),
		(is_between, ":town_no", towns_begin, towns_end),
	    (set_spawn_radius, 0),
	    (spawn_around_party, ":village_no", "pt_village_farmers"),
	    (assign, ":new_party", reg0),
	      
	    (party_set_faction, ":new_party", ":party_faction"),
	    (party_set_slot, ":new_party", slot_party_home_center, ":village_no"),
	    (party_set_slot, ":new_party", slot_party_last_traded_center, ":village_no"),

	    (party_set_slot, ":new_party", slot_party_type, spt_village_farmer),
	    (party_set_slot, ":new_party", slot_party_ai_state, spai_trading_with_town),
	    (party_set_slot, ":new_party", slot_party_ai_object, ":town_no"),
		#(store_faction_of_party, ":village_faction", ":village_no"),
		#(try_begin),
		#  (eq, ":village_faction", "fac_player_supporters_faction"),
		(party_get_slot, ":reinforcement_faction", ":village_no", slot_center_original_faction), # Script changed to make farmer troops local based on their village
		(faction_get_slot, ":reinforcements_a", ":reinforcement_faction", slot_faction_reinforcements_a),
	    #(try_end),
	    (party_add_template, ":new_party", ":reinforcements_a"), #1 peasant/militia template
#		(party_add_template, ":new_party", ":reinforcements_a"), #you can add multiple if you want, just uncomment and copy and paste
	    (party_set_ai_behavior, ":new_party", ai_bhvr_travel_to_party),
	    (party_set_ai_object, ":new_party", ":town_no"),
	    (party_set_flags, ":new_party", pf_default_behavior, 0),
	    (store_sub, ":item_to_price_slot", slot_town_trade_good_prices_begin, trade_goods_begin),
	    (try_for_range, ":cur_goods", trade_goods_begin, trade_goods_end),
	      (store_add, ":cur_good_price_slot", ":cur_goods", ":item_to_price_slot"),
	      (party_get_slot, ":cur_village_price", ":village_no", ":cur_good_price_slot"),
	      (party_set_slot, ":new_party", ":cur_good_price_slot", ":cur_village_price"),
	    (try_end),
	    (assign, reg0, ":new_party"),
	(try_end),

#	(try_begin), # Template for reinforcements from caravan script, not actually part of the farmer party script but you can see how it works
#	  (eq, ":party_type", spt_kingdom_caravan),
#	  (try_begin),
#		(eq, ":faction_no", "fac_player_supporters_faction"),
#		(party_get_slot, ":reinforcement_faction", ":spawn_center", slot_center_original_faction),
#		(faction_get_slot, ":reinforcements_b", ":reinforcement_faction", slot_faction_reinforcements_b),
#	  (try_end),
#	  (party_add_template, ":result", ":reinforcements_b"),
#	  (party_add_template, ":result", ":reinforcements_b"),
#	  (party_set_ai_behavior,":result",ai_bhvr_travel_to_party),
#	  (party_set_ai_object,":result",":spawn_center"),
#	  (party_set_flags, ":result", pf_default_behavior, 1),
#	  (store_sub, ":item_to_price_slot", slot_town_trade_good_prices_begin, trade_goods_begin),
#	  (try_for_range, ":cur_goods", trade_goods_begin, trade_goods_end),
#		(store_add, ":cur_goods_price_slot", ":cur_goods", ":item_to_price_slot"),
#		(party_set_slot, ":result", ":cur_goods_price_slot", average_price_factor),
#	  (try_end),
#	(try_end),
	
    ]),
This does mean that Khergit villager parties are going to be faster, but that fits in well with their theme, right? :grin:
 
TheSwan bodyguard troops

Small code that cause lords that stay/rest in a fief to replenish bodyguard troops each day(or how often you want).


(in module_constants.py):
Code:
######TheSwan bodyguard troops
slot_faction_bodyguard_troop = 480
######TheSwan bodyguard troops

(in module_troops.py)(can define the bodyguard as any other troop you wish):
Code:
######TheSwan bodyguard troops
["swadian_bodyguard","Swadian Retainer","Swadian Retainers",tf_mounted|tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_gloves|tf_guarantee_helmet|tf_guarantee_horse|tf_guarantee_shield,0,0,fac_kingdom_1,
[itm_heavy_lance,itm_sword_two_handed_b,itm_sword_medieval_d_long,itm_morningstar,itm_morningstar,itm_sword_medieval_d_long,itm_tab_shield_heater_cav_b,
  itm_coat_of_plates_red,itm_cuir_bouilli,itm_plate_boots,itm_guard_helmet,itm_great_helmet,itm_bascinet,itm_charger,itm_warhorse,itm_gauntlets,itm_mail_mittens],
def_attrib|level(28),wp_one_handed (150) | wp_two_handed (130) | wp_polearm (130) | wp_archery (75) | wp_crossbow (75) | wp_throwing (75),knows_common|knows_riding_5|knows_shield_5|knows_ironflesh_5|knows_power_strike_5,swadian_face_middle_1, swadian_face_older_2],

["vaegir_bodyguard","Vaegir Retainer","Vaegir Retainer",tf_mounted|tf_guarantee_shield|tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_helmet,0,0,fac_kingdom_2,
[itm_ashwood_pike,itm_fighting_axe,itm_bardiche,itm_battle_axe,itm_fighting_axe,itm_tab_shield_kite_d,
  itm_banded_armor,itm_lamellar_vest,itm_lamellar_armor,itm_mail_chausses,itm_iron_greaves,itm_vaegir_war_helmet,itm_vaegir_war_helmet,itm_vaegir_lamellar_helmet,itm_leather_gloves],
def_attrib|level(24),wp_melee(130),knows_riding_2|knows_athletics_4|knows_shield_2|knows_ironflesh_3|knows_power_strike_4,vaegir_face_middle_1, vaegir_face_older_2],


["khergit_bodyguard","Khergit Retainer","Khergit Retainers",tf_mounted|tf_guarantee_all_wo_ranged,0,0,fac_kingdom_3,
[itm_sword_khergit_4,itm_spiked_mace,itm_one_handed_war_axe_b,itm_hafted_blade_a,itm_hafted_blade_b,itm_heavy_lance,itm_lance,
  itm_khergit_guard_helmet,itm_khergit_cavalry_helmet,itm_khergit_war_helmet,itm_lamellar_vest_khergit,itm_lamellar_armor,itm_khergit_leather_boots,itm_splinted_leather_greaves,itm_leather_gloves,itm_scale_gauntlets,itm_tab_shield_small_round_b,itm_tab_shield_small_round_c,itm_courser,itm_warhorse_steppe,itm_warhorse_steppe,itm_warhorse_steppe],
def_attrib|level(23),wp_one_handed (110) | wp_two_handed (110) | wp_polearm (150) | wp_archery (110) | wp_crossbow (110) | wp_throwing (110),knows_riding_7|knows_power_strike_4|knows_power_draw_4|knows_power_throw_2|knows_ironflesh_4|knows_horse_archery_1|knows_shield_2,khergit_face_middle_1, khergit_face_older_2],


["nord_bodyguard","Nord Retainer","Nord Retainers",tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_shield|tf_guarantee_helmet,0,0,fac_kingdom_4,
[itm_sword_viking_3,itm_sword_viking_3_small,itm_great_axe,itm_one_handed_battle_axe_c,itm_tab_shield_round_e,itm_throwing_spears,itm_heavy_throwing_axes,itm_heavy_throwing_axes,
  itm_nordic_huscarl_helmet,itm_nordic_warlord_helmet,itm_banded_armor,itm_mail_boots,itm_mail_chausses,itm_mail_mittens],
def_attrib|level(28),wp(170),knows_ironflesh_7|knows_power_strike_7|knows_power_throw_5|knows_riding_2|knows_athletics_7|knows_shield_6,nord_face_middle_1, nord_face_older_2],

["rhodok_bodyguard","Rhodok Retainer","Rhodok Retainers",tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_helmet|tf_guarantee_shield|tf_guarantee_gloves,0,0,fac_kingdom_5,
[itm_glaive,itm_military_hammer,itm_military_cleaver_c,itm_tab_shield_pavise_d,
  itm_full_helm, itm_bascinet_3,itm_bascinet_2,itm_surcoat_over_mail,itm_surcoat_over_mail,itm_heraldic_mail_with_surcoat,itm_mail_chausses,itm_leather_gloves,itm_mail_mittens],
def_attrib|level(25),wp_one_handed (130) | wp_two_handed (115) | wp_polearm (155) | wp_archery (115) | wp_crossbow (115) | wp_throwing (115),knows_common|knows_ironflesh_6|knows_shield_5|knows_power_strike_5|knows_athletics_5,rhodok_face_middle_1, rhodok_face_older_2],


["sarranid_bodyguard","Sarranid Retainer","Sarranid Retainers",tf_mounted|tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_gloves|tf_guarantee_helmet|tf_guarantee_horse|tf_guarantee_shield,0,0,fac_kingdom_6,
  [itm_heavy_lance,itm_scimitar_b,itm_sarranid_two_handed_mace_1,itm_sarranid_cavalry_sword,itm_tab_shield_small_round_c,
   itm_mamluke_mail,itm_sarranid_boots_d,itm_sarranid_boots_c,itm_sarranid_veiled_helmet,itm_arabian_horse_b,itm_warhorse_sarranid,itm_scale_gauntlets,itm_mail_mittens],
  def_attrib|level(27),wp_one_handed (150) | wp_two_handed (130) | wp_polearm (130) | wp_archery (75) | wp_crossbow (75) | wp_throwing (110),knows_common|knows_riding_6|knows_shield_5|knows_ironflesh_5|knows_power_strike_5,swadian_face_middle_1, swadian_face_older_2],

["player_faction_bodyguard","Retainer","Retainers",tf_mounted|tf_guarantee_helmet|tf_guarantee_armor|tf_guarantee_boots|tf_guarantee_shield|tf_guarantee_gloves|tf_guarantee_horse,0,0,fac_player_supporters_faction,[itm_heavy_lance, itm_bastard_sword_b, itm_sword_medieval_d_long, itm_tab_shield_heater_cav_b, itm_tab_shield_kite_cav_b, itm_tab_shield_small_round_c, itm_winged_great_helmet, itm_great_helmet, itm_heraldic_mail_with_tunic, itm_heraldic_mail_with_tunic_b, itm_plate_boots, itm_gauntlets, itm_charger, itm_warhorse],def_attrib|level(28),wp(150),knows_ironflesh_5|knows_power_strike_5|knows_shield_5|knows_riding_5|knows_athletics_2,mercenary_face_1, mercenary_face_2],
######TheSwan bodyguard troops

(the following Spoiler put in module_scripts.py in the "game_start" script in the top of the file ):
Code:
######TheSwan bodyguard troops
      (faction_set_slot, "fac_kingdom_1", slot_faction_bodyguard_troop, "trp_swadian_bodyguard"),
      (faction_set_slot, "fac_kingdom_2", slot_faction_bodyguard_troop, "trp_vaegir_bodyguard"),
      (faction_set_slot, "fac_kingdom_3", slot_faction_bodyguard_troop, "trp_khergit_bodyguard"),
      (faction_set_slot, "fac_kingdom_4", slot_faction_bodyguard_troop, "trp_nord_bodyguard"),
      (faction_set_slot, "fac_kingdom_5", slot_faction_bodyguard_troop, "trp_rhodok_bodyguard"),
      (faction_set_slot, "fac_kingdom_6", slot_faction_bodyguard_troop, "trp_sarranid_bodyguard"),
      (faction_set_slot, "fac_player_supporters_faction", slot_faction_bodyguard_troop, "trp_player_faction_bodyguard"),
######TheSwan bodyguard troops

In the following script the limit per party is 20 bodyguards(can be changed) and the thing that effect it is the policy of that faction(aristocracy)
that provided by the Diplomacy mod, if you dont use/dont have it, comment out(#) the lines from
"(faction_get_slot, ":aristocraty", ":cur_faction", dplmc_slot_faction_aristocracy)," include and instead put
"(try_begin),
(assign, ":limit", 20,),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(try_end),"
And if you want put any other limitations.

(in module_script.py)(new script put at the end of the file):
Code:
######TheSwan bodyguard troops
("theswan_bodyguard_troops",
[
(try_for_range, ":lord_no", active_npcs_begin, active_npcs_end),
(troop_slot_eq, ":lord_no", slot_troop_occupation, slto_kingdom_hero),
(neg|troop_slot_ge, ":lord_no", slot_troop_prisoner_of_party, 0),
(troop_get_slot, ":party", ":lord_no", slot_troop_leaded_party),
(party_is_active, ":party"),
(gt, ":party", 0),
(store_faction_of_party, ":cur_faction", ":party"),
(party_get_attached_to, ":lord_attachment", ":party"),
(is_between, ":lord_attachment", centers_begin, centers_end),
(faction_get_slot, ":troop_bodyguard", ":cur_faction", slot_faction_bodyguard_troop),
(party_count_members_of_type, ":count", ":party", ":troop_bodyguard"),
(faction_get_slot, ":aristocraty", ":cur_faction", dplmc_slot_faction_aristocracy),
(try_begin),
(assign, ":limit", 20,),
(eq, ":aristocraty", 3),
(val_add, ":limit", 12),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(else_try),
(eq, ":aristocraty", 2),
(val_add, ":limit", 8),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(else_try),
(eq, ":aristocraty", 1),
(val_add, ":limit", 4),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(else_try),
(eq, ":aristocraty", 0),
(val_add, ":limit", 0),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(else_try),
(eq, ":aristocraty", -1),
(val_sub, ":limit", 4),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(else_try),
(eq, ":aristocraty", -2),
(val_sub, ":limit", 8),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(else_try),
(eq, ":aristocraty", -3),
(val_sub, ":limit", 12),
(lt, ":count", ":limit"),
(party_add_members, ":party", ":troop_bodyguard", 1),
(try_end),
  (try_end),
        ]
    ),
######TheSwan bodyguard troops

(in module_simple_triggers.py):
Code:
######TheSwan bodyguard troops
(24,
[
     (call_script, "script_theswan_bodyguard_troops"),
]),
######TheSwan bodyguard troops
 
Last edited:
TheSwan Reforged Blacksmith

This blacksmith menu is improved version of the original made by Jinnai,
the original menu let you repair items, i added an option also to upgrade their modifier and increased the denar cost of those actions.


The code is too long to be posted here so there is a viewing/download link that contain the code and instructions below.



 
Double (or singular, enhanced) Jump (without any new animations)
Concept: Make any agent be able to double jump without any new animation work or jerkiness.


Python:
slot_agent_is_double_jumping = 8 # Tweak slot number to any open slot

Python:
# Replace unused_human_anim with these
# Not 100% necessary, but it will stop your agents from spamjumping into the atmosphere.

["double_jump", acf_enforce_lowerbody|acf_displace_position, amf_priority_jump|amf_play|amf_client_prediction|amf_continue_to_next,
   [1.0, "jump", 22, 46, arf_blend_in_1],
],
["double_jump_loop", acf_enforce_lowerbody, amf_priority_jump|amf_play|amf_client_prediction,
   [0.5, "jump_loop", 0, 14, arf_blend_in_3|arf_cyclic],

Python:
double_jump = (
     0, 0, 0, [],
    [
    (set_fixed_point_multiplier, 100),
    (get_player_agent_no, ":agent"),         # Who is the player
    (agent_get_position, pos0, ":agent"),     # Where is the player
    (agent_get_animation, ":animation", ":agent", 0), # What are their legs doing?
    (agent_get_slot, ":double_jump", ":agent", slot_agent_is_double_jumping), # Are they double-jumping?

    # This is if you want to add more forward momentum at the start of the double jump
    # (agent_get_speed, pos2, ":agent"),        # Get the agent's speed
    # (position_get_y, ":forward_momentum", pos2), # What is their speed in decimeters/sec on their local Y (-Y = backwards, +Y = forwards)
    # (val_div, ":forward_momentum", 100),            # To shrink the speed to their per frame speed
    # 1/2 the Z value also feels fine, but it might annoy players to have a "fixed" arc

    (try_begin),
        (key_clicked, key_space),             # If the player pressed space this frame
        (this_or_next|eq, ":animation", "anim_jump"), # And they were already jumping
        (eq, ":animation", "anim_jump_loop"), # or in middle of a jump
        (val_add, ":double_jump", 50),           # storing the amount of time, in centiseconds, you want to add motion to. 0.5 seconds seems to line up perfectly with the upwards portion of a jump
        (agent_set_animation, ":agent", "anim_double_jump", 0), # And change their animation to the double_jump
# (else_try), # Uncomment this to make a boosted normal jump
      # (key_clicked, key_space),
      #  (neq, ":animation", "anim_jump"), # And they aren't already jumping
      #  (neq, ":animation", "anim_jump_loop"), # or in middle of a jump
      #  (neq, ":animation", "anim_double_jump_loop"), # or in middle of a double jump
      #  (neq, ":animation", "anim_double_jump"), # or even starting a double jump
      #  (val_add, ":double_jump", 25),    # Add time for the engine to move your agent higher.
    (try_end),


    (try_begin),
        (ge, ":double_jump", 1),
        (agent_set_no_dynamics, ":agent", 1),  # Turning dynamics off allows us to basically no_clip
        # (position_move_y, pos0, ":forward_momentum"), # Activating this will make a longer jump arc, based on the speed of the character
        (position_move_z, pos0, 2),            # Setting this to 2 makes an IDENTICAL jumping arc to the original! I use something like 5~10 personally.
        (agent_set_position, ":agent", pos0),    # Move them to the new position
        (agent_set_no_dynamics, ":agent", 0), #Dynamics back on
        (val_sub, ":double_jump", 1),        # subtract a centisecond from remaining upwards movement time
    (try_end),
    (agent_set_slot, ":agent", slot_agent_is_double_jumping, ":double_jump"), # Store the double_jump value

    ])

This is just a prototype for modders to work off of and is very rough. The way it is laid out here can be adapted to work with AI if the groundwork for jumping logic has already been put into place. Tweak it to your hearts content and feel free to use freely without credit.
 
Last edited:
Character name generator/randomizer

Small presentation page in the start to choose the character name with randomize button for female or male, 200 names for each.



In module_game_menus in the "mnu_start_game_1" menu replace (jump_to_menu,"mnu_start_character_1"), in both male and female options to "(start_presentation, "prsnt_set_player_name")

("male_name_001", "Marcus"),
("male_name_002", "John"),
("name_1", "Albard"),
("name_2", "Euscarl"),
("name_3", "Sigmar"),
("name_4", "Talesqe"),
("name_5", "Ritmand"),
("name_6", "Aels"),
("name_7", "Raurqe"),
("name_8", "Bragamus"),
("name_9", "Taarl"),
("name_10", "Ramin"),
("name_11", "Shulk"),
("name_12", "Putar"),
("name_13", "Tamus"),
("name_14", "Reichad"),
("name_15", "Walcheas"),
("name_16", "Rulkh"),
("name_17", "Marlund"),
("name_18", "Auguryn"),
("name_19", "Daynad"),
("name_20", "Joayah"),
("name_21", "Ramar"),
("name_22", "Caldaran"),
("name_23", "Brabas"),
("name_24", "Kundrin"),
("name_25", "Pechnak"),
("male_name_003", "Hernigam"),
("male_name_004", "Petter"),
("male_name_005", "Cristian"),
("male_name_006", "Arthur"),
("male_name_007", "Cesar"),
("male_name_008", "Lucas"),
("male_name_009", "Avladikus"),
("male_name_010", "Senit"),
("male_name_011", "Milain"),
("male_name_012", "Bombaide"),
("male_name_013", "Malipe"),
("male_name_014", "Singai"),
("male_name_015", "Amunegan"),
("male_name_016", "Jungas"),
("male_name_017", "Artheus"),
("male_name_018", "Fergus"),
("male_name_019", "Lugaid"),
("male_name_020", "Fedelmid"),
("male_name_021", "Donngal"),
("male_name_022", "Lóegaire"),
("male_name_023", "Carthach"),
("male_name_024", "Eochaid"),
("male_name_025", "Cormac"),
("male_name_026", "Muiredach"),
("male_name_027", "Éogan"),
("male_name_028", "Colmán"),
("male_name_029", "Alanus"),
("male_name_030", "Arthurus"),
("male_name_031", "Balian"),
("male_name_032", "Bryan"),
("male_name_033", "Conon"),
("male_name_034", "Gawyne"),
("male_name_035", "Joceus"),
("male_name_036", "Malcolinus"),
("male_name_037", "Marmaduc"),
("male_name_038", "Nigelle"),
("male_name_039", "Ywain"),
("male_name_040", "Trustram"),
("male_name_041", "Urien"),
("male_name_042", "Aylard"),
("male_name_043", "Athelardus"),
("male_name_044", "Amaurri"),
("male_name_045", "Ancelin"),
("male_name_046", "Alphonsins"),
("male_name_047", "Auguinare"),
("male_name_048", "Ernaldus"),
("male_name_049", "Arnoldus"),
("male_name_050", "Bardol"),
("male_name_051", "Audouin"),
("male_name_052", "Berengarius"),
("male_name_053", "Berengerus"),
("male_name_054", "Barnard"),
("male_name_055", "Beroldus"),
("male_name_056", "Beroldus"),
("male_name_057", "Betin"),
("male_name_058", "Beavis"),
("male_name_059", "Blayves"),
("male_name_060", "Botolfe"),
("male_name_061", "Carle"),
("male_name_062", "Karolus"),
("male_name_063", "Clarembaut"),
("male_name_064", "Courtois"),
("male_name_065", "Degarre"),
("male_name_066", "Droet"),
("male_name_067", "Dreues"),
("male_name_068", "Erneis"),
("male_name_069", "Udona"),
("male_name_070", "Aberardus"),
("male_name_071", "Heinricus"),
("male_name_072", "Hermannus"),
("male_name_073", "Cunradus"),
("male_name_074", "Wilhelmus"),
("male_name_075", "Hartmannus"),
("male_name_076", "Wikerus"),
("male_name_077", "Didericus"),
("male_name_078", "Wigandus"),
("male_name_079", "Ditmarus"),
("male_name_080", "Hartmudus"),
("male_name_081", "Meingotus"),
("male_name_082", "Fridebertus"),
("male_name_083", "Rudegerus"),
("male_name_084", "Wecelo"),
("male_name_085", "Everwinus"),
("male_name_086", "Fridericus"),
("male_name_087", "Gerhardus"),
("male_name_088", "Guntramus"),
("male_name_089", "Harpernus"),
("male_name_090", "Meffridus"),
("male_name_091", "Sifridus"),
("male_name_092", "Theodericus"),
("male_name_093", "Eberhardus"),
("male_name_094", "Gernandus"),
("male_name_095", "Johannes"),
("male_name_096", "Ludewicus"),
("male_name_097", "Ortwinus"),
("male_name_098", "Eginolf"),
("male_name_099", "Ripertus"),
("male_name_100", "Fretsol"),
("male_name_101", "Derflok"),
("male_name_102", "Resvero"),
("male_name_103", "Tupl"),
("male_name_104", "Carven"),
("male_name_105", "Stakso"),
("male_name_106", "Jordan"),
("male_name_107", "Ian"),
("male_name_108", "Bedvelier"),
("male_name_109", "Craset"),
("male_name_110", "Rasklip"),
("male_name_111", "Highol"),
("male_name_112", "Trevsto"),
("male_name_113", "Gresfolk"),
("male_name_114", "Ceter"),
("male_name_115", "Despinl"),
("male_name_116", "Retrosperian Loksver"),
("male_name_117", "Reftovlom"),
("male_name_118", "Ikargo"),
("male_name_119", "Fretonsk"),
("male_name_120", "Poveri"),
("male_name_121", "Zexir"),
("male_name_122", "Frequo"),
("male_name_123", "Quervoltai"),
("male_name_124", "Puntop"),
("male_name_125", "Losver"),
("male_name_126", "Erap"),
("male_name_127", "Rsto"),
("male_name_128", "Xevrien"),
("male_name_129", "Polvisk"),
("male_name_130", "Xec"),
("male_name_131", "Father Blood"),
("male_name_132", "Brevshu"),
("male_name_133", "Bulbois"),
("male_name_134", "Larkstop"),
("male_name_135", "Lovten"),
("male_name_136", "Lship"),
("male_name_137", "Le Rewn"),
("male_name_138", "El Matdor"),
("male_name_139", "Guarierien"),
("male_name_140", "Chance"),
("male_name_141", "Andrew"),
("male_name_142", "Rickey"),
("male_name_143", "Elijah"),
("male_name_144", "Dustoph"),
("male_name_145", "Kevin"),
("male_name_146", "Barbari"),
("male_name_147", "Axzel"),
("male_name_148", "Axel"),
("male_name_149", "Aphelto"),
("male_name_150", "Apheltono"),
("male_name_151", "Afreckso"),
("male_name_152", "Atshi"),
("male_name_153", "Pulmonisl"),
("male_name_154", "Murphy"),
("male_name_155", "Lawfonteri"),
("male_name_156", "Clackrentrackoneck"),
("male_name_157", "Khryill"),
("male_name_158", "Black Fren"),
("male_name_159", "Resvol"),
("male_name_160", "Coraveriosk"),
("male_name_161", "Carter"),
("male_name_162", "Strange Man"),
("male_name_163", "Soper"),
("male_name_164", "Lofiskl"),
("male_name_165", "Sixlop"),
("male_name_166", "Kester"),
("male_name_167", "Velominus"),
("male_name_168", "Polvernisko"),
("male_name_169", "Lofsh"),
("male_name_170", "Nosh"),
("male_name_171", "Kilzmop"),
("male_name_172", "Treveri"),
("male_name_173", "Nafshi"),
("male_name_174", "Zer"),
("male_name_175", "Nofashil"),
("male_name_176", "Trepo"),
("male_name_177", "Likstox"),
("male_name_178", "Uvumipila"),
("male_name_179", "Oren"),
("male_name_180", "Odinsk"),
("male_name_181", "Axer"),
("male_name_182", "Tevriskop"),
("male_name_183", "Lolzeriom"),
("male_name_184", "Taragoth"),
("male_name_185", "Osper"),
("male_name_186", "Pellagus"),
("male_name_187", "Reps"),
("male_name_188", "Nativer Sefanson"),
("male_name_189", "Eightynine"),
("male_name_190", "Dashpolmu"),
("male_name_191", "Pitireful"),
("male_name_192", "Achoful"),
("male_name_193", "Brian"),
("male_name_194", "Timmerna"),
("male_name_195", "Malo"),
("male_name_196", "Wrevil"),
("male_name_197", "Wrepil"),
("male_name_198", "Wreskil"),
("male_name_199", "Wretil"),
("male_name_200", "Lofilsk"),
("male_name_end", "End"),
("female_name_001", "Anachorita"),
("female_name_002", "Braya"),
("female_name_003", "Branwyne"),
("female_name_004", "Bragwayn"),
("female_name_005", "Brigida"),
("female_name_006", "Guener"),
("female_name_007", "Wannore"),
("female_name_008", "Emayn"),
("female_name_009", "Ismena"),
("female_name_010", "Imaigne"),
("female_name_011", "Jessimond"),
("female_name_012", "Essylt"),
("female_name_013", "Isard"),
("female_name_014", "Iseldis"),
("female_name_015", "Iseult"),
("female_name_016", "Isolde"),
("female_name_017", "Isota"),
("female_name_018", "Isouda"),
("female_name_019", "Izett"),
("female_name_020", "Yseulte"),
("female_name_021", "Ysout"),
("female_name_022", "Hysode"),
("female_name_023", "Isata"),
("female_name_024", "Iselota"),
("female_name_025", "Iseut"),
("female_name_026", "Isolt"),
("female_name_027", "Isott"),
("female_name_028", "Issat"),
("female_name_029", "Izot"),
("female_name_030", "Ysolt"),
("female_name_031", "Isaut"),
("female_name_032", "Iseuda"),
("female_name_033", "Isold"),
("female_name_034", "Isot"),
("female_name_035", "Isotta"),
("female_name_036", "Isylte"),
("female_name_037", "Yseult"),
("female_name_038", "Ysoude"),
("female_name_039", "Jocea"),
("female_name_040", "Jocosa"),
("female_name_041", "Jossy"),
("female_name_042", "Jocey"),
("female_name_043", "Jodoca"),
("female_name_044", "Joyse"),
("female_name_045", "Josse"),
("female_name_046", "Juicea"),
("female_name_047", "Eluned"),
("female_name_048", "Linette"),
("female_name_049", "Linota"),
("female_name_050", "Luned"),
("female_name_051", "Lynette"),
("female_name_052", "Lina"),
("female_name_053", "Linnet"),
("female_name_054", "Linyeve"),
("female_name_055", "Lunet"),
("female_name_056", "Lyneue"),
("female_name_057", "Linniue"),
("female_name_058", "Linyive"),
("female_name_059", "Lunete"),
("female_name_060", "Lyonnete"),
("female_name_061", "Merewen"),
("female_name_062", "Merwenna"),
("female_name_063", "Merewina"),
("female_name_064", "Wantelien"),
("female_name_065", "Wentiliana"),
("female_name_066", "Wenthelen"),
("female_name_067", "Wenefreda"),
("female_name_068", "Wynifreed"),
("female_name_069", "Winefred"),
("female_name_070", "Winnifred"),
("female_name_071", "Maryell"),
("female_name_072", "Meriall"),
("female_name_073", "Meryall"),
("female_name_074", "Meriel"),
("female_name_075", "Miriel"),
("female_name_076", "Miriild"),
("female_name_077", "Muriele"),
("female_name_078", "Merhild"),
("female_name_079", "Meriel"),
("female_name_080", "Meryld"),
("female_name_081", "Miriela"),
("female_name_082", "Mirielis"),
("female_name_083", "Mirils"),
("female_name_084", "Muriella"),
("female_name_085", "Merilda"),
("female_name_086", "Miriald"),
("female_name_087", "Mirield"),
("female_name_088", "Miriella"),
("female_name_089", "Murie"),
("female_name_090", "Murienne"),
("female_name_091", "Gismon"),
("female_name_092", "Isamaya"),
("female_name_093", "Imme"),
("female_name_094", "Hyssmaye"),
("female_name_095", "Ysmene"),
("female_name_096", "Gwenhevare"),
("female_name_097", "Jenefer"),
("female_name_098", "Bragwayn"),
("female_name_099", "Bryde"),
("female_name_101", "Aldonza"),
("female_name_102", "Beatriz"),
("female_name_103", "Adela"),
("female_name_104", "Allison"),
("female_name_105", "Amela"),
("female_name_106", "Ava"),
("female_name_107", "Bliss"),
("female_name_108", "Cass"),
("female_name_109", "Cecily"),
("female_name_110", "Christabel"),
("female_name_111", "Christian"),
("female_name_112", "Christina"),
("female_name_113", "Clare"),
("female_name_114", "Clarice"),
("female_name_115", "Clarimond"),
("female_name_116", "Clarissa"),
("female_name_117", "Clemence"),
("female_name_118", "Colette"),
("female_name_119", "Constance"),
("female_name_120", "Courtney"),
("female_name_121", "Emma"),
("female_name_122", "Gaynor"),
("female_name_123", "Lisabelle"),
("female_name_124", "Jay"),
("female_name_125", "Joan"),
("female_name_126", "Katelyn"),
("female_name_127", "Katherine"),
("female_name_128", "Latisha"),
("female_name_129", "Letita"),
("female_name_130", "Morgan"),
("female_name_131", "Moragine"),
("female_name_132", "Morgayne"),
("female_name_133", "Lauda"),
("female_name_134", "Pagan"),
("female_name_135", "Paige"),
("female_name_136", "Ysabel"),
("female_name_137", "Isable"),
("female_name_138", "Able"),
("female_name_139", "Eleanor"),
("female_name_140", "Matilda"),
("female_name_141", "Maude"),
("female_name_142", "Matildae"),
("female_name_143", "Matilday"),
("female_name_144", "Bareguieria"),
("female_name_145", "Isabelle"),
("female_name_146", "Isabella"),
("female_name_147", "Elanoria"),
("female_name_148", "Phillipa"),
("female_name_149", "Mary"),
("female_name_150", "Catherine"),
("female_name_151", "Mary"),
("female_name_152", "Bohun"),
("female_name_153", "Margaret"),
("female_name_154", "Margeret"),
("female_name_155", "Magarit"),
("female_name_156", "Elizabeth"),
("female_name_157", "Anne"),
("female_name_158", "Annie"),
("female_name_159", "Provinciea"),
("female_name_160", "Anna"),
("female_name_161", "Heloise"),
("female_name_162", "Hildegard"),
("female_name_163", "Julian"),
("female_name_164", "Christine"),
("female_name_165", "Jane"),
("female_name_166", "Shoria"),
("female_name_167", "Alice"),
("female_name_168", "Katherin"),
("female_name_169", "Margarey"),
("female_name_170", "Joaness"),
("female_name_171", "Godiva"),
("female_name_172", "Marigold"),
("female_name_173", "Lulu"),
("female_name_174", "Marden"),
("female_name_175", "Magge"),
("female_name_176", "Madi"),
("female_name_177", "Luei"),
("female_name_178", "Lufu"),
("female_name_179", "Luella"),
("female_name_180", "Lovedie"),
("female_name_181", "Lovedeya"),
("female_name_182", "LoveDaya"),
("female_name_183", "Lovedaia"),
("female_name_184", "Lorcia"),
("female_name_185", "Lorelle"),
("female_name_186", "Lorellen"),
("female_name_187", "Loricar"),
("female_name_188", "Long"),
("female_name_189", "Linsey"),
("female_name_190", "Lindsey"),
("female_name_191", "Linden"),
("female_name_192", "Lily"),
("female_name_193", "Lili"),
("female_name_194", "Lilli"),
("female_name_195", "Lilian"),
("female_name_196", "Leuedai"),
("female_name_197", "Liliana"),
("female_name_198", "Letha"),
("female_name_199", "Lee"),
("female_name_200", "Lark"),
("female_name_end", "End"),

Code:
  ("set_player_name", 0, mesh_load_window, [
        (ti_on_presentation_load,
         [(set_fixed_point_multiplier, 1000),

          (str_store_string, s1, "@What will be the name of your character?"),
          (create_text_overlay, reg1, s1, tf_center_justify),
          (position_set_x, pos1, 500),
          (position_set_y, pos1, 400),
          (overlay_set_position, reg1, pos1),
          (overlay_set_text, reg1, s1),
          (create_simple_text_box_overlay, "$g_presentation_obj_set_player_name_1"),
          (position_set_x, pos1, 400),
          (position_set_y, pos1, 350),
          (overlay_set_position, "$g_presentation_obj_set_player_name_1", pos1),

          (create_button_overlay, "$g_presentation_obj_set_player_name_2", "@Randomize male name", tf_center_justify),
          (position_set_x, pos1, 585),
          (position_set_y, pos1, 325),
          (overlay_set_position, "$g_presentation_obj_set_player_name_2", pos1),

          (create_button_overlay, "$g_presentation_obj_set_player_name_3", "@Randomize female name",
           tf_center_justify),
          (position_set_x, pos1, 585),
          (position_set_y, pos1, 285),
          (overlay_set_position, "$g_presentation_obj_set_player_name_3", pos1),

          (create_button_overlay, "$g_presentation_obj_set_player_name_4", "@Continue...", tf_center_justify),
          (position_set_x, pos1, 500),
          (position_set_y, pos1, 200),
          (overlay_set_position, "$g_presentation_obj_set_player_name_4", pos1),

          (presentation_set_duration, 999999),
          ]),
        (ti_on_presentation_event_state_change,
         [(store_trigger_param_1, ":object"),
          (try_begin),
          (eq, ":object", "$g_presentation_obj_set_player_name_2"),
(store_random_in_range, reg3, "str_male_name_001", "str_male_name_200"),
          (str_store_string, s11, reg3),
          (troop_set_name, "trp_player", s11),
          (troop_set_plural_name, "trp_player", s11),
          (overlay_set_text, "$g_presentation_obj_set_player_name_1", s11),
          (str_store_string, s0, s11),
          (else_try),
          (eq, ":object", "$g_presentation_obj_set_player_name_3"),
(store_random_in_range, reg3, "str_female_name_001", "str_female_name_200"),
          (str_store_string, s11, reg3),
          (troop_set_name, "trp_player", s11),
          (troop_set_plural_name, "trp_player", s11),
          (overlay_set_text, "$g_presentation_obj_set_player_name_1", s11),
          (str_store_string, s0, s11),
          (else_try),
          (eq, ":object", "$g_presentation_obj_set_player_name_4"),
          (str_store_string, s7, s0),
         (troop_set_name, "trp_player", s7),
          (troop_set_plural_name, "trp_player", s7),

          (jump_to_menu, "mnu_start_character_1"),
          (try_end),
          ]),
          ]),
 
Last edited:
Passable Allies

I loved it how in Bannerlord you can pass through ally troop lines. Turns out it's possible in Warband too. But, to lower the load on engine and possibly on performance, I tied this effect to holding a left [Ctrl] key while moving. You don't need this permanently active anyway. Have fun =)

Code:
passable_allies = (0, 0, 0,
    [
    (neg|main_hero_fallen),
    (key_is_down, key_left_control),
    ],
    [
    (set_fixed_point_multiplier, 1),
    (get_player_agent_no, ":player"),
    (agent_get_position, pos1, ":player"),
    (agent_get_team, ":p_team", ":player"),
    (try_for_agents, ":agent", pos1, 1),
        (agent_is_alive, ":agent"),
        (agent_is_human, ":agent"),
        (agent_is_non_player, ":agent"),
        (agent_get_team, ":a_team", ":agent"),
        (neg|teams_are_enemies, ":a_team", ":p_team"),
        (agent_get_speed, pos2, ":player"),
        (position_get_y, ":forward_momentum", pos2),
        (position_get_x, ":sideway_momentum", pos2),
        (convert_to_fixed_point, ":forward_momentum"),
        (convert_to_fixed_point, ":sideway_momentum"),
        (try_begin),
            (lt, ":forward_momentum", 0), # backwards moving speed is higher somehow, so we divide it in half
            (val_div, ":forward_momentum", 2),
        (try_end),
        (val_div, ":sideway_momentum", 2), # so is sideways moving speed
        (position_move_y, pos1, ":forward_momentum"),
        (position_move_x, pos1, ":sideway_momentum"),
        (agent_set_position, ":player", pos1),      
    (try_end),
    ])

Props to SupaNinjaMan and Garedyr for support, you're the best.
 
Last edited:
Sorting main party members in various ways

The main code is from rubik sorting parties by level script.
Instead of sorting with many clicks the party members with this it can be made with fewer clicks.
Include: sort by stack level. sort by stack amount. sort by infantry, archers, cavalry and companions to the top or bottom
Screenshot:


new script in module_scripts.py
Python:
("sort_party_members_stack_level",
   [
    (try_for_parties, ":party_no"),
        (assign, ":continue", 0),
        (try_begin),
            (eq, ":party_no", "p_main_party"),
            (party_is_active, ":party_no"),
            (assign, ":continue", 1),
            (try_begin),
                (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                (this_or_next | troop_is_hero, ":cur_troop"),
                (eq, ":cur_troop", "trp_caravan_master"),
                (assign, ":first_stack", 1),
            (else_try),
                (assign, ":first_stack", 0),
            (try_end),
        (try_end),
        (eq, ":continue", 1),
        (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
        (gt, ":num_stacks", ":first_stack"),
        (assign, ":last_stack", ":num_stacks"),
        # start to sort
        (store_sub, ":num_times", ":num_stacks", ":first_stack"),
        (try_for_range, ":unused", 0, ":num_times"),
            # find highest-level troop
            (assign, ":best_stack", -1),
            (assign, ":best_level", -1),
            (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                (store_character_level, ":troop_level", ":cur_troop"),
                (gt, ":troop_level", ":best_level"),
                (assign, ":best_level", ":troop_level"),
                (assign, ":best_stack", ":cur_stack"),
            (try_end),
            # move to the end
            (try_begin),
                (gt, ":best_level", -1),
                (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                (val_sub, ":last_stack", 1),
            (try_end),
        (try_end),
    (try_end),
   ]),

in module_game_menus.py
Below "camp_recruit_prisoners" option add below this new option-
Python:
("action_sort_party_members", [], "Sort party members.",
[(jump_to_menu, "mnu_camp_action_sort_party"),
  ]
),
The new menu-
Python:
("camp_action_sort_party", 0,
     "Choose what to sort by:^^(can be mixed sorting, for example, sorting stack level and then sorting party infantry to the top will make the infantry stacks to sort by level, same goes to stack amount)",
     "none",
     [

     ],
     [
         ("sort_party_1",
          [], "Sort party members by stack level.",
          [
              (call_script, "script_sort_party_members_stack_level"),
              (display_message, "@Your party members is now sorted by stack level."),
          ],
          ),

         ("sort_party_2",
          [], "Sort party members by stack amount.",
          [
              (call_script, "script_sort_party_members_stack_level"),
              (try_for_parties, ":party_no"),
                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),
                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          #(party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (party_stack_get_size, ":troop_level", "p_main_party", ":cur_stack"),
                          (gt, ":troop_level", ":best_level"),
                          (assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          (gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),

              (display_message, "@Your party members is now sorted by stack amount."),
          ]
          ),
         ("blank", [
         ],
          "------------------------------",
          []),
         ("sort_party_3",
          [], "Sort party infantry to the top.",
          [
              (try_for_parties, ":party_no"),
                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                         (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                         (this_or_next | troop_is_hero, ":cur_troop"),
                         (eq, ":cur_troop", "trp_caravan_master"),
                         (assign, ":first_stack", 1),
                     (else_try),
                         (assign, ":first_stack", 0),
                     (try_end),
                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                     # find highest-level troop
                     (assign, ":best_stack", -1),
                     (assign, ":best_level", -1),
                     (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                         (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                         (troop_get_class, ":troop_class", ":cur_troop"),
                         (neq, ":troop_class", 0),
                         #(store_character_level, ":troop_level", ":cur_troop"),
                         #(gt, ":troop_level", ":best_level"),
                         #(assign, ":best_level", ":troop_level"),
                         (assign, ":best_stack", ":cur_stack"),
                     (try_end),
                     # move to the end
                     (try_begin),
                         #(gt, ":best_level", -1),
                         (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                         (troop_get_class, ":troop_class", ":stack_troop"),
                         (neq, ":troop_class", 0),
                         (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                         (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                         (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                         (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                         (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                         (val_sub, ":last_stack", 1),
                     (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party infantry is now sorted to the top."),
          ],
          ),
         ("sort_party_4",
          [], "Sort party infantry to the buttom.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (troop_get_class, ":troop_class", ":cur_troop"),
                          (eq, ":troop_class", 0),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                      #(gt, ":best_level", -1),
                         (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                         (troop_get_class, ":troop_class", ":stack_troop"),
                         (eq, ":troop_class", 0),
                         (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                         (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                         (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                         (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                         (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                         (val_sub, ":last_stack", 1),
                     (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party infantry is now sorted to the buttom."),
          ],
          ),
         ("blank_1", [
         ],
          "------------------------------",
          []),
         ("sort_party_5",
          [], "Sort party archers to the top.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (troop_get_class, ":troop_class", ":cur_troop"),
                          (neq, ":troop_class", 1),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          #(gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (troop_get_class, ":troop_class", ":stack_troop"),
                          (neq, ":troop_class", 1),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party archers is now sorted to the top."),
          ],
          ),
         ("sort_party_6",
          [], "Sort party archers to the buttom.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                  (try_begin),
                      (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                      (this_or_next | troop_is_hero, ":cur_troop"),
                      (eq, ":cur_troop", "trp_caravan_master"),
                      (assign, ":first_stack", 1),
                  (else_try),
                      (assign, ":first_stack", 0),
                  (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (troop_get_class, ":troop_class", ":cur_troop"),
                          (eq, ":troop_class", 1),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          #(gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (troop_get_class, ":troop_class", ":stack_troop"),
                          (eq, ":troop_class", 1),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party archers is now sorted to the buttom."),
          ],
          ),
         ("blank_2", [
         ],
          "------------------------------",
          []),
         ("sort_party_7",
          [], "Sort party cavalry to the top.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                       # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (troop_get_class, ":troop_class", ":cur_troop"),
                          (neq, ":troop_class", 2),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          #(gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (troop_get_class, ":troop_class", ":stack_troop"),
                          (neq, ":troop_class", 2),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party cavalry is now sorted to the top."),
          ],
          ),
         ("sort_party_8",
          [], "Sort party cavalry to the buttom.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (troop_get_class, ":troop_class", ":cur_troop"),
                          (eq, ":troop_class", 2),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          #(gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (troop_get_class, ":troop_class", ":stack_troop"),
                          (eq, ":troop_class", 2),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party cavalry is now sorted to the buttom."),
          ],
          ),
         ("blank_3", [
         ],
          "------------------------------",
          []),
         ("sort_party_9",
          [], "Sort party companions to the top.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (neg | troop_is_hero, ":cur_troop"),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          #(gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (neg | troop_is_hero, ":stack_troop"),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party companions is now sorted to the top."),
          ],
          ),
         ("sort_party_10",
          [], "Sort party companions to the buttom.",
          [
              (try_for_parties, ":party_no"),

                  (assign, ":continue", 0),
                  (try_begin),
                      (eq, ":party_no", "p_main_party"),
                      (party_is_active, ":party_no"),
                      (assign, ":continue", 1),
                      (try_begin),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", 0),
                          (this_or_next | troop_is_hero, ":cur_troop"),
                          (eq, ":cur_troop", "trp_caravan_master"),
                          (assign, ":first_stack", 1),
                      (else_try),
                          (assign, ":first_stack", 0),
                      (try_end),

                  (try_end),
                  (eq, ":continue", 1),
                  (party_get_num_companion_stacks, ":num_stacks", ":party_no"),
                  (gt, ":num_stacks", ":first_stack"),
                  (assign, ":last_stack", ":num_stacks"),

                  # start to sort
                  (store_sub, ":num_times", ":num_stacks", ":first_stack"),
                  (try_for_range, ":unused", 0, ":num_times"),
                      # find highest-level troop
                      (assign, ":best_stack", -1),
                      (assign, ":best_level", -1),
                      (try_for_range, ":cur_stack", ":first_stack", ":last_stack"),
                          (party_stack_get_troop_id, ":cur_troop", ":party_no", ":cur_stack"),
                          (troop_is_hero, ":cur_troop"),
                          #(store_character_level, ":troop_level", ":cur_troop"),
                          #(gt, ":troop_level", ":best_level"),
                          #(assign, ":best_level", ":troop_level"),
                          (assign, ":best_stack", ":cur_stack"),
                      (try_end),
                      # move to the end
                      (try_begin),
                          #(gt, ":best_level", -1),
                          (party_stack_get_troop_id, ":stack_troop", ":party_no", ":best_stack"),
                          (troop_is_hero, ":stack_troop"),
                          (party_stack_get_size, ":stack_size", ":party_no", ":best_stack"),
                          (party_stack_get_num_wounded, ":num_wounded", ":party_no", ":best_stack"),
                          (party_remove_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_add_members, ":party_no", ":stack_troop", ":stack_size"),
                          (party_wound_members, ":party_no", ":stack_troop", ":num_wounded"),
                          (val_sub, ":last_stack", 1),
                      (try_end),
                  (try_end),
              (try_end),
              (display_message, "@Your party companions is now sorted to the buttom."),
          ],
          ),


         ("camp_sort_leave_to_menu", [], "Back to camp menu.",
          [(jump_to_menu, "mnu_camp_action"),
           ]
          ),
     ]
     ),
 
Last edited by a moderator:
Auto-Pickup Missiles

Recently I was trying horse archery and found one aspect of this playstyle quite frustrating. When you are low on ammo, your best bet is to collect arrows from the ground. But it's not very comfortable sometimes to point the camera on those (especially when there is a bunch of cavalry chasing you), not to mention you need to be on the correct distance from the arrow for pickup option to appear. So I decided to make this trigger. To lower the load on engine and possibly on performance, I tied it to holding a [Num_Enter] key while moving. You don't need this permanently active anyway. Two things to remember when using it:
1) unlike the pickup via F button, this one requires you to wield the respective weapon to succeed. Just keep it in mind;
2) it won't pickup quivers, only single missiles. That's because it would always give a full quiver, even if there was 3 arrows left after agent died. And I haven't figured out how to retrieve valid ammo amount of quivers on the ground yet.

Have fun =)

Code:
missiles_auto_pickup = (0, 0, 0.6,
  [
  (neg|main_hero_fallen),
  (key_is_down, key_numpad_enter),
  ],
  [
    (set_fixed_point_multiplier, 100),
    (get_player_agent_no, ":player"),
    (agent_is_active, ":player"),
    (agent_get_position, pos1, ":player"),
    (agent_get_wielded_item, ":weapon", ":player", 0),
    (neq, ":weapon", -1), # preventing errors from bare fists
    (item_get_type, ":w_type", ":weapon"),
    (assign, ":free_slots", 0),
    (assign, ":valid_ammo", 0),
    (try_for_range_backwards, ":s", 0, 4), # retrieve the current quiver that matches weapon type. Game 
                                           # spends quivers from top to bottom, so we need backwards loop
        (agent_get_item_slot, ":slot_item", ":player", ":s"),
        (try_begin),
            (eq, ":slot_item", -1),
            (assign, ":empty_slot", ":s"),
            (val_add, ":free_slots", 1),
        (else_try),
            (item_get_type, ":m_type", ":slot_item"),
            (eq, ":m_type", itp_type_arrows),
            (eq, ":w_type", itp_type_bow),
            (assign, ":ammo_item", ":slot_item"),
            (assign, ":ammo_slot", ":s"),
        (else_try),
            (item_get_type, ":m_type", ":slot_item"),
            (eq, ":m_type", itp_type_bolts),
            (eq, ":w_type", itp_type_crossbow),
            (assign, ":ammo_item", ":slot_item"),
            (assign, ":ammo_slot", ":s"),
        (else_try),
            (item_get_type, ":m_type", ":slot_item"),
            (eq, ":m_type", itp_type_thrown),
            (eq, ":slot_item", ":weapon"), # no need to compare weapon type this time, it's a 2-in-1 check
            (assign, ":ammo_item", ":slot_item"),
            (assign, ":ammo_slot", ":s"),
        (try_end),
    (try_end),   
    (try_for_prop_instances, ":missile", -1, somt_spawned_single_ammo_item), # only single missiles, not quivers
        (prop_instance_get_position, pos2, ":missile"),
        (get_distance_between_positions, ":dist", pos2, pos1),
        (le, ":dist", 250), # pickup radius, adjust to your liking
        (prop_instance_get_scene_prop_kind, ":item", ":missile"), # get item id to compare it with current weapon
        (item_get_type, ":i_type", ":item"),
        (try_begin),
            (eq, ":i_type", itp_type_arrows),
            (eq, ":w_type", itp_type_bow),
            (assign, ":valid_ammo", 1),
        (else_try),
            (eq, ":i_type", itp_type_bolts),
            (eq, ":w_type", itp_type_crossbow),
            (assign, ":valid_ammo", 1),
        (else_try),
            (eq, ":i_type", itp_type_thrown),
            (eq, ":item", ":weapon"), 
            (assign, ":valid_ammo", 1),
        (try_end),
        (eq, ":valid_ammo", 1), #invalid ammo will be ignored without warnings
        (neg|item_has_property, ":item", itp_no_pick_up_from_ground),
        (agent_get_ammo, ":old_ammo", ":player", 1), # ONLY for total amount comparison
        (agent_get_ammo_for_slot, ":s_ammo", ":player", ":ammo_slot"), # for actual pickup calculation
        (store_add, ":new_ammo", ":s_ammo", 1),
        (agent_set_ammo, ":player", ":ammo_item", ":new_ammo"),
        (str_store_item_name, s2, ":item"),   
        (try_begin),
            (agent_get_ammo, ":cur_ammo", ":player", 1),
            (eq, ":cur_ammo", ":old_ammo"), # if these values are the same, it means there are no room for more ammo. In this
                                            # case, when you pick up something via F, game will create new quiver given there
                                            # are empty slots left. So we should replicate this behaviour
            (try_begin),
                (ge, ":free_slots", 1),
                (agent_equip_item, ":player", ":item", ":empty_slot"),
                (agent_set_ammo, ":player", ":item", 1),
                (scene_prop_set_prune_time, ":missile", 0), # remove missile from ground
                (display_message, "@Picking up {s2}."), # duplicate default message               
            (else_try), # if there are no room for ammo in current quiver and no empty slots for new one
                (display_message, "@Unable to take that."), # duplicate default warning
            (try_end),           
        (else_try),
            (scene_prop_set_prune_time, ":missile", 0),
            (display_message, "@Picking up {s2}."),
        (try_end),
    (try_end),   
  ])
 
Last edited:
Prop Clock

It was just an experiment, not really it's own thread level, so I'm posting it here. If you need a clock, better make it text-based, trust me you don't need props for this. But prop clock is possible too, and it looks cooler maybe.

Final result:

Have fun =)

lrU1awD.jpg

Code:
clock_1 = (0, 0, ti_once, [], # preparing the 00:00 situation
[
  (try_for_prop_instances, ":instance_no", "itm_linen"),
    (prop_instance_get_variation_id, ":var1", ":instance_no"),
    (eq, ":var1", 4),
    (scene_prop_set_visibility, ":instance_no", 0),
  (try_end),
  (assign, "$clock_time", 0),
  (assign, "$start_clock", 0),
])

clock_2 = (1, 0, 0, # actual clock with 1 sec interval
[
(eq, "$start_clock", 1),
],
[  
  (val_add, "$clock_time", 1),
  (assign, ":time", "$clock_time"),
  (store_mission_timer_a_msec, ":cur_time"), # getting msec value to make exact digits
  (val_mul, ":time", 1000),
  (val_sub, ":cur_time", ":time"),
  (val_div, ":time", 1000),
  (gt, ":cur_time", 1000),   
  (store_mod, reg1, ":time", 10),
  (call_script, "script_make_digit_of_linens", reg1, 1),
  (val_div, ":time", 10),
  (store_mod, reg2, ":time", 6),
  (call_script, "script_make_digit_of_linens", reg2, 2),
  (val_div, ":time", 6),
  (store_mod, reg3, ":time", 10),
  (call_script, "script_make_digit_of_linens", reg3, 3),
  (val_div, ":time", 10),
  (store_mod, reg4, ":time", 6),
  (call_script, "script_make_digit_of_linens", reg4, 4),
  #(tutorial_message, "@{reg4}{reg3}:{reg2}{reg1}"),  # I used this to make sure prop clock matches text one
  (play_sound, "snd_shield_hit_metal_wood"),
  (val_add, "$clock_time", 1),
])

Code:
("make_digit_of_linens", # long but very simple script
  [
    (store_script_param_1, ":digit", 1),
    (store_script_param_2, ":position", 2),

    (try_for_prop_instances, ":instance_no", "itm_linen"),
      (prop_instance_get_variation_id, ":var1", ":instance_no"),
      (prop_instance_get_variation_id_2, ":var2", ":instance_no"),
      (eq, ":var2", ":position"),
      (try_begin),
        (eq, ":digit", 0),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 1),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 2),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 0),
        (try_end),
      (else_try),
        (eq, ":digit", 3),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 4),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 5),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 6),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 7),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 8),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (else_try),
        (eq, ":digit", 9),
        (try_begin),
          (eq, ":var1", 1),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 2),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 3),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 4),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 5),
          (scene_prop_set_visibility, ":instance_no", 0),
        (else_try),
          (eq, ":var1", 6),
          (scene_prop_set_visibility, ":instance_no", 1),
        (else_try),
          (eq, ":var1", 7),
          (scene_prop_set_visibility, ":instance_no", 1),
        (try_end),
      (try_end),
    (try_end),  
  ]),

Code:
("clock_trigger",0,"bucket_a","bo_bucket_a", [
  (ti_on_scene_prop_hit,
  [
    (store_trigger_param_1, ":instance_no"),
    (play_sound, "snd_dummy_hit"),
    (particle_system_burst, "psys_dummy_smoke", pos1, 3),
    (particle_system_burst, "psys_dummy_straw", pos1, 10),
    (scene_prop_slot_eq, ":instance_no", scene_prop_open_or_close_slot, 0),
    (prop_instance_get_position, pos2, ":instance_no"), # pos1 is trigger param so we use pos2
    (position_move_z, pos2, 20),
    (prop_instance_animate_to_position, ":instance_no", pos2, 20),
    (scene_prop_set_slot, ":instance_no", scene_prop_open_or_close_slot, 1),
    (assign, "$start_clock", 1),
  ]),

  (ti_on_scene_prop_animation_finished,
  [
    (store_trigger_param_1, ":instance_no"),
    (scene_prop_slot_eq, ":instance_no", scene_prop_open_or_close_slot, 1),
    (prop_instance_get_starting_position, pos1, ":instance_no"),
    (prop_instance_animate_to_position, ":instance_no", pos1, 100),
    (scene_prop_set_slot, ":instance_no", scene_prop_open_or_close_slot, 0),
  ]),
  ]),
 
Last edited:
I came up with a way to insult any fellow lord even without a denounce quest XD It's split up into 2 parts and both of them are in module_dialogs.py, so you'll have to search them up to replace them;

Code:
# KINGDOM LORD DUEL OUTCOMES
  [anyone,"start",
  [(eq, "$talk_context", tc_after_duel),
   (check_quest_active, "qst_denounce_lord"),
   (check_quest_succeeded, "qst_denounce_lord"),
   (quest_slot_eq, "qst_denounce_lord", slot_quest_target_troop, "$g_talk_troop"),
  ],
   "Very well. You've made your point. I have nothing more to say.", "close_window", [
   (call_script, "script_change_troop_renown", "trp_player", 10),
   (try_begin),
     (quest_get_slot, ":giver_troop", "qst_denounce_lord", slot_quest_giver_troop),
     (eq, ":giver_troop", "$g_talk_troop"),
     #(call_script, "script_succeed_quest", "qst_denounce_lord"),
     (call_script, "script_end_quest", "qst_denounce_lord"),
   (try_end),
   (assign, "$g_leave_encounter", 1),
   ]],

  [anyone,"start",
  [(eq, "$talk_context", tc_after_duel),
   (check_quest_active, "qst_denounce_lord"),
   (check_quest_failed, "qst_denounce_lord"),
   (quest_slot_eq, "qst_denounce_lord", slot_quest_target_troop, "$g_talk_troop"),
  ],
   "Well, {sir/my lady}! Please, do not trouble yourself to rise from the ground, as I would simply have to knock you down again. I shall take your silence as an apology. Good day to you.", "close_window", [
   (call_script, "script_change_troop_renown", "trp_player", -10),
   (try_begin),
     (quest_get_slot, ":giver_troop", "qst_denounce_lord", slot_quest_giver_troop),
     (eq, ":giver_troop", "$g_talk_troop"),
     #(call_script, "script_fail_quest", "qst_denounce_lord"),
     (call_script, "script_end_quest", "qst_denounce_lord"),
   (try_end),
   (assign, "$g_leave_encounter", 1),
   ]],

Code:
   [anyone|plyr,"lord_talk", [
    (assign, ":dew_it", 0),
    (try_begin),
      (check_quest_active, "qst_denounce_lord"),
      (neg|check_quest_succeeded, "qst_denounce_lord"),
      (neg|check_quest_failed, "qst_denounce_lord"),
     
      (quest_slot_eq, "qst_denounce_lord", slot_quest_target_troop, "$g_talk_troop"),
      (assign, ":dew_it", 1),
    (else_try),
      (ge, "$g_talk_troop_relation", -10), # can only pick fights with people who aren't already your enemies, but can be removed if you like
      (eq, "$g_talk_troop_faction", "$players_kingdom"), # is a fellow lord
      (eq, "$player_has_homage", 1), # not a mercenary
      (neq, "$players_kingdom", "fac_player_supporters_faction"), # player is not a king/queen
      (neg|is_between, "$g_talk_troop", pretenders_begin, pretenders_end), # not insulting a pretender
      (neg|faction_slot_eq, "$g_talk_troop_faction", slot_faction_leader, "$g_talk_troop"), # not insulting your liege (lol)
      (neg|troop_slot_eq, "trp_player", slot_troop_spouse, "$g_talk_troop"), # not insulting your spouse
      (assign, ":dew_it", 2),
    (try_end),
   

   (troop_get_slot, ":reputation_string", "$g_talk_troop", slot_lord_reputation_type),
   (val_add, ":reputation_string", "str_lord_derogatory_default"),
   (str_store_string, s4, ":reputation_string"),  
 
   (ge, ":dew_it", 1),
   ],
   "I want to tell you something -- we have had enough of your {s4} ways", "lord_denounce_1",[
   ]],
 
   [anyone,"lord_denounce_1", [
   ],
   "I'm sorry... What did you say?", "lord_denounce_2",[
   ]],
 
   [anyone|plyr,"lord_denounce_2", [

   (troop_get_slot, ":reputation_string", "$g_talk_troop", slot_lord_reputation_type),
   (val_add, ":reputation_string", "str_lord_derogatory_result"),
   (str_store_string, s4, ":reputation_string"),

   ],
   "You heard me. You will {s4}", "lord_denounce_3",[
    (call_script, "script_troop_change_relation_with_troop", "$g_talk_troop", "trp_player", -15),
   
   (try_begin),
     (neg|check_quest_active, "qst_denounce_lord"),
     (quest_set_slot, "qst_denounce_lord", slot_quest_target_troop, "$g_talk_troop"),
   
     (quest_get_slot, ":target_troop", "qst_denounce_lord", slot_quest_target_troop),
     (str_store_troop_name_link, s14, ":target_troop"),
     (str_store_troop_name_link, s12, "$g_talk_troop"),

     (str_store_string, s2, "str_you_intend_to_denounce_s14_to_his_face_on_behalf_of_s14"),
     (setup_quest_text, "qst_denounce_lord"),
   
     (call_script, "script_start_quest", "qst_denounce_lord", ":target_troop"),
   (try_end),

   (store_div, ":impact", "$g_talk_troop_relation", 10),
   (val_add, ":impact", 1),
   (val_max, ":impact", 1),
   (val_mul, ":impact", -1),
 
   #Change his respect level, slightly.  In the future game, there should be more sophisticated metrics for this
   (try_for_range, ":other_lord", active_npcs_begin, active_npcs_end),
     (neq, "$g_talk_troop", ":other_lord"),
     (store_faction_of_troop, ":other_lord_faction",":other_lord"),
     (eq, ":other_lord_faction", "$g_talk_troop_faction"),
     (call_script, "script_troop_get_relation_with_troop", ":other_lord", "$g_talk_troop"),
     (lt, reg0, 15),
     (call_script, "script_troop_change_relation_with_troop", ":other_lord", "$g_talk_troop", ":impact"),
   (try_end),
 

 
   ]],

   [anyone|plyr,"lord_denounce_2", [
   ],
   "Never mind. You must have misheard me.", "lord_pretalk",[
   ]],
 
 
   [anyone,"lord_denounce_3", [
   (ge, "$g_talk_troop_relation", 10),
   (this_or_next|neg|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_quarrelsome),
    (neg|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_martial),
   ],
   "Why would you say such a thing? To insult me like this, in spite of our friendship -- how much crueler is a knife in my back from an erstwhile friends, than the sword of a sworn foe. I do not know what game you are playing, but I want no part of it. Go away. I do not want to look at you.", "close_window",[
   (call_script, "script_succeed_quest", "qst_denounce_lord"),
 
   (try_begin),
     (quest_get_slot, ":giver_troop", "qst_denounce_lord", slot_quest_giver_troop),
     (eq, ":giver_troop", "$g_talk_troop"),
     (call_script, "script_end_quest", "qst_denounce_lord"),
   (try_end),
   ]],
 
   [anyone,"lord_denounce_3", [
   (troop_slot_ge, "trp_player", slot_troop_renown, 300),
   (this_or_next|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_cunning),
   (this_or_next|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_upstanding),
    (troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_goodnatured),
   ],
   "Hmf. Really? Is that your opinion, or did one of my rivals put those words in your mouth? Never mind. I will not play your game. Go away, and take your intrigues with you.", "close_window",[
   (call_script, "script_succeed_quest", "qst_denounce_lord"),
 
   (try_begin),
     (quest_get_slot, ":giver_troop", "qst_denounce_lord", slot_quest_giver_troop),
     (eq, ":giver_troop", "$g_talk_troop"),
     (call_script, "script_end_quest", "qst_denounce_lord"),
   (try_end),
   ]],

   [anyone,"lord_denounce_3", [
   (this_or_next|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_martial),
   (this_or_next|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_cunning),
   (this_or_next|troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_upstanding),
    (troop_slot_eq, "$g_talk_troop", slot_lord_reputation_type, lrep_goodnatured),
   ],
   "I will not have you shame me in public, {sir/my lady}. Retract your words, or meet me on the duelling ground.", "lord_denounce_4",[
   ]],
 
   [anyone,"lord_denounce_3", [
   ],
   "Is that so? Well, hear this -- you're a snake, and a knave, and -- if you don't meet me on the duelling ground -- a coward. What say you to that? Do you retract your words, or shall we cross swords?", "lord_denounce_4",[
   ]],
 
   [anyone|plyr,"lord_denounce_4", [
   ],
   "It would be a pleasure to fight you.", "lord_respond_to_insult_challenge_duel_confirm",[
   ]],

   [anyone|plyr,"lord_denounce_4", [
   ],
   "I spoke rashly. I retract my words.", "lord_denounce_retract",[
   (call_script, "script_fail_quest", "qst_denounce_lord"),
 
   (try_begin),
     (quest_get_slot, ":giver_troop", "qst_denounce_lord", slot_quest_giver_troop),
     (eq, ":giver_troop", "$g_talk_troop"),
     (call_script, "script_end_quest", "qst_denounce_lord"),
   (try_end),

   ]],
 
   [anyone,"lord_denounce_retract", [
   ],
   "I thought as much. Now, be gone from here.", "lord_pretalk",[
   ]],

It will look a bit weird and might not work 100% of the time but I particularly enjoyed barging into one of my ally's castles and insulting him out of nowhere about his cruel and tyrannical ways, so I'd say it's worth it :grin:

edited to not allow insulting your spouse (why would you do that anyways?)
 
Last edited:
Back
Top Bottom