Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2004:
[Freeciv-Dev] (PR#9637) Ocean numbers
Home

[Freeciv-Dev] (PR#9637) Ocean numbers

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9637) Ocean numbers
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxxx>
Date: Mon, 9 Aug 2004 05:58:41 -0700
Reply-to: rt@xxxxxxxxxxx

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

A new version:

* Fixed a couple of bugs.  
* We now force renumbering and sending info to clients if somebody did a
ocean<-->land change.  
* I did not use Mateusz' suggestion because, ughm, I am not sure if
bitwise operation is ok here.
* Created a capability and changed the protocol (although it was wroking
fine before).
* Did some testing, in particular with generator 5 (it often creates
inland lakes).  Numbers are assigned sanely.

G.
? cont.txt
? isles.gz
? rrr
? ttt.diff
? ttt.gz
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.393
diff -u -r1.393 packhand.c
--- client/packhand.c   2 Aug 2004 16:59:14 -0000       1.393
+++ client/packhand.c   9 Aug 2004 12:51:16 -0000
@@ -2012,8 +2012,11 @@
   }
 
   /* update continents */
-  if (ptile->continent != packet->continent && ptile->continent != 0) {
-    /* we're renumbering continents, somebody did a transform. */
+  if (ptile->continent != packet->continent && ptile->continent != 0
+      && packet->continent > 0) {
+    /* We're renumbering continents, somebody did a transform.
+     * But we don't care about renumbering oceans since 
+     * num_oceans is not kept at the client. */
     map.num_continents = 0;
   }
 
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.175
diff -u -r1.175 capstr.c
--- common/capstr.c     30 Jul 2004 20:40:49 -0000      1.175
+++ common/capstr.c     9 Aug 2004 12:51:16 -0000
@@ -78,7 +78,7 @@
                    "+change_production +tilespec1 +no_earth +trans " \
                    "+want_hack invasions bombard +killstack2 spec +spec2 " \
                    "+city_map startunits +turn_last_built +happyborders " \
-                   "+connid +love"
+                   "+connid +love +ocean_num"
 
 /* "+1.14.delta" is the new delta protocol for 1.14.0-dev.
  *
@@ -136,6 +136,9 @@
  * info sent to clients.
  * 
  * "love" means that we show the AI love for you in the client
+ *
+ * "ocean_num" means that the oceans are numbered by negative numbers
+ * which are stored in ptile->continent and sent to client.
  */
 
 void init_our_capability(void)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.203
diff -u -r1.203 map.h
--- common/map.h        5 Aug 2004 10:41:34 -0000       1.203
+++ common/map.h        9 Aug 2004 12:51:16 -0000
@@ -44,7 +44,7 @@
                           Player_no is index */
   int assigned; /* these can save a lot of CPU usage -- Syela */
   struct city *worked;      /* city working tile, or NULL if none */
-  unsigned short continent;
+  signed short continent;
   signed char move_cost[8]; /* don't know if this helps! */
   struct player *owner;     /* Player owning this tile, or NULL. */
   struct {
@@ -169,6 +169,7 @@
   bool have_huts;
   bool have_rivers_overlay;    /* only applies if !have_specials */
   int num_continents;
+  int num_oceans;               /* not updated at the client */
   struct tile *tiles;
 
   /* Only used by server. */
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.36
diff -u -r1.36 packets.def
--- common/packets.def  30 Jul 2004 20:40:49 -0000      1.36
+++ common/packets.def  9 Aug 2004 12:51:16 -0000
@@ -188,7 +188,7 @@
 type GOVERNMENT                = UINT8
 type CONNECTION                = UINT8
 type TEAM              = UINT8
-type CONTINENT          = UINT16
+type CONTINENT          = SINT16
 type IMPROVEMENT       = uint8(Impr_Type_id)
 
 # other typedefs
Index: common/packets_gen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_gen.c,v
retrieving revision 1.40
diff -u -r1.40 packets_gen.c
--- common/packets_gen.c        30 Jul 2004 20:40:49 -0000      1.40
+++ common/packets_gen.c        9 Aug 2004 12:51:17 -0000
@@ -3076,7 +3076,7 @@
     dio_get_uint8(&din, (int *) &real_packet->owner);
   }
   if (BV_ISSET(fields, 4)) {
-    dio_get_uint16(&din, (int *) &real_packet->continent);
+    dio_get_sint16(&din, (int *) &real_packet->continent);
   }
   if (BV_ISSET(fields, 5)) {
     dio_get_string(&din, real_packet->spec_sprite, 
sizeof(real_packet->spec_sprite));
@@ -3160,7 +3160,7 @@
     dio_put_uint8(&dout, real_packet->owner);
   }
   if (BV_ISSET(fields, 4)) {
-    dio_put_uint16(&dout, real_packet->continent);
+    dio_put_sint16(&dout, real_packet->continent);
   }
   if (BV_ISSET(fields, 5)) {
     dio_put_string(&dout, real_packet->spec_sprite);
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.142
diff -u -r1.142 mapgen.c
--- server/mapgen.c     5 Aug 2004 10:41:34 -0000       1.142
+++ server/mapgen.c     9 Aug 2004 12:51:17 -0000
@@ -1203,48 +1203,59 @@
 }
 
 /**************************************************************************
- Number this tile and recursive adjacent tiles with specified
- continent number, by flood-fill algorithm.
+  Number this tile and recursive adjacent tiles with specified
+  continent number, by flood-fill algorithm.
+  is_land tells us whether we are assigning continent numbers or ocean 
+  numbers.
 **************************************************************************/
-static void assign_continent_flood(int x, int y, int nr)
+static void assign_continent_flood(int x, int y, bool is_land, int nr)
 {
   if (map_get_continent(x, y) != 0) {
     return;
   }
 
-  if (is_ocean(map_get_terrain(x, y))) {
+  if ((is_land && is_ocean(map_get_terrain(x, y)))
+      || (!is_land && !is_ocean(map_get_terrain(x, y)))) {
     return;
   }
 
   map_set_continent(x, y, nr);
 
   adjc_iterate(x, y, x1, y1) {
-    assign_continent_flood(x1, y1, nr);
+    assign_continent_flood(x1, y1, is_land, nr);
   } adjc_iterate_end;
 }
 
 /**************************************************************************
- Assign continent numbers to all tiles.
- Also sets map.num_continents (note 0 is ocean, and continents
- have numbers 1 to map.num_continents _inclusive_).
- Note this is not used by generators 2,3 or 4 at map creation
- time, as these assign their own continent numbers.
+  Assign continent and ocean numbers to all tiles, set map.num_continents 
+  and map.num_oceans.
+  Continents have numbers 1 to map.num_continents _inclusive_.
+  Oceans have (negative) numbers -1 to -map.num_oceans _inclusive_.
 **************************************************************************/
 void assign_continent_numbers(void)
 {
+  /* Initialize */
   map.num_continents = 0;
+  map.num_oceans = 0;
   whole_map_iterate(x, y) {
     map_set_continent(x, y, 0);
   } whole_map_iterate_end;
 
+  /* Assign new numbers */
   whole_map_iterate(x, y) {
-    if (map_get_continent(x, y) == 0 
-        && !is_ocean(map_get_terrain(x, y))) {
-      assign_continent_flood(x, y, ++map.num_continents);
+    if (map_get_continent(x, y) != 0) {
+      /* Already assigned */
+      continue;
     }
+    if (!is_ocean(map_get_terrain(x, y))) {
+      assign_continent_flood(x, y, TRUE, ++map.num_continents);
+    } else {
+      assign_continent_flood(x, y, FALSE, --map.num_oceans);
+    }      
   } whole_map_iterate_end;
 
-  freelog(LOG_VERBOSE, "Map has %d continents", map.num_continents);
+  freelog(LOG_VERBOSE, "Map has %d continents and %d oceans", 
+         map.num_continents, map.num_oceans);
 }
 
 /****************************************************************************
@@ -1315,7 +1326,7 @@
     map_city_radius_iterate(x, y, x1, y1) {
       /* (x1,y1) is possible location of a future city which will
        * be able to get benefit of the tile (x,y) */
-      if (map_get_continent(x1, y1) < 1 
+      if (is_ocean(map_get_terrain(x1, y1)) 
          || map_temperature(x1, y1) <= 2 * ICE_BASE_LEVEL) { 
        /* Not land, or too cold. */
         continue;
@@ -1417,6 +1428,10 @@
   int i;
   enum tile_terrain_type t = map_get_terrain(x, y);
 
+  if (is_ocean(map_get_terrain(x, y))) {
+    return FALSE;
+  }
+
   if (islands[(int)map_get_continent(x, y)].starters == 0) {
     return FALSE;
   }
@@ -1465,7 +1480,7 @@
   data.dist = MIN(40, MIN(map.xsize / 2, map.ysize / 2));
 
   sum = 0;
-  for (k = 0; k <= map.num_continents; k++) {
+  for (k = 1; k <= map.num_continents; k++) {
     sum += islands[k].starters;
     if (islands[k].starters != 0) {
       freelog(LOG_VERBOSE, "starters on isle %i", k);
@@ -2326,7 +2341,9 @@
   } whole_map_iterate_end;
   if (!map.alltemperate) {
     make_polar();
-    assign_continent_numbers(); /* set poles numbers */
+    /* Set poles numbers.  After the map is generated continents will 
+     * be renumbered. */
+    assign_continent_numbers(); 
   }
   make_island(0, 0, pstate, 0);
   islands[2].starters = 0;
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.136
diff -u -r1.136 maphand.c
--- server/maphand.c    28 Jul 2004 15:24:43 -0000      1.136
+++ server/maphand.c    9 Aug 2004 12:51:17 -0000
@@ -1332,106 +1332,11 @@
 }
 
 /**************************************************************************
-  Recursively renumber the client continent at (x,y) with continent
-  number 'new'.  Ie, renumber (x,y) tile and recursive adjacent
-  land tiles with the same previous continent ('old').
-**************************************************************************/
-static void renumber_continent(int x, int y, int newnum)
-{
-  unsigned short old;
-
-  if(!normalize_map_pos(&x, &y)) {
-    return;
-  }
-  
-  old = map_get_continent(x, y);
-  
-  map_set_continent(x, y, newnum);
-  adjc_iterate(x, y, i, j) {
-    if (!is_ocean(map_get_terrain(i, j))
-        && map_get_continent(i, j) == old) {
-      freelog(LOG_DEBUG,
-              " renumbering continent %d to %d at (%d %d)", old, newnum, i, j);
-      renumber_continent(i, j, newnum);
-    }
-  } adjc_iterate_end;
-}
-
-/**************************************************************************
-  We just transformed (x,y). If we changed it from ocean to land, check to
-  see if we merged a continent. (assign a continent number if we didn't)
-  If we changed it from land to ocean, check to see if we split a continent 
-  in pieces.
-
-  There are two special cases: we raised atlantis and have ourselves a shiny
-  new island. so we set it to map.num_continents + 1 (this btw is impossible
-  under the current transform rules, but it's an easy enough case that we 
-  check for it here anyway), or we sunk a little atoll. In that case, we'll 
-  return FALSE, even though we lost a continent. 
-  It shouldn't make a difference.
-
-  As a bonus, we set the transformed tile's new continent number here.
-**************************************************************************/
-static bool check_for_continent_change(int x, int y)
-{
-  unsigned short con = 0, unused = map.num_continents + 1;
-
-  if (is_ocean(map_get_terrain(x, y))) {
-    map_set_continent(x, y, 0);
-    /* check for land surrounding this tile. */
-    adjc_iterate(x, y, i, j) {
-      if (!is_ocean(map_get_terrain(i, j))) {
-        /* we found a land tile, check for another */
-        adjc_iterate(x, y, l, m) {
-          if (!(l == i && j == m) && !is_ocean(map_get_terrain(l, m))) {
-            /* we found a second adjacent land tile. renumber it */
-            con = map_get_continent(l, m);
-            renumber_continent(l, m, unused);
-
-            /* did the original tile get renumbered? if it did, then we
-             * didn't split the continent. if it's different, then 
-             * we are the proud owner of separate continents */
-            if (map_get_continent(i, j) == unused) {
-              renumber_continent(l, m, con);
-            } else {
-              return TRUE;
-            }
-          }
-        } adjc_iterate_end; 
-      }
-    } adjc_iterate_end;
-  } else {
-    /* check for land surrounding this tile. */
-    adjc_iterate(x, y, i, j) {
-      if (!is_ocean(map_get_terrain(i, j))) {
-        if (con == 0) {
-          con = map_get_continent(i, j);
-        } else if (map_get_continent(i, j) != con) {
-          return TRUE;
-        }
-      }
-    } adjc_iterate_end;
-
-    if (con == 0) {
-      /* we raised atlantis */
-      map_set_continent(x, y, ++map.num_continents);
-
-      allot_island_improvs();
-    } else {
-      /* set the tile to something adjacent to it */
-      map_set_continent(x, y, con);
-    }
-  }
-
-  return FALSE;
-}
-
-/**************************************************************************
   Checks for terrain change between ocean and land.  Handles side-effects.
   (Should be called after any potential ocean/land terrain changes.)
   Also, returns an enum ocean_land_change, describing the change, if any.
 
-  if we did a land change, we do everything in our power to avoid reassigning
+  if we did a land change, we try to avoid reassigning
   continent numbers.
 **************************************************************************/
 enum ocean_land_change check_terrain_ocean_land_change(int x, int y,
@@ -1444,13 +1349,9 @@
     ocean_to_land_fix_rivers(x, y);
     city_landlocked_sell_coastal_improvements(x, y);
 
-    if (check_for_continent_change(x, y)) {
-      assign_continent_numbers();
-
-      allot_island_improvs();
-
-      send_all_known_tiles(NULL);
-    }
+    assign_continent_numbers();
+    allot_island_improvs();
+    send_all_known_tiles(NULL);
     
     map_update_borders_landmass_change(x, y);
 
@@ -1459,13 +1360,9 @@
   } else if (!is_ocean(oldter) && is_ocean(newter)) {
     /* land to ocean ... */
 
-    if (check_for_continent_change(x, y)) {
-      assign_continent_numbers();
-
-      allot_island_improvs();
-
-      send_all_known_tiles(NULL);
-    }
+    assign_continent_numbers();
+    allot_island_improvs();
+    send_all_known_tiles(NULL);
 
     map_update_borders_landmass_change(x, y);
 
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.45
diff -u -r1.45 sanitycheck.c
--- server/sanitycheck.c        27 Jul 2004 16:43:48 -0000      1.45
+++ server/sanitycheck.c        9 Aug 2004 12:51:17 -0000
@@ -103,10 +103,15 @@
     struct tile *ptile = map_get_tile(x, y);
     struct city *pcity = map_get_city(x, y);
     int cont = map_get_continent(x, y);
+
+    assert(cont != 0);
     if (is_ocean(map_get_terrain(x, y))) {
-      assert(cont == 0);
+      adjc_iterate(x, y, x1, y1) {
+       if (is_ocean(map_get_terrain(x1, y1))) {
+         assert(map_get_continent(x1, y1) == cont);
+       }
+      } adjc_iterate_end;
     } else {
-      assert(cont != 0);
       adjc_iterate(x, y, x1, y1) {
        if (!is_ocean(map_get_terrain(x1, y1))) {
          assert(map_get_continent(x1, y1) == cont);
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.179
diff -u -r1.179 srv_main.c
--- server/srv_main.c   5 Aug 2004 11:34:18 -0000       1.179
+++ server/srv_main.c   9 Aug 2004 12:51:17 -0000
@@ -1688,9 +1688,7 @@
     map_fractal_generate();
   }
 
-  if (map.num_continents == 0) {
-    assign_continent_numbers();
-  }
+  assign_continent_numbers();
 
   gamelog_map();
   /* start the game */

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