Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2004:
[Freeciv-Dev] Re: (PR#6972) Wishlist: units lost on arctic
Home

[Freeciv-Dev] Re: (PR#6972) Wishlist: units lost on arctic

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#6972) Wishlist: units lost on arctic
From: "Marcelo Burda" <mburda@xxxxxxxxx>
Date: Sat, 15 May 2004 03:49:05 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=6972 >

Le sam 15/05/2004 à 09:23, Jason Short a écrit :
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=6972 >
> 
> Marcelo Burda wrote:
> 
> > mmm, yes i see, but it is realy not a bug of my code, but a bug in the
> > original goto system i think, my patch show the limit of this system. i
> > need understand who it work to patch it
> 
> Greg understands it best.
> 
> I haven't looked closely, but I think the bug must be in your 
> implementation of is_dangerous_pos.  It is coming out that all positions 
> are dangerous.
> 
Yupi! i find it, it was a bug in pf code. i hate pf!
@@ -844,7 +844,7 @@
 
       /* Is the move ZOC-ok? */
       if (pf_map->params->get_zoc
-         && !(node->zoc_number > 1 || node1->zoc_number > 2)) {
+         && !(node->zoc_number > 1 || node1->zoc_number > 0)) {
        continue;
       }
this never was executed, gound unit neve has is_pos_dangerous defined
befor my patch!
> jason
-- 
 . /  .     '    ,    .      (*)   '        `     '      `    .    
  |    ,  |   `     ,     .      ,   '  Marcelo Julián Burda      .
 /  '     \     `     \@_     '      .        '      `        '    
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff -ruN -Xdiff_ignore freeciv/common/aicore/path_finding.c 
freeciv_/common/aicore/path_finding.c
--- freeciv/common/aicore/path_finding.c        2004-01-19 07:01:22.000000000 
+0100
+++ freeciv_/common/aicore/path_finding.c       2004-05-15 14:43:24.000000000 
+0200
@@ -214,12 +214,12 @@
 
   if (params->get_zoc) {
     struct tile *tile = map_get_tile(x, y);
-    bool my_zoc = (tile->city || is_ocean(tile->terrain)
-                  || params->get_zoc(params->owner, x, y));
+    bool my_zoc = tile->city || is_ocean(tile->terrain)
+                  || params->get_zoc(params->owner, x, y);
     /* ZoC rules cannot prevent us from moving into/attacking an occupied 
      * tile.  Other rules can, but we don't care about them here. */ 
-    bool occupied = (unit_list_size(&(map_get_tile(x, y)->units)) > 0
-                     || map_get_city(x, y));
+    bool occupied = unit_list_size(&(map_get_tile(x, y)->units)) > 0
+                     || map_get_city(x, y);
 
     /* 2 means can move unrestricted from/into it, 
      * 1 means can move unrestricted into it, but not necessarily from it */
@@ -252,7 +252,7 @@
   mapindex_t index;
   struct pf_node *node = &pf_map->lattice[pf_map->index];
 
-  if (pf_map->params->is_pos_dangerous) {
+  if (pf_map->params->is_pos_dangerous != NULL) {
     /* It's a lot different if is_pos_dangerous is defined */
     return danger_iterate_map(pf_map);
   }
@@ -403,7 +403,7 @@
   pf_map->lattice[pf_map->index].cost = pf_map->params->move_rate
       - pf_map->params->moves_left_initially;
   pf_map->lattice[pf_map->index].extra_cost = 0;
-  if (pf_map->params->is_pos_dangerous) {
+  if (pf_map->params->is_pos_dangerous != NULL) {
     /* The starting point is safe */
     pf_map->d_lattice[pf_map->index].is_dangerous = FALSE;
     /* Initialize step counter */
@@ -599,7 +599,7 @@
 ************************************************************************/
 struct pf_path *pf_next_get_path(const struct pf_map *pf_map)
 {
-  if (!pf_map->params->is_pos_dangerous) {
+  if (pf_map->params->is_pos_dangerous == NULL) {
     return construct_path(pf_map, pf_map->x, pf_map->y);
   } else {
     /* It's very different in the presence of danger */
@@ -616,7 +616,7 @@
   mapindex_t index = map_pos_to_index(x, y);
   utiny_t status = pf_map->status[index];
 
-  if (pf_map->params->is_pos_dangerous) {
+  if (pf_map->params->is_pos_dangerous != NULL) {
     /* It's very different in the presence of danger */
     return danger_get_path(pf_map, x, y);
   }
@@ -694,7 +694,7 @@
   struct pf_parameter *params = pf_map->params;
 
   /* Is the tile dangerous (i.e. no ending turn there) */
-  if (params->is_pos_dangerous) {
+  if (params->is_pos_dangerous != NULL) {
     d_node->is_dangerous =
        params->is_pos_dangerous(x, y, node->node_known_type, params);
   } else {
@@ -844,7 +844,7 @@
 
       /* Is the move ZOC-ok? */
       if (pf_map->params->get_zoc
-         && !(node->zoc_number > 1 || node1->zoc_number > 2)) {
+         && !(node->zoc_number > 1 || node1->zoc_number > 0)) {
        continue;
       }
 
diff -ruN -Xdiff_ignore freeciv/common/aicore/pf_tools.c 
freeciv_/common/aicore/pf_tools.c
--- freeciv/common/aicore/pf_tools.c    2004-04-30 00:49:10.000000000 +0200
+++ freeciv_/common/aicore/pf_tools.c   2004-05-15 14:21:34.000000000 +0200
@@ -385,13 +385,28 @@
 /**********************************************************************
   An example of position-dangerous callback.  For triremes.
   FIXME: it cheats.
+  FIXME We test for safe_ocean and  TER_UNSAFE but there is posible we 
+  only need to test the frist one
+  (later if we include spetials polar "triremes" i am thinking to the 
+  peple of the arctic making iglus)
 ***********************************************************************/
 static bool trireme_is_pos_dangerous(int x, int y, enum known_type known,
                                     struct pf_parameter *param)
 {
-  return is_ocean(map_get_terrain(x, y)) && !is_coastline(x, y);
+  return ( terrain_has_flag(map_get_terrain(x, y),TER_UNSAFE) 
+      || (is_ocean(map_get_terrain(x, y)) && !is_safe_ocean(x, y)))
+      && (map_get_city(x, y) == NULL ); /* no danger in cities */
 }
 
+/**********************************************************************
+  Position-dangerous callback.  For all units other than triremes.
+***********************************************************************/
+static bool is_pos_dangerous(int x, int y, enum known_type known,
+                                    struct pf_parameter *param)
+{
+  return terrain_has_flag(map_get_terrain(x, y),TER_UNSAFE)
+      && (map_get_city(x, y) == NULL );/* no danger in cities */
+}
 
 /* =====================  Tools for filling parameters =============== */
 
@@ -436,9 +451,11 @@
       && base_trireme_loss_pct(unit_owner(punit), punit) > 0) {
     parameter->turn_mode = TM_WORST_TIME;
     parameter->is_pos_dangerous = trireme_is_pos_dangerous;
-  } else {
-    parameter->is_pos_dangerous = NULL;
-  }
+  } else if (base_unsafe_terrain_loss_pct(unit_owner(punit), punit) > 0)
+  {
+    parameter->turn_mode = TM_WORST_TIME;
+    parameter->is_pos_dangerous = is_pos_dangerous;
+  } 
 }
 
 /**********************************************************************
@@ -467,9 +484,10 @@
   if (unit_flag(punit, F_TRIREME)
       && base_trireme_loss_pct(unit_owner(punit), punit) > 0) {
     parameter->is_pos_dangerous = trireme_is_pos_dangerous;
-  } else {
-    parameter->is_pos_dangerous = NULL;
-  }
+  } else if (base_unsafe_terrain_loss_pct(unit_owner(punit), punit) > 0)
+  {
+    parameter->is_pos_dangerous = is_pos_dangerous;
+  } 
 }
 
 /**********************************************************************
diff -ruN -Xdiff_ignore freeciv/common/map.c freeciv_/common/map.c
--- freeciv/common/map.c        2004-04-27 18:28:09.000000000 +0200
+++ freeciv_/common/map.c       2004-05-15 14:45:21.000000000 +0200
@@ -403,11 +403,11 @@
 /***************************************************************
 ...
 ***************************************************************/
-bool is_coastline(int x, int y)
+bool is_safe_ocean(int x, int y)
 {
   adjc_iterate(x, y, x1, y1) {
     enum tile_terrain_type ter = map_get_terrain(x1, y1);
-    if (!is_ocean(ter) && ter != T_UNKNOWN) {
+    if (!terrain_has_flag(ter, TER_UNSAFE_COAST) && ter != T_UNKNOWN) {
       return TRUE;
     }
   } adjc_iterate_end;
diff -ruN -Xdiff_ignore freeciv/common/map.h freeciv_/common/map.h
--- freeciv/common/map.h        2004-05-11 18:42:50.000000000 +0200
+++ freeciv_/common/map.h       2004-05-15 14:45:21.000000000 +0200
@@ -291,7 +291,7 @@
 const char *get_special_name(enum tile_special_type type);
 bool is_special_near_tile(int x, int y, enum tile_special_type spe);
 int count_special_near_tile(int x, int y, enum tile_special_type spe);
-bool is_coastline(int x,int y);
+bool is_safe_ocean(int x,int y);
 bool is_at_coast(int x, int y);
 bool is_sea_usable(int x, int y);
 int get_tile_food_base(struct tile * ptile);
diff -ruN -Xdiff_ignore freeciv/common/terrain.c freeciv_/common/terrain.c
--- freeciv/common/terrain.c    2004-02-27 11:13:01.000000000 +0100
+++ freeciv_/common/terrain.c   2004-05-15 10:44:01.000000000 +0200
@@ -67,6 +67,8 @@
     "NoPollution",
     "Starter",
     "CanHaveRiver",
+    "UnsafeCoast",
+    "Unsafe",
     "Oceanic"
   };
 
diff -ruN -Xdiff_ignore freeciv/common/terrain.h freeciv_/common/terrain.h
--- freeciv/common/terrain.h    2004-02-27 11:13:01.000000000 +0100
+++ freeciv_/common/terrain.h   2004-05-15 10:44:01.000000000 +0200
@@ -75,7 +75,9 @@
   TER_NO_POLLUTION, /* This terrain cannot be polluted. */
   TER_STARTER, /* Players will start on this terrain type. */
   TER_CAN_HAVE_RIVER, /* Terrains with this type can have S_RIVER on them. */
-  TER_OCEANIC, /* This is an ocean terrain. */
+  TER_UNSAFE_COAST,/*this tile is not safe as coast, (all ocean / ice) */ 
+  TER_UNSAFE,  /*unsafe for all units (ice,...) */
+  TER_OCEANIC, /* This is an ocean terrain. */ 
   TER_LAST
 };
 #define TER_FIRST (TER_NO_BARBS)
diff -ruN -Xdiff_ignore freeciv/common/unit.c freeciv_/common/unit.c
--- freeciv/common/unit.c       2004-05-08 17:21:07.000000000 +0200
+++ freeciv_/common/unit.c      2004-05-15 10:44:01.000000000 +0200
@@ -1567,22 +1567,34 @@
 }
 
 /**************************************************************************
-  Like base_trireme_loss_pct but take the position into account.
+  calculate lost_pct of unit taking the position into account.
 **************************************************************************/
-int trireme_loss_pct(struct player *pplayer, int x, int y,
+int unit_loss_pct(struct player *pplayer, int x, int y,
                     struct unit *punit)
 {
+  int loss_pct = 0;
+
   /*
    * If we are in a city or next to land, we have no chance of losing
    * the ship.  To make this really useful for ai planning purposes,
    * we'd need to confirm that we can exist/move at the (x, y)
    * location we are given.
    */
-  if (!is_ocean(map_get_terrain(x, y)) || is_coastline(x, y)) {
-    return 0;
-  } else {
-    return base_trireme_loss_pct(pplayer, punit);
+  if( map_get_city(x, y) ) {
+    return 0; 
+  }
+ 
+  if( unit_flag(punit, F_TRIREME)) {
+    if (!is_safe_ocean(x, y)) {
+      loss_pct = base_trireme_loss_pct(pplayer, punit);
+    }
+  }
+
+  if (terrain_has_flag(map_get_terrain(x, y), TER_UNSAFE)) {
+    return loss_pct + base_unsafe_terrain_loss_pct( pplayer, punit);
   }
+
+  return loss_pct;
 }
 
 /**************************************************************************
@@ -1603,6 +1615,14 @@
 }
 
 /**************************************************************************
+ all no air unit have a 15% loss percentage in unsafe terrains
+ **************************************************************************/
+int base_unsafe_terrain_loss_pct(struct player *pplayer,struct unit *punit)
+{
+    return is_air_unit(punit) ? 0 : 15;
+}
+
+/**************************************************************************
 An "aggressive" unit is a unit which may cause unhappiness
 under a Republic or Democracy.
 A unit is *not* aggressive if one or more of following is true:
diff -ruN -Xdiff_ignore freeciv/common/unit.h freeciv_/common/unit.h
--- freeciv/common/unit.h       2004-05-08 17:21:07.000000000 +0200
+++ freeciv_/common/unit.h      2004-05-15 10:44:01.000000000 +0200
@@ -312,9 +312,13 @@
 struct unit *is_non_attack_unit_tile(struct tile *ptile,
                                     struct player *pplayer);
 
-int trireme_loss_pct(struct player *pplayer, int x, int y,
+
+
+int unit_loss_pct(struct player *pplayer, int x, int y,
                     struct unit *punit);
 int base_trireme_loss_pct(struct player *pplayer, struct unit *punit);
+int base_unsafe_terrain_loss_pct(struct player *pplayer,
+                                struct unit *punit);
 
 bool is_my_zoc(struct player *unit_owner, int x0, int y0);
 bool unit_being_aggressive(struct unit *punit);
diff -ruN -Xdiff_ignore freeciv/data/civ1/terrain.ruleset 
freeciv_/data/civ1/terrain.ruleset
--- freeciv/data/civ1/terrain.ruleset   2004-02-27 11:13:02.000000000 +0100
+++ freeciv_/data/civ1/terrain.ruleset  2004-05-15 10:44:49.000000000 +0200
@@ -403,6 +403,7 @@
 mining_time          = 10
 transform_result     = "no"
 transform_time       = 0
+flags                =
 helptext            = _("\
 Mountains are regions of extreme altitude, making agriculture and\
  trade very difficult.\
@@ -439,7 +440,7 @@
 mining_time          = 0
 transform_result     = "no"
 transform_time       = 0
-flags                = "Oceanic", "NoPollution"
+flags                = "Oceanic", "NoPollution", "UnsafeCoast"
 helptext            = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
diff -ruN -Xdiff_ignore freeciv/data/civ2/terrain.ruleset 
freeciv_/data/civ2/terrain.ruleset
--- freeciv/data/civ2/terrain.ruleset   2004-02-27 11:13:02.000000000 +0100
+++ freeciv_/data/civ2/terrain.ruleset  2004-05-15 10:44:01.000000000 +0200
@@ -452,7 +452,7 @@
 mining_time          = 0
 transform_result     = "no"
 transform_time       = 0
-flags                = "Oceanic", "NoPollution"
+flags                = "Oceanic", "NoPollution, "UnsafeCoast"
 helptext            = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
diff -ruN -Xdiff_ignore freeciv/data/default/terrain.ruleset 
freeciv_/data/default/terrain.ruleset
--- freeciv/data/default/terrain.ruleset        2004-02-27 11:13:02.000000000 
+0100
+++ freeciv_/data/default/terrain.ruleset       2004-05-15 10:44:01.000000000 
+0200
@@ -193,7 +193,7 @@
 mining_time          = 10
 transform_result     = "Tundra"
 transform_time       = 24
-flags                = "NoBarbs", "CanHaveRiver"
+flags                = "NoBarbs", "CanHaveRiver", "UnsafeCoast", "Unsafe"
 helptext            = _("\
 Glaciers are found only in the most northerly or southerly\
  reaches of the world.  They are very cold, and hence difficult to\
@@ -452,7 +452,7 @@
 mining_time          = 0
 transform_result     = "Swamp"
 transform_time       = 36
-flags                = "Oceanic", "NoPollution"
+flags                = "Oceanic", "NoPollution", "UnsafeCoast" 
 helptext            = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
diff -ruN -Xdiff_ignore freeciv/server/gotohand.c freeciv_/server/gotohand.c
--- freeciv/server/gotohand.c   2004-01-20 22:52:09.000000000 +0100
+++ freeciv_/server/gotohand.c  2004-05-15 10:44:01.000000000 +0200
@@ -690,7 +690,11 @@
              /* Allow players to target anything */
              continue;
            } else {
-             move_cost = SINGLE_MOVE;
+               /* avoid to travel over danger tiles */
+             move_cost =
+                 (unit_loss_pct(unit_owner(punit), x1, y1, punit)>0)
+                 ?(2*SINGLE_MOVE+1)
+                 :SINGLE_MOVE;
            }
          }
        } else if (!goto_zoc_ok(punit, x, y, x1, y1, LOCAL_VECTOR(x, y))) {
@@ -712,8 +716,7 @@
            && !same_pos(x1, y1, dest_x, dest_y)) {
          continue;
        }
-       else if (unit_flag(punit, F_TRIREME) &&
-                trireme_loss_pct(unit_owner(punit), x1, y1, punit) > 0) {
+       else if (unit_loss_pct(unit_owner(punit), x1, y1, punit) > 0) {
          move_cost = 2*SINGLE_MOVE+1;
        } else {
          move_cost = SINGLE_MOVE;
@@ -1153,7 +1156,7 @@
   } adjc_dir_iterate_end;
 
   if (best_fitness == DONT_SELECT_ME_FITNESS && afraid_of_sinking
-      && !is_coastline(punit->x, punit->y)) {
+      && !is_safe_ocean(punit->x, punit->y)) {
     /* 
      * We've got a trireme in the middle of the sea. With
      * best_fitness==DONT_SELECT_ME_FITNESS, it'll end its turn right
diff -ruN -Xdiff_ignore freeciv/server/mapgen.c freeciv_/server/mapgen.c
--- freeciv/server/mapgen.c     2004-04-27 18:28:18.000000000 +0200
+++ freeciv_/server/mapgen.c    2004-05-15 10:44:01.000000000 +0200
@@ -1462,6 +1462,18 @@
   return FALSE;
 }
 
+/* ************************************************************
+ * return TRUE if a safe tile is in a city radius
+ * ************************************************************/
+static bool near_safe_tiles(int x_ct, int y_ct)
+{
+    map_city_radius_iterate(x_ct, y_ct, map_x, map_y) {
+    if (!terrain_has_flag(map_get_terrain(map_x, map_y), TER_UNSAFE_COAST)) {
+      return TRUE;
+    }  
+  }  map_city_radius_iterate_end;
+  return FALSE;
+}
 /**************************************************************************
   this function spreads out huts on the map, a position can be used for a
   hut if there isn't another hut close and if it's not on the ocean.
@@ -1516,7 +1528,8 @@
     for (xn = 0; xn < map.xsize; xn++) {
       do_in_map_pos(x, y, xn, yn) {
        ttype = map_get_terrain(x, y);
-       if ((is_ocean(ttype) && is_coastline(x, y)) || !is_ocean(ttype)) {
+       if ((is_ocean(ttype) && near_safe_tiles(x,y)) 
+           || !is_ocean(ttype)) {
          if (myrand(1000) < prob) {
            if (!is_special_close(x, y)) {
              if (tile_types[ttype].special_1_name[0] != '\0'
@@ -1679,10 +1692,20 @@
   }
 }
 
-/*************************************************************************/
+/*************************************************************************
+*************************************************************************/
+static bool is_near_land(center_x, center_y)
+{
+  adjc_iterate(center_x, center_y, x_itr, y_itr) {
+    if (!is_ocean(map_get_terrain(x_itr, y_itr))) {
+      return TRUE;
+    }
+  }
+  adjc_iterate_end;
+  return FALSE;
+}
 
 static long int checkmass;
-
 /**************************************************************************
   finds a place and drop the island created when called with islemass != 0
 **************************************************************************/
@@ -1709,7 +1732,7 @@
     if (!normalize_map_pos(&map_x, &map_y)) {
       return FALSE;
     }
-    if (hnat(xn, yn) != 0 && is_coastline(map_x, map_y)) {
+    if (hnat(xn, yn) != 0 && is_near_land(map_x, map_y)) {
       return FALSE;
     }
   }
@@ -1724,7 +1747,7 @@
       if (!normalize_map_pos(&map_x, &map_y)) {
        return FALSE;
       }
-      if (hnat(xn, yn) != 0 && is_coastline(map_x, map_y)) {
+      if (hnat(xn, yn) != 0 && is_near_land(map_x, map_y)) {
        return FALSE;
       }
     }
diff -ruN -Xdiff_ignore freeciv/server/unittools.c freeciv_/server/unittools.c
--- freeciv/server/unittools.c  2004-05-11 18:59:15.000000000 +0200
+++ freeciv_/server/unittools.c 2004-05-15 10:44:02.000000000 +0200
@@ -286,6 +286,7 @@
 that is handled within unit_restore_hitpoints().)
 Triremes will be wiped with a variable chance if they're not close to
 land, and player doesn't have Lighthouse.
+all ground units in unsafe tiles can lost
 ****************************************************************************/
 void player_restore_units(struct player *pplayer)
 {
@@ -296,6 +297,7 @@
   unit_list_iterate_safe(pplayer->units, punit) {
 
     /* 2) Modify unit hitpoints. Helicopters can even lose them. */
+    /*    all ground and see unit in unsafe tiles too */
     unit_restore_hitpoints(pplayer, punit);
 
     /* 3) Check that unit has hitpoints */
@@ -315,7 +317,7 @@
 
     /* 4) Check that triremes are near coastline, otherwise... */
     if (unit_flag(punit, F_TRIREME)) {
-      int loss_chance = trireme_loss_pct(pplayer, punit->x, punit->y, punit);
+      int loss_chance = unit_loss_pct(pplayer, punit->x, punit->y, punit);
       if (myrand(100) < loss_chance) {
         notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_LOST, 
                          _("Game: Your %s has been lost on the high seas."),
@@ -333,6 +335,17 @@
                            unit_name(punit->type));
         }
       }
+  /* 4bis> Check that not air unit or triremes is on a unsafe place */
+    } else if ((!is_air_unit(punit))
+       && (myrand(100) < unit_loss_pct(pplayer, punit->x,
+                                                  punit->y, punit))) {
+      notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_LOST,
+                      _("Game: Your %s has been lost on unsafe terrain."),
+                      unit_name(punit->type));
+      gamelog(GAMELOG_UNITTRI, _("%s unit lost on unsafe terrain"),
+             get_nation_name_plural(pplayer->nation));
+      wipe_unit(punit);
+      continue;                        /* Continue iterating... */
     }
 
     /* 5) Rescue planes if needed */
@@ -390,6 +403,7 @@
       wipe_unit(punit);
     } 
   } unit_list_iterate_safe_end;
+
 }
 
 /****************************************************************************

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