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