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