Freeciv-3.1
Loading...
Searching...
No Matches
diplomats.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19
20/* utility */
21#include "bitvector.h"
22#include "capability.h"
23#include "fcintl.h"
24#include "log.h"
25#include "rand.h"
26
27/* common */
28#include "base.h"
29#include "combat.h"
30#include "events.h"
31#include "game.h"
32#include "government.h"
33#include "map.h"
34#include "movement.h"
35#include "player.h"
36#include "research.h"
37#include "unitlist.h"
38
39/* server */
40#include "actiontools.h"
41#include "aiiface.h"
42#include "citytools.h"
43#include "cityturn.h"
44#include "diplhand.h"
45#include "diplomats.h"
46#include "maphand.h"
47#include "notify.h"
48#include "plrhand.h"
49#include "techtools.h"
50#include "unithand.h"
51#include "unittools.h"
52
53/* server/scripting */
54#include "script_server.h"
55
56/****************************************************************************/
57
58static void diplomat_charge_movement (struct unit *pdiplomat,
59 struct tile *ptile);
60static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef,
61 struct tile *pdefender_tile,
62 int *att_vet, int *def_vet);
63static bool diplomat_may_lose_gold(struct player *dec_player,
64 struct player *inc_player,
65 int revolt_gold);
66static bool diplomat_infiltrate_tile(struct player *pplayer,
67 struct player *cplayer,
68 const struct action *paction,
69 struct unit *pdiplomat,
70 struct unit *pvictim,
71 struct tile *ptile,
72 struct player **defender_owner);
73static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
74 const struct city *pcity,
75 const struct action *paction);
76static void diplomat_escape_full(struct player *pplayer,
77 struct unit *pdiplomat,
78 bool city_related,
79 struct tile *ptile,
80 const char *vlink,
81 const struct action *paction);
82
83/************************************************************************/
98bool spy_poison(struct player *pplayer, struct unit *pdiplomat,
99 struct city *pcity, const struct action *paction)
100{
101 const struct unit_type *act_utype;
102 struct player *cplayer;
103 struct tile *ctile;
104 const char *clink;
105
106 /* Fetch target city's player. Sanity checks. */
107 fc_assert_ret_val(pcity, FALSE);
108 cplayer = city_owner(pcity);
109 fc_assert_ret_val(cplayer, FALSE);
110
111 /* Sanity check: The actor still exists. */
112 fc_assert_ret_val(pplayer, FALSE);
113 fc_assert_ret_val(pdiplomat, FALSE);
114
115 act_utype = unit_type_get(pdiplomat);
116
117 ctile = city_tile(pcity);
118 clink = city_link(pcity);
119
120 log_debug("poison: unit: %d", pdiplomat->id);
121
122 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
123 if (!diplomat_infiltrate_tile(pplayer, cplayer, paction,
124 pdiplomat, NULL, ctile, NULL)) {
125 return FALSE;
126 }
127
128 log_debug("poison: infiltrated");
129
130 /* The Spy may get caught while trying to poison the city. */
131 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
132 paction)) {
133 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
134 /* TRANS: unit, action */
135 _("Your %s was caught attempting to do %s!"),
136 unit_tile_link(pdiplomat),
137 action_name_translation(paction));
138 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_FAILED,
140 /* TRANS: nation, unit, action, city */
141 _("You caught %s %s attempting to do %s in %s!"),
143 unit_tile_link(pdiplomat),
145 clink);
146
147 /* This may cause a diplomatic incident */
148 action_consequence_caught(paction, pplayer, act_utype,
149 cplayer, ctile, clink);
150
151 /* Execute the caught Spy. */
152 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
153
154 return FALSE;
155 }
156
157 log_debug("poison: succeeded");
158
159 /* Poison people! */
160 if (city_reduce_size(pcity, 1, pplayer, "poison")) {
161 /* Notify everybody involved. */
162 notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
163 _("Your %s poisoned the water supply of %s."),
164 unit_link(pdiplomat), clink);
165 notify_player(cplayer, ctile,
166 E_ENEMY_DIPLOMAT_POISON, ftc_server,
167 _("%s is suspected of poisoning the water supply of %s."),
168 player_name(pplayer), clink);
169
171 /* The food was poisoned too. */
173 }
174
175 /* Update clients. */
176 city_refresh (pcity);
177 send_city_info(NULL, pcity);
178 } else {
179 /* Notify everybody involved. */
180 notify_player(pplayer, ctile, E_MY_DIPLOMAT_POISON, ftc_server,
181 _("Your %s destroyed %s by poisoning its water supply."),
182 unit_link(pdiplomat), clink);
183 notify_player(cplayer, ctile,
184 E_ENEMY_DIPLOMAT_POISON, ftc_server,
185 _("%s is suspected of destroying %s by poisoning its"
186 " water supply."),
187 player_name(pplayer), clink);
188 }
189
190 /* this may cause a diplomatic incident */
191 action_consequence_success(paction, pplayer, act_utype,
192 cplayer, ctile, clink);
193
194 /* Now lets see if the spy survives. */
195 diplomat_escape_full(pplayer, pdiplomat, TRUE, ctile, clink, paction);
196
197 return TRUE;
198}
199
200/************************************************************************/
215bool spy_spread_plague(struct player *act_player, struct unit *act_unit,
216 struct city *tgt_city, const struct action *paction)
217{
218 const struct unit_type *act_utype;
219 struct player *tgt_player;
220 struct tile *tgt_tile;
221
222 const char *tgt_city_link;
223
224 /* Sanity check: The actor still exists. */
225 fc_assert_ret_val(act_player, FALSE);
226 fc_assert_ret_val(act_unit, FALSE);
227 act_utype = unit_type_get(act_unit);
228
229 /* Sanity check: The target city still exists. */
230 fc_assert_ret_val(tgt_city, FALSE);
231
232 /* Who to infect. */
233 tgt_player = city_owner(tgt_city);
234
235 /* Sanity check: The target player still exists. */
236 fc_assert_ret_val(tgt_player, FALSE);
237
238 tgt_tile = city_tile(tgt_city);
239 tgt_city_link = city_link(tgt_city);
240
241 log_debug("spread plague: unit: %d", act_unit->id);
242
243 /* Battle all units capable of diplomatic defense. */
244 if (!diplomat_infiltrate_tile(act_player, tgt_player,
245 paction,
246 act_unit, NULL, tgt_tile, NULL)) {
247 return FALSE;
248 }
249
250 log_debug("spread plague: infiltrated");
251
252 /* The infector may get caught while trying to spread a plague in the
253 * city. */
254 if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
255 paction)) {
256 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
257 /* TRANS: unit, action */
258 _("Your %s was caught attempting to do %s!"),
259 unit_tile_link(act_unit),
260 action_name_translation(paction));
261 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
263 /* TRANS: nation, unit, action, city */
264 _("You caught %s %s attempting to do %s in %s!"),
265 nation_adjective_for_player(act_player),
266 unit_tile_link(act_unit),
268 tgt_city_link);
269
270 /* This may cause a diplomatic incident */
271 action_consequence_caught(paction, act_player, act_utype,
272 tgt_player, tgt_tile, tgt_city_link);
273
274 /* Execute the caught infector. */
275 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
276
277 return FALSE;
278 }
279
280 log_debug("spread plague: succeeded");
281
282 /* Commit bio-terrorism. */
283 if (city_illness_strike(tgt_city)) {
284 /* Update the clients. */
285 city_refresh(tgt_city);
286 send_city_info(NULL, tgt_city);
287 }
288
289 /* Notify everyone involved. */
290 notify_player(act_player, tgt_tile, E_UNIT_ACTION_ACTOR_SUCCESS,
292 /* TRANS: unit, action, city */
293 _("Your %s did %s to %s."),
294 unit_link(act_unit), action_name_translation(paction),
295 tgt_city_link);
296 notify_player(tgt_player, tgt_tile, E_UNIT_ACTION_TARGET_HOSTILE,
298 /* TRANS: action, city, nation */
299 _("%s done to %s, %s suspected."),
300 action_name_translation(paction), tgt_city_link,
301 nation_plural_for_player(act_player));
302
303 /* This may cause a diplomatic incident. */
304 action_consequence_success(paction, act_player, act_utype,
305 tgt_player, tgt_tile, tgt_city_link);
306
307 /* Try to escape. */
308 diplomat_escape_full(act_player, act_unit, TRUE,
309 tgt_tile, tgt_city_link, paction);
310
311 return TRUE;
312}
313
314/************************************************************************/
325bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
326 struct city *pcity,
327 const struct action *paction)
328{
329 struct player *cplayer;
330 struct packet_unit_short_info unit_packet;
331 struct packet_city_info city_packet;
332 struct packet_city_nationalities nat_packet;
333 struct packet_city_rally_point rally_packet;
334 struct packet_web_city_info_addition web_packet;
335 struct trade_route_packet_list *routes;
336 const struct unit_type *act_utype;
337
338 /* Fetch target city's player. Sanity checks. */
339 fc_assert_ret_val(pcity, FALSE);
340 cplayer = city_owner(pcity);
341 fc_assert_ret_val(cplayer, FALSE);
342
343 /* Sanity check: The actor still exists. */
344 fc_assert_ret_val(pplayer, FALSE);
345 fc_assert_ret_val(pdiplomat, FALSE);
346
347 act_utype = unit_type_get(pdiplomat);
348
349 /* Sanity check: The target is foreign. */
350 if (cplayer == pplayer) {
351 /* Nothing to do to a domestic target. */
352 return FALSE;
353 }
354
355 log_debug("investigate: unit: %d", pdiplomat->id);
356
357 conn_list_iterate(pplayer->connections, pconn) {
358 if (has_capability("obsinv", pconn->capability)) {
359 dsend_packet_investigate_started(pconn, pdiplomat->id, pdiplomat->id,
360 pcity->id, pcity->id);
361 }
363
364 /* Do It... */
365 update_dumb_city(pplayer, pcity);
366 /* Special case for a diplomat/spy investigating a city:
367 The investigator needs to know the supported and present
368 units of a city, whether or not they are fogged. So, we
369 send a list of them all before sending the city info.
370 As this is a special case we bypass send_unit_info(). */
372 package_short_unit(punit, &unit_packet,
374 /* We need to force to send the packet to ensure the client will receive
375 * something (e.g. investigating twice). */
376 lsend_packet_unit_short_info(pplayer->connections, &unit_packet, TRUE);
378 unit_list_iterate((pcity->tile)->units, punit) {
379 package_short_unit(punit, &unit_packet,
380 UNIT_INFO_CITY_PRESENT, pcity->id);
381 /* We need to force to send the packet to ensure the client will receive
382 * something (e.g. investigating twice). */
383 lsend_packet_unit_short_info(pplayer->connections, &unit_packet, TRUE);
385 /* Send city info to investigator's player.
386 As this is a special case we bypass send_city_info. */
387 routes = trade_route_packet_list_new();
388 package_city(pcity, &city_packet, &nat_packet, &rally_packet,
389 &web_packet, routes, TRUE);
390 /* We need to force to send the packet to ensure the client will receive
391 * something and popup the city dialog. */
392 city_packet.original = city_original_owner(pcity, pplayer);
393 lsend_packet_city_info(pplayer->connections, &city_packet, TRUE);
394 lsend_packet_city_nationalities(pplayer->connections, &nat_packet, TRUE);
395 lsend_packet_city_rally_point(pplayer->connections, &rally_packet, TRUE);
396 web_lsend_packet(city_info_addition, pplayer->connections, &web_packet, TRUE);
397 trade_route_packet_list_iterate(routes, route_packet) {
398 lsend_packet_trade_route_info(pplayer->connections, route_packet);
399 FC_FREE(route_packet);
401 trade_route_packet_list_destroy(routes);
402
403 /* This may cause a diplomatic incident */
404 action_consequence_success(paction, pplayer, act_utype, cplayer,
405 city_tile(pcity), city_link(pcity));
406
407 /* The actor unit always survive unless the action it self has determined
408 * to always consume it. */
409 if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
410 /* This unit isn't about to be consumed. Send updated unit information
411 * to the clients. */
412 send_unit_info(NULL, pdiplomat);
413 }
414
415 conn_list_iterate(pplayer->connections, pconn) {
416 if (has_capability("obsinv", pconn->capability)) {
417 dsend_packet_investigate_finished(pconn, pdiplomat->id, pdiplomat->id,
418 pcity->id, pcity->id);
419 }
421
422 return TRUE;
423}
424
425/************************************************************************/
432void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat,
433 struct city *pcity,
434 const struct action *paction,
435 int request_kind)
436{
437 struct packet_city_sabotage_list packet;
438
439 /* Send city improvements info to player. */
440 BV_CLR_ALL(packet.improvements);
441
442 if (action_has_result(paction, ACTRES_SPY_TARGETED_SABOTAGE_CITY)) {
443 /* Can see hidden buildings. */
444 improvement_iterate(ptarget) {
445 if (city_has_building(pcity, ptarget)) {
446 BV_SET(packet.improvements, improvement_index(ptarget));
447 }
449 } else {
450 /* Can't see hidden buildings. */
451 struct vision_site *plrcity;
452
453 plrcity = map_get_player_city(city_tile(pcity), unit_owner(pdiplomat));
454
455 if (!plrcity) {
456 /* Must know city to remember visible buildings. */
457 return;
458 }
459
460 improvement_iterate(ptarget) {
461 if (BV_ISSET(plrcity->improvements, improvement_index(ptarget))) {
462 BV_SET(packet.improvements, improvement_index(ptarget));
463 }
465 }
466
467 packet.actor_id32 = pdiplomat->id;
468 packet.actor_id16 = packet.actor_id32;
469 packet.city_id32 = pcity->id;
470 packet.city_id16 = packet.city_id32;
471 packet.act_id = paction->id;
472 packet.request_kind = request_kind;
474}
475
476/************************************************************************/
488bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
489 struct city *pcity, const struct action *paction)
490{
491 struct player *cplayer;
492 const struct unit_type *act_utype;
493
494 /* Fetch target city's player. Sanity checks. */
495 fc_assert_ret_val(pcity, FALSE);
496 cplayer = city_owner(pcity);
497 fc_assert_ret_val(cplayer, FALSE);
498
499 /* Sanity check: The actor still exists. */
500 fc_assert_ret_val(pplayer, FALSE);
501 fc_assert_ret_val(pdiplomat, FALSE);
502
503 act_utype = unit_type_get(pdiplomat);
504
505 /* Sanity check: The target is foreign. */
506 if (cplayer == pplayer) {
507 /* Nothing to do to a domestic target. */
508 return FALSE;
509 }
510
511 log_debug("embassy: unit: %d", pdiplomat->id);
512
513 log_debug("embassy: succeeded");
514
515 establish_embassy(pplayer, cplayer);
516
517 /* Notify everybody involved. */
518 notify_player(pplayer, city_tile(pcity),
519 E_MY_DIPLOMAT_EMBASSY, ftc_server,
520 _("You have established an embassy in %s."),
521 city_link(pcity));
522 notify_player(cplayer, city_tile(pcity),
523 E_ENEMY_DIPLOMAT_EMBASSY, ftc_server,
524 _("The %s have established an embassy in %s."),
526 city_link(pcity));
527
528 /* this may cause a diplomatic incident */
529 action_consequence_success(paction, pplayer, act_utype, cplayer,
530 city_tile(pcity), city_link(pcity));
531
532 /* The actor unit always survive unless the action it self has determined
533 * to always consume it. */
534 if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
535 /* This unit isn't about to be consumed. Send updated unit information
536 * to the clients. */
537 send_unit_info(NULL, pdiplomat);
538 }
539
540 return TRUE;
541}
542
543/************************************************************************/
553bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat,
554 struct unit *pvictim,
555 const struct action *paction)
556{
557 char victim_link[MAX_LEN_LINK];
558 struct player *uplayer;
559 const struct unit_type *act_utype;
560
561 /* Fetch target unit's player. Sanity checks. */
562 fc_assert_ret_val(pvictim, FALSE);
563 uplayer = unit_owner(pvictim);
564 fc_assert_ret_val(uplayer, FALSE);
565
566 /* Sanity check: The actor still exists. */
567 fc_assert_ret_val(pplayer, FALSE);
568 fc_assert_ret_val(pdiplomat, FALSE);
569
570 act_utype = unit_type_get(pdiplomat);
571
572 log_debug("sabotage-unit: unit: %d", pdiplomat->id);
573
574 /* N.B: unit_link() always returns the same pointer. */
575 sz_strlcpy(victim_link, unit_link(pvictim));
576
577 /* Diplomatic battle against any diplomatic defender except the intended
578 * victim of the sabotage. */
579 if (!diplomat_infiltrate_tile(pplayer, uplayer,
580 paction,
581 pdiplomat, pvictim,
582 unit_tile(pvictim),
583 NULL)) {
584 return FALSE;
585 }
586
587 log_debug("sabotage-unit: succeeded");
588
589 if (pvictim->hp < 2) {
590 /* Not possible to halve the hit points. Kill it. */
591 wipe_unit(pvictim, ULR_KILLED, pplayer);
592
593 /* Notify everybody involved. */
594 notify_player(pplayer, unit_tile(pvictim),
595 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
596 _("Your %s's successful sabotage killed the %s %s."),
597 unit_link(pdiplomat),
599 victim_link);
600 notify_player(uplayer, unit_tile(pvictim),
601 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
602 /* TRANS: ... the Poles! */
603 _("Your %s was killed by %s sabotage!"),
604 victim_link,
605 nation_plural_for_player(pplayer));
606 } else {
607 /* Sabotage the unit by removing half its remaining hit points. */
608 pvictim->hp /= 2;
609 send_unit_info(NULL, pvictim);
610
611 /* Notify everybody involved. */
612 notify_player(pplayer, unit_tile(pvictim),
613 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
614 _("Your %s succeeded in sabotaging the %s %s."),
615 unit_link(pdiplomat),
617 victim_link);
618 notify_player(uplayer, unit_tile(pvictim),
619 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
620 /* TRANS: ... the Poles! */
621 _("Your %s was sabotaged by the %s!"),
622 victim_link,
623 nation_plural_for_player(pplayer));
624 }
625
626 /* this may cause a diplomatic incident */
627 action_consequence_success(paction, pplayer, act_utype, uplayer,
628 unit_tile(pvictim), victim_link);
629
630 /* Now lets see if the spy survives. */
631 diplomat_escape(pplayer, pdiplomat, NULL, paction);
632
633 return TRUE;
634}
635
636/************************************************************************/
648bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat,
649 struct unit *pvictim, const struct action *paction)
650{
651 char victim_link[MAX_LEN_LINK];
652 struct player *uplayer;
653 struct tile *victim_tile;
654 int bribe_cost;
655 int diplomat_id;
656 const struct unit_type *act_utype, *victim_type;
657 struct city *pcity;
658 bool bounce;
659
660 /* Fetch target unit's player. Sanity checks. */
661 fc_assert_ret_val(pvictim, FALSE);
662 uplayer = unit_owner(pvictim);
663 victim_type = unit_type_get(pvictim);
664 fc_assert_ret_val(uplayer, FALSE);
665
666 /* Sanity check: The actor still exists. */
667 fc_assert_ret_val(pplayer, FALSE);
668 fc_assert_ret_val(pdiplomat, FALSE);
669 diplomat_id = pdiplomat->id;
670
671 act_utype = unit_type_get(pdiplomat);
672
673 /* Sanity check: The target is foreign. */
674 if (uplayer == pplayer) {
675 /* Nothing to do to a domestic target. */
676 return FALSE;
677 }
678
679 /* Sanity check: The victim isn't a unique unit the actor player already
680 * has. */
682 unit_type_get(pvictim)),
683 FALSE,
684 "bribe-unit: already got unique unit");
685
686 log_debug("bribe-unit: unit: %d", pdiplomat->id);
687
688 /* Get bribe cost, ignoring any previously saved value. */
689 bribe_cost = unit_bribe_cost(pvictim, pplayer);
690
691 /* If player doesn't have enough gold, can't bribe. */
692 if (pplayer->economic.gold < bribe_cost) {
693 notify_player(pplayer, unit_tile(pdiplomat),
694 E_MY_DIPLOMAT_FAILED, ftc_server,
695 _("You don't have enough gold to bribe the %s %s."),
697 unit_link(pvictim));
698 log_debug("bribe-unit: not enough gold");
699 return FALSE;
700 }
701
702 log_debug("bribe-unit: enough gold");
703
704 /* Diplomatic battle against any diplomatic defender except the one that
705 * will get the bribe. */
706 if (!diplomat_infiltrate_tile(pplayer, uplayer,
707 paction,
708 pdiplomat, pvictim,
709 pvictim->tile,
710 NULL)) {
711 return FALSE;
712 }
713
714 log_debug("bribe-unit: succeeded");
715
716 victim_tile = unit_tile(pvictim);
717 pvictim = unit_change_owner(pvictim, pplayer, pdiplomat->homecity,
718 ULR_BRIBED);
719
720 if (pvictim) {
721 /* N.B.: unit_link always returns the same pointer. As unit_change_owner()
722 * currently remove the old unit and replace by a new one (with a new id),
723 * we want to make link to the new unit. */
724 sz_strlcpy(victim_link, unit_link(pvictim));
725 } else {
726 sz_strlcpy(victim_link, utype_name_translation(victim_type));
727 }
728
729 if (!unit_is_alive(diplomat_id)) {
730 /* Destroyed by a script */
731 pdiplomat = NULL;
732 }
733
734 /* Notify everybody involved. */
735 notify_player(pplayer, victim_tile, E_MY_DIPLOMAT_BRIBE, ftc_server,
736 /* TRANS: <diplomat> ... <unit> */
737 _("Your %s succeeded in bribing the %s."),
738 pdiplomat ? unit_link(pdiplomat)
739 : utype_name_translation(act_utype), victim_link);
740 if (pdiplomat && maybe_make_veteran(pdiplomat, 100)) {
741 notify_unit_experience(pdiplomat);
742 }
743 notify_player(uplayer, victim_tile, E_ENEMY_DIPLOMAT_BRIBE, ftc_server,
744 /* TRANS: <unit> ... <Poles> */
745 _("Your %s was bribed by the %s."),
746 victim_link, nation_plural_for_player(pplayer));
747
748 if (pvictim) {
749 /* The unit may have been on a tile shared with a city or a unit
750 * it no longer can share a tile with. */
751 pcity = tile_city(unit_tile(pvictim));
752 bounce = ((NULL != pcity
753 && !pplayers_allied(city_owner(pcity), unit_owner(pvictim)))
754 /* Keep the old behavior (insto check is_non_allied_unit_tile) */
755 || 1 < unit_list_size(unit_tile(pvictim)->units));
756 if (bounce) {
757 bounce_unit(pvictim, TRUE);
758 }
759 } else {
760 bounce = FALSE;
761 }
762
763 /* This costs! */
764 pplayer->economic.gold -= bribe_cost;
765 if (pplayer->economic.gold < 0) {
766 /* Scripts have deprived us of too much gold before we paid */
767 log_normal("%s has bribed %s but has not %d gold at payment time, "
768 "%d is the discount", player_name(pplayer),
769 utype_rule_name(victim_type), bribe_cost,
770 -pplayer->economic.gold);
771 pplayer->economic.gold = 0;
772 }
773
774 /* This may cause a diplomatic incident */
775 action_consequence_success(paction, pplayer, act_utype, uplayer,
776 victim_tile, victim_link);
777
778 if (!pdiplomat || !unit_is_alive(diplomat_id)) {
779 return TRUE;
780 }
781
782 /* Try to move the briber onto the victim's square unless the victim has
783 * been bounced because it couldn't share tile with a unit or city. */
784 if (!bounce
785 /* Try to perform post move forced actions. */
786 && (NULL == action_auto_perf_unit_do(AAPC_POST_ACTION, pdiplomat,
787 uplayer, NULL, paction,
788 victim_tile, tile_city(victim_tile),
789 pvictim, NULL))
790 /* May have died while trying to do forced actions. */
791 && unit_is_alive(diplomat_id)) {
792 pdiplomat->moves_left = 0;
793 }
794 if (NULL != player_unit_by_number(pplayer, diplomat_id)) {
795 send_unit_info(NULL, pdiplomat);
796 }
797
798 /* Update clients. */
799 send_player_all_c(pplayer, NULL);
800
801 return TRUE;
802}
803
804/************************************************************************/
812bool spy_attack(struct player *act_player, struct unit *act_unit,
813 struct tile *tgt_tile, const struct action *paction)
814{
815 int act_unit_id;
816 struct player *tgt_player = NULL;
817 const struct unit_type *act_utype;
818
819 /* Sanity check: The actor still exists. */
820 fc_assert_ret_val(act_player, FALSE);
821 fc_assert_ret_val(act_unit, FALSE);
822
823 act_utype = unit_type_get(act_unit);
824 act_unit_id = act_unit->id;
825
826 /* Do the diplomatic battle against a diplomatic defender. */
827 diplomat_infiltrate_tile(act_player, NULL,
828 paction,
829 act_unit, NULL, tgt_tile,
830 &tgt_player);
831
832 /* Sanity check: the defender had an owner. */
833 fc_assert_ret_val(tgt_player != NULL, TRUE);
834
835 if (!unit_is_alive(act_unit_id)) {
836 /* action_consequence_caught() is handled in
837 * diplomat_infiltrate_tile() */
838
839 /* The action was to start a diplomatic battle. */
840 return TRUE;
841 }
842
843 /* This may cause a diplomatic incident. */
844 action_consequence_success(paction, act_player, act_utype,
845 tgt_player, tgt_tile, tile_link(tgt_tile));
846
847 /* The action was to start a diplomatic battle. */
848 return TRUE;
849}
850
851/************************************************************************/
856 struct city *pcity)
857{
858 int times;
859 int bonus = get_unit_bonus(pdiplomat, EFT_STEALINGS_IGNORE);
860
861 if (bonus < 0) {
862 /* Negative effect value means infinite bonus */
863 times = 0;
864 } else {
865 times = pcity->steal - bonus;
866 if (times < 0) {
867 times = 0;
868 }
869 }
870
871 return times;
872}
873
874/************************************************************************/
896bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat,
897 struct city *pcity, Tech_type_id technology,
898 const struct action *paction)
899{
900 struct research *presearch, *cresearch;
901 struct player *cplayer;
902 const struct unit_type *act_utype;
903 int count;
904 int times;
905 Tech_type_id tech_stolen;
906 bool expected_kills;
907
908 /* We have to check arguments. They are sent to us by a client,
909 so we cannot trust them */
910 fc_assert_ret_val(pcity, FALSE);
911 cplayer = city_owner(pcity);
912 fc_assert_ret_val(cplayer, FALSE);
913
914 /* Sanity check: The actor still exists. */
915 fc_assert_ret_val(pplayer, FALSE);
916 fc_assert_ret_val(pdiplomat, FALSE);
917
918 act_utype = unit_type_get(pdiplomat);
919
920 /* Sanity check: The target is foreign. */
921 if (cplayer == pplayer) {
922 /* Nothing to do to a domestic target. */
923 return FALSE;
924 }
925
926 /* Currently based on if unit is consumed or not. */
927 expected_kills = utype_is_consumed_by_action(paction,
928 unit_type_get(pdiplomat));
929
930 if (action_has_result(paction, ACTRES_SPY_STEAL_TECH)) {
931 /* Can't choose target. Will steal a random tech. */
932 technology = A_UNSET;
933 }
934
935 /* Targeted technology should be a ruleset defined tech,
936 * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
937 if (technology == A_NONE
938 || (technology != A_FUTURE
939 && !(technology == A_UNSET
940 && action_has_result(paction, ACTRES_SPY_STEAL_TECH))
941 && !valid_advance_by_number(technology))) {
942 return FALSE;
943 }
944
945 presearch = research_get(pplayer);
946 cresearch = research_get(cplayer);
947
948 if (technology == A_FUTURE) {
949 if (presearch->future_tech >= cresearch->future_tech) {
950 return FALSE;
951 }
952 } else if (technology != A_UNSET) {
953 if (research_invention_state(presearch, technology) == TECH_KNOWN) {
954 return FALSE;
955 }
956 if (research_invention_state(cresearch, technology) != TECH_KNOWN) {
957 return FALSE;
958 }
959 if (!research_invention_gettable(presearch, technology,
961 return FALSE;
962 }
963 }
964
965 log_debug("steal-tech: unit: %d", pdiplomat->id);
966
967 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
968 if (!diplomat_infiltrate_tile(pplayer, cplayer,
969 paction,
970 pdiplomat, NULL,
971 pcity->tile,
972 NULL)) {
973 return FALSE;
974 }
975
976 log_debug("steal-tech: infiltrated");
977
978 times = diplomats_unignored_tech_stealings(pdiplomat, pcity);
979
980 /* Check if the Diplomat/Spy succeeds with their task. */
981 /* (Twice as difficult if target is specified.) */
982 /* (If already stolen from, impossible for Diplomats and harder for Spies.) */
983 if (times > 0 && expected_kills) {
984 /* Already stolen from: Diplomat always fails! */
985 count = 1;
986 log_debug("steal-tech: difficulty: impossible");
987 } else {
988 /* Determine difficulty. */
989 count = 1;
990 if (action_has_result(paction, ACTRES_SPY_TARGETED_STEAL_TECH)) {
991 /* Targeted steal tech is more difficult. */
992 count++;
993 }
994 count += times;
995 log_debug("steal-tech: difficulty: %d", count);
996 /* Determine success or failure. */
997 while (count > 0) {
998 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
999 paction)) {
1000 break;
1001 }
1002 count--;
1003 }
1004 }
1005
1006 if (count > 0) {
1007 /* Failed to steal a tech. */
1008 if (times > 0 && expected_kills) {
1009 notify_player(pplayer, city_tile(pcity),
1010 E_MY_DIPLOMAT_FAILED, ftc_server,
1011 /* TRANS: Paris was expecting ... Your Spy was caught */
1012 _("%s was expecting your attempt to steal technology "
1013 "again. Your %s was caught and executed."),
1014 city_link(pcity),
1015 unit_tile_link(pdiplomat));
1016 notify_player(cplayer, city_tile(pcity),
1017 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1018 /* TRANS: The Belgian Spy ... from Paris */
1019 _("The %s %s failed to steal technology again from %s. "
1020 "We were prepared for the attempt."),
1022 unit_tile_link(pdiplomat),
1023 city_link(pcity));
1024 } else {
1025 notify_player(pplayer, city_tile(pcity),
1026 E_MY_DIPLOMAT_FAILED, ftc_server,
1027 /* TRANS: Your Spy was caught ... from %s. */
1028 _("Your %s was caught in the attempt of"
1029 " stealing technology from %s."),
1030 unit_tile_link(pdiplomat),
1031 city_link(pcity));
1032 notify_player(cplayer, city_tile(pcity),
1033 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1034 /* TRANS: The Belgian Spy ... from Paris */
1035 _("The %s %s failed to steal technology from %s."),
1037 unit_tile_link(pdiplomat),
1038 city_link(pcity));
1039 }
1040
1041 /* This may cause a diplomatic incident */
1042 action_consequence_caught(paction, pplayer, act_utype, cplayer,
1043 city_tile(pcity), city_link(pcity));
1044 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1045 return FALSE;
1046 }
1047
1048 tech_stolen = steal_a_tech(pplayer, cplayer, technology);
1049
1050 if (tech_stolen == A_NONE) {
1051 notify_player(pplayer, city_tile(pcity),
1052 E_MY_DIPLOMAT_FAILED, ftc_server,
1053 _("No new technology found in %s."),
1054 city_link(pcity));
1055 diplomat_charge_movement (pdiplomat, pcity->tile);
1056 send_unit_info(NULL, pdiplomat);
1057 return FALSE;
1058 }
1059
1060 /* Update stealing player's science progress and research fields */
1061 send_player_all_c(pplayer, NULL);
1062
1063 /* Record the theft. */
1064 (pcity->steal)++;
1065
1066 /* this may cause a diplomatic incident */
1067 action_consequence_success(paction, pplayer, act_utype, cplayer,
1068 city_tile(pcity), city_link(pcity));
1069
1070 /* Check if a spy survives her mission. */
1071 diplomat_escape(pplayer, pdiplomat, pcity, paction);
1072
1073 return TRUE;
1074}
1075
1076/************************************************************************/
1086bool diplomat_may_lose_gold(struct player *dec_player, struct player *inc_player,
1087 int revolt_gold)
1088{
1090 return FALSE;
1091 }
1092
1093 /* Roll the dice. */
1095 notify_player(dec_player, NULL, E_MY_DIPLOMAT_FAILED, ftc_server,
1096 PL_("Your %d gold prepared to incite the revolt was lost!",
1097 "Your %d gold prepared to incite the revolt was lost!",
1098 revolt_gold), revolt_gold);
1099 dec_player->economic.gold -= revolt_gold;
1100 /* Lost money was pocketed by fraudulent executioners?
1101 * Or returned to local authority?
1102 * Roll the dice twice. */
1104 inc_player->economic.gold += revolt_gold;
1105 notify_player(inc_player, NULL, E_ENEMY_DIPLOMAT_FAILED,
1106 ftc_server,
1107 PL_("Your security service captured %d gold prepared "
1108 "to incite your town!",
1109 "Your security service captured %d gold prepared "
1110 "to incite your town!", revolt_gold), revolt_gold);
1111 }
1112 /* Update clients. */
1113 send_player_all_c(dec_player, NULL);
1114 send_player_all_c(inc_player, NULL);
1115
1116 return TRUE;
1117 } else {
1118 return FALSE;
1119 }
1120}
1121
1122/************************************************************************/
1140bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat,
1141 struct city *pcity, const struct action *paction)
1142{
1143 struct player *cplayer;
1144 struct tile *ctile;
1145 const char *clink;
1146 int revolt_cost;
1147 const struct unit_type *act_utype;
1148
1149 /* Fetch target civilization's player. Sanity checks. */
1150 fc_assert_ret_val(pcity, FALSE);
1151 cplayer = city_owner(pcity);
1152 fc_assert_ret_val(cplayer, FALSE);
1153
1154 /* Sanity check: The actor still exists. */
1155 fc_assert_ret_val(pplayer, FALSE);
1156 fc_assert_ret_val(pdiplomat, FALSE);
1157
1158 /* Sanity check: The target is foreign. */
1159 if (cplayer == pplayer) {
1160 /* Nothing to do to a domestic target. */
1161 return FALSE;
1162 }
1163
1164 act_utype = unit_type_get(pdiplomat);
1165
1166 ctile = city_tile(pcity);
1167 clink = city_link(pcity);
1168
1169 log_debug("incite: unit: %d", pdiplomat->id);
1170
1171 /* Get incite cost, ignoring any previously saved value. */
1172 revolt_cost = city_incite_cost(pplayer, pcity);
1173
1174 /* If player doesn't have enough gold, can't incite a revolt. */
1175 if (pplayer->economic.gold < revolt_cost) {
1176 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
1177 _("You don't have enough gold to subvert %s."),
1178 clink);
1179 log_debug("incite: not enough gold");
1180 return FALSE;
1181 }
1182
1183 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1184 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1185 paction,
1186 pdiplomat, NULL,
1187 pcity->tile,
1188 NULL)) {
1189 diplomat_may_lose_gold(pplayer, cplayer, revolt_cost / 2 );
1190 return FALSE;
1191 }
1192
1193 log_debug("incite: infiltrated");
1194
1195 /* Check if the Diplomat/Spy succeeds with their task. */
1196 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
1197 paction)) {
1198 notify_player(pplayer, ctile, E_MY_DIPLOMAT_FAILED, ftc_server,
1199 _("Your %s was caught in the attempt"
1200 " of inciting a revolt!"),
1201 unit_tile_link(pdiplomat));
1202 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1203 _("You caught %s %s attempting"
1204 " to incite a revolt in %s!"),
1206 unit_tile_link(pdiplomat),
1207 clink);
1208
1209 diplomat_may_lose_gold(pplayer, cplayer, revolt_cost / 4);
1210
1211 /* This may cause a diplomatic incident */
1212 action_consequence_caught(paction, pplayer, act_utype,
1213 cplayer, ctile, clink);
1214
1215 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1216 return FALSE;
1217 }
1218
1219 log_debug("incite: succeeded");
1220
1221 /* Subvert the city to your cause... */
1222
1223 /* City loses some population. */
1224 if (city_size_get(pcity) > 1) {
1225 city_reduce_size(pcity, 1, pplayer, "incited");
1226 }
1227
1228 /* This costs! */
1229 pplayer->economic.gold -= revolt_cost;
1230
1231 /* Notify everybody involved. */
1232 notify_player(pplayer, ctile, E_MY_DIPLOMAT_INCITE, ftc_server,
1233 _("Revolt incited in %s, you now rule the city!"),
1234 clink);
1235 notify_player(cplayer, ctile, E_ENEMY_DIPLOMAT_INCITE, ftc_server,
1236 _("%s has revolted, %s influence suspected."),
1237 clink,
1239
1240 pcity->shield_stock = 0;
1242
1243 /* You get a technology advance, too! */
1244 steal_a_tech(pplayer, cplayer, A_UNSET);
1245
1246 /* this may cause a diplomatic incident */
1247 action_consequence_success(paction, pplayer, act_utype,
1248 cplayer, ctile, clink);
1249
1250 /* Transfer city and units supported by this city (that
1251 are within one square of the city) to the new owner. */
1252 if (transfer_city(pplayer, pcity, 1, TRUE, TRUE, FALSE,
1253 !is_barbarian(pplayer))) {
1254 script_server_signal_emit("city_transferred", pcity, cplayer, pplayer,
1255 "incited");
1256 }
1257
1258 /* Check if a spy survives her mission.
1259 * _After_ transferring the city, or the city area is first fogged
1260 * when the diplomat is removed, and then unfogged when the city
1261 * is transferred. */
1262 diplomat_escape_full(pplayer, pdiplomat, TRUE, ctile, clink, paction);
1263
1264 /* Update the players gold in the client */
1265 send_player_info_c(pplayer, pplayer->connections);
1266
1267 return TRUE;
1268}
1269
1270/************************************************************************/
1289bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat,
1290 struct city *pcity, Impr_type_id improvement,
1291 const struct action *paction)
1292{
1293 struct player *cplayer;
1294 struct impr_type *ptarget;
1295 int count, which;
1296 const struct unit_type *act_utype;
1297
1298 /* Fetch target city's player. Sanity checks. */
1299 fc_assert_ret_val(pcity, FALSE);
1300 cplayer = city_owner(pcity);
1301 fc_assert_ret_val(cplayer, FALSE);
1302
1303 /* Sanity check: The actor still exists. */
1304 fc_assert_ret_val(pplayer, FALSE);
1305 fc_assert_ret_val(pdiplomat, FALSE);
1306
1307 act_utype = unit_type_get(pdiplomat);
1308
1309 log_debug("sabotage: unit: %d", pdiplomat->id);
1310
1311 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
1312 if (!diplomat_infiltrate_tile(pplayer, cplayer,
1313 paction,
1314 pdiplomat, NULL,
1315 pcity->tile,
1316 NULL)) {
1317 return FALSE;
1318 }
1319
1320 log_debug("sabotage: infiltrated");
1321
1322 /* Check if the Diplomat/Spy succeeds with their task. */
1323 if (action_failed_dice_roll(pplayer, pdiplomat, pcity, cplayer,
1324 paction)) {
1325 notify_player(pplayer, city_tile(pcity),
1326 E_MY_DIPLOMAT_FAILED, ftc_server,
1327 _("Your %s was caught in the attempt"
1328 " of industrial sabotage!"),
1329 unit_tile_link(pdiplomat));
1330 notify_player(cplayer, city_tile(pcity),
1331 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1332 _("You caught %s %s attempting sabotage in %s!"),
1334 unit_tile_link(pdiplomat),
1335 city_link(pcity));
1336
1337 /* This may cause a diplomatic incident */
1338 action_consequence_caught(paction, pplayer, act_utype, cplayer,
1339 city_tile(pcity), city_link(pcity));
1340
1341 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1342 return FALSE;
1343 }
1344
1345 log_debug("sabotage: succeeded");
1346
1347 /* Examine the city for improvements to sabotage. */
1348 count = 0;
1349 city_built_iterate(pcity, pimprove) {
1350 if (pimprove->sabotage > 0) {
1351 count++;
1352 }
1354
1355 log_debug("sabotage: count of improvements: %d", count);
1356
1357 /* Determine the target (-1 is production). */
1358 if (action_has_result(paction, ACTRES_SPY_SABOTAGE_CITY)) {
1359 /*
1360 * Pick random:
1361 * 50/50 chance to pick production or some improvement.
1362 * Won't pick something that doesn't exit.
1363 * If nothing to do, say so, deduct movement cost and return.
1364 */
1365 if (count == 0 && pcity->shield_stock == 0) {
1366 notify_player(pplayer, city_tile(pcity),
1367 E_MY_DIPLOMAT_FAILED, ftc_server,
1368 _("Your %s could not find anything to sabotage in %s."),
1369 unit_link(pdiplomat),
1370 city_link(pcity));
1371 diplomat_charge_movement(pdiplomat, pcity->tile);
1372 send_unit_info(NULL, pdiplomat);
1373 log_debug("sabotage: random: nothing to do");
1374 return FALSE;
1375 }
1376 if (count == 0 || fc_rand (2) == 1) {
1377 ptarget = NULL;
1378 log_debug("sabotage: random: targeted production");
1379 } else {
1380 ptarget = NULL;
1381 which = fc_rand (count);
1382
1383 city_built_iterate(pcity, pimprove) {
1384 if (pimprove->sabotage > 0) {
1385 if (which > 0) {
1386 which--;
1387 } else {
1388 ptarget = pimprove;
1389 break;
1390 }
1391 }
1393
1394 if (NULL != ptarget) {
1395 log_debug("sabotage: random: targeted improvement: %d (%s)",
1396 improvement_number(ptarget),
1397 improvement_rule_name(ptarget));
1398 } else {
1399 log_error("sabotage: random: targeted improvement error!");
1400 }
1401 }
1402 } else if (improvement < 0) {
1403 /* If told to sabotage production, do so. */
1404 ptarget = NULL;
1405 log_debug("sabotage: specified target production");
1406 } else {
1407 struct impr_type *pimprove = improvement_by_number(improvement);
1408 if (pimprove == NULL) {
1409 log_error("sabotage: requested for invalid improvement %d", improvement);
1410 return FALSE;
1411 }
1412 /*
1413 * Told which improvement to pick:
1414 * If try for wonder or palace, complain, deduct movement cost and return.
1415 * If not available, say so, deduct movement cost and return.
1416 */
1417 if (city_has_building(pcity, pimprove)) {
1418 if (pimprove->sabotage > 0) {
1419 ptarget = pimprove;
1420 log_debug("sabotage: specified target improvement: %d (%s)",
1421 improvement, improvement_rule_name(pimprove));
1422 } else {
1423 notify_player(pplayer, city_tile(pcity),
1424 E_MY_DIPLOMAT_FAILED, ftc_server,
1425 _("You cannot sabotage a %s!"),
1427 diplomat_charge_movement(pdiplomat, pcity->tile);
1428 send_unit_info(NULL, pdiplomat);
1429 log_debug("sabotage: disallowed target improvement: %d (%s)",
1430 improvement, improvement_rule_name(pimprove));
1431 return FALSE;
1432 }
1433 } else {
1434 notify_player(pplayer, city_tile(pcity),
1435 E_MY_DIPLOMAT_FAILED, ftc_server,
1436 _("Your %s could not find the %s to sabotage in %s."),
1437 unit_name_translation(pdiplomat),
1439 city_link(pcity));
1440 diplomat_charge_movement(pdiplomat, pcity->tile);
1441 send_unit_info(NULL, pdiplomat);
1442 log_debug("sabotage: target improvement not found: %d (%s)",
1443 improvement, improvement_rule_name(pimprove));
1444 return FALSE;
1445 }
1446 }
1447
1448 /* Now, the fun stuff! Do the sabotage! */
1449 if (NULL == ptarget) {
1450 char prod[256];
1451
1452 /* Do it. */
1453 pcity->shield_stock = 0;
1454 nullify_prechange_production(pcity); /* Make it impossible to recover */
1455
1456 /* Report it. */
1457 universal_name_translation(&pcity->production, prod, sizeof(prod));
1458
1459 notify_player(pplayer, city_tile(pcity),
1460 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
1461 _("Your %s succeeded in destroying"
1462 " the production of %s in %s."),
1463 unit_link(pdiplomat),
1464 prod,
1465 city_name_get(pcity));
1466 notify_player(cplayer, city_tile(pcity),
1467 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1468 _("The production of %s was destroyed in %s,"
1469 " %s are suspected."),
1470 prod,
1471 city_link(pcity),
1472 nation_plural_for_player(pplayer));
1473 log_debug("sabotage: sabotaged production");
1474 } else {
1475 int vulnerability = ptarget->sabotage;
1476
1477 /* Sabotage a city improvement. */
1478
1479 /*
1480 * One last chance to get caught:
1481 * If target was specified, and it is in the capital or are
1482 * City Walls, then there is a 50% chance of getting caught.
1483 */
1484 vulnerability -= (vulnerability
1485 * get_city_bonus(pcity, EFT_SABOTEUR_RESISTANT)
1486 / 100);
1487
1488 if (fc_rand(100) >= vulnerability) {
1489 /* Caught! */
1490 notify_player(pplayer, city_tile(pcity),
1491 E_MY_DIPLOMAT_FAILED, ftc_server,
1492 _("Your %s was caught in the attempt of sabotage!"),
1493 unit_tile_link(pdiplomat));
1494 notify_player(cplayer, city_tile(pcity),
1495 E_ENEMY_DIPLOMAT_FAILED, ftc_server,
1496 _("You caught %s %s attempting"
1497 " to sabotage the %s in %s!"),
1499 unit_tile_link(pdiplomat),
1501 city_link(pcity));
1502
1503 /* This may cause a diplomatic incident */
1504 action_consequence_caught(paction, pplayer, act_utype, cplayer,
1505 city_tile(pcity), city_link(pcity));
1506
1507 wipe_unit(pdiplomat, ULR_CAUGHT, cplayer);
1508 log_debug("sabotage: caught in capital or on city walls");
1509 return FALSE;
1510 }
1511
1512 /* Report it. */
1513 notify_player(pplayer, city_tile(pcity),
1514 E_MY_DIPLOMAT_SABOTAGE, ftc_server,
1515 _("Your %s destroyed the %s in %s."),
1516 unit_link(pdiplomat),
1518 city_link(pcity));
1519 notify_player(cplayer, city_tile(pcity),
1520 E_ENEMY_DIPLOMAT_SABOTAGE, ftc_server,
1521 _("The %s destroyed the %s in %s."),
1522 nation_plural_for_player(pplayer),
1524 city_link(pcity));
1525 log_debug("sabotage: sabotaged improvement: %d (%s)",
1526 improvement_number(ptarget),
1527 improvement_rule_name(ptarget));
1528
1529 /* Do it. */
1530 building_lost(pcity, ptarget, "sabotaged", pdiplomat);
1531
1532 /* FIXME: Lua script might have destroyed the diplomat, the city, or even the player.
1533 * Avoid dangling pointers below in that case. */
1534 }
1535
1536 /* Update clients. */
1537 send_city_info(NULL, pcity);
1538
1539 /* this may cause a diplomatic incident */
1540 action_consequence_success(paction, pplayer, act_utype, cplayer,
1541 city_tile(pcity), city_link(pcity));
1542
1543 /* Check if a spy survives her mission. */
1544 diplomat_escape(pplayer, pdiplomat, pcity, paction);
1545
1546 return TRUE;
1547}
1548
1549/************************************************************************/
1561bool spy_steal_gold(struct player *act_player, struct unit *act_unit,
1562 struct city *tgt_city, const struct action *paction)
1563{
1564 struct player *tgt_player;
1565 struct tile *tgt_tile;
1566
1567 const char *tgt_city_link;
1568
1569 int gold_take;
1570 int gold_give;
1571 const struct unit_type *act_utype;
1572
1573 /* Sanity check: The actor still exists. */
1574 fc_assert_ret_val(act_player, FALSE);
1575 fc_assert_ret_val(act_unit, FALSE);
1576
1577 act_utype = unit_type_get(act_unit);
1578
1579 /* Sanity check: The target city still exists. */
1580 fc_assert_ret_val(tgt_city, FALSE);
1581
1582 /* Who to steal from. */
1583 tgt_player = city_owner(tgt_city);
1584
1585 /* Sanity check: The target player still exists. */
1586 fc_assert_ret_val(tgt_player, FALSE);
1587
1588 /* Sanity check: The target is foreign. */
1589 if (tgt_player == act_player) {
1590 /* Nothing to do to a domestic target. */
1591 return FALSE;
1592 }
1593
1594 /* Sanity check: There is something to steal. */
1595 if (tgt_player->economic.gold <= 0) {
1596 return FALSE;
1597 }
1598
1599 tgt_tile = city_tile(tgt_city);
1600 tgt_city_link = city_link(tgt_city);
1601
1602 log_debug("steal gold: unit: %d", act_unit->id);
1603
1604 /* Battle all units capable of diplomatic defense. */
1605 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1606 paction,
1607 act_unit, NULL, tgt_tile,
1608 NULL)) {
1609 return FALSE;
1610 }
1611
1612 log_debug("steal gold: infiltrated");
1613
1614 /* The thief may get caught while trying to steal the gold. */
1615 if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
1616 paction)) {
1617 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1618 _("Your %s was caught attempting to steal gold!"),
1619 unit_tile_link(act_unit));
1620 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1621 ftc_server,
1622 /* TRANS: nation, unit, city */
1623 _("You caught %s %s attempting"
1624 " to steal your gold in %s!"),
1625 nation_adjective_for_player(act_player),
1626 unit_tile_link(act_unit),
1627 tgt_city_link);
1628
1629 /* This may cause a diplomatic incident */
1630 action_consequence_caught(paction, act_player, act_utype,
1631 tgt_player, tgt_tile, tgt_city_link);
1632
1633 /* Execute the caught thief. */
1634 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1635
1636 return FALSE;
1637 }
1638
1639 log_debug("steal gold: succeeded");
1640
1641 /* The upper limit on how much gold the thief can steal. */
1642 gold_take = (tgt_player->economic.gold
1643 * get_city_bonus(tgt_city, EFT_MAX_STOLEN_GOLD_PM))
1644 / 1000;
1645
1646 /* How much to actually take. 1 gold is the smallest amount that can be
1647 * stolen. The victim player has at least 1 gold. If they didn't, the
1648 * something to steal sanity check would have aborted the theft. */
1649 gold_take = fc_rand(gold_take) + 1;
1650
1651 log_debug("steal gold: will take %d gold", gold_take);
1652
1653 /* Steal the gold. */
1654 tgt_player->economic.gold -= gold_take;
1655
1656 /* Some gold may be lost during transfer. */
1657 gold_give = gold_take
1658 - (gold_take * get_unit_bonus(act_unit, EFT_THIEFS_SHARE_PM))
1659 / 1000;
1660
1661 log_debug("steal gold: will give %d gold", gold_give);
1662
1663 /* Pocket the stolen money. */
1664 act_player->economic.gold += gold_give;
1665
1666 /* Notify everyone involved. */
1667 notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_GOLD, ftc_server,
1668 /* TRANS: unit, gold, city */
1669 PL_("Your %s stole %d gold from %s.",
1670 "Your %s stole %d gold from %s.", gold_give),
1671 unit_link(act_unit), gold_give, tgt_city_link);
1672 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_GOLD, ftc_server,
1673 /* TRANS: gold, city, nation */
1674 PL_("%d gold stolen from %s, %s suspected.",
1675 "%d gold stolen from %s, %s suspected.", gold_take),
1676 gold_take, tgt_city_link,
1677 nation_plural_for_player(act_player));
1678
1679 /* This may cause a diplomatic incident. */
1680 action_consequence_success(paction, act_player, act_utype,
1681 tgt_player, tgt_tile, tgt_city_link);
1682
1683 /* Try to escape. */
1684 diplomat_escape_full(act_player, act_unit, TRUE,
1685 tgt_tile, tgt_city_link, paction);
1686
1687 /* Update the players' gold in the client */
1688 send_player_info_c(act_player, act_player->connections);
1689 send_player_info_c(tgt_player, tgt_player->connections);
1690
1691 return TRUE;
1692}
1693
1694/************************************************************************/
1703bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit,
1704 struct city *tgt_city,
1705 const struct action *paction)
1706{
1707 struct player *tgt_player;
1708 struct tile *tgt_tile;
1709 const struct unit_type *act_utype;
1710
1711 int normal_tile_prob;
1712
1713 const char *tgt_city_link;
1714
1715 /* Sanity check: The actor still exists. */
1716 fc_assert_ret_val(act_player, FALSE);
1717 fc_assert_ret_val(act_unit, FALSE);
1718
1719 act_utype = unit_type_get(act_unit);
1720
1721 /* Sanity check: The target city still exists. */
1722 fc_assert_ret_val(tgt_city, FALSE);
1723
1724 /* Who to steal from. */
1725 tgt_player = city_owner(tgt_city);
1726
1727 /* Sanity check: The target player still exists. */
1728 fc_assert_ret_val(tgt_player, FALSE);
1729
1730 /* Sanity check: The target is foreign. */
1731 if (tgt_player == act_player) {
1732 /* Nothing to do to a domestic target. */
1733 return FALSE;
1734 }
1735
1736 tgt_tile = city_tile(tgt_city);
1737 tgt_city_link = city_link(tgt_city);
1738
1739 log_debug("steal some maps: unit: %d", act_unit->id);
1740
1741 /* Battle all units capable of diplomatic defense. */
1742 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1743 paction,
1744 act_unit, NULL, tgt_tile,
1745 NULL)) {
1746 return FALSE;
1747 }
1748
1749 log_debug("steal some maps: infiltrated");
1750
1751 /* Try to steal the map. */
1752 if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
1753 paction)) {
1754 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1755 _("Your %s was caught in an attempt of"
1756 " stealing parts of the %s world map!"),
1757 unit_tile_link(act_unit),
1758 nation_adjective_for_player(tgt_player));
1759 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1760 ftc_server,
1761 _("You caught %s %s attempting to steal"
1762 " parts of your world map in %s!"),
1763 nation_adjective_for_player(act_player),
1764 unit_tile_link(act_unit),
1765 tgt_city_link);
1766
1767 /* This may cause a diplomatic incident. */
1768 action_consequence_caught(paction, act_player, act_utype,
1769 tgt_player, tgt_tile, tgt_city_link);
1770
1771 /* Execute the caught thief. */
1772 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1773
1774 return FALSE;
1775 }
1776
1777 log_debug("steal some maps: succeeded");
1778
1779 /* Steal it. */
1780 normal_tile_prob = 100
1782 &(const struct req_context) {
1783 .player = act_player,
1784 /* City: Decide once requests from ruleset
1785 * authors arrive. Could be target city or
1786 * - with a refactoring - the city at the
1787 * tile that may be transferred. */
1788 /* Tile: Decide once requests from ruleset
1789 * authors arrive. Could be actor unit
1790 * tile, target city tile or even - with a
1791 * refactoring - the tile that may be
1792 * transferred. */
1793 .unit = act_unit,
1794 .unittype = unit_type_get(act_unit),
1795 .action = paction,
1796 },
1797 tgt_player,
1798 EFT_MAPS_STOLEN_PCT);
1799 give_distorted_map(tgt_player, act_player,
1800 normal_tile_prob,
1801 /* Could - with a refactoring where EFT_MAPS_STOLEN_PCT
1802 * is evaulated for each tile and the city sent to it
1803 * is the tile to transfer's city - be moved into
1804 * EFT_MAPS_STOLEN_PCT. */
1806
1807 /* Notify everyone involved. */
1808 notify_player(act_player, tgt_tile, E_MY_SPY_STEAL_MAP, ftc_server,
1809 _("Your %s stole parts of the %s world map in %s."),
1810 unit_link(act_unit),
1811 nation_adjective_for_player(tgt_player),
1812 tgt_city_link);
1813 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_STEAL_MAP, ftc_server,
1814 _("The %s are suspected of stealing"
1815 " parts of your world map in %s."),
1816 nation_plural_for_player(act_player),
1817 tgt_city_link);
1818
1819 /* This may cause a diplomatic incident. */
1820 action_consequence_success(paction, act_player, act_utype,
1821 tgt_player, tgt_tile, tgt_city_link);
1822
1823 /* Try to escape. */
1824 diplomat_escape_full(act_player, act_unit, TRUE,
1825 tgt_tile, tgt_city_link, paction);
1826
1827 return TRUE;
1828}
1829
1830/************************************************************************/
1839bool spy_nuke_city(struct player *act_player, struct unit *act_unit,
1840 struct city *tgt_city, const struct action *paction)
1841{
1842 struct player *tgt_player;
1843 struct tile *tgt_tile;
1844
1845 const char *tgt_city_link;
1846 const struct unit_type *act_utype;
1847
1848 /* Sanity check: The actor still exists. */
1849 fc_assert_ret_val(act_player, FALSE);
1850 fc_assert_ret_val(act_unit, FALSE);
1851
1852 act_utype = unit_type_get(act_unit);
1853
1854 /* Sanity check: The target city still exists. */
1855 fc_assert_ret_val(tgt_city, FALSE);
1856
1857 /* The victim. */
1858 tgt_player = city_owner(tgt_city);
1859
1860 /* Sanity check: The target player still exists. */
1861 fc_assert_ret_val(tgt_player, FALSE);
1862
1863 tgt_tile = city_tile(tgt_city);
1864 tgt_city_link = city_link(tgt_city);
1865
1866 log_debug("suitcase nuke: unit: %d", act_unit->id);
1867
1868 /* Battle all units capable of diplomatic defense. */
1869 if (!diplomat_infiltrate_tile(act_player, tgt_player,
1870 paction,
1871 act_unit, NULL, tgt_tile,
1872 NULL)) {
1873 return FALSE;
1874 }
1875
1876 log_debug("suitcase nuke: infiltrated");
1877
1878 /* Try to hide the nuke. */
1879 if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
1880 paction)) {
1881 notify_player(act_player, tgt_tile, E_MY_DIPLOMAT_FAILED, ftc_server,
1882 _("Your %s was caught in an attempt of"
1883 " hiding a nuke in %s!"),
1884 unit_tile_link(act_unit),
1885 tgt_city_link);
1886 notify_player(tgt_player, tgt_tile, E_ENEMY_DIPLOMAT_FAILED,
1887 ftc_server,
1888 _("You caught %s %s attempting to hide a nuke in %s!"),
1889 nation_adjective_for_player(act_player),
1890 unit_tile_link(act_unit),
1891 tgt_city_link);
1892
1893 /* This may cause a diplomatic incident. */
1894 action_consequence_caught(paction, act_player, act_utype,
1895 tgt_player, tgt_tile, tgt_city_link);
1896
1897 /* Execute the caught terrorist. */
1898 wipe_unit(act_unit, ULR_CAUGHT, tgt_player);
1899
1900 return FALSE;
1901 }
1902
1903 log_debug("suitcase nuke: succeeded");
1904
1905 /* Notify everyone involved. */
1906 notify_player(act_player, tgt_tile, E_MY_SPY_NUKE, ftc_server,
1907 _("Your %s hid a nuke in %s."),
1908 unit_link(act_unit),
1909 tgt_city_link);
1910 notify_player(tgt_player, tgt_tile, E_ENEMY_SPY_NUKE, ftc_server,
1911 _("The %s are suspected of hiding a nuke in %s."),
1912 nation_plural_for_player(act_player),
1913 tgt_city_link);
1914
1915 /* Try to escape before the blast. */
1916 diplomat_escape_full(act_player, act_unit, TRUE,
1917 tgt_tile, tgt_city_link, paction);
1918
1919 if (utype_is_consumed_by_action(paction, unit_type_get(act_unit))) {
1920 /* The unit must be wiped here so it won't be seen as a victim of the
1921 * detonation of its own nuke. */
1922 wipe_unit(act_unit, ULR_USED, NULL);
1923 }
1924
1925 /* TODO: In real life a suitcase nuke is way less powerful than an ICBM.
1926 * Maybe the size of the suitcase nuke explosion should be ruleset
1927 * configurable? */
1928
1929 /* Detonate the nuke. */
1931 do_nuclear_explosion(act_player, tgt_tile);
1932
1933 /* This may cause a diplomatic incident. */
1934 action_consequence_success(paction, act_player, act_utype,
1935 tgt_player, tgt_tile, tgt_city_link);
1936
1937 return TRUE;
1938}
1939
1940/************************************************************************/
1943static void diplomat_charge_movement(struct unit *pdiplomat, struct tile *ptile)
1944{
1945 pdiplomat->moves_left -=
1946 map_move_cost_unit(&(wld.map), pdiplomat, ptile);
1947 if (pdiplomat->moves_left < 0) {
1948 pdiplomat->moves_left = 0;
1949 }
1950}
1951
1952/************************************************************************/
1959static bool diplomat_success_vs_defender(struct unit *pattacker,
1960 struct unit *pdefender,
1961 struct tile *pdefender_tile,
1962 int *att_vet, int *def_vet)
1963{
1964 int chance = 50; /* Base 50% chance */
1965
1966 /* There's no challenge for the SuperSpy to gain veterancy from,
1967 * i.e. no veterancy if we exit early in next couple of checks. */
1968 *att_vet = 0;
1969 *def_vet = 0;
1970
1971 if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
1972 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
1973 return FALSE;
1974 }
1975 if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
1976 /* An attacking UTYF_SUPERSPY will defeat every possible defender
1977 * except another UTYF_SUPERSPY. */
1978 return TRUE;
1979 }
1980
1981 /* Add or remove 25% if spy flag. */
1982 if (unit_has_type_flag(pattacker, UTYF_SPY)) {
1983 chance += 25;
1984 }
1985 if (unit_has_type_flag(pdefender, UTYF_SPY)) {
1986 chance -= 25;
1987 }
1988
1989 /* Use power_fact from veteran level to modify chance in a linear way.
1990 * Equal veteran levels cancel out.
1991 * It's probably not good for rulesets to allow this to have more than
1992 * 20% effect. */
1993 {
1994 const struct veteran_level
1995 *vatt = utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
1996 const struct veteran_level
1997 *vdef = utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
1998
1999 fc_assert_ret_val(vatt != NULL && vdef != NULL, FALSE);
2000
2001 chance += vatt->power_fact - vdef->power_fact;
2002 }
2003
2004 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
2005 chance -= chance * get_target_bonus_effects(
2006 NULL,
2007 &(const struct req_context) {
2008 .player = tile_owner(pdefender_tile),
2009 .city = tile_city(pdefender_tile),
2010 .tile = pdefender_tile,
2011 },
2012 NULL,
2013 EFT_SPY_RESISTANT
2014 ) / 100;
2015
2016 chance = CLIP(0, chance, 100);
2017
2018 /* In a combat between equal strength units the values are 50% / 50%.
2019 * -> scaling that to 100% by doubling, to match scale of chances
2020 * in existing rulesets, and in !combat_odds_scaled_veterancy case. */
2021 *att_vet = (100 - chance) * 2;
2022 *def_vet = chance * 2;
2023
2024 return (int)fc_rand(100) < chance;
2025}
2026
2027/************************************************************************/
2043static bool diplomat_infiltrate_tile(struct player *pplayer,
2044 struct player *cplayer,
2045 const struct action *paction,
2046 struct unit *pdiplomat,
2047 struct unit *pvictim,
2048 struct tile *ptile,
2049 struct player **defender_owner)
2050{
2051 struct unit *punit;
2052 char link_city[MAX_LEN_LINK] = "";
2053 char link_diplomat[MAX_LEN_LINK];
2054 char link_unit[MAX_LEN_LINK];
2055 struct city *pcity = tile_city(ptile);
2056 const struct unit_type *act_utype = unit_type_get(pdiplomat);
2057 int att_vet;
2058 int def_vet;
2059
2060 if (pcity) {
2061 /* N.B.: *_link() always returns the same pointer. */
2062 sz_strlcpy(link_city, city_link(pcity));
2063 }
2064
2065 if ((punit = get_diplomatic_defender(pdiplomat, pvictim, ptile))) {
2066 struct player *uplayer = unit_owner(punit);
2067
2068 if (defender_owner != NULL) {
2069 /* Some action performers may want to know defender player. */
2070 *defender_owner = uplayer;
2071 }
2072
2073 if (diplomat_success_vs_defender(pdiplomat, punit, ptile,
2074 &att_vet, &def_vet)) {
2075 /* Defending Spy/Diplomat dies. */
2076
2077 /* N.B.: *_link() always returns the same pointer. */
2078 sz_strlcpy(link_unit, unit_tile_link(punit));
2079 sz_strlcpy(link_diplomat, unit_link(pdiplomat));
2080
2081 notify_player(pplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2082 /* TRANS: <unit> ... <diplomat> */
2083 _("An enemy %s has been eliminated by your %s."),
2084 link_unit, link_diplomat);
2085
2086 if (pcity) {
2087 if (uplayer == cplayer || cplayer == NULL) {
2088 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2089 /* TRANS: <unit> ... <city> ... <diplomat> */
2090 _("Your %s has been eliminated defending %s"
2091 " against a %s."), link_unit, link_city,
2092 link_diplomat);
2093 } else {
2094 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2095 /* TRANS: <nation adj> <unit> ... <city>
2096 * TRANS: ... <diplomat> */
2097 _("A %s %s has been eliminated defending %s "
2098 "against a %s."),
2100 link_unit, link_city, link_diplomat);
2101 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2102 /* TRANS: ... <unit> ... <nation adj> <city>
2103 * TRANS: ... <diplomat> */
2104 _("Your %s has been eliminated defending %s %s "
2105 "against a %s."), link_unit,
2107 link_city, link_diplomat);
2108 }
2109 } else {
2110 if (uplayer == cplayer || cplayer == NULL) {
2111 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2112 /* TRANS: <unit> ... <diplomat> */
2113 _("Your %s has been eliminated defending "
2114 "against a %s."), link_unit, link_diplomat);
2115 } else {
2116 notify_player(cplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2117 /* TRANS: <nation adj> <unit> ... <diplomat> */
2118 _("A %s %s has been eliminated defending "
2119 "against a %s."),
2121 link_unit, link_diplomat);
2122 notify_player(uplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2123 /* TRANS: ... <unit> ... <diplomat> */
2124 _("Your %s has been eliminated defending "
2125 "against a %s."), link_unit, link_diplomat);
2126 }
2127 }
2128
2129 pdiplomat->moves_left = MAX(0, pdiplomat->moves_left - SINGLE_MOVE);
2130
2131 /* Attacking unit became more experienced? */
2132 if (maybe_make_veteran(pdiplomat,
2133 game.info.combat_odds_scaled_veterancy ? att_vet : 100)) {
2134 notify_unit_experience(pdiplomat);
2135 }
2136 send_unit_info(NULL, pdiplomat);
2137 wipe_unit(punit, ULR_ELIMINATED, pplayer);
2138 return FALSE;
2139 } else {
2140 /* Attacking Spy/Diplomat dies. */
2141
2142 const char *victim_link;
2143
2144 /* N.B.: *_link() always returns the same pointer. */
2145 sz_strlcpy(link_unit, unit_link(punit));
2146 sz_strlcpy(link_diplomat, unit_tile_link(pdiplomat));
2147
2148 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2149 _("Your %s was eliminated by a defending %s."),
2150 link_diplomat, link_unit);
2151
2152 if (pcity) {
2153 if (uplayer == cplayer || cplayer == NULL) {
2154 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2155 _("Eliminated a %s %s while infiltrating %s."),
2157 link_diplomat, link_city);
2158 } else {
2159 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2160 _("A %s %s eliminated a %s %s while infiltrating "
2161 "%s."), nation_adjective_for_player(uplayer),
2162 link_unit, nation_adjective_for_player(pplayer),
2163 link_diplomat, link_city);
2164 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2165 _("Your %s eliminated a %s %s while infiltrating "
2166 "%s."), link_unit,
2168 link_diplomat, link_city);
2169 }
2170 } else {
2171 if (uplayer == cplayer || cplayer == NULL) {
2172 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2173 _("Eliminated a %s %s while infiltrating our troops."),
2175 link_diplomat);
2176 } else {
2177 notify_player(cplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2178 _("A %s %s eliminated a %s %s while infiltrating our "
2179 "troops."), nation_adjective_for_player(uplayer),
2180 link_unit, nation_adjective_for_player(pplayer),
2181 link_diplomat);
2182 notify_player(uplayer, ptile, E_ENEMY_DIPLOMAT_FAILED, ftc_server,
2183 /* TRANS: ... <unit> ... <diplomat> */
2184 _("Your %s eliminated a %s %s while infiltrating our "
2185 "troops."), link_unit,
2187 link_diplomat);
2188 }
2189 }
2190
2191 /* Defending unit became more experienced? */
2193 game.info.combat_odds_scaled_veterancy ? def_vet : 100)) {
2195 }
2196
2197 victim_link = NULL;
2198
2199 switch (action_get_target_kind(paction)) {
2200 case ATK_CITY:
2201 victim_link = city_link(pcity);
2202 break;
2203 case ATK_UNIT:
2204 case ATK_UNITS:
2205 victim_link = pvictim ? unit_tile_link(pvictim)
2206 : tile_link(ptile);
2207 break;
2208 case ATK_TILE:
2209 case ATK_EXTRAS:
2210 victim_link = tile_link(ptile);
2211 break;
2212 case ATK_SELF:
2213 /* How did a self targeted action end up here? */
2214 fc_assert(action_get_target_kind(paction) != ATK_SELF);
2215 break;
2216 case ATK_COUNT:
2217 break;
2218 }
2219
2220 fc_assert(victim_link != NULL);
2221
2222 action_consequence_caught(paction, pplayer, act_utype, uplayer,
2223 ptile, victim_link);
2224
2225 wipe_unit(pdiplomat, ULR_ELIMINATED, uplayer);
2226 return FALSE;
2227 }
2228 }
2229
2230 return TRUE;
2231}
2232
2233/************************************************************************/
2243static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
2244 const struct city *pcity,
2245 const struct action *paction)
2246{
2247 struct tile *ptile;
2248 const char *vlink;
2249
2250 if (pcity) {
2251 ptile = city_tile(pcity);
2252 vlink = city_link(pcity);
2253 } else {
2254 ptile = unit_tile(pdiplomat);
2255 vlink = NULL;
2256 }
2257
2258 return diplomat_escape_full(pplayer, pdiplomat, pcity != NULL,
2259 ptile, vlink, paction);
2260}
2261
2262/************************************************************************/
2271static void diplomat_escape_full(struct player *pplayer,
2272 struct unit *pdiplomat,
2273 bool city_related,
2274 struct tile *ptile,
2275 const char *vlink,
2276 const struct action *paction)
2277{
2278 int escapechance;
2279 struct city *spyhome;
2280 const struct unit_type *dipltype = unit_type_get(pdiplomat);
2281
2282 fc_assert(paction->actor.is_unit.moves_actor == MAK_ESCAPE);
2283
2284 /* Veteran level's power factor's effect on escape chance is relative to
2285 * unpromoted unit's power factor */
2286 {
2287 const struct veteran_level
2288 *vunit = utype_veteran_level(dipltype, pdiplomat->veteran);
2289 const struct veteran_level
2290 *vbase = utype_veteran_level(dipltype, 0);
2291
2292 escapechance = game.server.diplchance
2293 + (vunit->power_fact - vbase->power_fact);
2294 }
2295
2296 /* find closest city for escape target */
2297 spyhome = find_closest_city(ptile, NULL, unit_owner(pdiplomat), FALSE,
2298 FALSE, FALSE, TRUE, FALSE, NULL);
2299
2300 if (spyhome
2301 && !utype_is_consumed_by_action(paction, dipltype)
2302 && (unit_has_type_flag(pdiplomat, UTYF_SUPERSPY)
2303 || fc_rand (100) < escapechance)) {
2304 /* Attacking Spy/Diplomat survives. */
2305 notify_player(pplayer, ptile, E_MY_DIPLOMAT_ESCAPE, ftc_server,
2306 _("Your %s has successfully completed"
2307 " the mission and returned unharmed to %s."),
2308 unit_link(pdiplomat),
2309 city_link(spyhome));
2310 if (maybe_make_veteran(pdiplomat, 100)) {
2311 notify_unit_experience(pdiplomat);
2312 }
2313
2314 if (!teleport_unit_to_city (pdiplomat, spyhome,
2315 /* Handled by the ruleset. */
2316 0,
2317 FALSE)) {
2318 send_unit_info(NULL, pdiplomat);
2319 log_error("Bug in diplomat_escape: Spy can't teleport.");
2320 return;
2321 }
2322
2323 return;
2324 } else {
2325 if (city_related) {
2326 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2327 _("Your %s was captured after completing"
2328 " the mission in %s."),
2329 unit_tile_link(pdiplomat),
2330 vlink);
2331 } else {
2332 notify_player(pplayer, ptile, E_MY_DIPLOMAT_FAILED, ftc_server,
2333 _("Your %s was captured after completing"
2334 " the mission."),
2335 unit_tile_link(pdiplomat));
2336 }
2337 }
2338
2339 if (!utype_is_consumed_by_action(paction, dipltype)) {
2340 /* The unit was caught, not spent. It must therefore be deleted by
2341 * hand. */
2342 wipe_unit(pdiplomat, ULR_CAUGHT, NULL);
2343 }
2344}
2345
2346/************************************************************************/
2350{
2351 int count = 0;
2352
2353 unit_list_iterate((ptile)->units, punit) {
2354 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
2355 count++;
2356 }
2358
2359 return count;
2360}
const char * action_name_translation(const struct action *action)
Definition actions.c:1890
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1740
#define action_has_result(_act_, _res_)
Definition actions.h:448
void action_consequence_caught(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
const struct action * action_auto_perf_unit_do(const enum action_auto_perf_cause cause, struct unit *actor, const struct player *other_player, const struct output_type *eval_output, const struct action *eval_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, const struct extra_type *target_extra)
void action_consequence_success(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
bool action_failed_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
bool has_capability(const char *cap, const char *capstr)
Definition capability.c:77
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1216
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
#define city_tile(_pcity_)
Definition city.h:544
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
#define city_owner(_pcity_)
Definition city.h:543
#define city_built_iterate(_pcity, _p)
Definition city.h:810
#define city_built_iterate_end
Definition city.h:816
void package_city(struct city *pcity, struct packet_city_info *packet, struct packet_city_nationalities *nat_packet, struct packet_city_rally_point *rally_packet, struct packet_web_city_info_addition *web_packet, struct trade_route_packet_list *routes, bool dipl_invest)
Definition citytools.c:2480
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2327
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2683
struct city * find_closest_city(const struct tile *ptile, const struct city *pexclcity, const struct player *pplayer, bool only_ocean, bool only_continent, bool only_known, bool only_player, bool only_enemy, const struct unit_class *pclass)
Definition citytools.c:854
int city_original_owner(const struct city *pcity, const struct player *known_for)
Definition citytools.c:3559
bool city_illness_strike(struct city *pcity)
Definition citytools.c:2884
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:2977
bool transfer_city(struct player *ptaker, struct city *pcity, int kill_outside, bool transfer_unit_verbose, bool resolve_stack, bool raze, bool build_free)
Definition citytools.c:1070
#define trade_route_packet_list_iterate_end
Definition citytools.h:28
#define trade_route_packet_list_iterate(ptrlist, ptr)
Definition citytools.h:26
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3379
bool city_empty_food_stock(struct city *pcity)
Definition cityturn.c:4055
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3267
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:808
bool city_refresh(struct city *pcity)
Definition cityturn.c:161
struct unit * get_diplomatic_defender(const struct unit *act_unit, const struct unit *pvictim, const struct tile *tgt_tile)
Definition combat.c:884
#define conn_list_iterate(connlist, pconn)
Definition connection.h:113
#define conn_list_iterate_end
Definition connection.h:115
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
void establish_embassy(struct player *pplayer, struct player *aplayer)
Definition diplhand.c:724
static void diplomat_escape_full(struct player *pplayer, struct unit *pdiplomat, bool city_related, struct tile *ptile, const char *vlink, const struct action *paction)
Definition diplomats.c:2271
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1703
int diplomats_unignored_tech_stealings(struct unit *pdiplomat, struct city *pcity)
Definition diplomats.c:855
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:553
static bool diplomat_may_lose_gold(struct player *dec_player, struct player *inc_player, int revolt_gold)
Definition diplomats.c:1086
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:488
void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat, struct city *pcity, const struct action *paction, int request_kind)
Definition diplomats.c:432
static bool diplomat_infiltrate_tile(struct player *pplayer, struct player *cplayer, const struct action *paction, struct unit *pdiplomat, struct unit *pvictim, struct tile *ptile, struct player **defender_owner)
Definition diplomats.c:2043
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Definition diplomats.c:896
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1289
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1140
static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat, const struct city *pcity, const struct action *paction)
Definition diplomats.c:2243
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1561
bool spy_spread_plague(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:215
bool spy_nuke_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1839
static bool diplomat_success_vs_defender(struct unit *patt, struct unit *pdef, struct tile *pdefender_tile, int *att_vet, int *def_vet)
Definition diplomats.c:1959
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:325
static void diplomat_charge_movement(struct unit *pdiplomat, struct tile *ptile)
Definition diplomats.c:1943
bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:648
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:812
bool spy_poison(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:98
int count_diplomats_on_tile(struct tile *ptile)
Definition diplomats.c:2349
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:691
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:992
int Tech_type_id
Definition fc_types.h:347
int Impr_type_id
Definition fc_types.h:346
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * tile_link(const struct tile *ptile)
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
const char * unit_link(const struct unit *punit)
const char * unit_tile_link(const struct unit *punit)
#define MAX_LEN_LINK
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct impr_type * improvement_by_number(const Impr_type_id id)
Impr_type_id improvement_number(const struct impr_type *pimprove)
const char * improvement_rule_name(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:287
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1346
bool give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Definition maphand.c:2680
#define FC_FREE(ptr)
Definition mem.h:41
#define SINGLE_MOVE
Definition movement.h:24
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:168
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:177
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
#define web_lsend_packet(packetname,...)
Definition packets.h:53
@ UNIT_INFO_CITY_PRESENT
Definition packets.h:84
@ UNIT_INFO_CITY_SUPPORTED
Definition packets.h:83
void lsend_packet_city_nationalities(struct conn_list *dest, const struct packet_city_nationalities *packet, bool force_to_send)
int dsend_packet_investigate_finished(struct connection *pc, int unit_id16, int unit_id32, int city_id16, int city_id32)
void lsend_packet_trade_route_info(struct conn_list *dest, const struct packet_trade_route_info *packet)
void lsend_packet_city_info(struct conn_list *dest, const struct packet_city_info *packet, bool force_to_send)
int send_packet_city_sabotage_list(struct connection *pc, const struct packet_city_sabotage_list *packet)
void lsend_packet_unit_short_info(struct conn_list *dest, const struct packet_unit_short_info *packet, bool force_to_send)
void dlsend_packet_nuke_tile_info(struct conn_list *dest, int tile)
int dsend_packet_investigate_started(struct connection *pc, int unit_id16, int unit_id32, int city_id16, int city_id32)
void lsend_packet_city_rally_point(struct conn_list *dest, const struct packet_city_rally_point *packet, bool force_to_send)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
const char * player_name(const struct player *pplayer)
Definition player.c:886
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
void send_player_all_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:983
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1000
#define fc_rand(_size)
Definition rand.h:34
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
void script_server_signal_emit(const char *signal_name,...)
#define CLIP(lower, current, upper)
Definition shared.h:57
#define MAX(x, y)
Definition shared.h:54
action_id id
Definition actions.h:380
enum moves_actor_kind moves_actor
Definition actions.h:432
struct action::@12::@13 is_unit
union action::@12 actor
Definition city.h:309
int id
Definition city.h:315
struct universal production
Definition city.h:382
int steal
Definition city.h:397
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
struct unit_list * units_supported
Definition city.h:391
int incite_gold_capt_chance
Definition game.h:141
struct civ_game::@30::@34 server
int diplchance
Definition game.h:137
int incite_gold_loss_chance
Definition game.h:140
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
bool tech_steal_allow_holes
bool steal_maps_reveals_all_cities
bool poison_empties_food_stock
bool combat_odds_scaled_veterancy
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
int future_tech
Definition research.h:42
Definition tile.h:49
Definition unit.h:138
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
int hp
Definition unit.h:151
struct tile * tile
Definition unit.h:140
int homecity
Definition unit.h:146
int veteran
Definition unit.h:152
bv_imprs improvements
Definition vision.h:125
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:167
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
#define A_FUTURE
Definition tech.h:46
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
Tech_type_id steal_a_tech(struct player *pplayer, struct player *victim, Tech_type_id preferred)
Definition techtools.c:1208
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:87
#define tile_owner(_tile)
Definition tile.h:95
bool unit_is_alive(int id)
Definition unit.c:2237
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2288
#define unit_tile(_pu)
Definition unit.h:395
#define unit_owner(_pu)
Definition unit.h:394
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2794
void notify_unit_experience(struct unit *punit)
Definition unittools.c:735
void package_short_unit(struct unit *punit, struct packet_unit_short_info *packet, enum unit_info_use packet_use, int info_city_id)
Definition unittools.c:2733
bool maybe_make_veteran(struct unit *punit, int base_chance)
Definition unittools.c:217
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2247
void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
Definition unittools.c:2946
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2307
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1203
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1241
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1621
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1979
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2645
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1271
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612