1 /***********************************************************************
2 Freeciv - Copyright (C) 1996-2015 - Freeciv Development Team
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>
26 #include "unittools.h"
28 #include "actiontools.h"
30 typedef void (*action_notify
)(struct player
*,
31 const struct action
*,
37 /**************************************************************************
38 Wipe an actor if the action it successfully performed consumed it.
39 **************************************************************************/
40 void action_success_actor_consume(struct action
*paction
,
41 int actor_id
, struct unit
*actor
)
43 if (unit_is_alive(actor_id
)
44 && utype_is_consumed_by_action(paction
, unit_type_get(actor
))) {
45 if (action_has_result(paction
, ACTION_DISBAND_UNIT
)
46 || action_has_result(paction
, ACTION_RECYCLE_UNIT
)) {
47 wipe_unit(actor
, ULR_DISBANDED
, NULL
);
48 } else if (action_has_result(paction
, ACTION_NUKE
)) {
49 wipe_unit(actor
, ULR_DETONATED
, NULL
);
50 } else if (action_has_result(paction
, ACTION_ATTACK
)) {
51 wipe_unit(actor
, ULR_MISSILE
, NULL
);
53 wipe_unit(actor
, ULR_USED
, NULL
);
58 /**************************************************************************
59 Give the victim a casus belli against the offender.
60 **************************************************************************/
61 static void action_give_casus_belli(struct player
*offender
,
62 struct player
*victim_player
,
66 /* This action is seen as a reason for any other player, no matter who
67 * the victim was, to declare war on the actor. It could be used to
68 * label certain actions atrocities in rule sets where international
69 * outrage over an action fits the setting. */
71 players_iterate(oplayer
) {
72 if (oplayer
!= offender
) {
73 player_diplstate_get(oplayer
, offender
)->has_reason_to_cancel
= 2;
75 } players_iterate_end
;
76 } else if (victim_player
&& offender
!= victim_player
) {
77 /* If an unclaimed tile is nuked there is no victim to give casus
78 * belli. If an actor nukes his own tile he is more than willing to
79 * forgive him self. */
81 /* Give the victim player a casus belli. */
82 player_diplstate_get(victim_player
, offender
)->has_reason_to_cancel
=
87 /**************************************************************************
88 Returns the kind of diplomatic incident an action may cause.
89 **************************************************************************/
90 static enum incident_type
action_to_incident(const int action_id
)
92 if (action_id
== ACTION_NUKE
93 || action_id
== ACTION_SPY_NUKE
94 || action_id
== ACTION_SPY_NUKE_ESC
) {
95 return INCIDENT_NUCLEAR
;
97 /* FIXME: Some actions are neither nuclear nor diplomat. */
98 return INCIDENT_DIPLOMAT
;
102 /**************************************************************************
103 Notify the players controlled by the built in AI.
104 **************************************************************************/
105 static void action_notify_ai(const struct action
*paction
,
106 struct player
*offender
,
107 struct player
*victim_player
)
109 const int incident
= action_to_incident(paction
->id
);
111 /* Notify the victim player. */
112 call_incident(incident
, offender
, victim_player
);
114 if (incident
== INCIDENT_NUCLEAR
) {
115 /* Tell the world. */
116 if (offender
== victim_player
) {
117 players_iterate(oplayer
) {
118 if (victim_player
!= oplayer
) {
119 call_incident(INCIDENT_NUCLEAR_SELF
, offender
, oplayer
);
121 } players_iterate_end
;
123 players_iterate(oplayer
) {
124 if (victim_player
!= oplayer
) {
125 call_incident(INCIDENT_NUCLEAR_NOT_TARGET
, offender
, oplayer
);
127 } players_iterate_end
;
131 /* TODO: Should incident be called when the ai gets a casus belli because
132 * of something done to a third party? If yes: should a new incident kind
136 /**************************************************************************
137 Take care of any consequences (like casus belli) of the given action
138 when the situation was as specified.
140 victim_player can be NULL
141 **************************************************************************/
142 static void action_consequence_common(const struct action
*paction
,
143 struct player
*offender
,
144 struct player
*victim_player
,
145 const struct tile
*victim_tile
,
146 const char *victim_link
,
147 const action_notify notify_actor
,
148 const action_notify notify_victim
,
149 const action_notify notify_global
,
150 const enum effect_type eft
)
152 int casus_belli_amount
;
154 /* The victim gets a casus belli if 1 or above. Everyone gets a casus
155 * belli if 1000 or above. */
157 get_target_bonus_effects(NULL
,
158 offender
, victim_player
,
159 tile_city(victim_tile
),
167 if (casus_belli_amount
>= 1) {
168 /* In this situation the specified action provides a casus belli
169 * against the actor. */
171 /* This isn't just between the offender and the victim. */
172 const bool global
= casus_belli_amount
>= 1000;
174 /* Notify the involved players by sending them a message. */
175 notify_actor(offender
, paction
, offender
, victim_player
,
176 victim_tile
, victim_link
);
177 notify_victim(victim_player
, paction
, offender
, victim_player
,
178 victim_tile
, victim_link
);
181 /* Every other player gets a casus belli against the actor. Tell each
182 * players about it. */
183 players_iterate(oplayer
) {
184 notify_global(oplayer
, paction
, offender
,
185 victim_player
, victim_tile
, victim_link
);
186 } players_iterate_end
;
189 /* Give casus belli. */
190 action_give_casus_belli(offender
, victim_player
, global
);
192 /* Notify players controlled by the built in AI. */
193 action_notify_ai(paction
, offender
, victim_player
);
195 /* Update the clients. */
196 send_player_all_c(offender
, NULL
);
198 if (victim_player
!= NULL
&& victim_player
!= offender
) {
199 /* The actor player was just sent. */
200 /* An action against an ownerless tile is victimless. */
201 send_player_all_c(victim_player
, NULL
);
206 /**************************************************************************
207 Notify the actor that the failed action gave the victim a casus belli
209 **************************************************************************/
210 static void notify_actor_caught(struct player
*receiver
,
211 const struct action
*paction
,
212 struct player
*offender
,
213 struct player
*victim_player
,
214 const struct tile
*victim_tile
,
215 const char *victim_link
)
217 if (!victim_player
|| offender
== victim_player
) {
218 /* There is no victim or the actor did this to him self. */
222 /* Custom message based on action type. */
223 switch (action_get_target_kind(paction
)) {
225 notify_player(receiver
, victim_tile
,
226 E_DIPLOMATIC_INCIDENT
, ftc_server
,
227 /* TRANS: Suitcase Nuke ... San Francisco */
228 _("You have caused an incident getting caught"
229 " trying to do %s to %s."),
230 action_name_translation(paction
),
235 notify_player(receiver
, victim_tile
,
236 E_DIPLOMATIC_INCIDENT
, ftc_server
,
237 /* Bribe Enemy Unit ... American ... Partisan */
238 _("You have caused an incident getting caught"
239 " trying to do %s to %s %s."),
240 action_name_translation(paction
),
241 nation_adjective_for_player(victim_player
),
245 /* Explode Nuclear ... (54, 26) */
246 notify_player(receiver
, victim_tile
,
247 E_DIPLOMATIC_INCIDENT
, ftc_server
,
248 _("You have caused an incident getting caught"
249 " trying to do %s at %s."),
250 action_name_translation(paction
),
254 /* Special actor notice not needed. Actor is victim. */
257 fc_assert(ATK_COUNT
!= ATK_COUNT
);
262 /**************************************************************************
263 Notify the victim that the failed action gave the victim a
264 casus belli against the actor.
265 **************************************************************************/
266 static void notify_victim_caught(struct player
*receiver
,
267 const struct action
*paction
,
268 struct player
*offender
,
269 struct player
*victim_player
,
270 const struct tile
*victim_tile
,
271 const char *victim_link
)
273 if (!victim_player
|| offender
== victim_player
) {
274 /* There is no victim or the actor did this to him self. */
278 /* Custom message based on action type. */
279 switch (action_get_target_kind(paction
)) {
281 notify_player(receiver
, victim_tile
,
282 E_DIPLOMATIC_INCIDENT
, ftc_server
,
283 /* TRANS: Europeans ... Suitcase Nuke ... San Francisco */
284 _("The %s have caused an incident getting caught"
285 " trying to do %s to %s."),
286 nation_plural_for_player(offender
),
287 action_name_translation(paction
),
292 notify_player(receiver
, victim_tile
,
293 E_DIPLOMATIC_INCIDENT
, ftc_server
,
294 /* Europeans ... Bribe Enemy Unit ... Partisan */
295 _("The %s have caused an incident getting caught"
296 " trying to do %s to your %s."),
297 nation_plural_for_player(offender
),
298 action_name_translation(paction
),
302 notify_player(receiver
, victim_tile
,
303 E_DIPLOMATIC_INCIDENT
, ftc_server
,
304 /* Europeans ... Explode Nuclear ... (54, 26) */
305 _("The %s have caused an incident getting caught"
306 " trying to do %s at %s."),
307 nation_plural_for_player(offender
),
308 action_name_translation(paction
),
312 /* Special victim notice not needed. Actor is victim. */
315 fc_assert(ATK_COUNT
!= ATK_COUNT
);
320 /**************************************************************************
321 Notify the world that the failed action gave the everyone a casus belli
323 **************************************************************************/
324 static void notify_global_caught(struct player
*receiver
,
325 const struct action
*paction
,
326 struct player
*offender
,
327 struct player
*victim_player
,
328 const struct tile
*victim_tile
,
329 const char *victim_link
)
331 if (receiver
== offender
) {
332 notify_player(receiver
, victim_tile
,
333 E_DIPLOMATIC_INCIDENT
, ftc_server
,
334 /* TRANS: Suitcase Nuke */
335 _("Getting caught while trying to do %s gives "
336 "everyone a casus belli against you."),
337 action_name_translation(paction
));
338 } else if (receiver
== victim_player
) {
339 notify_player(receiver
, victim_tile
,
340 E_DIPLOMATIC_INCIDENT
, ftc_server
,
341 /* TRANS: Suitcase Nuke ... Europeans */
342 _("Getting caught while trying to do %s to you gives "
343 "everyone a casus belli against the %s."),
344 action_name_translation(paction
),
345 nation_plural_for_player(offender
));
346 } else if (victim_player
== NULL
) {
347 notify_player(receiver
, victim_tile
,
348 E_DIPLOMATIC_INCIDENT
, ftc_server
,
349 /* TRANS: Europeans ... Suitcase Nuke */
350 _("You now have a casus belli against the %s. "
351 "They got caught trying to do %s."),
352 nation_plural_for_player(offender
),
353 action_name_translation(paction
));
355 notify_player(receiver
, victim_tile
,
356 E_DIPLOMATIC_INCIDENT
, ftc_server
,
357 /* TRANS: Europeans ... Suitcase Nuke ... Americans */
358 _("You now have a casus belli against the %s. "
359 "They got caught trying to do %s to the %s."),
360 nation_plural_for_player(offender
),
361 action_name_translation(paction
),
362 nation_plural_for_player(victim_player
));
366 /**************************************************************************
367 Take care of any consequences (like casus belli) of getting caught while
368 trying to perform the given action.
370 victim_player can be NULL
371 **************************************************************************/
372 void action_consequence_caught(const struct action
*paction
,
373 struct player
*offender
,
374 struct player
*victim_player
,
375 const struct tile
*victim_tile
,
376 const char *victim_link
)
379 action_consequence_common(paction
, offender
,
380 victim_player
, victim_tile
, victim_link
,
382 notify_victim_caught
,
383 notify_global_caught
,
384 EFT_CASUS_BELLI_CAUGHT
);
387 /**************************************************************************
388 Notify the actor that the performed action gave the victim a casus belli
390 **************************************************************************/
391 static void notify_actor_success(struct player
*receiver
,
392 const struct action
*paction
,
393 struct player
*offender
,
394 struct player
*victim_player
,
395 const struct tile
*victim_tile
,
396 const char *victim_link
)
398 if (!victim_player
|| offender
== victim_player
) {
399 /* There is no victim or the actor did this to him self. */
403 /* Custom message based on action type. */
404 switch (action_get_target_kind(paction
)) {
406 notify_player(receiver
, victim_tile
,
407 E_DIPLOMATIC_INCIDENT
, ftc_server
,
408 /* TRANS: Suitcase Nuke ... San Francisco */
409 _("You have caused an incident doing %s to %s."),
410 action_name_translation(paction
),
415 notify_player(receiver
, victim_tile
,
416 E_DIPLOMATIC_INCIDENT
, ftc_server
,
417 /* Bribe Enemy Unit ... American ... Partisan */
418 _("You have caused an incident doing %s to %s %s."),
419 action_name_translation(paction
),
420 nation_adjective_for_player(victim_player
),
424 notify_player(receiver
, victim_tile
,
425 E_DIPLOMATIC_INCIDENT
, ftc_server
,
426 /* Explode Nuclear ... (54, 26) */
427 _("You have caused an incident doing %s at %s."),
428 action_name_translation(paction
),
432 /* Special actor notice not needed. Actor is victim. */
435 fc_assert(ATK_COUNT
!= ATK_COUNT
);
440 /**************************************************************************
441 Notify the victim that the performed action gave the victim a casus
442 belli against the actor.
443 **************************************************************************/
444 static void notify_victim_success(struct player
*receiver
,
445 const struct action
*paction
,
446 struct player
*offender
,
447 struct player
*victim_player
,
448 const struct tile
*victim_tile
,
449 const char *victim_link
)
451 if (!victim_player
|| offender
== victim_player
) {
452 /* There is no victim or the actor did this to him self. */
456 /* Custom message based on action type. */
457 switch (action_get_target_kind(paction
)) {
459 notify_player(receiver
, victim_tile
,
460 E_DIPLOMATIC_INCIDENT
, ftc_server
,
461 /* TRANS: Europeans ... Suitcase Nuke ... San Francisco */
462 _("The %s have caused an incident doing %s to %s."),
463 nation_plural_for_player(offender
),
464 action_name_translation(paction
),
469 notify_player(receiver
, victim_tile
,
470 E_DIPLOMATIC_INCIDENT
, ftc_server
,
471 /* Europeans ... Bribe Enemy Unit ... Partisan */
472 _("The %s have caused an incident doing "
474 nation_plural_for_player(offender
),
475 action_name_translation(paction
),
479 notify_player(receiver
, victim_tile
,
480 E_DIPLOMATIC_INCIDENT
, ftc_server
,
481 /* Europeans ... Explode Nuclear ... (54, 26) */
482 _("The %s have caused an incident doing %s at %s."),
483 nation_plural_for_player(offender
),
484 action_name_translation(paction
),
488 /* Special victim notice not needed. Actor is victim. */
491 fc_assert(ATK_COUNT
!= ATK_COUNT
);
496 /**************************************************************************
497 Notify the world that the performed action gave the everyone a casus
498 belli against the actor.
499 **************************************************************************/
500 static void notify_global_success(struct player
*receiver
,
501 const struct action
*paction
,
502 struct player
*offender
,
503 struct player
*victim_player
,
504 const struct tile
*victim_tile
,
505 const char *victim_link
)
507 if (receiver
== offender
) {
508 notify_player(receiver
, victim_tile
,
509 E_DIPLOMATIC_INCIDENT
, ftc_server
,
510 /* TRANS: Suitcase Nuke */
511 _("Doing %s gives everyone a casus belli against you."),
512 action_name_translation(paction
));
513 } else if (receiver
== victim_player
) {
514 notify_player(receiver
, victim_tile
,
515 E_DIPLOMATIC_INCIDENT
, ftc_server
,
516 /* TRANS: Suitcase Nuke ... Europeans */
517 _("Doing %s to you gives everyone a casus belli against "
519 action_name_translation(paction
),
520 nation_plural_for_player(offender
));
521 } else if (victim_player
== NULL
) {
522 notify_player(receiver
, victim_tile
,
523 E_DIPLOMATIC_INCIDENT
, ftc_server
,
524 /* TRANS: Europeans ... Suitcase Nuke */
525 _("You now have a casus belli against the %s. "
527 nation_plural_for_player(offender
),
528 action_name_translation(paction
));
530 notify_player(receiver
, victim_tile
,
531 E_DIPLOMATIC_INCIDENT
, ftc_server
,
532 /* TRANS: Europeans ... Suitcase Nuke ... Americans */
533 _("You now have a casus belli against the %s. "
534 "They did %s to the %s."),
535 nation_plural_for_player(offender
),
536 action_name_translation(paction
),
537 nation_plural_for_player(victim_player
));
541 /**************************************************************************
542 Take care of any consequences (like casus belli) of successfully
543 performing the given action.
545 victim_player can be NULL
546 **************************************************************************/
547 void action_consequence_success(const struct action
*paction
,
548 struct player
*offender
,
549 struct player
*victim_player
,
550 const struct tile
*victim_tile
,
551 const char *victim_link
)
553 action_consequence_common(paction
, offender
,
554 victim_player
, victim_tile
, victim_link
,
555 notify_actor_success
,
556 notify_victim_success
,
557 notify_global_success
,
558 EFT_CASUS_BELLI_SUCCESS
);
561 /**************************************************************************
562 Returns TRUE iff, from the point of view of the owner of the actor unit,
563 it looks like the actor unit may be able to do any action to the target
566 If the owner of the actor unit don't have the knowledge needed to know
567 for sure if the unit can act TRUE will be returned.
569 If the only action(s) that can be performed against a target has the
570 rare_pop_up property the target will only be considered valid if the
571 accept_all_actions argument is TRUE.
572 **************************************************************************/
573 static bool may_unit_act_vs_city(struct unit
*actor
, struct city
*target
,
574 bool accept_all_actions
)
576 if (actor
== NULL
|| target
== NULL
) {
577 /* Can't do any actions if actor or target are missing. */
581 action_iterate(act
) {
582 if (!(action_id_get_actor_kind(act
) == AAK_UNIT
583 && action_id_get_target_kind(act
) == ATK_CITY
)) {
584 /* Not a relevant action. */
588 if (action_id_is_rare_pop_up(act
) && !accept_all_actions
) {
589 /* Not relevant since not accepted here. */
593 if (action_prob_possible(action_prob_vs_city(actor
, act
, target
))) {
594 /* The actor unit may be able to do this action to the target
598 } action_iterate_end
;
603 /**************************************************************************
604 Find a city to target for an action on the specified tile.
606 Returns NULL if no proper target is found.
608 If the only action(s) that can be performed against a target has the
609 rare_pop_up property the target will only be considered valid if the
610 accept_all_actions argument is TRUE.
611 **************************************************************************/
612 struct city
*action_tgt_city(struct unit
*actor
, struct tile
*target_tile
,
613 bool accept_all_actions
)
615 struct city
*target
= tile_city(target_tile
);
617 if (target
&& may_unit_act_vs_city(actor
, target
, accept_all_actions
)) {
618 /* It may be possible to act against this city. */
625 /**************************************************************************
626 Returns TRUE iff, from the point of view of the owner of the actor unit,
627 it looks like the actor unit may be able to do any action to the target
630 If the owner of the actor unit don't have the knowledge needed to know
631 for sure if the unit can act TRUE will be returned.
633 If the only action(s) that can be performed against a target has the
634 rare_pop_up property the target will only be considered valid if the
635 accept_all_actions argument is TRUE.
636 **************************************************************************/
637 static bool may_unit_act_vs_unit(struct unit
*actor
, struct unit
*target
,
638 bool accept_all_actions
)
640 if (actor
== NULL
|| target
== NULL
) {
641 /* Can't do any actions if actor or target are missing. */
645 action_iterate(act
) {
646 if (!(action_id_get_actor_kind(act
) == AAK_UNIT
647 && action_id_get_target_kind(act
) == ATK_UNIT
)) {
648 /* Not a relevant action. */
652 if (action_id_is_rare_pop_up(act
) && !accept_all_actions
) {
653 /* Not relevant since not accepted here. */
657 if (action_prob_possible(action_prob_vs_unit(actor
, act
, target
))) {
658 /* The actor unit may be able to do this action to the target
662 } action_iterate_end
;
667 /**************************************************************************
668 Find a unit to target for an action at the specified tile.
670 Returns the first unit found at the tile that the actor may act against
671 or NULL if no proper target is found.
673 If the only action(s) that can be performed against a target has the
674 rare_pop_up property the target will only be considered valid if the
675 accept_all_actions argument is TRUE.
676 **************************************************************************/
677 struct unit
*action_tgt_unit(struct unit
*actor
, struct tile
*target_tile
,
678 bool accept_all_actions
)
680 unit_list_iterate(target_tile
->units
, target
) {
681 if (may_unit_act_vs_unit(actor
, target
, accept_all_actions
)) {
684 } unit_list_iterate_end
;
689 /**************************************************************************
690 Returns the tile iff it, from the point of view of the owner of the
691 actor unit, looks like each unit on it is an ATK_UNITS target for the
694 Returns NULL if the player knows that the actor unit can't do any
695 ATK_UNITS action to all units at the target tile.
697 If the owner of the actor unit don't have the knowledge needed to know
698 for sure if the unit can act the tile will be returned.
700 If the only action(s) that can be performed against a target has the
701 rare_pop_up property the target will only be considered valid if the
702 accept_all_actions argument is TRUE.
703 **************************************************************************/
704 struct tile
*action_tgt_tile_units(struct unit
*actor
,
706 bool accept_all_actions
)
708 if (actor
== NULL
|| target
== NULL
) {
709 /* Can't do any actions if actor or target are missing. */
713 action_iterate(act
) {
714 if (!(action_id_get_actor_kind(act
) == AAK_UNIT
715 && action_id_get_target_kind(act
) == ATK_UNITS
)) {
716 /* Not a relevant action. */
720 if (action_id_is_rare_pop_up(act
) && !accept_all_actions
) {
721 /* Not relevant since not accepted here. */
725 if (action_prob_possible(action_prob_vs_units(actor
, act
, target
))) {
726 /* One action is enough. */
729 } action_iterate_end
;
734 /**************************************************************************
735 Returns the tile iff it, from the point of view of the owner of the
736 actor unit, looks like a target tile.
738 Returns NULL if the player knows that the actor unit can't do any
739 ATK_TILE action to the tile.
741 If the owner of the actor unit doesn't have the knowledge needed to know
742 for sure if the unit can act the tile will be returned.
744 If the only action(s) that can be performed against a target has the
745 rare_pop_up property the target will only be considered valid if the
746 accept_all_actions argument is TRUE.
747 **************************************************************************/
748 struct tile
*action_tgt_tile(struct unit
*actor
,
750 bool accept_all_actions
)
752 if (actor
== NULL
|| target
== NULL
) {
753 /* Can't do any actions if actor or target are missing. */
757 action_iterate(act
) {
758 if (!(action_id_get_actor_kind(act
) == AAK_UNIT
759 && action_id_get_target_kind(act
) == ATK_TILE
)) {
760 /* Not a relevant action. */
764 if (action_id_is_rare_pop_up(act
) && !accept_all_actions
) {
765 /* Not relevant since not accepted here. */
769 if (action_prob_possible(action_prob_vs_tile(actor
, act
, target
))) {
770 /* The actor unit may be able to do this action to the target
774 } action_iterate_end
;
779 /**************************************************************************
780 Returns the action auto performer that the specified cause can force the
781 specified actor to perform. Returns NULL if no such action auto performer
783 **************************************************************************/
784 const struct action_auto_perf
*
785 action_auto_perf_unit_sel(const enum action_auto_perf_cause cause
,
786 const struct unit
*actor
,
787 const struct player
*other_player
,
788 const struct output_type
*output
)
790 action_auto_perf_by_cause_iterate(cause
, autoperformer
) {
791 if (are_reqs_active(unit_owner(actor
), other_player
,
792 NULL
, NULL
, unit_tile(actor
),
793 actor
, unit_type_get(actor
),
795 &autoperformer
->reqs
, RPT_CERTAIN
)) {
796 /* Select this action auto performer. */
797 return autoperformer
;
799 } action_auto_perf_by_cause_iterate_end
;
801 /* Can't even try to force an action. */
805 #define action_auto_perf_acquire_targets \
806 tgt_city = (target_city ? target_city \
807 : action_tgt_city(actor, unit_tile(actor), \
809 tgt_tile = (target_tile ? target_tile \
810 : action_tgt_tile(actor, unit_tile(actor), \
812 tgt_unit = (target_unit ? target_unit \
813 : action_tgt_unit(actor, unit_tile(actor), \
815 tgt_units = (target_tile \
817 : action_tgt_tile_units(actor, unit_tile(actor), TRUE));
819 /**************************************************************************
820 Make the specified actor unit perform an action because of cause.
822 Returns the action the actor unit was forced to perform.
823 Returns NULL if that didn't happen.
825 Note that the return value doesn't say anything about survival.
826 **************************************************************************/
827 const struct action
*
828 action_auto_perf_unit_do(const enum action_auto_perf_cause cause
,
830 const struct player
*other_player
,
831 const struct output_type
*output
,
832 const struct tile
*target_tile
,
833 const struct city
*target_city
,
834 const struct unit
*target_unit
)
838 const struct city
*tgt_city
;
839 const struct tile
*tgt_tile
;
840 const struct unit
*tgt_unit
;
841 const struct tile
*tgt_units
;
843 const struct action_auto_perf
*autoperf
844 = action_auto_perf_unit_sel(cause
, actor
, other_player
, output
);
847 /* No matching Action Auto Performer. */
851 actor_id
= actor
->id
;
853 /* Acquire the targets. */
854 action_auto_perf_acquire_targets
;
856 action_auto_perf_actions_iterate(autoperf
, act
) {
857 if (action_id_get_actor_kind(act
) == AAK_UNIT
) {
858 /* This action can be done by units. */
860 #define perform_action_to(act, actor, tgtid) \
861 if (unit_perform_action(unit_owner(actor), \
863 0, NULL, act, ACT_REQ_RULES)) { \
864 return action_by_number(act); \
867 switch (action_id_get_target_kind(act
)) {
870 && is_action_enabled_unit_on_units(act
, actor
, tgt_units
)) {
871 perform_action_to(act
, actor
, tgt_units
->index
);
876 && is_action_enabled_unit_on_tile(act
, actor
, tgt_tile
)) {
877 perform_action_to(act
, actor
, tgt_tile
->index
);
882 && is_action_enabled_unit_on_city(act
, actor
, tgt_city
)) {
883 perform_action_to(act
, actor
, tgt_city
->id
)
888 && is_action_enabled_unit_on_unit(act
, actor
, tgt_unit
)) {
889 perform_action_to(act
, actor
, tgt_unit
->id
);
894 && is_action_enabled_unit_on_self(act
, actor
)) {
895 perform_action_to(act
, actor
, actor
->id
);
899 fc_assert(action_id_get_target_kind(act
) != ATK_COUNT
);
902 if (!unit_is_alive(actor_id
)) {
903 /* The unit is gone. Maybe it was killed in Lua? */
907 } action_auto_perf_actions_iterate_end
;
912 /**************************************************************************
913 Returns the probability for the specified actor unit to be forced to
914 perform an action by the specified cause.
915 **************************************************************************/
917 action_auto_perf_unit_prob(const enum action_auto_perf_cause cause
,
919 const struct player
*other_player
,
920 const struct output_type
*output
,
921 const struct tile
*target_tile
,
922 const struct city
*target_city
,
923 const struct unit
*target_unit
)
927 const struct city
*tgt_city
;
928 const struct tile
*tgt_tile
;
929 const struct unit
*tgt_unit
;
930 const struct tile
*tgt_units
;
932 const struct action_auto_perf
*autoperf
933 = action_auto_perf_unit_sel(cause
, actor
, other_player
, output
);
936 /* No matching Action Auto Performer. */
937 return ACTPROB_IMPOSSIBLE
;
940 out
= ACTPROB_IMPOSSIBLE
;
942 /* Acquire the targets. */
943 action_auto_perf_acquire_targets
;
945 action_auto_perf_actions_iterate(autoperf
, act
) {
946 struct act_prob current
= ACTPROB_IMPOSSIBLE
;
948 if (action_id_get_actor_kind(act
) == AAK_UNIT
) {
949 /* This action can be done by units. */
951 switch (action_id_get_target_kind(act
)) {
954 && is_action_enabled_unit_on_units(act
, actor
, tgt_units
)) {
955 current
= action_prob_vs_units(actor
, act
, tgt_units
);
960 && is_action_enabled_unit_on_tile(act
, actor
, tgt_tile
)) {
961 current
= action_prob_vs_tile(actor
, act
, tgt_tile
);
966 && is_action_enabled_unit_on_city(act
, actor
, tgt_city
)) {
967 current
= action_prob_vs_city(actor
, act
, tgt_city
);
972 && is_action_enabled_unit_on_unit(act
, actor
, tgt_unit
)) {
973 current
= action_prob_vs_unit(actor
, act
, tgt_unit
);
978 && is_action_enabled_unit_on_self(act
, actor
)) {
979 current
= action_prob_self(actor
, act
);
983 fc_assert(action_id_get_target_kind(act
) != ATK_COUNT
);
987 out
= action_prob_fall_back(&out
, ¤t
);
988 } action_auto_perf_actions_iterate_end
;