From d253995c8611fb4cdb5b7fd0840f23744a5293e9 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sun, 12 May 2024 05:13:18 +0300
Subject: [PATCH 76/76] Unhardcode wld.map from can_city_build_unit_direct()

See RM #594

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 ai/default/daimilitary.c  |  4 ++--
 common/aicore/aisupport.c | 14 ++++++++------
 common/city.c             | 25 ++++++++++++++++---------
 common/city.h             |  9 +++++----
 server/cityturn.c         | 15 +++++++++------
 5 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c
index 9fda555337..a21f0df178 100644
--- a/ai/default/daimilitary.c
+++ b/ai/default/daimilitary.c
@@ -1275,8 +1275,8 @@ static void process_attacker_want(struct ai_type *ait,
     if (dai_can_unit_type_follow_unit_type(punittype, orig_utype, ait)
         && is_native_near_tile(&(wld.map), utype_class(punittype), ptile)
         && (U_NOT_OBSOLETED == punittype->obsoleted_by
-            || !can_city_build_unit_direct(pcity, punittype->obsoleted_by))
-        && punittype->attack_strength > 0 /* or we'll get SIGFPE */) {
+            || !can_city_build_unit_direct(nmap, pcity, punittype->obsoleted_by))
+        && punittype->attack_strength > 0 /* Or we'll get SIGFPE */) {
       /* Values to be computed */
       adv_want desire;
       adv_want want;
diff --git a/common/aicore/aisupport.c b/common/aicore/aisupport.c
index 8186d081a9..29de1b17ca 100644
--- a/common/aicore/aisupport.c
+++ b/common/aicore/aisupport.c
@@ -110,6 +110,7 @@ int city_gold_worth(struct city *pcity)
   struct player *pplayer = city_owner(pcity);
   int worth = 0, i;
   struct unit_type *u = NULL;
+  const struct civ_map *nmap = &(wld.map);
 
   if (!game.scenario.prevent_new_cities) {
     u = best_role_unit_for_player(city_owner(pcity),
@@ -117,10 +118,10 @@ int city_gold_worth(struct city *pcity)
   }
 
   if (u != NULL) {
-    worth += utype_buy_gold_cost(pcity, u, 0); /* cost of settler */
+    worth += utype_buy_gold_cost(pcity, u, 0); /* Cost of settler */
   }
   for (i = 1; i < city_size_get(pcity); i++) {
-    worth += city_granary_size(i); /* cost of growing city */
+    worth += city_granary_size(i); /* Cost of growing city */
   }
   output_type_iterate(o) {
     worth += pcity->prod[o] * 10;
@@ -129,18 +130,18 @@ int city_gold_worth(struct city *pcity)
     if (same_pos(unit_tile(punit), pcity->tile)) {
       const struct unit_type *punittype = unit_type_get(punit)->obsoleted_by;
 
-      if (punittype && can_city_build_unit_direct(pcity, punittype)) {
-        /* obsolete, candidate for disbanding */
+      if (punittype && can_city_build_unit_direct(nmap, pcity, punittype)) {
+        /* Obsolete, candidate for disbanding */
         worth += unit_shield_value(punit, unit_type_get(punit),
                                    action_by_number(ACTION_DISBAND_UNIT_RECOVER));
       } else {
-        worth += unit_build_shield_cost(pcity, punit); /* good stuff */
+        worth += unit_build_shield_cost(pcity, punit); /* Good stuff */
       }
     }
   } unit_list_iterate_end;
   city_built_iterate(pcity, pimprove) {
     if (improvement_obsolete(pplayer, pimprove, pcity)) {
-      worth += impr_sell_gold(pimprove); /* obsolete, candidate for selling */
+      worth += impr_sell_gold(pimprove); /* Obsolete, candidate for selling */
     } else if (!is_wonder(pimprove)) {
       /* Buy cost, with nonzero shield amount */
       worth += impr_build_shield_cost(pcity, pimprove) * 2;
@@ -151,5 +152,6 @@ int city_gold_worth(struct city *pcity)
   if (city_unhappy(pcity)) {
     worth *= 0.75;
   }
+
   return worth;
 }
diff --git a/common/city.c b/common/city.c
index d1bc439ff7..f55a229616 100644
--- a/common/city.c
+++ b/common/city.c
@@ -900,11 +900,10 @@ bool can_city_build_improvement_later(const struct city *pcity,
   Return whether given city can build given unit, ignoring whether unit 
   is obsolete.
 **************************************************************************/
-bool can_city_build_unit_direct(const struct city *pcity,
+bool can_city_build_unit_direct(const struct civ_map *nmap,
+                                const struct city *pcity,
                                 const struct unit_type *punittype)
 {
-  const struct civ_map *nmap = &(wld.map);
-
   if (!can_player_build_unit_direct(city_owner(pcity), punittype, FALSE)) {
     return FALSE;
   }
@@ -946,11 +945,14 @@ bool can_city_build_unit_direct(const struct city *pcity,
   obsolete.
 **************************************************************************/
 bool can_city_build_unit_now(const struct city *pcity,
-			     const struct unit_type *punittype)
-{  
-  if (!can_city_build_unit_direct(pcity, punittype)) {
+                             const struct unit_type *punittype)
+{
+  const struct civ_map *nmap = &(wld.map);
+
+  if (!can_city_build_unit_direct(nmap, pcity, punittype)) {
     return FALSE;
   }
+
   while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
     /* TODO: Decide if fulfilled impr_req is needed to make unit obsolete,
      *       i.e., should the 'consider_reg_impr_req' be TRUE or FALSE. */
@@ -958,6 +960,7 @@ bool can_city_build_unit_now(const struct city *pcity,
       return FALSE;
     }
   }
+
   return TRUE;
 }
 
@@ -993,9 +996,11 @@ bool can_city_build_unit_later(const struct city *pcity,
 bool can_city_build_direct(const struct city *pcity,
                            const struct universal *target)
 {
+  const struct civ_map *nmap = &(wld.map);
+
   switch (target->kind) {
   case VUT_UTYPE:
-    return can_city_build_unit_direct(pcity, target->value.utype);
+    return can_city_build_unit_direct(nmap, pcity, target->value.utype);
   case VUT_IMPROVEMENT:
     return can_city_build_improvement_direct(pcity, target->value.building);
   default:
@@ -1082,9 +1087,11 @@ bool city_can_change_build(const struct city *pcity)
 **************************************************************************/
 void city_choose_build_default(struct city *pcity)
 {
+  const struct civ_map *nmap = &(wld.map);
+
   if (NULL == city_tile(pcity)) {
     /* When a "dummy" city is created with no tile, then choosing a build 
-     * target could fail.  This currently might happen during map editing.
+     * target could fail. This currently might happen during map editing.
      * FIXME: assumes the first unit is always "valid", so check for
      * obsolete units elsewhere. */
     pcity->production.kind = VUT_UTYPE;
@@ -1110,7 +1117,7 @@ void city_choose_build_default(struct city *pcity)
 
       if (!found) {
         unit_type_iterate(punittype) {
-          if (can_city_build_unit_direct(pcity, punittype)) {
+          if (can_city_build_unit_direct(nmap, pcity, punittype)) {
 #ifndef FREECIV_NDEBUG
             /* Later than this, 'found' is only needed in an fc_assert() */
             found = TRUE;
diff --git a/common/city.h b/common/city.h
index 5253769a2f..a4e0ba88f0 100644
--- a/common/city.h
+++ b/common/city.h
@@ -592,7 +592,7 @@ bool city_celebrating(const struct city *pcity);            /* love the king ???
 bool city_rapture_grow(const struct city *pcity);
 bool city_is_occupied(const struct city *pcity);
 
-/* city related improvement and unit functions */
+/* City related improvement and unit functions */
 
 int city_improvement_upkeep(const struct city *pcity,
                             const struct impr_type *pimprove);
@@ -604,7 +604,8 @@ bool can_city_build_improvement_later(const struct city *pcity,
 bool can_city_build_improvement_now(const struct city *pcity,
                                     const struct impr_type *pimprove);
 
-bool can_city_build_unit_direct(const struct city *pcity,
+bool can_city_build_unit_direct(const struct civ_map *nmap,
+                                const struct city *pcity,
                                 const struct unit_type *punittype);
 bool can_city_build_unit_later(const struct city *pcity,
                                const struct unit_type *punittype);
@@ -654,13 +655,13 @@ bool city_can_change_build(const struct city *pcity);
 
 void city_choose_build_default(struct city *pcity);
 
-/* textual representation of buildings */
+/* Textual representation of buildings */
 
 const char *city_improvement_name_translation(const struct city *pcity,
 					      const struct impr_type *pimprove);
 const char *city_production_name_translation(const struct city *pcity);
 
-/* city map functions */
+/* City map functions */
 bool is_valid_city_coords(const int city_radius_sq, const int city_map_x,
                           const int city_map_y);
 bool city_map_includes_tile(const struct city *const pcity,
diff --git a/server/cityturn.c b/server/cityturn.c
index bea071e0da..e620f27229 100644
--- a/server/cityturn.c
+++ b/server/cityturn.c
@@ -1168,8 +1168,8 @@ static bool worklist_item_postpone_req_vec(struct universal *target,
     .player = pplayer,
     .city = pcity,
     .tile = city_tile(pcity)
-    /* FIXME: Setting .unittype is currently redundant
-     * but can_city_build_unit_direct() does it */
+    /* FIXME: Setting .unittype is currently redundant,
+     *        but can_city_build_unit_direct() does it */
   };
   bool purge = FALSE;
   bool known = FALSE;
@@ -2489,12 +2489,13 @@ static const struct unit_type *unit_upgrades_to(struct city *pcity,
 {
   const struct unit_type *check = punittype;
   const struct unit_type *best_upgrade = U_NOT_OBSOLETED;
+  const struct civ_map *nmap = &(wld.map);
 
-  if (!can_city_build_unit_direct(pcity, punittype)) {
+  if (!can_city_build_unit_direct(nmap, pcity, punittype)) {
     return U_NOT_OBSOLETED;
   }
   while ((check = check->obsoleted_by) != U_NOT_OBSOLETED) {
-    if (can_city_build_unit_direct(pcity, check)) {
+    if (can_city_build_unit_direct(nmap, pcity, check)) {
       best_upgrade = check;
     }
   }
@@ -2509,8 +2510,9 @@ static void upgrade_unit_prod(struct city *pcity)
 {
   const struct unit_type *producing = pcity->production.value.utype;
   const struct unit_type *upgrading = unit_upgrades_to(pcity, producing);
+  const struct civ_map *nmap = &(wld.map);
 
-  if (upgrading && can_city_build_unit_direct(pcity, upgrading)) {
+  if (upgrading && can_city_build_unit_direct(nmap, pcity, upgrading)) {
     notify_player(city_owner(pcity), city_tile(pcity),
                   E_UNIT_UPGRADED, ftc_server,
 		  _("Production of %s is upgraded to %s in %s."),
@@ -2835,6 +2837,7 @@ static bool city_build_unit(struct player *pplayer, struct city *pcity)
   struct worklist *pwl = &pcity->worklist;
   int unit_shield_cost, num_units, i;
   int saved_city_id = pcity->id;
+  const struct civ_map *nmap = &(wld.map);
 
   fc_assert_ret_val(pcity->production.kind == VUT_UTYPE, FALSE);
 
@@ -2853,7 +2856,7 @@ static bool city_build_unit(struct player *pplayer, struct city *pcity)
   /* We must make a special case for barbarians here, because they are
      so dumb. Really. They don't know the prerequisite techs for units
      they build!! - Per */
-  if (!can_city_build_unit_direct(pcity, utype)
+  if (!can_city_build_unit_direct(nmap, pcity, utype)
       && !is_barbarian(pplayer)) {
     notify_player(pplayer, city_tile(pcity), E_CITY_CANTBUILD, ftc_server,
                   _("%s is building %s, which is no longer available."),
-- 
2.43.0

