Freeciv-3.1
Loading...
Searching...
No Matches
aidiplomat.c
Go to the documentation of this file.
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 "aiactions.h"
41#include "pf_tools.h"
42
43/* server */
44#include "barbarian.h"
45#include "citytools.h"
46#include "cityturn.h"
47#include "diplomats.h"
48#include "maphand.h"
49#include "srv_log.h"
50#include "unithand.h"
51#include "unittools.h"
52
53/* server/advisors */
54#include "advbuilding.h"
55#include "advdata.h"
56#include "advgoto.h"
57#include "autosettlers.h"
58
59/* ai */
60#include "handicaps.h"
61
62/* ai/default */
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 "daiactions.h"
71#include "daicity.h"
72#include "daimilitary.h"
73
74#include "aidiplomat.h"
75
76
77#define LOG_DIPLOMAT LOG_DEBUG
78#define LOG_DIPLOMAT_BUILD LOG_DEBUG
79
80/* 3000 is a just a large number, but not hillariously large as the
81 * previously used one. This is important for diplomacy. - Per */
82#define DIPLO_DEFENSE_WANT 3000
83
84static bool is_city_surrounded_by_our_spies(struct player *pplayer,
85 struct city *pcity);
86
87static void find_city_to_diplomat(struct player *pplayer, struct unit *punit,
88 struct city **ctarget, int *move_dist,
89 struct pf_map *pfm);
90
91/**************************************************************************/
94static int count_stealable_techs(struct player *pplayer, struct player *tplayer)
95{
96 struct research *presearch = research_get(pplayer);
97 struct research *tresearch = research_get(tplayer);
98 int count = 0;
99
101 if (research_invention_state(presearch, idx) != TECH_KNOWN
102 && research_invention_state(tresearch, idx) == TECH_KNOWN) {
103 count++;
104 }
106
107 return count;
108}
109
110/**************************************************************************/
116 struct player *pplayer,
117 struct city *pcity,
118 struct adv_choice *choice, int def)
119{
120 /* Build a diplomat if our city is threatened by enemy diplomats, and
121 we have other defensive troops, and we don't already have a diplomat
122 to protect us. If we see an enemy diplomat and we don't have diplomat
123 tech... race it! */
124 struct ai_city *city_data = def_ai_city_data(pcity, ait);
125
126 if (def != 0 && city_data->diplomat_threat
127 && !city_data->has_diplomat) {
128 struct unit_type *ut = best_role_unit(pcity, UTYF_DIPLOMAT);
129
130 if (ut) {
132 "A defensive diplomat will be built in city %s.",
133 city_name_get(pcity));
134 choice->want = 16000; /* diplomat more important than soldiers */
135 city_data->urgency = 1;
136 choice->type = CT_DEFENDER;
137 choice->value.utype = ut;
138 choice->need_boat = FALSE;
139 adv_choice_set_use(choice, "defensive diplomat");
140 } else if (num_role_units(UTYF_DIPLOMAT) > 0) {
141 /* We don't know diplomats yet... */
143 "A defensive diplomat is wanted badly in city %s.",
144 city_name_get(pcity));
145 ut = get_role_unit(UTYF_DIPLOMAT, 0);
146 if (ut) {
147 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
148
151 TECH_LOG(ait, LOG_DEBUG, pplayer, ut->require_advance,
152 "ai_choose_diplomat_defensive() + %d for %s",
154 utype_rule_name(ut));
155 }
156 }
157 }
158}
159
160/**************************************************************************/
165 struct player *pplayer,
166 struct city *pcity,
167 struct adv_choice *choice)
168{
169 struct unit_type *ut = best_role_unit(pcity, UTYF_DIPLOMAT);
170 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
171 int expenses;
172 const struct civ_map *nmap = &(wld.map);
173
174 dai_calc_data(pplayer, NULL, &expenses, NULL);
175
176 if (!ut) {
177 /* We don't know diplomats yet! */
178 return;
179 }
180
181 if (has_handicap(pplayer, H_DIPLOMAT)) {
182 /* Diplomats are too tough on newbies */
183 return;
184 }
185
186 /* Do we have a good reason for building diplomats? */
187 {
188 const struct research *presearch = research_get(pplayer);
189 struct pf_map *pfm;
190 struct pf_parameter parameter;
191 struct city *acity;
192 adv_want want;
193 int loss, p_success, p_failure, time_to_dest;
194 int gain_incite = 0, gain_theft = 0, gain = 1;
195 int incite_cost;
197 pplayer, pcity, ut,
199
200 pft_fill_unit_parameter(&parameter, nmap, punit);
201 parameter.omniscience = !has_handicap(pplayer, H_MAP);
202 pfm = pf_map_new(&parameter);
203
204 find_city_to_diplomat(pplayer, punit, &acity, &time_to_dest, pfm);
205
206 pf_map_destroy(pfm);
208
209 if (acity == NULL
210 || BV_ISSET(ai->stats.diplomat_reservations, acity->id)) {
211 /* Found no target or city already considered */
212 return;
213 }
214 incite_cost = city_incite_cost(pplayer, acity);
215 if (POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(acity))
216 && (is_action_possible_on_city(ACTION_SPY_INCITE_CITY,
217 pplayer, acity)
218 || is_action_possible_on_city(ACTION_SPY_INCITE_CITY_ESC,
219 pplayer, acity))
220 && (incite_cost < INCITE_IMPOSSIBLE_COST)
221 && (incite_cost < pplayer->economic.gold - expenses)) {
222 /* incite gain (FIXME: we should count wonders too but need to
223 cache that somehow to avoid CPU hog -- Per) */
224 gain_incite = acity->prod[O_FOOD] * FOOD_WEIGHTING
225 + acity->prod[O_SHIELD] * SHIELD_WEIGHTING
226 + (acity->prod[O_LUXURY]
227 + acity->prod[O_GOLD]
228 + acity->prod[O_SCIENCE]) * TRADE_WEIGHTING;
229 gain_incite *= SHIELD_WEIGHTING; /* WAG cost to take city otherwise */
230 gain_incite -= incite_cost * TRADE_WEIGHTING;
231 }
232 if ((research_get(city_owner(acity))->techs_researched
233 > presearch->techs_researched)
234 && (is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH,
235 pplayer, acity)
236 || is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH_ESC,
237 pplayer, acity)
238 || is_action_possible_on_city(ACTION_SPY_STEAL_TECH,
239 pplayer, acity)
240 || is_action_possible_on_city(ACTION_SPY_STEAL_TECH_ESC,
241 pplayer, acity))
242 && !pplayers_allied(pplayer, city_owner(acity))) {
243 /* tech theft gain */
244 /* FIXME: this value is right only when
245 * 'game.info.game.info.tech_cost_style' is set to
246 * TECH_COST_CIV1CIV2. */
247 gain_theft =
248 (research_total_bulbs_required(presearch, presearch->researching,
250 }
251 gain = MAX(gain_incite, gain_theft);
252 loss = utype_build_shield_cost(pcity, NULL, ut) * SHIELD_WEIGHTING;
253
254 /* Probability to succeed, assuming no defending diplomat */
255 p_success = game.server.diplchance;
256 /* Probability to lose our unit */
257 p_failure = (utype_can_do_action(ut, ACTION_SPY_TARGETED_STEAL_TECH_ESC)
258 || utype_can_do_action(ut, ACTION_SPY_STEAL_TECH_ESC) ?
259 100 - p_success :
260 100);
261
262 /* Get the time to dest in turns (minimum 1 turn) */
263 time_to_dest = (time_to_dest + ut->move_rate - 1) / ut->move_rate;
264 /* Discourage long treks */
265 time_to_dest *= ((time_to_dest + 1) / 2);
266
267 /* Almost kill_desire() */
268 want = (adv_want)(p_success * gain - p_failure * loss) / 100
269 - SHIELD_WEIGHTING * time_to_dest;
270 if (want <= 0) {
271 return;
272 }
273
274 want = military_amortize(pplayer, pcity, want, time_to_dest,
275 utype_build_shield_cost(pcity, NULL, ut));
276
277 if (!player_has_embassy(pplayer, city_owner(acity))
278 && want < 99
279 && (is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY,
280 pplayer, acity)
281 || is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY_STAY,
282 pplayer, acity))) {
284 "A diplomat desired in %s to establish an embassy with %s "
285 "in %s",
286 city_name_get(pcity),
287 player_name(city_owner(acity)),
288 city_name_get(acity));
289 want = 99;
290 }
291 if (want > choice->want) {
293 "%s, %s: %s is desired with want " ADV_WANT_PRINTF
294 " to spy in %s (incite want %d cost %d gold %d, "
295 "tech theft want %d, ttd %d)",
296 player_name(pplayer),
297 city_name_get(pcity),
298 utype_rule_name(ut),
299 want,
300 city_name_get(acity),
301 gain_incite,
302 incite_cost,
303 pplayer->economic.gold - expenses,
304 gain_theft,
305 time_to_dest);
306 choice->want = want;
307 choice->type = CT_CIVILIAN; /* so we don't build barracks for it */
308 choice->value.utype = ut;
309 choice->need_boat = FALSE;
310 adv_choice_set_use(choice, "offensive diplomat");
312 }
313 }
314}
315
316/**************************************************************************/
325static void dai_diplomat_city(struct ai_type *ait, struct unit *punit,
326 struct city *ctarget)
327{
328 struct action *chosen_action;
329 adv_want chosen_action_utility;
330 int chosen_sub_tgt_id;
331 struct player *pplayer = unit_owner(punit);
332 struct player *tplayer = city_owner(ctarget);
333 int count_tech = count_stealable_techs(pplayer, tplayer);
334 const struct civ_map *nmap = &(wld.map);
335
336 fc_assert_ret(is_ai(pplayer));
337
338 if (punit->moves_left == 0) {
339 UNIT_LOG(LOG_ERROR, punit, "no moves left in ai_diplomat_city()!");
340 }
341
342 unit_activity_handling(punit, ACTIVITY_IDLE);
343
344 /* Select the best potentially legal action. */
345 /* FIXME: what if it is illegal? */
346 chosen_action = NULL;
347 chosen_action_utility = -1;
348 chosen_sub_tgt_id = 0;
349 action_iterate(act_id) {
350 struct action *paction = action_by_number(act_id);
351 adv_want action_utility;
352 int sub_tgt_id;
353
354 if (action_get_actor_kind(paction) != AAK_UNIT
355 || action_get_target_kind(paction) != ATK_CITY) {
356 /* Not relevant here. */
357 continue;
358 }
359
361 action_prob_vs_city(nmap, punit, action_number(paction),ctarget))) {
362 /* Not possible. */
363 continue;
364 }
365
366 if (paction->target_complexity == ACT_TGT_COMPL_SIMPLE) {
367 /* No sub target */
368 sub_tgt_id = 0;
369 } else {
370 /* Pick a suitable sub target. */
371 sub_tgt_id = dai_action_choose_sub_tgt_unit_vs_city(paction,
372 punit, ctarget);
373 }
374
375 action_utility = dai_action_value_unit_vs_city(paction, punit,
376 ctarget, sub_tgt_id,
377 count_tech);
378
379 if (chosen_action_utility < action_utility) {
380 chosen_action = paction;
381 chosen_action_utility = action_utility;
382 chosen_sub_tgt_id = sub_tgt_id;
383 }
385
386 if (chosen_action != NULL) {
387 /* An action has been selected. */
388
390 action_prob_vs_city(nmap, punit, action_number(chosen_action),
391 ctarget))) {
392 log_base(LOG_DIPLOMAT, "%s %s[%d] does %s at %s",
395 action_rule_name(chosen_action),
396 city_name_get(ctarget));
397 unit_do_action(pplayer, punit->id,
398 ctarget->id, chosen_sub_tgt_id, "",
399 action_number(chosen_action));
400 return;
401 }
402 }
403
404 /* This can happen for a number of odd and esoteric reasons */
406 "decides to stand idle outside enemy city %s!",
407 city_name_get(ctarget));
409}
410
411/**************************************************************************/
415static bool is_city_surrounded_by_our_spies(struct player *pplayer,
416 struct city *enemy_city)
417{
418 adjc_iterate(&(wld.map), city_tile(enemy_city), ptile) {
419 if (has_handicap(pplayer, H_FOG)
420 && !map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
421 /* We cannot see danger at (ptile) => assume there is none. */
422 continue;
423 }
424 unit_list_iterate(ptile->units, punit) {
425 if (unit_owner(punit) == pplayer
427 return TRUE;
428 }
431
432 return FALSE;
433}
434
435/**************************************************************************/
439static void find_city_to_diplomat(struct player *pplayer, struct unit *punit,
440 struct city **ctarget, int *move_dist,
441 struct pf_map *pfm)
442{
443 bool has_embassy;
444 int incite_cost = 0; /* incite cost */
445 int expenses;
446 bool dipldef; /* whether target is protected by diplomats */
447
448 fc_assert_ret(punit != NULL);
449 *ctarget = NULL;
450 *move_dist = -1;
451 dai_calc_data(pplayer, NULL, &expenses, NULL);
452
453 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
454 struct city *acity;
455 struct player *aplayer;
456 bool can_incite;
457 bool can_steal;
458
459 acity = tile_city(ptile);
460
461 if (!acity) {
462 continue;
463 }
464 aplayer = city_owner(acity);
465
466 has_embassy = player_has_embassy(pplayer, aplayer);
467
468 if (aplayer == pplayer || is_barbarian(aplayer)
469 || (pplayers_allied(pplayer, aplayer) && has_embassy)) {
470 continue;
471 }
472
473 incite_cost = city_incite_cost(pplayer, acity);
474 can_incite = (incite_cost < INCITE_IMPOSSIBLE_COST)
475 && (is_action_possible_on_city(ACTION_SPY_INCITE_CITY,
476 pplayer, acity)
477 || is_action_possible_on_city(ACTION_SPY_INCITE_CITY_ESC,
478 pplayer, acity));
479
480 can_steal = is_action_possible_on_city(ACTION_SPY_STEAL_TECH,
481 pplayer, acity)
482 || is_action_possible_on_city(ACTION_SPY_STEAL_TECH_ESC,
483 pplayer, acity)
484 || is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH,
485 pplayer, acity)
486 || is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH_ESC,
487 pplayer, acity);
488
489 dipldef = (count_diplomats_on_tile(acity->tile) > 0);
490 /* Three actions to consider:
491 * 1. establishing embassy OR
492 * 2. stealing techs OR
493 * 3. inciting revolt */
494 if ((!has_embassy
495 && (is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY,
496 pplayer, acity)
497 || is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY_STAY,
498 pplayer, acity)))
500 && !dipldef && can_steal
501 && (research_get(pplayer)->techs_researched
502 < research_get(aplayer)->techs_researched))
503 || (incite_cost < (pplayer->economic.gold - expenses)
504 && can_incite && !dipldef)) {
505 if (!is_city_surrounded_by_our_spies(pplayer, acity)) {
506 /* We have the closest enemy city on the continent */
507 *ctarget = acity;
508 *move_dist = move_cost;
509 break;
510 }
511 }
513}
514
515/**************************************************************************/
518static struct city *dai_diplomat_defend(struct ai_type *ait,
519 struct player *pplayer,
520 struct unit *punit,
521 const struct unit_type *utype,
522 struct pf_map *pfm)
523{
524 int best_dist = 30; /* any city closer than this is better than none */
525 int best_urgency = 0;
526 struct city *ctarget = NULL;
527 struct city *pcity = tile_city(unit_tile(punit));
528
529 if (pcity
530 && count_diplomats_on_tile(pcity->tile) == 1
531 && def_ai_city_data(pcity, ait)->urgency > 0) {
532 /* Danger and we are only diplomat present - stay. */
533 return pcity;
534 }
535
536 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
537 struct city *acity;
538 struct player *aplayer;
539 int dipls, urgency;
540 struct ai_city *city_data;
541
542 acity = tile_city(ptile);
543 if (!acity) {
544 continue;
545 }
546 aplayer = city_owner(acity);
547 if (aplayer != pplayer) {
548 continue;
549 }
550
551 city_data = def_ai_city_data(acity, ait);
552 urgency = city_data->urgency;
553 dipls = (count_diplomats_on_tile(ptile)
554 - (same_pos(ptile, unit_tile(punit)) ? 1 : 0));
555 if (dipls == 0 && city_data->diplomat_threat) {
556 /* We are _really_ needed there */
557 urgency = (urgency + 1) * 5;
558 } else if (dipls > 0) {
559 /* We are probably not needed there... */
560 urgency /= 3;
561 }
562
563 /* This formula may not be optimal, but it works. */
564 if (move_cost > best_dist) {
565 /* punish city for being so far away */
566 urgency /= (float) (move_cost / best_dist);
567 }
568
569 if (urgency > best_urgency) {
570 /* Found something worthy of our presence */
571 ctarget = acity;
572 best_urgency = urgency;
573 /* squelch divide-by-zero */
574 best_dist = MAX(move_cost, 1);
575 }
577
578 return ctarget;
579}
580
581/**************************************************************************/
586static bool dai_diplomat_bribe_nearby(struct ai_type *ait,
587 struct player *pplayer,
588 struct unit *punit, struct pf_map *pfm)
589{
590 int gold_avail, expenses;
591 const struct civ_map *nmap = &(wld.map);
592
593 dai_calc_data(pplayer, NULL, &expenses, NULL);
594 gold_avail = pplayer->economic.gold - expenses;
595
597 struct tile *ptile = pos.tile;
598 bool threat = FALSE;
599 int newval, bestval = 0, cost;
600 struct unit *pvictim = tile_other_players_unit(ptile, pplayer);
601 int sanity = punit->id;
602 const struct unit_type *ptype;
603
604 if (pos.total_MC > punit->moves_left) {
605 /* Didn't find anything within range. */
606 break;
607 }
608
609 if (!pvictim
610 || !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, unit_owner(pvictim))
611 || unit_list_size(ptile->units) > 1
612 || tile_city(ptile)
613 || !is_action_enabled_unit_on_unit(nmap, ACTION_SPY_BRIBE_UNIT,
614 punit, pvictim)) {
615 continue;
616 }
617
618 /* Calculate if enemy is a threat */
619 /* First find best defender on our tile */
620 unit_list_iterate(ptile->units, aunit) {
621 const struct unit_type *atype = unit_type_get(aunit);
622
623 newval = DEFENSE_POWER(atype);
624 if (bestval < newval) {
625 bestval = newval;
626 }
628 /* Compare with victim's attack power */
629 ptype = unit_type_get(pvictim);
630 newval = ATTACK_POWER(ptype);
631 if (newval > bestval
632 && unit_move_rate(pvictim) > pos.total_MC) {
633 /* Enemy can probably kill us */
634 threat = TRUE;
635 } else {
636 /* Enemy cannot reach us or probably not kill us */
637 threat = FALSE;
638 }
639
640 if (has_handicap(pplayer, H_NOBRIBE_WF)) {
641 /* Don't bribe workers or city founders! */
643 || unit_can_do_action_result(pvictim, ACTRES_FOUND_CITY)) {
644 continue;
645 }
646 }
647
648 /* Should we make the expense? */
649 cost = unit_bribe_cost(pvictim, pplayer);
650 if (!threat) {
651 /* Don't empty our treasure without good reason! */
652 gold_avail = pplayer->economic.gold - dai_gold_reserve(pplayer);
653 }
654 if (cost > gold_avail) {
655 /* Can't afford */
656 continue;
657 }
658
659 /* Found someone! */
660 {
661 struct tile *bribee_tile;
662 struct pf_path *path;
663
664 bribee_tile = mapstep(nmap, pos.tile, DIR_REVERSE(pos.dir_to_here));
665 path = pf_map_path(pfm, bribee_tile);
666 if (!path || !adv_unit_execute_path(punit, path)
667 || punit->moves_left <= 0) {
668 pf_path_destroy(path);
669 return FALSE;
670 }
671 pf_path_destroy(path);
672 }
673
675 ACTION_SPY_BRIBE_UNIT,
676 pvictim))) {
677 unit_do_action(pplayer, punit->id,
678 pvictim->id, -1, "",
679 ACTION_SPY_BRIBE_UNIT);
680 /* autoattack might kill us as we move in */
681 if (game_unit_by_number(sanity) && punit->moves_left > 0) {
682 return TRUE;
683 } else {
684 return FALSE;
685 }
687 ACTION_SPY_SABOTAGE_UNIT_ESC,
688 pvictim))
689 && threat) {
690 /* don't stand around waiting for the final blow */
691 unit_do_action(pplayer, punit->id,
692 pvictim->id, -1, "",
693 ACTION_SPY_SABOTAGE_UNIT_ESC);
694 /* autoattack might kill us as we move in */
695 if (game_unit_by_number(sanity) && punit->moves_left > 0) {
696 return TRUE;
697 } else {
698 return FALSE;
699 }
700 } else {
701 /* usually because we ended move early due to another unit */
702 UNIT_LOG(LOG_DIPLOMAT, punit, "could not bribe target (%d, %d), "
703 " %d moves left", TILE_XY(pos.tile), punit->moves_left);
704 return FALSE;
705 }
707
708 return (punit->moves_left > 0);
709}
710
711/**************************************************************************/
721void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer,
722 struct unit *punit)
723{
724 struct city *pcity, *ctarget = NULL;
725 struct pf_parameter parameter;
726 struct pf_map *pfm;
727 struct pf_position pos;
728 struct unit_ai *unit_data;
729 const struct civ_map *nmap = &(wld.map);
730
732
733 /* Generate map */
734 pft_fill_unit_parameter(&parameter, nmap, punit);
735 parameter.omniscience = !has_handicap(pplayer, H_MAP);
736 parameter.get_zoc = NULL; /* Kludge */
737 parameter.get_TB = no_intermediate_fights;
738 pfm = pf_map_new(&parameter);
739
740 /* Look for someone to bribe */
741 if (!dai_diplomat_bribe_nearby(ait, pplayer, punit, pfm)) {
742 /* Died or ran out of moves */
743 pf_map_destroy(pfm);
744 return;
745 }
746
747 /* If we are the only diplomat in a threatened city, then stay to defend */
748 pcity = tile_city(unit_tile(punit)); /* we may have moved */
749 if (pcity) {
750 struct ai_city *city_data = def_ai_city_data(pcity, ait);
751
753 && (city_data->diplomat_threat
754 || city_data->urgency > 0)) {
755 UNIT_LOG(LOG_DIPLOMAT, punit, "stays to protect %s (urg %d)",
756 city_name_get(pcity), city_data->urgency);
757 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); /* abort mission */
759 pf_map_destroy(pfm);
760 return;
761 }
762 }
763
764 unit_data = def_ai_unit_data(punit, ait);
765
766 /* Check if existing target still makes sense */
767 if (unit_data->task == AIUNIT_ATTACK
768 || unit_data->task == AIUNIT_DEFEND_HOME) {
769 bool failure = FALSE;
770
771 ctarget = tile_city(punit->goto_tile);
773 && ctarget) {
774 if (same_pos(ctarget->tile, unit_tile(punit))) {
775 failure = TRUE;
776 } else if (pplayers_allied(pplayer, city_owner(ctarget))
777 && unit_data->task == AIUNIT_ATTACK
778 && player_has_embassy(pplayer, city_owner(ctarget))) {
779 /* We probably incited this city with another diplomat */
780 failure = TRUE;
781 } else if (!pplayers_allied(pplayer, city_owner(ctarget))
782 && unit_data->task == AIUNIT_DEFEND_HOME) {
783 /* We probably lost the city */
784 failure = TRUE;
785 }
786 } else {
787 /* City vanished! */
788 failure = TRUE;
789 }
790 if (failure) {
791 UNIT_LOG(LOG_DIPLOMAT, punit, "mission aborted");
793 }
794 }
795
796 /* We may need a new map now. Both because we cannot get paths from an
797 * old map, and we need paths to move, and because fctd below requires
798 * a new map for its iterator. */
799 if (!same_pos(parameter.start_tile, unit_tile(punit))
800 || unit_data->task == AIUNIT_NONE) {
801 pf_map_destroy(pfm);
802 pft_fill_unit_parameter(&parameter, nmap, punit);
803 parameter.omniscience = !has_handicap(pplayer, H_MAP);
804 parameter.get_zoc = NULL; /* Kludge */
805 parameter.get_TB = no_intermediate_fights;
806 pfm = pf_map_new(&parameter);
807 }
808
809 /* If we are not busy, acquire a target. */
810 if (unit_data->task == AIUNIT_NONE) {
811 enum ai_unit_task task;
812 int move_dist; /* dummy */
813
814 find_city_to_diplomat(pplayer, punit, &ctarget, &move_dist, pfm);
815
816 if (ctarget) {
817 task = AIUNIT_ATTACK;
819 UNIT_LOG(LOG_DIPLOMAT, punit, "going on attack");
820 } else if ((ctarget = dai_diplomat_defend(ait, pplayer, punit,
821 unit_type_get(punit), pfm))
822 != NULL) {
823 task = AIUNIT_DEFEND_HOME;
824 UNIT_LOG(LOG_DIPLOMAT, punit, "going to defend %s",
825 city_name_get(ctarget));
826 } else if ((ctarget = find_closest_city(unit_tile(punit), NULL, pplayer,
828 NULL))
829 != NULL) {
830 /* This should only happen if the entire continent was suddenly
831 * conquered. So we head for closest coastal city and wait for someone
832 * to code ferrying for diplomats, or hostile attacks from the sea. */
833 task = AIUNIT_DEFEND_HOME;
834 UNIT_LOG(LOG_DIPLOMAT, punit, "going idle");
835 } else {
836 UNIT_LOG(LOG_DIPLOMAT, punit, "could not find a job");
838 pf_map_destroy(pfm);
839 return;
840 }
841
842 dai_unit_new_task(ait, punit, task, ctarget->tile);
843 fc_assert(punit->moves_left > 0 && ctarget
844 && unit_data->task != AIUNIT_NONE);
845 }
846
848 if (ctarget == NULL) {
849 UNIT_LOG(LOG_ERROR, punit, "ctarget not set (task == %d)",
850 unit_data->task);
851 pf_map_destroy(pfm);
852 return;
853 }
854
855 /* GOTO unless we want to stay */
856 if (!same_pos(unit_tile(punit), ctarget->tile)) {
857 struct pf_path *path;
858
859 path = pf_map_path(pfm, punit->goto_tile);
860 if (path && adv_unit_execute_path(punit, path) && punit->moves_left > 0) {
861 /* Check if we can do something with our destination now. */
862 if (unit_data->task == AIUNIT_ATTACK) {
864
865 UNIT_LOG(LOG_DIPLOMAT, punit, "attack, dist %d to %s",
866 dist, ctarget ? city_name_get(ctarget) : "(none)");
867 if (dist <= 1) {
868 /* Do our stuff */
870 dai_diplomat_city(ait, punit, ctarget);
871 }
872 }
873 }
874 pf_path_destroy(path);
875 } else {
877 }
878 pf_map_destroy(pfm);
879}
bool is_action_possible_on_city(action_id act_id, const struct player *actor_player, const struct city *target_city)
Definition actions.c:7142
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6703
const char * action_rule_name(const struct action *action)
Definition actions.c:1876
int action_number(const struct action *action)
Definition actions.c:1868
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:4832
struct act_prob action_prob_vs_city(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:5870
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1740
struct act_prob action_prob_vs_unit(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5953
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define action_iterate_end
Definition actions.h:472
#define action_iterate(_act_)
Definition actions.h:467
#define TRADE_WEIGHTING
Definition advbuilding.h:21
#define FOOD_WEIGHTING
Definition advbuilding.h:19
#define SHIELD_WEIGHTING
Definition advbuilding.h:20
#define adv_choice_set_use(_choice, _use)
Definition advchoice.h:85
@ CT_CIVILIAN
Definition advchoice.h:39
@ CT_DEFENDER
Definition advchoice.h:41
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:82
bool aia_utype_is_considered_spy(const struct unit_type *putype)
Definition aiactions.c:53
bool aia_utype_is_considered_worker(const struct unit_type *putype)
Definition aiactions.c:91
static struct city * dai_diplomat_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit, const struct unit_type *utype, struct pf_map *pfm)
Definition aidiplomat.c:518
void dai_choose_diplomat_defensive(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, int def)
Definition aidiplomat.c:115
void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aidiplomat.c:721
#define LOG_DIPLOMAT_BUILD
Definition aidiplomat.c:78
static void dai_diplomat_city(struct ai_type *ait, struct unit *punit, struct city *ctarget)
Definition aidiplomat.c:325
void dai_choose_diplomat_offensive(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice)
Definition aidiplomat.c:164
#define LOG_DIPLOMAT
Definition aidiplomat.c:77
#define DIPLO_DEFENSE_WANT
Definition aidiplomat.c:82
static bool dai_diplomat_bribe_nearby(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct pf_map *pfm)
Definition aidiplomat.c:586
static int count_stealable_techs(struct player *pplayer, struct player *tplayer)
Definition aidiplomat.c:94
static void find_city_to_diplomat(struct player *pplayer, struct unit *punit, struct city **ctarget, int *move_dist, struct pf_map *pfm)
Definition aidiplomat.c:439
static bool is_city_surrounded_by_our_spies(struct player *pplayer, struct city *pcity)
Definition aidiplomat.c:415
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Definition aiguard.c:228
void dai_calc_data(const struct player *pplayer, int *trade, int *expenses, int *income)
Definition aihand.c:118
#define TECH_LOG(ait, loglevel, pplayer, padvance, msg,...)
Definition ailog.h:36
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition aiplayer.h:54
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition aiplayer.h:42
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition aiplayer.h:48
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition aitools.c:644
int dai_gold_reserve(struct player *pplayer)
Definition aitools.c:1309
adv_want military_amortize(struct player *pplayer, struct city *pcity, adv_want value, int delay, int build_cost)
Definition aitools.c:118
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition aiunit.h:72
ai_unit_task
Definition aiunit.h:27
@ AIUNIT_NONE
Definition aiunit.h:27
@ AIUNIT_ATTACK
Definition aiunit.h:28
@ AIUNIT_DEFEND_HOME
Definition aiunit.h:28
#define DEFENSE_POWER(ptype)
Definition aiunit.h:66
#define ATTACK_POWER(ptype)
Definition aiunit.h:68
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:789
#define city_tile(_pcity_)
Definition city.h:544
#define INCITE_IMPOSSIBLE_COST
Definition city.h:88
#define city_owner(_pcity_)
Definition city.h:543
struct city * find_closest_city(const struct tile *ptile, const struct city *pexclcity, const struct player *pplayer, bool only_ocean, bool only_continent, bool only_known, bool only_player, bool only_enemy, const struct unit_class *pclass)
Definition citytools.c:854
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3267
int dai_action_choose_sub_tgt_unit_vs_city(struct action *paction, struct unit *actor_unit, struct city *target_city)
Definition daiactions.c:309
adv_want dai_action_value_unit_vs_city(struct action *paction, struct unit *actor_unit, struct city *target_city, int sub_tgt_id, int count_tech)
Definition daiactions.c:95
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
int diplomats_unignored_tech_stealings(struct unit *pdiplomat, struct city *pcity)
Definition diplomats.c:855
int count_diplomats_on_tile(struct tile *ptile)
Definition diplomats.c:2349
float adv_want
Definition fc_types.h:1206
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
@ O_SCIENCE
Definition fc_types.h:91
@ O_LUXURY
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
static struct tile * pos
Definition finddlg.c:53
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_MAP
Definition handicaps.h:28
@ H_DIPLOMAT
Definition handicaps.h:18
@ H_NOBRIBE_WF
Definition handicaps.h:34
@ H_FOG
Definition handicaps.h:26
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define log_base(level, message,...)
Definition log.h:94
@ LOG_ERROR
Definition log.h:30
@ LOG_DEBUG
Definition log.h:34
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:369
#define adjc_iterate_end
Definition map.h:427
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:422
#define DIR_REVERSE(dir)
Definition map.h:555
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:900
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:137
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:462
void pf_path_destroy(struct pf_path *path)
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
struct pf_path * pf_map_path(struct pf_map *pfm, struct tile *ptile)
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
void pf_map_destroy(struct pf_map *pfm)
#define pf_map_move_costs_iterate_end
#define pf_map_positions_iterate_end
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
#define pf_map_positions_iterate(ARG_pfm, NAME_pos, COND_from_start)
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:840
enum tile_behavior no_intermediate_fights(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition pf_tools.c:524
const char * player_name(const struct player *pplayer)
Definition player.c:886
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
bool player_has_embassy(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:202
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define is_ai(plr)
Definition player.h:234
int research_total_bulbs_required(const struct research *presearch, Tech_type_id tech, bool loss_value)
Definition research.c:858
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
#define MAX(x, y)
Definition shared.h:54
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
enum act_tgt_compl target_complexity
Definition actions.h:390
enum choice_type type
Definition advchoice.h:46
adv_want want
Definition advchoice.h:48
universals_u value
Definition advchoice.h:47
bool need_boat
Definition advchoice.h:49
bool has_diplomat
Definition daicity.h:59
unsigned int urgency
Definition daicity.h:49
bool diplomat_threat
Definition daicity.h:58
struct ai_plr::@267 stats
adv_want tech_want[A_LAST+1]
Definition aidata.h:103
bv_id diplomat_reservations
Definition aidata.h:85
Definition ai.h:50
Definition city.h:309
int id
Definition city.h:315
struct tile * tile
Definition city.h:311
int prod[O_LAST]
Definition city.h:346
struct civ_game::@30::@34 server
int diplchance
Definition game.h:137
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
bool(* get_zoc)(const struct player *pplayer, const struct tile *ptile, const struct civ_map *zmap)
struct tile * start_tile
struct player_economic economic
Definition player.h:284
Tech_type_id researching
Definition research.h:52
int techs_researched
Definition research.h:42
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
bool done
Definition aiunit.h:44
enum ai_unit_task task
Definition aiunit.h:46
int move_rate
Definition unittype.h:497
struct advance * require_advance
Definition unittype.h:500
Definition unit.h:138
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
struct tile * goto_tile
Definition unit.h:155
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
#define advance_index_iterate_end
Definition tech.h:248
#define A_FIRST
Definition tech.h:44
#define advance_index_iterate(_start, _index)
Definition tech.h:244
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define TILE_XY(ptile)
Definition tile.h:42
const struct unit_type * utype
Definition fc_types.h:604
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2288
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:338
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1617
struct unit * tile_other_players_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1349
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1713
#define unit_tile(_pu)
Definition unit.h:395
#define CHECK_UNIT(punit)
Definition unit.h:268
#define unit_owner(_pu)
Definition unit.h:394
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6179
void unit_do_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id, const char *name, const action_id action_type)
Definition unithand.c:3155
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
struct unit_type * best_role_unit(const struct city *pcity, int role)
Definition unittype.c:2319
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2301
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
int num_role_units(int role)
Definition unittype.c:2251
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443