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: Tue, 4 May 2004 16:46:56 -0700
Reply-to: rt@xxxxxxxxxxx

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

Le mar 04/05/2004 à 21:12, Jason Short a écrit :
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=6972 >
> 
> Marcelo Burda wrote:
> > <URL: http://rt.freeciv.org/Ticket/Display.html?id=6972 >
...
> OK, it's not blocked on any design or gameplay issue.  We just have to 
> agree on the details.
> 
> - is_safeline is no good as a name.  I suggest is_safe_ocean().  This 
> should only be called for ocean terrains and handles tririeme loss.  In 
> fact it probably shouldn't be in map.h but should be moved into unit.c 
> and made static.
ok for is_safe_ocean() but this function still used directly by the ia.
this go change later with a deepocean terrains.
> 
> - Normal unit loss is handled directly by the TER_UNSAFE flag.  If this 
> flag is set there is a chance of loss.  Don't check for adjacent safe 
> coasts here.
donne
> 
> - Eventually we should merge tririeme_loss_pct and 
> unsafe_terrain_loss_pct into a single function.  unit_loss_pct or 
> something like that.  This function should do _all_ the work, checking 
> the terrain and the unit flags.  Maybe this shouldn't happen immediately.
> 
donne
> - Your base_unsafe_terrain_loss_pct should be static.  And it needs a 
> return type; currently the code doesn't compile properly.
used by pf(no static). now compile
> 
> - This AI code:
> 
> -             move_cost = SINGLE_MOVE;
> +             move_cost = (unsafe_terrain_loss_pct>0)
> +                 ?(2*SINGLE_MOVE+1)
> +                 :SINGLE_MOVE;
comment add and bug fixed (unsafe_terrain_loss_pct was no args!!)
> 
> needs an explanatory comment.
> 
> - near_ok_city_places should use a city iterator (from common/city.h), 
> not square_iterate.  I can't quite figure out what this function does. 
> It returns true if there is any tile within city range that is not an 
> unsafe coast terrain?  What's the point of that?  Is this just a clever 
> way of special-casing arctic?
reanme as near_safe_tiles(), iterator donne
> 
> - is_near_land is a good function.
Fine! :-)
> 
> jason
There is the corrected version
Marcelo

diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/common/aicore/pf_tools.c 
freeciv-cvs-Apr-29_/common/aicore/pf_tools.c
--- freeciv-cvs-Apr-29/common/aicore/pf_tools.c 2004-04-30 07:11:51.000000000 
+0200
+++ freeciv-cvs-Apr-29_/common/aicore/pf_tools.c        2004-05-05 
02:58:36.000000000 +0200
@@ -389,9 +389,19 @@
 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));
 }
 
+/**********************************************************************
+  An example of position-dangerous callback.  For all units.
+  FIXME: it cheats.
+***********************************************************************/
+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);
+}
 
 /* =====================  Tools for filling parameters =============== */
 
@@ -436,9 +446,12 @@
       && 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;
+  } /* FIX ME triremes are safes in unsafe oceans where best naval
+       unit are unsafe! */
 }
 
 /**********************************************************************
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/common/map.c 
freeciv-cvs-Apr-29_/common/map.c
--- freeciv-cvs-Apr-29/common/map.c     2004-04-21 07:11:39.000000000 +0200
+++ freeciv-cvs-Apr-29_/common/map.c    2004-05-05 01:53:05.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-cvs-Apr-29/common/map.h 
freeciv-cvs-Apr-29_/common/map.h
--- freeciv-cvs-Apr-29/common/map.h     2004-04-30 07:11:50.000000000 +0200
+++ freeciv-cvs-Apr-29_/common/map.h    2004-05-05 01:53:05.000000000 +0200
@@ -288,7 +288,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-cvs-Apr-29/common/terrain.c 
freeciv-cvs-Apr-29_/common/terrain.c
--- freeciv-cvs-Apr-29/common/terrain.c 2004-02-23 07:01:51.000000000 +0100
+++ freeciv-cvs-Apr-29_/common/terrain.c        2004-05-05 01:53:05.000000000 
+0200
@@ -67,6 +67,8 @@
     "NoPollution",
     "Starter",
     "CanHaveRiver",
+    "UnsafeCoast",
+    "Unsafe",
     "Oceanic"
   };
 
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/common/terrain.h 
freeciv-cvs-Apr-29_/common/terrain.h
--- freeciv-cvs-Apr-29/common/terrain.h 2004-02-23 07:01:51.000000000 +0100
+++ freeciv-cvs-Apr-29_/common/terrain.h        2004-05-05 02:40:16.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-cvs-Apr-29/common/unit.c 
freeciv-cvs-Apr-29_/common/unit.c
--- freeciv-cvs-Apr-29/common/unit.c    2004-04-30 07:11:50.000000000 +0200
+++ freeciv-cvs-Apr-29_/common/unit.c   2004-05-05 03:02:41.000000000 +0200
@@ -1552,22 +1552,30 @@
 }
 
 /**************************************************************************
-  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( unit_flag(punit, F_TRIREME)) {
+    if (is_ocean(map_get_terrain(x, y)) && !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;
 }
 
 /**************************************************************************
@@ -1588,6 +1596,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 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-cvs-Apr-29/common/unit.h 
freeciv-cvs-Apr-29_/common/unit.h
--- freeciv-cvs-Apr-29/common/unit.h    2004-04-30 07:11:50.000000000 +0200
+++ freeciv-cvs-Apr-29_/common/unit.h   2004-05-05 02:50:55.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-cvs-Apr-29/data/civ1/terrain.ruleset 
freeciv-cvs-Apr-29_/data/civ1/terrain.ruleset
--- freeciv-cvs-Apr-29/data/civ1/terrain.ruleset        2004-02-23 
07:01:51.000000000 +0100
+++ freeciv-cvs-Apr-29_/data/civ1/terrain.ruleset       2004-05-05 
01:53:05.000000000 +0200
@@ -403,6 +403,7 @@
 mining_time          = 10
 transform_result     = "no"
 transform_time       = 0
+flags                = "UnsafeCoast"
 helptext            = _("\
 Mountains are regions of extreme altitude, making agriculture and\
  trade very difficult.\
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/data/civ2/terrain.ruleset 
freeciv-cvs-Apr-29_/data/civ2/terrain.ruleset
--- freeciv-cvs-Apr-29/data/civ2/terrain.ruleset        2004-02-23 
07:01:51.000000000 +0100
+++ freeciv-cvs-Apr-29_/data/civ2/terrain.ruleset       2004-05-05 
01:53:05.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-cvs-Apr-29/data/default/terrain.ruleset 
freeciv-cvs-Apr-29_/data/default/terrain.ruleset
--- freeciv-cvs-Apr-29/data/default/terrain.ruleset     2004-02-23 
07:01:51.000000000 +0100
+++ freeciv-cvs-Apr-29_/data/default/terrain.ruleset    2004-05-05 
01:53:05.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-cvs-Apr-29/server/gotohand.c 
freeciv-cvs-Apr-29_/server/gotohand.c
--- freeciv-cvs-Apr-29/server/gotohand.c        2004-01-21 07:16:42.000000000 
+0100
+++ freeciv-cvs-Apr-29_/server/gotohand.c       2004-05-05 02:46:43.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))) {
@@ -713,7 +717,7 @@
          continue;
        }
        else if (unit_flag(punit, F_TRIREME) &&
-                trireme_loss_pct(unit_owner(punit), x1, y1, punit) > 0) {
+                unit_loss_pct(unit_owner(punit), x1, y1, punit) > 0) {
          move_cost = 2*SINGLE_MOVE+1;
        } else {
          move_cost = SINGLE_MOVE;
@@ -1153,7 +1157,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-cvs-Apr-29/server/mapgen.c 
freeciv-cvs-Apr-29_/server/mapgen.c
--- freeciv-cvs-Apr-29/server/mapgen.c  2004-04-21 07:11:44.000000000 +0200
+++ freeciv-cvs-Apr-29_/server/mapgen.c 2004-05-05 03:29:27.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-cvs-Apr-29/server/unittools.c 
freeciv-cvs-Apr-29_/server/unittools.c
--- freeciv-cvs-Apr-29/server/unittools.c       2004-04-22 07:11:31.000000000 
+0200
+++ freeciv-cvs-Apr-29_/server/unittools.c      2004-05-05 03:07:50.000000000 
+0200
@@ -285,6 +285,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)
 {
@@ -295,6 +296,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 */
@@ -314,7 +316,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."),
@@ -332,6 +334,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 */
@@ -389,6 +402,7 @@
       wipe_unit(punit);
     } 
   } unit_list_iterate_safe_end;
+
 }
 
 /****************************************************************************

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