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. */
106 fc_assert_ret_val(pcity, FALSE);
107 cplayer = city_owner(pcity);
109
110 /* Sanity check: The actor still exists. */
111 fc_assert_ret_val(pplayer, FALSE);
113
115
116 ctile = city_tile(pcity);
117 clink = city_link(pcity);
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. */
130 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
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. */
175 city_refresh (pcity);
176 send_city_info(NULL, pcity);
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. */
339 fc_assert_ret_val(pcity, FALSE);
340 cplayer = city_owner(pcity);
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. */
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) {
375 UNIT_INFO_CITY_PRESENT, pcity->id);
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 */
407 city_tile(pcity), city_link(pcity));
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. */
442 if (city_has_building(pcity, ptarget)) {
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. */
491 fc_assert_ret_val(pcity, FALSE);
492 cplayer = city_owner(pcity);
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."),
517 city_link(pcity));
520 _("The %s have established an embassy in %s."),
522 city_link(pcity));
523
524 /* this may cause a diplomatic incident */
526 city_tile(pcity), city_link(pcity));
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(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. */
747 pcity = tile_city(unit_tile(pvictim));
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/************************************************************************/
809 struct tile *tgt_tile, const struct action *paction)
810{
811 int act_unit_id;
812 struct player *tgt_player = NULL;
813 const struct unit_type *act_utype;
814
815 /* Sanity check: The actor still exists. */
818
820 act_unit_id = act_unit->id;
821
822 /* Do the diplomatic battle against a diplomatic defender. */
824 paction,
826 &tgt_player);
827
828 /* Sanity check: the defender had an owner. */
830
832 /* action_consequence_caught() is handled in
833 * diplomat_infiltrate_tile() */
834
835 /* The action was to start a diplomatic battle. */
836 return TRUE;
837 }
838
839 /* This may cause a diplomatic incident. */
842
843 /* The action was to start a diplomatic battle. */
844 return TRUE;
845}
846
847/************************************************************************/
852 struct city *pcity)
853{
854 int times;
856
857 if (bonus < 0) {
858 /* Negative effect value means infinite bonus */
859 times = 0;
860 } else {
861 times = pcity->steal - bonus;
862 if (times < 0) {
863 times = 0;
864 }
865 }
866
867 return times;
868}
869
870/************************************************************************/
892bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat,
893 struct city *pcity, Tech_type_id technology,
894 const struct action *paction)
895{
896 struct research *presearch, *cresearch;
897 struct player *cplayer;
898 const struct unit_type *act_utype;
899 int count;
900 int times;
902 bool expected_kills;
903
904 /* We have to check arguments. They are sent to us by a client,
905 so we cannot trust them */
906 fc_assert_ret_val(pcity, FALSE);
907 cplayer = city_owner(pcity);
909
910 /* Sanity check: The actor still exists. */
911 fc_assert_ret_val(pplayer, FALSE);
913
915
916 /* Sanity check: The target is foreign. */
917 if (cplayer == pplayer) {
918 /* Nothing to do to a domestic target. */
919 return FALSE;
920 }
921
922 /* Currently based on if unit is consumed or not. */
925
927 /* Can't choose target. Will steal a random tech. */
928 technology = A_UNSET;
929 }
930
931 /* Targeted technology should be a ruleset defined tech,
932 * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
933 if (technology == A_NONE
934 || (technology != A_FUTURE
935 && !(technology == A_UNSET
937 && !valid_advance_by_number(technology))) {
938 return FALSE;
939 }
940
941 presearch = research_get(pplayer);
943
944 if (technology == A_FUTURE) {
945 if (presearch->future_tech >= cresearch->future_tech) {
946 return FALSE;
947 }
948 } else if (technology != A_UNSET) {
949 if (research_invention_state(presearch, technology) == TECH_KNOWN) {
950 return FALSE;
951 }
952 if (research_invention_state(cresearch, technology) != TECH_KNOWN) {
953 return FALSE;
954 }
955 if (!research_invention_gettable(presearch, technology,
957 return FALSE;
958 }
959 }
960
961 log_debug("steal-tech: unit: %d", pdiplomat->id);
962
963 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
964 if (!diplomat_infiltrate_tile(pplayer, cplayer,
965 paction,
967 pcity->tile,
968 NULL)) {
969 return FALSE;
970 }
971
972 log_debug("steal-tech: infiltrated");
973
975
976 /* Check if the Diplomat/Spy succeeds with their task. */
977 /* (Twice as difficult if target is specified.) */
978 /* (If already stolen from, impossible for Diplomats and harder for Spies.) */
979 if (times > 0 && expected_kills) {
980 /* Already stolen from: Diplomat always fails! */
981 count = 1;
982 log_debug("steal-tech: difficulty: impossible");
983 } else {
984 /* Determine difficulty. */
985 count = 1;
987 /* Targeted steal tech is more difficult. */
988 count++;
989 }
990 count += times;
991 log_debug("steal-tech: difficulty: %d", count);
992 /* Determine success or failure. */
993 while (count > 0) {
994 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
995 paction)) {
996 break;
997 }
998 count--;
999 }
1000 }
1001
1002 if (count > 0) {
1003 /* Failed to steal a tech. */
1004 if (times > 0 && expected_kills) {
1005 notify_player(pplayer, city_tile(pcity),
1007 /* TRANS: Paris was expecting ... Your Spy was caught */
1008 _("%s was expecting your attempt to steal technology "
1009 "again. Your %s was caught and executed."),
1010 city_link(pcity),
1014 /* TRANS: The Belgian Spy ... from Paris */
1015 _("The %s %s failed to steal technology again from %s. "
1016 "We were prepared for the attempt."),
1019 city_link(pcity));
1020 } else {
1021 notify_player(pplayer, city_tile(pcity),
1023 /* TRANS: Your Spy was caught ... from %s. */
1024 _("Your %s was caught in the attempt of"
1025 " stealing technology from %s."),
1027 city_link(pcity));
1030 /* TRANS: The Belgian Spy ... from Paris */
1031 _("The %s %s failed to steal technology from %s."),
1034 city_link(pcity));
1035 }
1036
1037 /* This may cause a diplomatic incident */
1039 city_tile(pcity), city_link(pcity));
1041 return FALSE;
1042 }
1043
1044 tech_stolen = steal_a_tech(pplayer, cplayer, technology);
1045
1046 if (tech_stolen == A_NONE) {
1047 notify_player(pplayer, city_tile(pcity),
1049 _("No new technology found in %s."),
1050 city_link(pcity));
1053 return FALSE;
1054 }
1055
1056 /* Update stealing player's science progress and research fields */
1057 send_player_all_c(pplayer, NULL);
1058
1059 /* Record the theft. */
1060 (pcity->steal)++;
1061
1062 /* this may cause a diplomatic incident */
1064 city_tile(pcity), city_link(pcity));
1065
1066 /* Check if a spy survives her mission. */
1067 diplomat_escape(pplayer, pdiplomat, pcity, paction);
1068
1069 return TRUE;
1070}
1071
1072/************************************************************************/
1083 int revolt_gold)
1084{
1086 return FALSE;
1087 }
1088
1089 /* Roll the dice. */
1092 PL_("Your %d gold prepared to incite the revolt was lost!",
1093 "Your %d gold prepared to incite the revolt was lost!",
1095 dec_player->economic.gold -= revolt_gold;
1096 /* Lost money was pocketed by fraudulent executioners?
1097 * Or returned to local authority?
1098 * Roll the dice twice. */
1100 inc_player->economic.gold += revolt_gold;
1102 ftc_server,
1103 PL_("Your security service captured %d gold prepared "
1104 "to incite your town!",
1105 "Your security service captured %d gold prepared "
1106 "to incite your town!", revolt_gold), revolt_gold);
1107 }
1108 /* Update clients. */
1111
1112 return TRUE;
1113 } else {
1114 return FALSE;
1115 }
1116}
1117
1118/************************************************************************/
1136bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat,
1137 struct city *pcity, const struct action *paction)
1138{
1139 struct player *cplayer;
1140 struct tile *ctile;
1141 const char *clink;
1142 int revolt_cost;
1143 const struct unit_type *act_utype;
1144
1145 /* Fetch target civilization's player. Sanity checks. */
1146 fc_assert_ret_val(pcity, FALSE);
1147 cplayer = city_owner(pcity);
1149
1150 /* Sanity check: The actor still exists. */
1151 fc_assert_ret_val(pplayer, FALSE);
1153
1154 /* Sanity check: The target is foreign. */
1155 if (cplayer == pplayer) {
1156 /* Nothing to do to a domestic target. */
1157 return FALSE;
1158 }
1159
1161
1162 ctile = city_tile(pcity);
1163 clink = city_link(pcity);
1164
1165 log_debug("incite: unit: %d", pdiplomat->id);
1166
1167 /* Get incite cost, ignoring any previously saved value. */
1168 revolt_cost = city_incite_cost(pplayer, pcity);
1169
1170 /* If player doesn't have enough gold, can't incite a revolt. */
1171 if (pplayer->economic.gold < revolt_cost) {
1173 _("You don't have enough gold to subvert %s."),
1174 clink);
1175 log_debug("incite: not enough gold");
1176 return FALSE;
1177 }
1178
1179 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1180 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1181 paction,
1182 pdiplomat, NULL,
1183 pcity->tile,
1184 NULL)) {
1186 return FALSE;
1187 }
1188
1189 log_debug("incite: infiltrated");
1190
1191 /* Check if the Diplomat/Spy succeeds with their task. */
1192 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
1193 paction)) {
1195 _("Your %s was caught in the attempt"
1196 " of inciting a revolt!"),
1199 _("You caught %s %s attempting"
1200 " to incite a revolt in %s!"),
1203 clink);
1204
1206
1207 /* This may cause a diplomatic incident */
1209 cplayer, ctile, clink);
1210
1212 return FALSE;
1213 }
1214
1215 log_debug("incite: succeeded");
1216
1217 /* Subvert the city to your cause... */
1218
1219 /* City loses some population. */
1220 if (city_size_get(pcity) > 1) {
1221 city_reduce_size(pcity, 1, pplayer, "incited");
1222 }
1223
1224 /* This costs! */
1225 pplayer->economic.gold -= revolt_cost;
1226
1227 /* Notify everybody involved. */
1229 _("Revolt incited in %s, you now rule the city!"),
1230 clink);
1232 _("%s has revolted, %s influence suspected."),
1233 clink,
1235
1236 pcity->shield_stock = 0;
1238
1239 /* You get a technology advance, too! */
1240 steal_a_tech(pplayer, cplayer, A_UNSET);
1241
1242 /* this may cause a diplomatic incident */
1244 cplayer, ctile, clink);
1245
1246 /* Transfer city and units supported by this city (that
1247 are within one square of the city) to the new owner. */
1248 if (transfer_city(pplayer, pcity, 1, TRUE, TRUE, FALSE,
1249 !is_barbarian(pplayer))) {
1250 script_server_signal_emit("city_transferred", pcity, cplayer, pplayer,
1251 "incited");
1252 }
1253
1254 /* Check if a spy survives her mission.
1255 * _After_ transferring the city, or the city area is first fogged
1256 * when the diplomat is removed, and then unfogged when the city
1257 * is transferred. */
1259
1260 /* Update the players gold in the client */
1261 send_player_info_c(pplayer, pplayer->connections);
1262
1263 return TRUE;
1264}
1265
1266/************************************************************************/
1285bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat,
1286 struct city *pcity, Impr_type_id improvement,
1287 const struct action *paction)
1288{
1289 struct player *cplayer;
1290 struct impr_type *ptarget;
1291 int count, which;
1292 const struct unit_type *act_utype;
1293
1294 /* Fetch target city's player. Sanity checks. */
1295 fc_assert_ret_val(pcity, FALSE);
1296 cplayer = city_owner(pcity);
1298
1299 /* Sanity check: The actor still exists. */
1300 fc_assert_ret_val(pplayer, FALSE);
1302
1304
1305 log_debug("sabotage: unit: %d", pdiplomat->id);
1306
1307 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1308 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1309 paction,
1310 pdiplomat, NULL,
1311 pcity->tile,
1312 NULL)) {
1313 return FALSE;
1314 }
1315
1316 log_debug("sabotage: infiltrated");
1317
1318 /* Check if the Diplomat/Spy succeeds with their task. */
1319 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
1320 paction)) {
1321 notify_player(pplayer, city_tile(pcity),
1323 _("Your %s was caught in the attempt"
1324 " of industrial sabotage!"),
1328 _("You caught %s %s attempting sabotage in %s!"),
1331 city_link(pcity));
1332
1333 /* This may cause a diplomatic incident */
1335 city_tile(pcity), city_link(pcity));
1336
1338 return FALSE;
1339 }
1340
1341 log_debug("sabotage: succeeded");
1342
1343 /* Examine the city for improvements to sabotage. */
1344 count = 0;
1345 city_built_iterate(pcity, pimprove) {
1346 if (pimprove->sabotage > 0) {
1347 count++;
1348 }
1350
1351 log_debug("sabotage: count of improvements: %d", count);
1352
1353 /* Determine the target (-1 is production). */
1355 /*
1356 * Pick random:
1357 * 50/50 chance to pick production or some improvement.
1358 * Won't pick something that doesn't exit.
1359 * If nothing to do, say so, deduct movement cost and return.
1360 */
1361 if (count == 0 && pcity->shield_stock == 0) {
1362 notify_player(pplayer, city_tile(pcity),
1364 _("Your %s could not find anything to sabotage in %s."),
1366 city_link(pcity));
1369 log_debug("sabotage: random: nothing to do");
1370 return FALSE;
1371 }
1372 if (count == 0 || fc_rand (2) == 1) {
1373 ptarget = NULL;
1374 log_debug("sabotage: random: targeted production");
1375 } else {
1376 ptarget = NULL;
1377 which = fc_rand (count);
1378
1379 city_built_iterate(pcity, pimprove) {
1380 if (pimprove->sabotage > 0) {
1381 if (which > 0) {
1382 which--;
1383 } else {
1384 ptarget = pimprove;
1385 break;
1386 }
1387 }
1389
1390 if (NULL != ptarget) {
1391 log_debug("sabotage: random: targeted improvement: %d (%s)",
1394 } else {
1395 log_error("sabotage: random: targeted improvement error!");
1396 }
1397 }
1398 } else if (improvement < 0) {
1399 /* If told to sabotage production, do so. */
1400 ptarget = NULL;
1401 log_debug("sabotage: specified target production");
1402 } else {
1403 struct impr_type *pimprove = improvement_by_number(improvement);
1404 if (pimprove == NULL) {
1405 log_error("sabotage: requested for invalid improvement %d", improvement);
1406 return FALSE;
1407 }
1408 /*
1409 * Told which improvement to pick:
1410 * If try for wonder or palace, complain, deduct movement cost and return.
1411 * If not available, say so, deduct movement cost and return.
1412 */
1413 if (city_has_building(pcity, pimprove)) {
1414 if (pimprove->sabotage > 0) {
1415 ptarget = pimprove;
1416 log_debug("sabotage: specified target improvement: %d (%s)",
1417 improvement, improvement_rule_name(pimprove));
1418 } else {
1419 notify_player(pplayer, city_tile(pcity),
1421 _("You cannot sabotage a %s!"),
1425 log_debug("sabotage: disallowed target improvement: %d (%s)",
1426 improvement, improvement_rule_name(pimprove));
1427 return FALSE;
1428 }
1429 } else {
1430 notify_player(pplayer, city_tile(pcity),
1432 _("Your %s could not find the %s to sabotage in %s."),
1435 city_link(pcity));
1438 log_debug("sabotage: target improvement not found: %d (%s)",
1439 improvement, improvement_rule_name(pimprove));
1440 return FALSE;
1441 }
1442 }
1443
1444 /* Now, the fun stuff! Do the sabotage! */
1445 if (NULL == ptarget) {
1446 char prod[256];
1447
1448 /* Do it. */
1449 pcity->shield_stock = 0;
1450 nullify_prechange_production(pcity); /* Make it impossible to recover */
1451
1452 /* Report it. */
1453 universal_name_translation(&pcity->production, prod, sizeof(prod));
1454
1455 notify_player(pplayer, city_tile(pcity),
1457 _("Your %s succeeded in destroying"
1458 " the production of %s in %s."),
1460 prod,
1461 city_name_get(pcity));
1464 _("The production of %s was destroyed in %s,"
1465 " %s are suspected."),
1466 prod,
1467 city_link(pcity),
1468 nation_plural_for_player(pplayer));
1469 log_debug("sabotage: sabotaged production");
1470 } else {
1471 int vulnerability = ptarget->sabotage;
1472
1473 /* Sabotage a city improvement. */
1474
1475 /*
1476 * One last chance to get caught:
1477 * If target was specified, and it is in the capital or are
1478 * City Walls, then there is a 50% chance of getting caught.
1479 */
1482 / 100);
1483
1484 if (fc_rand(100) >= vulnerability) {
1485 /* Caught! */
1486 notify_player(pplayer, city_tile(pcity),
1488 _("Your %s was caught in the attempt of sabotage!"),
1492 _("You caught %s %s attempting"
1493 " to sabotage the %s in %s!"),
1497 city_link(pcity));
1498
1499 /* This may cause a diplomatic incident */
1501 city_tile(pcity), city_link(pcity));
1502
1504 log_debug("sabotage: caught in capital or on city walls");
1505 return FALSE;
1506 }
1507
1508 /* Report it. */
1509 notify_player(pplayer, city_tile(pcity),
1511 _("Your %s destroyed the %s in %s."),
1514 city_link(pcity));
1517 _("The %s destroyed the %s in %s."),
1518 nation_plural_for_player(pplayer),
1520 city_link(pcity));
1521 log_debug("sabotage: sabotaged improvement: %d (%s)",
1524
1525 /* Do it. */
1526 building_lost(pcity, ptarget, "sabotaged", pdiplomat);
1527
1528 /* FIXME: Lua script might have destroyed the diplomat, the city, or even the player.
1529 * Avoid dangling pointers below in that case. */
1530 }
1531
1532 /* Update clients. */
1533 send_city_info(NULL, pcity);
1534
1535 /* this may cause a diplomatic incident */
1537 city_tile(pcity), city_link(pcity));
1538
1539 /* Check if a spy survives her mission. */
1540 diplomat_escape(pplayer, pdiplomat, pcity, paction);
1541
1542 return TRUE;
1543}
1544
1545/************************************************************************/
1558 struct city *tgt_city, const struct action *paction)
1559{
1560 struct player *tgt_player;
1561 struct tile *tgt_tile;
1562
1563 const char *tgt_city_link;
1564
1565 int gold_take;
1566 int gold_give;
1567 const struct unit_type *act_utype;
1568
1569 /* Sanity check: The actor still exists. */
1572
1574
1575 /* Sanity check: The target city still exists. */
1577
1578 /* Who to steal from. */
1580
1581 /* Sanity check: The target player still exists. */
1583
1584 /* Sanity check: The target is foreign. */
1585 if (tgt_player == act_player) {
1586 /* Nothing to do to a domestic target. */
1587 return FALSE;
1588 }
1589
1590 /* Sanity check: There is something to steal. */
1591 if (tgt_player->economic.gold <= 0) {
1592 return FALSE;
1593 }
1594
1597
1598 log_debug("steal gold: unit: %d", act_unit->id);
1599
1600 /* Battle all units capable of diplomatic defense. */
1602 paction,
1604 NULL)) {
1605 return FALSE;
1606 }
1607
1608 log_debug("steal gold: infiltrated");
1609
1610 /* The thief may get caught while trying to steal the gold. */
1612 paction)) {
1614 _("Your %s was caught attempting to steal gold!"),
1617 ftc_server,
1618 /* TRANS: nation, unit, city */
1619 _("You caught %s %s attempting"
1620 " to steal your gold in %s!"),
1624
1625 /* This may cause a diplomatic incident */
1628
1629 /* Execute the caught thief. */
1631
1632 return FALSE;
1633 }
1634
1635 log_debug("steal gold: succeeded");
1636
1637 /* The upper limit on how much gold the thief can steal. */
1638 gold_take = (tgt_player->economic.gold
1640 / 1000;
1641
1642 /* How much to actually take. 1 gold is the smallest amount that can be
1643 * stolen. The victim player has at least 1 gold. If they didn't, the
1644 * something to steal sanity check would have aborted the theft. */
1646
1647 log_debug("steal gold: will take %d gold", gold_take);
1648
1649 /* Steal the gold. */
1650 tgt_player->economic.gold -= gold_take;
1651
1652 /* Some gold may be lost during transfer. */
1655 / 1000;
1656
1657 log_debug("steal gold: will give %d gold", gold_give);
1658
1659 /* Pocket the stolen money. */
1660 act_player->economic.gold += gold_give;
1661
1662 /* Notify everyone involved. */
1664 /* TRANS: unit, gold, city */
1665 PL_("Your %s stole %d gold from %s.",
1666 "Your %s stole %d gold from %s.", gold_give),
1669 /* TRANS: gold, city, nation */
1670 PL_("%d gold stolen from %s, %s suspected.",
1671 "%d gold stolen from %s, %s suspected.", gold_take),
1674
1675 /* This may cause a diplomatic incident. */
1678
1679 /* Try to escape. */
1682
1683 /* Update the players' gold in the client */
1686
1687 return TRUE;
1688}
1689
1690/************************************************************************/
1700 struct city *tgt_city,
1701 const struct action *paction)
1702{
1703 struct player *tgt_player;
1704 struct tile *tgt_tile;
1705 const struct unit_type *act_utype;
1706
1707 int normal_tile_prob;
1708
1709 const char *tgt_city_link;
1710
1711 /* Sanity check: The actor still exists. */
1714
1716
1717 /* Sanity check: The target city still exists. */
1719
1720 /* Who to steal from. */
1722
1723 /* Sanity check: The target player still exists. */
1725
1726 /* Sanity check: The target is foreign. */
1727 if (tgt_player == act_player) {
1728 /* Nothing to do to a domestic target. */
1729 return FALSE;
1730 }
1731
1734
1735 log_debug("steal some maps: unit: %d", act_unit->id);
1736
1737 /* Battle all units capable of diplomatic defense. */
1739 paction,
1741 NULL)) {
1742 return FALSE;
1743 }
1744
1745 log_debug("steal some maps: infiltrated");
1746
1747 /* Try to steal the map. */
1749 paction)) {
1751 _("Your %s was caught in an attempt of"
1752 " stealing parts of the %s world map!"),
1756 ftc_server,
1757 _("You caught %s %s attempting to steal"
1758 " parts of your world map in %s!"),
1762
1763 /* This may cause a diplomatic incident. */
1766
1767 /* Execute the caught thief. */
1769
1770 return FALSE;
1771 }
1772
1773 log_debug("steal some maps: succeeded");
1774
1775 /* Steal it. */
1776 normal_tile_prob = 100
1778 &(const struct req_context) {
1779 .player = act_player,
1780 /* City: Decide once requests from ruleset
1781 * authors arrive. Could be target city or
1782 * - with a refactoring - the city at the
1783 * tile that may be transferred. */
1784 /* Tile: Decide once requests from ruleset
1785 * authors arrive. Could be actor unit
1786 * tile, target city tile or even - with a
1787 * refactoring - the tile that may be
1788 * transferred. */
1789 .unit = act_unit,
1790 .unittype = unit_type_get(act_unit),
1791 .action = paction,
1792 },
1793 &(const struct req_context) {
1794 .player = tgt_player,
1795 },
1799 /* Could - with a refactoring where EFT_MAPS_STOLEN_PCT
1800 * is evaulated for each tile and the city sent to it
1801 * is the tile to transfer's city - be moved into
1802 * EFT_MAPS_STOLEN_PCT. */
1804
1805 /* Notify everyone involved. */
1807 _("Your %s stole parts of the %s world map in %s."),
1812 _("The %s are suspected of stealing"
1813 " parts of your world map in %s."),
1816
1817 /* This may cause a diplomatic incident. */
1820
1821 /* Try to escape. */
1824
1825 return TRUE;
1826}
1827
1828/************************************************************************/
1838 struct city *tgt_city, const struct action *paction)
1839{
1840 struct player *tgt_player;
1841 struct tile *tgt_tile;
1842
1843 const char *tgt_city_link;
1844 const struct unit_type *act_utype;
1845
1846 /* Sanity check: The actor still exists. */
1849
1851
1852 /* Sanity check: The target city still exists. */
1854
1855 /* The victim. */
1857
1858 /* Sanity check: The target player still exists. */
1860
1863
1864 log_debug("suitcase nuke: unit: %d", act_unit->id);
1865
1866 /* Battle all units capable of diplomatic defense. */
1868 paction,
1870 NULL)) {
1871 return FALSE;
1872 }
1873
1874 log_debug("suitcase nuke: infiltrated");
1875
1876 /* Try to hide the nuke. */
1878 paction)) {
1880 _("Your %s was caught in an attempt of"
1881 " hiding a nuke in %s!"),
1885 ftc_server,
1886 _("You caught %s %s attempting to hide a nuke in %s!"),
1890
1891 /* This may cause a diplomatic incident. */
1894
1895 /* Execute the caught terrorist. */
1897
1898 return FALSE;
1899 }
1900
1901 log_debug("suitcase nuke: succeeded");
1902
1903 /* Notify everyone involved. */
1905 _("Your %s hid a nuke in %s."),
1909 _("The %s are suspected of hiding a nuke in %s."),
1912
1913 /* Try to escape before the blast. */
1916
1918 /* The unit must be wiped here so it won't be seen as a victim of the
1919 * detonation of its own nuke. */
1921 }
1922
1923 /* Detonate the nuke. */
1926
1927 /* This may cause a diplomatic incident. */
1930
1931 return TRUE;
1932}
1933
1934/************************************************************************/
1937static void diplomat_charge_movement(struct unit *pdiplomat, struct tile *ptile)
1938{
1939 pdiplomat->moves_left -=
1940 map_move_cost_unit(&(wld.map), pdiplomat, ptile);
1941 if (pdiplomat->moves_left < 0) {
1942 pdiplomat->moves_left = 0;
1943 }
1944}
1945
1946/************************************************************************/
1954 struct unit *pdefender,
1955 struct tile *pdefender_tile,
1956 int *att_vet, int *def_vet)
1957{
1958 int chance = 50; /* Base 50% chance */
1959
1960 /* There's no challenge for the SuperSpy to gain veterancy from,
1961 * i.e. no veterancy if we exit early in next couple of checks. */
1962 *att_vet = 0;
1963 *def_vet = 0;
1964
1966 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
1967 return FALSE;
1968 }
1970 /* An attacking UTYF_SUPERSPY will defeat every possible defender
1971 * except another UTYF_SUPERSPY. */
1972 return TRUE;
1973 }
1974
1975 /* Add or remove 25% if spy flag. */
1977 chance += 25;
1978 }
1980 chance -= 25;
1981 }
1982
1983 /* Use power_fact from veteran level to modify chance in a linear way.
1984 * Equal veteran levels cancel out.
1985 * It's probably not good for rulesets to allow this to have more than
1986 * 20% effect. */
1987 {
1988 const struct veteran_level
1990 const struct veteran_level
1993 chance += vatt->power_fact - vdef->power_fact;
1994 }
1995
1996 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
1998 NULL,
1999 &(const struct req_context) {
2000 .player = tile_owner(pdefender_tile),
2001 .city = tile_city(pdefender_tile),
2003 },
2004 NULL,
2006 ) / 100;
2007
2008 chance = CLIP(0, chance, 100);
2009
2010 /* In a combat between equal strength units the values are 50% / 50%.
2011 * -> scaling that to 100% by doubling, to match scale of chances
2012 * in existing rulesets, and in !combat_odds_scaled_veterancy case. */
2013 *att_vet = (100 - chance) * 2;
2014 *def_vet = chance * 2;
2015
2016 return (int)fc_rand(100) < chance;
2017}
2018
2019/************************************************************************/
2035static bool diplomat_infiltrate_tile(struct player *pplayer,
2036 struct player *cplayer,
2037 const struct action *paction,
2038 struct unit *pdiplomat,
2039 struct unit *pvictim,
2040 struct tile *ptile,
2041 struct player **defender_owner)
2042{
2043 struct unit *punit;
2044 char link_city[MAX_LEN_LINK] = "";
2046 char link_unit[MAX_LEN_LINK];
2047 struct city *pcity = tile_city(ptile);
2048 const struct unit_type *act_utype = unit_type_get(pdiplomat);
2049 int att_vet;
2050 int def_vet;
2051
2052 if (pcity) {
2053 /* N.B.: *_link() always returns the same pointer. */
2055 }
2056
2058 paction))) {
2059 struct player *uplayer = unit_owner(punit);
2060
2061 if (defender_owner != NULL) {
2062 /* Some action performers may want to know defender player. */
2064 }
2065
2067 &att_vet, &def_vet)) {
2068 /* Defending Spy/Diplomat dies. */
2069
2070 /* N.B.: *_link() always returns the same pointer. */
2073
2075 /* TRANS: <unit> ... <diplomat> */
2076 _("An enemy %s has been eliminated by your %s."),
2078
2079 if (pcity) {
2080 if (uplayer == cplayer || cplayer == NULL) {
2082 /* TRANS: <unit> ... <city> ... <diplomat> */
2083 _("Your %s has been eliminated defending %s"
2084 " against a %s."), link_unit, link_city,
2086 } else {
2088 /* TRANS: <nation adj> <unit> ... <city>
2089 * TRANS: ... <diplomat> */
2090 _("A %s %s has been eliminated defending %s "
2091 "against a %s."),
2095 /* TRANS: ... <unit> ... <nation adj> <city>
2096 * TRANS: ... <diplomat> */
2097 _("Your %s has been eliminated defending %s %s "
2098 "against a %s."), link_unit,
2101 }
2102 } else {
2103 if (uplayer == cplayer || cplayer == NULL) {
2105 /* TRANS: <unit> ... <diplomat> */
2106 _("Your %s has been eliminated defending "
2107 "against a %s."), link_unit, link_diplomat);
2108 } else {
2110 /* TRANS: <nation adj> <unit> ... <diplomat> */
2111 _("A %s %s has been eliminated defending "
2112 "against a %s."),
2116 /* TRANS: ... <unit> ... <diplomat> */
2117 _("Your %s has been eliminated defending "
2118 "against a %s."), link_unit, link_diplomat);
2119 }
2120 }
2121
2122 pdiplomat->moves_left = MAX(0, pdiplomat->moves_left - SINGLE_MOVE);
2123
2124 /* Attacking unit became more experienced? */
2128 }
2130 wipe_unit(punit, ULR_ELIMINATED, pplayer);
2131 return FALSE;
2132 } else {
2133 /* Attacking Spy/Diplomat dies. */
2134
2135 const char *victim_link;
2136
2137 /* N.B.: *_link() always returns the same pointer. */
2140
2142 _("Your %s was eliminated by a defending %s."),
2144
2145 if (pcity) {
2146 if (uplayer == cplayer || cplayer == NULL) {
2148 _("Eliminated a %s %s while infiltrating %s."),
2151 } else {
2153 _("A %s %s eliminated a %s %s while infiltrating "
2158 _("Your %s eliminated a %s %s while infiltrating "
2159 "%s."), link_unit,
2162 }
2163 } else {
2164 if (uplayer == cplayer || cplayer == NULL) {
2166 _("Eliminated a %s %s while infiltrating our troops."),
2169 } else {
2171 _("A %s %s eliminated a %s %s while infiltrating our "
2176 /* TRANS: ... <unit> ... <diplomat> */
2177 _("Your %s eliminated a %s %s while infiltrating our "
2178 "troops."), link_unit,
2181 }
2182 }
2183
2184 /* Defending unit became more experienced? */
2188 }
2189
2190 victim_link = NULL;
2191
2193 case ATK_CITY:
2194 victim_link = city_link(pcity);
2195 break;
2196 case ATK_UNIT:
2197 case ATK_UNITS:
2199 : tile_link(ptile);
2200 break;
2201 case ATK_TILE:
2202 case ATK_EXTRAS:
2203 victim_link = tile_link(ptile);
2204 break;
2205 case ATK_SELF:
2206 /* How did a self targeted action end up here? */
2208 break;
2209 case ATK_COUNT:
2210 break;
2211 }
2212
2214
2216 ptile, victim_link);
2217
2219 return FALSE;
2220 }
2221 }
2222
2223 return TRUE;
2224}
2225
2226/************************************************************************/
2236void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
2237 const struct city *pcity,
2238 const struct action *paction)
2239{
2240 struct tile *ptile;
2241 const char *vlink;
2242
2243 if (pcity) {
2244 ptile = city_tile(pcity);
2245 vlink = city_link(pcity);
2246 } else {
2247 ptile = unit_tile(pdiplomat);
2248 vlink = NULL;
2249 }
2250
2251 return diplomat_escape_full(pplayer, pdiplomat, pcity != NULL,
2252 ptile, vlink, paction);
2253}
2254
2255/************************************************************************/
2264static void diplomat_escape_full(struct player *pplayer,
2265 struct unit *pdiplomat,
2266 bool city_related,
2267 struct tile *ptile,
2268 const char *vlink,
2269 const struct action *paction)
2270{
2271 int escapechance;
2272 struct city *spyhome;
2273
2274 fc_assert(paction->actor.is_unit.moves_actor == MAK_ESCAPE);
2275
2276 /* Veteran level's power factor's effect on escape chance is relative to
2277 * unpromoted unit's power factor */
2278 {
2279 const struct veteran_level
2281 const struct veteran_level
2283
2285 + (vunit->power_fact - vbase->power_fact);
2286 }
2287
2288 /* find closest city for escape target */
2290 FALSE, FALSE, TRUE, FALSE, NULL);
2291
2292 if (spyhome
2295 || fc_rand (100) < escapechance)) {
2296 /* Attacking Spy/Diplomat survives. */
2298 _("Your %s has successfully completed"
2299 " the mission and returned unharmed to %s."),
2302 if (maybe_make_veteran(pdiplomat, 100)) {
2304 }
2305
2307 /* Handled by the ruleset. */
2308 0,
2309 FALSE)) {
2311 log_error("Bug in diplomat_escape: Spy can't teleport.");
2312 return;
2313 }
2314
2315 return;
2316 } else {
2317 if (city_related) {
2319 _("Your %s was captured after completing"
2320 " the mission in %s."),
2322 vlink);
2323 } else {
2325 _("Your %s was captured after completing"
2326 " the mission."),
2328 }
2329 }
2330
2332 /* The unit was caught, not spent. It must therefore be deleted by
2333 * hand. */
2335 }
2336}
2337
2338/************************************************************************/
2346bool spy_escape(struct player *pplayer,
2347 struct unit *actor_unit,
2348 struct city *target_city,
2349 struct tile *target_tile,
2350 const struct action *paction)
2351{
2352 const char *vlink;
2354
2355 if (target_city != NULL) {
2358 } else {
2360 }
2361
2362 /* this may cause a diplomatic incident */
2366
2367 /* Try to escape. */
2370
2371 return TRUE;
2372}
2373
2374/************************************************************************/
2378{
2379 int count = 0;
2380
2381 unit_list_iterate((ptile)->units, punit) {
2383 count++;
2384 }
2386
2387 return count;
2388}
const char * action_name_translation(const struct action *paction)
Definition actions.c:1205
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1083
#define action_has_result(_act_, _res_)
Definition actions.h:175
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:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1236
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_owner(_pcity_)
Definition city.h:563
#define city_built_iterate(_pcity, _p)
Definition city.h:825
#define city_built_iterate_end
Definition city.h:831
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:2514
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2351
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2751
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:851
int city_original_owner(const struct city *pcity, const struct player *known_for)
Definition citytools.c:3674
bool city_illness_strike(struct city *pcity)
Definition citytools.c:2954
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3052
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:1072
#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:3550
bool city_empty_food_stock(struct city *pcity)
Definition cityturn.c:4255
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3438
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:761
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:945
char * incite_cost
Definition comments.c:74
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 * 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:2264
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:2346
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1699
int diplomats_unignored_tech_stealings(struct unit *pdiplomat, struct city *pcity)
Definition diplomats.c:851
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:1082
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:484
static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat, const struct city *pcity, const struct action *paction)
Definition diplomats.c:2236
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:2035
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Definition diplomats.c:892
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1285
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1136
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1557
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:1837
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:1953
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:1937
bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:644
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:808
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:2377
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:381
int Impr_type_id
Definition fc_types.h:380
#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:316
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:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:279
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1374
bool give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Definition maphand.c:2701
#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:292
#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_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:1129
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1146
#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:320
int id
Definition city.h:326
struct universal production
Definition city.h:396
int steal
Definition city.h:414
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
struct unit_list * units_supported
Definition city.h:406
int incite_gold_capt_chance
Definition game.h:142
int diplchance
Definition game.h:138
int incite_gold_loss_chance
Definition game.h:141
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct civ_game::@31::@35 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
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:189
#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:1233
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:2291
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2345
#define unit_tile(_pu)
Definition unit.h:397
#define unit_owner(_pu)
Definition unit.h:396
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:3035
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2878
void notify_unit_experience(struct unit *punit)
Definition unittools.c:744
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:2815
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:2140
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2200
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1188
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1226
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:1569
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1927
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2583
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1219
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560