From 5b4bd54006d39c29cc4e346484eba793598eea54 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sat, 18 May 2024 03:44:58 +0300
Subject: [PATCH 32/63] Unhardcode wld.map from can_city_build_unit_now()

See RM #646

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 ai/default/aiparatrooper.c |  3 ++-
 ai/default/daiair.c        |  3 ++-
 ai/default/daicity.c       |  5 +++--
 ai/default/daihunter.c     |  6 ++++--
 ai/default/daimilitary.c   | 13 ++++++++-----
 ai/default/daitech.c       |  8 +++++---
 ai/default/daiunit.c       |  3 ++-
 ai/tex/texaicity.c         |  2 +-
 client/climisc.c           |  2 +-
 client/gui-sdl2/wldlg.c    |  2 +-
 client/gui-sdl3/wldlg.c    |  2 +-
 common/city.c              |  9 +++++----
 common/city.h              |  3 ++-
 common/improvement.c       |  8 ++++++--
 common/unittype.c          |  3 ++-
 server/citytools.c         |  2 +-
 server/cityturn.c          |  4 +++-
 server/techtools.c         |  3 ++-
 18 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/ai/default/aiparatrooper.c b/ai/default/aiparatrooper.c
index ee4f80b79d..e7c4e7c58c 100644
--- a/ai/default/aiparatrooper.c
+++ b/ai/default/aiparatrooper.c
@@ -384,6 +384,7 @@ void dai_choose_paratrooper(struct ai_type *ait,
   const struct research *presearch = research_get(pplayer);
   int profit;
   struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
+  const struct civ_map *nmap = &(wld.map);
 
   /* military_advisor_choose_build() does something idiotic,
    * this function should not be called if there is danger... */
@@ -434,7 +435,7 @@ void dai_choose_paratrooper(struct ai_type *ait,
     } unit_tech_reqs_iterate_end;
 
     /* we only update choice struct if we can build it! */
-    if (!can_city_build_unit_now(pcity, u_type)) {
+    if (!can_city_build_unit_now(nmap, pcity, u_type)) {
       continue;
     }
 
diff --git a/ai/default/daiair.c b/ai/default/daiair.c
index 7f0309c24b..249eb44d23 100644
--- a/ai/default/daiair.c
+++ b/ai/default/daiair.c
@@ -585,6 +585,7 @@ bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer,
                              bool allow_gold_upkeep)
 {
   bool want_something = FALSE;
+  const struct civ_map *nmap = &(wld.map);
 
   /* This AI doesn't know how to build planes */
   if (has_handicap(pplayer, H_NOPLANES)) {
@@ -617,7 +618,7 @@ bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer,
       continue;
     }
 
-    if (can_city_build_unit_now(pcity, punittype)) {
+    if (can_city_build_unit_now(nmap, pcity, punittype)) {
       struct unit *virtual_unit =
        unit_virtual_create(
           pplayer, pcity, punittype,
diff --git a/ai/default/daicity.c b/ai/default/daicity.c
index c5a26e8c5e..df8da427fa 100644
--- a/ai/default/daicity.c
+++ b/ai/default/daicity.c
@@ -204,13 +204,14 @@ static void dai_barbarian_choose_build(struct player *pplayer,
 {
   struct unit_type *bestunit = NULL;
   int i, bestattack = 0;
+  const struct civ_map *nmap = &(wld.map);
 
   /* Choose the best unit among the basic ones */
   for (i = 0; i < num_role_units(L_BARBARIAN_BUILD); i++) {
     struct unit_type *iunit = get_role_unit(L_BARBARIAN_BUILD, i);
 
     if (iunit->attack_strength > bestattack
-        && can_city_build_unit_now(pcity, iunit)) {
+        && can_city_build_unit_now(nmap, pcity, iunit)) {
       bestunit = iunit;
       bestattack = iunit->attack_strength;
     }
@@ -221,7 +222,7 @@ static void dai_barbarian_choose_build(struct player *pplayer,
     struct unit_type *iunit = get_role_unit(L_BARBARIAN_BUILD_TECH, i);
 
     if (iunit->attack_strength > bestattack
-        && can_city_build_unit_now(pcity, iunit)) {
+        && can_city_build_unit_now(nmap, pcity, iunit)) {
       bestunit = iunit;
       bestattack = iunit->attack_strength;
     }
diff --git a/ai/default/daihunter.c b/ai/default/daihunter.c
index f6d34b4b55..61130c7646 100644
--- a/ai/default/daihunter.c
+++ b/ai/default/daihunter.c
@@ -85,6 +85,7 @@ static struct unit_type *dai_hunter_guess_best(struct city *pcity,
   struct unit_type *bestid = NULL;
   int best = 0;
   struct player *pplayer = city_owner(pcity);
+  const struct civ_map *nmap = &(wld.map);
 
   unit_type_iterate(ut) {
     struct unit_type_ai *utai = utype_ai_data(ut, ait);
@@ -94,7 +95,7 @@ static struct unit_type *dai_hunter_guess_best(struct city *pcity,
       continue;
     }
 
-    if (!can_city_build_unit_now(pcity, ut)
+    if (!can_city_build_unit_now(nmap, pcity, ut)
         || ut->attack_strength < ut->transport_capacity
         || (tc == TC_OCEAN && utype_class(ut)->adv.sea_move == MOVE_NONE)
         || (tc == TC_LAND && utype_class(ut)->adv.land_move == MOVE_NONE)) {
@@ -148,6 +149,7 @@ static void dai_hunter_missile_want(struct player *pplayer,
   adv_want best = -1;
   struct unit_type *best_unit_type = NULL;
   struct unit *hunter = NULL;
+  const struct civ_map *nmap = &(wld.map);
 
   unit_list_iterate(pcity->tile->units, punit) {
     if (dai_hunter_qualify(pplayer, punit)) {
@@ -173,7 +175,7 @@ static void dai_hunter_missile_want(struct player *pplayer,
     int desire;
 
     if (!utype_can_do_action(ut, ACTION_SUICIDE_ATTACK)
-        || !can_city_build_unit_now(pcity, ut)) {
+        || !can_city_build_unit_now(nmap, pcity, ut)) {
       continue;
     }
 
diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c
index 9e268527bc..0d3f1491d5 100644
--- a/ai/default/daimilitary.c
+++ b/ai/default/daimilitary.c
@@ -96,7 +96,7 @@ struct unit_type *dai_choose_defender_versus(struct city *pcity,
   struct civ_map *nmap = &(wld.map);
 
   simple_ai_unit_type_iterate(punittype) {
-    if (can_city_build_unit_now(pcity, punittype)) {
+    if (can_city_build_unit_now(nmap, pcity, punittype)) {
       int fpatt, fpdef, defense, attack;
       double want, loss, cost = utype_build_shield_cost(pcity, NULL, punittype);
       struct unit *defender;
@@ -149,6 +149,7 @@ static struct unit_type *dai_choose_attacker(struct ai_type *ait,
   adv_want best = -1;
   adv_want cur;
   struct player *pplayer = city_owner(pcity);
+  const struct civ_map *nmap = &(wld.map);
 
   simple_ai_unit_type_iterate(putype) {
     if (!allow_gold_upkeep && utype_upkeep_cost(putype, pplayer, O_GOLD) > 0) {
@@ -159,7 +160,7 @@ static struct unit_type *dai_choose_attacker(struct ai_type *ait,
     if ((tc == TC_LAND && utype_class(putype)->adv.land_move != MOVE_NONE)
         || (tc == TC_OCEAN
             && utype_class(putype)->adv.sea_move != MOVE_NONE)) {
-      if (can_city_build_unit_now(pcity, putype)
+      if (can_city_build_unit_now(nmap, pcity, putype)
           && (cur > best
               || (ADV_WANTS_EQ(cur, best)
                   && utype_build_shield_cost(pcity, NULL, putype)
@@ -190,6 +191,7 @@ static struct unit_type *dai_choose_bodyguard(struct ai_type *ait,
   struct unit_type *bestid = NULL;
   adv_want best = 0;
   struct player *pplayer = city_owner(pcity);
+  const struct civ_map *nmap = &(wld.map);
 
   simple_ai_unit_type_iterate(putype) {
     /* Only consider units of given role, or any if invalid given */
@@ -211,7 +213,7 @@ static struct unit_type *dai_choose_bodyguard(struct ai_type *ait,
     }
 
     /* Now find best */
-    if (can_city_build_unit_now(pcity, putype)) {
+    if (can_city_build_unit_now(nmap, pcity, putype)) {
       const adv_want desire = dai_unit_defense_desirability(ait, putype);
 
       if (desire > best
@@ -1068,6 +1070,7 @@ bool dai_process_defender_want(struct ai_type *ait, struct player *pplayer,
   struct ai_city *city_data = def_ai_city_data(pcity, ait);
   struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
   adv_want total_want = danger + extra_want;
+  const struct civ_map *nmap = &(wld.map);
 
   memset(tech_desire, 0, sizeof(tech_desire));
 
@@ -1103,7 +1106,7 @@ bool dai_process_defender_want(struct ai_type *ait, struct player *pplayer,
       desire /= POWER_DIVIDER / 2; /* Good enough, no rounding errors. */
       desire *= desire;
 
-      if (can_city_build_unit_now(pcity, punittype)) {
+      if (can_city_build_unit_now(nmap, pcity, punittype)) {
         /* We can build the unit now... */
 
         int build_cost = utype_build_shield_cost(pcity, NULL, punittype);
@@ -1451,7 +1454,7 @@ static void process_attacker_want(struct ai_type *ait,
         } else if (want > best_choice->want) {
           const struct impr_type *impr_req;
 
-          if (can_city_build_unit_now(pcity, punittype)) {
+          if (can_city_build_unit_now(nmap, pcity, punittype)) {
             /* This is a real unit and we really want it */
 
             CITY_LOG(LOG_DEBUG, pcity, "overriding %s(" ADV_WANT_PRINTF
diff --git a/ai/default/daitech.c b/ai/default/daitech.c
index 22126920e5..5a1d53814a 100644
--- a/ai/default/daitech.c
+++ b/ai/default/daitech.c
@@ -403,6 +403,7 @@ struct unit_type *dai_wants_defender_against(struct ai_type *ait,
   int att_idx = utype_index(att);
   int defbonus = 100
     + get_unittype_bonus(pplayer, ptile, att, NULL, EFT_DEFEND_BONUS);
+  const struct civ_map *nmap = &(wld.map);
 
   unit_type_iterate(deftype) {
     int mp_pct = deftype->cache.defense_mp_bonuses_pct[att_idx] + 100;
@@ -417,7 +418,7 @@ struct unit_type *dai_wants_defender_against(struct ai_type *ait,
 
     def_values[utype_index(deftype)] = def;
 
-    if (can_city_build_unit_now(pcity, deftype)) {
+    if (can_city_build_unit_now(nmap, pcity, deftype)) {
       if (def > best_avl_def) {
         best_avl_def = def;
         best_avl = deftype;
@@ -427,7 +428,7 @@ struct unit_type *dai_wants_defender_against(struct ai_type *ait,
 
   unit_type_iterate(deftype) {
     if (def_values[utype_index(deftype)] > best_avl_def
-        && !can_city_build_unit_now(pcity, deftype)
+        && !can_city_build_unit_now(nmap, pcity, deftype)
         && can_city_build_unit_later(pcity, deftype)) {
       /* It would be better than current best. Consider researching tech */
       const struct impr_type *building;
@@ -527,12 +528,13 @@ struct unit_type *dai_wants_role_unit(struct ai_type *ait, struct player *pplaye
   struct advance *best_tech = A_NEVER;
   struct unit_type *best_unit = NULL;
   struct unit_type *build_unit = NULL;
+  const struct civ_map *nmap = &(wld.map);
 
   n = num_role_units(role);
   for (i = n - 1; i >= 0; i--) {
     struct unit_type *iunit = get_role_unit(role, i);
 
-    if (can_city_build_unit_now(pcity, iunit)) {
+    if (can_city_build_unit_now(nmap, pcity, iunit)) {
       build_unit = iunit;
       break;
     } else if (can_city_build_unit_later(pcity, iunit)) {
diff --git a/ai/default/daiunit.c b/ai/default/daiunit.c
index 9ce135b62e..adf906aa81 100644
--- a/ai/default/daiunit.c
+++ b/ai/default/daiunit.c
@@ -3418,6 +3418,7 @@ static bool role_unit_cb(struct unit_type *ptype, void *data)
 {
   struct role_unit_cb_data *cb_data = (struct role_unit_cb_data *)data;
   struct unit_class *pclass = utype_class(ptype);
+  const struct civ_map *nmap = &(wld.map);
 
   if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
       || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
@@ -3425,7 +3426,7 @@ static bool role_unit_cb(struct unit_type *ptype, void *data)
   }
 
   if (cb_data->build_city == NULL
-      || can_city_build_unit_now(cb_data->build_city, ptype)) {
+      || can_city_build_unit_now(nmap, cb_data->build_city, ptype)) {
     return TRUE;
   }
 
diff --git a/ai/tex/texaicity.c b/ai/tex/texaicity.c
index 6c44b3710a..7e5c1dfeb8 100644
--- a/ai/tex/texaicity.c
+++ b/ai/tex/texaicity.c
@@ -463,7 +463,7 @@ static bool texai_city_worker_task_select(struct ai_type *ait,
   case TWTL_BUILDABLE_UNITS:
     units = unit_list_new();
     unit_type_iterate(ptype) {
-      if (can_city_build_unit_now(pcity, ptype)) {
+      if (can_city_build_unit_now(nmap, pcity, ptype)) {
         unit_list_append(units, unit_virtual_create(pplayer, pcity, ptype, 0));
       }
     } unit_type_iterate_end;
diff --git a/client/climisc.c b/client/climisc.c
index 77a030deb4..620972c85e 100644
--- a/client/climisc.c
+++ b/client/climisc.c
@@ -860,7 +860,7 @@ int collect_eventually_buildable_targets(struct universal *targets,
 
     if (NULL != pcity) {
       /* Can the city build? */
-      can_build = can_city_build_unit_now(pcity, punittype);
+      can_build = can_city_build_unit_now(&(wld.map), pcity, punittype);
       can_eventually_build = can_city_build_unit_later(pcity, punittype);
     } else if (NULL != pplayer) {
       /* Can our player build? */
diff --git a/client/gui-sdl2/wldlg.c b/client/gui-sdl2/wldlg.c
index dac9288580..603fd64fc0 100644
--- a/client/gui-sdl2/wldlg.c
+++ b/client/gui-sdl2/wldlg.c
@@ -1592,7 +1592,7 @@ void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
 
     /* If there's a city, can the city build the unit? */
     if (pcity) {
-      can_build = can_build && can_city_build_unit_now(pcity, un);
+      can_build = can_build && can_city_build_unit_now(&(wld.map), pcity, un);
       can_eventually_build = can_eventually_build
         && can_city_build_unit_later(pcity, un);
     }
diff --git a/client/gui-sdl3/wldlg.c b/client/gui-sdl3/wldlg.c
index 8bbf3bd1b4..06374a13ac 100644
--- a/client/gui-sdl3/wldlg.c
+++ b/client/gui-sdl3/wldlg.c
@@ -1588,7 +1588,7 @@ void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
 
     /* If there's a city, can the city build the unit? */
     if (pcity) {
-      can_build = can_build && can_city_build_unit_now(pcity, un);
+      can_build = can_build && can_city_build_unit_now(&(wld.map), pcity, un);
       can_eventually_build = can_eventually_build
         && can_city_build_unit_later(pcity, un);
     }
diff --git a/common/city.c b/common/city.c
index f55a229616..453ca5cdae 100644
--- a/common/city.c
+++ b/common/city.c
@@ -944,11 +944,10 @@ bool can_city_build_unit_direct(const struct civ_map *nmap,
   Return whether given city can build given unit; returns FALSE if unit is 
   obsolete.
 **************************************************************************/
-bool can_city_build_unit_now(const struct city *pcity,
+bool can_city_build_unit_now(const struct civ_map *nmap,
+                             const struct city *pcity,
                              const struct unit_type *punittype)
 {
-  const struct civ_map *nmap = &(wld.map);
-
   if (!can_city_build_unit_direct(nmap, pcity, punittype)) {
     return FALSE;
   }
@@ -1016,9 +1015,11 @@ bool can_city_build_direct(const struct city *pcity,
 bool can_city_build_now(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_now(pcity, target->value.utype);
+    return can_city_build_unit_now(nmap, pcity, target->value.utype);
   case VUT_IMPROVEMENT:
     return can_city_build_improvement_now(pcity, target->value.building);
   default:
diff --git a/common/city.h b/common/city.h
index a4e0ba88f0..b2066dfd5c 100644
--- a/common/city.h
+++ b/common/city.h
@@ -609,7 +609,8 @@ bool can_city_build_unit_direct(const struct civ_map *nmap,
                                 const struct unit_type *punittype);
 bool can_city_build_unit_later(const struct city *pcity,
                                const struct unit_type *punittype);
-bool can_city_build_unit_now(const struct city *pcity,
+bool can_city_build_unit_now(const struct civ_map *nmap,
+                             const struct city *pcity,
                              const struct unit_type *punittype);
 
 bool can_city_build_direct(const struct city *pcity,
diff --git a/common/improvement.c b/common/improvement.c
index 662e85afcd..ed0a6fadd9 100644
--- a/common/improvement.c
+++ b/common/improvement.c
@@ -434,6 +434,8 @@ bool improvement_obsolete(const struct player *pplayer,
 static bool impr_provides_buildable_units(const struct city *pcity,
                                           const struct impr_type *pimprove)
 {
+  const struct civ_map *nmap = &(wld.map);
+
   /* Fast check */
   if (!pimprove->allows_units) {
     return FALSE;
@@ -441,7 +443,7 @@ static bool impr_provides_buildable_units(const struct city *pcity,
 
   unit_type_iterate(ut) {
     if (requirement_needs_improvement(pimprove, &ut->build_reqs)
-        && can_city_build_unit_now(pcity, ut)) {
+        && can_city_build_unit_now(nmap, pcity, ut)) {
       return TRUE;
     }
   } unit_type_iterate_end;
@@ -528,6 +530,8 @@ static bool impr_protects_vs_actions(const struct city *pcity,
 static bool impr_allows_actions(const struct city *pcity,
                                 const struct impr_type *pimprove)
 {
+  const struct civ_map *nmap = &(wld.map);
+
   /* Fast check */
   if (!pimprove->allows_actions) {
     return FALSE;
@@ -550,7 +554,7 @@ static bool impr_allows_actions(const struct city *pcity,
             return TRUE;
           }
 
-          if (can_city_build_unit_now(pcity, ut)) {
+          if (can_city_build_unit_now(nmap, pcity, ut)) {
             /* This city can build a unit that uses the building */
             return TRUE;
           }
diff --git a/common/unittype.c b/common/unittype.c
index 1b8bad21f9..13111307d6 100644
--- a/common/unittype.c
+++ b/common/unittype.c
@@ -2272,6 +2272,7 @@ struct unit_type *best_role_unit(const struct city *pcity, int role)
 {
   struct unit_type *u;
   int j;
+  const struct civ_map *nmap = &(wld.map);
 
   fc_assert_ret_val((role >= 0 && role <= UTYF_LAST_USER_FLAG)
                     || (role >= L_FIRST && role < L_LAST)
@@ -2280,7 +2281,7 @@ struct unit_type *best_role_unit(const struct city *pcity, int role)
 
   for (j = n_with_role[role] - 1; j >= 0; j--) {
     u = with_role[role][j];
-    if (can_city_build_unit_now(pcity, u)) {
+    if (can_city_build_unit_now(nmap, pcity, u)) {
       return u;
     }
   }
diff --git a/server/citytools.c b/server/citytools.c
index d9332656e7..08551fb6b5 100644
--- a/server/citytools.c
+++ b/server/citytools.c
@@ -2721,7 +2721,7 @@ void package_city(struct city *pcity, struct packet_city_info *packet,
     } improvement_iterate_end;
 
     unit_type_iterate(punittype) {
-      if (can_city_build_unit_now(pcity, punittype)) {
+      if (can_city_build_unit_now(nmap, pcity, punittype)) {
         BV_SET(web_packet->can_build_unit, utype_index(punittype));
       }
     } unit_type_iterate_end;
diff --git a/server/cityturn.c b/server/cityturn.c
index 837e41c548..44581d3368 100644
--- a/server/cityturn.c
+++ b/server/cityturn.c
@@ -2398,6 +2398,8 @@ static bool worklist_change_build_target(struct player *pplayer,
 **************************************************************************/
 void choose_build_target(struct player *pplayer, struct city *pcity)
 {
+  const struct civ_map *nmap = &(wld.map);
+
   /* Pick the next thing off the worklist. */
   if (worklist_change_build_target(pplayer, pcity)) {
     return;
@@ -2409,7 +2411,7 @@ void choose_build_target(struct player *pplayer, struct city *pcity)
   case VUT_UTYPE:
     /* We can build a unit again unless it's unique or we have lost the tech. */
     if (!utype_has_flag(pcity->production.value.utype, UTYF_UNIQUE)
-        && can_city_build_unit_now(pcity, pcity->production.value.utype)) {
+        && can_city_build_unit_now(nmap, pcity, pcity->production.value.utype)) {
       log_base(LOG_BUILD_TARGET, "%s repeats building %s", city_name_get(pcity),
                utype_rule_name(pcity->production.value.utype));
       return;
diff --git a/server/techtools.c b/server/techtools.c
index 261c18005e..c6a2c1a994 100644
--- a/server/techtools.c
+++ b/server/techtools.c
@@ -822,6 +822,7 @@ static void research_tech_lost(struct research *presearch, Tech_type_id tech)
 {
   char research_name[MAX_LEN_NAME * 2];
   /* Research members will be notified when new tech is chosen. */
+  const struct civ_map *nmap = &(wld.map);
 
   research_pretty_name(presearch, research_name, sizeof(research_name));
 
@@ -899,7 +900,7 @@ static void research_tech_lost(struct research *presearch, Tech_type_id tech)
       bool update = FALSE;
 
       if (pcity->production.kind == VUT_UTYPE
-          && !can_city_build_unit_now(pcity, pcity->production.value.utype)) {
+          && !can_city_build_unit_now(nmap, pcity, pcity->production.value.utype)) {
         notify_player(pplayer, city_tile(pcity),
                       E_CITY_CANTBUILD, ftc_server,
                       _("%s can't build %s. The required technology was "
-- 
2.43.0

