From a6273bc3920d098fe81af1b11cba04938519ee1a Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sat, 11 May 2024 19:15:26 +0300
Subject: [PATCH 34/34] Make dying unit to correctly triggger auto turn done

See RM #586

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/climisc.c |  2 +-
 client/control.c | 40 +++++++++++++++++++++++++++++-----------
 client/control.h |  2 +-
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/client/climisc.c b/client/climisc.c
index b4af1574c3..d7fb89291b 100644
--- a/client/climisc.c
+++ b/client/climisc.c
@@ -97,7 +97,7 @@ void client_remove_unit(struct unit *punit)
   game_remove_unit(&wld, punit);
   punit = NULL;
   if (old > 0 && get_num_units_in_focus() == 0) {
-    unit_focus_advance();
+    unit_focus_advance(TRUE);
   } else if (update) {
     update_unit_pix_label(get_units_in_focus());
     update_unit_info_label(get_units_in_focus());
diff --git a/client/control.c b/client/control.c
index fe9f57d136..46836adb48 100644
--- a/client/control.c
+++ b/client/control.c
@@ -229,6 +229,11 @@ void control_unit_killed(struct unit *punit)
 
   goto_unit_killed(punit);
 
+  if (unit_is_in_focus(punit)
+      && get_num_units_in_focus() == 1) {
+    unit_focus_advance(FALSE);
+  }
+
   unit_list_remove(get_units_in_focus(), punit);
   if (get_num_units_in_focus() < 1) {
     clear_hover_state();
@@ -586,6 +591,8 @@ void unit_focus_add(struct unit *punit)
 **************************************************************************/
 void unit_focus_remove(struct unit *punit)
 {
+  bool keep_in_focus = FALSE;
+
   if (NULL != punit
       && NULL != client.conn.playing
       && unit_owner(punit) != client.conn.playing) {
@@ -607,11 +614,20 @@ void unit_focus_remove(struct unit *punit)
     clear_hover_state();
   }
 
-  current_focus_remove(punit);
-  if (get_num_units_in_focus() > 0) {
-    focus_units_changed();
-  } else {
-    unit_focus_advance();
+  if (get_num_units_in_focus() == 1) {
+    unit_focus_advance(TRUE);
+
+    if (unit_is_in_focus(punit)) {
+      /* Unit was restored to focus (there was no other units to focus to) */
+      keep_in_focus = TRUE;
+    }
+  }
+
+  if (!keep_in_focus) {
+    current_focus_remove(punit);
+    if (get_num_units_in_focus() > 0) {
+      focus_units_changed();
+    }
   }
 }
 
@@ -667,8 +683,10 @@ static struct unit *find_best_focus_candidate(bool accept_current)
   called when user press the "Wait" command.
  
   FIXME: Add feature to focus only units of a certain category.
+
+  @param accept_current The current focus can be kept if no other candidates
 **************************************************************************/
-void unit_focus_advance(void)
+void unit_focus_advance(bool accept_current)
 {
   struct unit *candidate = NULL;
   const int num_units_in_old_focus = get_num_units_in_focus();
@@ -685,7 +703,7 @@ void unit_focus_advance(void)
   unit_list_iterate(get_units_in_focus(), punit) {
     /* 
      * Is the unit which just lost focus a non-AI unit? If yes this
-     * enables the auto end turn. 
+     * enables the auto end turn.
      */
     if (punit->ssa_controller == SSA_NONE) {
       non_ai_unit_focus = TRUE;
@@ -740,7 +758,7 @@ void unit_focus_advance(void)
       } unit_list_iterate_end;
       candidate = find_best_focus_candidate(FALSE);
 
-      if (!candidate) {
+      if (!candidate && accept_current) {
         /* Accept current focus unit as last resort. */
         candidate = find_best_focus_candidate(TRUE);
       }
@@ -796,7 +814,7 @@ void unit_focus_update(void)
     }
   } unit_list_iterate_end;
 
-  unit_focus_advance();
+  unit_focus_advance(TRUE);
 }
 
 /**********************************************************************//**
@@ -2626,7 +2644,7 @@ void request_units_wait(struct unit_list *punits)
     punit->client.focus_status = FOCUS_WAIT;
   } unit_list_iterate_end;
   if (punits == get_units_in_focus()) {
-    unit_focus_advance();
+    unit_focus_advance(TRUE);
   }
 }
 
@@ -2649,7 +2667,7 @@ void request_unit_move_done(void)
       punit->client.focus_status = new_status;
     } unit_list_iterate_end;
     if (new_status == FOCUS_DONE) {
-      unit_focus_advance();
+      unit_focus_advance(TRUE);
     }
   }
 }
diff --git a/client/control.h b/client/control.h
index 5c01794145..fff87882a2 100644
--- a/client/control.h
+++ b/client/control.h
@@ -190,7 +190,7 @@ void unit_focus_add(struct unit *punit);
 void unit_focus_remove(struct unit *punit);
 void unit_focus_urgent(struct unit *punit);
 
-void unit_focus_advance(void);
+void unit_focus_advance(bool accept_current);
 void unit_focus_update(void);
 
 void auto_center_on_focus_unit(void);
-- 
2.43.0

