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)
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 ***********************************************************************/
15 #include <fc_config.h>
21 #include "bitvector.h"
30 #include "government.h"
38 #include "actiontools.h"
40 #include "citytools.h"
43 #include "diplomats.h"
47 #include "techtools.h"
49 #include "unittools.h"
51 /* server/scripting */
52 #include "script_server.h"
54 /****************************************************************************/
56 static void diplomat_charge_movement (struct unit
*pdiplomat
,
58 static bool diplomat_success_vs_defender(struct unit
*patt
, struct unit
*pdef
,
59 struct tile
*pdefender_tile
);
60 static bool diplomat_infiltrate_tile(struct player
*pplayer
,
61 struct player
*cplayer
,
62 const struct action
*paction
,
63 struct unit
*pdiplomat
,
66 static bool diplomat_was_caught(struct player
*act_player
,
67 struct unit
*act_unit
,
68 struct city
*tgt_city
,
69 struct player
*tgt_player
,
70 const struct action
*act
);
71 static void diplomat_escape(struct player
*pplayer
, struct unit
*pdiplomat
,
72 const struct city
*pcity
,
73 const struct action
*paction
);
74 static void diplomat_escape_full(struct player
*pplayer
,
75 struct unit
*pdiplomat
,
79 const struct action
*paction
);
81 /******************************************************************************
82 Poison a city's water supply.
84 - Check for infiltration success. Our poisoner may not survive this.
85 - If successful, reduces population by one point.
87 - The poisoner may be captured and executed, or escape to its home town.
89 'pplayer' is the player who tries to poison 'pcity' with its unit
92 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
93 this returns TRUE, unit may have died during the action.
94 ****************************************************************************/
95 bool spy_poison(struct player
*pplayer
, struct unit
*pdiplomat
,
96 struct city
*pcity
, const struct action
*paction
)
98 struct player
*cplayer
;
102 /* Fetch target city's player. Sanity checks. */
103 fc_assert_ret_val(pcity
, FALSE
);
104 cplayer
= city_owner(pcity
);
105 fc_assert_ret_val(cplayer
, FALSE
);
107 /* Sanity check: The actor still exists. */
108 fc_assert_ret_val(pplayer
, FALSE
);
109 fc_assert_ret_val(pdiplomat
, FALSE
);
111 ctile
= city_tile(pcity
);
112 clink
= city_link(pcity
);
114 log_debug("poison: unit: %d", pdiplomat
->id
);
116 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
117 if (!diplomat_infiltrate_tile(pplayer
, cplayer
, paction
,
118 pdiplomat
, NULL
, ctile
)) {
122 log_debug("poison: infiltrated");
123 log_debug("poison: succeeded");
126 if (city_reduce_size(pcity
, 1, pplayer
, "poison")) {
127 /* Notify everybody involved. */
128 notify_player(pplayer
, ctile
, E_MY_DIPLOMAT_POISON
, ftc_server
,
129 _("Your %s poisoned the water supply of %s."),
130 unit_link(pdiplomat
), clink
);
131 notify_player(cplayer
, ctile
,
132 E_ENEMY_DIPLOMAT_POISON
, ftc_server
,
133 _("%s is suspected of poisoning the water supply of %s."),
134 player_name(pplayer
), clink
);
136 if (game
.info
.poison_empties_food_stock
) {
137 /* The food was poisoned too. */
138 city_empty_food_stock(pcity
);
141 /* Update clients. */
142 city_refresh (pcity
);
143 send_city_info(NULL
, pcity
);
145 /* Notify everybody involved. */
146 notify_player(pplayer
, ctile
, E_MY_DIPLOMAT_POISON
, ftc_server
,
147 _("Your %s destroyed %s by poisoning its water supply."),
148 unit_link(pdiplomat
), clink
);
149 notify_player(cplayer
, ctile
,
150 E_ENEMY_DIPLOMAT_POISON
, ftc_server
,
151 _("%s is suspected of destroying %s by poisoning its"
153 player_name(pplayer
), clink
);
156 /* this may cause a diplomatic incident */
157 action_consequence_success(paction
, pplayer
, cplayer
, ctile
, clink
);
159 /* Now lets see if the spy survives. */
160 diplomat_escape_full(pplayer
, pdiplomat
, TRUE
, ctile
, clink
, paction
);
165 /******************************************************************************
168 - It costs some minimal movement to investigate a city.
170 - The actor unit always survives the investigation unless the action
171 being performed is configured to always consume the actor unit.
173 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
174 this returns TRUE, unit may have died during the action.
175 ****************************************************************************/
176 bool diplomat_investigate(struct player
*pplayer
, struct unit
*pdiplomat
,
178 const struct action
*paction
)
180 struct player
*cplayer
;
181 struct packet_unit_short_info unit_packet
;
182 struct packet_city_info city_packet
;
183 struct packet_web_city_info_addition web_packet
;
184 struct traderoute_packet_list
*routes
;
186 /* Fetch target city's player. Sanity checks. */
187 fc_assert_ret_val(pcity
, FALSE
);
188 cplayer
= city_owner(pcity
);
189 fc_assert_ret_val(cplayer
, FALSE
);
191 /* Sanity check: The actor still exists. */
192 fc_assert_ret_val(pplayer
, FALSE
);
193 fc_assert_ret_val(pdiplomat
, FALSE
);
195 /* Sanity check: The target is foreign. */
196 if (cplayer
== pplayer
) {
197 /* Nothing to do to a domestic target. */
201 log_debug("investigate: unit: %d", pdiplomat
->id
);
204 update_dumb_city(pplayer
, pcity
);
205 /* Special case for a diplomat/spy investigating a city:
206 The investigator needs to know the supported and present
207 units of a city, whether or not they are fogged. So, we
208 send a list of them all before sending the city info.
209 As this is a special case we bypass send_unit_info. */
210 unit_list_iterate(pcity
->units_supported
, punit
) {
211 package_short_unit(punit
, &unit_packet
,
212 UNIT_INFO_CITY_SUPPORTED
, pcity
->id
);
213 /* We need to force to send the packet to ensure the client will receive
214 * something (e.g. investigating twice). */
215 lsend_packet_unit_short_info(pplayer
->connections
, &unit_packet
, TRUE
);
216 } unit_list_iterate_end
;
217 unit_list_iterate((pcity
->tile
)->units
, punit
) {
218 package_short_unit(punit
, &unit_packet
,
219 UNIT_INFO_CITY_PRESENT
, pcity
->id
);
220 /* We need to force to send the packet to ensure the client will receive
221 * something (e.g. investigating twice). */
222 lsend_packet_unit_short_info(pplayer
->connections
, &unit_packet
, TRUE
);
223 } unit_list_iterate_end
;
224 /* Send city info to investigator's player.
225 As this is a special case we bypass send_city_info. */
226 routes
= traderoute_packet_list_new();
227 package_city(pcity
, &city_packet
, &web_packet
, routes
, TRUE
);
228 /* We need to force to send the packet to ensure the client will receive
229 * something and popup the city dialog. */
230 lsend_packet_city_info(pplayer
->connections
, &city_packet
, TRUE
);
231 web_lsend_packet(city_info_addition
, pplayer
->connections
, &web_packet
, TRUE
);
232 traderoute_packet_list_iterate(routes
, route_packet
) {
233 lsend_packet_traderoute_info(pplayer
->connections
, route_packet
);
234 FC_FREE(route_packet
);
235 } traderoute_packet_list_iterate_end
;
236 traderoute_packet_list_destroy(routes
);
238 /* Charge a nominal amount of movement for this. */
239 (pdiplomat
->moves_left
)--;
240 if (pdiplomat
->moves_left
< 0) {
241 pdiplomat
->moves_left
= 0;
244 /* this may cause a diplomatic incident */
245 action_consequence_success(paction
, pplayer
, cplayer
,
246 city_tile(pcity
), city_link(pcity
));
248 /* The actor unit always survive unless the action it self has determined
249 * to always consume it. */
250 if (!utype_is_consumed_by_action(paction
, unit_type_get(pdiplomat
))) {
251 /* This unit isn't about to be consumed. Send updated unit information
253 send_unit_info(NULL
, pdiplomat
);
259 /******************************************************************************
260 Get list of improvements from city (for purposes of sabotage).
262 - Always successful; returns list.
264 Only send back to the originating connection, if there is one. (?)
265 ****************************************************************************/
266 void spy_send_sabotage_list(struct connection
*pc
, struct unit
*pdiplomat
,
268 const struct action
*paction
)
270 struct packet_city_sabotage_list packet
;
272 /* Send city improvements info to player. */
273 BV_CLR_ALL(packet
.improvements
);
275 improvement_iterate(ptarget
) {
276 if (city_has_building(pcity
, ptarget
)) {
277 BV_SET(packet
.improvements
, improvement_index(ptarget
));
279 } improvement_iterate_end
;
281 packet
.diplomat_id
= pdiplomat
->id
;
282 packet
.city_id
= pcity
->id
;
283 packet
.action_id
= paction
->id
;
284 send_packet_city_sabotage_list(pc
, &packet
);
287 /******************************************************************************
288 Establish an embassy.
290 - Barbarians always execute ambassadors.
291 - Otherwise, the embassy is created.
292 - It costs some minimal movement to establish an embassy.
294 - The actor unit always survives the investigation unless the action
295 being performed is configured to always consume the actor unit.
297 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
298 this returns TRUE, unit may have died during the action.
299 ****************************************************************************/
300 bool diplomat_embassy(struct player
*pplayer
, struct unit
*pdiplomat
,
301 struct city
*pcity
, const struct action
*paction
)
303 struct player
*cplayer
;
305 /* Fetch target city's player. Sanity checks. */
306 fc_assert_ret_val(pcity
, FALSE
);
307 cplayer
= city_owner(pcity
);
308 fc_assert_ret_val(cplayer
, FALSE
);
310 /* Sanity check: The actor still exists. */
311 fc_assert_ret_val(pplayer
, FALSE
);
312 fc_assert_ret_val(pdiplomat
, FALSE
);
314 /* Sanity check: The target is foreign. */
315 if (cplayer
== pplayer
) {
316 /* Nothing to do to a domestic target. */
320 log_debug("embassy: unit: %d", pdiplomat
->id
);
322 log_debug("embassy: succeeded");
324 establish_embassy(pplayer
, cplayer
);
326 /* Notify everybody involved. */
327 notify_player(pplayer
, city_tile(pcity
),
328 E_MY_DIPLOMAT_EMBASSY
, ftc_server
,
329 _("You have established an embassy in %s."),
331 notify_player(cplayer
, city_tile(pcity
),
332 E_ENEMY_DIPLOMAT_EMBASSY
, ftc_server
,
333 _("The %s have established an embassy in %s."),
334 nation_plural_for_player(pplayer
),
337 /* Charge a nominal amount of movement for this. */
338 (pdiplomat
->moves_left
)--;
339 if (pdiplomat
->moves_left
< 0) {
340 pdiplomat
->moves_left
= 0;
343 /* this may cause a diplomatic incident */
344 action_consequence_success(paction
, pplayer
, cplayer
,
345 city_tile(pcity
), city_link(pcity
));
347 /* The actor unit always survive unless the action it self has determined
348 * to always consume it. */
349 if (!utype_is_consumed_by_action(paction
, unit_type_get(pdiplomat
))) {
350 /* This unit isn't about to be consumed. Send updated unit information
352 send_unit_info(NULL
, pdiplomat
);
358 /******************************************************************************
359 Sabotage an enemy unit.
361 - If successful, reduces hit points by half of those remaining.
363 - The saboteur may be captured and executed, or escape to its home town.
365 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
366 this returns TRUE, unit may have died during the action.
367 ****************************************************************************/
368 bool spy_sabotage_unit(struct player
*pplayer
, struct unit
*pdiplomat
,
369 struct unit
*pvictim
,
370 const struct action
*paction
)
372 char victim_link
[MAX_LEN_LINK
];
373 struct player
*uplayer
;
375 /* Fetch target unit's player. Sanity checks. */
376 fc_assert_ret_val(pvictim
, FALSE
);
377 uplayer
= unit_owner(pvictim
);
378 fc_assert_ret_val(uplayer
, FALSE
);
380 /* Sanity check: The actor still exists. */
381 fc_assert_ret_val(pplayer
, FALSE
);
382 fc_assert_ret_val(pdiplomat
, FALSE
);
384 log_debug("sabotage-unit: unit: %d", pdiplomat
->id
);
386 /* N.B: unit_link() always returns the same pointer. */
387 sz_strlcpy(victim_link
, unit_link(pvictim
));
389 /* Diplomatic battle against any diplomatic defender except the intended
390 * victim of the sabotage. */
391 if (!diplomat_infiltrate_tile(pplayer
, uplayer
,
394 unit_tile(pvictim
))) {
398 log_debug("sabotage-unit: succeeded");
400 if (pvictim
->hp
< 2) {
401 /* Not possible to halve the hit points. Kill it. */
402 wipe_unit(pvictim
, ULR_KILLED
, pplayer
);
404 /* Notify everybody involved. */
405 notify_player(pplayer
, unit_tile(pvictim
),
406 E_MY_DIPLOMAT_SABOTAGE
, ftc_server
,
407 _("Your %s's successful sabotage killed the %s %s."),
408 unit_link(pdiplomat
),
409 nation_adjective_for_player(uplayer
),
411 notify_player(uplayer
, unit_tile(pvictim
),
412 E_ENEMY_DIPLOMAT_SABOTAGE
, ftc_server
,
413 /* TRANS: ... the Poles! */
414 _("Your %s was killed by %s sabotage!"),
416 nation_plural_for_player(pplayer
));
418 /* Sabotage the unit by removing half its remaining hit points. */
420 send_unit_info(NULL
, pvictim
);
422 /* Notify everybody involved. */
423 notify_player(pplayer
, unit_tile(pvictim
),
424 E_MY_DIPLOMAT_SABOTAGE
, ftc_server
,
425 _("Your %s succeeded in sabotaging the %s %s."),
426 unit_link(pdiplomat
),
427 nation_adjective_for_player(uplayer
),
429 notify_player(uplayer
, unit_tile(pvictim
),
430 E_ENEMY_DIPLOMAT_SABOTAGE
, ftc_server
,
431 /* TRANS: ... the Poles! */
432 _("Your %s was sabotaged by the %s!"),
434 nation_plural_for_player(pplayer
));
437 /* this may cause a diplomatic incident */
438 action_consequence_success(paction
, pplayer
, uplayer
,
439 unit_tile(pvictim
), victim_link
);
441 /* Now lets see if the spy survives. */
442 diplomat_escape(pplayer
, pdiplomat
, NULL
, paction
);
447 /******************************************************************************
450 - Can't bribe a unit if:
451 - Player doesn't have enough gold.
452 - Otherwise, the unit will be bribed.
454 - A successful briber will try to move onto the victim's square.
456 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
457 this returns TRUE, unit may have died during the action.
458 ****************************************************************************/
459 bool diplomat_bribe(struct player
*pplayer
, struct unit
*pdiplomat
,
460 struct unit
*pvictim
, const struct action
*paction
)
462 char victim_link
[MAX_LEN_LINK
];
463 struct player
*uplayer
;
464 struct tile
*victim_tile
;
466 int diplomat_id
= pdiplomat
->id
;
469 /* Fetch target unit's player. Sanity checks. */
470 fc_assert_ret_val(pvictim
, FALSE
);
471 uplayer
= unit_owner(pvictim
);
472 fc_assert_ret_val(uplayer
, FALSE
);
474 /* Sanity check: The actor still exists. */
475 fc_assert_ret_val(pplayer
, FALSE
);
476 fc_assert_ret_val(pdiplomat
, FALSE
);
478 /* Sanity check: The target is foreign. */
479 if (uplayer
== pplayer
) {
480 /* Nothing to do to a domestic target. */
484 /* Sanity check: The victim isn't a unique unit the actor player already
486 if (utype_player_already_has_this_unique(pplayer
,
487 unit_type_get(pvictim
))) {
488 log_debug("bribe-unit: already got unique unit");
489 notify_player(pplayer
, unit_tile(pdiplomat
),
490 E_UNIT_ILLEGAL_ACTION
, ftc_server
,
491 /* TRANS: You already have a Leader. */
492 _("You already have a %s."),
498 log_debug("bribe-unit: unit: %d", pdiplomat
->id
);
500 /* Get bribe cost, ignoring any previously saved value. */
501 bribe_cost
= unit_bribe_cost(pvictim
, pplayer
);
503 /* If player doesn't have enough gold, can't bribe. */
504 if (pplayer
->economic
.gold
< bribe_cost
) {
505 notify_player(pplayer
, unit_tile(pdiplomat
),
506 E_MY_DIPLOMAT_FAILED
, ftc_server
,
507 _("You don't have enough gold to bribe the %s %s."),
508 nation_adjective_for_player(uplayer
),
510 log_debug("bribe-unit: not enough gold");
514 log_debug("bribe-unit: enough gold");
516 /* Diplomatic battle against any diplomatic defender except the one that
517 * will get the bribe. */
518 if (!diplomat_infiltrate_tile(pplayer
, uplayer
,
525 log_debug("bribe-unit: succeeded");
527 victim_tile
= unit_tile(pvictim
);
528 pvictim
= unit_change_owner(pvictim
, pplayer
, pdiplomat
->homecity
,
531 /* N.B.: unit_link always returns the same pointer. As unit_change_owner()
532 * currently remove the old unit and replace by a new one (with a new id),
533 * we want to make link to the new unit. */
534 sz_strlcpy(victim_link
, unit_link(pvictim
));
536 /* Notify everybody involved. */
537 notify_player(pplayer
, victim_tile
, E_MY_DIPLOMAT_BRIBE
, ftc_server
,
538 /* TRANS: <diplomat> ... <unit> */
539 _("Your %s succeeded in bribing the %s."),
540 unit_link(pdiplomat
), victim_link
);
541 if (maybe_make_veteran(pdiplomat
)) {
542 notify_unit_experience(pdiplomat
);
544 notify_player(uplayer
, victim_tile
, E_ENEMY_DIPLOMAT_BRIBE
, ftc_server
,
545 /* TRANS: <unit> ... <Poles> */
546 _("Your %s was bribed by the %s."),
547 victim_link
, nation_plural_for_player(pplayer
));
549 /* The unit may have been on a tile shared with a city or a unit
550 * it no longer can share a tile with. */
551 pcity
= tile_city(unit_tile(pvictim
));
552 if ((NULL
!= pcity
&& !pplayers_allied(city_owner(pcity
), pplayer
))
553 || 1 < unit_list_size(unit_tile(pvictim
)->units
)) {
554 bounce_unit(pvictim
, TRUE
);
558 pplayer
->economic
.gold
-= bribe_cost
;
560 /* This may cause a diplomatic incident */
561 action_consequence_success(paction
, pplayer
, uplayer
,
562 victim_tile
, victim_link
);
564 if (!unit_is_alive(diplomat_id
)) {
568 /* Try to move the briber onto the victim's square unless its a city or
569 * have other units. */
570 if (NULL
== pcity
&& unit_list_size(unit_tile(pvictim
)->units
) < 2
571 /* Post bribe move. */
572 && !unit_move_handling(pdiplomat
, victim_tile
, FALSE
, TRUE
, NULL
)
573 /* May have died while trying to move. */
574 && unit_is_alive(diplomat_id
)) {
575 pdiplomat
->moves_left
= 0;
577 if (NULL
!= player_unit_by_number(pplayer
, diplomat_id
)) {
578 send_unit_info(NULL
, pdiplomat
);
581 /* Update clients. */
582 send_player_all_c(pplayer
, NULL
);
587 /****************************************************************************
588 Try to steal a technology from an enemy city.
589 If paction results in ACTION_SPY_STEAL_TECH, steal a random technology.
590 Otherwise, steal the technology whose ID is "technology".
591 (Note: Only Spies can select what to steal.)
593 - Check for infiltration success. Our thief may not survive this.
594 - Check for basic success. Again, our thief may not survive this.
595 - If a technology has already been stolen from this city at any time:
596 - Diplomats will be caught and executed.
597 - Spies will have an increasing chance of being caught and executed.
600 - The thief may be captured and executed, or escape to its home town.
602 FIXME: It should give a loss of reputation to steal from a player you are
605 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
606 this returns TRUE, unit may have died during the action.
607 ****************************************************************************/
608 bool diplomat_get_tech(struct player
*pplayer
, struct unit
*pdiplomat
,
609 struct city
*pcity
, Tech_type_id technology
,
610 const struct action
*paction
)
612 struct research
*presearch
, *cresearch
;
613 struct player
*cplayer
;
617 Tech_type_id tech_stolen
;
619 /* We have to check arguments. They are sent to us by a client,
620 so we cannot trust them */
621 fc_assert_ret_val(pcity
, FALSE
);
622 cplayer
= city_owner(pcity
);
623 fc_assert_ret_val(cplayer
, FALSE
);
625 /* Sanity check: The actor still exists. */
626 fc_assert_ret_val(pplayer
, FALSE
);
627 fc_assert_ret_val(pdiplomat
, FALSE
);
629 /* Sanity check: The target is foreign. */
630 if (cplayer
== pplayer
) {
631 /* Nothing to do to a domestic target. */
635 if (action_has_result(paction
, ACTION_SPY_STEAL_TECH
)) {
636 /* Can't choose target. Will steal a random tech. */
637 technology
= A_UNSET
;
640 /* Targeted technology should be a ruleset defined tech,
641 * "At Spy's Discretion" (A_UNSET) or a future tech (A_FUTURE). */
642 if (technology
== A_NONE
643 || (technology
!= A_FUTURE
644 && !(technology
== A_UNSET
645 && action_has_result(paction
, ACTION_SPY_STEAL_TECH
))
646 && !valid_advance_by_number(technology
))) {
650 presearch
= research_get(pplayer
);
651 cresearch
= research_get(cplayer
);
653 if (technology
== A_FUTURE
) {
654 if (presearch
->future_tech
>= cresearch
->future_tech
) {
657 } else if (technology
!= A_UNSET
) {
658 if (research_invention_state(presearch
, technology
) == TECH_KNOWN
) {
661 if (research_invention_state(cresearch
, technology
) != TECH_KNOWN
) {
664 if (!research_invention_gettable(presearch
, technology
,
665 game
.info
.tech_steal_allow_holes
)) {
670 log_debug("steal-tech: unit: %d", pdiplomat
->id
);
672 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
673 if (!diplomat_infiltrate_tile(pplayer
, cplayer
,
680 log_debug("steal-tech: infiltrated");
682 bonus
= get_unit_bonus(pdiplomat
, EFT_STEALINGS_IGNORE
);
684 /* Negative effect value means infinite bonus */
687 times
= pcity
->server
.steal
- bonus
;
693 /* Check if the Diplomat/Spy succeeds with his/her task. */
694 /* (Twice as difficult if target is specified.) */
695 /* (If already stolen from, impossible for Diplomats and harder for Spies.) */
696 if (times
> 0 && !unit_has_type_flag(pdiplomat
, UTYF_SPY
)) {
697 /* Already stolen from: Diplomat always fails! */
699 log_debug("steal-tech: difficulty: impossible");
701 /* Determine difficulty. */
703 if (action_has_result(paction
, ACTION_SPY_TARGETED_STEAL_TECH
)) {
704 /* Targeted steal tech is more difficult. */
708 log_debug("steal-tech: difficulty: %d", count
);
709 /* Determine success or failure. */
711 if (fc_rand(100) >= game
.server
.diplchance
) {
719 if (pcity
->server
.steal
> 0 && !unit_has_type_flag(pdiplomat
, UTYF_SPY
)) {
720 notify_player(pplayer
, city_tile(pcity
),
721 E_MY_DIPLOMAT_FAILED
, ftc_server
,
722 _("%s was expecting your attempt to steal technology "
723 "again. Your %s was caught and executed."),
725 unit_tile_link(pdiplomat
));
727 notify_player(pplayer
, city_tile(pcity
),
728 E_MY_DIPLOMAT_FAILED
, ftc_server
,
729 _("Your %s was caught in the attempt of"
730 " stealing technology from %s."),
731 unit_tile_link(pdiplomat
),
734 notify_player(cplayer
, city_tile(pcity
),
735 E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
736 _("The %s %s failed to steal technology from %s."),
737 nation_adjective_for_player(pplayer
),
738 unit_tile_link(pdiplomat
),
740 /* this may cause a diplomatic incident */
741 action_consequence_caught(paction
, pplayer
, cplayer
,
742 city_tile(pcity
), city_link(pcity
));
743 wipe_unit(pdiplomat
, ULR_CAUGHT
, cplayer
);
747 tech_stolen
= steal_a_tech(pplayer
, cplayer
, technology
);
749 if (tech_stolen
== A_NONE
) {
750 notify_player(pplayer
, city_tile(pcity
),
751 E_MY_DIPLOMAT_FAILED
, ftc_server
,
752 _("No new technology found in %s."),
754 diplomat_charge_movement (pdiplomat
, pcity
->tile
);
755 send_unit_info(NULL
, pdiplomat
);
759 /* Update stealing player's science progress and research fields */
760 send_player_all_c(pplayer
, NULL
);
762 /* Record the theft. */
763 (pcity
->server
.steal
)++;
765 /* this may cause a diplomatic incident */
766 action_consequence_success(paction
, pplayer
, cplayer
,
767 city_tile(pcity
), city_link(pcity
));
769 /* Check if a spy survives her mission. */
770 diplomat_escape(pplayer
, pdiplomat
, pcity
, paction
);
775 /**************************************************************************
776 Incite a city to disaffect.
778 - Can't incite a city to disaffect if:
779 - Player doesn't have enough gold.
780 - Check for infiltration success. Our provocateur may not survive this.
781 - Check for basic success. Again, our provocateur may not survive this.
782 - Otherwise, the city will disaffect:
783 - Player gets the city.
784 - Player gets certain of the city's present/supported units.
785 - Player gets a technology advance, if any were unknown.
787 - The provocateur may be captured and executed, or escape to its home
790 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
791 this returns TRUE, unit may have died during the action.
792 **************************************************************************/
793 bool diplomat_incite(struct player
*pplayer
, struct unit
*pdiplomat
,
794 struct city
*pcity
, const struct action
*paction
)
796 struct player
*cplayer
;
801 /* Fetch target civilization's player. Sanity checks. */
802 fc_assert_ret_val(pcity
, FALSE
);
803 cplayer
= city_owner(pcity
);
804 fc_assert_ret_val(cplayer
, FALSE
);
806 /* Sanity check: The actor still exists. */
807 fc_assert_ret_val(pplayer
, FALSE
);
808 fc_assert_ret_val(pdiplomat
, FALSE
);
810 /* Sanity check: The target is foreign. */
811 if (cplayer
== pplayer
) {
812 /* Nothing to do to a domestic target. */
816 ctile
= city_tile(pcity
);
817 clink
= city_link(pcity
);
819 log_debug("incite: unit: %d", pdiplomat
->id
);
821 /* Get incite cost, ignoring any previously saved value. */
822 revolt_cost
= city_incite_cost(pplayer
, pcity
);
824 /* If player doesn't have enough gold, can't incite a revolt. */
825 if (pplayer
->economic
.gold
< revolt_cost
) {
826 notify_player(pplayer
, ctile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
827 _("You don't have enough gold to subvert %s."),
829 log_debug("incite: not enough gold");
833 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
834 if (!diplomat_infiltrate_tile(pplayer
, cplayer
,
841 log_debug("incite: infiltrated");
843 /* Check if the Diplomat/Spy succeeds with his/her task. */
844 if (diplomat_was_caught(pplayer
, pdiplomat
, pcity
, cplayer
,
846 notify_player(pplayer
, ctile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
847 _("Your %s was caught in the attempt"
848 " of inciting a revolt!"),
849 unit_tile_link(pdiplomat
));
850 notify_player(cplayer
, ctile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
851 _("You caught %s %s attempting"
852 " to incite a revolt in %s!"),
853 nation_adjective_for_player(pplayer
),
854 unit_tile_link(pdiplomat
),
857 /* This may cause a diplomatic incident */
858 action_consequence_caught(paction
, pplayer
, cplayer
, ctile
, clink
);
860 wipe_unit(pdiplomat
, ULR_CAUGHT
, cplayer
);
864 log_debug("incite: succeeded");
866 /* Subvert the city to your cause... */
868 /* City loses some population. */
869 if (city_size_get(pcity
) > 1) {
870 city_reduce_size(pcity
, 1, pplayer
, "incited");
874 pplayer
->economic
.gold
-= revolt_cost
;
876 /* Notify everybody involved. */
877 notify_player(pplayer
, ctile
, E_MY_DIPLOMAT_INCITE
, ftc_server
,
878 _("Revolt incited in %s, you now rule the city!"),
880 notify_player(cplayer
, ctile
, E_ENEMY_DIPLOMAT_INCITE
, ftc_server
,
881 _("%s has revolted, %s influence suspected."),
883 nation_adjective_for_player(pplayer
));
885 pcity
->shield_stock
= 0;
886 nullify_prechange_production(pcity
);
888 /* You get a technology advance, too! */
889 steal_a_tech(pplayer
, cplayer
, A_UNSET
);
891 /* this may cause a diplomatic incident */
892 action_consequence_success(paction
, pplayer
, cplayer
, ctile
, clink
);
894 /* Transfer city and units supported by this city (that
895 are within one square of the city) to the new owner. */
896 if (transfer_city(pplayer
, pcity
, 1, TRUE
, TRUE
, FALSE
,
897 !is_barbarian(pplayer
))) {
898 script_server_signal_emit("city_transferred", 4,
899 API_TYPE_CITY
, pcity
,
900 API_TYPE_PLAYER
, cplayer
,
901 API_TYPE_PLAYER
, pplayer
,
902 API_TYPE_STRING
, "incited");
905 /* Check if a spy survives her mission.
906 * _After_ transferring the city, or the city area is first fogged
907 * when the diplomat is removed, and then unfogged when the city
909 diplomat_escape_full(pplayer
, pdiplomat
, TRUE
, ctile
, clink
, paction
);
911 /* Update the players gold in the client */
912 send_player_info_c(pplayer
, pplayer
->connections
);
917 /**************************************************************************
918 Sabotage enemy city's improvement or production.
919 If this is untargeted sabotage city a random improvement or production is
921 Targeted sabotage city lets the value of "improvement" decide the target.
922 If "improvement" is -1, sabotage current production.
923 Otherwise, sabotage the city improvement whose ID is "improvement".
925 - Check for infiltration success. Our saboteur may not survive this.
926 - Check for basic success. Again, our saboteur may not survive this.
927 - Determine target, given arguments and constraints.
928 - If specified, city walls and anything in a capital are 50% likely to fail.
931 - The saboteur may be captured and executed, or escape to its home town.
933 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
934 this returns TRUE, unit may have died during the action.
935 **************************************************************************/
936 bool diplomat_sabotage(struct player
*pplayer
, struct unit
*pdiplomat
,
937 struct city
*pcity
, Impr_type_id improvement
,
938 const struct action
*paction
)
940 struct player
*cplayer
;
941 struct impr_type
*ptarget
;
944 /* Fetch target city's player. Sanity checks. */
945 fc_assert_ret_val(pcity
, FALSE
);
946 cplayer
= city_owner(pcity
);
947 fc_assert_ret_val(cplayer
, FALSE
);
949 /* Sanity check: The actor still exists. */
950 fc_assert_ret_val(pplayer
, FALSE
);
951 fc_assert_ret_val(pdiplomat
, FALSE
);
953 log_debug("sabotage: unit: %d", pdiplomat
->id
);
955 /* Check if the Diplomat/Spy succeeds against defending Diplomats/Spies. */
956 if (!diplomat_infiltrate_tile(pplayer
, cplayer
,
963 log_debug("sabotage: infiltrated");
965 /* Check if the Diplomat/Spy succeeds with his/her task. */
966 if (diplomat_was_caught(pplayer
, pdiplomat
, pcity
, cplayer
,
968 notify_player(pplayer
, city_tile(pcity
),
969 E_MY_DIPLOMAT_FAILED
, ftc_server
,
970 _("Your %s was caught in the attempt"
971 " of industrial sabotage!"),
972 unit_tile_link(pdiplomat
));
973 notify_player(cplayer
, city_tile(pcity
),
974 E_ENEMY_DIPLOMAT_SABOTAGE
, ftc_server
,
975 _("You caught %s %s attempting sabotage in %s!"),
976 nation_adjective_for_player(pplayer
),
977 unit_tile_link(pdiplomat
),
980 /* This may cause a diplomatic incident */
981 action_consequence_caught(paction
, pplayer
, cplayer
,
982 city_tile(pcity
), city_link(pcity
));
984 wipe_unit(pdiplomat
, ULR_CAUGHT
, cplayer
);
988 log_debug("sabotage: succeeded");
990 /* Examine the city for improvements to sabotage. */
992 city_built_iterate(pcity
, pimprove
) {
993 if (pimprove
->sabotage
> 0) {
996 } city_built_iterate_end
;
998 log_debug("sabotage: count of improvements: %d", count
);
1000 /* Determine the target (-1 is production). */
1001 if (action_has_result(paction
, ACTION_SPY_SABOTAGE_CITY
)) {
1004 * 50/50 chance to pick production or some improvement.
1005 * Won't pick something that doesn't exit.
1006 * If nothing to do, say so, deduct movement cost and return.
1008 if (count
== 0 && pcity
->shield_stock
== 0) {
1009 notify_player(pplayer
, city_tile(pcity
),
1010 E_MY_DIPLOMAT_FAILED
, ftc_server
,
1011 _("Your %s could not find anything to sabotage in %s."),
1012 unit_link(pdiplomat
),
1014 diplomat_charge_movement(pdiplomat
, pcity
->tile
);
1015 send_unit_info(NULL
, pdiplomat
);
1016 log_debug("sabotage: random: nothing to do");
1019 if (count
== 0 || fc_rand (2) == 1) {
1021 log_debug("sabotage: random: targeted production");
1024 which
= fc_rand (count
);
1026 city_built_iterate(pcity
, pimprove
) {
1027 if (pimprove
->sabotage
> 0) {
1035 } city_built_iterate_end
;
1037 if (NULL
!= ptarget
) {
1038 log_debug("sabotage: random: targeted improvement: %d (%s)",
1039 improvement_number(ptarget
),
1040 improvement_rule_name(ptarget
));
1042 log_error("sabotage: random: targeted improvement error!");
1045 } else if (improvement
< 0) {
1046 /* If told to sabotage production, do so. */
1048 log_debug("sabotage: specified target production");
1050 struct impr_type
*pimprove
= improvement_by_number(improvement
);
1051 if (pimprove
== NULL
) {
1052 log_error("sabotage: requested for invalid improvement %d", improvement
);
1056 * Told which improvement to pick:
1057 * If try for wonder or palace, complain, deduct movement cost and return.
1058 * If not available, say so, deduct movement cost and return.
1060 if (city_has_building(pcity
, pimprove
)) {
1061 if (pimprove
->sabotage
> 0) {
1063 log_debug("sabotage: specified target improvement: %d (%s)",
1064 improvement
, improvement_rule_name(pimprove
));
1066 notify_player(pplayer
, city_tile(pcity
),
1067 E_MY_DIPLOMAT_FAILED
, ftc_server
,
1068 _("You cannot sabotage a %s!"),
1069 improvement_name_translation(pimprove
));
1070 diplomat_charge_movement(pdiplomat
, pcity
->tile
);
1071 send_unit_info(NULL
, pdiplomat
);
1072 log_debug("sabotage: disallowed target improvement: %d (%s)",
1073 improvement
, improvement_rule_name(pimprove
));
1077 notify_player(pplayer
, city_tile(pcity
),
1078 E_MY_DIPLOMAT_FAILED
, ftc_server
,
1079 _("Your %s could not find the %s to sabotage in %s."),
1080 unit_name_translation(pdiplomat
),
1081 improvement_name_translation(pimprove
),
1083 diplomat_charge_movement(pdiplomat
, pcity
->tile
);
1084 send_unit_info(NULL
, pdiplomat
);
1085 log_debug("sabotage: target improvement not found: %d (%s)",
1086 improvement
, improvement_rule_name(pimprove
));
1091 /* Now, the fun stuff! Do the sabotage! */
1092 if (NULL
== ptarget
) {
1096 pcity
->shield_stock
= 0;
1097 nullify_prechange_production(pcity
); /* Make it impossible to recover */
1100 universal_name_translation(&pcity
->production
, prod
, sizeof(prod
));
1102 notify_player(pplayer
, city_tile(pcity
),
1103 E_MY_DIPLOMAT_SABOTAGE
, ftc_server
,
1104 _("Your %s succeeded in destroying"
1105 " the production of %s in %s."),
1106 unit_link(pdiplomat
),
1108 city_name_get(pcity
));
1109 notify_player(cplayer
, city_tile(pcity
),
1110 E_ENEMY_DIPLOMAT_SABOTAGE
, ftc_server
,
1111 _("The production of %s was destroyed in %s,"
1112 " %s are suspected."),
1115 nation_plural_for_player(pplayer
));
1116 log_debug("sabotage: sabotaged production");
1118 int vulnerability
= ptarget
->sabotage
;
1120 /* Sabotage a city improvement. */
1123 * One last chance to get caught:
1124 * If target was specified, and it is in the capital or are
1125 * City Walls, then there is a 50% chance of getting caught.
1127 vulnerability
-= (vulnerability
1128 * get_city_bonus(pcity
, EFT_SABOTEUR_RESISTANT
)
1131 if (fc_rand(100) >= vulnerability
) {
1133 notify_player(pplayer
, city_tile(pcity
),
1134 E_MY_DIPLOMAT_FAILED
, ftc_server
,
1135 _("Your %s was caught in the attempt of sabotage!"),
1136 unit_tile_link(pdiplomat
));
1137 notify_player(cplayer
, city_tile(pcity
),
1138 E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1139 _("You caught %s %s attempting"
1140 " to sabotage the %s in %s!"),
1141 nation_adjective_for_player(pplayer
),
1142 unit_tile_link(pdiplomat
),
1143 improvement_name_translation(ptarget
),
1146 /* This may cause a diplomatic incident */
1147 action_consequence_caught(paction
, pplayer
, cplayer
,
1148 city_tile(pcity
), city_link(pcity
));
1150 wipe_unit(pdiplomat
, ULR_CAUGHT
, cplayer
);
1151 log_debug("sabotage: caught in capital or on city walls");
1156 notify_player(pplayer
, city_tile(pcity
),
1157 E_MY_DIPLOMAT_SABOTAGE
, ftc_server
,
1158 _("Your %s destroyed the %s in %s."),
1159 unit_link(pdiplomat
),
1160 improvement_name_translation(ptarget
),
1162 notify_player(cplayer
, city_tile(pcity
),
1163 E_ENEMY_DIPLOMAT_SABOTAGE
, ftc_server
,
1164 _("The %s destroyed the %s in %s."),
1165 nation_plural_for_player(pplayer
),
1166 improvement_name_translation(ptarget
),
1168 log_debug("sabotage: sabotaged improvement: %d (%s)",
1169 improvement_number(ptarget
),
1170 improvement_rule_name(ptarget
));
1173 building_lost(pcity
, ptarget
);
1176 /* Update clients. */
1177 send_city_info(NULL
, pcity
);
1179 /* this may cause a diplomatic incident */
1180 action_consequence_success(paction
, pplayer
, cplayer
,
1181 city_tile(pcity
), city_link(pcity
));
1183 /* Check if a spy survives her mission. */
1184 diplomat_escape(pplayer
, pdiplomat
, pcity
, paction
);
1189 /**************************************************************************
1190 Steal gold from another player.
1191 The amount stolen is decided randomly.
1192 Not everything stolen reaches the player that ordered it stolen.
1194 - Check for infiltration success. Our thief may not survive this.
1195 - Check for basic success. Again, our thief may not survive this.
1196 - Can't steal if there is no money to take.
1198 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
1199 this returns TRUE, unit may have died during the action.
1200 **************************************************************************/
1201 bool spy_steal_gold(struct player
*act_player
, struct unit
*act_unit
,
1202 struct city
*tgt_city
, const struct action
*paction
)
1204 struct player
*tgt_player
;
1205 struct tile
*tgt_tile
;
1207 const char *tgt_city_link
;
1212 /* Sanity check: The actor still exists. */
1213 fc_assert_ret_val(act_player
, FALSE
);
1214 fc_assert_ret_val(act_unit
, FALSE
);
1216 /* Sanity check: The target city still exists. */
1217 fc_assert_ret_val(tgt_city
, FALSE
);
1219 /* Who to steal from. */
1220 tgt_player
= city_owner(tgt_city
);
1222 /* Sanity check: The target player still exists. */
1223 fc_assert_ret_val(tgt_player
, FALSE
);
1225 /* Sanity check: The target is foreign. */
1226 if (tgt_player
== act_player
) {
1227 /* Nothing to do to a domestic target. */
1231 /* Sanity check: There is something to steal. */
1232 if (tgt_player
->economic
.gold
<= 0) {
1236 tgt_tile
= city_tile(tgt_city
);
1237 tgt_city_link
= city_link(tgt_city
);
1239 log_debug("steal gold: unit: %d", act_unit
->id
);
1241 /* Battle all units capable of diplomatic defence. */
1242 if (!diplomat_infiltrate_tile(act_player
, tgt_player
,
1244 act_unit
, NULL
, tgt_tile
)) {
1248 log_debug("steal gold: infiltrated");
1250 /* The thief may get caught while trying to steal the gold. */
1251 if (diplomat_was_caught(act_player
, act_unit
, tgt_city
, tgt_player
,
1253 notify_player(act_player
, tgt_tile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1254 _("Your %s was caught attempting to steal gold!"),
1255 unit_tile_link(act_unit
));
1256 notify_player(tgt_player
, tgt_tile
, E_ENEMY_DIPLOMAT_FAILED
,
1258 _("You caught %s %s attempting"
1259 " to steal your gold in %s!"),
1260 nation_adjective_for_player(act_player
),
1261 unit_tile_link(act_unit
),
1264 /* This may cause a diplomatic incident */
1265 action_consequence_caught(paction
, act_player
,
1266 tgt_player
, tgt_tile
, tgt_city_link
);
1268 /* Execute the caught thief. */
1269 wipe_unit(act_unit
, ULR_CAUGHT
, tgt_player
);
1274 log_debug("steal gold: succeeded");
1276 /* The upper limit on how much gold the thief can steal. */
1277 gold_take
= (tgt_player
->economic
.gold
1278 * get_city_bonus(tgt_city
, EFT_MAX_STOLEN_GOLD_PM
))
1281 /* How much to actually take. 1 gold is the smallest amount that can be
1282 * stolen. The victim player has at least 1 gold. If he didn't the
1283 * something to steal sanity check would have aborted the theft. */
1284 gold_take
= fc_rand(gold_take
) + 1;
1286 log_debug("steal gold: will take %d gold", gold_take
);
1288 /* Steal the gold. */
1289 tgt_player
->economic
.gold
-= gold_take
;
1291 /* Some gold may be lost during transfer. */
1292 gold_give
= gold_take
1293 - (gold_take
* get_unit_bonus(act_unit
, EFT_THIEFS_SHARE_PM
))
1296 log_debug("steal gold: will give %d gold", gold_give
);
1298 /* Pocket the stolen money. */
1299 act_player
->economic
.gold
+= gold_give
;
1301 /* Notify everyone involved. */
1302 notify_player(act_player
, tgt_tile
, E_MY_SPY_STEAL_GOLD
, ftc_server
,
1303 PL_("Your %s stole %d gold from %s.",
1304 "Your %s stole %d gold from %s.", gold_give
),
1305 unit_link(act_unit
), gold_give
, tgt_city_link
);
1306 notify_player(tgt_player
, tgt_tile
, E_ENEMY_SPY_STEAL_GOLD
, ftc_server
,
1307 PL_("The %s are suspected of stealing %d gold from %s.",
1308 "The %s are suspected of stealing %d gold from %s.",
1310 nation_plural_for_player(act_player
),
1311 gold_take
, tgt_city_link
);
1313 /* This may cause a diplomatic incident. */
1314 action_consequence_success(paction
, act_player
,
1315 tgt_player
, tgt_tile
, tgt_city_link
);
1317 /* Try to escape. */
1318 diplomat_escape_full(act_player
, act_unit
, TRUE
,
1319 tgt_tile
, tgt_city_link
, paction
);
1321 /* Update the players' gold in the client */
1322 send_player_info_c(act_player
, act_player
->connections
);
1323 send_player_info_c(tgt_player
, tgt_player
->connections
);
1328 /**************************************************************************
1329 Steal part of another player's map.
1331 - Check for infiltration success. Our thief may not survive this.
1332 - Check for basic success. Again, our thief may not survive this.
1334 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
1335 this returns TRUE, unit may have died during the action.
1336 **************************************************************************/
1337 bool spy_steal_some_maps(struct player
*act_player
, struct unit
*act_unit
,
1338 struct city
*tgt_city
,
1339 const struct action
*paction
)
1341 struct player
*tgt_player
;
1342 struct tile
*tgt_tile
;
1344 const char *tgt_city_link
;
1346 /* Sanity check: The actor still exists. */
1347 fc_assert_ret_val(act_player
, FALSE
);
1348 fc_assert_ret_val(act_unit
, FALSE
);
1350 /* Sanity check: The target city still exists. */
1351 fc_assert_ret_val(tgt_city
, FALSE
);
1353 /* Who to steal from. */
1354 tgt_player
= city_owner(tgt_city
);
1356 /* Sanity check: The target player still exists. */
1357 fc_assert_ret_val(tgt_player
, FALSE
);
1359 /* Sanity check: The target is foreign. */
1360 if (tgt_player
== act_player
) {
1361 /* Nothing to do to a domestic target. */
1365 tgt_tile
= city_tile(tgt_city
);
1366 tgt_city_link
= city_link(tgt_city
);
1368 log_debug("steal some maps: unit: %d", act_unit
->id
);
1370 /* Battle all units capable of diplomatic defence. */
1371 if (!diplomat_infiltrate_tile(act_player
, tgt_player
,
1373 act_unit
, NULL
, tgt_tile
)) {
1377 log_debug("steal some maps: infiltrated");
1379 /* Try to steal the map. */
1380 if (diplomat_was_caught(act_player
, act_unit
, tgt_city
, tgt_player
,
1382 notify_player(act_player
, tgt_tile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1383 _("Your %s was caught in an attempt of"
1384 " stealing parts of the %s world map!"),
1385 unit_tile_link(act_unit
),
1386 nation_adjective_for_player(tgt_player
));
1387 notify_player(tgt_player
, tgt_tile
, E_ENEMY_DIPLOMAT_FAILED
,
1389 _("You caught %s %s attempting to steal"
1390 " parts of your world map in %s!"),
1391 nation_adjective_for_player(act_player
),
1392 unit_tile_link(act_unit
),
1395 /* This may cause a diplomatic incident. */
1396 action_consequence_caught(paction
, act_player
,
1397 tgt_player
, tgt_tile
, tgt_city_link
);
1399 /* Execute the caught thief. */
1400 wipe_unit(act_unit
, ULR_CAUGHT
, tgt_player
);
1405 log_debug("steal some maps: succeeded");
1408 give_distorted_map(tgt_player
, act_player
, 1, 1, TRUE
);
1410 /* Notify everyone involved. */
1411 notify_player(act_player
, tgt_tile
, E_MY_SPY_STEAL_MAP
, ftc_server
,
1412 _("Your %s stole parts of the %s world map in %s."),
1413 unit_link(act_unit
),
1414 nation_adjective_for_player(tgt_player
),
1416 notify_player(tgt_player
, tgt_tile
, E_ENEMY_SPY_STEAL_MAP
, ftc_server
,
1417 _("The %s are suspected of stealing"
1418 " parts of your world map in %s."),
1419 nation_plural_for_player(act_player
),
1422 /* This may cause a diplomatic incident. */
1423 action_consequence_success(paction
, act_player
,
1424 tgt_player
, tgt_tile
, tgt_city_link
);
1426 /* Try to escape. */
1427 diplomat_escape_full(act_player
, act_unit
, TRUE
,
1428 tgt_tile
, tgt_city_link
, paction
);
1433 /**************************************************************************
1434 Hide a suitcase nuke in a city and detonate it.
1436 - Check for infiltration success. Our thief may not survive this.
1437 - Check for basic success. Again, our thief may not survive this.
1439 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
1440 this returns TRUE, unit may have died during the action.
1441 **************************************************************************/
1442 bool spy_nuke_city(struct player
*act_player
, struct unit
*act_unit
,
1443 struct city
*tgt_city
, const struct action
*paction
)
1445 struct player
*tgt_player
;
1446 struct tile
*tgt_tile
;
1448 const char *tgt_city_link
;
1450 /* Sanity check: The actor still exists. */
1451 fc_assert_ret_val(act_player
, FALSE
);
1452 fc_assert_ret_val(act_unit
, FALSE
);
1454 /* Sanity check: The target city still exists. */
1455 fc_assert_ret_val(tgt_city
, FALSE
);
1458 tgt_player
= city_owner(tgt_city
);
1460 /* Sanity check: The target player still exists. */
1461 fc_assert_ret_val(tgt_player
, FALSE
);
1463 tgt_tile
= city_tile(tgt_city
);
1464 tgt_city_link
= city_link(tgt_city
);
1466 log_debug("suitcase nuke: unit: %d", act_unit
->id
);
1468 /* Battle all units capable of diplomatic defense. */
1469 if (!diplomat_infiltrate_tile(act_player
, tgt_player
,
1471 act_unit
, NULL
, tgt_tile
)) {
1475 log_debug("suitcase nuke: infiltrated");
1477 /* Try to hide the nuke. */
1478 if (diplomat_was_caught(act_player
, act_unit
, tgt_city
, tgt_player
,
1480 notify_player(act_player
, tgt_tile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1481 _("Your %s was caught in an attempt of"
1482 " hiding a nuke in %s!"),
1483 unit_tile_link(act_unit
),
1485 notify_player(tgt_player
, tgt_tile
, E_ENEMY_DIPLOMAT_FAILED
,
1487 _("You caught %s %s attempting to hide a nuke in %s!"),
1488 nation_adjective_for_player(act_player
),
1489 unit_tile_link(act_unit
),
1492 /* This may cause a diplomatic incident. */
1493 action_consequence_caught(paction
, act_player
,
1494 tgt_player
, tgt_tile
, tgt_city_link
);
1496 /* Execute the caught terrorist. */
1497 wipe_unit(act_unit
, ULR_CAUGHT
, tgt_player
);
1502 log_debug("suitcase nuke: succeeded");
1504 /* Notify everyone involved. */
1505 notify_player(act_player
, tgt_tile
, E_MY_SPY_NUKE
, ftc_server
,
1506 _("Your %s hid a nuke in %s."),
1507 unit_link(act_unit
),
1509 notify_player(tgt_player
, tgt_tile
, E_ENEMY_SPY_NUKE
, ftc_server
,
1510 _("The %s are suspected of hiding a nuke in %s."),
1511 nation_plural_for_player(act_player
),
1514 /* Try to escape before the blast. */
1515 diplomat_escape_full(act_player
, act_unit
, TRUE
,
1516 tgt_tile
, tgt_city_link
, paction
);
1518 if (utype_is_consumed_by_action(paction
, unit_type_get(act_unit
))) {
1519 /* The unit must be wiped here so it won't be seen as a victim of the
1520 * detonation of its own nuke. */
1521 wipe_unit(act_unit
, ULR_USED
, NULL
);
1524 /* TODO: In real life a suitcase nuke is way less powerful than an ICBM.
1525 * Maybe the size of the suitcase nuke explosion should be ruleset
1528 /* Detonate the nuke. */
1529 dlsend_packet_nuke_tile_info(game
.est_connections
, tile_index(tgt_tile
));
1530 do_nuclear_explosion(act_player
, tgt_tile
);
1532 /* This may cause a diplomatic incident. */
1533 action_consequence_success(paction
, act_player
,
1534 tgt_player
, tgt_tile
, tgt_city_link
);
1539 /**************************************************************************
1540 Returns TRUE iff the spy/diplomat was caught outside of a diplomatic
1542 **************************************************************************/
1543 static bool diplomat_was_caught(struct player
*act_player
,
1544 struct unit
*act_unit
,
1545 struct city
*tgt_city
,
1546 struct player
*tgt_player
,
1547 const struct action
*act
)
1551 /* Take the odds from the diplchance setting. */
1552 odds
= game
.server
.diplchance
;
1554 /* Let the Action_Odds_Pct effect modify the odds. The advantage of doing
1555 * it this way in stead of rolling twice is that Action_Odds_Pct can
1556 * increase the odds. */
1558 * get_target_bonus_effects(NULL
,
1559 act_player
, tgt_player
,
1560 tgt_city
, NULL
, NULL
,
1561 act_unit
, unit_type_get(act_unit
),
1563 EFT_ACTION_ODDS_PCT
))
1566 /* Roll the dice. */
1567 return fc_rand (100) >= odds
;
1570 /**************************************************************************
1571 This subtracts the destination movement cost from a diplomat/spy.
1572 **************************************************************************/
1573 static void diplomat_charge_movement(struct unit
*pdiplomat
, struct tile
*ptile
)
1575 pdiplomat
->moves_left
-=
1576 map_move_cost_unit(&(wld
.map
), pdiplomat
, ptile
);
1577 if (pdiplomat
->moves_left
< 0) {
1578 pdiplomat
->moves_left
= 0;
1582 /**************************************************************************
1583 This determines if a diplomat/spy succeeds against some defender,
1584 who is also a diplomat or spy. Note: a superspy defender always
1585 succeeds, otherwise a superspy attacker always wins.
1587 Return TRUE if the "attacker" succeeds.
1588 **************************************************************************/
1589 static bool diplomat_success_vs_defender(struct unit
*pattacker
,
1590 struct unit
*pdefender
,
1591 struct tile
*pdefender_tile
)
1593 int chance
= 50; /* Base 50% chance */
1595 if (unit_has_type_flag(pdefender
, UTYF_SUPERSPY
)) {
1596 /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
1599 if (unit_has_type_flag(pattacker
, UTYF_SUPERSPY
)) {
1600 /* An attacking UTYF_SUPERSPY will defeat every possible defender
1601 * except another UTYF_SUPERSPY. */
1605 /* Add or remove 25% if spy flag. */
1606 if (unit_has_type_flag(pattacker
, UTYF_SPY
)) {
1609 if (unit_has_type_flag(pdefender
, UTYF_SPY
)) {
1613 /* Use power_fact from veteran level to modify chance in a linear way.
1614 * Equal veteran levels cancel out.
1615 * It's probably not good for rulesets to allow this to have more than
1618 const struct veteran_level
1619 *vatt
= utype_veteran_level(unit_type_get(pattacker
), pattacker
->veteran
);
1620 const struct veteran_level
1621 *vdef
= utype_veteran_level(unit_type_get(pdefender
), pdefender
->veteran
);
1622 fc_assert_ret_val(vatt
!= NULL
&& vdef
!= NULL
, FALSE
);
1623 chance
+= vatt
->power_fact
- vdef
->power_fact
;
1626 /* Reduce the chance of an attack by EFT_SPY_RESISTANT percent. */
1628 * get_target_bonus_effects(NULL
,
1629 tile_owner(pdefender_tile
), NULL
,
1630 tile_city(pdefender_tile
), NULL
,
1631 pdefender_tile
, NULL
, NULL
, NULL
,
1633 EFT_SPY_RESISTANT
) / 100;
1635 return (int)fc_rand(100) < chance
;
1638 /**************************************************************************
1639 This determines if a diplomat/spy succeeds in infiltrating a tile.
1641 - The infiltrator must go up against each defender.
1642 - The victim unit won't defend. (NULL if everyone should defend)
1643 - One or the other is eliminated in each contest.
1645 - Return TRUE if the infiltrator succeeds.
1647 'pplayer' is the player who tries to do a spy/diplomat action on 'ptile'
1648 with the unit 'pdiplomat' against 'cplayer'.
1649 **************************************************************************/
1650 static bool diplomat_infiltrate_tile(struct player
*pplayer
,
1651 struct player
*cplayer
,
1652 const struct action
*paction
,
1653 struct unit
*pdiplomat
,
1654 struct unit
*pvictim
,
1657 char link_city
[MAX_LEN_LINK
] = "";
1658 char link_diplomat
[MAX_LEN_LINK
];
1659 char link_unit
[MAX_LEN_LINK
];
1660 struct city
*pcity
= tile_city(ptile
);
1663 /* N.B.: *_link() always returns the same pointer. */
1664 sz_strlcpy(link_city
, city_link(pcity
));
1667 /* We don't need a _safe iterate since no transporters should be
1669 unit_list_iterate(ptile
->units
, punit
) {
1670 struct player
*uplayer
= unit_owner(punit
);
1672 /* I can't confirm if we won't deny that we weren't involved. */
1673 if (uplayer
== pplayer
) {
1677 if (punit
== pvictim
1678 && !unit_has_type_flag(punit
, UTYF_SUPERSPY
)) {
1679 /* The victim unit is defenseless unless it's a SuperSpy.
1680 * Rationalization: A regular diplomat don't mind being bribed. A
1681 * SuperSpy is high enough up the chain that accepting a bribe is
1682 * against his own interests. */
1686 if (unit_has_type_flag(punit
, UTYF_DIPLOMAT
)
1687 || unit_has_type_flag(punit
, UTYF_SUPERSPY
)) {
1688 /* A UTYF_SUPERSPY unit may not actually be a spy, but a superboss
1689 * which we cannot allow puny diplomats from getting the better
1690 * of. UTYF_SUPERSPY vs UTYF_SUPERSPY in a diplomatic contest always
1691 * kills the attacker. */
1693 if (diplomat_success_vs_defender(pdiplomat
, punit
, ptile
)) {
1694 /* Defending Spy/Diplomat dies. */
1696 /* N.B.: *_link() always returns the same pointer. */
1697 sz_strlcpy(link_unit
, unit_tile_link(punit
));
1698 sz_strlcpy(link_diplomat
, unit_link(pdiplomat
));
1700 notify_player(pplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1701 /* TRANS: <unit> ... <diplomat> */
1702 _("An enemy %s has been eliminated by your %s."),
1703 link_unit
, link_diplomat
);
1706 if (uplayer
== cplayer
) {
1707 notify_player(cplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1708 /* TRANS: <unit> ... <city> ... <diplomat> */
1709 _("Your %s has been eliminated defending %s"
1710 " against a %s."), link_unit
, link_city
,
1713 notify_player(cplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1714 /* TRANS: <nation adj> <unit> ... <city>
1715 * TRANS: ... <diplomat> */
1716 _("A %s %s has been eliminated defending %s "
1718 nation_adjective_for_player(uplayer
),
1719 link_unit
, link_city
, link_diplomat
);
1720 notify_player(uplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1721 /* TRANS: ... <unit> ... <nation adj> <city>
1722 * TRANS: ... <diplomat> */
1723 _("Your %s has been eliminated defending %s %s "
1724 "against a %s."), link_unit
,
1725 nation_adjective_for_player(cplayer
),
1726 link_city
, link_diplomat
);
1729 if (uplayer
== cplayer
) {
1730 notify_player(cplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1731 /* TRANS: <unit> ... <diplomat> */
1732 _("Your %s has been eliminated defending "
1733 "against a %s."), link_unit
, link_diplomat
);
1735 notify_player(cplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1736 /* TRANS: <nation adj> <unit> ... <diplomat> */
1737 _("A %s %s has been eliminated defending "
1739 nation_adjective_for_player(uplayer
),
1740 link_unit
, link_diplomat
);
1741 notify_player(uplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1742 /* TRANS: ... <unit> ... <diplomat> */
1743 _("Your %s has been eliminated defending "
1744 "against a %s."), link_unit
, link_diplomat
);
1748 pdiplomat
->moves_left
= MAX(0, pdiplomat
->moves_left
- SINGLE_MOVE
);
1750 /* Attacking unit became more experienced? */
1751 if (maybe_make_veteran(pdiplomat
)) {
1752 notify_unit_experience(pdiplomat
);
1754 send_unit_info(NULL
, pdiplomat
);
1755 wipe_unit(punit
, ULR_ELIMINATED
, pplayer
);
1758 /* Attacking Spy/Diplomat dies. */
1760 const char *victim_link
;
1762 /* N.B.: *_link() always returns the same pointer. */
1763 sz_strlcpy(link_unit
, unit_link(punit
));
1764 sz_strlcpy(link_diplomat
, unit_tile_link(pdiplomat
));
1766 notify_player(pplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1767 _("Your %s was eliminated by a defending %s."),
1768 link_diplomat
, link_unit
);
1771 if (uplayer
== cplayer
) {
1772 notify_player(cplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1773 _("Eliminated a %s %s while infiltrating %s."),
1774 nation_adjective_for_player(pplayer
),
1775 link_diplomat
, link_city
);
1777 notify_player(cplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1778 _("A %s %s eliminated a %s %s while infiltrating "
1779 "%s."), nation_adjective_for_player(uplayer
),
1780 link_unit
, nation_adjective_for_player(pplayer
),
1781 link_diplomat
, link_city
);
1782 notify_player(uplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1783 _("Your %s eliminated a %s %s while infiltrating "
1785 nation_adjective_for_player(pplayer
),
1786 link_diplomat
, link_city
);
1789 if (uplayer
== cplayer
) {
1790 notify_player(cplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1791 _("Eliminated a %s %s while infiltrating our troops."),
1792 nation_adjective_for_player(pplayer
),
1795 notify_player(cplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1796 _("A %s %s eliminated a %s %s while infiltrating our "
1797 "troops."), nation_adjective_for_player(uplayer
),
1798 link_unit
, nation_adjective_for_player(pplayer
),
1800 notify_player(uplayer
, ptile
, E_ENEMY_DIPLOMAT_FAILED
, ftc_server
,
1801 /* TRANS: ... <unit> ... <diplomat> */
1802 _("Your %s eliminated a %s %s while infiltrating our "
1803 "troops."), link_unit
,
1804 nation_adjective_for_player(pplayer
),
1809 /* Defending unit became more experienced? */
1810 if (maybe_make_veteran(punit
)) {
1811 notify_unit_experience(punit
);
1814 switch (action_get_target_kind(paction
)) {
1816 victim_link
= city_link(pcity
);
1820 victim_link
= pvictim
? unit_tile_link(pvictim
)
1824 victim_link
= tile_link(ptile
);
1827 /* How did a self targeted action end up here? */
1828 fc_assert(action_get_target_kind(paction
) != ATK_SELF
);
1834 fc_assert(victim_link
!= NULL
);
1836 action_consequence_caught(paction
, pplayer
, cplayer
,
1837 ptile
, victim_link
);
1839 wipe_unit(pdiplomat
, ULR_ELIMINATED
, uplayer
);
1843 } unit_list_iterate_end
;
1848 /**************************************************************************
1849 This determines if a diplomat/spy survives and escapes.
1850 If "pcity" is NULL, assume action was in the field.
1852 Spies have a game.server.diplchance specified chance of survival (better
1854 - Diplomats always die.
1855 - Escapes to home city.
1856 - Escapee may become a veteran.
1857 **************************************************************************/
1858 static void diplomat_escape(struct player
*pplayer
, struct unit
*pdiplomat
,
1859 const struct city
*pcity
,
1860 const struct action
*paction
)
1866 ptile
= city_tile(pcity
);
1867 vlink
= city_link(pcity
);
1869 ptile
= unit_tile(pdiplomat
);
1873 return diplomat_escape_full(pplayer
, pdiplomat
, pcity
!= NULL
,
1874 ptile
, vlink
, paction
);
1877 /**************************************************************************
1878 This determines if a diplomat/spy survives and escapes.
1880 Spies have a game.server.diplchance specified chance of survival (better
1882 - Diplomats always die.
1883 - Escapes to home city.
1884 - Escapee may become a veteran.
1885 **************************************************************************/
1886 static void diplomat_escape_full(struct player
*pplayer
,
1887 struct unit
*pdiplomat
,
1891 const struct action
*paction
)
1894 struct city
*spyhome
;
1896 /* Veteran level's power factor's effect on escape chance is relative to
1897 * unpromoted unit's power factor */
1899 const struct veteran_level
1900 *vunit
= utype_veteran_level(unit_type_get(pdiplomat
), pdiplomat
->veteran
);
1901 const struct veteran_level
1902 *vbase
= utype_veteran_level(unit_type_get(pdiplomat
), 0);
1904 escapechance
= game
.server
.diplchance
1905 + (vunit
->power_fact
- vbase
->power_fact
);
1908 /* find closest city for escape target */
1909 spyhome
= find_closest_city(ptile
, NULL
, unit_owner(pdiplomat
), FALSE
,
1910 FALSE
, FALSE
, TRUE
, FALSE
, NULL
);
1913 && !utype_is_consumed_by_action(paction
, unit_type_get(pdiplomat
))
1914 && (unit_has_type_flag(pdiplomat
, UTYF_SUPERSPY
)
1915 || fc_rand (100) < escapechance
)) {
1916 /* Attacking Spy/Diplomat survives. */
1917 notify_player(pplayer
, ptile
, E_MY_DIPLOMAT_ESCAPE
, ftc_server
,
1918 _("Your %s has successfully completed"
1919 " the mission and returned unharmed to %s."),
1920 unit_link(pdiplomat
),
1921 city_link(spyhome
));
1922 if (maybe_make_veteran(pdiplomat
)) {
1923 notify_unit_experience(pdiplomat
);
1926 /* being teleported costs all movement */
1927 if (!teleport_unit_to_city (pdiplomat
, spyhome
, -1, FALSE
)) {
1928 send_unit_info(NULL
, pdiplomat
);
1929 log_error("Bug in diplomat_escape: Spy can't teleport.");
1936 notify_player(pplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1937 _("Your %s was captured after completing"
1938 " the mission in %s."),
1939 unit_tile_link(pdiplomat
),
1942 notify_player(pplayer
, ptile
, E_MY_DIPLOMAT_FAILED
, ftc_server
,
1943 _("Your %s was captured after completing"
1945 unit_tile_link(pdiplomat
));
1949 if (!utype_is_consumed_by_action(paction
, unit_type_get(pdiplomat
))) {
1950 /* The unit was caught, not spent. It must therefore be deleted by
1952 wipe_unit(pdiplomat
, ULR_CAUGHT
, NULL
);
1956 /**************************************************************************
1957 return number of diplomats on this square. AJS 20000130
1958 **************************************************************************/
1959 int count_diplomats_on_tile(struct tile
*ptile
)
1963 unit_list_iterate((ptile
)->units
, punit
) {
1964 if (unit_has_type_flag(punit
, UTYF_DIPLOMAT
)) {
1967 } unit_list_iterate_end
;