Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2006:
[Freeciv-Dev] Re: (PR#18605) [Bugfix] auto-return fixes
Home

[Freeciv-Dev] Re: (PR#18605) [Bugfix] auto-return fixes

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#18605) [Bugfix] auto-return fixes
From: "Marko Lindqvist" <cazfi74@xxxxxxxxx>
Date: Wed, 19 Jul 2006 12:04:49 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=18605 >

Marko Lindqvist wrote:
> 
>   These fix several airplane auto-return problems
> 
>   - Don't go for another refuel point if we are loaded to carrier.
>   - If we are above free carrier: land
>   - Once we reach free carrier: land

  - Fixed assert failure
  - Auto-return also when we already have zero fuel - this means saving 
aircrafts created by editor
  - Renamed is_airunit_refuel_point() parameter unit_is_on_tile to 
unit_is_on_carrier


  - ML

diff -Nurd -X.diff_ignore freeciv/ai/aiair.c freeciv/ai/aiair.c
--- freeciv/ai/aiair.c  2006-07-19 20:53:48.293399800 +0300
+++ freeciv/ai/aiair.c  2006-07-19 21:33:44.746524800 +0300
@@ -292,8 +292,7 @@
 
   CHECK_UNIT(punit);
 
-  if (!is_airunit_refuel_point(punit->tile, 
-                              pplayer, punit->type, FALSE)) {
+  if (!is_unit_being_refueled(punit)) {
     /* We are out in the open, what shall we do? */
     struct tile *refuel_tile;
 
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c  2006-07-19 21:33:37.246524800 +0300
+++ freeciv/server/unittools.c  2006-07-19 21:35:30.637149800 +0300
@@ -385,34 +385,45 @@
       /* I think this is strongly against the spirit of client goto.
        * The problem is (again) that here we know too much. -- Zamar */
 
-      if (punit->fuel == 1
-         && !is_airunit_refuel_point(punit->tile,
-                                     unit_owner(punit), punit->type, TRUE)) {
-       iterate_outward(punit->tile, punit->moves_left/3, itr_tile) {
-         if (is_airunit_refuel_point(itr_tile, unit_owner(punit),
-                                     punit->type, FALSE)
-             &&(air_can_move_between(punit->moves_left / 3, punit->tile,
-                                     itr_tile, unit_owner(punit)) >= 0)) {
-           punit->goto_tile = itr_tile;
-           set_unit_activity(punit, ACTIVITY_GOTO);
-           (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
-           notify_player(pplayer, punit->tile, E_UNIT_ORDERS, 
-                            _("Your %s has returned to refuel."),
-                            unit_name(punit->type));
-           goto OUT;
-         }
-       } iterate_outward_end;
+      if (punit->fuel <= 1
+          && !is_unit_being_refueled(punit)) {
+        struct unit *carrier;
+
+        carrier = find_transport_from_tile(punit, punit->tile);
+        if (carrier) {
+          put_unit_onto_transporter(punit, carrier);
+        } else {
+          iterate_outward(punit->tile, punit->moves_left / SINGLE_MOVE, 
itr_tile) {
+            if (is_airunit_refuel_point(itr_tile, unit_owner(punit),
+                                        punit->type, FALSE)
+                &&(air_can_move_between(punit->moves_left / SINGLE_MOVE, 
punit->tile,
+                                        itr_tile, unit_owner(punit)) >= 0)) {
+              punit->goto_tile = itr_tile;
+              set_unit_activity(punit, ACTIVITY_GOTO);
+              (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
+
+              if (!is_unit_being_refueled(punit)) {
+                carrier = find_transport_from_tile(punit, punit->tile);
+                if (carrier) {
+                  put_unit_onto_transporter(punit, carrier);
+                }
+              }
+
+              notify_player(pplayer, punit->tile, E_UNIT_ORDERS, 
+                            _("Your %s has returned to refuel."),
+                            unit_name(punit->type));
+              break;
+            }
+          } iterate_outward_end;
+        }
       }
-    OUT:
 
       /* 6) Update fuel */
       punit->fuel--;
 
       /* 7) Automatically refuel air units in cities, airbases, and
        *    transporters (carriers). */
-      if (tile_get_city(punit->tile)
-         || tile_has_special(punit->tile, S_AIRBASE)
-         || punit->transported_by != -1) {
+      if (is_unit_being_refueled(punit)) {
        punit->fuel=unit_type(punit)->fuel;
       }
     }
@@ -1171,11 +1182,21 @@
 }
 
 /**************************************************************************
+ Is unit being refueled in its current position
+**************************************************************************/
+bool is_unit_being_refueled(const struct unit *punit)
+{
+  return (punit->transported_by != -1                   /* Carrier */
+          || punit->tile->city                          /* City    */
+          || tile_has_special(punit->tile, S_AIRBASE)); /* Airbase */
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
                             const struct unit_type *type,
-                            bool unit_is_on_tile)
+                            bool unit_is_on_carrier)
 {
   int cap;
   struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
@@ -1188,7 +1209,7 @@
 
   cap = unit_class_transporter_capacity(ptile, pplayer, get_unit_class(type));
 
-  if (unit_is_on_tile) {
+  if (unit_is_on_carrier) {
     cap++;
   }
 
diff -Nurd -X.diff_ignore freeciv/server/unittools.h freeciv/server/unittools.h
--- freeciv/server/unittools.h  2006-07-19 20:59:28.980899800 +0300
+++ freeciv/server/unittools.h  2006-07-19 21:35:46.121524800 +0300
@@ -27,9 +27,10 @@
                      bool bombard);
 
 /* move check related */
+bool is_unit_being_refueled(const struct unit *punit);
 bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
                             const struct unit_type *punittype,
-                            bool unit_is_on_tile);
+                            bool unit_is_on_carrier);
 
 /* turn update related */
 void player_restore_units(struct player *pplayer);
diff -Nurd -X.diff_ignore freeciv/ai/aiair.c freeciv/ai/aiair.c
--- freeciv/ai/aiair.c  2006-07-18 15:19:56.187500000 +0300
+++ freeciv/ai/aiair.c  2006-07-19 21:43:03.965274800 +0300
@@ -292,8 +292,7 @@
 
   CHECK_UNIT(punit);
 
-  if (!is_airunit_refuel_point(punit->tile, 
-                              pplayer, punit->type, FALSE)) {
+  if (!is_unit_being_refueled(punit)) {
     /* We are out in the open, what shall we do? */
     struct tile *refuel_tile;
 
diff -Nurd -X.diff_ignore freeciv/common/unit.c freeciv/common/unit.c
--- freeciv/common/unit.c       2006-07-18 15:20:49.843750000 +0300
+++ freeciv/common/unit.c       2006-07-19 21:43:03.996524800 +0300
@@ -1094,15 +1094,10 @@
 /****************************************************************************
   Measure the carrier (missile + airplane) capacity of the given tile for
   a player.
-
-  In the future this should probably look at the actual occupancy of the
-  transporters.  However for now we only look at the potential capacity and
-  leave loading up to the caller.
 ****************************************************************************/
 static void count_carrier_capacity(int *airall, int *misonly,
                                   const struct tile *ptile,
-                                  const struct player *pplayer,
-                                  bool count_units_with_extra_fuel)
+                                  const struct player *pplayer)
 {
   *airall = *misonly = 0;
 
@@ -1111,61 +1106,49 @@
       if (unit_flag(punit, F_CARRIER)
          && !(is_ground_unit(punit) && is_ocean(ptile->terrain))) {
        *airall += get_transporter_capacity(punit);
+        *airall -= get_transporter_occupancy(punit);
        continue;
       }
       if (unit_flag(punit, F_MISSILE_CARRIER)
          && !(is_ground_unit(punit) && is_ocean(ptile->terrain))) {
        *misonly += get_transporter_capacity(punit);
+        *misonly -= get_transporter_occupancy(punit);
        continue;
       }
-
-      /* Don't count units which have enough fuel (>1) */
-      if (is_air_unit(punit)
-         && (count_units_with_extra_fuel || punit->fuel <= 1)) {
-       if (unit_flag(punit, F_MISSILE)) {
-         (*misonly)--;
-       } else {
-         (*airall)--;
-       }
-      }
     }
   } unit_list_iterate_end;
 }
 
 /**************************************************************************
   Returns the number of free spaces for missiles for the given player on
-  the given tile. Can be 0 or negative.
+  the given tile. Can be 0.
 **************************************************************************/
 int missile_carrier_capacity(const struct tile *ptile,
-                            const struct player *pplayer,
-                            bool count_units_with_extra_fuel)
+                            const struct player *pplayer)
 {
   int airall, misonly;
 
-  count_carrier_capacity(&airall, &misonly, ptile, pplayer,
-                        count_units_with_extra_fuel);
+  count_carrier_capacity(&airall, &misonly, ptile, pplayer);
 
-  /* Any extra air spaces can be used by missles, but if there aren't enough
+  /* Any extra air spaces can be used by missiles, but if there aren't enough
    * air spaces this doesn't bother missiles. */
-  return MAX(airall, 0) + misonly;
+  return airall + misonly;
 }
 
 /**************************************************************************
   Returns the number of free spaces for airunits (includes missiles) for
-  the given player on the given tile.  Can be 0 or negative.
+  the given player on the given tile.  Can be 0.
 **************************************************************************/
 int airunit_carrier_capacity(const struct tile *ptile,
-                            const struct player *pplayer,
-                            bool count_units_with_extra_fuel)
+                            const struct player *pplayer)
 {
   int airall, misonly;
 
-  count_carrier_capacity(&airall, &misonly, ptile, pplayer,
-                        count_units_with_extra_fuel);
+  count_carrier_capacity(&airall, &misonly, ptile, pplayer);
 
   /* Any extra missile spaces are useless to air units, but if there aren't
    * enough missile spaces the missles must take up airunit capacity. */
-  return airall + MIN(misonly, 0);
+  return airall;
 }
 
 /**************************************************************************
diff -Nurd -X.diff_ignore freeciv/common/unit.h freeciv/common/unit.h
--- freeciv/common/unit.h       2006-07-18 15:20:49.859375000 +0300
+++ freeciv/common/unit.h       2006-07-19 21:43:04.027774800 +0300
@@ -269,11 +269,9 @@
 int get_transporter_capacity(const struct unit *punit);
 bool is_ground_units_transport(const struct unit *punit);
 int missile_carrier_capacity(const struct tile *ptile,
-                            const struct player *pplayer,
-                            bool count_units_with_extra_fuel);
+                            const struct player *pplayer);
 int airunit_carrier_capacity(const struct tile *ptile,
-                            const struct player *pplayer,
-                            bool count_units_with_extra_fuel);
+                            const struct player *pplayer);
 
 struct player *unit_owner(const struct unit *punit);
 
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c  2006-07-18 15:22:30.718750000 +0300
+++ freeciv/server/unittools.c  2006-07-19 21:44:03.590274800 +0300
@@ -385,34 +385,60 @@
       /* I think this is strongly against the spirit of client goto.
        * The problem is (again) that here we know too much. -- Zamar */
 
-      if (punit->fuel == 1
-         && !is_airunit_refuel_point(punit->tile,
-                                     unit_owner(punit), punit->type, TRUE)) {
-       iterate_outward(punit->tile, punit->moves_left/3, itr_tile) {
-         if (is_airunit_refuel_point(itr_tile, unit_owner(punit),
-                                     punit->type, FALSE)
-             &&(air_can_move_between(punit->moves_left / 3, punit->tile,
-                                     itr_tile, unit_owner(punit)) >= 0)) {
-           punit->goto_tile = itr_tile;
-           set_unit_activity(punit, ACTIVITY_GOTO);
-           (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
-           notify_player(pplayer, punit->tile, E_UNIT_ORDERS, 
-                            _("Your %s has returned to refuel."),
-                            unit_name(punit->type));
-           goto OUT;
-         }
-       } iterate_outward_end;
+      if (punit->fuel <= 1
+          && !is_unit_being_refueled(punit)) {
+        bool carrier_found = FALSE;
+
+        unit_list_iterate(punit->tile->units, carrier) {
+          if ((unit_flag(carrier, F_CARRIER)
+               || (unit_flag(punit, F_MISSILE)
+                   && unit_flag(carrier, F_MISSILE_CARRIER)))
+              && get_transporter_capacity(carrier) >
+                 get_transporter_occupancy(carrier)) {
+            put_unit_onto_transporter(punit, carrier);
+            carrier_found = TRUE;
+            break;
+          }
+        } unit_list_iterate_end;
+       
+        if (!carrier_found) {
+          iterate_outward(punit->tile, punit->moves_left / SINGLE_MOVE, 
itr_tile) {
+            if (is_airunit_refuel_point(itr_tile, unit_owner(punit),
+                                        punit->type, FALSE)
+                &&(air_can_move_between(punit->moves_left / SINGLE_MOVE, 
punit->tile,
+                                        itr_tile, unit_owner(punit)) >= 0)) {
+              punit->goto_tile = itr_tile;
+              set_unit_activity(punit, ACTIVITY_GOTO);
+              (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
+
+              if (!is_unit_being_refueled(punit)) {
+                unit_list_iterate(punit->tile->units, carrier) {
+                  if ((unit_flag(carrier, F_CARRIER)
+                       || (unit_flag(punit, F_MISSILE)
+                           && unit_flag(carrier, F_MISSILE_CARRIER)))
+                      && get_transporter_capacity(carrier) >
+                         get_transporter_occupancy(carrier)) {
+                    put_unit_onto_transporter(punit, carrier);
+                    break;
+                  }
+                } unit_list_iterate_end;
+              }
+
+              notify_player(pplayer, punit->tile, E_UNIT_ORDERS, 
+                            _("Your %s has returned to refuel."),
+                            unit_name(punit->type));
+              break;
+            }
+          } iterate_outward_end;
+        }
       }
-    OUT:
 
       /* 6) Update fuel */
       punit->fuel--;
 
       /* 7) Automatically refuel air units in cities, airbases, and
        *    transporters (carriers). */
-      if (tile_get_city(punit->tile)
-         || tile_has_special(punit->tile, S_AIRBASE)
-         || punit->transported_by != -1) {
+      if (is_unit_being_refueled(punit)) {
        punit->fuel=unit_type(punit)->fuel;
       }
     }
@@ -1171,11 +1197,21 @@
 }
 
 /**************************************************************************
+ Is unit being refueled in its current position
+**************************************************************************/
+bool is_unit_being_refueled(const struct unit *punit)
+{
+  return (punit->transported_by != -1                   /* Carrier */
+          || punit->tile->city                          /* City    */
+          || tile_has_special(punit->tile, S_AIRBASE)); /* Airbase */
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
                             const struct unit_type *type,
-                            bool unit_is_on_tile)
+                            bool unit_is_on_carrier)
 {
   struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
 
@@ -1186,13 +1222,13 @@
     return TRUE;
 
   if (unit_type_flag(type, F_MISSILE)) {
-    int cap = missile_carrier_capacity(ptile, pplayer, FALSE);
-    if (unit_is_on_tile)
+    int cap = missile_carrier_capacity(ptile, pplayer);
+    if (unit_is_on_carrier)
       cap++;
     return cap>0;
   } else {
-    int cap = airunit_carrier_capacity(ptile, pplayer, FALSE);
-    if (unit_is_on_tile)
+    int cap = airunit_carrier_capacity(ptile, pplayer);
+    if (unit_is_on_carrier)
       cap++;
     return cap>0;
   }
diff -Nurd -X.diff_ignore freeciv/server/unittools.h freeciv/server/unittools.h
--- freeciv/server/unittools.h  2006-07-18 15:22:30.734375000 +0300
+++ freeciv/server/unittools.h  2006-07-19 21:44:13.840274800 +0300
@@ -27,9 +27,10 @@
                      bool bombard);
 
 /* move check related */
+bool is_unit_being_refueled(const struct unit *punit);
 bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
                             const struct unit_type *punittype,
-                            bool unit_is_on_tile);
+                            bool unit_is_on_carrier);
 
 /* turn update related */
 void player_restore_units(struct player *pplayer);

[Prev in Thread] Current Thread [Next in Thread]