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

As recently brought to our attention, the terrain generator is already
making civ3+ water (badly).  Sadly, the internal documentation of the
ocean_depth parameter was incorrect.  It is not a percentage, it merely
specifies a relative level from 1 to 100.

Revised the ocean_depth to empirical levels that make more plausible
oceans and coastlines.  Still has serious problems with most of the
deep parts next to polar caps, and oceanic ridges near coast.

Also, handled some FIXME comments:

    pick_terrain_by_flag currently called only by mapgen.c, move there
    and check error.

    pick_ocean should return NULL if there is no available ocean.

Committed trunk release 13120.

Index: server/generator/startpos.c
===================================================================
--- server/generator/startpos.c (revision 13119)
+++ server/generator/startpos.c (working copy)
@@ -198,6 +198,7 @@
   MT_ALL: all players in asingle isle
   MT_VARIABLE: at least 2 player per isle
   
+  Assumes assign_continent_numbers() has already been done!
   Returns true on success
 **************************************************************************/
 bool create_start_positions(enum start_mode mode,
@@ -223,8 +224,6 @@
     create_tmap(FALSE);
   }
 
-  assign_continent_numbers();
-
   /* If the default is given, just use MT_VARIABLE. */
   if (mode == MT_DEFAULT) {
     mode = MT_VARIABLE;
Index: server/generator/mapgen.c
===================================================================
--- server/generator/mapgen.c   (revision 13119)
+++ server/generator/mapgen.c   (working copy)
@@ -22,14 +22,13 @@
 #include <time.h>
 
 #include "fcintl.h"
-#include "game.h"
+#include "game.h" /* game.info.nplayers */
 #include "log.h"
 #include "map.h"
 #include "maphand.h" /* assign_continent_numbers(), MAP_NCONT */
 #include "mem.h"
 #include "rand.h"
 #include "shared.h"
-#include "srv_main.h"
 
 #include "height_map.h"
 #include "mapgen.h"
@@ -223,6 +222,36 @@
 }
 
 /****************************************************************************
+  Return a random terrain that has the specified flag.
+  Returns T_UNKNOWN when there is no matching terrain.
+****************************************************************************/
+static struct terrain *pick_terrain_by_flag(enum terrain_flag_id flag)
+{
+  bool has_flag[T_COUNT];
+  int count = 0;
+
+  terrain_type_iterate(pterrain) {
+    if ((has_flag[pterrain->index] = terrain_has_flag(pterrain, flag))) {
+      count++;
+    }
+  } terrain_type_iterate_end;
+
+  count = myrand(count);
+  terrain_type_iterate(pterrain) {
+    if (has_flag[pterrain->index]) {
+      if (count == 0) {
+       return pterrain;
+      }
+      count--;
+    }
+  } terrain_type_iterate_end;
+#if 0
+  die("Reached end of pick_terrain_by_flag!");
+#endif
+  return T_UNKNOWN;
+}
+
+/****************************************************************************
   Pick a terrain based on the target property and a property to avoid.
 
   If the target property is given, then all terrains with that property
@@ -297,21 +326,20 @@
 }
 
 /**************************************************************************
-  Picks an ocean terrain to match the given depth (as a percentage).
-
-  FIXME: this should return NULL if there is no available ocean.
+  Picks an ocean terrain to match the given depth.
+  Return NULL when there is no available ocean.
 **************************************************************************/
 static struct terrain *pick_ocean(int depth)
 {
-  /* FIXME: pick_terrain_by_flag may return NULL if there is no match. */
-  struct terrain *best_terrain = pick_terrain_by_flag(TER_OCEANIC);
-  int best_match = abs(depth - best_terrain->property[MG_OCEAN_DEPTH]);
+  struct terrain *best_terrain = NULL;
+  int best_match = TERRAIN_OCEAN_DEPTH_MAXIMUM;
 
   terrain_type_iterate(pterrain) {
-    if (terrain_has_flag(pterrain, TER_OCEANIC)) {
+    if (terrain_has_flag(pterrain, TER_OCEANIC)
+      &&  TERRAIN_OCEAN_DEPTH_MINIMUM <= pterrain->property[MG_OCEAN_DEPTH]) {
       int match = abs(depth - pterrain->property[MG_OCEAN_DEPTH]);
 
-      if (match < best_match) {
+      if (best_match > match) {
        best_match = match;
        best_terrain = pterrain;
       }
@@ -980,10 +1008,10 @@
 
            if (!terrain_has_flag(pterrain, TER_CAN_HAVE_RIVER)) {
              /* We have to change the terrain to put a river here. */
-             /* FIXME: pick_terrain_by_flag may return NULL
-              * if there is no match. */
              pterrain = pick_terrain_by_flag(TER_CAN_HAVE_RIVER);
-             tile_set_terrain(tile1, pterrain);
+             if (pterrain) {
+               tile_set_terrain(tile1, pterrain);
+             }
            }
            tile_set_special(tile1, S_RIVER);
            current_riverlength++;
@@ -992,8 +1020,7 @@
                    tile1->x, tile1->y);
          }
        } whole_map_iterate_end;
-      }
-      else {
+      } else {
        freelog(LOG_DEBUG,
                "mapgen.c: A river failed. It might have gotten stuck in a 
helix.");
       }
@@ -1075,9 +1102,12 @@
 **************************************************************************/
 static void remove_tiny_islands(void)
 {
+  struct terrain *ridge = terrain_by_identifier(TERRAIN_RIDGE_IDENTIFIER);
+
+  assert(NULL != ridge);
   whole_map_iterate(ptile) {
     if (is_tiny_island(ptile)) {
-      tile_set_terrain(ptile, pick_ocean(0));
+      tile_set_terrain(ptile, ridge);
       tile_clear_special(ptile, S_RIVER);
       tile_set_continent(ptile, 0);
     }
@@ -1187,6 +1217,7 @@
       remove_tiny_islands();
     }
   }
+  assign_continent_numbers();
 
   if (!temperature_is_initialized()) {
     create_tmap(FALSE);
@@ -1253,13 +1284,8 @@
          die("The server couldn't allocate starting positions.");
       }
     }
-
-
   }
 
-  assign_continent_numbers();
-  game_map_init();
-
   print_mapgen_map();
 }
 
@@ -1817,12 +1843,15 @@
 **************************************************************************/
 static void initworld(struct gen234_state *pstate)
 {
+  struct terrain *deepest_ocean = pick_ocean(TERRAIN_OCEAN_DEPTH_MAXIMUM);
+
+  assert(NULL != deepest_ocean);
   height_map = fc_malloc(MAP_INDEX_SIZE * sizeof(*height_map));
   create_placed_map(); /* land tiles which aren't placed yet */
   create_tmap(FALSE);
   
   whole_map_iterate(ptile) {
-    tile_set_terrain(ptile, pick_ocean(100));
+    tile_set_terrain(ptile, deepest_ocean);
     tile_set_continent(ptile, 0);
     map_set_placed(ptile); /* not a land tile */
     tile_clear_all_specials(ptile);
Index: server/srv_main.c
===================================================================
--- server/srv_main.c   (revision 13119)
+++ server/srv_main.c   (working copy)
@@ -1926,6 +1926,7 @@
     struct unit_type *utype = crole_to_unit_type(game.info.start_units[0], 
NULL);
 
     map_fractal_generate(TRUE, utype);
+    game_map_init();
   }
 
   /* start the game */
Index: server/maphand.c
===================================================================
--- server/maphand.c    (revision 13119)
+++ server/maphand.c    (working copy)
@@ -186,7 +186,7 @@
   struct terrain *coast = terrain_by_identifier(TERRAIN_COAST_IDENTIFIER);
   struct terrain *shelf = terrain_by_identifier(TERRAIN_SHELF_IDENTIFIER);
   struct terrain *floor = terrain_by_identifier(TERRAIN_FLOOR_IDENTIFIER);
-  int shelf_depth = shelf->property[MG_OCEAN_DEPTH];
+  int coast_depth = coast->property[MG_OCEAN_DEPTH];
   int coast_count = 0;
   int shelf_count = 0;
   int floor_count = 0;
@@ -212,7 +212,7 @@
       continue;
     }
     /* leave any existing deep features in place */
-    if (pterrain->property[MG_OCEAN_DEPTH] > shelf_depth) {
+    if (pterrain->property[MG_OCEAN_DEPTH] > coast_depth) {
       continue;
     }
 
Index: data/amplio/ocean.spec
===================================================================
--- data/amplio/ocean.spec      (revision 13119)
+++ data/amplio/ocean.spec      (working copy)
@@ -10,6 +10,7 @@
     Yautja
     CapTVK
     Eleazar
+    William Allen Simpson
 "
 
 [file]
@@ -25,7 +26,7 @@
 
 tiles = { "row", "column", "tag"
 
-;land, shallow(coast/shelf), deep(floor/trench/ridge/vent)
+;land, shallow(coast/shelf/ridge/vent), deep(floor/trench)
   8, 8, "t.l0.cellgroup_d_d_d_d"
   8, 7, "t.l0.cellgroup_s_d_d_d"
   8, 6, "t.l0.cellgroup_l_d_d_d"
Index: data/amplio.tilespec
===================================================================
--- data/amplio.tilespec        (revision 13119)
+++ data/amplio.tilespec        (working copy)
@@ -154,8 +154,8 @@
 [tile_ridge]
 is_blended = 0
 num_layers = 3
-layer0_match_type = "deep"
-layer0_match_with = "shallow", "land"
+layer0_match_type = "shallow"
+layer0_match_with = "deep", "land"
 layer0_sprite_type = "corner"
 layer1_match_type = "ridge"
 layer1_match_with = "ridge"
@@ -166,8 +166,8 @@
 [tile_vent]
 is_blended = 0
 num_layers = 3
-layer0_match_type = "deep"
-layer0_match_with = "shallow", "land"
+layer0_match_type = "shallow"
+layer0_match_with = "deep", "land"
 layer0_sprite_type = "corner"
 layer1_match_type = "ridge"
 layer1_match_with = "ridge"
Index: data/civ1/terrain.ruleset
===================================================================
--- data/civ1/terrain.ruleset   (revision 13119)
+++ data/civ1/terrain.ruleset   (working copy)
@@ -169,7 +169,7 @@
 ;  - frozen            = how "frozen" the terrain is (very low temperature)
 ;  - wet               = how "wet" the terrain is (moisture)
 ;  - dry               = how "dry" the terrain is (moisture)
-;  - ocean_depth       = the depth of an ocean, as a percentage
+;  - ocean_depth       = the depth of an ocean, as an average level
 ; helptext            = optional help text string; should escape all raw 
 ;                       newlines so that xgettext parsing works
 
@@ -201,7 +201,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"
-property_ocean_depth = 10
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -236,7 +236,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 3
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -271,7 +271,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 7
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -306,7 +306,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 13
+property_ocean_depth = 36
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -341,7 +341,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"
-property_ocean_depth = 23
+property_ocean_depth = 48
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -376,7 +376,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 66
+property_ocean_depth = 87
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -446,7 +446,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 33
+property_ocean_depth = 42
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -481,7 +481,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 33
+property_ocean_depth = 42 ; same as ridge, not generated
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
Index: data/civ2/terrain.ruleset
===================================================================
--- data/civ2/terrain.ruleset   (revision 13119)
+++ data/civ2/terrain.ruleset   (working copy)
@@ -177,7 +177,7 @@
 ;  - frozen            = how "frozen" the terrain is (very low temperature)
 ;  - wet               = how "wet" the terrain is (moisture)
 ;  - dry               = how "dry" the terrain is (moisture)
-;  - ocean_depth       = the depth of an ocean, as a percentage
+;  - ocean_depth       = the depth of an ocean, as an average level
 ; helptext            = optional help text string; should escape all raw 
 ;                       newlines so that xgettext parsing works
 
@@ -209,7 +209,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"
-property_ocean_depth = 10
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -244,7 +244,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 3
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -279,7 +279,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 7
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -314,7 +314,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 13
+property_ocean_depth = 36
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -349,7 +349,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"
-property_ocean_depth = 23
+property_ocean_depth = 48
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -384,7 +384,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 66
+property_ocean_depth = 87
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -454,7 +454,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 33
+property_ocean_depth = 42
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -489,7 +489,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 33
+property_ocean_depth = 42 ; same as ridge, not generated
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
Index: data/default/terrain.ruleset
===================================================================
--- data/default/terrain.ruleset        (revision 13119)
+++ data/default/terrain.ruleset        (working copy)
@@ -177,7 +177,7 @@
 ;  - frozen            = how "frozen" the terrain is (very low temperature)
 ;  - wet               = how "wet" the terrain is (moisture)
 ;  - dry               = how "dry" the terrain is (moisture)
-;  - ocean_depth       = the depth of an ocean, as a percentage
+;  - ocean_depth       = the depth of an ocean, as an average level
 ; helptext            = optional help text string; should escape all raw 
 ;                       newlines so that xgettext parsing works
 
@@ -214,7 +214,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"
-property_ocean_depth = 10
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -254,7 +254,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 3
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -294,7 +294,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 7
+property_ocean_depth = 0
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -334,7 +334,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution"
-property_ocean_depth = 13
+property_ocean_depth = 36
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -374,7 +374,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"
-property_ocean_depth = 23
+property_ocean_depth = 48
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -414,7 +414,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 66
+property_ocean_depth = 87
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -494,7 +494,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 33
+property_ocean_depth = 42
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
@@ -534,7 +534,7 @@
 cooler_drier_result  = "no"
 native_to            = "Sea", "Air", "Missile", "Helicopter"
 flags                = "Oceanic", "NoCities", "NoPollution", "UnsafeCoast"; 
"UnsafeOcean"
-property_ocean_depth = 33
+property_ocean_depth = 42 ; same as ridge, not generated
 helptext             = _("\
 Oceans cover much of the world, and only sea units (Triremes and\
  other boats) can travel on them.\
Index: common/terrain.c
===================================================================
--- common/terrain.c    (revision 13119)
+++ common/terrain.c    (working copy)
@@ -180,36 +180,6 @@
 }
 
 /****************************************************************************
-  Return a random terrain that has the specified flag.  Returns T_UNKNOWN if
-  there is no matching terrain.
-  FIXME: currently called only by mapgen.c, move there and check error.
-****************************************************************************/
-struct terrain *pick_terrain_by_flag(enum terrain_flag_id flag)
-{
-  bool has_flag[T_COUNT];
-  int count = 0;
-
-  terrain_type_iterate(pterrain) {
-    if ((has_flag[pterrain->index] = terrain_has_flag(pterrain, flag))) {
-      count++;
-    }
-  } terrain_type_iterate_end;
-
-  count = myrand(count);
-  terrain_type_iterate(pterrain) {
-    if (has_flag[pterrain->index]) {
-      if (count == 0) {
-       return pterrain;
-      }
-      count--;
-    }
-  } terrain_type_iterate_end;
-
-  die("Reached end of pick_terrain_by_flag!");
-  return T_UNKNOWN;
-}
-
-/****************************************************************************
   Free memory which is associated with terrain types.
 ****************************************************************************/
 void terrains_free(void)
Index: common/terrain.h
===================================================================
--- common/terrain.h    (revision 13119)
+++ common/terrain.h    (working copy)
@@ -129,6 +129,7 @@
 #define TERRAIN_COAST_IDENTIFIER '.'
 #define TERRAIN_SHELF_IDENTIFIER ','
 #define TERRAIN_FLOOR_IDENTIFIER ':'
+#define TERRAIN_RIDGE_IDENTIFIER '^'
 #define TERRAIN_GLACIER_IDENTIFIER 'a'
 #define TERRAIN_UNKNOWN_IDENTIFIER 'u'
 
@@ -162,14 +163,19 @@
   struct terrain *warmer_wetter_result, *warmer_drier_result;
   struct terrain *cooler_wetter_result, *cooler_drier_result;
 
-  /* These are special properties of the terrain used by mapgen.  Generally
-   * for each property, if a tile is deemed to have that property then
-   * the value gives the wieghted amount of tiles that will be assigned
-   * this terrain.
+  /* These are special properties of the terrain used by mapgen.  If a tile
+   * has a property, then the value gives the weighted amount of tiles that
+   * will be assigned this terrain.
    *
    * For instance if mountains have 70 and hills have 30 of MG_MOUNTAINOUS
-   * then 70% of 'mountainous' tiles will be given mountains. */
+   * then 70% of 'mountainous' tiles will be given mountains.
+   *
+   * Ocean_depth is different.  Instead of a percentage, the depth of the
+   * tile in the range 0 (never chosen) to 100 (deepest) is used.
+   */
   int property[MG_LAST];
+#define TERRAIN_OCEAN_DEPTH_MINIMUM (1)
+#define TERRAIN_OCEAN_DEPTH_MAXIMUM (100)
 
   bv_unit_classes native_to;
 
@@ -206,7 +212,6 @@
 
 enum terrain_flag_id find_terrain_flag_by_rule_name(const char *s);
 #define terrain_has_flag(terr, flag) BV_ISSET((terr)->flags, flag)
-struct terrain *pick_terrain_by_flag(enum terrain_flag_id flag);
 void terrains_free(void);
 
 /* General resource accessor functions. */

_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to