From 658b640afc41acb6c06260bd149190c0f97e4d5a Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Tue, 30 Jan 2024 20:11:04 +0200
Subject: [PATCH 23/23] Unhardcode wld.map from can_unit_[paradrop|teleport]()

See RM #209

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 ai/default/aiparatrooper.c  | 18 +++++++++---------
 client/control.c            |  4 ++--
 client/gui-gtk-3.22/menu.c  |  2 +-
 client/gui-gtk-4.0/menu.c   |  4 ++--
 client/gui-qt/hudwidget.cpp |  2 +-
 client/gui-qt/menu.cpp      |  4 ++--
 client/gui-sdl2/dialogs.c   |  2 +-
 client/gui-sdl2/menu.c      |  2 +-
 client/gui-sdl3/dialogs.c   |  2 +-
 client/gui-sdl3/menu.c      |  2 +-
 common/unit.c               |  8 ++------
 common/unit.h               |  4 ++--
 common/unitlist.c           | 18 ++++++++++++++++++
 common/unitlist.h           |  8 ++++++--
 14 files changed, 49 insertions(+), 31 deletions(-)

diff --git a/ai/default/aiparatrooper.c b/ai/default/aiparatrooper.c
index fd85f667c4..568e41df25 100644
--- a/ai/default/aiparatrooper.c
+++ b/ai/default/aiparatrooper.c
@@ -199,23 +199,23 @@ void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer,
 {
   struct city *pcity = tile_city(unit_tile(punit));
   struct tile *ptile_dest = NULL;
-
+  const struct civ_map *nmap = &(wld.map);
   int sanity = punit->id;
 
-  /* defend attacking (and be opportunistic too) */
+  /* Defend attacking (and be opportunistic too) */
   if (!dai_military_rampage(punit, RAMPAGE_ANYTHING,
                             RAMPAGE_FREE_CITY_OR_BETTER)) {
-    /* dead */
+    /* Dead */
     return;
   }
 
-  /* check to recover hit points */
+  /* Check to recover hit points */
   if ((punit->hp < unit_type_get(punit)->hp / 2) && pcity) {
     UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "Recovering hit points.");
     return;
   }
 
-  /* nothing to do! */
+  /* Nothing to do! */
   if (punit->moves_left == 0) {
     return;
   }
@@ -225,7 +225,7 @@ void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer,
     return;
   }
 
-  if (can_unit_paradrop(punit)) {
+  if (can_unit_paradrop(nmap, punit)) {
     ptile_dest = find_best_tile_to_paradrop_to(ait, punit);
 
     if (ptile_dest) {
@@ -276,17 +276,17 @@ void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer,
       }
     }
   } else {
-    /* we can't paradrop :-(  */
+    /* We can't paradrop :-(  */
     struct city *acity = NULL;
 
-    /* we are in a city, so don't try to find another */
+    /* We are in a city, so don't try to find another */
     if (pcity) {
       UNIT_LOG(LOGLEVEL_PARATROOPER, punit,
 	       "waiting in a city for next turn.");
       return;
     }
 
-    /* find a city to go to recover and paradrop from */
+    /* Find a city to go to recover and paradrop from */
     acity = find_nearest_safe_city(punit);
 
     if (acity) {
diff --git a/client/control.c b/client/control.c
index af44743116..6816e1d46e 100644
--- a/client/control.c
+++ b/client/control.c
@@ -2223,7 +2223,7 @@ void request_unit_paradrop(struct unit_list *punits)
     return;
   }
   unit_list_iterate(punits, punit) {
-    if (can_unit_paradrop(punit)) {
+    if (can_unit_paradrop(&(wld.map), punit)) {
       can = TRUE;
       break;
     }
@@ -2260,7 +2260,7 @@ static void request_unit_teleport(struct unit_list *punits)
   }
 
   unit_list_iterate(punits, punit) {
-    if (can_unit_teleport(punit)) {
+    if (can_unit_teleport(&(wld.map), punit)) {
       can = TRUE;
       break;
     }
diff --git a/client/gui-gtk-3.22/menu.c b/client/gui-gtk-3.22/menu.c
index 1e09cb1daa..19c22dab85 100644
--- a/client/gui-gtk-3.22/menu.c
+++ b/client/gui-gtk-3.22/menu.c
@@ -2587,7 +2587,7 @@ void real_menus_update(void)
   menu_entry_set_sensitive("UNIT_SENTRY",
                            can_units_do_activity_client(punits, ACTIVITY_SENTRY));
   menu_entry_set_sensitive("DO_PARADROP",
-                           can_units_do(punits, can_unit_paradrop));
+                           can_units_do_on_map(&(wld.map), punits, can_unit_paradrop));
   /* FIXME: should conditionally rename "Pillage" to "Pillage..." in cases
    * where selecting the command results in a dialog box listing options of
    * what to pillage */
diff --git a/client/gui-gtk-4.0/menu.c b/client/gui-gtk-4.0/menu.c
index 89db3ad506..a5e427cb34 100644
--- a/client/gui-gtk-4.0/menu.c
+++ b/client/gui-gtk-4.0/menu.c
@@ -3782,7 +3782,7 @@ void real_menus_update(void)
                            units_can_do_action(punits, ACTION_ANY, TRUE));
 
   menu_entry_set_sensitive(map, "UNIT_TELEPORT",
-                           can_units_do(punits, can_unit_teleport));
+                           can_units_do_on_map(&(wld.map), punits, can_unit_teleport));
 
   menu_entry_set_sensitive(map, "BUILD_ROAD",
                            (can_units_do_any_road(&(wld.map), punits)
@@ -3802,7 +3802,7 @@ void real_menus_update(void)
                            can_units_do_activity_client(punits,
                                                         ACTIVITY_FORTIFYING));
   menu_entry_set_sensitive(map, "PARADROP",
-                           can_units_do(punits, can_unit_paradrop));
+                           can_units_do_on_map(&(wld.map), punits, can_unit_paradrop));
   menu_entry_set_sensitive(map, "PILLAGE",
                            can_units_do_activity_client(punits, ACTIVITY_PILLAGE));
   menu_entry_set_sensitive(map, "CLEAN",
diff --git a/client/gui-qt/hudwidget.cpp b/client/gui-qt/hudwidget.cpp
index fc206de54e..ee738c7c38 100644
--- a/client/gui-qt/hudwidget.cpp
+++ b/client/gui-qt/hudwidget.cpp
@@ -1112,7 +1112,7 @@ int unit_actions::update_actions()
   }
 
   // Paradrop
-  if (can_unit_paradrop(current_unit)) {
+  if (can_unit_paradrop(&(wld.map), current_unit)) {
     a = new hud_action(this);
     a->action_shortcut = SC_PARADROP;
     a->set_pixmap(fc_icons::instance()->get_pixmap("paradrop"));
diff --git a/client/gui-qt/menu.cpp b/client/gui-qt/menu.cpp
index e1ffa1539e..bee056a521 100644
--- a/client/gui-qt/menu.cpp
+++ b/client/gui-qt/menu.cpp
@@ -2416,7 +2416,7 @@ void mr_menu::menus_sensitive()
         break;
 
       case PARADROP:
-        if (can_units_do(punits, can_unit_paradrop)) {
+        if (can_units_do_on_map(&(wld.map), punits, can_unit_paradrop)) {
           i.value()->setEnabled(true);
           i.value()->setText(QString(action_id_name_translation(ACTION_PARADROP))
                              .replace("&", "&&"));
@@ -2748,7 +2748,7 @@ void mr_menu::slot_transform()
 void mr_menu::slot_paradrop()
 {
   unit_list_iterate(get_units_in_focus(), punit) {
-    if (can_unit_paradrop(punit)) {
+    if (can_unit_paradrop(&(wld.map), punit)) {
       key_unit_paradrop();
     }
   } unit_list_iterate_end;
diff --git a/client/gui-sdl2/dialogs.c b/client/gui-sdl2/dialogs.c
index 2ec0633149..2afdf447e3 100644
--- a/client/gui-sdl2/dialogs.c
+++ b/client/gui-sdl2/dialogs.c
@@ -1880,7 +1880,7 @@ void popup_advanced_terrain_dialog(struct tile *ptile,
 #endif /* 0 */
 
     /* FIXME: This logic seems to try to mirror do_paradrop() why? */
-    if (can_unit_paradrop(focus_unit) && client_tile_get_known(ptile)
+    if (can_unit_paradrop(&(wld.map), focus_unit) && client_tile_get_known(ptile)
         && !(((pcity && pplayers_non_attack(client.conn.playing, city_owner(pcity)))
               || is_non_attack_unit_tile(ptile, client.conn.playing)))
         && (unit_type_get(focus_unit)->paratroopers_range >=
diff --git a/client/gui-sdl2/menu.c b/client/gui-sdl2/menu.c
index 1f0617b057..519e7a12e0 100644
--- a/client/gui-sdl2/menu.c
+++ b/client/gui-sdl2/menu.c
@@ -1270,7 +1270,7 @@ void real_menus_update(void)
         set_wflag(order_airbase_button, WF_HIDDEN);
       }
 
-      if (can_unit_paradrop(punit)) {
+      if (can_unit_paradrop(&(wld.map), punit)) {
         local_show(ID_UNIT_ORDER_PARADROP);
       } else {
         local_hide(ID_UNIT_ORDER_PARADROP);
diff --git a/client/gui-sdl3/dialogs.c b/client/gui-sdl3/dialogs.c
index efd15332ca..847d3e35f3 100644
--- a/client/gui-sdl3/dialogs.c
+++ b/client/gui-sdl3/dialogs.c
@@ -1876,7 +1876,7 @@ void popup_advanced_terrain_dialog(struct tile *ptile,
 #endif /* 0 */
 
     /* FIXME: This logic seems to try to mirror do_paradrop() why? */
-    if (can_unit_paradrop(focus_unit) && client_tile_get_known(ptile)
+    if (can_unit_paradrop(&(wld.map), focus_unit) && client_tile_get_known(ptile)
         && !(((pcity && pplayers_non_attack(client.conn.playing, city_owner(pcity)))
               || is_non_attack_unit_tile(ptile, client.conn.playing)))
         && (unit_type_get(focus_unit)->paratroopers_range >=
diff --git a/client/gui-sdl3/menu.c b/client/gui-sdl3/menu.c
index c8245baa1f..ff95c145e6 100644
--- a/client/gui-sdl3/menu.c
+++ b/client/gui-sdl3/menu.c
@@ -1266,7 +1266,7 @@ void real_menus_update(void)
         set_wflag(order_airbase_button, WF_HIDDEN);
       }
 
-      if (can_unit_paradrop(punit)) {
+      if (can_unit_paradrop(&(wld.map), punit)) {
         local_show(ID_UNIT_ORDER_PARADROP);
       } else {
         local_hide(ID_UNIT_ORDER_PARADROP);
diff --git a/common/unit.c b/common/unit.c
index a6953097b2..c7eacfcc4a 100644
--- a/common/unit.c
+++ b/common/unit.c
@@ -796,10 +796,8 @@ bool can_unit_deboard_or_be_unloaded(const struct unit *pcargo,
   a friendly city or on an airbase special, has enough movepoints left, and
   has not paradropped yet this turn.
 **************************************************************************/
-bool can_unit_teleport(const struct unit *punit)
+bool can_unit_teleport(const struct civ_map *nmap, const struct unit *punit)
 {
-  const struct civ_map *nmap = &(wld.map);
-
   action_by_result_iterate(paction, ACTRES_TELEPORT) {
     if (action_maybe_possible_actor_unit(nmap, action_id(paction), punit)) {
       return TRUE;
@@ -814,10 +812,8 @@ bool can_unit_teleport(const struct unit *punit)
   a friendly city or on an airbase special, has enough movepoints left, and
   has not paradropped yet this turn.
 **************************************************************************/
-bool can_unit_paradrop(const struct unit *punit)
+bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
 {
-  const struct civ_map *nmap = &(wld.map);
-
   action_by_result_iterate(paction, ACTRES_PARADROP) {
     if (action_maybe_possible_actor_unit(nmap, action_id(paction), punit)) {
       return TRUE;
diff --git a/common/unit.h b/common/unit.h
index 7e041fba53..3aa284fa48 100644
--- a/common/unit.h
+++ b/common/unit.h
@@ -322,8 +322,8 @@ bool can_unit_load(const struct unit *punit, const struct unit *ptrans);
 bool can_unit_unload(const struct unit *punit, const struct unit *ptrans);
 bool can_unit_deboard_or_be_unloaded(const struct unit *pcargo,
                                      const struct unit *ptrans);
-bool can_unit_teleport(const struct unit *punit);
-bool can_unit_paradrop(const struct unit *punit);
+bool can_unit_teleport(const struct civ_map *nmap, const struct unit *punit);
+bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit);
 bool can_unit_change_homecity_to(const struct unit *punit,
                                  const struct city *pcity);
 bool can_unit_change_homecity(const struct unit *punit);
diff --git a/common/unitlist.c b/common/unitlist.c
index 14e782c0a2..559907018b 100644
--- a/common/unitlist.c
+++ b/common/unitlist.c
@@ -104,6 +104,24 @@ bool can_units_do(const struct unit_list *punits,
   return FALSE;
 }
 
+/************************************************************************//**
+  Return TRUE if the function returns true for any of the units,
+  on specific map.
+****************************************************************************/
+bool can_units_do_on_map(const struct civ_map *nmap,
+                         const struct unit_list *punits,
+                         bool (can_fn)(const struct civ_map *nmap,
+                                       const struct unit *punit))
+{
+  unit_list_iterate(punits, punit) {
+    if (can_fn(nmap, punit)) {
+      return TRUE;
+    }
+  } unit_list_iterate_end;
+
+  return FALSE;
+}
+
 /************************************************************************//**
   Returns TRUE if any of the units can do the activity.
 ****************************************************************************/
diff --git a/common/unitlist.h b/common/unitlist.h
index 0f81d12d27..94ddcaf85a 100644
--- a/common/unitlist.h
+++ b/common/unitlist.h
@@ -70,7 +70,11 @@ void unit_list_sort_ord_map(struct unit_list *punitlist);
 void unit_list_sort_ord_city(struct unit_list *punitlist);
 
 bool can_units_do(const struct unit_list *punits,
-		  bool (can_fn)(const struct unit *punit));
+                  bool (can_fn)(const struct unit *punit));
+bool can_units_do_on_map(const struct civ_map *nmap,
+                         const struct unit_list *punits,
+                         bool (can_fn)(const struct civ_map *nmap,
+                                       const struct unit *punit));
 bool can_units_do_activity(const struct civ_map *nmap,
                            const struct unit_list *punits,
                            enum unit_activity activity);
@@ -105,4 +109,4 @@ bool units_can_convert(const struct civ_map *nmap,
 }
 #endif /* __cplusplus */
 
-#endif  /* FC__UNITLIST_H */
+#endif /* FC__UNITLIST_H */
-- 
2.43.0

