Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2005:
[Freeciv-Dev] (PR#12559) [Patch] is_ocean() -> can_unit_exist_at_tile()
Home

[Freeciv-Dev] (PR#12559) [Patch] is_ocean() -> can_unit_exist_at_tile()

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: marko.lindqvist@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#12559) [Patch] is_ocean() -> can_unit_exist_at_tile()
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 21 Mar 2005 20:25:54 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Here is an updated version of the patch.

However the patch is buggy.  It doesn't allow any open-ground attacks by
air units (in can_unit_attack_unit_at_tile).  I think
can_unit_survive_at_tile doesn't do what you think it does.  In general
all of these changes need to be closely scrutinized, and a lot of the
code it touches I'm not familiar with.

-jason

Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.61
diff -u -r1.61 aidata.c
--- ai/aidata.c 21 Mar 2005 14:10:53 -0000      1.61
+++ ai/aidata.c 22 Mar 2005 04:23:12 -0000
@@ -535,6 +535,8 @@
   unit_list_iterate(pplayer->units, punit) {
     struct tile *ptile = punit->tile;
 
+    /* FIXME: Use can_unit_exist_at_tile() instead of is_ocean(),
+     * when stats.workers[] has space for sea workers. */
     if (!is_ocean(ptile->terrain) && unit_flag(punit, F_SETTLERS)) {
       ai->stats.workers[(int)map_get_continent(punit->tile)]++;
     }
Index: ai/aiferry.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiferry.c,v
retrieving revision 1.17
diff -u -r1.17 aiferry.c
--- ai/aiferry.c        21 Mar 2005 12:28:00 -0000      1.17
+++ ai/aiferry.c        22 Mar 2005 04:23:12 -0000
@@ -331,6 +331,10 @@
   search_map = pf_create_map(&param);
 
   pf_iterator(search_map, pos) {
+    /* Should this be !can_unit_exist_at_tile() instead of is_ocean() some day?
+     * That would allow special units to wade in shallow coast waters to meet
+     * ferry where deep sea starts. That would require some quite fundamental
+     * code changes elsewhere. */
     int radius = (is_ocean(pos.tile->terrain) ? 1 : 0);
 
     if (pos.turn + pos.total_EC/PF_TURN_FACTOR > best_turns) {
Index: ai/aihunt.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aihunt.c,v
retrieving revision 1.15
diff -u -r1.15 aihunt.c
--- ai/aihunt.c 19 Mar 2005 23:45:34 -0000      1.15
+++ ai/aihunt.c 22 Mar 2005 04:23:12 -0000
@@ -280,12 +280,12 @@
 
       if (ptile->city
           || TEST_BIT(target->ai.hunted, pplayer->player_no)
-          || (!is_ocean(ptile->terrain) && is_sailing_unit(punit))
-          || (is_ocean(ptile->terrain) && is_ground_unit(punit))
+         || !can_unit_exist_at_tile(punit, ptile)
           || (!is_sailing_unit(target) && is_sailing_unit(punit))
           || (is_sailing_unit(target) && !is_sailing_unit(punit))
           || !goto_is_sane(punit, target->tile, TRUE)) {
         /* Can't hunt this one. */
+       /* FIXME: this prevents airplanes from hunting sailing units. */
         continue;
       }
       if (target->ai.cur_pos && target->ai.prev_pos) {
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.347
diff -u -r1.347 aiunit.c
--- ai/aiunit.c 21 Mar 2005 12:28:00 -0000      1.347
+++ ai/aiunit.c 22 Mar 2005 04:23:13 -0000
@@ -1745,7 +1745,7 @@
     struct tile *ftile;
 
     if ((pc = dist_nearest_city(pplayer, punit->tile, FALSE, TRUE))) {
-      if (!is_ocean(map_get_terrain(punit->tile))) {
+      if (can_unit_exist_at_tile(punit, punit->tile)) {
         UNIT_LOG(LOG_DEBUG, punit, "Barbarian marching to conquer %s", 
pc->name);
         (void) ai_gothere(pplayer, punit, pc->tile);
       } else {
@@ -2214,9 +2214,9 @@
 
   CHECK_UNIT(leader);
 
-  if (leader->moves_left == 0 || 
-      (!is_ocean(map_get_terrain(leader->tile)) &&
-       unit_list_size(leader->tile->units) > 1) ) {
+  if (leader->moves_left == 0
+      || (can_unit_exist_at_tile(leader, leader->tile)
+          && unit_list_size(leader->tile->units) > 1) ) {
       handle_unit_activity_request(leader, ACTIVITY_SENTRY);
       return;
   }
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.319
diff -u -r1.319 city.c
--- common/city.c       15 Mar 2005 16:08:24 -0000      1.319
+++ common/city.c       22 Mar 2005 04:23:13 -0000
@@ -887,16 +887,10 @@
     return FALSE;
   }
 
-  if (punit) {
-    enum unit_move_type move_type = unit_type(punit)->move_type;
-    Terrain_type_id t = ptile->terrain;
-
+  if (punit && !can_unit_exist_at_tile(punit, ptile)) {
     /* We allow land units to build land cities and sea units to build
-     * ocean cities. */
-    if ((move_type == LAND_MOVING && is_ocean(t))
-       || (move_type == SEA_MOVING && !is_ocean(t))) {
-      return FALSE;
-    }
+     * ocean cities. Air units can build cities anywhere. */
+    return FALSE;
   }
 
   /* game.rgame.min_dist_bw_cities minimum is 1, meaning adjacent is okay */
Index: common/combat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.c,v
retrieving revision 1.51
diff -u -r1.51 combat.c
--- common/combat.c     14 Mar 2005 20:26:25 -0000      1.51
+++ common/combat.c     22 Mar 2005 04:23:13 -0000
@@ -80,7 +80,6 @@
                                  const struct unit *pdefender,
                                   const struct tile *dest_tile)
 {
-  Terrain_type_id fromtile = punit->tile->terrain;
   Terrain_type_id totile = dest_tile->terrain;
   struct city *pcity = dest_tile->city;
 
@@ -95,10 +94,11 @@
     return FALSE;
   }
 
-  /* 3. Can't attack with ground unit from ocean, except for marines */
-  if (is_ocean(fromtile)
-      && is_ground_unit(punit)
-      && !unit_flag(punit, F_MARINES)) {
+  /* 3. Can't attack from hostile terrain, except marines to
+        friendly terrain. */
+  if (!can_unit_survive_at_tile(punit, punit->tile)
+      && !(can_unit_survive_at_tile(punit, dest_tile)
+           && unit_flag(punit, F_MARINES))) {
     return FALSE;
   }
 
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.232
diff -u -r1.232 unit.c
--- common/unit.c       21 Mar 2005 12:28:00 -0000      1.232
+++ common/unit.c       22 Mar 2005 04:23:14 -0000
@@ -77,8 +77,8 @@
 {
   struct city *pcity=map_get_city(ptile);
 
-  if (action!=DIPLOMAT_MOVE
-      && is_ocean(map_get_terrain(pdiplomat->tile))) {
+  if (action != DIPLOMAT_MOVE
+      && !can_unit_exist_at_tile(pdiplomat, ptile)) {
     return FALSE;
   }
 
@@ -1127,12 +1127,12 @@
   unit_list_iterate(ptile->units, punit) {
     if (unit_owner(punit) == pplayer) {
       if (unit_flag(punit, F_CARRIER)
-         && !(is_ground_unit(punit) && is_ocean(ptile->terrain))) {
+          && can_unit_exist_at_tile(punit, ptile)) {
        *airall += get_transporter_capacity(punit);
        continue;
       }
       if (unit_flag(punit, F_MISSILE_CARRIER)
-         && !(is_ground_unit(punit) && is_ocean(ptile->terrain))) {
+         && can_unit_exist_at_tile(punit, ptile)) {
        *misonly += get_transporter_capacity(punit);
        continue;
       }
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.326
diff -u -r1.326 unithand.c
--- server/unithand.c   14 Mar 2005 20:26:26 -0000      1.326
+++ server/unithand.c   22 Mar 2005 04:23:14 -0000
@@ -1041,10 +1041,7 @@
         return FALSE;
       } else if (!can_unit_move_to_tile(punit, pdesttile, igzoc)) {
         notify_player_ex(pplayer, punit->tile, E_NOEVENT,
-                         is_ocean(map_get_terrain(punit->tile))
-                         ? _("Unit must be on land to "
-                             "perform diplomatic action.")
-                         : _("No diplomat action possible."));
+                         _("No diplomat action possible."));
         return FALSE;
       }
     }
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.328
diff -u -r1.328 unittools.c
--- server/unittools.c  21 Mar 2005 13:05:21 -0000      1.328
+++ server/unittools.c  22 Mar 2005 04:23:15 -0000
@@ -1269,7 +1269,7 @@
 
 /**************************************************************************
   For each pplayer's unit, check if we stack illegally, if so,
-  bounce both players' units. If on ocean tile, bounce everyone
+  bounce both players' units. If on ocean tile, bounce everyone but ships
   to avoid drowning. This function assumes that cities are clean.
 
   If verbose is true, the unit owner gets messages about where each
@@ -1285,7 +1285,7 @@
       unit_list_iterate_safe(ptile->units, aunit) {
         if (unit_owner(aunit) == pplayer
             || unit_owner(aunit) == aplayer
-            || is_ocean(ptile->terrain)) {
+            || !can_unit_survive_at_tile(aunit, ptile)) {
           bounce_unit(aunit, verbose);
         }
       } unit_list_iterate_safe_end;
@@ -2178,11 +2178,16 @@
     return FALSE;
   }
 
+  /* FIXME: Should check if unit can exist at terrain instead
+   *        of checking if terrain is ocean. */
+  /* FIXME: Should we allow paradropping anyway, player may have
+   *        reason to believe that ocean is terraformed into land? */
   if (is_ocean(map_get_player_tile(ptile, pplayer)->terrain)
       && is_ground_unit(punit)) {
     notify_player_ex(pplayer, ptile, E_NOEVENT,
-                     _("This unit cannot paradrop into ocean."));
-    return FALSE;    
+                     _("This unit cannot paradrop into %s."),
+                       get_terrain_name(map_get_player_tile(ptile, 
pplayer)->terrain));
+    return FALSE;
   }
 
   if (map_is_known_and_seen(ptile, pplayer)
@@ -2206,16 +2211,15 @@
     }
   }
 
-  if (is_ocean(map_get_terrain(ptile))
-      && is_ground_unit(punit)) {
+  if (!can_unit_exist_at_tile(punit, ptile)) {
     int srange = unit_type(punit)->vision_range;
 
     show_area(pplayer, ptile, srange);
 
     notify_player_ex(pplayer, ptile, E_UNIT_LOST,
-                     _("Your %s paradropped into the ocean "
+                     _("Your %s paradropped into the %s."
                        "and was lost."),
-                     unit_type(punit)->name);
+                     unit_type(punit)->name, get_terrain_name(ptile->terrain));
     server_remove_unit(punit);
     return TRUE;
   }
@@ -2589,8 +2593,6 @@
   square_iterate(punit->tile, 3, ptile) {
     unit_list_iterate(ptile->units, penemy) {
       int range;
-      enum unit_move_type move_type = unit_type(penemy)->move_type;
-      Terrain_type_id terrain = map_get_terrain(ptile);
 
       if (map_has_special(ptile, S_FORTRESS)
          && unit_profits_of_watchtower(penemy))
@@ -2603,7 +2605,7 @@
          && range >= real_map_distance(punit->tile, ptile)
          && can_player_see_unit(unit_owner(penemy), punit)
          /* on board transport; don't awaken */
-         && !(move_type == LAND_MOVING && is_ocean(terrain))) {
+          && !can_unit_exist_at_tile(punit, punit->tile)) {
        set_unit_activity(penemy, ACTIVITY_IDLE);
        send_unit_info(NULL, penemy);
       }

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