Rework civ2civ3 ruleset help and documentation.
[freeciv.git] / server / diplhand.c
blob4ce29a9f7b8182cb2aff6c7648701ad6f031da09
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
21 /* utility */
22 #include "bitvector.h"
23 #include "fcintl.h"
24 #include "log.h"
25 #include "mem.h"
27 /* common */
28 #include "diptreaty.h"
29 #include "events.h"
30 #include "game.h"
31 #include "map.h"
32 #include "packets.h"
33 #include "player.h"
34 #include "research.h"
35 #include "unit.h"
37 /* common/scriptcore */
38 #include "luascript_types.h"
40 /* server */
41 #include "citytools.h"
42 #include "cityturn.h"
43 #include "maphand.h"
44 #include "plrhand.h"
45 #include "notify.h"
46 #include "techtools.h"
47 #include "unittools.h"
49 /* server/advisors */
50 #include "autosettlers.h"
52 /* server/scripting */
53 #include "script_server.h"
55 #include "diplhand.h"
57 #define SPECLIST_TAG treaty
58 #define SPECLIST_TYPE struct Treaty
59 #include "speclist.h"
61 #define treaty_list_iterate(list, p) \
62 TYPED_LIST_ITERATE(struct Treaty, list, p)
63 #define treaty_list_iterate_end LIST_ITERATE_END
65 static struct treaty_list *treaties = NULL;
67 /* FIXME: Should this be put in a ruleset somewhere? */
68 #define TURNS_LEFT 16
70 /**************************************************************************
71 Calls treaty_evaluate function if such is set for AI player.
72 **************************************************************************/
73 static void call_treaty_evaluate(struct player *pplayer, struct player *aplayer,
74 struct Treaty *ptreaty)
76 if (pplayer->ai_controlled) {
77 CALL_PLR_AI_FUNC(treaty_evaluate, pplayer, pplayer, aplayer, ptreaty);
81 /**************************************************************************
82 Calls treaty_accepted function if such is set for AI player.
83 **************************************************************************/
84 static void call_treaty_accepted(struct player *pplayer, struct player *aplayer,
85 struct Treaty *ptreaty)
87 if (pplayer->ai_controlled) {
88 CALL_PLR_AI_FUNC(treaty_accepted, pplayer, pplayer, aplayer, ptreaty);
92 /**************************************************************************
93 Initialize diplhand module
94 **************************************************************************/
95 void diplhand_init(void)
97 treaties = treaty_list_new();
100 /**************************************************************************
101 Free all the resources allocated by diplhand.
102 **************************************************************************/
103 void diplhand_free(void)
105 free_treaties();
107 treaty_list_destroy(treaties);
108 treaties = NULL;
111 /**************************************************************************
112 Free all the treaties currently in treaty list.
113 **************************************************************************/
114 void free_treaties(void)
116 /* Free memory allocated for treaties */
117 treaty_list_iterate(treaties, pt) {
118 clear_treaty(pt);
119 free(pt);
120 } treaty_list_iterate_end;
122 treaty_list_clear(treaties);
125 /**************************************************************************
126 Find currently active treaty between two players.
127 **************************************************************************/
128 struct Treaty *find_treaty(struct player *plr0, struct player *plr1)
130 treaty_list_iterate(treaties, ptreaty) {
131 if ((ptreaty->plr0 == plr0 && ptreaty->plr1 == plr1) ||
132 (ptreaty->plr0 == plr1 && ptreaty->plr1 == plr0)) {
133 return ptreaty;
135 } treaty_list_iterate_end;
137 return NULL;
140 /**************************************************************************
141 pplayer clicked the accept button. If he accepted the treaty we check the
142 clauses. If both players have now accepted the treaty we execute the agreed
143 clauses.
144 **************************************************************************/
145 void handle_diplomacy_accept_treaty_req(struct player *pplayer,
146 int counterpart)
148 struct Treaty *ptreaty;
149 bool *player_accept, *other_accept;
150 enum dipl_reason diplcheck;
151 bool worker_refresh_required = FALSE;
152 struct player *pother = player_by_number(counterpart);
154 if (NULL == pother || pplayer == pother) {
155 return;
158 ptreaty = find_treaty(pplayer, pother);
160 if (!ptreaty) {
161 return;
164 if (ptreaty->plr0 == pplayer) {
165 player_accept = &ptreaty->accept0;
166 other_accept = &ptreaty->accept1;
167 } else {
168 player_accept = &ptreaty->accept1;
169 other_accept = &ptreaty->accept0;
172 if (!*player_accept) { /* Tries to accept. */
174 /* Check that player who accepts can keep what (s)he promises. */
176 clause_list_iterate(ptreaty->clauses, pclause) {
177 struct city *pcity = NULL;
179 if (pclause->from == pplayer) {
180 switch(pclause->type) {
181 case CLAUSE_EMBASSY:
182 if (player_has_real_embassy(pother, pplayer)) {
183 log_error("%s tried to give embassy to %s, who already "
184 "has an embassy",
185 player_name(pplayer), player_name(pother));
186 return;
188 break;
189 case CLAUSE_ADVANCE:
190 if (!player_invention_reachable(pother, pclause->value, FALSE)) {
191 /* It is impossible to give a technology to a civilization that
192 * can never possess it (the client should enforce this). */
193 log_error("Treaty: %s can't have tech %s",
194 nation_rule_name(nation_of_player(pother)),
195 advance_name_by_player(pplayer, pclause->value));
196 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
197 _("The %s can't accept %s."),
198 nation_plural_for_player(pother),
199 advance_name_for_player(pplayer, pclause->value));
200 return;
202 if (player_invention_state(pplayer, pclause->value) != TECH_KNOWN) {
203 log_error("Nation %s try to give unknown tech %s to nation %s.",
204 nation_rule_name(nation_of_player(pplayer)),
205 advance_name_by_player(pplayer, pclause->value),
206 nation_rule_name(nation_of_player(pother)));
207 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
208 _("You don't have tech %s, you can't accept treaty."),
209 advance_name_for_player(pplayer, pclause->value));
210 return;
212 break;
213 case CLAUSE_CITY:
214 pcity = game_city_by_number(pclause->value);
215 if (!pcity) { /* Can't find out cityname any more. */
216 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
217 _("City you are trying to give no longer exists, "
218 "you can't accept treaty."));
219 return;
221 if (city_owner(pcity) != pplayer) {
222 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
223 _("You are not owner of %s, you can't accept treaty."),
224 city_link(pcity));
225 return;
227 if (is_capital(pcity)) {
228 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
229 _("Your capital (%s) is requested, "
230 "you can't accept treaty."),
231 city_link(pcity));
232 return;
234 break;
235 case CLAUSE_CEASEFIRE:
236 diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_CEASEFIRE);
237 if (diplcheck != DIPL_OK) {
238 return;
240 break;
241 case CLAUSE_PEACE:
242 diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_PEACE);
243 if (diplcheck != DIPL_OK) {
244 return;
246 break;
247 case CLAUSE_ALLIANCE:
248 diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_ALLIANCE);
249 if (diplcheck == DIPL_ALLIANCE_PROBLEM_US) {
250 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
251 _("You cannot form an alliance because you are "
252 "at war with an ally of %s."),
253 player_name(pother));
254 } else if (diplcheck == DIPL_ALLIANCE_PROBLEM_THEM) {
255 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
256 _("You cannot form an alliance because %s is "
257 "at war with an ally of yours."),
258 player_name(pother));
260 if (diplcheck != DIPL_OK) {
261 return;
263 break;
264 case CLAUSE_GOLD:
265 if (pplayer->economic.gold < pclause->value) {
266 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
267 _("You don't have enough gold, "
268 "you can't accept treaty."));
269 return;
271 break;
272 default:
273 ; /* nothing */
276 } clause_list_iterate_end;
279 *player_accept = ! *player_accept;
281 dlsend_packet_diplomacy_accept_treaty(pplayer->connections,
282 player_number(pother), *player_accept,
283 *other_accept);
284 dlsend_packet_diplomacy_accept_treaty(pother->connections,
285 player_number(pplayer), *other_accept,
286 *player_accept);
288 if (ptreaty->accept0 && ptreaty->accept1) {
289 int nclauses = clause_list_size(ptreaty->clauses);
291 dlsend_packet_diplomacy_cancel_meeting(pplayer->connections,
292 player_number(pother),
293 player_number(pplayer));
294 dlsend_packet_diplomacy_cancel_meeting(pother->connections,
295 player_number(pplayer),
296 player_number(pplayer));
298 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
299 PL_("A treaty containing %d clause was agreed upon.",
300 "A treaty containing %d clauses was agreed upon.",
301 nclauses),
302 nclauses);
303 notify_player(pother, NULL, E_DIPLOMACY, ftc_server,
304 PL_("A treaty containing %d clause was agreed upon.",
305 "A treaty containing %d clauses was agreed upon.",
306 nclauses),
307 nclauses);
309 /* Check that one who accepted treaty earlier still have everything
310 (s)he promised to give. */
312 clause_list_iterate(ptreaty->clauses, pclause) {
313 struct city *pcity;
314 if (pclause->from == pother) {
315 switch (pclause->type) {
316 case CLAUSE_CITY:
317 pcity = game_city_by_number(pclause->value);
318 if (!pcity) { /* Can't find out cityname any more. */
319 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
320 _("One of the cities the %s are giving away"
321 " is destroyed! Treaty canceled!"),
322 nation_plural_for_player(pother));
323 notify_player(pother, NULL, E_DIPLOMACY, ftc_server,
324 _("One of the cities the %s are giving away"
325 " is destroyed! Treaty canceled!"),
326 nation_plural_for_player(pother));
327 goto cleanup;
329 if (city_owner(pcity) != pother) {
330 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
331 _("The %s no longer control %s! "
332 "Treaty canceled!"),
333 nation_plural_for_player(pother),
334 city_link(pcity));
335 notify_player(pother, NULL, E_DIPLOMACY, ftc_server,
336 _("The %s no longer control %s! "
337 "Treaty canceled!"),
338 nation_plural_for_player(pother),
339 city_link(pcity));
340 goto cleanup;
342 if (is_capital(pcity)) {
343 notify_player(pother, NULL, E_DIPLOMACY, ftc_server,
344 _("Your capital (%s) is requested, "
345 "you can't accept treaty."),
346 city_link(pcity));
347 goto cleanup;
350 break;
351 case CLAUSE_ALLIANCE:
352 /* We need to recheck this way since things might have
353 * changed. */
354 diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_ALLIANCE);
355 if (diplcheck != DIPL_OK) {
356 goto cleanup;
358 break;
359 case CLAUSE_PEACE:
360 diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_PEACE);
361 if (diplcheck != DIPL_OK) {
362 goto cleanup;
364 break;
365 case CLAUSE_CEASEFIRE:
366 diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_CEASEFIRE);
367 if (diplcheck != DIPL_OK) {
368 goto cleanup;
370 break;
371 case CLAUSE_GOLD:
372 if (pother->economic.gold < pclause->value) {
373 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
374 _("The %s don't have the promised amount "
375 "of gold! Treaty canceled!"),
376 nation_plural_for_player(pother));
377 notify_player(pother, NULL, E_DIPLOMACY, ftc_server,
378 _("The %s don't have the promised amount "
379 "of gold! Treaty canceled!"),
380 nation_plural_for_player(pother));
381 goto cleanup;
383 break;
384 default:
385 ; /* nothing */
388 } clause_list_iterate_end;
390 call_treaty_accepted(pplayer, pother, ptreaty);
391 call_treaty_accepted(pother, pplayer, ptreaty);
393 clause_list_iterate(ptreaty->clauses, pclause) {
394 struct player *pgiver = pclause->from;
395 struct player *pdest = (pplayer == pgiver) ? pother : pplayer;
396 struct player_diplstate *ds_giverdest
397 = player_diplstate_get(pgiver, pdest);
398 struct player_diplstate *ds_destgiver
399 = player_diplstate_get(pdest, pgiver);
400 enum diplstate_type old_diplstate = ds_giverdest->type;
401 struct unit_list *pgiver_seen_units, *pdest_seen_units;
403 switch (pclause->type) {
404 case CLAUSE_EMBASSY:
405 establish_embassy(pdest, pgiver); /* sic */
406 notify_player(pgiver, NULL, E_TREATY_EMBASSY, ftc_server,
407 _("You gave an embassy to %s."),
408 player_name(pdest));
409 notify_player(pdest, NULL, E_TREATY_EMBASSY, ftc_server,
410 _("%s allowed you to create an embassy!"),
411 player_name(pgiver));
412 break;
413 case CLAUSE_ADVANCE:
414 /* It is possible that two players open the diplomacy dialog
415 * and try to give us the same tech at the same time. This
416 * should be handled discreetly instead of giving a core dump. */
417 if (player_invention_state(pdest, pclause->value) == TECH_KNOWN) {
418 log_verbose("Nation %s already know tech %s, "
419 "that %s want to give them.",
420 nation_rule_name(nation_of_player(pdest)),
421 advance_name_by_player(pplayer, pclause->value),
422 nation_rule_name(nation_of_player(pgiver)));
423 break;
425 notify_player(pdest, NULL, E_TECH_GAIN, ftc_server,
426 _("You are taught the knowledge of %s."),
427 advance_name_for_player(pdest, pclause->value));
429 if (tech_transfer(pdest, pgiver, pclause->value)) {
430 notify_embassies(pdest, pgiver, NULL, E_TECH_GAIN, ftc_server,
431 _("The %s have acquired %s from the %s."),
432 nation_plural_for_player(pdest),
433 advance_name_for_player(pdest, pclause->value),
434 nation_plural_for_player(pgiver));
435 script_tech_learned(pdest, advance_by_number(pclause->value),
436 "traded");
437 do_dipl_cost(pdest, pclause->value);
438 found_new_tech(pdest, pclause->value, FALSE, TRUE);
440 break;
441 case CLAUSE_GOLD:
443 int received = pclause->value
444 * (100 - game.server.diplcost) / 100;
445 pgiver->economic.gold -= pclause->value;
446 pdest->economic.gold += received;
447 notify_player(pdest, NULL, E_DIPLOMACY, ftc_server,
448 PL_("You get %d gold.",
449 "You get %d gold.", received), received);
451 break;
452 case CLAUSE_MAP:
453 give_map_from_player_to_player(pgiver, pdest);
454 notify_player(pdest, NULL, E_DIPLOMACY, ftc_server,
455 /* TRANS: ... Polish worldmap. */
456 _("You receive the %s worldmap."),
457 nation_adjective_for_player(pgiver));
459 worker_refresh_required = TRUE; /* See CLAUSE_VISION */
460 break;
461 case CLAUSE_SEAMAP:
462 give_seamap_from_player_to_player(pgiver, pdest);
463 notify_player(pdest, NULL, E_DIPLOMACY, ftc_server,
464 /* TRANS: ... Polish seamap. */
465 _("You receive the %s seamap."),
466 nation_adjective_for_player(pgiver));
468 worker_refresh_required = TRUE; /* See CLAUSE_VISION */
469 break;
470 case CLAUSE_CITY:
472 struct city *pcity = game_city_by_number(pclause->value);
474 if (!pcity) {
475 log_error("Treaty city id %d not found - skipping clause.",
476 pclause->value);
477 break;
480 notify_player(pdest, city_tile(pcity), E_CITY_TRANSFER, ftc_server,
481 _("You receive the city of %s from %s."),
482 city_link(pcity), player_name(pgiver));
484 notify_player(pgiver, city_tile(pcity), E_CITY_LOST, ftc_server,
485 _("You give the city of %s to %s."),
486 city_link(pcity), player_name(pdest));
488 (void) transfer_city(pdest, pcity, -1, TRUE, TRUE, FALSE,
489 !is_barbarian(pdest));
490 break;
492 case CLAUSE_CEASEFIRE:
493 if (old_diplstate == DS_ALLIANCE) {
494 pgiver_seen_units = get_seen_units(pgiver, pdest);
495 pdest_seen_units = get_seen_units(pdest, pgiver);
497 ds_giverdest->type = DS_CEASEFIRE;
498 ds_giverdest->turns_left = TURNS_LEFT;
499 ds_destgiver->type = DS_CEASEFIRE;
500 ds_destgiver->turns_left = TURNS_LEFT;
501 notify_player(pgiver, NULL, E_TREATY_CEASEFIRE, ftc_server,
502 _("You agree on a cease-fire with %s."),
503 player_name(pdest));
504 notify_player(pdest, NULL, E_TREATY_CEASEFIRE, ftc_server,
505 _("You agree on a cease-fire with %s."),
506 player_name(pgiver));
507 if (old_diplstate == DS_ALLIANCE) {
508 update_players_after_alliance_breakup(pgiver, pdest,
509 pgiver_seen_units,
510 pdest_seen_units);
511 unit_list_destroy(pgiver_seen_units);
512 unit_list_destroy(pdest_seen_units);
515 worker_refresh_required = TRUE;
516 break;
517 case CLAUSE_PEACE:
518 if (old_diplstate == DS_ALLIANCE) {
519 pgiver_seen_units = get_seen_units(pgiver, pdest);
520 pdest_seen_units = get_seen_units(pdest, pgiver);
522 ds_giverdest->type = DS_ARMISTICE;
523 ds_destgiver->type = DS_ARMISTICE;
524 ds_giverdest->turns_left = TURNS_LEFT;
525 ds_destgiver->turns_left = TURNS_LEFT;
526 ds_giverdest->max_state = MAX(DS_PEACE, ds_giverdest->max_state);
527 ds_destgiver->max_state = MAX(DS_PEACE, ds_destgiver->max_state);
528 notify_player(pgiver, NULL, E_TREATY_PEACE, ftc_server,
529 /* TRANS: ... the Poles ... Polish territory. */
530 PL_("You agree on an armistice with the %s. In %d turn, "
531 "it will become a peace treaty. Move your "
532 "units out of %s territory.",
533 "You agree on an armistice with the %s. In %d turns, "
534 "it will become a peace treaty. Move your "
535 "units out of %s territory.",
536 TURNS_LEFT),
537 nation_plural_for_player(pdest),
538 TURNS_LEFT,
539 nation_adjective_for_player(pdest));
540 notify_player(pdest, NULL, E_TREATY_PEACE, ftc_server,
541 /* TRANS: ... the Poles ... Polish territory. */
542 PL_("You agree on an armistice with the %s. In %d turn, "
543 "it will become a peace treaty. Move your "
544 "units out of %s territory.",
545 "You agree on an armistice with the %s. In %d turns, "
546 "it will become a peace treaty. Move your "
547 "units out of %s territory.",
548 TURNS_LEFT),
549 nation_plural_for_player(pgiver),
550 TURNS_LEFT,
551 nation_adjective_for_player(pgiver));
552 if (old_diplstate == DS_ALLIANCE) {
553 update_players_after_alliance_breakup(pgiver, pdest,
554 pgiver_seen_units,
555 pdest_seen_units);
556 unit_list_destroy(pgiver_seen_units);
557 unit_list_destroy(pdest_seen_units);
560 worker_refresh_required = TRUE;
561 break;
562 case CLAUSE_ALLIANCE:
563 ds_giverdest->type = DS_ALLIANCE;
564 ds_destgiver->type = DS_ALLIANCE;
565 ds_giverdest->max_state = MAX(DS_ALLIANCE, ds_giverdest->max_state);
566 ds_destgiver->max_state = MAX(DS_ALLIANCE, ds_destgiver->max_state);
567 notify_player(pgiver, NULL, E_TREATY_ALLIANCE, ftc_server,
568 _("You agree on an alliance with %s."),
569 player_name(pdest));
570 notify_player(pdest, NULL, E_TREATY_ALLIANCE, ftc_server,
571 _("You agree on an alliance with %s."),
572 player_name(pgiver));
573 give_allied_visibility(pgiver, pdest);
574 give_allied_visibility(pdest, pgiver);
576 worker_refresh_required = TRUE;
577 break;
578 case CLAUSE_VISION:
579 give_shared_vision(pgiver, pdest);
580 notify_player(pgiver, NULL, E_TREATY_SHARED_VISION, ftc_server,
581 _("You give shared vision to %s."),
582 player_name(pdest));
583 notify_player(pdest, NULL, E_TREATY_SHARED_VISION, ftc_server,
584 _("%s gives you shared vision."),
585 player_name(pgiver));
587 /* Yes, shared vision may let us to _know_ tiles
588 * within radius of our own city. */
589 worker_refresh_required = TRUE;
590 break;
591 case CLAUSE_LAST:
592 log_error("Received bad clause type");
593 break;
596 } clause_list_iterate_end;
598 /* In theory, we would need refresh only receiving party of
599 * CLAUSE_MAP, CLAUSE_SEAMAP and CLAUSE_VISION clauses.
600 * It's quite unlikely that there is such a clause going one
601 * way but no clauses affecting both parties or going other
602 * way. */
603 if (worker_refresh_required) {
604 city_map_update_all_cities_for_player(pplayer);
605 city_map_update_all_cities_for_player(pother);
606 sync_cities();
609 cleanup:
610 treaty_list_remove(treaties, ptreaty);
611 clear_treaty(ptreaty);
612 free(ptreaty);
613 send_player_all_c(pplayer, NULL);
614 send_player_all_c(pother, NULL);
618 /****************************************************************************
619 Create an embassy. pplayer gets an embassy with aplayer.
620 ****************************************************************************/
621 void establish_embassy(struct player *pplayer, struct player *aplayer)
623 /* Establish the embassy. */
624 BV_SET(pplayer->real_embassy, player_index(aplayer));
625 send_player_all_c(pplayer, pplayer->connections);
626 /* update player dialog with embassy */
627 send_player_all_c(pplayer, aplayer->connections);
628 /* INFO_EMBASSY level info */
629 send_player_all_c(aplayer, pplayer->connections);
632 /**************************************************************************
633 Handle request to remove clause from treaty.
634 **************************************************************************/
635 void handle_diplomacy_remove_clause_req(struct player *pplayer,
636 int counterpart, int giver,
637 enum clause_type type, int value)
639 struct Treaty *ptreaty;
640 struct player *pgiver = player_by_number(giver);
641 struct player *pother = player_by_number(counterpart);
643 if (NULL == pother || pplayer == pother || NULL == pgiver) {
644 return;
647 if (pgiver != pplayer && pgiver != pother) {
648 return;
651 ptreaty = find_treaty(pplayer, pother);
653 if (ptreaty && remove_clause(ptreaty, pgiver, type, value)) {
654 dlsend_packet_diplomacy_remove_clause(pplayer->connections,
655 player_number(pother), giver, type,
656 value);
657 dlsend_packet_diplomacy_remove_clause(pother->connections,
658 player_number(pplayer), giver, type,
659 value);
660 call_treaty_evaluate(pplayer, pother, ptreaty);
661 call_treaty_evaluate(pother, pplayer, ptreaty);
665 /**************************************************************************
666 Handle request to add clause to treaty between two players.
667 **************************************************************************/
668 void handle_diplomacy_create_clause_req(struct player *pplayer,
669 int counterpart, int giver,
670 enum clause_type type, int value)
672 struct Treaty *ptreaty;
673 struct player *pgiver = player_by_number(giver);
674 struct player *pother = player_by_number(counterpart);
676 if (NULL == pother || pplayer == pother || NULL == pgiver) {
677 return;
680 if (pgiver != pplayer && pgiver != pother) {
681 return;
684 ptreaty = find_treaty(pplayer, pother);
686 if (ptreaty && add_clause(ptreaty, pgiver, type, value)) {
688 * If we are trading cities, then it is possible that the
689 * dest is unaware of it's existence. We have 2 choices,
690 * forbid it, or lighten that area. If we assume that
691 * the giver knows what they are doing, then 2. is the
692 * most powerful option - I'll choose that for now.
693 * - Kris Bubendorfer
695 if (type == CLAUSE_CITY) {
696 struct city *pcity = game_city_by_number(value);
698 if (pcity && !map_is_known_and_seen(pcity->tile, pother, V_MAIN))
699 give_citymap_from_player_to_player(pcity, pplayer, pother);
702 dlsend_packet_diplomacy_create_clause(pplayer->connections,
703 player_number(pother), giver, type,
704 value);
705 dlsend_packet_diplomacy_create_clause(pother->connections,
706 player_number(pplayer), giver, type,
707 value);
708 call_treaty_evaluate(pplayer, pother, ptreaty);
709 call_treaty_evaluate(pother, pplayer, ptreaty);
713 /**************************************************************************
714 Cancel meeting. No sanity checking of input parameters, so don't call
715 this with input directly from untrusted source.
716 **************************************************************************/
717 static void really_diplomacy_cancel_meeting(struct player *pplayer,
718 struct player *pother)
720 struct Treaty *ptreaty = find_treaty(pplayer, pother);
722 if (ptreaty) {
723 dlsend_packet_diplomacy_cancel_meeting(pother->connections,
724 player_number(pplayer),
725 player_number(pplayer));
726 notify_player(pother, NULL, E_DIPLOMACY, ftc_server,
727 _("%s canceled the meeting!"),
728 player_name(pplayer));
729 /* Need to send to pplayer too, for multi-connects: */
730 dlsend_packet_diplomacy_cancel_meeting(pplayer->connections,
731 player_number(pother),
732 player_number(pplayer));
733 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
734 _("Meeting with %s canceled."),
735 player_name(pother));
736 treaty_list_remove(treaties, ptreaty);
737 clear_treaty(ptreaty);
738 free(ptreaty);
742 /**************************************************************************
743 Handle meeting cancelling request.
744 **************************************************************************/
745 void handle_diplomacy_cancel_meeting_req(struct player *pplayer,
746 int counterpart)
748 struct player *pother = player_by_number(counterpart);
750 if (NULL == pother || pplayer == pother) {
751 return;
754 really_diplomacy_cancel_meeting(pplayer, pother);
757 /**************************************************************************
758 Handle meeting opening request.
759 **************************************************************************/
760 void handle_diplomacy_init_meeting_req(struct player *pplayer,
761 int counterpart)
763 struct player *pother = player_by_number(counterpart);
765 if (NULL == pother || pplayer == pother) {
766 return;
769 if (find_treaty(pplayer, pother)) {
770 return;
773 if (get_player_bonus(pplayer, EFT_NO_DIPLOMACY)
774 || get_player_bonus(pother, EFT_NO_DIPLOMACY)) {
775 notify_player(pplayer, NULL, E_DIPLOMACY, ftc_server,
776 _("Your diplomatic envoy was decapitated!"));
777 return;
780 if (could_meet_with_player(pplayer, pother)) {
781 struct Treaty *ptreaty;
783 ptreaty = fc_malloc(sizeof(*ptreaty));
784 init_treaty(ptreaty, pplayer, pother);
785 treaty_list_prepend(treaties, ptreaty);
787 dlsend_packet_diplomacy_init_meeting(pplayer->connections,
788 player_number(pother),
789 player_number(pplayer));
790 dlsend_packet_diplomacy_init_meeting(pother->connections,
791 player_number(pplayer),
792 player_number(pplayer));
796 /**************************************************************************
797 Send information on any on-going diplomatic meetings for connection's
798 player. For re-connections.
799 **************************************************************************/
800 void send_diplomatic_meetings(struct connection *dest)
802 struct player *pplayer = dest->playing;
804 if (!pplayer) {
805 return;
807 players_iterate(other) {
808 struct Treaty *ptreaty = find_treaty(pplayer, other);
810 if (ptreaty) {
811 fc_assert_action(pplayer != other, continue);
812 dsend_packet_diplomacy_init_meeting(dest, player_number(other),
813 player_number(pplayer));
814 clause_list_iterate(ptreaty->clauses, pclause) {
815 dsend_packet_diplomacy_create_clause(dest,
816 player_number(other),
817 player_number(pclause->from),
818 pclause->type,
819 pclause->value);
820 } clause_list_iterate_end;
821 if (ptreaty->plr0 == pplayer) {
822 dsend_packet_diplomacy_accept_treaty(dest, player_number(other),
823 ptreaty->accept0,
824 ptreaty->accept1);
825 } else {
826 dsend_packet_diplomacy_accept_treaty(dest, player_number(other),
827 ptreaty->accept1,
828 ptreaty->accept0);
831 } players_iterate_end;
834 /**************************************************************************
835 Cancels all meetings of player.
836 **************************************************************************/
837 void cancel_all_meetings(struct player *pplayer)
839 players_iterate(pplayer2) {
840 if (find_treaty(pplayer, pplayer2)) {
841 really_diplomacy_cancel_meeting(pplayer, pplayer2);
843 } players_iterate_end;
846 /**************************************************************************
847 Reject all treaties currently being negotiated
848 **************************************************************************/
849 void reject_all_treaties(struct player *pplayer)
851 struct Treaty* treaty;
852 players_iterate(pplayer2) {
853 treaty = find_treaty(pplayer, pplayer2);
854 if (!treaty) {
855 continue;
857 treaty->accept0 = FALSE;
858 treaty->accept1 = FALSE;
859 dlsend_packet_diplomacy_accept_treaty(pplayer->connections,
860 player_number(pplayer2),
861 FALSE,
862 FALSE);
863 dlsend_packet_diplomacy_accept_treaty(pplayer2->connections,
864 player_number(pplayer),
865 FALSE,
866 FALSE);
867 } players_iterate_end;