Freeciv21
Develop your civilization from humble roots to a global empire
diplomats.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // utility
15 #include "bitvector.h"
16 #include "log.h"
17 #include "rand.h"
18 
19 // common
20 #include "base.h"
21 #include "combat.h"
22 #include "events.h"
23 #include "game.h"
24 #include "map.h"
25 #include "movement.h"
26 #include "player.h"
27 #include "research.h"
28 #include "unitlist.h"
29 
30 // server
31 #include "actiontools.h"
32 #include "aiiface.h"
33 #include "citytools.h"
34 #include "cityturn.h"
35 #include "diplhand.h"
36 #include "diplomats.h"
37 #include "maphand.h"
38 #include "notify.h"
39 #include "plrhand.h"
40 #include "techtools.h"
41 #include "unithand.h"
42 #include "unittools.h"
43 
44 /* server/scripting */
45 #include "script_server.h"
46 
47 /****************************************************************************/
48 
49 static void diplomat_charge_movement(struct unit *pdiplomat,
50  struct tile *ptile);
51 static bool diplomat_success_vs_defender(struct unit *patt,
52  struct unit *pdef,
53  struct tile *pdefender_tile);
54 static bool diplomat_may_lose_gold(struct player *dec_player,
55  struct player *inc_player,
56  int revolt_gold);
57 static bool
58 diplomat_infiltrate_tile(struct player *pplayer, struct player *cplayer,
59  const struct action *paction,
60  struct unit *pdiplomat, struct unit *pvictim,
61  struct tile *ptile, struct player **defender_owner);
62 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
63  const struct city *pcity,
64  const struct action *paction);
65 static void diplomat_escape_full(struct player *pplayer,
66  struct unit *pdiplomat, bool city_related,
67  struct tile *ptile, const char *vlink,
68  const struct action *paction);
69 
84 bool spy_poison(struct player *pplayer, struct unit *pdiplomat,
85  struct city *pcity, const struct action *paction)
86 {
87  struct player *cplayer;
88  struct tile *ctile;
89  const char *clink;
90 
91  // Fetch target city's player. Sanity checks.
92  fc_assert_ret_val(pcity, false);
93  cplayer = city_owner(pcity);
94  fc_assert_ret_val(cplayer, false);
95 
96  // Sanity check: The actor still exists.
97  fc_assert_ret_val(pplayer, false);
98  fc_assert_ret_val(pdiplomat, false);
99 
100  ctile = city_tile(pcity);
101  clink = city_link(pcity);
102 
103  log_debug("poison: unit: %d", pdiplomat->id);
104 
105  /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
106  if (!diplomat_infiltrate_tile(pplayer, cplayer, paction, pdiplomat,
107  nullptr, ctile, nullptr)) {
108  return false;
109  }
110 
111  log_debug("poison: infiltrated");
112  log_debug("poison: succeeded");
113 
114  // Poison people!
115  if (city_reduce_size(pcity, 1, pplayer, "poison")) {
116  // Notify everybody involved.
117  notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
118  _("Your %s poisoned the water supply of %s."),
119  unit_link(pdiplomat), clink);
120  notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_POISON, ftc_server,
121  _("%s is suspected of poisoning the water supply of %s."),
122  player_name(pplayer), clink);
123 
124  if (game.info.poison_empties_food_stock) {
125  // The food was poisoned too.
126  city_empty_food_stock(pcity);
127  }
128 
129  // Update clients.
130  city_refresh(pcity);
131  send_city_info(nullptr, pcity);
132  } else {
133  // Notify everybody involved.
134  notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
135  _("Your %s destroyed %s by poisoning its water supply."),
136  unit_link(pdiplomat), clink);
137  notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_POISON, ftc_server,
138  _("%s is suspected of destroying %s by poisoning its"
139  " water supply."),
140  player_name(pplayer), clink);
141  }
142 
143  // this may cause a diplomatic incident
144  action_consequence_success(paction, pplayer, cplayer, ctile, clink);
145 
146  // Now lets see if the spy survives.
147  diplomat_escape_full(pplayer, pdiplomat, true, ctile, clink, paction);
148 
149  return true;
150 }
151 
167 bool spy_spread_plague(struct player *act_player, struct unit *act_unit,
168  struct city *tgt_city, const struct action *paction)
169 {
170  struct player *tgt_player;
171  struct tile *tgt_tile;
172 
173  const char *tgt_city_link;
174 
175  // Sanity check: The actor still exists.
176  fc_assert_ret_val(act_player, false);
177  fc_assert_ret_val(act_unit, false);
178 
179  // Sanity check: The target city still exists.
180  fc_assert_ret_val(tgt_city, false);
181 
182  // Who to infect.
183  tgt_player = city_owner(tgt_city);
184 
185  // Sanity check: The target player still exists.
186  fc_assert_ret_val(tgt_player, false);
187 
188  tgt_tile = city_tile(tgt_city);
189  tgt_city_link = city_link(tgt_city);
190 
191  log_debug("spread plague: unit: %d", act_unit->id);
192 
193  // Battle all units capable of diplomatic defense.
194  if (!diplomat_infiltrate_tile(act_player, tgt_player, paction, act_unit,
195  nullptr, tgt_tile, nullptr)) {
196  return false;
197  }
198 
199  log_debug("spread plague: infiltrated");
200 
201  /* The infector may get caught while trying to spread a plague in the
202  * city. */
203  if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
204  paction)) {
205  notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
206  // TRANS: unit, action
207  _("Your %s was caught attempting to do %s!"),
208  unit_tile_link(act_unit),
209  qUtf8Printable(action_name_translation(paction)));
211  tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
212  // TRANS: nation, unit, action, city
213  _("You caught %s %s attempting to do %s in %s!"),
214  nation_adjective_for_player(act_player), unit_tile_link(act_unit),
215  qUtf8Printable(action_name_translation(paction)), tgt_city_link);
216 
217  // This may cause a diplomatic incident
218  action_consequence_caught(paction, act_player, tgt_player, tgt_tile,
219  tgt_city_link);
220 
221  // Execute the caught infector.
222  wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
223 
224  return false;
225  }
226 
227  log_debug("spread plague: succeeded");
228 
229  // Commit bio-terrorism.
230  city_illness_strike(tgt_city);
231 
232  // Update the clients.
233  city_refresh(tgt_city);
234  send_city_info(nullptr, tgt_city);
235 
236  // Notify everyone involved.
238  act_player, tgt_tile, E_UNIT_ACTION_ACTOR_SUCCESS, ftc_server,
239  // TRANS: unit, action, city
240  _("Your %s did %s to %s."), unit_link(act_unit),
241  qUtf8Printable(action_name_translation(paction)), tgt_city_link);
242  notify_player(tgt_player, tgt_tile, E_UNIT_ACTION_TARGET_HOSTILE,
243  ftc_server,
244  // TRANS: action, city, nation
245  _("%s done to %s, %s suspected."),
246  qUtf8Printable(action_name_translation(paction)),
247  tgt_city_link, nation_plural_for_player(act_player));
248 
249  // This may cause a diplomatic incident.
250  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
251  tgt_city_link);
252 
253  // Try to escape.
254  diplomat_escape_full(act_player, act_unit, true, tgt_tile, tgt_city_link,
255  paction);
256 
257  return true;
258 }
259 
271 bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
272  struct city *pcity, const struct action *paction)
273 {
274  struct player *cplayer;
275  struct packet_unit_short_info unit_packet {
276  };
277  struct packet_city_info city_packet {
278  };
279  struct traderoute_packet_list *routes;
280 
281  // Fetch target city's player. Sanity checks.
282  fc_assert_ret_val(pcity, false);
283  cplayer = city_owner(pcity);
284  fc_assert_ret_val(cplayer, false);
285 
286  // Sanity check: The actor still exists.
287  fc_assert_ret_val(pplayer, false);
288  fc_assert_ret_val(pdiplomat, false);
289 
290  // Sanity check: The target is foreign.
291  if (cplayer == pplayer) {
292  // Nothing to do to a domestic target.
293  return false;
294  }
295 
296  log_debug("investigate: unit: %d", pdiplomat->id);
297 
298  // Do It...
299  update_dumb_city(pplayer, pcity);
300  /* Special case for a diplomat/spy investigating a city:
301  The investigator needs to know the supported and present
302  units of a city, whether or not they are fogged. So, we
303  send a list of them all before sending the city info.
304  As this is a special case we bypass send_unit_info. */
305  unit_list_iterate(pcity->units_supported, punit)
306  {
307  package_short_unit(punit, &unit_packet, UNIT_INFO_CITY_SUPPORTED,
308  pcity->id);
309  /* We need to force to send the packet to ensure the client will receive
310  * something (e.g. investigating twice). */
311  lsend_packet_unit_short_info(pplayer->connections, &unit_packet, true);
312  }
314  unit_list_iterate((pcity->tile)->units, punit)
315  {
316  package_short_unit(punit, &unit_packet, UNIT_INFO_CITY_PRESENT,
317  pcity->id);
318  /* We need to force to send the packet to ensure the client will receive
319  * something (e.g. investigating twice). */
320  lsend_packet_unit_short_info(pplayer->connections, &unit_packet, true);
321  }
323  /* Send city info to investigator's player.
324  As this is a special case we bypass send_city_info. */
325  routes = traderoute_packet_list_new();
326  package_city(pcity, &city_packet, routes, true);
327  /* We need to force to send the packet to ensure the client will receive
328  * something and popup the city dialog. */
329  lsend_packet_city_info(pplayer->connections, &city_packet, true);
330  traderoute_packet_list_iterate(routes, route_packet)
331  {
332  lsend_packet_traderoute_info(pplayer->connections, route_packet);
333  delete route_packet;
334  route_packet = nullptr;
335  }
337  traderoute_packet_list_destroy(routes);
338 
339  // this may cause a diplomatic incident
340  action_consequence_success(paction, pplayer, cplayer, city_tile(pcity),
341  city_link(pcity));
342 
343  /* The actor unit always survive unless the action it self has determined
344  * to always consume it. */
345  if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
346  /* This unit isn't about to be consumed. Send updated unit information
347  * to the clients. */
348  send_unit_info(nullptr, pdiplomat);
349  }
350 
351  return true;
352 }
353 
361 void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat,
362  struct city *pcity, const struct action *paction,
363  bool disturb_player)
364 {
365  struct packet_city_sabotage_list packet;
366 
367  // Send city improvements info to player.
368  BV_CLR_ALL(packet.improvements);
369 
370  if (action_has_result(paction, ACTRES_SPY_TARGETED_SABOTAGE_CITY)) {
371  // Can see hidden buildings.
372  improvement_iterate(ptarget)
373  {
374  if (city_has_building(pcity, ptarget)) {
375  BV_SET(packet.improvements, improvement_index(ptarget));
376  }
377  }
379  } else {
380  // Can't see hidden buildings.
381  const vision_site *plrcity =
382  map_get_player_city(city_tile(pcity), unit_owner(pdiplomat));
383 
384  if (!plrcity) {
385  // Must know city to remember visible buildings.
386  return;
387  }
388 
389  improvement_iterate(ptarget)
390  {
391  if (BV_ISSET(plrcity->improvements, improvement_index(ptarget))) {
392  BV_SET(packet.improvements, improvement_index(ptarget));
393  }
394  }
396  }
397 
398  packet.actor_id = pdiplomat->id;
399  packet.city_id = pcity->id;
400  packet.act_id = paction->id;
401  packet.disturb_player = disturb_player;
402  send_packet_city_sabotage_list(pc, &packet);
403 }
404 
418 bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
419  struct city *pcity, const struct action *paction)
420 {
421  struct player *cplayer;
422 
423  // Fetch target city's player. Sanity checks.
424  fc_assert_ret_val(pcity, false);
425  cplayer = city_owner(pcity);
426  fc_assert_ret_val(cplayer, false);
427 
428  // Sanity check: The actor still exists.
429  fc_assert_ret_val(pplayer, false);
430  fc_assert_ret_val(pdiplomat, false);
431 
432  // Sanity check: The target is foreign.
433  if (cplayer == pplayer) {
434  // Nothing to do to a domestic target.
435  return false;
436  }
437 
438  log_debug("embassy: unit: %d", pdiplomat->id);
439 
440  log_debug("embassy: succeeded");
441 
442  establish_embassy(pplayer, cplayer);
443 
444  // Notify everybody involved.
445  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_EMBASSY, ftc_server,
446  _("You have established an embassy in %s."),
447  city_link(pcity));
448  notify_player(cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_EMBASSY,
449  ftc_server, _("The %s have established an embassy in %s."),
450  nation_plural_for_player(pplayer), city_link(pcity));
451 
452  // this may cause a diplomatic incident
453  action_consequence_success(paction, pplayer, cplayer, city_tile(pcity),
454  city_link(pcity));
455 
456  /* The actor unit always survive unless the action it self has determined
457  * to always consume it. */
458  if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
459  /* This unit isn't about to be consumed. Send updated unit information
460  * to the clients. */
461  send_unit_info(nullptr, pdiplomat);
462  }
463 
464  return true;
465 }
466 
477 bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat,
478  struct unit *pvictim, const struct action *paction)
479 {
480  char victim_link[MAX_LEN_LINK];
481  struct player *uplayer;
482 
483  // Fetch target unit's player. Sanity checks.
484  fc_assert_ret_val(pvictim, false);
485  uplayer = unit_owner(pvictim);
486  fc_assert_ret_val(uplayer, false);
487 
488  // Sanity check: The actor still exists.
489  fc_assert_ret_val(pplayer, false);
490  fc_assert_ret_val(pdiplomat, false);
491 
492  log_debug("sabotage-unit: unit: %d", pdiplomat->id);
493 
494  // N.B: unit_link() always returns the same pointer.
495  sz_strlcpy(victim_link, unit_link(pvictim));
496 
497  /* Diplomatic battle against any diplomatic defender except the intended
498  * victim of the sabotage. */
499  if (!diplomat_infiltrate_tile(pplayer, uplayer, paction, pdiplomat,
500  pvictim, unit_tile(pvictim), nullptr)) {
501  return false;
502  }
503 
504  log_debug("sabotage-unit: succeeded");
505 
506  if (pvictim->hp < 2) {
507  // Not possible to halve the hit points. Kill it.
508  wipe_unit(pvictim, ULR_KILLED, pplayer);
509 
510  // Notify everybody involved.
511  notify_player(pplayer, unit_tile(pvictim), E_MY_DIPLOMAT_SABOTAGE,
512  ftc_server,
513  _("Your %s's successful sabotage killed the %s %s."),
514  unit_link(pdiplomat), nation_adjective_for_player(uplayer),
515  victim_link);
516  notify_player(uplayer, unit_tile(pvictim), E_ENEMY_DIPLOMAT_SABOTAGE,
517  ftc_server,
518  // TRANS: ... the Poles!
519  _("Your %s was killed by %s sabotage!"), victim_link,
520  nation_plural_for_player(pplayer));
521  } else {
522  // Sabotage the unit by removing half its remaining hit points.
523  pvictim->hp /= 2;
524  send_unit_info(nullptr, pvictim);
525 
526  // Notify everybody involved.
527  notify_player(pplayer, unit_tile(pvictim), E_MY_DIPLOMAT_SABOTAGE,
528  ftc_server,
529  _("Your %s succeeded in sabotaging the %s %s."),
530  unit_link(pdiplomat), nation_adjective_for_player(uplayer),
531  victim_link);
532  notify_player(uplayer, unit_tile(pvictim), E_ENEMY_DIPLOMAT_SABOTAGE,
533  ftc_server,
534  // TRANS: ... the Poles!
535  _("Your %s was sabotaged by the %s!"), victim_link,
536  nation_plural_for_player(pplayer));
537  }
538 
539  // this may cause a diplomatic incident
540  action_consequence_success(paction, pplayer, uplayer, unit_tile(pvictim),
541  victim_link);
542 
543  // Now lets see if the spy survives.
544  diplomat_escape(pplayer, pdiplomat, nullptr, paction);
545 
546  return true;
547 }
548 
561 bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat,
562  struct unit *pvictim, const struct action *paction)
563 {
564  char victim_link[MAX_LEN_LINK];
565  struct player *uplayer;
566  struct tile *victim_tile;
567  int bribe_cost;
568  int diplomat_id = pdiplomat->id;
569  struct city *pcity;
570  bool bounce;
571 
572  // Fetch target unit's player. Sanity checks.
573  fc_assert_ret_val(pvictim, false);
574  uplayer = unit_owner(pvictim);
575  fc_assert_ret_val(uplayer, false);
576 
577  // Sanity check: The actor still exists.
578  fc_assert_ret_val(pplayer, false);
579  fc_assert_ret_val(pdiplomat, false);
580 
581  // Sanity check: The target is foreign.
582  if (uplayer == pplayer) {
583  // Nothing to do to a domestic target.
584  return false;
585  }
586 
587  /* Sanity check: The victim isn't a unique unit the actor player already
588  * has. */
591  false, "bribe-unit: already got unique unit");
592 
593  log_debug("bribe-unit: unit: %d", pdiplomat->id);
594 
595  // Get bribe cost, ignoring any previously saved value.
596  bribe_cost = unit_bribe_cost(pvictim, pplayer);
597 
598  // If player doesn't have enough gold, can't bribe.
599  if (pplayer->economic.gold < bribe_cost) {
600  notify_player(pplayer, unit_tile(pdiplomat), E_MY_DIPLOMAT_FAILED,
601  ftc_server,
602  _("You don't have enough gold to bribe the %s %s."),
603  nation_adjective_for_player(uplayer), unit_link(pvictim));
604  log_debug("bribe-unit: not enough gold");
605  return false;
606  }
607 
608  log_debug("bribe-unit: enough gold");
609 
610  /* Diplomatic battle against any diplomatic defender except the one that
611  * will get the bribe. */
612  if (!diplomat_infiltrate_tile(pplayer, uplayer, paction, pdiplomat,
613  pvictim, pvictim->tile, nullptr)) {
614  return false;
615  }
616 
617  log_debug("bribe-unit: succeeded");
618 
619  victim_tile = unit_tile(pvictim);
620  pvictim =
621  unit_change_owner(pvictim, pplayer, pdiplomat->homecity, ULR_BRIBED);
622 
623  /* N.B.: unit_link always returns the same pointer. As unit_change_owner()
624  * currently remove the old unit and replace by a new one (with a new id),
625  * we want to make link to the new unit. */
626  sz_strlcpy(victim_link, unit_link(pvictim));
627 
628  // Notify everybody involved.
629  notify_player(pplayer, victim_tile, E_MY_DIPLOMAT_BRIBE, ftc_server,
630  // TRANS: <diplomat> ... <unit>
631  _("Your %s succeeded in bribing the %s."),
632  unit_link(pdiplomat), victim_link);
633  if (maybe_make_veteran(pdiplomat)) {
634  notify_unit_experience(pdiplomat);
635  }
636  notify_player(uplayer, victim_tile, E_ENEMY_DIPLOMAT_BRIBE, ftc_server,
637  // TRANS: <unit> ... <Poles>
638  _("Your %s was bribed by the %s."), victim_link,
639  nation_plural_for_player(pplayer));
640 
641  /* The unit may have been on a tile shared with a city or a unit
642  * it no longer can share a tile with. */
643  pcity = tile_city(unit_tile(pvictim));
644  bounce =
645  ((nullptr != pcity && !pplayers_allied(city_owner(pcity), pplayer))
646  || 1 < unit_list_size(unit_tile(pvictim)->units));
647  if (bounce) {
648  bounce_unit(pvictim, true);
649  }
650 
651  // This costs!
652  pplayer->economic.gold -= bribe_cost;
653 
654  // This may cause a diplomatic incident
655  action_consequence_success(paction, pplayer, uplayer, victim_tile,
656  victim_link);
657 
658  if (!unit_is_alive(diplomat_id)) {
659  return true;
660  }
661 
662  if (game.server.unitwaittime_extended) {
663  /* Counts as an action even if the move to be tried doesn't succeed */
664  unit_did_action(pdiplomat);
665  }
666 
667  /* Try to move the briber onto the victim's square unless the victim has
668  * been bounced because it couldn't share tile with a unit or city. */
669  if (!bounce
670  // Post bribe embark.
671  && (can_unit_exist_at_tile(&(wld.map), pdiplomat, victim_tile)
672  || !(is_action_enabled_unit_on_unit(ACTION_TRANSPORT_EMBARK,
673  pdiplomat, pvictim)
675  unit_owner(pdiplomat), pdiplomat->id, pvictim->id, 0, "",
676  ACTION_TRANSPORT_EMBARK, ACT_REQ_RULES)))
677  // May have died while trying to embark.
678  && unit_is_alive(diplomat_id)
679  // Post bribe disembark.
680  && (!unit_transported(pdiplomat)
681  || !(is_action_enabled_unit_on_tile(ACTION_TRANSPORT_DISEMBARK1,
682  pdiplomat, victim_tile,
683  nullptr)
684  && unit_perform_action(unit_owner(pdiplomat), pdiplomat->id,
685  tile_index(victim_tile), 0, "",
686  ACTION_TRANSPORT_DISEMBARK1,
687  ACT_REQ_RULES)))
688  // May have died while trying to disembark.
689  && unit_is_alive(diplomat_id)
690  // Post bribe disembark 2.
691  && (!unit_transported(pdiplomat)
692  || !(is_action_enabled_unit_on_tile(ACTION_TRANSPORT_DISEMBARK2,
693  pdiplomat, victim_tile,
694  nullptr)
695  && unit_perform_action(unit_owner(pdiplomat), pdiplomat->id,
696  tile_index(victim_tile), 0, "",
697  ACTION_TRANSPORT_DISEMBARK2,
698  ACT_REQ_RULES)))
699  // May have died while trying to disembark.
700  && unit_is_alive(diplomat_id)
701  // Post bribe move.
702  && !unit_move_handling(pdiplomat, victim_tile, false, true)
703  // May have died while trying to move.
704  && unit_is_alive(diplomat_id)) {
705  pdiplomat->moves_left = 0;
706  }
707  if (nullptr != player_unit_by_number(pplayer, diplomat_id)) {
708  send_unit_info(nullptr, pdiplomat);
709  }
710 
711  // Update clients.
712  send_player_all_c(pplayer, nullptr);
713 
714  return true;
715 }
716 
725 bool spy_attack(struct player *act_player, struct unit *act_unit,
726  struct tile *tgt_tile, const struct action *paction)
727 {
728  int act_unit_id;
729  struct player *tgt_player = nullptr;
730 
731  // Sanity check: The actor still exists.
732  fc_assert_ret_val(act_player, false);
733  fc_assert_ret_val(act_unit, false);
734 
735  act_unit_id = act_unit->id;
736 
737  // Do the diplomatic battle against a diplomatic defender.
738  diplomat_infiltrate_tile(act_player, nullptr, paction, act_unit, nullptr,
739  tgt_tile, &tgt_player);
740 
741  // Sanity check: the defender had an owner.
742  fc_assert_ret_val(tgt_player != nullptr, true);
743 
744  if (!unit_is_alive(act_unit_id)) {
745  /* action_consequence_caught() is handled in
746  * diplomat_infiltrate_tile() */
747 
748  // The action was to start a diplomatic battle.
749  return true;
750  }
751 
752  // This may cause a diplomatic incident.
753  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
754  tile_link(tgt_tile));
755 
756  // The action was to start a diplomatic battle.
757  return true;
758 }
759 
765  struct city *pcity)
766 {
767  int times;
768  int bonus = get_unit_bonus(pdiplomat, EFT_STEALINGS_IGNORE);
769 
770  if (bonus < 0) {
771  // Negative effect value means infinite bonus
772  times = 0;
773  } else {
774  times = pcity->steal - bonus;
775  if (times < 0) {
776  times = 0;
777  }
778  }
779 
780  return times;
781 }
782 
805 bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat,
806  struct city *pcity, Tech_type_id technology,
807  const struct action *paction)
808 {
809  struct research *presearch, *cresearch;
810  struct player *cplayer;
811  int count;
812  int times;
813  Tech_type_id tech_stolen;
814  bool expected_kills;
815 
816  /* We have to check arguments. They are sent to us by a client,
817  so we cannot trust them */
818  fc_assert_ret_val(pcity, false);
819  cplayer = city_owner(pcity);
820  fc_assert_ret_val(cplayer, false);
821 
822  // Sanity check: The actor still exists.
823  fc_assert_ret_val(pplayer, false);
824  fc_assert_ret_val(pdiplomat, false);
825 
826  // Sanity check: The target is foreign.
827  if (cplayer == pplayer) {
828  // Nothing to do to a domestic target.
829  return false;
830  }
831 
832  // Currently based on if unit is consumed or not.
833  expected_kills =
834  utype_is_consumed_by_action(paction, unit_type_get(pdiplomat));
835 
836  if (action_has_result(paction, ACTRES_SPY_STEAL_TECH)) {
837  // Can't choose target. Will steal a random tech.
838  technology = A_UNSET;
839  }
840 
841  /* Targeted technology should be a ruleset defined tech,
842  * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
843  if (technology == A_NONE
844  || (technology != A_FUTURE
845  && !(technology == A_UNSET
846  && action_has_result(paction, ACTRES_SPY_STEAL_TECH))
847  && !valid_advance_by_number(technology))) {
848  return false;
849  }
850 
851  presearch = research_get(pplayer);
852  cresearch = research_get(cplayer);
853 
854  if (technology == A_FUTURE) {
855  if (presearch->future_tech >= cresearch->future_tech) {
856  return false;
857  }
858  } else if (technology != A_UNSET) {
859  if (research_invention_state(presearch, technology) == TECH_KNOWN) {
860  return false;
861  }
862  if (research_invention_state(cresearch, technology) != TECH_KNOWN) {
863  return false;
864  }
865  if (!research_invention_gettable(presearch, technology,
866  game.info.tech_steal_allow_holes)) {
867  return false;
868  }
869  }
870 
871  log_debug("steal-tech: unit: %d", pdiplomat->id);
872 
873  /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
874  if (!diplomat_infiltrate_tile(pplayer, cplayer, paction, pdiplomat,
875  nullptr, pcity->tile, nullptr)) {
876  return false;
877  }
878 
879  log_debug("steal-tech: infiltrated");
880 
881  times = diplomats_unignored_tech_stealings(pdiplomat, pcity);
882 
883  /* Check if the Diplomat/Spy succeeds with his/her task. */
884  // (Twice as difficult if target is specified.)
885  /* (If already stolen from, impossible for Diplomats and harder for Spies.)
886  */
887  if (times > 0 && expected_kills) {
888  // Already stolen from: Diplomat always fails!
889  count = 1;
890  log_debug("steal-tech: difficulty: impossible");
891  } else {
892  // Determine difficulty.
893  count = 1;
894  if (action_has_result(paction, ACTRES_SPY_TARGETED_STEAL_TECH)) {
895  // Targeted steal tech is more difficult.
896  count++;
897  }
898  count += times;
899  log_debug("steal-tech: difficulty: %d", count);
900  // Determine success or failure.
901  while (count > 0) {
902  if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
903  paction)) {
904  break;
905  }
906  count--;
907  }
908  }
909 
910  if (count > 0) {
911  // Failed to steal a tech.
912  if (times > 0 && expected_kills) {
913  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
914  ftc_server,
915  // TRANS: Paris was expecting ... Your Spy was caught
916  _("%s was expecting your attempt to steal technology "
917  "again. Your %s was caught and executed."),
918  city_link(pcity), unit_tile_link(pdiplomat));
919  notify_player(cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_FAILED,
920  ftc_server,
921  // TRANS: The Belgian Spy ... from Paris
922  _("The %s %s failed to steal technology again from %s. "
923  "We were prepared for the attempt."),
925  unit_tile_link(pdiplomat), city_link(pcity));
926  } else {
927  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
928  ftc_server,
929  // TRANS: Your Spy was caught ... from %s.
930  _("Your %s was caught in the attempt of"
931  " stealing technology from %s."),
932  unit_tile_link(pdiplomat), city_link(pcity));
933  notify_player(cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_FAILED,
934  ftc_server,
935  // TRANS: The Belgian Spy ... from Paris
936  _("The %s %s failed to steal technology from %s."),
938  unit_tile_link(pdiplomat), city_link(pcity));
939  }
940 
941  // This may cause a diplomatic incident
942  action_consequence_caught(paction, pplayer, cplayer, city_tile(pcity),
943  city_link(pcity));
944  wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
945  return false;
946  }
947 
948  tech_stolen = steal_a_tech(pplayer, cplayer, technology);
949 
950  if (tech_stolen == A_NONE) {
951  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
952  ftc_server, _("No new technology found in %s."),
953  city_link(pcity));
954  diplomat_charge_movement(pdiplomat, pcity->tile);
955  send_unit_info(nullptr, pdiplomat);
956  return false;
957  }
958 
959  // Update stealing player's science progress and research fields
960  send_player_all_c(pplayer, nullptr);
961 
962  // Record the theft.
963  (pcity->steal)++;
964 
965  // this may cause a diplomatic incident
966  action_consequence_success(paction, pplayer, cplayer, city_tile(pcity),
967  city_link(pcity));
968 
969  // Check if a spy survives her mission.
970  diplomat_escape(pplayer, pdiplomat, pcity, paction);
971 
972  return true;
973 }
974 
985 bool diplomat_may_lose_gold(struct player *dec_player,
986  struct player *inc_player, int revolt_gold)
987 {
988  if (game.server.incite_gold_loss_chance <= 0) {
989  return false;
990  }
991 
992  // Roll the dice.
993  if (fc_rand(100) < game.server.incite_gold_loss_chance) {
994  notify_player(dec_player, nullptr, E_MY_DIPLOMAT_FAILED, ftc_server,
995  _("Your %d gold prepared to incite the revolt was lost!"),
996  revolt_gold);
997  dec_player->economic.gold -= revolt_gold;
998  /* Lost money was pocketed by fraudulent executioners?
999  * Or returned to local authority?
1000  * Roll the dice twice. */
1001  if (fc_rand(100) < game.server.incite_gold_capt_chance) {
1002  inc_player->economic.gold += revolt_gold;
1003  notify_player(inc_player, nullptr, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1004  _("Your security service captured %d gold prepared "
1005  "to incite your town!"),
1006  revolt_gold);
1007  }
1008  // Update clients.
1009  send_player_all_c(dec_player, nullptr);
1010  send_player_all_c(inc_player, nullptr);
1011 
1012  return true;
1013  } else {
1014  return false;
1015  }
1016 }
1017 
1036 bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat,
1037  struct city *pcity, const struct action *paction)
1038 {
1039  struct player *cplayer;
1040  struct tile *ctile;
1041  const char *clink;
1042  int revolt_cost;
1043 
1044  // Fetch target civilization's player. Sanity checks.
1045  fc_assert_ret_val(pcity, false);
1046  cplayer = city_owner(pcity);
1047  fc_assert_ret_val(cplayer, false);
1048 
1049  // Sanity check: The actor still exists.
1050  fc_assert_ret_val(pplayer, false);
1051  fc_assert_ret_val(pdiplomat, false);
1052 
1053  // Sanity check: The target is foreign.
1054  if (cplayer == pplayer) {
1055  // Nothing to do to a domestic target.
1056  return false;
1057  }
1058 
1059  ctile = city_tile(pcity);
1060  clink = city_link(pcity);
1061 
1062  log_debug("incite: unit: %d", pdiplomat->id);
1063 
1064  // Get incite cost, ignoring any previously saved value.
1065  revolt_cost = city_incite_cost(pplayer, pcity);
1066 
1067  // If player doesn't have enough gold, can't incite a revolt.
1068  if (pplayer->economic.gold < revolt_cost) {
1069  notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
1070  _("You don't have enough gold to subvert %s."), clink);
1071  log_debug("incite: not enough gold");
1072  return false;
1073  }
1074 
1075  /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1076  if (!diplomat_infiltrate_tile(pplayer, cplayer, paction, pdiplomat,
1077  nullptr, pcity->tile, nullptr)) {
1078  diplomat_may_lose_gold(pplayer, cplayer, revolt_cost / 2);
1079  return false;
1080  }
1081 
1082  log_debug("incite: infiltrated");
1083 
1084  /* Check if the Diplomat/Spy succeeds with his/her task. */
1085  if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer, paction)) {
1086  notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
1087  _("Your %s was caught in the attempt"
1088  " of inciting a revolt!"),
1089  unit_tile_link(pdiplomat));
1090  notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1091  _("You caught %s %s attempting"
1092  " to incite a revolt in %s!"),
1093  nation_adjective_for_player(pplayer),
1094  unit_tile_link(pdiplomat), clink);
1095 
1096  diplomat_may_lose_gold(pplayer, cplayer, revolt_cost / 4);
1097 
1098  // This may cause a diplomatic incident
1099  action_consequence_caught(paction, pplayer, cplayer, ctile, clink);
1100 
1101  wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1102  return false;
1103  }
1104 
1105  log_debug("incite: succeeded");
1106 
1107  // Subvert the city to your cause...
1108 
1109  // City loses some population.
1110  if (city_size_get(pcity) > 1) {
1111  city_reduce_size(pcity, 1, pplayer, "incited");
1112  }
1113 
1114  // This costs!
1115  pplayer->economic.gold -= revolt_cost;
1116 
1117  // Notify everybody involved.
1118  notify_player(pplayer, ctile, E_MY_DIPLOMAT_INCITE, ftc_server,
1119  _("Revolt incited in %s, you now rule the city!"), clink);
1120  notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_INCITE, ftc_server,
1121  _("%s has revolted, %s influence suspected."), clink,
1122  nation_adjective_for_player(pplayer));
1123 
1124  pcity->shield_stock = 0;
1126 
1127  // this may cause a diplomatic incident
1128  action_consequence_success(paction, pplayer, cplayer, ctile, clink);
1129 
1130  /* Transfer city and units supported by this city (that
1131  are within one square of the city) to the new owner. */
1132  if (transfer_city(pplayer, pcity, 1, true, true, false,
1133  !is_barbarian(pplayer))) {
1134  script_server_signal_emit("city_transferred", pcity, cplayer, pplayer,
1135  "incited");
1136  }
1137 
1138  /* Check if a spy survives her mission.
1139  * _After_ transferring the city, or the city area is first fogged
1140  * when the diplomat is removed, and then unfogged when the city
1141  * is transferred. */
1142  diplomat_escape_full(pplayer, pdiplomat, true, ctile, clink, paction);
1143 
1144  // Update the players gold in the client
1145  send_player_info_c(pplayer, pplayer->connections);
1146 
1147  return true;
1148 }
1149 
1170 bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat,
1171  struct city *pcity, Impr_type_id improvement,
1172  const struct action *paction)
1173 {
1174  struct player *cplayer;
1175  struct impr_type *ptarget;
1176  int count, which;
1177 
1178  // Fetch target city's player. Sanity checks.
1179  fc_assert_ret_val(pcity, false);
1180  cplayer = city_owner(pcity);
1181  fc_assert_ret_val(cplayer, false);
1182 
1183  // Sanity check: The actor still exists.
1184  fc_assert_ret_val(pplayer, false);
1185  fc_assert_ret_val(pdiplomat, false);
1186 
1187  log_debug("sabotage: unit: %d", pdiplomat->id);
1188 
1189  /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1190  if (!diplomat_infiltrate_tile(pplayer, cplayer, paction, pdiplomat,
1191  nullptr, pcity->tile, nullptr)) {
1192  return false;
1193  }
1194 
1195  log_debug("sabotage: infiltrated");
1196 
1197  /* Check if the Diplomat/Spy succeeds with his/her task. */
1198  if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer, paction)) {
1199  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
1200  ftc_server,
1201  _("Your %s was caught in the attempt"
1202  " of industrial sabotage!"),
1203  unit_tile_link(pdiplomat));
1204  notify_player(cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_SABOTAGE,
1205  ftc_server,
1206  _("You caught %s %s attempting sabotage in %s!"),
1207  nation_adjective_for_player(pplayer),
1208  unit_tile_link(pdiplomat), city_link(pcity));
1209 
1210  // This may cause a diplomatic incident
1211  action_consequence_caught(paction, pplayer, cplayer, city_tile(pcity),
1212  city_link(pcity));
1213 
1214  wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1215  return false;
1216  }
1217 
1218  log_debug("sabotage: succeeded");
1219 
1220  // Examine the city for improvements to sabotage.
1221  count = 0;
1222  city_built_iterate(pcity, pimprove)
1223  {
1224  if (pimprove->sabotage > 0) {
1225  count++;
1226  }
1227  }
1229 
1230  log_debug("sabotage: count of improvements: %d", count);
1231 
1232  // Determine the target (-1 is production).
1233  if (action_has_result(paction, ACTRES_SPY_SABOTAGE_CITY)) {
1234  /*
1235  * Pick random:
1236  * 50/50 chance to pick production or some improvement.
1237  * Won't pick something that doesn't exit.
1238  * If nothing to do, say so, deduct movement cost and return.
1239  */
1240  if (count == 0 && pcity->shield_stock == 0) {
1241  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
1242  ftc_server,
1243  _("Your %s could not find anything to sabotage in %s."),
1244  unit_link(pdiplomat), city_link(pcity));
1245  diplomat_charge_movement(pdiplomat, pcity->tile);
1246  send_unit_info(nullptr, pdiplomat);
1247  log_debug("sabotage: random: nothing to do");
1248  return false;
1249  }
1250  if (count == 0 || fc_rand(2) == 1) {
1251  ptarget = nullptr;
1252  log_debug("sabotage: random: targeted production");
1253  } else {
1254  ptarget = nullptr;
1255  which = fc_rand(count);
1256 
1257  city_built_iterate(pcity, pimprove)
1258  {
1259  if (pimprove->sabotage > 0) {
1260  if (which > 0) {
1261  which--;
1262  } else {
1263  ptarget = pimprove;
1264  break;
1265  }
1266  }
1267  }
1269 
1270  if (nullptr != ptarget) {
1271  log_debug("sabotage: random: targeted improvement: %d (%s)",
1272  improvement_number(ptarget),
1273  improvement_rule_name(ptarget));
1274  } else {
1275  qCritical("sabotage: random: targeted improvement error!");
1276  }
1277  }
1278  } else if (improvement < 0) {
1279  // If told to sabotage production, do so.
1280  ptarget = nullptr;
1281  log_debug("sabotage: specified target production");
1282  } else {
1283  struct impr_type *pimprove = improvement_by_number(improvement);
1284  if (pimprove == nullptr) {
1285  qCritical("sabotage: requested for invalid improvement %d",
1286  improvement);
1287  return false;
1288  }
1289  /*
1290  * Told which improvement to pick:
1291  * If try for wonder or palace, complain, deduct movement cost and
1292  * return. If not available, say so, deduct movement cost and return.
1293  */
1294  if (city_has_building(pcity, pimprove)) {
1295  if (pimprove->sabotage > 0) {
1296  ptarget = pimprove;
1297  log_debug("sabotage: specified target improvement: %d (%s)",
1298  improvement, improvement_rule_name(pimprove));
1299  } else {
1300  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
1301  ftc_server, _("You cannot sabotage a %s!"),
1302  improvement_name_translation(pimprove));
1303  diplomat_charge_movement(pdiplomat, pcity->tile);
1304  send_unit_info(nullptr, pdiplomat);
1305  log_debug("sabotage: disallowed target improvement: %d (%s)",
1306  improvement, improvement_rule_name(pimprove));
1307  return false;
1308  }
1309  } else {
1310  notify_player(
1311  pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED, ftc_server,
1312  _("Your %s could not find the %s to sabotage in %s."),
1313  unit_name_translation(pdiplomat),
1314  improvement_name_translation(pimprove), city_link(pcity));
1315  diplomat_charge_movement(pdiplomat, pcity->tile);
1316  send_unit_info(nullptr, pdiplomat);
1317  log_debug("sabotage: target improvement not found: %d (%s)",
1318  improvement, improvement_rule_name(pimprove));
1319  return false;
1320  }
1321  }
1322 
1323  // Now, the fun stuff! Do the sabotage!
1324  if (nullptr == ptarget) {
1325  char prod[256];
1326 
1327  // Do it.
1328  pcity->shield_stock = 0;
1329  nullify_prechange_production(pcity); // Make it impossible to recover
1330 
1331  // Report it.
1332  universal_name_translation(&pcity->production, prod, sizeof(prod));
1333 
1334  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_SABOTAGE,
1335  ftc_server,
1336  _("Your %s succeeded in destroying"
1337  " the production of %s in %s."),
1338  unit_link(pdiplomat), prod, city_name_get(pcity));
1339  notify_player(cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_SABOTAGE,
1340  ftc_server,
1341  _("The production of %s was destroyed in %s,"
1342  " %s are suspected."),
1343  prod, city_link(pcity), nation_plural_for_player(pplayer));
1344  log_debug("sabotage: sabotaged production");
1345  } else {
1346  int vulnerability = ptarget->sabotage;
1347 
1348  // Sabotage a city improvement.
1349 
1350  /*
1351  * One last chance to get caught:
1352  * If target was specified, and it is in the capital or are
1353  * City Walls, then there is a 50% chance of getting caught.
1354  */
1355  vulnerability -= (vulnerability
1356  * get_city_bonus(pcity, EFT_SABOTEUR_RESISTANT) / 100);
1357 
1358  if (fc_rand(100) >= vulnerability) {
1359  // Caught!
1360  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_FAILED,
1361  ftc_server,
1362  _("Your %s was caught in the attempt of sabotage!"),
1363  unit_tile_link(pdiplomat));
1364  notify_player(
1365  cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1366  _("You caught %s %s attempting"
1367  " to sabotage the %s in %s!"),
1368  nation_adjective_for_player(pplayer), unit_tile_link(pdiplomat),
1369  improvement_name_translation(ptarget), city_link(pcity));
1370 
1371  // This may cause a diplomatic incident
1372  action_consequence_caught(paction, pplayer, cplayer, city_tile(pcity),
1373  city_link(pcity));
1374 
1375  wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1376  log_debug("sabotage: caught in capital or on city walls");
1377  return false;
1378  }
1379 
1380  // Report it.
1381  notify_player(pplayer, city_tile(pcity), E_MY_DIPLOMAT_SABOTAGE,
1382  ftc_server, _("Your %s destroyed the %s in %s."),
1383  unit_link(pdiplomat),
1384  improvement_name_translation(ptarget), city_link(pcity));
1385  notify_player(cplayer, city_tile(pcity), E_ENEMY_DIPLOMAT_SABOTAGE,
1386  ftc_server, _("The %s destroyed the %s in %s."),
1387  nation_plural_for_player(pplayer),
1388  improvement_name_translation(ptarget), city_link(pcity));
1389  log_debug("sabotage: sabotaged improvement: %d (%s)",
1390  improvement_number(ptarget), improvement_rule_name(ptarget));
1391 
1392  // Do it.
1393  building_lost(pcity, ptarget, "sabotaged", pdiplomat);
1394 
1395  /* FIXME: Lua script might have destroyed the diplomat, the city, or even
1396  * the player. Avoid dangling pointers below in that case. */
1397  }
1398 
1399  // Update clients.
1400  send_city_info(nullptr, pcity);
1401 
1402  // this may cause a diplomatic incident
1403  action_consequence_success(paction, pplayer, cplayer, city_tile(pcity),
1404  city_link(pcity));
1405 
1406  // Check if a spy survives her mission.
1407  diplomat_escape(pplayer, pdiplomat, pcity, paction);
1408 
1409  return true;
1410 }
1411 
1424 bool spy_steal_gold(struct player *act_player, struct unit *act_unit,
1425  struct city *tgt_city, const struct action *paction)
1426 {
1427  struct player *tgt_player;
1428  struct tile *tgt_tile;
1429 
1430  const char *tgt_city_link;
1431 
1432  int gold_take;
1433  int gold_give;
1434 
1435  // Sanity check: The actor still exists.
1436  fc_assert_ret_val(act_player, false);
1437  fc_assert_ret_val(act_unit, false);
1438 
1439  // Sanity check: The target city still exists.
1440  fc_assert_ret_val(tgt_city, false);
1441 
1442  // Who to steal from.
1443  tgt_player = city_owner(tgt_city);
1444 
1445  // Sanity check: The target player still exists.
1446  fc_assert_ret_val(tgt_player, false);
1447 
1448  // Sanity check: The target is foreign.
1449  if (tgt_player == act_player) {
1450  // Nothing to do to a domestic target.
1451  return false;
1452  }
1453 
1454  // Sanity check: There is something to steal.
1455  if (tgt_player->economic.gold <= 0) {
1456  return false;
1457  }
1458 
1459  tgt_tile = city_tile(tgt_city);
1460  tgt_city_link = city_link(tgt_city);
1461 
1462  log_debug("steal gold: unit: %d", act_unit->id);
1463 
1464  // Battle all units capable of diplomatic defence.
1465  if (!diplomat_infiltrate_tile(act_player, tgt_player, paction, act_unit,
1466  nullptr, tgt_tile, nullptr)) {
1467  return false;
1468  }
1469 
1470  log_debug("steal gold: infiltrated");
1471 
1472  // The thief may get caught while trying to steal the gold.
1473  if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
1474  paction)) {
1475  notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1476  _("Your %s was caught attempting to steal gold!"),
1477  unit_tile_link(act_unit));
1478  notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1479  // TRANS: nation, unit, city
1480  _("You caught %s %s attempting"
1481  " to steal your gold in %s!"),
1482  nation_adjective_for_player(act_player),
1483  unit_tile_link(act_unit), tgt_city_link);
1484 
1485  // This may cause a diplomatic incident
1486  action_consequence_caught(paction, act_player, tgt_player, tgt_tile,
1487  tgt_city_link);
1488 
1489  // Execute the caught thief.
1490  wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1491 
1492  return false;
1493  }
1494 
1495  log_debug("steal gold: succeeded");
1496 
1497  // The upper limit on how much gold the thief can steal.
1498  gold_take = (tgt_player->economic.gold
1499  * get_city_bonus(tgt_city, EFT_MAX_STOLEN_GOLD_PM))
1500  / 1000;
1501 
1502  /* How much to actually take. 1 gold is the smallest amount that can be
1503  * stolen. The victim player has at least 1 gold. If he didn't the
1504  * something to steal sanity check would have aborted the theft. */
1505  gold_take = fc_rand(gold_take) + 1;
1506 
1507  log_debug("steal gold: will take %d gold", gold_take);
1508 
1509  // Steal the gold.
1510  tgt_player->economic.gold -= gold_take;
1511 
1512  // Some gold may be lost during transfer.
1513  gold_give =
1514  gold_take
1515  - (gold_take * get_unit_bonus(act_unit, EFT_THIEFS_SHARE_PM)) / 1000;
1516 
1517  log_debug("steal gold: will give %d gold", gold_give);
1518 
1519  // Pocket the stolen money.
1520  act_player->economic.gold += gold_give;
1521 
1522  // Notify everyone involved.
1523  notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_GOLD, ftc_server,
1524  // TRANS: unit, gold, city
1525  PL_("Your %s stole %d gold from %s.",
1526  "Your %s stole %d gold from %s.", gold_give),
1527  unit_link(act_unit), gold_give, tgt_city_link);
1528  notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_GOLD, ftc_server,
1529  // TRANS: gold, city, nation
1530  PL_("%d gold stolen from %s, %s suspected.",
1531  "%d gold stolen from %s, %s suspected.", gold_take),
1532  gold_take, tgt_city_link,
1533  nation_plural_for_player(act_player));
1534 
1535  // This may cause a diplomatic incident.
1536  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
1537  tgt_city_link);
1538 
1539  // Try to escape.
1540  diplomat_escape_full(act_player, act_unit, true, tgt_tile, tgt_city_link,
1541  paction);
1542 
1543  // Update the players' gold in the client
1544  send_player_info_c(act_player, act_player->connections);
1545  send_player_info_c(tgt_player, tgt_player->connections);
1546 
1547  return true;
1548 }
1549 
1559 bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit,
1560  struct city *tgt_city, const struct action *paction)
1561 {
1562  struct player *tgt_player;
1563  struct tile *tgt_tile;
1564 
1565  int normal_tile_prob;
1566 
1567  const char *tgt_city_link;
1568 
1569  // Sanity check: The actor still exists.
1570  fc_assert_ret_val(act_player, false);
1571  fc_assert_ret_val(act_unit, false);
1572 
1573  // Sanity check: The target city still exists.
1574  fc_assert_ret_val(tgt_city, false);
1575 
1576  // Who to steal from.
1577  tgt_player = city_owner(tgt_city);
1578 
1579  // Sanity check: The target player still exists.
1580  fc_assert_ret_val(tgt_player, false);
1581 
1582  // Sanity check: The target is foreign.
1583  if (tgt_player == act_player) {
1584  // Nothing to do to a domestic target.
1585  return false;
1586  }
1587 
1588  tgt_tile = city_tile(tgt_city);
1589  tgt_city_link = city_link(tgt_city);
1590 
1591  log_debug("steal some maps: unit: %d", act_unit->id);
1592 
1593  // Battle all units capable of diplomatic defence.
1594  if (!diplomat_infiltrate_tile(act_player, tgt_player, paction, act_unit,
1595  nullptr, tgt_tile, nullptr)) {
1596  return false;
1597  }
1598 
1599  log_debug("steal some maps: infiltrated");
1600 
1601  // Try to steal the map.
1602  if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
1603  paction)) {
1604  notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1605  _("Your %s was caught in an attempt of"
1606  " stealing parts of the %s world map!"),
1607  unit_tile_link(act_unit),
1608  nation_adjective_for_player(tgt_player));
1609  notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1610  _("You caught %s %s attempting to steal"
1611  " parts of your world map in %s!"),
1612  nation_adjective_for_player(act_player),
1613  unit_tile_link(act_unit), tgt_city_link);
1614 
1615  // This may cause a diplomatic incident.
1616  action_consequence_caught(paction, act_player, tgt_player, tgt_tile,
1617  tgt_city_link);
1618 
1619  // Execute the caught thief.
1620  wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1621 
1622  return false;
1623  }
1624 
1625  log_debug("steal some maps: succeeded");
1626 
1627  // Steal it.
1628  normal_tile_prob = 100
1630  nullptr, act_player, tgt_player,
1631  /* Decide once requests from ruleset
1632  * authors arrive. Could be target city or
1633  * - with a refactoring - the city at the
1634  * tile that may be transferred. */
1635  nullptr, nullptr,
1636  /* Decide once requests from ruleset
1637  * authors arrive. Could be actor unit
1638  * tile, target city tile or even - with a
1639  * refactoring - the tile that may be
1640  * transferred. */
1641  nullptr, act_unit, unit_type_get(act_unit), nullptr,
1642  nullptr, paction, EFT_MAPS_STOLEN_PCT);
1643  give_distorted_map(tgt_player, act_player, normal_tile_prob,
1644  /* Could - with a refactoring where EFT_MAPS_STOLEN_PCT
1645  * is evaulated for each tile and the city sent to it
1646  * is the tile to transfer's city - be moved into
1647  * EFT_MAPS_STOLEN_PCT. */
1648  game.info.steal_maps_reveals_all_cities);
1649 
1650  // Notify everyone involved.
1651  notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_MAP, ftc_server,
1652  _("Your %s stole parts of the %s world map in %s."),
1653  unit_link(act_unit), nation_adjective_for_player(tgt_player),
1654  tgt_city_link);
1655  notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_MAP, ftc_server,
1656  _("The %s are suspected of stealing"
1657  " parts of your world map in %s."),
1658  nation_plural_for_player(act_player), tgt_city_link);
1659 
1660  // This may cause a diplomatic incident.
1661  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
1662  tgt_city_link);
1663 
1664  // Try to escape.
1665  diplomat_escape_full(act_player, act_unit, true, tgt_tile, tgt_city_link,
1666  paction);
1667 
1668  return true;
1669 }
1670 
1680 bool spy_nuke_city(struct player *act_player, struct unit *act_unit,
1681  struct city *tgt_city, const struct action *paction)
1682 {
1683  struct player *tgt_player;
1684  struct tile *tgt_tile;
1685 
1686  const char *tgt_city_link;
1687 
1688  // Sanity check: The actor still exists.
1689  fc_assert_ret_val(act_player, false);
1690  fc_assert_ret_val(act_unit, false);
1691 
1692  // Sanity check: The target city still exists.
1693  fc_assert_ret_val(tgt_city, false);
1694 
1695  // The victim.
1696  tgt_player = city_owner(tgt_city);
1697 
1698  // Sanity check: The target player still exists.
1699  fc_assert_ret_val(tgt_player, false);
1700 
1701  tgt_tile = city_tile(tgt_city);
1702  tgt_city_link = city_link(tgt_city);
1703 
1704  log_debug("suitcase nuke: unit: %d", act_unit->id);
1705 
1706  // Battle all units capable of diplomatic defense.
1707  if (!diplomat_infiltrate_tile(act_player, tgt_player, paction, act_unit,
1708  nullptr, tgt_tile, nullptr)) {
1709  return false;
1710  }
1711 
1712  log_debug("suitcase nuke: infiltrated");
1713 
1714  // Try to hide the nuke.
1715  if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
1716  paction)) {
1717  notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1718  _("Your %s was caught in an attempt of"
1719  " hiding a nuke in %s!"),
1720  unit_tile_link(act_unit), tgt_city_link);
1721  notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1722  _("You caught %s %s attempting to hide a nuke in %s!"),
1723  nation_adjective_for_player(act_player),
1724  unit_tile_link(act_unit), tgt_city_link);
1725 
1726  // This may cause a diplomatic incident.
1727  action_consequence_caught(paction, act_player, tgt_player, tgt_tile,
1728  tgt_city_link);
1729 
1730  // Execute the caught terrorist.
1731  wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1732 
1733  return false;
1734  }
1735 
1736  log_debug("suitcase nuke: succeeded");
1737 
1738  // Notify everyone involved.
1739  notify_player(act_player, tgt_tile, E_MY_SPY_NUKE, ftc_server,
1740  _("Your %s hid a nuke in %s."), unit_link(act_unit),
1741  tgt_city_link);
1742  notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_NUKE, ftc_server,
1743  _("The %s are suspected of hiding a nuke in %s."),
1744  nation_plural_for_player(act_player), tgt_city_link);
1745 
1746  // Try to escape before the blast.
1747  diplomat_escape_full(act_player, act_unit, true, tgt_tile, tgt_city_link,
1748  paction);
1749 
1750  if (utype_is_consumed_by_action(paction, unit_type_get(act_unit))) {
1751  /* The unit must be wiped here so it won't be seen as a victim of the
1752  * detonation of its own nuke. */
1753  wipe_unit(act_unit, ULR_USED, nullptr);
1754  }
1755 
1756  /* TODO: In real life a suitcase nuke is way less powerful than an ICBM.
1757  * Maybe the size of the suitcase nuke explosion should be ruleset
1758  * configurable? */
1759 
1760  // Detonate the nuke.
1761  dlsend_packet_nuke_tile_info(game.est_connections, tile_index(tgt_tile));
1762  do_nuclear_explosion(act_player, tgt_tile);
1763 
1764  // This may cause a diplomatic incident.
1765  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
1766  tgt_city_link);
1767 
1768  return true;
1769 }
1770 
1774 static void diplomat_charge_movement(struct unit *pdiplomat,
1775  struct tile *ptile)
1776 {
1777  pdiplomat->moves_left -= map_move_cost_unit(&(wld.map), pdiplomat, ptile);
1778  if (pdiplomat->moves_left < 0) {
1779  pdiplomat->moves_left = 0;
1780  }
1781 }
1782 
1790 static bool diplomat_success_vs_defender(struct unit *pattacker,
1791  struct unit *pdefender,
1792  struct tile *pdefender_tile)
1793 {
1794  int chance = 50; // Base 50% chance
1795 
1796  if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
1797  // A defending UTYF_SUPERSPY will defeat every possible attacker.
1798  return false;
1799  }
1800  if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
1801  /* An attacking UTYF_SUPERSPY will defeat every possible defender
1802  * except another UTYF_SUPERSPY. */
1803  return true;
1804  }
1805 
1806  // Add or remove 25% if spy flag.
1807  if (unit_has_type_flag(pattacker, UTYF_SPY)) {
1808  chance += 25;
1809  }
1810  if (unit_has_type_flag(pdefender, UTYF_SPY)) {
1811  chance -= 25;
1812  }
1813 
1814  /* Use power_fact from veteran level to modify chance in a linear way.
1815  * Equal veteran levels cancel out.
1816  * It's probably not good for rulesets to allow this to have more than
1817  * 20% effect. */
1818  {
1819  const struct veteran_level *vatt =
1820  utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
1821  const struct veteran_level *vdef =
1822  utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
1823  fc_assert_ret_val(vatt != nullptr && vdef != nullptr, false);
1824  chance += vatt->power_fact - vdef->power_fact;
1825  }
1826 
1827  // Reduce the chance of an attack by EFT_SPY_RESISTANT percent.
1828  chance -= chance
1830  nullptr, tile_owner(pdefender_tile), nullptr,
1831  tile_city(pdefender_tile), nullptr, pdefender_tile, nullptr,
1832  nullptr, nullptr, nullptr, nullptr, EFT_SPY_RESISTANT)
1833  / 100;
1834 
1835  return static_cast<int>(fc_rand(100)) < chance;
1836 }
1837 
1854 static bool
1855 diplomat_infiltrate_tile(struct player *pplayer, struct player *cplayer,
1856  const struct action *paction,
1857  struct unit *pdiplomat, struct unit *pvictim,
1858  struct tile *ptile, struct player **defender_owner)
1859 {
1860  struct unit *punit;
1861  char link_city[MAX_LEN_LINK] = "";
1862  char link_diplomat[MAX_LEN_LINK];
1863  char link_unit[MAX_LEN_LINK];
1864  struct city *pcity = tile_city(ptile);
1865 
1866  if (pcity) {
1867  // N.B.: *_link() always returns the same pointer.
1868  sz_strlcpy(link_city, city_link(pcity));
1869  }
1870  punit = get_diplomatic_defender(pdiplomat, pvictim, ptile);
1871  if (punit) {
1872  struct player *uplayer = unit_owner(punit);
1873 
1874  if (defender_owner != nullptr) {
1875  // Some action performers may want to know defender player.
1876  *defender_owner = uplayer;
1877  }
1878 
1879  if (diplomat_success_vs_defender(pdiplomat, punit, ptile)) {
1880  /* Defending Spy/Diplomat dies. */
1881 
1882  // N.B.: *_link() always returns the same pointer.
1883  sz_strlcpy(link_unit, unit_tile_link(punit));
1884  sz_strlcpy(link_diplomat, unit_link(pdiplomat));
1885 
1886  notify_player(pplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1887  // TRANS: <unit> ... <diplomat>
1888  _("An enemy %s has been eliminated by your %s."),
1889  link_unit, link_diplomat);
1890 
1891  if (pcity) {
1892  if (uplayer == cplayer || cplayer == nullptr) {
1893  notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1894  // TRANS: <unit> ... <city> ... <diplomat>
1895  _("Your %s has been eliminated defending %s"
1896  " against a %s."),
1897  link_unit, link_city, link_diplomat);
1898  } else {
1899  notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1900  /* TRANS: <nation adj> <unit> ... <city>
1901  * TRANS: ... <diplomat> */
1902  _("A %s %s has been eliminated defending %s "
1903  "against a %s."),
1904  nation_adjective_for_player(uplayer), link_unit,
1905  link_city, link_diplomat);
1906  notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1907  /* TRANS: ... <unit> ... <nation adj> <city>
1908  * TRANS: ... <diplomat> */
1909  _("Your %s has been eliminated defending %s %s "
1910  "against a %s."),
1911  link_unit, nation_adjective_for_player(cplayer),
1912  link_city, link_diplomat);
1913  }
1914  } else {
1915  if (uplayer == cplayer || cplayer == nullptr) {
1916  notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1917  // TRANS: <unit> ... <diplomat>
1918  _("Your %s has been eliminated defending "
1919  "against a %s."),
1920  link_unit, link_diplomat);
1921  } else {
1922  notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1923  // TRANS: <nation adj> <unit> ... <diplomat>
1924  _("A %s %s has been eliminated defending "
1925  "against a %s."),
1926  nation_adjective_for_player(uplayer), link_unit,
1927  link_diplomat);
1928  notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1929  // TRANS: ... <unit> ... <diplomat>
1930  _("Your %s has been eliminated defending "
1931  "against a %s."),
1932  link_unit, link_diplomat);
1933  }
1934  }
1935 
1936  pdiplomat->moves_left = MAX(0, pdiplomat->moves_left - SINGLE_MOVE);
1937 
1938  // Attacking unit became more experienced?
1939  if (maybe_make_veteran(pdiplomat)) {
1940  notify_unit_experience(pdiplomat);
1941  }
1942  send_unit_info(nullptr, pdiplomat);
1943  wipe_unit(punit, ULR_ELIMINATED, pplayer);
1944  return false;
1945  } else {
1946  /* Attacking Spy/Diplomat dies. */
1947 
1948  const char *victim_link;
1949 
1950  // N.B.: *_link() always returns the same pointer.
1951  sz_strlcpy(link_unit, unit_link(punit));
1952  sz_strlcpy(link_diplomat, unit_tile_link(pdiplomat));
1953 
1954  notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1955  _("Your %s was eliminated by a defending %s."),
1956  link_diplomat, link_unit);
1957 
1958  if (pcity) {
1959  if (uplayer == cplayer || cplayer == nullptr) {
1960  notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1961  _("Eliminated a %s %s while infiltrating %s."),
1962  nation_adjective_for_player(pplayer), link_diplomat,
1963  link_city);
1964  } else {
1965  notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1966  _("A %s %s eliminated a %s %s while infiltrating "
1967  "%s."),
1968  nation_adjective_for_player(uplayer), link_unit,
1969  nation_adjective_for_player(pplayer), link_diplomat,
1970  link_city);
1971  notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1972  _("Your %s eliminated a %s %s while infiltrating "
1973  "%s."),
1974  link_unit, nation_adjective_for_player(pplayer),
1975  link_diplomat, link_city);
1976  }
1977  } else {
1978  if (uplayer == cplayer || cplayer == nullptr) {
1979  notify_player(
1980  uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1981  _("Eliminated a %s %s while infiltrating our troops."),
1982  nation_adjective_for_player(pplayer), link_diplomat);
1983  } else {
1984  notify_player(
1985  cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1986  _("A %s %s eliminated a %s %s while infiltrating our "
1987  "troops."),
1988  nation_adjective_for_player(uplayer), link_unit,
1989  nation_adjective_for_player(pplayer), link_diplomat);
1990  notify_player(
1991  uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1992  // TRANS: ... <unit> ... <diplomat>
1993  _("Your %s eliminated a %s %s while infiltrating our "
1994  "troops."),
1995  link_unit, nation_adjective_for_player(pplayer),
1996  link_diplomat);
1997  }
1998  }
1999 
2000  // Defending unit became more experienced?
2001  if (maybe_make_veteran(punit)) {
2002  notify_unit_experience(punit);
2003  }
2004 
2005  victim_link = nullptr;
2006 
2007  switch (action_get_target_kind(paction)) {
2008  case ATK_CITY:
2009  fc_assert_ret_val(pcity, false);
2010  victim_link = city_link(pcity);
2011  break;
2012  case ATK_UNIT:
2013  case ATK_UNITS:
2014  victim_link = pvictim ? unit_tile_link(pvictim) : tile_link(ptile);
2015  break;
2016  case ATK_TILE:
2017  victim_link = tile_link(ptile);
2018  break;
2019  case ATK_SELF:
2020  // How did a self targeted action end up here?
2021  fc_assert(action_get_target_kind(paction) != ATK_SELF);
2022  break;
2023  case ATK_COUNT:
2024  break;
2025  }
2026 
2027  fc_assert(victim_link != nullptr);
2028 
2029  action_consequence_caught(paction, pplayer, uplayer, ptile,
2030  victim_link);
2031 
2032  wipe_unit(pdiplomat, ULR_ELIMINATED, uplayer);
2033  return false;
2034  }
2035  }
2036 
2037  return true;
2038 }
2039 
2050 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
2051  const struct city *pcity,
2052  const struct action *paction)
2053 {
2054  struct tile *ptile;
2055  const char *vlink;
2056 
2057  if (pcity) {
2058  ptile = city_tile(pcity);
2059  vlink = city_link(pcity);
2060  } else {
2061  ptile = unit_tile(pdiplomat);
2062  vlink = nullptr;
2063  }
2064 
2065  return diplomat_escape_full(pplayer, pdiplomat, pcity != nullptr, ptile,
2066  vlink, paction);
2067 }
2068 
2078 static void diplomat_escape_full(struct player *pplayer,
2079  struct unit *pdiplomat, bool city_related,
2080  struct tile *ptile, const char *vlink,
2081  const struct action *paction)
2082 {
2083  int escapechance;
2084  struct city *spyhome;
2085 
2086  fc_assert(paction->actor.is_unit.moves_actor == MAK_ESCAPE);
2087 
2088  /* Veteran level's power factor's effect on escape chance is relative to
2089  * unpromoted unit's power factor */
2090  {
2091  const struct veteran_level *vunit =
2092  utype_veteran_level(unit_type_get(pdiplomat), pdiplomat->veteran);
2093  const struct veteran_level *vbase =
2094  utype_veteran_level(unit_type_get(pdiplomat), 0);
2095 
2096  escapechance =
2097  game.server.diplchance + (vunit->power_fact - vbase->power_fact);
2098  }
2099 
2100  // find closest city for escape target
2101  spyhome = find_closest_city(ptile, nullptr, unit_owner(pdiplomat), false,
2102  false, false, true, false, nullptr);
2103 
2104  if (spyhome
2105  && !utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))
2106  && (unit_has_type_flag(pdiplomat, UTYF_SUPERSPY)
2107  || fc_rand(100) < escapechance)) {
2108  /* Attacking Spy/Diplomat survives. */
2109  notify_player(pplayer, ptile, E_MY_DIPLOMAT_ESCAPE, ftc_server,
2110  _("Your %s has successfully completed"
2111  " the mission and returned unharmed to %s."),
2112  unit_link(pdiplomat), city_link(spyhome));
2113  if (maybe_make_veteran(pdiplomat)) {
2114  notify_unit_experience(pdiplomat);
2115  }
2116 
2117  // being teleported costs all movement
2118  if (!teleport_unit_to_city(pdiplomat, spyhome, -1, false)) {
2119  send_unit_info(nullptr, pdiplomat);
2120  qCritical("Bug in diplomat_escape: Spy can't teleport.");
2121  return;
2122  }
2123 
2124  return;
2125  } else {
2126  if (city_related) {
2127  notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2128  _("Your %s was captured after completing"
2129  " the mission in %s."),
2130  unit_tile_link(pdiplomat), vlink);
2131  } else {
2132  notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2133  _("Your %s was captured after completing"
2134  " the mission."),
2135  unit_tile_link(pdiplomat));
2136  }
2137  }
2138 
2139  if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
2140  /* The unit was caught, not spent. It must therefore be deleted by
2141  * hand. */
2142  wipe_unit(pdiplomat, ULR_CAUGHT, nullptr);
2143  }
2144 }
2145 
2149 int count_diplomats_on_tile(struct tile *ptile)
2150 {
2151  int count = 0;
2152 
2153  unit_list_iterate((ptile)->units, punit)
2154  {
2155  if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
2156  count++;
2157  }
2158  }
2160 
2161  return count;
2162 }
bool is_action_enabled_unit_on_unit(const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Returns TRUE if actor_unit can do wanted_action to target_unit as far as action enablers are concerne...
Definition: actions.cpp:4007
const QString action_name_translation(const struct action *action)
Get the action name used when displaying the action in the UI.
Definition: actions.cpp:1353
bool is_action_enabled_unit_on_tile(const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Returns TRUE if actor_unit can do wanted_action to the target_tile as far as action enablers are conc...
Definition: actions.cpp:4136
enum action_target_kind action_get_target_kind(const struct action *paction)
Get the target kind of an action.
Definition: actions.cpp:1198
bool action_has_result(const struct action *paction, enum action_result result)
Returns TRUE iff performing the specified action has the specified result.
Definition: actions.cpp:1248
void action_consequence_success(const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Take care of any consequences (like casus belli) of successfully performing the given action.
void action_consequence_caught(const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Take care of any consequences (like casus belli) of getting caught while trying to perform the given ...
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)
Returns TRUE iff the spy/diplomat was caught outside of a diplomatic battle.
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Return TRUE iff the city has this building in it.
Definition: city.cpp:1189
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
citizens city_size_get(const struct city *pcity)
Get the city size.
Definition: city.cpp:1101
#define city_built_iterate(_pcity, _p)
Definition: city.h:752
#define city_built_iterate_end
Definition: city.h:759
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)
Find the city closest to 'ptile'.
Definition: citytools.cpp:849
void send_city_info(struct player *dest, struct city *pcity)
A wrapper, accessing either broadcast_city_info() (dest == nullptr), or a convenience case of send_ci...
Definition: citytools.cpp:2295
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Updates a players knowledge about a city.
Definition: citytools.cpp:2637
void city_illness_strike(struct city *pcity)
Give the city a plague.
Definition: citytools.cpp:2829
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Destroy the improvement in the city straight-out.
Definition: citytools.cpp:2878
bool transfer_city(struct player *ptaker, struct city *pcity, int kill_outside, bool transfer_unit_verbose, bool resolve_stack, bool raze, bool build_free)
Handles all transactions in relation to transferring a city.
Definition: citytools.cpp:1084
void package_city(struct city *pcity, struct packet_city_info *packet, struct traderoute_packet_list *routes, bool dipl_invest)
Fill city info packet with information about given city.
Definition: citytools.cpp:2438
#define traderoute_packet_list_iterate_end
Definition: citytools.h:28
#define traderoute_packet_list_iterate(ptrlist, ptr)
Definition: citytools.h:26
void nullify_prechange_production(struct city *pcity)
Initialize all variables containing information about production before it was changed.
Definition: cityturn.cpp:3254
bool city_empty_food_stock(struct city *pcity)
Returns TRUE iff the city's food stock was emptied.
Definition: cityturn.cpp:3988
int city_incite_cost(struct player *pplayer, struct city *pcity)
Returns the cost to incite a city.
Definition: cityturn.cpp:3135
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Reduce the city size.
Definition: cityturn.cpp:815
bool city_refresh(struct city *pcity)
Updates unit upkeeps and city internal cached data.
Definition: cityturn.cpp:147
struct unit * get_diplomatic_defender(const struct unit *act_unit, const struct unit *pvictim, const struct tile *tgt_tile)
Returns the defender of the tile in a diplomatic battle or nullptr if no diplomatic defender could be...
Definition: combat.cpp:792
void establish_embassy(struct player *pplayer, struct player *aplayer)
Create an embassy.
Definition: diplhand.cpp:689
static void diplomat_escape_full(struct player *pplayer, struct unit *pdiplomat, bool city_related, struct tile *ptile, const char *vlink, const struct action *paction)
This determines if a diplomat/spy survives and escapes.
Definition: diplomats.cpp:2078
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Steal part of another player's map.
Definition: diplomats.cpp:1559
int diplomats_unignored_tech_stealings(struct unit *pdiplomat, struct city *pcity)
Returns the amount of tech thefts from a city not ignored by the EFT_STEALINGS_IGNORE effect.
Definition: diplomats.cpp:764
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Sabotage an enemy unit.
Definition: diplomats.cpp:477
static bool diplomat_may_lose_gold(struct player *dec_player, struct player *inc_player, int revolt_gold)
Gold for inciting might get lost.
Definition: diplomats.cpp:985
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Establish an embassy.
Definition: diplomats.cpp:418
static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef, struct tile *pdefender_tile)
This determines if a diplomat/spy succeeds against some defender, who is also a diplomat or spy.
Definition: diplomats.cpp:1790
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)
This determines if a diplomat/spy succeeds in infiltrating a tile.
Definition: diplomats.cpp:1855
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Try to steal a technology from an enemy city.
Definition: diplomats.cpp:805
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Sabotage enemy city's improvement or production.
Definition: diplomats.cpp:1170
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Incite a city to disaffect.
Definition: diplomats.cpp:1036
static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat, const struct city *pcity, const struct action *paction)
This determines if a diplomat/spy survives and escapes.
Definition: diplomats.cpp:2050
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Steal gold from another player.
Definition: diplomats.cpp:1424
bool spy_spread_plague(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Spread a plague to the target city.
Definition: diplomats.cpp:167
bool spy_nuke_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Hide a suitcase nuke in a city and detonate it.
Definition: diplomats.cpp:1680
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Investigate a city.
Definition: diplomats.cpp:271
static void diplomat_charge_movement(struct unit *pdiplomat, struct tile *ptile)
This subtracts the destination movement cost from a diplomat/spy.
Definition: diplomats.cpp:1774
void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat, struct city *pcity, const struct action *paction, bool disturb_player)
Get list of improvements from city (for purposes of sabotage).
Definition: diplomats.cpp:361
bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Bribe an enemy unit.
Definition: diplomats.cpp:561
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Diplomatic battle.
Definition: diplomats.cpp:725
bool spy_poison(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Poison a city's water supply.
Definition: diplomats.cpp:84
int count_diplomats_on_tile(struct tile *ptile)
Return number of diplomats on this square.
Definition: diplomats.cpp:2149
int get_target_bonus_effects(struct effect_list *plist, const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, enum effect_type effect_type, enum vision_layer vision_layer, enum national_intelligence nintel)
Returns the effect bonus of a given type for any target.
Definition: effects.cpp:611
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Returns the effect bonus at a unit.
Definition: effects.cpp:869
int get_city_bonus(const struct city *pcity, enum effect_type effect_type, enum vision_layer vlayer)
Returns the effect bonus at a city.
Definition: effects.cpp:688
int Tech_type_id
Definition: fc_types.h:294
int Impr_type_id
Definition: fc_types.h:293
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
const char * tile_link(const struct tile *ptile)
Get a text link to a tile.
const char * unit_tile_link(const struct unit *punit)
Get a text link to a unit tile (make a clickable link to a tile with the unit type name as text).
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
Get a text link to a city.
const char * unit_link(const struct unit *punit)
Get a text link to an unit.
#define MAX_LEN_LINK
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
const char * improvement_rule_name(const struct impr_type *pimprove)
Return the (untranslated) rule name of the improvement.
struct impr_type * improvement_by_number(const Impr_type_id id)
Returns the improvement type for the given index/ID.
Impr_type_id improvement_number(const struct impr_type *pimprove)
Return the improvement index.
Impr_type_id improvement_index(const struct impr_type *pimprove)
Return the improvement index.
const char * improvement_name_translation(const struct impr_type *pimprove)
Return the (translated) name of the given improvement.
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_debug(message,...)
Definition: log.h:65
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition: log.h:132
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition: map.h:221
void give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Transfer (random parts of) player pfrom's world map to pto.
Definition: maphand.cpp:2558
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Returns city located at given tile from player map.
Definition: maphand.cpp:1317
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "exist" at this location.
Definition: movement.cpp:267
#define SINGLE_MOVE
Definition: movement.h:17
const char * nation_plural_for_player(const struct player *pplayer)
Return the (translated) plural noun of the given nation of a player.
Definition: nation.cpp:155
const char * nation_adjective_for_player(const struct player *pplayer)
Return the (translated) adjective for the given nation of a player.
Definition: nation.cpp:146
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Similar to notify_conn_packet (see also), but takes player as "destination".
Definition: notify.cpp:284
@ UNIT_INFO_CITY_PRESENT
Definition: packets.h:63
@ UNIT_INFO_CITY_SUPPORTED
Definition: packets.h:62
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
If the specified player owns the unit with the specified id, return pointer to the unit struct.
Definition: player.cpp:1139
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
Definition: player.cpp:1334
static bool is_barbarian(const struct player *pplayer)
Definition: player.h:474
void send_player_all_c(struct player *src, struct conn_list *dest)
Send all information about a player (player_info and all player_diplstates) to the given connections.
Definition: plrhand.cpp:1031
void send_player_info_c(struct player *src, struct conn_list *dest)
Send information about player slot 'src', or all valid (i.e.
Definition: plrhand.cpp:1048
#define fc_rand(_size)
Definition: rand.h:16
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Make user-friendly text for the source.
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Returns TRUE iff the given tech can be given to the players sharing the research immediately.
Definition: research.cpp:686
void script_server_signal_emit(const char *signal_name,...)
Invoke all the callback functions attached to a given signal.
#define MAX(x, y)
Definition: shared.h:48
struct action::@10::@11 is_unit
action_id id
Definition: actions.h:306
union action::@10 actor
Definition: city.h:291
int id
Definition: city.h:296
struct universal production
Definition: city.h:368
int steal
Definition: city.h:383
struct tile * tile
Definition: city.h:293
int shield_stock
Definition: city.h:339
struct unit_list * units_supported
Definition: city.h:377
struct civ_game::@28::@32 server
struct conn_list * est_connections
Definition: game.h:88
struct packet_game_info info
Definition: game.h:80
int sabotage
Definition: improvement.h:70
Definition: player.h:231
struct conn_list * connections
Definition: player.h:280
struct player_economic economic
Definition: player.h:266
int future_tech
Definition: research.h:35
Definition: tile.h:42
Definition: unit.h:134
int moves_left
Definition: unit.h:147
int id
Definition: unit.h:141
int hp
Definition: unit.h:148
struct tile * tile
Definition: unit.h:136
int homecity
Definition: unit.h:142
int veteran
Definition: unit.h:149
int power_fact
Definition: unittype.h:453
bv_imprs improvements
Definition: vision.h:129
struct civ_map map
Definition: world_object.h:21
#define sz_strlcpy(dest, src)
Definition: support.h:140
struct advance * valid_advance_by_number(const Tech_type_id id)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:154
#define A_FUTURE
Definition: tech.h:39
#define A_NONE
Definition: tech.h:36
#define A_UNSET
Definition: tech.h:41
Tech_type_id steal_a_tech(struct player *pplayer, struct player *victim, Tech_type_id preferred)
If victim has a tech which pplayer doesn't have, pplayer will get it.
Definition: techtools.cpp:1227
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_owner(_tile)
Definition: tile.h:78
bool unit_is_alive(int id)
Check if unit with given id is still alive.
Definition: unit.cpp:2014
int unit_bribe_cost(struct unit *punit, struct player *briber)
Calculate how expensive it is to bribe the unit.
Definition: unit.cpp:2061
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool igzoc, bool move_do_not_act)
Will try to move to/attack the tile dest_x,dest_y.
Definition: unithand.cpp:4654
bool unit_perform_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id_incoming, const char *name, const action_id action_type, const enum action_requester requester)
Execute a request to perform an action and let the caller know if it was performed or not.
Definition: unithand.cpp:2737
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
void unit_did_action(struct unit *punit)
Mark a unit as having done something at the current time.
Definition: unittools.cpp:4879
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
We don't really change owner of the unit, but create completely new unit as its copy.
Definition: unittools.cpp:2302
void bounce_unit(struct unit *punit, bool verbose, bounce_reason reason, int max_distance)
Move or remove a unit due to stack conflicts.
Definition: unittools.cpp:1327
void send_unit_info(struct conn_list *dest, struct unit *punit)
Send the unit to the players who need the info.
Definition: unittools.cpp:2808
void notify_unit_experience(struct unit *punit)
Common notification for all experience levels.
Definition: unittools.cpp:723
void package_short_unit(struct unit *punit, struct packet_unit_short_info *packet, enum unit_info_use packet_use, int info_city_id)
Package a short_unit_info packet.
Definition: unittools.cpp:2750
bool maybe_make_veteran(struct unit *punit)
Unit has a chance to become veteran.
Definition: unittools.cpp:204
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Remove the unit, and passengers if it is a carrying any.
Definition: unittools.cpp:2248
void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
Nuke all the squares in a 3x3 square around the center of the explosion pplayer is the player that ca...
Definition: unittools.cpp:2999
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Teleport punit to city at cost specified.
Definition: unittools.cpp:1212
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Returns TRUE iff the unit type is unique and the player already has one.
Definition: unittype.cpp:1599
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Returns TRUE iff performing the specified action will consume an actor unit of the specified type.
Definition: unittype.cpp:936
const char * unit_name_translation(const struct unit *punit)
Return the (translated) name of the unit.
Definition: unittype.cpp:1265
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Return veteran level properties of given unit in given veterancy level.
Definition: unittype.cpp:2224