From a03895e9b987cd4ce193cbb99240b54c135f24b8 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sun, 20 Oct 2024 03:33:07 +0300
Subject: [PATCH 31/31] Unhardcode wld.map from can_city_build_now()

See RM #993

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/citydlg_common.c       |  2 +-
 client/climisc.c              | 11 ++++++++++-
 client/climisc.h              |  2 ++
 client/gui-gtk-3.22/citydlg.c |  2 +-
 client/gui-gtk-3.22/cityrep.c | 36 +++++++++++++++++------------------
 client/gui-gtk-4.0/citydlg.c  |  2 +-
 client/gui-gtk-4.0/cityrep.c  | 12 ++++++------
 client/gui-qt/citydlg.cpp     |  6 +++---
 client/gui-qt/cityrep.cpp     | 21 ++++++++++----------
 client/mapctrl_common.c       |  2 +-
 common/city.c                 |  5 ++---
 common/city.h                 |  3 ++-
 server/cityhand.c             |  3 ++-
 server/citytools.c            |  3 ++-
 server/cityturn.c             |  2 +-
 15 files changed, 62 insertions(+), 50 deletions(-)

diff --git a/client/citydlg_common.c b/client/citydlg_common.c
index 05b66c54e4..60c2b2f5a4 100644
--- a/client/citydlg_common.c
+++ b/client/citydlg_common.c
@@ -1337,7 +1337,7 @@ void city_worklist_commit(struct city *pcity, struct worklist *pwl)
     }
 
     /* If it can be built... */
-    if (can_city_build_now(pcity, &target)) {
+    if (can_city_build_now(&(wld.map), pcity, &target)) {
       /* ...but we're not yet building it, then switch. */
       if (!same_as_current_build) {
         /* Change the current target */
diff --git a/client/climisc.c b/client/climisc.c
index f23e807063..458c73d6a3 100644
--- a/client/climisc.c
+++ b/client/climisc.c
@@ -180,7 +180,7 @@ void client_change_all(struct universal *from, struct universal *to)
   connection_do_buffer(&client.conn);
   city_list_iterate (client.conn.playing->cities, pcity) {
     if (are_universals_equal(&pcity->production, from)
-        && can_city_build_now(pcity, to)) {
+        && can_city_build_now(&(wld.map), pcity, to)) {
       city_change_production(pcity, to);
     }
   } city_list_iterate_end;
@@ -586,6 +586,15 @@ bool city_building_present(const struct city *pcity,
     && city_has_building(pcity, target->value.building);
 }
 
+/**********************************************************************//**
+  A TestCityFunc wrapper for can_city_build_now()
+**************************************************************************/
+bool can_city_build_now_client(const struct city *pcity,
+                               const struct universal *target)
+{
+  return can_city_build_now(&(wld.map), pcity, target);
+}
+
 /**********************************************************************//**
   Return the numerical "section" of an item.  This is used for sorting.
 **************************************************************************/
diff --git a/client/climisc.h b/client/climisc.h
index d10ea0f453..1fb6e2b705 100644
--- a/client/climisc.h
+++ b/client/climisc.h
@@ -76,6 +76,8 @@ bool city_unit_present(const struct city *pcity,
                        const struct universal *target);
 bool city_building_present(const struct city *pcity,
                            const struct universal *target);
+bool can_city_build_now_client(const struct city *pcity,
+                               const struct universal *target);
 
 struct item {
   struct universal item;
diff --git a/client/gui-gtk-3.22/citydlg.c b/client/gui-gtk-3.22/citydlg.c
index 10db8206f3..873d595afc 100644
--- a/client/gui-gtk-3.22/citydlg.c
+++ b/client/gui-gtk-3.22/citydlg.c
@@ -2149,7 +2149,7 @@ static void city_dialog_update_building(struct city_dialog *pdialog)
     name_and_sort_items(targets, targets_used, items, FALSE, pcity);
 
     for (item = 0; item < targets_used; item++) {
-      if (can_city_build_now(pcity, &items[item].item)) {
+      if (can_city_build_now(&(wld.map), pcity, &items[item].item)) {
         const char *name;
         struct sprite* sprite;
         GdkPixbuf *pix;
diff --git a/client/gui-gtk-3.22/cityrep.c b/client/gui-gtk-3.22/cityrep.c
index ddd769f2b4..b7e8e78807 100644
--- a/client/gui-gtk-3.22/cityrep.c
+++ b/client/gui-gtk-3.22/cityrep.c
@@ -1629,15 +1629,15 @@ static void popup_change_menu(GtkMenuShell *menu, gpointer data)
 
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(change_improvements_item),
                                    FALSE, FALSE, CO_CHANGE,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(change_units_item),
                                    TRUE, FALSE, CO_CHANGE,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(change_wonders_item),
                                    FALSE, TRUE, CO_CHANGE,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
 }
 
@@ -1652,15 +1652,15 @@ static void popup_last_menu(GtkMenuShell *menu, gpointer data)
 
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(last_improvements_item),
                                    FALSE, FALSE, CO_LAST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(last_units_item),
                                    TRUE, FALSE, CO_LAST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(last_wonders_item),
                                    FALSE, TRUE, CO_LAST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
 }
 
@@ -1675,15 +1675,15 @@ static void popup_first_menu(GtkMenuShell *menu, gpointer data)
 
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(first_improvements_item),
                                    FALSE, FALSE, CO_FIRST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(first_units_item),
                                    TRUE, FALSE, CO_FIRST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(first_wonders_item),
                                    FALSE, TRUE, CO_FIRST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
 }
 
@@ -1698,15 +1698,15 @@ static void popup_next_menu(GtkMenuShell *menu, gpointer data)
 
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(next_improvements_item),
                                    FALSE, FALSE, CO_NEXT,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(next_units_item),
                                    TRUE, FALSE, CO_NEXT,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(next_wonders_item),
                                    FALSE, TRUE, CO_NEXT,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), n);
 }
 
@@ -1727,17 +1727,17 @@ static void popup_next_to_last_menu(GtkMenuShell *menu, gpointer data)
   item = next_to_last_improvements_item;
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(item),
                                    FALSE, FALSE, CO_NEXT_TO_LAST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    callback, n);
   item = next_to_last_units_item;
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(item),
                                    TRUE, FALSE, CO_NEXT_TO_LAST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    callback, n);
   item = next_to_last_wonders_item;
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(item),
                                    FALSE, TRUE, CO_NEXT_TO_LAST,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    callback, n);
 }
 
@@ -1941,15 +1941,15 @@ static void popup_select_menu(GtkMenuShell *menu, gpointer data)
 
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(select_improvements_item),
                                    FALSE, FALSE, CO_NONE,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), -1);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(select_units_item),
                                    TRUE, FALSE, CO_NONE,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), -1);
   append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(select_wonders_item),
                                    FALSE, TRUE, CO_NONE,
-                                   can_city_build_now,
+                                   can_city_build_now_client,
                                    G_CALLBACK(select_impr_or_unit_callback), -1);
   append_cma_to_menu_item(GTK_MENU_ITEM(select_cma_item), FALSE);
 
diff --git a/client/gui-gtk-4.0/citydlg.c b/client/gui-gtk-4.0/citydlg.c
index a47d4f1275..457b3e5502 100644
--- a/client/gui-gtk-4.0/citydlg.c
+++ b/client/gui-gtk-4.0/citydlg.c
@@ -2137,7 +2137,7 @@ static void city_dialog_update_building(struct city_dialog *pdialog)
     name_and_sort_items(targets, targets_used, items, FALSE, pcity);
 
     for (item = 0; item < targets_used; item++) {
-      if (can_city_build_now(pcity, &items[item].item)) {
+      if (can_city_build_now(&(wld.map), pcity, &items[item].item)) {
         const char *name;
         struct sprite *sprite;
         GdkPixbuf *pix;
diff --git a/client/gui-gtk-4.0/cityrep.c b/client/gui-gtk-4.0/cityrep.c
index 766b159e96..157f4bea6e 100644
--- a/client/gui-gtk-4.0/cityrep.c
+++ b/client/gui-gtk-4.0/cityrep.c
@@ -1568,7 +1568,7 @@ static GMenu *create_change_menu(GActionGroup *group, const char *mname,
   submenu = g_menu_new();
   append_impr_or_unit_to_menu(submenu, group, mname, "_u",
                               TRUE, FALSE, oper,
-                              can_city_build_now,
+                              can_city_build_now_client,
                               G_CALLBACK(select_impr_or_unit_callback), n);
   fc_snprintf(buf, sizeof(buf), human_mname, _("Unit"));
   submenu_append_unref(menu, buf, G_MENU_MODEL(submenu));
@@ -1576,7 +1576,7 @@ static GMenu *create_change_menu(GActionGroup *group, const char *mname,
   submenu = g_menu_new();
   append_impr_or_unit_to_menu(submenu, group, mname, "_i",
                               FALSE, FALSE, oper,
-                              can_city_build_now,
+                              can_city_build_now_client,
                               G_CALLBACK(select_impr_or_unit_callback), n);
   fc_snprintf(buf, sizeof(buf), human_mname, _("Improvement"));
   submenu_append_unref(menu, buf, G_MENU_MODEL(submenu));
@@ -1584,7 +1584,7 @@ static GMenu *create_change_menu(GActionGroup *group, const char *mname,
   submenu = g_menu_new();
   append_impr_or_unit_to_menu(submenu, group, mname, "_w",
                               FALSE, TRUE, oper,
-                              can_city_build_now,
+                              can_city_build_now_client,
                               G_CALLBACK(select_impr_or_unit_callback), n);
   fc_snprintf(buf, sizeof(buf), human_mname, _("Wonder"));
   submenu_append_unref(menu, buf, G_MENU_MODEL(submenu));
@@ -1835,7 +1835,7 @@ static GMenu *create_select_menu(GActionGroup *group)
   unit_a_select_menu = g_menu_new();
   append_impr_or_unit_to_menu(unit_a_select_menu, group, "sel", "_a_u",
                               TRUE, FALSE, CO_NONE,
-                              can_city_build_now,
+                              can_city_build_now_client,
                               G_CALLBACK(select_impr_or_unit_callback), -1);
   fc_snprintf(buf, sizeof(buf), _("Available %s"), _("Unit"));
   submenu_append_unref(select_menu, buf, G_MENU_MODEL(unit_a_select_menu));
@@ -1843,7 +1843,7 @@ static GMenu *create_select_menu(GActionGroup *group)
   impr_a_select_menu = g_menu_new();
   append_impr_or_unit_to_menu(impr_a_select_menu, group, "sel", "_a_b",
                               FALSE, FALSE, CO_NONE,
-                              can_city_build_now,
+                              can_city_build_now_client,
                               G_CALLBACK(select_impr_or_unit_callback), -1);
   fc_snprintf(buf, sizeof(buf), _("Available %s"), _("Improvement"));
   submenu_append_unref(select_menu, buf, G_MENU_MODEL(impr_a_select_menu));
@@ -1851,7 +1851,7 @@ static GMenu *create_select_menu(GActionGroup *group)
   wndr_a_select_menu = g_menu_new();
   append_impr_or_unit_to_menu(wndr_a_select_menu, group, "sel", "_a_w",
                               FALSE, TRUE, CO_NONE,
-                              can_city_build_now,
+                              can_city_build_now_client,
                               G_CALLBACK(select_impr_or_unit_callback), -1);
   fc_snprintf(buf, sizeof(buf), _("Available %s"), _("Wonder"));
   submenu_append_unref(select_menu, buf, G_MENU_MODEL(wndr_a_select_menu));
diff --git a/client/gui-qt/citydlg.cpp b/client/gui-qt/citydlg.cpp
index 62545d4bbc..d6027f2c2e 100644
--- a/client/gui-qt/citydlg.cpp
+++ b/client/gui-qt/citydlg.cpp
@@ -2087,7 +2087,7 @@ void city_dialog::change_production(bool next)
   name_and_sort_items(targets, targets_used, items, false, dlgcity);
 
   for (item = 0; item < targets_used; item++) {
-    if (can_city_build_now(dlgcity, &items[item].item)) {
+    if (can_city_build_now(&(wld.map), dlgcity, &items[item].item)) {
       prod_list << cid_encode(items[item].item);
     }
   }
@@ -4450,10 +4450,10 @@ void city_production_model::populate()
   name_and_sort_items(targets, targets_used, items, false, mcity);
 
   for (item = 0; item < targets_used; item++) {
-    if (future_t || can_city_build_now(mcity, &items[item].item)) {
+    if (future_t || can_city_build_now(&(wld.map), mcity, &items[item].item)) {
       renegade = new universal(items[item].item);
 
-      // Renagade deleted in production_item destructor
+      // Renegade deleted in production_item destructor
       if (VUT_UTYPE == renegade->kind) {
         str = utype_name_translation(renegade->value.utype);
         sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
diff --git a/client/gui-qt/cityrep.cpp b/client/gui-qt/cityrep.cpp
index 8e29570632..cb16132e88 100644
--- a/client/gui-qt/cityrep.cpp
+++ b/client/gui-qt/cityrep.cpp
@@ -484,16 +484,16 @@ void city_widget::display_list_menu(const QPoint &)
   if (!selected_cities.isEmpty()) {
     some_menu = list_menu->addMenu(_("Production"));
     tmp_menu = some_menu->addMenu(_("Change"));
-    fill_production_menus(CHANGE_PROD_NOW, custom_labels, can_city_build_now,
+    fill_production_menus(CHANGE_PROD_NOW, custom_labels, can_city_build_now_client,
                           tmp_menu);
     tmp_menu = some_menu->addMenu(_("Add next"));
-    fill_production_menus(CHANGE_PROD_NEXT, custom_labels, can_city_build_now,
+    fill_production_menus(CHANGE_PROD_NEXT, custom_labels, can_city_build_now_client,
                           tmp_menu);
     tmp_menu = some_menu->addMenu(_("Add before last"));
     fill_production_menus(CHANGE_PROD_BEF_LAST, custom_labels,
-                          can_city_build_now, tmp_menu);
+                          can_city_build_now_client, tmp_menu);
     tmp_menu = some_menu->addMenu(_("Add last"));
-    fill_production_menus(CHANGE_PROD_LAST, custom_labels, can_city_build_now,
+    fill_production_menus(CHANGE_PROD_LAST, custom_labels, can_city_build_now_client,
                           tmp_menu);
 
     tmp_menu = some_menu->addMenu(_("Worklist"));
@@ -613,7 +613,7 @@ void city_widget::display_list_menu(const QPoint &)
             clearSelection();
           }
           need_clear = false;
-          if (can_city_build_now(iter_city, &target)) {
+          if (can_city_build_now(&(wld.map), iter_city, &target)) {
             select_city(iter_city);
           }
           break;
@@ -622,7 +622,7 @@ void city_widget::display_list_menu(const QPoint &)
             clearSelection();
           }
           need_clear = false;
-          if (can_city_build_now(iter_city, &target)) {
+          if (can_city_build_now(&(wld.map), iter_city, &target)) {
             select_city(iter_city);
           }
           break;
@@ -631,7 +631,7 @@ void city_widget::display_list_menu(const QPoint &)
             clearSelection();
           }
           need_clear = false;
-          if (can_city_build_now(iter_city, &target)) {
+          if (can_city_build_now(&(wld.map), iter_city, &target)) {
             select_city(iter_city);
           }
           break;
@@ -1002,17 +1002,16 @@ void city_widget::gen_select_labels(QMenu *menu)
   menu->addSeparator();
   tmp_menu = menu->addMenu(_("Available Units"));
   gen_production_labels(SELECT_AVAIL_UNITS, custom_labels, true, false,
-                        can_city_build_now, true);
+                        can_city_build_now_client, true);
   fill_data(SELECT_AVAIL_UNITS, custom_labels, tmp_menu);
   tmp_menu = menu->addMenu(_("Available Improvements"));
   gen_production_labels(SELECT_AVAIL_IMPR, custom_labels, false, false,
-                        can_city_build_now, true);
+                        can_city_build_now_client, true);
   fill_data(SELECT_AVAIL_IMPR, custom_labels, tmp_menu);
   tmp_menu = menu->addMenu(_("Available Wonders"));
   gen_production_labels(SELECT_AVAIL_WONDERS, custom_labels, false, true,
-                        can_city_build_now, true);
+                        can_city_build_now_client, true);
   fill_data(SELECT_AVAIL_WONDERS, custom_labels, tmp_menu);
-
 }
 
 /***********************************************************************//**
diff --git a/client/mapctrl_common.c b/client/mapctrl_common.c
index fb87b0f8a2..12f8e95540 100644
--- a/client/mapctrl_common.c
+++ b/client/mapctrl_common.c
@@ -454,7 +454,7 @@ void clipboard_paste_production(struct city *pcity)
 static void clipboard_send_production_packet(struct city *pcity)
 {
   if (are_universals_equal(&pcity->production, &clipboard)
-      || !can_city_build_now(pcity, &clipboard)) {
+      || !can_city_build_now(&(wld.map), pcity, &clipboard)) {
     return;
   }
 
diff --git a/common/city.c b/common/city.c
index 65c86340e1..86fae6829a 100644
--- a/common/city.c
+++ b/common/city.c
@@ -1010,11 +1010,10 @@ bool can_city_build_direct(const struct civ_map *nmap,
   Returns whether city can immediately build given target,
   unit or improvement. This considers obsolete targets no longer buildable.
 **************************************************************************/
-bool can_city_build_now(const struct city *pcity,
+bool can_city_build_now(const struct civ_map *nmap,
+                        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(nmap, pcity, target->value.utype);
diff --git a/common/city.h b/common/city.h
index 5e0ddcc0db..8def7d364c 100644
--- a/common/city.h
+++ b/common/city.h
@@ -619,7 +619,8 @@ bool can_city_build_direct(const struct civ_map *nmap,
                            const struct universal *target);
 bool can_city_build_later(const struct city *pcity,
                           const struct universal *target);
-bool can_city_build_now(const struct city *pcity,
+bool can_city_build_now(const struct civ_map *nmap,
+                        const struct city *pcity,
                         const struct universal *target);
 
 int city_unit_slots_available(const struct city *pcity);
diff --git a/server/cityhand.c b/server/cityhand.c
index df7fe4c92d..13f6e55256 100644
--- a/server/cityhand.c
+++ b/server/cityhand.c
@@ -437,6 +437,7 @@ void handle_city_change(struct player *pplayer, int city_id,
 {
   struct universal prod;
   struct city *pcity = player_city_by_number(pplayer, city_id);
+  const struct civ_map *nmap = &(wld.map);
 
   if (!universals_n_is_valid(production_kind)) {
     log_error("[%s] bad production_kind %d.", __FUNCTION__,
@@ -462,7 +463,7 @@ void handle_city_change(struct player *pplayer, int city_id,
     return;
   }
 
-  if (!can_city_build_now(pcity, &prod)) {
+  if (!can_city_build_now(nmap, pcity, &prod)) {
     return;
   }
   if (!city_can_change_build(pcity)) {
diff --git a/server/citytools.c b/server/citytools.c
index 96efeabb3b..f4e4ddcf9a 100644
--- a/server/citytools.c
+++ b/server/citytools.c
@@ -1096,6 +1096,7 @@ bool transfer_city(struct player *ptaker, struct city *pcity,
   int central_units[ul_size + 1];
   bv_player *could_see_unit = NULL;
   int i;
+  const struct civ_map *nmap = &(wld.map);
 
   fc_assert_ret_val(pgiver != ptaker, TRUE);
 
@@ -1297,7 +1298,7 @@ bool transfer_city(struct player *ptaker, struct city *pcity,
 
     /* Set production to something valid for pplayer, if not.
      * (previously allowed building obsolete units.) */
-    if (!can_city_build_now(pcity, &pcity->production)) {
+    if (!can_city_build_now(nmap, pcity, &pcity->production)) {
       advisor_choose_build(ptaker, pcity);
     }
 
diff --git a/server/cityturn.c b/server/cityturn.c
index 0d3cce1c5c..910884eb8a 100644
--- a/server/cityturn.c
+++ b/server/cityturn.c
@@ -2197,7 +2197,7 @@ static bool worklist_change_build_target(struct player *pplayer,
     }
 
     if (worklist_peek_ith(pwl, &target, i)) {
-      success = can_city_build_now(pcity, &target);
+      success = can_city_build_now(nmap, pcity, &target);
     } else {
       success = FALSE;
     }
-- 
2.45.2

