Do not build gtk3.22-client by default
[freeciv.git] / server / diplomats.c
blob586495b5d55e00e06ef5f1dfa937fc234666a7fc
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 "notify.h"
45 #include "plrhand.h"
46 #include "techtools.h"
47 #include "unithand.h"
48 #include "unittools.h"
50 /* server/scripting */
51 #include "script_server.h"
53 /****************************************************************************/
55 static void diplomat_charge_movement (struct unit *pdiplomat,
56 struct tile *ptile);
57 static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef,
58 struct tile *pdefender_tile);
59 static bool diplomat_infiltrate_tile(struct player *pplayer,
60 struct player *cplayer,
61 struct unit *pdiplomat,
62 struct unit *pvictim,
63 struct tile *ptile);
64 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
65 const struct city *pcity);
66 static void diplomat_escape_full(struct player *pplayer,
67 struct unit *pdiplomat,
68 bool city_related,
69 struct tile *ptile,
70 const char *vlink);
72 /******************************************************************************
73 Poison a city's water supply.
75 - Check for infiltration success. Our poisoner may not survive this.
76 - If successful, reduces population by one point.
78 - The poisoner may be captured and executed, or escape to its home town.
80 'pplayer' is the player who tries to poison 'pcity' with its unit
81 'pdiplomat'.
82 ****************************************************************************/
83 void spy_poison(struct player *pplayer, struct unit *pdiplomat,
84 struct city *pcity)
86 struct player *cplayer;
87 struct tile *ctile;
88 const char *clink;
90 /* Fetch target city's player. Sanity checks. */
91 fc_assert_ret(pcity);
92 cplayer = city_owner(pcity);
93 fc_assert_ret(cplayer);
95 /* Sanity check: The actor still exists. */
96 fc_assert_ret(pplayer);
97 fc_assert_ret(pdiplomat);
99 ctile = city_tile(pcity);
100 clink = city_link(pcity);
102 log_debug("poison: unit: %d", pdiplomat->id);
104 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
105 if (!diplomat_infiltrate_tile(pplayer, cplayer,
106 pdiplomat, NULL, ctile)) {
107 return;
110 log_debug("poison: infiltrated");
111 log_debug("poison: succeeded");
113 /* Poison people! */
114 if (city_reduce_size(pcity, 1, pplayer, "poison")) {
115 /* Notify everybody involved. */
116 notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
117 _("Your %s poisoned the water supply of %s."),
118 unit_link(pdiplomat), clink);
119 notify_player(cplayer, ctile,
120 E_ENEMY_DIPLOMAT_POISON, ftc_server,
121 _("%s is suspected of poisoning the water supply of %s."),
122 player_name(pplayer), clink);
124 /* Update clients. */
125 city_refresh (pcity);
126 send_city_info(NULL, pcity);
127 } else {
128 /* Notify everybody involved. */
129 notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
130 _("Your %s destroyed %s by poisoning its water supply."),
131 unit_link(pdiplomat), clink);
132 notify_player(cplayer, ctile,
133 E_ENEMY_DIPLOMAT_POISON, ftc_server,
134 _("%s is suspected of destroying %s by poisoning its"
135 " water supply."),
136 player_name(pplayer), clink);
139 /* this may cause a diplomatic incident */
140 action_consequence_success(ACTION_SPY_POISON, pplayer, cplayer,
141 ctile, clink);
143 /* Now lets see if the spy survives. */
144 diplomat_escape_full(pplayer, pdiplomat, TRUE, ctile, clink);
147 /******************************************************************************
148 Investigate a city.
150 - It costs some minimal movement to investigate a city.
152 - Diplomats die after investigation.
153 - Spies always survive. There is no risk.
154 ****************************************************************************/
155 void diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
156 struct city *pcity)
158 struct player *cplayer;
159 struct packet_unit_short_info unit_packet;
160 struct packet_city_info city_packet;
162 /* Fetch target city's player. Sanity checks. */
163 fc_assert_ret(pcity);
164 cplayer = city_owner(pcity);
165 fc_assert_ret(cplayer);
167 /* Sanity check: The actor still exists. */
168 fc_assert_ret(pplayer);
169 fc_assert_ret(pdiplomat);
171 /* Sanity check: The target is foreign. */
172 if (cplayer == pplayer) {
173 /* Nothing to do to a domestic target. */
174 return;
177 log_debug("investigate: unit: %d", pdiplomat->id);
179 /* Do It... */
180 update_dumb_city(pplayer, pcity);
181 /* Special case for a diplomat/spy investigating a city:
182 The investigator needs to know the supported and present
183 units of a city, whether or not they are fogged. So, we
184 send a list of them all before sending the city info.
185 As this is a special case we bypass send_unit_info. */
186 unit_list_iterate(pcity->units_supported, punit) {
187 package_short_unit(punit, &unit_packet,
188 UNIT_INFO_CITY_SUPPORTED, pcity->id);
189 /* We need to force to send the packet to ensure the client will receive
190 * something (e.g. investigating twice). */
191 lsend_packet_unit_short_info(pplayer->connections, &unit_packet, TRUE);
192 } unit_list_iterate_end;
193 unit_list_iterate((pcity->tile)->units, punit) {
194 package_short_unit(punit, &unit_packet,
195 UNIT_INFO_CITY_PRESENT, pcity->id);
196 /* We need to force to send the packet to ensure the client will receive
197 * something (e.g. investigating twice). */
198 lsend_packet_unit_short_info(pplayer->connections, &unit_packet, TRUE);
199 } unit_list_iterate_end;
200 /* Send city info to investigator's player.
201 As this is a special case we bypass send_city_info. */
202 package_city(pcity, &city_packet, TRUE);
203 /* We need to force to send the packet to ensure the client will receive
204 * something and popup the city dialog. */
205 lsend_packet_city_info(pplayer->connections, &city_packet, TRUE);
207 /* Charge a nominal amount of movement for this. */
208 (pdiplomat->moves_left)--;
209 if (pdiplomat->moves_left < 0) {
210 pdiplomat->moves_left = 0;
213 /* this may cause a diplomatic incident */
214 action_consequence_success(ACTION_SPY_INVESTIGATE_CITY, pplayer, cplayer,
215 city_tile(pcity), city_link(pcity));
217 /* Spies always survive. Diplomats never do. */
218 if (!unit_has_type_flag(pdiplomat, UTYF_SPY)) {
219 wipe_unit(pdiplomat, ULR_USED, NULL);
220 } else {
221 send_unit_info(NULL, pdiplomat);
225 /******************************************************************************
226 Get list of improvements from city (for purposes of sabotage).
228 - Always successful; returns list.
230 Only send back to the originating connection, if there is one. (?)
231 ****************************************************************************/
232 void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat,
233 struct city *pcity)
235 struct packet_city_sabotage_list packet;
237 /* Send city improvements info to player. */
238 BV_CLR_ALL(packet.improvements);
240 improvement_iterate(ptarget) {
241 if (city_has_building(pcity, ptarget)) {
242 BV_SET(packet.improvements, improvement_index(ptarget));
244 } improvement_iterate_end;
246 packet.diplomat_id = pdiplomat->id;
247 packet.city_id = pcity->id;
248 send_packet_city_sabotage_list(pc, &packet);
251 /******************************************************************************
252 Establish an embassy.
254 - Barbarians always execute ambassadors.
255 - Otherwise, the embassy is created.
256 - It costs some minimal movement to establish an embassy.
258 - Diplomats are consumed in creation of embassy.
259 - Spies always survive.
260 ****************************************************************************/
261 void diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
262 struct city *pcity)
264 struct player *cplayer;
266 /* Fetch target city's player. Sanity checks. */
267 fc_assert_ret(pcity);
268 cplayer = city_owner(pcity);
269 fc_assert_ret(cplayer);
271 /* Sanity check: The actor still exists. */
272 fc_assert_ret(pplayer);
273 fc_assert_ret(pdiplomat);
275 /* Sanity check: The target is foreign. */
276 if (cplayer == pplayer) {
277 /* Nothing to do to a domestic target. */
278 return;
281 log_debug("embassy: unit: %d", pdiplomat->id);
283 log_debug("embassy: succeeded");
285 establish_embassy(pplayer, cplayer);
287 /* Notify everybody involved. */
288 notify_player(pplayer, city_tile(pcity),
289 E_MY_DIPLOMAT_EMBASSY, ftc_server,
290 _("You have established an embassy in %s."),
291 city_link(pcity));
292 notify_player(cplayer, city_tile(pcity),
293 E_ENEMY_DIPLOMAT_EMBASSY, ftc_server,
294 _("The %s have established an embassy in %s."),
295 nation_plural_for_player(pplayer),
296 city_link(pcity));
298 /* Charge a nominal amount of movement for this. */
299 (pdiplomat->moves_left)--;
300 if (pdiplomat->moves_left < 0) {
301 pdiplomat->moves_left = 0;
304 /* this may cause a diplomatic incident */
305 action_consequence_success(ACTION_ESTABLISH_EMBASSY, pplayer, cplayer,
306 city_tile(pcity), city_link(pcity));
308 /* Spies always survive. Diplomats never do. */
309 if (!unit_has_type_flag(pdiplomat, UTYF_SPY)) {
310 wipe_unit(pdiplomat, ULR_USED, NULL);
311 } else {
312 send_unit_info(NULL, pdiplomat);
316 /******************************************************************************
317 Sabotage an enemy unit.
319 - If successful, reduces hit points by half of those remaining.
321 - The saboteur may be captured and executed, or escape to its home town.
322 ****************************************************************************/
323 void spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat,
324 struct unit *pvictim)
326 char victim_link[MAX_LEN_LINK];
327 struct player *uplayer;
329 /* Fetch target unit's player. Sanity checks. */
330 fc_assert_ret(pvictim);
331 uplayer = unit_owner(pvictim);
332 fc_assert_ret(uplayer);
334 /* Sanity check: The actor still exists. */
335 fc_assert_ret(pplayer);
336 fc_assert_ret(pdiplomat);
338 log_debug("sabotage-unit: unit: %d", pdiplomat->id);
340 /* N.B: unit_link() always returns the same pointer. */
341 sz_strlcpy(victim_link, unit_link(pvictim));
343 /* Diplomatic battle against any diplomatic defender except the intended
344 * victim of the sabotage. */
345 if (!diplomat_infiltrate_tile(pplayer, uplayer, pdiplomat, pvictim,
346 unit_tile(pvictim))) {
347 return;
350 log_debug("sabotage-unit: succeeded");
352 if (pvictim->hp < 2) {
353 /* Not possible to halve the hit points. Kill it. */
354 wipe_unit(pvictim, ULR_KILLED, pplayer);
356 /* Notify everybody involved. */
357 notify_player(pplayer, unit_tile(pvictim),
358 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
359 _("Your %s's successful sabotage killed the %s %s."),
360 unit_link(pdiplomat),
361 nation_adjective_for_player(uplayer),
362 victim_link);
363 notify_player(uplayer, unit_tile(pvictim),
364 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
365 /* TRANS: ... the Poles! */
366 _("Your %s was killed by %s sabotage!"),
367 victim_link,
368 nation_plural_for_player(pplayer));
369 } else {
370 /* Sabotage the unit by removing half its remaining hit points. */
371 pvictim->hp /= 2;
372 send_unit_info(NULL, pvictim);
374 /* Notify everybody involved. */
375 notify_player(pplayer, unit_tile(pvictim),
376 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
377 _("Your %s succeeded in sabotaging the %s %s."),
378 unit_link(pdiplomat),
379 nation_adjective_for_player(uplayer),
380 victim_link);
381 notify_player(uplayer, unit_tile(pvictim),
382 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
383 /* TRANS: ... the Poles! */
384 _("Your %s was sabotaged by the %s!"),
385 victim_link,
386 nation_plural_for_player(pplayer));
389 /* this may cause a diplomatic incident */
390 action_consequence_success(ACTION_SPY_SABOTAGE_UNIT, pplayer, uplayer,
391 unit_tile(pvictim), victim_link);
393 /* Now lets see if the spy survives. */
394 diplomat_escape(pplayer, pdiplomat, NULL);
397 /******************************************************************************
398 Bribe an enemy unit.
400 - Can't bribe a unit if:
401 - Player doesn't have enough gold.
402 - Otherwise, the unit will be bribed.
404 - A successful briber will try to move onto the victim's square.
405 ****************************************************************************/
406 void diplomat_bribe(struct player *pplayer, struct unit *pdiplomat,
407 struct unit *pvictim)
409 char victim_link[MAX_LEN_LINK];
410 struct player *uplayer;
411 struct tile *victim_tile;
412 int bribe_cost;
413 int diplomat_id = pdiplomat->id;
414 struct city *pcity;
416 /* Fetch target unit's player. Sanity checks. */
417 fc_assert_ret(pvictim);
418 uplayer = unit_owner(pvictim);
419 fc_assert_ret(uplayer);
421 /* Sanity check: The actor still exists. */
422 fc_assert_ret(pplayer);
423 fc_assert_ret(pdiplomat);
425 /* Sanity check: The target is foreign. */
426 if (uplayer == pplayer) {
427 /* Nothing to do to a domestic target. */
428 return;
431 /* Sanity check: The victim isn't a unique unit the actor player already
432 * has. */
433 if (utype_player_already_has_this_unique(pplayer,
434 unit_type_get(pvictim))) {
435 log_debug("bribe-unit: already got unique unit");
436 notify_player(pplayer, unit_tile(pdiplomat),
437 E_UNIT_ILLEGAL_ACTION, ftc_server,
438 /* TRANS: You already have a Leader. */
439 _("You already have a %s."),
440 unit_link(pvictim));
442 return;
445 log_debug("bribe-unit: unit: %d", pdiplomat->id);
447 /* Get bribe cost, ignoring any previously saved value. */
448 bribe_cost = unit_bribe_cost(pvictim, pplayer);
450 /* If player doesn't have enough gold, can't bribe. */
451 if (pplayer->economic.gold < bribe_cost) {
452 notify_player(pplayer, unit_tile(pdiplomat),
453 E_MY_DIPLOMAT_FAILED, ftc_server,
454 _("You don't have enough gold to bribe the %s %s."),
455 nation_adjective_for_player(uplayer),
456 unit_link(pvictim));
457 log_debug("bribe-unit: not enough gold");
458 return;
461 log_debug("bribe-unit: enough gold");
463 /* Diplomatic battle against any diplomatic defender except the one that
464 * will get the bribe. */
465 if (!diplomat_infiltrate_tile(pplayer, uplayer,
466 pdiplomat, pvictim,
467 pvictim->tile)) {
468 return;
471 log_debug("bribe-unit: succeeded");
473 victim_tile = unit_tile(pvictim);
474 pvictim = unit_change_owner(pvictim, pplayer, pdiplomat->homecity,
475 ULR_BRIBED);
477 /* N.B.: unit_link always returns the same pointer. As unit_change_owner()
478 * currently remove the old unit and replace by a new one (with a new id),
479 * we want to make link to the new unit. */
480 sz_strlcpy(victim_link, unit_link(pvictim));
482 /* Notify everybody involved. */
483 notify_player(pplayer, victim_tile, E_MY_DIPLOMAT_BRIBE, ftc_server,
484 /* TRANS: <diplomat> ... <unit> */
485 _("Your %s succeeded in bribing the %s."),
486 unit_link(pdiplomat), victim_link);
487 if (maybe_make_veteran(pdiplomat)) {
488 notify_unit_experience(pdiplomat);
490 notify_player(uplayer, victim_tile, E_ENEMY_DIPLOMAT_BRIBE, ftc_server,
491 /* TRANS: <unit> ... <Poles> */
492 _("Your %s was bribed by the %s."),
493 victim_link, nation_plural_for_player(pplayer));
495 /* The unit may have been on a tile shared with a city or a unit
496 * it no longer can share a tile with. */
497 pcity = tile_city(unit_tile(pvictim));
498 if ((NULL != pcity && !pplayers_allied(city_owner(pcity), pplayer))
499 || 1 < unit_list_size(unit_tile(pvictim)->units)) {
500 bounce_unit(pvictim, TRUE);
503 /* This costs! */
504 pplayer->economic.gold -= bribe_cost;
506 /* This may cause a diplomatic incident */
507 action_consequence_success(ACTION_SPY_BRIBE_UNIT, pplayer, uplayer,
508 victim_tile, victim_link);
510 if (!unit_is_alive(diplomat_id)) {
511 return;
514 /* Try to move the briber onto the victim's square unless its a city or
515 * have other units. */
516 if (NULL == pcity && unit_list_size(unit_tile(pvictim)->units) < 2
517 /* Post bribe move. */
518 && !unit_move_handling(pdiplomat, victim_tile, FALSE, TRUE, NULL)
519 /* May have died while trying to move. */
520 && unit_is_alive(diplomat_id)) {
521 pdiplomat->moves_left = 0;
523 if (NULL != player_unit_by_number(pplayer, diplomat_id)) {
524 send_unit_info(NULL, pdiplomat);
527 /* Update clients. */
528 send_player_all_c(pplayer, NULL);
531 /****************************************************************************
532 Try to steal a technology from an enemy city.
533 If action_id is ACTION_SPY_STEAL_TECH, steal a random technology.
534 Otherwise, steal the technology whose ID is "technology".
535 (Note: Only Spies can select what to steal.)
537 - Check for infiltration success. Our thief may not survive this.
538 - Check for basic success. Again, our thief may not survive this.
539 - If a technology has already been stolen from this city at any time:
540 - Diplomats will be caught and executed.
541 - Spies will have an increasing chance of being caught and executed.
542 - Steal technology!
544 - The thief may be captured and executed, or escape to its home town.
546 FIXME: It should give a loss of reputation to steal from a player you are
547 not at war with
548 ****************************************************************************/
549 void diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat,
550 struct city *pcity, Tech_type_id technology,
551 const enum gen_action action_id)
553 struct research *presearch, *cresearch;
554 struct player *cplayer;
555 int count;
556 Tech_type_id tech_stolen;
558 /* We have to check arguments. They are sent to us by a client,
559 so we cannot trust them */
560 fc_assert_ret(pcity);
561 cplayer = city_owner(pcity);
562 fc_assert_ret(cplayer);
564 /* Sanity check: The actor still exists. */
565 fc_assert_ret(pplayer);
566 fc_assert_ret(pdiplomat);
568 /* Sanity check: The target is foreign. */
569 if (cplayer == pplayer) {
570 /* Nothing to do to a domestic target. */
571 return;
574 if (action_id == ACTION_SPY_STEAL_TECH) {
575 /* Can't choose target. Will steal a random tech. */
576 technology = A_UNSET;
579 /* Targeted technology should be a ruleset defined tech,
580 * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
581 if (technology == A_NONE
582 || (technology != A_FUTURE
583 && !(technology == A_UNSET && action_id == ACTION_SPY_STEAL_TECH)
584 && !valid_advance_by_number(technology))) {
585 return;
588 presearch = research_get(pplayer);
589 cresearch = research_get(cplayer);
591 if (technology == A_FUTURE) {
592 if (presearch->future_tech >= cresearch->future_tech) {
593 return;
595 } else if (technology != A_UNSET) {
596 if (research_invention_state(presearch, technology) == TECH_KNOWN) {
597 return;
599 if (research_invention_state(cresearch, technology) != TECH_KNOWN) {
600 return;
602 if (!research_invention_gettable(presearch, technology,
603 game.info.tech_steal_allow_holes)) {
604 return;
608 log_debug("steal-tech: unit: %d", pdiplomat->id);
610 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
611 if (!diplomat_infiltrate_tile(pplayer, cplayer, pdiplomat, NULL,
612 pcity->tile)) {
613 return;
616 log_debug("steal-tech: infiltrated");
618 /* Check if the Diplomat/Spy succeeds with his/her task. */
619 /* (Twice as difficult if target is specified.) */
620 /* (If already stolen from, impossible for Diplomats and harder for Spies.) */
621 if (pcity->server.steal > 0 && !unit_has_type_flag(pdiplomat, UTYF_SPY)) {
622 /* Already stolen from: Diplomat always fails! */
623 count = 1;
624 log_debug("steal-tech: difficulty: impossible");
625 } else {
626 /* Determine difficulty. */
627 count = 1;
628 if (action_id == ACTION_SPY_TARGETED_STEAL_TECH) {
629 /* Targeted steal tech is more difficult. */
630 count++;
632 count += pcity->server.steal;
633 log_debug("steal-tech: difficulty: %d", count);
634 /* Determine success or failure. */
635 while (count > 0) {
636 if (fc_rand (100) >= game.server.diplchance) {
637 break;
639 count--;
643 if (count > 0) {
644 if (pcity->server.steal > 0 && !unit_has_type_flag(pdiplomat, UTYF_SPY)) {
645 notify_player(pplayer, city_tile(pcity),
646 E_MY_DIPLOMAT_FAILED, ftc_server,
647 _("%s was expecting your attempt to steal technology "
648 "again. Your %s was caught and executed."),
649 city_link(pcity),
650 unit_tile_link(pdiplomat));
651 } else {
652 notify_player(pplayer, city_tile(pcity),
653 E_MY_DIPLOMAT_FAILED, ftc_server,
654 _("Your %s was caught in the attempt of"
655 " stealing technology from %s."),
656 unit_tile_link(pdiplomat),
657 city_link(pcity));
659 notify_player(cplayer, city_tile(pcity),
660 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
661 _("The %s %s failed to steal technology from %s."),
662 nation_adjective_for_player(pplayer),
663 unit_tile_link(pdiplomat),
664 city_link(pcity));
665 /* this may cause a diplomatic incident */
666 action_consequence_caught(action_id, pplayer, cplayer,
667 city_tile(pcity), city_link(pcity));
668 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
669 return;
672 tech_stolen = steal_a_tech(pplayer, cplayer, technology);
674 if (tech_stolen == A_NONE) {
675 notify_player(pplayer, city_tile(pcity),
676 E_MY_DIPLOMAT_FAILED, ftc_server,
677 _("No new technology found in %s."),
678 city_link(pcity));
679 diplomat_charge_movement (pdiplomat, pcity->tile);
680 send_unit_info(NULL, pdiplomat);
681 return;
684 /* Update stealing player's science progress and research fields */
685 send_player_all_c(pplayer, NULL);
687 /* Record the theft. */
688 (pcity->server.steal)++;
690 /* this may cause a diplomatic incident */
691 action_consequence_success(action_id, pplayer, cplayer,
692 city_tile(pcity), city_link(pcity));
694 /* Check if a spy survives her mission. Diplomats never do. */
695 diplomat_escape(pplayer, pdiplomat, pcity);
698 /**************************************************************************
699 Incite a city to disaffect.
701 - Can't incite a city to disaffect if:
702 - Player doesn't have enough gold.
703 - Check for infiltration success. Our provocateur may not survive this.
704 - Check for basic success. Again, our provocateur may not survive this.
705 - Otherwise, the city will disaffect:
706 - Player gets the city.
707 - Player gets certain of the city's present/supported units.
708 - Player gets a technology advance, if any were unknown.
710 - The provocateur may be captured and executed, or escape to its home town.
711 **************************************************************************/
712 void diplomat_incite(struct player *pplayer, struct unit *pdiplomat,
713 struct city *pcity)
715 struct player *cplayer;
716 struct tile *ctile;
717 const char *clink;
718 int revolt_cost;
720 /* Fetch target civilization's player. Sanity checks. */
721 fc_assert_ret(pcity);
722 cplayer = city_owner(pcity);
723 fc_assert_ret(cplayer);
725 /* Sanity check: The actor still exists. */
726 fc_assert_ret(pplayer);
727 fc_assert_ret(pdiplomat);
729 /* Sanity check: The target is foreign. */
730 if (cplayer == pplayer) {
731 /* Nothing to do to a domestic target. */
732 return;
735 ctile = city_tile(pcity);
736 clink = city_link(pcity);
738 log_debug("incite: unit: %d", pdiplomat->id);
740 /* Get incite cost, ignoring any previously saved value. */
741 revolt_cost = city_incite_cost(pplayer, pcity);
743 /* If player doesn't have enough gold, can't incite a revolt. */
744 if (pplayer->economic.gold < revolt_cost) {
745 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
746 _("You don't have enough gold to subvert %s."),
747 clink);
748 log_debug("incite: not enough gold");
749 return;
752 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
753 if (!diplomat_infiltrate_tile(pplayer, cplayer, pdiplomat, NULL,
754 pcity->tile)) {
755 return;
758 log_debug("incite: infiltrated");
760 /* Check if the Diplomat/Spy succeeds with his/her task. */
761 if (fc_rand (100) >= game.server.diplchance) {
762 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
763 _("Your %s was caught in the attempt"
764 " of inciting a revolt!"),
765 unit_tile_link(pdiplomat));
766 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
767 _("You caught %s %s attempting"
768 " to incite a revolt in %s!"),
769 nation_adjective_for_player(pplayer),
770 unit_tile_link(pdiplomat),
771 clink);
772 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
773 return;
776 log_debug("incite: succeeded");
778 /* Subvert the city to your cause... */
780 /* City loses some population. */
781 if (city_size_get(pcity) > 1) {
782 city_reduce_size(pcity, 1, pplayer, "incited");
785 /* This costs! */
786 pplayer->economic.gold -= revolt_cost;
788 /* Notify everybody involved. */
789 notify_player(pplayer, ctile, E_MY_DIPLOMAT_INCITE, ftc_server,
790 _("Revolt incited in %s, you now rule the city!"),
791 clink);
792 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_INCITE, ftc_server,
793 _("%s has revolted, %s influence suspected."),
794 clink,
795 nation_adjective_for_player(pplayer));
797 pcity->shield_stock = 0;
798 nullify_prechange_production(pcity);
800 /* You get a technology advance, too! */
801 steal_a_tech(pplayer, cplayer, A_UNSET);
803 /* this may cause a diplomatic incident */
804 action_consequence_success(ACTION_SPY_INCITE_CITY,
805 pplayer, cplayer, ctile, clink);
807 /* Transfer city and units supported by this city (that
808 are within one square of the city) to the new owner. */
809 if (transfer_city(pplayer, pcity, 1, TRUE, TRUE, FALSE,
810 !is_barbarian(pplayer))) {
811 script_server_signal_emit("city_transferred", 4,
812 API_TYPE_CITY, pcity,
813 API_TYPE_PLAYER, cplayer,
814 API_TYPE_PLAYER, pplayer,
815 API_TYPE_STRING, "incited");
818 /* Check if a spy survives her mission. Diplomats never do.
819 * _After_ transferring the city, or the city area is first fogged
820 * when the diplomat is removed, and then unfogged when the city
821 * is transferred. */
822 diplomat_escape_full(pplayer, pdiplomat, TRUE, ctile, clink);
824 /* Update the players gold in the client */
825 send_player_info_c(pplayer, pplayer->connections);
828 /**************************************************************************
829 Sabotage enemy city's improvement or production.
830 If this is untargeted sabotage city a random improvement or production is
831 targeted.
832 Targeted sabotage city lets the value of "improvement" decide the target.
833 If "improvement" is -1, sabotage current production.
834 Otherwise, sabotage the city improvement whose ID is "improvement".
836 - Check for infiltration success. Our saboteur may not survive this.
837 - Check for basic success. Again, our saboteur may not survive this.
838 - Determine target, given arguments and constraints.
839 - If specified, city walls and anything in a capital are 50% likely to fail.
840 - Do sabotage!
842 - The saboteur may be captured and executed, or escape to its home town.
843 **************************************************************************/
844 void diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat,
845 struct city *pcity, Impr_type_id improvement,
846 const enum gen_action action_id)
848 struct player *cplayer;
849 struct impr_type *ptarget;
850 int count, which;
851 int success_prob;
853 /* Fetch target city's player. Sanity checks. */
854 fc_assert_ret(pcity);
855 cplayer = city_owner(pcity);
856 fc_assert_ret(cplayer);
858 /* Sanity check: The actor still exists. */
859 fc_assert_ret(pplayer);
860 fc_assert_ret(pdiplomat);
862 log_debug("sabotage: unit: %d", pdiplomat->id);
864 /* Twice as difficult if target is specified. */
865 success_prob = (improvement >= B_LAST ? game.server.diplchance
866 : game.server.diplchance / 2);
868 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
869 if (!diplomat_infiltrate_tile(pplayer, cplayer, pdiplomat, NULL,
870 pcity->tile)) {
871 return;
874 log_debug("sabotage: infiltrated");
876 /* Check if the Diplomat/Spy succeeds with his/her task. */
877 if (fc_rand (100) >= success_prob) {
878 notify_player(pplayer, city_tile(pcity),
879 E_MY_DIPLOMAT_FAILED, ftc_server,
880 _("Your %s was caught in the attempt"
881 " of industrial sabotage!"),
882 unit_tile_link(pdiplomat));
883 notify_player(cplayer, city_tile(pcity),
884 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
885 _("You caught %s %s attempting sabotage in %s!"),
886 nation_adjective_for_player(pplayer),
887 unit_tile_link(pdiplomat),
888 city_link(pcity));
889 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
890 return;
893 log_debug("sabotage: succeeded");
895 /* Examine the city for improvements to sabotage. */
896 count = 0;
897 city_built_iterate(pcity, pimprove) {
898 if (pimprove->sabotage > 0) {
899 count++;
901 } city_built_iterate_end;
903 log_debug("sabotage: count of improvements: %d", count);
905 /* Determine the target (-1 is production). */
906 if (action_id == ACTION_SPY_SABOTAGE_CITY) {
908 * Pick random:
909 * 50/50 chance to pick production or some improvement.
910 * Won't pick something that doesn't exit.
911 * If nothing to do, say so, deduct movement cost and return.
913 if (count == 0 && pcity->shield_stock == 0) {
914 notify_player(pplayer, city_tile(pcity),
915 E_MY_DIPLOMAT_FAILED, ftc_server,
916 _("Your %s could not find anything to sabotage in %s."),
917 unit_link(pdiplomat),
918 city_link(pcity));
919 diplomat_charge_movement(pdiplomat, pcity->tile);
920 send_unit_info(NULL, pdiplomat);
921 log_debug("sabotage: random: nothing to do");
922 return;
924 if (count == 0 || fc_rand (2) == 1) {
925 ptarget = NULL;
926 log_debug("sabotage: random: targeted production");
927 } else {
928 ptarget = NULL;
929 which = fc_rand (count);
931 city_built_iterate(pcity, pimprove) {
932 if (pimprove->sabotage > 0) {
933 if (which > 0) {
934 which--;
935 } else {
936 ptarget = pimprove;
937 break;
940 } city_built_iterate_end;
942 if (NULL != ptarget) {
943 log_debug("sabotage: random: targeted improvement: %d (%s)",
944 improvement_number(ptarget),
945 improvement_rule_name(ptarget));
946 } else {
947 log_error("sabotage: random: targeted improvement error!");
950 } else if (improvement < 0) {
951 /* If told to sabotage production, do so. */
952 ptarget = NULL;
953 log_debug("sabotage: specified target production");
954 } else {
955 struct impr_type *pimprove = improvement_by_number(improvement);
956 if (pimprove == NULL) {
957 log_error("sabotage: requested for invalid improvement %d", improvement);
958 return;
961 * Told which improvement to pick:
962 * If try for wonder or palace, complain, deduct movement cost and return.
963 * If not available, say so, deduct movement cost and return.
965 if (city_has_building(pcity, pimprove)) {
966 if (pimprove->sabotage > 0) {
967 ptarget = pimprove;
968 log_debug("sabotage: specified target improvement: %d (%s)",
969 improvement, improvement_rule_name(pimprove));
970 } else {
971 notify_player(pplayer, city_tile(pcity),
972 E_MY_DIPLOMAT_FAILED, ftc_server,
973 _("You cannot sabotage a %s!"),
974 improvement_name_translation(pimprove));
975 diplomat_charge_movement(pdiplomat, pcity->tile);
976 send_unit_info(NULL, pdiplomat);
977 log_debug("sabotage: disallowed target improvement: %d (%s)",
978 improvement, improvement_rule_name(pimprove));
979 return;
981 } else {
982 notify_player(pplayer, city_tile(pcity),
983 E_MY_DIPLOMAT_FAILED, ftc_server,
984 _("Your %s could not find the %s to sabotage in %s."),
985 unit_name_translation(pdiplomat),
986 improvement_name_translation(pimprove),
987 city_link(pcity));
988 diplomat_charge_movement(pdiplomat, pcity->tile);
989 send_unit_info(NULL, pdiplomat);
990 log_debug("sabotage: target improvement not found: %d (%s)",
991 improvement, improvement_rule_name(pimprove));
992 return;
996 /* Now, the fun stuff! Do the sabotage! */
997 if (NULL == ptarget) {
998 char prod[256];
1000 /* Do it. */
1001 pcity->shield_stock = 0;
1002 nullify_prechange_production(pcity); /* Make it impossible to recover */
1004 /* Report it. */
1005 universal_name_translation(&pcity->production, prod, sizeof(prod));
1007 notify_player(pplayer, city_tile(pcity),
1008 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
1009 _("Your %s succeeded in destroying"
1010 " the production of %s in %s."),
1011 unit_link(pdiplomat),
1012 prod,
1013 city_name_get(pcity));
1014 notify_player(cplayer, city_tile(pcity),
1015 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1016 _("The production of %s was destroyed in %s,"
1017 " %s are suspected."),
1018 prod,
1019 city_link(pcity),
1020 nation_plural_for_player(pplayer));
1021 log_debug("sabotage: sabotaged production");
1022 } else {
1023 int vulnerability = ptarget->sabotage;
1025 /* Sabotage a city improvement. */
1028 * One last chance to get caught:
1029 * If target was specified, and it is in the capital or are
1030 * City Walls, then there is a 50% chance of getting caught.
1032 vulnerability -= (vulnerability
1033 * get_city_bonus(pcity, EFT_SPY_RESISTANT) / 100);
1035 if (fc_rand(100) >= vulnerability) {
1036 /* Caught! */
1037 notify_player(pplayer, city_tile(pcity),
1038 E_MY_DIPLOMAT_FAILED, ftc_server,
1039 _("Your %s was caught in the attempt of sabotage!"),
1040 unit_tile_link(pdiplomat));
1041 notify_player(cplayer, city_tile(pcity),
1042 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1043 _("You caught %s %s attempting"
1044 " to sabotage the %s in %s!"),
1045 nation_adjective_for_player(pplayer),
1046 unit_tile_link(pdiplomat),
1047 improvement_name_translation(ptarget),
1048 city_link(pcity));
1049 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1050 log_debug("sabotage: caught in capital or on city walls");
1051 return;
1054 /* Report it. */
1055 notify_player(pplayer, city_tile(pcity),
1056 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
1057 _("Your %s destroyed the %s in %s."),
1058 unit_link(pdiplomat),
1059 improvement_name_translation(ptarget),
1060 city_link(pcity));
1061 notify_player(cplayer, city_tile(pcity),
1062 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1063 _("The %s destroyed the %s in %s."),
1064 nation_plural_for_player(pplayer),
1065 improvement_name_translation(ptarget),
1066 city_link(pcity));
1067 log_debug("sabotage: sabotaged improvement: %d (%s)",
1068 improvement_number(ptarget),
1069 improvement_rule_name(ptarget));
1071 /* Do it. */
1072 building_lost(pcity, ptarget);
1075 /* Update clients. */
1076 send_city_info(NULL, pcity);
1078 /* this may cause a diplomatic incident */
1079 action_consequence_success(action_id, pplayer, cplayer,
1080 city_tile(pcity), city_link(pcity));
1082 /* Check if a spy survives her mission. Diplomats never do. */
1083 diplomat_escape(pplayer, pdiplomat, pcity);
1086 /**************************************************************************
1087 Steal gold from another player.
1088 The amount stolen is decided randomly.
1089 Not everything stolen reaches the player that ordered it stolen.
1091 - Check for infiltration success. Our thief may not survive this.
1092 - Check for basic success. Again, our thief may not survive this.
1093 - Can't steal if there is no money to take.
1094 **************************************************************************/
1095 void spy_steal_gold(struct player *act_player, struct unit *act_unit,
1096 struct city *tgt_city)
1098 struct player *tgt_player;
1099 struct tile *tgt_tile;
1101 const char *tgt_city_link;
1103 int gold_take;
1104 int gold_give;
1106 /* Sanity check: The actor still exists. */
1107 fc_assert_ret(act_player);
1108 fc_assert_ret(act_unit);
1110 /* Sanity check: The target city still exists. */
1111 fc_assert_ret(tgt_city);
1113 /* Who to steal from. */
1114 tgt_player = city_owner(tgt_city);
1116 /* Sanity check: The target player still exists. */
1117 fc_assert_ret(tgt_player);
1119 /* Sanity check: The target is foreign. */
1120 if (tgt_player == act_player) {
1121 /* Nothing to do to a domestic target. */
1122 return;
1125 /* Sanity check: There is something to steal. */
1126 if (tgt_player->economic.gold <= 0) {
1127 return;
1130 tgt_tile = city_tile(tgt_city);
1131 tgt_city_link = city_link(tgt_city);
1133 log_debug("steal gold: unit: %d", act_unit->id);
1135 /* Battle all units capable of diplomatic defence. */
1136 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1137 act_unit, NULL, tgt_tile)) {
1138 return;
1141 log_debug("steal gold: infiltrated");
1143 /* The thief may get caught while trying to steal the gold. */
1144 if (fc_rand (100) >= game.server.diplchance) {
1145 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1146 _("Your %s was caught attempting to steal gold!"),
1147 unit_tile_link(act_unit));
1148 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1149 ftc_server,
1150 _("You caught %s %s attempting"
1151 " to steal your gold in %s!"),
1152 nation_adjective_for_player(act_player),
1153 unit_tile_link(act_unit),
1154 tgt_city_link);
1156 /* Execute the caught thief. */
1157 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1159 return;
1162 log_debug("steal gold: succeeded");
1164 /* The upper limit on how much gold the thief can steal. */
1165 gold_take = (tgt_player->economic.gold
1166 * get_city_bonus(tgt_city, EFT_MAX_STOLEN_GOLD_PM))
1167 / 1000;
1169 /* How much to actually take. 1 gold is the smallest amount that can be
1170 * stolen. The victim player has at least 1 gold. If he didn't the
1171 * something to steal sanity check would have aborted the theft. */
1172 gold_take = fc_rand(gold_take) + 1;
1174 log_debug("steal gold: will take %d gold", gold_take);
1176 /* Steal the gold. */
1177 tgt_player->economic.gold -= gold_take;
1179 /* Some gold may be lost during transfer. */
1180 gold_give = gold_take
1181 - (gold_take * get_unit_bonus(act_unit, EFT_THIEFS_SHARE_PM))
1182 / 1000;
1184 log_debug("steal gold: will give %d gold", gold_give);
1186 /* Pocket the stolen money. */
1187 act_player->economic.gold += gold_give;
1189 /* Notify everyone involved. */
1190 notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_GOLD, ftc_server,
1191 PL_("Your %s stole %d gold from %s.",
1192 "Your %s stole %d gold from %s.", gold_give),
1193 unit_link(act_unit), gold_give, tgt_city_link);
1194 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_GOLD, ftc_server,
1195 PL_("The %s are suspected of stealing %d gold from %s.",
1196 "The %s are suspected of stealing %d gold from %s.",
1197 gold_take),
1198 nation_plural_for_player(act_player),
1199 gold_take, tgt_city_link);
1201 /* This may cause a diplomatic incident. */
1202 action_consequence_success(ACTION_SPY_STEAL_GOLD, act_player,
1203 tgt_player, tgt_tile, tgt_city_link);
1205 /* Try to escape. */
1206 diplomat_escape_full(act_player, act_unit, TRUE,
1207 tgt_tile, tgt_city_link);
1209 /* Update the players' gold in the client */
1210 send_player_info_c(act_player, act_player->connections);
1211 send_player_info_c(tgt_player, tgt_player->connections);
1214 /**************************************************************************
1215 This subtracts the destination movement cost from a diplomat/spy.
1216 **************************************************************************/
1217 static void diplomat_charge_movement (struct unit *pdiplomat, struct tile *ptile)
1219 pdiplomat->moves_left -=
1220 map_move_cost_unit(pdiplomat, ptile);
1221 if (pdiplomat->moves_left < 0) {
1222 pdiplomat->moves_left = 0;
1226 /**************************************************************************
1227 This determines if a diplomat/spy succeeds against some defender,
1228 who is also a diplomat or spy. Note: a superspy defender always
1229 succeeds, otherwise a superspy attacker always wins.
1231 Return TRUE if the "attacker" succeeds.
1232 **************************************************************************/
1233 static bool diplomat_success_vs_defender(struct unit *pattacker,
1234 struct unit *pdefender,
1235 struct tile *pdefender_tile)
1237 int chance = 50; /* Base 50% chance */
1239 if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
1240 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
1241 return FALSE;
1243 if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
1244 /* An attacking UTYF_SUPERSPY will defeat every possible defender
1245 * except another UTYF_SUPERSPY. */
1246 return TRUE;
1249 /* Add or remove 25% if spy flag. */
1250 if (unit_has_type_flag(pattacker, UTYF_SPY)) {
1251 chance += 25;
1253 if (unit_has_type_flag(pdefender, UTYF_SPY)) {
1254 chance -= 25;
1257 /* Use power_fact from veteran level to modify chance in a linear way.
1258 * Equal veteran levels cancel out.
1259 * It's probably not good for rulesets to allow this to have more than
1260 * 20% effect. */
1262 const struct veteran_level
1263 *vatt = utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
1264 const struct veteran_level
1265 *vdef = utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
1266 fc_assert_ret_val(vatt != NULL && vdef != NULL, FALSE);
1267 chance += vatt->power_fact - vdef->power_fact;
1270 /* Reduce the chance of an attack if BF_DIPLOMAT_DEFENSE is active. */
1271 if (tile_has_base_flag_for_unit(pdefender_tile, unit_type_get(pdefender),
1272 BF_DIPLOMAT_DEFENSE)) {
1273 chance -= chance * 25 / 100; /* 25% penalty */
1276 if (tile_city(pdefender_tile)) {
1277 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
1278 chance -= chance * get_city_bonus(tile_city(pdefender_tile),
1279 EFT_SPY_RESISTANT) / 100;
1282 return (int)fc_rand(100) < chance;
1285 /**************************************************************************
1286 This determines if a diplomat/spy succeeds in infiltrating a tile.
1288 - The infiltrator must go up against each defender.
1289 - The victim unit won't defend. (NULL if everyone should defend)
1290 - One or the other is eliminated in each contest.
1292 - Return TRUE if the infiltrator succeeds.
1294 'pplayer' is the player who tries to do a spy/diplomat action on 'ptile'
1295 with the unit 'pdiplomat' against 'cplayer'.
1296 **************************************************************************/
1297 static bool diplomat_infiltrate_tile(struct player *pplayer,
1298 struct player *cplayer,
1299 struct unit *pdiplomat,
1300 struct unit *pvictim,
1301 struct tile *ptile)
1303 char link_city[MAX_LEN_LINK] = "";
1304 char link_diplomat[MAX_LEN_LINK];
1305 char link_unit[MAX_LEN_LINK];
1306 struct city *pcity = tile_city(ptile);
1308 if (pcity) {
1309 /* N.B.: *_link() always returns the same pointer. */
1310 sz_strlcpy(link_city, city_link(pcity));
1313 /* We don't need a _safe iterate since no transporters should be
1314 * destroyed. */
1315 unit_list_iterate(ptile->units, punit) {
1316 struct player *uplayer = unit_owner(punit);
1318 /* I can't confirm if we won't deny that we weren't involved. */
1319 if (uplayer == pplayer) {
1320 continue;
1323 if (punit == pvictim
1324 && !unit_has_type_flag(punit, UTYF_SUPERSPY)) {
1325 /* The victim unit is defenseless unless it's a SuperSpy.
1326 * Rationalization: A regular diplomat don't mind being bribed. A
1327 * SuperSpy is high enough up the chain that accepting a bribe is
1328 * against his own interests. */
1329 continue;
1332 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)
1333 || unit_has_type_flag(punit, UTYF_SUPERSPY)) {
1334 /* A UTYF_SUPERSPY unit may not actually be a spy, but a superboss
1335 * which we cannot allow puny diplomats from getting the better
1336 * of. UTYF_SUPERSPY vs UTYF_SUPERSPY in a diplomatic contest always
1337 * kills the attacker. */
1339 if (diplomat_success_vs_defender(pdiplomat, punit, ptile)) {
1340 /* Defending Spy/Diplomat dies. */
1342 /* N.B.: *_link() always returns the same pointer. */
1343 sz_strlcpy(link_unit, unit_tile_link(punit));
1344 sz_strlcpy(link_diplomat, unit_link(pdiplomat));
1346 notify_player(pplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1347 /* TRANS: <unit> ... <diplomat> */
1348 _("An enemy %s has been eliminated by your %s."),
1349 link_unit, link_diplomat);
1351 if (pcity) {
1352 if (uplayer == cplayer) {
1353 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1354 /* TRANS: <unit> ... <city> ... <diplomat> */
1355 _("Your %s has been eliminated defending %s"
1356 " against a %s."), link_unit, link_city,
1357 link_diplomat);
1358 } else {
1359 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1360 /* TRANS: <nation adj> <unit> ... <city>
1361 * TRANS: ... <diplomat> */
1362 _("A %s %s has been eliminated defending %s "
1363 "against a %s."),
1364 nation_adjective_for_player(uplayer),
1365 link_unit, link_city, link_diplomat);
1366 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1367 /* TRANS: ... <unit> ... <nation adj> <city>
1368 * TRANS: ... <diplomat> */
1369 _("Your %s has been eliminated defending %s %s "
1370 "against a %s."), link_unit,
1371 nation_adjective_for_player(cplayer),
1372 link_city, link_diplomat);
1374 } else {
1375 if (uplayer == cplayer) {
1376 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1377 /* TRANS: <unit> ... <diplomat> */
1378 _("Your %s has been eliminated defending "
1379 "against a %s."), link_unit, link_diplomat);
1380 } else {
1381 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1382 /* TRANS: <nation adj> <unit> ... <diplomat> */
1383 _("A %s %s has been eliminated defending "
1384 "against a %s."),
1385 nation_adjective_for_player(uplayer),
1386 link_unit, link_diplomat);
1387 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1388 /* TRANS: ... <unit> ... <diplomat> */
1389 _("Your %s has been eliminated defending "
1390 "against a %s."), link_unit, link_diplomat);
1394 pdiplomat->moves_left = MAX(0, pdiplomat->moves_left - SINGLE_MOVE);
1396 /* Attacking unit became more experienced? */
1397 if (maybe_make_veteran(pdiplomat)) {
1398 notify_unit_experience(pdiplomat);
1400 send_unit_info(NULL, pdiplomat);
1401 wipe_unit(punit, ULR_ELIMINATED, pplayer);
1402 return FALSE;
1403 } else {
1404 /* Attacking Spy/Diplomat dies. */
1406 /* N.B.: *_link() always returns the same pointer. */
1407 sz_strlcpy(link_unit, unit_link(punit));
1408 sz_strlcpy(link_diplomat, unit_tile_link(pdiplomat));
1410 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1411 _("Your %s was eliminated by a defending %s."),
1412 link_diplomat, link_unit);
1414 if (pcity) {
1415 if (uplayer == cplayer) {
1416 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1417 _("Eliminated a %s %s while infiltrating %s."),
1418 nation_adjective_for_player(pplayer),
1419 link_diplomat, link_city);
1420 } else {
1421 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1422 _("A %s %s eliminated a %s %s while infiltrating "
1423 "%s."), nation_adjective_for_player(uplayer),
1424 link_unit, nation_adjective_for_player(pplayer),
1425 link_diplomat, link_city);
1426 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1427 _("Your %s eliminated a %s %s while infiltrating "
1428 "%s."), link_unit,
1429 nation_adjective_for_player(pplayer),
1430 link_diplomat, link_city);
1432 } else {
1433 if (uplayer == cplayer) {
1434 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1435 _("Eliminated a %s %s while infiltrating our troops."),
1436 nation_adjective_for_player(pplayer),
1437 link_diplomat);
1438 } else {
1439 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1440 _("A %s %s eliminated a %s %s while infiltrating our "
1441 "troops."), nation_adjective_for_player(uplayer),
1442 link_unit, nation_adjective_for_player(pplayer),
1443 link_diplomat);
1444 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1445 /* TRANS: ... <unit> ... <diplomat> */
1446 _("Your %s eliminated a %s %s while infiltrating our "
1447 "troops."), link_unit,
1448 nation_adjective_for_player(pplayer),
1449 link_diplomat);
1453 /* Defending unit became more experienced? */
1454 if (maybe_make_veteran(punit)) {
1455 notify_unit_experience(punit);
1457 wipe_unit(pdiplomat, ULR_ELIMINATED, uplayer);
1458 return FALSE;
1461 } unit_list_iterate_end;
1463 return TRUE;
1466 /**************************************************************************
1467 This determines if a diplomat/spy survives and escapes.
1468 If "pcity" is NULL, assume action was in the field.
1470 Spies have a game.server.diplchance specified chance of survival (better
1471 if veteran):
1472 - Diplomats always die.
1473 - Escapes to home city.
1474 - Escapee may become a veteran.
1475 **************************************************************************/
1476 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
1477 const struct city *pcity)
1479 struct tile *ptile;
1480 const char *vlink;
1482 if (pcity) {
1483 ptile = city_tile(pcity);
1484 vlink = city_link(pcity);
1485 } else {
1486 ptile = unit_tile(pdiplomat);
1487 vlink = NULL;
1490 return diplomat_escape_full(pplayer, pdiplomat, pcity != NULL,
1491 ptile, vlink);
1494 /**************************************************************************
1495 This determines if a diplomat/spy survives and escapes.
1497 Spies have a game.server.diplchance specified chance of survival (better
1498 if veteran):
1499 - Diplomats always die.
1500 - Escapes to home city.
1501 - Escapee may become a veteran.
1502 **************************************************************************/
1503 static void diplomat_escape_full(struct player *pplayer,
1504 struct unit *pdiplomat,
1505 bool city_related,
1506 struct tile *ptile,
1507 const char *vlink)
1509 int escapechance;
1510 struct city *spyhome;
1512 /* Veteran level's power factor's effect on escape chance is relative to
1513 * unpromoted unit's power factor */
1515 const struct veteran_level
1516 *vunit = utype_veteran_level(unit_type_get(pdiplomat), pdiplomat->veteran);
1517 const struct veteran_level
1518 *vbase = utype_veteran_level(unit_type_get(pdiplomat), 0);
1520 escapechance = game.server.diplchance
1521 + (vunit->power_fact - vbase->power_fact);
1524 /* find closest city for escape target */
1525 spyhome = find_closest_city(ptile, NULL, unit_owner(pdiplomat), FALSE,
1526 FALSE, FALSE, TRUE, FALSE, NULL);
1528 if (spyhome
1529 && unit_has_type_flag(pdiplomat, UTYF_SPY)
1530 && (unit_has_type_flag(pdiplomat, UTYF_SUPERSPY)
1531 || fc_rand (100) < escapechance)) {
1532 /* Attacking Spy/Diplomat survives. */
1533 notify_player(pplayer, ptile, E_MY_DIPLOMAT_ESCAPE, ftc_server,
1534 _("Your %s has successfully completed"
1535 " the mission and returned unharmed to %s."),
1536 unit_link(pdiplomat),
1537 city_link(spyhome));
1538 if (maybe_make_veteran(pdiplomat)) {
1539 notify_unit_experience(pdiplomat);
1542 /* being teleported costs all movement */
1543 if (!teleport_unit_to_city (pdiplomat, spyhome, -1, FALSE)) {
1544 send_unit_info(NULL, pdiplomat);
1545 log_error("Bug in diplomat_escape: Spy can't teleport.");
1546 return;
1549 return;
1550 } else {
1551 if (city_related) {
1552 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1553 _("Your %s was captured after completing"
1554 " the mission in %s."),
1555 unit_tile_link(pdiplomat),
1556 vlink);
1557 } else {
1558 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
1559 _("Your %s was captured after completing"
1560 " the mission."),
1561 unit_tile_link(pdiplomat));
1565 /* FIXME: Reason should be ULR_USED for diplomats? */
1566 wipe_unit(pdiplomat, ULR_CAUGHT, NULL);
1569 /**************************************************************************
1570 return number of diplomats on this square. AJS 20000130
1571 **************************************************************************/
1572 int count_diplomats_on_tile(struct tile *ptile)
1574 int count = 0;
1576 unit_list_iterate((ptile)->units, punit) {
1577 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
1578 count++;
1580 } unit_list_iterate_end;
1582 return count;