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

So unfortunately it did end up being due to the patch in 40417
(separatepoles fix), in particular:

   land_fill = pick_terrain(MG_LAST, MG_LAST, MG_LAST);

was being used to pick a "land" (i.e. non-ocean) terrain that
was then used to fill in all land tiles so that apparently
continent assignment would work. The call as is would sometimes
(pick_terrain uses myrand) return an ocean terrain so the map
ended up being 99% water (only a little land left at the
"poles"), which in turn would cause the assertion failure in 

Note that naively we could try just changing the call to

   pick_terrain(MG_LAST, MG_LAST, MG_OCEAN_DEPTH)

to avoid ocean types (based on the property_ocean_depth field
in the terrain.ruleset file), and for S2_1 this would be
sufficient, but for S2_2 the "lake" terrain has ocean depth
equal to zero, which is the same as the default value when
this field is unset (i.e. all land terrains have this value)
so we would have the same assertion failure still occur, just
less frequently (e.g. mapseed=5 gameseed=1 gen=1 in S2_2).

But we also cannot set property_ocean_depth=1 in the terrain
ruleset file because then gen=2 makes lakes at the edges of
oceans (I'll start a new ticket for this inconsistency in the
use of property_ocean_depth for the lake terrain).

So the attached patch removes the call to pick_terrain and
just uses a loop over the terrain types to select a non-ocean
land filler. It checks that it actually found one, and if not
aborts with a hopefully helpful fatal error message.

(P.S. Use "patch -l" to avoid whitespace gremlins.)

diff --git a/server/generator/mapgen.c b/server/generator/mapgen.c
index 0a14680..c8bf227 100644
--- a/server/generator/mapgen.c
+++ b/server/generator/mapgen.c
@@ -1041,12 +1041,31 @@ static void make_rivers(void)
 static void make_land(void)
+  struct terrain *land_fill = NULL;
   if (HAS_POLES) {
-  /* Pick terrain just once and fill all land tiles with that terrain */
-  struct terrain *land_fill = pick_terrain(MG_LAST, MG_LAST, MG_LAST);
+  /* Pick a non-ocean terrain just once and fill all land tiles with "
+   * that terrain. We must set some terrain (and not T_UNKNOWN) so that "
+   * continent number assignment works. */
+  terrain_type_iterate(pterrain) {
+    if (!is_ocean(pterrain)) {
+      land_fill = pterrain;
+      break;
+    }
+  } terrain_type_iterate_end;
+  if (land_fill == NULL) {
+    freelog(LOG_FATAL, "No land terrain type could be found for the "
+            "purpose of temporarily filling in land tiles during map "
+            "generation. This could be an error in freeciv, or a "
+            "mistake in the terrain.ruleset file. Please make sure "
+            "there is at least one land terrain type in the ruleset, "
+            "or use a different map generator. If this error persists, "
+            "please report it at: %s", BUG_URL);
+    assert(land_fill != NULL);
+  }
   hmap_shore_level = (hmap_max_level * (100 - map.landpercent)) / 100;
@@ -1073,8 +1092,7 @@ static void make_land(void)
       tile_set_terrain(ptile, pick_ocean(depth));
     } else {
-      /* Must set some terrain (and not T_UNKNOWN) so continent number
-         assignment works */
+      /* See note above for 'land_fill'. */
       tile_set_terrain(ptile, land_fill);
   } whole_map_iterate_end;
Freeciv-dev mailing list

Reply via email to