Arris Rumi
Recruit
Hi everybody,
As the title says, this OSP implements some basic sorting for Warband. Now you can sort by troop level, faction or class (infantry, archer, any custom class, etc.), and even combine a few of them. This is very useful for when you have all kinds of troops and just want some order, to help you decide what troops will enter battle first, and even in some mods that have many factions and tens of troops types. This is an OSP, so you can use it freely as long as credit is given. The complete files are in this github.
The OSP includes a new presentation, a new entry in the "take action" submenu of the Camping menu, some new scripts for sorting, and a couple of temp troops that work as extra arrays.
The presentation:
The new scripts:
New submenu (included in "camp_action"):
A couple more temp arrays as new troops:
(Operation instructions and images in next post)
As the title says, this OSP implements some basic sorting for Warband. Now you can sort by troop level, faction or class (infantry, archer, any custom class, etc.), and even combine a few of them. This is very useful for when you have all kinds of troops and just want some order, to help you decide what troops will enter battle first, and even in some mods that have many factions and tens of troops types. This is an OSP, so you can use it freely as long as credit is given. The complete files are in this github.
The OSP includes a new presentation, a new entry in the "take action" submenu of the Camping menu, some new scripts for sorting, and a couple of temp troops that work as extra arrays.
The presentation:
Python:
#Arris
("sort_troops", 0, mesh_load_window,[
(ti_on_presentation_load,
[
(presentation_set_duration,999999),
(set_fixed_point_multiplier, 1000),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_c", ":i", 0), #factions in party
(try_end),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_d", ":i", -1), #classes in party
(try_end),
(assign, "$g_st_param_asc", 0),
(assign, "$g_st_param_fixcomp", 0),
(party_get_num_companion_stacks , ":num_stacks", "p_main_party"),
#list factions in party
(assign, ":indx_faction", -1),
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, ":troop", "p_main_party", ":i"),
(store_troop_faction, reg0, ":troop"),
(assign, ":flag_found", 0),
(try_for_range, ":i", 0, 100),
(troop_get_slot, ":temp1", "trp_temp_array_c", ":i"),
(try_begin),
(eq, ":temp1", reg0),
(assign, ":flag_found", 1),
(try_end),
(try_end),
(try_begin),
(neq, ":flag_found", 1),
(val_add, ":indx_faction", 1),
(troop_set_slot, "trp_temp_array_c", ":indx_faction", reg0),
(try_end),
(try_end),
(store_add, "$tot_factions", ":indx_faction", 1),
#list classes in party
(assign, ":indx_class", -1),
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, ":troop", "p_main_party", ":i"),
(troop_get_class, reg0, ":troop"),
(assign, ":flag_found", 0),
(try_for_range, ":i", 0, 100),
(troop_get_slot, ":temp1", "trp_temp_array_d", ":i"),
(try_begin),
(eq, ":temp1", reg0),
(assign, ":flag_found", 1),
(try_end),
(try_end),
(try_begin),
(neq, ":flag_found", 1),
(val_add, ":indx_class", 1),
(troop_set_slot, "trp_temp_array_d", ":indx_class", reg0),
(try_end),
(try_end),
(store_add, "$tot_classes", ":indx_class", 1),
#indx elems to exchange
(assign, "$g_elem1", -1), (assign, "$g_elem2", -1), (assign, "$g_elem3", -1), (assign, "$g_elem4", -1),
#Title
(create_text_overlay, "$g_presentation_obj_16","@Sort your Troops",tf_center_justify),
(position_set_x, pos1, 500), (position_set_y, pos1, 650),
(overlay_set_position, "$g_presentation_obj_16", pos1),
(position_set_x, pos2,1200), (position_set_y, pos2,1200),
(overlay_set_size,"$g_presentation_obj_16",pos2),
# Button Return
(create_game_button_overlay,"$g_st_cancel","@_Return_",tf_center_justify),
(position_set_x, pos1, 500),(position_set_y, pos1, 50),
(overlay_set_position, "$g_st_cancel", pos1),
# Button Sort by Level
(create_game_button_overlay,"$g_st_sort_lvl","@By Level",tf_center_justify),
(position_set_x, pos1, 500),(position_set_y, pos1, 570),
(overlay_set_position, "$g_st_sort_lvl", pos1),
# Button Sort by Faction
(create_game_button_overlay,"$g_st_sort_fac","@By Faction",tf_center_justify),
(position_set_x, pos1, 500),(position_set_y, pos1, 520),
(overlay_set_position, "$g_st_sort_fac", pos1),
# Button Sort by Classes
(create_game_button_overlay,"$g_st_sort_class","@By Class",tf_center_justify),
(position_set_x, pos1, 500),(position_set_y, pos1, 470),
(overlay_set_position, "$g_st_sort_class", pos1),
#Checkbox Asc/Desc
(create_check_box_overlay, "$g_st_asc", "mesh_checkbox_off", "mesh_checkbox_on"),
(position_set_x, pos1, 600),(position_set_y, pos1, 585),
(overlay_set_position, "$g_st_asc", pos1),
#Label Ascending
(create_text_overlay, reg0, "@Ascending"),
(position_set_x, pos1, 630),(position_set_y, pos1, 580),
(overlay_set_position, reg0, pos1),
#Checkbox Fix Companions
(create_check_box_overlay, "$g_st_fix", "mesh_checkbox_off", "mesh_checkbox_on"),
(position_set_x, pos1, 430),(position_set_y, pos1, 430),
(overlay_set_position, "$g_st_fix", pos1),
#Label Fix Companions
(create_text_overlay, reg0, "@Fixed Companions"),
(position_set_x, pos1, 460),(position_set_y, pos1, 425),
(overlay_set_position, reg0, pos1),
#Label faction order
(create_text_overlay, reg0, "@Faction Order"),
(position_set_x, pos1, 180),(position_set_y, pos1, 380),
(overlay_set_position, reg0, pos1),
#Faction List
(str_clear, s0),
(create_text_overlay, ":list_factions", s0, tf_scrollable),
(position_set_x, pos1, 140), (position_set_y, pos1, 120),
(overlay_set_position, ":list_factions", pos1),
(position_set_x, pos1, 300), (position_set_y, pos1, 3000), #later adjust y to fit #buttons exactly
(overlay_set_size, ":list_factions", pos1),
(position_set_x, pos1, 230), (position_set_y, pos1, 250),
(overlay_set_area_size, ":list_factions", pos1),
(set_container_overlay, ":list_factions"),
(assign, ":x_pos", 80), (assign, ":y_pos", 2900),
(try_for_range, ":i", 0, "$tot_factions"),
(troop_get_slot, ":id_faction", "trp_temp_array_c", ":i"),
(str_store_faction_name, s0, ":id_faction"),
(create_game_button_overlay, reg1 , "@{s0}", tf_center_justify),
(try_begin),
(eq, ":i", 0),
(assign, "$first_faction_btn", reg1),
(try_end),
(position_set_x, pos3, ":x_pos"), (position_set_y, pos3, ":y_pos"),
(overlay_set_position, reg1, pos3),
(position_set_x, pos3, 200), (position_set_y, pos3, 30),
(overlay_set_size, reg1, pos3),
(val_sub, ":y_pos", 30),
(try_end),
(assign, "$last_faction_btn", reg1),
(set_container_overlay, -1),
#Label Class Order
(create_text_overlay, reg0, "@Class Order"),
(position_set_x, pos1, 620),(position_set_y, pos1, 380),
(overlay_set_position, reg0, pos1),
#Classes List
(str_clear, s0),
(create_text_overlay, ":list_classes", s0, tf_scrollable),
(position_set_x, pos1, 580), (position_set_y, pos1, 120),
(overlay_set_position, ":list_classes", pos1),
(position_set_x, pos1, 300), (position_set_y, pos1, 3000), #later adjust y to fit #buttons exactly
(overlay_set_size, ":list_classes", pos1),
(position_set_x, pos1, 230), (position_set_y, pos1, 250),
(overlay_set_area_size, ":list_classes", pos1),
(set_container_overlay, ":list_classes"),
(assign, ":x_pos", 80), (assign, ":y_pos", 2900),
(try_for_range, ":i", 0, "$tot_classes"),
(troop_get_slot, ":id_class", "trp_temp_array_d", ":i"),
(str_store_class_name, s0, ":id_class"),
(create_game_button_overlay, reg1 , "@{s0}", tf_center_justify),
(try_begin),
(eq, ":i", 0),
(assign, "$first_class_btn", reg1),
(try_end),
(position_set_x, pos3, ":x_pos"), (position_set_y, pos3, ":y_pos"),
(overlay_set_position, reg1, pos3),
(position_set_x, pos3, 200), (position_set_y, pos3, 30),
(overlay_set_size, reg1, pos3),
(val_sub, ":y_pos", 30),
(try_end),
(assign, "$last_class_btn", reg1),
(set_container_overlay, -1),
]),
(ti_on_presentation_event_state_change,
[
(store_trigger_param_1, ":object"),
(store_trigger_param_2, ":value"),
(try_begin),
(eq,"$g_st_cancel",":object"),
(presentation_set_duration,0),
(try_end),
(try_begin),
(eq,"$g_st_asc",":object"),
(assign, "$g_st_param_asc", ":value"),
(try_end),
(try_begin),
(eq,"$g_st_fix",":object"),
(assign, "$g_st_param_fixcomp", ":value"),
(try_end),
(try_begin),
(eq,"$g_st_sort_lvl",":object"),
(call_script, "script_position_companions"),
(call_script, "script_sort_troops_by_level", "$g_st_param_asc"),
(try_begin),
(eq, "$g_st_param_fixcomp" , 1),
(call_script, "script_reinsert_companions"),
(try_end),
(display_message, "@Sorted by level."),
(try_end),
(try_begin),
(eq, "$g_st_sort_fac", ":object"),
(call_script, "script_position_companions"),
(call_script, "script_sort_troops_by_faction"),
(try_begin),
(eq, "$g_st_param_fixcomp" , 1),
(call_script, "script_reinsert_companions"),
(try_end),
(display_message, "@Sorted by faction."),
(try_end),
(try_begin),
(eq, "$g_st_sort_class", ":object"),
(call_script, "script_position_companions"),
(call_script, "script_sort_troops_by_class"),
(try_begin),
(eq, "$g_st_param_fixcomp" , 1),
(call_script, "script_reinsert_companions"),
(try_end),
(display_message, "@Sorted by class."),
(try_end),
#Clicks on faction list
(try_begin),
(ge, ":object", "$first_faction_btn"),
(le, ":object", "$last_faction_btn" ),
(try_begin), #1st click
(eq, "$g_elem1", -1),
(assign, "$g_elem1", ":object"),
(assign, "$g_elem3", -1), (assign, "$g_elem4", -1), #clicks in other list annulled
(store_sub, ":i", "$g_elem1", "$first_faction_btn"),
(troop_get_slot, ":id_faction", "trp_temp_array_c", ":i"),
(str_store_faction_name, s0, ":id_faction"),
(display_message, "@ Swapping {s0} ... "),
(else_try), #2nd click
(assign, "$g_elem2", ":object"),
(store_sub, ":i", "$g_elem2", "$first_faction_btn"),
(troop_get_slot, ":id_faction", "trp_temp_array_c", ":i"),
(str_store_faction_name, s0, ":id_faction"),
(display_message, "@...with {s0}."),
#swapping...
(store_sub, ":i1", "$g_elem1", "$first_faction_btn"),
(store_sub, ":i2", "$g_elem2", "$first_faction_btn"),
(troop_get_slot, ":temp1", "trp_temp_array_c", ":i1"),
(troop_get_slot, ":temp2", "trp_temp_array_c", ":i2"),
(troop_set_slot, "trp_temp_array_c", ":i2", ":temp1"),
(troop_set_slot, "trp_temp_array_c", ":i1", ":temp2"),
(try_for_range, ":i", 0, "$tot_factions"),
(troop_get_slot, ":id_faction", "trp_temp_array_c", ":i"),
(str_store_faction_name, s0, ":id_faction"),
(store_add, reg0, "$first_faction_btn", ":i"),
(overlay_set_text, reg0, "@{s0}"),
(try_end),
(assign, "$g_elem1", -1),
(try_end),
(try_end),
#Clicks on class list
(try_begin),
(ge, ":object", "$first_class_btn" ),
(le, ":object", "$last_class_btn" ),
(try_begin), #1st click
(eq, "$g_elem3", -1),
(assign, "$g_elem3", ":object"),
(assign, "$g_elem1", -1), (assign, "$g_elem2", -1), #clicks in other list annulled
(store_sub, ":i", "$g_elem3", "$first_class_btn"),
(troop_get_slot, ":id_class", "trp_temp_array_d", ":i"),
(str_store_class_name, s0, ":id_class"),
(display_message, "@ Swapping {s0} ... "),
(else_try), #2nd click
(assign, "$g_elem4", ":object"),
(store_sub, ":i", "$g_elem4", "$first_class_btn"),
(troop_get_slot, ":id_class", "trp_temp_array_d", ":i"),
(str_store_class_name, s0, ":id_class"),
(display_message, "@...with {s0}."),
#swapping...
(store_sub, ":i1", "$g_elem3", "$first_class_btn"),
(store_sub, ":i2", "$g_elem4", "$first_class_btn"),
(troop_get_slot, ":temp1", "trp_temp_array_d", ":i1"),
(troop_get_slot, ":temp2", "trp_temp_array_d", ":i2"),
(troop_set_slot, "trp_temp_array_d", ":i2", ":temp1"),
(troop_set_slot, "trp_temp_array_d", ":i1", ":temp2"),
(try_for_range, ":i", 0, "$tot_classes"),
(troop_get_slot, ":id_class", "trp_temp_array_d", ":i"),
(str_store_class_name, s0, ":id_class"),
(store_add, reg0, "$first_class_btn", ":i"),
(overlay_set_text, reg0, "@{s0}"),
(try_end),
(assign, "$g_elem3", -1),
(try_end),
(try_end),
]),
]),
The new scripts:
Python:
#Arris
#Sort troops in main party by level.
#param - 0:descending, 1:ascending
("sort_troops_by_level",
[
(store_script_param, ":ascending", 1),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_a", ":i", 0), #troop id
(try_end),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_b", ":i", 0), # number troops
(try_end),
(party_get_num_companion_stacks , ":num_stacks_original", "p_main_party"),
(try_for_range, ":i", 1, ":num_stacks_original"),
(party_get_num_companion_stacks , ":num_stacks_current", "p_main_party"),
(assign, ":indx_candidate", 1),
(try_begin),
(eq, ":ascending", 0),
(assign, ":lvl_candidate", 0),
(else_try),
(assign, ":lvl_candidate", 1000),
(try_end),
(try_for_range, ":j", 1, ":num_stacks_current"),
(party_stack_get_troop_id, ":troop_a", "p_main_party", ":j"),
(store_character_level, ":lvl_a", ":troop_a"),
(try_begin),
(eq, ":ascending", 0),
(gt, ":lvl_a", ":lvl_candidate"),
(assign, ":lvl_candidate", ":lvl_a"),
(assign, ":indx_candidate", ":j"),
(else_try),
(eq, ":ascending", 1),
(lt, ":lvl_a", ":lvl_candidate"),
(assign, ":lvl_candidate", ":lvl_a"),
(assign, ":indx_candidate", ":j"),
(try_end),
(try_end),
(party_stack_get_troop_id, ":troop_s", "p_main_party", ":indx_candidate"),
(party_stack_get_size, ":size_s", "p_main_party", ":indx_candidate"),
(troop_set_slot, "trp_temp_array_a", ":i", ":troop_s"),
(troop_set_slot, "trp_temp_array_b", ":i", ":size_s"),
(party_remove_members, "p_main_party", ":troop_s", ":size_s"),
(try_end),
(try_for_range, ":i", 0, ":num_stacks_original"),
(troop_get_slot, reg0, "trp_temp_array_a", ":i"),
(troop_get_slot, reg1, "trp_temp_array_b", ":i"),
(party_add_members, "p_main_party", reg0, reg1),
(try_end),
]
),
#Arris
# Sort troops in main party by faction.
# Faction order is in trp_temp_array_c
# Limit reading of trp_temp_array_c "array" with $tot_factions
("sort_troops_by_faction",
[
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_a", ":i", 0), #troop id
(try_end),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_b", ":i", 0), # number troops
(try_end),
(assign, ":indx_temp", -1),
(party_get_num_companion_stacks , ":num_stacks", "p_main_party"),
(try_for_range,":indx", 0, "$tot_factions"), #for each faction, select
(troop_get_slot, ":id_faction", "trp_temp_array_c", ":indx"),
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, ":troop", "p_main_party", ":i"),
(store_troop_faction, reg0, ":troop"),
#if match, copy troop id, size to temps.
(try_begin),
(eq, reg0, ":id_faction"),
(val_add, ":indx_temp", 1),
(party_stack_get_troop_id, ":troop_f", "p_main_party", ":i"),
(party_stack_get_size, ":size", "p_main_party", ":i"),
(troop_set_slot, "trp_temp_array_a", ":indx_temp", ":troop_f"),
(troop_set_slot, "trp_temp_array_b", ":indx_temp", ":size"),
(try_end),
(try_end),
(try_end),
#delete all minus player
(try_for_range, ":i", 0, ":num_stacks"),
(troop_get_slot, reg0, "trp_temp_array_a", ":i"),
(troop_get_slot, reg1, "trp_temp_array_b", ":i"),
(party_remove_members, "p_main_party", reg0, reg1),
(try_end),
#add troops following order from temp a and b.
(try_for_range, ":i", 0, ":num_stacks"),
(troop_get_slot, reg0, "trp_temp_array_a", ":i"),
(troop_get_slot, reg1, "trp_temp_array_b", ":i"),
(party_add_members, "p_main_party", reg0, reg1),
(try_end),
]),
#Arris
# Sort troops in main party by class.
# Class order is in trp_temp_array_d
# Limit reading of trp_temp_array_d "array" with $tot_classes
("sort_troops_by_class",
[
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_a", ":i", 0), #troop id
(try_end),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_b", ":i", 0), # number troops
(try_end),
(assign, ":indx_temp", -1),
(party_get_num_companion_stacks , ":num_stacks", "p_main_party"),
(try_for_range,":indx", 0, "$tot_classes"), #for each class, select
(troop_get_slot, ":id_class", "trp_temp_array_d", ":indx"),
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, ":troop", "p_main_party", ":i"),
(troop_get_class, reg0, ":troop"),
#if match, copy troop id, size to temps.
(try_begin),
(eq, reg0, ":id_class"),
(val_add, ":indx_temp", 1),
(party_stack_get_troop_id, ":troop_c", "p_main_party", ":i"),
(party_stack_get_size, ":size", "p_main_party", ":i"),
(troop_set_slot, "trp_temp_array_a", ":indx_temp", ":troop_c"),
(troop_set_slot, "trp_temp_array_b", ":indx_temp", ":size"),
(try_end),
(try_end),
(try_end),
#delete all minus player
(try_for_range, ":i", 0, ":num_stacks"),
(troop_get_slot, reg0, "trp_temp_array_a", ":i"),
(troop_get_slot, reg1, "trp_temp_array_b", ":i"),
(party_remove_members, "p_main_party", reg0, reg1),
(try_end),
#add troops following order from temp a and b.
(try_for_range, ":i", 0, ":num_stacks"),
(troop_get_slot, reg0, "trp_temp_array_a", ":i"),
(troop_get_slot, reg1, "trp_temp_array_b", ":i"),
(party_add_members, "p_main_party", reg0, reg1),
(try_end),
]),
#Arris
# Reinserts companions in ordered party
# in their original places.
# Uses trp_temp_array_e for companion position info.
("reinsert_companions",
[
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_a", ":i", 0), #troop id
(try_end),
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_b", ":i", 0), # number troops
(try_end),
(party_get_num_companion_stacks , ":num_stacks", "p_main_party"),
#copy main_party a temp, with no companions
(assign, ":indx_temp", -1),
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, ":troop", "p_main_party", ":i"),
(party_stack_get_size, ":size", "p_main_party", ":i"),
(try_begin),
(troop_is_hero, ":troop"),
(else_try),
(val_add, ":indx_temp", 1),
(troop_set_slot, "trp_temp_array_a", ":indx_temp", ":troop"),
(troop_set_slot, "trp_temp_array_b", ":indx_temp", ":size"),
(try_end),
(try_end),
#delete all minus player in main_party
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, reg0, "p_main_party", 1),
(party_stack_get_size, reg1, "p_main_party", 1),
(party_remove_members, "p_main_party", reg0, reg1),
(try_end),
#recopy from temp_e to main_party, intercalating companions at recorded position
(assign, ":indx_temp", -1),
(try_for_range, ":i", 1, ":num_stacks"),
(try_begin),
(troop_get_slot, ":troop", "trp_temp_array_e", ":i"),
(neq, ":troop", -1),
(party_add_members, "p_main_party", ":troop", 1),
(else_try),
(val_add, ":indx_temp", 1),
(troop_get_slot, reg0, "trp_temp_array_a", ":indx_temp"),
(troop_get_slot, reg1, "trp_temp_array_b", ":indx_temp"),
(party_add_members, "p_main_party", reg0, reg1),
(try_end),
(try_end),
]),
# Arris
# Compile companion's positions in main party
# Stored in trp_temp_array_e
("position_companions",
[
(try_for_range, ":i", 0, 100),
(troop_set_slot, "trp_temp_array_e", ":i", -1),
(try_end),
(party_get_num_companion_stacks , ":num_stacks", "p_main_party"),
(try_for_range, ":i", 1, ":num_stacks"),
(party_stack_get_troop_id, ":troop", "p_main_party", ":i"),
(try_begin),
(troop_is_hero, ":troop"),
(troop_set_slot, "trp_temp_array_e", ":i", ":troop"),
(try_end),
(try_end),
]),
New submenu (included in "camp_action"):
Python:
#Arris
("action_sort_troops",
[
(party_get_num_companions, reg0, "p_main_party"),
(gt, reg0, 1),
],
"Sort troops.",
[
(start_presentation, "prsnt_sort_troops"),
]
),
A couple more temp arrays as new troops:
Code:
["temp_array_d","{!}temp_array_d","{!}temp_array_d",tf_hero|tf_inactive, 0,reserved, fac_neutral,[],def_attrib|level(18),wp(60),knows_common, 0], #Arris
["temp_array_e","{!}temp_array_e","{!}temp_array_e",tf_hero|tf_inactive, 0,reserved, fac_neutral,[],def_attrib|level(18),wp(60),knows_common, 0], #Arris
(Operation instructions and images in next post)
Last edited: