Freeciv21
Develop your civilization from humble roots to a global empire
diplhand.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // utility
15 #include "bitvector.h"
16 #include "fcintl.h"
17 #include "log.h"
18 
19 // common
20 #include "ai.h"
21 #include "diptreaty.h"
22 #include "events.h"
23 #include "game.h"
24 #include "packets.h"
25 #include "player.h"
26 #include "research.h"
27 /* common/scriptcore */
28 #include "luascript_types.h"
29 
30 // server
31 #include "citytools.h"
32 #include "cityturn.h"
33 #include "maphand.h"
34 #include "notify.h"
35 #include "plrhand.h"
36 #include "techtools.h"
37 #include "unittools.h"
38 
39 /* server/scripting */
40 #include "script_server.h"
41 
42 #include "diplhand.h"
43 
44 static struct treaty_list *treaties = nullptr;
45 
49 static void call_treaty_evaluate(struct player *pplayer,
50  struct player *aplayer,
51  struct Treaty *ptreaty)
52 {
53  if (is_ai(pplayer)) {
54  CALL_PLR_AI_FUNC(treaty_evaluate, pplayer, pplayer, aplayer, ptreaty);
55  }
56 }
57 
61 static void call_treaty_accepted(struct player *pplayer,
62  struct player *aplayer,
63  struct Treaty *ptreaty)
64 {
65  if (is_ai(pplayer)) {
66  CALL_PLR_AI_FUNC(treaty_accepted, pplayer, pplayer, aplayer, ptreaty);
67  }
68 }
69 
73 void diplhand_init() { treaties = treaty_list_new(); }
74 
79 {
80  free_treaties();
81 
82  treaty_list_destroy(treaties);
83  treaties = nullptr;
84 }
85 
90 {
91  // Free memory allocated for treaties
93  {
94  clear_treaty(pt);
95  delete pt;
96  }
98 
99  treaty_list_clear(treaties);
100 }
101 
105 struct Treaty *find_treaty(struct player *plr0, struct player *plr1)
106 {
107  treaty_list_iterate(treaties, ptreaty)
108  {
109  if ((ptreaty->plr0 == plr0 && ptreaty->plr1 == plr1)
110  || (ptreaty->plr0 == plr1 && ptreaty->plr1 == plr0)) {
111  return ptreaty;
112  }
113  }
115 
116  return nullptr;
117 }
118 
122 static enum diplstate_type dst_closest(enum diplstate_type a,
123  enum diplstate_type b)
124 {
125  static int how_close[DS_LAST];
126  how_close[DS_NO_CONTACT] = 0;
127  how_close[DS_WAR] = 1;
128  how_close[DS_CEASEFIRE] = 2;
129  how_close[DS_ARMISTICE] = 3;
130  how_close[DS_PEACE] = 4;
131  how_close[DS_ALLIANCE] = 5;
132  how_close[DS_TEAM] = 6;
133 
134  if (how_close[a] < how_close[b]) {
135  return b;
136  } else {
137  return a;
138  }
139 }
140 
147  int counterpart)
148 {
149  struct Treaty *ptreaty;
150  bool *player_accept, *other_accept;
151  enum dipl_reason diplcheck;
152  bool worker_refresh_required = false;
153  struct player *pother = player_by_number(counterpart);
154 
155  if (nullptr == pother || pplayer == pother) {
156  return;
157  }
158 
159  ptreaty = find_treaty(pplayer, pother);
160 
161  if (!ptreaty) {
162  return;
163  }
164 
165  if (ptreaty->plr0 == pplayer) {
166  player_accept = &ptreaty->accept0;
167  other_accept = &ptreaty->accept1;
168  } else {
169  player_accept = &ptreaty->accept1;
170  other_accept = &ptreaty->accept0;
171  }
172 
173  if (!*player_accept) { // Tries to accept.
174 
175  // Check that player who accepts can keep what (s)he promises.
176 
177  clause_list_iterate(ptreaty->clauses, pclause)
178  {
179  struct city *pcity = nullptr;
180 
181  if (pclause->from == pplayer) {
182  struct clause_info *info = clause_info_get(pclause->type);
183 
184  if (!are_reqs_active(pplayer, pother, nullptr, nullptr, nullptr,
185  nullptr, nullptr, nullptr, nullptr, nullptr,
186  &(info->giver_reqs), RPT_POSSIBLE)
187  || !are_reqs_active(pother, pplayer, nullptr, nullptr, nullptr,
188  nullptr, nullptr, nullptr, nullptr, nullptr,
189  &(info->receiver_reqs), RPT_POSSIBLE)) {
190  qCritical(
191  "Requirements of a clause between %s and %s not fullfilled",
192  player_name(pplayer), player_name(pother));
193  return;
194  }
195  }
196 
197  if (pclause->from == pplayer || is_pact_clause(pclause->type)) {
198  switch (pclause->type) {
199  case CLAUSE_EMBASSY:
200  if (player_has_real_embassy(pother, pplayer)) {
201  qCritical("%s tried to give embassy to %s, who already "
202  "has an embassy",
203  player_name(pplayer), player_name(pother));
204  return;
205  }
206  break;
207  case CLAUSE_ADVANCE:
209  research_get(pother), pclause->value,
210  game.info.tech_trade_allow_holes)) {
211  /* It is impossible to give a technology to a civilization that
212  * can not possess it (the client should enforce this). */
213  qCritical("Treaty: %s can't have tech %s",
215  advance_rule_name(advance_by_number(pclause->value)));
217  pplayer, nullptr, E_DIPLOMACY, ftc_server,
218  _("The %s can't accept %s."),
219  nation_plural_for_player(pother),
221  return;
222  }
223  if (research_invention_state(research_get(pplayer), pclause->value)
224  != TECH_KNOWN) {
225  qCritical("Nation %s try to give unknown tech %s to nation %s.",
227  advance_rule_name(advance_by_number(pclause->value)),
230  pplayer, nullptr, E_DIPLOMACY, ftc_server,
231  _("You don't have tech %s, you can't accept treaty."),
233  return;
234  }
235  break;
236  case CLAUSE_CITY:
237  pcity = game_city_by_number(pclause->value);
238  if (!pcity) { // Can't find out cityname any more.
239  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
240  _("City you are trying to give no longer exists, "
241  "you can't accept treaty."));
242  return;
243  }
244  if (city_owner(pcity) != pplayer) {
246  pplayer, nullptr, E_DIPLOMACY, ftc_server,
247  _("You are not owner of %s, you can't accept treaty."),
248  city_link(pcity));
249  return;
250  }
251  if (is_capital(pcity)) {
252  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
253  _("Your capital (%s) is requested, "
254  "you can't accept treaty."),
255  city_link(pcity));
256  return;
257  }
258  break;
259  case CLAUSE_CEASEFIRE:
260  diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_CEASEFIRE);
261  if (diplcheck != DIPL_OK) {
262  return;
263  }
264  break;
265  case CLAUSE_PEACE:
266  diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_PEACE);
267  if (diplcheck != DIPL_OK) {
268  return;
269  }
270  break;
271  case CLAUSE_ALLIANCE:
272  diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_ALLIANCE);
273  if (diplcheck == DIPL_ALLIANCE_PROBLEM_US) {
274  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
275  _("You cannot form an alliance because you are "
276  "at war with an ally of %s."),
277  player_name(pother));
278  } else if (diplcheck == DIPL_ALLIANCE_PROBLEM_THEM) {
279  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
280  _("You cannot form an alliance because %s is "
281  "at war with an ally of yours."),
282  player_name(pother));
283  }
284  if (diplcheck != DIPL_OK) {
285  return;
286  }
287  break;
288  case CLAUSE_GOLD:
289  if (pplayer->economic.gold < pclause->value) {
290  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
291  _("You don't have enough gold, "
292  "you can't accept treaty."));
293  return;
294  }
295  break;
296  default:; // nothing
297  }
298  }
299  }
301  }
302 
303  *player_accept = !*player_accept;
304 
305  dlsend_packet_diplomacy_accept_treaty(pplayer->connections,
306  player_number(pother),
307  *player_accept, *other_accept);
308  dlsend_packet_diplomacy_accept_treaty(pother->connections,
309  player_number(pplayer),
310  *other_accept, *player_accept);
311 
312  if (ptreaty->accept0 && ptreaty->accept1) {
313  int nclauses = clause_list_size(ptreaty->clauses);
314 
315  dlsend_packet_diplomacy_cancel_meeting(
316  pplayer->connections, player_number(pother), player_number(pplayer));
317  dlsend_packet_diplomacy_cancel_meeting(
318  pother->connections, player_number(pplayer), player_number(pplayer));
319 
320  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
321  PL_("A treaty containing %d clause was agreed upon.",
322  "A treaty containing %d clauses was agreed upon.",
323  nclauses),
324  nclauses);
325  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
326  PL_("A treaty containing %d clause was agreed upon.",
327  "A treaty containing %d clauses was agreed upon.",
328  nclauses),
329  nclauses);
330 
331  /* Check that one who accepted treaty earlier still have everything
332  (s)he promised to give. */
333 
334  clause_list_iterate(ptreaty->clauses, pclause)
335  {
336  struct city *pcity;
337 
338  if (pclause->from == pother) {
339  struct clause_info *info = clause_info_get(pclause->type);
340 
341  if (!are_reqs_active(pother, pplayer, nullptr, nullptr, nullptr,
342  nullptr, nullptr, nullptr, nullptr, nullptr,
343  &(info->giver_reqs), RPT_POSSIBLE)
344  || !are_reqs_active(pplayer, pother, nullptr, nullptr, nullptr,
345  nullptr, nullptr, nullptr, nullptr, nullptr,
346  &(info->receiver_reqs), RPT_POSSIBLE)) {
347  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
348  _("Clause requirements are no longer fulfilled. "
349  "Treaty with %s canceled!"),
350  nation_plural_for_player(pother));
351  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
352  _("Clause requirements are no longer fulfilled. "
353  "Treaty with %s canceled!"),
354  nation_plural_for_player(pplayer));
355  return;
356  }
357  }
358 
359  if (pclause->from == pother) {
360  switch (pclause->type) {
361  case CLAUSE_CITY:
362  pcity = game_city_by_number(pclause->value);
363  if (!pcity) { // Can't find out cityname any more.
364  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
365  _("One of the cities the %s are giving away"
366  " is destroyed! Treaty canceled!"),
367  nation_plural_for_player(pother));
368  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
369  _("One of the cities the %s are giving away"
370  " is destroyed! Treaty canceled!"),
371  nation_plural_for_player(pother));
372  goto cleanup;
373  }
374  if (city_owner(pcity) != pother) {
375  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
376  _("The %s no longer control %s! "
377  "Treaty canceled!"),
378  nation_plural_for_player(pother),
379  city_link(pcity));
380  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
381  _("The %s no longer control %s! "
382  "Treaty canceled!"),
383  nation_plural_for_player(pother),
384  city_link(pcity));
385  goto cleanup;
386  }
387  if (is_capital(pcity)) {
388  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
389  _("Your capital (%s) is requested, "
390  "you can't accept treaty."),
391  city_link(pcity));
392  goto cleanup;
393  }
394 
395  break;
396  case CLAUSE_ALLIANCE:
397  /* We need to recheck this way since things might have
398  * changed. */
399  diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_ALLIANCE);
400  if (diplcheck != DIPL_OK) {
401  goto cleanup;
402  }
403  break;
404  case CLAUSE_PEACE:
405  diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_PEACE);
406  if (diplcheck != DIPL_OK) {
407  goto cleanup;
408  }
409  break;
410  case CLAUSE_CEASEFIRE:
411  diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_CEASEFIRE);
412  if (diplcheck != DIPL_OK) {
413  goto cleanup;
414  }
415  break;
416  case CLAUSE_GOLD:
417  if (pother->economic.gold < pclause->value) {
418  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
419  _("The %s don't have the promised amount "
420  "of gold! Treaty canceled!"),
421  nation_plural_for_player(pother));
422  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
423  _("The %s don't have the promised amount "
424  "of gold! Treaty canceled!"),
425  nation_plural_for_player(pother));
426  goto cleanup;
427  }
428  break;
429  default:; // nothing
430  }
431  }
432  }
434 
435  call_treaty_accepted(pplayer, pother, ptreaty);
436  call_treaty_accepted(pother, pplayer, ptreaty);
437 
438  clause_list_iterate(ptreaty->clauses, pclause)
439  {
440  struct player *pgiver = pclause->from;
441  struct player *pdest = (pplayer == pgiver) ? pother : pplayer;
442  struct player_diplstate *ds_giverdest =
443  player_diplstate_get(pgiver, pdest);
444  struct player_diplstate *ds_destgiver =
445  player_diplstate_get(pdest, pgiver);
446  enum diplstate_type old_diplstate = ds_giverdest->type;
447  struct unit_list *pgiver_seen_units BAD_HEURISTIC_INIT(nullptr);
448  struct unit_list *pdest_seen_units BAD_HEURISTIC_INIT(nullptr);
449 
450  switch (pclause->type) {
451  case CLAUSE_EMBASSY:
452  establish_embassy(pdest, pgiver); // sic
453  notify_player(pgiver, nullptr, E_TREATY_EMBASSY, ftc_server,
454  _("You gave an embassy to %s."), player_name(pdest));
455  notify_player(pdest, nullptr, E_TREATY_EMBASSY, ftc_server,
456  _("%s allowed you to create an embassy!"),
457  player_name(pgiver));
458  break;
459  case CLAUSE_ADVANCE: {
460  /* It is possible that two players open the diplomacy dialog
461  * and try to give us the same tech at the same time. This
462  * should be handled discreetly instead of giving a core dump. */
463  struct research *presearch = research_get(pdest);
464  const char *advance_name;
465 
466  if (research_invention_state(presearch, pclause->value)
467  == TECH_KNOWN) {
468  qDebug("Nation %s already know tech %s, "
469  "that %s want to give them.",
471  advance_rule_name(advance_by_number(pclause->value)),
473  break;
474  }
475  advance_name =
477  notify_player(pdest, nullptr, E_TECH_GAIN, ftc_server,
478  _("You are taught the knowledge of %s."),
479  advance_name);
480 
481  if (tech_transfer(pdest, pgiver, pclause->value)) {
482  char research_name[MAX_LEN_NAME * 2];
483 
484  research_pretty_name(presearch, research_name,
485  sizeof(research_name));
486  notify_research(presearch, pdest, E_TECH_GAIN, ftc_server,
487  _("You have acquired %s thanks to the %s "
488  "treaty with the %s."),
489  advance_name, nation_adjective_for_player(pdest),
490  nation_plural_for_player(pgiver));
492  presearch, pgiver, E_TECH_EMBASSY, ftc_server,
493  // TRANS: Tech from another player
494  Q_("?fromplr:The %s have acquired %s from the %s."),
495  research_name, advance_name, nation_plural_for_player(pgiver));
496 
497  script_tech_learned(presearch, pdest,
498  advance_by_number(pclause->value), "traded");
499  research_apply_penalty(presearch, pclause->value,
500  game.server.diplbulbcost);
501  found_new_tech(presearch, pclause->value, false, true);
502  }
503  } break;
504  case CLAUSE_GOLD: {
505  int received =
506  pclause->value * (100 - game.server.diplgoldcost) / 100;
507  pgiver->economic.gold -= pclause->value;
508  pdest->economic.gold += received;
509  notify_player(pdest, nullptr, E_DIPLOMACY, ftc_server,
510  PL_("You get %d gold.", "You get %d gold.", received),
511  received);
512  } break;
513  case CLAUSE_MAP:
514  give_map_from_player_to_player(pgiver, pdest);
515  notify_player(pdest, nullptr, E_DIPLOMACY, ftc_server,
516  // TRANS: ... Polish worldmap.
517  _("You receive the %s worldmap."),
519 
520  worker_refresh_required = true; // See CLAUSE_VISION
521  break;
522  case CLAUSE_SEAMAP:
523  give_seamap_from_player_to_player(pgiver, pdest);
524  notify_player(pdest, nullptr, E_DIPLOMACY, ftc_server,
525  // TRANS: ... Polish seamap.
526  _("You receive the %s seamap."),
528 
529  worker_refresh_required = true; // See CLAUSE_VISION
530  break;
531  case CLAUSE_CITY: {
532  struct city *pcity = game_city_by_number(pclause->value);
533 
534  if (!pcity) {
535  qCritical("Treaty city id %d not found - skipping clause.",
536  pclause->value);
537  break;
538  }
539 
540  notify_player(pdest, city_tile(pcity), E_CITY_TRANSFER, ftc_server,
541  _("You receive the city of %s from %s."),
542  city_link(pcity), player_name(pgiver));
543 
544  notify_player(pgiver, city_tile(pcity), E_CITY_LOST, ftc_server,
545  _("You give the city of %s to %s."), city_link(pcity),
546  player_name(pdest));
547 
548  if (transfer_city(pdest, pcity, -1, true, true, false,
549  !is_barbarian(pdest))) {
550  script_server_signal_emit("city_transferred", pcity, pgiver, pdest,
551  "trade");
552  }
553  break;
554  }
555  case CLAUSE_CEASEFIRE:
556  if (old_diplstate == DS_ALLIANCE) {
557  pgiver_seen_units = get_units_seen_via_ally(pgiver, pdest);
558  pdest_seen_units = get_units_seen_via_ally(pdest, pgiver);
559  }
560  ds_giverdest->type = DS_CEASEFIRE;
561  ds_giverdest->turns_left = TURNS_LEFT;
562  ds_destgiver->type = DS_CEASEFIRE;
563  ds_destgiver->turns_left = TURNS_LEFT;
564  notify_player(pgiver, nullptr, E_TREATY_CEASEFIRE, ftc_server,
565  _("You agree on a cease-fire with %s."),
566  player_name(pdest));
567  notify_player(pdest, nullptr, E_TREATY_CEASEFIRE, ftc_server,
568  _("You agree on a cease-fire with %s."),
569  player_name(pgiver));
570  if (old_diplstate == DS_ALLIANCE) {
572  pgiver, pdest, pgiver_seen_units, pdest_seen_units);
573  unit_list_destroy(pgiver_seen_units);
574  unit_list_destroy(pdest_seen_units);
575  }
576 
577  worker_refresh_required = true;
578  break;
579  case CLAUSE_PEACE:
580  if (old_diplstate == DS_ALLIANCE) {
581  pgiver_seen_units = get_units_seen_via_ally(pgiver, pdest);
582  pdest_seen_units = get_units_seen_via_ally(pdest, pgiver);
583  }
584  ds_giverdest->type = DS_ARMISTICE;
585  ds_destgiver->type = DS_ARMISTICE;
586  ds_giverdest->turns_left = TURNS_LEFT;
587  ds_destgiver->turns_left = TURNS_LEFT;
588  ds_giverdest->max_state =
589  dst_closest(DS_PEACE, ds_giverdest->max_state);
590  ds_destgiver->max_state =
591  dst_closest(DS_PEACE, ds_destgiver->max_state);
593  pgiver, nullptr, E_TREATY_PEACE, ftc_server,
594  // TRANS: ... the Poles ... Polish territory
595  PL_("You agree on an armistice with the %s. In %d turn, "
596  "it will become a peace treaty. Move your "
597  "military units out of %s territory to avoid them "
598  "being disbanded.",
599  "You agree on an armistice with the %s. In %d turns, "
600  "it will become a peace treaty. Move any "
601  "military units out of %s territory to avoid them "
602  "being disbanded.",
603  TURNS_LEFT),
607  pdest, nullptr, E_TREATY_PEACE, ftc_server,
608  // TRANS: ... the Poles ... Polish territory
609  PL_("You agree on an armistice with the %s. In %d turn, "
610  "it will become a peace treaty. Move your "
611  "military units out of %s territory to avoid them "
612  "being disbanded.",
613  "You agree on an armistice with the %s. In %d turns, "
614  "it will become a peace treaty. Move any "
615  "military units out of %s territory to avoid them "
616  "being disbanded.",
617  TURNS_LEFT),
620  if (old_diplstate == DS_ALLIANCE) {
622  pgiver, pdest, pgiver_seen_units, pdest_seen_units);
623  unit_list_destroy(pgiver_seen_units);
624  unit_list_destroy(pdest_seen_units);
625  }
626 
627  worker_refresh_required = true;
628  break;
629  case CLAUSE_ALLIANCE:
630  ds_giverdest->type = DS_ALLIANCE;
631  ds_destgiver->type = DS_ALLIANCE;
632  ds_giverdest->max_state =
633  dst_closest(DS_ALLIANCE, ds_giverdest->max_state);
634  ds_destgiver->max_state =
635  dst_closest(DS_ALLIANCE, ds_destgiver->max_state);
636  notify_player(pgiver, nullptr, E_TREATY_ALLIANCE, ftc_server,
637  _("You agree on an alliance with %s."),
638  player_name(pdest));
639  notify_player(pdest, nullptr, E_TREATY_ALLIANCE, ftc_server,
640  _("You agree on an alliance with %s."),
641  player_name(pgiver));
642  give_allied_visibility(pgiver, pdest);
643  give_allied_visibility(pdest, pgiver);
644 
645  worker_refresh_required = true;
646  break;
647  case CLAUSE_VISION:
648  give_shared_vision(pgiver, pdest);
649  notify_player(pgiver, nullptr, E_TREATY_SHARED_VISION, ftc_server,
650  _("You give shared vision to %s."),
651  player_name(pdest));
652  notify_player(pdest, nullptr, E_TREATY_SHARED_VISION, ftc_server,
653  _("%s gives you shared vision."), player_name(pgiver));
654 
655  /* Yes, shared vision may let us to _know_ tiles
656  * within radius of our own city. */
657  worker_refresh_required = true;
658  break;
659  case CLAUSE_COUNT:
660  fc_assert(pclause->type != CLAUSE_COUNT);
661  break;
662  }
663  }
665 
666  /* In theory, we would need refresh only receiving party of
667  * CLAUSE_MAP, CLAUSE_SEAMAP and CLAUSE_VISION clauses.
668  * It's quite unlikely that there is such a clause going one
669  * way but no clauses affecting both parties or going other
670  * way. */
671  if (worker_refresh_required) {
674  sync_cities();
675  }
676 
677  cleanup:
678  treaty_list_remove(treaties, ptreaty);
679  clear_treaty(ptreaty);
680  delete ptreaty;
681  send_player_all_c(pplayer, nullptr);
682  send_player_all_c(pother, nullptr);
683  }
684 }
685 
689 void establish_embassy(struct player *pplayer, struct player *aplayer)
690 {
691  // Establish the embassy.
692  BV_SET(pplayer->real_embassy, player_index(aplayer));
693  send_player_all_c(pplayer, pplayer->connections);
694  // update player dialog with embassy
695  send_player_all_c(pplayer, aplayer->connections);
696  // INFO_EMBASSY level info
697  send_player_all_c(aplayer, pplayer->connections);
698  // Send research info
699  send_research_info(research_get(aplayer), pplayer->connections);
700 }
701 
706  int counterpart, int giver,
707  enum clause_type type, int value)
708 {
709  struct Treaty *ptreaty;
710  struct player *pgiver = player_by_number(giver);
711  struct player *pother = player_by_number(counterpart);
712 
713  if (nullptr == pother || pplayer == pother || nullptr == pgiver) {
714  return;
715  }
716 
717  if (pgiver != pplayer && pgiver != pother) {
718  return;
719  }
720 
721  ptreaty = find_treaty(pplayer, pother);
722 
723  if (ptreaty && remove_clause(ptreaty, pgiver, type, value)) {
724  dlsend_packet_diplomacy_remove_clause(
725  pplayer->connections, player_number(pother), giver, type, value);
726  dlsend_packet_diplomacy_remove_clause(
727  pother->connections, player_number(pplayer), giver, type, value);
728  call_treaty_evaluate(pplayer, pother, ptreaty);
729  call_treaty_evaluate(pother, pplayer, ptreaty);
730  }
731 }
732 
737  int counterpart, int giver,
738  enum clause_type type, int value)
739 {
740  struct Treaty *ptreaty;
741  struct player *pgiver = player_by_number(giver);
742  struct player *pother = player_by_number(counterpart);
743 
744  if (nullptr == pother || pplayer == pother || nullptr == pgiver) {
745  return;
746  }
747 
748  if (pgiver != pplayer && pgiver != pother) {
749  return;
750  }
751 
752  ptreaty = find_treaty(pplayer, pother);
753 
754  if (ptreaty && add_clause(ptreaty, pgiver, type, value)) {
755  /*
756  * If we are trading cities, then it is possible that the
757  * dest is unaware of it's existence. We have 2 choices,
758  * forbid it, or lighten that area. If we assume that
759  * the giver knows what they are doing, then 2. is the
760  * most powerful option - I'll choose that for now.
761  * - Kris Bubendorfer
762  */
763  if (type == CLAUSE_CITY) {
764  struct city *pcity = game_city_by_number(value);
765 
766  if (pcity && !map_is_known_and_seen(pcity->tile, pother, V_MAIN)) {
767  give_citymap_from_player_to_player(pcity, pplayer, pother);
768  }
769  }
770 
771  dlsend_packet_diplomacy_create_clause(
772  pplayer->connections, player_number(pother), giver, type, value);
773  dlsend_packet_diplomacy_create_clause(
774  pother->connections, player_number(pplayer), giver, type, value);
775  call_treaty_evaluate(pplayer, pother, ptreaty);
776  call_treaty_evaluate(pother, pplayer, ptreaty);
777  }
778 }
779 
784 static void really_diplomacy_cancel_meeting(struct player *pplayer,
785  struct player *pother)
786 {
787  struct Treaty *ptreaty = find_treaty(pplayer, pother);
788 
789  if (ptreaty) {
790  dlsend_packet_diplomacy_cancel_meeting(
791  pother->connections, player_number(pplayer), player_number(pplayer));
792  notify_player(pother, nullptr, E_DIPLOMACY, ftc_server,
793  _("%s canceled the meeting!"), player_name(pplayer));
794  // Need to send to pplayer too, for multi-connects:
795  dlsend_packet_diplomacy_cancel_meeting(
796  pplayer->connections, player_number(pother), player_number(pplayer));
797  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
798  _("Meeting with %s canceled."), player_name(pother));
799  treaty_list_remove(treaties, ptreaty);
800  clear_treaty(ptreaty);
801  delete ptreaty;
802  }
803 }
804 
809  int counterpart)
810 {
811  struct player *pother = player_by_number(counterpart);
812 
813  if (nullptr == pother || pplayer == pother) {
814  return;
815  }
816 
817  really_diplomacy_cancel_meeting(pplayer, pother);
818 }
819 
824  int counterpart)
825 {
826  struct player *pother = player_by_number(counterpart);
827 
828  if (nullptr == pother || pplayer == pother) {
829  return;
830  }
831 
832  if (find_treaty(pplayer, pother)) {
833  return;
834  }
835 
836  if (get_player_bonus(pplayer, EFT_NO_DIPLOMACY) > 0
837  || get_player_bonus(pother, EFT_NO_DIPLOMACY) > 0) {
838  notify_player(pplayer, nullptr, E_DIPLOMACY, ftc_server,
839  _("Your diplomatic envoy was decapitated!"));
840  return;
841  }
842 
843  if (could_meet_with_player(pplayer, pother)) {
844  auto *ptreaty = new Treaty;
845  init_treaty(ptreaty, pplayer, pother);
846  treaty_list_prepend(treaties, ptreaty);
847 
848  dlsend_packet_diplomacy_init_meeting(
849  pplayer->connections, player_number(pother), player_number(pplayer));
850  dlsend_packet_diplomacy_init_meeting(
851  pother->connections, player_number(pplayer), player_number(pplayer));
852  }
853 }
854 
860 {
861  struct player *pplayer = dest->playing;
862 
863  if (!pplayer) {
864  return;
865  }
866  players_iterate(other)
867  {
868  struct Treaty *ptreaty = find_treaty(pplayer, other);
869 
870  if (ptreaty) {
871  fc_assert_action(pplayer != other, continue);
872  dsend_packet_diplomacy_init_meeting(dest, player_number(other),
873  player_number(pplayer));
874  clause_list_iterate(ptreaty->clauses, pclause)
875  {
876  dsend_packet_diplomacy_create_clause(dest, player_number(other),
877  player_number(pclause->from),
878  pclause->type, pclause->value);
879  }
881 
882  if (ptreaty->plr0 == pplayer) {
883  dsend_packet_diplomacy_accept_treaty(
884  dest, player_number(other), ptreaty->accept0, ptreaty->accept1);
885  } else {
886  dsend_packet_diplomacy_accept_treaty(
887  dest, player_number(other), ptreaty->accept1, ptreaty->accept0);
888  }
889  }
890  }
892 }
893 
897 void cancel_all_meetings(struct player *pplayer)
898 {
899  players_iterate(pplayer2)
900  {
901  if (find_treaty(pplayer, pplayer2)) {
902  really_diplomacy_cancel_meeting(pplayer, pplayer2);
903  }
904  }
906 }
907 
911 void reject_all_treaties(struct player *pplayer)
912 {
913  struct Treaty *treaty;
914  players_iterate(pplayer2)
915  {
916  treaty = find_treaty(pplayer, pplayer2);
917  if (!treaty) {
918  continue;
919  }
920  treaty->accept0 = false;
921  treaty->accept1 = false;
922  dlsend_packet_diplomacy_accept_treaty(
923  pplayer->connections, player_number(pplayer2), false, false);
924  dlsend_packet_diplomacy_accept_treaty(
925  pplayer2->connections, player_number(pplayer), false, false);
926  }
928 }
929 
933 struct treaty_list *get_all_treaties() { return treaties; }
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition: ai.h:383
#define BV_SET(bv, bit)
Definition: bitvector.h:44
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
bool is_capital(const struct city *pcity)
Return TRUE iff this city is its nation's capital.
Definition: city.cpp:1495
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
void city_map_update_all_cities_for_player(struct player *pplayer)
Update worked map of all cities of given player.
Definition: citytools.cpp:3189
bool transfer_city(struct player *ptaker, struct city *pcity, int kill_outside, bool transfer_unit_verbose, bool resolve_stack, bool raze, bool build_free)
Handles all transactions in relation to transferring a city.
Definition: citytools.cpp:1084
void sync_cities()
Make sure all players (clients) have up-to-date information about all their cities.
Definition: citytools.cpp:3150
static struct treaty_list * treaties
Definition: diplhand.cpp:44
void establish_embassy(struct player *pplayer, struct player *aplayer)
Create an embassy.
Definition: diplhand.cpp:689
void diplhand_init()
Initialize diplhand module.
Definition: diplhand.cpp:73
void send_diplomatic_meetings(struct connection *dest)
Send information on any on-going diplomatic meetings for connection's player.
Definition: diplhand.cpp:859
struct Treaty * find_treaty(struct player *plr0, struct player *plr1)
Find currently active treaty between two players.
Definition: diplhand.cpp:105
void free_treaties()
Free all the treaties currently in treaty list.
Definition: diplhand.cpp:89
void handle_diplomacy_remove_clause_req(struct player *pplayer, int counterpart, int giver, enum clause_type type, int value)
Handle request to remove clause from treaty.
Definition: diplhand.cpp:705
void handle_diplomacy_create_clause_req(struct player *pplayer, int counterpart, int giver, enum clause_type type, int value)
Handle request to add clause to treaty between two players.
Definition: diplhand.cpp:736
void diplhand_free()
Free all the resources allocated by diplhand.
Definition: diplhand.cpp:78
static void call_treaty_accepted(struct player *pplayer, struct player *aplayer, struct Treaty *ptreaty)
Calls treaty_accepted function if such is set for AI player.
Definition: diplhand.cpp:61
struct treaty_list * get_all_treaties()
Get treaty list.
Definition: diplhand.cpp:933
void reject_all_treaties(struct player *pplayer)
Reject all treaties currently being negotiated.
Definition: diplhand.cpp:911
void handle_diplomacy_init_meeting_req(struct player *pplayer, int counterpart)
Handle meeting opening request.
Definition: diplhand.cpp:823
void cancel_all_meetings(struct player *pplayer)
Cancels all meetings of player.
Definition: diplhand.cpp:897
void handle_diplomacy_cancel_meeting_req(struct player *pplayer, int counterpart)
Handle meeting cancelling request.
Definition: diplhand.cpp:808
static void call_treaty_evaluate(struct player *pplayer, struct player *aplayer, struct Treaty *ptreaty)
Calls treaty_evaluate function if such is set for AI player.
Definition: diplhand.cpp:49
static enum diplstate_type dst_closest(enum diplstate_type a, enum diplstate_type b)
Return the closest of the two diplstate types.
Definition: diplhand.cpp:122
static void really_diplomacy_cancel_meeting(struct player *pplayer, struct player *pother)
Cancel meeting.
Definition: diplhand.cpp:784
void handle_diplomacy_accept_treaty_req(struct player *pplayer, int counterpart)
pplayer clicked the accept button.
Definition: diplhand.cpp:146
#define treaty_list_iterate(list, p)
Definition: diplhand.h:29
#define treaty_list_iterate_end
Definition: diplhand.h:31
const int TURNS_LEFT
Definition: diplhand.h:26
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Add clause to treaty.
Definition: diptreaty.cpp:134
struct clause_info * clause_info_get(enum clause_type type)
Free memory associated with clause infos.
Definition: diptreaty.cpp:257
void clear_treaty(struct Treaty *ptreaty)
Free the clauses of a treaty.
Definition: diptreaty.cpp:100
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Initialize treaty structure between two players.
Definition: diptreaty.cpp:87
bool remove_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Remove clause from treaty.
Definition: diptreaty.cpp:110
bool could_meet_with_player(const struct player *pplayer, const struct player *aplayer)
Returns TRUE iff pplayer could do diplomatic meetings with aplayer.
Definition: diptreaty.cpp:56
#define clause_list_iterate_end
Definition: diptreaty.h:61
#define clause_list_iterate(clauselist, pclause)
Definition: diptreaty.h:59
#define is_pact_clause(x)
Definition: diptreaty.h:43
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Returns the effect bonus for a player.
Definition: effects.cpp:673
@ RPT_POSSIBLE
Definition: fc_types.h:567
#define MAX_LEN_NAME
Definition: fc_types.h:61
#define Q_(String)
Definition: fcintl.h:53
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
Get a text link to a city.
struct civ_game game
Definition: game.cpp:47
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_action(condition, action)
Definition: log.h:104
void give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Give information about whole map (all tiles) from player to player.
Definition: maphand.cpp:368
void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest)
Give information about all oceanic tiles from player to player.
Definition: maphand.cpp:387
void give_citymap_from_player_to_player(struct city *pcity, struct player *pfrom, struct player *pdest)
Give information about tiles within city radius from player to player.
Definition: maphand.cpp:408
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Returns whether the layer 'vlayer' of the tile 'ptile' is known and seen by the player 'pplayer'.
Definition: maphand.cpp:894
void give_shared_vision(struct player *pfrom, struct player *pto)
Starts shared vision between two players.
Definition: maphand.cpp:1568
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
const char * nation_plural_for_player(const struct player *pplayer)
Return the (translated) plural noun of the given nation of a player.
Definition: nation.cpp:155
const char * nation_adjective_for_player(const struct player *pplayer)
Return the (translated) adjective for the given nation of a player.
Definition: nation.cpp:146
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
void notify_research(const struct research *presearch, const struct player *exclude, enum event_type event, const struct ft_color color, const char *format,...)
Sends a message to all players that share research.
Definition: notify.cpp:386
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Similar to notify_conn_packet (see also), but takes player as "destination".
Definition: notify.cpp:284
void notify_research_embassies(const struct research *presearch, const struct player *exclude, enum event_type event, const struct ft_color color, const char *format,...)
Sends a message to all players that have embassies with someone who shares research.
Definition: notify.cpp:426
struct player * player_by_number(const int player_id)
Return struct player pointer for the given player index.
Definition: player.cpp:768
int player_number(const struct player *pplayer)
Return the player index/number/id.
Definition: player.cpp:756
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Returns true iff p1 can make given treaty with p2.
Definition: player.cpp:150
bool player_has_real_embassy(const struct player *pplayer, const struct player *pplayer2)
Returns whether pplayer has a real embassy with pplayer2, established from a diplomat,...
Definition: player.cpp:206
int player_index(const struct player *pplayer)
Return the player index.
Definition: player.cpp:748
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
#define players_iterate_end
Definition: player.h:520
dipl_reason
Definition: player.h:183
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition: player.h:188
@ DIPL_ALLIANCE_PROBLEM_US
Definition: player.h:187
@ DIPL_OK
Definition: player.h:184
#define players_iterate(_pplayer)
Definition: player.h:514
static bool is_barbarian(const struct player *pplayer)
Definition: player.h:474
#define is_ai(plr)
Definition: player.h:227
void send_player_all_c(struct player *src, struct conn_list *dest)
Send all information about a player (player_info and all player_diplstates) to the given connections.
Definition: plrhand.cpp:1031
void update_players_after_alliance_breakup(struct player *pplayer, struct player *pplayer2, const struct unit_list *pplayer_seen_units, const struct unit_list *pplayer2_seen_units)
After the alliance is breaken, we need to do two things:
Definition: plrhand.cpp:665
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement(s) to see if they are active on the given target.
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Returns TRUE iff the given tech can be given to the players sharing the research immediately.
Definition: research.cpp:686
int research_pretty_name(const struct research *presearch, char *buf, size_t buf_len)
Set in 'buf' the name of the research owner.
Definition: research.cpp:163
void script_server_signal_emit(const char *signal_name,...)
Invoke all the callback functions attached to a given signal.
#define BAD_HEURISTIC_INIT(_ini_val_)
Definition: shared.h:37
struct player * plr0
Definition: diptreaty.h:70
bool accept0
Definition: diptreaty.h:71
bool accept1
Definition: diptreaty.h:71
struct clause_list * clauses
Definition: diptreaty.h:72
struct player * plr1
Definition: diptreaty.h:70
Definition: city.h:291
struct tile * tile
Definition: city.h:293
struct civ_game::@28::@32 server
struct packet_game_info info
Definition: game.h:80
struct requirement_vector receiver_reqs
Definition: diptreaty.h:50
struct requirement_vector giver_reqs
Definition: diptreaty.h:49
struct player * playing
Definition: connection.h:142
enum diplstate_type max_state
Definition: player.h:194
enum diplstate_type type
Definition: player.h:193
Definition: player.h:231
struct conn_list * connections
Definition: player.h:280
bv_player real_embassy
Definition: player.h:259
struct player_economic economic
Definition: player.h:266
const char * advance_rule_name(const struct advance *padvance)
Return the (untranslated) rule name of the advance/technology.
Definition: tech.cpp:283
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
Definition: tech.cpp:94
const char * advance_name_translation(const struct advance *padvance)
Return the (translated) name of the given advance/technology.
Definition: tech.cpp:274
void found_new_tech(struct research *presearch, Tech_type_id tech_found, bool was_discovery, bool saving_bulbs)
Players sharing the research have got a new technology (from somewhere).
Definition: techtools.cpp:341
void research_apply_penalty(struct research *presearch, Tech_type_id tech, int penalty_percent)
Apply a penalty to the research.
Definition: techtools.cpp:59
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Send research info for 'presearch' to 'dest'.
Definition: techtools.cpp:273
void script_tech_learned(struct research *presearch, struct player *originating_plr, struct advance *tech, const char *reason)
Emit script signal(s) for player/team learning new tech.
Definition: techtools.cpp:77
bool tech_transfer(struct player *plr_recv, struct player *plr_donor, Tech_type_id tech)
Check if the tech is lost by the donor or receiver.
Definition: techtools.cpp:1432
void give_allied_visibility(struct player *pplayer, struct player *aplayer)
Refresh units visibility of 'aplayer' for 'pplayer' after alliance have been contracted.
Definition: unittools.cpp:1621
struct unit_list * get_units_seen_via_ally(const struct player *pplayer, const struct player *aplayer)
Returns the list of the units seen by 'pplayer' potentially seen only thanks to an alliance with 'apl...
Definition: unittools.cpp:1552