1616
1717local function is_army_valid_and_returning (army )
1818 local controller = get_top_controller (army .controller )
19- if not controller or controller .goal ~= df .army_controller_goal_type .SITE_INVASION then
20- return false , false
19+ if not controller then return false , false end
20+ if controller .goal == df .army_controller_goal_type .SITE_INVASION then
21+ return true , controller .data .goal_site_invasion .flag .RETURNING_HOME
22+ elseif controller .goal == df .army_controller_goal_type .MAKE_REQUEST then
23+ return true , controller .data .goal_make_request .flag .RETURNING_HOME
2124 end
22- return true , controller .data .goal_site_invasion .flag .RETURNING_HOME
25+ return false , false
26+ end
27+
28+ local function get_hf_army (hf )
29+ if not hf then return end
30+ return df .army .find (hf .info and hf .info .whereabouts and hf .info .whereabouts .army_id or - 1 )
2331end
2432
2533-- need to check all squad positions since some members may have died
@@ -28,7 +36,7 @@ local function get_squad_army(squad)
2836 for _ ,sp in ipairs (squad .positions ) do
2937 local hf = df .historical_figure .find (sp .occupant )
3038 if not hf then goto continue end
31- local army = df . army . find (hf . info and hf . info . whereabouts and hf . info . whereabouts . army_id or - 1 )
39+ local army = get_hf_army (hf )
3240 if army then return army end
3341 :: continue::
3442 end
@@ -58,6 +66,24 @@ function scan_fort_armies()
5866 end
5967 :: continue::
6068 end
69+
70+ if # stuck_armies == 0 then return stuck_armies , nil , nil end
71+
72+ -- prefer returning with a messenger if one is readily available
73+ for _ ,messenger in ipairs (dfhack .units .getUnitsByNobleRole (' Messenger' )) do
74+ local army = get_hf_army (df .historical_figure .find (messenger .hist_figure_id ))
75+ if not army then goto continue end
76+ local valid , returning = is_army_valid_and_returning (army )
77+ if valid then
78+ if returning then
79+ returning_army = {army = army }
80+ else
81+ outbound_army = {army = army }
82+ end
83+ end
84+ :: continue::
85+ end
86+
6187 return stuck_armies , outbound_army , returning_army
6288end
6389
@@ -67,14 +93,14 @@ local function unstick_armies()
6793 if not returning_army then
6894 local instructions = outbound_army
6995 and (' Please wait for %s to complete their objective and run this command again when they are on their way home.' ):format (
70- dfhack .df2console (dfhack .military .getSquadName (outbound_army .squad .id )))
71- or ' Please send a squad out on a mission that will return to the fort, and' ..
96+ outbound_army . squad and dfhack .df2console (dfhack .military .getSquadName (outbound_army .squad .id )) or ' the messenger ' )
97+ or ' Please send a squad or a messenger out on a mission that will return to the fort, and' ..
7298 ' run this command again when they are on the way home.'
73- qerror ((' %d stuck arm %s found, but no returning armies found to rescue them!\n %s' ):format (
74- # stuck_armies , # stuck_armies == 1 and ' y ' or ' ies ' , instructions ))
99+ qerror ((' %d stuck squad %s found, but no returning squads or messengers are available to rescue them!\n %s' ):format (
100+ # stuck_armies , # stuck_armies == 1 and ' ' or ' s ' , instructions ))
75101 return
76102 end
77- local returning_squad_name = dfhack .df2console (dfhack .military .getSquadName (returning_army .squad .id ))
103+ local returning_squad_name = returning_army . squad and dfhack .df2console (dfhack .military .getSquadName (returning_army .squad .id )) or ' the messenger '
78104 for _ ,stuck in ipairs (stuck_armies ) do
79105 print ((' fix/stuck-squad: Squad rescue operation underway! %s is rescuing %s' ):format (
80106 returning_squad_name , dfhack .military .getSquadName (stuck .squad .id )))
0 commit comments