1 /***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Project
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
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17
18 /* utility */
19 #include "bitvector.h"
20 #include "log.h"
21 #include "mem.h"
22 #include "shared.h"
23 #include "timing.h"
24
25 /* common */
26 #include "actions.h"
27 #include "city.h"
28 #include "combat.h"
29 #include "game.h"
30 #include "government.h"
31 #include "map.h"
32 #include "movement.h"
33 #include "packets.h"
34 #include "player.h"
35 #include "research.h"
36 #include "unit.h"
37 #include "unitlist.h"
38
39 /* aicore */
40 #include "pf_tools.h"
41
42 /* server */
43 #include "barbarian.h"
44 #include "citytools.h"
45 #include "cityturn.h"
46 #include "diplomats.h"
47 #include "maphand.h"
48 #include "srv_log.h"
49 #include "unithand.h"
50 #include "unittools.h"
51
52 /* server/advisors */
53 #include "advbuilding.h"
54 #include "advdata.h"
55 #include "advgoto.h"
56 #include "autosettlers.h"
57
58 /* ai */
59 #include "handicaps.h"
60
61 /* ai/default */
62 #include "aicity.h"
63 #include "aidata.h"
64 #include "aiguard.h"
65 #include "aihand.h"
66 #include "ailog.h"
67 #include "aiplayer.h"
68 #include "aitools.h"
69 #include "aiunit.h"
70 #include "daimilitary.h"
71
72 #include "aidiplomat.h"
73
74
75 #define LOG_DIPLOMAT LOG_DEBUG
76 #define LOG_DIPLOMAT_BUILD LOG_DEBUG
77
78 /* 3000 is a just a large number, but not hillariously large as the
79 * previously used one. This is important for diplomacy. - Per */
80 #define DIPLO_DEFENSE_WANT 3000
81
82 static bool is_city_surrounded_by_our_spies(struct player *pplayer,
83 struct city *pcity);
84
85 static void find_city_to_diplomat(struct player *pplayer, struct unit *punit,
86 struct city **ctarget, int *move_dist,
87 struct pf_map *pfm);
88
89 /******************************************************************************
90 Number of improvements that can be sabotaged in pcity.
91 ******************************************************************************/
count_sabotagable_improvements(struct city * pcity)92 static int count_sabotagable_improvements(struct city *pcity)
93 {
94 int count = 0;
95
96 city_built_iterate(pcity, pimprove) {
97 if (pimprove->sabotage > 0) {
98 count++;
99 }
100 } city_built_iterate_end;
101
102 return count;
103 }
104
105 /******************************************************************************
106 Number of techs that we don't have and the enemy (tplayer) does.
107 ******************************************************************************/
count_stealable_techs(struct player * pplayer,struct player * tplayer)108 static int count_stealable_techs(struct player *pplayer, struct player *tplayer)
109 {
110 struct research *presearch = research_get(pplayer);
111 struct research *tresearch = research_get(tplayer);
112 int count = 0;
113
114 advance_index_iterate(A_FIRST, idx) {
115 if (research_invention_state(presearch, idx) != TECH_KNOWN
116 && research_invention_state(tresearch, idx) == TECH_KNOWN) {
117 count++;
118 }
119 } advance_index_iterate_end;
120
121 return count;
122 }
123
124 /**********************************************************************
125 Calculates our need for diplomats as defensive units. May replace
126 values in choice. The values 16000 and 3000 used below are totally
127 arbitrary but seem to work.
128 ***********************************************************************/
dai_choose_diplomat_defensive(struct ai_type * ait,struct player * pplayer,struct city * pcity,struct adv_choice * choice,int def)129 void dai_choose_diplomat_defensive(struct ai_type *ait,
130 struct player *pplayer,
131 struct city *pcity,
132 struct adv_choice *choice, int def)
133 {
134 /* Build a diplomat if our city is threatened by enemy diplomats, and
135 we have other defensive troops, and we don't already have a diplomat
136 to protect us. If we see an enemy diplomat and we don't have diplomat
137 tech... race it! */
138 struct ai_city *city_data = def_ai_city_data(pcity, ait);
139
140 if (def != 0 && city_data->diplomat_threat
141 && !city_data->has_diplomat) {
142 struct unit_type *ut = best_role_unit(pcity, UTYF_DIPLOMAT);
143
144 if (ut) {
145 log_base(LOG_DIPLOMAT_BUILD,
146 "A defensive diplomat will be built in city %s.",
147 city_name_get(pcity));
148 choice->want = 16000; /* diplomat more important than soldiers */
149 city_data->urgency = 1;
150 choice->type = CT_DEFENDER;
151 choice->value.utype = ut;
152 choice->need_boat = FALSE;
153 } else if (num_role_units(UTYF_DIPLOMAT) > 0) {
154 /* We don't know diplomats yet... */
155 log_base(LOG_DIPLOMAT_BUILD,
156 "A defensive diplomat is wanted badly in city %s.",
157 city_name_get(pcity));
158 ut = get_role_unit(UTYF_DIPLOMAT, 0);
159 if (ut) {
160 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
161
162 plr_data->tech_want[advance_index(ut->require_advance)]
163 += DIPLO_DEFENSE_WANT;
164 TECH_LOG(ait, LOG_DEBUG, pplayer, ut->require_advance,
165 "ai_choose_diplomat_defensive() + %d for %s",
166 DIPLO_DEFENSE_WANT,
167 utype_rule_name(ut));
168 }
169 }
170 }
171 }
172
173 /**********************************************************************
174 Calculates our need for diplomats as offensive units. May replace
175 values in choice.
176 ***********************************************************************/
dai_choose_diplomat_offensive(struct ai_type * ait,struct player * pplayer,struct city * pcity,struct adv_choice * choice)177 void dai_choose_diplomat_offensive(struct ai_type *ait,
178 struct player *pplayer,
179 struct city *pcity,
180 struct adv_choice *choice)
181 {
182 struct unit_type *ut = best_role_unit(pcity, UTYF_DIPLOMAT);
183 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
184 int expenses;
185
186 dai_calc_data(pplayer, NULL, &expenses, NULL);
187
188 if (!ut) {
189 /* We don't know diplomats yet! */
190 return;
191 }
192
193 if (has_handicap(pplayer, H_DIPLOMAT)) {
194 /* Diplomats are too tough on newbies */
195 return;
196 }
197
198 /* Do we have a good reason for building diplomats? */
199 {
200 const struct research *presearch = research_get(pplayer);
201 struct pf_map *pfm;
202 struct pf_parameter parameter;
203 struct city *acity;
204 int want, loss, p_success, p_failure, time_to_dest;
205 int gain_incite = 0, gain_theft = 0, gain = 1;
206 int incite_cost;
207 struct unit *punit = unit_virtual_create(pplayer, pcity, ut,
208 do_make_unit_veteran(pcity, ut));
209
210 pft_fill_unit_parameter(¶meter, punit);
211 parameter.omniscience = !has_handicap(pplayer, H_MAP);
212 pfm = pf_map_new(¶meter);
213
214 find_city_to_diplomat(pplayer, punit, &acity, &time_to_dest, pfm);
215
216 pf_map_destroy(pfm);
217 unit_virtual_destroy(punit);
218
219 if (acity == NULL
220 || BV_ISSET(ai->stats.diplomat_reservations, acity->id)) {
221 /* Found no target or city already considered */
222 return;
223 }
224 incite_cost = city_incite_cost(pplayer, acity);
225 if (POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(acity))
226 && is_action_possible_on_city(ACTION_SPY_INCITE_CITY,
227 pplayer, acity)
228 && (incite_cost < INCITE_IMPOSSIBLE_COST)
229 && (incite_cost < pplayer->economic.gold - expenses)) {
230 /* incite gain (FIXME: we should count wonders too but need to
231 cache that somehow to avoid CPU hog -- Per) */
232 gain_incite = acity->prod[O_FOOD] * FOOD_WEIGHTING
233 + acity->prod[O_SHIELD] * SHIELD_WEIGHTING
234 + (acity->prod[O_LUXURY]
235 + acity->prod[O_GOLD]
236 + acity->prod[O_SCIENCE]) * TRADE_WEIGHTING;
237 gain_incite *= SHIELD_WEIGHTING; /* WAG cost to take city otherwise */
238 gain_incite -= incite_cost * TRADE_WEIGHTING;
239 }
240 if ((research_get(city_owner(acity))->techs_researched
241 > presearch->techs_researched)
242 && (is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH,
243 pplayer, acity)
244 || is_action_possible_on_city(ACTION_SPY_STEAL_TECH,
245 pplayer, acity))
246 && !pplayers_allied(pplayer, city_owner(acity))) {
247 /* tech theft gain */
248 /* FIXME: this value is right only when
249 * 'game.info.game.info.tech_cost_style' is set to
250 * TECH_COST_CIV1CIV2. */
251 gain_theft =
252 (research_total_bulbs_required(presearch, presearch->researching,
253 FALSE) * TRADE_WEIGHTING);
254 }
255 gain = MAX(gain_incite, gain_theft);
256 loss = utype_build_shield_cost(ut) * SHIELD_WEIGHTING;
257
258 /* Probability to succeed, assuming no defending diplomat */
259 p_success = game.server.diplchance;
260 /* Probability to lose our unit */
261 p_failure = (utype_has_flag(ut, UTYF_SPY) ? 100 - p_success : 100);
262
263 /* Get the time to dest in turns (minimum 1 turn) */
264 time_to_dest = (time_to_dest + ut->move_rate - 1) / ut->move_rate;
265 /* Discourage long treks */
266 time_to_dest *= ((time_to_dest + 1) / 2);
267
268 /* Almost kill_desire */
269 want = (p_success * gain - p_failure * loss) / 100
270 - SHIELD_WEIGHTING * time_to_dest;
271 if (want <= 0) {
272 return;
273 }
274
275 want = military_amortize(pplayer, pcity, want, time_to_dest,
276 utype_build_shield_cost(ut));
277
278 if (!player_has_embassy(pplayer, city_owner(acity))
279 && want < 99
280 && is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY,
281 pplayer, acity)) {
282 log_base(LOG_DIPLOMAT_BUILD,
283 "A diplomat desired in %s to establish an embassy with %s "
284 "in %s",
285 city_name_get(pcity),
286 player_name(city_owner(acity)),
287 city_name_get(acity));
288 want = 99;
289 }
290 if (want > choice->want) {
291 log_base(LOG_DIPLOMAT_BUILD,
292 "%s, %s: %s is desired with want %d to spy in %s (incite "
293 "want %d cost %d gold %d, tech theft want %d, ttd %d)",
294 player_name(pplayer),
295 city_name_get(pcity),
296 utype_rule_name(ut),
297 want,
298 city_name_get(acity),
299 gain_incite,
300 incite_cost,
301 pplayer->economic.gold - expenses,
302 gain_theft,
303 time_to_dest);
304 choice->want = want;
305 choice->type = CT_CIVILIAN; /* so we don't build barracks for it */
306 choice->value.utype = ut;
307 choice->need_boat = FALSE;
308 BV_SET(ai->stats.diplomat_reservations, acity->id);
309 }
310 }
311 }
312
313 /**************************************************************************
314 Pick a tech for actor_player to steal from target_player.
315
316 TODO: Make a smarter choice than picking the first stealable tech found.
317 **************************************************************************/
318 static Tech_type_id
choose_tech_to_steal(const struct player * actor_player,const struct player * target_player)319 choose_tech_to_steal(const struct player *actor_player,
320 const struct player *target_player)
321 {
322 const struct research *actor_research = research_get(actor_player);
323 const struct research *target_research = research_get(target_player);
324
325 if (actor_research != target_research) {
326 if (can_see_techs_of_target(actor_player, target_player)) {
327 advance_iterate(A_FIRST, padvance) {
328 Tech_type_id i = advance_number(padvance);
329
330 if (research_invention_state(target_research, i) == TECH_KNOWN
331 && research_invention_gettable(actor_research, i,
332 game.info.tech_steal_allow_holes)
333 && (research_invention_state(actor_research, i) == TECH_UNKNOWN
334 || (research_invention_state(actor_research, i)
335 == TECH_PREREQS_KNOWN))) {
336
337 return i;
338 }
339 } advance_iterate_end;
340 }
341 }
342
343 /* Unable to find a target. */
344 return A_UNSET;
345 }
346
347 /**************************************************************************
348 Check if something is on our receiving end for some nasty diplomat
349 business! Note that punit may die or be moved during this function. We
350 must be adjacent to target city.
351
352 We try to make embassy first, and abort if we already have one and target
353 is allied. Then we steal, incite, sabotage or poison the city, in that
354 order of priority.
355 **************************************************************************/
dai_diplomat_city(struct ai_type * ait,struct unit * punit,struct city * ctarget)356 static void dai_diplomat_city(struct ai_type *ait, struct unit *punit,
357 struct city *ctarget)
358 {
359 struct player *pplayer = unit_owner(punit);
360 struct player *tplayer = city_owner(ctarget);
361 int count_impr = count_sabotagable_improvements(ctarget);
362 int count_tech = count_stealable_techs(pplayer, tplayer);
363 int incite_cost, expenses;
364
365 fc_assert_ret(pplayer->ai_controlled);
366
367 if (punit->moves_left == 0) {
368 UNIT_LOG(LOG_ERROR, punit, "no moves left in ai_diplomat_city()!");
369 }
370
371 unit_activity_handling(punit, ACTIVITY_IDLE);
372
373 #define T(my_act, my_val) \
374 if (action_prob_possible(action_prob_vs_city(punit, my_act, ctarget))) { \
375 log_base(LOG_DIPLOMAT, "%s %s[%d] does " #my_act " at %s", \
376 nation_rule_name(nation_of_unit(punit)), \
377 unit_rule_name(punit), punit->id, city_name_get(ctarget)); \
378 handle_unit_do_action(pplayer, punit->id, \
379 ctarget->id, my_val, my_act); \
380 return; \
381 }
382
383 T(ACTION_ESTABLISH_EMBASSY, 0);
384
385 if (pplayers_allied(pplayer, tplayer)) {
386 return; /* Don't do the rest to allies */
387 }
388
389 if (count_tech > 0
390 && (ctarget->server.steal == 0
391 || unit_has_type_flag(punit, UTYF_SPY))) {
392 Tech_type_id tgt_tech;
393
394 /* Picking a random tech has better odds. */
395 T(ACTION_SPY_STEAL_TECH, 0);
396
397 /* Not able to steal a random tech. This means worse odds. */
398 tgt_tech = choose_tech_to_steal(pplayer, tplayer);
399 if (tgt_tech != A_UNSET) {
400 /* A tech target can be identified. */
401 T(ACTION_SPY_TARGETED_STEAL_TECH, tgt_tech);
402 }
403 } else {
404 UNIT_LOG(LOG_DIPLOMAT, punit, "We have already stolen from %s!",
405 city_name_get(ctarget));
406 }
407
408 incite_cost = city_incite_cost(pplayer, ctarget);
409 dai_calc_data(pplayer, NULL, &expenses, NULL);
410
411 if (incite_cost <= pplayer->economic.gold - 2 * expenses) {
412 T(ACTION_SPY_INCITE_CITY, 0);
413 } else {
414 UNIT_LOG(LOG_DIPLOMAT, punit, "%s too expensive!",
415 city_name_get(ctarget));
416 }
417
418 if (!pplayers_at_war(pplayer, tplayer)) {
419 return; /* The rest are casus belli */
420 }
421
422 if (count_impr > 0) {
423 T(ACTION_SPY_SABOTAGE_CITY, 0);
424 }
425
426 /* Sabotage a specific city improvement. This has worse odds than
427 * sabotaging a random city improvement. */
428 if (count_impr > 0) {
429 /* TODO: consider target improvements in stead of always going after
430 * the current production. */
431 int tgt_impr = -1;
432
433 T(ACTION_SPY_TARGETED_SABOTAGE_CITY, tgt_impr + 1);
434 }
435
436 T(ACTION_SPY_STEAL_GOLD, 0);
437
438 T(ACTION_SPY_POISON, 0); /* absolutely last resort */
439 #undef T
440
441 /* This can happen for a number of odd and esoteric reasons */
442 UNIT_LOG(LOG_DIPLOMAT, punit,
443 "decides to stand idle outside enemy city %s!",
444 city_name_get(ctarget));
445 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
446 }
447
448 /*****************************************************************************
449 Check if we have a diplomat / spy near a given city. This is used to prevent
450 a stack of such units next to a foreign city.
451 *****************************************************************************/
is_city_surrounded_by_our_spies(struct player * pplayer,struct city * enemy_city)452 static bool is_city_surrounded_by_our_spies(struct player *pplayer,
453 struct city *enemy_city)
454 {
455 adjc_iterate(city_tile(enemy_city), ptile) {
456 if (has_handicap(pplayer, H_FOG)
457 && !map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
458 /* We cannot see danger at (ptile) => assume there is none. */
459 continue;
460 }
461 unit_list_iterate(ptile->units, punit) {
462 if (unit_owner(punit) == pplayer &&
463 utype_acts_hostile(unit_type_get(punit))) {
464 return TRUE;
465 }
466 } unit_list_iterate_end;
467 } adjc_iterate_end;
468
469 return FALSE;
470 }
471
472 /**************************************************************************
473 Returns (in ctarget) the closest city to send diplomats against, or NULL
474 if none available on this continent. punit can be virtual.
475 **************************************************************************/
find_city_to_diplomat(struct player * pplayer,struct unit * punit,struct city ** ctarget,int * move_dist,struct pf_map * pfm)476 static void find_city_to_diplomat(struct player *pplayer, struct unit *punit,
477 struct city **ctarget, int *move_dist,
478 struct pf_map *pfm)
479 {
480 bool has_embassy;
481 int incite_cost = 0; /* incite cost */
482 int expenses;
483 bool dipldef; /* whether target is protected by diplomats */
484
485 fc_assert_ret(punit != NULL);
486 *ctarget = NULL;
487 *move_dist = -1;
488 dai_calc_data(pplayer, NULL, &expenses, NULL);
489
490 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
491 struct city *acity;
492 struct player *aplayer;
493 bool can_incite;
494 bool can_steal;
495
496 acity = tile_city(ptile);
497
498 if (!acity) {
499 continue;
500 }
501 aplayer = city_owner(acity);
502
503 has_embassy = player_has_embassy(pplayer, aplayer);
504
505 if (aplayer == pplayer || is_barbarian(aplayer)
506 || (pplayers_allied(pplayer, aplayer) && has_embassy)) {
507 continue;
508 }
509
510 incite_cost = city_incite_cost(pplayer, acity);
511 can_incite = (incite_cost < INCITE_IMPOSSIBLE_COST)
512 && is_action_possible_on_city(ACTION_SPY_INCITE_CITY,
513 pplayer, acity);
514
515 can_steal = is_action_possible_on_city(ACTION_SPY_STEAL_TECH,
516 pplayer, acity)
517 || is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH,
518 pplayer, acity);
519
520 dipldef = (count_diplomats_on_tile(acity->tile) > 0);
521 /* Three actions to consider:
522 * 1. establishing embassy OR
523 * 2. stealing techs OR
524 * 3. inciting revolt */
525 if ((!has_embassy
526 && is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY,
527 pplayer, acity))
528 || (acity->server.steal == 0
529 && !dipldef && can_steal
530 && (research_get(pplayer)->techs_researched
531 < research_get(aplayer)->techs_researched))
532 || (incite_cost < (pplayer->economic.gold - expenses)
533 && can_incite && !dipldef)) {
534 if (!is_city_surrounded_by_our_spies(pplayer, acity)) {
535 /* We have the closest enemy city on the continent */
536 *ctarget = acity;
537 *move_dist = move_cost;
538 break;
539 }
540 }
541 } pf_map_move_costs_iterate_end;
542 }
543
544 /**************************************************************************
545 Go to nearest/most threatened city (can be the current city too).
546 **************************************************************************/
dai_diplomat_defend(struct ai_type * ait,struct player * pplayer,struct unit * punit,const struct unit_type * utype,struct pf_map * pfm)547 static struct city *dai_diplomat_defend(struct ai_type *ait,
548 struct player *pplayer,
549 struct unit *punit,
550 const struct unit_type *utype,
551 struct pf_map *pfm)
552 {
553 int best_dist = 30; /* any city closer than this is better than none */
554 int best_urgency = 0;
555 struct city *ctarget = NULL;
556 struct city *pcity = tile_city(unit_tile(punit));
557
558 if (pcity
559 && count_diplomats_on_tile(pcity->tile) == 1
560 && def_ai_city_data(pcity, ait)->urgency > 0) {
561 /* Danger and we are only diplomat present - stay. */
562 return pcity;
563 }
564
565 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
566 struct city *acity;
567 struct player *aplayer;
568 int dipls, urgency;
569 struct ai_city *city_data;
570
571 acity = tile_city(ptile);
572 if (!acity) {
573 continue;
574 }
575 aplayer = city_owner(acity);
576 if (aplayer != pplayer) {
577 continue;
578 }
579
580 city_data = def_ai_city_data(acity, ait);
581 urgency = city_data->urgency;
582 dipls = (count_diplomats_on_tile(ptile)
583 - (same_pos(ptile, unit_tile(punit)) ? 1 : 0));
584 if (dipls == 0 && city_data->diplomat_threat) {
585 /* We are _really_ needed there */
586 urgency = (urgency + 1) * 5;
587 } else if (dipls > 0) {
588 /* We are probably not needed there... */
589 urgency /= 3;
590 }
591
592 /* This formula may not be optimal, but it works. */
593 if (move_cost > best_dist) {
594 /* punish city for being so far away */
595 urgency /= (float) (move_cost / best_dist);
596 }
597
598 if (urgency > best_urgency) {
599 /* Found something worthy of our presence */
600 ctarget = acity;
601 best_urgency = urgency;
602 /* squelch divide-by-zero */
603 best_dist = MAX(move_cost, 1);
604 }
605 } pf_map_move_costs_iterate_end;
606
607 return ctarget;
608 }
609
610 /**************************************************************************
611 Find units that we can reach, and bribe them. Returns TRUE if survived
612 the ordeal, FALSE if not or we expended all our movement.
613 Will try to bribe a ship on the coast as well as land stuff.
614 **************************************************************************/
dai_diplomat_bribe_nearby(struct ai_type * ait,struct player * pplayer,struct unit * punit,struct pf_map * pfm)615 static bool dai_diplomat_bribe_nearby(struct ai_type *ait,
616 struct player *pplayer,
617 struct unit *punit, struct pf_map *pfm)
618 {
619 int gold_avail, expenses;
620
621 dai_calc_data(pplayer, NULL, &expenses, NULL);
622 gold_avail = pplayer->economic.gold - expenses;
623
624 pf_map_positions_iterate(pfm, pos, FALSE) {
625 struct tile *ptile = pos.tile;
626 bool threat = FALSE;
627 int newval, bestval = 0, cost;
628 struct unit *pvictim = is_other_players_unit_tile(ptile, pplayer);
629 int sanity = punit->id;
630 struct unit_type *ptype;
631
632 if (pos.total_MC > punit->moves_left) {
633 /* Didn't find anything within range. */
634 break;
635 }
636
637 if (!pvictim
638 || !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, unit_owner(pvictim))
639 || unit_list_size(ptile->units) > 1
640 || tile_city(ptile)
641 || !is_action_enabled_unit_on_unit(ACTION_SPY_BRIBE_UNIT,
642 punit, pvictim)) {
643 continue;
644 }
645
646 /* Calculate if enemy is a threat */
647 /* First find best defender on our tile */
648 unit_list_iterate(ptile->units, aunit) {
649 struct unit_type *atype = unit_type_get(aunit);
650
651 newval = DEFENSE_POWER(atype);
652 if (bestval < newval) {
653 bestval = newval;
654 }
655 } unit_list_iterate_end;
656 /* Compare with victim's attack power */
657 ptype = unit_type_get(pvictim);
658 newval = ATTACK_POWER(ptype);
659 if (newval > bestval
660 && unit_move_rate(pvictim) > pos.total_MC) {
661 /* Enemy can probably kill us */
662 threat = TRUE;
663 } else {
664 /* Enemy cannot reach us or probably not kill us */
665 threat = FALSE;
666 }
667 /* Don't bribe settlers! */
668 if (unit_has_type_flag(pvictim, UTYF_SETTLERS)
669 || unit_has_type_flag(pvictim, UTYF_CITIES)) {
670 continue;
671 }
672 /* Should we make the expense? */
673 cost = unit_bribe_cost(pvictim, pplayer);
674 if (!threat) {
675 /* Don't empty our treasure without good reason! */
676 gold_avail = pplayer->economic.gold - dai_gold_reserve(pplayer);
677 }
678 if (cost > gold_avail) {
679 /* Can't afford */
680 continue;
681 }
682
683 /* Found someone! */
684 {
685 struct tile *bribee_tile;
686 struct pf_path *path;
687
688 bribee_tile = mapstep(pos.tile, DIR_REVERSE(pos.dir_to_here));
689 path = pf_map_path(pfm, bribee_tile);
690 if (!path || !adv_unit_execute_path(punit, path)
691 || punit->moves_left <= 0) {
692 pf_path_destroy(path);
693 return FALSE;
694 }
695 pf_path_destroy(path);
696 }
697
698 if (action_prob_possible(action_prob_vs_unit(punit,
699 ACTION_SPY_BRIBE_UNIT,
700 pvictim))) {
701 handle_unit_do_action(pplayer, punit->id,
702 pvictim->id, -1,
703 ACTION_SPY_BRIBE_UNIT);
704 /* autoattack might kill us as we move in */
705 if (game_unit_by_number(sanity) && punit->moves_left > 0) {
706 return TRUE;
707 } else {
708 return FALSE;
709 }
710 } else if (action_prob_possible(action_prob_vs_unit(punit,
711 ACTION_SPY_SABOTAGE_UNIT,
712 pvictim))
713 && threat) {
714 /* don't stand around waiting for the final blow */
715 handle_unit_do_action(pplayer, punit->id,
716 pvictim->id, -1,
717 ACTION_SPY_SABOTAGE_UNIT);
718 /* autoattack might kill us as we move in */
719 if (game_unit_by_number(sanity) && punit->moves_left > 0) {
720 return TRUE;
721 } else {
722 return FALSE;
723 }
724 } else {
725 /* usually because we ended move early due to another unit */
726 UNIT_LOG(LOG_DIPLOMAT, punit, "could not bribe target (%d, %d), "
727 " %d moves left", TILE_XY(pos.tile), punit->moves_left);
728 return FALSE;
729 }
730 } pf_map_positions_iterate_end;
731
732 return (punit->moves_left > 0);
733 }
734
735 /**************************************************************************
736 If we are the only diplomat in a threatened city, defend against enemy
737 actions. The passive defense is set by game.diplchance. The active
738 defense is to bribe units which end their move nearby. Our next trick is
739 to look for enemy cities on our continent and do our diplomat things.
740
741 FIXME: It is important to establish contact with all civilizations, so
742 we should send diplomats by boat eventually. I just don't know how that
743 part of the code works, yet - Per
744 **************************************************************************/
dai_manage_diplomat(struct ai_type * ait,struct player * pplayer,struct unit * punit)745 void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer,
746 struct unit *punit)
747 {
748 struct city *pcity, *ctarget = NULL;
749 struct pf_parameter parameter;
750 struct pf_map *pfm;
751 struct pf_position pos;
752 struct unit_ai *unit_data;
753
754 CHECK_UNIT(punit);
755
756 /* Generate map */
757 pft_fill_unit_parameter(¶meter, punit);
758 parameter.omniscience = !has_handicap(pplayer, H_MAP);
759 parameter.get_zoc = NULL; /* kludge */
760 parameter.get_TB = no_intermediate_fights;
761 pfm = pf_map_new(¶meter);
762
763 pcity = tile_city(unit_tile(punit));
764
765 /* Look for someone to bribe */
766 if (!dai_diplomat_bribe_nearby(ait, pplayer, punit, pfm)) {
767 /* Died or ran out of moves */
768 pf_map_destroy(pfm);
769 return;
770 }
771
772 /* If we are the only diplomat in a threatened city, then stay to defend */
773 pcity = tile_city(unit_tile(punit)); /* we may have moved */
774 if (pcity) {
775 struct ai_city *city_data = def_ai_city_data(pcity, ait);
776
777 if (count_diplomats_on_tile(unit_tile(punit)) == 1
778 && (city_data->diplomat_threat
779 || city_data->urgency > 0)) {
780 UNIT_LOG(LOG_DIPLOMAT, punit, "stays to protect %s (urg %d)",
781 city_name_get(pcity), city_data->urgency);
782 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); /* abort mission */
783 def_ai_unit_data(punit, ait)->done = TRUE;
784 pf_map_destroy(pfm);
785 return;
786 }
787 }
788
789 unit_data = def_ai_unit_data(punit, ait);
790
791 /* Check if existing target still makes sense */
792 if (unit_data->task == AIUNIT_ATTACK
793 || unit_data->task == AIUNIT_DEFEND_HOME) {
794 bool failure = FALSE;
795
796 ctarget = tile_city(punit->goto_tile);
797 if (pf_map_position(pfm, punit->goto_tile, &pos)
798 && ctarget) {
799 if (same_pos(ctarget->tile, unit_tile(punit))) {
800 failure = TRUE;
801 } else if (pplayers_allied(pplayer, city_owner(ctarget))
802 && unit_data->task == AIUNIT_ATTACK
803 && player_has_embassy(pplayer, city_owner(ctarget))) {
804 /* We probably incited this city with another diplomat */
805 failure = TRUE;
806 } else if (!pplayers_allied(pplayer, city_owner(ctarget))
807 && unit_data->task == AIUNIT_DEFEND_HOME) {
808 /* We probably lost the city */
809 failure = TRUE;
810 }
811 } else {
812 /* City vanished! */
813 failure = TRUE;
814 }
815 if (failure) {
816 UNIT_LOG(LOG_DIPLOMAT, punit, "mission aborted");
817 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
818 }
819 }
820
821 /* We may need a new map now. Both because we cannot get paths from an
822 * old map, and we need paths to move, and because fctd below requires
823 * a new map for its iterator. */
824 if (!same_pos(parameter.start_tile, unit_tile(punit))
825 || unit_data->task == AIUNIT_NONE) {
826 pf_map_destroy(pfm);
827 pft_fill_unit_parameter(¶meter, punit);
828 parameter.omniscience = !has_handicap(pplayer, H_MAP);
829 parameter.get_zoc = NULL; /* kludge */
830 parameter.get_TB = no_intermediate_fights;
831 pfm = pf_map_new(¶meter);
832 }
833
834 /* If we are not busy, acquire a target. */
835 if (unit_data->task == AIUNIT_NONE) {
836 enum ai_unit_task task;
837 int move_dist; /* dummy */
838
839 find_city_to_diplomat(pplayer, punit, &ctarget, &move_dist, pfm);
840
841 if (ctarget) {
842 task = AIUNIT_ATTACK;
843 aiguard_request_guard(ait, punit);
844 UNIT_LOG(LOG_DIPLOMAT, punit, "going on attack");
845 } else if ((ctarget = dai_diplomat_defend(ait, pplayer, punit,
846 unit_type_get(punit), pfm))
847 != NULL) {
848 task = AIUNIT_DEFEND_HOME;
849 UNIT_LOG(LOG_DIPLOMAT, punit, "going to defend %s",
850 city_name_get(ctarget));
851 } else if ((ctarget = find_closest_city(unit_tile(punit), NULL, pplayer,
852 TRUE, FALSE, FALSE, TRUE, FALSE,
853 NULL))
854 != NULL) {
855 /* This should only happen if the entire continent was suddenly
856 * conquered. So we head for closest coastal city and wait for someone
857 * to code ferrying for diplomats, or hostile attacks from the sea. */
858 task = AIUNIT_DEFEND_HOME;
859 UNIT_LOG(LOG_DIPLOMAT, punit, "going idle");
860 } else {
861 UNIT_LOG(LOG_DIPLOMAT, punit, "could not find a job");
862 def_ai_unit_data(punit, ait)->done = TRUE;
863 pf_map_destroy(pfm);
864 return;
865 }
866
867 dai_unit_new_task(ait, punit, task, ctarget->tile);
868 fc_assert(punit->moves_left > 0 && ctarget
869 && unit_data->task != AIUNIT_NONE);
870 }
871
872 CHECK_UNIT(punit);
873 if (ctarget == NULL) {
874 UNIT_LOG(LOG_ERROR, punit, "ctarget not set (task == %d)",
875 unit_data->task);
876 pf_map_destroy(pfm);
877 return;
878 }
879
880 /* GOTO unless we want to stay */
881 if (!same_pos(unit_tile(punit), ctarget->tile)) {
882 struct pf_path *path;
883
884 path = pf_map_path(pfm, punit->goto_tile);
885 if (path && adv_unit_execute_path(punit, path) && punit->moves_left > 0) {
886 /* Check if we can do something with our destination now. */
887 if (unit_data->task == AIUNIT_ATTACK) {
888 int dist = real_map_distance(unit_tile(punit), punit->goto_tile);
889
890 UNIT_LOG(LOG_DIPLOMAT, punit, "attack, dist %d to %s",
891 dist, ctarget ? city_name_get(ctarget) : "(none)");
892 if (dist <= 1) {
893 /* Do our stuff */
894 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
895 dai_diplomat_city(ait, punit, ctarget);
896 }
897 }
898 }
899 pf_path_destroy(path);
900 } else {
901 def_ai_unit_data(punit, ait)->done = TRUE;
902 }
903 pf_map_destroy(pfm);
904 }
905