~ubuntu-branches/ubuntu/natty/freeciv/natty-proposed

« back to all changes in this revision

Viewing changes to server/settlers.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100223220902-s3spqi1x4e190y0t
Tags: 2.2.0-1
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include <stdio.h>
21
21
#include <string.h>
22
22
 
 
23
/* utility */
23
24
#include "log.h"
24
25
#include "mem.h"
25
26
#include "support.h"
26
27
#include "timing.h"
27
28
 
 
29
/* common */
28
30
#include "city.h"
29
31
#include "game.h"
30
32
#include "government.h"
33
35
#include "packets.h"
34
36
#include "unitlist.h"
35
37
 
36
 
#include "citytools.h"
37
 
#include "gotohand.h"
38
 
#include "maphand.h"
39
 
#include "plrhand.h"
40
 
#include "settlers.h"
41
 
#include "unithand.h"
42
 
#include "unittools.h"
 
38
/* aicore */
 
39
#include "citymap.h"
 
40
#include "path_finding.h"
 
41
#include "pf_tools.h"
43
42
 
 
43
/* ai */
44
44
#include "aicity.h"
45
45
#include "aidata.h"
46
46
#include "ailog.h"
47
47
#include "aisettler.h"
48
48
#include "aitools.h"
49
49
#include "aiunit.h"
50
 
#include "citymap.h"
 
50
 
 
51
/* server */
 
52
#include "citytools.h"
 
53
#include "maphand.h"
 
54
#include "plrhand.h"
 
55
#include "unithand.h"
 
56
#include "unittools.h"
 
57
 
 
58
#include "settlers.h"
51
59
 
52
60
/* This factor is multiplied on when calculating the want.  This is done
53
61
 * to avoid rounding errors in comparisons when looking for the best
77
85
  struct city *pcity;
78
86
 
79
87
  assert(pplayer == unit_owner(punit));
80
 
  handle_unit_activity_request(punit, ACTIVITY_IDLE);
 
88
  unit_activity_handling(punit, ACTIVITY_IDLE);
81
89
 
82
90
  /* Free city reservations */
83
91
  ai_unit_new_role(punit, AIUNIT_NONE, NULL);
84
92
 
85
 
  pcity = tile_get_city(ptile);
 
93
  pcity = tile_city(ptile);
86
94
  if (pcity) {
87
95
    /* This can happen for instance when there was hut at this tile
88
96
     * and it turned in to a city when settler entered tile. */
93
101
  }
94
102
  handle_unit_build_city(pplayer, punit->id,
95
103
                         city_name_suggestion(pplayer, ptile));
96
 
  pcity = tile_get_city(ptile);
 
104
  pcity = tile_city(ptile);
97
105
  if (!pcity) {
98
106
    freelog(LOG_ERROR, "%s: Failed to build city at (%d, %d)", 
99
107
            player_name(pplayer),
108
116
  initialize_infrastructure_cache(pplayer);
109
117
 
110
118
  /* Init ai.choice. Handling ferryboats might use it. */
111
 
  init_choice(&pcity->ai.choice);
 
119
  init_choice(&pcity->ai->choice);
112
120
 
113
121
  return TRUE;
114
122
}
148
156
 
149
157
  FIXME: foodneed and prodneed are always 0.
150
158
**************************************************************************/
151
 
int city_tile_value(struct city *pcity, int x, int y, 
152
 
                    int foodneed, int prodneed)
 
159
static int city_tile_value(struct city *pcity, struct tile *ptile,
 
160
                           int foodneed, int prodneed)
153
161
{
154
 
  int food = city_get_output_tile(x, y, pcity, O_FOOD);
155
 
  int shield = city_get_output_tile(x, y, pcity, O_SHIELD);
156
 
  int trade = city_get_output_tile(x, y, pcity, O_TRADE);
 
162
  int food = city_tile_output_now(pcity, ptile, O_FOOD);
 
163
  int shield = city_tile_output_now(pcity, ptile, O_SHIELD);
 
164
  int trade = city_tile_output_now(pcity, ptile, O_TRADE);
157
165
  int value = 0;
158
166
 
159
167
  /* Each food, trade, and shield gets a certain weighting.  We also benefit
195
203
    return -1;
196
204
  }
197
205
  tile_clear_special(ptile, S_POLLUTION);
198
 
  goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
206
  goodness = city_tile_value(pcity, ptile, 0, 0);
199
207
  tile_set_special(ptile, S_POLLUTION);
200
208
 
201
209
  /* FIXME: need a better way to guarantee pollution is cleaned up. */
225
233
    return -1;
226
234
  }
227
235
  tile_clear_special(ptile, S_FALLOUT);
228
 
  goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
236
  goodness = city_tile_value(pcity, ptile, 0, 0);
229
237
  tile_set_special(ptile, S_FALLOUT);
230
238
 
231
239
  /* FIXME: need a better way to guarantee fallout is cleaned up. */
232
 
  if (!pplayer->ai.control) {
 
240
  if (!pplayer->ai_data.control) {
233
241
    goodness = (goodness + best + 50) * 2;
234
242
  }
235
243
 
247
255
static bool is_wet(struct player *pplayer, struct tile *ptile)
248
256
{
249
257
  /* FIXME: this should check a handicap. */
250
 
  if (!pplayer->ai.control && !map_is_known(ptile, pplayer)) {
 
258
  if (!pplayer->ai_data.control && !map_is_known(ptile, pplayer)) {
251
259
    return FALSE;
252
260
  }
253
261
 
254
 
  if (is_ocean(ptile->terrain)) {
 
262
  if (is_ocean_tile(ptile)) {
255
263
    /* TODO: perhaps salt water should not be usable for irrigation? */
256
264
    return TRUE;
257
265
  }
304
312
                            int city_x, int city_y, struct tile *ptile)
305
313
{
306
314
  int goodness;
307
 
  struct terrain *old_terrain = ptile->terrain;
 
315
  struct terrain *old_terrain = tile_terrain(ptile);
308
316
  bv_special old_special = ptile->special;
309
317
  struct terrain *new_terrain = old_terrain->irrigation_result;
310
318
 
311
319
  if (old_terrain != new_terrain && new_terrain != T_NONE) {
312
320
    /* Irrigation would change the terrain type, clearing the mine
313
321
     * in the process.  Calculate the benefit of doing so. */
314
 
    if (ptile->city && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
 
322
    if (tile_city(ptile) && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
315
323
      return -1;
316
324
    }
317
325
    tile_change_terrain(ptile, new_terrain);
318
326
    tile_clear_special(ptile, S_MINE);
319
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
320
 
    ptile->terrain = old_terrain;
 
327
    goodness = city_tile_value(pcity, ptile, 0, 0);
 
328
    tile_set_terrain(ptile, old_terrain);
321
329
    ptile->special = old_special;
322
330
    return goodness;
323
331
  } else if (old_terrain == new_terrain
328
336
     * the benefit of doing so. */
329
337
    tile_clear_special(ptile, S_MINE);
330
338
    tile_set_special(ptile, S_IRRIGATION);
331
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
339
    goodness = city_tile_value(pcity, ptile, 0, 0);
332
340
    ptile->special = old_special;
333
 
    assert(ptile->terrain == old_terrain);
 
341
    assert(tile_terrain(ptile) == old_terrain);
334
342
    return goodness;
335
343
  } else if (old_terrain == new_terrain
336
344
             && tile_has_special(ptile, S_IRRIGATION)
341
349
     * S_FARMLAND on it.  Calculate the benefit of doing so. */
342
350
    assert(!tile_has_special(ptile, S_MINE));
343
351
    tile_set_special(ptile, S_FARMLAND);
344
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
352
    goodness = city_tile_value(pcity, ptile, 0, 0);
345
353
    tile_clear_special(ptile, S_FARMLAND);
346
 
    assert(ptile->terrain == old_terrain
 
354
    assert(tile_terrain(ptile) == old_terrain
347
355
           && memcmp(&ptile->special, &old_special,
348
356
                     sizeof(old_special)) == 0);
349
357
    return goodness;
368
376
                        int city_x, int city_y, struct tile *ptile)
369
377
{
370
378
  int goodness;
371
 
  struct terrain *old_terrain = ptile->terrain;
 
379
  struct terrain *old_terrain = tile_terrain(ptile);
372
380
  bv_special old_special = ptile->special;
373
381
  struct terrain *new_terrain = old_terrain->mining_result;
374
382
 
375
383
  if (old_terrain != new_terrain && new_terrain != T_NONE) {
376
384
    /* Mining would change the terrain type, clearing the irrigation
377
385
     * in the process.  Calculate the benefit of doing so. */
378
 
    if (ptile->city && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
 
386
    if (tile_city(ptile) && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
379
387
      return -1;
380
388
    }
381
389
    tile_change_terrain(ptile, new_terrain);
382
390
    tile_clear_special(ptile, S_IRRIGATION);
383
391
    tile_clear_special(ptile, S_FARMLAND);
384
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
385
 
    ptile->terrain = old_terrain;
 
392
    goodness = city_tile_value(pcity, ptile, 0, 0);
 
393
    tile_set_terrain(ptile, old_terrain);
386
394
    ptile->special = old_special;
387
395
    return goodness;
388
396
  } else if (old_terrain == new_terrain
393
401
    tile_clear_special(ptile, S_IRRIGATION);
394
402
    tile_clear_special(ptile, S_FARMLAND);
395
403
    tile_set_special(ptile, S_MINE);
396
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
404
    goodness = city_tile_value(pcity, ptile, 0, 0);
397
405
    ptile->special = old_special;
398
 
    assert(ptile->terrain == old_terrain);
 
406
    assert(tile_terrain(ptile) == old_terrain);
399
407
    return goodness;
400
408
  } else {
401
409
    return -1;
419
427
                             int city_x, int city_y, struct tile *ptile)
420
428
{
421
429
  int goodness;
422
 
  struct terrain *old_terrain = ptile->terrain;
 
430
  struct terrain *old_terrain = tile_terrain(ptile);
423
431
  bv_special old_special = ptile->special;
424
432
  struct terrain *new_terrain = old_terrain->transform_result;
425
433
 
438
446
    return -1;
439
447
  }
440
448
 
441
 
  if (ptile->city && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
 
449
  if (tile_city(ptile) && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
442
450
    return -1;
443
451
  }
444
452
 
445
453
  tile_change_terrain(ptile, new_terrain);
446
 
  goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
454
  goodness = city_tile_value(pcity, ptile, 0, 0);
447
455
 
448
 
  ptile->terrain = old_terrain;
 
456
  tile_set_terrain(ptile, old_terrain);
449
457
  ptile->special = old_special;
450
458
 
451
459
  return goodness;
475
483
      has_road[i] = FALSE;
476
484
      is_slow[i] = FALSE; /* FIXME: should be TRUE? */
477
485
    } else {
478
 
      struct terrain *pterrain = tile1->terrain;
 
486
      struct terrain *pterrain = tile_terrain(tile1);
479
487
 
480
488
      has_road[i] = tile_has_special(tile1, special);
481
489
 
594
602
{
595
603
  int goodness;
596
604
 
597
 
  if (!is_ocean(ptile->terrain)
 
605
  if (!is_ocean_tile(ptile)
598
606
      && (!tile_has_special(ptile, S_RIVER)
599
607
          || player_knows_techs_with_flag(pplayer, TF_BRIDGE))
600
608
      && !tile_has_special(ptile, S_ROAD)) {
604
612
    assert(!tile_has_special(ptile, S_ROAD));
605
613
    set_special(&ptile->special, S_ROAD);
606
614
 
607
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
615
    goodness = city_tile_value(pcity, ptile, 0, 0);
608
616
 
609
617
    clear_special(&ptile->special, S_ROAD);
610
618
 
636
644
  int goodness;
637
645
  bv_special old_special;
638
646
 
639
 
  if (!is_ocean(ptile->terrain)
 
647
  if (!is_ocean_tile(ptile)
640
648
      && player_knows_techs_with_flag(pplayer, TF_RAILROAD)
641
649
      && !tile_has_special(ptile, S_RAILROAD)) {
642
650
    old_special = ptile->special;
646
654
    set_special(&ptile->special, S_ROAD);
647
655
    set_special(&ptile->special, S_RAILROAD);
648
656
 
649
 
    goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
657
    goodness = city_tile_value(pcity, ptile, 0, 0);
650
658
 
651
659
    ptile->special = old_special;
652
660
 
656
664
  }
657
665
}
658
666
 
659
 
/**************************************************************************
660
 
  Tries to find a boat for our unit. Requires warmap to be initialized
661
 
  with respect to x, y. cap is the requested capacity on the transport.
662
 
  Note that it may return a transport with less than cap capacity if this
663
 
  transport has zero move cost to x, y.
664
 
 
665
 
  The "virtual boats" code is not used. It is probably too unreliable, 
666
 
  since the AI switches its production back and forth continously.
667
 
 
668
 
  FIXME: if there is a (free) boat in a city filled with units, 
669
 
  ground_unit_transporter_capacity will return negative.
670
 
  TODO: Kill me.  There is a reliable version of this, find_ferry.
671
 
**************************************************************************/
672
 
Unit_type_id find_boat(struct player *pplayer, struct tile **ptile, int cap)
673
 
{
674
 
  int best = 22; /* arbitrary maximum distance, I will admit! */
675
 
  Unit_type_id id = 0;
676
 
  unit_list_iterate(pplayer->units, aunit)
677
 
    if (is_ground_units_transport(aunit)) {
678
 
      if (WARMAP_COST(aunit->tile) < best &&
679
 
          (WARMAP_COST(aunit->tile) == 0 ||
680
 
           ground_unit_transporter_capacity(aunit->tile,
681
 
                                            pplayer) >= cap)) {
682
 
        id = aunit->id;
683
 
        best = WARMAP_COST(aunit->tile);
684
 
        *ptile = aunit->tile;
685
 
      }
686
 
    }
687
 
  unit_list_iterate_end;
688
 
  if (id != 0) return(id);
689
 
  return(id);
690
 
}
691
 
 
692
 
/**************************************************************************
693
 
  Returns TRUE if there are (other) ground units than punit stacked on
694
 
  punit's tile.
695
 
**************************************************************************/
696
 
struct unit *other_passengers(struct unit *punit)
697
 
{
698
 
  unit_list_iterate(punit->tile->units, aunit)
699
 
    if (is_ground_unit(aunit) && aunit != punit) return aunit;
700
 
  unit_list_iterate_end;
701
 
  return NULL;
702
 
}
703
 
 
704
667
/****************************************************************************
705
 
  Compares the best known tile improvement action with improving the tile
706
 
  at (x,y) with activity act.  Calculates the value of improving the tile
707
 
  by discounting the total value by the time it would take to do the work
 
668
  Compares the best known tile improvement action with improving ptile
 
669
  with activity act.  Calculates the value of improving the tile by
 
670
  discounting the total value by the time it would take to do the work
708
671
  and multiplying by some factor.
709
672
****************************************************************************/
710
 
static void consider_settler_action(struct player *pplayer, 
 
673
static void consider_settler_action(const struct player *pplayer, 
711
674
                                    enum unit_activity act, int extra, 
712
675
                                    int new_tile_value, int old_tile_value,
713
 
                                    bool in_use, int move_turns, int delay,
714
 
                                    int *best_value,
715
 
                                    int *best_old_tile_value,
716
 
                                    int *best_move_turns,
717
 
                                    enum unit_activity *best_act,
718
 
                                    struct tile **best_tile,
 
676
                                    bool in_use, int delay,
 
677
                                    int *best_value,
 
678
                                    int *best_old_tile_value,
 
679
                                    enum unit_activity *best_act,
 
680
                                    struct tile **best_tile,
719
681
                                    struct tile *ptile)
720
682
{
721
683
  bool consider;
756
718
    *best_old_tile_value = old_tile_value;
757
719
    *best_act = act;
758
720
    *best_tile = ptile;
759
 
    *best_move_turns = move_turns;
760
721
  }
761
722
}
762
723
 
774
735
 
775
736
  if (punit->id == 0) {
776
737
    /* It is a virtual unit, so must start in a city... */
777
 
    struct city *pcity = tile_get_city(punit->tile);
 
738
    struct city *pcity = tile_city(punit->tile);
778
739
 
779
740
    /* The default is to lose 100%.  The growth bonus reduces this. */
780
741
    int foodloss_pct = 100 - get_city_bonus(pcity, EFT_GROWTH_FOOD);
794
755
static int unit_food_upkeep(struct unit *punit)
795
756
{
796
757
  struct player *pplayer = unit_owner(punit);
797
 
  int upkeep = utype_upkeep_cost(unit_type(punit), pplayer,
798
 
                                 government_of_player(pplayer), O_FOOD);
 
758
  int upkeep = utype_upkeep_cost(unit_type(punit), pplayer, O_FOOD);
799
759
  if (punit->id != 0 && punit->homecity == 0)
800
760
    upkeep = 0; /* thanks, Peter */
801
761
 
802
762
  return upkeep;
803
763
}
804
764
 
 
765
/**************************************************************************
 
766
  Don't enter in enemy territories.
 
767
**************************************************************************/
 
768
static bool autosettler_enter_territory(const struct player *pplayer,
 
769
                                        const struct tile *ptile)
 
770
{
 
771
  const struct player *owner = tile_owner(ptile);
 
772
 
 
773
  return (NULL == owner
 
774
          || pplayers_allied(owner, pplayer));
 
775
}
 
776
 
805
777
/****************************************************************************
806
778
  Finds tiles to improve, using punit.
807
779
 
808
780
  The returned value is the goodness of the best tile and action found.  If
809
 
  this return value is >0, then (gx,gy) indicates the tile chosen and bestact
810
 
  indicates the activity it wants to do.  If 0 is returned then there are no
811
 
  worthwhile activities available.
 
781
  this return value is > 0, then best_tile indicates the tile chosen,
 
782
  bestact indicates the activity it wants to do, and path (if not NULL)
 
783
  indicates the path to follow for the unit.  If 0 is returned
 
784
  then there are no worthwhile activities available.
812
785
 
813
786
  completion_time is the time that would be taken by punit to travel to
814
787
  and complete work at best_tile
819
792
  if this array is NULL, workers are never displaced.
820
793
****************************************************************************/
821
794
static int evaluate_improvements(struct unit *punit,
822
 
                                 enum unit_activity *best_act,
823
 
                                 struct tile **best_tile,
824
 
                                 int *travel_time,
825
 
                                 struct settlermap *state)
 
795
                                 enum unit_activity *best_act,
 
796
                                 struct tile **best_tile,
 
797
                                 struct pf_path **path,
 
798
                                 struct settlermap *state)
826
799
{
827
 
  struct city *mycity = tile_get_city(punit->tile);
828
 
  struct player *pplayer = unit_owner(punit);
829
 
  bool in_use;                  /* true if the target square is being used
830
 
                                   by one of our cities */
831
 
  Continent_id ucont     = tile_get_continent(punit->tile);
832
 
  int mv_rate         = unit_type(punit)->move_rate;
833
 
  int mv_turns;                 /* estimated turns to move to target square */
834
 
  int oldv;                     /* current value of consideration tile */
835
 
  int best_oldv = 9999;         /* oldv of best target so far; compared if
836
 
                                   newv==best_newv; not initialized to zero,
837
 
                                   so that newv=0 activities are not chosen */
 
800
  const struct player *pplayer = unit_owner(punit);
 
801
  struct pf_parameter parameter;
 
802
  struct pf_map *pfm;
 
803
  struct pf_position pos;
 
804
  int oldv;             /* Current value of consideration tile. */
 
805
  int best_oldv = 9999; /* oldv of best target so far; compared if
 
806
                         * newv == best_newv; not initialized to zero,
 
807
                         * so that newv = 0 activities are not chosen. */
838
808
  bool can_rr = player_knows_techs_with_flag(pplayer, TF_RAILROAD);
839
 
 
840
809
  int best_newv = 0;
841
810
 
842
811
  /* closest worker, if any, headed towards target tile */
843
812
  struct unit *enroute = NULL;
844
813
 
845
 
  generate_warmap(mycity, punit);
846
 
  
 
814
  pft_fill_unit_parameter(&parameter, punit);
 
815
  parameter.can_invade_tile = autosettler_enter_territory;
 
816
  pfm = pf_map_new(&parameter);
 
817
 
847
818
  city_list_iterate(pplayer->cities, pcity) {
 
819
    struct tile *pcenter = city_tile(pcity);
 
820
 
848
821
    /* try to work near the city */
849
 
    city_map_checked_iterate(pcity->tile, cx, cy, ptile) {
 
822
    city_tile_iterate_cxy(pcenter, ptile, cx, cy) {
850
823
      bool consider = TRUE;
 
824
      bool in_use = (tile_worked(ptile) == pcity);
851
825
 
852
 
      if (get_worker_city(pcity, cx, cy) == C_TILE_UNAVAILABLE
853
 
          || terrain_has_flag(pcity->tile->terrain, TER_UNSAFE)) {
854
 
        /* Don't risk bothering with this tile. */
855
 
        continue;
 
826
      if (!in_use && !city_can_work_tile(pcity, ptile)) {
 
827
        /* Don't risk bothering with this tile. */
 
828
        continue;
856
829
      }
857
830
 
858
 
      /* do not go to tiles that already have workers there */
 
831
      /* Do not go to tiles that already have workers there. */
859
832
      unit_list_iterate(ptile->units, aunit) {
860
 
        if (unit_owner(aunit) == pplayer
861
 
            && aunit->id != punit->id
862
 
            && unit_has_type_flag(aunit, F_SETTLERS)) {
863
 
          consider = FALSE;
864
 
        }
 
833
        if (unit_owner(aunit) == pplayer
 
834
            && aunit->id != punit->id
 
835
            && unit_has_type_flag(aunit, F_SETTLERS)) {
 
836
          consider = FALSE;
 
837
        }
865
838
      } unit_list_iterate_end;
866
839
 
867
 
      in_use = (get_worker_city(pcity, cx, cy) == C_TILE_WORKER);
 
840
      if (!consider) {
 
841
        continue;
 
842
      }
 
843
 
868
844
      if (state) {
869
 
        enroute = player_find_unit_by_id(pplayer,
870
 
                                         state[ptile->index].enroute);
 
845
        enroute = player_find_unit_by_id(pplayer,
 
846
                                         state[tile_index(ptile)].enroute);
871
847
      }
872
 
      if (consider 
873
 
          && tile_get_continent(ptile) == ucont
874
 
          && WARMAP_COST(ptile) <= THRESHOLD * mv_rate) {
875
 
        int eta = FC_INFINITY, inbound_distance = FC_INFINITY, time;
876
 
 
877
 
        if (enroute) {
878
 
          eta = state[ptile->index].eta;
879
 
          inbound_distance = real_map_distance(ptile, enroute->tile);
880
 
        }
881
 
        mv_turns = WARMAP_COST(ptile) / mv_rate;
882
 
        oldv = city_tile_value(pcity, cx, cy, 0, 0);
883
 
 
884
 
        /* only consider this tile if we are closer in time and space to
885
 
         * it than our other worker (if any) travelling to the site */
886
 
        if ((enroute && enroute->id == punit->id)
887
 
            || mv_turns < eta
888
 
            || (mv_turns == eta
889
 
                && (real_map_distance(ptile, punit->tile)
890
 
                    < inbound_distance))) {
891
 
 
892
 
          if (enroute) {
893
 
            UNIT_LOG(LOG_DEBUG, punit,
894
 
                     "Considering %d,%d because we're closer "
895
 
                     "(%d,%d) than %d (%d,%d)",
896
 
                     TILE_XY(ptile), mv_turns,
897
 
                     real_map_distance(ptile, punit->tile),
898
 
                     enroute->id, eta, inbound_distance);
899
 
          }
900
 
 
901
 
          /* now, consider various activities... */
902
 
          activity_type_iterate(act) {
903
 
            if (pcity->ai.act_value[act][cx][cy] >= 0
904
 
                && can_unit_do_activity_targeted_at(punit, act, 
905
 
                                                    S_LAST, ptile)) {
906
 
              int extra = 0;
907
 
              int base_value = pcity->ai.act_value[act][cx][cy];
908
 
 
909
 
              time = mv_turns + get_turns_for_activity_at(punit, act, ptile);
910
 
              
911
 
              if (act == ACTIVITY_ROAD) {
912
 
                extra = road_bonus(ptile, S_ROAD) * 5;
913
 
                if (can_rr) {
914
 
                  /* if we can make railroads eventually, consider making
915
 
                   * road here, and set extras and time to to consider
916
 
                   * railroads in main consider_settler_action call */
917
 
                  consider_settler_action(pplayer, ACTIVITY_ROAD,
918
 
                                extra,
919
 
                                pcity->ai.act_value[ACTIVITY_ROAD][cx][cy], 
920
 
                                oldv, in_use, mv_turns, time,
921
 
                                &best_newv, &best_oldv, travel_time,
922
 
                                best_act, best_tile,
923
 
                                ptile);
924
 
                  
925
 
                  base_value
926
 
                    = pcity->ai.act_value[ACTIVITY_RAILROAD][cx][cy];
927
 
                  
928
 
                  /* Count road time plus rail time. */
929
 
                  time += get_turns_for_activity_at(punit, ACTIVITY_RAILROAD, 
930
 
                                                    ptile);
931
 
                }
932
 
              } else if (act == ACTIVITY_RAILROAD) {
933
 
                extra = road_bonus(ptile, S_RAILROAD) * 3;
934
 
              } else if (act == ACTIVITY_FALLOUT) {
935
 
                extra = pplayer->ai.frost;
936
 
              } else if (act == ACTIVITY_POLLUTION) {
937
 
                extra = pplayer->ai.warmth;
938
 
              }    
939
 
              
940
 
              consider_settler_action(pplayer, act,
941
 
                                      extra, 
942
 
                                      base_value, oldv, 
943
 
                                      in_use,
944
 
                                      mv_turns, time,
945
 
                                      &best_newv, &best_oldv, travel_time,
946
 
                                      best_act, best_tile,
947
 
                                      ptile);
948
 
              
949
 
            } /* endif: can the worker perform this action */
950
 
          } activity_type_iterate_end;
951
 
        } /* endif: can we finish sooner than current worker, if any? */
 
848
 
 
849
      if (pf_map_get_position(pfm, ptile, &pos)) {
 
850
        int eta = FC_INFINITY, inbound_distance = FC_INFINITY, time;
 
851
 
 
852
        if (enroute) {
 
853
          eta = state[tile_index(ptile)].eta;
 
854
          inbound_distance = real_map_distance(ptile, unit_tile(enroute));
 
855
        }
 
856
 
 
857
        /* Only consider this tile if we are closer in time and space to
 
858
         * it than our other worker (if any) travelling to the site. */
 
859
        if ((enroute && enroute->id == punit->id)
 
860
            || pos.turn < eta
 
861
            || (pos.turn == eta
 
862
                && (real_map_distance(ptile, unit_tile(punit))
 
863
                    < inbound_distance))) {
 
864
 
 
865
          if (enroute) {
 
866
            UNIT_LOG(LOG_DEBUG, punit,
 
867
                     "Considering (%d, %d) because we're closer "
 
868
                     "(%d, %d) than %d (%d, %d)",
 
869
                     TILE_XY(ptile), pos.turn,
 
870
                     real_map_distance(ptile, unit_tile(punit)),
 
871
                     enroute->id, eta, inbound_distance);
 
872
          }
 
873
 
 
874
          oldv = city_tile_value(pcity, ptile, 0, 0);
 
875
 
 
876
          /* Now, consider various activities... */
 
877
          activity_type_iterate(act) {
 
878
            if (pcity->ai->act_value[act][cx][cy] >= 0
 
879
                /* This needs separate implementation. */
 
880
                && act != ACTIVITY_BASE
 
881
                && can_unit_do_activity_targeted_at(punit, act, S_LAST,
 
882
                                                    ptile, -1)) {
 
883
              int extra = 0;
 
884
              int base_value = pcity->ai->act_value[act][cx][cy];
 
885
 
 
886
              time = pos.turn + get_turns_for_activity_at(punit, act, ptile);
 
887
 
 
888
              if (act == ACTIVITY_ROAD) {
 
889
                extra = road_bonus(ptile, S_ROAD) * 5;
 
890
                if (can_rr) {
 
891
                  /* If we can make railroads eventually, consider making
 
892
                   * road here, and set extras and time to to consider
 
893
                   * railroads in main consider_settler_action call. */
 
894
                  consider_settler_action(pplayer, ACTIVITY_ROAD, extra,
 
895
                                          pcity->ai->act_value[ACTIVITY_ROAD][cx][cy], 
 
896
                                          oldv, in_use, time,
 
897
                                          &best_newv, &best_oldv,
 
898
                                          best_act, best_tile, ptile);
 
899
 
 
900
                  base_value
 
901
                    = pcity->ai->act_value[ACTIVITY_RAILROAD][cx][cy];
 
902
 
 
903
                  /* Count road time plus rail time. */
 
904
                  time += get_turns_for_activity_at(punit, ACTIVITY_RAILROAD, 
 
905
                                                    ptile);
 
906
                }
 
907
              } else if (act == ACTIVITY_RAILROAD) {
 
908
                extra = road_bonus(ptile, S_RAILROAD) * 3;
 
909
              } else if (act == ACTIVITY_FALLOUT) {
 
910
                extra = pplayer->ai_data.frost;
 
911
              } else if (act == ACTIVITY_POLLUTION) {
 
912
                extra = pplayer->ai_data.warmth;
 
913
              }
 
914
 
 
915
              consider_settler_action(pplayer, act, extra, base_value,
 
916
                                      oldv, in_use, time,
 
917
                                      &best_newv, &best_oldv,
 
918
                                      best_act, best_tile, ptile);
 
919
 
 
920
            } /* endif: can the worker perform this action */
 
921
          } activity_type_iterate_end;
 
922
        } /* endif: can we finish sooner than current worker, if any? */
952
923
      } /* endif: are we travelling to a legal destination? */
953
 
    } city_map_checked_iterate_end;
 
924
    } city_tile_iterate_cxy_end;
954
925
  } city_list_iterate_end;
955
926
 
956
927
  best_newv /= WORKER_FACTOR;
959
930
 
960
931
  if (best_newv > 0) {
961
932
    freelog(LOG_DEBUG,
962
 
            "Settler %d@(%d,%d) wants to %s at (%d,%d) with desire %d",
963
 
            punit->id, TILE_XY(punit->tile), get_activity_text(*best_act),
964
 
            TILE_XY(*best_tile), best_newv);
 
933
            "Settler %d@(%d,%d) wants to %s at (%d,%d) with desire %d",
 
934
            punit->id, TILE_XY(punit->tile), get_activity_text(*best_act),
 
935
            TILE_XY(*best_tile), best_newv);
965
936
  } else {
966
937
    /* Fill in dummy values.  The callers should check if the return value
967
938
     * is > 0 but this will avoid confusing them. */
969
940
    *best_tile = NULL;
970
941
  }
971
942
 
 
943
  if (path) {
 
944
    *path = *best_tile ? pf_map_get_path(pfm, *best_tile) : NULL;
 
945
  }
 
946
 
 
947
  pf_map_destroy(pfm);
 
948
 
972
949
  return best_newv;
973
950
}
974
951
 
985
962
  int best_impr = 0;            /* best terrain improvement we can do */
986
963
  enum unit_activity best_act;
987
964
  struct tile *best_tile = NULL;
 
965
  struct pf_path *path = NULL;
988
966
  struct ai_data *ai = ai_data_get(pplayer);
989
967
 
990
968
  /* time it will take worker to complete its given task */
1008
986
 
1009
987
  /*** If we are on a city mission: Go where we should ***/
1010
988
 
 
989
BUILD_CITY:
1011
990
  if (punit->ai.ai_role == AIUNIT_BUILD_CITY) {
1012
991
    struct tile *ptile = punit->goto_tile;
1013
992
    int sanity = punit->id;
1014
993
 
1015
994
    /* Check that the mission is still possible.  If the tile has become
1016
995
     * unavailable or the player has been autotoggled, call it off. */
1017
 
    if (!unit_owner(punit)->ai.control
1018
 
        || !city_can_be_built_here(ptile, punit)) {
 
996
    if (!unit_owner(punit)->ai_data.control
 
997
        || !city_can_be_built_here(ptile, punit)) {
1019
998
      UNIT_LOG(LOG_SETTLER, punit, "city founding mission failed");
1020
999
      ai_unit_new_role(punit, AIUNIT_NONE, NULL);
1021
1000
      set_unit_activity(punit, ACTIVITY_IDLE);
1023
1002
      return; /* avoid recursion at all cost */
1024
1003
    } else {
1025
1004
      /* Go there */
1026
 
      if ((!ai_gothere(pplayer, punit, ptile) && !game_find_unit_by_number(sanity))
 
1005
      if ((!ai_gothere(pplayer, punit, ptile)
 
1006
           && !game_find_unit_by_number(sanity))
1027
1007
          || punit->moves_left <= 0) {
1028
1008
        return;
1029
1009
      }
1030
1010
      if (same_pos(punit->tile, ptile)) {
1031
1011
        if (!ai_do_build_city(pplayer, punit)) {
1032
1012
          UNIT_LOG(LOG_DEBUG, punit, "could not make city on %s",
1033
 
                   tile_get_info_text(punit->tile));
 
1013
                   tile_get_info_text(punit->tile, 0));
1034
1014
          ai_unit_new_role(punit, AIUNIT_NONE, NULL);
1035
 
          return; /* Avoid infinite recursion at all costs! */
 
1015
          /* Only known way to end in here is that hut turned in to a city
 
1016
           * when settler entered tile. So this is not going to lead in any
 
1017
           * serious recursion. */
 
1018
          auto_settler_findwork(pplayer, punit, state, recursion + 1);
 
1019
 
 
1020
          return;
1036
1021
        } else {
1037
1022
          return; /* We came, we saw, we built... */
1038
1023
        }
1051
1036
  if (unit_has_type_flag(punit, F_SETTLERS)) {
1052
1037
    TIMING_LOG(AIT_WORKERS, TIMER_START);
1053
1038
    best_impr = evaluate_improvements(punit, &best_act, &best_tile, 
1054
 
                                      &completion_time, state);
 
1039
                                      &path, state);
 
1040
    if (path) {
 
1041
      completion_time = pf_path_get_last_position(path)->turn;
 
1042
    }
1055
1043
    TIMING_LOG(AIT_WORKERS, TIMER_STOP);
1056
1044
  }
1057
1045
 
1058
 
  if (unit_has_type_flag(punit, F_CITIES) && pplayer->ai.control) {
 
1046
  if (unit_has_type_flag(punit, F_CITIES) && pplayer->ai_data.control) {
1059
1047
    /* may use a boat: */
1060
1048
    TIMING_LOG(AIT_SETTLERS, TIMER_START);
1061
1049
    find_best_city_placement(punit, &result, TRUE, FALSE);
1063
1051
             best_impr);
1064
1052
    TIMING_LOG(AIT_SETTLERS, TIMER_STOP);
1065
1053
    if (result.result > best_impr) {
1066
 
      if (tile_get_city(result.tile)) {
 
1054
      if (tile_city(result.tile)) {
1067
1055
        UNIT_LOG(LOG_SETTLER, punit, "immigrates to %s (%d, %d)", 
1068
 
                 city_name(tile_get_city(result.tile)),
 
1056
                 city_name(tile_city(result.tile)),
1069
1057
                 TILE_XY(result.tile));
1070
1058
      } else {
1071
1059
        UNIT_LOG(LOG_SETTLER, punit, "makes city at (%d, %d)", 
1077
1065
      /* Go make a city! */
1078
1066
      ai_unit_new_role(punit, AIUNIT_BUILD_CITY, result.tile);
1079
1067
      if (result.other_tile) {
1080
 
        /* Reserve best other tile (if there is one). */
1081
 
        /* FIXME: what is an "other tile" and why would we want to reserve
1082
 
         * it? */
1083
 
        citymap_reserve_tile(result.other_tile, punit->id);
 
1068
        /* Reserve best other tile (if there is one). */
 
1069
        /* FIXME: what is an "other tile" and why would we want to reserve
 
1070
         * it? */
 
1071
        citymap_reserve_tile(result.other_tile, punit->id);
1084
1072
      }
1085
1073
      punit->goto_tile = result.tile; /* TMP */
 
1074
 
 
1075
      /*** Go back to and found a city ***/
 
1076
      pf_path_destroy(path);
 
1077
      path = NULL;
 
1078
      goto BUILD_CITY;
1086
1079
    } else if (best_impr > 0) {
1087
1080
      UNIT_LOG(LOG_SETTLER, punit, "improves terrain instead of founding");
1088
1081
      /* Terrain improvements follows the old model, and is recalculated
1091
1084
    } else {
1092
1085
      UNIT_LOG(LOG_SETTLER, punit, "cannot find work");
1093
1086
      ai_unit_new_role(punit, AIUNIT_NONE, NULL);
1094
 
      return;
 
1087
      goto CLEANUP;
1095
1088
    }
1096
1089
  } else {
1097
1090
    /* We are a worker or engineer */
1100
1093
 
1101
1094
  /* Run the "autosettler" program */
1102
1095
  if (punit->ai.ai_role == AIUNIT_AUTO_SETTLER) {
 
1096
    struct pf_map *pfm = NULL;
 
1097
    struct pf_parameter parameter;
 
1098
 
 
1099
    struct unit *displaced;
 
1100
 
 
1101
    if (!best_tile) {
 
1102
      UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
 
1103
      goto CLEANUP; /* We cannot do anything */
 
1104
    }
 
1105
 
1103
1106
    /* Mark the square as taken. */
1104
 
    if (best_tile) {
1105
 
      struct unit *displaced
1106
 
        = player_find_unit_by_id(pplayer, state[best_tile->index].enroute);
1107
 
 
1108
 
      if (displaced) {
1109
 
        assert(state[best_tile->index].enroute == displaced->id);
1110
 
        assert(state[best_tile->index].eta > completion_time
1111
 
               || (state[best_tile->index].eta == completion_time
1112
 
                   && (real_map_distance(best_tile, punit->tile)
1113
 
                       < real_map_distance(best_tile, displaced->tile))));
1114
 
        UNIT_LOG(LOG_DEBUG, punit,
1115
 
                 "%d (%d,%d) has displaced %d (%d,%d) on %d,%d",
1116
 
                punit->id, completion_time,
1117
 
                real_map_distance(best_tile, punit->tile),
1118
 
                displaced->id, state[best_tile->index].eta,
1119
 
                real_map_distance(best_tile, displaced->tile),
1120
 
                TILE_XY(best_tile));
1121
 
      }
1122
 
 
1123
 
      state[best_tile->index].enroute = punit->id;
1124
 
      state[best_tile->index].eta = completion_time;
 
1107
    displaced = player_find_unit_by_id(pplayer, state[tile_index(best_tile)].enroute);
 
1108
 
 
1109
    if (displaced) {
 
1110
      assert(state[tile_index(best_tile)].enroute == displaced->id);
 
1111
      assert(state[tile_index(best_tile)].eta > completion_time
 
1112
             || (state[tile_index(best_tile)].eta == completion_time
 
1113
                 && (real_map_distance(best_tile, punit->tile)
 
1114
                     < real_map_distance(best_tile, displaced->tile))));
 
1115
      UNIT_LOG(LOG_DEBUG, punit,
 
1116
               "%d (%d,%d) has displaced %d (%d,%d) on %d,%d",
 
1117
               punit->id, completion_time,
 
1118
               real_map_distance(best_tile, punit->tile),
 
1119
               displaced->id, state[tile_index(best_tile)].eta,
 
1120
               real_map_distance(best_tile, displaced->tile),
 
1121
               TILE_XY(best_tile));
 
1122
    }
 
1123
 
 
1124
    state[tile_index(best_tile)].enroute = punit->id;
 
1125
    state[tile_index(best_tile)].eta = completion_time;
1125
1126
      
1126
 
      if (displaced) {
1127
 
        int saved_id = punit->id;
1128
 
 
1129
 
        displaced->goto_tile = NULL;
1130
 
        auto_settler_findwork(pplayer, displaced, state, recursion + 1);
1131
 
        if (player_find_unit_by_id(pplayer, saved_id) == NULL) {
1132
 
          /* Actions of the displaced settler somehow caused this settler
1133
 
           * to die. (maybe by recursively giving control back to this unit)
1134
 
           */
1135
 
          return;
1136
 
        }
 
1127
    if (displaced) {
 
1128
      struct tile *goto_tile = punit->goto_tile;
 
1129
      int saved_id = punit->id;
 
1130
 
 
1131
      displaced->goto_tile = NULL;
 
1132
      auto_settler_findwork(pplayer, displaced, state, recursion + 1);
 
1133
      if (player_find_unit_by_id(pplayer, saved_id) == NULL) {
 
1134
        /* Actions of the displaced settler somehow caused this settler
 
1135
         * to die. (maybe by recursively giving control back to this unit)
 
1136
         */
 
1137
        goto CLEANUP;
 
1138
      }
 
1139
      if (goto_tile != punit->goto_tile) {
 
1140
        /* Actions of the displaced settler somehow caused this settler
 
1141
         * to get a new job. (A displaced B, B displaced C, C displaced A)
 
1142
         */
 
1143
        UNIT_LOG(LOG_DEBUG, punit, "%d has changed goals from (%d, %d) "
 
1144
                 "to (%d, %d) due to recursion",
 
1145
                 punit->id, TILE_XY(goto_tile), TILE_XY(punit->goto_tile));
 
1146
        goto CLEANUP;
 
1147
      }
 
1148
    }
 
1149
 
 
1150
    if (!path) {
 
1151
      pft_fill_unit_parameter(&parameter, punit);
 
1152
      parameter.can_invade_tile = autosettler_enter_territory;
 
1153
      pfm = pf_map_new(&parameter);
 
1154
      path = pf_map_get_path(pfm, best_tile);
 
1155
    }
 
1156
 
 
1157
    if (path) {
 
1158
      bool alive;
 
1159
 
 
1160
      alive = ai_follow_path(punit, path, best_tile);
 
1161
 
 
1162
      if (alive && same_pos(punit->tile, best_tile)
 
1163
          && punit->moves_left > 0) {
 
1164
        /* Reached destination and can start working immediately */
 
1165
        unit_activity_handling(punit, best_act);
 
1166
        send_unit_info(NULL, punit); /* FIXME: probably duplicate */
1137
1167
      }
1138
1168
    } else {
1139
 
      UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
1140
 
      return; /* We cannot do anything */
1141
 
    }
1142
 
    punit->goto_tile = best_tile; /* TMP */
1143
 
    if (do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) == GR_DIED) {
1144
 
      return;
1145
 
    }
1146
 
    if (punit->moves_left > 0
1147
 
        && same_pos(best_tile, punit->tile)) {
1148
 
      handle_unit_activity_request(punit, best_act);
1149
 
      send_unit_info(NULL, punit);
1150
 
      return;
1151
 
    }
 
1169
      freelog(LOG_DEBUG, "Autosettler does not find path (%d,%d) -> (%d,%d)",
 
1170
              punit->tile->x, punit->tile->y, best_tile->x, best_tile->y);
 
1171
    }
 
1172
 
 
1173
    if (pfm) {
 
1174
      pf_map_destroy(pfm);
 
1175
    }
 
1176
 
 
1177
    goto CLEANUP;
1152
1178
  }
1153
1179
 
1154
1180
  /*** Recurse if we want to found a city ***/
1157
1183
      && punit->moves_left > 0) {
1158
1184
    auto_settler_findwork(pplayer, punit, state, recursion + 1);
1159
1185
  }
 
1186
 
 
1187
CLEANUP:
 
1188
  if (NULL != path) {
 
1189
    pf_path_destroy(path);
 
1190
  }
1160
1191
}
1161
1192
#undef LOG_SETTLER
1162
1193
 
1165
1196
**************************************************************************/
1166
1197
static int best_worker_tile_value(struct city *pcity)
1167
1198
{
 
1199
  struct tile *pcenter = city_tile(pcity);
1168
1200
  int best = 0;
1169
1201
 
1170
 
  city_map_iterate(x, y) {
1171
 
    if (is_free_worked_tile(x, y) 
1172
 
        || get_worker_city(pcity, x, y) == C_TILE_WORKER 
1173
 
        || get_worker_city(pcity, x, y) == C_TILE_EMPTY) {
1174
 
      int tmp = city_tile_value(pcity, x, y, 0, 0);
 
1202
  city_tile_iterate(pcenter, ptile) {
 
1203
    if (is_free_worked(pcity, ptile)
 
1204
        || tile_worked(ptile) == pcity /* quick test */
 
1205
        || city_can_work_tile(pcity, ptile)) {
 
1206
      int tmp = city_tile_value(pcity, ptile, 0, 0);
1175
1207
 
1176
 
      if (tmp > best) {
 
1208
      if (best < tmp) {
1177
1209
        best = tmp;
1178
1210
      }
1179
1211
    }
1180
 
  } city_map_iterate_end;
 
1212
  } city_tile_iterate_end;
 
1213
 
1181
1214
  return best;
1182
1215
}
1183
1216
 
1191
1224
void initialize_infrastructure_cache(struct player *pplayer)
1192
1225
{
1193
1226
  city_list_iterate(pplayer->cities, pcity) {
 
1227
    struct tile *pcenter = city_tile(pcity);
1194
1228
    int best = best_worker_tile_value(pcity);
1195
1229
 
1196
1230
    city_map_iterate(city_x, city_y) {
1197
1231
      activity_type_iterate(act) {
1198
 
        pcity->ai.act_value[act][city_x][city_y] = -1;
 
1232
        pcity->ai->act_value[act][city_x][city_y] = -1;
1199
1233
      } activity_type_iterate_end;
1200
1234
    } city_map_iterate_end;
1201
1235
 
1202
 
    city_map_checked_iterate(pcity->tile,
1203
 
                             city_x, city_y, ptile) {
 
1236
    city_tile_iterate_cxy(pcenter, ptile, city_x, city_y) {
1204
1237
#ifndef NDEBUG
1205
 
      struct terrain *old_terrain = ptile->terrain;
 
1238
      struct terrain *old_terrain = tile_terrain(ptile);
1206
1239
      bv_special old_special = ptile->special;
1207
1240
#endif
1208
1241
 
1209
 
      pcity->ai.act_value[ACTIVITY_POLLUTION][city_x][city_y] 
1210
 
        = ai_calc_pollution(pcity, city_x, city_y, best, ptile);
1211
 
      pcity->ai.act_value[ACTIVITY_FALLOUT][city_x][city_y]
1212
 
        = ai_calc_fallout(pcity, pplayer, city_x, city_y, best, ptile);
1213
 
      pcity->ai.act_value[ACTIVITY_MINE][city_x][city_y]
1214
 
        = ai_calc_mine(pcity, city_x, city_y, ptile);
1215
 
      pcity->ai.act_value[ACTIVITY_IRRIGATE][city_x][city_y]
 
1242
      pcity->ai->act_value[ACTIVITY_POLLUTION][city_x][city_y] 
 
1243
        = ai_calc_pollution(pcity, city_x, city_y, best, ptile);
 
1244
      pcity->ai->act_value[ACTIVITY_FALLOUT][city_x][city_y]
 
1245
        = ai_calc_fallout(pcity, pplayer, city_x, city_y, best, ptile);
 
1246
      pcity->ai->act_value[ACTIVITY_MINE][city_x][city_y]
 
1247
        = ai_calc_mine(pcity, city_x, city_y, ptile);
 
1248
      pcity->ai->act_value[ACTIVITY_IRRIGATE][city_x][city_y]
1216
1249
        = ai_calc_irrigate(pcity, pplayer, city_x, city_y, ptile);
1217
 
      pcity->ai.act_value[ACTIVITY_TRANSFORM][city_x][city_y]
1218
 
        = ai_calc_transform(pcity, city_x, city_y, ptile);
 
1250
      pcity->ai->act_value[ACTIVITY_TRANSFORM][city_x][city_y]
 
1251
        = ai_calc_transform(pcity, city_x, city_y, ptile);
1219
1252
 
1220
1253
      /* road_bonus() is handled dynamically later; it takes into
1221
1254
       * account settlers that have already been assigned to building
1222
1255
       * roads this turn. */
1223
 
      pcity->ai.act_value[ACTIVITY_ROAD][city_x][city_y]
1224
 
        = ai_calc_road(pcity, pplayer, city_x, city_y, ptile);
1225
 
      pcity->ai.act_value[ACTIVITY_RAILROAD][city_x][city_y]
1226
 
        = ai_calc_railroad(pcity, pplayer, city_x, city_y, ptile);
 
1256
      pcity->ai->act_value[ACTIVITY_ROAD][city_x][city_y]
 
1257
        = ai_calc_road(pcity, pplayer, city_x, city_y, ptile);
 
1258
      pcity->ai->act_value[ACTIVITY_RAILROAD][city_x][city_y]
 
1259
        = ai_calc_railroad(pcity, pplayer, city_x, city_y, ptile);
1227
1260
 
1228
1261
      /* Make sure nothing was accidentally changed by these calculations. */
1229
 
      assert(old_terrain == ptile->terrain
 
1262
      assert(old_terrain == tile_terrain(ptile)
1230
1263
             && memcmp(&ptile->special, &old_special,
1231
1264
                       sizeof(old_special)) == 0);
1232
 
    } city_map_checked_iterate_end;
 
1265
    } city_tile_iterate_cxy_end;
1233
1266
  } city_list_iterate_end;
1234
1267
}
1235
1268
 
1244
1277
  
1245
1278
  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
1246
1279
 
1247
 
  if (pplayer->ai.control) {
 
1280
  if (pplayer->ai_data.control) {
1248
1281
    /* Set up our city map. */
1249
1282
    citymap_turn_init(pplayer);
1250
1283
  }
1251
1284
 
1252
1285
  whole_map_iterate(ptile) {
1253
 
    state[ptile->index].enroute = -1;
1254
 
    state[ptile->index].eta = FC_INFINITY;    
 
1286
    state[tile_index(ptile)].enroute = -1;
 
1287
    state[tile_index(ptile)].eta = FC_INFINITY;    
1255
1288
  } whole_map_iterate_end;
1256
1289
 
1257
1290
  /* Initialize the infrastructure cache, which is used shortly. */
1261
1294
   * This depends heavily on the calculations in update_environmental_upset.
1262
1295
   * Aside from that it's more or less a WAG that simply grows incredibly
1263
1296
   * large as an environmental disaster approaches. */
1264
 
  pplayer->ai.warmth
 
1297
  pplayer->ai_data.warmth
1265
1298
    = (WARMING_FACTOR * game.info.heating / ((game.info.warminglevel + 1) / 2)
1266
1299
       + game.info.globalwarming);
1267
 
  pplayer->ai.frost
 
1300
  pplayer->ai_data.frost
1268
1301
    = (COOLING_FACTOR * game.info.cooling / ((game.info.coolinglevel + 1) / 2)
1269
1302
       + game.info.nuclearwinter);
1270
1303
 
1271
1304
  freelog(LOG_DEBUG, "Warmth = %d, game.globalwarming=%d",
1272
 
          pplayer->ai.warmth, game.info.globalwarming);
 
1305
          pplayer->ai_data.warmth, game.info.globalwarming);
1273
1306
  freelog(LOG_DEBUG, "Frost = %d, game.nuclearwinter=%d",
1274
 
          pplayer->ai.warmth, game.info.nuclearwinter);
 
1307
          pplayer->ai_data.warmth, game.info.nuclearwinter);
1275
1308
 
1276
1309
  /* Auto-settle with a settler unit if it's under AI control (e.g. human
1277
1310
   * player auto-settler mode) or if the player is an AI.  But don't
1278
1311
   * auto-settle with a unit under orders even for an AI player - these come
1279
1312
   * from the human player and take precedence. */
1280
1313
  unit_list_iterate_safe(pplayer->units, punit) {
1281
 
    if ((punit->ai.control || pplayer->ai.control)
 
1314
    if ((punit->ai.control || pplayer->ai_data.control)
1282
1315
        && (unit_has_type_flag(punit, F_SETTLERS)
1283
1316
            || unit_has_type_flag(punit, F_CITIES))
1284
1317
        && !unit_has_orders(punit)
1287
1320
              nation_rule_name(nation_of_player(pplayer)),
1288
1321
              TILE_XY(punit->tile)); 
1289
1322
      if (punit->activity == ACTIVITY_SENTRY) {
1290
 
        handle_unit_activity_request(punit, ACTIVITY_IDLE);
 
1323
        unit_activity_handling(punit, ACTIVITY_IDLE);
1291
1324
      }
1292
1325
      if (punit->activity == ACTIVITY_GOTO && punit->moves_left > 0) {
1293
 
        handle_unit_activity_request(punit, ACTIVITY_IDLE);
 
1326
        unit_activity_handling(punit, ACTIVITY_IDLE);
1294
1327
      }
1295
1328
      if (punit->activity == ACTIVITY_IDLE) {
1296
1329
        auto_settler_findwork(pplayer, punit, state, 0);
1311
1344
**************************************************************************/
1312
1345
void contemplate_new_city(struct city *pcity)
1313
1346
{
 
1347
  struct unit *virtualunit;
 
1348
  struct tile *pcenter = city_tile(pcity);
1314
1349
  struct player *pplayer = city_owner(pcity);
1315
 
  struct unit *virtualunit;
1316
1350
  struct unit_type *unit_type = best_role_unit(pcity, F_CITIES); 
1317
1351
 
1318
1352
  if (unit_type == NULL) {
1322
1356
 
1323
1357
  /* Create a localized "virtual" unit to do operations with. */
1324
1358
  virtualunit = create_unit_virtual(pplayer, pcity, unit_type, 0);
1325
 
  virtualunit->tile = pcity->tile;
1326
 
 
1327
 
  assert(pplayer->ai.control);
1328
 
 
1329
 
  if (pplayer->ai.control) {
 
1359
  virtualunit->tile = pcenter;
 
1360
 
 
1361
  assert(pplayer->ai_data.control);
 
1362
 
 
1363
  if (pplayer->ai_data.control) {
1330
1364
    struct cityresult result;
1331
 
    bool is_coastal = is_ocean_near_tile(pcity->tile);
 
1365
    bool is_coastal = is_ocean_near_tile(pcenter);
1332
1366
 
1333
1367
    find_best_city_placement(virtualunit, &result, is_coastal, is_coastal);
1334
1368
    assert(0 <= result.result);
1339
1373
             (result.virt_boat ? "build a boat" : 
1340
1374
              (result.overseas ? "use a boat" : "walk")));
1341
1375
 
1342
 
    pcity->ai.founder_want = (result.virt_boat ? 
1343
 
                              -result.result : result.result);
1344
 
    pcity->ai.founder_boat = result.overseas;
 
1376
    pcity->ai->founder_want = (result.virt_boat ? 
 
1377
                               -result.result : result.result);
 
1378
    pcity->ai->founder_boat = result.overseas;
1345
1379
  }
1346
1380
  destroy_unit_virtual(virtualunit);
1347
1381
}
1354
1388
**************************************************************************/
1355
1389
void contemplate_terrain_improvements(struct city *pcity)
1356
1390
{
1357
 
  struct player *pplayer = city_owner(pcity);
1358
1391
  struct unit *virtualunit;
1359
1392
  int want;
 
1393
  enum unit_activity best_act;
1360
1394
  struct tile *best_tile = NULL; /* May be accessed by freelog() calls. */
1361
 
  enum unit_activity best_act;
1362
 
  struct tile *ptile = pcity->tile;
 
1395
  struct tile *pcenter = city_tile(pcity);
 
1396
  struct player *pplayer = city_owner(pcity);
1363
1397
  struct ai_data *ai = ai_data_get(pplayer);
1364
1398
  struct unit_type *unit_type = best_role_unit(pcity, F_SETTLERS);
1365
 
  int completion_time;
 
1399
  Continent_id place = tile_continent(pcenter);
1366
1400
 
1367
1401
  if (unit_type == NULL) {
1368
1402
    freelog(LOG_DEBUG, "No F_SETTLERS role unit available");
1371
1405
 
1372
1406
  /* Create a localized "virtual" unit to do operations with. */
1373
1407
  virtualunit = create_unit_virtual(pplayer, pcity, unit_type, 0);
1374
 
  virtualunit->tile = pcity->tile;
1375
 
  want = evaluate_improvements(virtualunit, &best_act,
1376
 
                               &best_tile, &completion_time,
1377
 
                               NULL);
 
1408
  virtualunit->tile = pcenter;
 
1409
  want = evaluate_improvements(virtualunit, &best_act, &best_tile,
 
1410
                               NULL, NULL);
1378
1411
  want = (want - unit_food_upkeep(virtualunit) * FOOD_WEIGHTING) * 100
1379
1412
         / (40 + unit_foodbox_cost(virtualunit));
1380
1413
  destroy_unit_virtual(virtualunit);
1382
1415
  /* Massage our desire based on available statistics to prevent
1383
1416
   * overflooding with worker type units if they come cheap in
1384
1417
   * the ruleset */
1385
 
  want /= MAX(1, ai->stats.workers[ptile->continent]
1386
 
                 / (ai->stats.cities[ptile->continent] + 1));
1387
 
  want -= ai->stats.workers[ptile->continent];
 
1418
  want /= MAX(1, ai->stats.workers[place]
 
1419
                 / (ai->stats.cities[place] + 1));
 
1420
  want -= ai->stats.workers[place];
1388
1421
  want = MAX(want, 0);
1389
1422
 
1390
1423
  CITY_LOG(LOG_DEBUG, pcity, "wants %s with want %d to do %s at (%d,%d), "
1393
1426
           want,
1394
1427
           get_activity_text(best_act),
1395
1428
           TILE_XY(best_tile),
1396
 
           ai->stats.workers[ptile->continent], 
1397
 
           ai->stats.cities[ptile->continent]);
 
1429
           ai->stats.workers[place], 
 
1430
           ai->stats.cities[place]);
1398
1431
  assert(want >= 0);
1399
 
  pcity->ai.settler_want = want;
 
1432
  pcity->ai->settler_want = want;
1400
1433
}