Freeciv-3.3
Loading...
Searching...
No Matches
diplomats.c
Go to the documentation of this file.
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.
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 <stdio.h>
19
20/* utility */
21#include "bitvector.h"
22#include "fcintl.h"
23#include "log.h"
24#include "rand.h"
25
26/* common */
27#include "base.h"
28#include "combat.h"
29#include "events.h"
30#include "game.h"
31#include "government.h"
32#include "map.h"
33#include "movement.h"
34#include "player.h"
35#include "research.h"
36#include "unitlist.h"
37
38/* server */
39#include "actiontools.h"
40#include "aiiface.h"
41#include "citytools.h"
42#include "cityturn.h"
43#include "diplhand.h"
44#include "diplomats.h"
45#include "maphand.h"
46#include "notify.h"
47#include "plrhand.h"
48#include "techtools.h"
49#include "unithand.h"
50#include "unittools.h"
51
52/* server/scripting */
53#include "script_server.h"
54
55/****************************************************************************/
56
57static void diplomat_charge_movement (struct unit *pdiplomat,
58 struct tile *ptile);
59static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef,
60 struct tile *pdefender_tile,
61 int *att_vet, int *def_vet);
62static bool diplomat_may_lose_gold(struct player *dec_player,
63 struct player *inc_player,
64 int revolt_gold);
65static bool diplomat_infiltrate_tile(struct player *pplayer,
66 struct player *cplayer,
67 const struct action *paction,
68 struct unit *pdiplomat,
69 struct unit *pvictim,
70 struct tile *ptile,
71 struct player **defender_owner);
72static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
73 const struct city *pcity,
74 const struct action *paction);
75static void diplomat_escape_full(struct player *pplayer,
76 struct unit *pdiplomat,
77 bool city_related,
78 struct tile *ptile,
79 const char *vlink,
80 const struct action *paction);
81
82/************************************************************************/
97bool spy_poison(struct player *pplayer, struct unit *pdiplomat,
98 struct city *pcity, const struct action *paction)
99{
100 const struct unit_type *act_utype;
101 struct player *cplayer;
102 struct tile *ctile;
103 const char *clink;
104
105 /* Fetch target city's player. Sanity checks. */
109
110 /* Sanity check: The actor still exists. */
111 fc_assert_ret_val(pplayer, FALSE);
113
115
118
119 log_debug("poison: unit: %d", pdiplomat->id);
120
121 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
123 pdiplomat, NULL, ctile, NULL)) {
124 return FALSE;
125 }
126
127 log_debug("poison: infiltrated");
128
129 /* The Spy may get caught while trying to poison the city. */
131 paction)) {
133 /* TRANS: unit, action */
134 _("Your %s was caught attempting to do %s!"),
139 /* TRANS: nation, unit, action, city */
140 _("You caught %s %s attempting to do %s in %s!"),
144 clink);
145
146 /* This may cause a diplomatic incident */
149
150 /* Execute the caught Spy. */
152
153 return FALSE;
154 }
155
156 log_debug("poison: succeeded");
157
158 /* Poison people! */
159 if (city_reduce_size(pcity, 1, pplayer, "poison")) {
160 /* Notify everybody involved. */
162 _("Your %s poisoned the water supply of %s."),
166 _("%s is suspected of poisoning the water supply of %s."),
167 player_name(pplayer), clink);
168
170 /* The food was poisoned too. */
172 }
173
174 /* Update clients. */
177 } else {
178 /* Notify everybody involved. */
180 _("Your %s destroyed %s by poisoning its water supply."),
184 _("%s is suspected of destroying %s by poisoning its"
185 " water supply."),
186 player_name(pplayer), clink);
187 }
188
189 /* this may cause a diplomatic incident */
192
193 /* Now lets see if the spy survives. */
195
196 return TRUE;
197}
198
199/************************************************************************/
215 struct city *tgt_city, const struct action *paction)
216{
217 const struct unit_type *act_utype;
218 struct player *tgt_player;
219 struct tile *tgt_tile;
220
221 const char *tgt_city_link;
222
223 /* Sanity check: The actor still exists. */
227
228 /* Sanity check: The target city still exists. */
230
231 /* Who to infect. */
233
234 /* Sanity check: The target player still exists. */
236
239
240 log_debug("spread plague: unit: %d", act_unit->id);
241
242 /* Battle all units capable of diplomatic defense. */
244 paction,
246 return FALSE;
247 }
248
249 log_debug("spread plague: infiltrated");
250
251 /* The infector may get caught while trying to spread a plague in the
252 * city. */
254 paction)) {
256 /* TRANS: unit, action */
257 _("Your %s was caught attempting to do %s!"),
262 /* TRANS: nation, unit, action, city */
263 _("You caught %s %s attempting to do %s in %s!"),
268
269 /* This may cause a diplomatic incident */
272
273 /* Execute the caught infector. */
275
276 return FALSE;
277 }
278
279 log_debug("spread plague: succeeded");
280
281 /* Commit bio-terrorism. */
283 /* Update the clients. */
286 }
287
288 /* Notify everyone involved. */
291 /* TRANS: unit, action, city */
292 _("Your %s did %s to %s."),
297 /* TRANS: action, city, nation */
298 _("%s done to %s, %s suspected."),
301
302 /* This may cause a diplomatic incident. */
305
306 /* Try to escape. */
309
310 return TRUE;
311}
312
313/************************************************************************/
324bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
325 struct city *pcity,
326 const struct action *paction)
327{
328 struct player *cplayer;
334 struct trade_route_packet_list *routes;
335 const struct unit_type *act_utype;
337
338 /* Fetch target city's player. Sanity checks. */
342
343 /* Sanity check: The actor still exists. */
344 fc_assert_ret_val(pplayer, FALSE);
346
348
349 /* Sanity check: The target is foreign. */
350 if (cplayer == pplayer) {
351 /* Nothing to do to a domestic target. */
352 return FALSE;
353 }
354
355 log_debug("investigate: unit: %d", pdiplomat->id);
356
358
359 /* Do It... */
360 update_dumb_city(pplayer, pcity);
361 /* Special case for a diplomat/spy investigating a city:
362 The investigator needs to know the supported and present
363 units of a city, whether or not they are fogged. So, we
364 send a list of them all before sending the city info.
365 As this is a special case we bypass send_unit_info. */
366 unit_list_iterate(pcity->units_supported, punit) {
369 /* We need to force to send the packet to ensure the client will receive
370 * something (e.g. investigating twice). */
373 unit_list_iterate((pcity->tile)->units, punit) {
376 /* We need to force to send the packet to ensure the client will receive
377 * something (e.g. investigating twice). */
380 /* Send city info to investigator's player.
381 As this is a special case we bypass send_city_info(). */
382
383 if (any_web_conns()) {
385 } else {
386 webp_ptr = NULL;
387 }
388
391 webp_ptr, routes, TRUE);
392 /* We need to force to send the packet to ensure the client will receive
393 * something and popup the city dialog. */
394 city_packet.original = city_original_owner(pcity, pplayer);
404
405 /* This may cause a diplomatic incident */
408
409 /* The actor unit always survive unless the action it self has determined
410 * to always consume it. */
412 /* This unit isn't about to be consumed. Send updated unit information
413 * to the clients. */
415 }
416
418
419 return TRUE;
420}
421
422/************************************************************************/
430 struct city *pcity,
431 const struct action *paction,
432 int request_kind)
433{
434 struct packet_city_sabotage_list packet;
435
436 /* Send city improvements info to player. */
437 BV_CLR_ALL(packet.improvements);
438
440 /* Can see hidden buildings. */
444 }
446 } else {
447 /* Can't see hidden buildings. */
448 struct vision_site *plrcity;
449
451
452 if (plrcity == nullptr) {
453 /* Must know city to remember visible buildings. */
454 return;
455 }
456
458 if (BV_ISSET(plrcity->improvements, improvement_index(ptarget))
461 }
463 }
464
465 packet.actor_id = pdiplomat->id;
466 packet.city_id = pcity->id;
467 packet.act_id = paction->id;
468 packet.request_kind = request_kind;
470}
471
472/************************************************************************/
484bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
485 struct city *pcity, const struct action *paction)
486{
487 struct player *cplayer;
488 const struct unit_type *act_utype;
489
490 /* Fetch target city's player. Sanity checks. */
494
495 /* Sanity check: The actor still exists. */
496 fc_assert_ret_val(pplayer, FALSE);
498
500
501 /* Sanity check: The target is foreign. */
502 if (cplayer == pplayer) {
503 /* Nothing to do to a domestic target. */
504 return FALSE;
505 }
506
507 log_debug("embassy: unit: %d", pdiplomat->id);
508
509 log_debug("embassy: succeeded");
510
511 establish_embassy(pplayer, cplayer);
512
513 /* Notify everybody involved. */
514 notify_player(pplayer, city_tile(pcity),
516 _("You have established an embassy in %s."),
520 _("The %s have established an embassy in %s."),
523
524 /* this may cause a diplomatic incident */
527
528 /* The actor unit always survive unless the action it self has determined
529 * to always consume it. */
531 /* This unit isn't about to be consumed. Send updated unit information
532 * to the clients. */
534 }
535
536 return TRUE;
537}
538
539/************************************************************************/
549bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat,
550 struct unit *pvictim,
551 const struct action *paction)
552{
554 struct player *uplayer;
555 const struct unit_type *act_utype;
556
557 /* Fetch target unit's player. Sanity checks. */
561
562 /* Sanity check: The actor still exists. */
563 fc_assert_ret_val(pplayer, FALSE);
565
567
568 log_debug("sabotage-unit: unit: %d", pdiplomat->id);
569
570 /* N.B: unit_link() always returns the same pointer. */
572
573 /* Diplomatic battle against any diplomatic defender except the intended
574 * victim of the sabotage. */
575 if (!diplomat_infiltrate_tile(pplayer, uplayer,
576 paction,
579 NULL)) {
580 return FALSE;
581 }
582
583 log_debug("sabotage-unit: succeeded");
584
585 if (pvictim->hp < 2) {
586 /* Not possible to halve the hit points. Kill it. */
587 wipe_unit(pvictim, ULR_KILLED, pplayer);
588
589 /* Notify everybody involved. */
592 _("Your %s's successful sabotage killed the %s %s."),
598 /* TRANS: ... the Poles! */
599 _("Your %s was killed by %s sabotage!"),
601 nation_plural_for_player(pplayer));
602 } else {
603 /* Sabotage the unit by removing half its remaining hit points. */
604 pvictim->hp /= 2;
606
607 /* Notify everybody involved. */
610 _("Your %s succeeded in sabotaging the %s %s."),
616 /* TRANS: ... the Poles! */
617 _("Your %s was sabotaged by the %s!"),
619 nation_plural_for_player(pplayer));
620 }
621
622 /* this may cause a diplomatic incident */
625
626 /* Now lets see if the spy survives. */
628
629 return TRUE;
630}
631
632/************************************************************************/
644bool diplomat_bribe_unit(struct player *pplayer, struct unit *pdiplomat,
645 struct unit *pvictim, const struct action *paction)
646{
648 struct player *uplayer;
649 struct tile *victim_tile;
650 int bribe_cost;
651 int diplomat_id;
652 const struct unit_type *act_utype, *victim_type;
653 struct city *pcity;
654 bool bounce;
655
656 /* Fetch target unit's player. Sanity checks. */
661
662 /* Sanity check: The actor still exists. */
663 fc_assert_ret_val(pplayer, FALSE);
666
668
669 /* Sanity check: The target is foreign. */
670 if (uplayer == pplayer) {
671 /* Nothing to do to a domestic target. */
672 return FALSE;
673 }
674
675 /* Sanity check: The victim isn't a unique unit the actor player already
676 * has. */
679 FALSE,
680 "bribe-unit: already got unique unit");
681
682 log_debug("bribe-unit: unit: %d", pdiplomat->id);
683
684 /* Get bribe cost, ignoring any previously saved value. */
686
687 /* If player doesn't have enough gold, can't bribe. */
688 if (pplayer->economic.gold < bribe_cost) {
691 _("You don't have enough gold to bribe the %s %s."),
694 log_debug("bribe-unit: not enough gold");
695 return FALSE;
696 }
697
698 log_debug("bribe-unit: enough gold");
699
700 /* Diplomatic battle against any diplomatic defender except the one that
701 * will get the bribe. */
702 if (!diplomat_infiltrate_tile(pplayer, uplayer,
703 paction,
705 pvictim->tile,
706 NULL)) {
707 return FALSE;
708 }
709
710 log_debug("bribe-unit: succeeded");
711
713 pvictim = unit_change_owner(pvictim, pplayer, pdiplomat->homecity,
714 ULR_BRIBED);
715
716 if (pvictim) {
717 /* N.B.: unit_link always returns the same pointer. As unit_change_owner()
718 * currently remove the old unit and replace by a new one (with a new id),
719 * we want to make link to the new unit. */
721 } else {
723 }
724
726 /* Destroyed by a script */
727 pdiplomat = NULL;
728 }
729
730 /* Notify everybody involved. */
732 /* TRANS: <diplomat> ... <unit> */
733 _("Your %s succeeded in bribing the %s."),
738 }
740 /* TRANS: <unit> ... <Poles> */
741 _("Your %s was bribed by the %s."),
743
744 if (pvictim) {
745 /* The unit may have been on a tile shared with a city or a unit
746 * it no longer can share a tile with. */
748 bounce = ((NULL != pcity
750 /* Keep the old behavior (insto check is_non_allied_unit_tile) */
751 || 1 < unit_list_size(unit_tile(pvictim)->units));
752 if (bounce) {
754 }
755 } else {
756 bounce = FALSE;
757 }
758
759 /* This costs! */
760 pplayer->economic.gold -= bribe_cost;
761 if (pplayer->economic.gold < 0) {
762 /* Scripts have deprived us of too much gold before we paid */
763 log_normal("%s has bribed %s but has not %d gold at payment time, "
764 "%d is the discount", player_name(pplayer),
766 -pplayer->economic.gold);
767 pplayer->economic.gold = 0;
768 }
769
770 /* This may cause a diplomatic incident */
773
775 return TRUE;
776 }
777
778 /* Try to move the briber onto the victim's square unless the victim has
779 * been bounced because it couldn't share tile with a unit or city. */
780 if (!bounce
781 /* Try to perform post move forced actions. */
785 pvictim, NULL))
786 /* May have died while trying to do forced actions. */
788 pdiplomat->moves_left = 0;
789 }
790 if (NULL != player_unit_by_number(pplayer, diplomat_id)) {
792 }
793
794 /* Update clients. */
795 send_player_all_c(pplayer, NULL);
796
797 return TRUE;
798}
799
800/************************************************************************/
812bool diplomat_bribe_stack(struct player *pplayer, struct unit *pdiplomat,
813 struct tile *pvictim, const struct action *paction)
814{
815 int bribe_cost = 0;
816 int bribe_count = 0;
817 struct city *pcity;
818 bool bounce = FALSE;
819 int diplomat_id = pdiplomat->id;
820 const struct unit_type *act_utype;
821
823 struct player *owner = unit_owner(pbribed);
824
825 if (!pplayers_at_war(pplayer, owner)) {
828 _("You are not in war with all the units in the stack."));
829 return FALSE;
830 }
832
834
835 /* If player doesn't have enough gold, can't bribe. */
836 if (pplayer->economic.gold < bribe_cost) {
839 _("You don't have enough gold to bribe the unit stack."));
840 log_debug("bribe-stack: not enough gold");
841 return FALSE;
842 }
843
845 if (pcity != NULL && !pplayers_allied(city_owner(pcity), pplayer)) {
846 bounce = TRUE;
847 }
848
850 struct player *owner = unit_owner(pbribed);
851 struct unit *nunit = unit_change_owner(pbribed, pplayer,
852 pdiplomat->homecity, ULR_BRIBED);
853
855 /* TRANS: <unit> ... <Poles> */
856 _("Your %s was bribed by the %s."),
858 bribe_count++;
859
860 if (bounce) {
862 }
864
866 /* Destroyed by a script */
867 pdiplomat = NULL;
868 }
869
871
872 /* Notify everybody involved. */
874 /* TRANS: <diplomat> ... */
875 _("Your %s succeeded in bribing %d units."),
880 }
881
882 /* This costs! */
883 pplayer->economic.gold -= bribe_cost;
884 if (pplayer->economic.gold < 0) {
885 /* Scripts have deprived us of too much gold before we paid */
886 log_normal("%s has bribed %d units but has not %d gold at payment time, "
887 "%d is the discount", player_name(pplayer),
889 -pplayer->economic.gold);
890 pplayer->economic.gold = 0;
891 }
892
894 return TRUE;
895 }
896
897 /* Try to move the briber onto the victim's square unless the victim has
898 * been bounced because it couldn't share tile with a unit or city. */
899 if (!bounce
900 /* Try to perform post move forced actions. */
902 NULL, NULL, paction,
903 pvictim, pcity,
904 NULL, NULL))
905 /* May have died while trying to do forced actions. */
907 pdiplomat->moves_left = 0;
908 }
909 if (NULL != player_unit_by_number(pplayer, diplomat_id)) {
911 }
912
913 /* Update clients. */
914 send_player_all_c(pplayer, NULL);
915
916 return TRUE;
917}
918
919/************************************************************************/
928 struct tile *tgt_tile, const struct action *paction)
929{
930 int act_unit_id;
931 struct player *tgt_player = NULL;
932 const struct unit_type *act_utype;
933
934 /* Sanity check: The actor still exists. */
937
939 act_unit_id = act_unit->id;
940
941 /* Do the diplomatic battle against a diplomatic defender. */
943 paction,
945 &tgt_player);
946
947 /* Sanity check: the defender had an owner. */
949
951 /* action_consequence_caught() is handled in
952 * diplomat_infiltrate_tile() */
953
954 /* The action was to start a diplomatic battle. */
955 return TRUE;
956 }
957
958 /* This may cause a diplomatic incident. */
961
962 /* The action was to start a diplomatic battle. */
963 return TRUE;
964}
965
966/************************************************************************/
971 struct city *pcity)
972{
973 int times;
975
976 if (bonus < 0) {
977 /* Negative effect value means infinite bonus */
978 times = 0;
979 } else {
980 times = pcity->steal - bonus;
981 if (times < 0) {
982 times = 0;
983 }
984 }
985
986 return times;
987}
988
989/************************************************************************/
1011bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat,
1012 struct city *pcity, Tech_type_id technology,
1013 const struct action *paction)
1014{
1015 struct research *presearch, *cresearch;
1016 struct player *cplayer;
1017 const struct unit_type *act_utype;
1018 int count;
1019 int times;
1021 bool expected_kills;
1022
1023 /* We have to check arguments. They are sent to us by a client,
1024 so we cannot trust them */
1028
1029 /* Sanity check: The actor still exists. */
1030 fc_assert_ret_val(pplayer, FALSE);
1032
1034
1035 /* Sanity check: The target is foreign. */
1036 if (cplayer == pplayer) {
1037 /* Nothing to do to a domestic target. */
1038 return FALSE;
1039 }
1040
1041 /* Currently based on if unit is consumed or not. */
1044
1046 /* Can't choose target. Will steal a random tech. */
1047 technology = A_UNSET;
1048 }
1049
1050 /* Targeted technology should be a ruleset defined tech,
1051 * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
1052 if (technology == A_NONE
1053 || (technology != A_FUTURE
1054 && !(technology == A_UNSET
1056 && !valid_advance_by_number(technology))) {
1057 return FALSE;
1058 }
1059
1060 presearch = research_get(pplayer);
1062
1063 if (technology == A_FUTURE) {
1064 if (presearch->future_tech >= cresearch->future_tech) {
1065 return FALSE;
1066 }
1067 } else if (technology != A_UNSET) {
1068 if (research_invention_state(presearch, technology) == TECH_KNOWN) {
1069 return FALSE;
1070 }
1071 if (research_invention_state(cresearch, technology) != TECH_KNOWN) {
1072 return FALSE;
1073 }
1074 if (!research_invention_gettable(presearch, technology,
1076 return FALSE;
1077 }
1078 }
1079
1080 log_debug("steal-tech: unit: %d", pdiplomat->id);
1081
1082 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1083 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1084 paction,
1085 pdiplomat, NULL,
1086 pcity->tile,
1087 NULL)) {
1088 return FALSE;
1089 }
1090
1091 log_debug("steal-tech: infiltrated");
1092
1094
1095 /* Check if the Diplomat/Spy succeeds with their task. */
1096 /* (Twice as difficult if target is specified.) */
1097 /* (If already stolen from, impossible for Diplomats and harder for Spies.) */
1098 if (times > 0 && expected_kills) {
1099 /* Already stolen from: Diplomat always fails! */
1100 count = 1;
1101 log_debug("steal-tech: difficulty: impossible");
1102 } else {
1103 /* Determine difficulty. */
1104 count = 1;
1106 /* Targeted steal tech is more difficult. */
1107 count++;
1108 }
1109 count += times;
1110 log_debug("steal-tech: difficulty: %d", count);
1111 /* Determine success or failure. */
1112 while (count > 0) {
1114 paction)) {
1115 break;
1116 }
1117 count--;
1118 }
1119 }
1120
1121 if (count > 0) {
1122 /* Failed to steal a tech. */
1123 if (times > 0 && expected_kills) {
1124 notify_player(pplayer, city_tile(pcity),
1126 /* TRANS: Paris was expecting ... Your Spy was caught */
1127 _("%s was expecting your attempt to steal technology "
1128 "again. Your %s was caught and executed."),
1133 /* TRANS: The Belgian Spy ... from Paris */
1134 _("The %s %s failed to steal technology again from %s. "
1135 "We were prepared for the attempt."),
1138 city_link(pcity));
1139 } else {
1140 notify_player(pplayer, city_tile(pcity),
1142 /* TRANS: Your Spy was caught ... from %s. */
1143 _("Your %s was caught in the attempt of"
1144 " stealing technology from %s."),
1146 city_link(pcity));
1149 /* TRANS: The Belgian Spy ... from Paris */
1150 _("The %s %s failed to steal technology from %s."),
1153 city_link(pcity));
1154 }
1155
1156 /* This may cause a diplomatic incident */
1160 return FALSE;
1161 }
1162
1163 tech_stolen = steal_a_tech(pplayer, cplayer, technology);
1164
1165 if (tech_stolen == A_NONE) {
1166 notify_player(pplayer, city_tile(pcity),
1168 _("No new technology found in %s."),
1169 city_link(pcity));
1172 return FALSE;
1173 }
1174
1175 /* Update stealing player's science progress and research fields */
1176 send_player_all_c(pplayer, NULL);
1177
1178 /* Record the theft. */
1179 (pcity->steal)++;
1180
1181 /* this may cause a diplomatic incident */
1184
1185 /* Check if a spy survives her mission. */
1187
1188 return TRUE;
1189}
1190
1191/************************************************************************/
1202 int revolt_gold)
1203{
1205 return FALSE;
1206 }
1207
1208 /* Roll the dice. */
1211 PL_("Your %d gold prepared to incite the revolt was lost!",
1212 "Your %d gold prepared to incite the revolt was lost!",
1214 dec_player->economic.gold -= revolt_gold;
1215 /* Lost money was pocketed by fraudulent executioners?
1216 * Or returned to local authority?
1217 * Roll the dice twice. */
1219 inc_player->economic.gold += revolt_gold;
1221 ftc_server,
1222 PL_("Your security service captured %d gold prepared "
1223 "to incite your town!",
1224 "Your security service captured %d gold prepared "
1225 "to incite your town!", revolt_gold), revolt_gold);
1226 }
1227 /* Update clients. */
1230
1231 return TRUE;
1232 } else {
1233 return FALSE;
1234 }
1235}
1236
1237/************************************************************************/
1255bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat,
1256 struct city *pcity, const struct action *paction)
1257{
1258 struct player *cplayer;
1259 struct tile *ctile;
1260 const char *clink;
1261 int revolt_cost;
1262 const struct unit_type *act_utype;
1263
1264 /* Fetch target civilization's player. Sanity checks. */
1268
1269 /* Sanity check: The actor still exists. */
1270 fc_assert_ret_val(pplayer, FALSE);
1272
1273 /* Sanity check: The target is foreign. */
1274 if (cplayer == pplayer) {
1275 /* Nothing to do to a domestic target. */
1276 return FALSE;
1277 }
1278
1280
1283
1284 log_debug("incite: unit: %d", pdiplomat->id);
1285
1286 /* Get incite cost, ignoring any previously saved value. */
1288
1289 /* If player doesn't have enough gold, can't incite a revolt. */
1290 if (pplayer->economic.gold < revolt_cost) {
1292 _("You don't have enough gold to subvert %s."),
1293 clink);
1294 log_debug("incite: not enough gold");
1295 return FALSE;
1296 }
1297
1298 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1299 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1300 paction,
1301 pdiplomat, NULL,
1302 pcity->tile,
1303 NULL)) {
1305 return FALSE;
1306 }
1307
1308 log_debug("incite: infiltrated");
1309
1310 /* Check if the Diplomat/Spy succeeds with their task. */
1312 paction)) {
1314 _("Your %s was caught in the attempt"
1315 " of inciting a revolt!"),
1318 _("You caught %s %s attempting"
1319 " to incite a revolt in %s!"),
1322 clink);
1323
1325
1326 /* This may cause a diplomatic incident */
1328 cplayer, ctile, clink);
1329
1331 return FALSE;
1332 }
1333
1334 log_debug("incite: succeeded");
1335
1336 /* Subvert the city to your cause... */
1337
1338 /* City loses some population. */
1339 if (city_size_get(pcity) > 1) {
1340 city_reduce_size(pcity, 1, pplayer, "incited");
1341 }
1342
1343 /* This costs! */
1344 pplayer->economic.gold -= revolt_cost;
1345
1346 /* Notify everybody involved. */
1348 _("Revolt incited in %s, you now rule the city!"),
1349 clink);
1351 _("%s has revolted, %s influence suspected."),
1352 clink,
1354
1355 pcity->shield_stock = 0;
1357
1358 /* You get a technology advance, too! */
1359 steal_a_tech(pplayer, cplayer, A_UNSET);
1360
1361 /* this may cause a diplomatic incident */
1363 cplayer, ctile, clink);
1364
1365 /* Transfer city and units supported by this city (that
1366 are within one square of the city) to the new owner. */
1367 if (transfer_city(pplayer, pcity, 1, TRUE, TRUE, FALSE,
1368 !is_barbarian(pplayer))) {
1369 script_server_signal_emit("city_transferred", pcity, cplayer, pplayer,
1370 "incited");
1371 }
1372
1373 /* Check if a spy survives her mission.
1374 * _After_ transferring the city, or the city area is first fogged
1375 * when the diplomat is removed, and then unfogged when the city
1376 * is transferred. */
1378
1379 /* Update the players gold in the client */
1380 send_player_info_c(pplayer, pplayer->connections);
1381
1382 return TRUE;
1383}
1384
1385/************************************************************************/
1404bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat,
1405 struct city *pcity, Impr_type_id improvement,
1406 const struct action *paction)
1407{
1408 struct player *cplayer;
1409 struct impr_type *ptarget;
1410 int count, which;
1411 const struct unit_type *act_utype;
1412
1413 /* Fetch target city's player. Sanity checks. */
1417
1418 /* Sanity check: The actor still exists. */
1419 fc_assert_ret_val(pplayer, FALSE);
1421
1423
1424 log_debug("sabotage: unit: %d", pdiplomat->id);
1425
1426 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1427 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1428 paction,
1429 pdiplomat, NULL,
1430 pcity->tile,
1431 NULL)) {
1432 return FALSE;
1433 }
1434
1435 log_debug("sabotage: infiltrated");
1436
1437 /* Check if the Diplomat/Spy succeeds with their task. */
1439 paction)) {
1440 notify_player(pplayer, city_tile(pcity),
1442 _("Your %s was caught in the attempt"
1443 " of industrial sabotage!"),
1447 _("You caught %s %s attempting sabotage in %s!"),
1450 city_link(pcity));
1451
1452 /* This may cause a diplomatic incident */
1455
1457 return FALSE;
1458 }
1459
1460 log_debug("sabotage: succeeded");
1461
1462 /* Examine the city for improvements to sabotage. */
1463 count = 0;
1464 city_built_iterate(pcity, pimprove) {
1465 if (pimprove->sabotage > 0) {
1466 count++;
1467 }
1469
1470 log_debug("sabotage: count of improvements: %d", count);
1471
1472 /* Determine the target (-1 is production). */
1474 /*
1475 * Pick random:
1476 * 50/50 chance to pick production or some improvement.
1477 * Won't pick something that doesn't exit.
1478 * If nothing to do, say so, deduct movement cost and return.
1479 */
1480 if (count == 0 && pcity->shield_stock == 0) {
1481 notify_player(pplayer, city_tile(pcity),
1483 _("Your %s could not find anything to sabotage in %s."),
1485 city_link(pcity));
1488 log_debug("sabotage: random: nothing to do");
1489 return FALSE;
1490 }
1491 if (count == 0 || fc_rand (2) == 1) {
1492 ptarget = NULL;
1493 log_debug("sabotage: random: targeted production");
1494 } else {
1495 ptarget = NULL;
1496 which = fc_rand (count);
1497
1498 city_built_iterate(pcity, pimprove) {
1499 if (pimprove->sabotage > 0) {
1500 if (which > 0) {
1501 which--;
1502 } else {
1503 ptarget = pimprove;
1504 break;
1505 }
1506 }
1508
1509 if (NULL != ptarget) {
1510 log_debug("sabotage: random: targeted improvement: %d (%s)",
1513 } else {
1514 log_error("sabotage: random: targeted improvement error!");
1515 }
1516 }
1517 } else if (improvement < 0) {
1518 /* If told to sabotage production, do so. */
1519 ptarget = NULL;
1520 log_debug("sabotage: specified target production");
1521 } else {
1522 struct impr_type *pimprove = improvement_by_number(improvement);
1523 if (pimprove == NULL) {
1524 log_error("sabotage: requested for invalid improvement %d", improvement);
1525 return FALSE;
1526 }
1527 /*
1528 * Told which improvement to pick:
1529 * If try for wonder or palace, complain, deduct movement cost and return.
1530 * If not available, say so, deduct movement cost and return.
1531 */
1532 if (city_has_building(pcity, pimprove)) {
1533 if (pimprove->sabotage > 0) {
1534 ptarget = pimprove;
1535 log_debug("sabotage: specified target improvement: %d (%s)",
1536 improvement, improvement_rule_name(pimprove));
1537 } else {
1538 notify_player(pplayer, city_tile(pcity),
1540 _("You cannot sabotage a %s!"),
1544 log_debug("sabotage: disallowed target improvement: %d (%s)",
1545 improvement, improvement_rule_name(pimprove));
1546 return FALSE;
1547 }
1548 } else {
1549 notify_player(pplayer, city_tile(pcity),
1551 _("Your %s could not find the %s to sabotage in %s."),
1554 city_link(pcity));
1557 log_debug("sabotage: target improvement not found: %d (%s)",
1558 improvement, improvement_rule_name(pimprove));
1559 return FALSE;
1560 }
1561 }
1562
1563 /* Now, the fun stuff! Do the sabotage! */
1564 if (NULL == ptarget) {
1565 char prod[256];
1566
1567 /* Do it. */
1568 pcity->shield_stock = 0;
1569 nullify_prechange_production(pcity); /* Make it impossible to recover */
1570
1571 /* Report it. */
1572 universal_name_translation(&pcity->production, prod, sizeof(prod));
1573
1574 notify_player(pplayer, city_tile(pcity),
1576 _("Your %s succeeded in destroying"
1577 " the production of %s in %s."),
1579 prod,
1583 _("The production of %s was destroyed in %s,"
1584 " %s are suspected."),
1585 prod,
1587 nation_plural_for_player(pplayer));
1588 log_debug("sabotage: sabotaged production");
1589 } else {
1590 int vulnerability = ptarget->sabotage;
1591
1592 /* Sabotage a city improvement. */
1593
1594 /*
1595 * One last chance to get caught:
1596 * If target was specified, and it is in the capital or are
1597 * City Walls, then there is a 50% chance of getting caught.
1598 */
1601 / 100);
1602
1603 if (fc_rand(100) >= vulnerability) {
1604 /* Caught! */
1605 notify_player(pplayer, city_tile(pcity),
1607 _("Your %s was caught in the attempt of sabotage!"),
1611 _("You caught %s %s attempting"
1612 " to sabotage the %s in %s!"),
1616 city_link(pcity));
1617
1618 /* This may cause a diplomatic incident */
1621
1623 log_debug("sabotage: caught in capital or on city walls");
1624 return FALSE;
1625 }
1626
1627 /* Report it. */
1628 notify_player(pplayer, city_tile(pcity),
1630 _("Your %s destroyed the %s in %s."),
1633 city_link(pcity));
1636 _("The %s destroyed the %s in %s."),
1637 nation_plural_for_player(pplayer),
1639 city_link(pcity));
1640 log_debug("sabotage: sabotaged improvement: %d (%s)",
1643
1644 /* Do it. */
1645 building_lost(pcity, ptarget, "sabotaged", pdiplomat);
1646
1647 /* FIXME: Lua script might have destroyed the diplomat, the city, or even the player.
1648 * Avoid dangling pointers below in that case. */
1649 }
1650
1651 /* Update clients. */
1653
1654 /* this may cause a diplomatic incident */
1657
1658 /* Check if a spy survives her mission. */
1660
1661 return TRUE;
1662}
1663
1664/************************************************************************/
1677 struct city *tgt_city, const struct action *paction)
1678{
1679 struct player *tgt_player;
1680 struct tile *tgt_tile;
1681
1682 const char *tgt_city_link;
1683
1684 int gold_take;
1685 int gold_give;
1686 const struct unit_type *act_utype;
1687
1688 /* Sanity check: The actor still exists. */
1691
1693
1694 /* Sanity check: The target city still exists. */
1696
1697 /* Who to steal from. */
1699
1700 /* Sanity check: The target player still exists. */
1702
1703 /* Sanity check: The target is foreign. */
1704 if (tgt_player == act_player) {
1705 /* Nothing to do to a domestic target. */
1706 return FALSE;
1707 }
1708
1709 /* Sanity check: There is something to steal. */
1710 if (tgt_player->economic.gold <= 0) {
1711 return FALSE;
1712 }
1713
1716
1717 log_debug("steal gold: unit: %d", act_unit->id);
1718
1719 /* Battle all units capable of diplomatic defense. */
1721 paction,
1723 NULL)) {
1724 return FALSE;
1725 }
1726
1727 log_debug("steal gold: infiltrated");
1728
1729 /* The thief may get caught while trying to steal the gold. */
1731 paction)) {
1733 _("Your %s was caught attempting to steal gold!"),
1736 ftc_server,
1737 /* TRANS: nation, unit, city */
1738 _("You caught %s %s attempting"
1739 " to steal your gold in %s!"),
1743
1744 /* This may cause a diplomatic incident */
1747
1748 /* Execute the caught thief. */
1750
1751 return FALSE;
1752 }
1753
1754 log_debug("steal gold: succeeded");
1755
1756 /* The upper limit on how much gold the thief can steal. */
1757 gold_take = (tgt_player->economic.gold
1759 / 1000;
1760
1761 /* How much to actually take. 1 gold is the smallest amount that can be
1762 * stolen. The victim player has at least 1 gold. If they didn't, the
1763 * something to steal sanity check would have aborted the theft. */
1765
1766 log_debug("steal gold: will take %d gold", gold_take);
1767
1768 /* Steal the gold. */
1769 tgt_player->economic.gold -= gold_take;
1770
1771 /* Some gold may be lost during transfer. */
1774 / 1000;
1775
1776 log_debug("steal gold: will give %d gold", gold_give);
1777
1778 /* Pocket the stolen money. */
1779 act_player->economic.gold += gold_give;
1780
1781 /* Notify everyone involved. */
1783 /* TRANS: unit, gold, city */
1784 PL_("Your %s stole %d gold from %s.",
1785 "Your %s stole %d gold from %s.", gold_give),
1788 /* TRANS: gold, city, nation */
1789 PL_("%d gold stolen from %s, %s suspected.",
1790 "%d gold stolen from %s, %s suspected.", gold_take),
1793
1794 /* This may cause a diplomatic incident. */
1797
1798 /* Try to escape. */
1801
1802 /* Update the players' gold in the client */
1805
1806 return TRUE;
1807}
1808
1809/************************************************************************/
1819 struct city *tgt_city,
1820 const struct action *paction)
1821{
1822 struct player *tgt_player;
1823 struct tile *tgt_tile;
1824 const struct unit_type *act_utype;
1825
1826 int normal_tile_prob;
1827
1828 const char *tgt_city_link;
1829
1830 /* Sanity check: The actor still exists. */
1833
1835
1836 /* Sanity check: The target city still exists. */
1838
1839 /* Who to steal from. */
1841
1842 /* Sanity check: The target player still exists. */
1844
1845 /* Sanity check: The target is foreign. */
1846 if (tgt_player == act_player) {
1847 /* Nothing to do to a domestic target. */
1848 return FALSE;
1849 }
1850
1853
1854 log_debug("steal some maps: unit: %d", act_unit->id);
1855
1856 /* Battle all units capable of diplomatic defense. */
1858 paction,
1860 NULL)) {
1861 return FALSE;
1862 }
1863
1864 log_debug("steal some maps: infiltrated");
1865
1866 /* Try to steal the map. */
1868 paction)) {
1870 _("Your %s was caught in an attempt of"
1871 " stealing parts of the %s world map!"),
1875 ftc_server,
1876 _("You caught %s %s attempting to steal"
1877 " parts of your world map in %s!"),
1881
1882 /* This may cause a diplomatic incident. */
1885
1886 /* Execute the caught thief. */
1888
1889 return FALSE;
1890 }
1891
1892 log_debug("steal some maps: succeeded");
1893
1894 /* Steal it. */
1895 normal_tile_prob = 100
1897 &(const struct req_context) {
1898 .player = act_player,
1899 /* City: Decide once requests from ruleset
1900 * authors arrive. Could be target city or
1901 * - with a refactoring - the city at the
1902 * tile that may be transferred. */
1903 /* Tile: Decide once requests from ruleset
1904 * authors arrive. Could be actor unit
1905 * tile, target city tile or even - with a
1906 * refactoring - the tile that may be
1907 * transferred. */
1908 .unit = act_unit,
1909 .unittype = unit_type_get(act_unit),
1910 .action = paction,
1911 },
1912 &(const struct req_context) {
1913 .player = tgt_player,
1914 },
1918 /* Could - with a refactoring where EFT_MAPS_STOLEN_PCT
1919 * is evaulated for each tile and the city sent to it
1920 * is the tile to transfer's city - be moved into
1921 * EFT_MAPS_STOLEN_PCT. */
1923
1924 /* Notify everyone involved. */
1926 _("Your %s stole parts of the %s world map in %s."),
1931 _("The %s are suspected of stealing"
1932 " parts of your world map in %s."),
1935
1936 /* This may cause a diplomatic incident. */
1939
1940 /* Try to escape. */
1943
1944 return TRUE;
1945}
1946
1947/************************************************************************/
1957 struct city *tgt_city, const struct action *paction)
1958{
1959 struct player *tgt_player;
1960 struct tile *tgt_tile;
1961
1962 const char *tgt_city_link;
1963 const struct unit_type *act_utype;
1964
1965 /* Sanity check: The actor still exists. */
1968
1970
1971 /* Sanity check: The target city still exists. */
1973
1974 /* The victim. */
1976
1977 /* Sanity check: The target player still exists. */
1979
1982
1983 log_debug("suitcase nuke: unit: %d", act_unit->id);
1984
1985 /* Battle all units capable of diplomatic defense. */
1987 paction,
1989 NULL)) {
1990 return FALSE;
1991 }
1992
1993 log_debug("suitcase nuke: infiltrated");
1994
1995 /* Try to hide the nuke. */
1997 paction)) {
1999 _("Your %s was caught in an attempt of"
2000 " hiding a nuke in %s!"),
2004 ftc_server,
2005 _("You caught %s %s attempting to hide a nuke in %s!"),
2009
2010 /* This may cause a diplomatic incident. */
2013
2014 /* Execute the caught terrorist. */
2016
2017 return FALSE;
2018 }
2019
2020 log_debug("suitcase nuke: succeeded");
2021
2022 /* Notify everyone involved. */
2024 _("Your %s hid a nuke in %s."),
2028 _("The %s are suspected of hiding a nuke in %s."),
2031
2032 /* Try to escape before the blast. */
2035
2037 /* The unit must be wiped here so it won't be seen as a victim of the
2038 * detonation of its own nuke. */
2040 }
2041
2042 /* Detonate the nuke. */
2045
2046 /* This may cause a diplomatic incident. */
2049
2050 return TRUE;
2051}
2052
2053/************************************************************************/
2056static void diplomat_charge_movement(struct unit *pdiplomat, struct tile *ptile)
2057{
2058 pdiplomat->moves_left -=
2059 map_move_cost_unit(&(wld.map), pdiplomat, ptile);
2060 if (pdiplomat->moves_left < 0) {
2061 pdiplomat->moves_left = 0;
2062 }
2063}
2064
2065/************************************************************************/
2073 struct unit *pdefender,
2074 struct tile *pdefender_tile,
2075 int *att_vet, int *def_vet)
2076{
2077 int chance = 50; /* Base 50% chance */
2078
2079 /* There's no challenge for the SuperSpy to gain veterancy from,
2080 * i.e. no veterancy if we exit early in next couple of checks. */
2081 *att_vet = 0;
2082 *def_vet = 0;
2083
2085 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
2086 return FALSE;
2087 }
2089 /* An attacking UTYF_SUPERSPY will defeat every possible defender
2090 * except another UTYF_SUPERSPY. */
2091 return TRUE;
2092 }
2093
2094 /* Add or remove 25% if spy flag. */
2096 chance += 25;
2097 }
2099 chance -= 25;
2100 }
2101
2102 /* Use power_fact from veteran level to modify chance in a linear way.
2103 * Equal veteran levels cancel out.
2104 * It's probably not good for rulesets to allow this to have more than
2105 * 20% effect. */
2106 {
2107 const struct veteran_level
2109 const struct veteran_level
2111
2113
2114 chance += vatt->power_fact - vdef->power_fact;
2115 }
2116
2117 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
2119 NULL,
2120 &(const struct req_context) {
2121 .player = tile_owner(pdefender_tile),
2122 .city = tile_city(pdefender_tile),
2124 },
2125 NULL,
2127 ) / 100;
2128
2129 chance = CLIP(0, chance, 100);
2130
2131 /* In a combat between equal strength units the values are 50% / 50%.
2132 * -> scaling that to 100% by doubling, to match scale of chances
2133 * in existing rulesets, and in !combat_odds_scaled_veterancy case. */
2134 *att_vet = (100 - chance) * 2;
2135 *def_vet = chance * 2;
2136
2137 return (int)fc_rand(100) < chance;
2138}
2139
2140/************************************************************************/
2156static bool diplomat_infiltrate_tile(struct player *pplayer,
2157 struct player *cplayer,
2158 const struct action *paction,
2159 struct unit *pdiplomat,
2160 struct unit *pvictim,
2161 struct tile *ptile,
2162 struct player **defender_owner)
2163{
2164 struct unit *punit;
2165 char link_city[MAX_LEN_LINK] = "";
2167 char link_unit[MAX_LEN_LINK];
2168 struct city *pcity = tile_city(ptile);
2169 const struct unit_type *act_utype = unit_type_get(pdiplomat);
2170 int att_vet;
2171 int def_vet;
2172
2173 if (pcity) {
2174 /* N.B.: *_link() always returns the same pointer. */
2176 }
2177
2179 paction))) {
2180 struct player *uplayer = unit_owner(punit);
2181
2182 if (defender_owner != NULL) {
2183 /* Some action performers may want to know defender player. */
2185 }
2186
2188 &att_vet, &def_vet)) {
2189 /* Defending Spy/Diplomat dies. */
2190
2191 /* N.B.: *_link() always returns the same pointer. */
2194
2196 /* TRANS: <unit> ... <diplomat> */
2197 _("An enemy %s has been eliminated by your %s."),
2199
2200 if (pcity) {
2201 if (uplayer == cplayer || cplayer == NULL) {
2203 /* TRANS: <unit> ... <city> ... <diplomat> */
2204 _("Your %s has been eliminated defending %s"
2205 " against a %s."), link_unit, link_city,
2207 } else {
2209 /* TRANS: <nation adj> <unit> ... <city>
2210 * TRANS: ... <diplomat> */
2211 _("A %s %s has been eliminated defending %s "
2212 "against a %s."),
2216 /* TRANS: ... <unit> ... <nation adj> <city>
2217 * TRANS: ... <diplomat> */
2218 _("Your %s has been eliminated defending %s %s "
2219 "against a %s."), link_unit,
2222 }
2223 } else {
2224 if (uplayer == cplayer || cplayer == NULL) {
2226 /* TRANS: <unit> ... <diplomat> */
2227 _("Your %s has been eliminated defending "
2228 "against a %s."), link_unit, link_diplomat);
2229 } else {
2231 /* TRANS: <nation adj> <unit> ... <diplomat> */
2232 _("A %s %s has been eliminated defending "
2233 "against a %s."),
2237 /* TRANS: ... <unit> ... <diplomat> */
2238 _("Your %s has been eliminated defending "
2239 "against a %s."), link_unit, link_diplomat);
2240 }
2241 }
2242
2243 pdiplomat->moves_left = MAX(0, pdiplomat->moves_left - SINGLE_MOVE);
2244
2245 /* Attacking unit became more experienced? */
2249 }
2251 wipe_unit(punit, ULR_ELIMINATED, pplayer);
2252 return FALSE;
2253 } else {
2254 /* Attacking Spy/Diplomat dies. */
2255
2256 const char *victim_link;
2257
2258 /* N.B.: *_link() always returns the same pointer. */
2261
2263 _("Your %s was eliminated by a defending %s."),
2265
2266 if (pcity) {
2267 if (uplayer == cplayer || cplayer == NULL) {
2269 _("Eliminated a %s %s while infiltrating %s."),
2272 } else {
2274 _("A %s %s eliminated a %s %s while infiltrating "
2279 _("Your %s eliminated a %s %s while infiltrating "
2280 "%s."), link_unit,
2283 }
2284 } else {
2285 if (uplayer == cplayer || cplayer == NULL) {
2287 _("Eliminated a %s %s while infiltrating our troops."),
2290 } else {
2292 _("A %s %s eliminated a %s %s while infiltrating our "
2297 /* TRANS: ... <unit> ... <diplomat> */
2298 _("Your %s eliminated a %s %s while infiltrating our "
2299 "troops."), link_unit,
2302 }
2303 }
2304
2305 /* Defending unit became more experienced? */
2309 }
2310
2311 victim_link = NULL;
2312
2314 case ATK_CITY:
2316 break;
2317 case ATK_UNIT:
2318 case ATK_STACK:
2320 : tile_link(ptile);
2321 break;
2322 case ATK_TILE:
2323 case ATK_EXTRAS:
2324 victim_link = tile_link(ptile);
2325 break;
2326 case ATK_SELF:
2327 /* How did a self targeted action end up here? */
2329 break;
2330 case ATK_COUNT:
2331 break;
2332 }
2333
2335
2337 ptile, victim_link);
2338
2340 return FALSE;
2341 }
2342 }
2343
2344 return TRUE;
2345}
2346
2347/************************************************************************/
2357void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
2358 const struct city *pcity,
2359 const struct action *paction)
2360{
2361 struct tile *ptile;
2362 const char *vlink;
2363
2364 if (pcity) {
2365 ptile = city_tile(pcity);
2367 } else {
2368 ptile = unit_tile(pdiplomat);
2369 vlink = NULL;
2370 }
2371
2372 return diplomat_escape_full(pplayer, pdiplomat, pcity != NULL,
2373 ptile, vlink, paction);
2374}
2375
2376/************************************************************************/
2385static void diplomat_escape_full(struct player *pplayer,
2386 struct unit *pdiplomat,
2387 bool city_related,
2388 struct tile *ptile,
2389 const char *vlink,
2390 const struct action *paction)
2391{
2392 int escapechance;
2393 struct city *spyhome;
2394 const struct unit_type *dipltype = unit_type_get(pdiplomat);
2395
2396 fc_assert(paction->actor.is_unit.moves_actor == MAK_ESCAPE);
2397
2398 /* Veteran level's power factor's effect on escape chance is relative to
2399 * unpromoted unit's power factor */
2400 {
2401 const struct veteran_level
2403 const struct veteran_level
2405
2407 + (vunit->power_fact - vbase->power_fact);
2408 }
2409
2410 /* find closest city for escape target */
2412 FALSE, FALSE, TRUE, FALSE, NULL);
2413
2414 if (spyhome
2417 || fc_rand (100) < escapechance)) {
2418 /* Attacking Spy/Diplomat survives. */
2420 _("Your %s has successfully completed"
2421 " the mission and returned unharmed to %s."),
2424 if (maybe_make_veteran(pdiplomat, 100)) {
2426 }
2427
2429 /* Handled by the ruleset. */
2430 0,
2431 FALSE)) {
2433 log_error("Bug in diplomat_escape: Spy can't teleport.");
2434 return;
2435 }
2436
2437 return;
2438 } else {
2439 if (city_related) {
2441 _("Your %s was captured after completing"
2442 " the mission in %s."),
2444 vlink);
2445 } else {
2447 _("Your %s was captured after completing"
2448 " the mission."),
2450 }
2451 }
2452
2454 /* The unit was caught, not spent. It must therefore be deleted by
2455 * hand. */
2457 }
2458}
2459
2460/************************************************************************/
2468bool spy_escape(struct player *pplayer,
2469 struct unit *actor_unit,
2470 struct city *target_city,
2471 struct tile *target_tile,
2472 const struct action *paction)
2473{
2474 const char *vlink;
2476
2477 if (target_city != NULL) {
2480 } else {
2482 }
2483
2484 /* this may cause a diplomatic incident */
2488
2489 /* Try to escape. */
2492
2493 return TRUE;
2494}
2495
2496/************************************************************************/
2500{
2501 int count = 0;
2502
2503 unit_list_iterate((ptile)->units, punit) {
2505 count++;
2506 }
2508
2509 return count;
2510}
const char * action_name_translation(const struct action *paction)
Definition actions.c:1230
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1108
#define action_has_result(_act_, _res_)
Definition actions.h:180
void action_consequence_caught(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
const struct action * action_auto_perf_unit_do(const enum action_auto_perf_cause cause, struct unit *actor, const struct player *other_player, const struct output_type *eval_output, const struct action *eval_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, const struct extra_type *target_extra)
void action_consequence_success(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
bool action_failed_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
#define city_tile(_pcity_)
Definition city.h:561
static citizens city_size_get(const struct city *pcity)
Definition city.h:566
#define city_owner(_pcity_)
Definition city.h:560
#define city_built_iterate(_pcity, _p)
Definition city.h:831
#define city_built_iterate_end
Definition city.h:837
void package_city(struct city *pcity, struct packet_city_info *packet, struct packet_city_nationalities *nat_packet, struct packet_city_rally_point *rally_packet, struct packet_web_city_info_addition *web_packet, struct trade_route_packet_list *routes, bool dipl_invest)
Definition citytools.c:2531
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2368
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2776
struct city * find_closest_city(const struct tile *ptile, const struct city *pexclcity, const struct player *pplayer, bool only_ocean, bool only_continent, bool only_known, bool only_player, bool only_enemy, const struct unit_class *pclass)
Definition citytools.c:856
int city_original_owner(const struct city *pcity, const struct player *known_for)
Definition citytools.c:3699
bool city_illness_strike(struct city *pcity)
Definition citytools.c:2979
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3077
bool transfer_city(struct player *ptaker, struct city *pcity, int kill_outside, bool transfer_unit_verbose, bool resolve_stack, bool raze, bool build_free)
Definition citytools.c:1077
#define trade_route_packet_list_iterate_end
Definition citytools.h:28
#define trade_route_packet_list_iterate(ptrlist, ptr)
Definition citytools.h:26
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3567
bool city_empty_food_stock(struct city *pcity)
Definition cityturn.c:4272
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3455
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:762
bool city_refresh(struct city *pcity)
Definition cityturn.c:158
struct unit * get_diplomatic_defender(const struct unit *act_unit, const struct unit *pvictim, const struct tile *tgt_tile, const struct action *paction)
Definition combat.c:947
char * incite_cost
Definition comments.c:76
struct unit * actor_unit
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
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:74
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 const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
struct unit struct city * target_city
Definition dialogs_g.h:56
void establish_embassy(struct player *pplayer, struct player *aplayer)
Definition diplhand.c:698
static void diplomat_escape_full(struct player *pplayer, struct unit *pdiplomat, bool city_related, struct tile *ptile, const char *vlink, const struct action *paction)
Definition diplomats.c:2385
bool spy_escape(struct player *pplayer, struct unit *actor_unit, struct city *target_city, struct tile *target_tile, const struct action *paction)
Definition diplomats.c:2468
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1818
bool diplomat_bribe_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:644
int diplomats_unignored_tech_stealings(struct unit *pdiplomat, struct city *pcity)
Definition diplomats.c:970
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:549
static bool diplomat_may_lose_gold(struct player *dec_player, struct player *inc_player, int revolt_gold)
Definition diplomats.c:1201
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:484
bool diplomat_bribe_stack(struct player *pplayer, struct unit *pdiplomat, struct tile *pvictim, const struct action *paction)
Definition diplomats.c:812
static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat, const struct city *pcity, const struct action *paction)
Definition diplomats.c:2357
void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat, struct city *pcity, const struct action *paction, int request_kind)
Definition diplomats.c:429
static bool diplomat_infiltrate_tile(struct player *pplayer, struct player *cplayer, const struct action *paction, struct unit *pdiplomat, struct unit *pvictim, struct tile *ptile, struct player **defender_owner)
Definition diplomats.c:2156
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Definition diplomats.c:1011
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1404
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1255
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1676
bool spy_spread_plague(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:214
bool spy_nuke_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1956
static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef, struct tile *pdefender_tile, int *att_vet, int *def_vet)
Definition diplomats.c:2072
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:324
static void diplomat_charge_movement(struct unit *pdiplomat, struct tile *ptile)
Definition diplomats.c:2056
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:927
bool spy_poison(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:97
int count_diplomats_on_tile(struct tile *ptile)
Definition diplomats.c:2499
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:1066
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
int Tech_type_id
Definition fc_types.h:236
int Impr_type_id
Definition fc_types.h:235
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * tile_link(const struct tile *ptile)
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
const char * unit_link(const struct unit *punit)
const char * unit_tile_link(const struct unit *punit)
#define MAX_LEN_LINK
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
#define any_web_conns()
Definition game.h:324
struct city * owner
Definition citydlg.c:226
struct impr_type * improvement_by_number(const Impr_type_id id)
Impr_type_id improvement_number(const struct impr_type *pimprove)
const char * improvement_rule_name(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
#define log_normal(message,...)
Definition log.h:108
#define log_error(message,...)
Definition log.h:104
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:209
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:290
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1372
bool give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Definition maphand.c:2652
#define FC_FREE(ptr)
Definition mem.h:41
#define SINGLE_MOVE
Definition movement.h:26
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
#define web_lsend_packet(packetname,...)
Definition packets.h:57
@ UNIT_INFO_CITY_PRESENT
Definition packets.h:69
@ UNIT_INFO_CITY_SUPPORTED
Definition packets.h:68
void lsend_packet_city_nationalities(struct conn_list *dest, const struct packet_city_nationalities *packet, bool force_to_send)
void lsend_packet_trade_route_info(struct conn_list *dest, const struct packet_trade_route_info *packet)
void dlsend_packet_investigate_finished(struct conn_list *dest, int city_id)
void lsend_packet_city_info(struct conn_list *dest, const struct packet_city_info *packet, bool force_to_send)
int send_packet_city_sabotage_list(struct connection *pc, const struct packet_city_sabotage_list *packet)
void lsend_packet_unit_short_info(struct conn_list *dest, const struct packet_unit_short_info *packet, bool force_to_send)
void dlsend_packet_nuke_tile_info(struct conn_list *dest, int tile)
void dlsend_packet_investigate_started(struct conn_list *dest, int city_id)
void lsend_packet_city_rally_point(struct conn_list *dest, const struct packet_city_rally_point *packet, bool force_to_send)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
const char * player_name(const struct player *pplayer)
Definition player.c:895
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1409
static bool is_barbarian(const struct player *pplayer)
Definition player.h:491
void send_player_all_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1131
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
#define fc_rand(_size)
Definition rand.h:56
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
struct research * research_get(const struct player *pplayer)
Definition research.c:128
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:693
void script_server_signal_emit(const char *signal_name,...)
#define CLIP(lower, current, upper)
Definition shared.h:57
#define MAX(x, y)
Definition shared.h:54
Definition city.h:317
struct tile * tile
Definition city.h:319
int incite_gold_capt_chance
Definition game.h:149
int diplchance
Definition game.h:145
int incite_gold_loss_chance
Definition game.h:148
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct civ_game::@32::@36 server
bool tech_steal_allow_holes
bool steal_maps_reveals_all_cities
bool poison_empties_food_stock
bool combat_odds_scaled_veterancy
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
Definition tile.h:50
struct veteran_system * veteran
Definition unittype.h:551
Definition unit.h:140
int id
Definition unit.h:147
struct tile * tile
Definition unit.h:142
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
#define A_FUTURE
Definition tech.h:46
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
Tech_type_id steal_a_tech(struct player *pplayer, struct player *victim, Tech_type_id preferred)
Definition techtools.c:1234
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:89
#define tile_owner(_tile)
Definition tile.h:97
bool unit_is_alive(int id)
Definition unit.c:2290
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2344
int stack_bribe_cost(const struct tile *ptile, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2432
#define unit_tile(_pu)
Definition unit.h:404
#define unit_owner(_pu)
Definition unit.h:403
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:3034
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2877
void notify_unit_experience(struct unit *punit)
Definition unittools.c:747
void package_short_unit(struct unit *punit, struct packet_unit_short_info *packet, enum unit_info_use packet_use, int info_city_id)
Definition unittools.c:2814
bool maybe_make_veteran(struct unit *punit, int base_chance)
Definition unittools.c:219
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2139
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2199
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1187
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1225
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1575
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1933
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1584
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2603
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:196
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1225
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1566