Freeciv21
Develop your civilization from humble roots to a global empire
unithand.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include <cstdlib>
15 #include <cstring>
16 #include <set>
17 
18 // utility
19 #include "astring.h"
20 #include "fcintl.h"
21 #include "rand.h"
22 #include "shared.h"
23 
24 // common
25 #include "actions.h"
26 #include "ai.h"
27 #include "city.h"
28 #include "combat.h"
29 #include "events.h"
30 #include "featured_text.h"
31 #include "game.h"
32 #include "log.h"
33 #include "map.h"
34 #include "movement.h"
35 #include "packets.h"
36 #include "player.h"
37 #include "research.h"
38 #include "specialist.h"
39 #include "traderoutes.h"
40 #include "unit.h"
41 #include "unitlist.h"
42 
43 /* common/scriptcore */
44 #include "luascript_types.h"
45 
46 // server
47 #include "actiontools.h"
48 #include "citizenshand.h"
49 #include "citytools.h"
50 #include "cityturn.h"
51 #include "diplomats.h"
52 #include "maphand.h"
53 #include "notify.h"
54 #include "plrhand.h"
55 #include "sanitycheck.h"
56 #include "spacerace.h"
57 #include "techtools.h"
58 #include "unittools.h"
59 
60 /* server/advisors */
61 #include "autosettlers.h"
62 
63 /* server/scripting */
64 #include "script_server.h"
65 
66 #include "unithand.h"
67 
68 // An explanation why an action isn't enabled.
69 struct ane_expl {
70  // The kind of reason why an action isn't enabled.
71  enum ane_kind kind;
72 
73  union {
74  // The city without the needed capacity-
76 
77  // The bad terrain in question.
79 
80  // The player to advice declaring war on.
82 
83  // The player to advice breaking peace with.
84  struct player *peace_with;
85 
86  // The nation that can't be involved.
88 
89  // The unit type that can't be targeted.
90  const struct unit_type *no_tgt_utype;
91 
92  // The action that blocks the action.
93  struct action *blocker;
94 
95  // The required distance.
96  int distance;
97 
98  // The required amount of gold.
100  };
101 };
102 
103 static bool unit_activity_internal(struct unit *punit,
104  enum unit_activity new_activity);
105 static bool unit_activity_targeted_internal(struct unit *punit,
106  enum unit_activity new_activity,
107  struct extra_type **new_target);
108 static void
109 illegal_action(struct player *pplayer, struct unit *actor,
110  action_id stopped_action, struct player *tgt_player,
111  struct tile *target_tile, const struct city *target_city,
112  const struct unit *target_unit, bool disturb_player,
113  const enum action_requester requester);
114 static bool city_add_unit(struct player *pplayer, struct unit *punit,
115  struct city *pcity, const struct action *paction);
116 static bool city_build(struct player *pplayer, struct unit *punit,
117  struct tile *ptile, const char *name,
118  const struct action *paction);
119 static bool do_unit_establish_trade(struct player *pplayer,
120  struct unit *punit,
121  struct city *pcity_dest,
122  const struct action *paction);
123 
124 static bool unit_do_help_build(struct player *pplayer, struct unit *punit,
125  struct city *pcity_dest,
126  const struct action *paction);
127 static bool unit_bombard(struct unit *punit, struct tile *ptile,
128  const struct action *paction);
129 static bool unit_nuke(struct player *pplayer, struct unit *punit,
130  struct tile *def_tile, const struct action *paction);
131 static bool unit_do_destroy_city(struct player *act_player,
132  struct unit *act_unit,
133  struct city *tgt_city,
134  const struct action *paction);
135 static bool do_unit_change_homecity(struct unit *punit, struct city *pcity,
136  const struct action *paction);
137 static bool do_attack(struct unit *actor_unit, struct tile *target_tile,
138  const struct action *paction);
139 static bool do_unit_strike_city_production(const struct player *act_player,
140  struct unit *act_unit,
141  struct city *tgt_city,
142  const struct action *paction);
143 static bool do_unit_strike_city_building(const struct player *act_player,
144  struct unit *act_unit,
145  struct city *tgt_city,
146  Impr_type_id tgt_bld_id,
147  const struct action *paction);
148 static bool do_unit_conquer_city(struct player *act_player,
149  struct unit *act_unit,
150  struct city *tgt_city,
151  struct action *paction);
152 static bool do_action_activity(struct unit *punit,
153  const struct action *paction);
154 static bool do_action_activity_targeted(struct unit *punit,
155  const struct action *paction,
156  struct extra_type **new_target);
157 
161 void handle_unit_type_upgrade(struct player *pplayer, Unit_type_id uti)
162 {
163  const struct unit_type *to_unittype;
164  struct unit_type *from_unittype = utype_by_number(uti);
165  int number_of_upgraded_units = 0;
166  struct action *paction = action_by_number(ACTION_UPGRADE_UNIT);
167 
168  if (nullptr == from_unittype) {
169  // Probably died or bribed.
170  qDebug("handle_unit_type_upgrade() invalid unit type %d", uti);
171  return;
172  }
173 
174  to_unittype = can_upgrade_unittype(pplayer, from_unittype);
175  if (!to_unittype) {
176  notify_player(pplayer, nullptr, E_BAD_COMMAND, ftc_server,
177  _("Illegal packet, can't upgrade %s (yet)."),
178  utype_name_translation(from_unittype));
179  return;
180  }
181 
182  /*
183  * Try to upgrade units. The order we upgrade in is arbitrary (if
184  * the player really cared they should have done it manually).
185  */
187  unit_list_iterate(pplayer->units, punit)
188  {
189  if (unit_type_get(punit) == from_unittype) {
190  struct city *pcity = tile_city(unit_tile(punit));
191 
192  if (is_action_enabled_unit_on_city(paction->id, punit, pcity)
193  && unit_perform_action(pplayer, punit->id, pcity->id, 0, "",
194  paction->id, ACT_REQ_SS_AGENT)) {
195  number_of_upgraded_units++;
196  } else if (UU_NO_MONEY == unit_upgrade_test(punit, false)) {
197  break;
198  }
199  }
200  }
203 
204  // Alert the player about what happened.
205  if (number_of_upgraded_units > 0) {
206  const int cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
207  notify_player(pplayer, nullptr, E_UNIT_UPGRADED, ftc_server,
208  /* FIXME: plurality of number_of_upgraded_units ignored!
209  * (Plurality of unit names is messed up anyway.) */
210  /* TRANS: "2 Musketeers upgraded to Riflemen for 100 gold."
211  * Plurality is in gold (second %d), not units. */
212  PL_("%d %s upgraded to %s for %d gold.",
213  "%d %s upgraded to %s for %d gold.",
214  cost * number_of_upgraded_units),
215  number_of_upgraded_units,
216  utype_name_translation(from_unittype),
217  utype_name_translation(to_unittype),
218  cost * number_of_upgraded_units);
219  send_player_info_c(pplayer, pplayer->connections);
220  } else {
221  notify_player(pplayer, nullptr, E_UNIT_UPGRADED, ftc_server,
222  _("No units could be upgraded."));
223  }
224 }
225 
232 static bool do_unit_upgrade(struct player *pplayer, struct unit *punit,
233  struct city *pcity,
234  enum action_requester ordered_by,
235  const struct action *paction)
236 {
237  const struct unit_type *from_unit = unit_type_get(punit);
238  const struct unit_type *to_unit = can_upgrade_unittype(pplayer, from_unit);
239 
240  transform_unit(punit, to_unit, false);
241  send_player_info_c(pplayer, pplayer->connections);
242 
243  if (ordered_by == ACT_REQ_PLAYER) {
244  int cost = unit_upgrade_price(pplayer, from_unit, to_unit);
245 
246  notify_player(pplayer, unit_tile(punit), E_UNIT_UPGRADED, ftc_server,
247  PL_("%s upgraded to %s for %d gold.",
248  "%s upgraded to %s for %d gold.", cost),
249  utype_name_translation(from_unit), unit_link(punit), cost);
250  }
251 
252  return true;
253 }
254 
261 static bool do_capture_units(struct player *pplayer, struct unit *punit,
262  struct tile *pdesttile,
263  const struct action *paction)
264 {
265  struct city *pcity;
266  char capturer_link[MAX_LEN_LINK];
267  const char *capturer_nation = nation_plural_for_player(pplayer);
268  bv_unit_types unique_on_tile;
269 
270  // Sanity check: The actor still exists.
271  fc_assert_ret_val(pplayer, false);
272  fc_assert_ret_val(punit, false);
273 
274  /* Sanity check: make sure that the capture won't result in the actor
275  * ending up with more than one unit of each unique unit type. */
276  BV_CLR_ALL(unique_on_tile);
277  unit_list_iterate(pdesttile->units, to_capture)
278  {
279  bool unique_conflict = false;
280 
281  // Check what the player already has.
283  unit_type_get(to_capture))) {
284  // The player already has a unit of this kind.
285  unique_conflict = true;
286  }
287 
288  if (utype_has_flag(unit_type_get(to_capture), UTYF_UNIQUE)) {
289  /* The type of the units at the tile must also be checked. Two allied
290  * players can both have their unique unit at the same tile.
291  * Capturing them both would give the actor two units of a kind that
292  * is supposed to be unique. */
293 
294  if (BV_ISSET(unique_on_tile, utype_index(unit_type_get(to_capture)))) {
295  // There is another unit of the same kind at this tile.
296  unique_conflict = true;
297  } else {
298  /* Remember the unit type in case another unit of the same kind is
299  * encountered later. */
300  BV_SET(unique_on_tile, utype_index(unit_type_get(to_capture)));
301  }
302  }
303 
304  if (unique_conflict) {
305  log_debug("capture units: already got unique unit");
306  notify_player(pplayer, pdesttile, E_UNIT_ILLEGAL_ACTION, ftc_server,
307  // TRANS: You can only have one Leader.
308  _("You can only have one %s."), unit_link(to_capture));
309 
310  return false;
311  }
312  }
314 
315  // N.B: unit_link() always returns the same pointer.
316  sz_strlcpy(capturer_link, unit_link(punit));
317 
318  pcity = tile_city(pdesttile);
319  unit_list_iterate(pdesttile->units, to_capture)
320  {
321  struct player *uplayer = unit_owner(to_capture);
322  const char *victim_link;
323 
324  unit_owner(to_capture)->score.units_lost++;
325  to_capture = unit_change_owner(to_capture, pplayer,
326  (game.server.homecaughtunits
327  ? punit->homecity
329  ULR_CAPTURED);
330  /* As unit_change_owner() currently remove the old unit and
331  * replace by a new one (with a new id), we want to make link to
332  * the new unit. */
333  victim_link = unit_link(to_capture);
334 
335  // Notify players
336  notify_player(pplayer, pdesttile, E_MY_DIPLOMAT_BRIBE, ftc_server,
337  // TRANS: <unit> ... <unit>
338  _("Your %s succeeded in capturing the %s %s."),
339  capturer_link, nation_adjective_for_player(uplayer),
340  victim_link);
341  notify_player(uplayer, pdesttile, E_ENEMY_DIPLOMAT_BRIBE, ftc_server,
342  // TRANS: <unit> ... <Poles>
343  _("Your %s was captured by the %s."), victim_link,
344  capturer_nation);
345 
346  // May cause an incident
347  action_consequence_success(paction, pplayer, unit_owner(to_capture),
348  pdesttile, victim_link);
349 
350  if (nullptr != pcity) {
351  // The captured unit is in a city. Bounce it.
352  bounce_unit(to_capture, true);
353  }
354  }
356 
357  unit_did_action(punit);
359 
360  send_unit_info(nullptr, punit);
361 
362  return true;
363 }
364 
368 static void occupy_move(unit *punit, tile *def_tile)
369 {
370  /* Hack: make sure the unit has enough moves_left for the move to
371  succeed, and adjust moves_left to afterward (if successful). */
372 
373  int old_moves = punit->moves_left;
374  int full_moves = unit_move_rate(punit);
375 
376  punit->moves_left = full_moves;
377  auto pcity = tile_city(def_tile);
378  // Post attack occupy move.
379  if ((is_action_enabled_unit_on_city(ACTION_CONQUER_CITY, punit, pcity)
380  && unit_perform_action(unit_owner(punit), punit->id, pcity->id, 0, "",
381  ACTION_CONQUER_CITY, ACT_REQ_RULES))
382  || (is_action_enabled_unit_on_city(ACTION_CONQUER_CITY2, punit, pcity)
383  && unit_perform_action(unit_owner(punit), punit->id, pcity->id, 0,
384  "", ACTION_CONQUER_CITY2, ACT_REQ_RULES))
385  || (unit_transported(punit)
386  && is_action_enabled_unit_on_tile(ACTION_TRANSPORT_DISEMBARK1,
387  punit, def_tile, nullptr)
388  && unit_perform_action(unit_owner(punit), punit->id,
389  tile_index(def_tile), 0, "",
390  ACTION_TRANSPORT_DISEMBARK1, ACT_REQ_RULES))
391  || (unit_transported(punit)
392  && is_action_enabled_unit_on_tile(ACTION_TRANSPORT_DISEMBARK2,
393  punit, def_tile, nullptr)
394  && unit_perform_action(unit_owner(punit), punit->id,
395  tile_index(def_tile), 0, "",
396  ACTION_TRANSPORT_DISEMBARK2, ACT_REQ_RULES))
397  || (unit_move_handling(punit, def_tile, false, true))) {
398  int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
399 
400  /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move
401  * costs. Attack SINGLE_COST is already calculated in to old_moves. */
402  punit->moves_left = old_moves - mcost;
403  if (punit->moves_left < 0) {
404  punit->moves_left = 0;
405  }
406  } else {
407  punit->moves_left = old_moves;
408  }
409 }
410 
417 static bool do_expel_unit(struct player *pplayer, struct unit *actor,
418  struct unit *target, const struct action *paction)
419 {
420  char target_link[MAX_LEN_LINK];
421  struct player *uplayer;
422  struct tile *target_tile;
423  struct city *pcity;
424 
425  /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
426  * the caller? Check in the code that emits the signal. */
427  fc_assert_ret_val(target, false);
428 
429  uplayer = unit_owner(target);
430 
431  // A unit is supposed to have an owner.
432  fc_assert_ret_val(uplayer, false);
433 
434  /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
435  * the caller? Check in the code that emits the signal. */
436  fc_assert_ret_val(actor, false);
437 
438  // Where is the actor player?
439  fc_assert_ret_val(pplayer, false);
440 
441  target_tile = unit_tile(target);
442 
443  // Expel the target unit to his owner's primary capital.
444  // TODO: Could be also nearest secondary capital
445  pcity = player_primary_capital(uplayer);
446 
447  // N.B: unit_link() always returns the same pointer.
448  sz_strlcpy(target_link, unit_link(target));
449 
450  if (pcity == nullptr) {
451  // No where to send the expelled unit.
452 
453  // The price of failing an expulsion is a single move.
454  actor->moves_left = MAX(0, actor->moves_left - SINGLE_MOVE);
455  send_unit_info(nullptr, actor);
456 
457  // Notify the actor player.
458  notify_player(pplayer, target_tile, E_UNIT_ACTION_FAILED, ftc_server,
459  // TRANS: <Poles> <Spy>
460  _("The %s don't have a capital to expel their %s to."),
461  nation_plural_for_player(uplayer), target_link);
462 
463  // Nothing more could be done.
464  return false;
465  }
466 
467  /* Please review the code below and above (including the strings sent to
468  * the players) before allowing expulsion to non capital cities. */
469  fc_assert(is_capital(pcity));
470 
471  // Notify everybody involved.
472  notify_player(pplayer, target_tile, E_UNIT_DID_EXPEL, ftc_server,
473  // TRANS: <Border Patrol> ... <Spy>
474  _("Your %s succeeded in expelling the %s %s."),
475  unit_link(actor), nation_adjective_for_player(uplayer),
476  target_link);
477  notify_player(uplayer, target_tile, E_UNIT_WAS_EXPELLED, ftc_server,
478  // TRANS: <unit> ... <Poles>
479  _("Your %s was expelled by the %s."), target_link,
480  nation_plural_for_player(pplayer));
481 
482  // Being expelled destroys all remaining movement.
483  if (!teleport_unit_to_city(target, pcity, 0, false)) {
484  qCritical("Bug in unit expulsion: unit can't teleport.");
485 
486  return false;
487  }
488 
489  // This may cause a diplomatic incident
490  action_consequence_success(paction, pplayer, uplayer, target_tile,
491  target_link);
492 
493  // Mission accomplished.
494  return true;
495 }
496 
503 static bool do_heal_unit(struct player *act_player, struct unit *act_unit,
504  struct unit *tgt_unit, const struct action *paction)
505 {
506  int healing_limit;
507  int tgt_hp_max;
508  struct player *tgt_player;
509  struct tile *tgt_tile;
510  char act_unit_link[MAX_LEN_LINK];
511  char tgt_unit_link[MAX_LEN_LINK];
512  const char *tgt_unit_owner;
513 
514  // Sanity checks: got all the needed input.
515  fc_assert_ret_val(act_player, false);
516  fc_assert_ret_val(act_unit, false);
517  fc_assert_ret_val(tgt_unit, false);
518 
519  // The target unit can't have more HP than this.
520  tgt_hp_max = unit_type_get(tgt_unit)->hp;
521 
522  /* Sanity check: target isn't at full health and can therefore can be
523  * healed. */
524  fc_assert_ret_val(tgt_unit->hp < tgt_hp_max, false);
525 
526  // Fetch the target unit's owner.
527  tgt_player = unit_owner(tgt_unit);
528  fc_assert_ret_val(tgt_player, false);
529 
530  // Fetch the target unit's tile.
531  tgt_tile = unit_tile(tgt_unit);
532  fc_assert_ret_val(tgt_tile, false);
533 
534  // The max amount of HP that can be added.
535  healing_limit = tgt_hp_max / 4;
536 
537  // Heal the target unit.
538  tgt_unit->hp = MIN(tgt_unit->hp + healing_limit, tgt_hp_max);
539  send_unit_info(nullptr, tgt_unit);
540 
541  send_unit_info(nullptr, act_unit);
542 
543  /* Every call to unit_link() overwrites the previous. Two units are being
544  * linked to. */
545  sz_strlcpy(act_unit_link, unit_link(act_unit));
546  sz_strlcpy(tgt_unit_link, unit_link(tgt_unit));
547 
548  // Notify everybody involved.
549  if (act_player == tgt_player) {
550  /* TRANS: used instead of nation adjective when the nation is
551  * domestic. */
552  tgt_unit_owner = _("your");
553  } else {
554  tgt_unit_owner = nation_adjective_for_player(unit_nationality(tgt_unit));
555  }
556 
557  notify_player(act_player, tgt_tile, E_MY_UNIT_DID_HEAL, ftc_server,
558  /* TRANS: If foreign: Your Leader heals Finnish Warrior.
559  * If domestic: Your Leader heals your Warrior. */
560  _("Your %s heals %s %s."), act_unit_link, tgt_unit_owner,
561  tgt_unit_link);
562 
563  if (act_player != tgt_player) {
564  notify_player(tgt_player, tgt_tile, E_MY_UNIT_WAS_HEALED, ftc_server,
565  // TRANS: Norwegian ... Leader ... Warrior
566  _("%s %s heals your %s."),
568  act_unit_link, tgt_unit_link);
569  }
570 
571  // This may have diplomatic consequences.
572  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
573  unit_link(tgt_unit));
574 
575  return true;
576 }
577 
584 static bool do_unit_alight(struct player *act_player, struct unit *act_unit,
585  struct unit *tgt_unit,
586  const struct action *paction)
587 {
588  // Unload the unit and send out info to clients.
589  unit_transport_unload_send(act_unit);
590 
591  return true;
592 }
593 
602 static bool do_unit_board(struct player *act_player, struct unit *act_unit,
603  struct unit *tgt_unit,
604  const struct action *paction)
605 {
606  if (unit_transported(act_unit)) {
607  unit_transport_unload_send(act_unit);
608  }
609 
610  // Load the unit and send out info to clients.
611  unit_transport_load_send(act_unit, tgt_unit);
612 
613  return true;
614 }
615 
622 static bool do_unit_unload(struct player *act_player, struct unit *act_unit,
623  struct unit *tgt_unit,
624  const struct action *paction)
625 {
626  // Unload the unit and send out info to clients.
627  unit_transport_unload_send(tgt_unit);
628 
629  return true;
630 }
631 
638 static bool do_disembark(struct player *act_player, struct unit *act_unit,
639  struct tile *tgt_tile, const struct action *paction)
640 {
641  int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
642 
643  // Sanity checks
644  fc_assert_ret_val(act_player, false);
645  fc_assert_ret_val(act_unit, false);
646  fc_assert_ret_val(tgt_tile, false);
647  fc_assert_ret_val(paction, false);
648 
649  unit_move(act_unit, tgt_tile, move_cost, nullptr, true, false);
650 
651  return true;
652 }
653 
662 static bool do_unit_embark(struct player *act_player, struct unit *act_unit,
663  struct unit *tgt_unit,
664  const struct action *paction)
665 {
666  struct tile *tgt_tile;
667  int move_cost;
668 
669  // Sanity checks
670  fc_assert_ret_val(act_player, false);
671  fc_assert_ret_val(act_unit, false);
672  fc_assert_ret_val(tgt_unit, false);
673  fc_assert_ret_val(paction, false);
674 
675  if (unit_transported(act_unit)) {
676  // Assumed to be legal.
677  unit_transport_unload_send(act_unit);
678  }
679 
680  // Do it.
681  tgt_tile = unit_tile(tgt_unit);
682  move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
683  unit_move(act_unit, tgt_tile, move_cost, tgt_unit, false, false);
684 
685  return true;
686 }
687 
695 static bool rel_may_become_war(const struct player *pplayer,
696  const struct player *oplayer)
697 {
698  enum diplstate_type ds;
699 
700  fc_assert_ret_val(pplayer, false);
701  fc_assert_ret_val(oplayer, false);
702 
703  ds = player_diplstate_get(pplayer, oplayer)->type;
704 
705  // The player can't declare war on someone he already is at war with.
706  return ds != DS_WAR
707  // The player can't declare war on a teammate or on himself.
708  && ds != DS_TEAM && pplayer != oplayer;
709 }
710 
717 static struct player *need_war_player_hlp(const struct unit *actor,
718  const action_id act,
719  const struct tile *target_tile,
720  const struct city *target_city,
721  const struct unit *target_unit)
722 {
723  struct player *target_player = nullptr;
724  struct player *actor_player = unit_owner(actor);
725  struct action *paction = action_by_number(act);
726 
727  fc_assert_ret_val(paction != nullptr, nullptr);
728 
729  if (action_id_get_actor_kind(act) != AAK_UNIT) {
730  // No unit can ever do this action so it isn't relevant.
731  return nullptr;
732  }
733 
734  if (!unit_can_do_action(actor, act)) {
735  // The unit can't do the action no matter if there is war or not.
736  return nullptr;
737  }
738 
739  /* Look for hard coded war requirements that can't be an action enabler
740  * requirement. */
741  switch (paction->result) {
742  case ACTRES_BOMBARD:
743  case ACTRES_ATTACK:
744  // Target is a unit stack but a city can block it.
745  fc_assert_action(action_get_target_kind(paction) == ATK_UNITS, break);
746  if (target_tile) {
747  struct city *tcity;
748 
749  if ((tcity = tile_city(target_tile))
750  && rel_may_become_war(unit_owner(actor), city_owner(tcity))) {
751  return city_owner(tcity);
752  }
753  }
754  break;
755 
756  case ACTRES_PARADROP:
757  // Target is a tile but a city or unit can block it.
758  fc_assert_action(action_get_target_kind(paction) == ATK_TILE, break);
759  if (target_tile
760  && map_is_known_and_seen(target_tile, actor_player, V_MAIN)) {
761  // Seen tile unit savers
762 
763  struct city *tcity;
764 
765  if ((tcity = is_non_attack_city_tile(target_tile, actor_player))) {
766  return city_owner(tcity);
767  }
768 
769  unit_list_iterate(target_tile->units, pother)
770  {
771  if (can_player_see_unit(actor_player, pother)
772  && pplayers_non_attack(actor_player, unit_owner(pother))) {
773  return unit_owner(pother);
774  }
775  }
777  }
778  break;
779  case ACTRES_ESTABLISH_EMBASSY:
780  case ACTRES_SPY_INVESTIGATE_CITY:
781  case ACTRES_SPY_POISON:
782  case ACTRES_SPY_SPREAD_PLAGUE:
783  case ACTRES_SPY_STEAL_GOLD:
784  case ACTRES_SPY_SABOTAGE_CITY:
785  case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
786  case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
787  case ACTRES_SPY_STEAL_TECH:
788  case ACTRES_SPY_TARGETED_STEAL_TECH:
789  case ACTRES_SPY_INCITE_CITY:
790  case ACTRES_TRADE_ROUTE:
791  case ACTRES_MARKETPLACE:
792  case ACTRES_HELP_WONDER:
793  case ACTRES_SPY_BRIBE_UNIT:
794  case ACTRES_SPY_SABOTAGE_UNIT:
795  case ACTRES_CAPTURE_UNITS: // Only foreign is a hard req.
796  case ACTRES_FOUND_CITY:
797  case ACTRES_JOIN_CITY:
798  case ACTRES_STEAL_MAPS:
799  case ACTRES_SPY_NUKE:
800  case ACTRES_NUKE:
801  case ACTRES_NUKE_CITY:
802  case ACTRES_NUKE_UNITS:
803  case ACTRES_DESTROY_CITY:
804  case ACTRES_EXPEL_UNIT:
805  case ACTRES_RECYCLE_UNIT:
806  case ACTRES_DISBAND_UNIT:
807  case ACTRES_HOME_CITY:
808  case ACTRES_UPGRADE_UNIT:
809  case ACTRES_AIRLIFT:
810  case ACTRES_HEAL_UNIT:
811  case ACTRES_STRIKE_BUILDING:
812  case ACTRES_STRIKE_PRODUCTION:
813  case ACTRES_CONQUER_CITY:
814  case ACTRES_TRANSFORM_TERRAIN:
815  case ACTRES_CULTIVATE:
816  case ACTRES_PLANT:
817  case ACTRES_PILLAGE:
818  case ACTRES_CLEAN_POLLUTION:
819  case ACTRES_CLEAN_FALLOUT:
820  case ACTRES_FORTIFY:
821  case ACTRES_CONVERT:
822  case ACTRES_ROAD:
823  case ACTRES_BASE:
824  case ACTRES_MINE:
825  case ACTRES_IRRIGATE:
826  case ACTRES_TRANSPORT_ALIGHT:
827  case ACTRES_TRANSPORT_UNLOAD:
828  case ACTRES_TRANSPORT_DISEMBARK:
829  case ACTRES_TRANSPORT_BOARD:
830  case ACTRES_TRANSPORT_EMBARK:
831  case ACTRES_SPY_ATTACK:
832  case ACTRES_NONE:
833  // No special help.
834  break;
835  }
836 
837  // Look for war requirements from the action enablers.
838  switch (action_get_target_kind(paction)) {
839  case ATK_CITY:
840  if (target_city == nullptr) {
841  // No target city.
842  return nullptr;
843  }
844 
845  target_player = city_owner(target_city);
846  break;
847  case ATK_UNIT:
848  if (target_unit == nullptr) {
849  // No target unit.
850  return nullptr;
851  }
852  target_player = unit_owner(target_unit);
853  break;
854  case ATK_UNITS:
855  if (target_tile == nullptr) {
856  // No target units since no target tile.
857  return nullptr;
858  }
859 
860  unit_list_iterate(target_tile->units, tunit)
861  {
862  if (rel_may_become_war(actor_player, unit_owner(tunit))) {
863  target_player = unit_owner(tunit);
864  break;
865  }
866  }
868  break;
869  case ATK_TILE:
870  if (target_tile == nullptr) {
871  // No target tile.
872  return nullptr;
873  }
874  target_player = tile_owner(target_tile);
875  break;
876  case ATK_SELF:
877  // Can't declare war on itself.
878  return nullptr;
879  break;
880  case ATK_COUNT:
881  // Nothing to check.
882  fc_assert(action_id_get_target_kind(act) != ATK_COUNT);
883  return nullptr;
884  }
885 
886  if (target_player == nullptr) {
887  // Declaring war won't enable the specified action.
888  return nullptr;
889  }
890 
891  if (!rel_may_become_war(actor_player, target_player)) {
892  // Can't declare war.
893  return nullptr;
894  }
895 
897  unit_type_get(actor), act,
898  player_diplstate_get(actor_player, target_player)->type, true)) {
899  // The current diplrel isn't a problem.
900  return nullptr;
901  }
902  if (!can_utype_do_act_if_tgt_diplrel(unit_type_get(actor), act, DS_WAR,
903  true)) {
904  // War won't make this action legal.
905  return nullptr;
906  }
907  /* No check if other, non war, diplomatic states also could make the
908  * action legal. This is need_war_player() so war is always the answer.
909  * If you disagree and decide to add support please check that
910  * webperimental's "can't found a city on a tile belonging to a non enemy"
911  * rule still is detected. */
912 
913  return target_player;
914 }
915 
921 static struct player *need_war_player(const struct unit *actor,
922  const action_id act_id,
923  const struct tile *target_tile,
924  const struct city *target_city,
925  const struct unit *target_unit)
926 {
927  if (act_id == ACTION_ANY) {
928  // Any action at all will do.
929  action_iterate(act)
930  {
931  struct player *war_player;
932 
933  war_player = need_war_player_hlp(actor, act, target_tile, target_city,
934  target_unit);
935 
936  if (war_player != nullptr) {
937  // Declaring war on this player may enable this action.
938  return war_player;
939  }
940  }
942 
943  // No action at all may be enabled by declaring war.
944  return nullptr;
945  } else {
946  // Look for the specified action.
947  return need_war_player_hlp(actor, act_id, target_tile, target_city,
948  target_unit);
949  }
950 }
951 
957 static bool does_terrain_block_action(const action_id act_id, bool is_target,
958  struct unit *actor_unit,
959  struct terrain *pterrain)
960 {
961  if (act_id == ACTION_ANY) {
962  // Any action is OK.
963  action_iterate(alt_act)
964  {
965  if (utype_can_do_action(unit_type_get(actor_unit), alt_act)
966  && !does_terrain_block_action(alt_act, is_target, actor_unit,
967  pterrain)) {
968  // Only one action has to be possible.
969  return false;
970  }
971  }
973 
974  // No action enabled.
975  return true;
976  }
977 
978  // ACTION_ANY is handled above.
979  fc_assert_ret_val(action_id_exists(act_id), false);
980 
982  {
984  pterrain,
985  (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
987  &enabler->actor_reqs)) {
988  // This terrain kind doesn't block this action enabler.
989  return false;
990  }
991  }
993 
994  return true;
995 }
996 
1002 static bool does_nation_block_action(const action_id act_id, bool is_target,
1003  struct unit *actor_unit,
1004  struct nation_type *pnation)
1005 {
1006  if (act_id == ACTION_ANY) {
1007  // Any action is OK.
1008  action_iterate(alt_act)
1009  {
1010  if (utype_can_do_action(unit_type_get(actor_unit), alt_act)
1011  && !does_nation_block_action(alt_act, is_target, actor_unit,
1012  pnation)) {
1013  // Only one action has to be possible.
1014  return false;
1015  }
1016  }
1018 
1019  // No action enabled.
1020  return true;
1021  }
1022 
1023  // ACTION_ANY is handled above.
1024  fc_assert_ret_val(action_id_exists(act_id), false);
1025 
1027  {
1029  pnation,
1030  (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1032  &enabler->actor_reqs)) {
1033  // This nation doesn't block this action enabler.
1034  return false;
1035  }
1036  }
1038 
1039  return true;
1040 }
1041 
1046 static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1047  const action_id act_id,
1048  const struct tile *target_tile,
1049  const struct city *target_city,
1050  const struct unit *target_unit)
1051 {
1052  struct player *must_war_player;
1053  const struct action *paction;
1054  struct action *blocker;
1055  const struct player *act_player = unit_owner(punit);
1056  const struct unit_type *act_utype = unit_type_get(punit);
1057  struct player *tgt_player = nullptr;
1058  auto *explnat = new ane_expl;
1059  bool can_exist =
1060  can_unit_exist_at_tile(&(wld.map), punit, unit_tile(punit));
1061  bool on_native = is_native_tile(unit_type_get(punit), unit_tile(punit));
1062  int action_custom;
1063 
1064  // Not know yet. (Initialize before the below check.)
1065  explnat->kind = ANEK_UNKNOWN;
1066 
1067  paction = action_by_number(act_id);
1068 
1069  if (act_id != ACTION_ANY) {
1070  // A specific action should have a suitable target.
1071  switch (action_get_target_kind(paction)) {
1072  case ATK_CITY:
1073  if (target_city == nullptr) {
1074  explnat->kind = ANEK_MISSING_TARGET;
1075  }
1076  break;
1077  case ATK_UNIT:
1078  if (target_unit == nullptr) {
1079  explnat->kind = ANEK_MISSING_TARGET;
1080  }
1081  break;
1082  case ATK_UNITS:
1083  case ATK_TILE:
1084  if (target_tile == nullptr) {
1085  explnat->kind = ANEK_MISSING_TARGET;
1086  }
1087  break;
1088  case ATK_SELF:
1089  // No other target.
1090  break;
1091  case ATK_COUNT:
1092  fc_assert(action_get_target_kind(paction) != ATK_COUNT);
1093  break;
1094  }
1095  }
1096 
1097  if (explnat->kind == ANEK_MISSING_TARGET) {
1098  // No point continuing.
1099  return explnat;
1100  }
1101 
1102  if (act_id == ACTION_ANY) {
1103  // Find the target player of some actions.
1104  if (target_city) {
1105  // Individual city targets have the highest priority.
1106  tgt_player = city_owner(target_city);
1107  } else if (target_unit) {
1108  // Individual unit targets have the next priority.
1109  tgt_player = unit_owner(target_unit);
1110  } else if (target_tile) {
1111  // Tile targets have the lowest priority.
1112  tgt_player = tile_owner(target_tile);
1113  }
1114  } else {
1115  // Find the target player of this action.
1116  switch (action_get_target_kind(paction)) {
1117  case ATK_CITY:
1118  tgt_player = city_owner(target_city);
1119  break;
1120  case ATK_UNIT:
1121  tgt_player = unit_owner(target_unit);
1122  break;
1123  case ATK_TILE:
1124  tgt_player = tile_owner(target_tile);
1125  break;
1126  case ATK_UNITS:
1127  /* A unit stack may contain units with multiple owners. Pick the
1128  * first one. */
1129  if (target_tile && unit_list_size(target_tile->units) > 0) {
1130  tgt_player = unit_owner(unit_list_get(target_tile->units, 0));
1131  }
1132  break;
1133  case ATK_SELF:
1134  // A unit acting against itself.
1135  tgt_player = unit_owner(punit);
1136  break;
1137  case ATK_COUNT:
1138  fc_assert(action_get_target_kind(paction) != ATK_COUNT);
1139  break;
1140  }
1141  }
1142 
1143  if (act_id == ACTION_ANY) {
1144  action_custom = 0;
1145  } else {
1146  switch (paction->result) {
1147  case ACTRES_UPGRADE_UNIT:
1148  action_custom = unit_upgrade_test(punit, false);
1149  break;
1150  case ACTRES_AIRLIFT:
1151  action_custom = test_unit_can_airlift_to(nullptr, punit, target_city);
1152  break;
1153  case ACTRES_NUKE_UNITS:
1154  action_custom = unit_attack_units_at_tile_result(punit, target_tile);
1155  break;
1156  case ACTRES_ATTACK:
1157  action_custom = unit_attack_units_at_tile_result(punit, target_tile);
1158  break;
1159  case ACTRES_CONQUER_CITY:
1160  if (target_city) {
1161  action_custom = unit_move_to_tile_test(
1162  &(wld.map), punit, punit->activity, unit_tile(punit),
1163  city_tile(target_city), false, nullptr, true);
1164  } else {
1165  action_custom = MR_OK;
1166  }
1167  break;
1168  case ACTRES_TRANSPORT_EMBARK:
1169  if (target_unit) {
1170  action_custom = unit_move_to_tile_test(
1171  &(wld.map), punit, punit->activity, unit_tile(punit),
1172  unit_tile(target_unit), false, nullptr, false);
1173  } else {
1174  action_custom = MR_OK;
1175  }
1176  break;
1177  case ACTRES_TRANSPORT_DISEMBARK:
1178  if (target_tile) {
1179  action_custom = unit_move_to_tile_test(
1180  &(wld.map), punit, punit->activity, unit_tile(punit),
1181  target_tile, false, nullptr, false);
1182  } else {
1183  action_custom = MR_OK;
1184  }
1185  break;
1186  default:
1187  action_custom = 0;
1188  break;
1189  }
1190  }
1191 
1192  if (!unit_can_do_action(punit, act_id)) {
1193  explnat->kind = ANEK_ACTOR_UNIT;
1194  } else if (action_has_result_safe(paction, ACTRES_FOUND_CITY)
1195  && tile_city(target_tile)) {
1196  explnat->kind = ANEK_BAD_TARGET;
1197  } else if ((!can_exist
1198  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1199  USP_LIVABLE_TILE, false))
1200  || (can_exist
1202  act_id, USP_LIVABLE_TILE,
1203  true))) {
1204  explnat->kind = ANEK_BAD_TERRAIN_ACT;
1205  explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1206  } else if ((!on_native
1207  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1208  USP_NATIVE_TILE, false))
1209  || (on_native
1211  unit_type_get(punit), act_id, USP_NATIVE_TILE, true))) {
1212  explnat->kind = ANEK_BAD_TERRAIN_ACT;
1213  explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1214  } else if (punit
1215  && does_terrain_block_action(act_id, false, punit,
1216  tile_terrain(unit_tile(punit)))) {
1217  // No action enabler allows acting against this terrain kind.
1218  explnat->kind = ANEK_BAD_TERRAIN_ACT;
1219  explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1220  } else if (action_has_result_safe(paction, ACTRES_FOUND_CITY)
1221  && target_tile
1222  && terrain_has_flag(tile_terrain(target_tile), TER_NO_CITIES)) {
1223  explnat->kind = ANEK_BAD_TERRAIN_TGT;
1224  explnat->no_act_terrain = tile_terrain(target_tile);
1225  } else if (action_has_result_safe(paction, ACTRES_PARADROP) && target_tile
1226  && map_is_known_and_seen(target_tile, unit_owner(punit), V_MAIN)
1227  && (!can_unit_exist_at_tile(&(wld.map), punit, target_tile)
1228  && (!game.info.paradrop_to_transport
1229  || !unit_could_load_at(punit, target_tile)))) {
1230  explnat->kind = ANEK_BAD_TERRAIN_TGT;
1231  explnat->no_act_terrain = tile_terrain(target_tile);
1232  } else if (target_tile
1233  && does_terrain_block_action(act_id, true, punit,
1234  tile_terrain(target_tile))) {
1235  // No action enabler allows acting against this terrain kind.
1236  explnat->kind = ANEK_BAD_TERRAIN_TGT;
1237  explnat->no_act_terrain = tile_terrain(target_tile);
1238  } else if (unit_transported(punit)
1239  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1240  USP_TRANSPORTED, true)) {
1241  explnat->kind = ANEK_IS_TRANSPORTED;
1242  } else if (!unit_transported(punit)
1243  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1244  USP_TRANSPORTED, false)) {
1245  explnat->kind = ANEK_IS_NOT_TRANSPORTED;
1246  } else if (0 < get_transporter_occupancy(punit)
1247  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1248  USP_TRANSPORTING, true)) {
1249  explnat->kind = ANEK_IS_TRANSPORTING;
1250  } else if (0 >= get_transporter_occupancy(punit)
1251  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1252  USP_TRANSPORTING, false)) {
1253  explnat->kind = ANEK_IS_NOT_TRANSPORTING;
1254  } else if ((punit->homecity > 0)
1255  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1256  USP_HAS_HOME_CITY, true)) {
1257  explnat->kind = ANEK_ACTOR_HAS_HOME_CITY;
1258  } else if ((punit->homecity <= 0)
1259  && !utype_can_do_act_when_ustate(unit_type_get(punit), act_id,
1260  USP_HAS_HOME_CITY, false)) {
1261  explnat->kind = ANEK_ACTOR_HAS_NO_HOME_CITY;
1262  } else if ((punit->homecity <= 0)
1263  && (action_has_result_safe(paction, ACTRES_TRADE_ROUTE)
1264  || action_has_result_safe(paction, ACTRES_MARKETPLACE))) {
1265  explnat->kind = ANEK_ACTOR_HAS_NO_HOME_CITY;
1266  } else if (act_player && tgt_player
1267  && (player_diplstate_get(act_player, tgt_player)->type
1268  == DS_PEACE)
1270  DS_PEACE, false)
1272  act_id, DS_PEACE, true)) {
1273  explnat->kind = ANEK_PEACE;
1274  explnat->peace_with = tgt_player;
1275  } else if ((must_war_player = need_war_player(punit, act_id, target_tile,
1276  target_city, target_unit))) {
1277  explnat->kind = ANEK_NO_WAR;
1278  explnat->no_war_with = must_war_player;
1279  } else if (action_mp_full_makes_legal(punit, act_id)) {
1280  explnat->kind = ANEK_LOW_MP;
1281  } else if (tgt_player && unit_owner(punit) != tgt_player
1283  unit_type_get(punit), act_id, DRO_FOREIGN, true)) {
1284  explnat->kind = ANEK_FOREIGN;
1285  } else if (tgt_player && unit_owner(punit) == tgt_player
1287  unit_type_get(punit), act_id, DRO_FOREIGN, false)) {
1288  explnat->kind = ANEK_DOMESTIC;
1289  } else if (punit
1290  && does_nation_block_action(act_id, false, punit,
1291  unit_owner(punit)->nation)) {
1292  explnat->kind = ANEK_NATION_ACT;
1293  explnat->no_act_nation = unit_owner(punit)->nation;
1294  } else if (tgt_player
1295  && does_nation_block_action(act_id, true, punit,
1296  tgt_player->nation)) {
1297  explnat->kind = ANEK_NATION_TGT;
1298  explnat->no_act_nation = tgt_player->nation;
1299  } else if ((target_tile && tile_city(target_tile))
1300  && !utype_may_act_tgt_city_tile(unit_type_get(punit), act_id,
1301  CITYT_CENTER, true)) {
1302  explnat->kind = ANEK_IS_CITY_CENTER;
1303  } else if ((target_tile && !tile_city(target_tile))
1304  && !utype_may_act_tgt_city_tile(unit_type_get(punit), act_id,
1305  CITYT_CENTER, false)) {
1306  explnat->kind = ANEK_IS_NOT_CITY_CENTER;
1307  } else if ((target_tile && tile_owner(target_tile) != nullptr)
1308  && !utype_may_act_tgt_city_tile(unit_type_get(punit), act_id,
1309  CITYT_CLAIMED, true)) {
1310  explnat->kind = ANEK_TGT_IS_CLAIMED;
1311  } else if ((target_tile && tile_owner(target_tile) == nullptr)
1312  && !utype_may_act_tgt_city_tile(unit_type_get(punit), act_id,
1313  CITYT_CLAIMED, false)) {
1314  explnat->kind = ANEK_TGT_IS_UNCLAIMED;
1315  } else if (paction && punit
1316  && ((target_tile
1318  paction,
1319  real_map_distance(unit_tile(punit), target_tile)))
1320  || (target_city
1322  paction, real_map_distance(unit_tile(punit),
1323  city_tile(target_city))))
1324  || (target_unit
1326  paction,
1328  unit_tile(target_unit)))))) {
1329  explnat->kind = ANEK_DISTANCE_FAR;
1330  explnat->distance = paction->max_distance;
1331  } else if (action_has_result_safe(paction, ACTRES_PARADROP) && punit
1332  && target_tile
1333  && real_map_distance(unit_tile(punit), target_tile)
1334  > unit_type_get(punit)->paratroopers_range) {
1335  explnat->kind = ANEK_DISTANCE_FAR;
1336  explnat->distance = unit_type_get(punit)->paratroopers_range;
1337  } else if (paction && punit
1338  && ((target_tile
1339  && real_map_distance(unit_tile(punit), target_tile)
1340  < paction->min_distance)
1341  || (target_city
1342  && real_map_distance(unit_tile(punit),
1343  city_tile(target_city))
1344  < paction->min_distance)
1345  || (target_unit
1346  && real_map_distance(unit_tile(punit),
1347  unit_tile(target_unit))
1348  < paction->min_distance))) {
1349  explnat->kind = ANEK_DISTANCE_NEAR;
1350  explnat->distance = paction->min_distance;
1351  } else if (target_city
1352  && (action_has_result_safe(paction, ACTRES_JOIN_CITY)
1353  && action_actor_utype_hard_reqs_ok(ACTRES_JOIN_CITY,
1354  unit_type_get(punit))
1355  && (city_size_get(target_city) + unit_pop_value(punit)
1356  > game.info.add_to_size_limit))) {
1357  /* TODO: Check max city size requirements from action enabler target
1358  * vectors. */
1359  explnat->kind = ANEK_CITY_TOO_BIG;
1360  } else if (target_city
1361  && (action_has_result_safe(paction, ACTRES_JOIN_CITY)
1362  && action_actor_utype_hard_reqs_ok(ACTRES_JOIN_CITY,
1363  unit_type_get(punit))
1364  && (!city_can_grow_to(target_city,
1365  city_size_get(target_city)
1366  + unit_pop_value(punit))))) {
1367  explnat->kind = ANEK_CITY_POP_LIMIT;
1368  } else if ((action_has_result_safe(paction, ACTRES_NUKE_UNITS)
1369  || action_has_result_safe(paction, ACTRES_ATTACK))
1370  && action_custom != ATT_OK) {
1371  switch (action_custom) {
1372  case ATT_NON_ATTACK:
1373  explnat->kind = ANEK_ACTOR_UNIT;
1374  break;
1375  case ATT_UNREACHABLE:
1376  explnat->kind = ANEK_TGT_UNREACHABLE;
1377  break;
1378  case ATT_NONNATIVE_SRC:
1379  explnat->kind = ANEK_BAD_TERRAIN_ACT;
1380  explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1381  break;
1382  case ATT_NONNATIVE_DST:
1383  explnat->kind = ANEK_BAD_TERRAIN_TGT;
1384  explnat->no_act_terrain = tile_terrain(target_tile);
1385  break;
1386  default:
1387  fc_assert(action_custom != ATT_OK);
1388  explnat->kind = ANEK_UNKNOWN;
1389  break;
1390  }
1391  } else if (action_has_result_safe(paction, ACTRES_AIRLIFT)
1392  && action_custom == AR_SRC_NO_FLIGHTS) {
1393  explnat->kind = ANEK_CITY_NO_CAPACITY;
1394  explnat->capacity_city = tile_city(unit_tile(punit));
1395  } else if (action_has_result_safe(paction, ACTRES_AIRLIFT)
1396  && action_custom == AR_DST_NO_FLIGHTS) {
1397  explnat->kind = ANEK_CITY_NO_CAPACITY;
1398  explnat->capacity_city = game_city_by_number(target_city->id);
1399  } else if (action_has_result_safe(paction, ACTRES_FOUND_CITY)
1400  && citymindist_prevents_city_on_tile(target_tile)) {
1401  explnat->kind = ANEK_CITY_TOO_CLOSE_TGT;
1402  } else if (action_has_result_safe(paction, ACTRES_PARADROP) && target_tile
1403  && !map_is_known(target_tile, unit_owner(punit))) {
1404  explnat->kind = ANEK_TGT_TILE_UNKNOWN;
1405  } else if ((action_has_result_safe(paction, ACTRES_CONQUER_CITY)
1406  || action_has_result_safe(paction, ACTRES_TRANSPORT_EMBARK)
1407  || action_has_result_safe(paction, ACTRES_TRANSPORT_DISEMBARK))
1408  && action_custom != MR_OK) {
1409  switch (action_custom) {
1410  case MR_CANNOT_DISEMBARK:
1411  explnat->kind = ANEK_DISEMBARK_ACT;
1412  break;
1413  case MR_TRIREME:
1414  explnat->kind = ANEK_TRIREME_MOVE;
1415  break;
1416  default:
1417  fc_assert(action_custom != MR_OK);
1418  explnat->kind = ANEK_UNKNOWN;
1419  break;
1420  }
1421  } else if (action_has_result_safe(paction, ACTRES_SPY_BRIBE_UNIT)
1423  unit_owner(punit), unit_type_get(target_unit))) {
1424  explnat->kind = ANEK_TGT_IS_UNIQUE_ACT_HAS;
1425  explnat->no_tgt_utype = unit_type_get(target_unit);
1426  } else if ((game.scenario.prevent_new_cities
1428  ACTION_FOUND_CITY))
1429  && (action_has_result_safe(paction, ACTRES_FOUND_CITY)
1430  || act_id == ACTION_ANY)) {
1431  /* Please add a check for any new action forbidding scenario setting
1432  * above this comment. */
1433  explnat->kind = ANEK_SCENARIO_DISABLED;
1434  } else if (action_has_result_safe(paction, ACTRES_UPGRADE_UNIT)
1435  && action_custom == UU_NO_MONEY) {
1436  explnat->kind = ANEK_ACT_NOT_ENOUGH_MONEY;
1437  explnat->gold_needed = unit_upgrade_price(
1438  act_player, act_utype, can_upgrade_unittype(act_player, act_utype));
1439  } else if (paction
1440  && (blocker = action_is_blocked_by(act_id, punit, target_tile,
1441  target_city, target_unit))) {
1442  explnat->kind = ANEK_ACTION_BLOCKS;
1443  explnat->blocker = blocker;
1444  } else {
1445  explnat->kind = ANEK_UNKNOWN;
1446  }
1447 
1448  return explnat;
1449 }
1450 
1454 enum ane_kind action_not_enabled_reason(struct unit *punit, action_id act_id,
1455  const struct tile *target_tile,
1456  const struct city *target_city,
1457  const struct unit *target_unit)
1458 {
1459  struct ane_expl *explnat = expl_act_not_enabl(punit, act_id, target_tile,
1460  target_city, target_unit);
1461  enum ane_kind out = explnat->kind;
1462 
1463  delete explnat;
1464 
1465  return out;
1466 }
1467 
1472 static void explain_why_no_action_enabled(struct unit *punit,
1473  const struct tile *target_tile,
1474  const struct city *target_city,
1475  const struct unit *target_unit)
1476 {
1477  struct player *pplayer = unit_owner(punit);
1478  struct ane_expl *explnat = expl_act_not_enabl(
1479  punit, ACTION_ANY, target_tile, target_city, target_unit);
1480 
1481  switch (explnat->kind) {
1482  case ANEK_ACTOR_UNIT:
1483  /* This shouldn't happen unless the client is buggy given the current
1484  * users. */
1485  fc_assert_msg(explnat->kind != ANEK_ACTOR_UNIT,
1486  "Asked to explain why a non actor can't act.");
1487 
1488  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1489  _("Unit cannot do anything."));
1490  break;
1491  case ANEK_MISSING_TARGET:
1492  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1493  _("Your %s found no suitable target."),
1494  unit_name_translation(punit));
1495  break;
1496  case ANEK_BAD_TARGET:
1497  /* This shouldn't happen at the moment. Only specific action checks
1498  * will trigger bad target checks. This is a reply to a question about
1499  * any action. */
1500  fc_assert(explnat->kind != ANEK_BAD_TARGET);
1501 
1502  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1503  _("Your %s found no suitable target."),
1504  unit_name_translation(punit));
1505  break;
1506  case ANEK_BAD_TERRAIN_ACT: {
1507  QVector<QString> types;
1508  types.reserve(utype_count());
1509  int i = 0;
1511  USP_LIVABLE_TILE, false)
1512  && !can_unit_exist_at_tile(&(wld.map), punit, unit_tile(punit))) {
1513  unit_type_iterate(utype)
1514  {
1515  if (utype_can_do_act_when_ustate(utype, ACTION_ANY, USP_LIVABLE_TILE,
1516  false)) {
1517  i++;
1518  types.append(utype_name_translation(utype));
1519  }
1520  }
1522  }
1523 
1524  if (0 < i) {
1525  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1526  /* TRANS: terrain name
1527  * "Your Diplomat cannot act from Ocean. Only
1528  * Spy or Partisan ... */
1529  _("Your %s cannot act from %s. "
1530  "Only %s can act from a non livable tile."),
1531  unit_name_translation(punit),
1533  qUtf8Printable(strvec_to_and_list(types)));
1534  } else {
1535  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1536  // TRANS: terrain name
1537  _("Unit cannot act from %s."),
1539  }
1540  } break;
1541  case ANEK_BAD_TERRAIN_TGT:
1542  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1543  // TRANS: terrain name
1544  _("Unit cannot act against %s."),
1546  break;
1547  case ANEK_IS_TRANSPORTED:
1548  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1549  _("This unit is being transported, and"
1550  " so cannot act."));
1551  break;
1553  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1554  _("This unit cannot act when it isn't being "
1555  "transported."));
1556  break;
1557  case ANEK_IS_TRANSPORTING:
1558  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1559  _("This unit is transporting, and"
1560  " so cannot act."));
1561  break;
1563  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1564  _("This unit cannot act when it isn't transporting."));
1565  break;
1567  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1568  _("This unit has a home city, and so cannot act."));
1569  break;
1571  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1572  _("This unit cannot act unless it has a home city."));
1573  break;
1574  case ANEK_NO_WAR:
1575  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1576  _("You must declare war on %s first. Try using "
1577  "the Nations report."),
1578  player_name(explnat->no_war_with));
1579  break;
1580  case ANEK_PEACE:
1581  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1582  _("You must break peace with %s first. Try using"
1583  " the Nations report."),
1584  player_name(explnat->peace_with));
1585  break;
1586  case ANEK_DOMESTIC:
1587  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1588  _("This unit cannot act against domestic targets."));
1589  break;
1590  case ANEK_FOREIGN:
1591  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1592  _("This unit cannot act against foreign targets."));
1593  break;
1594  case ANEK_NATION_ACT:
1595  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1596  // TRANS: Swedish ... Riflemen
1597  _("%s %s cannot act."),
1599  unit_name_translation(punit));
1600  break;
1601  case ANEK_NATION_TGT:
1602  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1603  // TRANS: ... Pirate ...
1604  _("This unit cannot act against %s targets."),
1606  break;
1607  case ANEK_LOW_MP:
1608  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1609  _("This unit has too few moves left to act."));
1610  break;
1611  case ANEK_IS_CITY_CENTER:
1612  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1613  _("This unit cannot act against city centers."));
1614  break;
1616  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1617  _("This unit cannot act against non city centers."));
1618  break;
1619  case ANEK_TGT_IS_CLAIMED:
1620  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1621  _("This unit cannot act against claimed tiles."));
1622  break;
1623  case ANEK_TGT_IS_UNCLAIMED:
1624  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1625  _("This unit cannot act against unclaimed tiles."));
1626  break;
1627  case ANEK_DISTANCE_NEAR:
1628  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1629  _("This unit is too near its target to act."));
1630  break;
1631  case ANEK_DISTANCE_FAR:
1632  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1633  _("This unit is too far away from its target to act."));
1634  break;
1636  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1637  _("Can't perform any action this scenario permits."));
1638  break;
1640  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1641  _("Can't perform any action this close to a city."));
1642  break;
1643  case ANEK_CITY_TOO_BIG:
1644  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1645  // TRANS: Settler ... Berlin
1646  _("%s can't do anything to %s. It is too big."),
1647  unit_name_translation(punit), city_name_get(target_city));
1648  break;
1649  case ANEK_CITY_POP_LIMIT:
1650  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1651  // TRANS: London ... Settlers
1652  _("%s needs an improvement to grow, so "
1653  "%s cannot do anything to it."),
1654  city_name_get(target_city), unit_name_translation(punit));
1655  break;
1656  case ANEK_CITY_NO_CAPACITY:
1657  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1658  // TRANS: Paris ... Warriors (think: airlift)
1659  _("%s don't have enough capacity, so "
1660  "%s cannot do anything."),
1661  city_name_get(explnat->capacity_city),
1662  unit_name_translation(punit));
1663  break;
1664  case ANEK_TGT_TILE_UNKNOWN:
1665  notify_player(pplayer, target_tile, E_BAD_COMMAND, ftc_server,
1666  // TRANS: Paratroopers ...
1667  _("%s can't do anything to an unknown target tile."),
1668  unit_name_translation(punit));
1669  break;
1671  notify_player(pplayer, target_tile, E_BAD_COMMAND, ftc_server,
1672  // TRANS: Spy ... 154
1673  _("You can't afford having your %s do anything."
1674  " %d gold needed."),
1675  unit_name_translation(punit), explnat->gold_needed);
1676  {
1677  char tbuf[MAX_LEN_MSG];
1678 
1679  /* TRANS: Used below. Separate so treasury content too can determine
1680  * if this is plural. */
1681  fc_snprintf(tbuf, ARRAY_SIZE(tbuf),
1682  PL_("Treasury contains %d gold.",
1683  "Treasury contains %d gold.", pplayer->economic.gold),
1684  pplayer->economic.gold);
1685 
1686  notify_player(pplayer, target_tile, E_BAD_COMMAND, ftc_server,
1687  /* TRANS: "Spy can't do anything. 154 gold may help.
1688  * Treasury contains 100 gold." */
1689  PL_("%s can't do anything. %d gold may help. %s",
1690  "%s can't do anything. %d gold may help. %s",
1691  explnat->gold_needed),
1692  unit_name_translation(punit), explnat->gold_needed,
1693  tbuf);
1694  }
1695  break;
1696  case ANEK_TRIREME_MOVE:
1697  notify_player(pplayer, target_tile, E_BAD_COMMAND, ftc_server,
1698  _("%s cannot move that far from the coast line."),
1699  unit_link(punit));
1700  break;
1701  case ANEK_DISEMBARK_ACT:
1702  notify_player(
1703  pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1704  _("%s cannot disembark outside of a city or a native base "
1705  "for %s."),
1706  unit_link(punit),
1708  break;
1709  case ANEK_TGT_UNREACHABLE:
1710  notify_player(pplayer, target_tile, E_BAD_COMMAND, ftc_server,
1711  _("%s can't do anything since there is an unreachable "
1712  "unit."),
1713  unit_name_translation(punit));
1714  break;
1716  notify_player(pplayer, target_tile, E_BAD_COMMAND, ftc_server,
1717  _("%s can't do anything since you already have a %s."),
1718  unit_name_translation(punit),
1720  break;
1721  case ANEK_ACTION_BLOCKS:
1722  /* If an action blocked another action the blocking action must be
1723  * possible. */
1724  fc_assert(explnat->kind != ANEK_ACTION_BLOCKS);
1725  fc__fallthrough; // Fall through to unknown cause.
1726  case ANEK_UNKNOWN:
1727  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
1728  _("No action possible."));
1729  break;
1730  }
1731 
1732  delete explnat;
1733 }
1734 
1743 void handle_unit_get_actions(struct connection *pc, const int actor_unit_id,
1744  const int target_unit_id_client,
1745  const int target_tile_id,
1746  const int target_extra_id_client,
1747  const bool disturb_player)
1748 {
1749  struct player *actor_player;
1750  struct unit *actor_unit;
1751  struct tile *target_tile;
1752  struct act_prob probabilities[MAX_NUM_ACTIONS];
1753  struct unit *target_unit;
1754  struct city *target_city;
1755  struct extra_type *target_extra;
1756  int actor_target_distance;
1757  const struct player_tile *plrtile;
1758  int target_extra_id = target_extra_id_client;
1759 
1760  /* No potentially legal action is known yet. If none is found the player
1761  * should get an explanation. */
1762  bool at_least_one_action = false;
1763 
1764  // A target should only be sent if it is possible to act against it
1765  int target_city_id = IDENTITY_NUMBER_ZERO;
1766  int target_unit_id = IDENTITY_NUMBER_ZERO;
1767 
1768  actor_player = pc->playing;
1769  actor_unit = game_unit_by_number(actor_unit_id);
1770  target_tile = index_to_tile(&(wld.map), target_tile_id);
1771 
1772  // Initialize the action probabilities.
1773  action_iterate(act) { probabilities[act] = ACTPROB_NA; }
1775 
1776  // Check if the request is valid.
1777  if (!target_tile || !actor_unit || !actor_player
1778  || actor_unit->owner != actor_player) {
1779  dsend_packet_unit_actions(
1780  pc, actor_unit_id, IDENTITY_NUMBER_ZERO, IDENTITY_NUMBER_ZERO,
1781  target_tile_id, target_extra_id, disturb_player, probabilities);
1782  return;
1783  }
1784 
1785  // Select the targets.
1786 
1787  if (target_unit_id_client == IDENTITY_NUMBER_ZERO) {
1788  // Find a new target unit.
1789  target_unit = action_tgt_unit(actor_unit, target_tile, true);
1790  } else {
1791  // Prepare the client selected target unit.
1792  target_unit = game_unit_by_number(target_unit_id_client);
1793  }
1794 
1795  // Find the target city.
1796  target_city = action_tgt_city(actor_unit, target_tile, true);
1797 
1798  // The specified target unit must be located at the target tile.
1799  if (target_unit && unit_tile(target_unit) != target_tile) {
1800  notify_player(actor_player, unit_tile(actor_unit), E_BAD_COMMAND,
1801  ftc_server, _("Target not at target tile."));
1802  dsend_packet_unit_actions(
1803  pc, actor_unit_id, IDENTITY_NUMBER_ZERO, IDENTITY_NUMBER_ZERO,
1804  target_tile_id, target_extra_id, disturb_player, probabilities);
1805  return;
1806  }
1807 
1808  if (target_extra_id_client == EXTRA_NONE) {
1809  // See if a target extra can be found.
1810  target_extra = action_tgt_tile_extra(actor_unit, target_tile, true);
1811  } else {
1812  // Use the client selected target extra.
1813  target_extra = extra_by_number(target_extra_id_client);
1814  }
1815 
1816  /* The player may have outdated information about the target tile.
1817  * Limiting the player knowledge look up to the target tile is OK since
1818  * all targets must be located at it. */
1819  plrtile = map_get_player_tile(target_tile, actor_player);
1820 
1821  // Distance between actor and target tile.
1822  actor_target_distance =
1823  real_map_distance(unit_tile(actor_unit), target_tile);
1824 
1825  // Find out what can be done to the targets.
1826 
1827  // Set the probability for the actions.
1828  action_iterate(act)
1829  {
1830  if (action_id_get_actor_kind(act) != AAK_UNIT) {
1831  // Not relevant.
1832  continue;
1833  }
1834 
1835  switch (action_id_get_target_kind(act)) {
1836  case ATK_CITY:
1837  if (plrtile && plrtile->site) {
1838  // Only a known city may be targeted.
1839  if (target_city) {
1840  // Calculate the probabilities.
1841  probabilities[act] =
1842  action_prob_vs_city(actor_unit, act, target_city);
1843  } else if (!tile_is_seen(target_tile, actor_player)
1844  && action_maybe_possible_actor_unit(act, actor_unit)
1846  actor_target_distance)) {
1847  /* The target city is non existing. The player isn't aware of this
1848  * fact because he can't see the tile it was located on. The
1849  * actor unit it self doesn't contradict the requirements to
1850  * perform the action. The (no longer existing) target city was
1851  * known to be close enough. */
1852  probabilities[act] = ACTPROB_NOT_KNOWN;
1853  } else {
1854  /* The actor unit is known to be unable to act or the target city
1855  * is known to be too far away. */
1856  probabilities[act] = ACTPROB_IMPOSSIBLE;
1857  }
1858  } else {
1859  // No target to act against.
1860  probabilities[act] = ACTPROB_IMPOSSIBLE;
1861  }
1862  break;
1863  case ATK_UNIT:
1864  if (target_unit) {
1865  // Calculate the probabilities.
1866  probabilities[act] =
1867  action_prob_vs_unit(actor_unit, act, target_unit);
1868  } else {
1869  // No target to act against.
1870  probabilities[act] = ACTPROB_IMPOSSIBLE;
1871  }
1872  break;
1873  case ATK_UNITS:
1874  if (target_tile) {
1875  // Calculate the probabilities.
1876  probabilities[act] =
1877  action_prob_vs_units(actor_unit, act, target_tile);
1878  } else {
1879  // No target to act against.
1880  probabilities[act] = ACTPROB_IMPOSSIBLE;
1881  }
1882  break;
1883  case ATK_TILE:
1884  if (target_tile) {
1885  // Calculate the probabilities.
1886  probabilities[act] =
1887  action_prob_vs_tile(actor_unit, act, target_tile, target_extra);
1888  } else {
1889  // No target to act against.
1890  probabilities[act] = ACTPROB_IMPOSSIBLE;
1891  }
1892  break;
1893  case ATK_SELF:
1894  if (actor_target_distance == 0) {
1895  // Calculate the probabilities.
1896  probabilities[act] = action_prob_self(actor_unit, act);
1897  } else {
1898  /* Don't bother with self targeted actions unless the actor is
1899  * asking about what can be done to its own tile. */
1900  probabilities[act] = ACTPROB_IMPOSSIBLE;
1901  }
1902  break;
1903  case ATK_COUNT:
1904  fc_assert_action(action_id_get_target_kind(act) != ATK_COUNT,
1905  probabilities[act] = ACTPROB_IMPOSSIBLE);
1906  break;
1907  }
1908  }
1910 
1911  /* Analyze the probabilities. Decide what targets to send and if an
1912  * explanation is needed. */
1913  action_iterate(act)
1914  {
1915  if (action_prob_possible(probabilities[act])) {
1916  /* An action can be done. No need to explain why no action can be
1917  * done. */
1918  at_least_one_action = true;
1919 
1920  switch (action_id_get_target_kind(act)) {
1921  case ATK_CITY:
1922  /* The city should be sent as a target since it is possible to act
1923  * against it. */
1924 
1925  /* All city targeted actions requires that the player is aware of
1926  * the target city. It is therefore in the player's map. */
1927  fc_assert_action(plrtile, continue);
1928  fc_assert_action(plrtile->site, continue);
1929 
1930  target_city_id = plrtile->site->identity;
1931  break;
1932  case ATK_UNIT:
1933  /* The unit should be sent as a target since it is possible to act
1934  * against it. */
1935  fc_assert_ret(target_unit != nullptr);
1936  target_unit_id = target_unit->id;
1937  break;
1938  case ATK_TILE:
1939  // The target tile isn't selected here so it hasn't changed.
1940  fc_assert(target_tile != nullptr);
1941 
1942  if (target_extra && action_id_has_complex_target(act)) {
1943  // The target extra may have been set here.
1944  target_extra_id = target_extra->id;
1945  }
1946  break;
1947  case ATK_UNITS:
1948  // The target tile isn't selected here so it hasn't changed.
1949  fc_assert(target_tile != nullptr);
1950  break;
1951  case ATK_SELF:
1952  // The target unit is the actor unit. It is already sent.
1953  fc_assert(actor_unit != nullptr);
1954  break;
1955  case ATK_COUNT:
1956  fc_assert_msg(action_id_get_target_kind(act) != ATK_COUNT,
1957  "Invalid action target kind.");
1958  break;
1959  }
1960 
1961  if (target_city_id != IDENTITY_NUMBER_ZERO
1962  && target_unit_id != IDENTITY_NUMBER_ZERO) {
1963  // No need to find out more.
1964  break;
1965  }
1966  }
1967  }
1969 
1970  // Send possible actions and targets.
1971  dsend_packet_unit_actions(pc, actor_unit_id, target_unit_id,
1972  target_city_id, target_tile_id, target_extra_id,
1973  disturb_player, probabilities);
1974 
1975  if (disturb_player && !at_least_one_action) {
1976  // The user should get an explanation why no action is possible.
1977  explain_why_no_action_enabled(actor_unit, target_tile, target_city,
1978  target_unit);
1979  }
1980 }
1981 
1985 void handle_unit_rename(player *pplayer, int unit_id, const char *name)
1986 {
1987  auto unit = game_unit_by_number(unit_id);
1988  fc_assert_ret(unit != nullptr);
1989  fc_assert_ret(pplayer == unit->owner);
1990 
1991  // Use the QByteArray overload to prevent unbounded read
1992  unit->name = QString::fromUtf8(name, MAX_LEN_NAME);
1993  send_unit_info(nullptr, unit);
1994 }
1995 
2003 void illegal_action_msg(struct player *pplayer, const enum event_type event,
2004  struct unit *actor, const action_id stopped_action,
2005  const struct tile *target_tile,
2006  const struct city *target_city,
2007  const struct unit *target_unit)
2008 {
2009  struct ane_expl *explnat;
2010 
2011  // Explain why the action was illegal.
2012  explnat = expl_act_not_enabl(actor, stopped_action, target_tile,
2013  target_city, target_unit);
2014  switch (explnat->kind) {
2015  case ANEK_ACTOR_UNIT: {
2016  QString roles;
2017 
2018  if (role_units_translations(roles, action_id_get_role(stopped_action),
2019  true)) {
2020  notify_player(
2021  pplayer, unit_tile(actor), event, ftc_server,
2022  // TRANS: Only Diplomat or Spy can do Steal Gold.
2023  _("Only %s can do %s."), qUtf8Printable(roles),
2024  qUtf8Printable(action_id_name_translation(stopped_action)));
2025  } else {
2026  notify_player(
2027  pplayer, unit_tile(actor), event, ftc_server,
2028  // TRANS: Spy can't do Capture Units.
2029  _("%s can't do %s."), unit_name_translation(actor),
2030  qUtf8Printable(action_id_name_translation(stopped_action)));
2031  }
2032  } break;
2033  case ANEK_MISSING_TARGET:
2034  notify_player(
2035  pplayer, unit_tile(actor), event, ftc_server,
2036  /* TRANS: "Your Spy found ... suitable for
2037  * Bribe Enemy Unit." */
2038  _("Your %s found no target suitable for %s."),
2039  unit_name_translation(actor),
2040  qUtf8Printable(action_id_name_translation(stopped_action)));
2041  break;
2042  case ANEK_BAD_TARGET:
2043  notify_player(
2044  pplayer, unit_tile(actor), event, ftc_server,
2045  /* TRANS: "Having your Spy do Bribe Enemy Unit to
2046  * this target ..." */
2047  _("Having your %s do %s to this target is redundant."),
2048  unit_name_translation(actor),
2049  qUtf8Printable(action_id_name_translation(stopped_action)));
2050  break;
2051  case ANEK_BAD_TERRAIN_ACT: {
2052  QVector<QString> types;
2053  types.reserve(utype_count());
2054  int i = 0;
2055 
2056  if (!utype_can_do_act_when_ustate(unit_type_get(actor), stopped_action,
2057  USP_LIVABLE_TILE, false)
2058  && !can_unit_exist_at_tile(&(wld.map), actor, unit_tile(actor))) {
2059  unit_type_iterate(utype)
2060  {
2061  if (utype_can_do_act_when_ustate(utype, stopped_action,
2062  USP_LIVABLE_TILE, false)) {
2063  types.append(utype_name_translation(utype));
2064  i++;
2065  }
2066  }
2068  }
2069 
2070  if (0 < i) {
2071  notify_player(
2072  pplayer, unit_tile(actor), event, ftc_server,
2073  /* TRANS: action name.
2074  * "Your Spy can't do Steal Gold from Ocean.
2075  * Only Explorer or Partisan can do Steal Gold ..." */
2076  _("Your %s can't do %s from %s. "
2077  "Only %s can do %s from a non livable tile."),
2078  unit_name_translation(actor),
2079  qUtf8Printable(action_id_name_translation(stopped_action)),
2081  qUtf8Printable(strvec_to_and_list(types)),
2082  qUtf8Printable(action_id_name_translation(stopped_action)));
2083  } else {
2084  notify_player(
2085  pplayer, unit_tile(actor), event, ftc_server,
2086  /* TRANS: action name.
2087  * "Your Spy can't do Steal Gold from Ocean." */
2088  _("Your %s can't do %s from %s."), unit_name_translation(actor),
2089  qUtf8Printable(action_id_name_translation(stopped_action)),
2091  }
2092  } break;
2093  case ANEK_BAD_TERRAIN_TGT:
2094  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2095  /* TRANS: action name.
2096  * "Your Spy can't do Industrial Sabotage to Mountains." */
2097  _("Your %s can't do %s to %s."),
2098  unit_name_translation(actor),
2099  qUtf8Printable(action_id_name_translation(stopped_action)),
2101  break;
2102  case ANEK_IS_TRANSPORTED:
2103  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2104  /* TRANS: action name.
2105  * "Your Spy can't do Industrial Sabotage while ..." */
2106  _("Your %s can't do %s while being transported."),
2107  unit_name_translation(actor),
2108  qUtf8Printable(qUtf8Printable(
2109  action_id_name_translation(stopped_action))));
2110  break;
2112  notify_player(
2113  pplayer, unit_tile(actor), event, ftc_server,
2114  /* TRANS: action name.
2115  * "Your Spy can't do Industrial Sabotage while ..." */
2116  _("Your %s can't do %s while not being transported."),
2117  unit_name_translation(actor),
2118  qUtf8Printable(action_id_name_translation(stopped_action)));
2119  break;
2120  case ANEK_IS_TRANSPORTING:
2121  notify_player(
2122  pplayer, unit_tile(actor), event, ftc_server,
2123  /* TRANS: action name.
2124  * "Your Spy can't do Industrial Sabotage while ..." */
2125  _("Your %s can't do %s while transporting."),
2126  unit_name_translation(actor),
2127  qUtf8Printable(action_id_name_translation(stopped_action)));
2128  break;
2130  notify_player(
2131  pplayer, unit_tile(actor), event, ftc_server,
2132  /* TRANS: action name.
2133  * "Your Spy can't do Industrial Sabotage while ..." */
2134  _("Your %s can't do %s while not transporting."),
2135  unit_name_translation(actor),
2136  qUtf8Printable(action_id_name_translation(stopped_action)));
2137  break;
2139  notify_player(
2140  pplayer, unit_tile(actor), event, ftc_server,
2141  /* TRANS: action name.
2142  * "Your Spy can't do Industrial Sabotage because ..." */
2143  _("Your %s can't do %s because it has a home city."),
2144  unit_name_translation(actor),
2145  qUtf8Printable(action_id_name_translation(stopped_action)));
2146  break;
2148  notify_player(
2149  pplayer, unit_tile(actor), event, ftc_server,
2150  /* TRANS: action name.
2151  * "Your Spy can't do Industrial Sabotage because ..." */
2152  _("Your %s can't do %s because it is homeless."),
2153  unit_name_translation(actor),
2154  qUtf8Printable(action_id_name_translation(stopped_action)));
2155  break;
2156  case ANEK_NO_WAR:
2157  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2158  /* TRANS: action name.
2159  * "Your Spy can't do Industrial Sabotage while you
2160  * aren't at war with Prester John." */
2161  _("Your %s can't do %s while you"
2162  " aren't at war with %s."),
2163  unit_name_translation(actor),
2164  qUtf8Printable(action_id_name_translation(stopped_action)),
2165  player_name(explnat->no_war_with));
2166  break;
2167  case ANEK_PEACE:
2168  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2169  /* TRANS: action name.
2170  * "Your Spy can't do Industrial Sabotage while you
2171  * are at peace with Prester John. Try using the
2172  * Nations report (F3)." */
2173  _("Your %s can't do %s while you"
2174  " are at peace with %s. Try using"
2175  " the Nations report."),
2176  unit_name_translation(actor),
2177  qUtf8Printable(action_id_name_translation(stopped_action)),
2178  player_name(explnat->peace_with));
2179  break;
2180  case ANEK_DOMESTIC:
2181  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2182  /* TRANS: action name.
2183  * "Your Riflemen can't do Expel Unit to domestic
2184  * unit stacks." */
2185  _("Your %s can't do %s to domestic %s."),
2186  unit_name_translation(actor),
2187  qUtf8Printable(action_id_name_translation(stopped_action)),
2188  action_target_kind_translated_name(
2189  action_id_get_target_kind(stopped_action)));
2190  break;
2191  case ANEK_FOREIGN:
2192  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2193  /* TRANS: action name.
2194  * "Your Leader can't do Use Court Physician to foreign
2195  * unit stacks." */
2196  _("Your %s can't do %s to foreign %s."),
2197  unit_name_translation(actor),
2198  qUtf8Printable(action_id_name_translation(stopped_action)),
2199  action_target_kind_translated_name(
2200  action_id_get_target_kind(stopped_action)));
2201  break;
2202  case ANEK_NATION_ACT:
2203  notify_player(
2204  pplayer, unit_tile(actor), event, ftc_server,
2205  /* TRANS: action name.
2206  * "Swedish Riflemen can't do Expel Unit." */
2207  _("%s %s can't do %s."),
2209  unit_name_translation(actor),
2210  qUtf8Printable(action_id_name_translation(stopped_action)));
2211  break;
2212  case ANEK_NATION_TGT:
2213  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2214  /* TRANS: action name.
2215  * "Riflemen... Expel Unit... Pirate Migrants." */
2216  _("Your %s can't do %s to %s %s."),
2217  unit_name_translation(actor),
2218  qUtf8Printable(action_id_name_translation(stopped_action)),
2220  action_target_kind_translated_name(
2221  action_id_get_target_kind(stopped_action)));
2222  break;
2223  case ANEK_LOW_MP:
2224  notify_player(
2225  pplayer, unit_tile(actor), event, ftc_server,
2226  /* TRANS: action name.
2227  * "Your Spy has ... to do Bribe Enemy Unit." */
2228  _("Your %s has too few moves left to do %s."),
2229  unit_name_translation(actor),
2230  qUtf8Printable(action_id_name_translation(stopped_action)));
2231  break;
2232  case ANEK_IS_CITY_CENTER:
2233  notify_player(
2234  pplayer, unit_tile(actor), event, ftc_server,
2235  /* TRANS: action name.
2236  * "Your Spy can't do Bribe Enemy Unit to city centers." */
2237  _("Your %s can't do %s to city centers."),
2238  unit_name_translation(actor),
2239  qUtf8Printable(action_id_name_translation(stopped_action)));
2240  break;
2242  notify_player(
2243  pplayer, unit_tile(actor), event, ftc_server,
2244  /* TRANS: action name.
2245  * "Your Spy can only do Investigate City to
2246  * city centers." */
2247  _("Your %s can only do %s to city centers."),
2248  unit_name_translation(actor),
2249  qUtf8Printable(action_id_name_translation(stopped_action)));
2250  break;
2251  case ANEK_TGT_IS_CLAIMED:
2252  notify_player(
2253  pplayer, unit_tile(actor), event, ftc_server,
2254  /* TRANS: action name.
2255  * "Your Settlers can't do Build City to claimed tiles." */
2256  _("Your %s can't do %s to claimed tiles."),
2257  unit_name_translation(actor),
2258  qUtf8Printable(action_id_name_translation(stopped_action)));
2259  break;
2260  case ANEK_TGT_IS_UNCLAIMED:
2261  notify_player(
2262  pplayer, unit_tile(actor), event, ftc_server,
2263  /* TRANS: action name.
2264  * "Your Spy can't do Bribe Enemy Unit to
2265  * unclaimed tiles." */
2266  _("Your %s can't do %s to unclaimed tiles."),
2267  unit_name_translation(actor),
2268  qUtf8Printable(action_id_name_translation(stopped_action)));
2269  break;
2270  case ANEK_DISTANCE_NEAR:
2271  notify_player(
2272  pplayer, unit_tile(actor), event, ftc_server,
2273  /* TRANS: action name.
2274  * "Your Spy must be at least 2 tiles away to do
2275  * Incite a Revolt and Escape." */
2276  PL_("Your %s must be at least %d tile away to do %s.",
2277  "Your %s must be at least %d tiles away to do %s.",
2278  explnat->distance),
2279  unit_name_translation(actor), explnat->distance,
2280  qUtf8Printable(action_id_name_translation(stopped_action)));
2281  break;
2282  case ANEK_DISTANCE_FAR:
2283  notify_player(
2284  pplayer, unit_tile(actor), event, ftc_server,
2285  /* TRANS: action name.
2286  * "Your Diplomat can't be more than 1 tile away to do
2287  * Establish Embassy." */
2288  PL_("Your %s can't be more than %d tile away to do %s.",
2289  "Your %s can't be more than %d tiles away to do %s.",
2290  explnat->distance),
2291  unit_name_translation(actor), explnat->distance,
2292  qUtf8Printable(action_id_name_translation(stopped_action)));
2293  break;
2295  notify_player(
2296  pplayer, unit_tile(actor), event, ftc_server,
2297  // TRANS: Can't do Build City in this scenario.
2298  _("Can't do %s in this scenario."),
2299  qUtf8Printable(action_id_name_translation(stopped_action)));
2300  break;
2302  notify_player(
2303  pplayer, unit_tile(actor), event, ftc_server,
2304  // TRANS: Can't do Build City this close to a city.
2305  _("Can't do %s this close to a city."),
2306  qUtf8Printable(action_id_name_translation(stopped_action)));
2307  break;
2308  case ANEK_CITY_TOO_BIG:
2309  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2310  // TRANS: Settlers ... Join City ... London
2311  _("%s can't do %s to %s. It is too big."),
2312  unit_name_translation(actor),
2313  qUtf8Printable(action_id_name_translation(stopped_action)),
2314  city_name_get(target_city));
2315  break;
2316  case ANEK_CITY_POP_LIMIT:
2317  notify_player(
2318  pplayer, unit_tile(actor), event, ftc_server,
2319  // TRANS: London ... Settlers ... Join City
2320  _("%s needs an improvement to grow, so "
2321  "%s cannot do %s."),
2322  city_name_get(target_city), unit_name_translation(actor),
2323  qUtf8Printable(action_id_name_translation(stopped_action)));
2324  break;
2325  case ANEK_CITY_NO_CAPACITY:
2326  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2327  // TRANS: Paris ... Airlift to City ... Warriors
2328  _("%s has no capacity to %s %s."),
2329  city_name_get(explnat->capacity_city),
2330  qUtf8Printable(action_id_name_translation(stopped_action)),
2331  unit_name_translation(actor));
2332  break;
2333  case ANEK_TGT_TILE_UNKNOWN:
2334  notify_player(
2335  pplayer, unit_tile(actor), event, ftc_server,
2336  // TRANS: Paratroopers ... Drop Paratrooper
2337  _("%s can't do %s to an unknown tile."),
2338  unit_name_translation(actor),
2339  qUtf8Printable(action_id_name_translation(stopped_action)));
2340  break;
2342  char tbuf[MAX_LEN_MSG];
2343 
2344  /* TRANS: Used below. Separate so treasury content too can determine
2345  * if this is plural. */
2346  fc_snprintf(tbuf, ARRAY_SIZE(tbuf),
2347  PL_("Treasury contains %d gold.",
2348  "Treasury contains %d gold.", pplayer->economic.gold),
2349  pplayer->economic.gold);
2350 
2351  notify_player(pplayer, unit_tile(actor), event, ftc_server,
2352  /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2353  * Treasury contains 100 gold." */
2354  PL_("%s can't do %s for %d gold. %s",
2355  "%s can't do %s for %d gold. %s",
2356  explnat->gold_needed),
2357  unit_name_translation(actor),
2358  qUtf8Printable(action_id_name_translation(stopped_action)),
2359  explnat->gold_needed, tbuf);
2360  } break;
2361  case ANEK_TRIREME_MOVE:
2362  notify_player(pplayer, target_tile, event, ftc_server,
2363  // TRANS: "Trireme cannot move ..."
2364  _("%s cannot move that far from the coast line."),
2365  unit_link(actor));
2366  break;
2367  case ANEK_DISEMBARK_ACT:
2368  notify_player(
2369  pplayer, unit_tile(actor), event, ftc_server,
2370  /* TRANS: "Riflemen cannot disembark ... native base
2371  * for Helicopter." */
2372  _("%s cannot disembark outside of a city or a native base "
2373  "for %s."),
2374  unit_link(actor),
2376  break;
2377  case ANEK_TGT_UNREACHABLE:
2378  notify_player(
2379  pplayer, target_tile, event, ftc_server,
2380  // TRANS: "Your Spy can't do Bribe Enemy Unit there ..."
2381  _("Your %s can't do %s there since there's an "
2382  "unreachable unit."),
2383  unit_name_translation(actor),
2384  qUtf8Printable(action_id_name_translation(stopped_action)));
2385  break;
2387  notify_player(pplayer, target_tile, event, ftc_server,
2388  // TRANS: "You already have a Leader."
2389  _("You already have a %s."),
2391  break;
2392  case ANEK_ACTION_BLOCKS:
2393  notify_player(
2394  pplayer, unit_tile(actor), event, ftc_server,
2395  // TRANS: Freight ... Recycle Unit ... Help Wonder ...
2396  _("Your %s can't do %s when %s is legal."),
2397  unit_name_translation(actor),
2398  qUtf8Printable(action_id_name_translation(stopped_action)),
2399  qUtf8Printable(action_id_name_translation(explnat->blocker->id)));
2400  break;
2401  case ANEK_UNKNOWN:
2402  notify_player(
2403  pplayer, unit_tile(actor), event, ftc_server,
2404  /* TRANS: action name.
2405  * "Your Spy was unable to do Bribe Enemy Unit." */
2406  _("Your %s was unable to do %s."), unit_name_translation(actor),
2407  qUtf8Printable(action_id_name_translation(stopped_action)));
2408  break;
2409  }
2410 
2411  delete explnat;
2412 }
2413 
2428  struct player *pplayer, bool information_revealed, struct unit *act_unit,
2429  struct action *stopped_action, struct player *tgt_player,
2430  struct tile *tgt_tile, const enum action_requester requester)
2431 {
2432  int punishment_mp;
2433  int punishment_hp;
2434 
2435  /* Don't punish the player for something the game did. Don't tell the
2436  * player that the rules required the game to try to do something
2437  * illegal. */
2439  (requester == ACT_REQ_PLAYER || requester == ACT_REQ_SS_AGENT), false,
2440  "The player wasn't responsible for this.");
2441 
2442  if (!information_revealed) {
2443  /* The player already had enough information to determine that this
2444  * action is illegal. Don't punish a client error or an accident. */
2445  return false;
2446  }
2447 
2448  // The mistake may have a cost.
2449 
2450  // HP cost
2451  punishment_hp = get_target_bonus_effects(
2452  nullptr, unit_owner(act_unit), tgt_player, nullptr, nullptr, nullptr,
2453  act_unit, unit_type_get(act_unit), nullptr, nullptr, stopped_action,
2454  EFT_ILLEGAL_ACTION_HP_COST);
2455 
2456  // Stay in range
2457  punishment_hp = MAX(0, punishment_hp);
2458 
2459  // Punish the unit's hit points.
2460  act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
2461 
2462  if (punishment_hp != 0) {
2463  if (utype_is_moved_to_tgt_by_action(stopped_action,
2464  unit_type_get(act_unit))) {
2465  /* The consolation prize is some information about the potentially
2466  * distant target tile and maybe some contacts. */
2467  map_show_circle(pplayer, tgt_tile,
2468  unit_type_get(act_unit)->vision_radius_sq);
2469  maybe_make_contact(tgt_tile, pplayer);
2470  }
2471 
2472  if (act_unit->hp > 0) {
2473  // The actor unit survived
2474 
2475  /* The player probably wants to be disturbed if his unit was punished
2476  * with the loss of hit points. */
2477  notify_player(pplayer, unit_tile(act_unit), E_UNIT_ILLEGAL_ACTION,
2478  ftc_server,
2479  // TRANS: Spy ... 5 ... Drop Paratrooper
2480  _("Your %s lost %d hit points while attempting to"
2481  " do %s."),
2482  unit_name_translation(act_unit), punishment_hp,
2483  qUtf8Printable(action_name_translation(stopped_action)));
2484  send_unit_info(nullptr, act_unit);
2485  } else {
2486  // The unit didn't survive
2487 
2488  /* The player probably wants to be disturbed if his unit was punished
2489  * with death. */
2490  notify_player(pplayer, unit_tile(act_unit), E_UNIT_ILLEGAL_ACTION,
2491  ftc_server,
2492  // TRANS: Spy ... Drop Paratrooper
2493  _("Your %s was killed while attempting to do %s."),
2494  unit_name_translation(act_unit),
2495  qUtf8Printable(action_name_translation(stopped_action)));
2496 
2497  wipe_unit(act_unit, ULR_KILLED, nullptr);
2498  act_unit = nullptr;
2499 
2500  return true;
2501  }
2502  }
2503 
2504  // MP cost
2505  punishment_mp = get_target_bonus_effects(
2506  nullptr, unit_owner(act_unit), tgt_player, nullptr, nullptr, nullptr,
2507  act_unit, unit_type_get(act_unit), nullptr, nullptr, stopped_action,
2508  EFT_ILLEGAL_ACTION_MOVE_COST);
2509 
2510  // Stay in range
2511  punishment_mp = MAX(0, punishment_mp);
2512 
2513  // Punish the unit's move fragments.
2514  act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
2515  send_unit_info(nullptr, act_unit);
2516 
2517  if (punishment_mp != 0) {
2518  /* The player probably wants to be disturbed if his unit was punished
2519  * with the loss of movement points. */
2520  notify_player(pplayer, unit_tile(act_unit), E_UNIT_ILLEGAL_ACTION,
2521  ftc_server,
2522  /* TRANS: Spy ... movement point text that may include
2523  * fractions. */
2524  _("Your %s lost %s MP for attempting an illegal action."),
2525  unit_name_translation(act_unit),
2526  move_points_text(punishment_mp, true));
2527  }
2528 
2529  return punishment_mp != 0 || punishment_hp != 0;
2530 }
2531 
2537 static void
2538 illegal_action(struct player *pplayer, struct unit *actor,
2539  action_id stopped_action_id, struct player *tgt_player,
2540  struct tile *target_tile, const struct city *target_city,
2541  const struct unit *target_unit, bool disturb_player,
2542  const enum action_requester requester)
2543 {
2544  bool information_revealed;
2545  bool was_punished;
2546 
2547  struct action *stopped_action = action_by_number(stopped_action_id);
2548 
2549  /* Why didn't the game check before trying something illegal? Did a good
2550  * reason to not call is_action_enabled_unit_on...() appear? The game is
2551  * omniscient... */
2552  fc_assert(requester != ACT_REQ_RULES);
2553 
2554  information_revealed = action_prob_possible(
2555  action_prob_unit_vs_tgt(stopped_action, actor, target_city,
2556  target_unit, target_tile, nullptr));
2557 
2558  if (disturb_player) {
2559  // This is a foreground request.
2561  pplayer,
2562  (information_revealed ? E_UNIT_ILLEGAL_ACTION : E_BAD_COMMAND),
2563  actor, stopped_action_id, target_tile, target_city, target_unit);
2564  }
2565 
2566  was_punished = illegal_action_pay_price(pplayer, information_revealed,
2567  actor, stopped_action, tgt_player,
2568  target_tile, requester);
2569 
2570  if (!disturb_player && was_punished) {
2571  /* FIXME: Temporary work around to prevent wrong information and/or
2572  * crashes. See hrm Bug #879880 */
2573  /* TODO: Get the explanation before the punishment and show it here.
2574  * See hrm Bug #879881 */
2575  notify_player(
2576  pplayer, unit_tile(actor),
2577  (information_revealed ? E_UNIT_ILLEGAL_ACTION : E_BAD_COMMAND),
2578  ftc_server,
2579  _("No explanation why you couldn't do %s. This is a bug."
2580  " Sorry about that. -- Sveinung"),
2581  qUtf8Printable(action_id_name_translation(stopped_action_id)));
2582  }
2583 }
2584 
2588 static void unit_query_impossible(struct connection *pc, const int actor_id,
2589  const int target_id, bool disturb_player)
2590 {
2591  dsend_packet_unit_action_answer(pc, actor_id, target_id, 0, ACTION_NONE,
2592  disturb_player);
2593 }
2594 
2602 void handle_unit_action_query(struct connection *pc, const int actor_id,
2603  const int target_id,
2604  const action_id action_type,
2605  bool disturb_player)
2606 {
2607  struct player *pplayer = pc->playing;
2608  struct unit *pactor = player_unit_by_number(pplayer, actor_id);
2609  struct action *paction = action_by_number(action_type);
2610  struct unit *punit = game_unit_by_number(target_id);
2611  struct city *pcity = game_city_by_number(target_id);
2612 
2613  if (nullptr == paction) {
2614  // Non existing action
2615  qCritical("handle_unit_action_query() the action %d doesn't exist.",
2616  action_type);
2617 
2618  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2619  return;
2620  }
2621 
2622  if (nullptr == pactor) {
2623  // Probably died or bribed.
2624  qDebug("handle_unit_action_query() invalid actor %d", actor_id);
2625  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2626  return;
2627  }
2628 
2629  switch (paction->result) {
2630  case ACTRES_SPY_BRIBE_UNIT:
2631  if (punit
2632  && is_action_enabled_unit_on_unit(action_type, pactor, punit)) {
2633  dsend_packet_unit_action_answer(pc, actor_id, target_id,
2634  unit_bribe_cost(punit, pplayer),
2635  action_type, disturb_player);
2636  } else {
2637  illegal_action(pplayer, pactor, action_type,
2638  punit ? unit_owner(punit) : nullptr, nullptr, nullptr,
2639  punit, disturb_player, ACT_REQ_PLAYER);
2640  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2641  return;
2642  }
2643  break;
2644  case ACTRES_SPY_INCITE_CITY:
2645  if (pcity
2646  && is_action_enabled_unit_on_city(action_type, pactor, pcity)) {
2647  dsend_packet_unit_action_answer(pc, actor_id, target_id,
2648  city_incite_cost(pplayer, pcity),
2649  action_type, disturb_player);
2650  } else {
2651  illegal_action(pplayer, pactor, action_type,
2652  pcity ? city_owner(pcity) : nullptr, nullptr, pcity,
2653  nullptr, disturb_player, ACT_REQ_PLAYER);
2654  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2655  return;
2656  }
2657  break;
2658  case ACTRES_UPGRADE_UNIT:
2659  if (pcity
2660  && is_action_enabled_unit_on_city(action_type, pactor, pcity)) {
2661  const struct unit_type *tgt_utype;
2662  int upgr_cost;
2663 
2664  tgt_utype = can_upgrade_unittype(pplayer, unit_type_get(pactor));
2665  // Already checked via is_action_enabled_unit_on_city()
2666  fc_assert_ret(tgt_utype);
2667  upgr_cost =
2668  unit_upgrade_price(pplayer, unit_type_get(pactor), tgt_utype);
2669 
2670  dsend_packet_unit_action_answer(pc, actor_id, target_id, upgr_cost,
2671  action_type, disturb_player);
2672  } else {
2673  illegal_action(pplayer, pactor, action_type,
2674  pcity ? city_owner(pcity) : nullptr, nullptr, pcity,
2675  nullptr, disturb_player, ACT_REQ_PLAYER);
2676  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2677  return;
2678  }
2679  break;
2680  case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2681  case ACTRES_STRIKE_BUILDING:
2682  if (pcity
2683  && is_action_enabled_unit_on_city(action_type, pactor, pcity)) {
2684  spy_send_sabotage_list(pc, pactor, pcity,
2685  action_by_number(action_type), disturb_player);
2686  } else {
2687  illegal_action(pplayer, pactor, action_type,
2688  pcity ? city_owner(pcity) : nullptr, nullptr, pcity,
2689  nullptr, disturb_player, ACT_REQ_PLAYER);
2690  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2691  return;
2692  }
2693  break;
2694  default:
2695  unit_query_impossible(pc, actor_id, target_id, disturb_player);
2696  return;
2697  };
2698 }
2699 
2705 void handle_unit_do_action(struct player *pplayer, const int actor_id,
2706  const int target_id, const int sub_tgt_id,
2707  const char *name, const action_id action_type)
2708 {
2709  (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
2710  action_type, ACT_REQ_PLAYER);
2711 }
2712 
2718 void unit_do_action(struct player *pplayer, const int actor_id,
2719  const int target_id, const int sub_tgt_id,
2720  const char *name, const action_id action_type)
2721 {
2722  bool unused;
2723  unused = unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id,
2724  name, action_type, ACT_REQ_PLAYER);
2725  Q_UNUSED(unused);
2726 }
2727 
2737 bool unit_perform_action(struct player *pplayer, const int actor_id,
2738  const int target_id, const int sub_tgt_id_incoming,
2739  const char *name, const action_id action_type,
2740  const enum action_requester requester)
2741 {
2742  struct action *paction;
2743  int sub_tgt_id;
2744  struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
2745  struct tile *target_tile = index_to_tile(&(wld.map), target_id);
2746  struct extra_type *target_extra;
2747  struct unit *punit = game_unit_by_number(target_id);
2748  struct city *pcity = game_city_by_number(target_id);
2749 
2750  if (!action_id_exists(action_type)) {
2751  // Non existing action
2752  qCritical("unit_perform_action() the action %d doesn't exist.",
2753  action_type);
2754 
2755  return false;
2756  }
2757 
2758  paction = action_by_number(action_type);
2759 
2760  // Server side sub target assignment
2761  if (actor_unit && paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
2762  && sub_tgt_id_incoming == NO_TARGET) {
2763  sub_tgt_id = action_sub_target_id_for_action(paction, actor_unit);
2764  } else {
2765  sub_tgt_id = sub_tgt_id_incoming;
2766  }
2767 
2768  if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
2769  && sub_tgt_id != NO_TARGET) {
2770  target_extra = extra_by_number(sub_tgt_id);
2771  fc_assert(!(target_extra->ruledit_disabled));
2772  } else {
2773  target_extra = nullptr;
2774  }
2775 
2776  if (action_get_activity(paction) != ACTIVITY_LAST
2778  && target_extra == nullptr) {
2779  // Missing required action extra target.
2780  qDebug("unit_perform_action() action %d requires action "
2781  "but extra id %d is invalid.",
2782  action_type, sub_tgt_id);
2783  return false;
2784  }
2785 
2786  if (nullptr == actor_unit) {
2787  // Probably died or bribed.
2788  qDebug("handle_unit_do_action() invalid actor %d", actor_id);
2789  return false;
2790  }
2791 
2792  if (paction->actor.is_unit.unitwaittime_controlled
2793  && !unit_can_do_action_now(actor_unit)) {
2794  // Action not possible due to unitwaittime setting.
2795  return false;
2796  }
2797 
2798 #define ACTION_STARTED_UNIT_CITY(action, actor, target, action_performer) \
2799  if (pcity \
2800  && is_action_enabled_unit_on_city(action_type, actor_unit, pcity)) { \
2801  bool success; \
2802  script_server_signal_emit("action_started_unit_city", \
2803  action_by_number(action), actor, target); \
2804  if (!actor || !unit_is_alive(actor_id)) { \
2805  /* Actor unit was destroyed during pre action Lua. */ \
2806  return false; \
2807  } \
2808  if (!target || !city_exist(target_id)) { \
2809  /* Target city was destroyed during pre action Lua. */ \
2810  return false; \
2811  } \
2812  success = action_performer; \
2813  if (success) { \
2814  action_success_actor_price(paction, actor_id, actor); \
2815  } \
2816  return success; \
2817  } else { \
2818  illegal_action(pplayer, actor_unit, action_type, \
2819  pcity ? city_owner(pcity) : nullptr, nullptr, pcity, \
2820  nullptr, true, requester); \
2821  }
2822 
2823 #define ACTION_STARTED_UNIT_SELF(action, actor, action_performer) \
2824  if (actor_unit \
2825  && is_action_enabled_unit_on_self(action_type, actor_unit)) { \
2826  bool success; \
2827  script_server_signal_emit("action_started_unit_self", \
2828  action_by_number(action), actor); \
2829  if (!actor || !unit_is_alive(actor_id)) { \
2830  /* Actor unit was destroyed during pre action Lua. */ \
2831  return false; \
2832  } \
2833  success = action_performer; \
2834  if (success) { \
2835  action_success_actor_price(paction, actor_id, actor); \
2836  } \
2837  return success; \
2838  } else { \
2839  illegal_action(pplayer, actor_unit, action_type, \
2840  unit_owner(actor_unit), nullptr, nullptr, actor_unit, \
2841  true, requester); \
2842  }
2843 
2844 #define ACTION_STARTED_UNIT_UNIT(action, actor, target, action_performer) \
2845  if (punit \
2846  && is_action_enabled_unit_on_unit(action_type, actor_unit, punit)) { \
2847  bool success; \
2848  script_server_signal_emit("action_started_unit_unit", \
2849  action_by_number(action), actor, target); \
2850  if (!actor || !unit_is_alive(actor_id)) { \
2851  /* Actor unit was destroyed during pre action Lua. */ \
2852  return false; \
2853  } \
2854  if (!target || !unit_is_alive(target_id)) { \
2855  /* Target unit was destroyed during pre action Lua. */ \
2856  return false; \
2857  } \
2858  success = action_performer; \
2859  if (success) { \
2860  action_success_actor_price(paction, actor_id, actor); \
2861  action_success_target_pay_mp(paction, target_id, punit); \
2862  } \
2863  return success; \
2864  } else { \
2865  illegal_action(pplayer, actor_unit, action_type, \
2866  punit ? unit_owner(punit) : nullptr, nullptr, nullptr, \
2867  punit, true, requester); \
2868  }
2869 
2870 #define ACTION_STARTED_UNIT_UNITS(action, actor, target, action_performer) \
2871  if (target_tile \
2872  && is_action_enabled_unit_on_units(action_type, actor_unit, \
2873  target_tile)) { \
2874  bool success; \
2875  script_server_signal_emit("action_started_unit_units", \
2876  action_by_number(action), actor, target); \
2877  if (!actor || !unit_is_alive(actor_id)) { \
2878  /* Actor unit was destroyed during pre action Lua. */ \
2879  return false; \
2880  } \
2881  success = action_performer; \
2882  if (success) { \
2883  action_success_actor_price(paction, actor_id, actor); \
2884  } \
2885  return success; \
2886  } else { \
2887  illegal_action(pplayer, actor_unit, action_type, nullptr, target_tile, \
2888  nullptr, nullptr, true, requester); \
2889  }
2890 
2891 #define ACTION_STARTED_UNIT_TILE(action, actor, target, action_performer) \
2892  if (target_tile \
2893  && is_action_enabled_unit_on_tile(action_type, actor_unit, \
2894  target_tile, target_extra)) { \
2895  bool success; \
2896  script_server_signal_emit("action_started_unit_tile", \
2897  action_by_number(action), actor, target); \
2898  if (!actor || !unit_is_alive(actor_id)) { \
2899  /* Actor unit was destroyed during pre action Lua. */ \
2900  return false; \
2901  } \
2902  success = action_performer; \
2903  if (success) { \
2904  action_success_actor_price(paction, actor_id, actor); \
2905  } \
2906  return success; \
2907  } else { \
2908  illegal_action(pplayer, actor_unit, action_type, \
2909  target_tile ? tile_owner(target_tile) : nullptr, \
2910  target_tile, nullptr, nullptr, true, requester); \
2911  }
2912 
2913  switch (paction->result) {
2914  case ACTRES_SPY_BRIBE_UNIT:
2916  action_type, actor_unit, punit,
2917  diplomat_bribe(pplayer, actor_unit, punit, paction));
2918  break;
2919  case ACTRES_SPY_SABOTAGE_UNIT:
2920  // Difference is caused by data in the action structure.
2922  action_type, actor_unit, punit,
2923  spy_sabotage_unit(pplayer, actor_unit, punit, paction));
2924  break;
2925  case ACTRES_EXPEL_UNIT:
2927  action_type, actor_unit, punit,
2928  do_expel_unit(pplayer, actor_unit, punit, paction));
2929  break;
2930  case ACTRES_HEAL_UNIT:
2932  action_type, actor_unit, punit,
2933  do_heal_unit(pplayer, actor_unit, punit, paction));
2934  break;
2935  case ACTRES_TRANSPORT_ALIGHT:
2937  action_type, actor_unit, punit,
2938  do_unit_alight(pplayer, actor_unit, punit, paction));
2939  break;
2940  case ACTRES_TRANSPORT_UNLOAD:
2942  action_type, actor_unit, punit,
2943  do_unit_unload(pplayer, actor_unit, punit, paction));
2944  break;
2945  case ACTRES_TRANSPORT_BOARD:
2947  action_type, actor_unit, punit,
2948  do_unit_board(pplayer, actor_unit, punit, paction));
2949  break;
2950  case ACTRES_TRANSPORT_EMBARK:
2952  action_type, actor_unit, punit,
2953  do_unit_embark(pplayer, actor_unit, punit, paction));
2954  break;
2955  case ACTRES_DISBAND_UNIT:
2956  // All consequences are handled by the action system.
2957  ACTION_STARTED_UNIT_SELF(action_type, actor_unit, true);
2958  break;
2959  case ACTRES_FORTIFY:
2960  ACTION_STARTED_UNIT_SELF(action_type, actor_unit,
2961  do_action_activity(actor_unit, paction));
2962  break;
2963  case ACTRES_CONVERT:
2964  ACTION_STARTED_UNIT_SELF(action_type, actor_unit,
2965  do_action_activity(actor_unit, paction));
2966  break;
2967  case ACTRES_SPY_SABOTAGE_CITY:
2968  // Difference is caused by data in the action structure.
2970  action_type, actor_unit, pcity,
2971  diplomat_sabotage(pplayer, actor_unit, pcity, B_LAST, paction));
2972  break;
2973  case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
2974  // Difference is caused by data in the action structure.
2976  action_type, actor_unit, pcity,
2977  diplomat_sabotage(pplayer, actor_unit, pcity, sub_tgt_id, paction));
2978  break;
2979  case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
2980  // Difference is caused by data in the action structure.
2982  action_type, actor_unit, pcity,
2983  diplomat_sabotage(pplayer, actor_unit, pcity, -1, paction));
2984  break;
2985  case ACTRES_SPY_POISON:
2986  // Difference is caused by data in the action structure.
2988  action_type, actor_unit, pcity,
2989  spy_poison(pplayer, actor_unit, pcity, paction));
2990  break;
2991  case ACTRES_SPY_SPREAD_PLAGUE:
2993  action_type, actor_unit, pcity,
2994  spy_spread_plague(pplayer, actor_unit, pcity, paction));
2995  break;
2996  case ACTRES_SPY_INVESTIGATE_CITY:
2997  // Difference is caused by data in the action structure.
2999  action_type, actor_unit, pcity,
3000  diplomat_investigate(pplayer, actor_unit, pcity, paction));
3001  break;
3002  case ACTRES_ESTABLISH_EMBASSY:
3003  // Difference is caused by data in the action structure.
3005  action_type, actor_unit, pcity,
3006  diplomat_embassy(pplayer, actor_unit, pcity, paction));
3007  break;
3008  case ACTRES_SPY_INCITE_CITY:
3009  // Difference is caused by data in the action structure.
3011  action_type, actor_unit, pcity,
3012  diplomat_incite(pplayer, actor_unit, pcity, paction));
3013  break;
3014  case ACTRES_SPY_STEAL_TECH:
3015  // Difference is caused by data in the action structure.
3017  action_type, actor_unit, pcity,
3018  diplomat_get_tech(pplayer, actor_unit, pcity, A_UNSET, paction));
3019  break;
3020  case ACTRES_SPY_TARGETED_STEAL_TECH:
3021  // Difference is caused by data in the action structure.
3023  action_type, actor_unit, pcity,
3024  diplomat_get_tech(pplayer, actor_unit, pcity, sub_tgt_id, paction));
3025  break;
3026  case ACTRES_SPY_STEAL_GOLD:
3027  // Difference is caused by data in the action structure.
3029  action_type, actor_unit, pcity,
3030  spy_steal_gold(pplayer, actor_unit, pcity, paction));
3031  break;
3032  case ACTRES_STEAL_MAPS:
3033  // Difference is caused by data in the action structure.
3035  action_type, actor_unit, pcity,
3036  spy_steal_some_maps(pplayer, actor_unit, pcity, paction));
3037  break;
3038  case ACTRES_TRADE_ROUTE:
3040  action_type, actor_unit, pcity,
3041  do_unit_establish_trade(pplayer, actor_unit, pcity, paction));
3042  break;
3043  case ACTRES_MARKETPLACE:
3045  action_type, actor_unit, pcity,
3046  do_unit_establish_trade(pplayer, actor_unit, pcity, paction));
3047  break;
3048  case ACTRES_HELP_WONDER:
3050  action_type, actor_unit, pcity,
3051  unit_do_help_build(pplayer, actor_unit, pcity, paction));
3052  break;
3053  case ACTRES_SPY_NUKE:
3054  // Difference is caused by data in the action structure.
3056  action_type, actor_unit, pcity,
3057  spy_nuke_city(pplayer, actor_unit, pcity, paction));
3058  break;
3059  case ACTRES_JOIN_CITY:
3061  action_type, actor_unit, pcity,
3062  city_add_unit(pplayer, actor_unit, pcity, paction));
3063  break;
3064  case ACTRES_DESTROY_CITY:
3066  action_type, actor_unit, pcity,
3067  unit_do_destroy_city(pplayer, actor_unit, pcity, paction));
3068  break;
3069  case ACTRES_RECYCLE_UNIT:
3071  action_type, actor_unit, pcity,
3072  unit_do_help_build(pplayer, actor_unit, pcity, paction));
3073  break;
3074  case ACTRES_HOME_CITY:
3076  action_type, actor_unit, pcity,
3077  do_unit_change_homecity(actor_unit, pcity, paction));
3078  break;
3079  case ACTRES_UPGRADE_UNIT:
3081  action_type, actor_unit, pcity,
3082  do_unit_upgrade(pplayer, actor_unit, pcity, requester, paction));
3083  break;
3084  case ACTRES_CONQUER_CITY:
3085  // Difference is caused by the ruleset. ("Fake generalized" actions)
3087  action_type, actor_unit, pcity,
3088  do_unit_conquer_city(pplayer, actor_unit, pcity, paction));
3089  break;
3090  case ACTRES_STRIKE_BUILDING:
3092  action_type, actor_unit, pcity,
3093  do_unit_strike_city_building(pplayer, actor_unit, pcity, sub_tgt_id,
3094  paction));
3095  break;
3096  case ACTRES_STRIKE_PRODUCTION:
3098  action_type, actor_unit, pcity,
3099  do_unit_strike_city_production(pplayer, actor_unit, pcity, paction));
3100  break;
3101  case ACTRES_AIRLIFT:
3102  ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity,
3103  do_airline(actor_unit, pcity, paction));
3104  break;
3105  case ACTRES_NUKE_CITY:
3107  action_type, actor_unit, pcity,
3108  unit_nuke(pplayer, actor_unit, city_tile(pcity), paction));
3109  break;
3110  case ACTRES_CAPTURE_UNITS:
3112  action_type, actor_unit, target_tile,
3113  do_capture_units(pplayer, actor_unit, target_tile, paction));
3114  break;
3115  case ACTRES_BOMBARD:
3116  // Difference is caused by the ruleset. ("Fake generalized" actions)
3118  action_type, actor_unit, target_tile,
3119  unit_bombard(actor_unit, target_tile, paction));
3120  break;
3121  case ACTRES_ATTACK:
3122  // Difference is caused by data in the action structure.
3123  ACTION_STARTED_UNIT_UNITS(action_type, actor_unit, target_tile,
3124  do_attack(actor_unit, target_tile, paction));
3125  break;
3126  case ACTRES_NUKE_UNITS:
3128  action_type, actor_unit, target_tile,
3129  unit_nuke(pplayer, actor_unit, target_tile, paction));
3130  break;
3131  case ACTRES_SPY_ATTACK:
3133  action_type, actor_unit, target_tile,
3134  spy_attack(pplayer, actor_unit, target_tile, paction));
3135  break;
3136  case ACTRES_FOUND_CITY:
3138  action_type, actor_unit, target_tile,
3139  city_build(pplayer, actor_unit, target_tile, name, paction));
3140  break;
3141  case ACTRES_NUKE:
3143  action_type, actor_unit, target_tile,
3144  unit_nuke(pplayer, actor_unit, target_tile, paction));
3145  break;
3146  case ACTRES_PARADROP:
3147  ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile,
3148  do_paradrop(actor_unit, target_tile, paction));
3149  break;
3150  case ACTRES_TRANSPORT_DISEMBARK:
3151  // Difference is caused by the ruleset. ("Fake generalized" actions)
3153  action_type, actor_unit, target_tile,
3154  do_disembark(pplayer, actor_unit, target_tile, paction));
3155  break;
3156  case ACTRES_TRANSFORM_TERRAIN:
3157  ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile,
3158  do_action_activity(actor_unit, paction));
3159  break;
3160  case ACTRES_CULTIVATE:
3161  ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile,
3162  do_action_activity(actor_unit, paction));
3163  break;
3164  case ACTRES_PLANT:
3165  ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile,
3166  do_action_activity(actor_unit, paction));
3167  break;
3168  case ACTRES_PILLAGE:
3170  action_type, actor_unit, target_tile,
3171  do_action_activity_targeted(actor_unit, paction, &target_extra));
3172  break;
3173  case ACTRES_CLEAN_POLLUTION:
3175  action_type, actor_unit, target_tile,
3176  do_action_activity_targeted(actor_unit, paction, &target_extra));
3177  break;
3178  case ACTRES_CLEAN_FALLOUT:
3180  action_type, actor_unit, target_tile,
3181  do_action_activity_targeted(actor_unit, paction, &target_extra));
3182  break;
3183  case ACTRES_ROAD:
3185  action_type, actor_unit, target_tile,
3186  do_action_activity_targeted(actor_unit, paction, &target_extra));
3187  break;
3188  case ACTRES_BASE:
3190  action_type, actor_unit, target_tile,
3191  do_action_activity_targeted(actor_unit, paction, &target_extra));
3192  break;
3193  case ACTRES_MINE:
3195  action_type, actor_unit, target_tile,
3196  do_action_activity_targeted(actor_unit, paction, &target_extra));
3197  break;
3198  case ACTRES_IRRIGATE:
3200  action_type, actor_unit, target_tile,
3201  do_action_activity_targeted(actor_unit, paction, &target_extra));
3202  break;
3203  case ACTRES_NONE:
3204  // 100% ruleset defined.
3205  switch (action_get_target_kind(paction)) {
3206  case ATK_CITY:
3207  ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity, true);
3208  break;
3209  case ATK_UNIT:
3210  ACTION_STARTED_UNIT_UNIT(action_type, actor_unit, punit, true);
3211  break;
3212  case ATK_UNITS:
3213  ACTION_STARTED_UNIT_UNITS(action_type, actor_unit, target_tile, true);
3214  break;
3215  case ATK_TILE:
3216  ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile, true);
3217  break;
3218  case ATK_SELF:
3219  ACTION_STARTED_UNIT_SELF(action_type, actor_unit, true);
3220  break;
3221  case ATK_COUNT:
3222  fc_assert(action_get_target_kind(paction) != ATK_COUNT);
3223  break;
3224  }
3225  break;
3226  }
3227 
3228  // Something must have gone wrong.
3229  return false;
3230 }
3231 
3240  struct city *new_pcity, bool rehome)
3241 {
3242  struct city *old_pcity = game_city_by_number(punit->homecity);
3243  struct player *old_owner = unit_owner(punit);
3244  struct player *new_owner = city_owner(new_pcity);
3245 
3246  /* Calling this function when new_pcity is same as old_pcity should
3247  * be safe with current implementation, but it is not meant to
3248  * be used that way. */
3249  fc_assert_ret(new_pcity != old_pcity);
3250 
3251  /* If 'rehome' is not set, this function should only be used to change
3252  * which player owns the unit */
3253  fc_assert_ret(rehome || new_owner != old_owner);
3254 
3255  if (old_owner != new_owner) {
3256  struct city *pcity = tile_city(punit->tile);
3257 
3259  unit_type_get(punit)));
3260 
3261  vision_clear_sight(punit->server.vision);
3262  vision_free(punit->server.vision);
3263 
3264  if (pcity != nullptr
3265  && !can_player_see_units_in_city(old_owner, pcity)) {
3266  /* Special case when city is being transferred. At this point city
3267  * itself has changed owner, so it's enemy city now that old owner
3268  * cannot see inside. All the normal methods of removing transferred
3269  * unit from previous owner's client think that there's no need to
3270  * remove unit as client shouldn't have it in first place. */
3271  unit_goes_out_of_sight(old_owner, punit);
3272  }
3273 
3274  // Remove AI control of the old owner.
3275  CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
3276 
3277  unit_list_remove(old_owner->units, punit);
3278  unit_list_prepend(new_owner->units, punit);
3279  punit->owner = new_owner;
3280 
3281  // Activate AI control of the new owner.
3282  CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
3283 
3284  punit->server.vision = vision_new(new_owner, unit_tile(punit));
3285  unit_refresh_vision(punit);
3286  }
3287 
3288  if (rehome) {
3289  fc_assert(!unit_has_type_flag(punit, UTYF_NOHOME));
3290 
3291  /* Remove from old city first and add to new city only after that.
3292  * This is more robust in case old_city == new_city (currently
3293  * prohibited by fc_assert in the beginning of the function).
3294  */
3295  if (old_pcity) {
3296  // Even if unit is dead, we have to unlink unit pointer (punit).
3297  unit_list_remove(old_pcity->units_supported, punit);
3298  // update unit upkeep
3299  city_units_upkeep(old_pcity);
3300  }
3301 
3302  unit_list_prepend(new_pcity->units_supported, punit);
3303 
3304  // update unit upkeep
3305  city_units_upkeep(new_pcity);
3306 
3307  punit->homecity = new_pcity->id;
3308  }
3309 
3310  if (!can_unit_continue_current_activity(punit)) {
3311  /* This is mainly for cases where unit owner changes to one not knowing
3312  * Railroad tech when unit is already building railroad. */
3313  set_unit_activity(punit, ACTIVITY_IDLE);
3314  }
3315 
3316  // Send info to players and observers.
3317  send_unit_info(nullptr, punit);
3318 
3319  city_refresh(new_pcity);
3320  send_city_info(new_owner, new_pcity);
3321 
3322  if (old_pcity) {
3323  fc_assert(city_owner(old_pcity) == old_owner);
3324  city_refresh(old_pcity);
3325  send_city_info(old_owner, old_pcity);
3326  }
3327 
3328  unit_get_goods(punit);
3329 
3330  fc_assert(unit_owner(punit) == city_owner(new_pcity));
3331 }
3332 
3338 static bool do_unit_change_homecity(struct unit *punit, struct city *pcity,
3339  const struct action *paction)
3340 {
3341  const char *giver = nullptr;
3342 
3343  if (unit_owner(punit) != city_owner(pcity)) {
3344  // This is a gift. Tell the receiver.
3345  giver = player_name(unit_owner(punit));
3346  }
3347 
3348  unit_change_homecity_handling(punit, pcity, true);
3349 
3350  if (punit->homecity == pcity->id && giver) {
3351  // Notify the city owner about the gift he received.
3352  notify_player(city_owner(pcity), city_tile(pcity), E_UNIT_BUILT,
3353  ftc_server,
3354  // TRANS: other player ... unit type ... city name.
3355  _("%s transferred control over a %s to you in %s."), giver,
3356  unit_tile_link(punit), city_link(pcity));
3357  ;
3358  }
3359 
3360  return punit->homecity == pcity->id;
3361 }
3362 
3370 static bool city_add_unit(struct player *pplayer, struct unit *punit,
3371  struct city *pcity, const struct action *paction)
3372 {
3373  int amount = unit_pop_value(punit);
3374 
3375  // Sanity check: The actor is still alive.
3376  fc_assert_ret_val(punit, false);
3377 
3378  // Sanity check: The target city still exists.
3379  fc_assert_ret_val(pcity, false);
3380 
3381  fc_assert_ret_val(amount > 0, false);
3382 
3383  city_size_add(pcity, amount);
3384  // Make the new people something, otherwise city fails the checks
3385  pcity->specialists[DEFAULT_SPECIALIST] += amount;
3386  citizens_update(pcity, unit_nationality(punit));
3387  // Refresh the city data.
3388  city_refresh(pcity);
3389 
3390  // Notify the unit owner that the unit successfully joined the city.
3391  notify_player(pplayer, city_tile(pcity), E_CITY_BUILD, ftc_server,
3392  _("%s added to aid %s in growing."), unit_tile_link(punit),
3393  city_link(pcity));
3394  if (pplayer != city_owner(pcity)) {
3395  // Notify the city owner when a foreign unit joins a city.
3396  notify_player(
3397  city_owner(pcity), city_tile(pcity), E_CITY_BUILD, ftc_server,
3398  // TRANS: another player had his unit joint your city.
3399  _("%s adds %s to your city %s."), player_name(unit_owner(punit)),
3400  unit_tile_link(punit), city_link(pcity));
3401  ;
3402  }
3403 
3404  action_consequence_success(paction, pplayer, city_owner(pcity),
3405  city_tile(pcity), city_link(pcity));
3406 
3407  sanity_check_city(pcity);
3408 
3409  send_city_info(nullptr, pcity);
3410 
3411  script_server_signal_emit("city_size_change", pcity, amount, "unit_added");
3412 
3413  return true;
3414 }
3415 
3425 static bool city_build(struct player *pplayer, struct unit *punit,
3426  struct tile *ptile, const char *name,
3427  const struct action *paction)
3428 {
3429  char message[1024];
3430  int size;
3431  struct player *nationality;
3432  struct player *towner;
3433 
3434  // Sanity check: The actor still exists.
3435  fc_assert_ret_val(pplayer, false);
3436  fc_assert_ret_val(punit, false);
3437 
3438  towner = tile_owner(ptile);
3439 
3440  if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
3441  notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server, "%s", message);
3442  return false;
3443  }
3444 
3445  nationality = unit_nationality(punit);
3446 
3447  create_city(pplayer, ptile, name, nationality);
3448  size = unit_type_get(punit)->city_size;
3449  if (size > 1) {
3450  struct city *pcity = tile_city(ptile);
3451 
3452  fc_assert_ret_val(pcity != nullptr, false);
3453 
3454  city_change_size(pcity, size, nationality, nullptr);
3455  }
3456 
3457  /* May cause an incident even if the target tile is unclaimed. A ruleset
3458  * could give everyone a casus belli against the city founder. A rule
3459  * like that would make sense in a story where deep ecology is on the
3460  * table. (See also Voluntary Human Extinction Movement) */
3461  action_consequence_success(paction, pplayer, towner, ptile,
3462  tile_link(ptile));
3463 
3464  return true;
3465 }
3466 
3470 static void
3471 handle_unit_change_activity_real(struct player *pplayer, int unit_id,
3472  enum unit_activity activity,
3473  struct extra_type *activity_target)
3474 {
3475  struct unit *punit = player_unit_by_number(pplayer, unit_id);
3476 
3477  if (nullptr == punit) {
3478  // Probably died or bribed.
3479  qDebug("handle_unit_change_activity() invalid unit %d", unit_id);
3480  return;
3481  }
3482 
3483  if (punit->activity == activity
3484  && punit->activity_target == activity_target) {
3485  return;
3486  }
3487 
3488  /* Remove city spot reservations for AI settlers on city founding
3489  * mission, before goto_tile reset. */
3490  if (punit->server.adv->task != AUT_NONE) {
3491  adv_unit_new_task(punit, AUT_NONE, nullptr);
3492  }
3493 
3494  punit->goto_tile = nullptr;
3495 
3496  if (activity == ACTIVITY_GOTO) {
3497  /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
3498  * Setting ACTIVITY_GOTO from the client results in a unit indicating
3499  * it is going somewhere while it is standing still. The appearance of
3500  * the unit doing something can trick the user to not make use of it.
3501  *
3502  * Handled here because adv_follow_path() uses unit_activity_handling()
3503  * to set a unit's activity to ACTIVITY_GOTO. */
3504  return;
3505  }
3506 
3507  if (activity == ACTIVITY_EXPLORE) {
3508  // Please use unit_server_side_agent_set.
3509  return;
3510  }
3511 
3512  // The activity can now be set.
3514 }
3515 
3519 void handle_unit_change_activity(struct player *pplayer, int unit_id,
3520  enum unit_activity activity, int target_id)
3521 {
3522  struct extra_type *activity_target;
3523 
3524  if (target_id < 0 || target_id >= game.control.num_extra_types) {
3525  activity_target = nullptr;
3526  } else {
3527  activity_target = extra_by_number(target_id);
3528  }
3529 
3530  handle_unit_change_activity_real(pplayer, unit_id, activity,
3531  activity_target);
3532 }
3533 
3547 static void see_combat_unit(struct unit *punit)
3548 {
3549  packet_unit_short_info short_packet;
3550  packet_unit_info full_packet;
3551 
3552  package_short_unit(punit, &short_packet, UNIT_INFO_IDENTITY, 0);
3553  package_unit(punit, &full_packet);
3554 
3556  {
3557  struct player *pplayer = pconn->playing;
3558 
3559  if (pplayer != nullptr) {
3560  // NOTE: this means the player can see combat between submarines even
3561  // if neither sub is visible. See similar comment in send_combat.
3562  if (map_is_known_and_seen(unit_tile(punit), pplayer, V_MAIN)) {
3563  // Units are sent even if they were visible already. They may have
3564  // changed orientation for combat.
3565  if (players_on_same_team(pplayer, unit_owner(punit))) {
3566  send_packet_unit_info(pconn, &full_packet);
3567  } else {
3568  send_packet_unit_short_info(pconn, &short_packet, false);
3569  }
3570  }
3571  } else if (pconn->observer) {
3572  // Global observer sees everything...
3573  send_packet_unit_info(pconn, &full_packet);
3574  }
3575  }
3577 }
3578 
3582 static void send_bombardment(const unit *pattacker, const tile *ptarget)
3583 {
3584  struct packet_unit_bombard_info info;
3585  info.attacker_unit_id = pattacker->id;
3586  info.target_tile = ptarget->index;
3587 
3588  players_iterate(other_player)
3589  {
3590  /* NOTE: this means the player can see combat between submarines even
3591  * if neither sub is visible. See similar comment in see_combat. */
3592  if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
3593  || map_is_known_and_seen(ptarget, other_player, V_MAIN)) {
3594  lsend_packet_unit_bombard_info(other_player->connections, &info);
3595 
3596  // Remove the client knowledge of the units. This corresponds to the
3597  // send_packet_unit_short_info calls in see_combat.
3598  if (!can_player_see_unit(other_player, pattacker)) {
3599  unit_goes_out_of_sight(other_player, pattacker);
3600  }
3601  }
3602  }
3604 
3605  /* Send combat info to non-player observers as well. They already know
3606  * about the unit so no unit_info is needed. */
3608  {
3609  if (nullptr == pconn->playing && pconn->observer) {
3610  send_packet_unit_bombard_info(pconn, &info);
3611  }
3612  }
3614 }
3615 
3619 static void send_combat(struct unit *pattacker, struct unit *pdefender,
3620  int att_veteran, int def_veteran)
3621 {
3622  struct packet_unit_combat_info combat;
3623 
3624  combat.attacker_unit_id = pattacker->id;
3625  combat.defender_unit_id = pdefender->id;
3626  combat.attacker_hp = pattacker->hp;
3627  combat.defender_hp = pdefender->hp;
3628  combat.make_att_veteran = att_veteran;
3629  combat.make_def_veteran = def_veteran;
3630 
3631  players_iterate(other_player)
3632  {
3633  /* NOTE: this means the player can see combat between submarines even
3634  * if neither sub is visible. See similar comment in see_combat. */
3635  if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
3636  || map_is_known_and_seen(unit_tile(pdefender), other_player,
3637  V_MAIN)) {
3638  lsend_packet_unit_combat_info(other_player->connections, &combat);
3639 
3640  /*
3641  * Remove the client knowledge of the units. This corresponds to the
3642  * send_packet_unit_short_info calls in see_combat.
3643  */
3644  if (!can_player_see_unit(other_player, pattacker)) {
3645  unit_goes_out_of_sight(other_player, pattacker);
3646  }
3647  if (!can_player_see_unit(other_player, pdefender)) {
3648  unit_goes_out_of_sight(other_player, pdefender);
3649  }
3650  }
3651  }
3653 
3654  /* Send combat info to non-player observers as well. They already know
3655  * about the unit so no unit_info is needed. */
3657  {
3658  if (nullptr == pconn->playing && pconn->observer) {
3659  send_packet_unit_combat_info(pconn, &combat);
3660  }
3661  }
3663 }
3664 
3668 static void unit_attack_civilian_casualties(const struct unit *punit,
3669  struct city *pcity,
3670  const struct action *paction,
3671  const char *reason)
3672 {
3673  struct player *pplayer = unit_owner(punit);
3674 
3675  if (pcity && city_size_get(pcity) > 1
3676  && get_city_bonus(pcity, EFT_UNIT_NO_LOSE_POP) <= 0
3677  && kills_citizen_after_attack(punit)) {
3678  city_reduce_size(pcity, 1, pplayer, reason);
3679  city_refresh(pcity);
3680  send_city_info(nullptr, pcity);
3681  }
3682 }
3683 
3691 static bool unit_bombard(struct unit *punit, struct tile *ptile,
3692  const struct action *paction)
3693 {
3694  struct player *pplayer = unit_owner(punit);
3695  struct city *pcity = tile_city(ptile);
3696  std::set<struct player *> players_to_notify;
3697 
3698  // Sanity check: The actor still exists.
3699  fc_assert_ret_val(pplayer, false);
3700  fc_assert_ret_val(punit, false);
3701 
3702  log_debug("Start bombard: %s %s to %d, %d.",
3704  unit_rule_name(punit), TILE_XY(ptile));
3705 
3706  unit_list_iterate_safe(ptile->units, pdefender)
3707  {
3708  // Sanity checks
3710  !pplayers_non_attack(unit_owner(punit), unit_owner(pdefender)),
3711  false,
3712  "Trying to attack a unit with which you have "
3713  "peace or cease-fire at (%d, %d).",
3714  TILE_XY(unit_tile(pdefender)));
3716  !pplayers_allied(unit_owner(punit), unit_owner(pdefender)), false,
3717  "Trying to attack a unit with which you have "
3718  "alliance at (%d, %d).",
3719  TILE_XY(unit_tile(pdefender)));
3720 
3721  if (is_unit_reachable_at(pdefender, punit, ptile)) {
3722  bool adj;
3723  enum direction8 facing;
3724  int att_hp, def_hp;
3725 
3726  adj = base_get_direction_for_step(&(wld.map), punit->tile,
3727  pdefender->tile, &facing);
3728 
3729  if (adj) {
3730  punit->facing = facing;
3731 
3732  /* Unlike with normal attack, we don't change orientation of
3733  * defenders when bombarding */
3734  }
3735 
3736  unit_bombs_unit(punit, pdefender, &att_hp, &def_hp);
3737 
3738  players_to_notify.insert(unit_owner(pdefender));
3739 
3740  punit->hp = att_hp;
3741  pdefender->hp = def_hp;
3742 
3743  // May cause an incident
3744  action_consequence_success(paction, unit_owner(punit),
3745  unit_owner(pdefender), unit_tile(pdefender),
3746  unit_link(pdefender));
3747  }
3748  }
3750 
3751  // Notify the client (triggers explosion on tile)
3752  see_combat_unit(punit);
3753  send_bombardment(punit, ptile);
3754 
3755  // Send updates about affected units
3756  unit_list_iterate_safe(ptile->units, pdefender)
3757  {
3758  if (is_unit_reachable_at(pdefender, punit, ptile)) {
3759  send_unit_info(nullptr, pdefender);
3760  }
3761  }
3763 
3764  // Notify the players hit by the bombardment
3765  for (auto player_to_notify : players_to_notify) {
3766  notify_player(
3767  player_to_notify, ptile, E_UNIT_BOMB_DEF, ftc_server,
3768  /* TRANS: Your units at (x, y) have been bombarded by the French
3769  green Bomber [id:123].*/
3770  _("Your units at %s were bombarded by a %s %s %s [id:%d]."),
3771  tile_link(ptile), nation_adjective_for_player(pplayer),
3773  punit->id);
3774  }
3775  // Notify the player that bombarded
3776  notify_player(
3777  pplayer, ptile, E_UNIT_BOMB_ATT, ftc_server,
3778  /* TRANS: Your green Bomber [id:123] bombarded the units at (x, y).*/
3779  _("Your %s %s [id:%d] bombarded the units at %s."),
3781  punit->id, tile_link(ptile));
3782 
3783  unit_did_action(punit);
3785  unit_attack_civilian_casualties(punit, pcity, paction, "bombard");
3786 
3787  send_unit_info(nullptr, punit);
3788 
3789  return true;
3790 }
3791 
3803 static bool unit_nuke(struct player *pplayer, struct unit *punit,
3804  struct tile *def_tile, const struct action *paction)
3805 {
3806  struct city *pcity;
3807 
3808  // Sanity check: The actor still exists.
3809  fc_assert_ret_val(pplayer, false);
3810  fc_assert_ret_val(punit, false);
3811 
3812  log_debug("Start nuclear attack: %s %s against (%d, %d).",
3814  unit_rule_name(punit), TILE_XY(def_tile));
3815 
3816  if ((pcity = sdi_try_defend(pplayer, def_tile))) {
3817  // FIXME: Remove the hard coded reference to SDI defense.
3818  notify_player(pplayer, unit_tile(punit), E_UNIT_LOST_ATT, ftc_server,
3819  _("Your %s was shot down by "
3820  "SDI defenses, what a waste."),
3821  unit_tile_link(punit));
3822  notify_player(city_owner(pcity), def_tile, E_UNIT_WIN_DEF, ftc_server,
3823  _("The nuclear attack on %s was avoided by"
3824  " your SDI defense."),
3825  city_link(pcity));
3826 
3827  // Trying to nuke something this close can be... unpopular.
3828  action_consequence_caught(paction, pplayer, city_owner(pcity), def_tile,
3829  unit_tile_link(punit));
3830 
3831  // Remove the destroyed nuke.
3832  wipe_unit(punit, ULR_SDI, city_owner(pcity));
3833 
3834  return false;
3835  }
3836 
3837  dlsend_packet_nuke_tile_info(game.est_connections, tile_index(def_tile));
3838 
3839  // A nuke is always consumed when it detonates. See below.
3841 
3842  /* The nuke must be wiped here so it won't be seen as a victim of its own
3843  * detonation. */
3844  wipe_unit(punit, ULR_DETONATED, nullptr);
3845 
3846  do_nuclear_explosion(pplayer, def_tile);
3847 
3848  /* May cause an incident even if the target tile is unclaimed. A ruleset
3849  * could give everyone a casus belli against the tile nuker. A rule
3850  * like that would make sense in a story where detonating any nuke at all
3851  * could be forbidden. */
3852  action_consequence_success(paction, pplayer, tile_owner(def_tile),
3853  def_tile, tile_link(def_tile));
3854 
3855  return true;
3856 }
3857 
3867 static bool unit_do_destroy_city(struct player *act_player,
3868  struct unit *act_unit,
3869  struct city *tgt_city,
3870  const struct action *paction)
3871 {
3872  int tgt_city_id;
3873  struct player *tgt_player;
3874  bool capital;
3875  bool try_civil_war = false;
3876 
3877  // Sanity check: The actor still exists.
3878  fc_assert_ret_val(act_player, false);
3879  fc_assert_ret_val(act_unit, false);
3880 
3881  // Sanity check: The target city still exists.
3882  fc_assert_ret_val(tgt_city, false);
3883 
3884  tgt_player = city_owner(tgt_city);
3885 
3886  // How can a city be ownerless?
3887  fc_assert_ret_val(tgt_player, false);
3888 
3889  // Save city ID.
3890  tgt_city_id = tgt_city->id;
3891 
3892  capital = (player_primary_capital(tgt_player) == tgt_city);
3893 
3894  if (capital
3895  && (tgt_player->spaceship.state == SSHIP_STARTED
3896  || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
3897  // Destroying this city destroys the victim's space ship.
3898  spaceship_lost(tgt_player);
3899  }
3900 
3901  if (capital && civil_war_possible(tgt_player, true, true)
3903  && civil_war_triggered(tgt_player)) {
3904  // Destroying this city can trigger a civil war.
3905  try_civil_war = true;
3906  }
3907 
3908  // Let the actor know.
3909  notify_player(act_player, city_tile(tgt_city), E_UNIT_WIN_ATT, ftc_server,
3910  _("You destroy %s completely."), city_tile_link(tgt_city));
3911 
3912  if (tgt_player != act_player) {
3913  // This was done to a foreign city. Inform the victim player.
3914  notify_player(tgt_player, city_tile(tgt_city), E_CITY_LOST, ftc_server,
3915  _("%s has been destroyed by %s."),
3916  city_tile_link(tgt_city), player_name(act_player));
3917  }
3918 
3919  // May cause an incident
3920  action_consequence_success(paction, act_player, tgt_player,
3921  city_tile(tgt_city), city_link(tgt_city));
3922 
3923  // Run post city destruction Lua script.
3924  script_server_signal_emit("city_destroyed", tgt_city, tgt_player,
3925  act_player);
3926 
3927  // Can't be sure of city existence after running script.
3928  if (city_exist(tgt_city_id)) {
3929  remove_city(tgt_city);
3930  }
3931 
3932  if (try_civil_war) {
3933  // Try to start the civil war.
3934  (void) civil_war(tgt_player);
3935  }
3936 
3937  // The city is no more.
3938  return true;
3939 }
3940 
3950 static bool do_attack(struct unit *punit, struct tile *def_tile,
3951  const struct action *paction)
3952 {
3953  char attacker_link[MAX_LEN_LINK], defender_link[MAX_LEN_LINK];
3954  char attacker_vet[MAX_LEN_LINK], defender_vet[MAX_LEN_LINK];
3955  char attacker_fp[MAX_LEN_LINK], defender_fp[MAX_LEN_LINK];
3956  char attacker_tired[MAX_LEN_LINK];
3957  int moves_used, def_moves_used;
3958  int old_unit_vet, old_defender_vet;
3959  struct player *pplayer = unit_owner(punit);
3960  bool adj;
3961  enum direction8 facing;
3962  int att_hp, def_hp, att_fp, def_fp;
3963  int att_hp_start, def_hp_start;
3964  int def_power, att_power;
3965  struct unit *pdefender;
3966 
3967  if (!(pdefender = get_defender(punit, def_tile))) {
3968  // Can't fight air...
3969  return false;
3970  }
3971 
3972  att_hp_start = punit->hp;
3973  def_hp_start = pdefender->hp;
3974  def_power = get_total_defense_power(punit, pdefender);
3975  att_power = get_total_attack_power(punit, pdefender);
3976  get_modified_firepower(punit, pdefender, &att_fp, &def_fp);
3977 
3978  log_debug("Start attack: %s %s against %s %s.",
3980  unit_rule_name(punit),
3981  nation_rule_name(nation_of_unit(pdefender)),
3982  unit_rule_name(pdefender));
3983 
3984  // Sanity checks
3986  false,
3987  "Trying to attack a unit with which you have peace "
3988  "or cease-fire at (%d, %d).",
3989  TILE_XY(def_tile));
3990  fc_assert_ret_val_msg(!pplayers_allied(pplayer, unit_owner(pdefender)),
3991  false,
3992  "Trying to attack a unit with which you have "
3993  "alliance at (%d, %d).",
3994  TILE_XY(def_tile));
3995 
3996  moves_used = unit_move_rate(punit) - punit->moves_left;
3997  def_moves_used = unit_move_rate(pdefender) - pdefender->moves_left;
3998 
3999  adj = base_get_direction_for_step(&(wld.map), punit->tile, pdefender->tile,
4000  &facing);
4001 
4002  fc_assert(adj);
4003  if (adj) {
4004  punit->facing = facing;
4005  pdefender->facing = opposite_direction(facing);
4006  }
4007 
4008  old_unit_vet = punit->veteran;
4009  old_defender_vet = pdefender->veteran;
4010 
4011  /* N.B.: unit_veteran_level_string always returns the same pointer. */
4012  sz_strlcpy(attacker_vet, unit_veteran_level_string(punit));
4013  sz_strlcpy(defender_vet, unit_veteran_level_string(pdefender));
4014 
4015  /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
4016  sz_strlcpy(attacker_fp, unit_firepower_if_not_one(att_fp));
4017  sz_strlcpy(defender_fp, unit_firepower_if_not_one(def_fp));
4018 
4019  /* Record tired attack string before attack */
4020  sz_strlcpy(attacker_tired, unit_tired_attack_string(punit));
4021 
4022  unit_versus_unit(punit, pdefender, &att_hp, &def_hp);
4023 
4024  if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
4025  && unit_transported(punit)) {
4026  /* Dying attacker must be first unloaded so it doesn't die insider
4027  * transport */
4029  }
4030 
4031  see_combat_unit(punit);
4032  see_combat_unit(pdefender);
4033 
4034  punit->hp = att_hp;
4035  pdefender->hp = def_hp;
4036 
4037  combat_veterans(punit, pdefender);
4038 
4039  /* Adjust attackers moves_left _after_ unit_versus_unit() so that
4040  * the movement attack modifier is correct! --dwp
4041  *
4042  * For greater Civ2 compatibility (and game balance issues), we recompute
4043  * the new total MP based on the HP the unit has left after being damaged,
4044  * and subtract the MPs that had been used before the combat (plus the
4045  * points used in the attack itself, for the attacker). -GJW, Glip
4046  */
4047  punit->moves_left = unit_move_rate(punit) - moves_used;
4048  pdefender->moves_left = unit_move_rate(pdefender) - def_moves_used;
4049 
4050  if (punit->moves_left < 0) {
4051  punit->moves_left = 0;
4052  }
4053  if (pdefender->moves_left < 0) {
4054  pdefender->moves_left = 0;
4055  }
4056  unit_did_action(punit);
4058 
4059  // This may cause a diplomatic incident.
4060  action_consequence_success(paction, pplayer, unit_owner(pdefender),
4061  def_tile, unit_link(pdefender));
4062 
4063  send_combat(punit, pdefender, punit->veteran - old_unit_vet,
4064  pdefender->veteran - old_defender_vet);
4065 
4066  // Neither died
4067  if (punit->hp > 0 && pdefender->hp > 0) {
4068  // both units are alive - link to them.
4069  sz_strlcpy(attacker_link, unit_link(punit));
4070  sz_strlcpy(defender_link, unit_link(pdefender));
4071 
4072  log_debug("Tied battle: %s %s against %s %s.",
4074  unit_rule_name(punit),
4075  nation_rule_name(nation_of_unit(pdefender)),
4076  unit_rule_name(pdefender));
4077 
4078  // scorn the attacker if defender lost no hp
4079  if (def_hp_start == pdefender->hp) {
4080  // notify attacker of battle tie
4081  notify_player(
4082  unit_owner(punit), unit_tile(punit), E_UNIT_TIE_ATT, ftc_server,
4083  /* TRANS: "Your green Warrior [id:100 ...A:1.0, lost 3 HP,
4084  * 7 HP remaining] failed to hit the Greek Polish Archer [id:200
4085  * ...D:8.0, lost 5 HP, 5 HP remaining]!"*/
4086  _("Your %s %s [id:%d %sA:%.1f, lost %d HP, %d HP remaining]"
4087  " failed to hit the %s %s %s [id:%d %sD:%.1f HP:%d%s]!"),
4088  attacker_vet, attacker_link, punit->id, attacker_fp,
4089  (float) att_power / POWER_FACTOR, att_hp_start - punit->hp,
4090  punit->hp, nation_adjective_for_player(unit_owner(pdefender)),
4091  defender_vet, defender_link, pdefender->id, defender_fp,
4092  (float) def_power / POWER_FACTOR, pdefender->hp,
4093  (pdefender->veteran != old_defender_vet)
4094  ? unit_achieved_rank_string(pdefender)
4095  : "");
4096  // notify defender of battle tie
4097  notify_player(
4098  unit_owner(pdefender), unit_tile(pdefender), E_UNIT_TIE_DEF,
4099  ftc_server,
4100  /* TRANS: "Your green Warrior [id:100 ...A:1.0, lost 3 HP,
4101  * 7 HP remaining%s] brushed off a pathetic attack from the Greek
4102  * Polish Archer [id:200* ...D:8.0, lost 5 HP, 5 HP remaining%s]!";
4103  * The last %s is either a promoted string or empty */
4104  _("Your %s %s [id:%d %sD:%.1f HP:%d]"
4105  " brushed off a pathetic attack from the %s %s %s [id:%d "
4106  "%sA:%.1f, lost %d"
4107  " HP, %d HP remaining%s]!"),
4108  defender_vet, defender_link, pdefender->id, defender_fp,
4109  (float) def_power / POWER_FACTOR, pdefender->hp,
4110  nation_adjective_for_player(unit_owner(punit)), attacker_vet,
4111  attacker_link, punit->id, attacker_fp,
4112  (float) att_power / POWER_FACTOR, att_hp_start - punit->hp,
4113  punit->hp,
4114  (punit->veteran != old_unit_vet) ? unit_achieved_rank_string(punit)
4115  : "");
4116  } else {
4117  // notify attacker of battle tie
4118  notify_player(
4119  unit_owner(punit), unit_tile(punit), E_UNIT_TIE_ATT, ftc_server,
4120  /* TRANS: "Your green Warrior [id:100 ...A:1.0, lost 3 HP,
4121  * 7 HP remaining] attacked the Greek Polish Archer [id:200
4122  * ...D:8.0, lost 5 HP, 5 HP remaining]!"*/
4123  _("Your %s %s [id:%d %sA:%.1f, lost %d HP, %d HP remaining]"
4124  " attacked the %s %s %s [id:%d %sD:%.1f, lost %d"
4125  " HP, %d HP remaining%s]!"),
4126  attacker_vet, attacker_link, punit->id, attacker_fp,
4127  (float) att_power / POWER_FACTOR, att_hp_start - punit->hp,
4128  punit->hp, nation_adjective_for_player(unit_owner(pdefender)),
4129  defender_vet, defender_link, pdefender->id, defender_fp,
4130  (float) def_power / POWER_FACTOR, def_hp_start - pdefender->hp,
4131  pdefender->hp,
4132  (pdefender->veteran != old_defender_vet)
4133  ? unit_achieved_rank_string(pdefender)
4134  : "");
4135  // notify defender of battle tie
4136  notify_player(
4137  unit_owner(pdefender), unit_tile(pdefender), E_UNIT_TIE_DEF,
4138  ftc_server,
4139  /* TRANS: "Your green Warrior [id:100 ...A:1.0, lost 3 HP,
4140  * 7 HP remaining%s] fought back the attacking Greek Polish Archer
4141  * [id:200 ...D:8.0, lost 5 HP, 5 HP remaining%s]!";
4142  * The last %s is either a promoted string or empty */
4143  _("Your %s %s [id:%d %sD:%.1f, lost %d HP, %d HP remaining]"
4144  " fought back the attacking %s %s %s [id:%d %sA:%.1f, lost %d"
4145  " HP, %d HP remaining%s]!"),
4146  defender_vet, defender_link, pdefender->id, defender_fp,
4147  (float) def_power / POWER_FACTOR, def_hp_start - pdefender->hp,
4148  pdefender->hp, nation_adjective_for_player(unit_owner(punit)),
4149  attacker_vet, attacker_link, punit->id, attacker_fp,
4150  (float) att_power / POWER_FACTOR, att_hp_start - punit->hp,
4151  punit->hp,
4152  (punit->veteran != old_unit_vet) ? unit_achieved_rank_string(punit)
4153  : "");
4154  }
4155 
4156  // notify attacker of promotion
4157  if (punit->veteran != old_unit_vet) {
4158  notify_unit_experience(punit);
4159  }
4160 
4161  // notify defender of promotion
4162  if (pdefender->veteran != old_defender_vet) {
4163  notify_unit_experience(pdefender);
4164  }
4165  return true;
4166  }
4167 
4168  // attacker killed the defender
4169  if (punit->hp > 0 && pdefender->hp <= 0) {
4170  // defender is dead; link to tile instead.
4171  sz_strlcpy(attacker_link, unit_link(punit));
4172  sz_strlcpy(defender_link, unit_tile_link(pdefender));
4173 
4174  log_debug("Attacker won: %s %s against %s %s.",
4176  unit_rule_name(punit),
4177  nation_rule_name(nation_of_unit(pdefender)),
4178  unit_rule_name(pdefender));
4179 
4180  // scorn the defender if the attacker didn't lose any hp
4181  if (att_hp_start == punit->hp) {
4182  // notify the attacker of victory
4183  notify_player(
4184  unit_owner(punit), unit_tile(punit), E_UNIT_WIN_ATT, ftc_server,
4185  /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
4186  * lost 1 HP, has 9 HP remaining%s] eliminated the
4187  * worthless Greek green Warriors [id:100 HP:10]." */
4188  _("Your %s %s [id:%d %s%sA:%.1f, HP:%d] eliminated the "
4189  "worthless %s %s %s [id:%d %sD:%.1f, lost %d HP]."),
4190  attacker_vet, attacker_link, punit->id, attacker_fp,
4191  attacker_tired, (float) att_power / POWER_FACTOR, punit->hp,
4192  nation_adjective_for_player(unit_owner(pdefender)), defender_vet,
4193  defender_link, pdefender->id, defender_fp,
4194  (float) def_power / POWER_FACTOR, def_hp_start);
4195  // notify defender of defeat
4196  notify_player(
4197  unit_owner(pdefender), unit_tile(pdefender), E_UNIT_LOST_DEF,
4198  ftc_server,
4199  /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
4200  * helplessly perished in an attack by the Greek green Legion
4201  * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
4202  * last %s is either ", promoted ..." or empty string */
4203  _("Your %s %s [id:%d %sD:%.1f HP:%d] helplessly perished in an"
4204  " attack by the %s %s %s [id:%d %s%sA:%.1f HP:%d%s]."),
4205  defender_vet, defender_link, pdefender->id, defender_fp,
4206  (float) def_power / POWER_FACTOR, def_hp_start,
4207  nation_adjective_for_player(unit_owner(punit)), attacker_vet,
4208  attacker_link, punit->id, attacker_fp, attacker_tired,
4209  (float) att_power / POWER_FACTOR, punit->hp,
4210  (punit->veteran != old_unit_vet) ? unit_achieved_rank_string(punit)
4211  : "");
4212  } else {
4213  // notify the attacker of victory
4214  notify_player(unit_owner(punit), unit_tile(punit), E_UNIT_WIN_ATT,
4215  ftc_server,
4216  /* TRANS: "Your green Legion [id:200 ...A:4.0
4217  * lost 1 HP, has 9 HP remaining%s] eliminated the
4218  * Greek green Warriors [id:100 ...D:2, lost 10 HP]." */
4219  _("Your %s %s [id:%d %s%sA:%.1f, lost %d HP, "
4220  "has %d remaining] eliminated the %s %s %s "
4221  "[id:%d %sD:%.1f, lost %d HP]."),
4222  attacker_vet, attacker_link, punit->id, attacker_fp,
4223  attacker_tired, (float) att_power / POWER_FACTOR,
4224  att_hp_start - punit->hp, punit->hp,
4226  defender_vet, defender_link, pdefender->id, defender_fp,
4227  (float) def_power / POWER_FACTOR, def_hp_start);
4228  // notify defender of defeat
4229  notify_player(
4230  unit_owner(pdefender), unit_tile(pdefender), E_UNIT_LOST_DEF,
4231  ftc_server,
4232  /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
4233  * perished in an attack by the Greek green Legion
4234  * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
4235  * last %s is either ", promoted ..." or empty string */
4236  _("Your %s %s [id:%d %sD:%.1f HP:%d] perished in an attack by "
4237  "the %s %s %s [id:%d %s%sA:%.1f, lost %d HP, has %d HP "
4238  "remaining%s]."),
4239  defender_vet, defender_link, pdefender->id, defender_fp,
4240  (float) def_power / POWER_FACTOR, def_hp_start,
4241  nation_adjective_for_player(unit_owner(punit)), attacker_vet,
4242  attacker_link, punit->id, attacker_fp, attacker_tired,
4243  (float) att_power / POWER_FACTOR, att_hp_start - punit->hp,
4244  punit->hp,
4245  (punit->veteran != old_unit_vet) ? unit_achieved_rank_string(punit)
4246  : "");
4247  }
4248  // notify attacker of promotion
4249  if (punit->veteran != old_unit_vet) {
4250  notify_unit_experience(punit);
4251  }
4252 
4253  punit->moved = true; // We moved
4254  kill_unit(punit, pdefender,
4255  punit->veteran == old_unit_vet
4256  && !utype_is_consumed_by_action(paction, punit->utype));
4257 
4258  /* Now that dead defender is certainly no longer listed as unit
4259  * supported by the city, we may even remove the city
4260  * (if it shrinks from size 1) */
4261  if (auto pcity = tile_city(def_tile); pcity != nullptr) {
4262  unit_attack_civilian_casualties(punit, pcity, paction, "attack");
4263  }
4264  if (!utype_is_consumed_by_action(paction, punit->utype)) {
4265  /* If attacker wins, and occupychance > 0, it might move in. Don't
4266  * move in if there are enemy units in the tile (a fortress, city or
4267  * air base with multiple defenders and unstacked combat). Note that
4268  * this could mean capturing (or destroying) a city. */
4269  if (fc_rand(100) < game.server.occupychance
4270  && !is_non_allied_unit_tile(def_tile, pplayer)) {
4271  occupy_move(punit, def_tile);
4272  }
4273  // The attacker may have died for many reasons
4274  // For example if there's a hut on the target tile.
4275  if (game_unit_by_number(punit->id) != nullptr) {
4276  send_unit_info(nullptr, punit);
4277  }
4278  }
4279  return true;
4280  }
4281 
4282  // defender killed the attacker
4283  if (punit->hp <= 0 && pdefender->hp > 0) {
4284  // attacker is dead; link to tile instead.
4285  sz_strlcpy(attacker_link, unit_tile_link(punit));
4286  sz_strlcpy(defender_link, unit_link(pdefender));
4287 
4288  // The attacker lost
4289  log_debug("Attacker lost: %s %s against %s %s.",
4291  unit_rule_name(punit),
4292  nation_rule_name(nation_of_unit(pdefender)),
4293  unit_rule_name(pdefender));
4294 
4295  // scorn the attacker if the defender didn't lose any hp
4296  if (def_hp_start == pdefender->hp) {
4297  // notify attacker of defeat
4298  notify_player(
4299  unit_owner(punit), unit_tile(punit), E_UNIT_LOST_ATT, ftc_server,
4300  /* TRANS: "Your green Cannon [id:100 ...A:8.0, lost 10 HP]
4301  * failed against the Greek Polish Destroyer
4302  * [id:200 ...D:20 HP:30]!";
4303  * last %s is either "and ..." or empty string. */
4304  _("Your %s %s [id:%d %sA:%.1f, lost %d HP] failed terribly"
4305  " against the %s %s %s [id:%d %sD:%.1f HP:%d%s]!"),
4306  attacker_vet, attacker_link, punit->id, attacker_fp,
4307  (float) att_power / POWER_FACTOR, att_hp_start,
4308  nation_adjective_for_player(unit_owner(pdefender)), defender_vet,
4309  defender_link, pdefender->id, defender_fp,
4310  (float) def_power / POWER_FACTOR, pdefender->hp,
4311  (pdefender->veteran != old_defender_vet)
4312  ? unit_achieved_rank_string(pdefender)
4313  : "");
4314  // notify defender of victory
4315  notify_player(
4316  unit_owner(pdefender), def_tile, E_UNIT_WIN_DEF, ftc_server,
4317  /* TRANS: "Your green Legion [id:100 ...D:4.0 HP:10]
4318  * stopped the pathetic ...attack from the
4319  * green Greek Warriors [id:90 ...A:1.0 HP:10]. */
4320  _("Your %s %s [id:%d %sD:%.1f HP:%d]"
4321  " stopped the pathetic %sattack from the %s %s %s "
4322  "[id:%d %sA:%.1f HP:%d]."),
4323  defender_vet, defender_link, pdefender->id, defender_fp,
4324  (float) def_power / POWER_FACTOR, pdefender->hp, attacker_tired,
4325  nation_adjective_for_player(unit_owner(punit)), attacker_vet,
4326  attacker_link, punit->id, attacker_fp,
4327  (float) att_power / POWER_FACTOR, att_hp_start);
4328  } else {
4329  // notify attacker of defeat
4330  notify_player(
4331  unit_owner(punit), unit_tile(punit), E_UNIT_LOST_ATT, ftc_server,
4332  /* TRANS: "Your green Cannon [id:100 ...A:8.0, lost 10 HP]
4333  * perished while attacking the Greek Polish Destroyer [id:200
4334  * ...D:12, lost 27 HP, 3 HP remaining%s]!";
4335  * last %s is either "and ..." or empty string */
4336  _("Your %s %s [id:%d %sA:%.1f, lost %d HP] perished while"
4337  " attacking the %s %s %s [id:%d %sD:%.1f, lost %d HP, %d HP "
4338  "remaining%s]!"),
4339  attacker_vet, attacker_link, punit->id, attacker_fp,
4340  (float) att_power / POWER_FACTOR, att_hp_start,
4341  nation_adjective_for_player(unit_owner(pdefender)), defender_vet,
4342  defender_link, pdefender->id, defender_fp,
4343  (float) def_power / POWER_FACTOR, def_hp_start - pdefender->hp,
4344  pdefender->hp,
4345  (pdefender->veteran != old_defender_vet)
4346  ? unit_achieved_rank_string(pdefender)
4347  : "");
4348  notify_player(
4349  unit_owner(pdefender), def_tile, E_UNIT_WIN_DEF, ftc_server,
4350  /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
4351  * 9 HP remaining] stopped the attack from the
4352  * green Greek Warriors [id:90 ...A:1.0 HP:10]. */
4353  _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
4354  " stopped the %sattack from the %s %s %s "
4355  "[id:%d %sA:%.1f HP:%d]."),
4356  defender_vet, defender_link, pdefender->id, defender_fp,
4357  (float) def_power / POWER_FACTOR, def_hp_start - pdefender->hp,
4358  pdefender->hp, attacker_tired,
4359  nation_adjective_for_player(unit_owner(punit)), attacker_vet,
4360  attacker_link, punit->id, attacker_fp,
4361  (float) att_power / POWER_FACTOR, att_hp_start);
4362  }
4363  // notify defender of promotion
4364  if (pdefender->veteran == old_defender_vet ? 0 : 1) {
4365  notify_unit_experience(pdefender);
4366  }
4367 
4368  wipe_unit(punit, ULR_KILLED, unit_owner(pdefender));
4369  return true;
4370  }
4371  // this function should have not passed through this line of code
4372  fc_assert_ret_val(false, true);
4373 }
4374 
4385 static bool do_unit_strike_city_production(const struct player *act_player,
4386  struct unit *act_unit,
4387  struct city *tgt_city,
4388  const struct action *paction)
4389 {
4390  struct player *tgt_player;
4391  char prod[256];
4392 
4393  // Sanity checks
4394  fc_assert_ret_val(act_player, false);
4395  fc_assert_ret_val(act_unit, false);
4396  fc_assert_ret_val(tgt_city, false);
4397  fc_assert_ret_val(paction, false);
4398 
4399  tgt_player = city_owner(tgt_city);
4400  fc_assert_ret_val(tgt_player, false);
4401 
4402  // The surgical strike may miss.
4403  {
4404  // Roll the dice.
4405  if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
4406  paction)) {
4407  // Notify the player.
4408  notify_player(act_player, city_tile(tgt_city),
4409  E_UNIT_ACTION_ACTOR_FAILURE, ftc_server,
4410  // TRANS: unit, action, city
4411  _("Your %s failed to do %s in %s."), unit_link(act_unit),
4412  qUtf8Printable(action_name_translation(paction)),
4413  city_link(tgt_city));
4414 
4415  // Make the failed attempt cost a single move.
4416  act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
4417 
4418  return false;
4419  }
4420  }
4421 
4422  // Get name of the production
4423  universal_name_translation(&tgt_city->production, prod, sizeof(prod));
4424 
4425  // Destroy the production
4426  tgt_city->shield_stock = 0;
4427  nullify_prechange_production(tgt_city);
4428 
4429  // Let the players know.
4430  notify_player(act_player, city_tile(tgt_city), E_UNIT_ACTION_ACTOR_SUCCESS,
4431  ftc_server,
4432  _("Your %s succeeded in destroying"
4433  " the production of %s in %s."),
4434  unit_link(act_unit), prod, city_name_get(tgt_city));
4435  notify_player(tgt_player, city_tile(tgt_city),
4436  E_UNIT_ACTION_TARGET_HOSTILE, ftc_server,
4437  _("The production of %s was destroyed in %s,"
4438  " %s are suspected."),
4439  prod, city_link(tgt_city),
4440  nation_plural_for_player(tgt_player));
4441 
4442  return true;
4443 }
4444 
4455 static bool do_unit_strike_city_building(const struct player *act_player,
4456  struct unit *act_unit,
4457  struct city *tgt_city,
4458  Impr_type_id tgt_bld_id,
4459  const struct action *paction)
4460 {
4461  struct player *tgt_player;
4462  struct impr_type *tgt_bld = improvement_by_number(tgt_bld_id);
4463 
4464  // Sanity checks
4465  fc_assert_ret_val(act_player, false);
4466  fc_assert_ret_val(act_unit, false);
4467  fc_assert_ret_val(tgt_city, false);
4468  fc_assert_ret_val(paction, false);
4469 
4470  tgt_player = city_owner(tgt_city);
4471  fc_assert_ret_val(tgt_player, false);
4472 
4473  // The surgical strike may miss.
4474  {
4475  // Roll the dice.
4476  if (action_failed_dice_roll(act_player, act_unit, tgt_city, tgt_player,
4477  paction)) {
4478  // Notify the player.
4479  notify_player(act_player, city_tile(tgt_city),
4480  E_UNIT_ACTION_ACTOR_FAILURE, ftc_server,
4481  // TRANS: unit, action, city
4482  _("Your %s failed to do %s in %s."), unit_link(act_unit),
4483  qUtf8Printable(action_name_translation(paction)),
4484  city_link(tgt_city));
4485 
4486  // Make the failed attempt cost a single move.
4487  act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
4488 
4489  return false;
4490  }
4491  }
4492 
4493  if (!city_has_building(tgt_city, tgt_bld)) {
4494  // Noting to destroy here.
4495 
4496  // Notify the player.
4497  notify_player(act_player, city_tile(tgt_city),
4498  E_UNIT_ACTION_ACTOR_FAILURE, ftc_server,
4499  _("Your %s didn't find a %s to %s in %s."),
4500  unit_link(act_unit), improvement_name_translation(tgt_bld),
4501  qUtf8Printable(action_name_translation(paction)),
4502  city_link(tgt_city));
4503 
4504  // Punish the player for blindly attacking a building.
4505  act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
4506 
4507  return false;
4508  }
4509 
4510  // Destroy the building.
4511  building_lost(tgt_city, tgt_bld, "attacked", act_unit);
4512 
4513  // Update the player's view of the city.
4514  send_city_info(nullptr, tgt_city);
4515 
4516  // Let the players know.
4517  notify_player(act_player, city_tile(tgt_city), E_UNIT_ACTION_ACTOR_SUCCESS,
4518  ftc_server, _("Your %s destroyed the %s in %s."),
4519  unit_link(act_unit), improvement_name_translation(tgt_bld),
4520  city_link(tgt_city));
4521  notify_player(tgt_player, city_tile(tgt_city),
4522  E_UNIT_ACTION_TARGET_HOSTILE, ftc_server,
4523  _("The %s destroyed the %s in %s."),
4524  nation_plural_for_player(tgt_player),
4525  improvement_name_translation(tgt_bld), city_link(tgt_city));
4526 
4527  return true;
4528 }
4529 
4539 static bool do_unit_conquer_city(struct player *act_player,
4540  struct unit *act_unit,
4541  struct city *tgt_city,
4542  struct action *paction)
4543 {
4544  bool success;
4545  struct tile *tgt_tile = city_tile(tgt_city);
4546  int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
4547  int tgt_city_id = tgt_city->id;
4548  struct player *tgt_player = city_owner(tgt_city);
4549  const char *victim_link = city_link(tgt_city);
4550 
4551  // Sanity check
4552  fc_assert_ret_val(tgt_tile, false);
4553 
4554  unit_move(act_unit, tgt_tile, move_cost, nullptr, false, true);
4555 
4556  // The city may have been destroyed during the conquest.
4557  success = (!city_exist(tgt_city_id) || city_owner(tgt_city) == act_player);
4558 
4559  if (success) {
4560  // May cause an incident
4561  action_consequence_success(paction, act_player, tgt_player, tgt_tile,
4562  victim_link);
4563  }
4564 
4565  return success;
4566 }
4567 
4571 static bool can_unit_move_to_tile_with_notify(struct unit *punit,
4572  struct tile *dest_tile,
4573  bool igzoc,
4574  struct unit *embark_to,
4575  bool enter_enemy_city)
4576 {
4577  struct tile *src_tile = unit_tile(punit);
4578  enum unit_move_result reason =
4579  unit_move_to_tile_test(&(wld.map), punit, punit->activity, src_tile,
4580  dest_tile, igzoc, embark_to, enter_enemy_city);
4581 
4582  switch (reason) {
4583  case MR_OK:
4584  return true;
4585 
4586  case MR_NO_WAR:
4587  notify_player(unit_owner(punit), src_tile, E_BAD_COMMAND, ftc_server,
4588  _("Cannot attack unless you declare war first."));
4589  break;
4590 
4591  case MR_ZOC:
4592  notify_player(unit_owner(punit), src_tile, E_BAD_COMMAND, ftc_server,
4593  _("%s can only move into your own zone of control."),
4594  unit_link(punit));
4595  break;
4596 
4597  case MR_TRIREME:
4598  notify_player(unit_owner(punit), src_tile, E_BAD_COMMAND, ftc_server,
4599  _("%s cannot move that far from the coast line."),
4600  unit_link(punit));
4601  break;
4602 
4603  case MR_PEACE:
4604  if (tile_owner(dest_tile)) {
4605  notify_player(unit_owner(punit), src_tile, E_BAD_COMMAND, ftc_server,
4606  _("Cannot invade unless you break peace with "
4607  "%s first."),
4608  player_name(tile_owner(dest_tile)));
4609  }
4610  break;
4611 
4612  case MR_CANNOT_DISEMBARK:
4613  notify_player(
4614  unit_owner(punit), src_tile, E_BAD_COMMAND, ftc_server,
4615  _("%s cannot disembark outside of a city or a native base "
4616  "for %s."),
4617  unit_link(punit),
4619  break;
4620 
4621  case MR_NON_NATIVE_MOVE:
4622  notify_player(unit_owner(punit), src_tile, E_BAD_COMMAND, ftc_server,
4623  _("Terrain is unsuitable for %s units."),
4625  break;
4626 
4627  default:
4628  // FIXME: need more explanations someday!
4629  break;
4630  };
4631 
4632  return false;
4633 }
4634 
4654 bool unit_move_handling(struct unit *punit, struct tile *pdesttile,
4655  bool igzoc, bool move_do_not_act)
4656 {
4657  struct player *pplayer = unit_owner(punit);
4658 
4659  /*** Phase 1: Basic checks ***/
4660 
4661  /* this occurs often during lag, and to the AI due to some quirks -- Syela
4662  */
4663  if (!is_tiles_adjacent(unit_tile(punit), pdesttile)) {
4664  log_debug("tiles not adjacent in move request");
4665  return false;
4666  }
4667 
4668  if (punit->moves_left <= 0) {
4669  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
4670  _("This unit has no moves left."));
4671  return false;
4672  }
4673 
4674  if (!unit_can_do_action_now(punit)) {
4675  return false;
4676  }
4677 
4678  /*** Phase 2: Attempted action interpretation checks ***/
4679 
4680  /* Check if the move should be interpreted as an attempt to perform an
4681  * enabler controlled action to the target tile. When the move may be an
4682  * action attempt the server stops moving the unit, marks it as wanting a
4683  * decision based on its own movement to the tile it attempted to move to
4684  * and notifies the client.
4685  *
4686  * In response to the unit being marked as wanting a decision the client
4687  * can query the server for what actions the unit, given the player's
4688  * knowledge, may be able to perform against a target at the tile it tried
4689  * to move to. The server will respond to the query with the actions that
4690  * may be enabled and, when all actions are known to be illegal given the
4691  * player's knowledge, an explanation why no action could be done. The
4692  * client will probably use the list of potentially legal actions, if any,
4693  * to pop up an action selection dialog. See handle_unit_action_query()
4694  *
4695  * If move_do_not_act is TRUE the move is never interpreted as an attempt
4696  * to perform an enabler controlled action.
4697  * Examples of where this is useful is for AI moves, goto, when the player
4698  * attempts to move to a tile occupied by potential targets like allied
4699  * cities or units and during rule forced moves.
4700  *
4701  * A move is not interpreted as an attempted action because the unit is
4702  * able to do a self targeted action.
4703  *
4704  * A move is not interpreted as an attempted action because an action
4705  * with rare_pop_up set to TRUE is legal unless the unit is unable to
4706  * perform a regular move to the tile.
4707  *
4708  * An attempted move to a tile a unit can't move to is always interpreted
4709  * as trying to perform an action (unless move_do_not_act is TRUE) */
4710  if (!move_do_not_act) {
4711  const bool can_not_move =
4712  !unit_can_move_to_tile(&(wld.map), punit, pdesttile, igzoc, false);
4713  bool one_action_may_be_legal =
4714  action_tgt_unit(punit, pdesttile, can_not_move)
4715  || action_tgt_city(punit, pdesttile, can_not_move)
4716  // A legal action with an extra sub target is a legal action
4717  || action_tgt_tile_extra(punit, pdesttile, can_not_move)
4718  // Tile target actions with extra sub targets are handled above
4719  // Includes actions vs unit stacks
4720  || action_tgt_tile(punit, pdesttile, nullptr, can_not_move);
4721 
4722  if (one_action_may_be_legal || can_not_move) {
4723  /* There is a target punit, from the player's point of view, may be
4724  * able to act against OR punit can't do any non action move. The
4725  * client should therefore ask what action(s) the unit can perform
4726  * to any targets at pdesttile.
4727  *
4728  * In the first case the unit needs a decision about what action, if
4729  * any at all, to take. Asking what actions the unit can perform
4730  * will return a list of actions that may, from the players point of
4731  * view, be possible. The client can then show this list to the
4732  * player or, if configured to do so, make the choice it self.
4733  *
4734  * In the last case the player may need an explanation about why no
4735  * action could be taken. Asking what actions the unit can perform
4736  * will provide this explanation. */
4737  punit->action_decision_want = ACT_DEC_ACTIVE;
4738  punit->action_decision_tile = pdesttile;
4739  send_unit_info(player_reply_dest(pplayer), punit);
4740 
4741  /* The move wasn't done because the unit wanted the player to
4742  * decide what to do or because the unit couldn't move to the
4743  * target tile. */
4744  return false;
4745  }
4746  }
4747 
4748  /*** Phase 3: OK now move the unit ***/
4749 
4750  /* We cannot move a transport into a tile that holds
4751  * units or cities not allied with all of our cargo. */
4752  if (get_transporter_capacity(punit) > 0) {
4753  unit_list_iterate(unit_tile(punit)->units, pcargo)
4754  {
4755  if (unit_contained_in(pcargo, punit)
4756  && (is_non_allied_unit_tile(pdesttile, unit_owner(pcargo))
4757  || is_non_allied_city_tile(pdesttile, unit_owner(pcargo)))) {
4758  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
4759  _("A transported unit is not allied to all "
4760  "units or city on target tile."));
4761  return false;
4762  }
4763  }
4765  }
4766 
4767  if (can_unit_move_to_tile_with_notify(punit, pdesttile, igzoc, nullptr,
4768  false)
4769  // Don't override "Transport Embark"
4770  && can_unit_exist_at_tile(&(wld.map), punit, pdesttile)
4771  // Don't override "Transport Disembark" or "Transport Disembark 2"
4772  && !unit_transported(punit)) {
4773  int move_cost = map_move_cost_unit(&(wld.map), punit, pdesttile);
4774 
4775  unit_move(punit, pdesttile, move_cost,
4776  // Don't override "Transport Embark"
4777  nullptr, false,
4778  // Don't override "Conquer City"
4779  false);
4780 
4781  return true;
4782  } else {
4783  return false;
4784  }
4785 }
4786 
4797 static bool unit_do_help_build(struct player *pplayer, struct unit *punit,
4798  struct city *pcity_dest,
4799  const struct action *paction)
4800 {
4801  const char *work;
4802  const char *prod;
4803  int shields;
4804 
4805  // Sanity check: The actor still exists.
4806  fc_assert_ret_val(pplayer, false);
4807  fc_assert_ret_val(punit, false);
4808 
4809  // Sanity check: The target city still exists.
4810  fc_assert_ret_val(pcity_dest, false);
4811 
4812  shields = unit_shield_value(punit, unit_type_get(punit), paction);
4813 
4814  if (action_has_result(paction, ACTRES_HELP_WONDER)) {
4815  // Add the caravan shields
4816  pcity_dest->shield_stock += shields;
4817 
4818  /* Will be punished for changing production to something that can't
4819  * receive "Help Wonder" help. */
4821  pcity_dest->caravan_shields += shields;
4822  } else {
4823  fc_assert(action_has_result(paction, ACTRES_RECYCLE_UNIT));
4824  /* Add the shields from recycling the unit to the city's current
4825  * production. */
4826  pcity_dest->shield_stock += shields;
4827 
4828  // If we change production later at this turn. No penalty is added.
4829  pcity_dest->disbanded_shields += shields;
4830  }
4831 
4832  conn_list_do_buffer(pplayer->connections);
4833 
4834  if (action_has_result(paction, ACTRES_HELP_WONDER)) {
4835  /* Let the player that just donated shields with "Help Wonder" know
4836  * the result of his donation. */
4837  prod = city_production_name_translation(pcity_dest);
4838  } else {
4839  fc_assert(action_has_result(paction, ACTRES_RECYCLE_UNIT));
4840  /* TRANS: Your Caravan does "Recycle Unit" to help build the
4841  * current production in Bergen (4 surplus).
4842  * "Recycle Unit" says "current production" rather than its name. */
4843  prod = _("current production");
4844  }
4845 
4846  if (build_points_left(pcity_dest) >= 0) {
4847  /* TRANS: Your Caravan does "Help Wonder" to help build the
4848  * Pyramids in Bergen (4 remaining).
4849  * You can reorder '4' and 'remaining' in the actual format string. */
4850  work = _("remaining");
4851  } else {
4852  /* TRANS: Your Caravan does "Help Wonder" to help build the
4853  * Pyramids in Bergen (4 surplus).
4854  * You can reorder '4' and 'surplus' in the actual format string. */
4855  work = _("surplus");
4856  }
4857 
4858  notify_player(
4859  pplayer, city_tile(pcity_dest), E_CARAVAN_ACTION, ftc_server,
4860  /* TRANS: Your Caravan does "Help Wonder" to help build the
4861  * Pyramids in Bergen (4 surplus). */
4862  _("Your %s does %s to help build the %s in %s (%d %s)."),
4863  unit_link(punit), qUtf8Printable(action_name_translation(paction)),
4864  prod, city_link(pcity_dest), abs(build_points_left(pcity_dest)), work);
4865 
4866  // May cause an incident
4867  action_consequence_success(paction, pplayer, city_owner(pcity_dest),
4868  city_tile(pcity_dest), city_link(pcity_dest));
4869 
4870  if (city_owner(pcity_dest) != unit_owner(punit)) {
4871  // Tell the city owner about the gift he just received.
4872 
4873  notify_player(city_owner(pcity_dest), city_tile(pcity_dest),
4874  E_CARAVAN_ACTION, ftc_server,
4875  /* TRANS: Help building the Pyramids in Bergen received
4876  * from Persian Caravan (4 surplus). */
4877  _("Help building the %s in %s received from %s %s "
4878  "(%d %s)."),
4880  city_link(pcity_dest),
4881  nation_adjective_for_player(pplayer), unit_link(punit),
4882  abs(build_points_left(pcity_dest)), work);
4883  }
4884 
4885  send_player_info_c(pplayer, pplayer->connections);
4886  send_city_info(pplayer, pcity_dest);
4888 
4889  return true;
4890 }
4891 
4899 static bool do_unit_establish_trade(struct player *pplayer,
4900  struct unit *punit,
4901  struct city *pcity_dest,
4902  const struct action *paction)
4903 {
4904  char homecity_link[MAX_LEN_LINK], destcity_link[MAX_LEN_LINK];
4905  char punit_link[MAX_LEN_LINK];
4906  int revenue;
4907  bool can_establish;
4908  int home_overbooked = 0;
4909  int dest_overbooked = 0;
4910  int home_max;
4911  int dest_max;
4912  struct city *pcity_homecity;
4913  struct trade_route_list *routes_out_of_dest;
4914  struct trade_route_list *routes_out_of_home;
4915  enum traderoute_bonus_type bonus_type;
4916  struct goods_type *goods;
4917  const char *goods_str;
4918 
4919  // Sanity check: The actor still exists.
4920  fc_assert_ret_val(pplayer, false);
4921  fc_assert_ret_val(punit, false);
4922 
4923  // Sanity check: The target city still exists.
4924  fc_assert_ret_val(pcity_dest, false);
4925 
4926  pcity_homecity = player_city_by_number(pplayer, punit->homecity);
4927 
4928  if (!pcity_homecity) {
4929  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
4930  _("Sorry, your %s cannot establish"
4931  " a trade route because it has no home city."),
4932  unit_link(punit));
4933  return false;
4934  }
4935 
4936  if (game.info.goods_selection == GSM_ARRIVAL) {
4937  goods = goods_from_city_to_unit(pcity_homecity, punit);
4938  } else {
4939  goods = punit->carrying;
4940  }
4941  if (goods == nullptr) {
4942  notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
4943  _("Sorry, your %s cannot establish"
4944  " a trade route because it's not carrying any goods."),
4945  unit_link(punit));
4946  return false;
4947  }
4948 
4949  sz_strlcpy(homecity_link, city_link(pcity_homecity));
4950  sz_strlcpy(destcity_link, city_link(pcity_dest));
4951 
4952  if (!can_cities_trade(pcity_homecity, pcity_dest)) {
4953  notify_player(pplayer, city_tile(pcity_dest), E_BAD_COMMAND, ftc_server,
4954  _("Sorry, your %s cannot establish"
4955  " a trade route between %s and %s."),
4956  unit_link(punit), homecity_link, destcity_link);
4957  return false;
4958  }
4959 
4960  sz_strlcpy(punit_link, unit_tile_link(punit));
4961  routes_out_of_home = trade_route_list_new();
4962  routes_out_of_dest = trade_route_list_new();
4963 
4964  /* This part of code works like can_establish_trade_route, except
4965  * that we actually do the action of making the trade route. */
4966 
4967  // If we can't make a new trade route we can still get the trade bonus.
4968  can_establish = action_has_result(paction, ACTRES_TRADE_ROUTE)
4969  && !have_cities_trade_route(pcity_homecity, pcity_dest);
4970 
4971  if (can_establish) {
4972  home_max = max_trade_routes(pcity_homecity);
4973  dest_max = max_trade_routes(pcity_dest);
4974  home_overbooked = city_num_trade_routes(pcity_homecity) - home_max;
4975  dest_overbooked = city_num_trade_routes(pcity_dest) - dest_max;
4976  }
4977 
4978  if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
4979  int trade = trade_base_between_cities(pcity_homecity, pcity_dest);
4980 
4981  // See if there's a trade route we can cancel at the home city.
4982  if (home_overbooked >= 0) {
4983  if (home_max <= 0
4984  || (city_trade_removable(pcity_homecity, routes_out_of_home)
4985  >= trade)) {
4986  notify_player(pplayer, city_tile(pcity_dest), E_BAD_COMMAND,
4987  ftc_server,
4988  _("Sorry, your %s cannot establish"
4989  " a trade route here!"),
4990  punit_link);
4991  if (home_max > 0) {
4992  notify_player(pplayer, city_tile(pcity_dest), E_BAD_COMMAND,
4993  ftc_server,
4994  PL_(" The city of %s already has %d "
4995  "better trade route!",
4996  " The city of %s already has %d "
4997  "better trade routes!",
4998  home_max),
4999  homecity_link, home_max);
5000  }
5001  can_establish = false;
5002  }
5003  }
5004 
5005  // See if there's a trade route we can cancel at the dest city.
5006  if (can_establish && dest_overbooked >= 0) {
5007  if (dest_max <= 0
5008  || (city_trade_removable(pcity_dest, routes_out_of_dest)
5009  >= trade)) {
5010  notify_player(pplayer, city_tile(pcity_dest), E_BAD_COMMAND,
5011  ftc_server,
5012  _("Sorry, your %s cannot establish"
5013  " a trade route here!"),
5014  punit_link);
5015  if (dest_max > 0) {
5016  notify_player(pplayer, city_tile(pcity_dest), E_BAD_COMMAND,
5017  ftc_server,
5018  PL_(" The city of %s already has %d "
5019  "better trade route!",
5020  " The city of %s already has %d "
5021  "better trade routes!",
5022  dest_max),
5023  destcity_link, dest_max);
5024  }
5025  can_establish = false;
5026  }
5027  }
5028  }
5029 
5030  // We now know for sure whether we can establish a trade route.
5031 
5032  // Calculate and announce initial revenue.
5034  pcity_homecity, pcity_dest, nullptr, goods, can_establish);
5035 
5036  bonus_type = trade_route_settings_by_type(
5037  cities_trade_route_type(pcity_homecity, pcity_dest))
5038  ->bonus_type;
5039 
5040  conn_list_do_buffer(pplayer->connections);
5041 
5042  goods_str = goods_name_translation(goods);
5043 
5044  /* We want to keep the bonus type string as the part of the format of the
5045  * PL_() strings for supporting proper pluralization for it. */
5046  switch (bonus_type) {
5047  case TBONUS_NONE:
5048  notify_player(pplayer, city_tile(pcity_dest), E_CARAVAN_ACTION,
5049  ftc_server,
5050  // TRANS: ... Caravan ... Paris ... Stockholm ... Goods
5051  _("Your %s from %s has arrived in %s carrying %s."),
5052  punit_link, homecity_link, destcity_link, goods_str);
5053  break;
5054  case TBONUS_GOLD:
5055  notify_player(
5056  pplayer, city_tile(pcity_dest), E_CARAVAN_ACTION, ftc_server,
5057  // TRANS: ... Caravan ... Paris ... Stockholm, ... Goods...
5058  PL_("Your %s from %s has arrived in %s carrying %s,"
5059  " and revenues amount to %d in gold.",
5060  "Your %s from %s has arrived in %s carrying %s,"
5061  " and revenues amount to %d in gold.",
5062  revenue),
5063  punit_link, homecity_link, destcity_link, goods_str, revenue);
5064  break;
5065  case TBONUS_SCIENCE:
5066  notify_player(
5067  pplayer, city_tile(pcity_dest), E_CARAVAN_ACTION, ftc_server,
5068  // TRANS: ... Caravan ... Paris ... Stockholm, ... Goods...
5069  PL_("Your %s from %s has arrived in %s carrying %s,"
5070  " and revenues amount to %d in research.",
5071  "Your %s from %s has arrived in %s carrying %s,"
5072  " and revenues amount to %d in research.",
5073  revenue),
5074  punit_link, homecity_link, destcity_link, goods_str, revenue);
5075  break;
5076  case TBONUS_BOTH:
5077  notify_player(
5078  pplayer, city_tile(pcity_dest), E_CARAVAN_ACTION, ftc_server,
5079  // TRANS: ... Caravan ... Paris ... Stockholm, ... Goods...
5080  PL_("Your %s from %s has arrived in %s carrying %s,"
5081  " and revenues amount to %d in gold and research.",
5082  "Your %s from %s has arrived in %s carrying %s,"
5083  " and revenues amount to %d in gold and research.",
5084  revenue),
5085  punit_link, homecity_link, destcity_link, goods_str, revenue);
5086  break;
5087  }
5088 
5089  if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
5090  pplayer->economic.gold += revenue;
5091 
5092  send_player_info_c(pplayer, pplayer->connections);
5093  }
5094 
5095  if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
5096  // add bulbs and check for finished research
5097  update_bulbs(pplayer, revenue, true);
5098 
5099  // Inform everyone about tech changes
5100  send_research_info(research_get(pplayer), nullptr);
5101  }
5102 
5103  if (can_establish) {
5104  struct trade_route *proute_from, *proute_to;
5105  struct city_list *cities_out_of_home;
5106  struct city_list *cities_out_of_dest;
5107  struct player *partner_player;
5108 
5109  /* Announce creation of trade route (it's not actually created until
5110  * later in this function, as we have to cancel existing routes, but
5111  * it makes more sense to announce in this order) */
5112 
5113  partner_player = city_owner(pcity_dest);
5114 
5115  // Always tell the unit owner
5116  notify_player(pplayer, nullptr, E_CARAVAN_ACTION, ftc_server,
5117  _("New trade route established from %s to %s."),
5118  homecity_link, destcity_link);
5119  if (pplayer != partner_player) {
5120  notify_player(partner_player, city_tile(pcity_dest), E_CARAVAN_ACTION,
5121  ftc_server,
5122  _("The %s established a trade route between their "
5123  "city %s and %s."),
5124  nation_plural_for_player(pplayer), homecity_link,
5125  destcity_link);
5126  }
5127 
5128  cities_out_of_home = city_list_new();
5129  cities_out_of_dest = city_list_new();
5130 
5131  // Now cancel any less profitable trade route from the home city.
5132  trade_route_list_iterate(routes_out_of_home, premove)
5133  {
5134  struct trade_route *pback;
5135 
5136  city_list_append(cities_out_of_home,
5137  game_city_by_number(premove->partner));
5138 
5139  pback = remove_trade_route(pcity_homecity, premove, true, false);
5140  delete premove;
5141  delete pback;
5142  }
5144 
5145  // And the same for the dest city.
5146  trade_route_list_iterate(routes_out_of_dest, premove)
5147  {
5148  struct trade_route *pback;
5149 
5150  city_list_append(cities_out_of_dest,
5151  game_city_by_number(premove->partner));
5152 
5153  pback = remove_trade_route(pcity_dest, premove, true, false);
5154  delete premove;
5155  delete pback;
5156  }
5158 
5159  // Actually create the new trade route
5160  proute_from = new trade_route;
5161  proute_from->partner = pcity_dest->id;
5162  proute_from->goods = goods;
5163 
5164  proute_to = new trade_route;
5165  proute_to->partner = pcity_homecity->id;
5166  proute_to->goods = goods;
5167 
5168  if (goods_has_flag(goods, GF_BIDIRECTIONAL)) {
5169  proute_from->dir = RDIR_BIDIRECTIONAL;
5170  proute_to->dir = RDIR_BIDIRECTIONAL;
5171  } else {
5172  proute_from->dir = RDIR_FROM;
5173  proute_to->dir = RDIR_TO;
5174  }
5175  trade_route_list_append(pcity_homecity->routes, proute_from);
5176  trade_route_list_append(pcity_dest->routes, proute_to);
5177 
5178  // Refresh the cities.
5179  city_refresh(pcity_homecity);
5180  city_refresh(pcity_dest);
5181  city_list_iterate(cities_out_of_home, pcity) { city_refresh(pcity); }
5183  city_list_iterate(cities_out_of_dest, pcity) { city_refresh(pcity); }
5185 
5186  // Notify the owners of the cities.
5187  send_city_info(pplayer, pcity_homecity);
5188  send_city_info(partner_player, pcity_dest);
5189  city_list_iterate(cities_out_of_home, pcity)
5190  {
5191  send_city_info(city_owner(pcity), pcity);
5192  }
5194  city_list_iterate(cities_out_of_dest, pcity)
5195  {
5196  send_city_info(city_owner(pcity), pcity);
5197  }
5199 
5200  /* Notify each player about the other cities so that they know about
5201  * its size for the trade calculation. */
5202  if (pplayer != partner_player) {
5203  reality_check_city(partner_player, city_tile(pcity_homecity));
5204  send_city_info(partner_player, pcity_homecity);
5205  reality_check_city(pplayer, city_tile(pcity_dest));
5206  send_city_info(pplayer, pcity_dest);
5207  }
5208 
5209  city_list_iterate(cities_out_of_home, pcity)
5210  {
5211  if (partner_player != city_owner(pcity)) {
5212  send_city_info(partner_player, pcity);
5213  send_city_info(city_owner(pcity), pcity_dest);
5214  }
5215  if (pplayer != city_owner(pcity)) {
5216  send_city_info(pplayer, pcity);
5217  send_city_info(city_owner(pcity), pcity_homecity);
5218  }
5219  }
5221 
5222  city_list_iterate(cities_out_of_dest, pcity)
5223  {
5224  if (partner_player != city_owner(pcity)) {
5225  send_city_info(partner_player, pcity);
5226  send_city_info(city_owner(pcity), pcity_dest);
5227  }
5228  if (pplayer != city_owner(pcity)) {
5229  send_city_info(pplayer, pcity);
5230  send_city_info(city_owner(pcity), pcity_homecity);
5231  }
5232  }
5234 
5235  city_list_destroy(cities_out_of_home);
5236  city_list_destroy(cities_out_of_dest);
5237  }
5238 
5239  // May cause an incident
5240  action_consequence_success(paction, pplayer, city_owner(pcity_dest),
5241  city_tile(pcity_dest), city_link(pcity_dest));
5242 
5244 
5245  // Free data.
5246  trade_route_list_destroy(routes_out_of_home);
5247  trade_route_list_destroy(routes_out_of_dest);
5248 
5249  return true;
5250 }
5251 
5260 void handle_unit_sscs_set(struct player *pplayer, int unit_id,
5261  enum unit_ss_data_type type, int value)
5262 {
5263  struct unit *punit = player_unit_by_number(pplayer, unit_id);
5264 
5265  if (nullptr == punit) {
5266  /* Being asked to unqueue a "spent" unit because the client haven't
5267  * been told that it's gone is expected. */
5268  if (type != USSDT_UNQUEUE) {
5269  // Probably died or bribed.
5270  qDebug("handle_unit_sscs_set() invalid unit %d", unit_id);
5271  }
5272 
5273  return;
5274  }
5275 
5276  switch (type) {
5277  case USSDT_QUEUE:
5278  /* Reminds the client to ask the server about what actions the unit can
5279  * perform against the target tile. Action decision state can be set by
5280  * the server it self too. */
5281 
5282  if (index_to_tile(&(wld.map), value) == nullptr) {
5283  /* Asked to be reminded to ask what actions the unit can do to a non
5284  * existing target tile. */
5285  qDebug("unit_sscs_set() invalid target tile %d for unit %d", value,
5286  unit_id);
5287  break;
5288  }
5289 
5290  punit->action_decision_want = ACT_DEC_ACTIVE;
5291  punit->action_decision_tile = index_to_tile(&(wld.map), value);
5292 
5293  /* Let the client know that this unit needs the player to decide
5294  * what to do. */
5295  send_unit_info(player_reply_dest(pplayer), punit);
5296 
5297  break;
5298  case USSDT_UNQUEUE:
5299  /* Delete the reminder for the client to ask the server about what
5300  * actions the unit can perform against a certain target tile.
5301  * Action decision state can be set by the server it self too. */
5302 
5303  punit->action_decision_want = ACT_DEC_NOTHING;
5304  punit->action_decision_tile = nullptr;
5305 
5306  /* Let the client know that this unit no longer needs the player to
5307  * decide what to do. */
5308  send_unit_info(player_reply_dest(pplayer), punit);
5309 
5310  break;
5311  case USSDT_BATTLE_GROUP:
5312  /* Battlegroups are handled entirely by the client, so all we have to
5313  do here is save the battlegroup ID so that it'll be persistent. */
5314 
5315  punit->battlegroup = CLIP(-1, value, MAX_NUM_BATTLEGROUPS);
5316 
5317  break;
5318  }
5319 }
5320 
5324 static void unit_plans_clear(struct unit *punit)
5325 {
5326  /* Remove city spot reservations for AI settlers on city founding
5327  * mission. */
5328  adv_unit_new_task(punit, AUT_NONE, nullptr);
5329 
5330  // Get rid of old orders.
5331  free_unit_orders(punit);
5332 
5333  // Make sure that no old goto_tile remains.
5334  punit->goto_tile = nullptr;
5335 }
5336 
5340 void handle_unit_server_side_agent_set(struct player *pplayer, int unit_id,
5341  enum server_side_agent agent)
5342 {
5343  struct unit *punit = player_unit_by_number(pplayer, unit_id);
5344 
5345  if (nullptr == punit) {
5346  // Probably died or bribed.
5347  qDebug("handle_unit_server_side_agent_set() invalid unit %d", unit_id);
5348  return;
5349  }
5350 
5351  if (!server_side_agent_is_valid(agent)) {
5352  // Client error.
5353  qDebug("handle_unit_server_side_agent_set() invalid agent %d", agent);
5354  return;
5355  }
5356 
5357  // Set the state or exit
5358  if (!unit_server_side_agent_set(pplayer, punit, agent)) {
5359  return;
5360  }
5361 
5362  // Give the new agent a blank slate
5363  unit_plans_clear(punit);
5364 
5365  if (agent == SSA_AUTOEXPLORE) {
5366  if (!unit_activity_internal(punit, ACTIVITY_EXPLORE)) {
5367  // Should have been caught above
5368  fc_assert(false);
5369  punit->ssa_controller = SSA_NONE;
5370  }
5371 
5372  /* Exploring is handled here explicitly, since the player expects to
5373  * see an immediate response from setting a unit to auto-explore.
5374  * Handling it deeper in the code leads to some tricky recursive loops -
5375  * see PR#2631. */
5376  if (punit->moves_left > 0) {
5377  do_explore(punit);
5378  }
5379  }
5380 }
5381 
5386 bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit,
5387  enum server_side_agent agent)
5388 {
5389  // Check that the agent can be activated for this unit.
5390  switch (agent) {
5391  case SSA_AUTOSETTLER:
5392  if (!can_unit_do_autosettlers(punit)) {
5393  return false;
5394  }
5395  break;
5396  case SSA_AUTOEXPLORE:
5397  if (!can_unit_do_activity(punit, ACTIVITY_EXPLORE)) {
5398  return false;
5399  }
5400  break;
5401  case SSA_NONE:
5402  // Always possible.
5403  break;
5404  case SSA_COUNT:
5405  fc_assert_ret_val(agent != SSA_COUNT, false);
5406  break;
5407  }
5408 
5409  punit->ssa_controller = agent;
5410 
5411  send_unit_info(nullptr, punit);
5412 
5413  return true;
5414 }
5415 
5420 static void unit_activity_dependencies(struct unit *punit,
5421  enum unit_activity old_activity,
5422  struct extra_type *old_target)
5423 {
5424  switch (punit->activity) {
5425  case ACTIVITY_IDLE:
5426  switch (old_activity) {
5427  case ACTIVITY_PILLAGE: {
5428  if (old_target != nullptr) {
5429  unit_list_iterate_safe(unit_tile(punit)->units, punit2)
5430  {
5431  if (punit2->activity == ACTIVITY_PILLAGE) {
5432  extra_deps_iterate(&(punit2->activity_target->reqs), pdep)
5433  {
5434  if (pdep == old_target) {
5435  set_unit_activity(punit2, ACTIVITY_IDLE);
5436  send_unit_info(nullptr, punit2);
5437  break;
5438  }
5439  }
5441  }
5442  }
5444  }
5445  break;
5446  }
5447  case ACTIVITY_EXPLORE:
5448  // Restore unit's control status
5449  punit->ssa_controller = SSA_NONE;
5450  break;
5451  default:; // do nothing
5452  }
5453  break;
5454  case ACTIVITY_EXPLORE:
5455  punit->ssa_controller = SSA_AUTOEXPLORE;
5456  set_unit_activity(punit, ACTIVITY_EXPLORE);
5457  send_unit_info(nullptr, punit);
5458  break;
5459  default:
5460  // do nothing
5461  break;
5462  }
5463 }
5464 
5471 static bool do_action_activity(struct unit *punit,
5472  const struct action *paction)
5473 {
5474  enum unit_activity new_activity = action_get_activity(paction);
5475 
5476  fc_assert_ret_val(new_activity != ACTIVITY_LAST, false);
5477  fc_assert_ret_val(!activity_requires_target(new_activity), false);
5478 
5479  return unit_activity_internal(punit, new_activity);
5480 }
5481 
5485 bool unit_activity_handling(struct unit *punit,
5486  enum unit_activity new_activity)
5487 {
5488  // Must specify target for ACTIVITY_BASE
5489  fc_assert_ret_val(new_activity != ACTIVITY_BASE
5490  && new_activity != ACTIVITY_GEN_ROAD,
5491  false);
5492 
5493  if (new_activity == ACTIVITY_PILLAGE) {
5494  struct extra_type *target = nullptr;
5495 
5496  // Assume untargeted pillaging if no target specified
5497  unit_activity_handling_targeted(punit, new_activity, &target);
5498  } else if (can_unit_do_activity(punit, new_activity)) {
5499  free_unit_orders(punit);
5500  unit_activity_internal(punit, new_activity);
5501  }
5502 
5503  return true;
5504 }
5505 
5512 static bool unit_activity_internal(struct unit *punit,
5513  enum unit_activity new_activity)
5514 {
5515  if (!can_unit_do_activity(punit, new_activity)) {
5516  return false;
5517  } else {
5518  enum unit_activity old_activity = punit->activity;
5519  struct extra_type *old_target = punit->activity_target;
5520 
5521  set_unit_activity(punit, new_activity);
5522  send_unit_info(nullptr, punit);
5523  unit_activity_dependencies(punit, old_activity, old_target);
5524 
5525  return true;
5526  }
5527 }
5528 
5535 static bool do_action_activity_targeted(struct unit *punit,
5536  const struct action *paction,
5537  struct extra_type **new_target)
5538 {
5539  enum unit_activity new_activity = action_get_activity(paction);
5540 
5541  fc_assert_ret_val(new_activity != ACTIVITY_LAST, false);
5543  unit_activity_internal(punit, new_activity));
5544 
5545  return unit_activity_targeted_internal(punit, new_activity, new_target);
5546 }
5547 
5552  enum unit_activity new_activity,
5553  struct extra_type **new_target)
5554 {
5555  if (!activity_requires_target(new_activity)) {
5556  unit_activity_handling(punit, new_activity);
5557  } else if (can_unit_do_activity_targeted(punit, new_activity,
5558  *new_target)) {
5559  free_unit_orders(punit);
5560  unit_activity_targeted_internal(punit, new_activity, new_target);
5561  }
5562 
5563  return true;
5564 }
5565 
5572 static bool unit_activity_targeted_internal(struct unit *punit,
5573  enum unit_activity new_activity,
5574  struct extra_type **new_target)
5575 {
5576  if (!can_unit_do_activity_targeted(punit, new_activity, *new_target)) {
5577  return false;
5578  } else {
5579  enum unit_activity old_activity = punit->activity;
5580  struct extra_type *old_target = punit->activity_target;
5581  enum unit_activity stored_activity = new_activity;
5582 
5583  unit_assign_specific_activity_target(punit, &new_activity, new_target);
5584  if (new_activity != stored_activity
5585  && !activity_requires_target(new_activity)) {
5586  /* unit_assign_specific_activity_target() changed our target activity
5587  * (to ACTIVITY_IDLE in practice) */
5588  unit_activity_handling(punit, new_activity);
5589  } else {
5590  set_unit_activity_targeted(punit, new_activity, *new_target);
5591  send_unit_info(nullptr, punit);
5592  unit_activity_dependencies(punit, old_activity, old_target);
5593 
5594  if (new_activity == ACTIVITY_PILLAGE) {
5595  // Casus Belli for when the activity successfully begins.
5596  /* TODO: is it more logical to change Casus_Belli_Complete to
5597  * Casus_Belli_Successful_Beginning and trigger it here? */
5599  action_by_number(ACTION_PILLAGE), unit_owner(punit),
5600  tile_owner(unit_tile(punit)), unit_tile(punit),
5601  tile_link(unit_tile(punit)));
5602  }
5603  }
5604 
5605  return true;
5606  }
5607 }
5608 
5612 void handle_unit_orders(struct player *pplayer,
5613  const struct packet_unit_orders *packet)
5614 {
5615  int length = packet->length;
5616  struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
5617  struct tile *src_tile = index_to_tile(&(wld.map), packet->src_tile);
5618  struct unit_order *order_list;
5619 #ifdef FREECIV_DEBUG
5620  int i;
5621 #endif
5622 
5623  if (nullptr == punit) {
5624  // Probably died or bribed.
5625  qDebug("handle_unit_orders() invalid unit %d", packet->unit_id);
5626  return;
5627  }
5628 
5629  if (0 > length || MAX_LEN_ROUTE < length) {
5630  // Shouldn't happen
5631  qCritical("handle_unit_orders() invalid %s (%d) "
5632  "packet length %d (max %d)",
5633  unit_rule_name(punit), packet->unit_id, length, MAX_LEN_ROUTE);
5634  return;
5635  }
5636 
5637  if (src_tile != unit_tile(punit)) {
5638  /* Failed sanity check. Usually this happens if the orders were sent
5639  * in the previous turn, and the client thought the unit was in a
5640  * different position than it's actually in. The easy solution is to
5641  * discard the packet. We don't send an error message to the client
5642  * here (though maybe we should?). */
5643  qDebug("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
5644  "!= (%d, %d)",
5645  unit_rule_name(punit), punit->id, TILE_XY(src_tile),
5646  TILE_XY(unit_tile(punit)));
5647  return;
5648  }
5649 
5650  if (ACTIVITY_IDLE != punit->activity) {
5651  // New orders implicitly abandon current activity
5652  unit_activity_handling(punit, ACTIVITY_IDLE);
5653  }
5654 
5655  if (length) {
5656  order_list = create_unit_orders(length, packet->orders);
5657  if (!order_list) {
5658  qCritical("received invalid orders from %s for %s (%d).",
5659  player_name(pplayer), unit_rule_name(punit),
5660  packet->unit_id);
5661  return;
5662  }
5663  }
5664 
5665  /* This must be before old orders are freed. If this is
5666  * settlers on city founding mission, city spot reservation
5667  * from goto_tile must be freed, and free_unit_orders() loses
5668  * goto_tile information */
5669  adv_unit_new_task(punit, AUT_NONE, nullptr);
5670 
5671  free_unit_orders(punit);
5672  // If we waited on a tile, reset punit->done_moving
5673  punit->done_moving = (punit->moves_left <= 0);
5674 
5675  if (length == 0) {
5676  fc_assert(!unit_has_orders(punit));
5677  send_unit_info(nullptr, punit);
5678  return;
5679  }
5680 
5681  punit->has_orders = true;
5682  punit->orders.length = length;
5683  punit->orders.index = 0;
5684  punit->orders.repeat = packet->repeat;
5685  punit->orders.vigilant = packet->vigilant;
5686  if (length) {
5687  punit->orders.list = order_list;
5688  }
5689 
5690  if (!packet->repeat) {
5691  punit->goto_tile = index_to_tile(&(wld.map), packet->dest_tile);
5692  } else {
5693  // Make sure that no old goto_tile remains.
5694  punit->goto_tile = nullptr;
5695  }
5696 
5697 #ifdef FREECIV_DEBUG
5698  log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
5699  for (i = 0; i < length; i++) {
5700  log_debug(" %d,%s,%s,%d,%d", packet->orders[i].order,
5701  dir_get_name(packet->orders[i].dir),
5702  packet->orders[i].order == ORDER_PERFORM_ACTION
5703  ? action_id_rule_name(packet->orders[i].action)
5704  : packet->orders[i].order == ORDER_ACTIVITY
5705  ? unit_activity_name(packet->orders[i].activity)
5706  : "no action/activity required",
5707  packet->orders[i].target, packet->orders[i].sub_target);
5708  }
5709 #endif // FREECIV_DEBUG
5710 
5711  if (!is_player_phase(unit_owner(punit), game.info.phase)
5712  || execute_orders(punit, true)) {
5713  // Looks like the unit survived.
5714  send_unit_info(nullptr, punit);
5715  }
5716 }
5717 
5721 void handle_worker_task(struct player *pplayer,
5722  const struct packet_worker_task *packet)
5723 {
5724  struct city *pcity = game_city_by_number(packet->city_id);
5725  struct worker_task *ptask = nullptr;
5726  struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
5727 
5728  if (pcity == nullptr || pcity->owner != pplayer || ptile == nullptr) {
5729  return;
5730  }
5731 
5732  worker_task_list_iterate(pcity->task_reqs, ptask_old)
5733  {
5734  if (tile_index(ptask_old->ptile) == packet->tile_id) {
5735  ptask = ptask_old;
5736  }
5737  }
5739 
5740  if (ptask == nullptr) {
5741  if (packet->activity == ACTIVITY_LAST) {
5742  return;
5743  }
5744 
5745  ptask = new worker_task;
5746  worker_task_init(ptask);
5747  worker_task_list_append(pcity->task_reqs, ptask);
5748  } else {
5749  if (packet->activity == ACTIVITY_LAST) {
5750  worker_task_list_remove(pcity->task_reqs, ptask);
5751  free(ptask);
5752  ptask = nullptr;
5753  }
5754  }
5755 
5756  if (ptask != nullptr) {
5757  ptask->ptile = ptile;
5758  ptask->act = packet->activity;
5759  if (packet->tgt >= 0) {
5760  if (packet->tgt < MAX_EXTRA_TYPES) {
5761  ptask->tgt = extra_by_number(packet->tgt);
5762  } else {
5763  log_debug("Illegal worker task target %d", packet->tgt);
5764  ptask->tgt = nullptr;
5765  }
5766  } else {
5767  ptask->tgt = nullptr;
5768  }
5769  ptask->want = packet->want;
5770  }
5771 
5772  lsend_packet_worker_task(pplayer->connections, packet);
5773 }
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
bool action_distance_inside_max(const struct action *action, const int distance)
Returns TRUE iff the specified distance between actor and target is sm,aller or equal to the max rang...
Definition: actions.cpp:1303
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Returns TRUE if the specified action can't be done now but would have been legal if the unit had full...
Definition: actions.cpp:5817
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
struct extra_type * action_tgt_tile_extra(const struct unit *actor, const struct tile *target_tile, bool accept_all_actions)
Find an extra to target for an action at the specified tile.
Definition: actions.cpp:7191
struct unit * action_tgt_unit(struct unit *actor, struct tile *target_tile, bool accept_all_actions)
Find a unit to target for an action at the specified tile.
Definition: actions.cpp:7050
struct city * action_tgt_city(struct unit *actor, struct tile *target_tile, bool accept_all_actions)
Find a city to target for an action on the specified tile.
Definition: actions.cpp:6983
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_unit_vs_tgt(const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Returns the actor unit's probability of successfully performing the specified action against the acti...
Definition: actions.cpp:5163
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
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 tile * action_tgt_tile(struct unit *actor, struct tile *target, const struct extra_type *target_extra, bool accept_all_actions)
Returns the tile iff it, from the point of view of the owner of the actor unit, looks like a target t...
Definition: actions.cpp:7078
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
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
bool action_maybe_possible_actor_unit(const action_id act_id, const struct unit *actor_unit)
Returns TRUE if the wanted action (as far as the player knows) can be performed right now by the spec...
Definition: actions.cpp:5765
struct action * action_is_blocked_by(const action_id act_id, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Returns the action that blocks the specified action or nullptr if the specified action isn't blocked.
Definition: actions.cpp:2530
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
const QString action_id_name_translation(action_id act_id)
Get the action name used when displaying the action in the UI.
Definition: actions.cpp:1373
struct action * action_by_number(action_id act_id)
Return the action with the given id.
Definition: actions.cpp:1149
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
bool action_actor_utype_hard_reqs_ok(enum action_result result, const struct unit_type *actor_unittype)
Returns TRUE if the specified unit type can perform an action with the wanted result given that an ac...
Definition: actions.cpp:2776
bool action_id_exists(const action_id act_id)
Returns TRUE iff the specified action ID refers to a valid action.
Definition: actions.cpp:1138
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
const char * action_id_rule_name(action_id act_id)
Get the rule name of the action.
Definition: actions.cpp:1362
struct action_enabler_list * action_enablers_for_action(action_id action)
Get all enablers for an action in the current ruleset.
Definition: actions.cpp:1884
#define ACTPROB_NA
Definition: actions.h:734
#define action_enabler_list_iterate_end
Definition: actions.h:376
#define action_id_get_role(act_id)
Definition: actions.h:580
#define action_iterate_end
Definition: actions.h:383
#define MAX_NUM_ACTIONS
Definition: actions.h:223
#define action_id_get_actor_kind(act_id)
Definition: actions.h:519
#define ACTPROB_NOT_KNOWN
Definition: actions.h:736
#define action_has_result_safe(paction, result)
Definition: actions.h:535
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition: actions.h:374
#define action_id_distance_accepted(act_id, distance)
Definition: actions.h:565
#define ACTPROB_IMPOSSIBLE
Definition: actions.h:732
#define action_iterate(_act_)
Definition: actions.h:378
#define ACTION_ANY
Definition: actions.h:217
#define action_id_get_target_kind(act_id)
Definition: actions.h:522
#define action_id_has_complex_target(act_id)
Definition: actions.h:542
#define ACTION_NONE
Definition: actions.h:220
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.
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 ...
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.
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition: ai.h:383
QString strvec_to_and_list(const QVector< QString > &psv)
Definition: astring.cpp:43
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
Change unit's advisor task.
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
void citizens_update(struct city *pcity, struct player *plr)
bool citymindist_prevents_city_on_tile(const struct tile *ptile)
Returns TRUE iff it is illegal to found a city on the specified tile because of citymindist.
Definition: city.cpp:1401
bool city_production_gets_caravan_shields(const struct universal *tgt)
Returns TRUE iff the specified production should get shields from units that has done ACTION_HELP_WON...
Definition: city.cpp:1752
struct city * is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Is there an non_allied city on this tile?
Definition: city.cpp:1968
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Return TRUE iff the city has this building in it.
Definition: city.cpp:1189
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
bool is_capital(const struct city *pcity)
Return TRUE iff this city is its nation's capital.
Definition: city.cpp:1495
struct city * is_non_attack_city_tile(const struct tile *ptile, const struct player *pplayer)
Is there an enemy city on this tile?
Definition: city.cpp:1953
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
void city_size_add(struct city *pcity, int add)
Add a (positive or negative) value to the city size.
Definition: city.cpp:1112
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
bool city_can_grow_to(const struct city *pcity, int pop_size)
Return TRUE iff the city can grow to the given size.
Definition: city.cpp:1914
bool city_exist(int id)
Check if city with given id still exist.
Definition: city.cpp:3465
citizens city_size_get(const struct city *pcity)
Get the city size.
Definition: city.cpp:1101
const char * city_production_name_translation(const struct city *pcity)
Return the extended name of the current production.
Definition: city.cpp:672
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_list_iterate_end
Definition: city.h:484
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Remove the trade route between pc1 and pc2 (if one exists).
Definition: citytools.cpp:2791
void send_city_info(struct player *dest, struct city *pcity)
A wrapper, accessing either broadcast_city_info() (dest == nullptr), or a convenience case of send_ci...
Definition: citytools.cpp:2295
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Creates real city.
Definition: citytools.cpp:1512
int build_points_left(struct city *pcity)
Calculate the remaining build points.
Definition: citytools.cpp:575
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Destroy the improvement in the city straight-out.
Definition: citytools.cpp:2878
void city_units_upkeep(const struct city *pcity)
Recalculate the upkeep needed for all units supported by the city.
Definition: citytools.cpp:2927
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Checks, if a city name is allowed for a player.
Definition: citytools.cpp:356
void remove_city(struct city *pcity)
Remove a city from the game.
Definition: citytools.cpp:1676
void reality_check_city(struct player *pplayer, struct tile *ptile)
Removes outdated (nonexistant) cities from a player.
Definition: citytools.cpp:2704
void nullify_prechange_production(struct city *pcity)
Initialize all variables containing information about production before it was changed.
Definition: cityturn.cpp:3254
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, const char *reason)
Change the city size.
Definition: cityturn.cpp:1067
int city_incite_cost(struct player *pplayer, struct city *pcity)
Returns the cost to incite a city.
Definition: cityturn.cpp:3135
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Reduce the city size.
Definition: cityturn.cpp:815
bool city_refresh(struct city *pcity)
Updates unit upkeeps and city internal cached data.
Definition: cityturn.cpp:147
struct unit * get_defender(const struct unit *attacker, const struct tile *ptile)
Finds the best defender on the tile, given an attacker.
Definition: combat.cpp:721
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Can unit attack other at given location.
Definition: combat.cpp:83
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Check if unit can attack unit stack at tile.
Definition: combat.cpp:237
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
return the modified defense power of a unit.
Definition: combat.cpp:654
struct city * sdi_try_defend(const struct player *owner, const struct tile *ptile)
Try defending against nuclear attack; if successful, return a city which had enough luck and EFT_NUKE...
Definition: combat.cpp:430
int get_total_attack_power(const struct unit *attacker, const struct unit *defender)
Return the modified attack power of a unit.
Definition: combat.cpp:526
void get_modified_firepower(const struct unit *attacker, const struct unit *defender, int *att_fp, int *def_fp)
A unit's effective firepower depend on the situation.
Definition: combat.cpp:352
#define POWER_FACTOR
Definition: combat.h:23
@ ATT_NONNATIVE_DST
Definition: combat.h:30
@ ATT_OK
Definition: combat.h:26
@ ATT_NON_ATTACK
Definition: combat.h:27
@ ATT_UNREACHABLE
Definition: combat.h:28
@ ATT_NONNATIVE_SRC
Definition: combat.h:29
char * goods
Definition: comments.cpp:43
void conn_list_do_unbuffer(struct conn_list *dest)
Convenience functions to unbuffer a list of connections.
Definition: connection.cpp:319
void conn_list_do_buffer(struct conn_list *dest)
Convenience functions to buffer a list of connections.
Definition: connection.cpp:310
#define conn_list_iterate(connlist, pconn)
Definition: connection.h:99
#define conn_list_iterate_end
Definition: connection.h:101
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Steal part of another player's map.
Definition: diplomats.cpp:1559
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Sabotage an enemy unit.
Definition: diplomats.cpp:477
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Establish an embassy.
Definition: diplomats.cpp:418
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Try to steal a technology from an enemy city.
Definition: diplomats.cpp:805
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Sabotage enemy city's improvement or production.
Definition: diplomats.cpp:1170
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Incite a city to disaffect.
Definition: diplomats.cpp:1036
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Steal gold from another player.
Definition: diplomats.cpp:1424
bool spy_spread_plague(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Spread a plague to the target city.
Definition: diplomats.cpp:167
bool spy_nuke_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Hide a suitcase nuke in a city and detonate it.
Definition: diplomats.cpp:1680
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Investigate a city.
Definition: diplomats.cpp:271
void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat, struct city *pcity, const struct action *paction, bool disturb_player)
Get list of improvements from city (for purposes of sabotage).
Definition: diplomats.cpp:361
bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Bribe an enemy unit.
Definition: diplomats.cpp:561
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Diplomatic battle.
Definition: diplomats.cpp:725
bool spy_poison(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Poison a city's water supply.
Definition: diplomats.cpp:84
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 get_city_bonus(const struct city *pcity, enum effect_type effect_type, enum vision_layer vlayer)
Returns the effect bonus at a city.
Definition: effects.cpp:688
enum event_type event
Definition: events.cpp:68
ane_kind
Definition: explanation.h:15
@ ANEK_IS_CITY_CENTER
Definition: explanation.h:53
@ ANEK_ACTION_BLOCKS
Definition: explanation.h:89
@ ANEK_DOMESTIC
Definition: explanation.h:43
@ ANEK_LOW_MP
Definition: explanation.h:51
@ ANEK_TGT_TILE_UNKNOWN
Definition: explanation.h:85
@ ANEK_BAD_TERRAIN_TGT
Definition: explanation.h:25
@ ANEK_TRIREME_MOVE
Definition: explanation.h:65
@ ANEK_CITY_TOO_CLOSE_TGT
Definition: explanation.h:74
@ ANEK_CITY_NO_CAPACITY
Definition: explanation.h:80
@ ANEK_NATION_TGT
Definition: explanation.h:49
@ ANEK_BAD_TARGET
Definition: explanation.h:21
@ ANEK_MISSING_TARGET
Definition: explanation.h:19
@ ANEK_TGT_IS_CLAIMED
Definition: explanation.h:57
@ ANEK_FOREIGN
Definition: explanation.h:45
@ ANEK_DISEMBARK_ACT
Definition: explanation.h:68
@ ANEK_IS_TRANSPORTED
Definition: explanation.h:27
@ ANEK_IS_NOT_CITY_CENTER
Definition: explanation.h:55
@ ANEK_TGT_IS_UNCLAIMED
Definition: explanation.h:59
@ ANEK_BAD_TERRAIN_ACT
Definition: explanation.h:23
@ ANEK_SCENARIO_DISABLED
Definition: explanation.h:72
@ ANEK_ACTOR_HAS_HOME_CITY
Definition: explanation.h:35
@ ANEK_PEACE
Definition: explanation.h:41
@ ANEK_DISTANCE_NEAR
Definition: explanation.h:61
@ ANEK_UNKNOWN
Definition: explanation.h:91
@ ANEK_ACT_NOT_ENOUGH_MONEY
Definition: explanation.h:87
@ ANEK_IS_NOT_TRANSPORTING
Definition: explanation.h:33
@ ANEK_TGT_UNREACHABLE
Definition: explanation.h:70
@ ANEK_ACTOR_HAS_NO_HOME_CITY
Definition: explanation.h:37
@ ANEK_CITY_TOO_BIG
Definition: explanation.h:76
@ ANEK_NO_WAR
Definition: explanation.h:39
@ ANEK_DISTANCE_FAR
Definition: explanation.h:63
@ ANEK_ACTOR_UNIT
Definition: explanation.h:17
@ ANEK_NATION_ACT
Definition: explanation.h:47
@ ANEK_IS_NOT_TRANSPORTED
Definition: explanation.h:29
@ ANEK_IS_TRANSPORTING
Definition: explanation.h:31
@ ANEK_CITY_POP_LIMIT
Definition: explanation.h:78
@ ANEK_TGT_IS_UNIQUE_ACT_HAS
Definition: explanation.h:83
struct extra_type * extra_by_number(int id)
Return extras type of given id.
Definition: extras.cpp:154
#define extra_deps_iterate(_reqs, _dep)
Definition: extras.h:335
#define extra_deps_iterate_end
Definition: extras.h:343
#define EXTRA_NONE
Definition: extras.h:72
#define NO_TARGET
Definition: fc_types.h:271
int Impr_type_id
Definition: fc_types.h:293
#define MAX_NUM_PLAYERS
Definition: fc_types.h:28
@ AUT_NONE
Definition: fc_types.h:287
int action_id
Definition: fc_types.h:306
#define MAX_EXTRA_TYPES
Definition: fc_types.h:42
#define MAX_LEN_NAME
Definition: fc_types.h:61
int Unit_type_id
Definition: fc_types.h:299
#define IDENTITY_NUMBER_ZERO
Definition: fc_types.h:76
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
const char * unit_firepower_if_not_one(int firepower)
Get string of unit's firepower text, i.e.
const char * city_tile_link(const struct city *pcity)
Get a text link to a city tile (make a clickable link to a tile with the city name as text).
const char * tile_link(const struct tile *ptile)
Get a text link to a tile.
const char * unit_tired_attack_string(const struct unit *punit)
Get string of unit's attack would be a tired attack or not.
const char * unit_tile_link(const struct unit *punit)
Get a text link to a unit tile (make a clickable link to a tile with the unit type name as text).
const char * unit_veteran_level_string(const struct unit *punit)
Get a text of a unit's vet level.
const struct ft_color ftc_server
const char * unit_achieved_rank_string(const struct unit *punit)
Get string of when unit gets upgraded to new veteran level.
const char * city_link(const struct city *pcity)
Get a text link to a city.
const char * unit_link(const struct unit *punit)
Get a text link to an unit.
#define MAX_LEN_LINK
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
Definition: game.cpp:112
struct civ_game game
Definition: game.cpp:47
bool is_player_phase(const struct player *pplayer, int phase)
Return TRUE if it is this player's phase.
Definition: game.cpp:672
struct world wld
Definition: game.cpp:48
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
struct impr_type * improvement_by_number(const Impr_type_id id)
Returns the improvement type for the given index/ID.
const char * improvement_name_translation(const struct impr_type *pimprove)
Return the (translated) name of the given improvement.
#define B_LAST
Definition: improvement.h:33
const char * name
Definition: inputfile.cpp:118
#define fc_assert_msg(condition, message,...)
Definition: log.h:96
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define fc_assert_action(condition, action)
Definition: log.h:104
#define log_debug(message,...)
Definition: log.h:65
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition: log.h:132
enum direction8 opposite_direction(enum direction8 dir)
Return direction that is opposite to given one.
Definition: map.cpp:1589
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Are two tiles adjacent to each other.
Definition: map.cpp:878
const char * dir_get_name(enum direction8 dir)
Return the debugging name of the direction.
Definition: map.cpp:1084
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Return real distance between two tiles.
Definition: map.cpp:599
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
Definition: map.cpp:429
bool base_get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile, enum direction8 *dir)
Return TRUE and sets dir to the direction of the step if (end_x, end_y) can be reached from (start_x,...
Definition: map.cpp:1267
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition: map.h:221
void vision_clear_sight(struct vision *vision)
Clear all sight points from this vision source.
Definition: maphand.cpp:2395
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Return whether the player knows the tile.
Definition: maphand.cpp:884
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Returns whether the layer 'vlayer' of the tile 'ptile' is known and seen by the player 'pplayer'.
Definition: maphand.cpp:894
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Shows the area to the player.
Definition: maphand.cpp:852
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Players' information of tiles is tracked so that fogged area can be kept consistent even when the cli...
Definition: maphand.cpp:1341
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "exist" at this location.
Definition: movement.cpp:267
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
This tile is native to unit.
Definition: movement.cpp:279
int unit_move_rate(const struct unit *punit)
This function calculates the move rate of the unit.
Definition: movement.cpp:78
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Return whether we could find a suitable transporter for given unit at 'ptile'.
Definition: movement.cpp:743
bool unit_can_move_to_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *dst_tile, bool igzoc, bool enter_enemy_city)
Returns whether the unit can move from its current tile to the destination tile.
Definition: movement.cpp:531
const char * move_points_text(int mp, bool reduce)
Simple version of move_points_text_full() – render positive movement points as text without any prefi...
Definition: movement.cpp:856
enum unit_move_result unit_move_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool igzoc, struct unit *embark_to, bool enter_enemy_city)
Returns whether the unit can move from its current tile to the destination tile.
Definition: movement.cpp:566
#define SINGLE_MOVE
Definition: movement.h:17
unit_move_result
Definition: movement.h:25
@ MR_CANNOT_DISEMBARK
Definition: movement.h:38
@ MR_OK
Definition: movement.h:26
@ MR_TRIREME
Definition: movement.h:37
@ MR_NON_NATIVE_MOVE
Definition: movement.h:39
@ MR_PEACE
Definition: movement.h:30
@ MR_ZOC
Definition: movement.h:31
@ MR_NO_WAR
Definition: movement.h:29
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
const char * nation_adjective_translation(const struct nation_type *pnation)
Return the (translated) adjective for the given nation.
Definition: nation.cpp:126
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
struct nation_type * nation_of_unit(const struct unit *punit)
Return the nation of the player who owns the unit.
Definition: nation.cpp:438
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
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
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
#define MAX_LEN_MSG
Definition: packets.h:37
#define MAX_LEN_ROUTE
Definition: packets.h:38
@ UNIT_INFO_IDENTITY
Definition: packets.h:61
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
If the specified player owns the unit with the specified id, return pointer to the unit struct.
Definition: player.cpp:1139
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Return TRUE if players are in the same team.
Definition: player.cpp:1405
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Checks if a unit can be seen by pplayer at its current location.
Definition: player.cpp:1016
struct city * player_primary_capital(const struct player *pplayer)
Locate the player's primary capital city, (nullptr Otherwise)
Definition: player.cpp:1247
struct city * player_city_by_number(const struct player *pplayer, int city_id)
If the specified player owns the city with the specified id, return pointer to the city struct.
Definition: player.cpp:1113
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
Definition: player.cpp:1334
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players have peace, cease-fire, or armistice.
Definition: player.cpp:1388
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Return TRUE iff the player can see units in the city.
Definition: player.cpp:1045
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
struct conn_list * player_reply_dest(struct player *pplayer)
Convenience function to return "reply" destination connection list for player: pplayer->current_conn ...
Definition: plrhand.cpp:1469
struct player * civil_war(struct player *pplayer)
Capturing a nation's primary capital is a devastating blow.
Definition: plrhand.cpp:2942
bool civil_war_triggered(struct player *pplayer)
civil_war_triggered: The capture of a primary capital is not a sure fire way to throw and empire into...
Definition: plrhand.cpp:2890
void maybe_make_contact(struct tile *ptile, struct player *pplayer)
Check if we make contact with anyone.
Definition: plrhand.cpp:2282
void send_player_info_c(struct player *src, struct conn_list *dest)
Send information about player slot 'src', or all valid (i.e.
Definition: plrhand.cpp:1048
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Check if civil war is possible for a player.
Definition: plrhand.cpp:2843
int normal_player_count()
Return the number of non-barbarian players.
Definition: plrhand.cpp:3140
#define fc_rand(_size)
Definition: rand.h:16
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Make user-friendly text for the source.
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
Definition: requirements.h:306
#define requirement_fulfilled_by_terrain(_ter_, _rqs_)
Definition: requirements.h:297
#define requirement_fulfilled_by_nation(_nat_, _rqs_)
Definition: requirements.h:288
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
#define sanity_check_city(x)
Definition: sanitycheck.h:35
void script_server_signal_emit(const char *signal_name,...)
Invoke all the callback functions attached to a given signal.
#define CLIP(lower, current, upper)
Definition: shared.h:51
#define ARRAY_SIZE(x)
Definition: shared.h:79
#define MIN(x, y)
Definition: shared.h:49
#define MAX(x, y)
Definition: shared.h:48
void spaceship_lost(struct player *pplayer)
Handle spaceship loss.
Definition: spacerace.cpp:422
@ SSHIP_STARTED
Definition: spaceship.h:79
@ SSHIP_LAUNCHED
Definition: spaceship.h:80
#define DEFAULT_SPECIALIST
Definition: specialist.h:37
size_t size
Definition: specvec.h:64
struct action::@10::@11 is_unit
action_id id
Definition: actions.h:306
bool actor_consuming_always
Definition: actions.h:337
int max_distance
Definition: actions.h:320
enum action_result result
Definition: actions.h:308
union action::@10 actor
enum act_tgt_compl target_complexity
Definition: actions.h:315
int min_distance
Definition: actions.h:320
int distance
Definition: unithand.cpp:96
struct player * no_war_with
Definition: unithand.cpp:81
struct action * blocker
Definition: unithand.cpp:93
const struct unit_type * no_tgt_utype
Definition: unithand.cpp:90
struct terrain * no_act_terrain
Definition: unithand.cpp:78
struct city * capacity_city
Definition: unithand.cpp:75
struct player * peace_with
Definition: unithand.cpp:84
struct nation_type * no_act_nation
Definition: unithand.cpp:87
int gold_needed
Definition: unithand.cpp:99
enum ane_kind kind
Definition: unithand.cpp:71
Definition: city.h:291
struct worker_task_list * task_reqs
Definition: city.h:381
int id
Definition: city.h:296
int disbanded_shields
Definition: city.h:363
struct player * owner
Definition: city.h:294
int caravan_shields
Definition: city.h:362
struct trade_route_list * routes
Definition: city.h:313
struct universal production
Definition: city.h:368
citizens * nationality
Definition: city.h:310
citizens specialists[SP_MAX]
Definition: city.h:305
int shield_stock
Definition: city.h:339
struct unit_list * units_supported
Definition: city.h:377
struct civ_game::@28::@32 server
struct packet_ruleset_control control
Definition: game.h:74
struct conn_list * est_connections
Definition: game.h:88
struct packet_game_info info
Definition: game.h:80
struct packet_scenario_info scenario
Definition: game.h:78
struct player * playing
Definition: connection.h:142
bool ruledit_disabled
Definition: extras.h:77
int id
Definition: extras.h:75
enum diplstate_type type
Definition: player.h:193
enum spaceship_state state
Definition: spaceship.h:105
std::unique_ptr< vision_site > site
Definition: maphand.h:28
Definition: player.h:231
struct unit_list * units
Definition: player.h:264
struct conn_list * connections
Definition: player.h:280
struct player_economic economic
Definition: player.h:266
struct player_spaceship spaceship
Definition: player.h:268
struct nation_type * nation
Definition: player.h:242
Definition: tile.h:42
int index
Definition: tile.h:43
struct unit_list * units
Definition: tile.h:50
enum traderoute_bonus_type bonus_type
Definition: traderoutes.h:67
enum route_direction dir
Definition: traderoutes.h:75
struct goods_type * goods
Definition: traderoutes.h:76
int paratroopers_range
Definition: unittype.h:506
int city_size
Definition: unittype.h:515
int hp
Definition: unittype.h:489
Definition: unit.h:134
int length
Definition: unit.h:192
bool has_orders
Definition: unit.h:190
enum action_decision action_decision_want
Definition: unit.h:199
int battlegroup
Definition: unit.h:188
enum unit_activity activity
Definition: unit.h:154
int moves_left
Definition: unit.h:147
int id
Definition: unit.h:141
bool moved
Definition: unit.h:170
int index
Definition: unit.h:192
bool vigilant
Definition: unit.h:194
int hp
Definition: unit.h:148
enum direction8 facing
Definition: unit.h:138
struct unit::@76::@79 server
struct tile * tile
Definition: unit.h:136
struct extra_type * activity_target
Definition: unit.h:161
struct unit_order * list
Definition: unit.h:195
bool repeat
Definition: unit.h:193
QString name
Definition: unit.h:143
int homecity
Definition: unit.h:142
bool done_moving
Definition: unit.h:178
struct goods_type * carrying
Definition: unit.h:183
struct tile * goto_tile
Definition: unit.h:152
struct unit::@75 orders
struct tile * action_decision_tile
Definition: unit.h:200
const struct unit_type * utype
Definition: unit.h:135
int veteran
Definition: unit.h:149
struct player * owner
Definition: unit.h:139
enum server_side_agent ssa_controller
Definition: unit.h:169
enum unit_activity act
Definition: workertask.h:17
struct tile * ptile
Definition: workertask.h:16
struct extra_type * tgt
Definition: workertask.h:18
struct civ_map map
Definition: world_object.h:21
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
#define sz_strlcpy(dest, src)
Definition: support.h:140
#define fc__fallthrough
Definition: support.h:49
#define A_UNSET
Definition: tech.h:41
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Send research info for 'presearch' to 'dest'.
Definition: techtools.cpp:273
void update_bulbs(struct player *pplayer, int bulbs, bool check_tech)
Adds the given number of bulbs into the player's tech and (if necessary and 'check_tech' is TRUE) com...
Definition: techtools.cpp:650
const char * terrain_name_translation(const struct terrain *pterrain)
Return the (translated) name of the terrain.
Definition: terrain.cpp:175
#define terrain_has_flag(terr, flag)
Definition: terrain.h:260
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Returns TRUE iff the target_tile is seen by pow_player.
Definition: tile.cpp:416
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_terrain(_tile)
Definition: tile.h:93
#define TILE_XY(ptile)
Definition: tile.h:36
#define tile_owner(_tile)
Definition: tile.h:78
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
Return TRUE iff the two cities are capable of trade; i.e., if a caravan from one city can enter the o...
enum trade_route_type cities_trade_route_type(const struct city *pcity1, const struct city *pcity2)
What is type of the traderoute between two cities.
Definition: traderoutes.cpp:51
int max_trade_routes(const struct city *pcity)
Return current maximum number of trade routes city can have.
Definition: traderoutes.cpp:41
int trade_base_between_cities(const struct city *pc1, const struct city *pc2)
Return the trade that exists between these cities, assuming they have a trade route.
int city_num_trade_routes(const struct city *pcity)
Return number of trade route city has.
const char * goods_name_translation(struct goods_type *pgood)
Return translated name of this goods type.
bool goods_has_flag(const struct goods_type *pgood, enum goods_flag_id flag)
Check if goods has given flag.
struct goods_type * goods_from_city_to_unit(struct city *src, struct unit *punit)
Return goods type for the new traderoute between given cities.
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
Get trade route settings related to type.
int city_trade_removable(const struct city *pcity, struct trade_route_list *would_remove)
Return the minimum value of the sum of trade routes which could be replaced by a new one.
int get_caravan_enter_city_trade_bonus(const struct city *pc1, const struct city *pc2, const player *seen_as, struct goods_type *pgood, const bool establish_trade)
Returns the revenue trade bonus - you get this when establishing a trade route and also when you simp...
bool have_cities_trade_route(const struct city *pc1, const struct city *pc2)
Check if cities have an established trade route.
#define trade_route_list_iterate(trade_route_list, proute)
Definition: traderoutes.h:84
#define trade_route_list_iterate_end
Definition: traderoutes.h:86
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Returns how many shields the unit (type) is worth.
Definition: unit.cpp:204
int get_transporter_occupancy(const struct unit *ptrans)
Return how many units are in the transport.
Definition: unit.cpp:1647
void free_unit_orders(struct unit *punit)
Free and reset the unit's goto route (punit->pgr).
Definition: unit.cpp:1633
enum unit_upgrade_result unit_upgrade_test(const struct unit *punit, bool is_free)
Tests if the unit could be updated.
Definition: unit.cpp:1826
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Assign a new untargeted task to a unit.
Definition: unit.cpp:1011
struct unit * is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Is there an non-allied unit on this tile?
Definition: unit.cpp:1252
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
Definition: unit.cpp:2189
bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
Returns whether 'pcargo' is transported by 'ptrans', either directly or indirectly.
Definition: unit.cpp:2274
bool can_unit_continue_current_activity(struct unit *punit)
Check if the unit's current activity is actually legal.
Definition: unit.cpp:780
int unit_bribe_cost(struct unit *punit, struct player *briber)
Calculate how expensive it is to bribe the unit.
Definition: unit.cpp:2061
bool can_unit_do_autosettlers(const struct unit *punit)
Return whether the unit can be put in auto-settler mode.
Definition: unit.cpp:548
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Return TRUE iff this unit can do the specified generalized (ruleset defined) action enabler controlle...
Definition: unit.cpp:309
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
assign a new targeted task to a unit.
Definition: unit.cpp:1028
bool can_unit_do_activity_targeted(const struct unit *punit, enum unit_activity activity, struct extra_type *target)
Return whether the unit can do the targeted activity at its current location.
Definition: unit.cpp:842
int get_transporter_capacity(const struct unit *punit)
Return the number of units the transporter can hold (or 0).
Definition: unit.cpp:280
bool can_unit_do_activity(const struct unit *punit, enum unit_activity activity)
Return TRUE iff the unit can do the given untargeted activity at its current location.
Definition: unit.cpp:806
enum unit_airlift_result test_unit_can_airlift_to(const struct player *restriction, const struct unit *punit, const struct city *pdest_city)
Determines if punit can be airlifted to dest_city now! So punit needs to be in a city now.
Definition: unit.cpp:75
bool kills_citizen_after_attack(const struct unit *punit)
Return TRUE iff an attack from this unit would kill a citizen in a city (city walls protect against t...
Definition: unit.cpp:389
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
bool unit_has_orders(const struct unit *punit)
Return TRUE iff the unit is following client-side orders.
Definition: unit.cpp:195
struct player * unit_nationality(const struct unit *punit)
Return the nationality of the unit.
Definition: unit.cpp:1190
bool activity_requires_target(enum unit_activity activity)
Return TRUE if activity requires some sort of target to be specified.
Definition: unit.cpp:506
#define unit_tile(_pu)
Definition: unit.h:371
@ ORDER_ACTIVITY
Definition: unit.h:35
@ ORDER_PERFORM_ACTION
Definition: unit.h:41
#define unit_owner(_pu)
Definition: unit.h:370
@ UU_NO_MONEY
Definition: unit.h:51
#define MAX_NUM_BATTLEGROUPS
Definition: unit.h:186
@ AR_SRC_NO_FLIGHTS
Definition: unit.h:71
@ AR_DST_NO_FLIGHTS
Definition: unit.h:72
static bool do_unit_strike_city_production(const struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Have the unit perform a surgical strike against the current production in the target city.
Definition: unithand.cpp:4385
static struct player * need_war_player_hlp(const struct unit *actor, const action_id act, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Returns the first player that may enable the specified action if war is declared.
Definition: unithand.cpp:717
static bool rel_may_become_war(const struct player *pplayer, const struct player *oplayer)
Returns TRUE iff the player is able to change his diplomatic relationship to the other player to war.
Definition: unithand.cpp:695
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool igzoc, bool move_do_not_act)
Will try to move to/attack the tile dest_x,dest_y.
Definition: unithand.cpp:4654
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran)
Send combat info to players.
Definition: unithand.cpp:3619
static bool do_unit_change_homecity(struct unit *punit, struct city *pcity, const struct action *paction)
Change a unit's home city.
Definition: unithand.cpp:3338
static bool do_unit_upgrade(struct player *pplayer, struct unit *punit, struct city *pcity, enum action_requester ordered_by, const struct action *paction)
Upgrade the unit to a newer unit type.
Definition: unithand.cpp:232
void handle_unit_do_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id, const char *name, const action_id action_type)
Handle a request to do an action.
Definition: unithand.cpp:2705
static void see_combat_unit(struct unit *punit)
Make sure everyone who can see combat does.
Definition: unithand.cpp:3547
void handle_unit_orders(struct player *pplayer, const struct packet_unit_orders *packet)
Receives route packages.
Definition: unithand.cpp:5612
void illegal_action_msg(struct player *pplayer, const enum event_type event, struct unit *actor, const action_id stopped_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Try to explain to the player why an action is illegal.
Definition: unithand.cpp:2003
static bool do_heal_unit(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Restore some of the target unit's hit points.
Definition: unithand.cpp:503
static bool do_unit_alight(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Unload actor unit from target unit.
Definition: unithand.cpp:584
static bool do_capture_units(struct player *pplayer, struct unit *punit, struct tile *pdesttile, const struct action *paction)
Capture all the units at pdesttile using punit.
Definition: unithand.cpp:261
static bool do_expel_unit(struct player *pplayer, struct unit *actor, struct unit *target, const struct action *paction)
Expel the target unit to his owner's capital.
Definition: unithand.cpp:417
static bool do_unit_conquer_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, struct action *paction)
Have the unit conquer a city.
Definition: unithand.cpp:4539
static bool do_unit_strike_city_building(const struct player *act_player, struct unit *act_unit, struct city *tgt_city, Impr_type_id tgt_bld_id, const struct action *paction)
Have the unit perform a surgical strike against a building in the target city.
Definition: unithand.cpp:4455
static bool does_nation_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct nation_type *pnation)
Returns TRUE iff the specified nation blocks the specified action.
Definition: unithand.cpp:1002
#define ACTION_STARTED_UNIT_UNIT(action, actor, target, action_performer)
void handle_unit_change_activity(struct player *pplayer, int unit_id, enum unit_activity activity, int target_id)
Handle change in unit activity.
Definition: unithand.cpp:3519
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Handle worker task assigned to the city.
Definition: unithand.cpp:5721
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Handle request for changing activity.
Definition: unithand.cpp:5485
#define ACTION_STARTED_UNIT_TILE(action, actor, target, action_performer)
static bool do_unit_embark(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Have the actor unit embark the target unit.
Definition: unithand.cpp:662
bool unit_perform_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id_incoming, const char *name, const action_id action_type, const enum action_requester requester)
Execute a request to perform an action and let the caller know if it was performed or not.
Definition: unithand.cpp:2737
static bool illegal_action_pay_price(struct player *pplayer, bool information_revealed, struct unit *act_unit, struct action *stopped_action, struct player *tgt_player, struct tile *tgt_tile, const enum action_requester requester)
Punish a player for trying to perform an action that turned out to be illegal.
Definition: unithand.cpp:2427
static void explain_why_no_action_enabled(struct unit *punit, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Explain why punit can't perform any action at all based on its current game state.
Definition: unithand.cpp:1472
static void illegal_action(struct player *pplayer, struct unit *actor, action_id stopped_action, struct player *tgt_player, struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, bool disturb_player, const enum action_requester requester)
Tell the client that the action it requested is illegal.
Definition: unithand.cpp:2538
static bool does_terrain_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct terrain *pterrain)
Returns TRUE iff the specified terrain type blocks the specified action.
Definition: unithand.cpp:957
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Update everything that needs changing when unit activity changes from old activity to new one.
Definition: unithand.cpp:5420
void handle_unit_action_query(struct connection *pc, const int actor_id, const int target_id, const action_id action_type, bool disturb_player)
Tell the client the cost of bribing a unit, inciting a revolt, or any other parameters needed for act...
Definition: unithand.cpp:2602
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
This function assumes the bombard is legal.
Definition: unithand.cpp:3691
static bool unit_do_destroy_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Destroy the target city.
Definition: unithand.cpp:3867
static void handle_unit_change_activity_real(struct player *pplayer, int unit_id, enum unit_activity activity, struct extra_type *activity_target)
Handle change in unit activity.
Definition: unithand.cpp:3471
void handle_unit_server_side_agent_set(struct player *pplayer, int unit_id, enum server_side_agent agent)
Handle request to change controlling server side agent.
Definition: unithand.cpp:5340
void unit_do_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id, const char *name, const action_id action_type)
Handle unit action.
Definition: unithand.cpp:2718
static bool do_action_activity(struct unit *punit, const struct action *paction)
Perform an action that is an activity.
Definition: unithand.cpp:5471
static struct ane_expl * expl_act_not_enabl(struct unit *punit, const action_id act_id, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Returns an explaination why punit can't perform the specified action based on the current game state.
Definition: unithand.cpp:1046
#define ACTION_STARTED_UNIT_CITY(action, actor, target, action_performer)
void handle_unit_rename(player *pplayer, int unit_id, const char *name)
Handle request to rename a unit.
Definition: unithand.cpp:1985
static bool do_unit_unload(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Unload target unit from actor unit.
Definition: unithand.cpp:622
void unit_change_homecity_handling(struct unit *punit, struct city *new_pcity, bool rehome)
Transfer a unit from one city (and possibly player) to another.
Definition: unithand.cpp:3239
static bool unit_activity_targeted_internal(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Handle request for targeted activity.
Definition: unithand.cpp:5572
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Perform an action that is an activity.
Definition: unithand.cpp:5535
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Help build the current production in a city.
Definition: unithand.cpp:4797
void handle_unit_type_upgrade(struct player *pplayer, Unit_type_id uti)
Upgrade all units of a given type.
Definition: unithand.cpp:161
static bool city_add_unit(struct player *pplayer, struct unit *punit, struct city *pcity, const struct action *paction)
This function assumes that the target city is valid.
Definition: unithand.cpp:3370
static bool unit_activity_internal(struct unit *punit, enum unit_activity new_activity)
Handle request for changing activity.
Definition: unithand.cpp:5512
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Handle request for targeted activity.
Definition: unithand.cpp:5551
static bool unit_nuke(struct player *pplayer, struct unit *punit, struct tile *def_tile, const struct action *paction)
Do a "regular" nuclear attack.
Definition: unithand.cpp:3803
static bool can_unit_move_to_tile_with_notify(struct unit *punit, struct tile *dest_tile, bool igzoc, struct unit *embark_to, bool enter_enemy_city)
See also aiunit could_unit_move_to_tile()
Definition: unithand.cpp:4571
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Change various unit server side client state.
Definition: unithand.cpp:5260
static void send_bombardment(const unit *pattacker, const tile *ptarget)
Send bombardment info to players.
Definition: unithand.cpp:3582
static bool do_unit_board(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Have the actor unit board the target unit.
Definition: unithand.cpp:602
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Do a "regular" attack.
Definition: unithand.cpp:3950
#define ACTION_STARTED_UNIT_UNITS(action, actor, target, action_performer)
#define ACTION_STARTED_UNIT_SELF(action, actor, action_performer)
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, bool disturb_player)
Inform the client that something went wrong during a unit diplomat query.
Definition: unithand.cpp:2588
static struct player * need_war_player(const struct unit *actor, const action_id act_id, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Returns the first player that may enable the specified action if war is declared.
Definition: unithand.cpp:921
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Change controlling server side agent.
Definition: unithand.cpp:5386
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Handle request to establish traderoute.
Definition: unithand.cpp:4899
static void occupy_move(unit *punit, tile *def_tile)
Occupying move after an action.
Definition: unithand.cpp:368
static bool do_disembark(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Disembark actor unit from target unit to target tile.
Definition: unithand.cpp:638
static void unit_plans_clear(struct unit *punit)
Delete a unit's current plans.
Definition: unithand.cpp:5324
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
This function assumes a certain level of consistency checking: There is no city under punit->(x,...
Definition: unithand.cpp:3425
void handle_unit_get_actions(struct connection *pc, const int actor_unit_id, const int target_unit_id_client, const int target_tile_id, const int target_extra_id_client, const bool disturb_player)
Handle a query for what actions a unit may do.
Definition: unithand.cpp:1743
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Reduce the city's population after an attack action.
Definition: unithand.cpp:3668
enum ane_kind action_not_enabled_reason(struct unit *punit, action_id act_id, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Give the reason kind why an action isn't enabled.
Definition: unithand.cpp:1454
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_safe(unitlist, _unit)
Definition: unitlist.h:33
#define unit_list_iterate_end
Definition: unitlist.h:27
#define unit_list_iterate_safe_end
Definition: unitlist.h:54
bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed)
Moves a unit.
Definition: unittools.cpp:3878
void unit_did_action(struct unit *punit)
Mark a unit as having done something at the current time.
Definition: unittools.cpp:4879
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Go by airline, if both cities have an airport and neither has been used this turn the unit will be tr...
Definition: unittools.cpp:3018
bool execute_orders(struct unit *punit, const bool fresh)
Executes a unit's orders stored in punit->orders.
Definition: unittools.cpp:4384
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
We don't really change owner of the unit, but create completely new unit as its copy.
Definition: unittools.cpp:2302
void bounce_unit(struct unit *punit, bool verbose, bounce_reason reason, int max_distance)
Move or remove a unit due to stack conflicts.
Definition: unittools.cpp:1327
void unit_bombs_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp)
This is the basic unit versus unit classic bombardment routine.
Definition: unittools.cpp:321
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Package a unit_info packet.
Definition: unittools.cpp:2662
void unit_versus_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp)
This is the basic unit versus unit combat routine.
Definition: unittools.cpp:268
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 transform_unit(struct unit *punit, const struct unit_type *to_unit, bool is_free)
Really transforms a single unit to another type.
Definition: unittools.cpp:1676
struct unit_order * create_unit_orders(int length, const struct unit_order *orders)
Sanity-check unit order arrays from a packet and create a unit_order array from their contents if val...
Definition: unittools.cpp:5119
void notify_unit_experience(struct unit *punit)
Common notification for all experience levels.
Definition: unittools.cpp:723
void package_short_unit(struct unit *punit, struct packet_unit_short_info *packet, enum unit_info_use packet_use, int info_city_id)
Package a short_unit_info packet.
Definition: unittools.cpp:2750
void unit_forget_last_activity(struct unit *punit)
Forget the unit's last activity so that it can't be resumed.
Definition: unittools.cpp:1073
void combat_veterans(struct unit *attacker, struct unit *defender)
Maybe make either side of combat veteran.
Definition: unittools.cpp:371
void unit_refresh_vision(struct unit *punit)
Refresh the unit's vision.
Definition: unittools.cpp:4818
void do_explore(struct unit *punit)
Autoexplore with unit.
Definition: unittools.cpp:3047
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Put the unit onto the transporter, and tell everyone.
Definition: unittools.cpp:3261
bool unit_can_do_action_now(const struct unit *punit)
Used to implement the game rule controlled by the unitwaittime setting.
Definition: unittools.cpp:4844
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_goes_out_of_sight(struct player *pplayer, const unit *punit)
Handle situation where unit goes out of player sight.
Definition: unittools.cpp:2795
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Returns whether the drop was made or not.
Definition: unittools.cpp:3082
void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
Nuke all the squares in a 3x3 square around the center of the explosion pplayer is the player that ca...
Definition: unittools.cpp:2999
void unit_transport_unload_send(struct unit *punit)
Pull the unit off of the transporter, and tell everyone.
Definition: unittools.cpp:3316
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Teleport punit to city at cost specified.
Definition: unittools.cpp:1212
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
void unit_get_goods(struct unit *punit)
Set carried goods for unit.
Definition: unittools.cpp:1773
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Called when one unit kills another in combat (this function is only called in one place).
Definition: unittools.cpp:2358
bool unit_activity_needs_target_from_client(enum unit_activity activity)
Return TRUE iff activity requires some sort of target to be specified by the client.
Definition: unittools.cpp:1085
bool utype_may_act_tgt_city_tile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Return TRUE iff the given (action enabler controlled) action may be performed by a unit of the given ...
Definition: unittype.cpp:870
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
Definition: unittype.cpp:1283
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
const char * uclass_name_translation(const struct unit_class *pclass)
Return the (translated) name of the unit class.
Definition: unittype.cpp:1324
struct unit_type * utype_by_number(const Unit_type_id id)
Return a pointer for the unit type struct for the given unit type id.
Definition: unittype.cpp:103
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Returns TRUE iff successfully performing the specified action always will move the actor unit of the ...
Definition: unittype.cpp:969
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Return whether this player can upgrade this unit type (to any other unit type).
Definition: unittype.cpp:1379
Unit_type_id utype_count()
Return the number of unit types.
Definition: unittype.cpp:74
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Returns TRUE iff the unit type is unique and the player already has one.
Definition: unittype.cpp:1599
struct unit_class * unit_class_get(const struct unit *punit)
Returns unit class pointer for a unit.
Definition: unittype.cpp:2151
bool utype_can_do_act_when_ustate(const struct unit_type *punit_type, const action_id act_id, const enum ustate_prop prop, const bool is_there)
Return TRUE iff the unit type can do the specified (action enabler controlled) action while its unit ...
Definition: unittype.cpp:746
bool role_units_translations(QString &astr, int flag, bool alts)
Return a string with all the names of units with this flag.
Definition: unittype.cpp:1343
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176
const char * utype_name_translation(const struct unit_type *punittype)
Return the (translated) name of the unit type.
Definition: unittype.cpp:1256
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
Unit_type_id utype_index(const struct unit_type *punittype)
Return the unit type index.
Definition: unittype.cpp:82
const char * unit_name_translation(const struct unit *punit)
Return the (translated) name of the unit.
Definition: unittype.cpp:1265
int unit_pop_value(const struct unit *punit)
How much population is put to building this unit.
Definition: unittype.cpp:1239
bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Return TRUE iff the given (action enabler controlled) action can be performed by a unit of the given ...
Definition: unittype.cpp:784
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Return TRUE iff units of the given type can do the specified generalized (ruleset defined) action ena...
Definition: unittype.cpp:386
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Return the cost (gold) of upgrading a single unit of the specified type to the new type.
Definition: unittype.cpp:1407
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition: unittype.h:584
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_iterate_end
Definition: unittype.h:791
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Create a new vision source.
Definition: vision.cpp:27
void vision_free(struct vision *vision)
Free the vision source.
Definition: vision.cpp:44
void worker_task_init(struct worker_task *ptask)
Initialize empty worker_task.
Definition: workertask.cpp:18
#define worker_task_list_iterate(tasklist, ptask)
Definition: workertask.h:27
#define worker_task_list_iterate_end
Definition: workertask.h:29