OSP Code QoL Advanced Soldier Management in Exchange Screens

Leonion

Master Knight
Best answers
0
Nothing too special, I just figured out a workaround to add more "operations" to soldier exchange screens that could save a lot of time for players.
First, video presentation:
Second, a copy of video description listing new "operations":
1) Taking all prisoners that your party can accommodate - select [top] prisoner stack, hold LEFT CTRL and A, click "capture" (CTRL+A is a common hotkey combination used to "select all).
2) Taking all members that your party can accommodate - select [top] soldier stack, hold LEFT CTRL and S, click "hire" (S is for "save").
3) Putting all prisoners into garrison - select [any] prisoner stack, hold LEFT CTRL and D, click "give".
4) Taking all prisoners from garrison that your party can accommodate - select [any] prisoner stack, hold LEFT CTRL and A, click "take".
5) Putting all soldiers into garrison - select [any] soldier stack, hold RIGHT CTRL and ARROW LEFT, click "give" (arrow left indicates direction - from the right part of the screen to the left).
6) Taking all soldiers from garrison that your party can accommodate - select [any] soldier stack, hold RIGHT CTRL and ARROW RIGHT, click "take" (arrow right indicates direction - from the left part of the screen to the right).
7) Moving a stack 1 position down inside garrison - select the particular soldier stack, hold ARROW DOWN, click "take".
:cool: Moving a stack 1 position up inside garrison - select the particular soldier stack, hold ARROW UP, click "take".
9) Moving a stack to the top of garrison - select the particular soldier stack, hold PAGE UP, click "take".
10) Moving a stack to the bottom of garrison - select the particular soldier stack, hold PAGE DOWN, click "take".
Controls 7-10 do not work if thee is only 1 soldier in the stack.
Third, the idea.
The idea is using game_get_troop_wage script called from game engine when you (1) click on any soldier (not prisoner) in soldier exchange screen, (2) when you just open this screen, (3) when you refresh this screen by clicking "hire"/"give"/etc. button. In the first case the game only calls this script for 1 soldier, in cases 2 and 3 it "refreshes" all soldiers seen on party exchange screen. Ordinary triggers just don't seem to work in this screen, so piggybacking is the only way I could come up with.
Forth, the main script code:
https://pastebin.com/JinZqRVd
Fifth, the instruction on adding it:
Introduction: to control's the script's activity we need either a couple of global variables or some unused troop whose slots are specifically used as a replacement for global variables.
Personally, I prefer the second as being less risky and more save-compatible. That's why in Perisno (where this script was created and tested) I use a certain trp_globals_troop. You can CTRL+H mass-replace it with your own "slot-only" troop or rewrite the conditions to work with global variables.
Now, the main part.
1) Add the main script to module_scripts file.
2) Find the script "game_get_troop_wage". Right after store_script_param-s insert these 2 lines in this exact order:
Code:
	  (call_script, "script_initialize_exchange_screen_extensions", ":troop_id"),
	  (troop_set_slot, "trp_globals_troop", slot_last_requested_troop, ":troop_id"),
3) In module_game_menus find (change_screen_exchange_with_party, "p_temp_party"), in total_victory menu and add the following right before it:
Code:
(troop_set_slot, "trp_globals_troop", slot_adv_transfer_mode, 10),
I also recommend calling sorting scripts (to sort troops and prisoners in p_temp_party by level) at this point if you have any in your module system.
4) In module_game_menus find Manage the garrison option and the respective operation (change_screen_exchange_members,1),. Insert the following right before this operation:
Code:
(troop_set_slot, "trp_globals_troop", slot_adv_transfer_mode, 12),
5) There are multiple ways to do, but I prefer using ti_on_switch_to_map trigger which I find very helpful. So add this new trigger to module_triggers or piggyback this operation to an already used ti_on_switch_to_map trigger:
Code:
(0,0, ti_on_switch_to_map, [],
  [
	   (troop_set_slot, "trp_globals_troop", slot_adv_transfer_mode, 0),
  ]
),
This is an idiot-proof precaution to prevent hotkeys from working in any other exchange screen but post-victory screen and garrison exchange screen.
6) Finally, add these constants to module_constant file:
Code:
slot_last_requested_troop = 11 #related to slot_adv_transfer_mode 12
slot_adv_transfer_mode = 12 #10 for prisoners, 12 for fiefs
Or turn them into global variables and rewrite this part if you want to.
 

imado552

Sergeant at Arms
Best answers
0
Leonion said:
Nothing too special, I just figured out a workaround to add more "operations" to soldier exchange screens that could save a lot of time for players.
First, video presentation:
Second, a copy of video description listing new "operations":
1) Taking all prisoners that your party can accommodate - select [top] prisoner stack, hold LEFT CTRL and A, click "capture" (CTRL+A is a common hotkey combination used to "select all).
2) Taking all members that your party can accommodate - select [top] soldier stack, hold LEFT CTRL and S, click "hire" (S is for "save").
3) Putting all prisoners into garrison - select [any] prisoner stack, hold LEFT CTRL and D, click "give".
4) Taking all prisoners from garrison that your party can accommodate - select [any] prisoner stack, hold LEFT CTRL and A, click "take".
5) Putting all soldiers into garrison - select [any] soldier stack, hold RIGHT CTRL and ARROW LEFT, click "give" (arrow left indicates direction - from the right part of the screen to the left).
6) Taking all soldiers from garrison that your party can accommodate - select [any] soldier stack, hold RIGHT CTRL and ARROW RIGHT, click "take" (arrow right indicates direction - from the left part of the screen to the right).
7) Moving a stack 1 position down inside garrison - select the particular soldier stack, hold ARROW DOWN, click "take".
:cool: Moving a stack 1 position up inside garrison - select the particular soldier stack, hold ARROW UP, click "take".
9) Moving a stack to the top of garrison - select the particular soldier stack, hold PAGE UP, click "take".
10) Moving a stack to the bottom of garrison - select the particular soldier stack, hold PAGE DOWN, click "take".
Controls 7-10 do not work if thee is only 1 soldier in the stack.
Third, the idea.
The idea is using game_get_troop_wage script called from game engine when you (1) click on any soldier (not prisoner) in soldier exchange screen, (2) when you just open this screen, (3) when you refresh this screen by clicking "hire"/"give"/etc. button. In the first case the game only calls this script for 1 soldier, in cases 2 and 3 it "refreshes" all soldiers seen on party exchange screen. Ordinary triggers just don't seem to work in this screen, so piggybacking is the only way I could come up with.
Forth, the main script code:
Code:
  ("initialize_exchange_screen_extensions",
    [
	(store_script_param, ":troop_id", 1),
	
	(try_begin), #MASS PRISONER TRANSFER AFTER BATTLE
		(key_is_down, key_left_control), (key_is_down, key_a),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 10),
		(party_get_num_prisoner_stacks, ":num_prisoner_stacks","p_temp_party"),
		(assign, ":stop_stack", -1),
		(assign, ":stop_no", -1),
		(try_for_range, ":stack_no", 0, ":num_prisoner_stacks"),
			(eq, ":stop_stack", -1),
			(party_get_free_prisoners_capacity, ":player_prisoner_capacity", "p_main_party"),
			(party_prisoner_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_prisoner_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(try_begin),
				(ge, ":player_prisoner_capacity", ":stack_size"),
				(party_add_prisoners, "p_main_party", ":stack_troop", ":stack_size"),
			(else_try),	
				(party_add_prisoners, "p_main_party", ":stack_troop", ":player_prisoner_capacity"),
				(assign, ":stop_stack", ":stack_no"),
				(assign, ":stop_no", ":player_prisoner_capacity"),
			(try_end),
		(try_end),
		(try_begin),
			(neq, ":stop_stack", -1),
			(store_add, ":stop_stack_plus_one", ":stop_stack", 1),
		(else_try),	
			(assign, ":stop_stack_plus_one", ":num_prisoner_stacks"),
		(try_end),
		(try_for_range_backwards, ":stack_no", 0, ":stop_stack_plus_one"),
			(party_prisoner_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_prisoner_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(try_begin),
				(neq, ":stop_no", -1),
				(eq, ":stack_no", ":stop_stack"),
				(party_remove_prisoners, "p_temp_party", ":stack_troop", ":stop_no"),
			(else_try),	
				(party_remove_prisoners, "p_temp_party", ":stack_troop", ":stack_size"),
			(try_end),
		(try_end),
	(try_end),
	#++++++++++++++++++++++++++++++++++++++++++++++++ MASS TRANSFER OF RESCUED PRISONERS AFTER BATTLE
	(try_begin), 
		#(display_message, "@Working!"),
		(key_is_down, key_left_control), (key_is_down, key_s),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 10),
		(party_get_num_companion_stacks, ":num_companion_stacks","p_temp_party"),
		(assign, ":stop_stack", -1),
		(assign, ":stop_no", -1),
		(try_for_range, ":stack_no", 0, ":num_companion_stacks"),
			(eq, ":stop_stack", -1),
			(party_get_free_companions_capacity, ":player_companion_capacity", "p_main_party"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(try_begin),
				(ge, ":player_companion_capacity", ":stack_size"),
				(party_add_members, "p_main_party", ":stack_troop", ":stack_size"),
			(else_try),	
				(party_add_members, "p_main_party", ":stack_troop", ":player_companion_capacity"),
				(assign, ":stop_stack", ":stack_no"),
				(assign, ":stop_no", ":player_companion_capacity"),
			(try_end),
		(try_end),
		(try_begin),
			(neq, ":stop_stack", -1),
			(store_add, ":stop_stack_plus_one", ":stop_stack", 1),
		(else_try),	
			(assign, ":stop_stack_plus_one", ":num_companion_stacks"),
		(try_end),
		(try_for_range_backwards, ":stack_no", 0, ":stop_stack_plus_one"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(try_begin),
				(neq, ":stop_no", -1),
				(eq, ":stack_no", ":stop_stack"),
				(party_remove_members, "p_temp_party", ":stack_troop", ":stop_no"),
			(else_try),	
				(party_remove_members, "p_temp_party", ":stack_troop", ":stack_size"),
			(try_end),
		(try_end),
	(try_end),
	#++++++++++++++++++++++++++++++++++++++++++++++++ SORTING GARRISONS
	(try_begin), #ARROW UP
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_last_requested_troop, ":troop_id"),
		(key_is_down, key_up),
		(party_clear, "p_temp_party"),
		(call_script, "script_party_add_party_companions", "p_temp_party", "$current_town"),
		(party_get_num_companion_stacks, ":num_stacks","$current_town"),
		(assign, ":key_stack", -1),
		(try_for_range, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(try_begin),
				(eq, ":stack_troop", ":troop_id"),
				(neq, ":stack_no", 0), #key_up can't be used with stack 0
				(assign, ":key_stack", ":stack_no"),
			(try_end),
		(try_end),
		(neq, ":key_stack", -1),
		(try_for_range_backwards, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(party_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(party_remove_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(store_sub, ":key_stack_minus_one", ":key_stack", 1),
		(store_add, ":key_stack_plus_one", ":key_stack", 1),
		(try_for_range, ":stack_no", 0, ":key_stack_minus_one"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_stack_get_troop_id, ":stack_troop","p_temp_party",":key_stack"),
		(party_stack_get_size, ":stack_size","p_temp_party",":key_stack"),
		(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(party_stack_get_troop_id, ":stack_troop","p_temp_party",":key_stack_minus_one"),
		(party_stack_get_size, ":stack_size","p_temp_party",":key_stack_minus_one"),
		(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_for_range, ":stack_no", ":key_stack_plus_one", ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_remove_members, "p_main_party", ":troop_id", 1),
		(party_add_members, "$current_town", ":troop_id", 1),
	(try_end),
	
	(try_begin), #ARROW DOWN
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_last_requested_troop, ":troop_id"),
		(key_is_down, key_down),
		(party_clear, "p_temp_party"),
		(call_script, "script_party_add_party_companions", "p_temp_party", "$current_town"),
		(party_get_num_companion_stacks, ":num_stacks","$current_town"),
		(store_sub, ":num_stacks_minus_one", ":num_stacks", 1),
		(assign, ":key_stack", -1),
		(try_for_range, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(try_begin),
				(eq, ":stack_troop", ":troop_id"),
				(neq, ":stack_no", ":num_stacks_minus_one"), #key_down can't be used with last stack
				(assign, ":key_stack", ":stack_no"),
			(try_end),
		(try_end),
		(neq, ":key_stack", -1),
		(try_for_range_backwards, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(party_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(party_remove_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(store_add, ":key_stack_plus_one", ":key_stack", 1),
		(store_add, ":key_stack_plus_two", ":key_stack", 2),
		(try_for_range, ":stack_no", 0, ":key_stack"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_stack_get_troop_id, ":stack_troop","p_temp_party",":key_stack_plus_one"),
		(party_stack_get_size, ":stack_size","p_temp_party",":key_stack_plus_one"),
		(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(party_stack_get_troop_id, ":stack_troop","p_temp_party",":key_stack"),
		(party_stack_get_size, ":stack_size","p_temp_party",":key_stack"),
		(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_for_range, ":stack_no", ":key_stack_plus_two", ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_remove_members, "p_main_party", ":troop_id", 1),
		(party_add_members, "$current_town", ":troop_id", 1),
	(try_end),
	
	(try_begin), #PAGE UP
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_last_requested_troop, ":troop_id"),
		(key_is_down, key_page_up),
		(party_clear, "p_temp_party"),
		(call_script, "script_party_add_party_companions", "p_temp_party", "$current_town"),
		(party_get_num_companion_stacks, ":num_stacks","$current_town"),
		(assign, ":key_stack", -1),
		(try_for_range, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(try_begin),
				(eq, ":stack_troop", ":troop_id"),
				(neq, ":stack_no", 0), #key_page_up can't be used with stack 0
				(assign, ":key_stack", ":stack_no"),
			(try_end),
		(try_end),
		(neq, ":key_stack", -1),
		(try_for_range_backwards, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(party_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(party_remove_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_stack_get_troop_id, ":stack_troop","p_temp_party",":key_stack"),
		(party_stack_get_size, ":stack_size","p_temp_party",":key_stack"),
		(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_for_range, ":stack_no", 0, ":num_stacks"),
			(neq, ":stack_no", ":key_stack"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_remove_members, "p_main_party", ":troop_id", 1),
		(party_add_members, "$current_town", ":troop_id", 1),
	(try_end),
	
	(try_begin), #PAGE DOWN
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_last_requested_troop, ":troop_id"),
		(key_is_down, key_page_down),
		(party_clear, "p_temp_party"),
		(call_script, "script_party_add_party_companions", "p_temp_party", "$current_town"),
		(party_get_num_companion_stacks, ":num_stacks","$current_town"),
		(store_sub, ":num_stacks_minus_one", ":num_stacks", 1),
		(assign, ":key_stack", -1),
		(try_for_range, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(try_begin),
				(eq, ":stack_troop", ":troop_id"),
				(neq, ":stack_no", ":num_stacks_minus_one"), #key_down can't be used with last stack
				(assign, ":key_stack", ":stack_no"),
			(try_end),
		(try_end),
		(neq, ":key_stack", -1),
		(try_for_range_backwards, ":stack_no", 0, ":num_stacks"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(party_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(party_remove_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(try_for_range, ":stack_no", 0, ":num_stacks"),
			(neq, ":stack_no", ":key_stack"),
			(party_stack_get_troop_id, ":stack_troop","p_temp_party",":stack_no"),
			(party_stack_get_size, ":stack_size","p_temp_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(party_stack_get_troop_id, ":stack_troop","p_temp_party",":key_stack"),
		(party_stack_get_size, ":stack_size","p_temp_party",":key_stack"),
		(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(party_remove_members, "p_main_party", ":troop_id", 1),
		(party_add_members, "$current_town", ":troop_id", 1),
	(try_end),
	#++++++++++++++++++++++++++++++++++++++++++++++++ MASSIVE TRANSFERS TO/FROM GARRISON
	(try_begin), #TROOPS FROM GARRISON TO PLAYER'S PARTY
		(key_is_down, key_right_control), (key_is_down, key_right),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(party_get_num_companion_stacks, ":num_companion_stacks","$current_town"),
		(assign, ":stop_stack", -1),
		(assign, ":stop_no", -1),
		(try_for_range, ":stack_no", 0, ":num_companion_stacks"),
			(eq, ":stop_stack", -1),
			(party_get_free_companions_capacity, ":player_companion_capacity", "p_main_party"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(party_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(try_begin),
				(ge, ":player_companion_capacity", ":stack_size"),
				(party_add_members, "p_main_party", ":stack_troop", ":stack_size"),
			(else_try),	
				(party_add_members, "p_main_party", ":stack_troop", ":player_companion_capacity"),
				(assign, ":stop_stack", ":stack_no"),
				(assign, ":stop_no", ":player_companion_capacity"),
			(try_end),
		(try_end),
		(try_begin),
			(neq, ":stop_stack", -1),
			(store_add, ":stop_stack_plus_one", ":stop_stack", 1),
		(else_try),	
			(assign, ":stop_stack_plus_one", ":num_companion_stacks"),
		(try_end),
		(try_for_range_backwards, ":stack_no", 0, ":stop_stack_plus_one"),
			(party_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(party_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(try_begin),
				(neq, ":stop_no", -1),
				(eq, ":stack_no", ":stop_stack"),
				(party_remove_members, "$current_town", ":stack_troop", ":stop_no"),
			(else_try),	
				(party_remove_members, "$current_town", ":stack_troop", ":stack_size"),
			(try_end),
		(try_end),
	(try_end),
	
	(try_begin), #TROOPS FROM PLAYER'S PARTY TO GARRISON
		(key_is_down, key_right_control), (key_is_down, key_left),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(party_get_num_companion_stacks, ":num_companion_stacks","p_main_party"),
		(try_for_range, ":stack_no", 0, ":num_companion_stacks"),
			(party_stack_get_troop_id, ":stack_troop","p_main_party",":stack_no"),
			(neg|troop_is_hero, ":stack_troop"),
			(party_stack_get_size, ":stack_size","p_main_party",":stack_no"),
			(party_add_members, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(try_for_range_backwards, ":stack_no", 0, ":num_companion_stacks"),
			(party_stack_get_troop_id, ":stack_troop","p_main_party",":stack_no"),
			(neg|troop_is_hero, ":stack_troop"),
			(party_stack_get_size, ":stack_size","p_main_party",":stack_no"),
			(party_remove_members, "p_main_party", ":stack_troop", ":stack_size"),
		(try_end),
	(try_end),
	
	(try_begin), #PRISONERS FROM GARRISON TO PLAYER'S PARTY
		(key_is_down, key_left_control), (key_is_down, key_a),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(party_get_num_prisoner_stacks, ":num_prisoner_stacks","$current_town"),
		(assign, ":stop_stack", -1),
		(assign, ":stop_no", -1),
		(try_for_range, ":stack_no", 0, ":num_prisoner_stacks"),
			(eq, ":stop_stack", -1),
			(party_get_free_prisoners_capacity, ":player_prisoner_capacity", "p_main_party"),
			(party_prisoner_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(neg|troop_is_hero, ":stack_troop"),
			(party_prisoner_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(try_begin),
				(ge, ":player_prisoner_capacity", ":stack_size"),
				(party_add_prisoners, "p_main_party", ":stack_troop", ":stack_size"),
			(else_try),	
				(party_add_prisoners, "p_main_party", ":stack_troop", ":player_prisoner_capacity"),
				(assign, ":stop_stack", ":stack_no"),
				(assign, ":stop_no", ":player_prisoner_capacity"),
			(try_end),
		(try_end),
		(try_begin),
			(neq, ":stop_stack", -1),
			(store_add, ":stop_stack_plus_one", ":stop_stack", 1),
		(else_try),	
			(assign, ":stop_stack_plus_one", ":num_prisoner_stacks"),
		(try_end),
		(try_for_range_backwards, ":stack_no", 0, ":stop_stack_plus_one"),
			(party_prisoner_stack_get_troop_id, ":stack_troop","$current_town",":stack_no"),
			(neg|troop_is_hero, ":stack_troop"),
			(party_prisoner_stack_get_size, ":stack_size","$current_town",":stack_no"),
			(try_begin),
				(neq, ":stop_no", -1),
				(eq, ":stack_no", ":stop_stack"),
				(party_remove_prisoners, "$current_town", ":stack_troop", ":stop_no"),
			(else_try),	
				(party_remove_prisoners, "$current_town", ":stack_troop", ":stack_size"),
			(try_end),
		(try_end),
	(try_end),
	
	(try_begin), #PRISONERS FROM PLAYER'S PARTY TO GARRISON
		(key_is_down, key_left_control), (key_is_down, key_d),
		(troop_slot_eq, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
		(party_get_num_prisoner_stacks, ":num_prisoner_stacks","p_main_party"),
		(try_for_range, ":stack_no", 0, ":num_prisoner_stacks"),
			(party_prisoner_stack_get_troop_id, ":stack_troop","p_main_party",":stack_no"),
			(neg|troop_is_hero, ":stack_troop"),
			(party_prisoner_stack_get_size, ":stack_size","p_main_party",":stack_no"),
			(party_add_prisoners, "$current_town", ":stack_troop", ":stack_size"),
		(try_end),
		(try_for_range_backwards, ":stack_no", 0, ":num_prisoner_stacks"),
			(party_prisoner_stack_get_troop_id, ":stack_troop","p_main_party",":stack_no"),
			(neg|troop_is_hero, ":stack_troop"),
			(party_prisoner_stack_get_size, ":stack_size","p_main_party",":stack_no"),
			(party_remove_prisoners, "p_main_party", ":stack_troop", ":stack_size"),
		(try_end),
	(try_end),
    ]
  ),
Fifth, the instruction on adding it:
Introduction: to control's the script's activity we need either a couple of global variables or some unused troop whose slots are specifically used as a replacement for global variables.
Personally, I prefer the second as being less risky and more save-compatible. That's why in Perisno (where this script was created and tested) I use a certain trp_zann_invasion_troop. You can CTRL+H mass-replace it with your own "slot-only" troop or rewrite the conditions to work with global variables.
Now, the main part.
1) Add the main script to module_scripts file.
2) Find the script "game_get_troop_wage". Right after store_script_param-s insert these 2 lines in this exact order:
Code:
	  (call_script, "script_initialize_exchange_screen_extensions", ":troop_id"),
	  (troop_set_slot, "trp_zann_invasion_troop", slot_last_requested_troop, ":troop_id"),
3) In module_game_menus find (change_screen_exchange_with_party, "p_temp_party"), in total_victory menu and add the following right before it:
Code:
(troop_set_slot, "trp_zann_invasion_troop", slot_adv_transfer_mode, 10),
I also recommend calling sorting scripts (to sort troops and prisoners in p_temp_party by level) at this point if you have any in your module system.
4) In module_game_menus find Manage the garrison option and the respective operation (change_screen_exchange_members,1),. Insert the following right before this operation:
Code:
(troop_set_slot, "trp_zann_invasion_troop", slot_adv_transfer_mode, 12),
5) There are multiple ways to do, but I prefer using ti_on_switch_to_map trigger which I find very helpful. So add this new trigger to module_triggers or piggyback this operation to an already used ti_on_switch_to_map trigger:
Code:
(0,0, ti_on_switch_to_map, [],
  [
	   (troop_set_slot, "trp_zann_invasion_troop", slot_adv_transfer_mode, 0),
  ]
),
This is an idiot-proof precaution to prevent hotkeys from working in any other exchange screen but post-victory screen and garrison exchange screen.
6) Finally, add these constants to module_constant file:
Code:
slot_last_requested_troop = 11 #related to slot_adv_transfer_mode 12
slot_adv_transfer_mode = 12 #10 for prisoners, 12 for fiefs
Or turn them into global variables and rewrite this part if you want to.
thank you for sharing this , it will help a lot since having to click many time is annoying !
 

kalarhan

Python Saint
Count
WBNWVCWF&S
Best answers
9
@Leonion: that is what I call out-of-the-box thinking  :grin:



if only TW would hear us after 7 years and add this to the engine  :dead:, we wouldn't need hacks


 

Leonion

Master Knight
Best answers
0
Updated the main script.
I'm sorry, I totally forgot about party_stack_get_num_wounded / party_wound_members stuff.
 

MitchellD

Veteran
Best answers
0
I'm a bit late to the party, but I only just discovered this and wanted to say that you're an absolute genius. This is pretty much the definition of lateral thinking, I love it!