civ2civ3: improve README.civ2civ3 text.
[freeciv.git] / server / diplomats.c
bloba7e3856ddce8602209127d039eca98e1a7ef64c6
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdio.h>
20 /* utility */
21 #include "bitvector.h"
22 #include "fcintl.h"
23 #include "log.h"
24 #include "rand.h"
26 /* common */
27 #include "base.h"
28 #include "events.h"
29 #include "game.h"
30 #include "government.h"
31 #include "map.h"
32 #include "movement.h"
33 #include "player.h"
34 #include "research.h"
35 #include "unitlist.h"
37 /* server */
38 #include "actiontools.h"
39 #include "aiiface.h"
40 #include "citytools.h"
41 #include "cityturn.h"
42 #include "diplhand.h"
43 #include "diplomats.h"
44 #include "maphand.h"
45 #include "notify.h"
46 #include "plrhand.h"
47 #include "techtools.h"
48 #include "unithand.h"
49 #include "unittools.h"
51 /* server/scripting */
52 #include "script_server.h"
54 /****************************************************************************/
56 static void diplomat_charge_movement (struct unit *pdiplomat,
57 struct tile *ptile);
58 static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef,
59 struct tile *pdefender_tile);
60 static bool diplomat_infiltrate_tile(struct player *pplayer,
61 struct player *cplayer,
62 int action_id,
63 struct unit *pdiplomat,
64 struct unit *pvictim,
65 struct tile *ptile);
66 static bool diplomat_was_caught(struct player *act_player,
67 struct unit *act_unit,
68 struct city *tgt_city,
69 struct player *tgt_player,
70 struct action *act);
71 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
72 const struct city *pcity);
73 static void diplomat_escape_full(struct player *pplayer,
74 struct unit *pdiplomat,
75 bool city_related,
76 struct tile *ptile,
77 const char *vlink);
79 /******************************************************************************
80 Poison a city's water supply.
82 - Check for infiltration success. Our poisoner may not survive this.
83 - If successful, reduces population by one point.
85 - The poisoner may be captured and executed, or escape to its home town.
87 'pplayer' is the player who tries to poison 'pcity' with its unit
88 'pdiplomat'.
90 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
91 this returns TRUE, unit may have died during the action.
92 ****************************************************************************/
93 bool spy_poison(struct player *pplayer, struct unit *pdiplomat,
94 struct city *pcity, const enum gen_action action_id)
96 struct player *cplayer;
97 struct tile *ctile;
98 const char *clink;
100 /* Fetch target city's player. Sanity checks. */
101 fc_assert_ret_val(pcity, FALSE);
102 cplayer = city_owner(pcity);
103 fc_assert_ret_val(cplayer, FALSE);
105 /* Sanity check: The actor still exists. */
106 fc_assert_ret_val(pplayer, FALSE);
107 fc_assert_ret_val(pdiplomat, FALSE);
109 ctile = city_tile(pcity);
110 clink = city_link(pcity);
112 log_debug("poison: unit: %d", pdiplomat->id);
114 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
115 if (!diplomat_infiltrate_tile(pplayer, cplayer, action_id,
116 pdiplomat, NULL, ctile)) {
117 return FALSE;
120 log_debug("poison: infiltrated");
121 log_debug("poison: succeeded");
123 /* Poison people! */
124 if (city_reduce_size(pcity, 1, pplayer, "poison")) {
125 /* Notify everybody involved. */
126 notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
127 _("Your %s poisoned the water supply of %s."),
128 unit_link(pdiplomat), clink);
129 notify_player(cplayer, ctile,
130 E_ENEMY_DIPLOMAT_POISON, ftc_server,
131 _("%s is suspected of poisoning the water supply of %s."),
132 player_name(pplayer), clink);
134 if (game.info.poison_empties_food_stock) {
135 /* The food was poisoned too. */
136 city_empty_food_stock(pcity);
139 /* Update clients. */
140 city_refresh (pcity);
141 send_city_info(NULL, pcity);
142 } else {
143 /* Notify everybody involved. */
144 notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
145 _("Your %s destroyed %s by poisoning its water supply."),
146 unit_link(pdiplomat), clink);
147 notify_player(cplayer, ctile,
148 E_ENEMY_DIPLOMAT_POISON, ftc_server,
149 _("%s is suspected of destroying %s by poisoning its"
150 " water supply."),
151 player_name(pplayer), clink);
154 /* this may cause a diplomatic incident */
155 action_id_consequence_success(action_id, pplayer, cplayer, ctile, clink);
157 /* Now lets see if the spy survives. */
158 diplomat_escape_full(pplayer, pdiplomat, TRUE, ctile, clink);
160 return TRUE;
163 /******************************************************************************
164 Investigate a city.
166 - It costs some minimal movement to investigate a city.
168 - The actor unit always survives the investigation unless the action
169 being performed is configured to always consume the actor unit.
171 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
172 this returns TRUE, unit may have died during the action.
173 ****************************************************************************/
174 bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
175 struct city *pcity,
176 const struct action *paction)
178 struct player *cplayer;
179 struct packet_unit_short_info unit_packet;
180 struct packet_city_info city_packet;
181 struct packet_web_city_info_addition web_packet;
182 struct traderoute_packet_list *routes;
184 /* Fetch target city's player. Sanity checks. */
185 fc_assert_ret_val(pcity, FALSE);
186 cplayer = city_owner(pcity);
187 fc_assert_ret_val(cplayer, FALSE);
189 /* Sanity check: The actor still exists. */
190 fc_assert_ret_val(pplayer, FALSE);
191 fc_assert_ret_val(pdiplomat, FALSE);
193 /* Sanity check: The target is foreign. */
194 if (cplayer == pplayer) {
195 /* Nothing to do to a domestic target. */
196 return FALSE;
199 log_debug("investigate: unit: %d", pdiplomat->id);
201 /* Do It... */
202 update_dumb_city(pplayer, pcity);
203 /* Special case for a diplomat/spy investigating a city:
204 The investigator needs to know the supported and present
205 units of a city, whether or not they are fogged. So, we
206 send a list of them all before sending the city info.
207 As this is a special case we bypass send_unit_info. */
208 unit_list_iterate(pcity->units_supported, punit) {
209 package_short_unit(punit, &unit_packet,
210 UNIT_INFO_CITY_SUPPORTED, pcity->id);
211 /* We need to force to send the packet to ensure the client will receive
212 * something (e.g. investigating twice). */
213 lsend_packet_unit_short_info(pplayer->connections, &unit_packet, TRUE);
214 } unit_list_iterate_end;
215 unit_list_iterate((pcity->tile)->units, punit) {
216 package_short_unit(punit, &unit_packet,
217 UNIT_INFO_CITY_PRESENT, pcity->id);
218 /* We need to force to send the packet to ensure the client will receive
219 * something (e.g. investigating twice). */
220 lsend_packet_unit_short_info(pplayer->connections, &unit_packet, TRUE);
221 } unit_list_iterate_end;
222 /* Send city info to investigator's player.
223 As this is a special case we bypass send_city_info. */
224 routes = traderoute_packet_list_new();
225 package_city(pcity, &city_packet, &web_packet, routes, TRUE);
226 /* We need to force to send the packet to ensure the client will receive
227 * something and popup the city dialog. */
228 lsend_packet_city_info(pplayer->connections, &city_packet, TRUE);
229 web_lsend_packet(city_info_addition, pplayer->connections, &web_packet, TRUE);
230 traderoute_packet_list_iterate(routes, route_packet) {
231 lsend_packet_traderoute_info(pplayer->connections, route_packet);
232 FC_FREE(route_packet);
233 } traderoute_packet_list_iterate_end;
234 traderoute_packet_list_destroy(routes);
236 /* Charge a nominal amount of movement for this. */
237 (pdiplomat->moves_left)--;
238 if (pdiplomat->moves_left < 0) {
239 pdiplomat->moves_left = 0;
242 /* this may cause a diplomatic incident */
243 action_consequence_success(paction, pplayer, cplayer,
244 city_tile(pcity), city_link(pcity));
246 /* The actor unit always survive unless the action it self has determined
247 * to always consume it. */
248 if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
249 /* This unit isn't about to be consumed. Send updated unit information
250 * to the clients. */
251 send_unit_info(NULL, pdiplomat);
254 return TRUE;
257 /******************************************************************************
258 Get list of improvements from city (for purposes of sabotage).
260 - Always successful; returns list.
262 Only send back to the originating connection, if there is one. (?)
263 ****************************************************************************/
264 void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat,
265 struct city *pcity,
266 const enum gen_action action_id)
268 struct packet_city_sabotage_list packet;
270 /* Send city improvements info to player. */
271 BV_CLR_ALL(packet.improvements);
273 improvement_iterate(ptarget) {
274 if (city_has_building(pcity, ptarget)) {
275 BV_SET(packet.improvements, improvement_index(ptarget));
277 } improvement_iterate_end;
279 packet.diplomat_id = pdiplomat->id;
280 packet.city_id = pcity->id;
281 send_packet_city_sabotage_list(pc, &packet);
284 /******************************************************************************
285 Establish an embassy.
287 - Barbarians always execute ambassadors.
288 - Otherwise, the embassy is created.
289 - It costs some minimal movement to establish an embassy.
291 - The actor unit always survives the investigation unless the action
292 being performed is configured to always consume the actor unit.
294 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
295 this returns TRUE, unit may have died during the action.
296 ****************************************************************************/
297 bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
298 struct city *pcity, const struct action *paction)
300 struct player *cplayer;
302 /* Fetch target city's player. Sanity checks. */
303 fc_assert_ret_val(pcity, FALSE);
304 cplayer = city_owner(pcity);
305 fc_assert_ret_val(cplayer, FALSE);
307 /* Sanity check: The actor still exists. */
308 fc_assert_ret_val(pplayer, FALSE);
309 fc_assert_ret_val(pdiplomat, FALSE);
311 /* Sanity check: The target is foreign. */
312 if (cplayer == pplayer) {
313 /* Nothing to do to a domestic target. */
314 return FALSE;
317 log_debug("embassy: unit: %d", pdiplomat->id);
319 log_debug("embassy: succeeded");
321 establish_embassy(pplayer, cplayer);
323 /* Notify everybody involved. */
324 notify_player(pplayer, city_tile(pcity),
325 E_MY_DIPLOMAT_EMBASSY, ftc_server,
326 _("You have established an embassy in %s."),
327 city_link(pcity));
328 notify_player(cplayer, city_tile(pcity),
329 E_ENEMY_DIPLOMAT_EMBASSY, ftc_server,
330 _("The %s have established an embassy in %s."),
331 nation_plural_for_player(pplayer),
332 city_link(pcity));
334 /* Charge a nominal amount of movement for this. */
335 (pdiplomat->moves_left)--;
336 if (pdiplomat->moves_left < 0) {
337 pdiplomat->moves_left = 0;
340 /* this may cause a diplomatic incident */
341 action_consequence_success(paction, pplayer, cplayer,
342 city_tile(pcity), city_link(pcity));
344 /* The actor unit always survive unless the action it self has determined
345 * to always consume it. */
346 if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
347 /* This unit isn't about to be consumed. Send updated unit information
348 * to the clients. */
349 send_unit_info(NULL, pdiplomat);
352 return TRUE;
355 /******************************************************************************
356 Sabotage an enemy unit.
358 - If successful, reduces hit points by half of those remaining.
360 - The saboteur may be captured and executed, or escape to its home town.
362 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
363 this returns TRUE, unit may have died during the action.
364 ****************************************************************************/
365 bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat,
366 struct unit *pvictim,
367 const enum gen_action action_id)
369 char victim_link[MAX_LEN_LINK];
370 struct player *uplayer;
372 /* Fetch target unit's player. Sanity checks. */
373 fc_assert_ret_val(pvictim, FALSE);
374 uplayer = unit_owner(pvictim);
375 fc_assert_ret_val(uplayer, FALSE);
377 /* Sanity check: The actor still exists. */
378 fc_assert_ret_val(pplayer, FALSE);
379 fc_assert_ret_val(pdiplomat, FALSE);
381 log_debug("sabotage-unit: unit: %d", pdiplomat->id);
383 /* N.B: unit_link() always returns the same pointer. */
384 sz_strlcpy(victim_link, unit_link(pvictim));
386 /* Diplomatic battle against any diplomatic defender except the intended
387 * victim of the sabotage. */
388 if (!diplomat_infiltrate_tile(pplayer, uplayer,
389 action_id,
390 pdiplomat, pvictim,
391 unit_tile(pvictim))) {
392 return FALSE;
395 log_debug("sabotage-unit: succeeded");
397 if (pvictim->hp < 2) {
398 /* Not possible to halve the hit points. Kill it. */
399 wipe_unit(pvictim, ULR_KILLED, pplayer);
401 /* Notify everybody involved. */
402 notify_player(pplayer, unit_tile(pvictim),
403 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
404 _("Your %s's successful sabotage killed the %s %s."),
405 unit_link(pdiplomat),
406 nation_adjective_for_player(uplayer),
407 victim_link);
408 notify_player(uplayer, unit_tile(pvictim),
409 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
410 /* TRANS: ... the Poles! */
411 _("Your %s was killed by %s sabotage!"),
412 victim_link,
413 nation_plural_for_player(pplayer));
414 } else {
415 /* Sabotage the unit by removing half its remaining hit points. */
416 pvictim->hp /= 2;
417 send_unit_info(NULL, pvictim);
419 /* Notify everybody involved. */
420 notify_player(pplayer, unit_tile(pvictim),
421 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
422 _("Your %s succeeded in sabotaging the %s %s."),
423 unit_link(pdiplomat),
424 nation_adjective_for_player(uplayer),
425 victim_link);
426 notify_player(uplayer, unit_tile(pvictim),
427 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
428 /* TRANS: ... the Poles! */
429 _("Your %s was sabotaged by the %s!"),
430 victim_link,
431 nation_plural_for_player(pplayer));
434 /* this may cause a diplomatic incident */
435 action_id_consequence_success(action_id, pplayer, uplayer,
436 unit_tile(pvictim), victim_link);
438 /* Now lets see if the spy survives. */
439 diplomat_escape(pplayer, pdiplomat, NULL);
441 return TRUE;
444 /******************************************************************************
445 Bribe an enemy unit.
447 - Can't bribe a unit if:
448 - Player doesn't have enough gold.
449 - Otherwise, the unit will be bribed.
451 - A successful briber will try to move onto the victim's square.
453 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
454 this returns TRUE, unit may have died during the action.
455 ****************************************************************************/
456 bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat,
457 struct unit *pvictim, const enum gen_action action_id)
459 char victim_link[MAX_LEN_LINK];
460 struct player *uplayer;
461 struct tile *victim_tile;
462 int bribe_cost;
463 int diplomat_id = pdiplomat->id;
464 struct city *pcity;
466 /* Fetch target unit's player. Sanity checks. */
467 fc_assert_ret_val(pvictim, FALSE);
468 uplayer = unit_owner(pvictim);
469 fc_assert_ret_val(uplayer, FALSE);
471 /* Sanity check: The actor still exists. */
472 fc_assert_ret_val(pplayer, FALSE);
473 fc_assert_ret_val(pdiplomat, FALSE);
475 /* Sanity check: The target is foreign. */
476 if (uplayer == pplayer) {
477 /* Nothing to do to a domestic target. */
478 return FALSE;
481 /* Sanity check: The victim isn't a unique unit the actor player already
482 * has. */
483 if (utype_player_already_has_this_unique(pplayer,
484 unit_type_get(pvictim))) {
485 log_debug("bribe-unit: already got unique unit");
486 notify_player(pplayer, unit_tile(pdiplomat),
487 E_UNIT_ILLEGAL_ACTION, ftc_server,
488 /* TRANS: You already have a Leader. */
489 _("You already have a %s."),
490 unit_link(pvictim));
492 return FALSE;
495 log_debug("bribe-unit: unit: %d", pdiplomat->id);
497 /* Get bribe cost, ignoring any previously saved value. */
498 bribe_cost = unit_bribe_cost(pvictim, pplayer);
500 /* If player doesn't have enough gold, can't bribe. */
501 if (pplayer->economic.gold < bribe_cost) {
502 notify_player(pplayer, unit_tile(pdiplomat),
503 E_MY_DIPLOMAT_FAILED, ftc_server,
504 _("You don't have enough gold to bribe the %s %s."),
505 nation_adjective_for_player(uplayer),
506 unit_link(pvictim));
507 log_debug("bribe-unit: not enough gold");
508 return FALSE;
511 log_debug("bribe-unit: enough gold");
513 /* Diplomatic battle against any diplomatic defender except the one that
514 * will get the bribe. */
515 if (!diplomat_infiltrate_tile(pplayer, uplayer,
516 action_id,
517 pdiplomat, pvictim,
518 pvictim->tile)) {
519 return FALSE;
522 log_debug("bribe-unit: succeeded");
524 victim_tile = unit_tile(pvictim);
525 pvictim = unit_change_owner(pvictim, pplayer, pdiplomat->homecity,
526 ULR_BRIBED);
528 /* N.B.: unit_link always returns the same pointer. As unit_change_owner()
529 * currently remove the old unit and replace by a new one (with a new id),
530 * we want to make link to the new unit. */
531 sz_strlcpy(victim_link, unit_link(pvictim));
533 /* Notify everybody involved. */
534 notify_player(pplayer, victim_tile, E_MY_DIPLOMAT_BRIBE, ftc_server,
535 /* TRANS: <diplomat> ... <unit> */
536 _("Your %s succeeded in bribing the %s."),
537 unit_link(pdiplomat), victim_link);
538 if (maybe_make_veteran(pdiplomat)) {
539 notify_unit_experience(pdiplomat);
541 notify_player(uplayer, victim_tile, E_ENEMY_DIPLOMAT_BRIBE, ftc_server,
542 /* TRANS: <unit> ... <Poles> */
543 _("Your %s was bribed by the %s."),
544 victim_link, nation_plural_for_player(pplayer));
546 /* The unit may have been on a tile shared with a city or a unit
547 * it no longer can share a tile with. */
548 pcity = tile_city(unit_tile(pvictim));
549 if ((NULL != pcity && !pplayers_allied(city_owner(pcity), pplayer))
550 || 1 < unit_list_size(unit_tile(pvictim)->units)) {
551 bounce_unit(pvictim, TRUE);
554 /* This costs! */
555 pplayer->economic.gold -= bribe_cost;
557 /* This may cause a diplomatic incident */
558 action_id_consequence_success(action_id, pplayer, uplayer,
559 victim_tile, victim_link);
561 if (!unit_is_alive(diplomat_id)) {
562 return TRUE;
565 /* Try to move the briber onto the victim's square unless its a city or
566 * have other units. */
567 if (NULL == pcity && unit_list_size(unit_tile(pvictim)->units) < 2
568 /* Post bribe move. */
569 && !unit_move_handling(pdiplomat, victim_tile, FALSE, TRUE, NULL)
570 /* May have died while trying to move. */
571 && unit_is_alive(diplomat_id)) {
572 pdiplomat->moves_left = 0;
574 if (NULL != player_unit_by_number(pplayer, diplomat_id)) {
575 send_unit_info(NULL, pdiplomat);
578 /* Update clients. */
579 send_player_all_c(pplayer, NULL);
581 return TRUE;
584 /****************************************************************************
585 Try to steal a technology from an enemy city.
586 If action_id is ACTION_SPY_STEAL_TECH, steal a random technology.
587 Otherwise, steal the technology whose ID is "technology".
588 (Note: Only Spies can select what to steal.)
590 - Check for infiltration success. Our thief may not survive this.
591 - Check for basic success. Again, our thief may not survive this.
592 - If a technology has already been stolen from this city at any time:
593 - Diplomats will be caught and executed.
594 - Spies will have an increasing chance of being caught and executed.
595 - Steal technology!
597 - The thief may be captured and executed, or escape to its home town.
599 FIXME: It should give a loss of reputation to steal from a player you are
600 not at war with
602 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
603 this returns TRUE, unit may have died during the action.
604 ****************************************************************************/
605 bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat,
606 struct city *pcity, Tech_type_id technology,
607 const enum gen_action action_id)
609 struct research *presearch, *cresearch;
610 struct player *cplayer;
611 int count;
612 int bonus;
613 int times;
614 Tech_type_id tech_stolen;
616 /* We have to check arguments. They are sent to us by a client,
617 so we cannot trust them */
618 fc_assert_ret_val(pcity, FALSE);
619 cplayer = city_owner(pcity);
620 fc_assert_ret_val(cplayer, FALSE);
622 /* Sanity check: The actor still exists. */
623 fc_assert_ret_val(pplayer, FALSE);
624 fc_assert_ret_val(pdiplomat, FALSE);
626 /* Sanity check: The target is foreign. */
627 if (cplayer == pplayer) {
628 /* Nothing to do to a domestic target. */
629 return FALSE;
632 if (action_id_has_result(action_id, ACTION_SPY_STEAL_TECH)) {
633 /* Can't choose target. Will steal a random tech. */
634 technology = A_UNSET;
637 /* Targeted technology should be a ruleset defined tech,
638 * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
639 if (technology == A_NONE
640 || (technology != A_FUTURE
641 && !(technology == A_UNSET
642 && action_id_has_result(action_id, ACTION_SPY_STEAL_TECH))
643 && !valid_advance_by_number(technology))) {
644 return FALSE;
647 presearch = research_get(pplayer);
648 cresearch = research_get(cplayer);
650 if (technology == A_FUTURE) {
651 if (presearch->future_tech >= cresearch->future_tech) {
652 return FALSE;
654 } else if (technology != A_UNSET) {
655 if (research_invention_state(presearch, technology) == TECH_KNOWN) {
656 return FALSE;
658 if (research_invention_state(cresearch, technology) != TECH_KNOWN) {
659 return FALSE;
661 if (!research_invention_gettable(presearch, technology,
662 game.info.tech_steal_allow_holes)) {
663 return FALSE;
667 log_debug("steal-tech: unit: %d", pdiplomat->id);
669 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
670 if (!diplomat_infiltrate_tile(pplayer, cplayer,
671 action_id,
672 pdiplomat, NULL,
673 pcity->tile)) {
674 return FALSE;
677 log_debug("steal-tech: infiltrated");
679 bonus = get_unit_bonus(pdiplomat, EFT_STEALINGS_IGNORE);
680 if (bonus < 0) {
681 /* Negative effect value means infinite bonus */
682 times = 0;
683 } else {
684 times = pcity->server.steal - bonus;
685 if (times < 0) {
686 times = 0;
690 /* Check if the Diplomat/Spy succeeds with his/her task. */
691 /* (Twice as difficult if target is specified.) */
692 /* (If already stolen from, impossible for Diplomats and harder for Spies.) */
693 if (times > 0 && !unit_has_type_flag(pdiplomat, UTYF_SPY)) {
694 /* Already stolen from: Diplomat always fails! */
695 count = 1;
696 log_debug("steal-tech: difficulty: impossible");
697 } else {
698 /* Determine difficulty. */
699 count = 1;
700 if (action_id_has_result(action_id, ACTION_SPY_TARGETED_STEAL_TECH)) {
701 /* Targeted steal tech is more difficult. */
702 count++;
704 count += times;
705 log_debug("steal-tech: difficulty: %d", count);
706 /* Determine success or failure. */
707 while (count > 0) {
708 if (fc_rand(100) >= game.server.diplchance) {
709 break;
711 count--;
715 if (count > 0) {
716 if (pcity->server.steal > 0 && !unit_has_type_flag(pdiplomat, UTYF_SPY)) {
717 notify_player(pplayer, city_tile(pcity),
718 E_MY_DIPLOMAT_FAILED, ftc_server,
719 _("%s was expecting your attempt to steal technology "
720 "again. Your %s was caught and executed."),
721 city_link(pcity),
722 unit_tile_link(pdiplomat));
723 } else {
724 notify_player(pplayer, city_tile(pcity),
725 E_MY_DIPLOMAT_FAILED, ftc_server,
726 _("Your %s was caught in the attempt of"
727 " stealing technology from %s."),
728 unit_tile_link(pdiplomat),
729 city_link(pcity));
731 notify_player(cplayer, city_tile(pcity),
732 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
733 _("The %s %s failed to steal technology from %s."),
734 nation_adjective_for_player(pplayer),
735 unit_tile_link(pdiplomat),
736 city_link(pcity));
737 /* this may cause a diplomatic incident */
738 action_id_consequence_caught(action_id, pplayer, cplayer,
739 city_tile(pcity), city_link(pcity));
740 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
741 return FALSE;
744 tech_stolen = steal_a_tech(pplayer, cplayer, technology);
746 if (tech_stolen == A_NONE) {
747 notify_player(pplayer, city_tile(pcity),
748 E_MY_DIPLOMAT_FAILED, ftc_server,
749 _("No new technology found in %s."),
750 city_link(pcity));
751 diplomat_charge_movement (pdiplomat, pcity->tile);
752 send_unit_info(NULL, pdiplomat);
753 return FALSE;
756 /* Update stealing player's science progress and research fields */
757 send_player_all_c(pplayer, NULL);
759 /* Record the theft. */
760 (pcity->server.steal)++;
762 /* this may cause a diplomatic incident */
763 action_id_consequence_success(action_id, pplayer, cplayer,
764 city_tile(pcity), city_link(pcity));
766 /* Check if a spy survives her mission. Diplomats never do. */
767 diplomat_escape(pplayer, pdiplomat, pcity);
769 return TRUE;
772 /**************************************************************************
773 Incite a city to disaffect.
775 - Can't incite a city to disaffect if:
776 - Player doesn't have enough gold.
777 - Check for infiltration success. Our provocateur may not survive this.
778 - Check for basic success. Again, our provocateur may not survive this.
779 - Otherwise, the city will disaffect:
780 - Player gets the city.
781 - Player gets certain of the city's present/supported units.
782 - Player gets a technology advance, if any were unknown.
784 - The provocateur may be captured and executed, or escape to its home
785 town.
787 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
788 this returns TRUE, unit may have died during the action.
789 **************************************************************************/
790 bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat,
791 struct city *pcity, const enum gen_action action_id)
793 struct player *cplayer;
794 struct tile *ctile;
795 const char *clink;
796 int revolt_cost;
798 /* Fetch target civilization's player. Sanity checks. */
799 fc_assert_ret_val(pcity, FALSE);
800 cplayer = city_owner(pcity);
801 fc_assert_ret_val(cplayer, FALSE);
803 /* Sanity check: The actor still exists. */
804 fc_assert_ret_val(pplayer, FALSE);
805 fc_assert_ret_val(pdiplomat, FALSE);
807 /* Sanity check: The target is foreign. */
808 if (cplayer == pplayer) {
809 /* Nothing to do to a domestic target. */
810 return FALSE;
813 ctile = city_tile(pcity);
814 clink = city_link(pcity);
816 log_debug("incite: unit: %d", pdiplomat->id);
818 /* Get incite cost, ignoring any previously saved value. */
819 revolt_cost = city_incite_cost(pplayer, pcity);
821 /* If player doesn't have enough gold, can't incite a revolt. */
822 if (pplayer->economic.gold < revolt_cost) {
823 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
824 _("You don't have enough gold to subvert %s."),
825 clink);
826 log_debug("incite: not enough gold");
827 return FALSE;
830 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
831 if (!diplomat_infiltrate_tile(pplayer, cplayer,
832 action_id,
833 pdiplomat, NULL,
834 pcity->tile)) {
835 return FALSE;
838 log_debug("incite: infiltrated");
840 /* Check if the Diplomat/Spy succeeds with his/her task. */
841 if (diplomat_was_caught(pplayer, pdiplomat, pcity, cplayer,
842 action_by_number(action_id))) {
843 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
844 _("Your %s was caught in the attempt"
845 " of inciting a revolt!"),
846 unit_tile_link(pdiplomat));
847 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
848 _("You caught %s %s attempting"
849 " to incite a revolt in %s!"),
850 nation_adjective_for_player(pplayer),
851 unit_tile_link(pdiplomat),
852 clink);
854 /* This may cause a diplomatic incident */
855 action_id_consequence_caught(action_id, pplayer,
856 cplayer, ctile, clink);
858 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
859 return FALSE;
862 log_debug("incite: succeeded");
864 /* Subvert the city to your cause... */
866 /* City loses some population. */
867 if (city_size_get(pcity) > 1) {
868 city_reduce_size(pcity, 1, pplayer, "incited");
871 /* This costs! */
872 pplayer->economic.gold -= revolt_cost;
874 /* Notify everybody involved. */
875 notify_player(pplayer, ctile, E_MY_DIPLOMAT_INCITE, ftc_server,
876 _("Revolt incited in %s, you now rule the city!"),
877 clink);
878 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_INCITE, ftc_server,
879 _("%s has revolted, %s influence suspected."),
880 clink,
881 nation_adjective_for_player(pplayer));
883 pcity->shield_stock = 0;
884 nullify_prechange_production(pcity);
886 /* You get a technology advance, too! */
887 steal_a_tech(pplayer, cplayer, A_UNSET);
889 /* this may cause a diplomatic incident */
890 action_id_consequence_success(action_id,
891 pplayer, cplayer, ctile, clink);
893 /* Transfer city and units supported by this city (that
894 are within one square of the city) to the new owner. */
895 if (transfer_city(pplayer, pcity, 1, TRUE, TRUE, FALSE,
896 !is_barbarian(pplayer))) {
897 script_server_signal_emit("city_transferred", 4,
898 API_TYPE_CITY, pcity,
899 API_TYPE_PLAYER, cplayer,
900 API_TYPE_PLAYER, pplayer,
901 API_TYPE_STRING, "incited");
904 /* Check if a spy survives her mission. Diplomats never do.
905 * _After_ transferring the city, or the city area is first fogged
906 * when the diplomat is removed, and then unfogged when the city
907 * is transferred. */
908 diplomat_escape_full(pplayer, pdiplomat, TRUE, ctile, clink);
910 /* Update the players gold in the client */
911 send_player_info_c(pplayer, pplayer->connections);
913 return TRUE;
916 /**************************************************************************
917 Sabotage enemy city's improvement or production.
918 If this is untargeted sabotage city a random improvement or production is
919 targeted.
920 Targeted sabotage city lets the value of "improvement" decide the target.
921 If "improvement" is -1, sabotage current production.
922 Otherwise, sabotage the city improvement whose ID is "improvement".
924 - Check for infiltration success. Our saboteur may not survive this.
925 - Check for basic success. Again, our saboteur may not survive this.
926 - Determine target, given arguments and constraints.
927 - If specified, city walls and anything in a capital are 50% likely to fail.
928 - Do sabotage!
930 - The saboteur may be captured and executed, or escape to its home town.
932 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
933 this returns TRUE, unit may have died during the action.
934 **************************************************************************/
935 bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat,
936 struct city *pcity, Impr_type_id improvement,
937 const enum gen_action action_id)
939 struct player *cplayer;
940 struct impr_type *ptarget;
941 int count, which;
943 /* Fetch target city's player. Sanity checks. */
944 fc_assert_ret_val(pcity, FALSE);
945 cplayer = city_owner(pcity);
946 fc_assert_ret_val(cplayer, FALSE);
948 /* Sanity check: The actor still exists. */
949 fc_assert_ret_val(pplayer, FALSE);
950 fc_assert_ret_val(pdiplomat, FALSE);
952 log_debug("sabotage: unit: %d", pdiplomat->id);
954 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
955 if (!diplomat_infiltrate_tile(pplayer, cplayer,
956 action_id,
957 pdiplomat, NULL,
958 pcity->tile)) {
959 return FALSE;
962 log_debug("sabotage: infiltrated");
964 /* Check if the Diplomat/Spy succeeds with his/her task. */
965 if (diplomat_was_caught(pplayer, pdiplomat, pcity, cplayer,
966 action_by_number(action_id))) {
967 notify_player(pplayer, city_tile(pcity),
968 E_MY_DIPLOMAT_FAILED, ftc_server,
969 _("Your %s was caught in the attempt"
970 " of industrial sabotage!"),
971 unit_tile_link(pdiplomat));
972 notify_player(cplayer, city_tile(pcity),
973 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
974 _("You caught %s %s attempting sabotage in %s!"),
975 nation_adjective_for_player(pplayer),
976 unit_tile_link(pdiplomat),
977 city_link(pcity));
979 /* This may cause a diplomatic incident */
980 action_id_consequence_caught(action_id, pplayer, cplayer,
981 city_tile(pcity), city_link(pcity));
983 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
984 return FALSE;
987 log_debug("sabotage: succeeded");
989 /* Examine the city for improvements to sabotage. */
990 count = 0;
991 city_built_iterate(pcity, pimprove) {
992 if (pimprove->sabotage > 0) {
993 count++;
995 } city_built_iterate_end;
997 log_debug("sabotage: count of improvements: %d", count);
999 /* Determine the target (-1 is production). */
1000 if (action_id_has_result(action_id, ACTION_SPY_SABOTAGE_CITY)) {
1002 * Pick random:
1003 * 50/50 chance to pick production or some improvement.
1004 * Won't pick something that doesn't exit.
1005 * If nothing to do, say so, deduct movement cost and return.
1007 if (count == 0 && pcity->shield_stock == 0) {
1008 notify_player(pplayer, city_tile(pcity),
1009 E_MY_DIPLOMAT_FAILED, ftc_server,
1010 _("Your %s could not find anything to sabotage in %s."),
1011 unit_link(pdiplomat),
1012 city_link(pcity));
1013 diplomat_charge_movement(pdiplomat, pcity->tile);
1014 send_unit_info(NULL, pdiplomat);
1015 log_debug("sabotage: random: nothing to do");
1016 return FALSE;
1018 if (count == 0 || fc_rand (2) == 1) {
1019 ptarget = NULL;
1020 log_debug("sabotage: random: targeted production");
1021 } else {
1022 ptarget = NULL;
1023 which = fc_rand (count);
1025 city_built_iterate(pcity, pimprove) {
1026 if (pimprove->sabotage > 0) {
1027 if (which > 0) {
1028 which--;
1029 } else {
1030 ptarget = pimprove;
1031 break;
1034 } city_built_iterate_end;
1036 if (NULL != ptarget) {
1037 log_debug("sabotage: random: targeted improvement: %d (%s)",
1038 improvement_number(ptarget),
1039 improvement_rule_name(ptarget));
1040 } else {
1041 log_error("sabotage: random: targeted improvement error!");
1044 } else if (improvement < 0) {
1045 /* If told to sabotage production, do so. */
1046 ptarget = NULL;
1047 log_debug("sabotage: specified target production");
1048 } else {
1049 struct impr_type *pimprove = improvement_by_number(improvement);
1050 if (pimprove == NULL) {
1051 log_error("sabotage: requested for invalid improvement %d", improvement);
1052 return FALSE;
1055 * Told which improvement to pick:
1056 * If try for wonder or palace, complain, deduct movement cost and return.
1057 * If not available, say so, deduct movement cost and return.
1059 if (city_has_building(pcity, pimprove)) {
1060 if (pimprove->sabotage > 0) {
1061 ptarget = pimprove;
1062 log_debug("sabotage: specified target improvement: %d (%s)",
1063 improvement, improvement_rule_name(pimprove));
1064 } else {
1065 notify_player(pplayer, city_tile(pcity),
1066 E_MY_DIPLOMAT_FAILED, ftc_server,
1067 _("You cannot sabotage a %s!"),
1068 improvement_name_translation(pimprove));
1069 diplomat_charge_movement(pdiplomat, pcity->tile);
1070 send_unit_info(NULL, pdiplomat);
1071 log_debug("sabotage: disallowed target improvement: %d (%s)",
1072 improvement, improvement_rule_name(pimprove));
1073 return FALSE;
1075 } else {
1076 notify_player(pplayer, city_tile(pcity),
1077 E_MY_DIPLOMAT_FAILED, ftc_server,
1078 _("Your %s could not find the %s to sabotage in %s."),
1079 unit_name_translation(pdiplomat),
1080 improvement_name_translation(pimprove),
1081 city_link(pcity));
1082 diplomat_charge_movement(pdiplomat, pcity->tile);
1083 send_unit_info(NULL, pdiplomat);
1084 log_debug("sabotage: target improvement not found: %d (%s)",
1085 improvement, improvement_rule_name(pimprove));
1086 return FALSE;
1090 /* Now, the fun stuff! Do the sabotage! */
1091 if (NULL == ptarget) {
1092 char prod[256];
1094 /* Do it. */
1095 pcity->shield_stock = 0;
1096 nullify_prechange_production(pcity); /* Make it impossible to recover */
1098 /* Report it. */
1099 universal_name_translation(&pcity->production, prod, sizeof(prod));
1101 notify_player(pplayer, city_tile(pcity),
1102 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
1103 _("Your %s succeeded in destroying"
1104 " the production of %s in %s."),
1105 unit_link(pdiplomat),
1106 prod,
1107 city_name_get(pcity));
1108 notify_player(cplayer, city_tile(pcity),
1109 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1110 _("The production of %s was destroyed in %s,"
1111 " %s are suspected."),
1112 prod,
1113 city_link(pcity),
1114 nation_plural_for_player(pplayer));
1115 log_debug("sabotage: sabotaged production");
1116 } else {
1117 int vulnerability = ptarget->sabotage;
1119 /* Sabotage a city improvement. */
1122 * One last chance to get caught:
1123 * If target was specified, and it is in the capital or are
1124 * City Walls, then there is a 50% chance of getting caught.
1126 vulnerability -= (vulnerability
1127 * get_city_bonus(pcity, EFT_SABOTEUR_RESISTANT)
1128 / 100);
1130 if (fc_rand(100) >= vulnerability) {
1131 /* Caught! */
1132 notify_player(pplayer, city_tile(pcity),
1133 E_MY_DIPLOMAT_FAILED, ftc_server,
1134 _("Your %s was caught in the attempt of sabotage!"),
1135 unit_tile_link(pdiplomat));
1136 notify_player(cplayer, city_tile(pcity),
1137 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1138 _("You caught %s %s attempting"
1139 " to sabotage the %s in %s!"),
1140 nation_adjective_for_player(pplayer),
1141 unit_tile_link(pdiplomat),
1142 improvement_name_translation(ptarget),
1143 city_link(pcity));
1145 /* This may cause a diplomatic incident */
1146 action_id_consequence_caught(action_id, pplayer, cplayer,
1147 city_tile(pcity), city_link(pcity));
1149 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1150 log_debug("sabotage: caught in capital or on city walls");
1151 return FALSE;
1154 /* Report it. */
1155 notify_player(pplayer, city_tile(pcity),
1156 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
1157 _("Your %s destroyed the %s in %s."),
1158 unit_link(pdiplomat),
1159 improvement_name_translation(ptarget),
1160 city_link(pcity));
1161 notify_player(cplayer, city_tile(pcity),
1162 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1163 _("The %s destroyed the %s in %s."),
1164 nation_plural_for_player(pplayer),
1165 improvement_name_translation(ptarget),
1166 city_link(pcity));
1167 log_debug("sabotage: sabotaged improvement: %d (%s)",
1168 improvement_number(ptarget),
1169 improvement_rule_name(ptarget));
1171 /* Do it. */
1172 building_lost(pcity, ptarget);
1175 /* Update clients. */
1176 send_city_info(NULL, pcity);
1178 /* this may cause a diplomatic incident */
1179 action_id_consequence_success(action_id, pplayer, cplayer,
1180 city_tile(pcity), city_link(pcity));
1182 /* Check if a spy survives her mission. Diplomats never do. */
1183 diplomat_escape(pplayer, pdiplomat, pcity);
1185 return TRUE;
1188 /**************************************************************************
1189 Steal gold from another player.
1190 The amount stolen is decided randomly.
1191 Not everything stolen reaches the player that ordered it stolen.
1193 - Check for infiltration success. Our thief may not survive this.
1194 - Check for basic success. Again, our thief may not survive this.
1195 - Can't steal if there is no money to take.
1197 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
1198 this returns TRUE, unit may have died during the action.
1199 **************************************************************************/
1200 bool spy_steal_gold(struct player *act_player, struct unit *act_unit,
1201 struct city *tgt_city, const enum gen_action action_id)
1203 struct player *tgt_player;
1204 struct tile *tgt_tile;
1206 const char *tgt_city_link;
1208 int gold_take;
1209 int gold_give;
1211 /* Sanity check: The actor still exists. */
1212 fc_assert_ret_val(act_player, FALSE);
1213 fc_assert_ret_val(act_unit, FALSE);
1215 /* Sanity check: The target city still exists. */
1216 fc_assert_ret_val(tgt_city, FALSE);
1218 /* Who to steal from. */
1219 tgt_player = city_owner(tgt_city);
1221 /* Sanity check: The target player still exists. */
1222 fc_assert_ret_val(tgt_player, FALSE);
1224 /* Sanity check: The target is foreign. */
1225 if (tgt_player == act_player) {
1226 /* Nothing to do to a domestic target. */
1227 return FALSE;
1230 /* Sanity check: There is something to steal. */
1231 if (tgt_player->economic.gold <= 0) {
1232 return FALSE;
1235 tgt_tile = city_tile(tgt_city);
1236 tgt_city_link = city_link(tgt_city);
1238 log_debug("steal gold: unit: %d", act_unit->id);
1240 /* Battle all units capable of diplomatic defence. */
1241 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1242 action_id,
1243 act_unit, NULL, tgt_tile)) {
1244 return FALSE;
1247 log_debug("steal gold: infiltrated");
1249 /* The thief may get caught while trying to steal the gold. */
1250 if (diplomat_was_caught(act_player, act_unit, tgt_city, tgt_player,
1251 action_by_number(action_id))) {
1252 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1253 _("Your %s was caught attempting to steal gold!"),
1254 unit_tile_link(act_unit));
1255 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1256 ftc_server,
1257 _("You caught %s %s attempting"
1258 " to steal your gold in %s!"),
1259 nation_adjective_for_player(act_player),
1260 unit_tile_link(act_unit),
1261 tgt_city_link);
1263 /* This may cause a diplomatic incident */
1264 action_id_consequence_caught(action_id, act_player,
1265 tgt_player, tgt_tile, tgt_city_link);
1267 /* Execute the caught thief. */
1268 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1270 return FALSE;
1273 log_debug("steal gold: succeeded");
1275 /* The upper limit on how much gold the thief can steal. */
1276 gold_take = (tgt_player->economic.gold
1277 * get_city_bonus(tgt_city, EFT_MAX_STOLEN_GOLD_PM))
1278 / 1000;
1280 /* How much to actually take. 1 gold is the smallest amount that can be
1281 * stolen. The victim player has at least 1 gold. If he didn't the
1282 * something to steal sanity check would have aborted the theft. */
1283 gold_take = fc_rand(gold_take) + 1;
1285 log_debug("steal gold: will take %d gold", gold_take);
1287 /* Steal the gold. */
1288 tgt_player->economic.gold -= gold_take;
1290 /* Some gold may be lost during transfer. */
1291 gold_give = gold_take
1292 - (gold_take * get_unit_bonus(act_unit, EFT_THIEFS_SHARE_PM))
1293 / 1000;
1295 log_debug("steal gold: will give %d gold", gold_give);
1297 /* Pocket the stolen money. */
1298 act_player->economic.gold += gold_give;
1300 /* Notify everyone involved. */
1301 notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_GOLD, ftc_server,
1302 PL_("Your %s stole %d gold from %s.",
1303 "Your %s stole %d gold from %s.", gold_give),
1304 unit_link(act_unit), gold_give, tgt_city_link);
1305 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_GOLD, ftc_server,
1306 PL_("The %s are suspected of stealing %d gold from %s.",
1307 "The %s are suspected of stealing %d gold from %s.",
1308 gold_take),
1309 nation_plural_for_player(act_player),
1310 gold_take, tgt_city_link);
1312 /* This may cause a diplomatic incident. */
1313 action_id_consequence_success(action_id, act_player,
1314 tgt_player, tgt_tile, tgt_city_link);
1316 /* Try to escape. */
1317 diplomat_escape_full(act_player, act_unit, TRUE,
1318 tgt_tile, tgt_city_link);
1320 /* Update the players' gold in the client */
1321 send_player_info_c(act_player, act_player->connections);
1322 send_player_info_c(tgt_player, tgt_player->connections);
1324 return TRUE;
1327 /**************************************************************************
1328 Steal part of another player's map.
1330 - Check for infiltration success. Our thief may not survive this.
1331 - Check for basic success. Again, our thief may not survive this.
1333 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
1334 this returns TRUE, unit may have died during the action.
1335 **************************************************************************/
1336 bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit,
1337 struct city *tgt_city,
1338 const enum gen_action action_id)
1340 struct player *tgt_player;
1341 struct tile *tgt_tile;
1343 const char *tgt_city_link;
1345 /* Sanity check: The actor still exists. */
1346 fc_assert_ret_val(act_player, FALSE);
1347 fc_assert_ret_val(act_unit, FALSE);
1349 /* Sanity check: The target city still exists. */
1350 fc_assert_ret_val(tgt_city, FALSE);
1352 /* Who to steal from. */
1353 tgt_player = city_owner(tgt_city);
1355 /* Sanity check: The target player still exists. */
1356 fc_assert_ret_val(tgt_player, FALSE);
1358 /* Sanity check: The target is foreign. */
1359 if (tgt_player == act_player) {
1360 /* Nothing to do to a domestic target. */
1361 return FALSE;
1364 tgt_tile = city_tile(tgt_city);
1365 tgt_city_link = city_link(tgt_city);
1367 log_debug("steal some maps: unit: %d", act_unit->id);
1369 /* Battle all units capable of diplomatic defence. */
1370 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1371 action_id,
1372 act_unit, NULL, tgt_tile)) {
1373 return FALSE;
1376 log_debug("steal some maps: infiltrated");
1378 /* Try to steal the map. */
1379 if (diplomat_was_caught(act_player, act_unit, tgt_city, tgt_player,
1380 action_by_number(action_id))) {
1381 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1382 _("Your %s was caught in an attempt of"
1383 " stealing parts of the %s world map!"),
1384 unit_tile_link(act_unit),
1385 nation_adjective_for_player(tgt_player));
1386 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1387 ftc_server,
1388 _("You caught %s %s attempting to steal"
1389 " parts of your world map in %s!"),
1390 nation_adjective_for_player(act_player),
1391 unit_tile_link(act_unit),
1392 tgt_city_link);
1394 /* This may cause a diplomatic incident. */
1395 action_id_consequence_caught(action_id, act_player,
1396 tgt_player, tgt_tile, tgt_city_link);
1398 /* Execute the caught thief. */
1399 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1401 return FALSE;
1404 log_debug("steal some maps: succeeded");
1406 /* Steal it. */
1407 give_distorted_map(tgt_player, act_player, 1, 1, TRUE);
1409 /* Notify everyone involved. */
1410 notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_MAP, ftc_server,
1411 _("Your %s stole parts of the %s world map in %s."),
1412 unit_link(act_unit),
1413 nation_adjective_for_player(tgt_player),
1414 tgt_city_link);
1415 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_MAP, ftc_server,
1416 _("The %s are suspected of stealing"
1417 " parts of your world map in %s."),
1418 nation_plural_for_player(act_player),
1419 tgt_city_link);
1421 /* This may cause a diplomatic incident. */
1422 action_id_consequence_success(action_id, act_player,
1423 tgt_player, tgt_tile, tgt_city_link);
1425 /* Try to escape. */
1426 diplomat_escape_full(act_player, act_unit, TRUE,
1427 tgt_tile, tgt_city_link);
1429 return TRUE;
1432 /**************************************************************************
1433 Hide a suitcase nuke in a city and detonate it.
1435 - Check for infiltration success. Our thief may not survive this.
1436 - Check for basic success. Again, our thief may not survive this.
1438 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
1439 this returns TRUE, unit may have died during the action.
1440 **************************************************************************/
1441 bool spy_nuke_city(struct player *act_player, struct unit *act_unit,
1442 struct city *tgt_city, const enum gen_action action_id)
1444 struct player *tgt_player;
1445 struct tile *tgt_tile;
1447 const char *tgt_city_link;
1449 /* Sanity check: The actor still exists. */
1450 fc_assert_ret_val(act_player, FALSE);
1451 fc_assert_ret_val(act_unit, FALSE);
1453 /* Sanity check: The target city still exists. */
1454 fc_assert_ret_val(tgt_city, FALSE);
1456 /* The victim. */
1457 tgt_player = city_owner(tgt_city);
1459 /* Sanity check: The target player still exists. */
1460 fc_assert_ret_val(tgt_player, FALSE);
1462 tgt_tile = city_tile(tgt_city);
1463 tgt_city_link = city_link(tgt_city);
1465 log_debug("suitcase nuke: unit: %d", act_unit->id);
1467 /* Battle all units capable of diplomatic defense. */
1468 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1469 action_id,
1470 act_unit, NULL, tgt_tile)) {
1471 return FALSE;
1474 log_debug("suitcase nuke: infiltrated");
1476 /* Try to hide the nuke. */
1477 if (diplomat_was_caught(act_player, act_unit, tgt_city, tgt_player,
1478 action_by_number(action_id))) {
1479 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1480 _("Your %s was caught in an attempt of"
1481 " hiding a nuke in %s!"),
1482 unit_tile_link(act_unit),
1483 tgt_city_link);
1484 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1485 ftc_server,
1486 _("You caught %s %s attempting to hide a nuke in %s!"),
1487 nation_adjective_for_player(act_player),
1488 unit_tile_link(act_unit),
1489 tgt_city_link);
1491 /* This may cause a diplomatic incident. */
1492 action_id_consequence_caught(action_id, act_player,
1493 tgt_player, tgt_tile, tgt_city_link);
1495 /* Execute the caught terrorist. */
1496 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1498 return FALSE;
1501 log_debug("suitcase nuke: succeeded");
1503 /* Notify everyone involved. */
1504 notify_player(act_player, tgt_tile, E_MY_SPY_NUKE, ftc_server,
1505 _("Your %s hid a nuke in %s."),
1506 unit_link(act_unit),
1507 tgt_city_link);
1508 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_NUKE, ftc_server,
1509 _("The %s are suspected of hiding a nuke in %s."),
1510 nation_plural_for_player(act_player),
1511 tgt_city_link);
1513 /* Try to escape before the blast. */
1514 diplomat_escape_full(act_player, act_unit, TRUE,
1515 tgt_tile, tgt_city_link);
1517 /* TODO: In real life a suitcase nuke is way less powerful than an ICBM.
1518 * Maybe the size of the suitcase nuke explosion should be ruleset
1519 * configurable? */
1521 /* Detonate the nuke. */
1522 dlsend_packet_nuke_tile_info(game.est_connections, tile_index(tgt_tile));
1523 do_nuclear_explosion(act_player, tgt_tile);
1525 /* This may cause a diplomatic incident. */
1526 action_id_consequence_success(action_id, act_player,
1527 tgt_player, tgt_tile, tgt_city_link);
1529 return TRUE;
1532 /**************************************************************************
1533 Returns TRUE iff the spy/diplomat was caught outside of a diplomatic
1534 battle.
1535 **************************************************************************/
1536 static bool diplomat_was_caught(struct player *act_player,
1537 struct unit *act_unit,
1538 struct city *tgt_city,
1539 struct player *tgt_player,
1540 struct action *act)
1542 int odds;
1544 /* Take the odds from the diplchance setting. */
1545 odds = game.server.diplchance;
1547 /* Let the Action_Odds_Pct effect modify the odds. The advantage of doing
1548 * it this way in stead of rolling twice is that Action_Odds_Pct can
1549 * increase the odds. */
1550 odds += ((odds
1551 * get_target_bonus_effects(NULL,
1552 act_player, tgt_player,
1553 tgt_city, NULL, NULL,
1554 act_unit, unit_type_get(act_unit),
1555 NULL, NULL, act,
1556 EFT_ACTION_ODDS_PCT))
1557 / 100);
1559 /* Roll the dice. */
1560 return fc_rand (100) >= odds;
1563 /**************************************************************************
1564 This subtracts the destination movement cost from a diplomat/spy.
1565 **************************************************************************/
1566 static void diplomat_charge_movement (struct unit *pdiplomat, struct tile *ptile)
1568 pdiplomat->moves_left -=
1569 map_move_cost_unit(pdiplomat, ptile);
1570 if (pdiplomat->moves_left < 0) {
1571 pdiplomat->moves_left = 0;
1575 /**************************************************************************
1576 This determines if a diplomat/spy succeeds against some defender,
1577 who is also a diplomat or spy. Note: a superspy defender always
1578 succeeds, otherwise a superspy attacker always wins.
1580 Return TRUE if the "attacker" succeeds.
1581 **************************************************************************/
1582 static bool diplomat_success_vs_defender(struct unit *pattacker,
1583 struct unit *pdefender,
1584 struct tile *pdefender_tile)
1586 int chance = 50; /* Base 50% chance */
1588 if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
1589 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
1590 return FALSE;
1592 if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
1593 /* An attacking UTYF_SUPERSPY will defeat every possible defender
1594 * except another UTYF_SUPERSPY. */
1595 return TRUE;
1598 /* Add or remove 25% if spy flag. */
1599 if (unit_has_type_flag(pattacker, UTYF_SPY)) {
1600 chance += 25;
1602 if (unit_has_type_flag(pdefender, UTYF_SPY)) {
1603 chance -= 25;
1606 /* Use power_fact from veteran level to modify chance in a linear way.
1607 * Equal veteran levels cancel out.
1608 * It's probably not good for rulesets to allow this to have more than
1609 * 20% effect. */
1611 const struct veteran_level
1612 *vatt = utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
1613 const struct veteran_level
1614 *vdef = utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
1615 fc_assert_ret_val(vatt != NULL && vdef != NULL, FALSE);
1616 chance += vatt->power_fact - vdef->power_fact;
1619 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
1620 chance -= chance
1621 * get_target_bonus_effects(NULL,
1622 tile_owner(pdefender_tile), NULL,
1623 tile_city(pdefender_tile), NULL,
1624 pdefender_tile, NULL, NULL, NULL,
1625 NULL, NULL,
1626 EFT_SPY_RESISTANT) / 100;
1628 return (int)fc_rand(100) < chance;
1631 /**************************************************************************
1632 This determines if a diplomat/spy succeeds in infiltrating a tile.
1634 - The infiltrator must go up against each defender.
1635 - The victim unit won't defend. (NULL if everyone should defend)
1636 - One or the other is eliminated in each contest.
1638 - Return TRUE if the infiltrator succeeds.
1640 'pplayer' is the player who tries to do a spy/diplomat action on 'ptile'
1641 with the unit 'pdiplomat' against 'cplayer'.
1642 **************************************************************************/
1643 static bool diplomat_infiltrate_tile(struct player *pplayer,
1644 struct player *cplayer,
1645 int action_id,
1646 struct unit *pdiplomat,
1647 struct unit *pvictim,
1648 struct tile *ptile)
1650 char link_city[MAX_LEN_LINK] = "";
1651 char link_diplomat[MAX_LEN_LINK];
1652 char link_unit[MAX_LEN_LINK];
1653 struct city *pcity = tile_city(ptile);
1655 if (pcity) {
1656 /* N.B.: *_link() always returns the same pointer. */
1657 sz_strlcpy(link_city, city_link(pcity));
1660 /* We don't need a _safe iterate since no transporters should be
1661 * destroyed. */
1662 unit_list_iterate(ptile->units, punit) {
1663 struct player *uplayer = unit_owner(punit);
1665 /* I can't confirm if we won't deny that we weren't involved. */
1666 if (uplayer == pplayer) {
1667 continue;
1670 if (punit == pvictim
1671 && !unit_has_type_flag(punit, UTYF_SUPERSPY)) {
1672 /* The victim unit is defenseless unless it's a SuperSpy.
1673 * Rationalization: A regular diplomat don't mind being bribed. A
1674 * SuperSpy is high enough up the chain that accepting a bribe is
1675 * against his own interests. */
1676 continue;
1679 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)
1680 || unit_has_type_flag(punit, UTYF_SUPERSPY)) {
1681 /* A UTYF_SUPERSPY unit may not actually be a spy, but a superboss
1682 * which we cannot allow puny diplomats from getting the better
1683 * of. UTYF_SUPERSPY vs UTYF_SUPERSPY in a diplomatic contest always
1684 * kills the attacker. */
1686 if (diplomat_success_vs_defender(pdiplomat, punit, ptile)) {
1687 /* Defending Spy/Diplomat dies. */
1689 /* N.B.: *_link() always returns the same pointer. */
1690 sz_strlcpy(link_unit, unit_tile_link(punit));
1691 sz_strlcpy(link_diplomat, unit_link(pdiplomat));
1693 notify_player(pplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1694 /* TRANS: <unit> ... <diplomat> */
1695 _("An enemy %s has been eliminated by your %s."),
1696 link_unit, link_diplomat);
1698 if (pcity) {
1699 if (uplayer == cplayer) {
1700 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1701 /* TRANS: <unit> ... <city> ... <diplomat> */
1702 _("Your %s has been eliminated defending %s"
1703 " against a %s."), link_unit, link_city,
1704 link_diplomat);
1705 } else {
1706 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1707 /* TRANS: <nation adj> <unit> ... <city>
1708 * TRANS: ... <diplomat> */
1709 _("A %s %s has been eliminated defending %s "
1710 "against a %s."),
1711 nation_adjective_for_player(uplayer),
1712 link_unit, link_city, link_diplomat);
1713 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1714 /* TRANS: ... <unit> ... <nation adj> <city>
1715 * TRANS: ... <diplomat> */
1716 _("Your %s has been eliminated defending %s %s "
1717 "against a %s."), link_unit,
1718 nation_adjective_for_player(cplayer),
1719 link_city, link_diplomat);
1721 } else {
1722 if (uplayer == cplayer) {
1723 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1724 /* TRANS: <unit> ... <diplomat> */
1725 _("Your %s has been eliminated defending "
1726 "against a %s."), link_unit, link_diplomat);
1727 } else {
1728 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1729 /* TRANS: <nation adj> <unit> ... <diplomat> */
1730 _("A %s %s has been eliminated defending "
1731 "against a %s."),
1732 nation_adjective_for_player(uplayer),
1733 link_unit, link_diplomat);
1734 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1735 /* TRANS: ... <unit> ... <diplomat> */
1736 _("Your %s has been eliminated defending "
1737 "against a %s."), link_unit, link_diplomat);
1741 pdiplomat->moves_left = MAX(0, pdiplomat->moves_left - SINGLE_MOVE);
1743 /* Attacking unit became more experienced? */
1744 if (maybe_make_veteran(pdiplomat)) {
1745 notify_unit_experience(pdiplomat);
1747 send_unit_info(NULL, pdiplomat);
1748 wipe_unit(punit, ULR_ELIMINATED, pplayer);
1749 return FALSE;
1750 } else {
1751 /* Attacking Spy/Diplomat dies. */
1753 const char *victim_link;
1755 /* N.B.: *_link() always returns the same pointer. */
1756 sz_strlcpy(link_unit, unit_link(punit));
1757 sz_strlcpy(link_diplomat, unit_tile_link(pdiplomat));
1759 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1760 _("Your %s was eliminated by a defending %s."),
1761 link_diplomat, link_unit);
1763 if (pcity) {
1764 if (uplayer == cplayer) {
1765 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1766 _("Eliminated a %s %s while infiltrating %s."),
1767 nation_adjective_for_player(pplayer),
1768 link_diplomat, link_city);
1769 } else {
1770 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1771 _("A %s %s eliminated a %s %s while infiltrating "
1772 "%s."), nation_adjective_for_player(uplayer),
1773 link_unit, nation_adjective_for_player(pplayer),
1774 link_diplomat, link_city);
1775 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1776 _("Your %s eliminated a %s %s while infiltrating "
1777 "%s."), link_unit,
1778 nation_adjective_for_player(pplayer),
1779 link_diplomat, link_city);
1781 } else {
1782 if (uplayer == cplayer) {
1783 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1784 _("Eliminated a %s %s while infiltrating our troops."),
1785 nation_adjective_for_player(pplayer),
1786 link_diplomat);
1787 } else {
1788 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1789 _("A %s %s eliminated a %s %s while infiltrating our "
1790 "troops."), nation_adjective_for_player(uplayer),
1791 link_unit, nation_adjective_for_player(pplayer),
1792 link_diplomat);
1793 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1794 /* TRANS: ... <unit> ... <diplomat> */
1795 _("Your %s eliminated a %s %s while infiltrating our "
1796 "troops."), link_unit,
1797 nation_adjective_for_player(pplayer),
1798 link_diplomat);
1802 /* Defending unit became more experienced? */
1803 if (maybe_make_veteran(punit)) {
1804 notify_unit_experience(punit);
1807 switch (action_id_get_target_kind(action_id)) {
1808 case ATK_CITY:
1809 victim_link = city_link(pcity);
1810 break;
1811 case ATK_UNIT:
1812 case ATK_UNITS:
1813 victim_link = pvictim ? unit_tile_link(pvictim)
1814 : tile_link(ptile);
1815 break;
1816 case ATK_TILE:
1817 victim_link = tile_link(ptile);
1818 break;
1819 case ATK_SELF:
1820 /* How did a self targeted action end up here? */
1821 fc_assert(action_id_get_target_kind(action_id) != ATK_SELF);
1822 default:
1823 victim_link = NULL;
1824 break;
1827 fc_assert(victim_link != NULL);
1829 action_id_consequence_caught(action_id, pplayer, cplayer,
1830 ptile, victim_link);
1832 wipe_unit(pdiplomat, ULR_ELIMINATED, uplayer);
1833 return FALSE;
1836 } unit_list_iterate_end;
1838 return TRUE;
1841 /**************************************************************************
1842 This determines if a diplomat/spy survives and escapes.
1843 If "pcity" is NULL, assume action was in the field.
1845 Spies have a game.server.diplchance specified chance of survival (better
1846 if veteran):
1847 - Diplomats always die.
1848 - Escapes to home city.
1849 - Escapee may become a veteran.
1850 **************************************************************************/
1851 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
1852 const struct city *pcity)
1854 struct tile *ptile;
1855 const char *vlink;
1857 if (pcity) {
1858 ptile = city_tile(pcity);
1859 vlink = city_link(pcity);
1860 } else {
1861 ptile = unit_tile(pdiplomat);
1862 vlink = NULL;
1865 return diplomat_escape_full(pplayer, pdiplomat, pcity != NULL,
1866 ptile, vlink);
1869 /**************************************************************************
1870 This determines if a diplomat/spy survives and escapes.
1872 Spies have a game.server.diplchance specified chance of survival (better
1873 if veteran):
1874 - Diplomats always die.
1875 - Escapes to home city.
1876 - Escapee may become a veteran.
1877 **************************************************************************/
1878 static void diplomat_escape_full(struct player *pplayer,
1879 struct unit *pdiplomat,
1880 bool city_related,
1881 struct tile *ptile,
1882 const char *vlink)
1884 int escapechance;
1885 struct city *spyhome;
1887 /* Veteran level's power factor's effect on escape chance is relative to
1888 * unpromoted unit's power factor */
1890 const struct veteran_level
1891 *vunit = utype_veteran_level(unit_type_get(pdiplomat), pdiplomat->veteran);
1892 const struct veteran_level
1893 *vbase = utype_veteran_level(unit_type_get(pdiplomat), 0);
1895 escapechance = game.server.diplchance
1896 + (vunit->power_fact - vbase->power_fact);
1899 /* find closest city for escape target */
1900 spyhome = find_closest_city(ptile, NULL, unit_owner(pdiplomat), FALSE,
1901 FALSE, FALSE, TRUE, FALSE, NULL);
1903 if (spyhome
1904 && unit_has_type_flag(pdiplomat, UTYF_SPY)
1905 && (unit_has_type_flag(pdiplomat, UTYF_SUPERSPY)
1906 || fc_rand (100) < escapechance)) {
1907 /* Attacking Spy/Diplomat survives. */
1908 notify_player(pplayer, ptile, E_MY_DIPLOMAT_ESCAPE, ftc_server,
1909 _("Your %s has successfully completed"
1910 " the mission and returned unharmed to %s."),
1911 unit_link(pdiplomat),
1912 city_link(spyhome));
1913 if (maybe_make_veteran(pdiplomat)) {
1914 notify_unit_experience(pdiplomat);
1917 /* being teleported costs all movement */
1918 if (!teleport_unit_to_city (pdiplomat, spyhome, -1, FALSE)) {
1919 send_unit_info(NULL, pdiplomat);
1920 log_error("Bug in diplomat_escape: Spy can't teleport.");
1921 return;
1924 return;
1925 } else {
1926 if (city_related) {
1927 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1928 _("Your %s was captured after completing"
1929 " the mission in %s."),
1930 unit_tile_link(pdiplomat),
1931 vlink);
1932 } else {
1933 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1934 _("Your %s was captured after completing"
1935 " the mission."),
1936 unit_tile_link(pdiplomat));
1940 wipe_unit(pdiplomat,
1941 /* A non Spy can't escape. It is therefore spent, not caught. */
1942 unit_has_type_flag(pdiplomat, UTYF_SPY) ? ULR_CAUGHT : ULR_USED,
1943 NULL);
1946 /**************************************************************************
1947 return number of diplomats on this square. AJS 20000130
1948 **************************************************************************/
1949 int count_diplomats_on_tile(struct tile *ptile)
1951 int count = 0;
1953 unit_list_iterate((ptile)->units, punit) {
1954 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
1955 count++;
1957 } unit_list_iterate_end;
1959 return count;