diff -Nur -Xfreecivdiff.ignore freeciv-patched/server/maphand.c freeciv-patched2/server/maphand.c
--- freeciv-patched/server/maphand.c	2003-06-26 20:17:02.000000000 +0100
+++ freeciv-patched2/server/maphand.c	2003-06-26 20:14:08.000000000 +0100
@@ -321,6 +321,19 @@
 }
 
 /**************************************************************************
+  Returns TRUE if the given player owns a tile adjacent to that passed.
+**************************************************************************/
+static bool player_owns_adjc_tile(struct player *pplayer, int x, int y)
+{
+  adjc_iterate(x, y, x1, y1) {
+    if (map_get_owner(x1, y1) == pplayer) {
+      return TRUE;
+    }
+  } adjc_iterate_end;
+  return FALSE;
+}
+
+/**************************************************************************
   Send tile information to all the clients in dest which know and see
   the tile.  Also updates player knowledge.  If dest is NULL, sends to
   all clients (game.game_connections) which know and see tile.
@@ -354,13 +367,18 @@
       send_packet_tile_info(pconn, &info);
     } else if (pplayer && map_get_known(x, y, pplayer)
 	       && !map_get_seen(x, y, pplayer)) {
-      /* Just update the owner */
       struct player_tile *plrtile = map_get_player_tile(x, y, pplayer);
+      /* Update the owner of a fogged tile ONLY if we are gaining or losing
+       * ownership, OR if the tile is adjacent to one we do own */
       info.known = TILE_KNOWN_FOGGED;
       info.type = plrtile->terrain;
       info.special = plrtile->special;
       info.continent = ptile->continent;
-      send_packet_tile_info(pconn, &info);
+      if (ptile->owner == pplayer || plrtile->owner == pplayer
+          || player_owns_adjc_tile(pplayer, x, y)) {
+	plrtile->owner = ptile->owner;
+	send_packet_tile_info(pconn, &info);
+      }
     }
   }
   conn_list_iterate_end;
@@ -394,16 +412,21 @@
     info.continent = ptile->continent;
   }
   else if (map_get_known(x, y, pplayer)) {
+    plrtile = map_get_player_tile(x, y, pplayer);
     if (map_get_seen(x, y, pplayer) != 0) { /* known and seen */
       update_tile_knowledge(pplayer,x,y); /* visible; update info */
       info.known = TILE_KNOWN;
     } else { /* known but not seen */
       info.known = TILE_KNOWN_FOGGED;
+      if (ptile->owner == pplayer || plrtile->owner == pplayer
+          || player_owns_adjc_tile(pplayer, x, y)) {
+	plrtile->owner = ptile->owner;
+      }
     }
-    plrtile = map_get_player_tile(x, y, pplayer);
     info.type = plrtile->terrain;
     info.special = plrtile->special;
     info.continent = ptile->continent;
+    info.owner = plrtile->owner ? plrtile->owner->player_no : MAP_TILE_OWNER_NULL;
   } else { /* unknown (the client needs these sometimes to draw correctly) */
     info.known = TILE_UNKNOWN;
     info.type = ptile->terrain;
@@ -920,6 +943,7 @@
   plrtile->terrain = T_UNKNOWN;
   plrtile->special = S_NO_SPECIAL;
   plrtile->city = NULL;
+  plrtile->owner = NULL;
 
   plrtile->seen = 0;
   plrtile->pending_seen = 0;
@@ -953,6 +977,7 @@
 
   plrtile->terrain = ptile->terrain;
   plrtile->special = ptile->special;
+  plrtile->owner = ptile->owner;
 }
 
 /***************************************************************
diff -Nur -Xfreecivdiff.ignore freeciv-patched/server/maphand.h freeciv-patched2/server/maphand.h
--- freeciv-patched/server/maphand.h	2003-06-26 20:17:02.000000000 +0100
+++ freeciv-patched2/server/maphand.h	2003-06-26 20:14:08.000000000 +0100
@@ -35,6 +35,7 @@
 struct player_tile {
   enum tile_terrain_type terrain;
   enum tile_special_type special;
+  struct player *owner;     /* Player owning this tile, or NULL. */
   unsigned short seen;
   unsigned short own_seen;
   /* If you build a city with an unknown square within city radius
diff -Nur -Xfreecivdiff.ignore freeciv-patched/server/savegame.c freeciv-patched2/server/savegame.c
--- freeciv-patched/server/savegame.c	2003-06-26 20:17:02.000000000 +0100
+++ freeciv-patched2/server/savegame.c	2003-06-26 20:14:08.000000000 +0100
@@ -213,6 +213,32 @@
 }
 
 /***************************************************************
+  Converts a tile owner pointer into a char suitable for
+  writing to the savefile.
+***************************************************************/
+static char owner2char(struct player *owner)
+{
+  if (!owner) {
+    return '+';
+  } else {
+    int plrno = owner->player_no;
+    return (plrno < 10 ? '0' + plrno :
+	    plrno < 36 ? 'a' + plrno - 10 : 'A' + plrno - 36);
+  }
+}
+
+/***************************************************************
+  Obtains a tile owner pointer from the savefile information.
+***************************************************************/
+static struct player *char2owner(char ch)
+{
+  return (ch == '+' ? NULL :
+	  ch >= '0' && ch <= '9' ? get_player(ch - '0') :
+	  ch >= 'a' && ch <= 'z' ? get_player(ch - 'a' + 10) :
+	  get_player(ch - 'A' + 36));
+}
+
+/***************************************************************
 Quote the memory block denoted by data and length so it consists only
 of " a-f0-9:". The returned string has to be freed by the caller using
 free().
@@ -1187,6 +1213,13 @@
 		  map_get_player_tile(x, y, plr)->terrain =
 		  char2terrain(ch));
 
+    /* Load tile ownership information if we're using borders */
+    if (game.borders > 0) {
+      LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_o%03d", plrno, y),
+		    map_get_player_tile(x, y, plr)->owner =
+		    char2owner(ch));
+    }
+
     /* get 4-bit segments of 12-bit "special" field. */
     LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_l%03d", plrno, y),
 		  map_get_player_tile(x, y, plr)->special =
@@ -1577,6 +1610,13 @@
 				       (x, y, plr)->terrain],
 			 "player%d.map_t%03d", plrno);
 
+    /* put tile ownership information if we're using borders */
+    if (game.borders > 0) {
+      SAVE_PLAYER_MAP_DATA(file,
+			   owner2char(map_get_player_tile(x, y, plr)->owner),
+			   "player%d.map_o%03d", plrno);
+    }
+
     /* put 4-bit segments of 12-bit "special flags" field */
     SAVE_PLAYER_MAP_DATA(file,
 			 bin2ascii_hex(map_get_player_tile(x, y, plr)->
