Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2003:
[Freeciv-Dev] Re: borders patch (PR#1870)
Home

[Freeciv-Dev] Re: borders patch (PR#1870)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: ben@xxxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: borders patch (PR#1870)
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 21 Apr 2003 16:29:55 -0700
Reply-to: rt@xxxxxxxxxxxxxx

ue80@xxxxxxxxxxxxxxxxxxxxx wrote:
> I've looked at the borders patch and changed it a little bit that it
> applies on cvs again.
> 
> + tridentborders are working now (not 100% ok)
> - isotrident borders aren't working ..
> 
> - all old things which weren't in ...

Here's a new version.

- Some minor updates to current cvs.

- I changed map_tiles[0].owner to be a 'struct player *' instead of an 
integer.  This is more typesafe and leads to simpler code in most cases. 
  All users had to be changed, of course.

- I fixed the drawing code, as well as the map coordinate handling.

- Since the capability is manditory we don't need to check it all the 
time (the alternative is to make it non-manditory).

- The owner field is removed from the player_map since it was unused.

- Some style fixes, and spurious changes removed.

- Maybe something else I forgot about...

Overall, I think the design is good.  The maphand.c code probably has 
some room for improvement (in terms of quantity of code and execution 
efficiency).

There is one significant bug: if a tile changes hands, players who know 
but cannot see (i.e., fog) the tile will not find out about it from the 
server.  This leads to inconsistent borders; if the client disconnects 
and reconnects they will find the correct border.  The solution is 
either to (1) send the tile info, but only the relevant parts (since the 
tile is fogged) or (2) keep track of and make use of the player's 
knowledge in the player_map.  #1 seems to be much simpler.

Another buglet is that borders are drawn differently (not a dashed line) 
in non-iso view.  This could be solved by adding another GUI function 
(or a new parameter to gui_draw_line).

And of course, there is only gui-gtk support.  If/when put_one_tile_iso 
is moved into mapview_common only a small number of GUI changes will be 
needed.

jason

Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.99
diff -u -r1.99 control.c
--- client/control.c    2003/04/04 15:47:45     1.99
+++ client/control.c    2003/04/21 23:21:16
@@ -924,6 +924,19 @@
 }
 
 /**************************************************************************
+ Toggle display of national borders on the map
+**************************************************************************/
+void request_toggle_map_borders(void) 
+{
+  if (!can_client_change_view()) {
+    return;
+  }
+
+  draw_borders ^= 1;
+  update_map_canvas_visible();
+}
+
+/**************************************************************************
  Toggle display of city names
 **************************************************************************/
 void request_toggle_city_names(void)
@@ -1707,6 +1720,14 @@
 void key_map_grid_toggle(void)
 {
   request_toggle_map_grid();
+}
+
+/**************************************************************************
+  Toggle map borders on the mapview on/off based on a keypress.
+**************************************************************************/
+void key_map_borders_toggle(void)
+{
+  request_toggle_map_borders();
 }
 
 /**************************************************************************
Index: client/control.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.h,v
retrieving revision 1.33
diff -u -r1.33 control.h
--- client/control.h    2003/03/21 20:05:49     1.33
+++ client/control.h    2003/04/21 23:21:16
@@ -63,6 +63,7 @@
 void request_unit_wait(struct unit *punit);
 void request_unit_wakeup(struct unit *punit);
 void request_toggle_map_grid(void);
+void request_toggle_map_borders(void);
 void request_toggle_city_names(void);
 void request_toggle_city_growth(void);
 void request_toggle_city_productions(void);
@@ -115,6 +116,7 @@
 void key_fog_of_war_toggle(void);
 void key_end_turn(void);
 void key_map_grid_toggle(void);
+void key_map_borders_toggle(void);
 void key_unit_move(enum direction8 gui_dir);
 void key_unit_airbase(void);
 void key_unit_auto_attack(void);
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.44
diff -u -r1.44 mapview_common.c
--- client/mapview_common.c     2003/04/21 22:57:25     1.44
+++ client/mapview_common.c     2003/04/21 23:21:16
@@ -433,6 +433,42 @@
                   canvas_x, canvas_y, NORMAL_TILE_WIDTH, 0);
     }
 
+    /* Draw national borders. */
+    if (draw_borders) {
+      struct player *this_owner = map_get_owner(map_x, map_y), *adjc_owner;
+      int x1, y1;
+
+      /* left side */
+      if (MAPSTEP(x1, y1, map_x, map_y, DIR8_WEST)
+         && this_owner != (adjc_owner = map_get_owner(x1, y1))
+         && tile_get_known(x1, y1)) {
+        if (adjc_owner) {
+          gui_put_line(pcanvas_store, player_color(adjc_owner),
+                      canvas_x - 1, canvas_y + 1,
+                      0, NORMAL_TILE_HEIGHT - 1);
+       }
+       if (this_owner) {
+         gui_put_line(pcanvas_store, player_color(this_owner),
+                      canvas_x + 1, canvas_y + 1,
+                      0, NORMAL_TILE_HEIGHT - 1);
+        }
+      }
+
+      /* top side */
+      if (MAPSTEP(x1, y1, map_x, map_y, DIR8_NORTH)
+         && this_owner != (adjc_owner = map_get_owner(x1, y1))
+         && tile_get_known(x1, y1)) {
+        if (adjc_owner) {
+          gui_put_line(pcanvas_store, player_color(adjc_owner),
+                      canvas_x + 1, canvas_y - 1, NORMAL_TILE_WIDTH - 1, 0);
+       }
+       if (this_owner) {
+         gui_put_line(pcanvas_store, player_color(this_owner),
+                      canvas_x + 1, canvas_y + 1, NORMAL_TILE_WIDTH - 1, 0);
+        }
+      }
+    }     
+
     if (draw_coastline && !draw_terrain) {
       enum tile_terrain_type t1 = map_get_terrain(map_x, map_y), t2;
       int x1, y1;
Index: client/options.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.c,v
retrieving revision 1.80
diff -u -r1.80 options.c
--- client/options.c    2003/04/12 18:24:41     1.80
+++ client/options.c    2003/04/21 23:21:17
@@ -148,6 +148,7 @@
 bool draw_units = TRUE;
 bool draw_focus_unit = FALSE;
 bool draw_fog_of_war = TRUE;
+bool draw_borders = TRUE;
 
 #define VIEW_OPTION(name) { #name, &name }
 #define VIEW_OPTION_TERMINATOR { NULL, NULL }
@@ -169,6 +170,7 @@
   VIEW_OPTION(draw_units),
   VIEW_OPTION(draw_focus_unit),
   VIEW_OPTION(draw_fog_of_war),
+  VIEW_OPTION(draw_borders),
   VIEW_OPTION_TERMINATOR
 };
 
Index: client/options.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.h,v
retrieving revision 1.29
diff -u -r1.29 options.h
--- client/options.h    2003/04/12 18:24:41     1.29
+++ client/options.h    2003/04/21 23:21:17
@@ -91,6 +91,7 @@
 extern bool draw_units;
 extern bool draw_focus_unit;
 extern bool draw_fog_of_war;
+extern bool draw_borders;
 
 typedef struct {
   const char *name;
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.301
diff -u -r1.301 packhand.c
--- client/packhand.c   2003/04/17 20:06:35     1.301
+++ client/packhand.c   2003/04/21 23:21:18
@@ -497,7 +497,7 @@
     }
   }
 
-  if (draw_map_grid && can_client_change_view()) {
+  if ((draw_map_grid || draw_borders) && can_client_change_view()) {
     /* We have to make sure we update any workers on the map grid, then
      * redraw the city descriptions on top of them. */
     update_map_canvas(pcity->x - CITY_MAP_SIZE / 2,
@@ -1680,6 +1680,19 @@
   if (ptile->special != packet->special) { /*add-on*/
     tile_changed = TRUE;
     ptile->special = packet->special;
+  }
+  if (packet->owner == MAP_TILE_OWNER_NULL) {
+    if (ptile->owner) {
+      ptile->owner = NULL;
+      tile_changed = TRUE;
+    }
+  } else {
+    struct player *newowner = get_player(packet->owner);
+
+    if (ptile->owner != newowner) {
+      ptile->owner = newowner;
+      tile_changed = TRUE;
+    }
   }
   ptile->known = packet->known;
 
Index: client/gui-gtk/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/gui_main.c,v
retrieving revision 1.134
diff -u -r1.134 gui_main.c
--- client/gui-gtk/gui_main.c   2003/04/21 16:06:12     1.134
+++ client/gui-gtk/gui_main.c   2003/04/21 23:21:19
@@ -97,6 +97,7 @@
 GdkGC *fill_tile_gc;
 GdkGC *thin_line_gc;
 GdkGC *thick_line_gc;
+GdkGC *border_line_gc;
 GdkPixmap *gray50, *gray25, *black50;
 GdkPixmap *mask_bitmap;
 
@@ -876,12 +877,17 @@
    * the tileset can change at runtime. */
   thin_line_gc = gdk_gc_new(root_window);
   thick_line_gc = gdk_gc_new(root_window);
+  border_line_gc = gdk_gc_new(root_window);
   gdk_gc_set_line_attributes(thin_line_gc, 1,
                             GDK_LINE_SOLID,
                             GDK_CAP_NOT_LAST,
                             GDK_JOIN_MITER);
   gdk_gc_set_line_attributes(thick_line_gc, 2,
                             GDK_LINE_SOLID,
+                            GDK_CAP_NOT_LAST,
+                            GDK_JOIN_MITER);
+  gdk_gc_set_line_attributes(border_line_gc, 2,
+                            GDK_LINE_ON_OFF_DASH,
                             GDK_CAP_NOT_LAST,
                             GDK_JOIN_MITER);
 
Index: client/gui-gtk/gui_main.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/gui_main.h,v
retrieving revision 1.10
diff -u -r1.10 gui_main.h
--- client/gui-gtk/gui_main.h   2003/02/26 19:00:36     1.10
+++ client/gui-gtk/gui_main.h   2003/04/21 23:21:19
@@ -26,6 +26,7 @@
 extern GdkGC *          fill_tile_gc;
 extern GdkGC *          thin_line_gc;
 extern GdkGC *          thick_line_gc;
+extern GdkGC *          border_line_gc;
 extern GdkPixmap *      gray50;
 extern GdkPixmap *      gray25;
 extern GdkPixmap *      black50;
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.167
diff -u -r1.167 mapview.c
--- client/gui-gtk/mapview.c    2003/04/16 08:26:55     1.167
+++ client/gui-gtk/mapview.c    2003/04/21 23:21:20
@@ -1695,6 +1695,60 @@
     }
   }
 
+  /* Draw national borders. */
+  if (draw_borders) {
+    struct player *owner = map_get_owner(x, y), *owner1;
+    int x1, y1;
+
+    if ((draw & D_M_R) && MAPSTEP(x1, y1, x, y, DIR8_NORTH)
+       && owner != (owner1 = map_get_owner(x1, y1))
+       && tile_get_known(x1, y1)) {
+      if (owner1) {
+       gdk_gc_set_foreground(border_line_gc,
+                             colors_standard[player_color(owner1)]);
+        gdk_draw_line(pm, border_line_gc,
+                     canvas_x + NORMAL_TILE_WIDTH / 2,
+                     canvas_y - 1,
+                     canvas_x + NORMAL_TILE_WIDTH,
+                     canvas_y + NORMAL_TILE_HEIGHT / 2 - 1);
+      }
+
+      if (owner) {
+        gdk_gc_set_foreground(border_line_gc,
+                             colors_standard[player_color(owner)]);
+        gdk_draw_line(pm, border_line_gc,
+                     canvas_x + NORMAL_TILE_WIDTH / 2,
+                     canvas_y + 1,
+                     canvas_x + NORMAL_TILE_WIDTH,
+                     canvas_y + NORMAL_TILE_HEIGHT / 2 + 1);
+      }
+    }
+
+    if ((draw & D_M_L) && MAPSTEP(x1, y1, x, y, DIR8_WEST)
+       && owner != (owner1 = map_get_owner(x1, y1))
+       && tile_get_known(x1, y1)) {
+      if (owner1) {
+       gdk_gc_set_foreground(border_line_gc,
+                             colors_standard[player_color(owner1)]);
+       gdk_draw_line(pm, border_line_gc,
+                     canvas_x,
+                     canvas_y + NORMAL_TILE_HEIGHT / 2 - 1,
+                     canvas_x + NORMAL_TILE_WIDTH / 2,
+                     canvas_y - 1);
+      }
+
+      if (owner) {
+       gdk_gc_set_foreground(border_line_gc,
+                             colors_standard[player_color(owner)]);
+       gdk_draw_line(pm, border_line_gc,
+                     canvas_x,
+                     canvas_y + NORMAL_TILE_HEIGHT / 2 + 1,
+                     canvas_x + NORMAL_TILE_WIDTH / 2,
+                     canvas_y + 1);
+      }
+    }
+  }
+
   if (draw_coastline && !draw_terrain) {
     enum tile_terrain_type t1 = map_get_terrain(x, y), t2;
     int x1, y1;
Index: client/gui-gtk/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/menu.c,v
retrieving revision 1.75
diff -u -r1.75 menu.c
--- client/gui-gtk/menu.c       2003/04/04 15:47:46     1.75
+++ client/gui-gtk/menu.c       2003/04/21 23:21:20
@@ -82,6 +82,7 @@
   MENU_KINGDOM_REVOLUTION,
 
   MENU_VIEW_SHOW_MAP_GRID,
+  MENU_VIEW_SHOW_NATIONAL_BORDERS,
   MENU_VIEW_SHOW_CITY_NAMES,
   MENU_VIEW_SHOW_CITY_GROWTH_TURNS,
   MENU_VIEW_SHOW_CITY_PRODUCTIONS,
@@ -230,6 +231,10 @@
     if (draw_map_grid ^ GTK_CHECK_MENU_ITEM(widget)->active)
       key_map_grid_toggle();
     break;
+  case MENU_VIEW_SHOW_NATIONAL_BORDERS:
+    if (draw_borders ^ GTK_CHECK_MENU_ITEM(widget)->active)
+      key_map_borders_toggle();
+    break;
   case MENU_VIEW_SHOW_CITY_NAMES:
     if (draw_city_names ^ GTK_CHECK_MENU_ITEM(widget)->active) {
       key_city_names_toggle();
@@ -612,6 +617,8 @@
        NULL,                   0,                                      
"<Tearoff>"     },
   { "/" N_("View") "/" N_("Map _Grid"),                        "<control>g",
        view_menu_callback,     MENU_VIEW_SHOW_MAP_GRID,                
"<CheckItem>"   },
+  { "/" N_("View") "/" N_("National _Borders"),                "<control>b",
+       view_menu_callback,     MENU_VIEW_SHOW_NATIONAL_BORDERS,        
"<CheckItem>"   },
   { "/" N_("View") "/" N_("City _Names"),              "<control>n",
        view_menu_callback,     MENU_VIEW_SHOW_CITY_NAMES,              
"<CheckItem>"   },
   { "/" N_("View") "/" N_("City G_rowth"),             "<control>r",
@@ -1048,6 +1055,7 @@
                        (game.player_ptr->spaceship.state!=SSHIP_NONE));
 
     menus_set_active("<main>/_View/Map _Grid", draw_map_grid);
+    menus_set_active("<main>/_View/National _Borders", draw_borders);
     menus_set_active("<main>/_View/City _Names", draw_city_names);
     menus_set_sensitive("<main>/_View/City G_rowth", draw_city_names);
     menus_set_active("<main>/_View/City G_rowth", draw_city_growth);
Index: client/gui-gtk/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/plrdlg.c,v
retrieving revision 1.46
diff -u -r1.46 plrdlg.c
--- client/gui-gtk/plrdlg.c     2003/04/17 20:06:35     1.46
+++ client/gui-gtk/plrdlg.c     2003/04/21 23:21:21
@@ -34,6 +34,7 @@
 #include "civclient.h"
 #include "climisc.h"
 #include "clinet.h"
+#include "tilespec.h"
 
 #include "chatline.h"
 #include "colors.h"
@@ -73,7 +74,7 @@
 static void players_list_ucallback(GtkWidget *w, gint row, gint column);
 static void players_sship_callback(GtkWidget *w, gpointer data);
 
-#define NUM_COLUMNS 13         /* number of columns in total */
+#define NUM_COLUMNS 14         /* number of columns in total */
 #define DEF_SORT_COLUMN 2 /* default sort column (1 = nation) */
 
 /****************************************************************
@@ -134,7 +135,8 @@
 void create_players_dialog(void)
 {
   static const char *titles_[NUM_COLUMNS] =
-      { N_("Name"), N_("Flag"), N_("Nation"), N_("Team"), N_("Ai"),
+      { N_("Name"), N_("Flag"), N_("Nation"),
+       N_("Color"), N_("Team"), N_("Ai"),
        N_("Embassy"), N_("Dipl.State"), N_("Vision"), N_("Reputation"),
        N_("State"), N_("Host"), N_("Idle"), N_("Ping")
   };
@@ -262,9 +264,11 @@
 {
   static char namebuf[MAX_LEN_NAME], flagbuf[1], aibuf[2], dsbuf[32],
       repbuf[32], statebuf[32], idlebuf[32];
+  static const char *colbuf = "";
   const struct player_diplstate *pds;
 
-  /* we assume that neither name, team nor the nation of a player changes */
+  /* we assume that the player's name, flag,
+   * nation and color never change. */
   if (update == 0) {
     /* the playername */
     my_snprintf(namebuf, sizeof(namebuf), "%-16s", game.players[i].name);
@@ -283,6 +287,9 @@
     } else {
       row[3] = (char *) "";
     }
+
+    /* the nation color, empty since it's a block of color (no text). */
+    row[4] = colbuf;
   }
 
   /* text for name, plus AI marker */
@@ -332,15 +339,15 @@
              reputation_text(game.players[i].reputation));
 
   /* assemble the whole lot */
-  row[4] = aibuf;
-  row[5] = get_embassy_status(game.player_ptr, &game.players[i]);
-  row[6] = dsbuf;
-  row[7] = get_vision_status(game.player_ptr, &game.players[i]);
-  row[8] = repbuf;
-  row[9] = statebuf;
-  row[10] = (char *) player_addr_hack(&game.players[i]);       /* Fixme */
-  row[11] = idlebuf;
-  row[12] = get_ping_time_text(&game.players[i]);
+  row[5] = aibuf;
+  row[6] = get_embassy_status(game.player_ptr, &game.players[i]);
+  row[7] = dsbuf;
+  row[8] = get_vision_status(game.player_ptr, &game.players[i]);
+  row[9] = repbuf;
+  row[10] = statebuf;
+  row[11] = (char *) player_addr_hack(&game.players[i]);       /* Fixme */
+  row[12] = idlebuf;
+  row[13] = get_ping_time_text(&game.players[i]);
 }
 
 #define MIN_DIMENSION 5
@@ -400,12 +407,15 @@
 {
   if (players_dialog_shell && !is_plrdlg_frozen()) {
     GdkColor *state_col;
+    GtkStyle *style;
     const char *row_texts[NUM_COLUMNS];
     int i, j, row, sort_needed = 0;
 
     gtk_clist_freeze(GTK_CLIST(players_list));
+
+    players_iterate(pplayer) {
+      int i = pplayer->player_no;
 
-    for (i = 0; i < game.nplayers; i++) {
       /* skip barbarians */
       if (is_barbarian(&game.players[i])) {
        continue;
@@ -437,7 +447,7 @@
         * The nation already had a row in the player report. In that
         * case we just update the row. 
         */
-       for (j = 4; j < NUM_COLUMNS; j++) {
+       for (j = 5; j < NUM_COLUMNS; j++) {
          gtk_clist_set_text(GTK_CLIST(players_list), row, j,
                             row_texts[j]);
        }
@@ -455,6 +465,13 @@
        state_col = colors_standard[COLOR_STD_BLACK];
       }
       gtk_clist_set_foreground(GTK_CLIST(players_list), row, state_col);
+      /* Make the background of column 3 match the nation's border colour. */
+      style = gtk_style_new();
+      style->fg[GTK_STATE_NORMAL]
+             = *(colors_standard[player_color(pplayer)]);
+      style->base[GTK_STATE_NORMAL]
+             = *(colors_standard[player_color(pplayer)]);
+      gtk_clist_set_cell_style(GTK_CLIST(players_list), row, 3, style);
     }
 
     if (sort_needed) {
@@ -468,7 +485,7 @@
 
     gtk_clist_thaw(GTK_CLIST(players_list));
     gtk_widget_show_all(players_list);
-  }
+  } players_iterate_end;
 }
 
 /**************************************************************************
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.131
diff -u -r1.131 capstr.c
--- common/capstr.c     2003/04/17 20:06:36     1.131
+++ common/capstr.c     2003/04/21 23:21:21
@@ -77,7 +77,7 @@
 #define CAPABILITY "+1.14.0 conn_info +occupied team tech_impr_gfx " \
                    "city_struct_minor_cleanup obsolete_last class_legend " \
                    "+impr_req +waste +fastfocus +continent +small_dipl " \
-                   "+no_nation_selected +diplomacy"
+                   "+no_nation_selected +diplomacy +borders"
 /* "+1.14.0" is protocol for 1.14.0 release.
  *
  * "conn_info" is sending the conn_id field. To preserve compatability
@@ -117,6 +117,8 @@
  * players who have no assigned nation (rather than MAX_NUM_NATIONS).
  *
  * "diplomacy": changed requirements for diplomatic meetings
+ *
+ * "borders" is support for national borders
  */
 
 void init_our_capability(void)
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.125
diff -u -r1.125 city.h
--- common/city.h       2003/02/04 17:07:43     1.125
+++ common/city.h       2003/04/21 23:21:21
@@ -317,6 +317,17 @@
     TYPED_LIST_ITERATE(struct city, citylist, pcity)
 #define city_list_iterate_end  LIST_ITERATE_END
 
+#define cities_iterate(pcity)                                               \
+{                                                                           \
+  players_iterate(CI_player) {                                              \
+    city_list_iterate(CI_player->cities, pcity) {
+
+#define cities_iterate_end                                                  \
+    } city_list_iterate_end;                                                \
+  } players_iterate_end;                                                    \
+}
+
+
 /* properties */
 
 struct player *city_owner(struct city *pcity);
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.161
diff -u -r1.161 game.c
--- common/game.c       2003/04/17 20:06:36     1.161
+++ common/game.c       2003/04/21 23:21:22
@@ -433,7 +433,7 @@
 /**************************************************************************
 ...
 **************************************************************************/
-int civ_score(struct player *pplayer)
+int civ_score_old(struct player *pplayer)
 {
   int i;
   struct city *pcity;
@@ -493,6 +493,7 @@
     free_landarea_map(&cmap);
     build_landarea_map(&cmap);
   }
+
   get_player_landarea(&cmap, pplayer, &landarea, &settledarea);
   pplayer->score.landarea=landarea;
   pplayer->score.settledarea=settledarea;
@@ -690,6 +691,7 @@
   game.spacerace   = GAME_DEFAULT_SPACERACE;
   game.fogofwar    = GAME_DEFAULT_FOGOFWAR;
   game.fogofwar_old= game.fogofwar;
+  game.borders     = GAME_DEFAULT_BORDERS;
   game.auto_ai_toggle = GAME_DEFAULT_AUTO_AI_TOGGLE;
   game.notradesize    = GAME_DEFAULT_NOTRADESIZE;
   game.fulltradesize  = GAME_DEFAULT_FULLTRADESIZE;
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.121
diff -u -r1.121 game.h
--- common/game.h       2003/04/17 20:06:36     1.121
+++ common/game.h       2003/04/21 23:21:22
@@ -160,6 +160,8 @@
   int watchtower_vision;
   int allowed_city_names;
 
+  int borders;         /* 0=no borders, otherwise distance of border from 
city. */
+
   char rulesetdir[MAX_LEN_NAME];
   int firepower_factor;                /* See README.rulesets */
   struct {
@@ -246,7 +248,8 @@
 void game_remove_unit(struct unit *punit);
 void game_remove_city(struct city *pcity);
 int total_player_citizens(struct player *pplayer);
-int civ_score(struct player *pplayer);
+int total_player_territory(struct player *pplayer);
+int civ_score_old(struct player *pplayer);
 void initialize_globals(void);
 
 void translate_data_names(void);
@@ -312,6 +315,10 @@
 #define GAME_MAX_DIPLCOST            100
 
 #define GAME_DEFAULT_FOGOFWAR        TRUE
+
+#define GAME_DEFAULT_BORDERS         7
+#define GAME_MIN_BORDERS             0 /* 0 means no national borders. */
+#define GAME_MAX_BORDERS             24 /* Performance sucks if this is too 
large, so limit at 24. */
 
 #define GAME_DEFAULT_DIPLCHANCE      80
 #define GAME_MIN_DIPLCHANCE          1
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.137
diff -u -r1.137 map.c
--- common/map.c        2003/04/03 04:13:49     1.137
+++ common/map.c        2003/04/21 23:21:23
@@ -214,6 +214,23 @@
   unit_list_init(&ptile->units);
   ptile->worked   = NULL; /* pointer to city working tile */
   ptile->assigned = 0; /* bitvector */
+  ptile->owner    = NULL; /* Tile not claimed by any nation. */
+}
+
+/**************************************************************************
+  Return the player who owns this tile (or NULL if none).
+**************************************************************************/
+struct player *map_get_owner(int x, int y)
+{
+  return MAP_TILE(x, y)->owner;
+}
+
+/**************************************************************************
+  Set the owner of a tile (may be NULL).
+**************************************************************************/
+void map_set_owner(int x, int y, struct player *owner)
+{
+  MAP_TILE(x, y)->owner = owner;
 }
 
 /***************************************************************
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.144
diff -u -r1.144 map.h
--- common/map.h        2003/04/21 22:57:25     1.144
+++ common/map.h        2003/04/21 23:21:23
@@ -62,6 +62,7 @@
   struct city *worked;      /* city working tile, or NULL if none */
   unsigned short continent;
   signed char move_cost[8]; /* don't know if this helps! */
+  struct player *owner;     /* Player owning this tile, or NULL. */
 };
 
 
@@ -254,6 +255,8 @@
      (dest_y) = (src_y) + DIR_DY[(dir)],               \
      normalize_map_pos(&(dest_x), &(dest_y)))
 
+struct player *map_get_owner(int x, int y);
+void map_set_owner(int x, int y, struct player *pplayer);
 struct city *map_get_city(int x, int y);
 void map_set_city(int x, int y, struct city *pcity);
 enum tile_terrain_type map_get_terrain(int x, int y);
@@ -601,6 +604,8 @@
 #define cartesian_adjacent_iterate_end                                        \
   }                                                                           \
 }
+
+#define MAP_TILE_OWNER_NULL     MAX_UINT8
 
 #define MAP_DEFAULT_HUTS         50
 #define MAP_MIN_HUTS             0
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.245
diff -u -r1.245 packets.c
--- common/packets.c    2003/04/17 20:06:36     1.245
+++ common/packets.c    2003/04/21 23:21:24
@@ -1156,6 +1156,7 @@
   dio_get_uint8(&din, &packet->type);
   dio_get_uint16(&din, &packet->special);
   dio_get_uint8(&din, &packet->known);
+  dio_get_uint16(&din, &packet->owner);
   if (has_capability("continent", pc->capability)) {
     dio_get_uint16(&din, (int *)&packet->continent);
   }
@@ -1186,6 +1187,7 @@
   dio_put_uint8(&dout, pinfo->type);
   dio_put_uint16(&dout, pinfo->special);
   dio_put_uint8(&dout, pinfo->known);
+  dio_put_uint16(&dout, pinfo->owner);
   if (has_capability("continent", pc->capability)) {
     dio_put_uint16(&dout, pinfo->continent);
   }
@@ -1866,6 +1868,8 @@
   dio_put_uint8(&dout, packet->playable_nation_count);
   dio_put_uint8(&dout, packet->style_count);
 
+  dio_put_uint8(&dout, packet->borders);
+  
   dio_put_tech_list(&dout, packet->rtech.partisan_req);
 
   if (has_capability("team", pc->capability)) {
@@ -1912,6 +1916,8 @@
   dio_get_uint8(&din, &packet->playable_nation_count);
   dio_get_uint8(&din, &packet->style_count);
 
+  dio_get_uint8(&din, &packet->borders);
+  
   dio_get_tech_list(&din, packet->rtech.partisan_req);
 
   for (i = 0; i < MAX_NUM_TEAMS; i++) {
Index: common/packets.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v
retrieving revision 1.144
diff -u -r1.144 packets.h
--- common/packets.h    2003/04/12 18:24:42     1.144
+++ common/packets.h    2003/04/21 23:21:25
@@ -264,7 +264,7 @@
   tile info
 *********************************************************/
 struct packet_tile_info {
-  int x, y, type, special, known;
+  int x, y, type, special, known, owner;
   unsigned short continent;
 };
 
@@ -562,6 +562,7 @@
   info for its own "control" packet, done separately.)
 *********************************************************/
 struct packet_ruleset_control {
+  int borders;
   int aqueduct_size;
   int sewer_size;
   int add_to_size_limit;
Index: common/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.h,v
retrieving revision 1.111
diff -u -r1.111 shared.h
--- common/shared.h     2003/03/07 05:08:42     1.111
+++ common/shared.h     2003/04/21 23:21:25
@@ -110,6 +110,7 @@
 
 /* This is duplicated in rand.h to avoid extra includes: */
 #define MAX_UINT32 0xFFFFFFFF
+#define MAX_UINT8  0xFF
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 #define ADD_TO_POINTER(p, n) ((void *)((char *)(p)+(n)))
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.215
diff -u -r1.215 citytools.c
--- server/citytools.c  2003/04/17 20:06:36     1.215
+++ server/citytools.c  2003/04/21 23:21:27
@@ -850,6 +850,9 @@
   pcity->owner = ptaker->player_no;
   city_list_insert(&ptaker->cities, pcity);
 
+  /* Update national borders. */
+  map_update_borders_city_change(pcity);
+
   /* transfer_city_units() destroys the city's units_supported
      list; we save the list so we can resolve units afterwards. */
   if (resolve_stack) {
@@ -1073,6 +1076,9 @@
   city_list_insert(&pplayer->cities, pcity);
   add_city_to_minimap(x, y);
 
+  /* Update the national borders. */
+  map_update_borders_city_change(pcity);
+
   /* it is possible to build a city on a tile that is already worked
    * this will displace the worker on the newly-built city's tile -- Syela */
   for (y_itr = 0; y_itr < CITY_MAP_SIZE; y_itr++) {
@@ -1231,6 +1237,7 @@
 /* DO NOT remove city from minimap here. -- Syela */
   
   game_remove_city(pcity);
+  map_update_borders_city_destroyed(x, y);
 
   players_iterate(other_player) {
     if (map_get_known_and_seen(x, y, other_player)) {
@@ -1920,6 +1927,10 @@
 
   if (ptile->worked && ptile->worked != pcity)
     return FALSE;
+
+  if (ptile->owner && ptile->owner->player_no != pcity->owner) {
+    return FALSE;
+  }
 
   return TRUE;
 }
Index: server/gamelog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamelog.c,v
retrieving revision 1.27
diff -u -r1.27 gamelog.c
--- server/gamelog.c    2003/04/04 15:47:49     1.27
+++ server/gamelog.c    2003/04/21 23:21:27
@@ -25,6 +25,7 @@
 #include "log.h"
 #include "map.h"
 #include "mem.h"
+#include "report.h"
 #include "support.h"
 
 #include "gamelog.h"
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.110
diff -u -r1.110 mapgen.c
--- server/mapgen.c     2003/02/20 09:45:22     1.110
+++ server/mapgen.c     2003/04/21 23:21:28
@@ -1750,6 +1750,7 @@
     for (x = 0 ; x < map.xsize ; x++) {
       map_set_terrain(x, y, T_OCEAN);
       map_set_continent(x, y, 0);
+      map_set_owner(x, y, NULL);
     }
   for (x = 0 ; x < map.xsize; x++) {
     map_set_terrain(x, 0, myrand(9) > 0 ? T_ARCTIC : T_TUNDRA);
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.121
diff -u -r1.121 maphand.c
--- server/maphand.c    2003/04/12 18:24:42     1.121
+++ server/maphand.c    2003/04/21 23:21:29
@@ -349,6 +349,7 @@
 
   info.x = x;
   info.y = y;
+  info.owner = ptile->owner ? ptile->owner->player_no : MAP_TILE_OWNER_NULL;
 
   conn_list_iterate(*dest, pconn) {
     struct player *pplayer = pconn->player;
@@ -388,6 +389,7 @@
 
   info.x = x;
   info.y = y;
+  info.owner = ptile->owner ? ptile->owner->player_no : MAP_TILE_OWNER_NULL;
 
   if (!pplayer) {      /* observer sees all */
     info.known=TILE_KNOWN;
@@ -1519,6 +1521,8 @@
 
       send_all_known_tiles(NULL);
     }
+    
+    map_update_borders_landmass_change(x, y);
 
     gamelog(GAMELOG_MAP, _("(%d,%d) land created from ocean"), x, y);
     return OLC_OCEAN_TO_LAND;
@@ -1533,8 +1537,200 @@
       send_all_known_tiles(NULL);
     }
 
+    map_update_borders_landmass_change(x, y);
+
     gamelog(GAMELOG_MAP, _("(%d,%d) ocean created from land"), x, y);
     return OLC_LAND_TO_OCEAN;
   }
   return OLC_NONE;
+}
+
+/*************************************************************************
+  Return pointer to the oldest adjacent city to this tile.  If
+  there is a city on the exact tile, that is returned instead.
+*************************************************************************/
+static struct city *map_get_adjc_city(int x, int y)
+{
+  struct city *closest = NULL;   /* Closest city */
+  struct tile *ptile;
+
+  ptile = map_get_tile(x, y);
+  if (ptile->city) {
+    return ptile->city;
+  }
+
+  adjc_iterate(x, y, xp, yp) {
+    ptile = map_get_tile(xp, yp);
+    if (ptile->city && 
+         (!closest || ptile->city->turn_founded < closest->turn_founded)) {
+      closest = ptile->city;
+    }
+  } adjc_iterate_end;
+
+  return closest;
+}
+
+/*************************************************************************
+  Return pointer to the closest city to this tile, which must be
+  on the same continent if the city is not immediately adjacent.
+  If two or more cities are equally distant, then return the
+  oldest (i.e. the one with the lowest id). This also correctly
+  works for water bases in SMAC mode, and allows coastal cities
+  to claim one square of ocean. If no cities are within game.borders
+  distance, returns NULL.
+
+  NOTE: The behaviour of this function will eventually depend
+  upon some planned ruleset options.
+*************************************************************************/
+static struct city *map_get_closest_city(int x, int y)
+{
+  struct city *closest;  /* Closest city */
+  int distsq;    /* Squared distance to city */
+  int cldistsq;  /* Squared distance to closest city */
+
+  closest = map_get_adjc_city(x, y);
+  if (!closest) {
+    cldistsq = game.borders * game.borders;
+    cities_iterate(pcity) {
+      if (map_get_continent(pcity->x, pcity->y) == map_get_continent(x, y)) {
+        distsq = sq_map_distance(pcity->x, pcity->y, x, y);
+        if (distsq < cldistsq ||
+             (distsq == cldistsq &&
+              (!closest || closest->turn_founded > pcity->turn_founded))) {
+          closest = pcity;
+          cldistsq = distsq;
+        } 
+      }
+    } cities_iterate_end;
+  }
+
+  return closest;
+}
+
+/*************************************************************************
+  Update tile worker states for all cities that have the given map tile
+  within their radius. Does not sync with client.
+*************************************************************************/
+static void tile_update_owner(int x, int y)
+{
+  cities_iterate(pcity) {
+    int cityx, cityy;
+    if (map_to_city_map(&cityx, &cityy, pcity, x, y)) {
+        update_city_tile_status_map(pcity, x, y);
+#if 0
+       update_city_tile_status_map(pcity, cityx, cityy);
+#endif
+    }
+  } cities_iterate_end;
+}
+
+/*************************************************************************
+  Recalculate the borders around a given position.
+*************************************************************************/
+static void map_update_borders_recalculate_position(int x, int y)
+{
+  if (game.borders > 0) {
+    iterate_outward(x, y, game.borders, xp, yp) {
+      struct city *pccity = map_get_closest_city(xp, yp);
+      struct player *new_owner = pccity ? get_player(pccity->owner) : NULL;
+
+      if (new_owner != map_get_owner(xp, yp)) {
+       map_set_owner(xp, yp, new_owner);
+       send_tile_info(NULL, xp, yp);
+       tile_update_owner(xp, yp);
+      }
+    } iterate_outward_end;
+  }
+}
+
+/*************************************************************************
+  Modify national territories as resulting from a city being destroyed.
+  x,y coords for (already deleted) city's location.
+  Tile worker states are updated as necessary, but not sync'd with client.
+*************************************************************************/
+void map_update_borders_city_destroyed(int x, int y)
+{
+  map_update_borders_recalculate_position(x, y);
+}
+
+/*************************************************************************
+  Modify national territories resulting from a change of landmass.
+  Tile worker states are updated as necessary, but not sync'd with client.
+  NOTE: Currently just recalculates all borders from scratch - this is
+  really inefficient.
+  NOTE: The behaviour of this function will eventually depend upon some
+  planned ruleset options, hence the passed (but unused) x,y parameters.
+*************************************************************************/
+void map_update_borders_landmass_change(int x, int y)
+{
+  if (game.borders > 0) {
+    map_calculate_borders();
+
+    whole_map_iterate(xp, yp) {
+      send_tile_info(NULL, xp, yp);
+    } whole_map_iterate_end;
+  }
+}
+
+/*************************************************************************
+  Modify national territories resulting from new city or change of city
+  ownership.
+  Tile worker states are updated as necessary, but not sync'd with client.
+*************************************************************************/
+void map_update_borders_city_change(struct city *pcity)
+{
+  map_update_borders_recalculate_position(pcity->x, pcity->y);
+}
+
+/*************************************************************************
+  Delete the territorial claims to all tiles.
+*************************************************************************/
+void map_clear_borders(void)
+{
+  whole_map_iterate(x, y) {
+    map_set_owner(x, y, NULL);
+  } whole_map_iterate_end;
+}
+
+/*************************************************************************
+  Minimal code that calculates all national territories from scratch.
+*************************************************************************/
+void map_calculate_territory(void)
+{
+  /* Clear any old territorial claims. */
+  map_clear_borders();
+
+  if (game.borders > 0) {
+    /* Loop over all cities and claim territory. */
+    cities_iterate(pcity) {
+      /* Loop over all map tiles within this city's sphere of influence. */
+      iterate_outward(pcity->x, pcity->y, game.borders, x, y) {
+       struct city *pccity = map_get_closest_city(x, y);
+
+       if (pccity) {
+         map_set_owner(x, y, get_player(pccity->owner));
+       }
+      } iterate_outward_end;
+    } cities_iterate_end;
+  }
+}
+
+/*************************************************************************
+  Calculate all national territories from scratch.  This can be slow, but
+  is only performed occasionally, i.e. after loading a saved game. Doesn't
+  send any tile information to the clients. Tile worker states are updated
+  as necessary, but not sync'd with client.
+*************************************************************************/
+void map_calculate_borders(void)
+{
+  if (game.borders > 0) {
+    map_calculate_territory();
+
+    /* Fix tile worker states. */
+    cities_iterate(pcity) {
+      city_map_iterate(x, y) {
+        update_city_tile_status_map(pcity, x, y);
+      } city_map_iterate_end;
+    } cities_iterate_end;
+  }
 }
Index: server/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.35
diff -u -r1.35 maphand.h
--- server/maphand.h    2003/04/04 15:47:50     1.35
+++ server/maphand.h    2003/04/21 23:21:29
@@ -90,6 +90,13 @@
 void disable_fog_of_war(void);
 bool is_coast_seen(int x, int y, struct player *pplayer);
 
+void map_update_borders_city_destroyed(int x, int y);
+void map_update_borders_city_change(struct city *pcity);
+void map_update_borders_landmass_change(int x, int y);
+void map_clear_borders(void);
+void map_calculate_territory(void);
+void map_calculate_borders(void);
+
 enum ocean_land_change check_terrain_ocean_land_change(int x, int y,
                                               enum tile_terrain_type oldter);
 #endif  /* FC__MAPHAND_H */
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.267
diff -u -r1.267 plrhand.c
--- server/plrhand.c    2003/04/17 20:06:36     1.267
+++ server/plrhand.c    2003/04/21 23:21:30
@@ -1312,6 +1312,11 @@
 
   game_remove_player(pplayer);
   game_renumber_players(pplayer->player_no);
+
+/* Update borders.
+ * Recalculating all borders from scratch is probably cheaper than updating 
for each removed city.
+ */
+  map_calculate_borders();
 }
 
 /**************************************************************************
Index: server/report.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/report.c,v
retrieving revision 1.44
diff -u -r1.44 report.c
--- server/report.c     2003/04/04 15:47:50     1.44
+++ server/report.c     2003/04/21 23:21:31
@@ -32,6 +32,7 @@
 
 #include "citytools.h"
 
+#include "maphand.h"
 #include "report.h"
 
 static void page_conn_etype(struct conn_list *dest, const char *caption,
@@ -42,7 +43,8 @@
         HISTORIAN_ADVANCED=1,
         HISTORIAN_MILITARY=2,
         HISTORIAN_HAPPIEST=3,
-        HISTORIAN_LARGEST=4};
+        HISTORIAN_LARGEST=4,
+        HISTORIAN_TERRITORY=5};
 
 #define HISTORIAN_FIRST                HISTORIAN_RICHEST
 #define HISTORIAN_LAST                 HISTORIAN_LARGEST
@@ -52,6 +54,7 @@
     N_("%s report on the most ADVANCED Civilizations in the World."),
     N_("%s report on the most MILITARIZED Civilizations in the World."),
     N_("%s report on the HAPPIEST Civilizations in the World."),
+    N_("%s report on the most POPULOUS Civilizations in the World."),
     N_("%s report on the LARGEST Civilizations in the World.")
 };
 
@@ -135,6 +138,8 @@
     { 'b', DEM_COL_BEST }
 };
 
+#define USER_AREA_MULT (1000)
+
 /**************************************************************************
 ...
 **************************************************************************/
@@ -184,6 +189,11 @@
       case HISTORIAN_LARGEST:
        size[j].value = total_player_citizens(pplayer);
        break;
+      case HISTORIAN_TERRITORY:
+       size[j].value=total_player_territory(pplayer);
+       break;
+      default:
+        freelog(LOG_DEBUG, "Unknown historian type.");
       }
       size[j].player = pplayer;
       j++;
@@ -858,6 +868,7 @@
 
 /**************************************************************************
 Create a log file of the civilizations so you can see what was happening.
+NOTE: This should be ammended to use new territory definition.
 **************************************************************************/
 static void log_civ_score(void)
 {
@@ -1068,6 +1079,155 @@
   if (report > HISTORIAN_LAST) {
     report = HISTORIAN_FIRST;
   }
+}
+
+/**************************************************************************
+Returns the given player's landarea and settledarea.  "landarea" is the
+claimed territory.  "settledarea" is claimed territory which is also
+within owned cities' radii.
+**************************************************************************/
+static void player_get_landarea(struct player *pplayer,
+                               int *return_landarea,
+                               int *return_settledarea)
+{
+  int settled;     /* Whether a particular tile is settled by this player. */
+  struct city *pcity;
+
+  if (pplayer) {
+    if (return_landarea) {
+      *return_landarea = 0;
+      whole_map_iterate(x, y) {
+        if (map_get_owner(x, y) == pplayer)
+          (*return_landarea)++;
+      } whole_map_iterate_end;
+
+      *return_landarea *= USER_AREA_MULT;
+    }
+    if (return_settledarea) {
+      *return_settledarea = 0;
+      whole_map_iterate(x, y) {
+        settled=0;
+        if (map_get_owner(x, y) == pplayer) {
+          map_city_radius_iterate(x, y, x_itr, y_itr) {
+            if ( (pcity=map_get_city(x_itr, y_itr)) &&
+                 pcity->owner == pplayer->player_no ) {
+              settled = 1;
+            }
+          } map_city_radius_iterate_end;
+        }
+        *return_settledarea += settled;
+      } whole_map_iterate_end;
+
+      *return_settledarea *= USER_AREA_MULT;
+    }
+  }
+}
+
+/**************************************************************************
+Return number of tiles claimed by player's nation.
+**************************************************************************/
+int total_player_territory(struct player *pplayer)
+{
+  return (pplayer->score.landarea);
+}
+
+/**************************************************************************
+Return the overall civilisation score.
+If borders are disabled for this game, then the default border radius is
+used to calculate the territories.
+**************************************************************************/
+int civ_score(struct player *pplayer)
+{
+  int i;
+  struct city *pcity;
+  int landarea, settledarea;
+  int orig_borders;
+
+  pplayer->score.happy=0;                       /* done */
+  pplayer->score.content=0;                     /* done */   
+  pplayer->score.unhappy=0;                     /* done */
+  pplayer->score.taxmen=0;                      /* done */
+  pplayer->score.scientists=0;                  /* done */
+  pplayer->score.elvis=0;                       /* done */ 
+  pplayer->score.wonders=0;                     /* done */
+  pplayer->score.techs=0;                       /* done */
+  pplayer->score.techout=0;                     /* done */
+  pplayer->score.landarea=0;                    /* done */
+  pplayer->score.settledarea=0;                 /* done */
+  pplayer->score.population=0;
+  pplayer->score.cities=0;                      /* done */
+  pplayer->score.units=0;                       /* done */
+  pplayer->score.pollution=0;                   /* done */
+  pplayer->score.bnp=0;                         /* done */
+  pplayer->score.mfg=0;                         /* done */
+  pplayer->score.literacy=0;
+  pplayer->score.spaceship=0;
+
+  if (is_barbarian(pplayer)) return 0;
+
+  city_list_iterate(pplayer->cities, pcity) {
+    pplayer->score.happy+=pcity->ppl_happy[4];
+    pplayer->score.content+=pcity->ppl_content[4];
+    pplayer->score.unhappy+=pcity->ppl_unhappy[4];
+    pplayer->score.taxmen+=pcity->ppl_taxman;
+    pplayer->score.scientists+=pcity->ppl_scientist;
+    pplayer->score.elvis+=pcity->ppl_elvis;
+    pplayer->score.population+=city_population(pcity);
+    pplayer->score.cities++;
+    pplayer->score.pollution+=pcity->pollution;
+    pplayer->score.techout+=pcity->science_total;
+    pplayer->score.bnp+=pcity->trade_prod;
+    pplayer->score.mfg+=pcity->shield_surplus;
+    if (city_got_building(pcity, B_UNIVERSITY)) 
+      pplayer->score.literacy+=city_population(pcity);
+    else if (city_got_building(pcity,B_LIBRARY))
+      pplayer->score.literacy+=(city_population(pcity)/2);
+  }
+  city_list_iterate_end;
+
+  if ( (orig_borders=game.borders) ) {
+    game.borders=GAME_DEFAULT_BORDERS;
+    map_calculate_territory();
+  }
+
+  player_get_landarea(pplayer, &landarea, &settledarea);
+  pplayer->score.landarea=landarea;
+  pplayer->score.settledarea=settledarea;
+
+  if (orig_borders==0) {
+    /* Delete territorial claims. */
+    game.borders=0;
+    map_clear_borders();
+  }
+
+  for (i=0;i<game.num_tech_types;i++) 
+    if (get_invention(pplayer, i)==TECH_KNOWN) 
+      pplayer->score.techs++;
+  pplayer->score.techs+=(((pplayer->future_tech)*5)/2);
+  
+  unit_list_iterate(pplayer->units, punit) 
+    if (is_military_unit(punit)) pplayer->score.units++;
+  unit_list_iterate_end;
+  
+  for (i=0;i<game.num_impr_types;i++) {
+    if (is_wonder(i) && (pcity=find_city_by_id(game.global_wonders[i])) && 
+       player_owns_city(pplayer, pcity))
+      pplayer->score.wonders++;
+  }
+
+  /* How much should a spaceship be worth??
+     This gives 100 points per 10,000 citizens.  --dwp
+  */
+  if (pplayer->spaceship.state == SSHIP_ARRIVED) {
+    pplayer->score.spaceship += (int)(100 * pplayer->spaceship.habitation
+                                     * pplayer->spaceship.success_rate);
+  }
+
+  return (total_player_citizens(pplayer)
+         +pplayer->score.happy
+         +pplayer->score.techs*2
+         +pplayer->score.wonders*5
+         +pplayer->score.spaceship);
 }
 
 /**************************************************************************
Index: server/report.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/report.h,v
retrieving revision 1.6
diff -u -r1.6 report.h
--- server/report.h     2002/12/18 17:36:20     1.6
+++ server/report.h     2003/04/21 23:21:31
@@ -26,6 +26,7 @@
 void report_top_five_cities(struct conn_list *dest);
 bool is_valid_demography(const char *demographics, char **error_message);
 void report_demographics(struct connection *pconn);
+int civ_score(struct player *pplayer);
 void report_scores(bool final);
 
 /* See also report_server_options() in stdinhand.h */
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.28
diff -u -r1.28 sanitycheck.c
--- server/sanitycheck.c        2003/02/17 02:11:27     1.28
+++ server/sanitycheck.c        2003/04/21 23:21:31
@@ -144,6 +144,8 @@
 
        if (city_map_to_map(&map_x, &map_y, pcity, x, y)) {
          struct tile *ptile = map_get_tile(map_x, map_y);
+         struct player *owner = map_get_owner(map_x, map_y);
+
          switch (get_worker_city(pcity, x, y)) {
          case C_TILE_EMPTY:
            if (map_get_tile(map_x, map_y)->worked) {
@@ -157,6 +159,12 @@
                      "empty but occupied by an enemy unit!",
                      pcity->name, x, y);
            }
+           if (game.borders > 0
+               && owner && owner->player_no != pcity->owner) {
+             freelog(LOG_ERROR, "Tile at %s->%d,%d marked as "
+                     "empty but in enemy territory!",
+                     pcity->name, x, y);
+           }
            break;
          case C_TILE_WORKER:
            if (map_get_tile(map_x, map_y)->worked != pcity) {
@@ -169,11 +177,18 @@
                      "worked but occupied by an enemy unit!",
                      pcity->name, x, y);
            }
+           if (game.borders > 0
+                && owner && owner->player_no != pcity->owner) {
+             freelog(LOG_ERROR, "Tile at %s->%d,%d marked as "
+                     "worked but in enemy territory!",
+                     pcity->name, x, y);
+           }
            break;
          case C_TILE_UNAVAILABLE:
            if (!map_get_tile(map_x, map_y)->worked
                && !is_enemy_unit_tile(ptile, pplayer)
-               && map_get_known(map_x, map_y, pplayer)) {
+               && map_get_known(map_x, map_y, pplayer)
+               && (!owner || owner->player_no == pcity->owner)) {
              freelog(LOG_ERROR, "Tile at %s->%d,%d marked as "
                      "unavailable but seems to be available!",
                      pcity->name, x, y);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.115
diff -u -r1.115 savegame.c
--- server/savegame.c   2003/04/17 20:06:37     1.115
+++ server/savegame.c   2003/04/21 23:21:32
@@ -1857,6 +1857,9 @@
     game.rapturedelay  = secfile_lookup_int_default(file,
       GAME_DEFAULT_RAPTUREDELAY, "game.rapturedelay");
 
+    /* National borders setting. */
+    game.borders = secfile_lookup_int_default(file, 0, "game.borders");
+
     if (has_capability("watchtower", savefile_options)) {
       game.watchtower_extra_vision =
          secfile_lookup_int(file, "game.watchtower_extra_vision");
@@ -2128,6 +2131,9 @@
     initialize_globals();
     apply_unit_ordering();
 
+    /* Rebuild national borders. */
+    map_calculate_borders();
+
     /* Make sure everything is consistent. */
     players_iterate(pplayer) {
       unit_list_iterate(pplayer->units, punit) {
@@ -2247,6 +2253,7 @@
   secfile_insert_int(file, game.onsetbarbarian, "game.onsetbarbs");
   secfile_insert_int(file, game.occupychance, "game.occupychance");
   secfile_insert_str(file, game.demography, "game.demography");
+  secfile_insert_int(file, game.borders, "game.borders");
   secfile_insert_int(file, game.watchtower_vision, "game.watchtower_vision");
   secfile_insert_int(file, game.watchtower_extra_vision, 
"game.watchtower_extra_vision");
   secfile_insert_int(file, game.allowed_city_names, "game.allowed_city_names");
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.277
diff -u -r1.277 stdinhand.c
--- server/stdinhand.c  2003/04/17 20:06:37     1.277
+++ server/stdinhand.c  2003/04/21 23:21:35
@@ -604,6 +604,13 @@
             "changes in squares not observed."), NULL, 
          GAME_DEFAULT_FOGOFWAR)
 
+  GEN_INT("borders", game.borders, SSET_RULES_FLEXIBLE, SSET_TO_CLIENT,
+         N_("National border's radius"),
+         N_("If this is set to greater than 0, nations will have territory "
+            "delineated by borders placed on the loci between cities, with "
+            "the maximum distance from any city specified."), NULL,
+         GAME_MIN_BORDERS, GAME_MAX_BORDERS, GAME_DEFAULT_BORDERS)
+
   GEN_INT("diplchance", game.diplchance, SSET_RULES_FLEXIBLE, SSET_TO_CLIENT,
          N_("Chance in diplomat/spy contests"),
          /* xgettext:no-c-format */

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