From be7e916045abed397eb883b0fecc849b976013e9 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Tue, 30 Jan 2024 20:21:29 +0200
Subject: [PATCH 17/17] Unhardcode wld.map from can_unit_paradrop()

See RM #209

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

diff --git a/ai/default/aiparatrooper.c b/ai/default/aiparatrooper.c
index 95f784476b..97b7da85c1 100644
--- a/ai/default/aiparatrooper.c
+++ b/ai/default/aiparatrooper.c
@@ -200,23 +200,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;
   }
@@ -226,7 +226,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) {
@@ -277,17 +277,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 58ebcf4c47..19c4890657 100644
--- a/client/control.c
+++ b/client/control.c
@@ -2143,7 +2143,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;
     }
diff --git a/client/gui-gtk-3.0/menu.c b/client/gui-gtk-3.0/menu.c
index a95858ed1b..82c1c17d9b 100644
--- a/client/gui-gtk-3.0/menu.c
+++ b/client/gui-gtk-3.0/menu.c
@@ -2519,7 +2519,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 */
   menu_entry_set_sensitive("DO_PILLAGE",
diff --git a/client/gui-gtk-3.22/menu.c b/client/gui-gtk-3.22/menu.c
index 3321637e07..3cb78ac401 100644
--- a/client/gui-gtk-3.22/menu.c
+++ b/client/gui-gtk-3.22/menu.c
@@ -2546,7 +2546,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 */
   menu_entry_set_sensitive("DO_PILLAGE",
diff --git a/client/gui-gtk-4.0/menu.c b/client/gui-gtk-4.0/menu.c
index e9886cbe68..07e26e9993 100644
--- a/client/gui-gtk-4.0/menu.c
+++ b/client/gui-gtk-4.0/menu.c
@@ -3783,7 +3783,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 5b0ffff249..757eae1510 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 e57433ae73..c6bbadf27b 100644
--- a/client/gui-qt/menu.cpp
+++ b/client/gui-qt/menu.cpp
@@ -2408,7 +2408,7 @@ void mr_menu::menus_sensitive()
 
       case POLLUTION:
         if (can_units_do_activity_client(punits, ACTIVITY_POLLUTION)
-            || can_units_do(punits, can_unit_paradrop)) {
+            || can_units_do_on_map(&(wld.map), punits, can_unit_paradrop)) {
           i.value()->setEnabled(true);
         }
         if (units_can_do_action_with_result(punits, ACTRES_PARADROP,
@@ -2675,9 +2675,9 @@ void mr_menu::slot_clean_pollution()
                                 unit_owner(punit), punit);
     if (pextra != NULL) {
       request_new_unit_activity_targeted(punit, ACTIVITY_POLLUTION, pextra);
-    } else if (can_unit_paradrop(punit)) {
+    } else if (can_unit_paradrop(&(wld.map), punit)) {
       /* FIXME: This is getting worse, we use a key_unit_*() function
-       * which assign the order for all units!  Very bad! */
+       * which assign the order for all units! Very bad! */
       key_unit_paradrop();
     }
   } unit_list_iterate_end;
diff --git a/client/gui-sdl2/dialogs.c b/client/gui-sdl2/dialogs.c
index 3dc984d160..8e20b270da 100644
--- a/client/gui-sdl2/dialogs.c
+++ b/client/gui-sdl2/dialogs.c
@@ -1877,7 +1877,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 8fd57f3439..91a8a54a58 100644
--- a/client/gui-sdl2/menu.c
+++ b/client/gui-sdl2/menu.c
@@ -1303,7 +1303,7 @@ void real_menus_update(void)
         set_wflag(order_pollution_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 1233a8657b..137dd58b54 100644
--- a/common/unit.c
+++ b/common/unit.c
@@ -816,10 +816,8 @@ bool can_unit_alight_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_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, paction->id, punit)) {
       return TRUE;
diff --git a/common/unit.h b/common/unit.h
index d339bd99b3..d6b53b5ab5 100644
--- a/common/unit.h
+++ b/common/unit.h
@@ -326,9 +326,9 @@ 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_alight_or_be_unloaded(const struct unit *pcargo,
                                     const struct unit *ptrans);
-bool can_unit_paradrop(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);
+                                 const struct city *pcity);
 bool can_unit_change_homecity(const struct unit *punit);
 const char *get_activity_text(enum unit_activity activity);
 bool can_unit_continue_current_activity(struct civ_map *nmap,
diff --git a/common/unitlist.c b/common/unitlist.c
index a6d038b3d6..adf214438d 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

