From 09b809be90b732884b0c30912e922511e6a121f9 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Tue, 18 Jul 2023 17:16:51 +0300
Subject: [PATCH 20/20] occupying move: Fix crash if unit died on
 autoperformers

See osdn #48300

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 server/unithand.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/server/unithand.c b/server/unithand.c
index 636ab2d24e..75d4a484de 100644
--- a/server/unithand.c
+++ b/server/unithand.c
@@ -4222,9 +4222,9 @@ static bool do_attack(struct unit *punit, struct tile *def_tile,
     }
   }
 
-  /* If attacker wins, and occupychance > 0, it might move in.  Don't move in
+  /* If attacker wins, and occupychance > 0, it might move in. Don't move in
    * if there are enemy units in the tile (a fortress, city or air base with
-   * multiple defenders and unstacked combat). Note that this could mean 
+   * multiple defenders and unstacked combat). Note that this could mean
    * capturing (or destroying) a city. */
 
   if (pwinner == punit && fc_rand(100) < game.server.occupychance
@@ -4235,6 +4235,7 @@ static bool do_attack(struct unit *punit, struct tile *def_tile,
 
     int old_moves = punit->moves_left;
     int full_moves = unit_move_rate(punit);
+    int id = punit->id;
 
     punit->moves_left = full_moves;
     /* Post attack occupy move. */
@@ -4244,15 +4245,17 @@ static bool do_attack(struct unit *punit, struct tile *def_tile,
          && unit_perform_action(unit_owner(punit), punit->id, pcity->id,
                                 0, "", ACTION_CONQUER_CITY, ACT_REQ_RULES))
         || (unit_move_handling(punit, def_tile, FALSE, TRUE, NULL))) {
-      int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
-
-      /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
-       * Attack SINGLE_COST is already calculated in to old_moves. */
-      punit->moves_left = old_moves - mcost;
-      if (punit->moves_left < 0) {
-        punit->moves_left = 0;
+      if (unit_is_alive(id)) {
+        int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
+
+        /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
+         * Attack SINGLE_COST is already calculated in to old_moves. */
+        punit->moves_left = old_moves - mcost;
+        if (punit->moves_left < 0) {
+          punit->moves_left = 0;
+        }
       }
-    } else {
+    } else if (unit_is_alive(id)) {
       punit->moves_left = old_moves;
     }
   }
-- 
2.40.1