Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2001:
[Freeciv-Dev] Some old patches synched and some new stuff
Home

[Freeciv-Dev] Some old patches synched and some new stuff

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Some old patches synched and some new stuff
From: Davide Pagnin <nightmare@xxxxxxxxxx>
Date: Wed, 25 Apr 2001 20:23:10 +0200

Hello Everybody!

I'm new to this mailing list and moreover, I'm new to freeciv-hacking!
All the patches are done against cvs of 23 April or are appliable to cvs
of 23 April!

What I posted here:

happiness-display-gtk.diff: Old patch, posted by Mike Jing, I've only
checked that everything is in order with the new cvs! (This patch
introduces the happiness dialog).

angry-citizen-handling.diff: This patch is a modified version of the
leftover-happiness patch proposed by Mike. In this case I've introduced
angry citizen, they are equivalent to superunhappy citizen on civ II.
(This one is for reaching civ II true compatibility!). In the patch,
there is a new capacity added to the server and to the client, but I've
used great care to make it compatible with old server and old client.
(Well, I've tried to...)

angry-citizen-display-gtk.diff & angry-citizen-misc-data-modified.diff:
These patch add the possibility to see the angry citizens in the city
dialog.

happiness-display-angry-citizen.diff: This patch add to happiness dialog
the possibility to see angry citizen. 
THIS CAN BE APPLIED ONLY AFTER happiness-display-gtk.diff

happiness-city-report.diff: This patch is an old patch of Mike Jing that
introduces a new button in the cities report dialog, related to the
happiness dialog!
THIS CAN BE APPLIED ONLY AFTER happiness-display-gtk.diff

luxury-limit.diff: This is an old proposal of Mike Jing, is a oneliner
that cut to 2*size_of_city the luxury that is usable in a city. (I post
this one, cause I think is correct to made this choice, nontheless if
you all think is not, there is always the civ II question!, we have to
reach compatibility, so, at least, this one must be made an option)

specialists_not_counted.diff: I think that specialists are handled
incorrectly when calculating happiness. This small patch tries to
correct the problem. (Now a specialist is considered as a one less
unhappy citizen, instead is to be considered as a one less CONTENT
citizen!)

no_stealth_wonders.diff: Another little patch, I'm not sure you'll like
it, but make visible ALL wonders that cities are building, also the ones
that have been already built! (There is the possibility for a player to
keep building an already built wonders and none can see that in the
report menu!)

production-before-goto.diff: This one is Thue's patch, I can't
understand why this one haven't already found is way in the CVS code!

I hope to have done a good job... 

        Ciao, Davide
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/client/gui-gtk/citydlg.c 
freeciv/client/gui-gtk/citydlg.c
--- freeciv.orig/client/gui-gtk/citydlg.c       Mon Apr 23 13:32:56 2001
+++ freeciv/client/gui-gtk/citydlg.c    Wed Apr 25 17:13:25 2001
@@ -1487,7 +1536,13 @@
                       i*width, 0, TRUE);
   }
 
-  for (n=0; n<pcity->ppl_unhappy[4]; n++, i++) {
+  for (n=0; n<pcity->ppl_residue[4]; n++, i++) {
+    gtk_pixcomm_copyto(GTK_PIXCOMM(pdialog->citizen_pixmap),
+                      get_citizen_sprite(9 + i%2),
+                      i*width, 0, TRUE);
+  }
+
+  for (n=0; n<pcity->ppl_unhappy[4]-pcity->ppl_residue[4]; n++, i++) {
     gtk_pixcomm_copyto(GTK_PIXCOMM(pdialog->citizen_pixmap),
                       get_citizen_sprite(7 + i%2),
                       i*width, 0, TRUE);
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/client/tilespec.c 
freeciv/client/tilespec.c
--- freeciv.orig/client/tilespec.c      Wed Apr 18 13:34:46 2001
+++ freeciv/client/tilespec.c   Wed Apr 25 17:14:36 2001
@@ -466,6 +466,8 @@
   SET_SPRITE(citizen[6], "citizen.happy_1");
   SET_SPRITE(citizen[7], "citizen.unhappy_0");
   SET_SPRITE(citizen[8], "citizen.unhappy_1");
+  SET_SPRITE(citizen[9], "citizen.angry_0");
+  SET_SPRITE(citizen[10], "citizen.angry_1");
 
   SET_SPRITE(spaceship.solar_panels, "spaceship.solar_panels");
   SET_SPRITE(spaceship.life_support, "spaceship.life_support");
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/client/tilespec.h 
freeciv/client/tilespec.h
--- freeciv.orig/client/tilespec.h      Wed Feb  7 13:31:11 2001
+++ freeciv/client/tilespec.h   Wed Apr 25 17:14:48 2001
@@ -66,7 +66,7 @@
                              (!!(e))*BIT_EAST  | (!!(w))*BIT_WEST)
 
 #define NUM_TILES_PROGRESS 8
-#define NUM_TILES_CITIZEN 9
+#define NUM_TILES_CITIZEN 11
 #define NUM_TILES_HP_BAR 11
 #define NUM_TILES_DIGITS 10
 
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/client/packhand.c 
freeciv/client/packhand.c
--- freeciv.orig/client/packhand.c      Sat Apr 14 13:34:04 2001
+++ freeciv/client/packhand.c   Wed Apr 25 15:01:02 2001
@@ -308,6 +308,7 @@
   
   pcity->size=packet->size;
   for (i=0;i<5;i++) {
+    pcity->ppl_residue[i]=packet->ppl_residue[i];
     pcity->ppl_happy[i]=packet->ppl_happy[i];
     pcity->ppl_content[i]=packet->ppl_content[i];
     pcity->ppl_unhappy[i]=packet->ppl_unhappy[i];
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/common/capstr.c 
freeciv/common/capstr.c
--- freeciv.orig/common/capstr.c        Tue Feb 20 13:35:32 2001
+++ freeciv/common/capstr.c     Wed Apr 25 15:01:02 2001
@@ -74,7 +74,8 @@
 " game_ruleset nuclear_fallout land_channel_requirement event_wonder_obsolete" 
\
 " event00_fix conn_info gen_impr_oversights diplo_move_city packet_short_city" 
\
 " indef_impr_types worklist_true_ids shared_vision activity_patrol" \
-" gen_granary_size happiness_display production_change_fix2 ping_packet"
+" gen_granary_size happiness_display production_change_fix2 ping_packet" \
+" angrycitizen"
 
 /* "+1.11" is protocol for 1.11.0 stable release.
 
@@ -142,6 +143,10 @@
    "production_change_fix2" is various fixes to lost/regained shield when
    changing production. (and sending disbanded_shields and caravan_shields
    over the connection.)
+
+   "angrycitizen" introduces angry citizen, they are like superunhappy citizen
+   in civilization II, they are saved in ppl_residue[], and you must dealt 
with 
+   them before any citizens in a city can become unhappy.
 */
 
 void init_our_capability(void)
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/common/city.h freeciv/common/city.h
--- freeciv.orig/common/city.h  Wed Apr 11 13:33:27 2001
+++ freeciv/common/city.h       Wed Apr 25 15:01:02 2001
@@ -180,6 +180,7 @@
   /* the people */
   int size;
 
+  int ppl_residue[5]; /* angry citizen */
   int ppl_happy[5], ppl_content[5], ppl_unhappy[5];
   int ppl_elvis, ppl_scientist, ppl_taxman;
 
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/common/game.c freeciv/common/game.c
--- freeciv.orig/common/game.c  Sat Apr 14 13:34:09 2001
+++ freeciv/common/game.c       Wed Apr 25 15:01:02 2001
@@ -704,6 +704,7 @@
   game.cityfactor  = GAME_DEFAULT_CITYFACTOR;
   game.civilwarsize= GAME_DEFAULT_CIVILWARSIZE;
   game.unhappysize = GAME_DEFAULT_UNHAPPYSIZE;
+  game.angrycitizen= GAME_DEFAULT_ANGRYCITIZEN;
   game.foodbox     = GAME_DEFAULT_FOODBOX;
   game.aqueductloss= GAME_DEFAULT_AQUEDUCTLOSS;
   game.killcitizen = GAME_DEFAULT_KILLCITIZEN;
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/common/game.h freeciv/common/game.h
--- freeciv.orig/common/game.h  Sat Apr 14 13:34:09 2001
+++ freeciv/common/game.h       Wed Apr 25 15:01:02 2001
@@ -78,6 +78,7 @@
   int nbarbarians;
   int occupychance;
   int unhappysize;
+  int angrycitizen;
   char *startmessage;
   int conn_id;                 /* client-only: id client known to server as */
   int player_idx;
@@ -255,6 +256,10 @@
 #define GAME_DEFAULT_UNHAPPYSIZE 4
 #define GAME_MIN_UNHAPPYSIZE     1
 #define GAME_MAX_UNHAPPYSIZE     6
+
+#define GAME_DEFAULT_ANGRYCITIZEN 0
+#define GAME_MIN_ANGRYCITIZEN     0
+#define GAME_MAX_ANGRYCITIZEN     1
 
 #define GAME_DEFAULT_END_YEAR    2000
 #define GAME_MIN_END_YEAR        GAME_START_YEAR
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/common/packets.c 
freeciv/common/packets.c
--- freeciv.orig/common/packets.c       Sat Apr 14 13:34:10 2001
+++ freeciv/common/packets.c    Wed Apr 25 15:03:42 2001
@@ -2213,6 +2213,8 @@
   cptr=put_uint8(cptr, req->size);
 if (pc && has_capability("happiness_display", pc->capability)) {
   for(data=0;data<5;data++) {
+    if (pc && has_capability("angrycitizen", pc->capability))
+      cptr=put_uint8(cptr, req->ppl_residue[data]);
     cptr=put_uint8(cptr, req->ppl_happy[data]);
     cptr=put_uint8(cptr, req->ppl_content[data]);
     cptr=put_uint8(cptr, req->ppl_unhappy[data]);
@@ -2309,16 +2311,19 @@
   iget_uint8(&iter, &packet->size);
 if (pc && has_capability("happiness_display", pc->capability)) {
   for(data=0;data<5;data++) {
+    iget_uint8(&iter, &packet->ppl_residue[data]);
     iget_uint8(&iter, &packet->ppl_happy[data]);
     iget_uint8(&iter, &packet->ppl_content[data]);
     iget_uint8(&iter, &packet->ppl_unhappy[data]);
   }
 } else {
   for(data=0;data<4;data++) {
+    packet->ppl_residue[data]   = 0;
     packet->ppl_happy[data]   = 0;
     packet->ppl_content[data] = packet->size;
     packet->ppl_unhappy[data] = 0;
   } 
+  packet->ppl_residue[4]=0;
   iget_uint8(&iter, &packet->ppl_happy[4]);
   iget_uint8(&iter, &packet->ppl_content[4]);
   iget_uint8(&iter, &packet->ppl_unhappy[4]);
@@ -2424,6 +2429,7 @@
     sz_strlcpy(old.name, req->name);
     old.size               = req->size;
     for (i=0;i<5;i++) {
+      old.ppl_residue[i]        = 0;
       old.ppl_happy[i]          = 0;
       if (req->happy) {
        old.ppl_content[i]        = req->size;
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/common/packets.h 
freeciv/common/packets.h
--- freeciv.orig/common/packets.h       Sat Apr 14 13:34:10 2001
+++ freeciv/common/packets.h    Wed Apr 25 15:01:02 2001
@@ -324,6 +324,7 @@
   char name[MAX_LEN_NAME];
 
   int size;
+  int ppl_residue[5];
   int ppl_happy[5], ppl_content[5], ppl_unhappy[5];
   int ppl_elvis, ppl_scientist, ppl_taxman;
   int food_prod, food_surplus;
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/server/citytools.c 
freeciv/server/citytools.c
--- freeciv.orig/server/citytools.c     Sun Apr 22 13:33:19 2001
+++ freeciv/server/citytools.c  Wed Apr 25 13:35:47 2001
@@ -984,6 +984,7 @@
   pcity->size=1;
   pcity->ppl_elvis=1;
   pcity->ppl_scientist=pcity->ppl_taxman=0;
+  pcity->ppl_residue[4]=0;
   pcity->ppl_happy[4]=0;
   pcity->ppl_content[4]=1;
   pcity->ppl_unhappy[4]=0;
@@ -1444,6 +1445,7 @@
 
   packet->size=pcity->size;
   for (i=0;i<5;i++) {
+    packet->ppl_residue[i]=pcity->ppl_residue[i];
     packet->ppl_happy[i]=pcity->ppl_happy[i];
     packet->ppl_content[i]=pcity->ppl_content[i];
     packet->ppl_unhappy[i]=pcity->ppl_unhappy[i];
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/server/cityturn.c 
freeciv/server/cityturn.c
--- freeciv.orig/server/cityturn.c      Sat Apr 14 13:34:17 2001
+++ freeciv/server/cityturn.c   Wed Apr 25 15:01:02 2001
@@ -153,6 +153,7 @@
 **************************************************************************/
 static void happy_copy(struct city *pcity, int i)
 {  
+  pcity->ppl_residue[i+1]=pcity->ppl_residue[i];
   pcity->ppl_unhappy[i+1]=pcity->ppl_unhappy[i];
   pcity->ppl_content[i+1]=pcity->ppl_content[i];
   pcity->ppl_happy[i+1]=pcity->ppl_happy[i];
@@ -170,6 +171,10 @@
   pcity->ppl_content[0] = MAX(0, MIN(workers, tmp));
   pcity->ppl_unhappy[0] = workers - pcity->ppl_content[0];
   pcity->ppl_happy[0] = 0; /* no one is born happy */
+  if (game.angrycitizen == 0) {
+    pcity->ppl_residue[0] = 0;
+  } else
+    pcity->ppl_residue[0] = MIN(MAX(0, -tmp), pcity->size);
 }
 
 /**************************************************************************
@@ -179,9 +184,15 @@
 {
   int x=pcity->luxury_total;
   happy_copy(pcity, 0);
-  /* make people happy, content are made happy first, then unhappy content,
-     etc.  each conversions costs 2 luxuries. */
-  while (x>=2 && (pcity->ppl_content[1])) {
+  /* make people happy: 
+     angry citizen (residue) are eliminated first,
+     then content are made happy, then unhappy content, etc.  
+     each conversions costs 2 luxuries. */
+  while (x>=2 && pcity->ppl_residue[1]) {
+    pcity->ppl_residue[1]--;
+    x-=2;
+  }
+  while (x>=2 && pcity->ppl_content[1]) {
     pcity->ppl_content[1]--;
     pcity->ppl_happy[1]++;
     x-=2;
@@ -189,13 +200,11 @@
   while (x>=4 && pcity->ppl_unhappy[1]) {
     pcity->ppl_unhappy[1]--;
     pcity->ppl_happy[1]++;
-/*    x-=2; We can't seriously mean this, right? -- Syela */
-    x-=4;
+    x-=4;  /* unhappy ->(content)-> happy costs 4 luxuries*/  
   }
-  if (x>=2 && pcity->ppl_unhappy[1]) {
+  if (x>=2 && pcity->ppl_unhappy[1]) { /* x=2 or 3 */
     pcity->ppl_unhappy[1]--;
     pcity->ppl_content[1]++;
-    x-=2;
   }
 }
 
@@ -205,27 +214,26 @@
 **************************************************************************/
 static void citizen_happy_units(struct city *pcity, int unhap)
 {
-  int step;         
-
-  if (unhap>0) {                                                           
-    step=MIN(unhap,pcity->ppl_content[3]);                          
-    pcity->ppl_content[3]-=step;
-    pcity->ppl_unhappy[3]+=step;
-    unhap-=step;                     
-    if (unhap>0) {                       
-      step=MIN((unhap/2),pcity->ppl_happy[3]);    
-      pcity->ppl_happy[3]-=step;
-      pcity->ppl_unhappy[3]+=step;
-      unhap -= step * 2;                                                
-      if ((unhap > 0) && pcity->ppl_happy[3]) {                      
-       pcity->ppl_happy[3]--;                                   
-       pcity->ppl_content[3]++;                
-       unhap--;              
-      }                                                           
-    }
+  while (unhap>0 && pcity->ppl_content[3]) {
+    pcity->ppl_content[3]--;
+    pcity->ppl_unhappy[3]++;
+    unhap--;
+  }
+  while (unhap>=2 && pcity->ppl_happy[3]) {
+    pcity->ppl_happy[3]--;
+    pcity->ppl_unhappy[3]++;
+    unhap-=2;
+  }
+  if (unhap>0) {
+    if (pcity->ppl_happy[3]>0) { /* 1 unhap left */
+      pcity->ppl_happy[3]--;
+      pcity->ppl_content[3]++;
+      unhap--;
+    } 
+    /* everyone is unhappy now, add unhap to residue */
+    if (game.angrycitizen == 1)
+      pcity->ppl_residue[3] = MIN(pcity->ppl_residue[3]+unhap, pcity->size);
   }
-    /* MAKE VERY UNHAPPY CITIZENS WITH THE REST, but that is not documented */
-
 }
 
 /**************************************************************************
@@ -235,35 +243,30 @@
 {
   struct government *g = get_gov_pcity(pcity);
   int faces=0;
+
   happy_copy(pcity, 1);
   
-  if (city_got_building(pcity,B_TEMPLE)) { 
+  if (city_got_building(pcity,B_TEMPLE))
     faces+=get_temple_power(pcity);
-  }
   if (city_got_building(pcity,B_COURTHOUSE) &&
-      g->corruption_level == 0) {
+      g->corruption_level == 0)
     faces++;
-  }
-
   if (city_got_building(pcity, B_COLOSSEUM)) 
     faces+=get_colosseum_power(pcity);
   if (city_got_effect(pcity, B_CATHEDRAL))
     faces+=get_cathedral_power(pcity);
+
+  /* make people content (but not happy):
+     get rid of residue first, then make unhappy content. */
+  while (faces && pcity->ppl_residue[2]) {
+    pcity->ppl_residue[2]--;
+    faces--;
+  }
   while (faces && pcity->ppl_unhappy[2]) {
     pcity->ppl_unhappy[2]--;
     pcity->ppl_content[2]++;
     faces--;
   }
-/* no longer hijacking ppl_content[0]; seems no longer to be helpful -- Syela 
*/
-  /* TV doesn't make people happy just content...
- 
-  while (faces && pcity->ppl_content[2]) { 
-    pcity->ppl_content[2]--;
-    pcity->ppl_happy[2]++;
-    faces--;
-  }
-
-  */
 }
 
 /**************************************************************************
@@ -272,8 +275,9 @@
 static void citizen_happy_wonders(struct city *pcity)
 {
   int bonus=0;
+
   happy_copy(pcity, 3);
-  bonus = 0;
+
   if (city_affected_by_wonder(pcity, B_HANGING)) {
     bonus += 1;
     if (city_got_building(pcity, B_HANGING)) 
@@ -290,6 +294,11 @@
     bonus+=2;
   if (city_affected_by_wonder(pcity, B_CURE))
     bonus+=1;
+  /* get rid of residue first, then make unhappy content */
+  while (bonus && pcity->ppl_residue[4]) {
+    pcity->ppl_residue[4]--;
+    bonus--;
+  }
   while (bonus && pcity->ppl_unhappy[4]) {
     pcity->ppl_unhappy[4]--;
     pcity->ppl_content[4]++;
@@ -298,6 +307,7 @@
   if (city_affected_by_wonder(pcity, B_SHAKESPEARE)) {
     pcity->ppl_content[4]+=pcity->ppl_unhappy[4];
     pcity->ppl_unhappy[4]=0;
+    pcity->ppl_residue[4]=0;
   }
 }
 
@@ -472,9 +482,16 @@
     }
     unit_list_iterate_end;
     city_units *= g->martial_law_per;
-    city_units = MIN(city_units, pcity->ppl_unhappy[3]);
-    pcity->ppl_unhappy[3] -= city_units;
-    pcity->ppl_content[3] += city_units;
+    /* get rid of residue first, then make unhappy content */
+    while (city_units>0 && pcity->ppl_residue[3]) {
+      pcity->ppl_residue[3]--;
+      city_units--;
+    }
+    while (city_units>0 && pcity->ppl_unhappy[3]) {
+      pcity->ppl_unhappy[3]--;
+      pcity->ppl_content[3]++;
+      city_units--;
+    }
   }
     
   /* loop over units, subtracting appropriate amounts of food, shields,
@@ -486,7 +503,7 @@
     int food_cost = utype_food_cost(ut, g);
     int gold_cost = utype_gold_cost(ut, g);
 
-    /* Save old values so ve can decide if the unit info should be resent */
+    /* Save old values so we can decide if the unit info should be resent */
     int old_unhappiness = this_unit->unhappiness;
     int old_upkeep      = this_unit->upkeep;
     int old_upkeep_food = this_unit->upkeep_food;
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/server/savegame.c 
freeciv/server/savegame.c
--- freeciv.orig/server/savegame.c      Sun Apr 22 13:33:20 2001
+++ freeciv/server/savegame.c   Wed Apr 25 15:01:02 2001
@@ -1829,6 +1829,7 @@
     game.nuclearwinter = secfile_lookup_int_default(file, 0, 
"game.nuclearwinter");
     game.coolinglevel  = secfile_lookup_int_default(file, 8, 
"game.coolinglevel");
     game.unhappysize   = secfile_lookup_int(file, "game.unhappysize");
+    game.angrycitizen = secfile_lookup_int_default(file, 0, 
"game.angrycitizen");
 
     if (game.version >= 10100) {
       game.cityfactor  = secfile_lookup_int(file, "game.cityfactor");
@@ -2169,6 +2170,7 @@
   secfile_insert_int(file, game.nuclearwinter, "game.nuclearwinter");
   secfile_insert_int(file, game.coolinglevel, "game.coolinglevel");
   secfile_insert_int(file, game.unhappysize, "game.unhappysize");
+  secfile_insert_int(file, game.angrycitizen, "game.angrycitizen");
   secfile_insert_int(file, game.cityfactor, "game.cityfactor");
   secfile_insert_int(file, game.civilwarsize, "game.civilwarsize");
   secfile_insert_int(file, game.diplcost, "game.diplcost");
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/server/stdinhand.c 
freeciv/server/stdinhand.c
--- freeciv.orig/server/stdinhand.c     Sat Apr 14 13:34:18 2001
+++ freeciv/server/stdinhand.c  Wed Apr 25 15:01:02 2001
@@ -458,6 +458,16 @@
        "city are content, and subsequent citizens are unhappy.  "
        "See also cityfactor.") },
 
+  { "angrycitizen", &game.angrycitizen, NULL, NULL,
+    SSET_RULES, SSET_TO_CLIENT,
+    GAME_MIN_ANGRYCITIZEN, GAME_MAX_ANGRYCITIZEN,
+    GAME_DEFAULT_ANGRYCITIZEN,
+    N_("Whether angry citizens are present"),
+    N_("Introduces angry citizens, they are equivalent to superunhappy "
+       "citizen of civilization II. Angry citizens have to become unhappy " 
+       "before any other class of citizens may be considered. \n"
+       "See also unhappysize, cityfactor and governments.") },
+
   { "cityfactor", &game.cityfactor, NULL, NULL,
     SSET_RULES, SSET_TO_CLIENT,
     GAME_MIN_CITYFACTOR, GAME_MAX_CITYFACTOR, GAME_DEFAULT_CITYFACTOR,
Binary files freeciv.orig/data/misc/.xvpics/small.xpm and 
freeciv/data/misc/.xvpics/small.xpm differ
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/data/misc/small.spec 
freeciv/data/misc/small.spec
--- freeciv.orig/data/misc/small.spec   Mon Jul 10 13:27:22 2000
+++ freeciv/data/misc/small.spec        Wed Apr 25 18:12:13 2001
@@ -9,6 +9,7 @@
 artists = "
     Alexandre Beraud <a_beraud@xxxxxxxx>
     Jeff Mallatt <jjm@xxxxxxxxxxxx> (cooling flakes)
+    Davide Pagnin <nightmare@xxxxxxxxxx>
 "
 
 [file]
@@ -39,46 +40,48 @@
   0,  8, "gov.anarchy"
   0,  9, "gov.despotism"
   0, 10, "gov.monarchy"
-  0, 11, "gov.communism"
-  0, 12, "gov.republic"
-  0, 13, "gov.democracy"
+  0, 11, "gov.republic"
+  0, 12, "gov.communism"
+  0, 14, "gov.fundamentalism"  ;for civII compatibility!
+  0, 15, "gov.democracy"
 
 ; Global warming progress indicators:
 
-  0, 14, "s.warming_sun_0"
-  0, 15, "s.warming_sun_1"
-  0, 16, "s.warming_sun_2"
-  0, 17, "s.warming_sun_3"
-  0, 18, "s.warming_sun_4"
-  0, 19, "s.warming_sun_5"
-  0, 20, "s.warming_sun_6"
-  0, 21, "s.warming_sun_7"
+  0, 16, "s.warming_sun_0"
+  0, 17, "s.warming_sun_1"
+  0, 18, "s.warming_sun_2"
+  0, 19, "s.warming_sun_3"
+  0, 20, "s.warming_sun_4"
+  0, 21, "s.warming_sun_5"
+  0, 22, "s.warming_sun_6"
+  0, 23, "s.warming_sun_7"
 
 ; Nuclear winter progress indicators:
 
-  0, 31, "s.cooling_flake_0"
-  0, 32, "s.cooling_flake_1"
-  0, 33, "s.cooling_flake_2"
-  0, 34, "s.cooling_flake_3"
-  0, 35, "s.cooling_flake_4"
-  0, 36, "s.cooling_flake_5"
-  0, 37, "s.cooling_flake_6"
-  0, 38, "s.cooling_flake_7"
+  0, 35, "s.cooling_flake_0"
+  0, 36, "s.cooling_flake_1"
+  0, 37, "s.cooling_flake_2"
+  0, 38, "s.cooling_flake_3"
+  0, 39, "s.cooling_flake_4"
+  0, 40, "s.cooling_flake_5"
+  0, 41, "s.cooling_flake_6"
+  0, 42, "s.cooling_flake_7"
 
 ; Citizen icons:
 
-  0, 22, "citizen.entertainer"
-  0, 23, "citizen.scientist"
-  0, 24, "citizen.tax_collector",
-        "gov.fundamentalism"    ; ?? need something...
-  0, 25, "citizen.content_0"
-  0, 26, "citizen.content_1"
-  0, 27, "citizen.happy_0"
-  0, 28, "citizen.happy_1"
-  0, 29, "citizen.unhappy_0", 
-        "citizen.unhappy_1"     ; Allow for two
+  0, 24, "citizen.entertainer"
+  0, 25, "citizen.scientist"
+  0, 26, "citizen.tax_collector"
+  0, 27, "citizen.content_0"
+  0, 28, "citizen.content_1"
+  0, 29, "citizen.happy_0"
+  0, 30, "citizen.happy_1"
+  0, 31, "citizen.unhappy_0" 
+  0, 32, "citizen.unhappy_1" 
+  0, 33, "citizen.angry_0" 
+  0, 34, "citizen.angry_1" 
 
 ; Right arrow icon:
 
-  0, 30, "s.right_arrow"
+  0, 43, "s.right_arrow"
 }
diff -Nur -Xfreeciv/diff_ignore freeciv.orig/data/misc/small.xpm 
freeciv/data/misc/small.xpm
--- freeciv.orig/data/misc/small.xpm    Mon Jul 10 13:27:23 2000
+++ freeciv/data/misc/small.xpm Wed Apr 25 18:27:42 2001
@@ -1,87 +1,87 @@
 /* XPM */
 static char * small_xpm[] = {
-"585 20 64 1",
+"660 20 64 1",
 "      c None",
-".     c #030408",
-"+     c #248C59",
-"@     c #899A68",
-"#     c #A30409",
-"$     c #8DD167",
-"%     c #134B54",
-"&     c #D69013",
-"*     c #CFCFB3",
-"=     c #9C5127",
-"-     c #5A0206",
-";     c #EDE92B",
-">     c #172F40",
-",     c #E45128",
-"'     c #624D32",
-")     c #AEA651",
-"!     c #3AC644",
-"~     c #E7B106",
-"{     c #2EAC52",
-"]     c #D4E6E2",
-"^     c #0305F5",
-"/     c #EFEADF",
-"(     c #EDD496",
-"_     c #A46D31",
-":     c #5F7373",
-"<     c #2230DA",
-"[     c #93AABB",
-"}     c #FDFDFA",
-"|     c #1C724A",
-"1     c #D16E23",
-"2     c #AEAEB2",
-"3     c #ED927B",
-"4     c #2C0E0F",
-"5     c #54D83C",
-"6     c #F90308",
-"7     c #AAEC2F",
-"8     c #70EB2A",
-"9     c #1EFE04",
-"0     c #5E9070",
-"a     c #5BB770",
-"b     c #5E331C",
-"c     c #9F3724",
-"d     c #F93621",
-"e     c #9594B2",
-"f     c #1753AD",
-"g     c #5453DA",
-"h     c #0A72EA",
-"i     c #6574DD",
-"j     c #98EBE0",
-"k     c #5B93E4",
-"l     c #308FD6",
-"m     c #EDB1AA",
-"n     c #03F2F2",
-"o     c #77EAFA",
-"p     c #6ECDF0",
-"q     c #E8797C",
-"r     c #A4D1D0",
-"s     c #AE7396",
-"t     c #2AAECD",
-"u     c #59ACF5",
-"v     c #B15A9D",
-"w     c #0DCEDE",
-"x     c #B18D27",
-"y     c #304E52",
-"^^^^^khiuk^^^^^^^^^^khiuk^^^^^^^^^^khiuk^^^^^^^^^^khiuk^^^^^^^^^^khiuk^^^^^^^^^^khiuk^^^^^^^^^^khiuk^^^^^^^g*gkliuk^g*<^~~~~~~~~~~~~~~~...............^^^^^^^^^^^^^^^666666666666666nnnnnn...wwwwtt<<gie2*/}(m3q,d........................................................................................................................hhhhh>..fhhhhhhy)33syyyyyyyyyyhhhhhl...hhhhhh}}}}}*c=c_}}}}}}}}}}}}}}}}}}}}}}}}}*c=c_}}}}}}}}}}}}}}}}}}}}}3m}}*c=c_}}}}}}}}}}}}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!",
-"^^^^kf^f^<k^^^^^^^^kf^f^<k^^^^^^^^leeei<k^^^^^^^^iki[i<k^^^^^^^^ike2i<k^^^^^^^^ik****k^^^^^^^^ik****k^^^^^g]eir/}}/u^e*^~~~~~~~~~~~~~~~...1q11=_===...^>^>^>^>^>^>^>^66&6666&d66,&,6nnnnnn...wwtttl<<iie2*//(m3qqd........................................................................................................................hhh>>....fhhhhh:*(m3q>by'e(***hhhhh.....hhhhh}}}}}c=s1c}}}}}}}}}}}*..]}}}}}}}}}}c=s1c}}}}}}}}}}}*..]}}}}}}33q}c=s1c}}}}}}}}}}}}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!!!}}}!!!!!!",
-"^^^k<uph^^hk^^^^^^k<uph^^hk^^^^^^uirpi<^hk^^^^^^uirri^^hk<^^^^^uerrr<^hk<^^^^^ue*]r((*k<^^^^^ue*/]/;*k^^^^/eu*}}/}}/u<*e~~~~_'4'bx~~~~~.41&==(~&=11=..^<^^<^^<^^<^^^<6&~&66&~~66&~~6nnnnnn...wtt3tl^ggie**//(m3q,d.............................................................................................................--#6#--....hh>...._=>hhhhhy((m3xyy@@['@yyhhhhhic1clhhhhh}}}}}m3331}}}}}}}}}}*.==.}}}}}}}}}}m3331}}}}}}}}}}*.==.}}}}}}(311m3331}}}}}}}*2}}}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!!!!}!!!!!!!!!!!!!!}!!!!!!!",
-"^^^uuog^^^^p<^^^^^uuog^^^^p<^^^^^p*of^^^^p<^^^^^2roi<^^^u<^^^^^pr]r*(2^u<^^^^^p;r**;((p<^^^^^$]/]/}/(p<^^g]^r}}}}}}/]^g]~~~'>'.__'b~~~~.&11=c(~&=c1==.^>~^^>^^>^^>x>^6d~6666~d666~66nnnnn.....tt3+l<<gie2*/}(m3q,d.................................................................................>.>...........44444.......-#-.....-#-..hhf>f3=4qbhhhhhy((33'by[*0y20*hhhhhh33qhhhhhh}}}}}}33q(}}}}}}}}}}/q33v}}}}}}}}}}}qqq(}}}}}}}}}}/q33v}}}}}}}m3q>33q(}}}}}}}222/}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!!!!}!!!!!!!}!!!!!!}!!!!!!}}!!}!!!}!!!}!!}",
-"^^k<ol^^^^^^l^^^^k<ol^^^^^^l^^^^kerk^^^^^^l^^^^k[oki)2<^^l^^^^k2rr(;(;*^l^^^^k**j(;((;*l^^^^k*]]}}}}}*l^^22k/}}}}}}}/k<*~~b'~'b>~~''~~~.=_1==~~x_=_==.^'~>^^>^^^><1y^66d6666666661d6nnnwww=1=tl33hl^ggie2]//(m3qqd................................................................>>>>>>.........>>%%%>>.......4>bybyb>4....--..44-44..--.hhhhh33'3=kklhhy'm3s'y>'/'y'*ehhhhh%[*mfhhhhh}}}}m##,c,3/}}}}}}}}._33='}}}}}}}}}31d,ss/}}}}}}}}._33='}}}}}}/33.....>:}}}}}2222/}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!}!!!!}}}!!!!}!!}}!!!}}}!!!}}!!}}!!!}}}!!!}}!",
-"^^ihu<^^^^^^u^^^^ihu<^^^^^^u^^^^hru<^^^^^^u^^^^h2ue(((*^^u^^^^ir]*;((((gk^^^^hr]*;//(((u^^^^hr//}}}}}(k^^]eh]}/}}}}}}u^/~xb~~bx'_~~''~~..1111m~&====..^:~'<^^^>^^<&_^666666666666666nnnwwwqq1tl**lf<<iie2*/}(m3q,d.................................................>>%%%>>.......>>%y|f%%>.....>>yfgy:f%>>....4>bb='c'b>4..-#.4-------4.#4hhik..33q222[hhy'//2:yyy:y}yyyhhhhf.>.'.hhhhh}}}3#######,}}}}}}}}>4334.}}}}}}}}es*v3ssv/}}}}}}}>4334.}}}}}}}3b......4e}}}}22[22/}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!}!!!}}}!!!}!!!!}!!!}}}!!!}!!!}}!!!}}}!!!}}!!}}!!!}}}!!!}}!",
-"^^u<f^^^^^^^u^^^^u<f^^^^^^^u^^^^kefgies^<^u^^^^u2i*(**()^u^^^^urr/}];(*eu^^^^kr*/}}};**u^^^^u*}}}}}}}*u^^*gk/}}}}}/}}p^]~b_~~bxx>&~~>_~...==1(~x===...^:~g^y^>^^>'x:^666666666666666nwwwtt1bq+h..|g<qgi22=//(m3q,d......................>.............>>>.........>>||l||>>.....>>f0:00:y%>....>f|:0::::%>...4b'==v=v=='b4.#..---###---..#he3_.>h[22222hhy*}}/*yby=3e>*:hhhh>.e.e.>hhhh}},#########s}}}}}}>|6||#|b}}}}}/sssmdmvsvv}}}}}}>p333el:}}}}}}}>4......3/}}}22e222}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!}!!!}!!!}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!}!!}}!!}!!}}!!}",
-"^^u^^g<^^<i<u^^^^u^^)(2i<i<u^^^^ug<2;(2eigu^^^^k:<(;/(*2eu^^^^u2*;//}}*ru^^^^u[];}}}/*ru^^^^u[]}}}}//*u^^[gu]}}}}}}/}u<e~yx~~>~~='~~&b&.=1111~~&=1=14.^y~x>x<^^x<x&'^666666666666166wwtwtt*b*+l..|g^qgie2c}/(m3qqd.......>>...........%%|%%.........>f|++%>.......%|0aaa0|%.....%y00@@@0:f>>..>%:::e_e::yf>..>b'=,,,,,='b>.-.4-#######--.-h'32lhl22*22e[hy*}}/2:y@(33ye2hhh>..>....fhhh}=##q1#######(}}}}r||6||#|+}}}}/3svv3#mvssv3}}}}]ptt3)ttt/}}}}}//>.4..>333}}}2[)e222/}}}}}!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!}!!}!!}!!!!!!!!}!!}!!}!!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!",
-"^^u^^eg^^ek<p^^^^u^^ee)**u<p^^^^u<<m;(;([kp^^^^u^i((;/;[ep^^^^u^;(;(;/]*p^^^^u*((}/};**p^^^^u*/}}}}}/*p^^ieu]}}}}}/}/peg~bx~~>~~~>&x_.b.1&1_1m~&=1_c'4^'~)x&x^_&_&x'^666,d1~d6666d~6wwtt.........ff<qq,e2==b(m33qd.....%%%%>.........%|+{+|>........|+{a{+f......>|ua$$$a{|>...>%:0@)))@0:%>.>>f::s_1_s@:y%.4b'=,,,,,,,='b4.4--##6#6##--...>222k2222222[hy//}}]22/*2:by:hhf....>....fhh},#v/m####1###}}}]|+|66##||$}}}msvsss#qvsssv*}}/3)tttttt[3/}}}}/}'..../33q(}}22ee[222/}}}}!!!!!!!}!!!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!",
-"^^^l<ie^<lkl<^^^^^l<ge^<kkl<^^^^^k<i2***2u<^^^^^k<22(*[[[<^^^^^u(;((;r][<^^^^^k;;(;/r]2<^^^^^k;}/}/}][<^^g2^[}}/}}}}*<e<~bx_b4'b>4.''>_.q1_1=(~&==_=c>^y~)~&x>x&x&&:^6d~~~&,66666&~dttt....}.....fy^qqqe2==c(m33qd....>%+{+%>........%+!5!+|.......>|{585{+>.....%|a$777$u+%...>f0@)x&))@0f>..%::xs111_s0y%>>bc=,,,d,,,v'b4.4-###6666##-4.fhk2222[[222e@iy]}}2/*/**@y___hh..>.....>..hh}/,#q3####}m##c}}3+{|66##+||r}}ssv(ss,sv/ssvv}}333ptttlr33m}}}}}}2..../}33m}}2[2)ee[22/}}}!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!",
-"^^^u^^2^kp^u^^^^^^u^<e^kp^u^^^^^^u^<@^[p:u^^^^^^u^<@(*$2p^^^^^^u2;];*](p^^^^^^u*(;*]**p^^^^^^u*(;}/](p^^^^2gp(}}/}}}p<2^..4b>_x&~~.~~'x.1111=~~&1=1=bb>g~~~)&&&&&&&_^6~~~~16d&,,&~~6ttl.........yfy<q1,e2='b(m333d....>|{9{|>.......>|{!85{f>......>+a878a+>.....%+a$7;7$a:%...%y0@)&&&)@0y>.>%g:s_1,11s::>.4y==,,d,,d,==b4.4-##666#6##--.>hhl*2e322222[[x/}}}****ssxsxeh%..h.....h..fh}}},3q4<--r},##/33q}|66##+++{}}ssq/ssssv(}ssvm33q/pttltp/33}}}}}}2..../}m3q}}2)ee2eee@}}}}!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!!!!!!!}}}!!!!!!",
-"^^^^l<e<[ip<^^^^^^^k<e<[ip<^^^^^^^l<e<[2r<^^^^^^^l<@e[2p<^^^^^^^l)(r*(p<^^^^^^^l2(*]*r<^^^^^^^l2**](p<^^^^<e^l]}/}/r<ei^~yx~b)~~~~_'~bx.1_111(~&11='=4^y~)~~&&&&&x&:<6~~~&~16d~~~~d6tll..}.}..fyfy<<}}}e2;;;(mb-bd.....%+{|%>........%{!5!+%.......>|{585{|>....4>|a$777$a+%>..>f:@)&~&@@0f%..%|:e1111_s0f%>4b'=,,,,,,,v'y4.4-###666###-4.f%hhhk33222222eh]/}//2khhhhhhhh>.>h.....h%.sh}}}}m<<<<.g}}##(33/}6666##j|+}}33}/sssvv/}/svm33m}patttl}33}}}}/2.....2}}3q}/22e)@ee:/}}}}!!!!!!!}!!!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!!!!!!}!}!}!!!!!",
-"^^^^^ukeeo^^^^^^^^^^ueeeo^^^^^^^^^^ukeeo^^^^^^^^^^uke2j^^^^^^^^^^uke*r^^^^^^^^^^u@e*r^^^^^^^^^^u@e*j^^^^^^^g*^u]/}j^ie^^~=_x>~~~~~xb)bx.1=~(~m~~~(&=c>4:~0)~1#1&x:x_^6d&d6,~~~&d,d66l+l...*3..yfyfy^...e2...(m...d.....>%|%>.........%|+{+|%.......>%+aa{+f>.....>|0a$$$a0|>...>%:0@)))@0:%>.>>y::_s1_e::y%.4>c=,,,,d,,=c>4.4--###6###--4.h>fhhhhl[2222)kh]/]}]rhhhhhhhhh33lh.....hhs3l}}}}e44^><.}}333q/}}6666##}|+}}33}mvvvsv(}}333q/}ruttltl]m3}}}}}'4:(..y}}3q}/22eees@*}}}}}!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!}!!}!!}!!!!!!!!}!!}!!}!!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!",
-"^^^^^^r[e^^^^^^^^^^^^p[e^^^^^^^^^^^^r[e^^^^^^^^^^^^r[e^^^^^^^^^^^^r@[^^^^^^^^^^^^p[@^^^^^^^^^^^^p@e^^^^^^^^^^^^p[e^^^^^^~&>__~~~~~~bb>~.c_m~~~~~~~&'bb^:@+0)6#6&:|::^66d6661~~666666lb-b-b-b-bbb-b><...e2...(m...d.......>>...........>%|%%.........>f|+|%>......>%|{aaa0|%.....%f00@@@00y%...>%::e:xs:::%>.4>''=,,,,===b>.-.--#######-4.-hhf>hhh[2222[ehhr}//]2hhhhhhhhhiehhf...%hh4'h}}}}g<^'<>^}}m333}}}6666##}33}}}}}ssv3sv*}}m333}}pattttta33/}}}/}/*2b..2=b3}/22)e:e/}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!}!!!}!!!}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!!!!}}!!}!!}}!!!}!!}}!!}!!}}!!}",
-"^^^^^^pep^^^^^^^^^^^^p[p^^^^^^^^^^^^p@p^^^^^^^^^^^^p[p^^^^^^^^^^^^pep^^^^^^^^^^^^pep^^^^^^^^^^^^p2p^^^^^^^^^^^^p)p^^^^^^~~>'&~~~~~~).4~.4_~&x(~x&x&bc4^:~0)&16=&&|x_^66666,~&~,66666|h11111111,11%><...e2...(m...d.....................>.>...........>>>>>........>>|:++|%>.....>%y:0:0:f%>....>fy:::0::%>>..4bb======='b4.#..--####---4.#hhhf>h2[222)ehhh]}}}**hhhhhhhhhhhhhh...fh>..h}}}}<44]g4^2}}}}}}}}6666##}3q}}}}}svs3vv(}}}}}}}}uttttltl3q}}}}**sgs24bc=}}}/2eee@/}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!}!!!}}}!!!}!!!!}!!!}}}!!!}!!!}}!!!}}}!!!}}!!}}!!!}}}!!!}}!",
-"^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^~~~._~~~~~~b'~~..==_1m~&=='bb4^:~~~~&~&&&&xx^66661~16d~,6666||_=========1<><...e2...(m...d.................................................>>>%>>........>>fyfy%>>.....>>%:f:yyf>.....4>b'==c'b>4..-#..4------..#4hhhhh[222[2[[hhhr}}]*rhhhhhhhhhhhhhh...fh..>h}}}2<^<}e<4<}}}}}}}}66####}}}}}}}/svs2sv}}}}}}}}]pttttttl}}}}}}b)iyee=b.]}}}/2e0s/}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!}!!!!}}}!!!!}!!}}!!!}}}!!!}}!!}}!!!}}}!!!}}!",
-"^^^^^^*22^^^^^^^^^^^^*2e^^^^^^^^^^^^*2[^^^^^^^^^^^^*2e^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*2e^^^^^^^^^^^^*22^^^^^^~~~~byxxx'>'~~~..b=1=&&&=cbb4.^y_:xxxx)xx:'^^666d&,666d~d666gf1=1_1_1_111>>^...e2...(m...d................................................................>>>>>>........>>>%%%>>>......4>bbbyb4>....--..44-44..#-.hhhhk22[eh22e_hh]}}}2*hhhhhhhhhhhhhh...hh...h}}}<>42}]<4<}}}}}}}}}mq3q}}}}}}}}ssvmqsv}}}}}}}}uatttttt+t}}}}}.>mige_..e}}}/2ee/}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!!!!}!!!!!!!}!!!!!!}!!!!!!}}!!}!!!}!!!}!!}",
-"^^^^^^*2[^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*2[^^^^^^^^^^^^*2[^^^^^^^^^^^^*22^^^^^^^^^^^^*2e^^^^^^~~~~~_'b''x~~~~...=1===c'c'4..^^^^^^^^^^^<^>^6666666666dd666|f1=,_,1=1_1_>><<gie2*//(m3q,d...................................................................>.............>.>............4444.......-#-.....-#4..hhhhc#=ehhhe##chhur*[hhhhhhhhhhhhhhh...fh...h}}}<^</}}<<./}}}}}}}}3333}}}}}}}}ssv/msv}}}}}}}}ptuuttuttu}}}}}.>22)e[..:}}}/e0/}}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!!!!!!!}}}!!!!!!",
-"^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*2e^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^^^^^^^*22^^^^^^~~~~~~~~~~~~~~~...b===='c'b4..<^>^>^>^>^^^^^<666666666666666fy1=1x1111111>><<iie2*}/(m3q,d.............................................................................................................--#6#--....hhfb###f%hhhv##hhh]2hhhhhhhhhhhhhhhh...hh>.>h}_=>4i}}}sbbe}}}}}}}}(3qm}}}}}}}'4>v/s'b:}}}}}}}}}}(33/}}}}}}_=..m2g<e=be}}}}}}}}}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}!!!!!!!",
-"^^^^^^^2^^^^^^^^^^^^^^2^^^^^^^^^^^^^^2^^^^^^^^^^^^^^[^^^^^^^^^^^^^^e^^^^^^^^^^^^^^2^^^^^^^^^^^^^^[^^^^^^^^^^^^^^2^^^^^^^~~~~~~~~~~~~~~~........444....^^<^^^^^>^>^>^^666666666666666f%1_11_111_11>>^ggie2*//(m3qqd........................................................................................................................hg####bhf%h####hhh...hhhhhhhhhhhhhh.....hhfhh}cbcb_}}}=bb=}}}}}}}}....}}}}}}/...b}24.'}}}}}}}}}}..4.}}}}}}bcbb_)e/=bb=}}}}}}}}}}}}}}}}}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"};
+".     c #0305F5",
+"+     c #5B93E4",
+"@     c #0A72EA",
+"#     c #6574DD",
+"$     c #59ACF5",
+"%     c #5453DA",
+"&     c #CFCFB3",
+"*     c #308FD6",
+"=     c #2230DA",
+"-     c #E7B106",
+";     c #030408",
+">     c #03F2F2",
+",     c #0DCEDE",
+"'     c #2AAECD",
+")     c #F90308",
+"!     c #FDFDFA",
+"~     c #9594B2",
+"{     c #AEAEB2",
+"]     c #EFEADF",
+"^     c #EDD496",
+"/     c #EDB1AA",
+"(     c #ED927B",
+"_     c #E8797C",
+":     c #E45128",
+"<     c #F93621",
+"[     c #172F40",
+"}     c #1753AD",
+"|     c #304E52",
+"1     c #AEA651",
+"2     c #AE7396",
+"3     c #9F3724",
+"4     c #9C5127",
+"5     c #A46D31",
+"6     c #3AC644",
+"7     c #93AABB",
+"8     c #D4E6E2",
+"9     c #A4D1D0",
+"0     c #D16E23",
+"a     c #D69013",
+"b     c #5F7373",
+"c     c #5E331C",
+"d     c #624D32",
+"e     c #6ECDF0",
+"f     c #EDE92B",
+"g     c #2C0E0F",
+"h     c #B18D27",
+"i     c #5A0206",
+"j     c #A30409",
+"k     c #899A68",
+"l     c #77EAFA",
+"m     c #8DD167",
+"n     c #248C59",
+"o     c #5E9070",
+"p     c #B15A9D",
+"q     c #98EBE0",
+"r     c #134B54",
+"s     c #1C724A",
+"t     c #5BB770",
+"u     c #2EAC52",
+"v     c #54D83C",
+"w     c #70EB2A",
+"x     c #AAEC2F",
+"y     c #1EFE04",
+".....+@#$+..........+@#$+..........+@#$+..........+@#$+..........+@#$+..........+@#$+..........+@#$+.......%&%+*#$+.%&=.---------------;;;;;;;;;;;;;;;...............>>>>>>;;;,,,,'')))))))))))))))!!!!!!!!!!!!!!!@@@@@*;;;@@@@@@==%#~{&]!^/(_:<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@@@@[;;}@@@@@@|1((2||||||||||@@@@@*;;;@@@@@@!!!!!&3435!!!!!!!!!!!!!!!!!!!!!!!!!&3435!!!!!!!!!!!!!!!!!!!!!(/!!&3435!!!!!!!!!!!!!!!!!!!!!(/!!&3435!!!!!!!!!!!!!!!!!!!!6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666!6666666!!!!!!!!!!!!!!!",
+"....+}.}.=+........+}.}.=+........*~~~#=+........#+#7#=+........#+~{#=+........#+&&&&+........#+&&&&+.....%8~#9]!!]$.~&.---------------;;;0_0045444;;;.[.[.[.[.[.[.[.>>>>>>;;;,,'''*))a))))a<)):a:)!!!!!!!!!!!!!!!@@@@@;;;;;@@@@@==##~{&]]^/(__<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@@[[;;;;}@@@@@b&^/(_[c|d~^&&&@@@@@;;;;;@@@@@!!!!!34203!!!!!!!!!!!&;;8!!!!!!!!!!34203!!!!!!!!!!!&;;8!!!!!!((_!34203!!!!!!!!!!!&;;8!!!!!!((_!34203!!!!!!!!!!!&;;8!!!!!6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666!6666666666666!!!666666!!!!!!!!!!!!!!!",
+"...+=$e@..@+......+=$e@..@+......$#9e#=.@+......$#99#..@+=.....$~999=.@+=.....$~&89^^&+=.....$~&]8]f&+....]~$&!!]!!]$=&~----5dgdch-----;g0a44^-a4004;;.=..=..=..=...=>>>>>>;;;,''('*)a-a))a--))a--)!!!!!!!!!!!!!!!@@@@@#303*@@@@@.%%#~&&]]^/(_:<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iij)jii;;;;@@[;;;;54[@@@@@|^^/(h||kk7dk||@@@@@#303*@@@@@!!!!!/(((0!!!!!!!!!!&;44;!!!!!!!!!!/(((0!!!!!!!!!!&;44;!!!!!!^(00/(((0!!!!!!!!!!&;44;!!!!!!^(00/(((0!!!!!!!!!!&;44;!!!!!6666666666666666666666666666666666666666666666666666666666666666666666666666666666!66666666666666!66666666666666!6666666!&{!!!!!!!!!!!!",
+"...$$l%....e=.....$$l%....e=.....e&l}....e=.....{9l#=...$=.....e989&^{.$=.....ef9&&f^^e=.....m8]8]!]^e=..%8.9!!!!!!]8.%8---d[d;55dc----;a0043^-a43044;.[-..[..[..[h[.>>>>>;;;;;''(n*)<-))))-<)))-))!!!!!!!!!!!!!!!@@@@@@((_@@@@@@==%#~{&]!^/(_:<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[;[;;;;;;;;;;;ggggg;;;;;;;iji;;;;;iji;;@@}[}(4g_c@@@@@|^^((dc|7&o|{o&@@@@@@((_@@@@@@!!!!!!((_^!!!!!!!!!!]_((p!!!!!!!!!!!___^!!!!!!!!!!]_((p!!!!!!!/(_[((_^!!!!!!!!!!]_((p!!!!!!!/(_j((_^!!!!!!!!!!]_((p!!!!!6666666666666666666666666666666666666666666666666666666666666666666!66666666666666!6666666!666666!666666!!66!666!666!66!!{{{]!!!!!!!!!!",
+"..+=l*......*....+=l*......*....+~9+......*....+7l+#1{=..*....+{99^f^f&.*....+&&q^f^^f&*....+&88!!!!!&*..{{+]!!!!!!!]+=&--cd-dc[--dd---;45044--h54544;.d-[..[...[=0|.>>>,,,404'*((@*))<)))))))))0<)!!!!!!!!!!!!!!!@@@@@r7&/}@@@@@.%%#~{8]]^/(__<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[[[[[[;;;;;;;;;[[rrr[[;;;;;;;g[c|c|c[g;;;;ii;;ggigg;;ii;@@@@@((d(4++*@@|d/(2d|[d]d|d&~@@@@@r7&/}@@@@@!!!!/jj:3:(]!!!!!!!!;5((4d!!!!!!!!!(0<:22]!!!!!!!!;5((4d!!!!!!]((;;;;;[b!!!!!!!!;5((4d!!!!!!]((jjjjjjb!!!!!!!!;5((4d!!!!6666666666666666666666666666666666666666666666666666666666666666666!66666666!6666!!!6666!66!!666!!!666!!66!!666!!!666!!6!{{{{]!!!!!!!!!",
+"..#@$=......$....#@$=......$....@9$=......$....@{$~^^^&..$....#98&f^^^^%+....@98&f]]^^^$....@9]]!!!!!^+..8~@8!]!!!!!!$.]-hc--chd5--dd--;;0000/-a4444;;.b-d=...[..=a5.>>>,,,__0'*&&*})))))))))))))))!!!!!!!!!!!!!!!@@@@};[;d;@@@@@==##~{&]!^/(_:<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[[rrr[[;;;;;;;[[r|s}rr[;;;;;[[|}%|b}r[[;;;;g[cc4d3dc[g;;ij;giiiiiiig;jg@@#+;;((_{{{7@@|d]]{b|||b|!|||@@@@};[;d;@@@@@!!!(jjjjjjj:!!!!!!!![g((g;!!!!!!!!~2&p(22p]!!!!!!![g((g;!!!!!!!(c;;;;;;g~!!!!!!![g((g;!!!!!!!(j))))))j~!!!!!!![g((g;!!!!6666666666666666666666666666666666666666666666666666!666666666!666!!!666!6666!666!!!666!666!!666!!!666!!66!!666!!!666!!6!{{7{{]!!!!!!!!",
+"..$=}.......$....$=}.......$....+~}%#~2.=.$....${#&^&&^1.$....$99]!8f^&~$....+9&]!!!f&&$....$&!!!!!!!&$..&%+]!!!!!]!!e.8-c5--chh[a--[5-;;;440^-h444;;;.b-%.|.[..[dhb.>,,,''0c_n@;;s%)))))))))))))))!!!!!!!!!!!!!!!@@@@[;~;~;[@@@@=_%#{{4]]^/(_:<;;;;;;;;;;;;;;;;;;;;;;[;;;;;;;;;;;;;[[[;;;;;;;;;[[ss*ss[[;;;;;[[}oboob|r[;;;;[}sbobbbbr[;;;gcd44p4p44dcg;j;;iiijjjiii;;j@~(5;[@7{{{{{@@|&!!]&|c|4(~[&b@@@@[;~;~;[@@@@!!:jjjjjjjjj2!!!!!![sjssjsc!!!!!]222/</p2pp!!!!!![e(((~*b!!!!!!![g;;;;;;(]!!!!![s;ss;sc!!!!!!!jj)))))j(]!!!!![s)ss)sc!!!6666666666666666666666666666666666666!6666666666!666!666!666666!!66!66!!666666!!66!66!!666666!!66!66!!666!66!!66!66!!66!!{{~{{{!!!!!!!!",
+"..$..%=..=#=$....$..1^{#=#=$....$%={f^{~#%$....+b=^f]^&{~$....${&f]]!!&9$....$78f!!!]&9$....$78!!!!]]&$..7%$8!!!!!!]!$=~-|h--[--4d--aca;40000--a4040g;.|-h[h=..h=had.,,',''&c&n*;;s%))))))))))))0))!!!!!!!!!!!!!!!@@@[;;[;;;;}@@@._%#~{3!]^/(__<;;;;;;;[[;;;;;;;;;;;rrsrr;;;;;;;;;[}snnr[;;;;;;;rsotttosr;;;;;r|ookkkob}[[;;[rbbb~5~bb|}[;;[cd4:::::4dc[;i;gijjjjjjjii;i@d({*@*{{&{{~7@|&!!]{b|k^((|~{@@@[;;[;;;;}@@@!4jj_0jjjjjjj^!!!!9ssjssjsn!!!!](2pp(j/p22p(!!!!8e''(1''']!!!!!]][;g;;[(((!!!!9ss;ss;sn!!!!!!]]j))))j(((!!!!9ss)ss)sn!!!6666666666666666666666!66666666666!66!66!66666666!66!66!6666666!!66!66!!666666!!66!66!!666666!!66!66!!666666!!66!66!!666!{71~{{{]!!!!!!",
+"..$..~%..~+=e....$..~~1&&$=e....$==/f^f^7+e....$.#^^f]f7~e....$.f^f^f]8&e....$&^^!]!f&&e....$&]!!!!!]&e..#~$8!!!!!]!]e~%-ch--[---[ah5;c;0a050/-a4053dg.d-1hah.5a5ahd.,,'';;;;;;;;;}}))):<0-<))))<-)!!!!!!!!!!!!!!!@@};;;;[;;;;}@@=__:~{44c^/((_<;;;;;rrrr[;;;;;;;;;rsnuns[;;;;;;;;snutun};;;;;;[s$tmmmtus[;;;[rbok111kobr[;[[}bb25052kb|r;gcd4:::::::4dcg;giijj)j)jjii;;;[{{{+{{{{{{{7@|]]!!8{{]&{bc|b@@};;;;[;;;;}@@!:jp]/jjjj0jjj!!!8snsjjjjssm!!!/2p222j_p222p&!!](1''''''7(]!!!!]!d;;;;]((_^!!8sns;;;;ssm!!!!!]!j))))]((_^!!8sns))))ssm!!6666666!666666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!66666!{{~~7{{{]!!!!!",
+"...*=#~.=*+*=.....*=%~.=++*=.....+=#{&&&{$=.....+={{^&777=.....$^f^^f987=.....+ff^f]98{=.....+f!]!]!87=..%{.7!!]!!!!&=~=-ch5cgdc[g;dd[5;_0504^-a44543[.|-1-ah[hahaab.''';;;;!;;;;;}|)<---a:)))))a-<!!!!!!!!!!!!!!!@@;;[;;;;;[;;@@.___~{443^/((_<;;;;[rnunr[;;;;;;;;rn6v6ns;;;;;;;[suvwvun[;;;;;rstmxxxm$nr;;;[}ok1ha11ko}[;;rbbh200052o|r[[c34:::<:::pdcg;gijjj))))jjig;}@+{{{{77{{{~k#|8!!{]&]&&k|555@@;;[;;;;;[;;@@!]:j_(jjjj!/jj3!!(nusjjjjnss9!!22p^22:2p]22pp!!(((e'''*9((/!!!!!!{;;;;]!((/!!(nus;;;;nss9!!!!!!{))))]!((/!!(nus))))nss9!666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666!{7{1~~7{{]!!!!",
+"...$..{.+e.$......$.=~.+e.$......$.=k.7eb$......$.=k^&m{e......${f8f&8^e......$&^f&8&&e......$&^f!]8^e....{%e^!!]!!!e={.;;gc[5ha--;--dh;00004--a0404cc[%---1aaaaaaa5.''*;;;;;;;;;|}|)----0)<a::a--)!!!!!!!!!!!!!!!@r;;@;;;;;@;;}@=_0:~{4dc^/(((<;;;;[suyus[;;;;;;;[su6wvu}[;;;;;;[ntwxwtn[;;;;;rntmxfxmtbr;;;r|ok1aaa1ko|[;[r%b250:002bb[;g|44::<::<:44cg;gijj)))j)jjii;[@@*&{~({{{{{77h]!!!&&&&22h2h~@r;;@;;;;;@;;}@!!!:(_g=ii9!:jj]((_!sjjjjnnnu!!22_]2222p^!22p/((_]e''*'e]((!!!!!!{;;;;]!/(_]((_!s;;;;nnnu!!!!!!{))))]!/(_]((_!s))))nnnu!666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666666666!!!666666!{1~~{~~~k!!!!!",
+"....*=~=7#e=.......+=~=7#e=.......*=~=7{9=.......*=k~7{e=.......*1^9&^e=.......*{^&8&9=.......*{&&8^e=....=~.*8!]!]9=~#.-|h-c1----5d-ch;05000^-a004d4g.|-1--aaaaahab='**;;!;!;;}|}|=)---a-0)<----<)!!!!!!!!!!!!!!!@[;[@;;;;;@r;2@=!!!~{fff^/cic<;;;;;rnusr[;;;;;;;;ru6v6nr;;;;;;;[suvwvus[;;;;g[stmxxxmtnr[;;[}bk1a-akko}r;;rsb~000052o}r[gcd4:::::::pd|g;gijjj)))jjjig;}r@@@+(({{{{{{~@8]!]]{+@@@@@@@@[;[@;;;;;@r;2@!!!!/====;%!!jj^((]!jjjjjjqsn!!((!]222pp]!]2p/((/!et'''*!((!!!!]{;;;;;{!!(_^((]!;;;;;;qsn!!!!]{))))){!!(_^((]!))))))qsn!6666666!666666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!6666666666!6!6!66666]{{~1k~~b]!!!!!",
+".....$+~~l..........$~~~l..........$+~~l..........$+~{q..........$+~&9..........$k~&9..........$k~&q.......%&.$8]!q.#~..-45h[-----hc1ch;04-^-/---^a43[gb-o1-0j0ahbh5.*n*;;;&(;;|}|}|)<a<):---a<:<))!!!!!!!!!!!!!!!@((*@;;;;;@@2(*.;;;~{;;;^/;;;<;;;;;[rsr[;;;;;;;;;rsnunsr;;;;;;;[rnttun}[;;;;;[sotmmmtos[;;;[rbok111kobr[;[[|bb5205~bb|r;g[34::::<::43[g;giijjj)jjjiig;@[}@@@@*7{{{{1+@8]8!89@@@@@@@@@((*@;;;;;@@2(*!!!!~gg.[=;!!(((_]!!jjjjjj!sn!!((!/ppp2p^!!(((_]!9$''*'*8/(!!!!!dgb^;;|!!(_(_]!!;;;;;;!sn!!!!!djb^))j!!(_(_]!!))))))!sn!6666666666666666666666!66666666666!66!66!66666666!66!66!6666666!!66!66!!666666!!66!66!!666666!!66!66!!666666!!66!66!!666]{{~~~2k&!!!!!!",
+"......97~............e7~............97~............97~............9k7............e7k............ek~............e7~......-a[55------cc[-;35/-------adcc.bkno1)j)absbb.*cicicicicccic[))<)))0--))))))!!!!!!!!!!!!!!!@#~@@};;;r@@gd@=;;;~{;;;^/;;;<;;;;;;;[[;;;;;;;;;;;[rsrr;;;;;;;;;[}snsr[;;;;;;[rsutttosr;;;;;r}ookkkoo|r;;;[rbb~bh2bbbr[;g[dd4::::444c[;i;iijjjjjjjig;i@@}[@@@7{{{{7~@@9!]]8{@@@@@@@@@#~@@};;;r@@gd@!!!!%=.d=[.!!/(((!!!jjjjjj!((!!!!!22p(2p&!!/(((!!et'''''t((]!!!]!]&{c;;{4c(((!!!;;;;;;!((!!!!]!]&{c)){4c(((!!!))))))!((!6666666666666666666666666666666666666!6666666666!666!666!666666!!66!66!!666666!!66!66!!666666!!66!66!!666!66!!66!66!!66!]{{1~b~]!!!!!!!",
+"......e~e............e7e............eke............e7e............e~e............e~e............e{e............e1e......--[da------1;g-;g5-ah^-hahac3g.b-o1a0)4aash5.s@00000000:00r[))))):-a-:)))))!!!!!!!!!!!!!!!@@@@@@;;;}@[;;@=;;;~{;;;^/;;;<;;;;;;;;;;;;;;;;;;;;;[;[;;;;;;;;;;;[[[[[;;;;;;;;[[sbnnsr[;;;;;[r|bobob}r[;;;;[}|bbbobbr[[;;gcc4444444dcg;j;;iijjjjiiig;j@@@}[@{7{{{1~@@@8!!!&&@@@@@@@@@@@@@@;;;}@[;;@!!!!=gg8%g.{!!!!!!!!jjjjjj!(_!!!!!2p2(pp^!!!!!!!!$''''*'*(_!!!!&&2%2{gc34!!!!!!!;;;;;;!(_!!!!&&2%2{gc34!!!!!!!))))))!(_!6666666666666666666666666666666666666666666666666666!666666666!666!!!666!6666!666!!!666!666!!666!!!666!!66!!666!!!666!!6]{~~~k]!!!!!!!!",
+"......&{{............&{{............&{{............&{{............&{{............&{{............&{{............&{{......---;5------cd--;;4450/-a44dccg.b----a-aaaahh.ss54444444440=[))))0-0)<-:))))!!!!!!!!!!!!!!!@@@@@@;;;}@;;[@=;;;~{;;;^/;;;<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[[[r[[;;;;;;;;[[}|}|r[[;;;;;[[rb}b||}[;;;;;g[cd443dc[g;;ij;;giiiiii;;jg@@@@@7{{{7{77@@@9!!8&9@@@@@@@@@@@@@@;;;}@;;[@!!!{=.=!~=g=!!!!!!!!jjjjjj!!!!!!!]2p2{2p!!!!!!!!8e''''''*!!!!!!c1#|~~4c;8!!!!!!!;;;;;;!!!!!!!c1#|~~4c)8!!!!!!!))))))!!!!6666666666666666666666666666666666666666666666666666666666666666666!66666666!6666!!!6666!66!!666!!!666!!66!!666!!!666!!6]{~o2]!!!!!!!!!",
+"......&{{............&{~............&{7............&{~............&{{............&{{............&{~............&{{......----c|hhhd[d---;;c404aaa43ccg;.|5bhhhh1hhbd..%}04050505000[[)))<a:)))<-<)))!!!!!!!!!!!!!!!@@@@@@;;;@@;;;@.;;;~{;;;^/;;;<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[[[[[[;;;;;;;;[[[rrr[[[;;;;;;g[ccc|cg[;;;;ii;;ggigg;;ji;@@@@+{{7~@{{~5@@8!!!{&@@@@@@@@@@@@@@;;;@@;;;@!!!=[g{!8=g=!!!!!!!!!/_(_!!!!!!!!22p/_2p!!!!!!!!$t''''''n'!!!!!;[/#%~5;;~!!!!!!!!/_(_!!!!!!!!)j/#%~5))~!!!!!!!!/_(_!!!!!6666666666666666666666666666666666666666666666666666666666666666666!66666666666666!6666666!666666!666666!!66!666!666!66!]{~~]!!!!!!!!!!",
+"......&{7............&{{............&{{............&{{............&{7............&{7............&{{............&{~......-----5dcddh----;;;404443d3dg;;...........=.[.s}04:5:040505[[))))))))))<<)))!!!!!!!!!!!!!!!@@@@@@;;;}@;;;@==%#~{&]]^/(_:<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[;;;;;;;;;;;;;[;[;;;;;;;;;;;;gggg;;;;;;;iji;;;;;ijg;;@@@@3j4~@@@~jj3@@$9&7@@@@@@@@@@@@@@@;;;}@;;;@!!!=.=]!!==;]!!!!!!!!((((!!!!!!!!22p]/2p!!!!!!!!e'$$''$''$!!!!!;[{{1~7;;b!!!!!!!!((((!!!!!!!!)j{{1~7))b!!!!!!!!((((!!!!!6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666!6666666666666!!!666666]~o]!!!!!!!!!!!",
+"......&{{............&{{............&{~............&{{............&{{............&{{............&{{............&{{......---------------;;;c4444d3dcg;;=.[.[.[.[.....=}|040h0000000[[)))))))))))))))!!!!!!!!!!!!!!!@@@@@@;;;@@[;[@==##~{&!]^/(_:<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iij)jii;;;;@@}cjjj}r@@@pjj@@@8{@@@@@@@@@@@@@@@@;;;@@[;[@!54[g#!!!2cc~!!!!!!!!^(_/!!!!!!!dg[p]2dcb!!!!!!!!!!^((]!!!!!!54;;/{%=~4c~!!!!!!!!^(_/!!!!!!54))/{%=~4j~!!!!!!!!^(_/!!!!!6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666!6666666!!!!!!!!!!!!!!!",
+".......{..............{..............{..............7..............~..............{..............7..............{.......---------------;;;;;;;;ggg;;;;..=.....[.[.[..}r05005000500[[)))))))))))))))!!!!!!!!!!!!!!!@@@@@;;;;;@@}@@.%%#~{&]]^/(__<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@%jjjjc@}r@jjjj@@@;;;@@@@@@@@@@@@@@;;;;;@@}@@!3c3c5!!!4cc4!!!!!!!!;;;;!!!!!!];;;c!{g;d!!!!!!!!!!;;g;!!!!!!c3cc51~]4cc4!!!!!!!!;;;;!!!!!!c3cc51~]4cc4!!!!!!!!;;;;!!!!!666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666!!!!!!!!!!!!!!!"};
diff -Nur -Xfreeciv/diff_ignore freeciv.left/client/gui-gtk/citydlg.c 
freeciv/client/gui-gtk/citydlg.c
--- freeciv.left/client/gui-gtk/citydlg.c       Wed Apr 25 18:50:57 2001
+++ freeciv/client/gui-gtk/citydlg.c    Wed Apr 25 18:48:33 2001
@@ -2883,9 +2883,10 @@
   int citizen_type;
   int n1 = pcity->ppl_happy[index];
   int n2 = n1 + pcity->ppl_content[index];
-  int n3 = n2 + pcity->ppl_unhappy[index];
-  int n4 = n3 + pcity->ppl_elvis;
-  int n5 = n4 + pcity->ppl_scientist;
+  int n3 = n2 + pcity->ppl_residue[index];
+  int n4 = n3 + pcity->ppl_unhappy[index] - pcity->ppl_residue[index];
+  int n5 = n4 + pcity->ppl_elvis;
+  int n6 = n5 + pcity->ppl_scientist;
   int num_citizens = pcity->size;
   int pix_width = HAPPINESS_PIX_WIDTH*SMALL_TILE_WIDTH;
   int offset = MIN(SMALL_TILE_WIDTH, pix_width/num_citizens);
@@ -2900,10 +2901,12 @@
     else if (i<n2)
       citizen_type = 3+i%2;
     else if (i<n3)
-      citizen_type = 7+1%2;
+      citizen_type = 9+i%2;
     else if (i<n4)
-      citizen_type = 0;
+      citizen_type = 7+i%2;
     else if (i<n5)
+      citizen_type = 0;
+    else if (i<n6)
       citizen_type = 1;
     else
       citizen_type = 2;
diff -urN -Xfreeciv/diff_ignore freeciv.orig/client/gui-gtk/citydlg.c 
freeciv/client/gui-gtk/citydlg.c
--- freeciv.orig/client/gui-gtk/citydlg.c       Mon Apr  9 13:31:26 2001
+++ freeciv/client/gui-gtk/citydlg.c    Sat Apr 21 16:58:37 2001
@@ -27,6 +27,7 @@
 #include "fcintl.h"
 #include "game.h"
 #include "genlist.h"
+#include "government.h"
 #include "map.h"
 #include "mem.h"
 #include "packets.h"
@@ -93,6 +94,7 @@
   GtkWidget *present_unit_button       [2];
   GtkWidget *close_command;
   GtkWidget *rename_command; 
+  GtkWidget *happiness_command; 
   GtkWidget *trade_command; 
   GtkWidget *activate_command;
   GtkWidget *show_units_command; 
@@ -155,6 +157,7 @@
 static void worklist_callback  (GtkWidget *w, gpointer data);
 static void close_callback     (GtkWidget *w, gpointer data);
 static void rename_callback    (GtkWidget *w, gpointer data);
+static void happiness_callback (GtkWidget *w, gpointer data);
 static void trade_callback     (GtkWidget *w, gpointer data);
 static void activate_callback  (GtkWidget *w, gpointer data);
 static void show_units_callback (GtkWidget *w, gpointer data);
@@ -203,6 +206,40 @@
 static gint sell_callback_delete(GtkWidget *widget, GdkEvent *event, gpointer 
data);
 static gint rename_callback_delete(GtkWidget *widget, GdkEvent *event, 
gpointer data);
 
+/* happiness display */
+#define HAPPINESS_PIX_WIDTH 30
+
+static struct genlist happiness_list;
+static int happiness_list_has_been_initialised;
+
+struct happiness_dialog {
+  struct city *pcity;
+  GtkWidget *shell;
+  GtkWidget *cityname_label;
+  GtkWidget *happiness_pixmaps[5];
+  GtkWidget *cities_label;
+  GtkWidget *luxury_label;
+  GtkWidget *buildings_label;
+  GtkWidget *units_label;
+  GtkWidget *wonders_label;
+  GtkWidget *close;
+};
+
+static GdkPixmap *create_happiness_pixmap(struct city *pcity, int index);
+static struct happiness_dialog *get_happiness_dialog(struct city *pcity);
+static struct happiness_dialog *create_happiness_dialog(struct city *pcity);
+static void happiness_close_callback(GtkWidget *w, gpointer data);
+static void popup_happiness_dialog(struct city *pcity);
+static void refresh_happiness_dialog(struct city *pcity);
+static void close_happiness_dialog(struct happiness_dialog *pdialog);
+static void happiness_dialog_update_cities(struct happiness_dialog *pdialog);
+static void happiness_dialog_update_luxury(struct happiness_dialog *pdialog);
+static void happiness_dialog_update_buildings(struct happiness_dialog 
*pdialog);
+static void happiness_dialog_update_units(struct happiness_dialog *pdialog);
+static void happiness_dialog_update_wonders(struct happiness_dialog *pdialog);
+static gint happiness_dialog_delete_callback(GtkWidget *w, GdkEvent *ev, 
gpointer data);
+
+
 /****************************************************************
 ...
 *****************************************************************/
@@ -256,7 +293,8 @@
 void refresh_city_dialog(struct city *pcity)
 {
   struct city_dialog *pdialog;
-  
+  struct happiness_dialog *phdialog;
+ 
   if((pdialog=get_city_dialog(pcity))) {
     city_dialog_update_improvement_list(pdialog);
     city_dialog_update_title(pdialog);
@@ -280,6 +318,10 @@
                        ?TRUE:FALSE);
     gtk_widget_set_sensitive(pdialog->cityopt_command, TRUE);
   }
+  /* hitch a ride here for the happiness display */
+  if((phdialog=get_happiness_dialog(pcity))) {
+    refresh_happiness_dialog(pcity);
+  }
   if(pcity->owner == game.player_idx)  {
     city_report_dialog_update_city(pcity);
     economy_report_dialog_update();
@@ -700,6 +742,11 @@
   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pdialog->shell)->action_area),
         pdialog->rename_command, TRUE, TRUE, 0);
 
+  pdialog->happiness_command=gtk_accelbutton_new(_("_Happiness"), accel);
+  GTK_WIDGET_SET_FLAGS(pdialog->happiness_command, GTK_CAN_DEFAULT);
+  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pdialog->shell)->action_area),
+       pdialog->happiness_command, TRUE, TRUE, 0);
+
   pdialog->trade_command=gtk_accelbutton_new(_("_Trade"), accel);
   GTK_WIDGET_SET_FLAGS(pdialog->trade_command, GTK_CAN_DEFAULT);
   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pdialog->shell)->action_area),
@@ -738,6 +785,9 @@
   gtk_signal_connect(GTK_OBJECT(pdialog->rename_command), "clicked",
        GTK_SIGNAL_FUNC(rename_callback), pdialog);
 
+  gtk_signal_connect(GTK_OBJECT(pdialog->happiness_command), "clicked",
+       GTK_SIGNAL_FUNC(happiness_callback), pdialog);
+
   gtk_signal_connect(GTK_OBJECT(pdialog->trade_command), "clicked",
        GTK_SIGNAL_FUNC(trade_callback), pdialog);
 
@@ -2678,4 +2728,426 @@
     gtk_widget_destroy(cityopt_shell);
     cityopt_shell = 0;
   }
+}
+
+/**************************************************************************
+ Happiness display
+
+I ended up copying off the city dialog code.  And it's modeless!  --Jing
+**************************************************************************/
+static void happiness_callback(GtkWidget *w, gpointer data)
+{
+  struct city_dialog *pdialog = (struct city_dialog *)data;
+
+  popup_happiness_dialog(pdialog->pcity);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void popup_happiness_dialog(struct city *pcity)
+{
+  struct happiness_dialog *pdialog;
+
+  if(!(pdialog=get_happiness_dialog(pcity)))
+    pdialog = create_happiness_dialog(pcity);
+
+  gtk_widget_show(pdialog->shell);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static struct happiness_dialog *get_happiness_dialog(struct city *pcity)
+{
+  struct genlist_iterator myiter;
+
+  if(!happiness_list_has_been_initialised) {
+    genlist_init(&happiness_list);
+    happiness_list_has_been_initialised=1;
+  }
+  
+  genlist_iterator_init(&myiter, &happiness_list, 0);
+    
+  for(; ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter))
+    if(((struct happiness_dialog *)ITERATOR_PTR(myiter))->pcity==pcity)
+      return ITERATOR_PTR(myiter);
+
+  return 0;
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static struct happiness_dialog *create_happiness_dialog(struct city *pcity)
+{
+  int i;
+  struct happiness_dialog *pdialog;
+  GtkWidget *table, *labels[5];
+  GtkAccelGroup *accel=gtk_accel_group_new();
+
+  pdialog = fc_malloc(sizeof(struct happiness_dialog));
+  pdialog->pcity = pcity;
+
+  pdialog->shell = gtk_dialog_new ();
+  gtk_signal_connect(GTK_OBJECT(pdialog->shell),"delete_event",
+                    GTK_SIGNAL_FUNC(happiness_dialog_delete_callback),
+                    (gpointer)pdialog);
+  gtk_window_set_title (GTK_WINDOW (pdialog->shell), _("Happiness"));
+  gtk_window_set_position(GTK_WINDOW(pdialog->shell), GTK_WIN_POS_MOUSE);
+  gtk_accel_group_attach(accel, GTK_OBJECT(pdialog->shell));
+  gtk_widget_realize(pdialog->shell);
+
+  pdialog->cityname_label = gtk_frame_new (pcity->name);
+  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pdialog->shell)->vbox), 
+                    pdialog->cityname_label, TRUE, TRUE, 0);
+  gtk_widget_realize(pdialog->cityname_label);
+
+  gtk_container_border_width(GTK_CONTAINER(pdialog->cityname_label), 5);
+
+  table = gtk_table_new(10, 2, FALSE);
+  gtk_table_set_row_spacings(GTK_TABLE(table), 5);
+  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+  gtk_container_add(GTK_CONTAINER(pdialog->cityname_label), table);
+  gtk_container_border_width(GTK_CONTAINER(table), 5);
+  gtk_widget_realize(table);
+
+  labels[0] = gtk_label_new(_("Cities:"));
+  labels[1] = gtk_label_new(_("Luxury:"));
+  labels[2] = gtk_label_new(_("Buildings:"));
+  labels[3] = gtk_label_new(_("Units:"));
+  labels[4] = gtk_label_new(_("Wonders:"));
+
+  for (i=0 ; i<5 ; i++) {
+    pdialog->happiness_pixmaps[i] = 
gtk_pixmap_new(create_happiness_pixmap(pcity, i), 
+                                                  NULL);
+    gtk_misc_set_alignment (GTK_MISC (pdialog->happiness_pixmaps[i]), 0, 0);
+    gtk_table_attach_defaults(GTK_TABLE(table), pdialog->happiness_pixmaps[i],
+                             1, 2, 2*i, 2*i+1);
+    gtk_misc_set_alignment (GTK_MISC (labels[i]), 1, 0);
+    gtk_table_attach_defaults(GTK_TABLE(table), labels[i], 
+                             0, 1, 2*i+1, 2*i+2);
+  }
+
+  pdialog->cities_label    = gtk_label_new("");
+  pdialog->luxury_label    = gtk_label_new("");
+  pdialog->buildings_label = gtk_label_new("");
+  pdialog->units_label     = gtk_label_new("");
+  pdialog->wonders_label   = gtk_label_new("");
+  gtk_misc_set_alignment (GTK_MISC (pdialog->cities_label), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (pdialog->luxury_label), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (pdialog->buildings_label), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (pdialog->units_label), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (pdialog->wonders_label), 0, 0);
+  gtk_table_attach_defaults(GTK_TABLE(table), pdialog->cities_label, 
+                           1, 2, 1, 2);
+  gtk_table_attach_defaults(GTK_TABLE(table), pdialog->luxury_label, 
+                           1, 2, 3, 4);
+  gtk_table_attach_defaults(GTK_TABLE(table), pdialog->buildings_label, 
+                           1, 2, 5, 6);
+  gtk_table_attach_defaults(GTK_TABLE(table), pdialog->units_label, 
+                           1, 2, 7, 8);
+  gtk_table_attach_defaults(GTK_TABLE(table), pdialog->wonders_label, 
+                           1, 2, 9, 10);
+
+  pdialog->close = gtk_accelbutton_new (_("Close"), accel);
+  GTK_WIDGET_SET_FLAGS(pdialog->close, GTK_CAN_DEFAULT);
+  gtk_widget_add_accelerator(pdialog->close, "clicked", accel, GDK_Return, 0, 
0);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(pdialog->shell)->action_area),
+                     pdialog->close, TRUE, TRUE, 0);
+  gtk_signal_connect(GTK_OBJECT(pdialog->close), "clicked",
+                    GTK_SIGNAL_FUNC(happiness_close_callback), pdialog);
+ 
+  gtk_widget_show_all(GTK_DIALOG(pdialog->shell)->vbox);
+  gtk_widget_show_all(GTK_DIALOG(pdialog->shell)->action_area);
+  
+  genlist_insert(&happiness_list, pdialog, 0);
+
+  refresh_happiness_dialog(pcity);
+
+  return pdialog;
+}
+  
+/**************************************************************************
+...
+**************************************************************************/
+static GdkPixmap *create_happiness_pixmap(struct city *pcity, int index)
+{
+  int i;
+  int citizen_type;
+  int n1 = pcity->ppl_happy[index];
+  int n2 = n1 + pcity->ppl_content[index];
+  int n3 = n2 + pcity->ppl_unhappy[index];
+  int n4 = n3 + pcity->ppl_elvis;
+  int n5 = n4 + pcity->ppl_scientist;
+  int num_citizens = pcity->size;
+  int pix_width = HAPPINESS_PIX_WIDTH*SMALL_TILE_WIDTH;
+  int offset = MIN(SMALL_TILE_WIDTH, pix_width/num_citizens);
+  int true_pix_width = (num_citizens-1)*offset + SMALL_TILE_WIDTH;
+
+  GdkPixmap *happiness_pixmap = gdk_pixmap_new(root_window, true_pix_width,
+                                                   SMALL_TILE_HEIGHT, -1);
+
+  for (i=0 ; i<num_citizens; i++) {
+    if (i<n1)
+      citizen_type = 5+i%2;
+    else if (i<n2)
+      citizen_type = 3+i%2;
+    else if (i<n3)
+      citizen_type = 7+1%2;
+    else if (i<n4)
+      citizen_type = 0;
+    else if (i<n5)
+      citizen_type = 1;
+    else
+      citizen_type = 2;
+
+    gdk_draw_pixmap(happiness_pixmap, civ_gc, 
+                   sprites.citizen[citizen_type]->pixmap,
+                   0, 0, i*offset, 0, SMALL_TILE_WIDTH, SMALL_TILE_HEIGHT);
+
+  }
+
+  return happiness_pixmap;
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void happiness_close_callback(GtkWidget *w, gpointer data)
+{
+  close_happiness_dialog((struct happiness_dialog *)data);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void refresh_happiness_dialog(struct city *pcity)
+{
+  int i;
+
+  struct happiness_dialog *pdialog = get_happiness_dialog(pcity);
+
+  for (i=0 ; i<5 ; i++) {
+    gtk_pixmap_set(GTK_PIXMAP(pdialog->happiness_pixmaps[i]), 
+                  create_happiness_pixmap(pdialog->pcity, i),
+                  NULL);
+  }
+
+  happiness_dialog_update_cities(pdialog);
+  happiness_dialog_update_luxury(pdialog);
+  happiness_dialog_update_buildings(pdialog);
+  happiness_dialog_update_units(pdialog);
+  happiness_dialog_update_wonders(pdialog);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void close_happiness_dialog(struct happiness_dialog *pdialog)
+{
+  gtk_widget_hide(pdialog->shell);
+  genlist_unlink(&happiness_list, pdialog);
+
+  gtk_widget_destroy(pdialog->shell);
+  free(pdialog);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void happiness_dialog_update_cities(struct happiness_dialog *pdialog)
+{
+  char buf[512], *bptr=buf;
+  int nleft = sizeof(buf);
+  
+  struct city *pcity = pdialog->pcity;
+  struct player *pplayer = &game.players[pcity->owner];
+  struct government *g = get_gov_pcity(pcity);
+  int cities = city_list_size(&pplayer->cities);
+  int content = game.unhappysize;
+  int basis = game.cityfactor + g->empire_size_mod;
+  int step = g->empire_size_inc;
+  int excess = cities - basis;
+  int penalty = 0;
+
+  if (excess>0) {
+    if (step>0)
+      penalty = 1 + (excess-1)/step;
+    else
+      penalty = 1;
+  } 
+  else {
+    excess = 0;
+    penalty = 0;
+  }
+
+  my_snprintf(bptr, nleft, _("%d total, %d over threshold of %d cities. "), 
+             cities, excess, basis);
+  bptr = end_of_strn(bptr, &nleft);
+
+  my_snprintf(bptr, nleft, _("%d content before penalty with "), content);
+  bptr = end_of_strn(bptr, &nleft);
+  my_snprintf(bptr, nleft, _("%d additional unhappy citizens."), penalty);
+  bptr = end_of_strn(bptr, &nleft);
+
+  gtk_set_label(pdialog->cities_label, buf);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void happiness_dialog_update_luxury(struct happiness_dialog *pdialog)
+{
+  char buf[512], *bptr=buf;
+  int nleft = sizeof(buf);
+  struct city *pcity=pdialog->pcity;
+
+  my_snprintf(bptr, nleft, _("%d total (maximum %d usable). "), 
+             pcity->luxury_total, 2*pcity->size);
+
+  gtk_set_label(pdialog->luxury_label, buf);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void happiness_dialog_update_buildings(struct happiness_dialog *pdialog)
+{
+  int faces=0;
+  char buf[512], *bptr=buf;
+  int nleft = sizeof(buf);
+  struct city *pcity=pdialog->pcity;
+  struct government *g = get_gov_pcity(pcity);
+
+  if (city_got_building(pcity, B_TEMPLE)) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_TEMPLE)); 
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+  if (city_got_building(pcity, B_COURTHOUSE) &&
+      g->corruption_level == 0) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_COURTHOUSE));
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+  if (city_got_building(pcity, B_COLOSSEUM)) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_COLOSSEUM));
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+  if (city_got_effect(pcity, B_CATHEDRAL)) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_CATHEDRAL));
+    bptr = end_of_strn(bptr, &nleft);
+    if (!city_got_building(pcity, B_CATHEDRAL)) {
+      my_snprintf(bptr, nleft, ("(")); 
+      bptr = end_of_strn(bptr, &nleft);
+      my_snprintf(bptr, nleft, get_improvement_name(B_MICHELANGELO));
+      bptr = end_of_strn(bptr, &nleft);
+      my_snprintf(bptr, nleft, (")")); 
+      bptr = end_of_strn(bptr, &nleft);
+    }
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+
+  if (faces==0) {
+    my_snprintf(bptr, nleft, _("None. ")); 
+  }
+
+  gtk_set_label(pdialog->buildings_label, buf);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void happiness_dialog_update_units(struct happiness_dialog *pdialog)
+{
+  char buf[512], *bptr=buf;
+  int nleft = sizeof(buf);
+  struct city *pcity=pdialog->pcity;
+  struct government *g = get_gov_pcity(pcity);
+  int mlmax = g->martial_law_max;
+
+  if (mlmax > 0) {
+    my_snprintf(bptr, nleft, _("Martial law in effect ("));
+    bptr = end_of_strn(bptr, &nleft);
+
+    if (mlmax == 100 )
+      my_snprintf(bptr, nleft, _("no maximum, "));
+    else
+      my_snprintf(bptr, nleft, _("%d units maximum, "), mlmax);
+    bptr = end_of_strn(bptr, &nleft);
+
+    my_snprintf(bptr, nleft, _("%d per unit). "), g->martial_law_per);
+  }
+  else {
+    my_snprintf(bptr, nleft, 
+               _("Military units in the field may cause unhappiness. "));
+  }
+  
+  gtk_set_label(pdialog->units_label, buf);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void happiness_dialog_update_wonders(struct happiness_dialog *pdialog)
+{
+  int faces=0;
+  char buf[512], *bptr=buf;
+  int nleft = sizeof(buf);
+  struct city *pcity=pdialog->pcity;
+
+  if (city_affected_by_wonder(pcity, B_HANGING)) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_HANGING));
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+  if (city_affected_by_wonder(pcity, B_SHAKESPEARE)) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_SHAKESPEARE));
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+  if (city_affected_by_wonder(pcity, B_BACH))  {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_BACH));
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+  if (city_affected_by_wonder(pcity, B_CURE)) {
+    faces++;
+    my_snprintf(bptr, nleft, get_improvement_name(B_CURE));
+    bptr = end_of_strn(bptr, &nleft);
+    my_snprintf(bptr, nleft, (". ")); 
+    bptr = end_of_strn(bptr, &nleft);
+  }
+
+  if (faces==0) {
+    my_snprintf(bptr, nleft, _("None. ")); 
+  }
+
+  gtk_set_label(pdialog->wonders_label, buf);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static gint happiness_dialog_delete_callback(GtkWidget *w, GdkEvent *ev,
+                                            gpointer data)
+{
+  close_happiness_dialog((struct happiness_dialog *)data);
+  return FALSE;
 }
diff -urN -Xfreeciv/diff_ignore freeciv.happy/client/civclient.c 
freeciv/client/civclient.c
--- freeciv.happy/client/civclient.c    Sat Apr 21 16:58:21 2001
+++ freeciv/client/civclient.c  Sat Apr 21 17:02:53 2001
@@ -490,6 +490,7 @@
     }
     else if(client_state==CLIENT_PRE_GAME_STATE) {
       popdown_all_city_dialogs();
+      popdown_all_happiness_dialogs();
       close_all_diplomacy_dialogs();
       client_remove_all_cli_conn();
       game_remove_all_players();
diff -urN -Xfreeciv/diff_ignore freeciv.happy/client/climisc.c 
freeciv/client/climisc.c
--- freeciv.happy/client/climisc.c      Sat Apr 21 16:58:21 2001
+++ freeciv/client/climisc.c    Sat Apr 21 17:02:53 2001
@@ -124,6 +124,7 @@
   freelog(LOG_DEBUG, "removing city %s, %s, (%d %d)", pcity->name,
          get_nation_name(city_owner(pcity)->nation), x, y);
   popdown_city_dialog(pcity);
+  popdown_happiness_dialog(pcity);
   game_remove_city(pcity);
   city_report_dialog_update();
   refresh_tile_mapcanvas(x, y, 1);
diff -urN -Xfreeciv/diff_ignore freeciv.happy/client/gui-gtk/citydlg.c 
freeciv/client/gui-gtk/citydlg.c
--- freeciv.happy/client/gui-gtk/citydlg.c      Sat Apr 21 16:58:37 2001
+++ freeciv/client/gui-gtk/citydlg.c    Sat Apr 21 17:02:53 2001
@@ -229,7 +229,6 @@
 static struct happiness_dialog *get_happiness_dialog(struct city *pcity);
 static struct happiness_dialog *create_happiness_dialog(struct city *pcity);
 static void happiness_close_callback(GtkWidget *w, gpointer data);
-static void popup_happiness_dialog(struct city *pcity);
 static void refresh_happiness_dialog(struct city *pcity);
 static void close_happiness_dialog(struct happiness_dialog *pdialog);
 static void happiness_dialog_update_cities(struct happiness_dialog *pdialog);
@@ -2745,19 +2744,6 @@
 /****************************************************************
 ...
 *****************************************************************/
-static void popup_happiness_dialog(struct city *pcity)
-{
-  struct happiness_dialog *pdialog;
-
-  if(!(pdialog=get_happiness_dialog(pcity)))
-    pdialog = create_happiness_dialog(pcity);
-
-  gtk_widget_show(pdialog->shell);
-}
-
-/****************************************************************
-...
-*****************************************************************/
 static struct happiness_dialog *get_happiness_dialog(struct city *pcity)
 {
   struct genlist_iterator myiter;
@@ -3151,3 +3137,41 @@
   close_happiness_dialog((struct happiness_dialog *)data);
   return FALSE;
 }
+
+/****************************************************************
+popup the dialog 
+*****************************************************************/
+void popup_happiness_dialog(struct city *pcity)
+{
+  struct happiness_dialog *pdialog;
+  
+  if(!(pdialog=get_happiness_dialog(pcity)))
+    pdialog=create_happiness_dialog(pcity);
+
+  gtk_widget_show(pdialog->shell);
+}
+
+/****************************************************************
+popdown the dialog 
+*****************************************************************/
+void popdown_happiness_dialog(struct city *pcity)
+{
+  struct happiness_dialog *pdialog;
+  
+  if((pdialog=get_happiness_dialog(pcity)))
+    close_happiness_dialog(pdialog);
+}
+
+/****************************************************************
+popdown all dialogs
+*****************************************************************/
+void popdown_all_happiness_dialogs(void)
+{
+  if(!happiness_list_has_been_initialised) {
+    return;
+  }
+  while(genlist_size(&happiness_list)) {
+    close_happiness_dialog(genlist_get(&happiness_list,0));
+  }
+}
+
diff -urN -Xfreeciv/diff_ignore freeciv.happy/client/gui-gtk/cityrep.c 
freeciv/client/gui-gtk/cityrep.c
--- freeciv.happy/client/gui-gtk/cityrep.c      Sat Apr 21 16:58:21 2001
+++ freeciv/client/gui-gtk/cityrep.c    Sat Apr 21 17:02:53 2001
@@ -60,6 +60,7 @@
 static void city_close_callback(GtkWidget *widget, gpointer data);
 static void city_center_callback(GtkWidget *widget, gpointer data);
 static void city_popup_callback(GtkWidget *widget, gpointer data);
+static void city_happiness_callback(GtkWidget *widget, gpointer data);
 static void city_buy_callback(GtkWidget *widget, gpointer data);
 static void city_refresh_callback(GtkWidget *widget, gpointer data);
 static void city_change_all_dialog_callback(GtkWidget *w, gpointer data);
@@ -73,8 +74,12 @@
 static GtkWidget *city_dialog_shell=NULL;
 static GtkWidget *city_label;
 static GtkWidget *city_list;
-static GtkWidget *city_center_command, *city_popup_command, *city_buy_command,
-  *city_refresh_command, *city_config_command;
+static GtkWidget *city_center_command; 
+static GtkWidget *city_popup_command; 
+static GtkWidget *city_happiness_command; 
+static GtkWidget *city_buy_command;
+static GtkWidget *city_refresh_command; 
+static GtkWidget *city_config_command;
 static GtkWidget *city_change_command;
 static GtkWidget *city_change_all_command;
 static GtkWidget *city_change_all_dialog_shell;
@@ -423,6 +428,7 @@
   static char  buf     [NUM_CREPORT_COLS][64];
 
   GtkWidget *close_command, *scrolled;
+  GtkWidget *hbox1, *hbox2, *vbox;
   char      *report_title;
   int        i;
   GtkAccelGroup *accel=gtk_accel_group_new();
@@ -464,64 +470,72 @@
   for (i=0;i<NUM_CREPORT_COLS;i++)
     gtk_clist_set_column_auto_resize (GTK_CLIST (city_list), i, TRUE);
 
-  close_command                = gtk_accelbutton_new(_("C_lose"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        close_command, TRUE, TRUE, 0 );
-  GTK_WIDGET_SET_FLAGS( close_command, GTK_CAN_DEFAULT );
-  gtk_widget_grab_default( close_command );
+  hbox1 = gtk_hbox_new (TRUE, 10);
 
   city_center_command  = gtk_accelbutton_new(_("Cen_ter"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_center_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox1), city_center_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_center_command, GTK_CAN_DEFAULT );
 
   city_popup_command   = gtk_accelbutton_new(_("_Popup"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_popup_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox1), city_popup_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_popup_command, GTK_CAN_DEFAULT );
 
+  city_happiness_command = gtk_accelbutton_new(_("_Happiness"), accel);
+  gtk_box_pack_start( GTK_BOX(hbox1), city_happiness_command, TRUE, TRUE, 0 );
+  GTK_WIDGET_SET_FLAGS( city_happiness_command, GTK_CAN_DEFAULT );
+
   city_buy_command     = gtk_accelbutton_new(_("_Buy"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_buy_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox1), city_buy_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_buy_command, GTK_CAN_DEFAULT );
 
   city_change_command  = gtk_accelbutton_new(_("_Change"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_change_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox1), city_change_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_change_command, GTK_CAN_DEFAULT );
 
   gtk_signal_connect( GTK_OBJECT( city_change_command ), "event",
        GTK_SIGNAL_FUNC( city_change_callback ), NULL );
 
-  city_change_all_command = gtk_accelbutton_new(_("Change _All"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_change_all_command, TRUE, TRUE, 0 );
-  GTK_WIDGET_SET_FLAGS( city_change_all_command, GTK_CAN_DEFAULT );
+  hbox2 = gtk_hbox_new (TRUE, 10);
+
+  close_command                = gtk_accelbutton_new(_("C_lose"), accel);
+  gtk_box_pack_start( GTK_BOX(hbox2), close_command, TRUE, TRUE, 0 );
+  GTK_WIDGET_SET_FLAGS( close_command, GTK_CAN_DEFAULT );
+  gtk_widget_grab_default( close_command );
 
   city_refresh_command = gtk_accelbutton_new(_("_Refresh"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_refresh_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox2), city_refresh_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_refresh_command, GTK_CAN_DEFAULT );
   
   city_select_command  = gtk_accelbutton_new(_("_Select"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_select_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox2), city_select_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_select_command, GTK_CAN_DEFAULT );
 
   gtk_signal_connect(GTK_OBJECT(city_select_command), "event",
        GTK_SIGNAL_FUNC(city_select_callback), NULL);
 
   city_config_command  = gtk_accelbutton_new(_("Con_figure"), accel);
-  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
-        city_config_command, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(hbox2), city_config_command, TRUE, TRUE, 0 );
   GTK_WIDGET_SET_FLAGS( city_config_command, GTK_CAN_DEFAULT );
 
+  city_change_all_command = gtk_accelbutton_new(_("Change _All"), accel);
+  gtk_box_pack_start( GTK_BOX(hbox2), city_change_all_command, TRUE, TRUE, 0 );
+  GTK_WIDGET_SET_FLAGS( city_change_all_command, GTK_CAN_DEFAULT );
+
+  vbox = gtk_vbox_new (TRUE, 5);
+
+  gtk_box_pack_start( GTK_BOX(vbox), hbox1, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX(vbox), hbox2, TRUE, TRUE, 0 );
+  gtk_box_pack_start( GTK_BOX( GTK_DIALOG(city_dialog_shell)->action_area ),
+                     vbox, TRUE, TRUE, 0 );
+
   gtk_signal_connect(GTK_OBJECT(close_command), "clicked",
        GTK_SIGNAL_FUNC(city_close_callback), NULL);
   gtk_signal_connect(GTK_OBJECT(city_center_command), "clicked",
        GTK_SIGNAL_FUNC(city_center_callback), NULL);
   gtk_signal_connect(GTK_OBJECT(city_popup_command), "clicked",
        GTK_SIGNAL_FUNC(city_popup_callback), NULL);
+  gtk_signal_connect(GTK_OBJECT(city_happiness_command), "clicked",
+       GTK_SIGNAL_FUNC(city_happiness_callback), NULL);
   gtk_signal_connect(GTK_OBJECT(city_buy_command), "clicked",
        GTK_SIGNAL_FUNC(city_buy_callback), NULL);
   gtk_signal_connect(GTK_OBJECT(city_refresh_command), "clicked",
@@ -558,6 +572,7 @@
     gtk_widget_set_sensitive(city_change_command, TRUE);
     gtk_widget_set_sensitive(city_center_command, TRUE);
     gtk_widget_set_sensitive(city_popup_command, TRUE);
+    gtk_widget_set_sensitive(city_happiness_command, TRUE);
     gtk_widget_set_sensitive(city_buy_command, TRUE);
   }
   else
@@ -565,6 +580,7 @@
     gtk_widget_set_sensitive(city_change_command, FALSE);
     gtk_widget_set_sensitive(city_center_command, FALSE);
     gtk_widget_set_sensitive(city_popup_command, FALSE);
+    gtk_widget_set_sensitive(city_happiness_command, FALSE);
     gtk_widget_set_sensitive(city_buy_command, FALSE);
   }
 }
@@ -1120,6 +1136,33 @@
   
   for(; copy; copy = g_list_next(copy))
     popup_city_dialog(copy->data, 0);
+
+  g_list_free(copy);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void city_happiness_callback(GtkWidget *w, gpointer data)
+{
+  GList *current = GTK_CLIST(city_list)->selection;
+  GList *copy = NULL;
+  struct city        *pcity;
+
+  if (!current)
+    return;
+
+  pcity = city_from_glist (current);
+  if (center_when_popup_city) {
+    center_tile_mapcanvas(pcity->x, pcity->y);
+  }
+
+  /* I copied all this from city_popup_callback() above */
+  for(; current; current = g_list_next(current))
+    copy = g_list_append (copy, city_from_glist(current));
+  
+  for(; copy; copy = g_list_next(copy))
+    popup_happiness_dialog(copy->data);
 
   g_list_free(copy);
 }
diff -urN -Xfreeciv/diff_ignore freeciv.happy/client/include/citydlg_g.h 
freeciv/client/include/citydlg_g.h
--- freeciv.happy/client/include/citydlg_g.h    Sat Apr 21 16:58:21 2001
+++ freeciv/client/include/citydlg_g.h  Sat Apr 21 17:02:53 2001
@@ -22,5 +22,8 @@
 void refresh_city_dialog(struct city *pcity);
 void refresh_unit_city_dialogs(struct unit *punit);
 
+void popup_happiness_dialog(struct city *pcity);
+void popdown_happiness_dialog(struct city *pcity);
+void popdown_all_happiness_dialogs(void);
 #endif  /* FC__CITYDLG_G_H */
 
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/cityturn.c 
freeciv/server/cityturn.c
--- freeciv.orig/server/cityturn.c      Sat Apr 14 13:34:17 2001
+++ freeciv/server/cityturn.c   Sat Apr 21 16:47:48 2001
@@ -177,7 +177,9 @@
 **************************************************************************/
 static void citizen_happy_luxury(struct city *pcity)
 {
-  int x=pcity->luxury_total;
+  /* luxury above 2*citysize has no effect, as in Civ2 -- Jing */
+  int x=MIN(pcity->luxury_total, 2*pcity->size);
+
   happy_copy(pcity, 0);
   /* make people happy, content are made happy first, then unhappy content,
      etc.  each conversions costs 2 luxuries. */
diff -urN -Xfreeciv.orig/diff_ignore freeciv.orig/server/cityturn.c 
freeciv/server/cityturn.c
--- freeciv.orig/server/cityturn.c      Sat Apr 14 13:34:17 2001
+++ freeciv/server/cityturn.c   Sat Apr 21 16:33:47 2001
@@ -163,12 +163,12 @@
 **************************************************************************/
 static void citizen_happy_size(struct city *pcity)
 {
-  int workers, tmp;
+  int specialists, tmp;
 
-  workers = pcity->size - city_specialists(pcity);
+  specialists = city_specialists(pcity);
   tmp = content_citizens(&game.players[pcity->owner]);
-  pcity->ppl_content[0] = MAX(0, MIN(workers, tmp));
-  pcity->ppl_unhappy[0] = workers - pcity->ppl_content[0];
+  pcity->ppl_content[0] = MAX(0, MIN(pcity->size, tmp) - specialists);
+  pcity->ppl_unhappy[0] = pcity->size - specialists - pcity->ppl_content[0];
   pcity->ppl_happy[0] = 0; /* no one is born happy */
 }
 
diff -urN -Xfreeciv.orig/diff_ignore freeciv.orig/server/report.c 
freeciv/server/report.c
--- freeciv.orig/server/report.c        Thu Oct 12 13:36:09 2000
+++ freeciv/server/report.c     Sat Apr 21 16:42:14 2001
@@ -213,7 +213,6 @@
   }
   for (i=0;i<game.num_impr_types;i++) {
     if (is_wonder(i)) {
-      if (!game.global_wonders[i]) {
        players_iterate(pplayer) {
          city_list_iterate(pplayer->cities, pcity2) {
            if (pcity2->currently_building == i && !pcity2->is_building_unit) {
@@ -224,7 +223,6 @@
            }
          } city_list_iterate_end;
        } players_iterate_end;
-      }
     }
   }
   page_conn(dest, _("Traveler's Report:"),
diff -urN -Xfreeciv/diff_ignore freeciv.orig/ai/aihand.c freeciv/ai/aihand.c
--- freeciv.orig/ai/aihand.c    Wed Apr 11 13:33:20 2001
+++ freeciv/ai/aihand.c Sat Apr 21 18:42:20 2001
@@ -477,17 +477,6 @@
 }
 #endif /* NEW_GOV_EVAL */
 
-/**************************************************************************
- Main AI routine.
-**************************************************************************/
-void ai_do_first_activities(struct player *pplayer)
-{
-#ifdef UNUSED
-  ai_before_work(pplayer); 
-#endif
-  ai_manage_units(pplayer); /* STOP.  Everything else is at end of turn. */
-}
-
 void ai_do_last_activities(struct player *pplayer)
 {
 /*  ai_manage_units(pplayer);  very useful to include this! -- Syela */
diff -urN -Xfreeciv/diff_ignore freeciv.orig/ai/aihand.h freeciv/ai/aihand.h
--- freeciv.orig/ai/aihand.h    Tue Jan 23 13:45:03 2001
+++ freeciv/ai/aihand.h Sat Apr 21 18:42:20 2001
@@ -15,7 +15,6 @@
 
 struct player;
 
-void ai_do_first_activities(struct player *pplayer);
 void ai_do_last_activities(struct player *pplayer);
 
 int is_unit_choice_type(enum choice_type type);
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/autoattack.c 
freeciv/server/autoattack.c
--- freeciv.orig/server/autoattack.c    Tue Jan  9 13:40:19 2001
+++ freeciv/server/autoattack.c Sat Apr 21 18:42:20 2001
@@ -212,7 +212,7 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static void auto_attack_player(struct player *pplayer)
+void auto_attack_player(struct player *pplayer)
 {
   freelog(LOG_DEBUG, "doing auto_attack for: %s",pplayer->name);
 
@@ -240,24 +240,4 @@
     }
   }
   unit_list_iterate_end;
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void auto_attack(void)
-{
-  static struct timer *t = NULL;      /* alloc once, never free */
-  int i;
-
-  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
-
-  /* re-use shuffle order from civserver.c */
-  for (i = 0; i < game.nplayers; i++) {
-    auto_attack_player(shuffled_player(i));
-  }
-  if (timer_in_use(t)) {
-    freelog(LOG_VERBOSE, "autoattack consumed %g milliseconds.",
-           1000.0*read_timer_seconds(t));
-  }
 }
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/autoattack.h 
freeciv/server/autoattack.h
--- freeciv.orig/server/autoattack.h    Mon Jul 12 12:48:19 1999
+++ freeciv/server/autoattack.h Sat Apr 21 18:42:20 2001
@@ -13,6 +13,6 @@
 #ifndef FC__AUTOATTACK_H
 #define FC__AUTOATTACK_H
 
-void auto_attack(void);
+void auto_attack_player(struct player *pplayer);
 
 #endif  /* FC__AUTOATTACK_H */
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/plrhand.c 
freeciv/server/plrhand.c
--- freeciv.orig/server/plrhand.c       Sat Apr 14 13:34:18 2001
+++ freeciv/server/plrhand.c    Sat Apr 21 18:42:20 2001
@@ -161,19 +161,17 @@
 void update_player_activities(struct player *pplayer) 
 {
   if (pplayer->ai.control) {
-    ai_do_last_activities(pplayer); /* why was this AFTER aliveness? */
+    /* note: this should not move any units. */
+    ai_do_last_activities(pplayer);
   }
   great_library(pplayer);
   update_revolution(pplayer);
-  player_restore_units(pplayer); /*note: restoring move point moved
-                                  to update_unit_activities*/
   update_city_activities(pplayer);
 #ifdef CITIES_PROVIDE_RESEARCH
   if (city_list_size(&pplayer->cities)) /* has to be below the above for 
got_tech */ 
     update_tech(pplayer, city_list_size(&pplayer->cities));
 #endif
   pplayer->research.changed_from=-1;
-  update_unit_activities(pplayer);
   update_player_aliveness(pplayer);
 }
 
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/sanitycheck.c 
freeciv/server/sanitycheck.c
--- freeciv.orig/server/sanitycheck.c   Sat Apr 14 13:34:18 2001
+++ freeciv/server/sanitycheck.c        Sat Apr 21 18:42:20 2001
@@ -184,6 +184,7 @@
   } players_iterate_end;
 }
 
+#include <stdio.h>
 /**************************************************************************
 ...
 **************************************************************************/
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/settlers.c 
freeciv/server/settlers.c
--- freeciv.orig/server/settlers.c      Wed Feb 14 13:43:33 2001
+++ freeciv/server/settlers.c   Sat Apr 21 18:42:20 2001
@@ -44,7 +44,6 @@
 static int city_desirability(struct player *pplayer, int x, int y);
 
 static int auto_settler_findwork(struct player *pplayer, struct unit *punit); 
-static void auto_settlers_player(struct player *pplayer); 
 
 static int is_already_assigned(struct unit *myunit, struct player *pplayer, 
                               int x, int y);
@@ -1336,44 +1335,6 @@
   }
 }
 
-/************************************************************************** 
-  run through all the players settlers and let those on ai.control work 
-  automagically
-**************************************************************************/
-static void auto_settlers_player(struct player *pplayer) 
-{
-  static struct timer *t = NULL;      /* alloc once, never free */
-
-  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
-
-  city_list_iterate(pplayer->cities, pcity)
-    initialize_infrastructure_cache(pcity); /* saves oodles of time -- Syela */
-  city_list_iterate_end;
-  pplayer->ai.warmth = WARMING_FACTOR * total_player_citizens(pplayer) * 10 *
-                       (game.globalwarming + game.heating) / (map.xsize *
-                        map.ysize * map.landpercent * 2); /* threat of warming 
*/
-  freelog(LOG_DEBUG, "Warmth = %d, game.globalwarming=%d",
-         pplayer->ai.warmth, game.globalwarming);
-  unit_list_iterate(pplayer->units, punit) {
-    if (punit->ai.control && unit_flag(punit->type, F_SETTLERS)) {
-      freelog(LOG_DEBUG, "%s's settler at (%d, %d) is ai controlled.",
-             pplayer->name, punit->x, punit->y); 
-      if(punit->activity == ACTIVITY_SENTRY)
-       set_unit_activity(punit, ACTIVITY_IDLE);
-      if (punit->activity == ACTIVITY_GOTO && punit->moves_left)
-        set_unit_activity(punit, ACTIVITY_IDLE);
-      if (punit->activity == ACTIVITY_IDLE)
-       auto_settler_findwork(pplayer, punit);
-      freelog(LOG_DEBUG, "Has been processed.");
-    }
-  }
-  unit_list_iterate_end;
-  if (timer_in_use(t)) {
-    freelog(LOG_VERBOSE, "%s's autosettlers consumed %g milliseconds.",
-           pplayer->name, 1000.0*read_timer_seconds(t));
-  }
-}
-
 static void assign_settlers_player(struct player *pplayer)
 {
   int i = 1<<pplayer->player_no;
@@ -1466,19 +1427,6 @@
    */
 }  
 
-/**************************************************************************
-  Do the auto_settler stuff for all the players. 
-**************************************************************************/
-void auto_settlers(void)
-{
-  int i;
-  assign_settlers();
-  assign_territory();
-  for (i = 0; i < game.nplayers; i++) {
-    auto_settlers_player(shuffled_player(i));
-  }
-}
-
 void contemplate_settling(struct player *pplayer, struct city *pcity)
 {
   struct unit virtualunit;
@@ -1539,4 +1487,45 @@
   }
 
   return 0;
+}
+
+/************************************************************************** 
+  run through all the player's settlers and let those on ai.control work 
+  automagically
+**************************************************************************/
+void auto_settlers_player(struct player *pplayer) 
+{
+  static struct timer *t = NULL;      /* alloc once, never free */
+
+  assign_settlers();
+  assign_territory();
+
+  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
+
+  city_list_iterate(pplayer->cities, pcity)
+    initialize_infrastructure_cache(pcity); /* saves oodles of time -- Syela */
+  city_list_iterate_end;
+  pplayer->ai.warmth = WARMING_FACTOR * total_player_citizens(pplayer) * 10 *
+                       (game.globalwarming + game.heating) / (map.xsize *
+                        map.ysize * map.landpercent * 2); /* threat of warming 
*/
+  freelog(LOG_DEBUG, "Warmth = %d, game.globalwarming=%d",
+         pplayer->ai.warmth, game.globalwarming);
+  unit_list_iterate(pplayer->units, punit) {
+    if (punit->ai.control && unit_flag(punit->type, F_SETTLERS)) {
+      freelog(LOG_DEBUG, "%s's settler at (%d, %d) is ai controlled.",
+             pplayer->name, punit->x, punit->y); 
+      if(punit->activity == ACTIVITY_SENTRY)
+       set_unit_activity(punit, ACTIVITY_IDLE);
+      if (punit->activity == ACTIVITY_GOTO && punit->moves_left)
+        set_unit_activity(punit, ACTIVITY_IDLE);
+      if (punit->activity == ACTIVITY_IDLE)
+       auto_settler_findwork(pplayer, punit);
+      freelog(LOG_DEBUG, "Has been processed.");
+    }
+  }
+  unit_list_iterate_end;
+  if (timer_in_use(t)) {
+    freelog(LOG_VERBOSE, "%s's autosettlers consumed %g milliseconds.",
+           pplayer->name, 1000.0*read_timer_seconds(t));
+  }
 }
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/settlers.h 
freeciv/server/settlers.h
--- freeciv.orig/server/settlers.h      Mon Jan 15 13:42:49 2001
+++ freeciv/server/settlers.h   Sat Apr 21 18:42:20 2001
@@ -19,7 +19,7 @@
 
 int auto_settler_do_goto(struct player *pplayer, struct unit *punit, 
                         int x, int y);
-void auto_settlers(void);
+void auto_settlers_player(struct player *pplayer); 
 int find_boat(struct player *pplayer, int *x, int *y, int cap);
 
 #define MORT 24
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/srv_main.c 
freeciv/server/srv_main.c
--- freeciv.orig/server/srv_main.c      Fri Apr  6 13:33:38 2001
+++ freeciv/server/srv_main.c   Sat Apr 21 18:42:20 2001
@@ -73,6 +73,7 @@
 #include "diplhand.h"
 #include "gamehand.h"
 #include "gamelog.h"
+#include "gotohand.h"
 #include "handchat.h"
 #include "mapgen.h"
 #include "maphand.h"
@@ -91,15 +92,15 @@
 
 #include "advmilitary.h"
 #include "aihand.h"
+#include "aiunit.h"
 
 #include "srv_main.h"
 
 
 static void begin_turn(void);
 static void before_end_year(void);
-static int end_turn(void);
+static void end_turn_update_game(void);
 static void send_all_info(struct conn_list *dest);
-static void ai_start_turn(void);
 static int is_game_over(void);
 static void save_game_auto(void);
 static void generate_ai_players(void);
@@ -185,11 +186,207 @@
 /**************************************************************************
 ...
 **************************************************************************/
+static void move_automated_units(struct player *pplayer)
+{
+  int *units;
+  int i, num_units;
+
+  auto_settlers_player(pplayer);
+
+  if (pplayer->ai.control) {
+    ai_manage_units(pplayer);
+  }
+
+  auto_attack_player(pplayer);
+
+  /* units can die in various functions, and take units they are
+     carrying with them. So we cannot count on the unit list
+     structure to be valid, therefor this. */
+  num_units = unit_list_size(&pplayer->units);
+  units = fc_malloc(sizeof(int) * num_units);
+  i = 0;
+  unit_list_iterate(pplayer->units, punit) {  
+    units[i++] = punit->id;
+  } unit_list_iterate_end;
+
+  for (i=0; i<num_units; i++) {
+    int activity, id;
+    struct unit *punit = player_find_unit_by_id(pplayer, units[i]);
+    if (!punit)
+      continue;
+    activity = punit->activity;
+    id = punit->id;
+
+    if (punit->connecting && !can_unit_do_activity(punit, activity)) {
+      punit->activity_count = 0;
+      do_unit_goto(punit, get_activity_move_restriction(activity), 0);
+      continue;
+    }
+
+    if (activity == ACTIVITY_EXPLORE) {
+      int more_to_explore = ai_manage_explorer(punit);
+      if (more_to_explore && player_find_unit_by_id(pplayer, id))
+       handle_unit_activity_request(punit, ACTIVITY_EXPLORE);
+      continue;
+    }
+
+    if (activity==ACTIVITY_GOTO) {
+      if (!punit->ai.control
+         && (!is_military_unit(punit)
+             || punit->ai.passenger
+             || !pplayer->ai.control)) {
+       /* autosettlers otherwise waste time; idling them breaks assignment */
+       /* Stalling infantry on GOTO so I can see where they're GOing TO. -- 
Syela */
+       do_unit_goto(punit, GOTO_MOVE_ANY, 1);
+      }
+      continue;
+    }
+
+    if (punit->activity == ACTIVITY_PATROL) {
+      goto_route_execute(punit);
+      continue;
+    }
+  }
+
+  free(units);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void server_main_loop(void)
+{
+  struct timer *eot_timer;     /* time server processing at end-of-turn */
+  int is_first_loop = 1;
+  int save_counter = 0;
+  int i;
+
+  /* When to start this timer the first time round is a bit arbitrary:
+     here start straight after stop sniffing for select_races and
+     before all following server initialization etc.
+  */
+  eot_timer = new_timer_start(TIMER_CPU, TIMER_ACTIVE);
+
+  while(server_state==RUN_GAME_STATE) {
+    /* absolute beginning of a turn */
+    freelog(LOG_DEBUG, "Begin turn");
+    begin_turn();
+
+#if (IS_DEVEL_VERSION || IS_BETA_VERSION)
+    sanity_check();
+#endif
+
+    force_end_of_sniff=0;
+
+    freelog(LOG_DEBUG, "Shuffleplayers");
+    shuffle_players();
+
+    /* Before sniff (human player activites), report time to now: */
+    if (!is_first_loop) {
+      freelog(LOG_VERBOSE, "End/start-turn server/ai activities: %g seconds",
+             read_timer_seconds(eot_timer));
+    }
+
+    /* Do auto-saves just before starting sniff_packets(), so that
+     * autosave happens effectively "at the same time" as manual
+     * saves, from the point of view of restarting and AI players.
+     * Post-increment so we don't count the first loop.
+     */
+    if(save_counter >= game.save_nturns && game.save_nturns>0) {
+      save_counter=0;
+      save_game_auto();
+    }
+    save_counter++;
+
+    /* First everybody gets to finish their production, fx their defence unit. 
*/
+    if (!is_first_loop) {
+      nocity_send = 1;
+      players_iterate(pplayer) {
+       if (!pplayer->ai.control) {
+         update_player_activities(pplayer);
+       }
+      } players_iterate_end;
+      nocity_send = 0;
+
+      /* the end of last turn and a good deal of the beginning of this
+        sending of city info has been inhibited. Now sync up with the client. 
*/
+      players_iterate(pplayer) {
+       city_list_iterate(pplayer->cities, pcity) {
+         city_refresh(pcity);
+         send_city_info(NULL, pcity);
+       } city_list_iterate_end;
+      } players_iterate_end;
+    }
+
+    /* Then we move the automated units, like goto, in random order. */
+    for (i = 0; i < game.nplayers; i++) {
+      struct player *pplayer = shuffled_player(i);
+      if (!pplayer->ai.control) {
+       move_automated_units(pplayer);
+      }
+    }
+
+    /* Now the players make their manual actions. */
+    while(sniff_packets()==1);
+
+    /* After sniff, re-zero the timer: (read-out above on next loop) */
+    clear_timer_start(eot_timer);
+
+    conn_list_do_buffer(&game.game_connections);
+
+#if (IS_DEVEL_VERSION || IS_BETA_VERSION)
+    sanity_check();
+#endif
+
+    /* This empties the client Messages window; put this before
+       everything else below, since otherwise any messages from
+       the following parts get wiped out before the user gets a
+       chance to see them.  --dwp */
+    before_end_year();
+
+    /* Move AIs. They always move in the same order and at the end
+       of the turn. This means that in single player the game is
+       turn-based and not pseudo-realtime. 
+       Note that we don't send city updates during the entire AI
+       update to save bandwidth. All cities are sendt once at the
+       beginning of the next turn. */
+    summon_barbarians();
+    players_iterate(pplayer) {
+      if (pplayer->ai.control) {
+       if (!is_first_loop) {
+         nocity_send = 1;
+         update_player_activities(pplayer);
+         nocity_send = 0;
+         city_list_iterate(pplayer->cities, pcity) {
+           city_refresh(pcity);
+           send_city_info(NULL, pcity);
+         } city_list_iterate_end;
+       }
+
+       /* in the case of the AI this is all units... */
+       move_automated_units(pplayer);
+
+       flush_packets(); /* AIs can be such spammers... */
+      }
+    } players_iterate_end;
+
+    end_turn_update_game();
+
+    conn_list_do_unbuffer(&game.game_connections);
+
+    if (game.year>game.end_year || is_game_over())
+      server_state=GAME_OVER_STATE;
+
+    is_first_loop = 0;
+  }
+}
+
+/**************************************************************************
+...
+**************************************************************************/
 void srv_main(void)
 {
   int i;
-  int save_counter = 0;
-  struct timer *eot_timer;     /* time server processing at end-of-turn */
 
   /* make sure it's initialized */
   if (!has_been_srv_init) {
@@ -333,12 +530,6 @@
     }
   }
 
-  /* When to start this timer the first time round is a bit arbitrary:
-     here start straight after stop sniffing for select_races and
-     before all following server initialization etc.
-  */
-  eot_timer = new_timer_start(TIMER_CPU, TIMER_ACTIVE);
-
   if(!game.randseed) {
     /* We strip the high bit for now because neither game file nor
        server options can handle unsigned ints yet. - Cedric */
@@ -415,86 +606,8 @@
 
   send_game_state(&game.est_connections, CLIENT_GAME_RUNNING_STATE);
 
-  while(server_state==RUN_GAME_STATE) {
-    /* absolute beginning of a turn */
-    freelog(LOG_DEBUG, "Begin turn");
-    begin_turn();
-
-#if (IS_DEVEL_VERSION || IS_BETA_VERSION)
-    sanity_check();
-#endif
-
-    force_end_of_sniff=0;
-
-    freelog(LOG_DEBUG, "Shuffleplayers");
-    shuffle_players();
-    freelog(LOG_DEBUG, "Aistartturn");
-    ai_start_turn();
-
-    /* Before sniff (human player activites), report time to now: */
-    freelog(LOG_VERBOSE, "End/start-turn server/ai activities: %g seconds",
-           read_timer_seconds(eot_timer));
-
-    /* Do auto-saves just before starting sniff_packets(), so that
-     * autosave happens effectively "at the same time" as manual
-     * saves, from the point of view of restarting and AI players.
-     * Post-increment so we don't count the first loop.
-     */
-    if(save_counter >= game.save_nturns && game.save_nturns>0) {
-      save_counter=0;
-      save_game_auto();
-    }
-    save_counter++;
-    
-    freelog(LOG_DEBUG, "sniffingpackets");
-    while(sniff_packets()==1);
-
-    /* After sniff, re-zero the timer: (read-out above on next loop) */
-    clear_timer_start(eot_timer);
-    
-    conn_list_do_buffer(&game.game_connections);
-
-#if (IS_DEVEL_VERSION || IS_BETA_VERSION)
-    sanity_check();
-#endif
-
-    before_end_year();
-    /* This empties the client Messages window; put this before
-       everything else below, since otherwise any messages from
-       the following parts get wiped out before the user gets a
-       chance to see them.  --dwp
-    */
-    freelog(LOG_DEBUG, "Season of native unrests");
-    summon_barbarians(); /* wild guess really, no idea where to put it, but
-                            I want to give them chance to move their units */
-    freelog(LOG_DEBUG, "Autosettlers");
-    auto_settlers(); /* moved this after ai_start_turn for efficiency -- Syela 
*/
-    /* moved after sniff_packets for even more efficiency.
-       What a guy I am. -- Syela */
-    /* and now, we must manage our remaining units BEFORE the cities that are
-       empty get to refresh and defend themselves.  How totally stupid. */
-    ai_start_turn(); /* Misleading name for manage_units -- Syela */
-    freelog(LOG_DEBUG, "Auto-Attack phase");
-    auto_attack();
-    freelog(LOG_DEBUG, "Endturn");
-    end_turn();
-    freelog(LOG_DEBUG, "Gamenextyear");
-    game_advance_year();
-    check_spaceship_arrivals();
-    freelog(LOG_DEBUG, "Sendplayerinfo");
-    send_player_info(0, 0);
-    freelog(LOG_DEBUG, "Sendgameinfo");
-    send_game_info(0);
-    freelog(LOG_DEBUG, "Sendyeartoclients");
-    send_year_to_clients(game.year);
-    freelog(LOG_DEBUG, "Sendinfotometaserver");
-    send_server_info_to_metaserver(0,0);
-
-    conn_list_do_unbuffer(&game.game_connections);
-
-    if (game.year>game.end_year || is_game_over()) 
-      server_state=GAME_OVER_STATE;
-  }
+  /*** This is where the action is taking place! ***/
+  server_main_loop();
 
   report_scores(1);
   show_map_to_all();
@@ -677,22 +790,6 @@
 }
 
 /**************************************************************************
-...
-**************************************************************************/
-static void ai_start_turn(void)
-{
-  int i;
-
-  for (i = 0; i < game.nplayers; i++) {
-    struct player *pplayer = shuffled_player(i);
-    if (pplayer->ai.control) {
-      ai_do_first_activities(pplayer);
-      flush_packets();                 /* AIs can be such spammers... */
-    }
-  }
-}
-
-/**************************************************************************
 Handle the beginning of each turn.
 Note: This does not give "time" to any player;
       it is solely for updating turn-dependent data.
@@ -720,10 +817,6 @@
            i, pplayer->name);
     begin_player_turn(pplayer);
   }
-  for (i=0; i<game.nplayers;i++) {
-    send_player_cities(&game.players[i]);
-  }
-  flush_packets();                     /* to curb major city spam */
 
   conn_list_do_unbuffer(&game.game_connections);
 }
@@ -731,28 +824,17 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static int end_turn(void)
+static void end_turn_update_game(void)
 {
-  int i;
+  players_iterate(pplayer) {
+    /* note: restoring move point moved to update_unit_activities */
+    player_restore_units(pplayer);
+    update_unit_activities(pplayer);
+  } players_iterate_end;
 
-  nocity_send = 1;
-  for(i=0; i<game.nplayers; i++) {
-    struct player *pplayer = shuffled_player(i);
-    freelog(LOG_DEBUG, "updating player activities for #%d (%s)",
-                 i, pplayer->name);
-    update_player_activities(pplayer);
-         /* ai unit activity has been moved UP -- Syela */
-
-    flush_packets();
-        /* update_player_activities calls update_unit_activities which
-           causes *major* network traffic */
+  players_iterate(pplayer) {
     pplayer->turn_done=0;
-  }
-  nocity_send = 0;
-  for (i=0; i<game.nplayers;i++) {
-    send_player_cities(&game.players[i]);
-  }
-  flush_packets();                     /* to curb major city spam */
+  } players_iterate_end;
 
   update_environmental_upset(S_POLLUTION, &game.heating,
                             &game.globalwarming, &game.warminglevel,
@@ -767,7 +849,18 @@
   send_player_turn_notifications(NULL);
   freelog(LOG_DEBUG, "Turn ended.");
   game.turn_start = time(NULL);
-  return 1;
+
+  freelog(LOG_DEBUG, "Gamenextyear");
+  game_advance_year();
+  check_spaceship_arrivals();
+  freelog(LOG_DEBUG, "Sendplayerinfo");
+  send_player_info(0, 0);
+  freelog(LOG_DEBUG, "Sendgameinfo");
+  send_game_info(0);
+  freelog(LOG_DEBUG, "Sendyeartoclients");
+  send_year_to_clients(game.year);
+  freelog(LOG_DEBUG, "Sendinfotometaserver");
+  send_server_info_to_metaserver(0,0);
 }
 
 /**************************************************************************
diff -urN -Xfreeciv/diff_ignore freeciv.orig/server/unittools.c 
freeciv/server/unittools.c
--- freeciv.orig/server/unittools.c     Wed Apr 11 13:33:37 2001
+++ freeciv/server/unittools.c  Sat Apr 21 18:42:20 2001
@@ -1457,19 +1457,6 @@
     }
   }
 
-  if (activity==ACTIVITY_GOTO) {
-    if (!punit->ai.control && (!is_military_unit(punit) ||
-       punit->ai.passenger || !pplayer->ai.control)) {
-/* autosettlers otherwise waste time; idling them breaks assignment */
-/* Stalling infantry on GOTO so I can see where they're GOing TO. -- Syela */
-      do_unit_goto(punit, GOTO_MOVE_ANY, 1);
-    }
-    return;
-  }
-
-  if (punit->activity == ACTIVITY_PATROL)
-    goto_route_execute(punit);
-
   send_unit_info(0, punit);
 
   unit_list_iterate(ptile->units, punit2) {

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] Some old patches synched and some new stuff, Davide Pagnin <=