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
314 ai = dai_plr_data_get(ait, pplayer, &close_here);
315
316 fc_assert_ret_val(pplayer != aplayer, 0);
317
318 diplomacy_verbose = verbose;
319 ds_after = MAX(ds_after, player_diplstate_get(pplayer, aplayer)->type);
320 giver = pclause->from;
321
322 switch (pclause->type) {
323 case CLAUSE_ADVANCE:
324 if (give) {
325 worth -= compute_tech_sell_price(ait, pplayer, aplayer, pclause->value,
326 &is_dangerous);
327 if (is_dangerous) {
328 worth = -BIG_NUMBER;
329 }
330 } else if (research_invention_state(research_get(pplayer),
331 pclause->value) != TECH_KNOWN) {
332 worth += compute_tech_sell_price(ait, aplayer, pplayer, pclause->value,
333 &is_dangerous);
334
335 if (game.info.tech_upkeep_style != TECH_UPKEEP_NONE) {
336 /* Consider the upkeep costs! Thus, one can not get an AI player by
337 * - given AI lots of techs for gold/cities etc.
338 * - AI losses tech due to high upkeep.
339 * FIXME: Is there a better way for this? */
340 struct research *research = research_get(pplayer);
341 int limit;
342
343 /* Make sure there's no division by zero */
344 if (research->techs_researched > 0) {
345 int upk_per_tech = player_tech_upkeep(pplayer)
347
348 limit = MAX(1, upk_per_tech);
349 } else {
350 limit = 1;
351 fc_assert(player_tech_upkeep(pplayer) == 0);
352 }
353
354 if (pplayer->server.bulbs_last_turn < limit) {
355 worth /= 2;
356 }
357 }
358 }
359 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "%s clause worth %d",
360 advance_rule_name(advance_by_number(pclause->value)), worth);
361 break;
362
363 case CLAUSE_ALLIANCE:
364 case CLAUSE_PEACE:
365 case CLAUSE_CEASEFIRE:
366 /* Don't do anything in away mode */
367 if (has_handicap(pplayer, H_AWAY)) {
368 dai_diplo_notify(aplayer, _("*%s (AI)* In away mode AI can't sign such a treaty."),
369 player_name(pplayer));
370 worth = -BIG_NUMBER;
371 break;
372 }
373
374 /* This guy is allied to one of our enemies. Only accept
375 * ceasefire. */
376 if ((penemy = get_allied_with_enemy_player(pplayer, aplayer))
377 && pclause->type != CLAUSE_CEASEFIRE) {
378 dai_diplo_notify(aplayer, _("*%s (AI)* First break alliance with %s, %s."),
379 player_name(pplayer), player_name(penemy),
380 player_name(aplayer));
381 worth = -BIG_NUMBER;
382 break;
383 }
384
385 /* They were allied with an enemy at the begining of the turn. */
386 if (adip->is_allied_with_enemy
387 && pclause->type != CLAUSE_CEASEFIRE) {
388 dai_diplo_notify(aplayer, _("*%s (AI)* I would like to see you keep your "
389 "distance from %s for some time, %s."),
391 player_name(aplayer));
392 worth = -BIG_NUMBER;
393 break;
394 }
395
396 /* Steps of the treaty ladder */
397 if (pclause->type == CLAUSE_PEACE) {
398 const struct player_diplstate *ds
399 = player_diplstate_get(pplayer, aplayer);
400
401 if (!pplayers_non_attack(pplayer, aplayer)) {
402 dai_diplo_notify(aplayer, _("*%s (AI)* Let us first cease hostilities, %s."),
403 player_name(pplayer),
404 player_name(aplayer));
405 worth = -BIG_NUMBER;
406 } else if (ds->type == DS_CEASEFIRE && ds->turns_left > 4) {
407 dai_diplo_notify(aplayer, _("*%s (AI)* I wish to see you keep the current "
408 "ceasefire for a bit longer first, %s."),
409 player_name(pplayer),
410 player_name(aplayer));
411 worth = -BIG_NUMBER;
412 } else if (adip->countdown >= 0 || adip->countdown < -1) {
413 worth = -BIG_NUMBER; /* but say nothing */
414 } else {
415 worth = greed(pplayer->ai_common.love[player_index(aplayer)]
417 }
418 } else if (pclause->type == CLAUSE_ALLIANCE) {
419 if (!pplayers_in_peace(pplayer, aplayer)) {
420 worth = greed(pplayer->ai_common.love[player_index(aplayer)]
422 }
423 if (adip->countdown >= 0 || adip->countdown < -1) {
424 worth = -BIG_NUMBER; /* but say nothing */
425 } else {
426 worth += greed(pplayer->ai_common.love[player_index(aplayer)]
428 }
429 if (pplayer->ai_common.love[player_index(aplayer)] < MAX_AI_LOVE / 10) {
430 dai_diplo_notify(aplayer, _("*%s (AI)* I simply do not trust you with an "
431 "alliance yet, %s."),
432 player_name(pplayer),
433 player_name(aplayer));
434 worth = -BIG_NUMBER;
435 }
436 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "ally clause worth %d", worth);
437 } else {
438 if (is_ai(pplayer) && is_ai(aplayer)
439 && dai_players_can_agree_on_ceasefire(ait, pplayer, aplayer)) {
440 worth = 0;
441 } else {
442 int turns = game.info.turn;
443
444 turns -= player_diplstate_get(pplayer, aplayer)->first_contact_turn;
445 if (turns < TURNS_BEFORE_TARGET) {
446 worth = 0; /* show some good faith */
447 break;
448 } else {
449 worth = greed(pplayer->ai_common.love[player_index(aplayer)]);
450 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "ceasefire worth=%d love=%d "
451 "turns=%d", worth,
452 pplayer->ai_common.love[player_index(aplayer)],
453 turns);
454 }
455 }
456 }
457
458 /* Let's all hold hands in one happy family! */
459 if (adip->is_allied_with_ally) {
460 worth /= 2;
461 break;
462 }
463
464 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "treaty clause worth %d", worth);
465 break;
466
467 case CLAUSE_GOLD:
468 if (give) {
469 worth -= pclause->value;
470 } else {
471 worth += pclause->value * (100 - game.server.diplgoldcost) / 100;
472 }
473 break;
474
475 case CLAUSE_SEAMAP:
476 if (!give || ds_after == DS_ALLIANCE) {
477 /* Useless to us - we're omniscient! And allies get it for free! */
478 worth = 0;
479 } else {
480 /* Very silly algorithm 1: Sea map more worth if enemy has more
481 cities. Reasoning is they have more use of seamap for settling
482 new areas the more cities they have already. */
483 worth -= 15 * city_list_size(aplayer->cities);
484 /* Don't like them? Don't give it to them! */
485 worth = MIN(pplayer->ai_common.love[player_index(aplayer)] * 7, worth);
486 /* Make maps from novice player cheap */
487 if (has_handicap(pplayer, H_DIPLOMACY)) {
488 worth /= 2;
489 }
490 }
491 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "seamap clause worth %d",
492 worth);
493 break;
494
495 case CLAUSE_MAP:
496 if (!give || ds_after == DS_ALLIANCE) {
497 /* Useless to us - we're omniscient! And allies get it for free! */
498 worth = 0;
499 } else {
500 /* Very silly algorithm 2: Land map more worth the more cities
501 we have, since we expose all of these to the enemy. */
502 worth -= 40 * MAX(city_list_size(pplayer->cities), 1);
503 /* Inflate numbers if not peace */
504 if (!pplayers_in_peace(pplayer, aplayer)) {
505 worth *= 2;
506 }
507 /* Don't like them? Don't give it to them! */
508 worth = MIN(pplayer->ai_common.love[player_index(aplayer)] * 10, worth);
509 /* Make maps from novice player cheap */
510 if (has_handicap(pplayer, H_DIPLOMACY)) {
511 worth /= 6;
512 }
513 }
514 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "landmap clause worth %d",
515 worth);
516 break;
517
518 case CLAUSE_CITY: {
519 struct city *offer = city_list_find_number(pclause->from->cities,
520 pclause->value);
521
522 if (!offer || city_owner(offer) != giver) {
523 /* City destroyed or taken during negotiations */
524 dai_diplo_notify(aplayer, _("*%s (AI)* I do not know the city you mention."),
525 player_name(pplayer));
526 worth = 0;
527 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "city destroyed during negotiations");
528 } else if (give) {
529 /* AI must be crazy to trade away its cities */
530 worth -= city_gold_worth(offer);
531 if (is_capital(offer)) {
532 worth = -BIG_NUMBER; /* Never! Ever! */
533 } else {
534 worth *= 15;
535 }
536 if (aplayer == offer->original) {
537 /* Let them buy back their own city cheaper. */
538 worth /= 2;
539 }
540 } else {
541 worth = city_gold_worth(offer);
542 }
543 if (offer != NULL) {
544 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "worth of %s is %d",
545 city_name_get(offer), worth);
546 }
547 break;
548 }
549
550 case CLAUSE_VISION:
551 if (give) {
552 if (ds_after == DS_ALLIANCE) {
553 if (!shared_vision_is_safe(pplayer, aplayer)) {
554 dai_diplo_notify(aplayer,
555 _("*%s (AI)* Sorry, sharing vision with you "
556 "is not safe."),
557 player_name(pplayer));
558 worth = -BIG_NUMBER;
559 } else {
560 worth = 0;
561 }
562 } else {
563 /* so out of the question */
564 worth = -BIG_NUMBER;
565 }
566 } else {
567 worth = 0; /* We are omniscient, so... */
568 }
569 break;
570
571 case CLAUSE_EMBASSY:
572 if (give) {
573 if (ds_after == DS_ALLIANCE) {
574 worth = 0;
575 } else if (ds_after == DS_PEACE) {
576 worth = -5 * game.info.turn;
577 } else {
578 worth = MIN(-50 * game.info.turn
579 + pplayer->ai_common.love[player_index(aplayer)],
580 -5 * game.info.turn);
581 }
582 } else if (game.info.tech_leakage == TECH_LEAKAGE_EMBASSIES) {
583 worth = game.info.tech_leak_pct / 10;
584 } else {
585 worth = 0; /* We don't need no stinkin' embassy, do we? */
586 }
587 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "embassy clause worth %d",
588 worth);
589 break;
590 case CLAUSE_COUNT:
591 fc_assert(pclause->type != CLAUSE_COUNT);
592 break;
593 } /* end of switch */
594
595 if (close_here) {
596 dai_data_phase_finished(ait, pplayer);
597 }
598
600 return worth;
601}
602
603/******************************************************************/
607void dai_treaty_evaluate(struct ai_type *ait, struct player *pplayer,
608 struct player *aplayer, struct Treaty *ptreaty)
609{
610 int total_balance = 0;
611 bool only_gifts = TRUE;
612 enum diplstate_type ds_after =
613 player_diplstate_get(pplayer, aplayer)->type;
614 int given_cities = 0;
615
616 clause_list_iterate(ptreaty->clauses, pclause) {
617 if (is_pact_clause(pclause->type)) {
618 ds_after = pact_clause_to_diplstate_type(pclause->type);
619 }
620 if (pclause->type == CLAUSE_CITY && pclause->from == pplayer) {
621 given_cities++;
622 }
624
625 /* Evaluate clauses */
626 clause_list_iterate(ptreaty->clauses, pclause) {
627 const struct research *presearch = research_get(pplayer);
628
629 total_balance +=
630 dai_goldequiv_clause(ait, pplayer, aplayer, pclause, TRUE, ds_after);
631
632 if (pclause->type != CLAUSE_GOLD && pclause->type != CLAUSE_MAP
633 && pclause->type != CLAUSE_SEAMAP && pclause->type != CLAUSE_VISION
634 && (pclause->type != CLAUSE_ADVANCE
635 || game.info.tech_cost_style != TECH_COST_CIV1CIV2
636 || pclause->value == research_get(pplayer)->tech_goal
637 || pclause->value == research_get(pplayer)->researching
638 || research_goal_tech_req(presearch, presearch->tech_goal,
639 pclause->value))) {
640 /* We accept the above list of clauses as gifts, even if we are
641 * at war. We do not accept tech or cities since these can be used
642 * against us, unless we know that we want this tech anyway, or
643 * it doesn't matter due to tech cost style. */
644 only_gifts = FALSE;
645 }
647
648 /* If we are at war, and no peace is offered, then no deal, unless
649 * it is just gifts, in which case we gratefully accept. */
650 if (ds_after == DS_WAR && !only_gifts) {
651 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "no peace offered, must refuse");
652 return;
653 }
654
655 if (given_cities > 0
656 && city_list_size(pplayer->cities) - given_cities <= 2) {
657 /* always keep at least two cities */
658 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "cannot give last cities");
659 return;
660 }
661
662 /* Accept if balance is good */
663 if (total_balance >= 0) {
665 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "balance was good: %d",
666 total_balance);
667 } else {
668 /* AI complains about the treaty which was proposed, unless the AI
669 * made the proposal. */
670 if (pplayer != ptreaty->plr0) {
671 dai_diplo_notify(aplayer, _("*%s (AI)* This deal was not very good for us, %s!"),
672 player_name(pplayer),
673 player_name(aplayer));
674 }
675 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "balance was bad: %d",
676 total_balance);
677 }
678}
679
680/******************************************************************/
684static void dai_treaty_react(struct ai_type *ait,
685 struct player *pplayer,
686 struct player *aplayer,
687 struct Clause *pclause)
688{
689 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
690
691 switch (pclause->type) {
692 case CLAUSE_ALLIANCE:
693 if (adip->is_allied_with_ally) {
694 dai_diplo_notify(aplayer, _("*%s (AI)* Welcome into our alliance %s!"),
695 player_name(pplayer),
696 player_name(aplayer));
697 } else {
698 dai_diplo_notify(aplayer, _("*%s (AI)* Yes, may we forever stand united, %s."),
699 player_name(pplayer),
700 player_name(aplayer));
701 }
702 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "become allies");
703 break;
704 case CLAUSE_PEACE:
705 dai_diplo_notify(aplayer, _("*%s (AI)* Yes, peace in our time!"),
706 player_name(pplayer));
707 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "sign peace treaty");
708 break;
709 case CLAUSE_CEASEFIRE:
710 dai_diplo_notify(aplayer, _("*%s (AI)* Agreed. No more hostilities, %s."),
711 player_name(pplayer),
712 player_name(aplayer));
713 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "sign ceasefire");
714 break;
715 default:
716 break;
717 }
718}
719
720/******************************************************************/
727void dai_treaty_accepted(struct ai_type *ait, struct player *pplayer,
728 struct player *aplayer, struct Treaty *ptreaty)
729{
730 bool close_here;
731 struct ai_plr *ai;
732 int total_balance = 0;
733 bool gift = TRUE;
734 enum diplstate_type ds_after =
735 player_diplstate_get(pplayer, aplayer)->type;
736
737 ai = dai_plr_data_get(ait, pplayer, &close_here);
738
739 fc_assert_ret(pplayer != aplayer);
740
741 clause_list_iterate(ptreaty->clauses, pclause) {
742 if (is_pact_clause(pclause->type)) {
743 ds_after = pact_clause_to_diplstate_type(pclause->type);
744 }
746
747 /* Evaluate clauses */
748 clause_list_iterate(ptreaty->clauses, pclause) {
749 int balance =
750 dai_goldequiv_clause(ait, pplayer, aplayer, pclause, TRUE, ds_after);
751
752 total_balance += balance;
753 gift = (gift && (balance >= 0));
754 dai_treaty_react(ait, pplayer, aplayer, pclause);
755 if (is_pact_clause(pclause->type)
756 && dai_diplomacy_get(ait, pplayer, aplayer)->countdown != -1) {
757 /* Cancel a countdown towards war if we just agreed to peace... */
758 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "countdown nullified");
759 dai_diplomacy_get(ait, pplayer, aplayer)->countdown = -1;
760 }
762
763 /* Rather arbitrary algorithm to increase our love for a player if
764 * they offer us gifts. It is only a gift if _all_ the clauses
765 * are beneficial to us. */
766 if (total_balance > 0 && gift) {
767 int i = total_balance / ((city_list_size(pplayer->cities) * 10) + 1);
768
769 i = MIN(i, ai->diplomacy.love_incr * 150) * 10;
770 pplayer->ai_common.love[player_index(aplayer)] += i;
771 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "gift increased love by %d", i);
772 }
773
774 if (close_here) {
775 dai_data_phase_finished(ait, pplayer);
776 }
777}
778
779/******************************************************************/
786static int dai_war_desire(struct ai_type *ait, struct player *pplayer,
787 struct player *target)
788{
789 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
790 struct adv_data *adv = adv_data_get(pplayer, NULL);
791 int want = 0, fear = 0, distance = 0, settlers = 0, cities = 0;
792 struct player_spaceship *ship = &target->spaceship;
793
794 city_list_iterate(target->cities, pcity) {
795 want += 100; /* base city want */
796 want += city_size_get(pcity) * 20;
797 want += pcity->surplus[O_SHIELD] * 8;
798 want += pcity->surplus[O_TRADE] * 6;
799
800 /* FIXME: This might be buggy if it ignores unmet UnitClass reqs. */
801 fear += get_city_bonus(pcity, EFT_DEFEND_BONUS);
802
803 city_built_iterate(pcity, pimprove) {
804 int cost = impr_build_shield_cost(pcity, pimprove);
805
806 want += cost;
807 if (improvement_obsolete(pplayer, pimprove, pcity)) {
808 continue;
809 }
810 if (is_great_wonder(pimprove)) {
811 want += cost * 2;
812 } else if (is_small_wonder(pimprove)) {
813 want += cost;
814 }
817 unit_list_iterate(target->units, punit) {
818 const struct unit_type *ptype = unit_type_get(punit);
819
820 fear += ATTACK_POWER(ptype);
821
822 /* Fear enemy expansionism */
824 want += 100;
825 }
827 unit_list_iterate(pplayer->units, punit) {
828 const struct unit_type *ptype = unit_type_get(punit);
829
830 fear -= ATTACK_POWER(ptype) / 2;
831
832 /* Our own expansionism reduces want for war */
834 want -= 200;
835 settlers++;
836 }
838 city_list_iterate(pplayer->cities, pcity) {
839 if (VUT_UTYPE == pcity->production.kind
840 && utype_is_cityfounder(pcity->production.value.utype)) {
841 want -= 150;
842 settlers++;
843 }
844 cities++;
846
847 /* Modify by settler/cities ratio to prevent early wars when
848 * we should be expanding. This will eliminate want if we
849 * produce settlers in all cities (ie full expansion). */
850 want -= abs(want) / MAX(cities - settlers, 1);
851
852 /* Calculate average distances to other player's empire. */
853 distance = player_distance_to_player(pplayer, target);
854 dai_diplomacy_get(ait, pplayer, target)->distance = distance;
855
856 /* Worry a bit if the other player has extreme amounts of wealth
857 * that can be used in cities to quickly buy an army. */
858 fear += (target->economic.gold / 5000) * city_list_size(target->cities);
859
860 /* Tech lead is worrisome. FIXME: Only consider 'military' techs. */
861 fear += MAX(research_get(target)->techs_researched
862 - research_get(pplayer)->techs_researched, 0) * 100;
863
864 /* Spacerace loss we will not allow! */
865 if (ship->state >= SSHIP_STARTED) {
866 want *= 2;
867 }
868 if (adv->dipl.spacerace_leader == target) {
870 return BIG_NUMBER; /* do NOT amortize this number! */
871 }
872
873 /* Modify by which treaties we would break to other players, and what
874 * excuses we have to do so. FIXME: We only consider immediate
875 * allies, but we might trigger a wider chain reaction. */
876 players_iterate_alive(eplayer) {
877 bool cancel_excuse =
878 player_diplstate_get(pplayer, eplayer)->has_reason_to_cancel != 0;
879 enum diplstate_type ds = player_diplstate_get(pplayer, eplayer)->type;
880
881 if (eplayer == pplayer) {
882 continue;
883 }
884
885 /* Remember: pplayers_allied() returns true when target == eplayer */
886 if (!cancel_excuse && pplayers_allied(target, eplayer)) {
887 if (ds == DS_ARMISTICE) {
888 want -= abs(want) / 10; /* 10% off */
889 } else if (ds == DS_CEASEFIRE) {
890 want -= abs(want) / 7; /* 15% off */
891 } else if (ds == DS_PEACE) {
892 want -= abs(want) / 5; /* 20% off */
893 } else if (ds == DS_ALLIANCE) {
894 want -= abs(want) / 3; /* 33% off */
895 }
896 }
898
899 /* Modify by love. Increase the divisor to make ai go to war earlier */
900 want -= MAX(0, want * pplayer->ai_common.love[player_index(target)]
901 / (2 * MAX_AI_LOVE));
902
903 /* Make novice AI more peaceful with human players */
904 if (has_handicap(pplayer, H_DIPLOMACY) && is_human(target)) {
905 want /= 2;
906 }
907
908 /* Amortize by distance */
909 want = amortize(want, distance);
910
911 if (pplayers_allied(pplayer, target)) {
912 want /= 4;
913 }
914
915 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target, "War want %d, war fear %d",
916 want, fear);
917 return (want - fear);
918}
919
920/******************************************************************/
925static void dai_diplomacy_suggest(struct player *pplayer,
926 struct player *aplayer,
927 enum clause_type what,
928 bool to_pplayer,
929 int value)
930{
931 if (!could_meet_with_player(pplayer, aplayer)) {
932 log_base(LOG_DIPL2, "%s tries to do diplomacy to %s without contact",
933 player_name(pplayer), player_name(aplayer));
934 return;
935 }
936
939 player_number(to_pplayer ? aplayer
940 : pplayer),
941 what, value);
942}
943
944/******************************************************************/
947void dai_diplomacy_first_contact(struct ai_type *ait, struct player *pplayer,
948 struct player *aplayer)
949{
950 bool wants_ceasefire = FALSE;
951
952 /* Randomize initial love */
953 pplayer->ai_common.love[player_index(aplayer)] += 2 - fc_rand(5);
954
955 if (is_ai(pplayer)
956 && player_diplstate_get(pplayer, aplayer)->type == DS_WAR
957 && could_meet_with_player(pplayer, aplayer)) {
958 if (has_handicap(pplayer, H_CEASEFIRE)) {
959 fc_assert(!has_handicap(pplayer, H_AWAY));
960 wants_ceasefire = TRUE;
961 } else if (!has_handicap(pplayer, H_AWAY)) {
962 struct Clause clause;
963
964 clause.from = pplayer;
965 clause.value = 0;
966 clause.type = CLAUSE_CEASEFIRE;
967
968 if (dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
969 FALSE, DS_CEASEFIRE) > 0) {
970 wants_ceasefire = TRUE;
971 }
972 }
973 }
974
975 if (wants_ceasefire) {
976 dai_diplo_notify(aplayer,
977 _("*%s (AI)* Greetings %s! May we suggest a ceasefire "
978 "while we get to know each other better?"),
979 player_name(pplayer),
980 player_name(aplayer));
981 clear_old_treaty(pplayer, aplayer);
982 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_CEASEFIRE, FALSE, 0);
983 } else {
984 dai_diplo_notify(aplayer,
985 _("*%s (AI)* I found you %s! Now make it worth my "
986 "letting you live, or be crushed."),
987 player_name(pplayer),
988 player_name(aplayer));
989 }
990}
991
992/******************************************************************/
1001void dai_diplomacy_begin_new_phase(struct ai_type *ait, struct player *pplayer)
1002{
1003 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
1004 struct adv_data *adv = adv_data_get(pplayer, NULL);
1005 int war_desire[player_slot_count()];
1006 int best_desire = 0;
1007 struct player *best_target = NULL;
1008
1009 fc_assert_ret(is_ai(pplayer));
1010
1011 if (!pplayer->is_alive) {
1012 return; /* duh */
1013 }
1014
1015 memset(war_desire, 0, sizeof(war_desire));
1016
1017 /* Calculate our desires, and find desired war target */
1018 players_iterate_alive(aplayer) {
1019 /* We don't hate ourselves, those we don't know or team members. */
1020 if (aplayer == pplayer
1021 || NEVER_MET(pplayer, aplayer)
1022 || players_on_same_team(pplayer, aplayer)) {
1023 continue;
1024 }
1025 war_desire[player_index(aplayer)] = dai_war_desire(ait, pplayer, aplayer);
1026 if (war_desire[player_index(aplayer)] > best_desire) {
1027 best_desire = war_desire[player_index(aplayer)];
1028 best_target = aplayer;
1029 }
1031
1032 /* Time to make love. If we've been wronged, hold off that love
1033 * for a while. Also, cool our head each turn with love_coeff. */
1034 players_iterate_alive(aplayer) {
1035 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1036 int amount = 0;
1037 int pit;
1038
1039 if (pplayer == aplayer) {
1040 continue;
1041 }
1042
1043 if ((pplayers_non_attack(pplayer, aplayer)
1044 || pplayers_allied(pplayer, aplayer))
1045 && player_diplstate_get(pplayer, aplayer)->has_reason_to_cancel == 0
1046 && adip->countdown == -1
1047 && !adip->is_allied_with_enemy
1048 && !adip->at_war_with_ally
1049 && aplayer != best_target
1050 && adip->ally_patience >= 0) {
1051 amount += ai->diplomacy.love_incr / 2;
1052 if (pplayers_allied(pplayer, aplayer)) {
1053 amount += ai->diplomacy.love_incr / 3;
1054 }
1055 /* Increase love by each enemy they are at war with */
1056 players_iterate(eplayer) {
1057 if (WAR(eplayer, aplayer) && WAR(pplayer, eplayer)) {
1058 amount += ai->diplomacy.love_incr / 4;
1059 }
1061 pplayer->ai_common.love[player_index(aplayer)] += amount;
1062 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "Increased love by %d", amount);
1063 } else if (WAR(pplayer, aplayer)) {
1064 amount -= ai->diplomacy.love_incr / 2;
1065 pplayer->ai_common.love[player_index(aplayer)] += amount;
1066 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "%d love lost to war", amount);
1067 } else if (player_diplstate_get(pplayer, aplayer)->has_reason_to_cancel
1068 != 0) {
1069 /* Provoked in time of peace */
1070 if (pplayer->ai_common.love[player_index(aplayer)] > 0) {
1071 amount -= pplayer->ai_common.love[player_index(aplayer)] / 2;
1072 }
1073 amount -= ai->diplomacy.love_incr * 6;
1074 pplayer->ai_common.love[player_index(aplayer)] += amount;
1075 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "Provoked! %d love lost!",
1076 amount);
1077 }
1078 if (pplayer->ai_common.love[player_index(aplayer)] > MAX_AI_LOVE * 8 / 10
1079 && !pplayers_allied(pplayer, aplayer)) {
1080 int love_change = ai->diplomacy.love_incr / 3;
1081
1082 /* Upper levels of AI trust and love is reserved for allies. */
1083 pplayer->ai_common.love[player_index(aplayer)] -= love_change;
1084 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "%d love lost from excess",
1085 love_change);
1086 }
1087 amount = 0;
1088
1089 /* Reduce love due to units in our territory.
1090 * AI is so naive, that we have to count it even if players are allied */
1091 pit = player_in_territory(pplayer, aplayer) * (MAX_AI_LOVE / 200);
1092 amount -= MIN(pit,
1094 * ((adip->is_allied_with_enemy != NULL) + 1));
1095 pplayer->ai_common.love[player_index(aplayer)] += amount;
1096 if (amount != 0) {
1097 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "%d love lost due to units inside "
1098 "our borders", amount);
1099 }
1100
1101 /* Increase the love if aplayer has got a building that makes
1102 * us love them more. Typically it's Eiffel Tower */
1103 if (!NEVER_MET(pplayer, aplayer)) {
1104 pplayer->ai_common.love[player_index(aplayer)] +=
1105 get_player_bonus(aplayer, EFT_GAIN_AI_LOVE) * MAX_AI_LOVE / 1000;
1106 }
1108
1109 /* Can we win by space race? */
1110 if (adv->dipl.spacerace_leader == pplayer) {
1111 log_base(LOG_DIPL2, "%s going for space race victory!",
1112 player_name(pplayer));
1113 ai->diplomacy.strategy = WIN_SPACE; /* Yes! */
1114 } else {
1115 if (ai->diplomacy.strategy == WIN_SPACE) {
1117 }
1118 }
1119
1120 players_iterate(aplayer) {
1121 int *love = &pplayer->ai_common.love[player_index(aplayer)];
1122
1123 if (aplayer == best_target && best_desire > 0) {
1124 int reduction = MIN(best_desire, MAX_AI_LOVE / 20);
1125
1126 *love -= reduction;
1127 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "Wants war, reducing "
1128 "love by %d ", reduction);
1129 }
1130
1131 /* Edge love towards zero */
1132 *love -= *love * ((double)ai->diplomacy.love_coeff / 100.0);
1133
1134 /* ai love should always be in range [-MAX_AI_LOVE..MAX_AI_LOVE] */
1135 *love = MAX(-MAX_AI_LOVE, MIN(MAX_AI_LOVE, *love));
1137}
1138
1139/******************************************************************/
1142static void suggest_tech_exchange(struct ai_type *ait,
1143 struct player *player1,
1144 struct player *player2)
1145{
1146 struct research *presearch1 = research_get(player1);
1147 struct research *presearch2 = research_get(player2);
1149 int worth[ac];
1150 bool is_dangerous;
1151
1152 worth[A_NONE] = 0;
1153
1155 if (research_invention_state(presearch1, tech)
1156 == TECH_KNOWN) {
1157 if (research_invention_state(presearch2, tech) != TECH_KNOWN
1159 worth[tech] = -compute_tech_sell_price(ait, player1, player2, tech,
1160 &is_dangerous);
1161 if (is_dangerous) {
1162 /* Don't try to exchange */
1163 worth[tech] = 0;
1164 }
1165 } else {
1166 worth[tech] = 0;
1167 }
1168 } else {
1169 if (research_invention_state(presearch2, tech) == TECH_KNOWN
1170 && research_invention_gettable(presearch1, tech,
1172 worth[tech] = compute_tech_sell_price(ait, player2, player1, tech,
1173 &is_dangerous);
1174 if (is_dangerous) {
1175 /* Don't try to exchange */
1176 worth[tech] = 0;
1177 }
1178 } else {
1179 worth[tech] = 0;
1180 }
1181 }
1183
1185 if (worth[tech] <= 0) {
1186 continue;
1187 }
1189 int diff;
1190
1191 if (worth[tech2] >= 0) {
1192 continue;
1193 }
1194 /* tech2 is given by player1, tech is given by player2 */
1195 diff = worth[tech] + worth[tech2];
1196 if ((diff > 0 && player1->economic.gold >= diff)
1197 || (diff < 0 && player2->economic.gold >= -diff)
1198 || diff == 0) {
1199 dai_diplomacy_suggest(player1, player2, CLAUSE_ADVANCE, FALSE, tech2);
1200 dai_diplomacy_suggest(player1, player2, CLAUSE_ADVANCE, TRUE, tech);
1201 if (diff > 0) {
1202 dai_diplomacy_suggest(player1, player2, CLAUSE_GOLD, FALSE, diff);
1203 } else if (diff < 0) {
1204 dai_diplomacy_suggest(player1, player2, CLAUSE_GOLD, TRUE, -diff);
1205 }
1206 return;
1207 }
1210}
1211
1212/******************************************************************/
1215static void clear_old_treaty(struct player *pplayer, struct player *aplayer)
1216{
1217 struct Treaty *old_treaty = find_treaty(pplayer, aplayer);
1218
1219 if (old_treaty != NULL) {
1220 /* Remove existing clauses */
1221 clause_list_iterate(old_treaty->clauses, pclause) {
1223 player_number(pplayer),
1224 player_number(pclause->from),
1225 pclause->type, pclause->value);
1226 free(pclause);
1228 clause_list_destroy(old_treaty->clauses);
1229 old_treaty->clauses = clause_list_new();
1230 }
1231}
1232
1233/******************************************************************/
1236static void dai_share(struct ai_type *ait, struct player *pplayer,
1237 struct player *aplayer)
1238{
1239 struct research *presearch = research_get(pplayer);
1240 struct research *aresearch = research_get(aplayer);
1241 bool gives_vision;
1242
1243 clear_old_treaty(pplayer, aplayer);
1244
1245 /* Only share techs with team mates */
1246 if (presearch != aresearch
1247 && players_on_same_team(pplayer, aplayer)) {
1249 if (research_invention_state(presearch, idx) != TECH_KNOWN
1250 && research_invention_state(aresearch, idx) == TECH_KNOWN
1251 && research_invention_gettable(presearch, idx,
1253 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_ADVANCE, TRUE, idx);
1254 } else if (research_invention_state(presearch, idx) == TECH_KNOWN
1255 && research_invention_state(aresearch, idx) != TECH_KNOWN
1256 && research_invention_gettable(aresearch, idx,
1258 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_ADVANCE, FALSE, idx);
1259 }
1261 }
1262
1263 /* Only give shared vision if safe. Only ask for shared vision if fair. */
1264 gives_vision = gives_shared_vision(pplayer, aplayer);
1265 if (!gives_vision
1266 && shared_vision_is_safe(pplayer, aplayer)) {
1267 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_VISION, FALSE, 0);
1268 gives_vision = TRUE;
1269 }
1270 if (gives_vision
1271 && !gives_shared_vision(aplayer, pplayer)
1272 && (is_human(aplayer)
1273 || shared_vision_is_safe(aplayer, pplayer))) {
1274 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_VISION, TRUE, 0);
1275 }
1276
1277 if (!player_has_embassy(pplayer, aplayer)) {
1278 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_EMBASSY, TRUE, 0);
1279 }
1280 if (!player_has_embassy(aplayer, pplayer)) {
1281 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_EMBASSY, FALSE, 0);
1282 }
1283
1284 if (!has_handicap(pplayer, H_DIPLOMACY) || is_human(aplayer)) {
1285 suggest_tech_exchange(ait, pplayer, aplayer);
1286 }
1287}
1288
1289/******************************************************************/
1294static void dai_go_to_war(struct ai_type *ait, struct player *pplayer,
1295 struct player *target, enum war_reason reason)
1296{
1297 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, target);
1298
1299 fc_assert_ret(pplayer != target);
1300 fc_assert_ret(target->is_alive);
1301
1302 switch (reason) {
1303 case DAI_WR_SPACE:
1304 dai_diplo_notify(target, _("*%s (AI)* Space will never be yours."),
1305 player_name(pplayer));
1306 adip->countdown = -10;
1307 break;
1308 case DAI_WR_BEHAVIOUR:
1309 dai_diplo_notify(target,
1310 _("*%s (AI)* I have tolerated your vicious antics "
1311 "long enough! To war!"),
1312 player_name(pplayer));
1313 adip->countdown = -20;
1314 break;
1315 case DAI_WR_NONE:
1316 dai_diplo_notify(target, _("*%s (AI)* Peace in ... some other time."),
1317 player_name(pplayer));
1318 adip->countdown = -10;
1319 break;
1320 case DAI_WR_HATRED:
1321 dai_diplo_notify(target,
1322 _("*%s (AI)* Finally I get around to you! Did "
1323 "you really think you could get away with your crimes?"),
1324 player_name(pplayer));
1325 adip->countdown = -20;
1326 break;
1327 case DAI_WR_EXCUSE:
1328 dai_diplo_notify(target,
1329 _("*%s (AI)* Your covert hostilities brought "
1330 "this war upon you!"),
1331 player_name(pplayer));
1332 adip->countdown = -20;
1333 break;
1334 case DAI_WR_ALLIANCE:
1335 if (adip->at_war_with_ally) {
1336 dai_diplo_notify(target,
1337 _("*%s (AI)* Your aggression against %s was "
1338 "your last mistake!"),
1339 player_name(pplayer),
1341 adip->countdown = -3;
1342 } else {
1343 /* Ooops! */
1344 DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "Wanted to declare war "
1345 "for their war against an ally, but can no longer find "
1346 "this ally! War declaration aborted.");
1347 adip->countdown = -1;
1348 return;
1349 }
1350 break;
1351 }
1352
1353 fc_assert_ret(adip->countdown < 0);
1354
1355 if (gives_shared_vision(pplayer, target)) {
1356 remove_shared_vision(pplayer, target);
1357 }
1358
1359 /* Check for Senate obstruction. If so, dissolve it. */
1360 if (pplayer_can_cancel_treaty(pplayer, target) == DIPL_SENATE_BLOCKING) {
1361 struct government *real_gov = pplayer->government;
1362
1364
1365 if (pplayer_can_cancel_treaty(pplayer, target) == DIPL_OK) {
1366 /* It seems that revolution would help. */
1367 pplayer->government = real_gov;
1370 } else {
1371 /* There would be Senate even during revolution. Better not to revolt for nothing */
1372 pplayer->government = real_gov;
1373 adip->countdown = -1; /* War declaration aborted */
1374
1375 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target,
1376 "Not revolting, as there would be Senate regardless.");
1377
1378 return;
1379 }
1380 }
1381
1382 /* This will take us straight to war. */
1383 while (player_diplstate_get(pplayer, target)->type != DS_WAR) {
1384 if (pplayer_can_cancel_treaty(pplayer, target) != DIPL_OK) {
1385 DIPLO_LOG(ait, LOG_ERROR, pplayer, target,
1386 "Wanted to cancel treaty but was unable to.");
1387 adip->countdown = -1; /* War declaration aborted */
1388
1389 return;
1390 }
1391 handle_diplomacy_cancel_pact(pplayer, player_number(target), clause_type_invalid());
1392 }
1393
1394 /* Throw a tantrum */
1395 if (pplayer->ai_common.love[player_index(target)] > 0) {
1396 pplayer->ai_common.love[player_index(target)] = -1;
1397 }
1398 pplayer->ai_common.love[player_index(target)] -= MAX_AI_LOVE / 8;
1399
1400 fc_assert(!gives_shared_vision(pplayer, target));
1401 DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "war declared");
1402}
1403
1404/******************************************************************/
1416static void war_countdown(struct ai_type *ait, struct player *pplayer,
1417 struct player *target,
1418 int countdown, enum war_reason reason)
1419{
1420 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, target);
1421
1422 DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "countdown to war in %d", countdown);
1423
1424 /* Otherwise we're resetting an existing countdown, which is very bad */
1425 fc_assert_ret(adip->countdown == -1);
1426
1427 adip->countdown = countdown;
1428 adip->war_reason = reason;
1429
1430 players_iterate_alive(ally) {
1431 if (!pplayers_allied(pplayer, ally)
1432 || ally == target
1433 || NEVER_MET(pplayer, ally)) {
1434 continue;
1435 }
1436
1437 switch (reason) {
1438 case DAI_WR_SPACE:
1439 dai_diplo_notify(ally,
1440 PL_("*%s (AI)* We will be launching an all-out war "
1441 "against %s in %d turn to stop the spaceship "
1442 "launch.",
1443 "*%s (AI)* We will be launching an all-out war "
1444 "against %s in %d turns to stop the spaceship "
1445 "launch.",
1446 countdown),
1447 player_name(pplayer),
1448 player_name(target),
1449 countdown);
1450 dai_diplo_notify(ally,
1451 _("*%s (AI)* Your aid in this matter will be expected. "
1452 "Long live our glorious alliance!"),
1453 player_name(pplayer));
1454 break;
1455 case DAI_WR_BEHAVIOUR:
1456 case DAI_WR_EXCUSE:
1457 dai_diplo_notify(ally,
1458 PL_("*%s (AI)* %s has grossly violated their treaties "
1459 "with us for own gain. We will answer in force in "
1460 "%d turn and expect you to honor your alliance "
1461 "with us and do likewise!",
1462 "*%s (AI)* %s has grossly violated their treaties "
1463 "with us for own gain. We will answer in force in "
1464 "%d turns and expect you to honor your alliance "
1465 "with us and do likewise!", countdown),
1466 player_name(pplayer),
1467 player_name(target),
1468 countdown);
1469 break;
1470 case DAI_WR_NONE:
1471 dai_diplo_notify(ally,
1472 PL_("*%s (AI)* We intend to pillage and plunder the rich "
1473 "civilization of %s. We declare war in %d turn.",
1474 "*%s (AI)* We intend to pillage and plunder the rich "
1475 "civilization of %s. We declare war in %d turns.",
1476 countdown),
1477 player_name(pplayer),
1478 player_name(target),
1479 countdown);
1480 dai_diplo_notify(ally,
1481 _("*%s (AI)* If you want a piece of the loot, feel "
1482 "free to join in the action!"),
1483 player_name(pplayer));
1484 break;
1485 case DAI_WR_HATRED:
1486 dai_diplo_notify(ally,
1487 PL_("*%s (AI)* We have had it with %s. Let us tear this "
1488 "pathetic civilization apart. We declare war in "
1489 "%d turn.",
1490 "*%s (AI)* We have had it with %s. Let us tear this "
1491 "pathetic civilization apart. We declare war in "
1492 "%d turns.",
1493 countdown),
1494 player_name(pplayer),
1495 player_name(target),
1496 countdown);
1497 dai_diplo_notify(ally,
1498 _("*%s (AI)* As our glorious allies, we expect your "
1499 "help in this war."),
1500 player_name(pplayer));
1501 break;
1502 case DAI_WR_ALLIANCE:
1503 if (WAR(ally, target)) {
1504 dai_diplo_notify(ally,
1505 PL_("*%s (AI)* We will honor our alliance and declare "
1506 "war on %s in %d turn. Hold on - we are coming!",
1507 "*%s (AI)* We will honor our alliance and declare "
1508 "war on %s in %d turns. Hold on - we are coming!",
1509 countdown),
1510 player_name(pplayer),
1511 player_name(target),
1512 countdown);
1513 } else if (adip->at_war_with_ally) {
1514 dai_diplo_notify(ally,
1515 PL_("*%s (AI)* We will honor our alliance with %s and "
1516 "declare war on %s in %d turns. We expect you to "
1517 "do likewise.",
1518 "*%s (AI)* We will honor our alliance with %s and "
1519 "declare war on %s in %d turns. We expect you to "
1520 "do likewise.",
1521 countdown),
1522 player_name(pplayer),
1524 player_name(target),
1525 countdown);
1526 } else {
1527 fc_assert(FALSE); /* Huh? */
1528 }
1529 break;
1530 }
1532}
1533
1534/******************************************************************/
1540void dai_diplomacy_actions(struct ai_type *ait, struct player *pplayer)
1541{
1542 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
1543 bool need_targets = TRUE;
1544 struct player *target = NULL;
1545 int most_hatred = MAX_AI_LOVE;
1546 int war_threshold;
1547 int aggr;
1548 float aggr_sr;
1549 float max_sr;
1550
1551 fc_assert_ret(is_ai(pplayer));
1552
1553 if (!pplayer->is_alive) {
1554 return;
1555 }
1556
1557 if (get_player_bonus(pplayer, EFT_NO_DIPLOMACY) > 0) {
1558 /* Diplomacy disabled for this player */
1559 return;
1560 }
1561
1562 /*** If we are greviously insulted, go to war immediately. ***/
1563
1564 players_iterate(aplayer) {
1565 if (pplayer->ai_common.love[player_index(aplayer)] < 0
1566 && player_diplstate_get(pplayer, aplayer)->has_reason_to_cancel >= 2
1567 && dai_diplomacy_get(ait, pplayer, aplayer)->countdown == -1) {
1568 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "Plans war in revenge");
1569 war_countdown(ait, pplayer, aplayer, map_size_checked(),
1570 DAI_WR_BEHAVIOUR);
1571 }
1573
1574 /*** Stop other players from winning by space race ***/
1575
1576 if (ai->diplomacy.strategy != WIN_SPACE) {
1577 struct adv_data *adv = adv_data_get(pplayer, NULL);
1578
1579 players_iterate_alive(aplayer) {
1580 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1581 struct player_spaceship *ship = &aplayer->spaceship;
1582
1583 if (aplayer == pplayer
1584 || adip->countdown >= 0 /* already counting down to war */
1585 || ship->state == SSHIP_NONE
1586 || players_on_same_team(pplayer, aplayer)
1587 || pplayers_at_war(pplayer, aplayer)) {
1588 continue;
1589 }
1590
1591 /* A spaceship victory is always one single player's or team's victory */
1592 if (aplayer->spaceship.state == SSHIP_LAUNCHED
1593 && adv->dipl.spacerace_leader == aplayer
1594 && pplayers_allied(pplayer, aplayer)) {
1595 dai_diplo_notify(aplayer,
1596 _("*%s (AI)* Your attempt to conquer space for "
1597 "yourself alone betrays your true intentions, and I "
1598 "will have no more of our alliance!"),
1599 player_name(pplayer));
1601 CLAUSE_ALLIANCE);
1602 if (gives_shared_vision(pplayer, aplayer)) {
1603 remove_shared_vision(pplayer, aplayer);
1604 }
1605 /* Never forgive this */
1606 pplayer->ai_common.love[player_index(aplayer)] = -MAX_AI_LOVE;
1607 } else if (ship->state == SSHIP_STARTED
1608 && adip->warned_about_space == 0) {
1609 pplayer->ai_common.love[player_index(aplayer)] -= MAX_AI_LOVE / 10;
1610 adip->warned_about_space = 10 + fc_rand(6);
1611 dai_diplo_notify(aplayer,
1612 _("*%s (AI)* Your attempt to unilaterally "
1613 "dominate outer space is highly offensive."),
1614 player_name(pplayer));
1615 dai_diplo_notify(aplayer,
1616 _("*%s (AI)* If you do not stop constructing your "
1617 "spaceship, I may be forced to take action!"),
1618 player_name(pplayer));
1619 }
1620 if (aplayer->spaceship.state == SSHIP_LAUNCHED
1621 && aplayer == adv->dipl.spacerace_leader) {
1622 /* This means war!!! */
1623 pplayer->ai_common.love[player_index(aplayer)] -= MAX_AI_LOVE / 2;
1624 DIPLO_LOG(ait, LOG_DIPL, pplayer, aplayer, "plans war due to spaceship");
1625 war_countdown(ait, pplayer, aplayer, 4 + map_size_checked(),
1626 DAI_WR_SPACE);
1627 }
1629 }
1630
1631 /*** Declare war against somebody if we are out of targets ***/
1632
1633 players_iterate_alive(aplayer) {
1634 int turns; /* turns since contact */
1635
1636 if (NEVER_MET(pplayer, aplayer)) {
1637 continue;
1638 }
1639 turns = game.info.turn;
1640 turns -= player_diplstate_get(pplayer, aplayer)->first_contact_turn;
1641 if (WAR(pplayer, aplayer)) {
1642 need_targets = FALSE;
1643 } else if (pplayer->ai_common.love[player_index(aplayer)] < most_hatred
1644 && turns > TURNS_BEFORE_TARGET) {
1645 most_hatred = pplayer->ai_common.love[player_index(aplayer)];
1646 target = aplayer;
1647 }
1649
1650 aggr = ai_trait_get_value(TRAIT_AGGRESSIVE, pplayer);
1651 max_sr = TRAIT_MAX_VALUE_SR;
1652 aggr_sr = sqrt(aggr);
1653
1654 war_threshold = (MAX_AI_LOVE * (0.70 + aggr_sr / max_sr / 2.0)) - MAX_AI_LOVE;
1655
1656 if (need_targets && target && most_hatred < war_threshold
1657 && dai_diplomacy_get(ait, pplayer, target)->countdown == -1) {
1658 enum war_reason war_reason;
1659
1660 if (pplayers_allied(pplayer, target)) {
1661 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target, "Plans war against an ally!");
1662 }
1663 if (player_diplstate_get(pplayer, target)->has_reason_to_cancel > 0) {
1664 /* We have good reason */
1665 war_reason = DAI_WR_EXCUSE;
1666 } else if (pplayer->ai_common.love[player_index(target)] < 0) {
1667 /* We have a reason of sorts from way back, maybe? */
1668 war_reason = DAI_WR_HATRED;
1669 } else {
1670 /* We have no legimitate reason... So what? */
1671 war_reason = DAI_WR_NONE;
1672 }
1673 DIPLO_LOG(ait, LOG_DEBUG, pplayer, target, "plans war for spoils");
1674 war_countdown(ait, pplayer, target, 4 + map_size_checked(), war_reason);
1675 }
1676
1677 /*** Declare war - against enemies of allies ***/
1678
1679 players_iterate_alive(aplayer) {
1680 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1681
1682 if (adip->at_war_with_ally
1683 && adip->countdown == -1
1684 && !adip->is_allied_with_ally
1685 && !pplayers_at_war(pplayer, aplayer)
1686 && (player_diplstate_get(pplayer, aplayer)->type != DS_CEASEFIRE
1687 || fc_rand(5) < 1)) {
1688 DIPLO_LOG(ait, LOG_DEBUG, pplayer, aplayer, "plans war to help ally %s",
1690 war_countdown(ait, pplayer, aplayer, 2 + map_size_checked(),
1691 DAI_WR_ALLIANCE);
1692 }
1694
1695 /*** Actually declare war (when we have moved units into position) ***/
1696
1697 players_iterate(aplayer) {
1698 if (!players_on_same_team(pplayer, aplayer)) {
1699 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1700
1701 if (!aplayer->is_alive) {
1702 adip->countdown = -1;
1703 continue;
1704 }
1705 if (adip->countdown > 0) {
1706 adip->countdown--;
1707 } else if (adip->countdown == 0) {
1708 if (!WAR(pplayer, aplayer)) {
1709 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer, "Declaring war!");
1710 dai_go_to_war(ait, pplayer, aplayer, adip->war_reason);
1711 }
1712 } else if (adip->countdown < -1) {
1713 /* Negative countdown less than -1 is war stubbornness */
1714 adip->countdown++;
1715 }
1716 }
1718
1719 /*** Try to make peace with everyone we love ***/
1720
1721 players_iterate_alive(aplayer) {
1722 if (get_player_bonus(aplayer, EFT_NO_DIPLOMACY) <= 0
1723 && diplomacy_possible(pplayer, aplayer)) {
1724 enum diplstate_type ds = player_diplstate_get(pplayer, aplayer)->type;
1725 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
1726 struct Clause clause;
1727
1728 /* Meaningless values, but rather not have them unset. */
1729 clause.from = pplayer;
1730 clause.value = 0;
1731
1732 /* Remove shared vision if we are not allied or it is no longer safe. */
1733 if (gives_shared_vision(pplayer, aplayer)) {
1734 if (!pplayers_allied(pplayer, aplayer)) {
1735 remove_shared_vision(pplayer, aplayer);
1736 } else if (!players_on_same_team(pplayer, aplayer)
1737 && !shared_vision_is_safe(pplayer, aplayer)) {
1738 dai_diplo_notify(aplayer,
1739 _("*%s (AI)* Sorry, sharing vision with you "
1740 "is no longer safe."),
1741 player_name(pplayer));
1742 remove_shared_vision(pplayer, aplayer);
1743 }
1744 }
1745
1746 /* No peace to enemies of our allies... or pointless peace. */
1747 if (is_barbarian(aplayer)
1748 || aplayer == pplayer
1749 || aplayer == target /* no mercy */
1750 || adip->countdown >= 0
1751 || !could_meet_with_player(pplayer, aplayer)) {
1752 continue;
1753 }
1754
1755 /* Spam control */
1756 adip->asked_about_peace = MAX(adip->asked_about_peace - 1, 0);
1757 adip->asked_about_alliance = MAX(adip->asked_about_alliance - 1, 0);
1758 adip->asked_about_ceasefire = MAX(adip->asked_about_ceasefire - 1, 0);
1759 adip->warned_about_space = MAX(adip->warned_about_space - 1, 0);
1760 adip->spam = MAX(adip->spam - 1, 0);
1761 if (adip->spam > 0 && is_ai(aplayer)) {
1762 /* Don't spam */
1763 continue;
1764 }
1765
1766 /* Canvass support from existing friends for our war, and try to
1767 * make friends with enemies. Then we wait some turns until next time
1768 * we spam them with our gibbering chatter. */
1769 if (adip->spam <= 0) {
1770 if (!pplayers_allied(pplayer, aplayer)) {
1771 adip->spam = fc_rand(4) + 3; /* Bugger allies often. */
1772 } else {
1773 adip->spam = fc_rand(8) + 6; /* Others are less important. */
1774 }
1775 }
1776
1777 switch (ds) {
1778 case DS_TEAM:
1779 dai_share(ait, pplayer, aplayer);
1780 break;
1781 case DS_ALLIANCE:
1782 /* See if our allies are diligently declaring war on our enemies... */
1783 if (adip->at_war_with_ally) {
1784 break;
1785 }
1786 target = NULL;
1787 players_iterate(eplayer) {
1788 if (WAR(pplayer, eplayer)
1789 && !pplayers_at_war(aplayer, eplayer)) {
1790 target = eplayer;
1791 break;
1792 }
1794
1795 if ((players_on_same_team(pplayer, aplayer)
1796 || pplayer->ai_common.love[player_index(aplayer)] > MAX_AI_LOVE / 2)) {
1797 /* Share techs only with team mates and allies we really like. */
1798 dai_share(ait, pplayer, aplayer);
1799 }
1800 if (!target || !target->is_alive) {
1801 adip->ally_patience = 0;
1802 break; /* No need to nag our ally */
1803 }
1804
1805 if (adip->spam <= 0) {
1806 /* Count down patience toward AI player (one that can have spam > 0)
1807 * at the same speed as toward human players. */
1808 if (adip->ally_patience == 0) {
1809 dai_diplo_notify(aplayer,
1810 _("*%s (AI)* Greetings our most trustworthy "
1811 "ally. We call upon you to destroy our enemy, %s."),
1812 player_name(pplayer),
1813 player_name(target));
1814 adip->ally_patience--;
1815 } else if (adip->ally_patience == -1) {
1816 if (fc_rand(5) == 1) {
1817 dai_diplo_notify(aplayer,
1818 _("*%s (AI)* Greetings ally, I see you have not yet "
1819 "made war with our enemy, %s. Why do I need to remind "
1820 "you of your promises?"),
1821 player_name(pplayer),
1822 player_name(target));
1823 adip->ally_patience--;
1824 }
1825 } else if (fc_rand(5) == 1
1826 && !players_on_same_team(pplayer, aplayer)) {
1827 dai_diplo_notify(aplayer,
1828 _("*%s (AI)* Dishonored one, we made a pact of "
1829 "alliance, and yet you remain at peace with our mortal "
1830 "enemy, %s! This is unacceptable; our alliance is no "
1831 "more!"),
1832 player_name(pplayer),
1833 player_name(target));
1834 DIPLO_LOG(ait, LOG_DIPL2, pplayer, aplayer,
1835 "breaking useless alliance");
1836 /* To peace */
1838 CLAUSE_ALLIANCE);
1839 pplayer->ai_common.love[player_index(aplayer)]
1840 = MIN(pplayer->ai_common.love[player_index(aplayer)], 0);
1841 if (gives_shared_vision(pplayer, aplayer)) {
1842 remove_shared_vision(pplayer, aplayer);
1843 }
1844
1845 fc_assert(!gives_shared_vision(pplayer, aplayer));
1846 }
1847 }
1848 break;
1849
1850 case DS_PEACE:
1851 clause.type = CLAUSE_ALLIANCE;
1852 if (adip->at_war_with_ally
1853 || (is_human(aplayer) && adip->asked_about_alliance > 0)
1854 || dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
1855 FALSE, DS_ALLIANCE) < 0) {
1856 break;
1857 }
1858 clear_old_treaty(pplayer, aplayer);
1859 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_ALLIANCE, FALSE, 0);
1860 adip->asked_about_alliance = is_human(aplayer) ? 13 : 0;
1861 dai_diplo_notify(aplayer,
1862 _("*%s (AI)* Greetings friend, may we suggest "
1863 "making a common cause and join in an alliance?"),
1864 player_name(pplayer));
1865 break;
1866
1867 case DS_CEASEFIRE:
1868 clause.type = CLAUSE_PEACE;
1869 if (adip->at_war_with_ally
1870 || (is_human(aplayer) && adip->asked_about_peace > 0)
1871 || dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
1872 FALSE, DS_PEACE) < 0) {
1873 break;
1874 }
1875 clear_old_treaty(pplayer, aplayer);
1876 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_PEACE, FALSE, 0);
1877 adip->asked_about_peace = is_human(aplayer) ? 12 : 0;
1878 dai_diplo_notify(aplayer,
1879 _("*%s (AI)* Greetings neighbor, may we suggest "
1880 "more peaceful relations?"),
1881 player_name(pplayer));
1882 break;
1883
1884 case DS_NO_CONTACT: /* but we do have embassy! weird. */
1885 case DS_WAR:
1886 clause.type = CLAUSE_CEASEFIRE;
1887 if ((is_human(aplayer) && adip->asked_about_ceasefire > 0)
1888 || dai_goldequiv_clause(ait, pplayer, aplayer, &clause,
1889 FALSE, DS_CEASEFIRE) < 0) {
1890 break; /* Fight until the end! */
1891 }
1892 clear_old_treaty(pplayer, aplayer);
1893 dai_diplomacy_suggest(pplayer, aplayer, CLAUSE_CEASEFIRE, FALSE, 0);
1894 adip->asked_about_ceasefire = is_human(aplayer) ? 9 : 0;
1895 dai_diplo_notify(aplayer,
1896 _("*%s (AI)* We grow weary of this constant "
1897 "bloodshed. May we suggest a cessation of hostilities?"),
1898 player_name(pplayer));
1899 break;
1900
1901 case DS_ARMISTICE:
1902 break;
1903 default:
1904 fc_assert_msg(FALSE, "Unknown pact type %d.", ds);
1905 break;
1906 }
1907 }
1909}
1910
1911/******************************************************************/
1915bool dai_on_war_footing(struct ai_type *ait, struct player *pplayer)
1916{
1917 players_iterate(plr) {
1918 if (dai_diplomacy_get(ait, pplayer, plr)->countdown >= 0) {
1919 return TRUE;
1920 }
1922
1923 return FALSE;
1924}
1925
1926/******************************************************************/
1929/* AI attitude call-backs */
1931 enum casus_belli_range scope,
1932 const struct action *paction,
1933 struct player *receiver,
1934 struct player *violator, struct player *victim)
1935{
1936 if (!is_ai(receiver) || violator == receiver) {
1937 return;
1938 }
1939
1940 /* Can only handle victim only and international incidents. */
1941 fc_assert_ret(scope == CBR_VICTIM_ONLY
1942 || scope == CBR_INTERNATIONAL_OUTRAGE);
1943
1944 switch (type) {
1945 case INCIDENT_ACTION:
1946 /* Feel free the change how the action results are grouped and how bad
1947 * the ai considers each group. */
1948 switch (paction->result) {
1949 case ACTRES_SPY_NUKE:
1950 case ACTRES_NUKE:
1951 case ACTRES_NUKE_UNITS:
1952 if (receiver == victim) {
1953 /* Tell the victim */
1954 dai_incident_nuclear(receiver, violator, victim);
1955 } else if (violator == victim) {
1956 dai_incident_nuclear_self(receiver, violator, victim);
1957 } else {
1958 dai_incident_nuclear_not_target(receiver, violator, victim);
1959 }
1960 break;
1961 case ACTRES_ESTABLISH_EMBASSY:
1962 case ACTRES_SPY_INVESTIGATE_CITY:
1963 /* Snoping */
1964 dai_incident_simple(receiver, violator, victim, scope, 2);
1965 break;
1966 case ACTRES_SPY_STEAL_GOLD:
1967 case ACTRES_SPY_STEAL_TECH:
1968 case ACTRES_SPY_TARGETED_STEAL_TECH:
1969 case ACTRES_STEAL_MAPS:
1970 /* Theft */
1971 dai_incident_simple(receiver, violator, victim, scope, 5);
1972 break;
1973 case ACTRES_EXPEL_UNIT:
1974 /* Unit position loss */
1975 dai_incident_simple(receiver, violator, victim, scope, 1);
1976 break;
1977 case ACTRES_SPY_SABOTAGE_UNIT:
1978 /* Unit weakening */
1979 dai_incident_simple(receiver, violator, victim, scope, 3);
1980 break;
1981 case ACTRES_SPY_BRIBE_UNIT:
1982 case ACTRES_CAPTURE_UNITS:
1983 case ACTRES_BOMBARD:
1984 case ACTRES_ATTACK:
1985 case ACTRES_SPY_ATTACK:
1986 /* Unit loss */
1987 dai_incident_simple(receiver, violator, victim, scope, 5);
1988 break;
1989 case ACTRES_SPY_INCITE_CITY:
1990 case ACTRES_DESTROY_CITY:
1991 case ACTRES_CONQUER_CITY:
1992 /* City loss */
1993 dai_incident_simple(receiver, violator, victim, scope, 10);
1994 break;
1995 case ACTRES_SPY_SABOTAGE_CITY:
1996 case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
1997 case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
1998 case ACTRES_STRIKE_BUILDING:
1999 case ACTRES_STRIKE_PRODUCTION:
2000 /* Building loss */
2001 dai_incident_simple(receiver, violator, victim, scope, 5);
2002 break;
2003 case ACTRES_SPY_POISON:
2004 case ACTRES_SPY_SPREAD_PLAGUE:
2005 /* Population loss */
2006 dai_incident_simple(receiver, violator, victim, scope, 5);
2007 break;
2008 case ACTRES_FOUND_CITY:
2009 /* Terrain loss */
2010 dai_incident_simple(receiver, violator, victim, scope, 4);
2011 break;
2012 case ACTRES_CONQUER_EXTRAS:
2013 case ACTRES_PILLAGE:
2014 /* Extra loss */
2015 dai_incident_simple(receiver, violator, victim, scope, 2);
2016 break;
2017 case ACTRES_UNIT_MOVE:
2018 case ACTRES_TRADE_ROUTE:
2019 case ACTRES_MARKETPLACE:
2020 case ACTRES_HELP_WONDER:
2021 case ACTRES_JOIN_CITY:
2022 case ACTRES_DISBAND_UNIT_RECOVER:
2023 case ACTRES_DISBAND_UNIT:
2024 case ACTRES_HOME_CITY:
2025 case ACTRES_HOMELESS:
2026 case ACTRES_UPGRADE_UNIT:
2027 case ACTRES_PARADROP:
2028 case ACTRES_PARADROP_CONQUER: /* TODO: bigger incident */
2029 case ACTRES_AIRLIFT:
2030 case ACTRES_HEAL_UNIT:
2031 case ACTRES_TRANSFORM_TERRAIN:
2032 case ACTRES_CULTIVATE:
2033 case ACTRES_PLANT:
2034 case ACTRES_CLEAN_POLLUTION:
2035 case ACTRES_CLEAN_FALLOUT:
2036 case ACTRES_FORTIFY:
2037 case ACTRES_ROAD:
2038 case ACTRES_CONVERT:
2039 case ACTRES_BASE:
2040 case ACTRES_MINE:
2041 case ACTRES_IRRIGATE:
2042 case ACTRES_TRANSPORT_ALIGHT:
2043 case ACTRES_TRANSPORT_UNLOAD:
2044 case ACTRES_TRANSPORT_DISEMBARK:
2045 case ACTRES_TRANSPORT_BOARD:
2046 case ACTRES_TRANSPORT_EMBARK:
2047 case ACTRES_HUT_ENTER:
2048 case ACTRES_HUT_FRIGHTEN:
2049 case ACTRES_NONE:
2050 /* Various */
2051 dai_incident_simple(receiver, violator, victim, scope, 1);
2052 break;
2053 }
2054 break;
2055 case INCIDENT_WAR:
2056 if (receiver == victim) {
2057 dai_incident_war(violator, victim);
2058 }
2059 break;
2060 case INCIDENT_LAST:
2061 /* Assert that always fails, but with meaningful message */
2063 break;
2064 }
2065}
2066
2067/******************************************************************/
2070static void dai_incident_nuclear(struct player *receiver,
2071 const struct player *violator,
2072 const struct player *victim)
2073{
2074 fc_assert_ret(receiver == victim);
2075
2076 if (violator == victim) {
2077 return;
2078 }
2079
2080 receiver->ai_common.love[player_index(violator)] -= 3 * MAX_AI_LOVE / 10;
2081}
2082
2083/******************************************************************/
2086static void dai_incident_nuclear_not_target(struct player *receiver,
2087 const struct player *violator,
2088 const struct player *victim)
2089{
2090 fc_assert_ret(receiver != victim);
2091
2092 receiver->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 10;
2093}
2094
2095/******************************************************************/
2098static void dai_incident_nuclear_self(struct player *receiver,
2099 const struct player *violator,
2100 const struct player *victim)
2101{
2102 fc_assert_ret(receiver != victim);
2103 fc_assert_ret(violator == victim);
2104
2105 receiver->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 20;
2106}
2107
2108/**********************************************************************/
2120static void dai_incident_simple(struct player *receiver,
2121 const struct player *violator,
2122 const struct player *victim,
2123 enum casus_belli_range scope,
2124 int how_bad)
2125{
2126 int displeasure = how_bad * MAX_AI_LOVE;
2127 if (victim == receiver) {
2128 if (scope == CBR_INTERNATIONAL_OUTRAGE) {
2129 /* The ruleset finds this bad enough to cause International Outrage.
2130 * Trust the ruleset author. Double the displeasure. */
2131 displeasure = displeasure * 2;
2132 }
2133 receiver->ai_common.love[player_index(violator)] -= displeasure / 35;
2134 } else if (violator == victim) {
2135 receiver->ai_common.love[player_index(violator)] -= displeasure / 1000;
2136 } else {
2137 receiver->ai_common.love[player_index(violator)] -= displeasure / 500;
2138 }
2139}
2140
2141/******************************************************************/
2149static void dai_incident_war(struct player *violator, struct player *victim)
2150{
2151 players_iterate(pplayer) {
2152 if (!is_ai(pplayer)) {
2153 continue;
2154 }
2155
2156 if (pplayer != violator) {
2157 /* Dislike backstabbing bastards */
2158 pplayer->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 30;
2159 if (player_diplstate_get(violator, victim)->max_state == DS_PEACE) {
2160 /* Extra penalty if they once had a peace treaty */
2161 pplayer->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 30;
2162 } else if (player_diplstate_get(violator, victim)->max_state
2163 == DS_ALLIANCE) {
2164 /* Extra penalty if they once had an alliance */
2165 pplayer->ai_common.love[player_index(violator)] -= MAX_AI_LOVE / 10;
2166 }
2167 if (victim == pplayer) {
2168 pplayer->ai_common.love[player_index(violator)] =
2169 MIN(pplayer->ai_common.love[player_index(violator)] - MAX_AI_LOVE / 3, -1);
2170 /* Scream for help!! */
2171 players_iterate_alive(ally) {
2172 if (!pplayers_allied(pplayer, ally)) {
2173 continue;
2174 }
2175 dai_diplo_notify(ally,
2176 _("*%s (AI)* We have been savagely attacked by "
2177 "%s, and we need your help! Honor our glorious "
2178 "alliance and your name will never be forgotten!"),
2179 player_name(victim),
2180 player_name(violator));
2182 }
2183 }
2185}
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(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:1548
const char * city_name_get(const struct city *pcity)
Definition city.c:1111
struct city * city_list_find_number(struct city_list *This, int id)
Definition city.c:1648
#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:801
#define city_built_iterate_end
Definition city.h:807
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
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:646
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:382
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
struct unit_type::@87 adv
#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:2625
#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:2967