~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to ai/aidiplomat.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100223220902-kiyrmr9i4152cka5
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:
63
63
 
64
64
static void find_city_to_diplomat(struct player *pplayer, struct unit *punit,
65
65
                                  struct city **ctarget, int *move_dist,
66
 
                                  struct pf_map *map);
 
66
                                  struct pf_map *pfm);
67
67
 
68
68
/******************************************************************************
69
69
  Number of improvements that can be sabotaged in pcity.
72
72
{
73
73
  int count = 0;
74
74
 
75
 
  built_impr_iterate(pcity, index) {
76
 
    if (improvement_by_number(index)->sabotage > 0) {
 
75
  city_built_iterate(pcity, pimprove) {
 
76
    if (pimprove->sabotage > 0) {
77
77
      count++;
78
78
    }
79
 
  } built_impr_iterate_end;
 
79
  } city_built_iterate_end;
80
80
 
81
81
  return count;
82
82
}
88
88
{
89
89
  int count = 0;
90
90
 
91
 
  tech_type_iterate(index) {
92
 
    if ((get_invention(pplayer, index) != TECH_KNOWN)
93
 
        && (get_invention(tplayer, index) == TECH_KNOWN)) {
 
91
  advance_index_iterate(A_FIRST, index) {
 
92
    if ((player_invention_state(pplayer, index) != TECH_KNOWN)
 
93
        && (player_invention_state(tplayer, index) == TECH_KNOWN)) {
94
94
      count++;
95
95
    }
96
 
  } tech_type_iterate_end;
 
96
  } advance_index_iterate_end;
97
97
 
98
98
  return count;
99
99
}
111
111
     we have other defensive troops, and we don't already have a diplomat
112
112
     to protect us. If we see an enemy diplomat and we don't have diplomat
113
113
     tech... race it! */
114
 
  if (def != 0 && pcity->ai.diplomat_threat && !pcity->ai.has_diplomat) {
 
114
  if (def != 0 && pcity->ai->diplomat_threat && !pcity->ai->has_diplomat) {
115
115
    struct unit_type *ut = best_role_unit(pcity, F_DIPLOMAT);
116
116
 
117
117
    if (ut) {
119
119
               "A defensive diplomat will be built in city %s.",
120
120
               city_name(pcity));
121
121
       choice->want = 16000; /* diplomat more important than soldiers */
122
 
       pcity->ai.urgency = 1;
 
122
       pcity->ai->urgency = 1;
123
123
       choice->type = CT_DEFENDER;
124
 
       choice->choice = ut->index;
 
124
       choice->value.utype = ut;
125
125
       choice->need_boat = FALSE;
126
126
    } else if (num_role_units(F_DIPLOMAT) > 0) {
127
127
      /* We don't know diplomats yet... */
130
130
              city_name(pcity));
131
131
      ut = get_role_unit(F_DIPLOMAT, 0);
132
132
      if (ut) {
133
 
        Tech_type_id tech_req = ut->tech_requirement;
134
 
 
135
 
        pplayer->ai.tech_want[tech_req] += DIPLO_DEFENSE_WANT;
136
 
        TECH_LOG(LOG_DEBUG, pplayer, tech_req,
 
133
        pplayer->ai_data.tech_want[advance_index(ut->require_advance)]
 
134
          += DIPLO_DEFENSE_WANT;
 
135
        TECH_LOG(LOG_DEBUG, pplayer, ut->require_advance,
137
136
                 "ai_choose_diplomat_defensive() + %d for %s",
138
137
                 DIPLO_DEFENSE_WANT,
139
138
                 utype_rule_name(ut));
165
164
 
166
165
  /* Do we have a good reason for building diplomats? */
167
166
  {
168
 
    struct pf_map *map;
 
167
    struct pf_map *pfm;
169
168
    struct pf_parameter parameter;
170
169
    struct city *acity;
171
170
    int want, loss, p_success, p_failure, time_to_dest;
175
174
                                             do_make_unit_veteran(pcity, ut));
176
175
 
177
176
    pft_fill_unit_parameter(&parameter, punit);
178
 
    map = pf_create_map(&parameter);
179
 
 
180
 
    find_city_to_diplomat(pplayer, punit, &acity, &time_to_dest, map);
181
 
 
182
 
    pf_destroy_map(map);
 
177
    pfm = pf_map_new(&parameter);
 
178
 
 
179
    find_city_to_diplomat(pplayer, punit, &acity, &time_to_dest, pfm);
 
180
 
 
181
    pf_map_destroy(pfm);
183
182
    destroy_unit_virtual(punit);
184
183
 
185
184
    if (acity == NULL
190
189
    incite_cost = city_incite_cost(pplayer, acity);
191
190
    if (HOSTILE_PLAYER(pplayer, ai, city_owner(acity))
192
191
        && (incite_cost < INCITE_IMPOSSIBLE_COST)
193
 
        && (incite_cost < pplayer->economic.gold - pplayer->ai.est_upkeep)) {
 
192
        && (incite_cost < pplayer->economic.gold - pplayer->ai_data.est_upkeep)) {
194
193
      /* incite gain (FIXME: we should count wonders too but need to
195
194
         cache that somehow to avoid CPU hog -- Per) */
196
195
      gain_incite = acity->prod[O_FOOD] * FOOD_WEIGHTING
208
207
      gain_theft = total_bulbs_required(pplayer) * TRADE_WEIGHTING;
209
208
    }
210
209
    gain = MAX(gain_incite, gain_theft);
211
 
    loss = unit_build_shield_cost(ut) * SHIELD_WEIGHTING;
 
210
    loss = utype_build_shield_cost(ut) * SHIELD_WEIGHTING;
212
211
 
213
212
    /* Probability to succeed, assuming no defending diplomat */
214
213
    p_success = game.info.diplchance;
228
227
    }
229
228
 
230
229
    want = military_amortize(pplayer, pcity, want, time_to_dest, 
231
 
                             unit_build_shield_cost(ut));
 
230
                             utype_build_shield_cost(ut));
232
231
 
233
232
    if (!player_has_embassy(pplayer, city_owner(acity))
234
233
        && want < 99) {
251
250
              city_name(acity),
252
251
              gain_incite,
253
252
              incite_cost,
254
 
              pplayer->economic.gold - pplayer->ai.est_upkeep,
 
253
              pplayer->economic.gold - pplayer->ai_data.est_upkeep,
255
254
              gain_theft,
256
255
              time_to_dest);
257
256
      choice->want = want;
258
 
      choice->type = CT_NONMIL; /* so we don't build barracks for it */
259
 
      choice->choice = ut->index;
 
257
      choice->type = CT_CIVILIAN; /* so we don't build barracks for it */
 
258
      choice->value.utype = ut;
260
259
      choice->need_boat = FALSE;
261
260
      BV_SET(ai->stats.diplomat_reservations, acity->id);
262
261
    }
278
277
  struct player *tplayer = city_owner(ctarget);
279
278
  int count_impr = count_sabotagable_improvements(ctarget);
280
279
  int count_tech = count_stealable_techs(pplayer, tplayer);
281
 
  int gold_avail = pplayer->economic.gold - 2 * pplayer->ai.est_upkeep;
 
280
  int gold_avail = pplayer->economic.gold - 2 * pplayer->ai_data.est_upkeep;
282
281
  int incite_cost;
283
282
 
284
 
  assert(pplayer->ai.control);
 
283
  assert(pplayer->ai_data.control);
285
284
 
286
285
  if (punit->moves_left == 0) {
287
286
    UNIT_LOG(LOG_ERROR, punit, "no moves left in ai_diplomat_city()!");
288
287
  }
289
288
 
290
 
  handle_unit_activity_request(punit, ACTIVITY_IDLE);
 
289
  unit_activity_handling(punit, ACTIVITY_IDLE);
291
290
 
292
291
#define T(my_act,my_val)                                            \
293
292
  if (diplomat_can_do_action(punit, my_act, ctarget->tile)) {       \
341
340
**************************************************************************/
342
341
static void find_city_to_diplomat(struct player *pplayer, struct unit *punit,
343
342
                                  struct city **ctarget, int *move_dist,
344
 
                                  struct pf_map *map)
 
343
                                  struct pf_map *pfm)
345
344
{
346
345
  bool has_embassy;
347
346
  int incite_cost = 0; /* incite cost */
351
350
  *ctarget = NULL;
352
351
  *move_dist = -1;
353
352
 
354
 
  pf_iterator(map, pos) {
 
353
  pf_map_iterate_move_costs(pfm, ptile, move_cost, FALSE) {
355
354
    struct city *acity;
356
355
    struct player *aplayer;
357
356
    bool can_incite;
358
357
 
359
 
    acity = tile_get_city(pos.tile);
 
358
    acity = tile_city(ptile);
360
359
 
361
360
    if (!acity) {
362
361
      continue;
383
382
            && (get_player_research(pplayer)->techs_researched
384
383
                < get_player_research(aplayer)->techs_researched)
385
384
            && !dipldef)
386
 
        || (incite_cost < (pplayer->economic.gold - pplayer->ai.est_upkeep)
 
385
        || (incite_cost < (pplayer->economic.gold - pplayer->ai_data.est_upkeep)
387
386
            && can_incite && !dipldef)) {
388
387
      /* We have the closest enemy city on the continent */
389
388
      *ctarget = acity;
390
 
      *move_dist = pos.total_MC;
 
389
      *move_dist = move_cost;
391
390
      break;
392
391
    }
393
 
  } pf_iterator_end;
 
392
  } pf_map_iterate_move_costs_end;
394
393
}
395
394
 
396
395
/**************************************************************************
399
398
static struct city *ai_diplomat_defend(struct player *pplayer,
400
399
                                       struct unit *punit,
401
400
                                       const struct unit_type *utype,
402
 
                                       struct pf_map *map)
 
401
                                       struct pf_map *pfm)
403
402
{
404
403
  int best_dist = 30; /* any city closer than this is better than none */
405
404
  int best_urgency = 0;
406
405
  struct city *ctarget = NULL;
407
 
  struct city *pcity = tile_get_city(punit->tile);
 
406
  struct city *pcity = tile_city(punit->tile);
408
407
 
409
408
  if (pcity 
410
409
      && count_diplomats_on_tile(pcity->tile) == 1
411
 
      && pcity->ai.urgency > 0) {
 
410
      && pcity->ai->urgency > 0) {
412
411
    /* Danger and we are only diplomat present - stay. */
413
412
    return pcity;
414
413
  }
415
414
 
416
 
  pf_iterator(map, pos) {
 
415
  pf_map_iterate_move_costs(pfm, ptile, move_cost, FALSE) {
417
416
    struct city *acity;
418
417
    struct player *aplayer;
419
418
    int dipls, urgency;
420
419
 
421
 
    acity = tile_get_city(pos.tile);
 
420
    acity = tile_city(ptile);
422
421
    if (!acity) {
423
422
      continue;
424
423
    }
427
426
      continue;
428
427
    }
429
428
 
430
 
    urgency = acity->ai.urgency;
431
 
    dipls = (count_diplomats_on_tile(pos.tile)
432
 
             - (same_pos(pos.tile, punit->tile) ? 1 : 0));
433
 
    if (dipls == 0 && acity->ai.diplomat_threat) {
 
429
    urgency = acity->ai->urgency;
 
430
    dipls = (count_diplomats_on_tile(ptile)
 
431
             - (same_pos(ptile, punit->tile) ? 1 : 0));
 
432
    if (dipls == 0 && acity->ai->diplomat_threat) {
434
433
      /* We are _really_ needed there */
435
434
      urgency = (urgency + 1) * 5;
436
435
    } else if (dipls > 0) {
439
438
    }
440
439
 
441
440
    /* This formula may not be optimal, but it works. */
442
 
    if (pos.total_MC > best_dist) {
 
441
    if (move_cost > best_dist) {
443
442
      /* punish city for being so far away */
444
 
      urgency /= (float)(pos.total_MC / best_dist);
 
443
      urgency /= (float) (move_cost / best_dist);
445
444
    }
446
445
 
447
446
    if (urgency > best_urgency) {
449
448
      ctarget = acity;
450
449
      best_urgency = urgency;
451
450
      /* squelch divide-by-zero */
452
 
      best_dist = MAX(pos.total_MC, 1);
 
451
      best_dist = MAX(move_cost, 1);
453
452
    }
454
 
  } pf_iterator_end;
 
453
  } pf_map_iterate_move_costs_end;
455
454
 
456
455
  return ctarget;
457
456
}
462
461
  Will try to bribe a ship on the coast as well as land stuff.
463
462
**************************************************************************/
464
463
static bool ai_diplomat_bribe_nearby(struct player *pplayer, 
465
 
                                     struct unit *punit, struct pf_map *map)
 
464
                                     struct unit *punit, struct pf_map *pfm)
466
465
{
467
 
  int gold_avail = pplayer->economic.gold - pplayer->ai.est_upkeep;
 
466
  int gold_avail = pplayer->economic.gold - pplayer->ai_data.est_upkeep;
468
467
  struct ai_data *ai = ai_data_get(pplayer);
469
468
 
470
 
  pf_iterator(map, pos) {
 
469
  pf_map_iterate_positions(pfm, pos, FALSE) {
471
470
    struct tile *ptile = pos.tile;
472
471
    bool threat = FALSE;
473
472
    int newval, bestval = 0, cost;
482
481
    if (!pvictim
483
482
        || !HOSTILE_PLAYER(pplayer, ai, unit_owner(pvictim))
484
483
        || unit_list_size(ptile->units) > 1
485
 
        || (ptile->city && get_city_bonus(ptile->city, EFT_NO_INCITE) > 0)
 
484
        || (tile_city(ptile)
 
485
         && get_city_bonus(tile_city(ptile), EFT_NO_INCITE) > 0)
486
486
        || get_player_bonus(unit_owner(pvictim), EFT_NO_INCITE) > 0) {
487
487
      continue;
488
488
    }
527
527
      struct pf_path *path;
528
528
 
529
529
      ptile = mapstep(pos.tile, DIR_REVERSE(pos.dir_to_here));
530
 
      path = pf_get_path(map, ptile);
 
530
      path = pf_map_get_path(pfm, ptile);
531
531
      if (!path || !ai_unit_execute_path(punit, path) 
532
532
          || punit->moves_left <= 0) {
533
 
        pf_destroy_path(path);
 
533
        pf_path_destroy(path);
534
534
        return FALSE;
535
535
      }
536
 
      pf_destroy_path(path);
 
536
      pf_path_destroy(path);
537
537
    }
538
538
 
539
539
    if (diplomat_can_do_action(punit, DIPLOMAT_BRIBE, pos.tile)) {
552
552
               " %d moves left", TILE_XY(pos.tile), punit->moves_left);
553
553
      return FALSE;
554
554
    }
555
 
  } pf_iterator_end;
 
555
  } pf_map_iterate_positions_end;
556
556
 
557
557
  return (punit->moves_left > 0);
558
558
}
571
571
{
572
572
  struct city *pcity, *ctarget = NULL;
573
573
  struct pf_parameter parameter;
574
 
  struct pf_map *map;
 
574
  struct pf_map *pfm;
575
575
  struct pf_position pos;
576
576
 
577
577
  CHECK_UNIT(punit);
579
579
  /* Generate map */
580
580
  pft_fill_unit_parameter(&parameter, punit);
581
581
  parameter.get_zoc = NULL; /* kludge */
582
 
  map = pf_create_map(&parameter);
 
582
  pfm = pf_map_new(&parameter);
583
583
 
584
 
  pcity = tile_get_city(punit->tile);
 
584
  pcity = tile_city(punit->tile);
585
585
 
586
586
  /* Look for someone to bribe */
587
 
  if (!ai_diplomat_bribe_nearby(pplayer, punit, map)) {
 
587
  if (!ai_diplomat_bribe_nearby(pplayer, punit, pfm)) {
588
588
    /* Died or ran out of moves */
589
 
    pf_destroy_map(map);
 
589
    pf_map_destroy(pfm);
590
590
    return;
591
591
  }
592
592
 
593
593
  /* If we are the only diplomat in a threatened city, then stay to defend */
594
 
  pcity = tile_get_city(punit->tile); /* we may have moved */
 
594
  pcity = tile_city(punit->tile); /* we may have moved */
595
595
  if (pcity && count_diplomats_on_tile(punit->tile) == 1
596
 
      && (pcity->ai.diplomat_threat || pcity->ai.urgency > 0)) {
 
596
      && (pcity->ai->diplomat_threat || pcity->ai->urgency > 0)) {
597
597
    UNIT_LOG(LOG_DIPLOMAT, punit, "stays to protect %s (urg %d)", 
598
 
             city_name(pcity), pcity->ai.urgency);
 
598
             city_name(pcity), pcity->ai->urgency);
599
599
    ai_unit_new_role(punit, AIUNIT_NONE, NULL); /* abort mission */
600
600
    punit->ai.done = TRUE;
601
 
    pf_destroy_map(map);
 
601
    pf_map_destroy(pfm);
602
602
    return;
603
603
  }
604
604
 
607
607
      || punit->ai.ai_role == AIUNIT_DEFEND_HOME) {
608
608
    bool failure = FALSE;
609
609
 
610
 
    ctarget = tile_get_city(punit->goto_tile);
611
 
    if (pf_get_position(map, punit->goto_tile, &pos)
 
610
    ctarget = tile_city(punit->goto_tile);
 
611
    if (pf_map_get_position(pfm, punit->goto_tile, &pos)
612
612
        && ctarget) {
613
613
      if (same_pos(ctarget->tile, punit->tile)) {
614
614
        failure = TRUE;
637
637
   * a new map for its iterator. */
638
638
  if (!same_pos(parameter.start_tile, punit->tile)
639
639
      || punit->ai.ai_role == AIUNIT_NONE) {
640
 
    pf_destroy_map(map);
 
640
    pf_map_destroy(pfm);
641
641
    pft_fill_unit_parameter(&parameter, punit);
642
642
    parameter.get_zoc = NULL; /* kludge */
643
 
    map = pf_create_map(&parameter);
 
643
    pfm = pf_map_new(&parameter);
644
644
  }
645
645
 
646
646
  /* If we are not busy, acquire a target. */
648
648
    enum ai_unit_task task;
649
649
    int move_dist; /* dummy */
650
650
 
651
 
    find_city_to_diplomat(pplayer, punit, &ctarget, &move_dist, map);
 
651
    find_city_to_diplomat(pplayer, punit, &ctarget, &move_dist, pfm);
652
652
 
653
653
    if (ctarget) {
654
654
      task = AIUNIT_ATTACK;
655
655
      aiguard_request_guard(punit);
656
656
      UNIT_LOG(LOG_DIPLOMAT, punit, "going on attack");
657
657
    } else if ((ctarget = ai_diplomat_defend(pplayer, punit,
658
 
                                             unit_type(punit), map)) != NULL) {
 
658
                                             unit_type(punit), pfm)) != NULL) {
659
659
      task = AIUNIT_DEFEND_HOME;
660
660
      UNIT_LOG(LOG_DIPLOMAT, punit, "going to defend %s",
661
661
               city_name(ctarget));
669
669
    } else {
670
670
      UNIT_LOG(LOG_DIPLOMAT, punit, "could not find a job");
671
671
      punit->ai.done = TRUE;
672
 
      pf_destroy_map(map);
 
672
      pf_map_destroy(pfm);
673
673
      return;
674
674
    }
675
675
 
682
682
  if (ctarget == NULL) {
683
683
    UNIT_LOG(LOG_ERROR, punit, "ctarget not set (role==%d)",
684
684
             punit->ai.ai_role);
685
 
    pf_destroy_map(map);
 
685
    pf_map_destroy(pfm);
686
686
    return;
687
687
  }
688
688
 
690
690
  if (!same_pos(punit->tile, ctarget->tile)) {
691
691
    struct pf_path *path;
692
692
 
693
 
    path = pf_get_path(map, punit->goto_tile);
 
693
    path = pf_map_get_path(pfm, punit->goto_tile);
694
694
    if (path && ai_unit_execute_path(punit, path) && punit->moves_left > 0) {
695
695
      /* Check if we can do something with our destination now. */
696
696
      if (punit->ai.ai_role == AIUNIT_ATTACK) {
704
704
        }
705
705
      }
706
706
    }
707
 
    pf_destroy_path(path);
 
707
    pf_path_destroy(path);
708
708
  } else {
709
709
    punit->ai.done = TRUE;
710
710
  }
711
 
  pf_destroy_map(map);
 
711
  pf_map_destroy(pfm);
712
712
}