Complete.Org: Mailing Lists: Archives: freeciv-dev: December 1999:
[Freeciv-Dev] patch for "ran out of continents in client" bug
Home

[Freeciv-Dev] patch for "ran out of continents in client" bug

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] patch for "ran out of continents in client" bug
From: Peter Schaefer <schaefer@xxxxxx>
Date: Tue, 21 Dec 1999 04:10:23 -0700

The bug is triggered by the apollo program, which tells the client about
every city,
which in turn becomes am entire continent by itself.

I have worked around it by assigning all these cities the same number.
In addition, I changed the continent renumbering function so that it
can actually merge continents.
Hmm, I havent thought about what happens to the continent numbers then.
Back to the drawing board .. Ok fixed afaik.
The continent number are released again.
Was this done elsewhere in the client ? I didn´t spot it .. .

Offtopic:
The attachments of my previous emails that didnt make it past Jitterbug
re-attached.
I recommend applying advdom1.diff, maybe the value 
of TRADE_WEIGHTING has to discussed.
advdom2.diff mainly points out a week spot.

if you do not see 3 attachments, I apologize - I´ve got a "permissions"
problem then :-P
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/ai/advdomestic.c 
freeciv-1.9.0/ai/advdomestic.c
--- freeciv-1.9.0-release/ai/advdomestic.c      Fri Dec 17 14:39:03 1999
+++ freeciv-1.9.0/ai/advdomestic.c      Sun Dec 19 22:54:06 1999
@@ -42,7 +42,7 @@
 static int ai_best_tile_value(struct city *pcity)
 {
   int x, y, bx, by, food, best, cur;
-
+ 
 /* food = (pcity->size *2 -get_food_tile(2,2, pcity)) + settler_eats(pcity); */
   food = 0; /* simply works better as far as I can tell */
   do {
@@ -175,31 +175,36 @@
   } 
   return(c); /* benefit or cost of this building */
 }
- 
+
+
 void ai_eval_buildings(struct city *pcity)
 {
   struct government *g = get_gov_pcity(pcity);
-  int i, val, a, t, food, j, k, hunger, bar, grana;
-  int tax, prod, sci, values[B_LAST];
+  int i, val, a, t_weight, food, j, k, hunger, bar, grana;
+  int tax, prod, prod_surplus, sci, values[B_LAST];
   int est_food = pcity->food_surplus + 2 * pcity->ppl_scientist + 2 * 
pcity->ppl_taxman; 
   struct player *pplayer = city_owner(pcity);
   int needpower;
   int wwtv = worst_worker_tile_value(pcity);
   
   a = get_nation_by_plr(city_owner(pcity))->attack;
-  t = pcity->ai.trade_want; /* trade_weighting */
+  t_weight = pcity->ai.trade_want; /* trade_weighting */
   sci = (pcity->trade_prod * pplayer->economic.science + 50) / 100;
   tax = pcity->trade_prod - sci;
 #ifdef STUPID
-  sci *= t;
-  tax *= t;
+  sci *= t_weight;
+  tax *= t_weight;
 #else
 /* better might be a longterm weighted average, this is a quick-n-dirty fix -- 
Syela */
-  sci = ((sci + pcity->trade_prod) * t)/2;
-  tax = ((tax + pcity->trade_prod) * t)/2;
+  sci = ((sci + pcity->trade_prod) * t_weight)/2;
+  tax = ((tax + pcity->trade_prod) * t_weight)/2;
 #endif
   if (pplayer->research.researching == A_NONE) sci = 0; /* don't need 
libraries!! */
+
+  /* this is the RAW production */
   prod = pcity->shield_prod * 100 / city_shield_bonus(pcity) * 
SHIELD_WEIGHTING;
+  prod_surplus = pcity->shield_surplus * SHIELD_WEIGHTING;
+
   needpower = (city_got_building(pcity, B_MFG) ? 2 :
               (city_got_building(pcity, B_FACTORY) ? 1 : 0));
   val = ai_best_tile_value(pcity);
@@ -233,27 +238,32 @@
   if (could_build_improvement(pcity, B_BANK))
     values[B_BANK] = (tax + 3*pcity->ppl_taxman + pcity->ppl_elvis*wwtv)/2;
   
-  j = 0; k = 0;
+     
+
+ j = 0; k = 0;
   city_list_iterate(pplayer->cities, acity)
     if (acity->is_building_unit) {
       if (!unit_flag(acity->currently_building, F_NONMIL) &&
           unit_types[acity->currently_building].move_type == LAND_MOVING)
-        j += prod;
+        j += prod_surplus;
       else if (unit_flag(acity->currently_building, F_CARAVAN) &&
-        built_elsewhere(acity, B_SUNTZU)) j += prod; /* this also stops 
flip-flops */
+        built_elsewhere(acity, B_SUNTZU)) 
+       j += prod_surplus; /* this also stops flip-flops */
     } else if (acity->currently_building == B_BARRACKS || /* this stops 
flip-flops */
              acity->currently_building == B_BARRACKS2 ||
              acity->currently_building == B_BARRACKS3 ||
-             acity->currently_building == B_SUNTZU) j += prod;
+             acity->currently_building == B_SUNTZU) 
+      j += prod_surplus;
     k++;
   city_list_iterate_end;
   if (!k) freelog(LOG_FATAL,
-                 "Gonna crash, 0 k, looking at %s (ai_eval_buildings)",
-                 pcity->name);
+                  "Gonna crash, 0 k, looking at %s (ai_eval_buildings)",
+                  pcity->name);
   /* rationale: barracks effectively double prod while building military units 
*/
   /* if half our production is military, effective gain is 1/2 city prod */
   bar = j / k;
 
+
   if (!built_elsewhere(pcity, B_SUNTZU)) { /* yes, I want can, not could! */
     if (can_build_improvement(pcity, B_BARRACKS3))
       values[B_BARRACKS3] = bar;
@@ -263,7 +273,8 @@
       values[B_BARRACKS] = bar;
   }
 
-  if (could_build_improvement(pcity, B_CAPITAL))
+  if (could_build_improvement(pcity, B_CAPITAL) 
+      && !built_elsewhere(pcity, B_CAPITAL) ) /* don't go mad building 
capitals */
     values[B_CAPITAL] = TRADE_WEIGHTING * 999 / MORT; /* trust me */
 /* rationale: If cost is N and benefit is N gold per MORT turns, want is
 TRADE_WEIGHTING * 100 / MORT.  This is comparable, thus the same weight -- 
Syela */
@@ -278,6 +289,8 @@
 /* it was so stupid, AI wouldn't start building walls until it was in danger */
 /* and it would have no chance to finish them before it was too late */
 
+
+  {
   if (could_build_improvement(pcity, B_CITY))
 /* && !built_elsewhere(pcity, B_WALL))      was counterproductive -- Syela */
     values[B_CITY] = 40; /* WAG */
@@ -287,6 +300,8 @@
 
   if (could_build_improvement(pcity, B_SAM))
     values[B_SAM] = 50; /* WAG */
+  }
+
 
   if (could_build_improvement(pcity, B_COLOSSEUM))
     values[B_COLOSSEUM] = building_value(get_colosseum_power(pcity), pcity, 
val);
@@ -298,7 +313,7 @@
     if (g->corruption_level == 0) {
       values[B_COURTHOUSE] += building_value (1, pcity, val);
     } else {
-      values[B_COURTHOUSE] = (pcity->corruption * t)/2;
+      values[B_COURTHOUSE] = (pcity->corruption * t_weight)/2;
     }
   }
   
@@ -380,7 +395,7 @@
     values[B_STOCK] = (tax + 3*pcity->ppl_taxman + pcity->ppl_elvis*wwtv)/2;
 
   if (could_build_improvement(pcity, B_SUPERHIGHWAYS))
-    values[B_SUPERHIGHWAYS] = road_trade(pcity) * t;
+    values[B_SUPERHIGHWAYS] = road_trade(pcity) * t_weight;
 
   if (could_build_improvement(pcity, B_SUPERMARKET))
     values[B_SUPERMARKET] = farmland_food(pcity) * food * hunger;
@@ -405,18 +420,18 @@
       if (i == B_ASMITHS)
         for (j = 0; j < B_LAST; j++)
           if (city_got_building(pcity, j) && improvement_upkeep(pcity, j) == 1)
-            values[i] += t;
+            values[i] += t_weight;
       if (i == B_COLLOSSUS)
-        values[i] = (pcity->size + 1) * t; /* probably underestimates the 
value */
+        values[i] = (pcity->size + 1) * t_weight; /* probably underestimates 
the value */
       if (i == B_COPERNICUS)
         values[i] = sci/2;
       if (i == B_CURE)
         values[i] = building_value(1, pcity, val);
       if (i == B_DARWIN) /* this is a one-time boost, not constant */
-        values[i] = ((research_time(pplayer) * 2 + game.techlevel) * t -
-                    pplayer->research.researched * t) / MORT;
+        values[i] = ((research_time(pplayer) * 2 + game.techlevel) * t_weight -
+                    pplayer->research.researched * t_weight) / MORT;
       if (i == B_GREAT) /* basically (100 - freecost)% of a free tech per turn 
*/
-        values[i] = (research_time(pplayer) * (100 - game.freecost)) * t *
+        values[i] = (research_time(pplayer) * (100 - game.freecost)) * 
t_weight *
                     (game.nplayers - 2) / (game.nplayers * 100); /* guessing */
 
       if (i == B_WALL && !city_got_citywalls(pcity))
@@ -482,7 +497,7 @@
         values[i] = bar;
       if (i == B_WOMENS) {
         unit_list_iterate(pcity->units_supported, punit)
-          if (punit->unhappiness) values[i] += t * 2;
+          if (punit->unhappiness) values[i] += t_weight * 2;
         unit_list_iterate_end;
       }
 
@@ -499,7 +514,7 @@
       freelog(LOG_DEBUG, "%s wants %s with desire %d.",
              pcity->name, get_improvement_name(i), values[i]);
     }
-    if (!is_wonder(i)) values[i] -= improvement_upkeep(pcity, i) * t;
+    if (!is_wonder(i)) values[i] -= improvement_upkeep(pcity, i) * t_weight;
     values[i] *= 100;
     if (!is_wonder(i)) { /* trying to buy fewer improvements */
       values[i] *= SHIELD_WEIGHTING;
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/ai/aiunit.c 
freeciv-1.9.0/ai/aiunit.c
--- freeciv-1.9.0-release/ai/aiunit.c   Fri Dec 17 14:39:03 1999
+++ freeciv-1.9.0/ai/aiunit.c   Sat Dec 18 21:33:13 1999
@@ -937,6 +937,7 @@
       acity->ai.a = reinforcements_value(punit, acity->x, acity->y);
       acity->ai.f = reinforcements_cost(punit, acity->x, acity->y);
       acity->ai.invasion = 0;
+      /*printf("city %s reinforcements value %d, cost %d\n", acity->name, 
acity->ai.a, acity->ai.f);*/
     city_list_iterate_end;
   }
 
Binary files freeciv-1.9.0-release/client/civclient and 
freeciv-1.9.0/client/civclient differ
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/common/map.c 
freeciv-1.9.0/common/map.c
--- freeciv-1.9.0-release/common/map.c  Fri Dec 17 14:39:01 1999
+++ freeciv-1.9.0/common/map.c  Sat Dec 18 21:01:27 1999
@@ -950,6 +950,7 @@
   unit_list_init(&ptile->units);
   ptile->worked = NULL; /* pointer to city working tile */
   ptile->assigned = 0; /* bitvector */
+  ptile->claimed = 0;
 }
 
 
@@ -1064,7 +1065,7 @@
 }
 
 /***************************************************************
-...
+ for client use only, because often "known>1" in server
 ***************************************************************/
 enum known_type tile_is_known(int x, int y)
 {
@@ -1112,4 +1113,52 @@
 {
   return (map_adjust_x(x1) == map_adjust_x(x2)
          && map_adjust_y(y1) == map_adjust_y(y2)); 
+}
+
+
+/***************************************************************
+...
+***************************************************************/
+int map_get_claimed(int x, int y, struct player *pplayer)
+{
+  return ((map.tiles+map_adjust_x(x)+
+          map_adjust_y(y)*map.xsize)->claimed)&(1u<<pplayer->player_no);
+}
+
+/***************************************************************
+...
+***************************************************************/
+void map_set_claimed(int x, int y, struct player *pplayer)
+{
+  (map.tiles+map_adjust_x(x)+
+   map_adjust_y(y)*map.xsize)->claimed|=(1u<<pplayer->player_no);
+}
+
+/***************************************************************
+...
+***************************************************************/
+void map_clear_claimed(int x, int y, struct player *pplayer)
+{
+  (map.tiles+map_adjust_x(x)+
+   map_adjust_y(y)*map.xsize)->claimed&=~(1u<<pplayer->player_no);
+}
+
+/***************************************************************
+ How many players claim this tile ?
+ This is a lowlevel function which does not implement game rules.
+***************************************************************/
+int map_count_claimed(int x, int y)
+{
+  int c;
+  unsigned short claims=
+    (map.tiles+map_adjust_x(x)+
+     map_adjust_y(y)*map.xsize)->claimed;
+
+  c = 0;
+  while( claims>0 ){
+    if(claims&1)
+      ++c;
+    claims >>= 1;
+  }
+  return c;
 }
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/common/map.h 
freeciv-1.9.0/common/map.h
--- freeciv-1.9.0-release/common/map.h  Fri Dec 17 14:39:01 1999
+++ freeciv-1.9.0/common/map.h  Fri Dec 17 17:46:46 1999
@@ -60,6 +60,7 @@
   struct city *worked;      /* city working tile, or NULL if none */
   unsigned char continent;
   signed char move_cost[8]; /* don't know if this helps! */
+  unsigned short claimed;
 };
 
 
@@ -208,6 +209,10 @@
 void map_set_known(int x, int y, struct player *pplayer);
 void map_clear_known(int x, int y, struct player *pplayer);
 void map_know_all(struct player *pplayer);
+int map_get_claimed(int x, int y, struct player *pplayer);
+void map_set_claimed(int x, int y, struct player *pplayer);
+void map_clear_claimed(int x, int y, struct player *pplayer);
+int map_count_claimed(int x, int y);
 
 int is_water_adjacent_to_tile(int x, int y);
 int is_tiles_adjacent(int x0, int y0, int x1, int y1);
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/server/cityhand.c 
freeciv-1.9.0/server/cityhand.c
--- freeciv-1.9.0-release/server/cityhand.c     Fri Dec 17 14:39:04 1999
+++ freeciv-1.9.0/server/cityhand.c     Sun Dec 19 20:16:40 1999
@@ -170,7 +170,7 @@
   pcity->city_options = CITYOPT_DEFAULT;
   
   pcity->ai.ai_role = AICITY_NONE;
-  pcity->ai.trade_want = 8; /* default value */
+  pcity->ai.trade_want = TRADE_WEIGHTING; 
   memset(pcity->ai.building_want, 0, sizeof(pcity->ai.building_want));
   pcity->ai.workremain = 1; /* there's always work to be done! */
   pcity->ai.danger = -1; /* flag, may come in handy later */
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/server/citytools.h 
freeciv-1.9.0/server/citytools.h
--- freeciv-1.9.0-release/server/citytools.h    Fri Dec 17 14:39:04 1999
+++ freeciv-1.9.0/server/citytools.h    Sun Dec 19 21:21:10 1999
@@ -18,7 +18,13 @@
 
 #define FOOD_WEIGHTING 19
 #define SHIELD_WEIGHTING 17
-#define TRADE_WEIGHTING 8
+#define TRADE_WEIGHTING 12
+/* The Trade Weighting has to about as large as the Shield Weighting,
+   otherwise the AI will build Barracks to create veterans in cities 
+   with only 1 shields production.
+    8 is too low
+   18 is too high
+ */
 #define POLLUTION_WEIGHTING 14 /* tentative */
 #define WARMING_FACTOR 32 /* tentative */
 
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/server/cityturn.c 
freeciv-1.9.0/server/cityturn.c
--- freeciv-1.9.0-release/server/cityturn.c     Sun Dec 19 20:15:28 1999
+++ freeciv-1.9.0/server/cityturn.c     Sun Dec 19 20:17:23 1999
@@ -362,7 +362,7 @@
     pcity->trade_prod+=pcity->trade_value[i];
   }
   pcity->corruption = city_corruption(pcity, pcity->trade_prod);
-  pcity->ai.trade_want = TRADE_WEIGHTING - city_corruption(pcity, 
TRADE_WEIGHTING );
+  pcity->ai.trade_want = TRADE_WEIGHTING - city_corruption(pcity, 
TRADE_WEIGHTING);
 /* AI would calculate this 1000 times otherwise; better to do it once -- Syela 
*/
   pcity->trade_prod -= pcity->corruption;
 }
Binary files freeciv-1.9.0-release/server/civserver and 
freeciv-1.9.0/server/civserver differ
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/server/plrhand.c 
freeciv-1.9.0/server/plrhand.c
--- freeciv-1.9.0-release/server/plrhand.c      Sun Dec 19 20:14:53 1999
+++ freeciv-1.9.0/server/plrhand.c      Sun Dec 19 20:34:40 1999
@@ -1791,7 +1791,7 @@
     
     pcity=fc_malloc(sizeof(struct city));
     pcity->ai.ai_role = AICITY_NONE;
-    pcity->ai.trade_want = TRADE_WEIGHTING; /* default value */
+    pcity->ai.trade_want = TRADE_WEIGHTING; 
     memset(pcity->ai.building_want, 0, sizeof(pcity->ai.building_want));
     pcity->ai.workremain = 1; /* there's always work to be done! */
     pcity->ai.danger = -1; /* flag, may come in handy later */
diff -Nurd -x*.[Poa] -x*.orig -x *.rej -x*.bak -x*.[ch]~ -x*.pot -x*.deps 
-x*.sav -x Makefile -xlibintl.h freeciv-1.9.0-release/server/unithand.c 
freeciv-1.9.0/server/unithand.c
--- freeciv-1.9.0-release/server/unithand.c     Fri Dec 17 20:12:44 1999
+++ freeciv-1.9.0/server/unithand.c     Mon Oct  4 06:23:35 1999
@@ -858,7 +858,7 @@
                       _("Game: You can't attack there."));
       return 0;
     };
-  } else if (pplayer->ai.control && punit->ai.bodyguard > 0 && (bodyguard = 
unit_list_find(&map_get_tile(punit->x,
+  } else if (punit->ai.bodyguard > 0 && (bodyguard = 
unit_list_find(&map_get_tile(punit->x,
       punit->y)->units, punit->ai.bodyguard)) && !bodyguard->moves_left) {
     notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
                     _("Game: %s doesn't want to leave its bodyguard."),
--- freeciv-1.9.0/ai/advdomestic.c      Sun Dec 19 22:54:06 1999
+++ advdomestic.c       Sun Dec 19 22:45:47 1999
@@ -176,6 +176,169 @@
   return(c); /* benefit or cost of this building */
 }
 
+ /***********************************************************************
+ Iterate over own neighboring cities to determine whether this is 
+ a land/ sea/ air border city. This mechanism is an O(2) CPU hog, and 
+ needs to be cached, but I want to get rid of the dumb wall building.
+ Return Values: int lsa[3] = { land, sea, air };
+***********************************************************************/
+static void city_need_defenses(struct player *pplayer, struct city *pcity, int 
*lsa )
+{
+#define _D_LAND (0)
+#define _D_SEA (1)
+#define _D_AIR (2)
+
+  int size_friendly, c_friendly, lsa_defenses[3];
+  int size_danger, lsa_danger[3];
+
+  int cthis, cthat;
+  int i;
+  int handicap;
+  int distance;
+
+  struct player *aplayer;
+
+  size_friendly = 0;
+  c_friendly = 0;
+  lsa_defenses[2]= lsa_defenses[1]= lsa_defenses[0]= 0;
+
+  size_danger = 0;
+  lsa_danger[2]= lsa_danger[1]= lsa_danger[0]= 0;
+
+  cthis= map_get_continent(pcity->x, pcity->y);
+
+
+  /* calculate some statistics */
+
+  /* own cities */
+  city_list_iterate(pplayer->cities, acity)
+    {
+      /* check that this city can help */
+      cthat= map_get_continent(acity->x, acity->y);
+      if( cthis == cthat ){
+       distance = real_map_distance(pcity->x, pcity->y, acity->x, acity->y);
+       if( distance < CITY_MAP_SIZE+2
+           &&
+           acity->ai.a <= pcity->ai.a
+           )
+         {        
+           size_friendly += pcity->size;
+           ++c_friendly;
+           if( city_got_effect(pcity, B_WALL) ){
+             ++lsa_defenses[_D_LAND];
+           }       
+             
+           if( city_got_effect(pcity, B_COASTAL) ){
+             ++lsa_defenses[_D_SEA];
+           }
+
+           if( city_got_effect(pcity, B_SAM) ){
+             ++lsa_defenses[_D_AIR];
+           }
+
+         }
+      }
+    }
+  city_list_iterate_end;
+
+
+  /* enemy cities */
+  handicap=ai_handicap(pplayer, H_TARGETS);
+  for (i = 0; i < game.nplayers; i++) {
+    aplayer = &game.players[i];
+    if (aplayer != pplayer) { /* enemy */
+      city_list_iterate(aplayer->cities, acity)
+       {
+         if (handicap && !map_get_known(acity->x, acity->y, pplayer)) 
+           continue;
+      
+         distance = real_map_distance(pcity->x, pcity->y, acity->x, acity->y);
+          
+           size_danger+= acity->size;
+
+           if( distance < CITY_MAP_SIZE + 2
+               || 
+               (( distance < CITY_MAP_SIZE * 2 +2 ) && cthis == 
map_get_continent(acity->x, acity->y) )
+               )
+             {                        
+               lsa_danger[_D_LAND]+= acity->size;
+             }
+           
+           /* Assuming 5 sea range, which is modified by MAGELLAN */
+           /* The correct way would be to scan all seen enemy and 
+              own sea units for their maximum range     */
+
+           if( distance 
+               < 
+               4* 
+               (
+                5 +
+                2 - ( player_owns_active_wonder(pplayer, B_MAGELLAN) ? ( 
(improvement_variant(B_MAGELLAN)==1) ? 3 : 6 )/3 : 0 )
+                )
+              )
+             {
+               if( is_terrain_near_tile(acity->x, acity->y, T_OCEAN) )
+                 {
+                   lsa_danger[_D_SEA]+= acity->size;
+                 }
+             }
+
+           /* Assuming 16 range (cruise missile range) .. */
+           /* The correct way would be to scan all seen enemy and 
+              own air units for their maximum range */
+
+           if( distance < 16 )
+             {           
+               lsa_danger[_D_AIR]+= acity->size; /* but air units are much 
more mobile than others ?! */
+             }
+
+         }
+    city_list_iterate_end;            
+    }
+  }
+
+  /* Let's cook up some rules which return maximum values of about 40-50 */  
+  {
+    int land, sea, air;
+
+    land = 36*lsa_danger[_D_LAND] / (size_friendly+1);
+    sea =   8*lsa_danger[_D_SEA] / (size_friendly+1);
+    air =  12*lsa_danger[_D_AIR] / (size_friendly+1);
+
+    freelog(LOG_DEBUG, "Step 1: %s lsa %d/%d/%d\n", pcity->name, land, sea, 
air);
+
+    /* only about every 2nd city builds city walls initially */
+    if( 2 * lsa_defenses[_D_LAND] > c_friendly )
+      land /= 2;
+
+    /* only about every 3rd city builds coastal defenses initially */
+    if( 3 * lsa_defenses[_D_LAND] > c_friendly )
+      sea /= 2;
+
+    /* only about every 4th city builds SAM initially */
+    if( 4 * lsa_defenses[_D_LAND] > c_friendly )
+      sea /= 2;
+
+    freelog(LOG_DEBUG, "Step 2: %s lsa %d/%d/%d\n", pcity->name, land, sea, 
air);
+
+    if( land > 40 )
+      land = 40;
+    if( sea > 45 )
+      sea = 45;
+    if( air > 50 )
+      air = 50;
+
+    lsa[0]= land;
+    lsa[1]= sea;
+    lsa[2]= air;
+
+    freelog(LOG_DEBUG, "Step 3: %s lsa %d/%d/%d\n", pcity->name, land, sea, 
air);
+
+  }
+
+  return;
+}
+
 
 void ai_eval_buildings(struct city *pcity)
 {
@@ -290,16 +453,21 @@
 /* and it would have no chance to finish them before it was too late */
 
 
+  /*!PS: added somewhat smarter code, which produces weights <50 */
   {
+    int lsa[3];
+
+    city_need_defenses(pplayer, pcity, lsa );
+
   if (could_build_improvement(pcity, B_CITY))
 /* && !built_elsewhere(pcity, B_WALL))      was counterproductive -- Syela */
-    values[B_CITY] = 40; /* WAG */
+    values[B_CITY] = lsa[0]; 
 
   if (could_build_improvement(pcity, B_COASTAL))
-    values[B_COASTAL] = 40; /* WAG */
+    values[B_COASTAL] = lsa[1]; 
 
   if (could_build_improvement(pcity, B_SAM))
-    values[B_SAM] = 50; /* WAG */
+    values[B_SAM] = lsa[2];
   }
 
 
--- /home/schaefer/climisc.c    Tue Dec 21 01:25:38 1999
+++ client/climisc.c    Tue Dec 21 03:54:33 1999
@@ -117,7 +117,7 @@
   int x=pcity->x;
   int y=pcity->y;
 
-  freelog(LOG_DEBUG, "removing city %s, %s, (%d %d)", pcity->name,
+  freelog(LOG_DEBUG, "rm city %s, %s, (%d %d)", pcity->name,
          get_nation_name(city_owner(pcity)->nation), x, y);
   popdown_city_dialog(pcity);
   game_remove_city(pcity);
@@ -137,6 +137,7 @@
   for(i=0; i<NCONT; i++) {
     used_continent_val[i] = 0;
   }
+  used_continent_val[NCONT-2] = 1; /* used for single revealed tiles */
 }
 
 /**************************************************************************
@@ -156,13 +157,47 @@
       if(!(i==x && j==y) && j>=0 && j<map.ysize
         && tile_is_known(i,j)>=TILE_KNOWN
         && map_get_terrain(i,j)!=T_OCEAN
-        && map_get_continent(i,j)==old) {
-       climap_renumber_continent(i,j,new);
+        ) {
+            int cont= map_get_continent(i,j);
+            if( cont != new ){
+              if( cont != old )
+                if( cont != NCONT-2 )
+                  {
+                    freelog(LOG_DEBUG, "merging continent %d at (%d %d)", 
cont, x, y);
+                    used_continent_val[cont] = 0;
+                  }
+
+              climap_renumber_continent(i,j,new);
+            }
       }
     }
   }
 }
 
+/*************************************************************************
+The Apollo programs reveals a lot of cities which appear to be on
+isolated continents, causing continent numbers to overflow (unless..).
+**************************************************************************/
+static int is_revealed_single_tile(x, y)
+{
+  int i, j;
+
+  if (y<0 || y>=map.ysize) 
+    return 1;
+  x = map_adjust_x(x);
+
+  for(i=x-1; i<=x+1; i++) {
+    for(j=y-1; j<=y+1; j++) {
+      if( (i!=x || j!=y) && j>=0 && j<map.ysize )
+       if( tile_is_known(i,j)>=TILE_KNOWN )
+         return 0;
+    }
+  }
+  
+  return 1;
+}
+
+
 /**************************************************************************
 ...
 **************************************************************************/
@@ -182,7 +217,7 @@
        if(this_con==-1) {
          ptile->continent = this_con = con;
        } else if(con != this_con) {
-         freelog(LOG_DEBUG, "renumbering client continent %d to %d at (%d %d)",
+         freelog(LOG_DEBUG, "renumber client continent %d to %d at (%d %d)",
               con, this_con, x, y);
          climap_renumber_continent(i,j,this_con);
          used_continent_val[con] = 0;
@@ -191,12 +226,20 @@
     }
   }
   if(this_con==-1) {
-    for(i=2; i<NCONT; i++) {
-      if(!used_continent_val[i]) {
-       freelog(LOG_DEBUG, "new client continent %d at (%d %d)", i, x, y);
-       ptile->continent = this_con = i;
-       used_continent_val[i] = 1;
-       break;
+    if( is_revealed_single_tile(x, y) )
+      {
+       freelog(LOG_DEBUG, "skipped single tile continent %d at (%d %d)", 
NCONT-2, x, y);
+       this_con= NCONT-2;
+       ptile->continent = NCONT-2; /* used_continent_val[NCONT-2]== 1; */
+      }
+    else{
+      for(i=2; i<NCONT; i++) {
+       if(!used_continent_val[i]) {
+         freelog(LOG_DEBUG, "new client continent %d at (%d %d)", i, x, y);
+         ptile->continent = this_con = i;
+         used_continent_val[i] = 1;
+         break;
+       }
       }
     }
   }

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