[Freeciv-Dev] (PR#9637) Ocean numbers
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9637 >
Here is the first version of the patch that introduces ocean numbers.
Very limited testing is done.
Here are my assumptions (correct me if I am wrong):
1. continent numbers are not saved nor loaded,
2. nowhere in the code continent==0 is used as a check for ocean
3. nowhere, after the map, is generated continent==1 or 2 is used as a
check for polar regions
Maybe some more but don't remember now.
G.
? cont.txt
? isles.gz
? rrr
? ttt.diff
? ttt.gz
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 8 Aug 2004 19:09:19 -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;
struct tile *tiles;
/* Only used by server. */
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 8 Aug 2004 19:09:20 -0000
@@ -1203,48 +1203,62 @@
}
/**************************************************************************
- 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 continent 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);
+ assign_continent_flood(x, y, TRUE, ++map.num_continents);
}
} whole_map_iterate_end;
- freelog(LOG_VERBOSE, "Map has %d continents", map.num_continents);
+ /* Assign ocean 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, FALSE, --map.num_oceans);
+ }
+ } whole_map_iterate_end;
+
+ freelog(LOG_VERBOSE, "Map has %d continents and %d oceans",
+ map.num_continents, map.num_oceans);
}
/****************************************************************************
@@ -2326,7 +2340,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 8 Aug 2004 19:09:20 -0000
@@ -1332,98 +1332,36 @@
}
/**************************************************************************
- 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;
+ Checks for continent change after ocean<-->land change at (x,y).
- 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.
+ The check is based on the reasoning that if continent renumbering does
+ change the continent and ocean numbers, this change _must_ manifest
+ itself around the tile which was changed (as well as in other places).
+ So we save all continent numbers, renumber the continents and check
+ the new numbers against the saved ones.
**************************************************************************/
-static bool check_for_continent_change(int x, int y)
+static void check_continent_change(int x, int y)
{
- unsigned short con = 0, unused = map.num_continents + 1;
+ int old_num[8];
+ bool change = FALSE;
- 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);
- }
+ /* Save the old numbers */
+ adjc_dir_iterate(x, y, x1, y1, dir) {
+ old_num[dir] = map_get_continent(x1, y1);
+ } adjc_dir_iterate_end;
+
+ /* Assign the new numbers */
+ assign_continent_numbers();
+
+ /* Check if the numbers changed */
+ adjc_dir_iterate(x, y, x1, y1, dir) {
+ change = (change || (old_num[dir] != map_get_continent(x1, y1)));
+ } adjc_dir_iterate_end;
+
+ if (change) {
+ allot_island_improvs();
+ send_all_known_tiles(NULL);
}
-
- return FALSE;
}
/**************************************************************************
@@ -1431,7 +1369,7 @@
(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 +1382,7 @@
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);
- }
+ check_continent_change(x, y);
map_update_borders_landmass_change(x, y);
@@ -1459,13 +1391,7 @@
} 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);
- }
+ check_continent_change(x, y);
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 8 Aug 2004 19:09:20 -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 8 Aug 2004 19:09:20 -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] |
- [Freeciv-Dev] (PR#9637) Ocean numbers,
Gregory Berkolaiko <=
|
|