Freeciv-3.1
Loading...
Searching...
No Matches
daidiplomacy.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Team
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#include <stdarg.h>
19#include <string.h>
20
21/* utility */
22#include "fcintl.h"
23#include "log.h"
24#include "mem.h"
25#include "rand.h"
26#include "shared.h"
27#include "support.h"
28
29/* common */
30#include "aisupport.h"
31#include "city.h"
32#include "diptreaty.h"
33#include "events.h"
34#include "game.h"
35#include "packets.h"
36#include "player.h"
37#include "nation.h"
38#include "research.h"
39#include "spaceship.h"
40#include "tech.h"
41#include "unitlist.h"
42
43/* server */
44#include "citytools.h"
45#include "diplhand.h"
46#include "maphand.h"
47#include "notify.h"
48#include "srv_log.h"
49
50/* server/advisors */
51#include "advdata.h"
52#include "advtools.h"
53
54/* ai */
55#include "aitraits.h"
56#include "handicaps.h"
57
58/* ai/default */
59#include "aidata.h"
60#include "ailog.h"
61#include "aiplayer.h"
62#include "aiunit.h"
63#include "aitools.h"
64#include "daicity.h"
65#include "daimilitary.h"
66
67#include "daidiplomacy.h"
68
69#define LOG_DIPL LOG_DEBUG
70#define LOG_DIPL2 LOG_DEBUG
71
72/* One hundred thousand. Basically a number of gold that no player is
73 * ever likely to have, but not so big that we get integer overflows. */
74#define BIG_NUMBER 100000
75
76/* turn this off when we don't want functions to message players */
77static bool diplomacy_verbose = TRUE;
78
79/* turns to wait after contact before taking aim for war */
80#define TURNS_BEFORE_TARGET 15
81
82static void dai_incident_war(struct player *violator, struct player *victim);
83static void dai_incident_simple(struct player *receiver,
84 const struct player *violator,
85 const struct player *victim,
86 enum casus_belli_range scope,
87 int how_bad);
88static void dai_incident_nuclear(struct player *receiver,
89 const struct player *violator,
90 const struct player *victim);
91static void dai_incident_nuclear_not_target(struct player *receiver,
92 const struct player *violator,
93 const struct player *victim);
94static void dai_incident_nuclear_self(struct player *receiver,
95 const struct player *violator,
96 const struct player *victim);
97static void clear_old_treaty(struct player *pplayer, struct player *aplayer);
98
99/******************************************************************/
104static void dai_diplo_notify(struct player *pplayer, const char *text, ...)
105{
106 if (diplomacy_verbose) {
107 va_list ap;
108 struct conn_list *dest = pplayer->connections;
109 struct packet_chat_msg packet;
110
111 va_start(ap, text);
112 vpackage_event(&packet, NULL, E_DIPLOMACY, ftc_chat_private, text, ap);
113 va_end(ap);
114
115 lsend_packet_chat_msg(dest, &packet);
116 /* Add to the event cache. */
117 event_cache_add_for_player(&packet, pplayer);
118 }
119}
120
121/******************************************************************/
125static int greed(int missing_love)
126{
127 if (missing_love > 0) {
128 return 0;
129 } else {
130 /* Don't change the operation order here.
131 * We do not want integer overflows */
132 return -((missing_love * MAX_AI_LOVE) / 1000) *
133 ((missing_love * MAX_AI_LOVE) / 1000) / 10;
134 }
135}
136
137/******************************************************************/
140static enum diplstate_type pact_clause_to_diplstate_type(enum clause_type type)
141{
142 switch (type) {
143 case CLAUSE_ALLIANCE:
144 return DS_ALLIANCE;
145 case CLAUSE_PEACE:
146 return DS_PEACE;
147 case CLAUSE_CEASEFIRE:
148 return DS_CEASEFIRE;
149 default:
150 log_error("Invalid diplomatic clause %d.", type)
151 return DS_WAR;
152 }
153}
154
155/******************************************************************/
158static int dai_goldequiv_tech(struct ai_type *ait,
159 struct player *pplayer, Tech_type_id tech)
160{
161 int bulbs, tech_want, worth;
162 struct research *presearch = research_get(pplayer);
163 enum tech_state state = research_invention_state(presearch, tech);
164 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
165
166 if (TECH_KNOWN == state
167 || !research_invention_gettable(presearch, tech,
169 return 0;
170 }
171 bulbs = research_goal_bulbs_required(presearch, tech) * 3;
172 tech_want = MAX(plr_data->tech_want[tech], 0) / MAX(game.info.turn, 1);
173 worth = bulbs + tech_want;
174 if (TECH_PREREQS_KNOWN == state) {
175 worth /= 2;
176 }
177 return worth;
178}
179
180/******************************************************************/
184static bool shared_vision_is_safe(struct player* pplayer,
185 struct player* aplayer)
186{
187 if (pplayer->team && pplayer->team == aplayer->team) {
188 return TRUE;
189 }
190 players_iterate_alive(eplayer) {
191 if (eplayer == pplayer || eplayer == aplayer) {
192 continue;
193 }
194 if (gives_shared_vision(aplayer, eplayer)) {
195 enum diplstate_type ds = player_diplstate_get(pplayer, eplayer)->type;
196
197 if (ds != DS_NO_CONTACT && ds != DS_ALLIANCE) {
198 return FALSE;
199 }
200 }
202 return TRUE;
203}
204
205/******************************************************************/
210 struct player* player1,
211 struct player* player2)
212{
213 return (player1->ai_common.love[player_index(player2)] > - (MAX_AI_LOVE * 4 / 10)
214 && dai_diplomacy_get(ait, player1, player2)->countdown == -1);
215}
216
217/******************************************************************/
224static int compute_tech_sell_price(struct ai_type *ait,
225 struct player *giver, struct player *taker,
226 int tech_id, bool *is_dangerous)
227{
228 int worth;
229
230 worth = dai_goldequiv_tech(ait, taker, tech_id);
231
232 *is_dangerous = FALSE;
233
234 /* Share and expect being shared brotherly between allies */
235 if (pplayers_allied(giver, taker)) {
236 worth /= 2;
237 }
238 if (players_on_same_team(giver, taker)) {
239 return 0;
240 }
241
242 /* Do not bother wanting a tech that we already have. */
243 if (research_invention_state(research_get(taker), tech_id)
244 == TECH_KNOWN) {
245 return 0;
246 }
247
248 /* Calculate in tech leak to our opponents, guess 50% chance */
249 players_iterate_alive(eplayer) {
250 if (eplayer == giver
251 || eplayer == taker
253 tech_id) == TECH_KNOWN) {
254 continue;
255 }
256
257 /* Don't risk it falling into enemy hands */
258 if (pplayers_allied(taker, eplayer)
259 && adv_is_player_dangerous(giver, eplayer)) {
260 *is_dangerous = TRUE;
261 }
262
263 if (pplayers_allied(taker, eplayer)
264 && !pplayers_allied(giver, eplayer)) {
265 /* Taker can enrich their side with this tech */
266 worth += dai_goldequiv_tech(ait, eplayer, tech_id) / 4;
267 }
269
270 return worth;
271}
272
273/******************************************************************/
276static const struct player *
278 const struct player *them)
279{
280 players_iterate_alive(aplayer) {
281 if (aplayer != us
282 && aplayer != them
283 && pplayers_allied(them, aplayer)
284 && player_diplstate_get(us, aplayer)->type == DS_WAR) {
285 return aplayer;
286 }
288 return NULL;
289}
290
291/******************************************************************/
298static int dai_goldequiv_clause(struct ai_type *ait,
299 struct player *pplayer,
300 struct player *aplayer,
301 struct Clause *pclause,
302 bool verbose,
303 enum diplstate_type ds_after)
304{
305 bool close_here;
306 struct ai_plr *ai;
307 int worth = 0; /* Worth for pplayer of what aplayer gives */
308 bool give = (pplayer == pclause->from);
309 struct player *giver;
310 const struct player *penemy;
311 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
312 bool is_dangerous;
313 const struct civ_map *nmap = &(wld.map);
314
315 ai = dai_plr_data_get(ait, pplayer, &close_here);
316
317 fc_assert_ret_val(pplayer != aplayer, 0);
318
319 diplomacy_verbose = verbose;
320 ds_after = MAX(ds_after, player_diplstate_get(pplayer, aplayer)->type);
321 giver = pclause->from;
322
323 switch (pclause->type) {
324 case CLAUSE_ADVANCE:
325 if (give) {
326 worth -= compute_tech_sell_price(ait, pplayer, aplayer, pclause->value,
327 &is_dangerous);
328 if (is_dangerous) {
329 worth = -BIG_NUMBER;
330 }
331 } else if (research_invention_state(research_get(pplayer),
332 pclause->value) != TECH_KNOWN) {
333 worth += compute_tech_sell_price(ait, aplayer, pplayer, pclause->value,
334 &is_dangerous);
335
336 if (game.info.tech_upkeep_style != TECH_UPKEEP_NONE) {
337 /* Consider the upkeep costs! Thus, one can not get an AI player by
338 * - given AI lots of techs for gold/cities etc.
339 * - AI losses tech due to high upkeep.
340 * FIXME: Is there a better way for this? */
341 struct research *research = research_get(pplayer);
342 int limit;
343
344 /* Make sure there's no division by zero */
345 if (research->techs_researched > 0) {
346 int upk_per_tech = player_tech_upkeep(pplayer)
348
349 limit = MAX(1, upk_per_tech);
350 } else {
351 limit = 1;
352 fc_assert(player_tech_upkeep(pplayer) == 0);
353 }
354
355 if (pplayer->server.bulbs_last_turn < limit) {
356 if (research->bulbs_researched < 0) {
357 worth = -BIG_NUMBER;
358 } else {
359 worth /= 2;
360 }
361 }
362 }
363 }
364 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "%s clause worth %d",
365 advance_rule_name(advance_by_number(pclause->value)), worth);
366 break;
367
368 case CLAUSE_ALLIANCE:
369 case CLAUSE_PEACE:
370 case CLAUSE_CEASEFIRE:
371 /* Don't do anything in away mode */
372 if (has_handicap(pplayer, H_AWAY)) {
373 dai_diplo_notify(aplayer, _("*%s (AI)* In away mode AI can't sign such a treaty."),
374 player_name(pplayer));
375 worth = -BIG_NUMBER;
376 break;
377 }
378
379 /* This guy is allied to one of our enemies. Only accept
380 * ceasefire. */
381 if ((penemy = get_allied_with_enemy_player(pplayer, aplayer))
382 && pclause->type != CLAUSE_CEASEFIRE) {
383 dai_diplo_notify(aplayer, _("*%s (AI)* First break alliance with %s, %s."),
384 player_name(pplayer), player_name(penemy),
385 player_name(aplayer));
386 worth = -BIG_NUMBER;
387 break;
388 }
389
390 /* They were allied with an enemy at the beginning of the turn. */
391 if (adip->is_allied_with_enemy
392 && pclause->type != CLAUSE_CEASEFIRE) {
393 dai_diplo_notify(aplayer, _("*%s (AI)* I would like to see you keep your "
394 "distance from %s for some time, %s."),
396 player_name(aplayer));
397 worth = -BIG_NUMBER;
398 break;
399 }
400
401 /* Steps of the treaty ladder */
402 if (pclause->type == CLAUSE_PEACE) {
403 const struct player_diplstate *ds
404 = player_diplstate_get(pplayer, aplayer);
405
406 if (!pplayers_non_attack(pplayer, aplayer)) {
407 dai_diplo_notify(aplayer, _("*%s (AI)* Let us first cease hostilities, %s."),
408 player_name(pplayer),
409 player_name(aplayer));
410 worth = -BIG_NUMBER;
411 } else if (ds->type == DS_CEASEFIRE && ds->turns_left > 4) {
412 dai_diplo_notify(aplayer, _("*%s (AI)* I wish to see you keep the current "
413 "ceasefire for a bit longer first, %s."),
414 player_name(pplayer),
415 player_name(aplayer));
416 worth = -BIG_NUMBER;
417 } else if (adip->countdown >= 0 || adip->countdown < -1) {
418 worth = -BIG_NUMBER; /* but say nothing */
419 } else {
420 worth = greed(pplayer->ai_common.love[player_index(aplayer)]
422 }
423 } else if (pclause->type == CLAUSE_ALLIANCE) {
424 if (!pplayers_in_peace(pplayer, aplayer)) {
425 worth = greed(pplayer->ai_common.love[player_index(aplayer)]
427 }
428 if (adip->countdown >= 0 || adip->countdown < -1) {
429 worth = -BIG_NUMBER; /* but say nothing */
430 } else {
431 worth += greed(pplayer->ai_common.love[player_index(aplayer)]
433 }
434 if (pplayer->ai_common.love[player_index(aplayer)] < MAX_AI_LOVE / 10) {
435 dai_diplo_notify(aplayer, _("*%s (AI)* I simply do not trust you with an "
436 "alliance yet, %s."),
437 player_name(pplayer),
438 player_name(aplayer));
439 worth = -BIG_NUMBER;
440 }
441 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "ally clause worth %d", worth);
442 } else {
443 if (is_ai(pplayer) && is_ai(aplayer)
444 && dai_players_can_agree_on_ceasefire(ait, pplayer, aplayer)) {
445 worth = 0;
446 } else {
447 int turns = game.info.turn;
448
449 turns -= player_diplstate_get(pplayer, aplayer)->first_contact_turn;
450 if (turns < TURNS_BEFORE_TARGET) {
451 worth = 0; /* show some good faith */
452 break;
453 } else {
454 worth = greed(pplayer->ai_common.love[player_index(aplayer)]);
455 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "ceasefire worth=%d love=%d "
456 "turns=%d", worth,
457 pplayer->ai_common.love[player_index(aplayer)],
458 turns);
459 }
460 }
461 }
462
463 /* Let's all hold hands in one happy family! */
464 if (adip->is_allied_with_ally) {
465 worth /= 2;
466 break;
467 }
468
469 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "treaty clause worth %d", worth);
470 break;
471
472 case CLAUSE_GOLD:
473 if (give) {
474 worth -= pclause->value;
475 } else {
476 worth += pclause->value * (100 - game.server.diplgoldcost) / 100;
477 }
478 break;
479
480 case CLAUSE_SEAMAP:
481 if (!give || ds_after == DS_ALLIANCE) {
482 /* Useless to us - we're omniscient! And allies get it for free! */
483 worth = 0;
484 } else {
485 /* Very silly algorithm 1: Sea map more worth if enemy has more
486 cities. Reasoning is they have more use of seamap for settling
487 new areas the more cities they have already. */
488 worth -= 15 * city_list_size(aplayer->cities);
489 /* Don't like them? Don't give it to them! */
490 worth = MIN(pplayer->ai_common.love[player_index(aplayer)] * 7, worth);
491 /* Make maps from novice player cheap */
492 if (has_handicap(pplayer, H_DIPLOMACY)) {
493 worth /= 2;
494 }
495 }
496 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "seamap clause worth %d",
497 worth);
498 break;
499
500 case CLAUSE_MAP:
501 if (!give || ds_after == DS_ALLIANCE) {
502 /* Useless to us - we're omniscient! And allies get it for free! */
503 worth = 0;
504 } else {
505 /* Very silly algorithm 2: Land map more worth the more cities
506 we have, since we expose all of these to the enemy. */
507 worth -= 40 * MAX(city_list_size(pplayer->cities), 1);
508 /* Inflate numbers if not peace */
509 if (!pplayers_in_peace(pplayer, aplayer)) {
510 worth *= 2;
511 }
512 /* Don't like them? Don't give it to them! */
513 worth = MIN(pplayer->ai_common.love[player_index(aplayer)] * 10, worth);
514 /* Make maps from novice player cheap */
515 if (has_handicap(pplayer, H_DIPLOMACY)) {
516 worth /= 6;
517 }
518 }
519 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "landmap clause worth %d",
520 worth);
521 break;
522
523 case CLAUSE_CITY: {
524 struct city *offer = city_list_find_number(pclause->from->cities,
525 pclause->value);
526
527 if (!offer || city_owner(offer) != giver) {
528 /* City destroyed or taken during negotiations */
529 dai_diplo_notify(aplayer, _("*%s (AI)* I do not know the city you mention."),
530 player_name(pplayer));
531 worth = 0;
532 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "city destroyed during negotiations");
533 } else if (give) {
534 /* AI must be crazy to trade away its cities */
535 worth -= city_gold_worth(nmap, offer);
536 if (is_capital(offer)) {
537 worth = -BIG_NUMBER; /* Never! Ever! */
538 } else {
539 worth *= 15;
540 }
541 if (aplayer == offer->original) {
542 /* Let them buy back their own city cheaper. */
543 worth /= 2;
544 }
545 } else {
546 worth = city_gold_worth(nmap, offer);
547 }
548 if (offer != NULL) {
549 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "worth of %s is %d",
550 city_name_get(offer), worth);
551 }
552 break;
553 }
554
555 case CLAUSE_VISION:
556 if (give) {
557 if (ds_after == DS_ALLIANCE) {
558 if (!shared_vision_is_safe(pplayer, aplayer)) {
559 dai_diplo_notify(aplayer,
560 _("*%s (AI)* Sorry, sharing vision with you "
561 "is not safe."),
562 player_name(pplayer));
563 worth = -BIG_NUMBER;
564 } else {
565 worth = 0;
566 }
567 } else {
568 /* so out of the question */
569 worth = -BIG_NUMBER;
570 }
571 } else {
572 worth = 0; /* We are omniscient, so... */
573 }
574 break;
575
576 case CLAUSE_EMBASSY:
577 if (give) {
578 if (ds_after == DS_ALLIANCE) {
579 worth = 0;
580 } else if (ds_after == DS_PEACE) {
581 worth = -5 * game.info.turn;
582 } else {
583 worth = MIN(-50 * game.info.turn
584 + pplayer->ai_common.love[player_index(aplayer)],
585 -5 * game.info.turn);
586 }
587 } else if (game.info.tech_leakage == TECH_LEAKAGE_EMBASSIES) {
588 worth = game.info.tech_leak_pct / 10;
589 } else {
590 worth = 0; /* We don't need no stinkin' embassy, do we? */
591 }
592 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "embassy clause worth %d",
593 worth);
594 break;
595 case CLAUSE_COUNT:
596 fc_assert(pclause->type != CLAUSE_COUNT);
597 break;
598 } /* end of switch */
599
600 if (close_here) {
601 dai_data_phase_finished(ait, pplayer);
602 }
603
605 return worth;
606}
607
608/******************************************************************/
612void dai_treaty_evaluate(struct ai_type *ait, struct player *pplayer,
613 struct player *aplayer, struct Treaty *ptreaty)
614{
615 int total_balance = 0;
616 bool only_gifts = TRUE;
617 enum diplstate_type ds_after =
618 player_diplstate_get(pplayer, aplayer)->type;
619 int given_cities = 0;
620
621 clause_list_iterate(ptreaty->clauses, pclause) {
622 if (is_pact_clause(pclause->type)) {
623 ds_after = pact_clause_to_diplstate_type(pclause->type);
624 }
625 if (pclause->type == CLAUSE_CITY && pclause->from == pplayer) {
626 given_cities++;
627 }
629
630 /* Evaluate clauses */
631 clause_list_iterate(ptreaty->clauses, pclause) {
632 const struct research *presearch = research_get(pplayer);
633
634 total_balance +=
635 dai_goldequiv_clause(ait, pplayer, aplayer, pclause, TRUE, ds_after);
636
637 if (pclause->type != CLAUSE_GOLD && pclause->type != CLAUSE_MAP
638 && pclause->type != CLAUSE_SEAMAP && pclause->type != CLAUSE_VISION
639 && (pclause->type != CLAUSE_ADVANCE
640 || game.info.tech_cost_style != TECH_COST_CIV1CIV2
641 || pclause->value == research_get(pplayer)->tech_goal
642 || pclause->value == research_get(pplayer)->researching
643 || research_goal_tech_req(presearch, presearch->tech_goal,
644 pclause->value))) {
645 /* We accept the above list of clauses as gifts, even if we are
646 * at war. We do not accept tech or cities since these can be used
647 * against us, unless we know that we want this tech anyway, or
648 * it doesn't matter due to tech cost style. */
649 only_gifts = FALSE;
650 }
652
653 /* If we are at war, and no peace is offered, then no deal, unless
654 * it is just gifts, in which case we gratefully accept. */
655 if (ds_after == DS_WAR && !only_gifts) {
656 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "no peace offered, must refuse");
657 return;
658 }
659
660 if (given_cities > 0
661 && city_list_size(pplayer->cities) - given_cities <= 2) {
662 /* always keep at least two cities */
663 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "cannot give last cities");
664 return;
665 }
666
667 /* Accept if balance is good */
668 if (total_balance >= 0) {
670 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "balance was good: %d",
671 total_balance);
672 } else {
673 /* AI complains about the treaty which was proposed, unless the AI
674 * made the proposal. */
675 if (pplayer != ptreaty->plr0) {
676 dai_diplo_notify(aplayer, _("*%s (AI)* This deal was not very good for us, %s!"),
677 player_name(pplayer),
678 player_name(aplayer));
679 }
680 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "balance was bad: %d",
681 total_balance);
682 }
683}
684
685/******************************************************************/
689static void dai_treaty_react(struct ai_type *ait,
690 struct player *pplayer,
691 struct player *aplayer,
692 struct Clause *pclause)
693{
694 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
695
696 switch (pclause->type) {
697 case CLAUSE_ALLIANCE:
698 if (adip->is_allied_with_ally) {
699 dai_diplo_notify(aplayer, _("*%s (AI)* Welcome into our alliance %s!"),
700 player_name(pplayer),
701 player_name(aplayer));
702 } else {
703 dai_diplo_notify(aplayer, _("*%s (AI)* Yes, may we forever stand united, %s."),
704 player_name(pplayer),
705 player_name(aplayer));
706 }
707 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "become allies");
708 break;
709 case CLAUSE_PEACE:
710 dai_diplo_notify(aplayer, _("*%s (AI)* Yes, peace in our time!"),
711 player_name(pplayer));
712 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "sign peace treaty");
713 break;
714 case CLAUSE_CEASEFIRE:
715 dai_diplo_notify(aplayer, _("*%s (AI)* Agreed. No more hostilities, %s."),
716 player_name(pplayer),
717 player_name(aplayer));
718 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "sign ceasefire");
719 break;
720 default:
721 break;
722 }
723}
724
725/******************************************************************/
732void dai_treaty_accepted(struct ai_type *ait, struct player *pplayer,
733 struct player *aplayer, struct Treaty *ptreaty)
734{
735 bool close_here;
736 struct ai_plr *ai;
737 int total_balance = 0;
738 bool gift = TRUE;
739 enum diplstate_type ds_after =
740 player_diplstate_get(pplayer, aplayer)->type;
741
742 ai = dai_plr_data_get(ait, pplayer, &close_here);
743
744 fc_assert_ret(pplayer != aplayer);
745
746 clause_list_iterate(ptreaty->clauses, pclause) {
747 if (is_pact_clause(pclause->type)) {
748 ds_after = pact_clause_to_diplstate_type(pclause->type);
749 }
751
752 /* Evaluate clauses */
753 clause_list_iterate(ptreaty->clauses, pclause) {
754 int balance =
755 dai_goldequiv_clause(ait, pplayer, aplayer, pclause, TRUE, ds_after);
756
757 total_balance += balance;
758 gift = (gift && (balance >= 0));
759 dai_treaty_react(ait, pplayer, aplayer, pclause);
760 if (is_pact_clause(pclause->type)
761 && dai_diplomacy_get(ait, pplayer, aplayer)->countdown != -1) {
762 /* Cancel a countdown towards war if we just agreed to peace... */
763 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "countdown nullified");
764 dai_diplomacy_get(ait, pplayer, aplayer)->countdown = -1;
765 }
767
768 /* Rather arbitrary algorithm to increase our love for a player if
769 * they offer us gifts. It is only a gift if _all_ the clauses
770 * are beneficial to us. */
771 if (total_balance > 0 && gift) {
772 int i = total_balance / ((city_list_size(pplayer->cities) * 10) + 1);
773
774 i = MIN(i, ai->diplomacy.love_incr * 150) * 10;
775 pplayer->ai_common.love[player_index(aplayer)] += i;
776 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "gift increased love by %d", i);
777 }
778
779 if (close_here) {
780 dai_data_phase_finished(ait, pplayer);
781 }
782}
783
784/******************************************************************/
791static int dai_war_desire(struct ai_type *ait, struct player *pplayer,
792 struct player *target)
793{
794 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
795 struct adv_data *adv = adv_data_get(pplayer, NULL);
796 int want = 0, fear = 0, distance = 0, settlers = 0, cities = 0;
797 struct player_spaceship *ship = &target->spaceship;
798
799 city_list_iterate(target->cities, pcity) {
800 want += 100; /* base city want */
801 want += city_size_get(pcity) * 20;
802 want += pcity->surplus[O_SHIELD] * 8;
803 want += pcity->surplus[O_TRADE] * 6;
804
805 /* FIXME: This might be buggy if it ignores unmet UnitClass reqs. */
806 fear += get_city_bonus(pcity, EFT_DEFEND_BONUS);
807
808 city_built_iterate(pcity, pimprove) {
809 int cost = impr_build_shield_cost(pcity, pimprove);
810
811 want += cost;
812 if (improvement_obsolete(pplayer, pimprove, pcity)) {
813 continue;
814 }
815 if (is_great_wonder(pimprove)) {
816 want += cost * 2;
817 } else if (is_small_wonder(pimprove)) {
818 want += cost;
819 }
822 unit_list_iterate(target->units, punit) {
823 const struct unit_type *ptype = unit_type_get(punit);
824
825 fear += ATTACK_POWER(ptype);
826
827 /* Fear enemy expansionism */
829 want += 100;
830 }
832 unit_list_iterate(pplayer->units, punit) {
833 const struct unit_type *ptype = unit_type_get(punit);
834
835 fear -= ATTACK_POWER(ptype) / 2;
836
837 /* Our own expansionism reduces want for war */
839 want -= 200;
840 settlers++;
841 }
843 city_list_iterate(pplayer->cities, pcity) {
844 if (VUT_UTYPE == pcity->production.kind
845 && utype_is_cityfounder(pcity->production.value.utype)) {
846 want -= 150;
847 settlers++;
848 }
849 cities++;
851
852 /* Modify by settler/cities ratio to prevent early wars when
853 * we should be expanding. This will eliminate want if we
854 * produce settlers in all cities (ie full expansion). */
855 want -= abs(want) / MAX(cities - settlers, 1);
856
857 /* Calculate average distances to other player's empire. */
858 distance = player_distance_to_player(pplayer, target);
859 dai_diplomacy_get(ait, pplayer, target)->distance = distance;
860
861 /* Worry a bit if the other player has extreme amounts of wealth
862 * that can be used in cities to quickly buy an army. */
863 fear += (target->economic.gold / 5000) * city_list_size(target->cities);
864
865 /* Tech lead is worrisome. FIXME: Only consider 'military' techs. */
866 fear += MAX(research_get(target)->techs_researched
867 - research_get(pplayer)->techs_researched, 0) * 100;
868
869 /* Spacerace loss we will not allow! */
870 if (ship->state >= SSHIP_STARTED) {
871 want *= 2;
872 }
873 if (adv->dipl.spacerace_leader == target) {
875 return BIG_NUMBER; /* do NOT amortize this number! */
876 }
877
878 /* Modify by which treaties we would break to other players, and what
879 * excuses we have to do so. FIXME: We only consider immediate
880 * allies, but we might trigger a wider chain reaction. */
881 players_iterate_alive(eplayer) {
882 bool cancel_excuse =
883 player_diplstate_get(pplayer, eplayer)->has_reason_to_cancel != 0;
884 enum diplstate_type ds = player_diplstate_get(pplayer, eplayer)->type;
885
886 if (eplayer == pplayer) {
887 continue;
888 }
889
890 /* Remember: pplayers_allied() returns true when target == eplayer */
891 if (!cancel_excuse && pplayers_allied(target, eplayer)) {
892 if (ds == DS_ARMISTICE) {
893 want -= abs(want) / 10; /* 10% off */
894 } else if (ds == DS_CEASEFIRE) {
895 want -= abs(want) / 7; /* 15% off */
896 } else if (ds == DS_PEACE) {
897 want -= abs(want) / 5; /* 20% off */
898 } else if (ds == DS_ALLIANCE) {
899 want -= abs(want) / 3; /* 33% off */
900 }
901 }
903
904 /* Modify by love. Increase the divisor to make ai go to war earlier */
905 want -= MAX(0, want * pplayer->ai_common.love[player_index(target)]
906 / (2 * MAX_AI_LOVE));
907
908 /* Make novice AI more peaceful with human players */
909 if (has_handicap(pplayer, H_DIPLOMACY) && is_human(target)) {
910 want /= 2;
911 }
912
913 /* Amortize by distance */
914 want = amortize(want, distance);
915
916 if (pplayers_allied(pplayer, target)) {
917 want /= 4;
918 }
919
920 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target, "War want %d, war fear %d",
921 want, fear);
922 return (want - fear);
923}
924
925/******************************************************************/
930static void dai_diplomacy_suggest(struct player *pplayer,
931 struct player *aplayer,
932 enum clause_type what,
933 bool to_pplayer,
934 int value)
935{
936 if (!could_meet_with_player(pplayer, aplayer)) {
937 log_base(LOG_DIPL2, "%s tries to do diplomacy to %s without contact",
938 player_name(pplayer), player_name(aplayer));
939 return;
940 }
941
944 player_number(to_pplayer ? aplayer
945 : pplayer),
946 what, value);
947}
948
949/******************************************************************/
952void dai_diplomacy_first_contact(struct ai_type *ait, struct player *pplayer,
953 struct player *aplayer)
954{
955 bool wants_ceasefire = FALSE;
956
957 /* Randomize initial love */
958 pplayer->ai_common.love[player_index(aplayer)] += 2 - fc_rand(5);
959
960 if (is_ai(pplayer)
961 && player_diplstate_get(pplayer, aplayer)->type == DS_WAR
962 && could_meet_with_player(pplayer, aplayer)) {
963 if (has_handicap(pplayer, H_CEASEFIRE)) {
964 fc_assert(!has_handicap(pplayer, H_AWAY));
965 wants_ceasefire = TRUE;
966 } else if (!has_handicap(pplayer, H_AWAY)) {
967 struct Clause clause;
968
969 clause.from = pplayer;
970 clause.value = 0;
971 clause.type = CLAUSE_CEASEFIRE;
972
973 if (dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
974 FALSE, DS_CEASEFIRE) > 0) {
975 wants_ceasefire = TRUE;
976 }
977 }
978 }
979
980 if (wants_ceasefire) {
981 dai_diplo_notify(aplayer,
982 _("*%s (AI)* Greetings %s! May we suggest a ceasefire "
983 "while we get to know each other better?"),
984 player_name(pplayer),
985 player_name(aplayer));
986 clear_old_treaty(pplayer, aplayer);
987 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_CEASEFIRE, FALSE, 0);
988 } else {
989 dai_diplo_notify(aplayer,
990 _("*%s (AI)* I found you %s! Now make it worth my "
991 "letting you live, or be crushed."),
992 player_name(pplayer),
993 player_name(aplayer));
994 }
995}
996
997/******************************************************************/
1006void dai_diplomacy_begin_new_phase(struct ai_type *ait, struct player *pplayer)
1007{
1008 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
1009 struct adv_data *adv = adv_data_get(pplayer, NULL);
1010 int war_desire[player_slot_count()];
1011 int best_desire = 0;
1012 struct player *best_target = NULL;
1013
1014 fc_assert_ret(is_ai(pplayer));
1015
1016 if (!pplayer->is_alive) {
1017 return; /* duh */
1018 }
1019
1020 memset(war_desire, 0, sizeof(war_desire));
1021
1022 /* Calculate our desires, and find desired war target */
1023 players_iterate_alive(aplayer) {
1024 /* We don't hate ourselves, those we don't know or team members. */
1025 if (aplayer == pplayer
1026 || NEVER_MET(pplayer, aplayer)
1027 || players_on_same_team(pplayer, aplayer)) {
1028 continue;
1029 }
1030 war_desire[player_index(aplayer)] = dai_war_desire(ait, pplayer, aplayer);
1031 if (war_desire[player_index(aplayer)] > best_desire) {
1032 best_desire = war_desire[player_index(aplayer)];
1033 best_target = aplayer;
1034 }
1036
1037 /* Time to make love. If we've been wronged, hold off that love
1038 * for a while. Also, cool our head each turn with love_coeff. */
1039 players_iterate_alive(aplayer) {
1040 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1041 int amount = 0;
1042 int pit;
1043
1044 if (pplayer == aplayer) {
1045 continue;
1046 }
1047
1048 if ((pplayers_non_attack(pplayer, aplayer)
1049 || pplayers_allied(pplayer, aplayer))
1050 && player_diplstate_get(pplayer, aplayer)->has_reason_to_cancel == 0
1051 && adip->countdown == -1
1052 && !adip->is_allied_with_enemy
1053 && !adip->at_war_with_ally
1054 && aplayer != best_target
1055 && adip->ally_patience >= 0) {
1056 amount += ai->diplomacy.love_incr / 2;
1057 if (pplayers_allied(pplayer, aplayer)) {
1058 amount += ai->diplomacy.love_incr / 3;
1059 }
1060 /* Increase love by each enemy they are at war with */
1061 players_iterate(eplayer) {
1062 if (WAR(eplayer, aplayer) && WAR(pplayer, eplayer)) {
1063 amount += ai->diplomacy.love_incr / 4;
1064 }
1066 pplayer->ai_common.love[player_index(aplayer)] += amount;
1067 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "Increased love by %d", amount);
1068 } else if (WAR(pplayer, aplayer)) {
1069 amount -= ai->diplomacy.love_incr / 2;
1070 pplayer->ai_common.love[player_index(aplayer)] += amount;
1071 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "%d love lost to war", amount);
1072 } else if (player_diplstate_get(pplayer, aplayer)->has_reason_to_cancel
1073 != 0) {
1074 /* Provoked in time of peace */
1075 if (pplayer->ai_common.love[player_index(aplayer)] > 0) {
1076 amount -= pplayer->ai_common.love[player_index(aplayer)] / 2;
1077 }
1078 amount -= ai->diplomacy.love_incr * 6;
1079 pplayer->ai_common.love[player_index(aplayer)] += amount;
1080 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "Provoked! %d love lost!",
1081 amount);
1082 }
1083 if (pplayer->ai_common.love[player_index(aplayer)] > MAX_AI_LOVE * 8 / 10
1084 && !pplayers_allied(pplayer, aplayer)) {
1085 int love_change = ai->diplomacy.love_incr / 3;
1086
1087 /* Upper levels of AI trust and love is reserved for allies. */
1088 pplayer->ai_common.love[player_index(aplayer)] -= love_change;
1089 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "%d love lost from excess",
1090 love_change);
1091 }
1092 amount = 0;
1093
1094 /* Reduce love due to units in our territory.
1095 * AI is so naive, that we have to count it even if players are allied */
1096 pit = player_in_territory(pplayer, aplayer) * (MAX_AI_LOVE / 200);
1097 amount -= MIN(pit,
1099 * ((adip->is_allied_with_enemy != NULL) + 1));
1100 pplayer->ai_common.love[player_index(aplayer)] += amount;
1101 if (amount != 0) {
1102 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "%d love lost due to units inside "
1103 "our borders", amount);
1104 }
1105
1106 /* Increase the love if aplayer has got a building that makes
1107 * us love them more. Typically it's Eiffel Tower */
1108 if (!NEVER_MET(pplayer, aplayer)) {
1109 pplayer->ai_common.love[player_index(aplayer)] +=
1110 get_player_bonus(aplayer, EFT_GAIN_AI_LOVE) * MAX_AI_LOVE / 1000;
1111 }
1113
1114 /* Can we win by space race? */
1115 if (adv->dipl.spacerace_leader == pplayer) {
1116 log_base(LOG_DIPL2, "%s going for space race victory!",
1117 player_name(pplayer));
1118 ai->diplomacy.strategy = WIN_SPACE; /* Yes! */
1119 } else {
1120 if (ai->diplomacy.strategy == WIN_SPACE) {
1122 }
1123 }
1124
1125 players_iterate(aplayer) {
1126 int *love = &pplayer->ai_common.love[player_index(aplayer)];
1127
1128 if (aplayer == best_target && best_desire > 0) {
1129 int reduction = MIN(best_desire, MAX_AI_LOVE / 20);
1130
1131 *love -= reduction;
1132 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "Wants war, reducing "
1133 "love by %d ", reduction);
1134 }
1135
1136 /* Edge love towards zero */
1137 *love -= *love * ((double)ai->diplomacy.love_coeff / 100.0);
1138
1139 /* ai love should always be in range [-MAX_AI_LOVE..MAX_AI_LOVE] */
1140 *love = MAX(-MAX_AI_LOVE, MIN(MAX_AI_LOVE, *love));
1142}
1143
1144/******************************************************************/
1147static void suggest_tech_exchange(struct ai_type *ait,
1148 struct player *player1,
1149 struct player *player2)
1150{
1151 struct research *presearch1 = research_get(player1);
1152 struct research *presearch2 = research_get(player2);
1154 int worth[ac];
1155 bool is_dangerous;
1156
1157 worth[A_NONE] = 0;
1158
1160 if (research_invention_state(presearch1, tech)
1161 == TECH_KNOWN) {
1162 if (research_invention_state(presearch2, tech) != TECH_KNOWN
1164 worth[tech] = -compute_tech_sell_price(ait, player1, player2, tech,
1165 &is_dangerous);
1166 if (is_dangerous) {
1167 /* Don't try to exchange */
1168 worth[tech] = 0;
1169 }
1170 } else {
1171 worth[tech] = 0;
1172 }
1173 } else {
1174 if (research_invention_state(presearch2, tech) == TECH_KNOWN
1175 && research_invention_gettable(presearch1, tech,
1177 worth[tech] = compute_tech_sell_price(ait, player2, player1, tech,
1178 &is_dangerous);
1179 if (is_dangerous) {
1180 /* Don't try to exchange */
1181 worth[tech] = 0;
1182 }
1183 } else {
1184 worth[tech] = 0;
1185 }
1186 }
1188
1190 if (worth[tech] <= 0) {
1191 continue;
1192 }
1194 int diff;
1195
1196 if (worth[tech2] >= 0) {
1197 continue;
1198 }
1199 /* tech2 is given by player1, tech is given by player2 */
1200 diff = worth[tech] + worth[tech2];
1201 if ((diff > 0 && player1->economic.gold >= diff)
1202 || (diff < 0 && player2->economic.gold >= -diff)
1203 || diff == 0) {
1204 dai_diplomacy_suggest(player1, player2, CLAUSE_ADVANCE, FALSE, tech2);
1205 dai_diplomacy_suggest(player1, player2, CLAUSE_ADVANCE, TRUE, tech);
1206 if (diff > 0) {
1207 dai_diplomacy_suggest(player1, player2, CLAUSE_GOLD, FALSE, diff);
1208 } else if (diff < 0) {
1209 dai_diplomacy_suggest(player1, player2, CLAUSE_GOLD, TRUE, -diff);
1210 }
1211 return;
1212 }
1215}
1216
1217/******************************************************************/
1220static void clear_old_treaty(struct player *pplayer, struct player *aplayer)
1221{
1222 struct Treaty *old_treaty = find_treaty(pplayer, aplayer);
1223
1224 if (old_treaty != NULL) {
1225 /* Remove existing clauses */
1226 clause_list_iterate(old_treaty->clauses, pclause) {
1228 player_number(pplayer),
1229 player_number(pclause->from),
1230 pclause->type, pclause->value);
1231 free(pclause);
1233 clause_list_destroy(old_treaty->clauses);
1234 old_treaty->clauses = clause_list_new();
1235 }
1236}
1237
1238/******************************************************************/
1241static void dai_share(struct ai_type *ait, struct player *pplayer,
1242 struct player *aplayer)
1243{
1244 struct research *presearch = research_get(pplayer);
1245 struct research *aresearch = research_get(aplayer);
1246 bool gives_vision;
1247
1248 clear_old_treaty(pplayer, aplayer);
1249
1250 /* Only share techs with team mates */
1251 if (presearch != aresearch
1252 && players_on_same_team(pplayer, aplayer)) {
1254 if (research_invention_state(presearch, idx) != TECH_KNOWN
1255 && research_invention_state(aresearch, idx) == TECH_KNOWN
1256 && research_invention_gettable(presearch, idx,
1258 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_ADVANCE, TRUE, idx);
1259 } else if (research_invention_state(presearch, idx) == TECH_KNOWN
1260 && research_invention_state(aresearch, idx) != TECH_KNOWN
1261 && research_invention_gettable(aresearch, idx,
1263 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_ADVANCE, FALSE, idx);
1264 }
1266 }
1267
1268 /* Only give shared vision if safe. Only ask for shared vision if fair. */
1269 gives_vision = gives_shared_vision(pplayer, aplayer);
1270 if (!gives_vision
1271 && shared_vision_is_safe(pplayer, aplayer)) {
1272 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_VISION, FALSE, 0);
1273 gives_vision = TRUE;
1274 }
1275 if (gives_vision
1276 && !gives_shared_vision(aplayer, pplayer)
1277 && (is_human(aplayer)
1278 || shared_vision_is_safe(aplayer, pplayer))) {
1279 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_VISION, TRUE, 0);
1280 }
1281
1282 if (!player_has_embassy(pplayer, aplayer)) {
1283 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_EMBASSY, TRUE, 0);
1284 }
1285 if (!player_has_embassy(aplayer, pplayer)) {
1286 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_EMBASSY, FALSE, 0);
1287 }
1288
1289 if (!has_handicap(pplayer, H_DIPLOMACY) || is_human(aplayer)) {
1290 suggest_tech_exchange(ait, pplayer, aplayer);
1291 }
1292}
1293
1294/******************************************************************/
1299static void dai_go_to_war(struct ai_type *ait, struct player *pplayer,
1300 struct player *target, enum war_reason reason)
1301{
1302 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, target);
1303
1304 fc_assert_ret(pplayer != target);
1305 fc_assert_ret(target->is_alive);
1306
1307 switch (reason) {
1308 case DAI_WR_SPACE:
1309 dai_diplo_notify(target, _("*%s (AI)* Space will never be yours."),
1310 player_name(pplayer));
1311 adip->countdown = -10;
1312 break;
1313 case DAI_WR_BEHAVIOUR:
1314 dai_diplo_notify(target,
1315 _("*%s (AI)* I have tolerated your vicious antics "
1316 "long enough! To war!"),
1317 player_name(pplayer));
1318 adip->countdown = -20;
1319 break;
1320 case DAI_WR_NONE:
1321 dai_diplo_notify(target, _("*%s (AI)* Peace in ... some other time."),
1322 player_name(pplayer));
1323 adip->countdown = -10;
1324 break;
1325 case DAI_WR_HATRED:
1326 dai_diplo_notify(target,
1327 _("*%s (AI)* Finally I get around to you! Did "
1328 "you really think you could get away with your crimes?"),
1329 player_name(pplayer));
1330 adip->countdown = -20;
1331 break;
1332 case DAI_WR_EXCUSE:
1333 dai_diplo_notify(target,
1334 _("*%s (AI)* Your covert hostilities brought "
1335 "this war upon you!"),
1336 player_name(pplayer));
1337 adip->countdown = -20;
1338 break;
1339 case DAI_WR_ALLIANCE:
1340 if (adip->at_war_with_ally) {
1341 dai_diplo_notify(target,
1342 _("*%s (AI)* Your aggression against %s was "
1343 "your last mistake!"),
1344 player_name(pplayer),
1346 adip->countdown = -3;
1347 } else {
1348 /* Ooops! */
1349 DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "Wanted to declare war "
1350 "for their war against an ally, but can no longer find "
1351 "this ally! War declaration aborted.");
1352 adip->countdown = -1;
1353 return;
1354 }
1355 break;
1356 }
1357
1358 fc_assert_ret(adip->countdown < 0);
1359
1360 if (gives_shared_vision(pplayer, target)) {
1361 remove_shared_vision(pplayer, target);
1362 }
1363
1364 /* Check for Senate obstruction. If so, dissolve it. */
1365 if (pplayer_can_cancel_treaty(pplayer, target) == DIPL_SENATE_BLOCKING) {
1366 struct government *real_gov = pplayer->government;
1367
1369
1370 if (pplayer_can_cancel_treaty(pplayer, target) == DIPL_OK) {
1371 /* It seems that revolution would help. */
1372 pplayer->government = real_gov;
1375 } else {
1376 /* There would be Senate even during revolution. Better not to revolt for nothing */
1377 pplayer->government = real_gov;
1378 adip->countdown = -1; /* War declaration aborted */
1379
1380 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target,
1381 "Not revolting, as there would be Senate regardless.");
1382
1383 return;
1384 }
1385 }
1386
1387 /* This will take us straight to war. */
1388 while (player_diplstate_get(pplayer, target)->type != DS_WAR) {
1389 if (pplayer_can_cancel_treaty(pplayer, target) != DIPL_OK) {
1390 DIPLO_LOG(ait, LOG_ERROR, pplayer, target,
1391 "Wanted to cancel treaty but was unable to.");
1392 adip->countdown = -1; /* War declaration aborted */
1393
1394 return;
1395 }
1396 handle_diplomacy_cancel_pact(pplayer, player_number(target), clause_type_invalid());
1397 }
1398
1399 /* Throw a tantrum */
1400 if (pplayer->ai_common.love[player_index(target)] > 0) {
1401 pplayer->ai_common.love[player_index(target)] = -1;
1402 }
1403 pplayer->ai_common.love[player_index(target)] -= MAX_AI_LOVE / 8;
1404
1405 fc_assert(!gives_shared_vision(pplayer, target));
1406 DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "war declared");
1407}
1408
1409/******************************************************************/
1421static void war_countdown(struct ai_type *ait, struct player *pplayer,
1422 struct player *target,
1423 int countdown, enum war_reason reason)
1424{
1425 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, target);
1426
1427 DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "countdown to war in %d", countdown);
1428
1429 /* Otherwise we're resetting an existing countdown, which is very bad */
1430 fc_assert_ret(adip->countdown == -1);
1431
1432 adip->countdown = countdown;
1433 adip->war_reason = reason;
1434
1435 players_iterate_alive(ally) {
1436 if (!pplayers_allied(pplayer, ally)
1437 || ally == target
1438 || NEVER_MET(pplayer, ally)) {
1439 continue;
1440 }
1441
1442 switch (reason) {
1443 case DAI_WR_SPACE:
1444 dai_diplo_notify(ally,
1445 PL_("*%s (AI)* We will be launching an all-out war "
1446 "against %s in %d turn to stop the spaceship "
1447 "launch.",
1448 "*%s (AI)* We will be launching an all-out war "
1449 "against %s in %d turns to stop the spaceship "
1450 "launch.",
1451 countdown),
1452 player_name(pplayer),
1453 player_name(target),
1454 countdown);
1455 dai_diplo_notify(ally,
1456 _("*%s (AI)* Your aid in this matter will be expected. "
1457 "Long live our glorious alliance!"),
1458 player_name(pplayer));
1459 break;
1460 case DAI_WR_BEHAVIOUR:
1461 case DAI_WR_EXCUSE:
1462 dai_diplo_notify(ally,
1463 PL_("*%s (AI)* %s has grossly violated their treaties "
1464 "with us for own gain. We will answer in force in "
1465 "%d turn and expect you to honor your alliance "
1466 "with us and do likewise!",
1467 "*%s (AI)* %s has grossly violated their treaties "
1468 "with us for own gain. We will answer in force in "
1469 "%d turns and expect you to honor your alliance "
1470 "with us and do likewise!", countdown),
1471 player_name(pplayer),
1472 player_name(target),
1473 countdown);
1474 break;
1475 case DAI_WR_NONE:
1476 dai_diplo_notify(ally,
1477 PL_("*%s (AI)* We intend to pillage and plunder the rich "
1478 "civilization of %s. We declare war in %d turn.",
1479 "*%s (AI)* We intend to pillage and plunder the rich "
1480 "civilization of %s. We declare war in %d turns.",
1481 countdown),
1482 player_name(pplayer),
1483 player_name(target),
1484 countdown);
1485 dai_diplo_notify(ally,
1486 _("*%s (AI)* If you want a piece of the loot, feel "
1487 "free to join in the action!"),
1488 player_name(pplayer));
1489 break;
1490 case DAI_WR_HATRED:
1491 dai_diplo_notify(ally,
1492 PL_("*%s (AI)* We have had it with %s. Let us tear this "
1493 "pathetic civilization apart. We declare war in "
1494 "%d turn.",
1495 "*%s (AI)* We have had it with %s. Let us tear this "
1496 "pathetic civilization apart. We declare war in "
1497 "%d turns.",
1498 countdown),
1499 player_name(pplayer),
1500 player_name(target),
1501 countdown);
1502 dai_diplo_notify(ally,
1503 _("*%s (AI)* As our glorious allies, we expect your "
1504 "help in this war."),
1505 player_name(pplayer));
1506 break;
1507 case DAI_WR_ALLIANCE:
1508 if (WAR(ally, target)) {
1509 dai_diplo_notify(ally,
1510 PL_("*%s (AI)* We will honor our alliance and declare "
1511 "war on %s in %d turn. Hold on - we are coming!",
1512 "*%s (AI)* We will honor our alliance and declare "
1513 "war on %s in %d turns. Hold on - we are coming!",
1514 countdown),
1515 player_name(pplayer),
1516 player_name(target),
1517 countdown);
1518 } else if (adip->at_war_with_ally) {
1519 dai_diplo_notify(ally,
1520 PL_("*%s (AI)* We will honor our alliance with %s and "
1521 "declare war on %s in %d turns. We expect you to "
1522 "do likewise.",
1523 "*%s (AI)* We will honor our alliance with %s and "
1524 "declare war on %s in %d turns. We expect you to "
1525 "do likewise.",
1526 countdown),
1527 player_name(pplayer),
1529 player_name(target),
1530 countdown);
1531 } else {
1532 fc_assert(FALSE); /* Huh? */
1533 }
1534 break;
1535 }
1537}
1538
1539/******************************************************************/
1545void dai_diplomacy_actions(struct ai_type *ait, struct player *pplayer)
1546{
1547 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
1548 bool need_targets = TRUE;
1549 struct player *target = NULL;
1550 int most_hatred = MAX_AI_LOVE;
1551 int war_threshold;
1552 int aggr;
1553 float aggr_sr;
1554 float max_sr;
1555
1556 fc_assert_ret(is_ai(pplayer));
1557
1558 if (!pplayer->is_alive) {
1559 return;
1560 }
1561
1562 if (get_player_bonus(pplayer, EFT_NO_DIPLOMACY) > 0) {
1563 /* Diplomacy disabled for this player */
1564 return;
1565 }
1566
1567 /*** If we are greviously insulted, go to war immediately. ***/
1568
1569 players_iterate(aplayer) {
1570 if (pplayer->ai_common.love[player_index(aplayer)] < 0
1571 && player_diplstate_get(pplayer, aplayer)->has_reason_to_cancel >= 2
1572 && dai_diplomacy_get(ait, pplayer, aplayer)->countdown == -1) {
1573 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "Plans war in revenge");
1574 war_countdown(ait, pplayer, aplayer, map_size_checked(),
1575 DAI_WR_BEHAVIOUR);
1576 }
1578
1579 /*** Stop other players from winning by space race ***/
1580
1581 if (ai->diplomacy.strategy != WIN_SPACE) {
1582 struct adv_data *adv = adv_data_get(pplayer, NULL);
1583
1584 players_iterate_alive(aplayer) {
1585 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1586 struct player_spaceship *ship = &aplayer->spaceship;
1587
1588 if (aplayer == pplayer
1589 || adip->countdown >= 0 /* already counting down to war */
1590 || ship->state == SSHIP_NONE
1591 || players_on_same_team(pplayer, aplayer)
1592 || pplayers_at_war(pplayer, aplayer)) {
1593 continue;
1594 }
1595
1596 /* A spaceship victory is always one single player's or team's victory */
1597 if (aplayer->spaceship.state == SSHIP_LAUNCHED
1598 && adv->dipl.spacerace_leader == aplayer
1599 && pplayers_allied(pplayer, aplayer)) {
1600 dai_diplo_notify(aplayer,
1601 _("*%s (AI)* Your attempt to conquer space for "
1602 "yourself alone betrays your true intentions, and I "
1603 "will have no more of our alliance!"),
1604 player_name(pplayer));
1606 CLAUSE_ALLIANCE);
1607 if (gives_shared_vision(pplayer, aplayer)) {
1608 remove_shared_vision(pplayer, aplayer);
1609 }
1610 /* Never forgive this */
1611 pplayer->ai_common.love[player_index(aplayer)] = -MAX_AI_LOVE;
1612 } else if (ship->state == SSHIP_STARTED
1613 && adip->warned_about_space == 0) {
1614 pplayer->ai_common.love[player_index(aplayer)] -= MAX_AI_LOVE / 10;
1615 adip->warned_about_space = 10 + fc_rand(6);
1616 dai_diplo_notify(aplayer,
1617 _("*%s (AI)* Your attempt to unilaterally "
1618 "dominate outer space is highly offensive."),
1619 player_name(pplayer));
1620 dai_diplo_notify(aplayer,
1621 _("*%s (AI)* If you do not stop constructing your "
1622 "spaceship, I may be forced to take action!"),
1623 player_name(pplayer));
1624 }
1625 if (aplayer->spaceship.state == SSHIP_LAUNCHED
1626 && aplayer == adv->dipl.spacerace_leader) {
1627 /* This means war!!! */
1628 pplayer->ai_common.love[player_index(aplayer)] -= MAX_AI_LOVE / 2;
1629 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "plans war due to spaceship");
1630 war_countdown(ait, pplayer, aplayer, 4 + map_size_checked(),
1631 DAI_WR_SPACE);
1632 }
1634 }
1635
1636 /*** Declare war against somebody if we are out of targets ***/
1637
1638 players_iterate_alive(aplayer) {
1639 int turns; /* turns since contact */
1640
1641 if (NEVER_MET(pplayer, aplayer)) {
1642 continue;
1643 }
1644 turns = game.info.turn;
1645 turns -= player_diplstate_get(pplayer, aplayer)->first_contact_turn;
1646 if (WAR(pplayer, aplayer)) {
1647 need_targets = FALSE;
1648 } else if (pplayer->ai_common.love[player_index(aplayer)] < most_hatred
1649 && turns > TURNS_BEFORE_TARGET) {
1650 most_hatred = pplayer->ai_common.love[player_index(aplayer)];
1651 target = aplayer;
1652 }
1654
1655 aggr = ai_trait_get_value(TRAIT_AGGRESSIVE, pplayer);
1656 max_sr = TRAIT_MAX_VALUE_SR;
1657 aggr_sr = sqrt(aggr);
1658
1659 war_threshold = (MAX_AI_LOVE * (0.70 + aggr_sr / max_sr / 2.0)) - MAX_AI_LOVE;
1660
1661 if (need_targets && target && most_hatred < war_threshold
1662 && dai_diplomacy_get(ait, pplayer, target)->countdown == -1) {
1663 enum war_reason war_reason;
1664
1665 if (pplayers_allied(pplayer, target)) {
1666 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target, "Plans war against an ally!");
1667 }
1668 if (player_diplstate_get(pplayer, target)->has_reason_to_cancel > 0) {
1669 /* We have good reason */
1670 war_reason = DAI_WR_EXCUSE;
1671 } else if (pplayer->ai_common.love[player_index(target)] < 0) {
1672 /* We have a reason of sorts from way back, maybe? */
1673 war_reason = DAI_WR_HATRED;
1674 } else {
1675 /* We have no legimitate reason... So what? */
1676 war_reason = DAI_WR_NONE;
1677 }
1678 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target, "plans war for spoils");
1679 war_countdown(ait, pplayer, target, 4 + map_size_checked(), war_reason);
1680 }
1681
1682 /*** Declare war - against enemies of allies ***/
1683
1684 players_iterate_alive(aplayer) {
1685 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1686
1687 if (adip->at_war_with_ally
1688 && adip->countdown == -1
1689 && !adip->is_allied_with_ally
1690 && !pplayers_at_war(pplayer, aplayer)
1691 && (player_diplstate_get(pplayer, aplayer)->type != DS_CEASEFIRE
1692 || fc_rand(5) < 1)) {
1693 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "plans war to help ally %s",
1695 war_countdown(ait, pplayer, aplayer, 2 + map_size_checked(),
1696 DAI_WR_ALLIANCE);
1697 }
1699
1700 /*** Actually declare war (when we have moved units into position) ***/
1701
1702 players_iterate(aplayer) {
1703 if (!players_on_same_team(pplayer, aplayer)) {
1704 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1705
1706 if (!aplayer->is_alive) {
1707 adip->countdown = -1;
1708 continue;
1709 }
1710 if (adip->countdown > 0) {
1711 adip->countdown--;
1712 } else if (adip->countdown == 0) {
1713 if (!WAR(pplayer, aplayer)) {
1714 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "Declaring war!");
1715 dai_go_to_war(ait, pplayer, aplayer, adip->war_reason);
1716 }
1717 } else if (adip->countdown < -1) {
1718 /* Negative countdown less than -1 is war stubbornness */
1719 adip->countdown++;
1720 }
1721 }
1723
1724 /*** Try to make peace with everyone we love ***/
1725
1726 players_iterate_alive(aplayer) {
1727 if (get_player_bonus(aplayer, EFT_NO_DIPLOMACY) <= 0
1728 && diplomacy_possible(pplayer, aplayer)) {
1729 enum diplstate_type ds = player_diplstate_get(pplayer, aplayer)->type;
1730 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1731 struct Clause clause;
1732
1733 /* Meaningless values, but rather not have them unset. */
1734 clause.from = pplayer;
1735 clause.value = 0;
1736
1737 /* Remove shared vision if we are not allied or it is no longer safe. */
1738 if (gives_shared_vision(pplayer, aplayer)) {
1739 if (!pplayers_allied(pplayer, aplayer)) {
1740 remove_shared_vision(pplayer, aplayer);
1741 } else if (!players_on_same_team(pplayer, aplayer)
1742 && !shared_vision_is_safe(pplayer, aplayer)) {
1743 dai_diplo_notify(aplayer,
1744 _("*%s (AI)* Sorry, sharing vision with you "
1745 "is no longer safe."),
1746 player_name(pplayer));
1747 remove_shared_vision(pplayer, aplayer);
1748 }
1749 }
1750
1751 /* No peace to enemies of our allies... or pointless peace. */
1752 if (is_barbarian(aplayer)
1753 || aplayer == pplayer
1754 || aplayer == target /* no mercy */
1755 || adip->countdown >= 0
1756 || !could_meet_with_player(pplayer, aplayer)) {
1757 continue;
1758 }
1759
1760 /* Spam control */
1761 adip->asked_about_peace = MAX(adip->asked_about_peace - 1, 0);
1762 adip->asked_about_alliance = MAX(adip->asked_about_alliance - 1, 0);
1763 adip->asked_about_ceasefire = MAX(adip->asked_about_ceasefire - 1, 0);
1764 adip->warned_about_space = MAX(adip->warned_about_space - 1, 0);
1765 adip->spam = MAX(adip->spam - 1, 0);
1766 if (adip->spam > 0 && is_ai(aplayer)) {
1767 /* Don't spam */
1768 continue;
1769 }
1770
1771 /* Canvass support from existing friends for our war, and try to
1772 * make friends with enemies. Then we wait some turns until next time
1773 * we spam them with our gibbering chatter. */
1774 if (adip->spam <= 0) {
1775 if (!pplayers_allied(pplayer, aplayer)) {
1776 adip->spam = fc_rand(4) + 3; /* Bugger allies often. */
1777 } else {
1778 adip->spam = fc_rand(8) + 6; /* Others are less important. */
1779 }
1780 }
1781
1782 switch (ds) {
1783 case DS_TEAM:
1784 dai_share(ait, pplayer, aplayer);
1785 break;
1786 case DS_ALLIANCE:
1787 /* See if our allies are diligently declaring war on our enemies... */
1788 if (adip->at_war_with_ally) {
1789 break;
1790 }
1791 target = NULL;
1792 players_iterate(eplayer) {
1793 if (WAR(pplayer, eplayer)
1794 && !pplayers_at_war(aplayer, eplayer)) {
1795 target = eplayer;
1796 break;
1797 }
1799
1800 if ((players_on_same_team(pplayer, aplayer)
1801 || pplayer->ai_common.love[player_index(aplayer)] > MAX_AI_LOVE / 2)) {
1802 /* Share techs only with team mates and allies we really like. */
1803 dai_share(ait, pplayer, aplayer);
1804 }
1805 if (!target || !target->is_alive) {
1806 adip->ally_patience = 0;
1807 break; /* No need to nag our ally */
1808 }
1809
1810 if (adip->spam <= 0) {
1811 /* Count down patience toward AI player (one that can have spam > 0)
1812 * at the same speed as toward human players. */
1813 if (adip->ally_patience == 0) {
1814 dai_diplo_notify(aplayer,
1815 _("*%s (AI)* Greetings our most trustworthy "
1816 "ally. We call upon you to destroy our enemy, %s."),
1817 player_name(pplayer),
1818 player_name(target));
1819 adip->ally_patience--;
1820 } else if (adip->ally_patience == -1) {
1821 if (fc_rand(5) == 1) {
1822 dai_diplo_notify(aplayer,
1823 _("*%s (AI)* Greetings ally, I see you have not yet "
1824 "made war with our enemy, %s. Why do I need to remind "
1825 "you of your promises?"),
1826 player_name(pplayer),
1827 player_name(target));
1828 adip->ally_patience--;
1829 }
1830 } else if (fc_rand(5) == 1
1831 && !players_on_same_team(pplayer, aplayer)) {
1832 dai_diplo_notify(aplayer,
1833 _("*%s (AI)* Dishonored one, we made a pact of "
1834 "alliance, and yet you remain at peace with our mortal "
1835 "enemy, %s! This is unacceptable; our alliance is no "
1836 "more!"),
1837 player_name(pplayer),
1838 player_name(target));
1839 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer,
1840 "breaking useless alliance");
1841 /* To peace */
1843 CLAUSE_ALLIANCE);
1844 pplayer->ai_common.love[player_index(aplayer)]
1845 = MIN(pplayer->ai_common.love[player_index(aplayer)], 0);
1846 if (gives_shared_vision(pplayer, aplayer)) {
1847 remove_shared_vision(pplayer, aplayer);
1848 }
1849
1850 fc_assert(!gives_shared_vision(pplayer, aplayer));
1851 }
1852 }
1853 break;
1854
1855 case DS_PEACE:
1856 clause.type = CLAUSE_ALLIANCE;
1857 if (adip->at_war_with_ally
1858 || (is_human(aplayer) && adip->asked_about_alliance > 0)
1859 || dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
1860 FALSE, DS_ALLIANCE) < 0) {
1861 break;
1862 }
1863 clear_old_treaty(pplayer, aplayer);
1864 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_ALLIANCE, FALSE, 0);
1865 adip->asked_about_alliance = is_human(aplayer) ? 13 : 0;
1866 dai_diplo_notify(aplayer,
1867 _("*%s (AI)* Greetings friend, may we suggest "
1868 "making a common cause and join in an alliance?"),
1869 player_name(pplayer));
1870 break;
1871
1872 case DS_CEASEFIRE:
1873 clause.type = CLAUSE_PEACE;
1874 if (adip->at_war_with_ally
1875 || (is_human(aplayer) && adip->asked_about_peace > 0)
1876 || dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
1877 FALSE, DS_PEACE) < 0) {
1878 break;
1879 }
1880 clear_old_treaty(pplayer, aplayer);
1881 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_PEACE, FALSE, 0);
1882 adip->asked_about_peace = is_human(aplayer) ? 12 : 0;
1883 dai_diplo_notify(aplayer,
1884 _("*%s (AI)* Greetings neighbor, may we suggest "
1885 "more peaceful relations?"),
1886 player_name(pplayer));
1887 break;
1888
1889 case DS_NO_CONTACT: /* but we do have embassy! weird. */
1890 case DS_WAR:
1891 clause.type = CLAUSE_CEASEFIRE;
1892 if ((is_human(aplayer) && adip->asked_about_ceasefire > 0)
1893 || dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
1894 FALSE, DS_CEASEFIRE) < 0) {
1895 break; /* Fight until the end! */
1896 }
1897 clear_old_treaty(pplayer, aplayer);
1898 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_CEASEFIRE, FALSE, 0);
1899 adip->asked_about_ceasefire = is_human(aplayer) ? 9 : 0;
1900 dai_diplo_notify(aplayer,
1901 _("*%s (AI)* We grow weary of this constant "
1902 "bloodshed. May we suggest a cessation of hostilities?"),
1903 player_name(pplayer));
1904 break;
1905
1906 case DS_ARMISTICE:
1907 break;
1908 default:
1909 fc_assert_msg(FALSE, "Unknown pact type %d.", ds);
1910 break;
1911 }
1912 }
1914}
1915
1916/******************************************************************/
1920bool dai_on_war_footing(struct ai_type *ait, struct player *pplayer)
1921{
1922 players_iterate(plr) {
1923 if (dai_diplomacy_get(ait, pplayer, plr)->countdown >= 0) {
1924 return TRUE;
1925 }
1927
1928 return FALSE;
1929}
1930
1931/******************************************************************/
1934/* AI attitude call-backs */
1936 enum casus_belli_range scope,
1937 const struct action *paction,
1938 struct player *receiver,
1939 struct player *violator, struct player *victim)
1940{
1941 if (!is_ai(receiver) || violator == receiver) {
1942 return;
1943 }
1944
1945 /* Can only handle victim only and international incidents. */
1946 fc_assert_ret(scope == CBR_VICTIM_ONLY
1947 || scope == CBR_INTERNATIONAL_OUTRAGE);
1948
1949 switch (type) {
1950 case INCIDENT_ACTION:
1951 /* Feel free the change how the action results are grouped and how bad
1952 * the ai considers each group. */
1953 switch (paction->result) {
1954 case ACTRES_SPY_NUKE:
1955 case ACTRES_NUKE:
1956 case ACTRES_NUKE_UNITS:
1957 if (receiver == victim) {
1958 /* Tell the victim */
1959 dai_incident_nuclear(receiver, violator, victim);
1960 } else if (violator == victim) {
1961 dai_incident_nuclear_self(receiver, violator, victim);
1962 } else {
1963 dai_incident_nuclear_not_target(receiver, violator, victim);
1964 }
1965 break;
1966 case ACTRES_ESTABLISH_EMBASSY:
1967 case ACTRES_SPY_INVESTIGATE_CITY:
1968 /* Snoping */
1969 dai_incident_simple(receiver, violator, victim, scope, 2);
1970 break;
1971 case ACTRES_SPY_STEAL_GOLD:
1972 case ACTRES_SPY_STEAL_TECH:
1973 case ACTRES_SPY_TARGETED_STEAL_TECH:
1974 case ACTRES_STEAL_MAPS:
1975 /* Theft */
1976 dai_incident_simple(receiver, violator, victim, scope, 5);
1977 break;
1978 case ACTRES_EXPEL_UNIT:
1979 /* Unit position loss */
1980 dai_incident_simple(receiver, violator, victim, scope, 1);
1981 break;
1982 case ACTRES_SPY_SABOTAGE_UNIT:
1983 /* Unit weakening */
1984 dai_incident_simple(receiver, violator, victim, scope, 3);
1985 break;
1986 case ACTRES_SPY_BRIBE_UNIT:
1987 case ACTRES_CAPTURE_UNITS:
1988 case ACTRES_BOMBARD:
1989 case ACTRES_ATTACK:
1990 case ACTRES_SPY_ATTACK:
1991 /* Unit loss */
1992 dai_incident_simple(receiver, violator, victim, scope, 5);
1993 break;
1994 case ACTRES_SPY_INCITE_CITY:
1995 case ACTRES_DESTROY_CITY:
1996 case ACTRES_CONQUER_CITY:
1997 /* City loss */
1998 dai_incident_simple(receiver, violator, victim, scope, 10);
1999 break;
2000 case ACTRES_SPY_SABOTAGE_CITY:
2001 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2002 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
2003 case ACTRES_STRIKE_BUILDING:
2004 case ACTRES_STRIKE_PRODUCTION:
2005 /* Building loss */
2006 dai_incident_simple(receiver, violator, victim, scope, 5);
2007 break;
2008 case ACTRES_SPY_POISON:
2009 case ACTRES_SPY_SPREAD_PLAGUE:
2010 /* Population loss */
2011 dai_incident_simple(receiver, violator, victim, scope, 5);
2012 break;
2013 case ACTRES_FOUND_CITY:
2014 /* Terrain loss */
2015 dai_incident_simple(receiver, violator, victim, scope, 4);
2016 break;
2017 case ACTRES_CONQUER_EXTRAS:
2018 case ACTRES_PILLAGE:
2019 /* Extra loss */
2020 dai_incident_simple(receiver, violator, victim, scope, 2);
2021 break;
2022 case ACTRES_UNIT_MOVE:
2023 case ACTRES_TRADE_ROUTE:
2024 case ACTRES_MARKETPLACE:
2025 case ACTRES_HELP_WONDER:
2026 case ACTRES_JOIN_CITY:
2027 case ACTRES_DISBAND_UNIT_RECOVER:
2028 case ACTRES_DISBAND_UNIT:
2029 case ACTRES_HOME_CITY:
2030 case ACTRES_HOMELESS:
2031 case ACTRES_UPGRADE_UNIT:
2032 case ACTRES_PARADROP:
2033 case ACTRES_PARADROP_CONQUER: /* TODO: bigger incident */
2034 case ACTRES_AIRLIFT:
2035 case ACTRES_HEAL_UNIT:
2036 case ACTRES_TRANSFORM_TERRAIN:
2037 case ACTRES_CULTIVATE:
2038 case ACTRES_PLANT:
2039 case ACTRES_CLEAN_POLLUTION:
2040 case ACTRES_CLEAN_FALLOUT:
2041 case ACTRES_FORTIFY:
2042 case ACTRES_ROAD:
2043 case ACTRES_CONVERT:
2044 case ACTRES_BASE:
2045 case ACTRES_MINE:
2046 case ACTRES_IRRIGATE:
2047 case ACTRES_TRANSPORT_ALIGHT:
2048 case ACTRES_TRANSPORT_UNLOAD:
2049 case ACTRES_TRANSPORT_DISEMBARK:
2050 case ACTRES_TRANSPORT_BOARD:
2051 case ACTRES_TRANSPORT_EMBARK:
2052 case ACTRES_HUT_ENTER:
2053 case ACTRES_HUT_FRIGHTEN:
2054 case ACTRES_NONE:
2055 /* Various */
2056 dai_incident_simple(receiver, violator, victim, scope, 1);
2057 break;
2058 }
2059 break;
2060 case INCIDENT_WAR:
2061 if (receiver == victim) {
2062 dai_incident_war(violator, victim);
2063 }
2064 break;
2065 case INCIDENT_LAST:
2066 /* Assert that always fails, but with meaningful message */
2068 break;
2069 }
2070}
2071
2072/******************************************************************/
2075static void dai_incident_nuclear(struct player *receiver,
2076 const struct player *violator,
2077 const struct player *victim)
2078{
2079 fc_assert_ret(receiver == victim);
2080
2081 if (violator == victim) {
2082 return;
2083 }
2084
2085 receiver->ai_common.love[player_index(violator)] -= 3 * MAX_AI_LOVE / 10;
2086}
2087
2088/******************************************************************/
2091static void dai_incident_nuclear_not_target(struct player *receiver,
2092 const struct player *violator,
2093 const struct player *victim)
2094{
2095 fc_assert_ret(receiver != victim);
2096
2097 receiver->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 10;
2098}
2099
2100/******************************************************************/
2103static void dai_incident_nuclear_self(struct player *receiver,
2104 const struct player *violator,
2105 const struct player *victim)
2106{
2107 fc_assert_ret(receiver != victim);
2108 fc_assert_ret(violator == victim);
2109
2110 receiver->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 20;
2111}
2112
2113/**********************************************************************/
2125static void dai_incident_simple(struct player *receiver,
2126 const struct player *violator,
2127 const struct player *victim,
2128 enum casus_belli_range scope,
2129 int how_bad)
2130{
2131 int displeasure = how_bad * MAX_AI_LOVE;
2132 if (victim == receiver) {
2133 if (scope == CBR_INTERNATIONAL_OUTRAGE) {
2134 /* The ruleset finds this bad enough to cause International Outrage.
2135 * Trust the ruleset author. Double the displeasure. */
2136 displeasure = displeasure * 2;
2137 }
2138 receiver->ai_common.love[player_index(violator)] -= displeasure / 35;
2139 } else if (violator == victim) {
2140 receiver->ai_common.love[player_index(violator)] -= displeasure / 1000;
2141 } else {
2142 receiver->ai_common.love[player_index(violator)] -= displeasure / 500;
2143 }
2144}
2145
2146/******************************************************************/
2154static void dai_incident_war(struct player *violator, struct player *victim)
2155{
2156 players_iterate(pplayer) {
2157 if (!is_ai(pplayer)) {
2158 continue;
2159 }
2160
2161 if (pplayer != violator) {
2162 /* Dislike backstabbing bastards */
2163 pplayer->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 30;
2164 if (player_diplstate_get(violator, victim)->max_state == DS_PEACE) {
2165 /* Extra penalty if they once had a peace treaty */
2166 pplayer->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 30;
2167 } else if (player_diplstate_get(violator, victim)->max_state
2168 == DS_ALLIANCE) {
2169 /* Extra penalty if they once had an alliance */
2170 pplayer->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 10;
2171 }
2172 if (victim == pplayer) {
2173 pplayer->ai_common.love[player_index(violator)] =
2174 MIN(pplayer->ai_common.love[player_index(violator)] - MAX_AI_LOVE / 3, -1);
2175 /* Scream for help!! */
2176 players_iterate_alive(ally) {
2177 if (!pplayers_allied(pplayer, ally)) {
2178 continue;
2179 }
2180 dai_diplo_notify(ally,
2181 _("*%s (AI)* We have been savagely attacked by "
2182 "%s, and we need your help! Honor our glorious "
2183 "alliance and your name will never be forgotten!"),
2184 player_name(victim),
2185 player_name(violator));
2187 }
2188 }
2190}
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:593
bool adv_is_player_dangerous(struct player *pplayer, struct player *aplayer)
Definition advdata.c:1087
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
incident_type
Definition ai.h:45
@ INCIDENT_LAST
Definition ai.h:46
@ INCIDENT_WAR
Definition ai.h:46
@ INCIDENT_ACTION
Definition ai.h:46
struct ai_plr * dai_plr_data_get(struct ai_type *ait, struct player *pplayer, bool *caller_closes)
Definition aidata.c:308
struct ai_dip_intel * dai_diplomacy_get(struct ai_type *ait, const struct player *plr1, const struct player *plr2)
Definition aidata.c:402
void dai_data_phase_finished(struct ai_type *ait, struct player *pplayer)
Definition aidata.c:285
@ WIN_SPACE
Definition aidata.h:34
@ WIN_CAPITAL
Definition aidata.h:35
@ WIN_OPEN
Definition aidata.h:32
#define DIPLO_LOG(ait, loglevel, pplayer, aplayer, msg,...)
Definition ailog.h:53
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition aiplayer.h:54
int player_distance_to_player(struct player *pplayer, struct player *target)
Definition aisupport.c:75
int city_gold_worth(const struct civ_map *nmap, struct city *pcity)
Definition aisupport.c:108
int ai_trait_get_value(enum trait tr, struct player *pplayer)
Definition aitraits.c:68
#define WAR(plr1, plr2)
Definition aiunit.h:62
#define NEVER_MET(plr1, plr2)
Definition aiunit.h:64
#define ATTACK_POWER(ptype)
Definition aiunit.h:68
bool is_capital(const struct city *pcity)
Definition city.c:1552
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
struct city * city_list_find_number(struct city_list *This, int id)
Definition city.c:1652
#define city_list_iterate(citylist, pcity)
Definition city.h:488
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
#define city_owner(_pcity_)
Definition city.h:543
#define city_list_iterate_end
Definition city.h:490
#define city_built_iterate(_pcity, _p)
Definition city.h:810
#define city_built_iterate_end
Definition city.h:816
void dai_treaty_accepted(struct ai_type *ait, struct player *pplayer, struct player *aplayer, struct Treaty *ptreaty)
static void dai_incident_nuclear_not_target(struct player *receiver, const struct player *violator, const struct player *victim)
void dai_incident(struct ai_type *ait, enum incident_type type, enum casus_belli_range scope, const struct action *paction, struct player *receiver, struct player *violator, struct player *victim)
bool dai_on_war_footing(struct ai_type *ait, struct player *pplayer)
void dai_diplomacy_actions(struct ai_type *ait, struct player *pplayer)
static int dai_goldequiv_clause(struct ai_type *ait, struct player *pplayer, struct player *aplayer, struct Clause *pclause, bool verbose, enum diplstate_type ds_after)
static const struct player * get_allied_with_enemy_player(const struct player *us, const struct player *them)
static void dai_incident_simple(struct player *receiver, const struct player *violator, const struct player *victim, enum casus_belli_range scope, int how_bad)
static void dai_incident_nuclear_self(struct player *receiver, const struct player *violator, const struct player *victim)
void dai_diplomacy_begin_new_phase(struct ai_type *ait, struct player *pplayer)
static void suggest_tech_exchange(struct ai_type *ait, struct player *player1, struct player *player2)
void dai_treaty_evaluate(struct ai_type *ait, struct player *pplayer, struct player *aplayer, struct Treaty *ptreaty)
#define LOG_DIPL2
static int greed(int missing_love)
static bool dai_players_can_agree_on_ceasefire(struct ai_type *ait, struct player *player1, struct player *player2)
static void dai_go_to_war(struct ai_type *ait, struct player *pplayer, struct player *target, enum war_reason reason)
static int dai_goldequiv_tech(struct ai_type *ait, struct player *pplayer, Tech_type_id tech)
#define BIG_NUMBER
#define LOG_DIPL
static enum diplstate_type pact_clause_to_diplstate_type(enum clause_type type)
static void dai_diplomacy_suggest(struct player *pplayer, struct player *aplayer, enum clause_type what, bool to_pplayer, int value)
static void dai_treaty_react(struct ai_type *ait, struct player *pplayer, struct player *aplayer, struct Clause *pclause)
static int compute_tech_sell_price(struct ai_type *ait, struct player *giver, struct player *taker, int tech_id, bool *is_dangerous)
static void clear_old_treaty(struct player *pplayer, struct player *aplayer)
static void dai_diplo_notify(struct player *pplayer, const char *text,...)
static void dai_incident_nuclear(struct player *receiver, const struct player *violator, const struct player *victim)
static void dai_incident_war(struct player *violator, struct player *victim)
static void war_countdown(struct ai_type *ait, struct player *pplayer, struct player *target, int countdown, enum war_reason reason)
static void dai_share(struct ai_type *ait, struct player *pplayer, struct player *aplayer)
static bool shared_vision_is_safe(struct player *pplayer, struct player *aplayer)
static int dai_war_desire(struct ai_type *ait, struct player *pplayer, struct player *target)
#define TURNS_BEFORE_TARGET
static bool diplomacy_verbose
void dai_diplomacy_first_contact(struct ai_type *ait, struct player *pplayer, struct player *aplayer)
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
void handle_diplomacy_create_clause_req(struct player *pplayer, int counterpart, int giver, enum clause_type type, int value)
Definition diplhand.c:779
void handle_diplomacy_init_meeting_req(struct player *pplayer, int counterpart)
Definition diplhand.c:872
struct Treaty * find_treaty(struct player *plr0, struct player *plr1)
Definition diplhand.c:121
void handle_diplomacy_accept_treaty_req(struct player *pplayer, int counterpart)
Definition diplhand.c:184
int int initiated_from int int giver
Definition diplodlg_g.h:28
bool diplomacy_possible(const struct player *pplayer1, const struct player *pplayer2)
Definition diptreaty.c:33
bool could_meet_with_player(const struct player *pplayer, const struct player *aplayer)
Definition diptreaty.c:61
#define clause_list_iterate_end
Definition diptreaty.h:68
#define clause_list_iterate(clauselist, pclause)
Definition diptreaty.h:66
#define is_pact_clause(x)
Definition diptreaty.h:49
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
int Tech_type_id
Definition fc_types.h:347
@ O_SHIELD
Definition fc_types.h:91
@ O_TRADE
Definition fc_types.h:91
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const struct ft_color ftc_chat_private
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
GType type
Definition repodlgs.c:1312
void handle_player_change_government(struct player *pplayer, Government_type_id government)
Definition plrhand.c:454
void handle_diplomacy_cancel_pact(struct player *pplayer, int other_player_id, enum clause_type clause)
Definition plrhand.c:761
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_DIPLOMACY
Definition handicaps.h:29
@ H_AWAY
Definition handicaps.h:19
@ H_CEASEFIRE
Definition handicaps.h:33
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity)
bool is_small_wonder(const struct impr_type *pimprove)
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_base(level, message,...)
Definition log.h:94
@ LOG_ERROR
Definition log.h:30
@ LOG_DEBUG
Definition log.h:34
#define log_error(message,...)
Definition log.h:103
#define map_size_checked()
Definition map.h:265
void remove_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1681
void vpackage_event(struct packet_chat_msg *packet, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format, va_list vargs)
Definition notify.c:147
void event_cache_add_for_player(const struct packet_chat_msg *packet, const struct player *pplayer)
Definition notify.c:645
void lsend_packet_chat_msg(struct conn_list *dest, const struct packet_chat_msg *packet)
void dlsend_packet_diplomacy_remove_clause(struct conn_list *dest, int counterpart, int giver, enum clause_type type, int value)
struct city_list * cities
Definition packhand.c:117
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1452
int player_slot_count(void)
Definition player.c:411
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
int player_index(const struct player *pplayer)
Definition player.c:820
int player_in_territory(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1842
enum dipl_reason pplayer_can_cancel_treaty(const struct player *p1, const struct player *p2)
Definition player.c:92
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:317
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1435
bool player_has_embassy(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:202
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1461
bool pplayers_in_peace(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1402
#define players_iterate_end
Definition player.h:535
@ DIPL_SENATE_BLOCKING
Definition player.h:195
@ DIPL_OK
Definition player.h:195
#define players_iterate(_pplayer)
Definition player.h:530
#define MAX_AI_LOVE
Definition player.h:559
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define is_ai(plr)
Definition player.h:234
#define players_iterate_alive_end
Definition player.h:545
#define is_human(plr)
Definition player.h:233
#define players_iterate_alive(_pplayer)
Definition player.h:540
#define fc_rand(_size)
Definition rand.h:34
bool research_goal_tech_req(const struct research *presearch, Tech_type_id goal, Tech_type_id tech)
Definition research.c:797
int player_tech_upkeep(const struct player *pplayer)
Definition research.c:1040
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:769
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
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
@ SSHIP_STARTED
Definition spaceship.h:84
@ SSHIP_LAUNCHED
Definition spaceship.h:85
@ SSHIP_NONE
Definition spaceship.h:84
enum clause_type type
Definition diptreaty.h:71
struct player * from
Definition diptreaty.h:72
int value
Definition diptreaty.h:73
struct player * plr0
Definition diptreaty.h:77
struct clause_list * clauses
Definition diptreaty.h:79
enum action_result result
Definition actions.h:384
struct adv_data::@93 dipl
struct player * spacerace_leader
Definition advdata.h:98
struct player * at_war_with_ally
Definition aidata.h:56
signed char asked_about_alliance
Definition aidata.h:65
enum war_reason war_reason
Definition aidata.h:62
signed char spam
Definition aidata.h:59
signed char asked_about_peace
Definition aidata.h:64
int distance
Definition aidata.h:60
struct player * is_allied_with_ally
Definition aidata.h:57
signed char warned_about_space
Definition aidata.h:67
int countdown
Definition aidata.h:61
signed char ally_patience
Definition aidata.h:63
struct player * is_allied_with_enemy
Definition aidata.h:55
signed char asked_about_ceasefire
Definition aidata.h:66
struct ai_plr::@268 diplomacy
adv_want tech_want[A_LAST+1]
Definition aidata.h:103
int req_love_for_alliance
Definition aidata.h:96
char love_incr
Definition aidata.h:94
char love_coeff
Definition aidata.h:93
int req_love_for_peace
Definition aidata.h:95
enum winning_strategy strategy
Definition aidata.h:91
Definition ai.h:50
Definition city.h:309
struct player * original
Definition city.h:313
int diplgoldcost
Definition game.h:139
struct civ_game::@30::@34 server
struct packet_game_info info
Definition game.h:89
struct government * government_during_revolution
Definition game.h:94
Government_type_id government_during_revolution_id
enum tech_upkeep_style tech_upkeep_style
enum tech_leakage_style tech_leakage
bool tech_trade_allow_holes
enum tech_cost_style tech_cost_style
int love[MAX_NUM_PLAYER_SLOTS]
Definition player.h:130
int first_contact_turn
Definition player.h:203
enum diplstate_type type
Definition player.h:201
char has_reason_to_cancel
Definition player.h:205
enum spaceship_state state
Definition spaceship.h:108
struct city_list * cities
Definition player.h:281
int bulbs_last_turn
Definition player.h:351
struct player_ai ai_common
Definition player.h:288
struct government * government
Definition player.h:258
struct team * team
Definition player.h:261
const struct ai_type * ai
Definition player.h:289
struct unit_list * units
Definition player.h:282
struct conn_list * connections
Definition player.h:298
bool is_alive
Definition player.h:268
struct player_economic economic
Definition player.h:284
struct player_spaceship spaceship
Definition player.h:286
struct player::@69::@71 server
Tech_type_id researching
Definition research.h:52
Tech_type_id tech_goal
Definition research.h:85
int techs_researched
Definition research.h:42
int bulbs_researched
Definition research.h:53
struct unit_type::@87 adv
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
#define advance_index_iterate_max(_start, _index, _max)
Definition tech.h:252
#define advance_index_iterate_end
Definition tech.h:248
#define advance_index_iterate_max_end
Definition tech.h:258
static Tech_type_id advance_count(void)
Definition tech.h:170
#define A_FIRST
Definition tech.h:44
#define A_NONE
Definition tech.h:43
#define advance_index_iterate(_start, _index)
Definition tech.h:244
#define TRAIT_MAX_VALUE_SR
Definition traits.h:34
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2631
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
bool utype_is_cityfounder(const struct unit_type *utype)
Definition unittype.c:2981