home *** CD-ROM | disk | FTP | other *** search
/ Amiga Times / AmigaTimes.iso / spiele / FreeCiv / src / freeciv-1.7.0 / server / settlers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-06  |  39.6 KB  |  1,108 lines

  1. /********************************************************************** 
  2.  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2, or (at your option)
  6.    any later version.
  7.  
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12. ***********************************************************************/
  13. #include <stdio.h>
  14. #include <string.h>
  15.  
  16. #include <settlers.h>
  17. #include <packets.h>
  18. #include <map.h>
  19. #include <game.h>
  20. #include <citytools.h>
  21. #include <aiunit.h>
  22. #include <gotohand.h>
  23. #include <assert.h>
  24. #include <cityhand.h>
  25. #include <unithand.h>
  26. #include <unitfunc.h>
  27. #include <maphand.h>
  28. #include <aicity.h>
  29. #include <unittools.h>
  30.  
  31. extern struct move_cost_map warmap;
  32. signed short int minimap[MAP_MAX_WIDTH][MAP_MAX_HEIGHT];
  33. /* negative: in_city_radius, 0: unassigned, positive: city_des */
  34.  
  35. /**************************************************************************
  36. ...
  37. **************************************************************************/
  38. const char *get_a_name(struct player *pplayer)
  39. {
  40.   static char buf[80];
  41.   static int x=0;
  42.   sprintf(buf, "%s", city_name_suggestion(pplayer)); /* Not a Number -- Syela */
  43.   if (!buf[0]) sprintf(buf, "city%d", x++);
  44.   return buf;
  45. }
  46.  
  47. /**************************************************************************
  48. ...
  49. **************************************************************************/
  50. int ai_do_build_city(struct player *pplayer, struct unit *punit)
  51. {
  52.   int x,y;
  53.   struct packet_unit_request req;
  54.   struct city *pcity;
  55.   req.unit_id=punit->id;
  56.   strcpy(req.name, get_a_name(pplayer));
  57.   x = punit->x; y = punit->y; /* Trevor Pering points out that punit gets freed */
  58.   handle_unit_build_city(pplayer, &req);        
  59.   pcity=map_get_city(x, y); /* so we need to cache x and y for a very short time */
  60.   if (!pcity)
  61.     return 0;
  62.   for (y=0;y<5;y++)
  63.     for (x=0;x<5;x++) {
  64.       if ((x==0 || x==4) && (y==0 || y==4)) 
  65.         continue;
  66.       light_square(pplayer, x+pcity->x-2, y+pcity->y-2, 0);
  67.     }
  68.   return 1;
  69. }
  70.  
  71. int amortize(int b, int d)
  72. {
  73.   int num = MORT - 1;
  74.   int denom;
  75.   int s = 1;
  76.   assert(d >= 0);
  77.   if (b < 0) { s = -1; b *= s; }
  78.   while (d && b) {
  79.     denom = 1;
  80.     while (d >= 12 && !(b>>28) && !(denom>>27)) {
  81.       b *= 3;          /* this is a kluge but it is 99.9% accurate and saves time */
  82.       denom *= 5;      /* as long as MORT remains 24! -- Syela */
  83.       d -= 12;
  84.     }
  85.     while (!(b>>25) && d && !(denom>>25)) {
  86.       b *= num;
  87.       denom *= MORT;
  88.       d--;
  89.     }
  90.     if (denom > 1) {
  91.       b = (b + (denom>>1)) / denom;
  92.     }
  93.   }
  94.   return(b * s);
  95. }
  96.  
  97. void generate_minimap(void)
  98. {
  99.   int a, i, j;
  100.  
  101.   memset(minimap, 0, sizeof(minimap));
  102.   for (a = 0; a < game.nplayers; a++) {
  103.     city_list_iterate(game.players[a].cities, pcity)
  104.       city_map_iterate(i, j) {
  105.         minimap[map_adjust_x(pcity->x+i-2)][map_adjust_y(pcity->y+j-2)]--;
  106.       }
  107.     city_list_iterate_end;
  108.   }
  109. }
  110.  
  111. void remove_city_from_minimap(int x, int y)
  112. {
  113.   int i, j, n, xx;
  114. /*printf("Removing (%d, %d) from minimap.\n", x, y);*/
  115.   for (j = -4; j <= 4; j++) {
  116.     if (y+j < 0 || y+j >= map.ysize) continue;
  117.     for (i = -4; i <= 4; i++) {
  118.       xx = map_adjust_x(x+i);
  119.       n = i * i + j * j;
  120.       if (n <= 5) {
  121.         if (minimap[xx][y+j] < 0) minimap[xx][y+j]++;
  122.         else minimap[xx][y+j] = 0;
  123.       } else if (n <= 20) {
  124.         if (minimap[xx][y+j] > 0) minimap[xx][y+j] = 0;
  125.       }
  126.     }
  127.   }
  128. }    
  129.  
  130. void add_city_to_minimap(int x, int y)
  131. {
  132.   int i, j, n, xx;
  133. /*printf("Adding (%d, %d) to minimap.\n", x, y);*/
  134.   for (j = -4; j <= 4; j++) {
  135.     if (y+j < 0 || y+j >= map.ysize) continue;
  136.     for (i = -4; i <= 4; i++) {
  137.       xx = map_adjust_x(x+i);
  138.       n = i * i + j * j;
  139.       if (n <= 5) {
  140.         if (minimap[xx][y+j] < 0) minimap[xx][y+j]--;
  141.         else minimap[xx][y+j] = -1;
  142.       } else if (n <= 20) {
  143.         if (minimap[xx][y+j] > 0) minimap[xx][y+j] = 0;
  144.       }
  145.     }
  146.   }
  147. }    
  148.  
  149. void locally_zero_minimap(int x, int y)
  150. {
  151.   int i, j, n, xx;
  152.   for (j = -2; j <= 2; j++) {
  153.     if (y+j < 0 || y+j >= map.ysize) continue;
  154.     for (i = -2; i <= 2; i++) {
  155.       xx = map_adjust_x(x+i);
  156.       n = i * i + j * j;
  157.       if (n <= 5) {
  158.         if (minimap[xx][y+j] > 0) minimap[xx][y+j] = 0;
  159.       }
  160.     }
  161.   }
  162. }  
  163.  
  164. int city_desirability(int x, int y)
  165. { /* this whole funct assumes G_REP^H^H^HDEMOCRACY -- Syela */
  166.   int taken[5][5], food[5][5], shield[5][5], trade[5][5];
  167.   int irrig[5][5], mine[5][5], road[5][5];
  168.   int i, j, f, n = 0;
  169.   int worst, b2, best, ii, jj, val, cur;
  170.   int d = 0;
  171.   int a, i0, j0; /* need some temp variables */
  172.   int temp=0, tmp=0;
  173.   int debug = 0;
  174.   int g = 1;
  175.   struct tile *ptile;
  176.   int con, con2;
  177.   int har, t, sh;
  178.   struct tile_type *ptype;
  179.   struct city *pcity;
  180.  
  181.   ptile = map_get_tile(x, y);
  182.   if (ptile->terrain == T_OCEAN) return(0);
  183.   pcity = map_get_city(x, y);
  184.   if (pcity && pcity->size > 7) return(0);
  185.   if (!pcity && minimap[x][y] < 0) return(0);
  186.   if (!pcity && minimap[x][y] > 0) return(minimap[x][y]);
  187.  
  188.   har = is_terrain_near_tile(x, y, T_OCEAN);
  189.  
  190.   sh = SHIELD_WEIGHTING * MORT;
  191.   t = TRADE_WEIGHTING * MORT; /* assuming DEMOCRACY now, much easier! - Syela */
  192.  
  193.   con = ptile->continent;
  194.  
  195. /* not worth the computations AFAICT -- Syela
  196.   city_list_iterate(pplayer->cities, acity)
  197.     if (city_got_building(acity, B_PYRAMIDS)) g++;
  198.   city_list_iterate_end;
  199. */
  200.  
  201.   memset(taken, 0, sizeof(taken));
  202.   memset(food, 0, sizeof(food));
  203.   memset(shield, 0, sizeof(shield));
  204.   memset(trade, 0, sizeof(trade));
  205.   memset(irrig, 0, sizeof(irrig));
  206.   memset(mine, 0, sizeof(mine));
  207.   memset(road, 0, sizeof(road));
  208.  
  209.   city_map_iterate(i, j) {
  210.     if ((minimap[map_adjust_x(x+i-2)][map_adjust_y(y+j-2)] >= 0 && !pcity) ||
  211.        (pcity && get_worker_city(pcity, i, j) == C_TILE_EMPTY)) {
  212.       ptile = map_get_tile(x+i-2, y+j-2);
  213.       con2 = ptile->continent;
  214.       ptype = get_tile_type(ptile->terrain);
  215.       food[i][j] = ((ptile->special&S_SPECIAL ? ptype->food_special : ptype->food) - 2) * MORT;
  216.       if (i == 2 && j == 2) food[i][j] += 2 * MORT;
  217.       if (ptype->irrigation_result == ptile->terrain && con2 == con) {
  218.         if (ptile->special&S_IRRIGATION || (i == 2 && j == 2)) irrig[i][j] = MORT;
  219.         else if (is_water_adjacent_to_tile(x+i-2, y+j-2) &&
  220.                  ptile->terrain != T_HILLS) irrig[i][j] = MORT - 9; /* KLUGE */
  221. /* all of these kluges are hardcoded amortize calls to save much CPU use -- Syela */
  222.       } else if (ptile->terrain == T_OCEAN && har) food[i][j] += MORT; /* harbor */
  223.       shield[i][j] = (ptile->special&S_SPECIAL ? ptype->shield_special : ptype->shield) * sh;
  224.       if (i == 2 && j == 2 && !shield[i][j]) shield[i][j] = sh;
  225.       if (ptile->terrain == T_OCEAN && har) shield[i][j] += sh;
  226. /* above line is not sufficiently tested.  AI was building on shores, but not
  227. as far out in the ocean as possible, which limits growth in the very long
  228. term (after SEWER).  These cities will all eventually have OFFSHORE, and
  229. I need to acknowledge that.  I probably shouldn't treat it as free, but
  230. that's the easiest, and I doubt pathological behavior will result. -- Syela */
  231.       if (ptile->special&S_MINE) mine[i][j] = (ptile->terrain == T_HILLS ? sh * 3 : sh);
  232.       else if (ptile->terrain == T_HILLS && con2 == con) mine[i][j] = sh * 3 - 300; /* KLUGE */
  233.       trade[i][j] =(ptile->special&S_SPECIAL ? ptype->trade_special : ptype->trade) * t;
  234.       if (ptile->terrain == T_DESERT || ptile->terrain == T_GRASSLAND ||
  235.         ptile->terrain == T_PLAINS) {
  236.         if (ptile->special&S_ROAD || (i == 2 && j == 2)) road[i][j] = t;
  237.         else if (con2 == con)
  238.           road[i][j] = t - 70; /* KLUGE */ /* actualy exactly 70 1/2 */
  239.       }
  240.       if (trade[i][j]) trade[i][j] += t;
  241.       else if (road[i][j]) road[i][j] += t;
  242.     }
  243.   }
  244.  
  245.   if (pcity) { /* quick-n-dirty immigration routine -- Syela */
  246.     n = pcity->size;
  247.     best = 0; ii = 0; jj = 0; /* blame -Wall -Werror for these */
  248.     city_map_iterate(i, j) {
  249.       cur = (food[i][j]) * food_weighting(n) + /* ignoring irrig on purpose */
  250.             (shield[i][j] + mine[i][j]) +
  251.             (trade[i][j] + road[i][j]);
  252.       if (cur > best && (i != 2 || j != 2)) { best = cur; ii = i; jj = j; }
  253.     }
  254.     if (!best) return(0);
  255.     val = (shield[ii][jj] + mine[ii][jj]) +
  256.           (food[ii][jj] + irrig[ii][jj]) * FOOD_WEIGHTING + /* seems to be needed */
  257.           (trade[ii][jj] + road[ii][jj]);
  258.     val -= amortize(40 * SHIELD_WEIGHTING + (50 - 20 * g) * FOOD_WEIGHTING, 12);
  259. /* 12 is arbitrary; need deterrent to represent loss of a settlers -- Syela */
  260. /*printf("Desire to immigrate to %s = %d -> %d\n", pcity->name, val,
  261. (val * 100) / MORT / 70);*/
  262.     return(val);
  263.   }
  264.  
  265.   f = food[2][2] + irrig[2][2];
  266.   if (!f) return(0); /* no starving cities, thank you! -- Syela */
  267.   val = f * FOOD_WEIGHTING + /* this needs to be here, strange as it seems */
  268.           (shield[2][2] + mine[2][2]) +
  269.           (trade[2][2] + road[2][2]);
  270.   taken[2][2]++;
  271.   /* val is mort times the real value */
  272.   /* treating harbor as free to approximate advantage of building boats. -- Syela */
  273.   val += (4 * (get_tile_type(map_get_tile(x, y)->terrain)->defense_bonus) - 40) * SHIELD_WEIGHTING;
  274. /* don't build cities in danger!! FIX! -- Syela */
  275.   val += 8 * MORT; /* one science per city */
  276. if (debug)
  277. printf("City value (%d, %d) = %d, har = %d, f = %d\n", x, y, val, har, f);
  278.  
  279.   for (n = 1; n <= 20 && f > 0; n++) {
  280.     for (a = 1; a; a--) {
  281.       best = 0; worst = -1; b2 = 0; i0 = 0; j0 = 0; ii = 0; jj = 0;
  282.       city_map_iterate(i, j) {
  283.         cur = (food[i][j]) * food_weighting(n) + /* ignoring irrig on purpose */
  284.               (shield[i][j] + mine[i][j]) +
  285.               (trade[i][j] + road[i][j]);
  286.         if (!taken[i][j]) {
  287.           if (cur > best) { b2 = best; best = cur; ii = i; jj = j; }
  288.           else if (cur > b2) b2 = cur;
  289.         } else if (i != 2 || j != 2) {
  290.           if (cur < worst || worst < 0) { worst = cur; i0 = i; j0 = j; }
  291.         }
  292.       }
  293.       if (!best) break;
  294.       cur = amortize((shield[ii][jj] + mine[ii][jj]) +
  295.             (food[ii][jj] + irrig[ii][jj]) * FOOD_WEIGHTING + /* seems to be needed */
  296.             (trade[ii][jj] + road[ii][jj]), d);
  297.       f += food[ii][jj] + irrig[ii][jj];
  298.       if (cur > 0) val += cur;
  299.       taken[ii][jj]++;
  300. if (debug)
  301. printf("Value of (%d, %d) = %d food = %d, type = %s, n = %d, d = %d\n",
  302.  ii, jj, cur, (food[ii][jj] + irrig[ii][jj]),
  303. get_tile_type(map_get_tile(x + ii - 2, y + jj - 2)->terrain)->terrain_name, n, d);
  304.  
  305. /* I hoped to avoid the following, but it seems I can't take ANY shortcuts
  306. in this unspeakable routine, so here comes even more CPU usage in order to
  307. get this EXACTLY right instead of just reasonably close. -- Syela */
  308.       if (worst < b2 && worst >= 0) {
  309.         cur = amortize((shield[i0][j0] + mine[i0][j0]) +
  310.               (trade[i0][j0] + road[i0][j0]), d);
  311.         f -= (food[i0][j0] + irrig[i0][j0]);
  312.         val -= cur;
  313.         taken[i0][j0]--;
  314.         a++;
  315. if (debug)
  316. printf("REJECTING Value of (%d, %d) = %d food = %d, type = %s, n = %d, d = %d\n",
  317.  i0, j0, cur, (food[i0][j0] + irrig[i0][j0]),
  318. get_tile_type(map_get_tile(x + i0 - 2, y + j0 - 2)->terrain)->terrain_name, n, d);
  319.       }
  320.     }
  321.     if (!best) break;
  322.     if (f > 0) d += (game.foodbox * MORT * n + (f*g) - 1) / (f*g);
  323.     if (n == 4) {
  324.       val -= amortize(40 * SHIELD_WEIGHTING + (50 - 20 * g) * FOOD_WEIGHTING, d); /* lers */
  325.       temp = amortize(40 * SHIELD_WEIGHTING, d); /* temple */
  326.       tmp = val;
  327.     }
  328.   } /* end while */
  329.   if (n > 4) {
  330.     if (val - temp > tmp) val -= temp;
  331.     else val = tmp;
  332.   }
  333.   val -= 110 * SHIELD_WEIGHTING; /* WAG: walls, defenders */
  334.   minimap[x][y] = val;
  335.  
  336. if (debug)
  337. printf("Total value of (%d, %d) [%d workers] = %d\n", x, y, n, val);
  338.   return(val);
  339. }
  340.  
  341. /**************************************************************************
  342. ...
  343. **************************************************************************/
  344. void ai_manage_settler(struct player *pplayer, struct unit *punit)
  345. {
  346.   punit->ai.control = 1;
  347.   if (punit->ai.ai_role == AIUNIT_NONE) /* if BUILD_CITY must remain BUILD_CITY */
  348.     punit->ai.ai_role = AIUNIT_AUTO_SETTLER;
  349. /* gonna handle city-building in the auto-settler routine -- Syela */
  350.   return;
  351. }
  352.  
  353. /*************************************************************************
  354.   returns dy according to the wrap rules
  355. **************************************************************************/
  356. int make_dy(int y1, int y2)
  357. {
  358.   int dy=y2-y1;
  359.   if (dy<0) dy=-dy;
  360.   return dy;
  361. }
  362.  
  363. /*************************************************************************
  364.   returns dx according to the wrap rules
  365. **************************************************************************/
  366. int make_dx(int x1, int x2)
  367. {
  368.   int tmp;
  369.   x1=map_adjust_x(x1);
  370.   x2=map_adjust_x(x2);
  371.   if(x1>x2)
  372.     tmp=x1, x1=x2, x2=tmp;
  373.  
  374.   return MIN(x2-x1, map.xsize-x2+x1);
  375. }
  376.  
  377. /**************************************************************************
  378.  return 1 if there is already a unit on this square or one destined for it 
  379.  (via goto)
  380. **************************************************************************/
  381. int is_already_assigned(struct unit *myunit, struct player *pplayer, int x, int y)
  382.   x=map_adjust_x(x);
  383.   y=map_adjust_y(y);
  384.   if (same_pos(myunit->x, myunit->y, x, y) || 
  385.       same_pos(myunit->goto_dest_x, myunit->goto_dest_y, x, y)) {
  386. /* I'm still not sure this is exactly right -- Syela */
  387.     unit_list_iterate(map_get_tile(x, y)->units, punit)
  388.       if (myunit==punit) continue;
  389.       if (punit->owner!=pplayer->player_no)
  390.         return 1;
  391.       if (unit_flag(punit->type, F_SETTLERS) && unit_flag(myunit->type, F_SETTLERS))
  392.         return 1;
  393.     unit_list_iterate_end;
  394.     return 0;
  395.   }
  396.   return(map_get_tile(x, y)->assigned & (1<<pplayer->player_no));
  397. }
  398.  
  399. int old_is_already_assigned(struct unit *myunit, struct player *pplayer, int x, int y)
  400. {
  401.   x=map_adjust_x(x);
  402.   y=map_adjust_y(y);
  403. #ifdef RIDICULOUS
  404.   if (same_pos(myunit->x, myunit->y, x, y))
  405.     return 0;
  406. #endif
  407.   unit_list_iterate(map_get_tile(x, y)->units, punit) {
  408.     if (myunit==punit) continue;
  409.     if (punit->owner!=pplayer->player_no)
  410.       return 1;
  411.     if (unit_flag(punit->type, F_SETTLERS) && unit_flag(myunit->type, F_SETTLERS))
  412.       return 1;
  413.   }
  414.   unit_list_iterate_end;
  415. #ifndef RIDICULOUS
  416.   if (same_pos(myunit->x, myunit->y, x, y))
  417.     return 0;
  418. #endif
  419.   unit_list_iterate(pplayer->units, punit) {
  420.     if (myunit==punit) continue;
  421.     if (punit->owner!=pplayer->player_no)
  422.       return 1;
  423.     if (same_pos(punit->goto_dest_x, punit->goto_dest_y, x, y) && unit_flag(punit->type, F_SETTLERS) && unit_flag(myunit->type,F_SETTLERS) && punit->activity==ACTIVITY_GOTO)
  424.       return 1;
  425.     if (same_pos(punit->goto_dest_x, punit->goto_dest_y, x, y) && !unit_flag(myunit->type, F_SETTLERS) && punit->activity==ACTIVITY_GOTO)
  426.       return 1;
  427.   }
  428.   unit_list_iterate_end;
  429.   return 0;
  430. }
  431.  
  432. /* all of the benefit and ai_calc routines rewritten by Syela */
  433. /* to conform with city_tile_value and related calculations elsewhere */
  434. /* all of these functions are VERY CPU-inefficient and are being cached */
  435. /* I don't really want to rewrite them and possibly screw them up. */
  436. /* The cache should keep the CPU increase linear instead of quadratic. -- Syela */
  437.  
  438. int ai_calc_pollution(struct city *pcity, struct player *pplayer, int i, int j)
  439. {
  440.   int x, y, m;
  441.   x = pcity->x + i - 2; y = pcity->y + j - 2;
  442.   if (!(map_get_special(x, y) & S_POLLUTION)) return(0);
  443.   map_clear_special(x, y, S_POLLUTION);
  444.   m = city_tile_value(pcity, i, j, 0, 0);
  445.   map_set_special(x, y, S_POLLUTION);
  446.   return(m);
  447. }
  448.  
  449. int is_wet(struct player *pplayer, int x, int y)
  450. {
  451.   if (!map_get_known(x, y, pplayer) && !pplayer->ai.control) return 0;
  452.   if (map_get_terrain(x,y) == T_OCEAN || map_get_terrain(x,y) == T_RIVER ||
  453.       map_get_special(x,y)&S_IRRIGATION) return 1;
  454.   return 0;
  455. }
  456.  
  457. int ai_calc_irrigate(struct city *pcity, struct player *pplayer, int i, int j)
  458. {
  459.   int x, y, m;
  460.   struct tile *ptile;
  461.   struct tile_type *type;
  462.   x = pcity->x + i - 2; y = pcity->y + j - 2;
  463.   ptile = map_get_tile(x, y);
  464.   type=get_tile_type(ptile->terrain);
  465.  
  466. /* changing terrain types?? */
  467.  
  468.   if((ptile->terrain==type->irrigation_result &&
  469.      !(ptile->special&S_IRRIGATION) &&
  470.      !(ptile->special&S_MINE) && !(ptile->city_id) &&
  471.      (is_wet(pplayer,x,y) || is_wet(pplayer,x,y-1) || is_wet(pplayer,x,y+1) ||
  472.      is_wet(pplayer,x-1,y) || is_wet(pplayer,x+1,y)))) {
  473.     map_set_special(x, y, S_IRRIGATION);
  474.     m = city_tile_value(pcity, i, j, 0, 0);
  475.     map_clear_special(x, y, S_IRRIGATION);
  476.     return(m);
  477.   } else return(0);
  478. }
  479.  
  480. int ai_calc_mine(struct city *pcity, struct player *pplayer, int i, int j)
  481. {
  482.   int x, y, m;
  483.   struct tile *ptile;
  484.   x = pcity->x + i - 2; y = pcity->y + j - 2;
  485.   ptile = map_get_tile(x, y);
  486. /* changing terrain types?? */
  487.   if ((ptile->terrain == T_HILLS || ptile->terrain == T_MOUNTAINS) &&
  488.       !(ptile->special&S_MINE)) {
  489.     map_set_special(x, y, S_MINE);
  490.     m = city_tile_value(pcity, i, j, 0, 0);
  491.     map_clear_special(x, y, S_MINE);
  492.     return(m);
  493.   } else return(0);
  494. }
  495.  
  496. int road_bonus(int x, int y, int spc)
  497. {
  498.   int m = 0, k;
  499.   int rd[12], te[12];
  500.   int ii[12] = { -1, 0, 1, -1, 1, -1, 0, 1, 0, -2, 2, 0 };
  501.   int jj[12] = { -1, -1, -1, 0, 0, 1, 1, 1, -2, 0, 0, 2 };
  502.   struct tile *ptile;
  503.   for (k = 0; k < 12; k++) {
  504.     ptile = map_get_tile(x + ii[k], y + jj[k]);
  505.     rd[k] = ptile->special&spc;
  506.     te[k] = (ptile->terrain == T_MOUNTAINS || ptile->terrain == T_OCEAN);
  507.     if (!rd[k]) {
  508.       unit_list_iterate(ptile->units, punit)
  509.         if (punit->activity == ACTIVITY_ROAD || punit->activity == ACTIVITY_RAILROAD)
  510.           rd[k] = spc;
  511.       unit_list_iterate_end;
  512.     }
  513.   }
  514.  
  515.   if (rd[0] && !rd[1] && !rd[3] && (!rd[2] || !rd[8]) &&
  516.       (!te[2] || !te[4] || !te[7] || !te[6] || !te[5])) m++;
  517.   if (rd[2] && !rd[1] && !rd[4] && (!rd[7] || !rd[10]) &&
  518.       (!te[0] || !te[3] || !te[7] || !te[6] || !te[5])) m++;
  519.   if (rd[5] && !rd[6] && !rd[3] && (!rd[5] || !rd[11]) &&
  520.       (!te[2] || !te[4] || !te[7] || !te[1] || !te[0])) m++;
  521.   if (rd[7] && !rd[6] && !rd[4] && (!rd[0] || !rd[9]) &&
  522.       (!te[2] || !te[3] || !te[0] || !te[1] || !te[5])) m++;
  523.  
  524.   if (rd[1] && !rd[4] && !rd[3] && (!te[5] || !te[6] || !te[7])) m++;
  525.   if (rd[3] && !rd[1] && !rd[6] && (!te[2] || !te[4] || !te[7])) m++;
  526.   if (rd[4] && !rd[1] && !rd[6] && (!te[0] || !te[3] || !te[5])) m++;
  527.   if (rd[6] && !rd[4] && !rd[3] && (!te[0] || !te[1] || !te[2])) m++;
  528.   return(m);
  529. }
  530.  
  531. int ai_calc_road(struct city *pcity, struct player *pplayer, int i, int j)
  532. {
  533.   int x, y, m;
  534.   struct tile *ptile;
  535.   x = pcity->x + i - 2; y = pcity->y + j - 2;
  536.   ptile = map_get_tile(x, y);
  537.   if (ptile->terrain != T_OCEAN && (ptile->terrain != T_RIVER ||
  538.       get_invention(pplayer, A_BRIDGE) == TECH_KNOWN) &&
  539.       !(ptile->special&S_ROAD)) {
  540.     ptile->special|=S_ROAD; /* have to do this to avoid reset_move_costs -- Syela */
  541.     m = city_tile_value(pcity, i, j, 0, 0);
  542.     ptile->special&=~S_ROAD;
  543.     return(m);
  544.   } else return(0);
  545. }
  546.  
  547. int ai_calc_railroad(struct city *pcity, struct player *pplayer, int i, int j)
  548. {
  549.   int x, y, m;
  550.   struct tile *ptile;
  551.   x = pcity->x + i - 2; y = pcity->y + j - 2;
  552.   ptile = map_get_tile(x, y);
  553.   if (ptile->terrain != T_OCEAN &&
  554.       get_invention(pplayer, A_RAILROAD) == TECH_KNOWN &&
  555.       !(ptile->special&S_RAILROAD)) {
  556.     if (ptile->special&S_ROAD) {
  557.       ptile->special|=S_RAILROAD;
  558.       m = city_tile_value(pcity, i, j, 0, 0);
  559.       ptile->special&=~S_RAILROAD;
  560.       return(m);
  561.     } else {
  562.       map_set_special(x, y, S_ROAD | S_RAILROAD);
  563.       m = city_tile_value(pcity, i, j, 0, 0);
  564.       map_clear_special(x, y, S_ROAD | S_RAILROAD);
  565.       return(m);
  566.     }
  567.   } else return(0);
  568. /* bonuses for adjacent railroad tiles */
  569. }
  570.  
  571. /*************************************************************************
  572.   return how good this square is for a new city.
  573. **************************************************************************/
  574. int is_ok_city_spot(int x, int y)
  575. {
  576.   int dx, dy;
  577.   int i;
  578.   switch (map_get_terrain(x,y)) {
  579.   case T_OCEAN:
  580.   case T_UNKNOWN:
  581.   case T_MOUNTAINS:
  582.   case T_FOREST:
  583.   case T_HILLS:
  584.   case T_ARCTIC:
  585.   case T_DESERT:
  586.   case T_JUNGLE:
  587.   case T_SWAMP:
  588.   case T_TUNDRA:
  589.   case T_LAST:
  590.     return 0;
  591.   case T_GRASSLAND:
  592.   case T_PLAINS:
  593.   case T_RIVER:
  594.     break;
  595.   default:
  596.     break;
  597.   }
  598.   for (i = 0; i < game.nplayers; i++) {
  599.     city_list_iterate(game.players[i].cities, pcity) {
  600.       if (map_distance(x, y, pcity->x, pcity->y)<=8) {
  601.         dx=make_dx(pcity->x, x);
  602.         dy=make_dy(pcity->y, y);
  603.         if (dx<=5 && dy<5)
  604.           return 0;
  605.         if (dx<5 && dy<=5)
  606.           return 0;
  607.       }
  608.     }
  609.     city_list_iterate_end;
  610.   }
  611.   return 1;
  612. }
  613.  
  614. /*************************************************************************
  615.   return the city if any that is in range of this square.
  616. **************************************************************************/
  617. int in_city_radius(int x, int y)
  618. {
  619.   int i, j;
  620.   city_map_iterate(i, j) {
  621.     if (map_get_tile(x+i-2, y+j-2)->city_id) return 1;
  622.   }
  623.   return 0;
  624. }
  625.  
  626. /**************************************************************************
  627.   simply puts the settler unit into goto
  628. **************************************************************************/
  629. int auto_settler_do_goto(struct player *pplayer, struct unit *punit, int x, int y)
  630. {
  631.   punit->goto_dest_x=map_adjust_x(x);
  632.   punit->goto_dest_y=map_adjust_y(y);
  633.   punit->activity=ACTIVITY_GOTO;
  634.   punit->activity_count=0;
  635.   send_unit_info(0, punit, 0);
  636.   do_unit_goto(pplayer, punit);
  637.   return 1;
  638. }
  639.  
  640. int find_boat(struct player *pplayer, int *x, int *y, int cap)
  641. { /* this function uses the current warmap, whatever it may hold */
  642. /* unit is no longer an arg!  we just trust the map! -- Syela */
  643.   int best = 22, id = 0; /* arbitrary maximum distance, I will admit! */
  644.   unit_list_iterate(pplayer->units, aunit)
  645.     if (get_transporter_capacity(aunit) &&
  646.         !unit_flag(aunit->type, F_CARRIER | F_SUBMARINE)) {
  647.       if (warmap.cost[aunit->x][aunit->y] < best &&
  648.           (warmap.cost[aunit->x][aunit->y] == 0 ||
  649.           is_transporter_with_free_space(pplayer, aunit->x, aunit->y) >= cap)) {
  650.         id = aunit->id;
  651.         best = warmap.cost[aunit->x][aunit->y];
  652.         *x = aunit->x;
  653.         *y = aunit->y;
  654.       }
  655.     }
  656.   unit_list_iterate_end;
  657.   if (id) return(id);
  658. #ifdef ALLOW_VIRTUAL_BOATS
  659.   city_list_iterate(pplayer->cities, pcity)
  660.     if (pcity->is_building_unit &&
  661.         unit_types[pcity->currently_building].transport_capacity &&
  662.         !unit_flag(pcity->currently_building, F_CARRIER | F_SUBMARINE)) {
  663.       if (warmap.cost[pcity->x][pcity->y] < best) {
  664.         id = pcity->id;
  665.         best = warmap.cost[pcity->x][pcity->y];
  666.         *x = pcity->x;
  667.         *y = pcity->y;
  668.       }
  669.     }
  670.   city_list_iterate_end;
  671. #endif
  672.   return(id);
  673. }
  674.  
  675. struct unit *other_passengers(struct unit *punit)
  676. {
  677.   unit_list_iterate(map_get_tile(punit->x, punit->y)->units, aunit)
  678.     if (is_ground_unit(aunit) && aunit != punit) return aunit;
  679.   unit_list_iterate_end;
  680.   return 0;
  681. }
  682.  
  683. /********************************************************************
  684.   find some work for the settler
  685. *********************************************************************/
  686. int auto_settler_findwork(struct player *pplayer, struct unit *punit)
  687. {
  688.   int gx,gy;
  689.   int co=map_get_continent(punit->x, punit->y);
  690.   int t=0, v=0, v2;
  691.   int x, y, z, i, j, ww = 99999; /* ww = 0 leads to v2=0 activities being OK */
  692.   int m = unit_types[punit->type].move_rate;
  693.   int food, val, w, a, b, d, fu;
  694.   struct city *mycity = map_get_city(punit->x, punit->y);
  695.   struct unit *ferryboat;
  696.   int boatid, bx, by;
  697.   int id = punit->id;
  698.   int near;
  699.   int nav = (get_invention(pplayer, A_NAVIGATION) == TECH_KNOWN);
  700.   struct ai_choice choice; /* for nav want only */
  701.  
  702.   choice.type = 1;
  703.   choice.choice = U_CARAVEL;
  704.   choice.want = 0; /* will change as needed */
  705.  
  706.   if (punit->id) fu = 30; /* fu is estimated food cost to produce settler -- Syela */
  707.   else {
  708.     if (mycity->size == 1) fu = 20;
  709.     else fu = 40 * (mycity->size - 1) / mycity->size;
  710.     if (city_got_building(mycity, B_GRANARY) ||
  711.         city_affected_by_wonder(mycity, B_PYRAMIDS)) fu -= 20;
  712.   }
  713.  
  714.   gx=-1;
  715.   gy=-1;
  716. /* iterating over the whole map is just ridiculous.  let's only look at
  717. our own cities.  The old method wasted billions of CPU cycles and led to
  718. AI settlers improving enemy cities. */ /* arguably should include city_spot */
  719.   generate_warmap(mycity, punit);
  720.   food = (get_government(pplayer->player_no) > G_COMMUNISM ? 2 : 1);
  721.   if (punit->id && !punit->homecity) food = 0; /* thanks, Peter */
  722.   city_list_iterate(pplayer->cities, pcity)
  723.     w = worst_worker_tile_value(pcity);
  724.     city_map_iterate(i, j) {
  725.       if (get_worker_city(pcity, i, j) == C_TILE_UNAVAILABLE) continue;
  726.       x = map_adjust_x(pcity->x + i - 2);
  727.       y = map_adjust_y(pcity->y + j - 2);
  728.       if (map_get_continent(x, y) == co &&
  729.           warmap.cost[x][y] <= THRESHOLD * m &&
  730.           !enemies_at(punit, x, y) && /* helps some, not nearly enough */
  731.           !is_already_assigned(punit, pplayer, x, y)) {
  732. /* calling is_already_assigned once instead of four times for obvious reasons */
  733. /* structure is much the same as it once was but subroutines are not -- Syela */
  734.     z = (warmap.cost[x][y]) / m;
  735.         val = city_tile_value(pcity, i, j, 0, 0);
  736.         if (w > val && (i != 2 || j != 2)) val = w;
  737. /* perhaps I should just subtract w rather than val but I prefer this -- Syela */
  738.  
  739.     v2 = pcity->ai.irrigate[i][j];
  740.         b = (v2 - val)<<6; /* arbitrary, for rounding errors */
  741.         if (b > 0) {
  742.           d = (map_build_irrigation_time(x, y) * 3 + m - 1) / m + z;
  743.           a = amortize(b, d);
  744.           v2 = ((a * b) / (MAX(1, b - a)))>>6;
  745.         } else v2 = 0;
  746.         if (v2>v || (v2 == v && val > ww)) {
  747. /*printf("Replacing (%d, %d) = %d with (%d, %d) I=%d d=%d, b=%d\n",
  748. gx, gy, v, x, y, v2, d, b);*/
  749.       t=ACTIVITY_IRRIGATE;
  750.       v=v2; gx=x; gy=y; ww=val;
  751.         }
  752.  
  753.     v2 = pcity->ai.mine[i][j];
  754.         b = (v2 - val)<<6; /* arbitrary, for rounding errors */
  755.         if (b > 0) {    
  756.           d = (map_build_mine_time(x, y) * 3 + m - 1) / m + z;
  757.           a = amortize(b, d);
  758.           v2 = ((a * b) / (MAX(1, b - a)))>>6;
  759.         } else v2 = 0;
  760.     if (v2>v || (v2 == v && val > ww)) {
  761. /*printf("Replacing (%d, %d) = %d with (%d, %d) M=%d d=%d, b=%d\n",
  762. gx, gy, v, x, y, v2, d, b);*/
  763.       t=ACTIVITY_MINE;
  764.       v=v2; gx=x; gy=y; ww=val;
  765.         }
  766.  
  767.         if (!(map_get_tile(x,y)->special&S_ROAD)) {
  768.         v2 = pcity->ai.road[i][j];
  769.           if (v2) v2 = MAX(v2, val) + road_bonus(x, y, S_ROAD) * 8;
  770. /* guessing about the weighting based on unit upkeeps; * 11 was too high! -- Syela */
  771.           b = (v2 - val)<<6; /* arbitrary, for rounding errors */
  772.           if (b > 0) {    
  773.             d = (map_build_road_time(x, y) * 3 + 3 + m - 1) / m + z; /* uniquely weird! */
  774.             a = amortize(b, d);
  775.             v2 = ((a * b) / (MAX(1, b - a)))>>6;
  776.           } else v2 = 0;
  777.           if (v2>v || (v2 == v && val > ww)) {
  778. /*printf("Replacing (%d, %d) = %d with (%d, %d) R=%d d=%d, b=%d\n",
  779. gx, gy, v, x, y, v2, d, b);*/
  780.         t=ACTIVITY_ROAD;
  781.         v=v2; gx=x; gy=y; ww=val;
  782.           }
  783.  
  784.       v2 = pcity->ai.railroad[i][j];
  785.           if (v2) v2 = MAX(v2, val) + road_bonus(x, y, S_RAILROAD) * 4;
  786.           b = (v2 - val)<<6; /* arbitrary, for rounding errors */
  787.           if (b > 0) {    
  788.             d = (3 * 3 + 3 * map_build_road_time(x,y) + 3 + m - 1) / m + z;
  789.             a = amortize(b, d);
  790.             v2 = ((a * b) / (MAX(1, b - a)))>>6;
  791.           } else v2 = 0;
  792.           if (v2>v || (v2 == v && val > ww)) {
  793.           t=ACTIVITY_ROAD;
  794.         v=v2; gx=x; gy=y; ww=val;
  795.           }
  796.         } else {
  797.       v2 = pcity->ai.railroad[i][j];
  798.           if (v2) v2 = MAX(v2, val) + road_bonus(x, y, S_RAILROAD) * 4;
  799.           b = (v2 - val)<<6; /* arbitrary, for rounding errors */
  800.           if (b > 0) {    
  801.             d = (3 * 3 + m - 1) / m + z;
  802.             a = amortize(b, d);
  803.             v2 = ((a * b) / (MAX(1, b - a)))>>6;
  804.           } else v2 = 0;
  805.           if (v2>v || (v2 == v && val > ww)) {
  806.           t=ACTIVITY_RAILROAD;
  807.         v=v2; gx=x; gy=y; ww=val;
  808.           }
  809.         } /* end else */
  810.  
  811.     v2 = pcity->ai.detox[i][j];
  812.         if (v2) v2 += pplayer->ai.warmth;
  813.         b = (v2 - val)<<6; /* arbitrary, for rounding errors */
  814.         if (b > 0) {    
  815.           d = (3 * 3 + z + m - 1) / m + z;
  816.           a = amortize(b, d);
  817.           v2 = ((a * b) / (MAX(1, b - a)))>>6;
  818.         } else v2 = 0;
  819.         if (v2>v || (v2 == v && val > ww)) {
  820.       t=ACTIVITY_POLLUTION;
  821.       v=v2; gx=x; gy=y; ww=val;
  822.         }
  823.       } /* end if we are a legal destination */
  824.     } /* end city map iterate */
  825.   city_list_iterate_end;
  826.  
  827.   v = (v - food * FOOD_WEIGHTING) * 100 / (40 + fu);
  828.   if (v < 0) v = 0; /* Bad Things happen without this line! :( -- Syela */
  829.  
  830.   boatid = find_boat(pplayer, &bx, &by, 1); /* might need 2 for body */
  831.   if ((ferryboat = unit_list_find(&(map_get_tile(punit->x, punit->y)->units), boatid)))
  832.     really_generate_warmap(mycity, ferryboat, SEA_MOVING);
  833.  
  834.   if (pplayer->ai.control) { /* don't want to make cities otherwise */
  835.     if (punit->ai.ai_role == AIUNIT_BUILD_CITY) {
  836.       remove_city_from_minimap(punit->goto_dest_x, punit->goto_dest_y);
  837.     }
  838.     punit->ai.ai_role = AIUNIT_AUTO_SETTLER; /* here and not before! -- Syela */
  839.     for (j = -11; j <= 11; j++) { /* hope this is far enough -- Syela */
  840.       y = punit->y + j;
  841.       if (y < 0 || y > map.ysize) continue;
  842.       for (i = -11; i <= 11; i++) {
  843.         x = map_adjust_x(punit->x + i);
  844.         w = 0;
  845.         near = (MAX((MAX(i, -i)),(MAX(j, -j))));
  846.         if (!is_already_assigned(punit, pplayer, x, y) &&
  847.             map_get_terrain(x, y) != T_OCEAN &&
  848.             (near < 8 || map_get_continent(x, y) != co)) {
  849.           if (ferryboat) { /* already aboard ship, can use real warmap */
  850.             if (!is_terrain_near_tile(x, y, T_OCEAN)) z = 9999;
  851.             else z = warmap.seacost[x][y] * m / unit_types[ferryboat->type].move_rate;
  852.           } else if (!goto_is_sane(pplayer, punit, x, y, 1)) {
  853.             if (!is_terrain_near_tile(x, y, T_OCEAN)) z = 9999;
  854.             else if (boatid) {
  855.               if (!punit->id && mycity->id == boatid) w = 1;
  856.               z = warmap.cost[bx][by] + real_map_distance(bx, by, x, y) + m;
  857.             } else if (punit->id || !is_terrain_near_tile(mycity->x,
  858.                         mycity->y, T_OCEAN)) z = 9999;
  859.             else {
  860.               z = warmap.seacost[x][y] * m / 9;  /* this should be fresh */
  861. /* the only thing that could have munged the seacost is the ferryboat code
  862. in k_s_w/f_s_t_k, but only if find_boat succeeded */
  863.               w = 1;
  864.             }
  865.           } else z = warmap.cost[x][y];
  866.           d = z / m;
  867. /* without this, the computer will go 6-7 tiles from X to build a city at Y */
  868.           d *= 2;
  869. /* and then build its NEXT city halfway between X and Y. -- Syela */
  870.           z = city_desirability(x, y);
  871.           v2 = amortize(z, d);
  872.           
  873.           b = (food * FOOD_WEIGHTING) * MORT;
  874.           if (map_get_continent(x, y) != co) b += SHIELD_WEIGHTING * MORT;
  875.           v2 -= (b - amortize(b, d));
  876. /* deal with danger Real Soon Now! -- Syela */
  877. /* v2 is now the value over mort turns */
  878.           v2 = (v2 * 100) / MORT / ((w ? 80 : 40) + fu);
  879.  
  880.           if (v && map_get_city(x, y)) v2 = 0;
  881. /* I added a line to discourage settling in existing cities, but it was
  882. inadequate.  It may be true that in the short-term building infrastructure
  883. on tiles that won't be worked for ages is not as useful as helping other
  884. cities grow and then building engineers later, but this is short-sighted.
  885. There was also a problem with workers suddenly coming onto unimproved tiles,
  886. either through city growth or de-elvisization, settlers being built and
  887. improving those tiles, and then immigrating shortly thereafter. -- Syela */
  888.  
  889. /*if (w) printf("%s: v = %d, w = 1, v2 = %d\n", mycity->name, v, v2);*/
  890.           if (map_get_continent(x, y) != co && !nav && near >= 8) {
  891.             if (v2 > choice.want && !punit->id) choice.want = v2;
  892. /*printf("%s@(%d, %d) city_des (%d, %d) = %d, v2 = %d, d = %d\n", 
  893. (punit->id ? unit_types[punit->type].name : mycity->name), 
  894. punit->x, punit->y, x, y, z, v2, d);*/
  895.           } else if (v2 > v) {
  896.             if (w) {
  897.               t = ACTIVITY_UNKNOWN; /* flag */
  898.               v = v2; gx = -1; gy = -1;
  899.             } else {
  900.               t = ACTIVITY_UNKNOWN; /* flag */
  901.               v = v2; gx = x; gy = y;
  902.             }
  903.           }
  904.         }
  905.       }
  906.     }
  907.   }
  908.  
  909.   choice.want -= v;
  910.   if (choice.want > 0) ai_choose_ferryboat(pplayer, mycity, &choice);
  911.  
  912. /*if (map_get_terrain(punit->x, punit->y) == T_OCEAN)
  913. printf("Punit %d@(%d,%d) wants to %d at (%d,%d) with desire %d\n",
  914. punit->id, punit->x, punit->y, t, gx, gy, v);*/
  915. /* I had the return here, but it led to stupidity where several engineers would
  916. be built to solve one problem.  Moving the return down will solve this. -- Syela */
  917.  
  918.   if (gx!=-1 && gy!=-1) {
  919.       map_get_tile(gx, gy)->assigned =
  920.         map_get_tile(gx, gy)->assigned | 1<<pplayer->player_no;
  921.   }
  922.  
  923.   if (!punit->id) { /* has to be before we try to send_unit_info()! -- Syela */
  924. /*    printf("%s (%d, %d) settler-want = %d, task = %d, target = (%d, %d)\n",
  925.       mycity->name, mycity->x, mycity->y, v, t, gx, gy);*/
  926.     if (gx < 0 && gy < 0) return(0 - v);
  927.     return(v); /* virtual unit for assessing settler want */
  928.   }
  929.  
  930.   if (gx!=-1 && gy!=-1) {
  931.     if (t == ACTIVITY_UNKNOWN) {
  932.       punit->ai.ai_role = AIUNIT_BUILD_CITY;
  933.       add_city_to_minimap(gx, gy);
  934.     } else punit->ai.ai_role = AIUNIT_AUTO_SETTLER;
  935.     if (!same_pos(gx, gy, punit->x, punit->y)) {
  936.       if (!goto_is_sane(pplayer, punit, gx, gy, 1) ||
  937.           (ferryboat && goto_is_sane(pplayer, ferryboat, gx, gy, 1) &&
  938.           (!is_tiles_adjacent(punit->x, punit->y, gx, gy) ||
  939.            !could_unit_move_to_tile(punit, punit->x, punit->y, gx,gy)))) {
  940.         punit->ai.ferryboat = find_boat(pplayer, &x, &y, 1); /* might need 2 */
  941. /*printf("%d@(%d, %d): Looking for BOAT.\n", punit->id, punit->x, punit->y);*/
  942.         if (!same_pos(x, y, punit->x, punit->y)) {
  943.           auto_settler_do_goto(pplayer, punit, x, y);
  944.           if (!unit_list_find(&pplayer->units, id)) return(0); /* died */
  945.         }
  946.         ferryboat = unit_list_find(&(map_get_tile(punit->x, punit->y)->units),
  947.                    punit->ai.ferryboat);
  948.         punit->goto_dest_x = gx;
  949.         punit->goto_dest_y = gy;
  950.         if (ferryboat && (!ferryboat->ai.passenger ||
  951.             ferryboat->ai.passenger == punit->id)) {
  952. /*printf("We have FOUND BOAT, %d ABOARD %d@(%d,%d)->(%d,%d).\n", punit->id,
  953. ferryboat->id, punit->x, punit->y, gx, gy);*/
  954.           set_unit_activity(punit, ACTIVITY_SENTRY); /* kinda cheating -- Syela */
  955.           ferryboat->ai.passenger = punit->id;
  956.           auto_settler_do_goto(pplayer, ferryboat, gx, gy);
  957.           set_unit_activity(punit, ACTIVITY_IDLE);
  958.         } /* need to zero pass & ferryboat at some point. */
  959.       }
  960.       if (goto_is_sane(pplayer, punit, gx, gy, 1) && punit->moves_left &&
  961.          ((!ferryboat) || other_passengers(punit) ||
  962.           is_tiles_adjacent(punit->x, punit->y, gx, gy))) {
  963. /* Two settlers on a boat led to boats yo-yoing back and forth.
  964. Therefore we need to let them disembark at this point. -- Syela */
  965.         auto_settler_do_goto(pplayer, punit, gx, gy);
  966.         if (!unit_list_find(&pplayer->units, id)) return(0); /* died */
  967.         punit->ai.ferryboat = 0;
  968.       }
  969.     }
  970.   } else punit->ai.control=0;
  971.  
  972.   if (punit->ai.control && punit->moves_left && punit->activity == ACTIVITY_IDLE) {
  973. /* if players can build with 0 moves left, so should the AI */
  974.     if (same_pos(gx, gy, punit->x, punit->y)) {
  975.       if (t == ACTIVITY_UNKNOWN) {
  976.         remove_city_from_minimap(gx, gy); /* yeah, I know. -- Syela */
  977.         ai_do_build_city(pplayer, punit);
  978.         return(0);
  979.       }
  980.       set_unit_activity(punit, t);
  981.       send_unit_info(0, punit, 0);
  982.       return(0);
  983.     }
  984.   }
  985.   return(0);
  986. }
  987.  
  988. void initialize_infrastructure_cache(struct city *pcity)
  989. {
  990.   int i, j;
  991.   struct player *pplayer = &game.players[pcity->owner];
  992.   city_map_iterate(i, j) {
  993.     pcity->ai.detox[i][j] = ai_calc_pollution(pcity, pplayer, i, j);
  994.     pcity->ai.mine[i][j] = ai_calc_mine(pcity, pplayer, i, j);
  995.     pcity->ai.irrigate[i][j] = ai_calc_irrigate(pcity, pplayer, i, j);
  996.     pcity->ai.road[i][j] = ai_calc_road(pcity, pplayer, i, j);
  997. /* gonna handle road_bo dynamically for now since it can change
  998. as punits arrive at adjacent tiles and start laying road -- Syela */
  999.     pcity->ai.railroad[i][j] = ai_calc_railroad(pcity, pplayer, i, j);
  1000.   }
  1001. }
  1002.  
  1003. /************************************************************************** 
  1004.   run through all the players settlers and let those on ai.control work 
  1005.   automagically
  1006. **************************************************************************/
  1007. void auto_settlers_player(struct player *pplayer) 
  1008. {
  1009. #ifdef CHRONO
  1010.   int sec, usec;
  1011.   struct timeval tv;
  1012.   gettimeofday(&tv, 0);
  1013.   sec = tv.tv_sec; usec = tv.tv_usec; 
  1014. #endif
  1015.   city_list_iterate(pplayer->cities, pcity)
  1016.     initialize_infrastructure_cache(pcity); /* saves oodles of time -- Syela */
  1017.   city_list_iterate_end;
  1018.   pplayer->ai.warmth = WARMING_FACTOR * total_player_citizens(pplayer) * 10 *
  1019.                        (game.globalwarming + game.heating) / (map.xsize *
  1020.                         map.ysize * map.landpercent * 2); /* threat of warming */
  1021. /*printf("Warmth = %d, game.globalwarming=%d\n", pplayer->ai.warmth, game.globalwarming);*/
  1022.   unit_list_iterate(pplayer->units, punit) {
  1023. /* printf("%s's settler at (%d, %d)\n", pplayer->name, punit->x, punit->y); */
  1024.     if (punit->ai.control) {
  1025. /* printf("Is ai controlled.\n");*/
  1026.       if(punit->activity == ACTIVITY_SENTRY)
  1027.     set_unit_activity(punit, ACTIVITY_IDLE);
  1028.       if (punit->activity == ACTIVITY_GOTO && punit->moves_left)
  1029.         set_unit_activity(punit, ACTIVITY_IDLE);
  1030.       if (punit->activity == ACTIVITY_IDLE)
  1031.     auto_settler_findwork(pplayer, punit);
  1032. /* printf("Has been processed.\n"); */
  1033.     }
  1034.   }
  1035.   unit_list_iterate_end;
  1036. #ifdef CHRONO
  1037.   gettimeofday(&tv, 0);
  1038.   printf("%s's autosettlers consumed %d microseconds.\n", pplayer->name, 
  1039.        (tv.tv_sec - sec) * 1000000 + (tv.tv_usec - usec));
  1040. #endif
  1041. }
  1042.  
  1043. void assign_settlers_player(struct player *pplayer)
  1044. {
  1045.   short i = 1<<pplayer->player_no;
  1046.   struct tile *ptile;
  1047.   unit_list_iterate(pplayer->units, punit)
  1048.     if (unit_flag(punit->type, F_SETTLERS)) {
  1049.       if (punit->activity == ACTIVITY_GOTO) {
  1050.         ptile = map_get_tile(punit->goto_dest_x, punit->goto_dest_y);
  1051.         ptile->assigned = ptile->assigned | i; /* assigned for us only */
  1052.       } else {
  1053.         ptile = map_get_tile(punit->x, punit->y);
  1054.         ptile->assigned = 32767; /* assigned for everyone */
  1055.       }
  1056.     } else {
  1057.       ptile = map_get_tile(punit->x, punit->y);
  1058.       ptile->assigned = ptile->assigned | (32767 ^ i); /* assigned for everyone else */
  1059.     }
  1060.   unit_list_iterate_end;
  1061. }
  1062.  
  1063. void assign_settlers()
  1064. {
  1065.   int i, x, y;
  1066.   for (x = 0; x < map.xsize; x++)
  1067.     for (y = 0; y < map.xsize; y++)
  1068.       map_get_tile(x, y)->assigned = 0;
  1069.  
  1070.   for (i = 0; i < game.nplayers; i++) {
  1071.     assign_settlers_player(&game.players[i]);
  1072.   }
  1073. }
  1074.  
  1075. /**************************************************************************
  1076.   Do the auto_settler stuff for all the players. 
  1077.   TODO: This should be moved into the update_player loop i think
  1078. **************************************************************************/
  1079. void auto_settlers()
  1080. {
  1081.   int i;
  1082.   assign_settlers();
  1083.   for (i = 0; i < game.nplayers; i++) {
  1084.     auto_settlers_player(&game.players[i]);
  1085.   }
  1086. }
  1087.  
  1088. void contemplate_settling(struct player *pplayer, struct city *pcity)
  1089. {
  1090.   struct unit virtualunit;
  1091.   int want;
  1092. /* used to use old crappy formulas for settler want, but now using actual want! */
  1093.   memset(&virtualunit, 0, sizeof(struct unit));
  1094.   virtualunit.id = 0;
  1095.   virtualunit.owner = pplayer->player_no;
  1096.   virtualunit.x = pcity->x;
  1097.   virtualunit.y = pcity->y;
  1098.   virtualunit.type = (can_build_unit(pcity, U_ENGINEERS) ? U_ENGINEERS : U_SETTLERS);
  1099.   virtualunit.moves_left = unit_types[virtualunit.type].move_rate;
  1100.   virtualunit.hp = 20;  
  1101.   want = auto_settler_findwork(pplayer, &virtualunit);
  1102.   unit_list_iterate(pplayer->units, qpass)
  1103.     if (qpass->ai.ferryboat == pcity->id) want = -199;
  1104.   unit_list_iterate_end;
  1105.   pcity->ai.settler_want = want;
  1106. }
  1107.