Freeciv21
Develop your civilization from humble roots to a global empire
actiontools.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 // utility
13 #include "rand.h"
14 
15 // common
16 #include "actions.h"
17 #include "nation.h"
18 // server
19 #include "aiiface.h"
20 #include "notify.h"
21 #include "plrhand.h"
22 #include "unithand.h"
23 #include "unittools.h"
24 
25 #include "actiontools.h"
26 
27 typedef void (*action_notify)(struct player *, const struct action *,
28  struct player *, struct player *,
29  const struct tile *, const char *);
30 
34 static void action_success_actor_consume(struct action *paction,
35  int actor_id, struct unit *actor)
36 {
37  if (unit_is_alive(actor_id)
38  && utype_is_consumed_by_action(paction, unit_type_get(actor))) {
39  if (action_has_result(paction, ACTRES_DISBAND_UNIT)
40  || action_has_result(paction, ACTRES_RECYCLE_UNIT)) {
41  wipe_unit(actor, ULR_DISBANDED, nullptr);
42  } else if (action_has_result(paction, ACTRES_NUKE)
43  || action_has_result(paction, ACTRES_NUKE_CITY)
44  || action_has_result(paction, ACTRES_NUKE_UNITS)) {
45  wipe_unit(actor, ULR_DETONATED, nullptr);
46  } else if (action_has_result(paction, ACTRES_ATTACK)) {
47  wipe_unit(actor, ULR_MISSILE, nullptr);
48  } else {
49  wipe_unit(actor, ULR_USED, nullptr);
50  }
51  }
52 }
53 
57 static void action_success_pay_mp(struct action *paction, int actor_id,
58  struct unit *actor)
59 {
60  if (unit_is_alive(actor_id)) {
61  int spent_mp = unit_pays_mp_for_action(paction, actor);
62  actor->moves_left = MAX(0, actor->moves_left - spent_mp);
63  send_unit_info(nullptr, actor);
64  }
65 }
66 
70 void action_success_target_pay_mp(struct action *paction, int target_id,
71  struct unit *target)
72 {
73  if (unit_is_alive(target_id)) {
74  int spent_mp = get_target_bonus_effects(
75  nullptr, unit_owner(target), nullptr,
76  unit_tile(target) ? tile_city(unit_tile(target)) : nullptr, nullptr,
77  unit_tile(target), target, unit_type_get(target), nullptr, nullptr,
78  paction, EFT_ACTION_SUCCESS_TARGET_MOVE_COST);
79 
80  target->moves_left = MAX(0, target->moves_left - spent_mp);
81  send_unit_info(nullptr, target);
82  }
83 }
84 
88 void action_success_actor_price(struct action *paction, int actor_id,
89  struct unit *actor)
90 {
91  action_success_actor_consume(paction, actor_id, actor);
92  action_success_pay_mp(paction, actor_id, actor);
93 }
94 
98 static void action_give_casus_belli(struct player *offender,
99  struct player *victim_player,
100  const bool int_outrage)
101 {
102  if (int_outrage) {
103  /* This action is seen as a reason for any other player, no matter who
104  * the victim was, to declare war on the actor. It could be used to
105  * label certain actions atrocities in rule sets where international
106  * outrage over an action fits the setting. */
107 
108  players_iterate(oplayer)
109  {
110  if (oplayer != offender) {
111  player_diplstate_get(oplayer, offender)->has_reason_to_cancel = 2;
113  }
114  }
116  } else if (victim_player && offender != victim_player) {
117  /* If an unclaimed tile is nuked there is no victim to give casus
118  * belli. If an actor nukes his own tile he is more than willing to
119  * forgive him self. */
120 
121  // Give the victim player a casus belli.
122  player_diplstate_get(victim_player, offender)->has_reason_to_cancel = 2;
123  player_update_last_war_action(victim_player);
124  }
126 }
127 
135  const struct action *paction, struct player *offender,
136  struct player *victim_player, const struct tile *victim_tile,
137  const char *victim_link, const action_notify notify_actor,
138  const action_notify notify_victim, const action_notify notify_global,
139  const enum effect_type eft)
140 {
141  enum casus_belli_range cbr;
142 
143  cbr = casus_belli_range_for(offender, victim_player, eft, paction,
144  victim_tile);
145 
146  if (cbr >= CBR_VICTIM_ONLY) {
147  /* In this situation the specified action provides a casus belli
148  * against the actor. */
149 
150  /* International outrage: This isn't just between the offender and the
151  * victim. */
152  const bool int_outrage = (cbr == CBR_INTERNATIONAL_OUTRAGE);
153 
154  // Notify the involved players by sending them a message.
155  notify_actor(offender, paction, offender, victim_player, victim_tile,
156  victim_link);
157  notify_victim(victim_player, paction, offender, victim_player,
158  victim_tile, victim_link);
159 
160  if (int_outrage) {
161  /* Every other player gets a casus belli against the actor. Tell each
162  * players about it. */
163  players_iterate(oplayer)
164  {
165  notify_global(oplayer, paction, offender, victim_player, victim_tile,
166  victim_link);
167  }
169  }
170 
171  // Give casus belli.
172  action_give_casus_belli(offender, victim_player, int_outrage);
173 
174  // Notify players controlled by the built in AI.
175  call_incident(INCIDENT_ACTION, cbr, paction, offender, victim_player);
176 
177  // Update the clients.
178  send_player_all_c(offender, nullptr);
179 
180  if (victim_player != nullptr && victim_player != offender) {
181  // The actor player was just sent.
182  // An action against an ownerless tile is victimless.
183  send_player_all_c(victim_player, nullptr);
184  }
185  }
186 }
187 
192 static void
193 notify_actor_caught(struct player *receiver, const struct action *paction,
194  struct player *offender, struct player *victim_player,
195  const struct tile *victim_tile, const char *victim_link)
196 {
197  if (!victim_player || offender == victim_player) {
198  // There is no victim or the actor did this to him self.
199  return;
200  }
201 
202  // Custom message based on action type.
203  switch (action_get_target_kind(paction)) {
204  case ATK_CITY:
205  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
206  // TRANS: Suitcase Nuke ... San Francisco
207  _("You have caused an incident getting caught"
208  " trying to do %s to %s."),
209  qUtf8Printable(action_name_translation(paction)),
210  victim_link);
211  break;
212  case ATK_UNIT:
213  case ATK_UNITS:
214  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
215  // TRANS: Bribe Enemy Unit ... American ... Partisan
216  _("You have caused an incident getting caught"
217  " trying to do %s to %s %s."),
218  qUtf8Printable(action_name_translation(paction)),
219  nation_adjective_for_player(victim_player), victim_link);
220  break;
221  case ATK_TILE:
222  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
223  // TRANS: Explode Nuclear ... (54, 26)
224  _("You have caused an incident getting caught"
225  " trying to do %s at %s."),
226  qUtf8Printable(action_name_translation(paction)),
227  victim_link);
228  break;
229  case ATK_SELF:
230  // Special actor notice not needed. Actor is victim.
231  break;
232  case ATK_COUNT:
233  fc_assert(ATK_COUNT != ATK_COUNT);
234  break;
235  }
236 }
237 
242 static void
243 notify_victim_caught(struct player *receiver, const struct action *paction,
244  struct player *offender, struct player *victim_player,
245  const struct tile *victim_tile, const char *victim_link)
246 {
247  if (!victim_player || offender == victim_player) {
248  // There is no victim or the actor did this to him self.
249  return;
250  }
251 
252  // Custom message based on action type.
253  switch (action_get_target_kind(paction)) {
254  case ATK_CITY:
255  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
256  // TRANS: Europeans ... Suitcase Nuke ... San Francisco
257  _("The %s have caused an incident getting caught"
258  " trying to do %s to %s."),
259  nation_plural_for_player(offender),
260  qUtf8Printable(action_name_translation(paction)),
261  victim_link);
262  break;
263  case ATK_UNIT:
264  case ATK_UNITS:
265  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
266  // TRANS: Europeans ... Bribe Enemy Unit ... Partisan
267  _("The %s have caused an incident getting caught"
268  " trying to do %s to your %s."),
269  nation_plural_for_player(offender),
270  qUtf8Printable(action_name_translation(paction)),
271  victim_link);
272  break;
273  case ATK_TILE:
274  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
275  // TRANS: Europeans ... Explode Nuclear ... (54, 26)
276  _("The %s have caused an incident getting caught"
277  " trying to do %s at %s."),
278  nation_plural_for_player(offender),
279  qUtf8Printable(action_name_translation(paction)),
280  victim_link);
281  break;
282  case ATK_SELF:
283  // Special victim notice not needed. Actor is victim.
284  break;
285  case ATK_COUNT:
286  fc_assert(ATK_COUNT != ATK_COUNT);
287  break;
288  }
289 }
290 
295 static void
296 notify_global_caught(struct player *receiver, const struct action *paction,
297  struct player *offender, struct player *victim_player,
298  const struct tile *victim_tile, const char *victim_link)
299 {
300  if (receiver == offender) {
301  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
302  // TRANS: Suitcase Nuke
303  _("Getting caught while trying to do %s gives "
304  "everyone a casus belli against you."),
305  qUtf8Printable(action_name_translation(paction)));
306  } else if (receiver == victim_player) {
307  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
308  // TRANS: Suitcase Nuke ... Europeans
309  _("Getting caught while trying to do %s to you gives "
310  "everyone a casus belli against the %s."),
311  qUtf8Printable(action_name_translation(paction)),
312  nation_plural_for_player(offender));
313  } else if (victim_player == nullptr) {
314  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
315  // TRANS: Europeans ... Suitcase Nuke
316  _("You now have a casus belli against the %s. "
317  "They got caught trying to do %s."),
318  nation_plural_for_player(offender),
319  qUtf8Printable(action_name_translation(paction)));
320  } else {
321  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
322  // TRANS: Europeans ... Suitcase Nuke ... Americans
323  _("You now have a casus belli against the %s. "
324  "They got caught trying to do %s to the %s."),
325  nation_plural_for_player(offender),
326  qUtf8Printable(action_name_translation(paction)),
327  nation_plural_for_player(victim_player));
328  }
329 }
330 
337 void action_consequence_caught(const struct action *paction,
338  struct player *offender,
339  struct player *victim_player,
340  const struct tile *victim_tile,
341  const char *victim_link)
342 {
343  action_consequence_common(paction, offender, victim_player, victim_tile,
344  victim_link, notify_actor_caught,
346  EFT_CASUS_BELLI_CAUGHT);
347 }
348 
353 static void
354 notify_actor_success(struct player *receiver, const struct action *paction,
355  struct player *offender, struct player *victim_player,
356  const struct tile *victim_tile, const char *victim_link)
357 {
358  if (!victim_player || offender == victim_player) {
359  // There is no victim or the actor did this to him self.
360  return;
361  }
362 
363  // Custom message based on action type.
364  switch (action_get_target_kind(paction)) {
365  case ATK_CITY:
366  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
367  // TRANS: Suitcase Nuke ... San Francisco
368  _("You have caused an incident doing %s to %s."),
369  qUtf8Printable(action_name_translation(paction)),
370  victim_link);
371  break;
372  case ATK_UNIT:
373  case ATK_UNITS:
374  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
375  // TRAND: Bribe Enemy Unit ... American ... Partisan
376  _("You have caused an incident doing %s to %s %s."),
377  qUtf8Printable(action_name_translation(paction)),
378  nation_adjective_for_player(victim_player), victim_link);
379  break;
380  case ATK_TILE:
381  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
382  // TRANS: Explode Nuclear ... (54, 26)
383  _("You have caused an incident doing %s at %s."),
384  qUtf8Printable(action_name_translation(paction)),
385  victim_link);
386  break;
387  case ATK_SELF:
388  // Special actor notice not needed. Actor is victim.
389  break;
390  case ATK_COUNT:
391  fc_assert(ATK_COUNT != ATK_COUNT);
392  break;
393  }
394 }
395 
400 static void notify_victim_success(struct player *receiver,
401  const struct action *paction,
402  struct player *offender,
403  struct player *victim_player,
404  const struct tile *victim_tile,
405  const char *victim_link)
406 {
407  if (!victim_player || offender == victim_player) {
408  // There is no victim or the actor did this to him self.
409  return;
410  }
411 
412  // Custom message based on action type.
413  switch (action_get_target_kind(paction)) {
414  case ATK_CITY:
415  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
416  // TRANS: Europeans ... Suitcase Nuke ... San Francisco
417  _("The %s have caused an incident doing %s to %s."),
418  nation_plural_for_player(offender),
419  qUtf8Printable(action_name_translation(paction)),
420  victim_link);
421  break;
422  case ATK_UNIT:
423  case ATK_UNITS:
424  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
425  // TRANS: Europeans ... Bribe Enemy Unit ... Partisan
426  _("The %s have caused an incident doing "
427  "%s to your %s."),
428  nation_plural_for_player(offender),
429  qUtf8Printable(action_name_translation(paction)),
430  victim_link);
431  break;
432  case ATK_TILE:
433  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
434  // TRANS: Europeans ... Explode Nuclear ... (54, 26)
435  _("The %s have caused an incident doing %s at %s."),
436  nation_plural_for_player(offender),
437  qUtf8Printable(action_name_translation(paction)),
438  victim_link);
439  break;
440  case ATK_SELF:
441  // Special victim notice not needed. Actor is victim.
442  break;
443  case ATK_COUNT:
444  fc_assert(ATK_COUNT != ATK_COUNT);
445  break;
446  }
447 }
448 
453 static void notify_global_success(struct player *receiver,
454  const struct action *paction,
455  struct player *offender,
456  struct player *victim_player,
457  const struct tile *victim_tile,
458  const char *victim_link)
459 {
460  if (receiver == offender) {
461  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
462  // TRANS: Suitcase Nuke
463  _("Doing %s gives everyone a casus belli against you."),
464  qUtf8Printable(action_name_translation(paction)));
465  } else if (receiver == victim_player) {
466  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
467  // TRANS: Suitcase Nuke ... Europeans
468  _("Doing %s to you gives everyone a casus belli against "
469  "the %s."),
470  qUtf8Printable(action_name_translation(paction)),
471  nation_plural_for_player(offender));
472  } else if (victim_player == nullptr) {
473  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
474  // TRANS: Europeans ... Suitcase Nuke
475  _("You now have a casus belli against the %s. "
476  "They did %s."),
477  nation_plural_for_player(offender),
478  qUtf8Printable(action_name_translation(paction)));
479  } else {
480  notify_player(receiver, victim_tile, E_DIPLOMATIC_INCIDENT, ftc_server,
481  // TRANS: Europeans ... Suitcase Nuke ... Americans
482  _("You now have a casus belli against the %s. "
483  "They did %s to the %s."),
484  nation_plural_for_player(offender),
485  qUtf8Printable(action_name_translation(paction)),
486  nation_plural_for_player(victim_player));
487  }
488 }
489 
496 void action_consequence_success(const struct action *paction,
497  struct player *offender,
498  struct player *victim_player,
499  const struct tile *victim_tile,
500  const char *victim_link)
501 {
502  action_consequence_common(paction, offender, victim_player, victim_tile,
503  victim_link, notify_actor_success,
505  EFT_CASUS_BELLI_SUCCESS);
506 }
507 
514 void action_consequence_complete(const struct action *paction,
515  struct player *offender,
516  struct player *victim_player,
517  const struct tile *victim_tile,
518  const char *victim_link)
519 {
520  action_consequence_common(paction, offender, victim_player, victim_tile,
521  victim_link, notify_actor_success,
523  EFT_CASUS_BELLI_COMPLETE);
524 }
525 
529 int action_sub_target_id_for_action(const struct action *paction,
530  struct unit *actor_unit)
531 {
532  const struct tile *tgt_tile = unit_tile(actor_unit);
533 
534  fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
535  NO_TARGET);
536 
537  switch (action_get_sub_target_kind(paction)) {
538  case ASTK_NONE:
539  // Should not be reached
540  fc_assert_ret_val(action_get_sub_target_kind(paction) != ASTK_NONE,
541  NO_TARGET);
542  break;
543  case ASTK_BUILDING:
544  // Implement if a building sub targeted action becomes flexible
545  fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
546  NO_TARGET);
547  break;
548  case ASTK_TECH:
549  // Implement if a tech sub targeted action becomes flexible
550  fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
551  NO_TARGET);
552  break;
553  case ASTK_EXTRA:
554  case ASTK_EXTRA_NOT_THERE:
555  if (action_has_result(paction, ACTRES_PILLAGE)) {
556  // Special treatment for "Pillage"
557  struct extra_type *pextra;
558  enum unit_activity activity = action_get_activity(paction);
559 
560  unit_assign_specific_activity_target(actor_unit, &activity, &pextra);
561 
562  if (pextra != nullptr) {
563  return extra_number(pextra);
564  }
565  }
567  {
568  if (action_prob_possible(action_prob_vs_tile(actor_unit, paction->id,
569  tgt_tile, tgt_extra))) {
570  /* The actor unit may be able to do this action to the target
571  * extra. */
572  return extra_number(tgt_extra);
573  }
574  }
576  break;
577  case ASTK_COUNT:
578  // Should not exist.
579  fc_assert_ret_val(action_get_sub_target_kind(paction) != ASTK_COUNT,
580  NO_TARGET);
581  break;
582  }
583 
584  return NO_TARGET;
585 }
586 
593  const enum action_auto_perf_cause cause, const struct unit *actor,
594  const struct player *other_player, const struct output_type *output)
595 {
597  {
598  if (are_reqs_active(unit_owner(actor), other_player, nullptr, nullptr,
599  unit_tile(actor), actor, unit_type_get(actor),
600  output, nullptr, nullptr, &autoperformer->reqs,
601  RPT_CERTAIN)) {
602  // Select this action auto performer.
603  return autoperformer;
604  }
605  }
607 
608  // Can't even try to force an action.
609  return nullptr;
610 }
611 
612 #define action_auto_perf_acquire_targets(_target_extra_) \
613  tgt_city = \
614  (target_city ? target_city \
615  : action_tgt_city(actor, unit_tile(actor), true)); \
616  tgt_tile = (target_tile ? target_tile \
617  : action_tgt_tile(actor, unit_tile(actor), \
618  _target_extra_, true)); \
619  tgt_unit = \
620  (target_unit ? target_unit \
621  : action_tgt_unit(actor, unit_tile(actor), true));
622 
632  const enum action_auto_perf_cause cause, struct unit *actor,
633  const struct player *other_player, const struct output_type *output,
634  const struct tile *target_tile, const struct city *target_city,
635  const struct unit *target_unit, const struct extra_type *target_extra)
636 {
637  int actor_id;
638 
639  const struct city *tgt_city;
640  const struct tile *tgt_tile;
641  const struct unit *tgt_unit;
642 
643  const struct action_auto_perf *autoperf =
644  action_auto_perf_unit_sel(cause, actor, other_player, output);
645 
646  if (!autoperf) {
647  // No matching Action Auto Performer.
648  return nullptr;
649  }
650 
651  actor_id = actor->id;
652 
653  // Acquire the targets.
654  action_auto_perf_acquire_targets(target_extra);
655 
656  action_auto_perf_actions_iterate(autoperf, act)
657  {
658  if (action_id_get_actor_kind(act) == AAK_UNIT) {
659  // This action can be done by units.
660 
661 #define perform_action_to(act, actor, tgtid, tgt_extra) \
662  if (unit_perform_action(unit_owner(actor), actor->id, tgtid, tgt_extra, \
663  nullptr, act, ACT_REQ_RULES)) { \
664  return action_by_number(act); \
665  }
666 
667  switch (action_id_get_target_kind(act)) {
668  case ATK_UNITS:
669  if (tgt_tile
670  && is_action_enabled_unit_on_units(act, actor, tgt_tile)) {
671  perform_action_to(act, actor, tgt_tile->index, EXTRA_NONE);
672  }
673  break;
674  case ATK_TILE:
675  if (tgt_tile
676  && is_action_enabled_unit_on_tile(act, actor, tgt_tile,
677  target_extra)) {
678  perform_action_to(act, actor, tgt_tile->index,
679  extra_number(target_extra));
680  }
681  break;
682  case ATK_CITY:
683  if (tgt_city
684  && is_action_enabled_unit_on_city(act, actor, tgt_city)) {
685  perform_action_to(act, actor, tgt_city->id, EXTRA_NONE)
686  }
687  break;
688  case ATK_UNIT:
689  if (tgt_unit
690  && is_action_enabled_unit_on_unit(act, actor, tgt_unit)) {
691  perform_action_to(act, actor, tgt_unit->id, EXTRA_NONE);
692  }
693  break;
694  case ATK_SELF:
695  if (is_action_enabled_unit_on_self(act, actor)) {
696  perform_action_to(act, actor, actor->id, EXTRA_NONE);
697  }
698  break;
699  case ATK_COUNT:
700  fc_assert(action_id_get_target_kind(act) != ATK_COUNT);
701  }
702 
703  if (!unit_is_alive(actor_id)) {
704  // The unit is gone. Maybe it was killed in Lua?
705  return nullptr;
706  }
707  }
708  }
710 
711  return nullptr;
712 }
713 
719  const enum action_auto_perf_cause cause, struct unit *actor,
720  const struct player *other_player, const struct output_type *output,
721  const struct tile *target_tile, const struct city *target_city,
722  const struct unit *target_unit, const struct extra_type *target_extra)
723 {
724  struct act_prob out;
725 
726  const struct city *tgt_city;
727  const struct tile *tgt_tile;
728  const struct unit *tgt_unit;
729 
730  const struct action_auto_perf *autoperf =
731  action_auto_perf_unit_sel(cause, actor, other_player, output);
732 
733  if (!autoperf) {
734  // No matching Action Auto Performer.
735  return ACTPROB_IMPOSSIBLE;
736  }
737 
738  out = ACTPROB_IMPOSSIBLE;
739 
740  // Acquire the targets.
741  action_auto_perf_acquire_targets(target_extra);
742 
743  action_auto_perf_actions_iterate(autoperf, act)
744  {
745  struct act_prob current = ACTPROB_IMPOSSIBLE;
746 
747  if (action_id_get_actor_kind(act) == AAK_UNIT) {
748  // This action can be done by units.
749 
750  switch (action_id_get_target_kind(act)) {
751  case ATK_UNITS:
752  if (tgt_tile
753  && is_action_enabled_unit_on_units(act, actor, tgt_tile)) {
754  current = action_prob_vs_units(actor, act, tgt_tile);
755  }
756  break;
757  case ATK_TILE:
758  if (tgt_tile
759  && is_action_enabled_unit_on_tile(act, actor, tgt_tile,
760  target_extra)) {
761  current = action_prob_vs_tile(actor, act, tgt_tile, target_extra);
762  }
763  break;
764  case ATK_CITY:
765  if (tgt_city
766  && is_action_enabled_unit_on_city(act, actor, tgt_city)) {
767  current = action_prob_vs_city(actor, act, tgt_city);
768  }
769  break;
770  case ATK_UNIT:
771  if (tgt_unit
772  && is_action_enabled_unit_on_unit(act, actor, tgt_unit)) {
773  current = action_prob_vs_unit(actor, act, tgt_unit);
774  }
775  break;
776  case ATK_SELF:
777  if (actor && is_action_enabled_unit_on_self(act, actor)) {
778  current = action_prob_self(actor, act);
779  }
780  break;
781  case ATK_COUNT:
782  fc_assert(action_id_get_target_kind(act) != ATK_COUNT);
783  }
784  }
785 
786  out = action_prob_fall_back(&out, &current);
787  }
789 
790  return out;
791 }
792 
797 bool action_failed_dice_roll(const struct player *act_player,
798  const struct unit *act_unit,
799  const struct city *tgt_city,
800  const struct player *tgt_player,
801  const struct action *paction)
802 {
803  int odds = action_dice_roll_odds(act_player, act_unit, tgt_city,
804  tgt_player, paction);
805 
806  // Roll the dice.
807  return fc_rand(100) >= odds;
808 }
bool is_action_enabled_unit_on_unit(const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Returns TRUE if actor_unit can do wanted_action to target_unit as far as action enablers are concerne...
Definition: actions.cpp:4007
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Get the actor unit's probability of successfully performing the chosen action on itself.
Definition: actions.cpp:5145
bool action_prob_possible(const struct act_prob probability)
Returns TRUE iff the given action probability belongs to an action that may be possible.
Definition: actions.cpp:5380
int action_dice_roll_odds(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
Returns the odds of an action not failing its dice roll.
Definition: actions.cpp:5657
bool is_action_enabled_unit_on_self(const action_id wanted_action, const struct unit *actor_unit)
Returns TRUE if actor_unit can do wanted_action to itself as far as action enablers are concerned.
Definition: actions.cpp:4196
bool is_action_enabled_unit_on_city(const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Returns TRUE if actor_unit can do wanted_action to target_city as far as action enablers are concerne...
Definition: actions.cpp:3948
struct act_prob action_prob_vs_city(const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Get the actor unit's probability of successfully performing the chosen action on the target city.
Definition: actions.cpp:4809
struct act_prob action_prob_vs_unit(const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Get the actor unit's probability of successfully performing the chosen action on the target unit.
Definition: actions.cpp:4871
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Get the sub target kind of an action.
Definition: actions.cpp:1209
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Get the actor unit's probability of successfully performing the chosen action on the target tile.
Definition: actions.cpp:5090
struct act_prob action_prob_vs_units(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Get the actor unit's probability of successfully performing the chosen action on all units at the tar...
Definition: actions.cpp:5029
bool is_action_enabled_unit_on_units(const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Returns TRUE if actor_unit can do wanted_action to all units on the target_tile as far as action enab...
Definition: actions.cpp:4078
const QString action_name_translation(const struct action *action)
Get the action name used when displaying the action in the UI.
Definition: actions.cpp:1353
struct act_prob action_prob_fall_back(const struct act_prob *ap1, const struct act_prob *ap2)
Returns ap1 with ap2 as fall back in cases where ap1 doesn't happen.
Definition: actions.cpp:5510
bool is_action_enabled_unit_on_tile(const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Returns TRUE if actor_unit can do wanted_action to the target_tile as far as action enablers are conc...
Definition: actions.cpp:4136
enum unit_activity action_get_activity(const struct action *paction)
Returns the unit activity this action may cause or ACTIVITY_LAST if the action doesn't result in a un...
Definition: actions.cpp:1557
enum action_target_kind action_get_target_kind(const struct action *paction)
Get the target kind of an action.
Definition: actions.cpp:1198
bool action_has_result(const struct action *paction, enum action_result result)
Returns TRUE iff performing the specified action has the specified result.
Definition: actions.cpp:1248
#define action_auto_perf_by_cause_iterate(_cause_, _act_perf_)
Definition: actions.h:483
#define action_auto_perf_actions_iterate_end
Definition: actions.h:497
#define action_auto_perf_by_cause_iterate_end
Definition: actions.h:490
#define action_auto_perf_actions_iterate(_autoperf_, _act_id_)
Definition: actions.h:494
#define action_id_get_actor_kind(act_id)
Definition: actions.h:519
#define ACTPROB_IMPOSSIBLE
Definition: actions.h:732
#define action_id_get_target_kind(act_id)
Definition: actions.h:522
static void notify_actor_success(struct player *receiver, const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Notify the actor that the performed action gave the victim a casus belli against the actor.
void action_consequence_success(const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Take care of any consequences (like casus belli) of successfully performing the given action.
struct act_prob action_auto_perf_unit_prob(const enum action_auto_perf_cause cause, struct unit *actor, const struct player *other_player, const struct output_type *output, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, const struct extra_type *target_extra)
Returns the probability for the specified actor unit to be forced to perform an action by the specifi...
void action_consequence_caught(const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Take care of any consequences (like casus belli) of getting caught while trying to perform the given ...
static void notify_victim_success(struct player *receiver, const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Notify the victim that the performed action gave the victim a casus belli against the actor.
void action_success_target_pay_mp(struct action *paction, int target_id, struct unit *target)
Pay the movement point price of being the target of an action.
Definition: actiontools.cpp:70
void(* action_notify)(struct player *, const struct action *, struct player *, struct player *, const struct tile *, const char *)
Definition: actiontools.cpp:27
static void notify_global_success(struct player *receiver, const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Notify the world that the performed action gave the everyone a casus belli against the actor.
static void notify_victim_caught(struct player *receiver, const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Notify the victim that the failed action gave the victim a casus belli against the actor.
const struct action * action_auto_perf_unit_do(const enum action_auto_perf_cause cause, struct unit *actor, const struct player *other_player, const struct output_type *output, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, const struct extra_type *target_extra)
Make the specified actor unit perform an action because of cause.
#define perform_action_to(act, actor, tgtid, tgt_extra)
static void notify_global_caught(struct player *receiver, const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Notify the world that the failed action gave the everyone a casus belli against the actor.
static void action_success_actor_consume(struct action *paction, int actor_id, struct unit *actor)
Wipe an actor if the action it successfully performed consumed it.
Definition: actiontools.cpp:34
static void notify_actor_caught(struct player *receiver, const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Notify the actor that the failed action gave the victim a casus belli against the actor.
static void action_give_casus_belli(struct player *offender, struct player *victim_player, const bool int_outrage)
Give the victim a casus belli against the offender.
Definition: actiontools.cpp:98
void action_success_actor_price(struct action *paction, int actor_id, struct unit *actor)
Make the actor that successfully performed the action pay the price.
Definition: actiontools.cpp:88
void action_consequence_complete(const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
Take care of any consequences (like casus belli) of successfully completing the given action.
bool action_failed_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
Returns TRUE iff the spy/diplomat was caught outside of a diplomatic battle.
int action_sub_target_id_for_action(const struct action *paction, struct unit *actor_unit)
Find an sub target for the specified action.
static void action_success_pay_mp(struct action *paction, int actor_id, struct unit *actor)
Pay the movement point cost of success.
Definition: actiontools.cpp:57
const struct action_auto_perf * action_auto_perf_unit_sel(const enum action_auto_perf_cause cause, const struct unit *actor, const struct player *other_player, const struct output_type *output)
Returns the action auto performer that the specified cause can force the specified actor to perform.
static void action_consequence_common(const struct action *paction, struct player *offender, struct player *victim_player, const struct tile *victim_tile, const char *victim_link, const action_notify notify_actor, const action_notify notify_victim, const action_notify notify_global, const enum effect_type eft)
Take care of any consequences (like casus belli) of the given action when the situation was as specif...
#define action_auto_perf_acquire_targets(_target_extra_)
@ INCIDENT_ACTION
Definition: ai.h:40
void call_incident(enum incident_type type, enum casus_belli_range scope, const struct action *paction, struct player *violator, struct player *victim)
Call incident function of victim.
Definition: aiiface.cpp:235
int get_target_bonus_effects(struct effect_list *plist, const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, enum effect_type effect_type, enum vision_layer vision_layer, enum national_intelligence nintel)
Returns the effect bonus of a given type for any target.
Definition: effects.cpp:611
int extra_number(const struct extra_type *pextra)
Return the extra id.
Definition: extras.cpp:132
#define EXTRA_NONE
Definition: extras.h:72
#define extra_type_re_active_iterate_end
Definition: extras.h:294
#define extra_type_re_active_iterate(_p)
Definition: extras.h:289
#define NO_TARGET
Definition: fc_types.h:271
@ RPT_CERTAIN
Definition: fc_types.h:568
#define _(String)
Definition: fcintl.h:50
const struct ft_color ftc_server
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
const char * nation_plural_for_player(const struct player *pplayer)
Return the (translated) plural noun of the given nation of a player.
Definition: nation.cpp:155
const char * nation_adjective_for_player(const struct player *pplayer)
Return the (translated) adjective for the given nation of a player.
Definition: nation.cpp:146
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Similar to notify_conn_packet (see also), but takes player as "destination".
Definition: notify.cpp:284
enum casus_belli_range casus_belli_range_for(const struct player *offender, const struct player *tgt_plr, const enum effect_type outcome, const struct action *paction, const struct tile *tgt_tile)
Return the Casus Belli range when offender performs paction to tgt_plr at tgt_tile and the outcome is...
Definition: player.cpp:1551
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
void send_player_all_c(struct player *src, struct conn_list *dest)
Send all information about a player (player_info and all player_diplstates) to the given connections.
Definition: plrhand.cpp:1031
void player_update_last_war_action(struct player *pplayer)
Update last war action timestamp (affects player mood).
Definition: plrhand.cpp:730
#define fc_rand(_size)
Definition: rand.h:16
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement(s) to see if they are active on the given target.
#define MAX(x, y)
Definition: shared.h:48
enum action_auto_perf_cause cause
Definition: actions.h:457
action_id id
Definition: actions.h:306
union action::@10 actor
enum act_tgt_compl target_complexity
Definition: actions.h:315
Definition: city.h:291
int id
Definition: city.h:296
int has_reason_to_cancel
Definition: player.h:197
Definition: player.h:231
Definition: tile.h:42
int index
Definition: tile.h:43
Definition: unit.h:134
int moves_left
Definition: unit.h:147
int id
Definition: unit.h:141
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
bool unit_is_alive(int id)
Check if unit with given id is still alive.
Definition: unit.cpp:2014
int unit_pays_mp_for_action(const struct action *paction, const struct unit *punit)
Returns the amount of movement points successfully performing the specified action will consume in th...
Definition: unit.cpp:1973
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
void send_unit_info(struct conn_list *dest, struct unit *punit)
Send the unit to the players who need the info.
Definition: unittools.cpp:2808
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Remove the unit, and passengers if it is a carrying any.
Definition: unittools.cpp:2248
void unit_assign_specific_activity_target(struct unit *punit, enum unit_activity *activity, struct extra_type **target)
For some activities (currently only pillaging), the precise target can be assigned by the server rath...
Definition: unittools.cpp:1105
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Returns TRUE iff performing the specified action will consume an actor unit of the specified type.
Definition: unittype.cpp:936