From 9ce94186ec8394b8f308b441ca1e8b73473f673a Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Fri, 23 Sep 2022 05:47:36 +0300
Subject: [PATCH 42/42] Split single unit upkeep out from city_units_upkeep()

See osdn #45686

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 server/citytools.c | 67 +++++++++++++++++++++++++++-------------------
 server/citytools.h |  1 +
 2 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/server/citytools.c b/server/citytools.c
index d5b4c59aa8..83d5bf48c8 100644
--- a/server/citytools.c
+++ b/server/citytools.c
@@ -2981,6 +2981,45 @@ void building_lost(struct city *pcity, const struct impr_type *pimprove,
   }
 }
 
+/************************************************************************//**
+  Recalculate the upkeep needed for one unit.
+
+  Note that this modifies the free_uk array it gets, if
+  the unit uses some of that free upkeep.
+
+  If the upkeep for a unit changes, an update is send to the player.
+****************************************************************************/
+void update_unit_upkeep(struct unit *punit, int free_uk[O_LAST])
+{
+  const struct unit_type *ut = unit_type_get(punit);
+  struct player *plr = unit_owner(punit);
+  bool update = FALSE;
+  int cost;
+
+  output_type_iterate(o) {
+    cost = utype_upkeep_cost(ut, plr, o);
+    if (cost > 0) {
+      if (free_uk[o] > cost) {
+        free_uk[o] -= cost;
+        cost = 0;
+      } else {
+        cost -= free_uk[o];
+        free_uk[o] = 0;
+      }
+    }
+
+    if (cost != punit->upkeep[o]) {
+      update = TRUE;
+      punit->upkeep[o] = cost;
+    }
+  } output_type_iterate_end;
+
+  if (update) {
+    /* Update unit information to the player and global observers. */
+    send_unit_info(NULL, punit);
+  }
+}
+
 /************************************************************************//**
   Recalculate the upkeep needed for all units supported by the city. It has
   to be called
@@ -3017,33 +3056,7 @@ void city_units_upkeep(const struct city *pcity)
 
   /* Save the upkeep for all units in the corresponding punit struct */
   unit_list_iterate(pcity->units_supported, punit) {
-    const struct unit_type *ut = unit_type_get(punit);
-    struct player *plr = unit_owner(punit);
-    bool update = FALSE;
-    int cost;
-
-    output_type_iterate(o) {
-      cost = utype_upkeep_cost(ut, plr, o);
-      if (cost > 0) {
-        if (free_uk[o] > cost) {
-          free_uk[o] -= cost;
-          cost = 0;
-        } else {
-          cost -= free_uk[o];
-          free_uk[o] = 0;
-        }
-      }
-
-      if (cost != punit->upkeep[o]) {
-        update = TRUE;
-        punit->upkeep[o] = cost;
-      }
-    } output_type_iterate_end;
-
-    if (update) {
-      /* Update unit information to the player and global observers. */
-      send_unit_info(NULL, punit);
-    }
+    update_unit_upkeep(punit, free_uk);
   } unit_list_iterate_end;
 }
 
diff --git a/server/citytools.h b/server/citytools.h
index 2795a7116a..62d1849d7e 100644
--- a/server/citytools.h
+++ b/server/citytools.h
@@ -84,6 +84,7 @@ bool building_removed(struct city *pcity, const struct impr_type *pimprove,
                       const char *reason, struct unit *destroyer);
 void building_lost(struct city *pcity, const struct impr_type *pimprove,
                    const char *reason, struct unit *destroyer);
+void update_unit_upkeep(struct unit *punit, int free_uk[O_LAST]);
 void city_units_upkeep(const struct city *pcity);
 
 bool is_production_equal(const struct universal *one,
-- 
2.35.1