Freeciv-3.2
Loading...
Searching...
No Matches
unithand.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22/* dependencies/lua */
23#include "lua.h" /* lua_Integer */
24
25/* utility */
26#include "astring.h"
27#include "fcintl.h"
28#include "mem.h"
29#include "rand.h"
30#include "shared.h"
31
32/* common */
33#include "actions.h"
34#include "ai.h"
35#include "city.h"
36#include "combat.h"
37#include "events.h"
38#include "featured_text.h"
39#include "game.h"
40#include "log.h"
41#include "map.h"
42#include "movement.h"
43#include "packets.h"
44#include "player.h"
45#include "research.h"
46#include "specialist.h"
47#include "traderoutes.h"
48#include "unit.h"
49#include "unitlist.h"
50
51/* common/scriptcore */
52#include "luascript_types.h"
53
54/* server */
55#include "actiontools.h"
56#include "barbarian.h"
57#include "citizenshand.h"
58#include "citytools.h"
59#include "cityturn.h"
60#include "diplomats.h"
61#include "maphand.h"
62#include "notify.h"
63#include "plrhand.h"
64#include "sanitycheck.h"
65#include "spacerace.h"
66#include "srv_main.h"
67#include "techtools.h"
68#include "unittools.h"
69
70/* server/advisors */
71#include "autoexplorer.h"
72#include "autosettlers.h"
73
74/* server/scripting */
75#include "script_server.h"
76
77#include "unithand.h"
78
79/* An explanation why an action isn't enabled. */
80struct ane_expl {
81 /* The kind of reason why an action isn't enabled. */
83
84 union {
85 /* The city without the needed capacity- */
87
88 /* The bad terrain in question. */
90
91 /* The player to advice declaring war on. */
93
94 /* The player to advice breaking peace with. */
96
97 /* The nation that can't be involved. */
99
100 /* The unit type that can't be targeted. */
101 const struct unit_type *no_tgt_utype;
102
103 /* The action that blocks the action. */
105
106 /* The required distance. */
108
109 /* The required amount of gold. */
111 };
112};
113
114static bool unit_activity_internal(struct unit *punit,
116static bool unit_activity_targeted_internal(struct unit *punit,
118 struct extra_type **new_target);
119static void illegal_action(struct player *pplayer,
120 struct unit *actor,
122 struct player *tgt_player,
123 struct tile *target_tile,
124 const struct city *target_city,
125 const struct unit *target_unit,
126 int request_kind,
127 const enum action_requester requester);
128static bool city_add_unit(struct player *pplayer, struct unit *punit,
129 struct city *pcity, const struct action *paction);
130static bool city_build(struct player *pplayer, struct unit *punit,
131 struct tile *ptile, const char *name,
132 const struct action *paction);
133static bool do_unit_establish_trade(struct player *pplayer,
134 struct unit *punit,
135 struct city *pcity_dest,
136 const struct action *paction);
137
138static bool unit_do_help_build(struct player *pplayer,
139 struct unit *punit,
140 struct city *pcity_dest,
141 const struct action *paction);
142static bool unit_do_regular_move(struct player *actor_player,
143 struct unit *actor_unit,
144 struct tile *target_tile,
145 const struct action *paction);
146static bool unit_bombard(struct unit *punit, struct tile *ptile,
147 const struct action *paction);
148static bool unit_nuke(struct player *pplayer, struct unit *punit,
149 struct tile *def_tile,
150 const struct action *paction);
151static bool unit_do_destroy_city(struct player *act_player,
152 struct unit *act_unit,
153 struct city *tgt_city,
154 const struct action *paction);
155static bool do_unit_change_homecity(struct unit *punit,
156 struct city *pcity,
157 const struct action *paction);
158static bool do_attack(struct unit *actor_unit, struct tile *target_tile,
159 const struct action *paction);
161 struct unit *act_unit,
162 struct city *tgt_city,
163 const struct action *paction);
165 struct unit *act_unit,
166 struct city *tgt_city,
168 const struct action *paction);
169static bool do_unit_conquer_city(struct player *act_player,
170 struct unit *act_unit,
171 struct city *tgt_city,
172 struct action *paction);
173static bool do_action_activity(struct unit *punit,
174 const struct action *paction);
175static bool do_action_activity_targeted(struct unit *punit,
176 const struct action *paction,
177 struct extra_type **new_target);
178static inline bool
179non_allied_not_listed_at(const struct player *pplayer,
180 const int *list, int n, const struct tile *ptile);
181
182/**********************************************************************/
186{
187 const struct unit_type *to_unittype;
191 const struct civ_map *nmap = &(wld.map);
192
193 if (NULL == from_unittype) {
194 /* Probably died or bribed. */
195 log_verbose("handle_unit_type_upgrade() invalid unit type %d", uti);
196 return;
197 }
198
200 if (!to_unittype) {
202 _("Illegal packet, can't upgrade %s (yet)."),
204 return;
205 }
206
207 /*
208 * Try to upgrade units. The order we upgrade in is arbitrary (if
209 * the player really cared they should have done it manually).
210 */
212 unit_list_iterate(pplayer->units, punit) {
214 struct city *pcity = tile_city(unit_tile(punit));
215
217 && unit_perform_action(pplayer, punit->id, pcity->id, 0, "",
220 } else if (UU_NO_MONEY == unit_upgrade_test(nmap, punit, FALSE)) {
221 break;
222 }
223 }
226
227 /* Alert the player about what happened. */
228 if (number_of_upgraded_units > 0) {
229 const int cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
231 /* FIXME: plurality of number_of_upgraded_units ignored!
232 * (Plurality of unit names is messed up anyway.) */
233 /* TRANS: "2 Musketeers upgraded to Riflemen for 100 gold."
234 * Plurality is in gold (second %d), not units. */
235 PL_("%d %s upgraded to %s for %d gold.",
236 "%d %s upgraded to %s for %d gold.",
242 send_player_info_c(pplayer, pplayer->connections);
243 } else {
245 _("No units could be upgraded."));
246 }
247}
248
249/**********************************************************************/
255static bool do_unit_upgrade(struct player *pplayer,
256 struct unit *punit, struct city *pcity,
258 const struct action *paction)
259{
260 const struct unit_type *from_unit = unit_type_get(punit);
261 const struct unit_type *to_unit = can_upgrade_unittype(pplayer, from_unit);
262 int cost = unit_upgrade_price(pplayer, from_unit, to_unit);
263
265 pplayer->economic.gold -= cost;
266 send_player_info_c(pplayer, pplayer->connections);
267
268 if (ordered_by == ACT_REQ_PLAYER) {
270 PL_("%s upgraded to %s for %d gold.",
271 "%s upgraded to %s for %d gold.", cost),
274 cost);
275 }
276
277 return TRUE;
278}
279
280/**********************************************************************/
284static inline bool
285non_allied_not_listed_at(const struct player *pplayer,
286 const int *list, int n, const struct tile *ptile)
287{
288 unit_list_iterate(ptile->units, punit) {
289 if (!pplayers_allied(pplayer, unit_owner(punit))) {
290 bool listed = FALSE;
291 int id = punit->id;
292 int i;
293
294 for (i = 0; i < n; i++) {
295 if (id == list[i]) {
296 listed = TRUE;
297 break;
298 }
299 }
300 if (!listed) {
301 return TRUE;
302 }
303 }
305 return FALSE;
306}
307
308/**********************************************************************/
314static bool do_capture_units(struct player *pplayer,
315 struct unit *punit,
316 struct tile *pdesttile,
317 const struct action *paction)
318{
319 struct city *pcity;
321 char hcity_name[MAX_LEN_NAME] = {'\0'};
322 const char *capturer_nation = nation_plural_for_player(pplayer);
324 const struct unit_type *act_utype;
325 int id, hcity;
326 int n = 0, capt[unit_list_size(pdesttile->units)];
327 bool lost_with_city = FALSE;
328 int i;
329
330 /* Sanity check: The actor still exists. */
331 fc_assert_ret_val(pplayer, FALSE);
333 id = punit->id;
334
336
337 /* Sanity check: make sure that the capture won't result in the actor
338 * ending up with more than one unit of each unique unit type. */
341 bool unique_conflict = FALSE;
342
343 /* Check what the player already has. */
346 /* The player already has a unit of this kind. */
348 }
349
351 /* The type of the units at the tile must also be checked. Two allied
352 * players can both have their unique unit at the same tile.
353 * Capturing them both would give the actor two units of a kind that
354 * is supposed to be unique. */
355
357 /* There is another unit of the same kind at this tile. */
359 } else {
360 /* Remember the unit type in case another unit of the same kind is
361 * encountered later. */
363 }
364 }
365
366 if (unique_conflict) {
367 log_debug("capture units: already got unique unit");
369 /* TRANS: You can only have one Leader. */
370 _("You can only have one %s."),
372
373 return FALSE;
374 }
375 /* Remember the units here
376 * for the mess callbacks may do in the process of transferring */
377 capt[n++] = to_capture->id;
379
380 /* N.B: unit_link() always returns the same pointer. */
382
383 pcity = tile_city(pdesttile);
386 if (hcity) {
387 /* Rarely, we'll need it... */
389 }
390
391 for (i = 0; i < n; i++) {
393 struct player *uplayer;
394 const char *victim_link;
395 const struct unit_type *utype;
396 struct tile *ptile = NULL;
397 bool really_lost = FALSE;
398
399 if (!to_capture) {
400 continue;
401 }
403 if (uplayer == pplayer) {
404 /* Somehow transferred by scripts (e.g. diplomat incited a city) */
405 continue;
406 }
407 utype = unit_type_get(to_capture);
409 uplayer->score.units_lost++;
410 if (!really_lost) {
411 /* A hack: if the captured unit is lost with a capturer's city,
412 * we link the old unit, otherwise the new one */
415 }
416 if (!to_capture) {
417 /* Lost during capturing */
419 } else {
420 /* As unit_change_owner() currently remove the old unit and
421 * replace by a new one (with a new id), we want to make link to
422 * the new unit. */
424 ptile = unit_tile(to_capture);
425 /* Notify capturer only if there is a gain */
427 /* TRANS: <unit> ... <unit> */
428 _("Your %s succeeded in capturing the %s %s."),
431 }
432
433 /* Notify loser */
436 /* TRANS: <unit> ... <Poles> */
437 _("Your %s was captured by the %s."),
439
440 /* May cause an incident */
443
444 if (really_lost) {
445 /* The city for which the unit was captured has perished! */
446 /* Nobody actually gets the unit. */
447 pplayer->score.units_lost++;
448 notify_player(pplayer, pdesttile,
450 _("%s lost along with control of %s."),
452 /* As in unit_change_owner(), don't say pplayer is killer */
454 continue;
455 }
456
457 if (to_capture
458 && (NULL != pcity /* Keep old behavior */
460 || (unit_owner(to_capture) == pplayer
461 ? non_allied_not_listed_at(pplayer, capt + (i + 1),
462 n - (i + 1), ptile)
463 : (bool)
465 /* The captured unit is in a city or with a foreign unit
466 * that its owner is not capturing. Bounce it. */
468 }
469
470 /* Check if the city we are going to home units in stays. */
471 if (hcity && i + 1 < n && !player_city_by_number(pplayer, hcity)) {
472 /* Oops, it's lost. Maybe the capturer is rehomed? */
473 if (player_unit_by_number(pplayer, id)) {
474 /* Well, it's natural to home them here now */
476 } else {
477 /* Removing the rest of the stack (except "NoHome" units) */
479 }
480 }
481 }
482
483 if (!unit_is_alive(id)) {
484 /* Callbacks took the capturer, nothing more to do */
485 return TRUE;
486 }
489
491
492 return TRUE;
493}
494
495/**********************************************************************/
498static bool occupy_move(struct tile *def_tile, struct unit *punit,
499 const struct action *paction)
500{
502 /* Hack: make sure the unit has enough moves_left for the move to succeed,
503 * and adjust moves_left to afterward (if successful). */
506 int id = punit->id;
507
509 /* Post attack occupy move. */
511 NULL, NULL, paction,
513 NULL, NULL)) {
514 if (unit_is_alive(id)) {
515 int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
516
517 /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
518 * Attack SINGLE_COST is already calculated in to old_moves. */
519 punit->moves_left = old_moves - mcost;
520 if (punit->moves_left < 0) {
521 punit->moves_left = 0;
522 }
523 } else {
524 return FALSE;
525 }
526 } else if (unit_is_alive(id)) {
528 } else {
529 return FALSE;
530 }
531 }
532
533 return TRUE;
534}
535
536/**********************************************************************/
542static bool do_wipe_units(struct unit *punit,
543 struct tile *pdesttile,
544 const struct action *paction)
545{
546 struct player *wiper = unit_owner(punit);
547 int wid = punit->id;
550 const struct unit_type *act_utype = unit_type_get(punit);
551
552 /* N.B: unit_link() always returns the same pointer. */
554
556 struct player *owner = unit_owner(to_wipe);
557 const char *victim_link = unit_link(to_wipe);
558
560
561 /* Notify players */
563 /* TRANS: <unit> ... <unit> */
564 _("Your %s wiped the %s %s."),
569 /* TRANS: <unit> ... <Poles> */
570 _("Your %s was wiped by the %s."),
572
573 /* May cause an incident */
576
578
582
584 }
585
586 return TRUE;
587}
588
589/**********************************************************************/
595static bool do_expel_unit(struct player *pplayer,
596 struct unit *actor,
597 struct unit *target,
598 const struct action *paction)
599{
601 struct player *uplayer;
602 struct tile *target_tile;
603 struct city *pcity;
604 const struct unit_type *act_utype;
605
606 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
607 * the caller? Check in the code that emits the signal. */
608 fc_assert_ret_val(target, FALSE);
609
610 uplayer = unit_owner(target);
611
612 /* A unit is supposed to have an owner. */
614
615 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
616 * the caller? Check in the code that emits the signal. */
619
620 /* Where is the actor player? */
621 fc_assert_ret_val(pplayer, FALSE);
622
623 target_tile = unit_tile(target);
624
625 /* Expel the target unit to its owner's primary capital. */
626 /* TODO: Could be also nearest secondary capital */
628
629 /* N.B: unit_link() always returns the same pointer. */
631
632 if (pcity == NULL) {
633 /* No where to send the expelled unit. */
634
635 /* The price of failing an expulsion is a single move. */
638
639 /* Notify the actor player. */
641 /* TRANS: <Poles> <Spy> */
642 _("The %s don't have a capital to expel their %s to."),
644
645 /* Nothing more could be done. */
646 return FALSE;
647 }
648
649 /* Please review the code below and above (including the strings sent to
650 * the players) before allowing expulsion to non capital cities. */
651 fc_assert(is_capital(pcity));
652
653 /* Notify everybody involved. */
655 /* TRANS: <Border Patrol> ... <Spy> */
656 _("Your %s succeeded in expelling the %s %s."),
660 /* TRANS: <unit> ... <Poles> */
661 _("Your %s was expelled by the %s."),
663
664 /* Being expelled destroys all remaining movement. */
665 if (!teleport_unit_to_city(target, pcity, 0, FALSE)) {
666 log_error("Bug in unit expulsion: unit can't teleport.");
667
668 return FALSE;
669 }
670
671 /* This may cause a diplomatic incident */
674
675 /* Mission accomplished. */
676 return TRUE;
677}
678
679/**********************************************************************/
686 struct unit *act_unit,
687 struct tile *tgt_tile,
688 const struct action *paction)
689{
690 bool success;
691 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
693
694 /* Sanity check */
697
698 unit_move(act_unit, tgt_tile, move_cost,
700 FALSE, TRUE,
703
705
706 if (success) {
707 const struct unit_type *act_utype = unit_type_get(act_unit);
708
709 /* May cause an incident */
713 }
714
715 return success;
716}
717
718/**********************************************************************/
724static bool do_heal_unit(struct player *act_player,
725 struct unit *act_unit,
726 struct unit *tgt_unit,
727 const struct action *paction)
728{
729 int healing_limit;
730 int tgt_hp_max;
731 struct player *tgt_player;
732 struct tile *tgt_tile;
735 const char *tgt_unit_owner;
736 const struct unit_type *act_utype;
737
738 /* Sanity checks: got all the needed input. */
742
744
745 /* The target unit can't have more HP than this. */
747
748 /* Sanity check: target isn't at full health and can therefore can be
749 * healed. */
751
752 /* Fetch the target unit's owner. */
755
756 /* Fetch the target unit's tile. */
759
760 /* The max amount of HP that can be added. */
762 NULL,
763 &(const struct req_context) {
764 .player = unit_owner(act_unit),
765 .city = tile_city(unit_tile(act_unit)),
767 .unit = act_unit,
768 .unittype = unit_type_get(act_unit),
769 .action = paction,
770 },
773 ) + 100)
774 * tgt_hp_max) / 100;
775
776 /* Heal the target unit. */
779
781
782 /* Every call to unit_link() overwrites the previous. Two units are being
783 * linked to. */
786
787 /* Notify everybody involved. */
788 if (act_player == tgt_player) {
789 /* TRANS: used instead of nation adjective when the nation is
790 * domestic. */
791 tgt_unit_owner = _("your");
792 } else {
794 }
795
797 /* TRANS: If foreign: Your Leader heals Finnish Warrior.
798 * If domestic: Your Leader heals your Warrior. */
799 _("Your %s heals %s %s."),
801
802 if (act_player != tgt_player) {
804 /* TRANS: Norwegian ... Leader ... Warrior */
805 _("%s %s heals your %s."),
808 }
809
810 /* This may have diplomatic consequences. */
813
814 return TRUE;
815}
816
817/**********************************************************************/
824 struct unit *act_unit,
825 struct unit *tgt_unit,
826 const struct action *paction)
827{
828 /* Unload the unit and send out info to clients. */
830
831 return TRUE;
832}
833
834/**********************************************************************/
842static bool do_unit_board(struct player *act_player,
843 struct unit *act_unit,
844 struct unit *tgt_unit,
845 const struct action *paction)
846{
849 }
850
851 /* Load the unit and send out info to clients. */
853
854 return TRUE;
855}
856
857/**********************************************************************/
865static bool do_unit_load(struct player *act_player,
866 struct unit *act_unit,
867 struct unit *tgt_unit,
868 const struct action *paction)
869{
872 }
873
874 /* Load the unit and send out info to clients. */
876
877 return TRUE;
878}
879
880/**********************************************************************/
886static bool do_unit_unload(struct player *act_player,
887 struct unit *act_unit,
888 struct unit *tgt_unit,
889 const struct action *paction)
890{
891 /* Unload the unit and send out info to clients. */
893
894 return TRUE;
895}
896
897/**********************************************************************/
903static bool do_disembark(struct player *act_player,
904 struct unit *act_unit,
905 struct tile *tgt_tile,
906 const struct action *paction)
907{
908 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
909
910 /* Sanity checks */
915
916 unit_move(act_unit, tgt_tile, move_cost,
918 FALSE, FALSE,
921
922 return TRUE;
923}
924
925/**********************************************************************/
931static bool do_unit_hut(struct player *act_player,
932 struct unit *act_unit,
933 struct tile *tgt_tile,
934 const struct action *paction)
935{
936 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
937
938 /* Sanity checks */
943
944 unit_move(act_unit, tgt_tile, move_cost,
946 FALSE, FALSE,
949
950 return TRUE;
951}
952
953/**********************************************************************/
961static bool do_unit_embark(struct player *act_player,
962 struct unit *act_unit,
963 struct unit *tgt_unit,
964 const struct action *paction)
965{
966 struct tile *tgt_tile;
967 int move_cost;
968
969 /* Sanity checks */
974
976 /* Assumed to be legal. */
978 }
979
980 /* Do it. */
982 move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
983 unit_move(act_unit, tgt_tile, move_cost,
984 tgt_unit, BV_ISSET(paction->sub_results,
986 FALSE, FALSE,
989
990 return TRUE;
991}
992
993/**********************************************************************/
998static bool do_unit_make_homeless(struct unit *punit,
999 const struct action *paction)
1000{
1002
1004}
1005
1006/**********************************************************************/
1013static bool rel_may_become_war(const struct player *pplayer,
1014 const struct player *oplayer)
1015{
1016 enum diplstate_type ds;
1017
1018 fc_assert_ret_val(pplayer, FALSE);
1020
1021 ds = player_diplstate_get(pplayer, oplayer)->type;
1022
1023 /* The player can't declare war on
1024 * someone they already are at war with. */
1025 return ds != DS_WAR
1026 /* The player can't declare war on a teammate or on themself. */
1027 && ds != DS_TEAM && pplayer != oplayer;
1028}
1029
1030/**********************************************************************/
1036static bool
1038 const struct action *paction,
1039 struct player *player1,
1040 struct player *player2,
1041 bool act_if_diplrel_kind(const struct unit_type *,
1042 const action_id,
1043 const int,
1044 const bool))
1045{
1046 if (player2 == NULL) {
1047 /* No one to declare war on */
1048 return FALSE;
1049 }
1050
1052 /* Can't declare war. */
1053 return FALSE;
1054 }
1055
1058 player2)->type,
1059 TRUE)) {
1060 /* The current diplrel isn't the problem. */
1061 return FALSE;
1062 }
1063
1065 /* War won't make this action legal. */
1066 return FALSE;
1067 }
1068
1069 return TRUE;
1070}
1071
1072/**********************************************************************/
1078static struct player *need_war_player_hlp(const struct unit *actor,
1079 const action_id act,
1080 const struct tile *target_tile,
1081 const struct city *target_city,
1082 const struct unit *target_unit)
1083{
1084 struct player *target_player = NULL;
1086 struct action *paction = action_by_number(act);
1087
1089
1090 if (action_id_get_actor_kind(act) != AAK_UNIT) {
1091 /* No unit can ever do this action so it isn't relevant. */
1092 return NULL;
1093 }
1094
1095 if (!unit_can_do_action(actor, act)) {
1096 /* The unit can't do the action no matter if there is war or not. */
1097 return NULL;
1098 }
1099
1100 /* Look for hard coded war requirements without support for looking up in
1101 * an action enabler requirement. */
1102 switch (paction->result) {
1103 case ACTRES_ATTACK:
1104 case ACTRES_WIPE_UNITS:
1106 /* Target is a unit stack but a city can block it. */
1108
1109 if (target_tile) {
1110 struct city *tcity;
1111
1112 if ((tcity = tile_city(target_tile))
1114 return city_owner(tcity);
1115 }
1116 }
1117 break;
1118
1119 case ACTRES_PARADROP:
1121 /* Target is a tile but a city can block it. */
1123 if (target_tile != NULL
1125 /* Seen tile unit savers */
1126
1127 struct city *tcity;
1128
1130 return city_owner(tcity);
1131 }
1132 }
1133 break;
1137 case ACTRES_SPY_POISON:
1146 case ACTRES_TRADE_ROUTE:
1147 case ACTRES_MARKETPLACE:
1148 case ACTRES_HELP_WONDER:
1151 case ACTRES_CAPTURE_UNITS: /* Only foreign is a hard req. */
1152 case ACTRES_FOUND_CITY:
1153 case ACTRES_JOIN_CITY:
1154 case ACTRES_STEAL_MAPS:
1155 case ACTRES_SPY_NUKE:
1156 case ACTRES_NUKE:
1157 case ACTRES_NUKE_UNITS:
1159 case ACTRES_EXPEL_UNIT:
1162 case ACTRES_HOME_CITY:
1163 case ACTRES_HOMELESS:
1165 case ACTRES_AIRLIFT:
1166 case ACTRES_HEAL_UNIT:
1169 case ACTRES_BOMBARD:
1172 case ACTRES_CULTIVATE:
1173 case ACTRES_PLANT:
1174 case ACTRES_PILLAGE:
1175 case ACTRES_CLEAN:
1176 case ACTRES_FORTIFY:
1177 case ACTRES_CONVERT:
1178 case ACTRES_ROAD:
1179 case ACTRES_BASE:
1180 case ACTRES_MINE:
1181 case ACTRES_IRRIGATE:
1188 case ACTRES_SPY_ATTACK:
1189 case ACTRES_HUT_ENTER:
1191 case ACTRES_UNIT_MOVE:
1192 case ACTRES_TELEPORT:
1195 case ACTRES_SPY_ESCAPE:
1196 case ACTRES_NONE:
1197 /* No special help. */
1198 break;
1199
1201 }
1202
1203 /* Look for war requirements from the action enablers. */
1205 case ATK_CITY:
1206 if (target_city == NULL) {
1207 /* No target city. */
1208 return NULL;
1209 }
1210
1212 break;
1213 case ATK_UNIT:
1214 if (target_unit == NULL) {
1215 /* No target unit. */
1216 return NULL;
1217 }
1219 break;
1220 case ATK_UNITS:
1221 if (target_tile == NULL) {
1222 /* No target units since no target tile. */
1223 return NULL;
1224 }
1225
1226 unit_list_iterate(target_tile->units, tunit) {
1228 target_player = unit_owner(tunit);
1229 break;
1230 }
1232 break;
1233 case ATK_TILE:
1234 if (target_tile == NULL) {
1235 /* No target tile. */
1236 return NULL;
1237 }
1239 break;
1240 case ATK_EXTRAS:
1241 if (target_tile == NULL) {
1242 /* No target tile. */
1243 return NULL;
1244 }
1246 break;
1247 case ATK_SELF:
1248 /* Can't declare war on itself. */
1249 return NULL;
1250 break;
1251 case ATK_COUNT:
1252 /* Nothing to check. */
1254 return NULL;
1255 }
1256
1257 if (target_player == NULL) {
1258 /* Declaring war won't enable the specified action. */
1259 return NULL;
1260 }
1261
1262 /* Look for DiplRelTileOther war requirements from the action enablers. */
1263 if (target_tile != NULL
1267 return tile_owner(target_tile);
1268 }
1269
1270 /* Look for DiplRel war requirements from the action enablers. */
1274 return target_player;
1275 }
1276
1277 /* No check if other, non war, diplomatic states also could make the
1278 * action legal. This is need_war_player() so war is always the answer.
1279 * If you disagree and decide to add support please check that
1280 * webperimental's "can't found a city on a tile belonging to a non enemy"
1281 * rule still is detected. */
1282
1283 return NULL;
1284}
1285
1286/**********************************************************************/
1291static struct player *need_war_player(const struct unit *actor,
1292 const action_id act_id,
1293 const struct tile *target_tile,
1294 const struct city *target_city,
1295 const struct unit *target_unit)
1296{
1297 if (act_id == ACTION_ANY) {
1298 /* Any action at all will do. */
1299 action_iterate(act) {
1300 struct player *war_player;
1301
1304 target_unit);
1305
1306 if (war_player != NULL) {
1307 /* Declaring war on this player may enable this action. */
1308 return war_player;
1309 }
1311
1312 /* No action at all may be enabled by declaring war. */
1313 return NULL;
1314 } else {
1315 /* Look for the specified action. */
1316 return need_war_player_hlp(actor, act_id,
1318 target_unit);
1319 }
1320}
1321
1322/**********************************************************************/
1326static bool
1328 const struct player *pplayer)
1329{
1330 unit_list_iterate(ptile->units, pother) {
1331 if (can_player_see_unit(pplayer, pother)
1332 && !pplayers_allied(pplayer, unit_owner(pother))) {
1333 return TRUE;
1334 }
1336
1337 return FALSE;
1338}
1339
1340/**********************************************************************/
1345static bool does_terrain_block_action(const action_id act_id,
1346 bool is_target,
1347 struct unit *actor_unit,
1348 struct terrain *pterrain)
1349{
1350 if (act_id == ACTION_ANY) {
1351 /* Any action is OK. */
1354 && !does_terrain_block_action(alt_act, is_target,
1355 actor_unit, pterrain)) {
1356 /* Only one action has to be possible. */
1357 return FALSE;
1358 }
1360
1361 /* No action enabled. */
1362 return TRUE;
1363 }
1364
1365 /* ACTION_ANY is handled above. */
1367
1369 enabler) {
1371 (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1373 &enabler->actor_reqs)) {
1374 /* This terrain kind doesn't block this action enabler. */
1375 return FALSE;
1376 }
1378
1379 return TRUE;
1380}
1381
1382/**********************************************************************/
1387static bool does_nation_block_action(const action_id act_id,
1388 bool is_target,
1389 struct unit *actor_unit,
1390 struct nation_type *pnation)
1391{
1392 if (act_id == ACTION_ANY) {
1393 /* Any action is OK. */
1396 && !does_nation_block_action(alt_act, is_target,
1397 actor_unit, pnation)) {
1398 /* Only one action has to be possible. */
1399 return FALSE;
1400 }
1402
1403 /* No action enabled. */
1404 return TRUE;
1405 }
1406
1407 /* ACTION_ANY is handled above. */
1409
1411 enabler) {
1413 (is_target ? &enabler->target_reqs
1414 : &enabler->actor_reqs))
1416 &enabler->actor_reqs)) {
1417 /* This nation doesn't block this action enabler. */
1418 return FALSE;
1419 }
1421
1422 return TRUE;
1423}
1424
1425/**********************************************************************/
1429static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1430 const action_id act_id,
1431 const struct tile *target_tile,
1432 const struct city *target_city,
1433 const struct unit *target_unit)
1434{
1435 struct player *must_war_player;
1436 const struct action *paction;
1437 struct action *blocker;
1438 struct player *act_player = unit_owner(punit);
1439 struct player *tgt_player = NULL;
1440 struct ane_expl *explnat = fc_malloc(sizeof(struct ane_expl));
1441 struct civ_map *nmap = &(wld.map);
1444 int action_custom;
1445
1446 /* Not know yet. (Initialize before the below check.) */
1447 explnat->kind = ANEK_UNKNOWN;
1448
1449 paction = action_by_number(act_id);
1450
1451 if (act_id != ACTION_ANY) {
1452 /* A specific action should have a suitable target. */
1454 case ATK_CITY:
1455 if (target_city == NULL) {
1457 }
1458 break;
1459 case ATK_UNIT:
1460 if (target_unit == NULL) {
1462 }
1463 break;
1464 case ATK_UNITS:
1465 case ATK_TILE:
1466 case ATK_EXTRAS:
1467 if (target_tile == NULL) {
1469 }
1470 break;
1471 case ATK_SELF:
1472 /* No other target. */
1473 break;
1474 case ATK_COUNT:
1476 break;
1477 }
1478 }
1479
1480 if (explnat->kind == ANEK_MISSING_TARGET) {
1481 /* No point continuing. */
1482 return explnat;
1483 }
1484
1485 if (act_id == ACTION_ANY) {
1486 /* Find the target player of some actions. */
1487 if (target_city) {
1488 /* Individual city targets have the highest priority. */
1490 } else if (target_unit) {
1491 /* Individual unit targets have the next priority. */
1493 } else if (target_tile) {
1494 /* Tile targets have the lowest priority. */
1496 }
1497 } else {
1498 /* Find the target player of this action. */
1500 case ATK_CITY:
1502 break;
1503 case ATK_UNIT:
1505 break;
1506 case ATK_TILE:
1508 break;
1509 case ATK_EXTRAS:
1510 tgt_player = target_tile->extras_owner;
1511 break;
1512 case ATK_UNITS:
1513 /* A unit stack may contain units with multiple owners. Pick the
1514 * first one. */
1515 if (target_tile
1516 && unit_list_size(target_tile->units) > 0) {
1518 }
1519 break;
1520 case ATK_SELF:
1521 /* A unit acting against itself. */
1523 break;
1524 case ATK_COUNT:
1526 break;
1527 }
1528 }
1529
1530 if (act_id == ACTION_ANY) {
1531 action_custom = 0;
1532 } else {
1533 switch (paction->result) {
1536 break;
1537 case ACTRES_AIRLIFT:
1539 break;
1540 case ACTRES_NUKE_UNITS:
1542 target_tile);
1543 break;
1544 case ACTRES_ATTACK:
1546 target_tile);
1547 break;
1548 case ACTRES_WIPE_UNITS:
1550 break;
1552 if (target_city) {
1554 punit->activity,
1557 FALSE, FALSE, NULL, TRUE);
1558 } else {
1560 }
1561 break;
1563 if (target_unit) {
1565 punit->activity,
1568 FALSE, TRUE, NULL, FALSE);
1569 } else {
1571 }
1572 break;
1574 case ACTRES_HUT_ENTER:
1577 case ACTRES_UNIT_MOVE:
1578 if (target_tile) {
1580 punit->activity,
1583 FALSE, FALSE, NULL, FALSE);
1584 } else {
1586 }
1587 break;
1588 case ACTRES_TELEPORT:
1589 if (target_tile != NULL) {
1591 punit->activity,
1594 FALSE, NULL, FALSE);
1595 } else {
1597 }
1598 break;
1599 default:
1600 action_custom = 0;
1601 break;
1602 }
1603 }
1604
1605 if (!unit_can_do_action(punit, act_id)) {
1606 explnat->kind = ANEK_ACTOR_UNIT;
1608 && tile_city(target_tile)) {
1609 explnat->kind = ANEK_BAD_TARGET;
1613 act_player)) {
1615 } else if ((!can_exist
1618 || (can_exist
1622 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1623 } else if ((!on_native
1626 || (on_native
1628 USP_NATIVE_TILE, TRUE))) {
1630 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1631 } else if (punit
1634 /* No action enabler allows acting against this terrain kind. */
1636 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1638 && target_tile
1640 TER_NO_CITIES)) {
1642 explnat->no_act_terrain = tile_terrain(target_tile);
1645 && target_tile != NULL
1647 V_MAIN)
1649 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
1652 explnat->no_act_terrain = tile_terrain(target_tile);
1653 } else if (target_tile
1656 /* No action enabler allows acting against this terrain kind. */
1658 explnat->no_act_terrain = tile_terrain(target_tile);
1659 } else if (unit_transported(punit)
1663 } else if (!unit_transported(punit)
1667 } else if (0 < get_transporter_occupancy(punit)
1671 } else if (!(0 < get_transporter_occupancy(punit))
1675 } else if ((punit->homecity > 0)
1679 } else if ((punit->homecity <= 0)
1683 } else if ((punit->homecity <= 0)
1687 } else if (act_player && tgt_player
1689 == DS_PEACE)
1691 act_id,
1692 DS_PEACE,
1693 FALSE)
1695 act_id,
1696 DS_PEACE,
1697 TRUE)) {
1698 explnat->kind = ANEK_PEACE;
1699 explnat->peace_with = tgt_player;
1701 act_id,
1704 target_unit))) {
1705 explnat->kind = ANEK_NO_WAR;
1706 explnat->no_war_with = must_war_player;
1707 } else if (action_mp_full_makes_legal(punit, act_id)) {
1708 explnat->kind = ANEK_LOW_MP;
1709 } else if (tgt_player != NULL
1712 act_id,
1714 TRUE)) {
1715 explnat->kind = ANEK_FOREIGN;
1716 } else if (tgt_player != NULL
1719 act_id,
1721 FALSE)) {
1722 explnat->kind = ANEK_DOMESTIC;
1723 } else if (punit != NULL
1725 punit, act_player->nation)) {
1726 explnat->kind = ANEK_NATION_ACT;
1727 explnat->no_act_nation = act_player->nation;
1728 } else if (tgt_player
1729 && does_nation_block_action(act_id, TRUE,
1730 punit, tgt_player->nation)) {
1731 explnat->kind = ANEK_NATION_TGT;
1732 explnat->no_act_nation = tgt_player->nation;
1733 } else if ((target_tile && tile_city(target_tile))
1735 act_id,
1737 TRUE)) {
1739 } else if ((target_tile && !tile_city(target_tile))
1741 act_id,
1743 FALSE)) {
1745 } else if ((target_tile && tile_owner(target_tile) != NULL)
1747 act_id,
1749 TRUE)) {
1751 } else if ((target_tile && tile_owner(target_tile) == NULL)
1753 act_id,
1755 FALSE)) {
1757 } else if (paction && punit
1758 && ((target_tile
1761 || (target_city
1765 || (target_unit
1768 unit_tile(target_unit)))))) {
1769 explnat->kind = ANEK_DISTANCE_FAR;
1770 explnat->distance = paction->max_distance;
1773 && punit && target_tile
1775 > unit_type_get(punit)->paratroopers_range) {
1776 explnat->kind = ANEK_DISTANCE_FAR;
1778 } else if (paction && punit
1779 && ((target_tile
1781 < paction->min_distance)
1782 || (target_city
1785 < paction->min_distance)
1786 || (target_unit
1789 < paction->min_distance))) {
1791 explnat->distance = paction->min_distance;
1792 } else if (target_city
1798 /* TODO: Check max city size requirements from action enabler target
1799 * vectors. */
1800 explnat->kind = ANEK_CITY_TOO_BIG;
1801 } else if (target_city
1807 + unit_pop_value(punit))))) {
1812 && action_custom != ATT_OK) {
1813 switch (action_custom) {
1814 case ATT_NON_ATTACK:
1815 explnat->kind = ANEK_ACTOR_UNIT;
1816 break;
1817 case ATT_UNREACHABLE:
1819 break;
1820 case ATT_NONNATIVE_SRC:
1822 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1823 break;
1824 case ATT_NONNATIVE_DST:
1826 explnat->no_act_terrain = tile_terrain(target_tile);
1827 break;
1828 case ATT_NOT_WIPABLE:
1829 explnat->kind = ANEK_NOT_WIPABLE;
1830 break;
1831 default:
1833 explnat->kind = ANEK_UNKNOWN;
1834 break;
1835 }
1839 explnat->capacity_city = tile_city(unit_tile(punit));
1843 explnat->capacity_city = game_city_by_number(target_city->id);
1849 && target_tile != NULL
1861 && action_custom != MR_OK) {
1862 switch (action_custom) {
1865 break;
1866 case MR_TRIREME:
1867 explnat->kind = ANEK_TRIREME_MOVE;
1868 break;
1871 break;
1872 default:
1874 explnat->kind = ANEK_UNKNOWN;
1875 break;
1876 }
1881 explnat->no_tgt_utype = unit_type_get(target_unit);
1882 } else if ((game.scenario.prevent_new_cities
1885 || act_id == ACTION_ANY)) {
1886 /* Please add a check for any new action forbidding scenario setting
1887 * above this comment. */
1890 && action_custom == UU_NO_MONEY) {
1891 const struct unit_type *act_utype = unit_type_get(punit);
1892
1897 } else if (paction
1898 && (blocker = action_is_blocked_by(nmap, paction, punit,
1900 target_unit))) {
1902 explnat->blocker = blocker;
1903 } else {
1904 explnat->kind = ANEK_UNKNOWN;
1905 }
1906
1907 return explnat;
1908}
1909
1910/**********************************************************************/
1914 action_id act_id,
1915 const struct tile *target_tile,
1916 const struct city *target_city,
1917 const struct unit *target_unit)
1918{
1919 struct ane_expl *explnat = expl_act_not_enabl(punit, act_id,
1922 enum ane_kind out = explnat->kind;
1923
1924 free(explnat);
1925
1926 return out;
1927}
1928
1929/**********************************************************************/
1934 const struct tile *target_tile,
1935 const struct city *target_city,
1936 const struct unit *target_unit)
1937{
1938 struct player *pplayer = unit_owner(punit);
1942 const struct civ_map *nmap = &(wld.map);
1943
1944 switch (explnat->kind) {
1945 case ANEK_ACTOR_UNIT:
1946 /* This shouldn't happen unless the client is buggy given the current
1947 * users. */
1949 "Asked to explain why a non actor can't act.");
1950
1952 _("Unit cannot do anything."));
1953 break;
1956 _("Your %s found no suitable target."),
1958 break;
1959 case ANEK_BAD_TARGET:
1960 /* This shouldn't happen at the moment. Only specific action checks
1961 * will trigger bad target checks. This is a reply to a question about
1962 * any action. */
1964
1966 _("Your %s found no suitable target."),
1968 break;
1970 {
1971 const char *types[utype_count()];
1972 int i = 0;
1973
1976 FALSE)
1978 unit_type_iterate(utype) {
1981 types[i++] = utype_name_translation(utype);
1982 }
1984 }
1985
1986 if (0 < i) {
1987 struct astring astr = ASTRING_INIT;
1988
1989 notify_player(pplayer, unit_tile(punit),
1991 /* TRANS: terrain name
1992 * "Your Diplomat cannot act from Ocean. Only
1993 * Spy or Partisan ... */
1994 _("Your %s cannot act from %s. "
1995 "Only %s can act from a non livable tile."),
1997 terrain_name_translation(explnat->no_act_terrain),
1998 astr_build_or_list(&astr, types, i));
1999
2000 astr_free(&astr);
2001 } else {
2003 /* TRANS: terrain name */
2004 _("Unit cannot act from %s."),
2005 terrain_name_translation(explnat->no_act_terrain));
2006 }
2007 }
2008 break;
2011 /* TRANS: terrain name */
2012 _("Unit cannot act against %s."),
2013 terrain_name_translation(explnat->no_act_terrain));
2014 break;
2017 _("This unit is being transported, and"
2018 " so cannot act."));
2019 break;
2022 _("This unit cannot act when it isn't being "
2023 "transported."));
2024 break;
2027 _("This unit is transporting, and"
2028 " so cannot act."));
2029 break;
2032 _("This unit cannot act when it isn't transporting."));
2033 break;
2036 _("This unit has a home city, and so cannot act."));
2037 break;
2040 _("This unit cannot act unless it has a home city."));
2041 break;
2042 case ANEK_NO_WAR:
2044 _("You must declare war on %s first. Try using "
2045 "the Nations report"
2047 " (F3)"
2048#endif /* FREECIV_WEB */
2049 "."),
2050 player_name(explnat->no_war_with));
2051 break;
2052 case ANEK_PEACE:
2054 _("You must break peace with %s first. Try using "
2055 "the Nations report to declare war"
2057 " (F3)"
2058#endif /* FREECIV_WEB */
2059 "."),
2060 player_name(explnat->peace_with));
2061 break;
2062 case ANEK_DOMESTIC:
2064 _("This unit cannot act against domestic targets."));
2065 break;
2066 case ANEK_FOREIGN:
2068 _("This unit cannot act against foreign targets."));
2069 break;
2072 /* TRANS: Riflemen */
2073 _("%s cannot act against tiles with non allied units."),
2075 break;
2076 case ANEK_NATION_ACT:
2078 /* TRANS: Swedish ... Riflemen */
2079 _("%s %s cannot act."),
2080 nation_adjective_translation(explnat->no_act_nation),
2082 break;
2083 case ANEK_NATION_TGT:
2085 /* TRANS: ... Pirate ... */
2086 _("This unit cannot act against %s targets."),
2087 nation_adjective_translation(explnat->no_act_nation));
2088 break;
2089 case ANEK_LOW_MP:
2091 _("This unit has too few moves left to act."));
2092 break;
2095 _("This unit cannot act against city centers."));
2096 break;
2099 _("This unit cannot act against non city centers."));
2100 break;
2103 _("This unit cannot act against claimed tiles."));
2104 break;
2107 _("This unit cannot act against unclaimed tiles."));
2108 break;
2109 case ANEK_DISTANCE_NEAR:
2111 _("This unit is too near its target to act."));
2112 break;
2113 case ANEK_DISTANCE_FAR:
2115 _("This unit is too far away from its target to act."));
2116 break;
2119 _("Can't perform any action this scenario permits."));
2120 break;
2123 _("Can't perform any action this close to a city."));
2124 break;
2125 case ANEK_CITY_TOO_BIG:
2127 /* TRANS: Settler ... Berlin */
2128 _("%s can't do anything to %s. It is too big."),
2131 break;
2134 /* TRANS: London ... Settlers */
2135 _("%s needs an improvement to grow, so "
2136 "%s cannot do anything to it."),
2139 break;
2142 /* TRANS: Paris ... Warriors (think: airlift) */
2143 _("%s don't have enough capacity, so "
2144 "%s cannot do anything."),
2145 city_name_get(explnat->capacity_city),
2147 break;
2150 /* TRANS: Paratroopers ... */
2151 _("%s can't do anything to an unknown target tile."),
2153 break;
2155 {
2156 char tbuf[MAX_LEN_MSG];
2157
2158 /* TRANS: Used below. Separate so treasury content too can determine
2159 * if this is plural. */
2160 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2161 "Treasury contains %d gold.",
2162 pplayer->economic.gold),
2163 pplayer->economic.gold);
2164
2166 /* TRANS: "Spy can't do anything. 154 gold may help.
2167 * Treasury contains 100 gold." */
2168 PL_("%s can't do anything. %d gold may help. %s",
2169 "%s can't do anything. %d gold may help. %s",
2170 explnat->gold_needed),
2172 explnat->gold_needed, tbuf);
2173 }
2174 break;
2175 case ANEK_TRIREME_MOVE:
2177 _("%s cannot move that far from the coast line."),
2178 unit_link(punit));
2179 break;
2180 case ANEK_DISEMBARK_ACT:
2182 _("%s cannot disembark outside of a city or a native base "
2183 "for %s."),
2187 break;
2190 _("%s can't do anything since there is an unreachable "
2191 "unit."),
2193 break;
2194 case ANEK_NOT_WIPABLE:
2196 _("%s can't do anything since there is unit with a positive "
2197 "defense value."),
2199 break;
2202 _("%s can't do anything since you already have a %s."),
2204 utype_name_translation(explnat->no_tgt_utype));
2205 break;
2206 case ANEK_ACTION_BLOCKS:
2207 /* If an action blocked another action the blocking action must be
2208 * possible. */
2210 fc__fallthrough; /* Fall through to unknown cause. */
2211 case ANEK_UNKNOWN:
2213 _("No action possible."));
2214 break;
2215 }
2216
2217 free(explnat);
2218}
2219
2220/**********************************************************************/
2229 const int actor_unit_id,
2230 const int target_unit_id_client,
2231 const int target_tile_id,
2232 const int target_extra_id_client,
2233 const int request_kind)
2234{
2235 struct player *actor_player;
2236 struct unit *actor_unit;
2237 struct tile *target_tile;
2239 struct unit *target_unit;
2240 struct city *target_city;
2241 struct extra_type *target_extra;
2243 const struct player_tile *plrtile;
2245 const struct civ_map *nmap = &(wld.map);
2246
2247 /* No potentially legal action is known yet. If none is found the player
2248 * should get an explanation. */
2250
2251 /* A target should only be sent if it is possible to act against it */
2252 int target_city_id = IDENTITY_NUMBER_ZERO;
2253 int target_unit_id = IDENTITY_NUMBER_ZERO;
2254
2255 actor_player = pc->playing;
2257 target_tile = index_to_tile(nmap, target_tile_id);
2258
2259 /* Initialize the action probabilities. */
2260 action_iterate(act) {
2263
2264 /* Check if the request is valid. */
2266 || actor_unit->owner != actor_player) {
2269 target_tile_id, target_extra_id,
2270 request_kind,
2272 return;
2273 }
2274
2275 /* Select the targets. */
2276
2278 /* Find a new target unit. */
2280 } else {
2281 /* Prepare the client selected target unit. */
2283 }
2284
2285 /* Find the target city. */
2287
2288 /* The specified target unit must be located at the target tile. */
2292 _("Target not at target tile."));
2295 target_tile_id, target_extra_id,
2296 request_kind,
2298 return;
2299 }
2300
2302 /* See if a target extra can be found. */
2304 } else {
2305 /* Use the client selected target extra. */
2307 }
2308
2309 /* The player may have outdated information about the target tile.
2310 * Limiting the player knowledge look up to the target tile is OK since
2311 * all targets must be located at it. */
2313
2314 /* Distance between actor and target tile. */
2316 target_tile);
2317
2318 /* Find out what can be done to the targets. */
2319
2320 /* Set the probability for the actions. */
2321 action_iterate(act) {
2322 if (action_id_get_actor_kind(act) != AAK_UNIT) {
2323 /* Not relevant. */
2324 continue;
2325 }
2326
2327 switch (action_id_get_target_kind(act)) {
2328 case ATK_CITY:
2329 if (plrtile && plrtile->site) {
2330 /* Only a known city may be targeted. */
2331 if (target_city) {
2332 /* Calculate the probabilities. */
2334 target_city);
2339 /* The target city is non existing. The player isn't aware of this
2340 * fact because they can't see the tile it was located on. The
2341 * actor unit it self doesn't contradict the requirements to
2342 * perform the action. The (no longer existing) target city was
2343 * known to be close enough. */
2345 } else {
2346 /* The actor unit is known to be unable to act or the target city
2347 * is known to be too far away. */
2349 }
2350 } else {
2351 /* No target to act against. */
2353 }
2354 break;
2355 case ATK_UNIT:
2356 if (target_unit) {
2357 /* Calculate the probabilities. */
2359 target_unit);
2360 } else {
2361 /* No target to act against. */
2363 }
2364 break;
2365 case ATK_UNITS:
2366 if (target_tile) {
2367 /* Calculate the probabilities. */
2369 target_tile);
2370 } else {
2371 /* No target to act against. */
2373 }
2374 break;
2375 case ATK_TILE:
2376 if (target_tile) {
2377 /* Calculate the probabilities. */
2380 } else {
2381 /* No target to act against. */
2383 }
2384 break;
2385 case ATK_EXTRAS:
2386 if (target_tile) {
2387 /* Calculate the probabilities. */
2390 target_extra);
2391 } else {
2392 /* No target to act against. */
2394 }
2395 break;
2396 case ATK_SELF:
2397 if (actor_target_distance == 0) {
2398 /* Calculate the probabilities. */
2400 } else {
2401 /* Don't bother with self targeted actions unless the actor is
2402 * asking about what can be done to its own tile. */
2404 }
2405 break;
2406 case ATK_COUNT:
2409 break;
2410 }
2412
2413 /* Analyze the probabilities. Decide what targets to send and if an
2414 * explanation is needed. */
2415 action_iterate(act) {
2417 /* An action can be done. No need to explain why no action can be
2418 * done. */
2420
2421 switch (action_id_get_target_kind(act)) {
2422 case ATK_CITY:
2423 /* The city should be sent as a target since it is possible to act
2424 * against it. */
2425
2426 /* All city targeted actions requires that the player is aware of
2427 * the target city. It is therefore in the player's map. */
2428 fc_assert_action(plrtile, continue);
2429 fc_assert_action(plrtile->site, continue);
2430
2431 target_city_id = plrtile->site->identity;
2432 break;
2433 case ATK_UNIT:
2434 /* The unit should be sent as a target since it is possible to act
2435 * against it. */
2437 target_unit_id = target_unit->id;
2438 break;
2439 case ATK_TILE:
2440 case ATK_EXTRAS:
2441 /* The target tile isn't selected here so it hasn't changed. */
2443
2445 /* The target extra may have been set here. */
2447 }
2448 break;
2449 case ATK_UNITS:
2450 /* The target tile isn't selected here so it hasn't changed. */
2452 break;
2453 case ATK_SELF:
2454 /* The target unit is the actor unit. It is already sent. */
2456 break;
2457 case ATK_COUNT:
2459 "Invalid action target kind.");
2460 break;
2461 }
2462
2463 if (target_city_id != IDENTITY_NUMBER_ZERO
2464 && target_unit_id != IDENTITY_NUMBER_ZERO) {
2465 /* No need to find out more. */
2466 break;
2467 }
2468 }
2470
2471 /* Send possible actions and targets. */
2473 actor_unit_id, target_unit_id, target_city_id,
2474 target_tile_id, target_extra_id,
2475 request_kind,
2477
2478 if (request_kind == REQEST_PLAYER_INITIATED && !at_least_one_action) {
2479 /* The user should get an explanation why no action is possible. */
2482 }
2483}
2484
2485/**********************************************************************/
2492void illegal_action_msg(struct player *pplayer,
2493 const enum event_type event,
2494 struct unit *actor,
2496 const struct tile *target_tile,
2497 const struct city *target_city,
2498 const struct unit *target_unit)
2499{
2500 struct ane_expl *explnat;
2501 const struct civ_map *nmap = &(wld.map);
2502
2503 /* Explain why the action was illegal. */
2506 switch (explnat->kind) {
2507 case ANEK_ACTOR_UNIT:
2508 {
2509 struct astring astr = ASTRING_INIT;
2510
2513 TRUE)) {
2514 notify_player(pplayer, unit_tile(actor),
2516 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
2517 _("Only %s can do %s."),
2518 astr_str(&astr),
2520 astr_free(&astr);
2521 } else {
2522 notify_player(pplayer, unit_tile(actor),
2524 /* TRANS: Spy can't do Capture Units. */
2525 _("%s can't do %s."),
2528 }
2529 }
2530 break;
2533 /* TRANS: "Your Spy found ... suitable for
2534 * Bribe Enemy Unit." */
2535 _("Your %s found no target suitable for %s."),
2538 break;
2539 case ANEK_BAD_TARGET:
2541 /* TRANS: "Having your Spy do Bribe Enemy Unit to
2542 * this target ..." */
2543 _("Having your %s do %s to this target is redundant."),
2546 break;
2548 {
2549 const char *types[utype_count()];
2550 int i = 0;
2551
2554 FALSE)
2556 unit_type_iterate(utype) {
2559 types[i++] = utype_name_translation(utype);
2560 }
2562 }
2563
2564 if (0 < i) {
2565 struct astring astr = ASTRING_INIT;
2566
2567 notify_player(pplayer, unit_tile(actor),
2569 /* TRANS: action name.
2570 * "Your Spy can't do Steal Gold from Ocean.
2571 * Only Explorer or Partisan can do Steal Gold ..." */
2572 _("Your %s can't do %s from %s. "
2573 "Only %s can do %s from a non livable tile."),
2576 terrain_name_translation(explnat->no_act_terrain),
2577 astr_build_or_list(&astr, types, i),
2579
2580 astr_free(&astr);
2581 } else {
2582 notify_player(pplayer, unit_tile(actor),
2584 /* TRANS: action name.
2585 * "Your Spy can't do Steal Gold from Ocean." */
2586 _("Your %s can't do %s from %s."),
2589 terrain_name_translation(explnat->no_act_terrain));
2590 }
2591 }
2592 break;
2594 notify_player(pplayer, unit_tile(actor),
2596 /* TRANS: action name.
2597 * "Your Spy can't do Industrial Sabotage to Mountains." */
2598 _("Your %s can't do %s to %s."),
2601 terrain_name_translation(explnat->no_act_terrain));
2602 break;
2604 notify_player(pplayer, unit_tile(actor),
2606 /* TRANS: action name.
2607 * "Your Spy can't do Industrial Sabotage while ..." */
2608 _("Your %s can't do %s while being transported."),
2611 break;
2613 notify_player(pplayer, unit_tile(actor),
2615 /* TRANS: action name.
2616 * "Your Spy can't do Industrial Sabotage while ..." */
2617 _("Your %s can't do %s while not being transported."),
2620 break;
2622 notify_player(pplayer, unit_tile(actor),
2624 /* TRANS: action name.
2625 * "Your Spy can't do Industrial Sabotage while ..." */
2626 _("Your %s can't do %s while transporting."),
2629 break;
2631 notify_player(pplayer, unit_tile(actor),
2633 /* TRANS: action name.
2634 * "Your Spy can't do Industrial Sabotage while ..." */
2635 _("Your %s can't do %s while not transporting."),
2638 break;
2640 notify_player(pplayer, unit_tile(actor),
2642 /* TRANS: action name.
2643 * "Your Spy can't do Industrial Sabotage because ..." */
2644 _("Your %s can't do %s because it has a home city."),
2647 break;
2649 notify_player(pplayer, unit_tile(actor),
2651 /* TRANS: action name.
2652 * "Your Spy can't do Industrial Sabotage because ..." */
2653 _("Your %s can't do %s because it is homeless."),
2656 break;
2657 case ANEK_NO_WAR:
2658 notify_player(pplayer, unit_tile(actor),
2660 /* TRANS: action name.
2661 * "Your Spy can't do Industrial Sabotage while you
2662 * aren't at war with Prester John." */
2663 _("Your %s can't do %s while you"
2664 " aren't at war with %s."),
2667 player_name(explnat->no_war_with));
2668 break;
2669 case ANEK_PEACE:
2670 notify_player(pplayer, unit_tile(actor),
2672 /* TRANS: action name.
2673 * "Your Spy can't do Industrial Sabotage while you
2674 * are at peace with Prester John. Try using the
2675 * Nations report (F3)." */
2676 _("Your %s can't do %s while you "
2677 "are at peace with %s. Try using "
2678 "the Nations report to declare war"
2680 " (F3)"
2681#endif /* FREECIV_WEB */
2682 "."),
2685 player_name(explnat->peace_with));
2686 break;
2687 case ANEK_DOMESTIC:
2688 notify_player(pplayer, unit_tile(actor),
2690 /* TRANS: action name.
2691 * "Your Riflemen can't do Expel Unit to domestic
2692 * unit stacks." */
2693 _("Your %s can't do %s to domestic %s."),
2698 break;
2699 case ANEK_FOREIGN:
2700 notify_player(pplayer, unit_tile(actor),
2702 /* TRANS: action name.
2703 * "Your Leader can't do Use Court Physician to foreign
2704 * unit stacks." */
2705 _("Your %s can't do %s to foreign %s."),
2710 break;
2712 notify_player(pplayer, unit_tile(actor),
2714 /* TRANS: Paratroopers ... Drop Paratrooper */
2715 _("Your %s can't do %s to tiles with non allied units."),
2718 break;
2719 case ANEK_NATION_ACT:
2720 notify_player(pplayer, unit_tile(actor),
2722 /* TRANS: action name.
2723 * "Swedish Riflemen can't do Expel Unit." */
2724 _("%s %s can't do %s."),
2725 nation_adjective_translation(explnat->no_act_nation),
2728 break;
2729 case ANEK_NATION_TGT:
2730 notify_player(pplayer, unit_tile(actor),
2732 /* TRANS: action name.
2733 * "Riflemen... Expel Unit... Pirate Migrants." */
2734 _("Your %s can't do %s to %s %s."),
2737 nation_adjective_translation(explnat->no_act_nation),
2740 break;
2741 case ANEK_LOW_MP:
2742 notify_player(pplayer, unit_tile(actor),
2744 /* TRANS: action name.
2745 * "Your Spy has ... to do Bribe Enemy Unit." */
2746 _("Your %s has too few moves left to do %s."),
2749 break;
2751 notify_player(pplayer, unit_tile(actor),
2753 /* TRANS: action name.
2754 * "Your Spy can't do Bribe Enemy Unit to city centers." */
2755 _("Your %s can't do %s to city centers."),
2758 break;
2760 notify_player(pplayer, unit_tile(actor),
2762 /* TRANS: action name.
2763 * "Your Spy can only do Investigate City to
2764 * city centers." */
2765 _("Your %s can only do %s to city centers."),
2768 break;
2770 notify_player(pplayer, unit_tile(actor),
2772 /* TRANS: action name.
2773 * "Your Settlers can't do Build City to claimed tiles." */
2774 _("Your %s can't do %s to claimed tiles."),
2777 break;
2779 notify_player(pplayer, unit_tile(actor),
2781 /* TRANS: action name.
2782 * "Your Spy can't do Bribe Enemy Unit to
2783 * unclaimed tiles." */
2784 _("Your %s can't do %s to unclaimed tiles."),
2787 break;
2788 case ANEK_DISTANCE_NEAR:
2789 notify_player(pplayer, unit_tile(actor),
2791 /* TRANS: action name.
2792 * "Your Spy must be at least 2 tiles away to do
2793 * Incite a Revolt and Escape." */
2794 PL_("Your %s must be at least %d tile away to do %s.",
2795 "Your %s must be at least %d tiles away to do %s.",
2796 explnat->distance),
2798 explnat->distance,
2800 break;
2801 case ANEK_DISTANCE_FAR:
2802 notify_player(pplayer, unit_tile(actor),
2804 /* TRANS: action name.
2805 * "Your Diplomat can't be more than 1 tile away to do
2806 * Establish Embassy." */
2807 PL_("Your %s can't be more than %d tile away to do %s.",
2808 "Your %s can't be more than %d tiles away to do %s.",
2809 explnat->distance),
2811 explnat->distance,
2813 break;
2815 notify_player(pplayer, unit_tile(actor),
2817 /* TRANS: Can't do Build City in this scenario. */
2818 _("Can't do %s in this scenario."),
2820 break;
2822 notify_player(pplayer, unit_tile(actor),
2824 /* TRANS: Can't do Build City this close to a city. */
2825 _("Can't do %s this close to a city."),
2827 break;
2828 case ANEK_CITY_TOO_BIG:
2829 notify_player(pplayer, unit_tile(actor),
2831 /* TRANS: Settlers ... Join City ... London */
2832 _("%s can't do %s to %s. It is too big."),
2836 break;
2838 notify_player(pplayer, unit_tile(actor),
2840 /* TRANS: London ... Settlers ... Join City */
2841 _("%s needs an improvement to grow, so "
2842 "%s cannot do %s."),
2846 break;
2848 notify_player(pplayer, unit_tile(actor),
2850 /* TRANS: Paris ... Airlift to City ... Warriors */
2851 _("%s has no capacity to %s %s."),
2852 city_name_get(explnat->capacity_city),
2855 break;
2857 notify_player(pplayer, unit_tile(actor),
2859 /* TRANS: Paratroopers ... Drop Paratrooper */
2860 _("%s can't do %s to an unknown tile."),
2863 break;
2865 {
2866 char tbuf[MAX_LEN_MSG];
2867
2868 /* TRANS: Used below. Separate so treasury content too can determine
2869 * if this is plural. */
2870 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2871 "Treasury contains %d gold.",
2872 pplayer->economic.gold),
2873 pplayer->economic.gold);
2874
2875 notify_player(pplayer, unit_tile(actor),
2877 /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2878 * Treasury contains 100 gold." */
2879 PL_("%s can't do %s for %d gold. %s",
2880 "%s can't do %s for %d gold. %s",
2881 explnat->gold_needed),
2884 explnat->gold_needed, tbuf);
2885 }
2886 break;
2887 case ANEK_TRIREME_MOVE:
2889 /* TRANS: "Trireme cannot move ..." */
2890 _("%s cannot move that far from the coast line."),
2891 unit_link(actor));
2892 break;
2893 case ANEK_DISEMBARK_ACT:
2895 /* TRANS: "Riflemen cannot disembark ... native base
2896 * for Helicopter." */
2897 _("%s cannot disembark outside of a city or a native base "
2898 "for %s."),
2902 break;
2904 notify_player(pplayer, target_tile,
2906 /* TRANS: "Your Spy can't do Bribe Enemy Unit there ..." */
2907 _("Your %s can't do %s there since there's an "
2908 "unreachable unit."),
2911 break;
2912 case ANEK_NOT_WIPABLE:
2913 notify_player(pplayer, target_tile,
2915 /* TRANS: "Your Legion can't do Wipe Units there ..." */
2916 _("Your %s can't do %s there since there's an "
2917 "unit with positive defense value."),
2920 break;
2923 /* TRANS: "You already have a Leader." */
2924 _("You already have a %s."),
2925 utype_name_translation(explnat->no_tgt_utype));
2926 break;
2927 case ANEK_ACTION_BLOCKS:
2928 {
2930
2931 notify_player(pplayer, unit_tile(actor),
2933 /* TRANS: Freight ... Disband Unit Recover ... Help Wonder ... */
2934 _("Your %s can't do %s when %s is legal."),
2937 action_id_name_translation(explnat->blocker->id));
2939 }
2940 break;
2941 case ANEK_UNKNOWN:
2942 notify_player(pplayer, unit_tile(actor),
2944 /* TRANS: action name.
2945 * "Your Spy was unable to do Bribe Enemy Unit." */
2946 _("Your %s was unable to do %s."),
2949 break;
2950 }
2951
2952 free(explnat);
2953}
2954
2955/**********************************************************************/
2968static bool illegal_action_pay_price(struct player *pplayer,
2970 struct unit *act_unit,
2971 struct action *stopped_action,
2972 struct player *tgt_player,
2973 struct tile *tgt_tile,
2974 const enum action_requester requester)
2975{
2976 int punishment_mp;
2977 int punishment_hp;
2978
2979 const struct req_context actor_ctxt = {
2981 .unit = act_unit,
2982 .unittype = unit_type_get(act_unit),
2983 .action = stopped_action,
2984 };
2985
2986 /* Don't punish the player for something the game did. Don't tell the
2987 * player that the rules required the game to try to do something
2988 * illegal. */
2991 FALSE,
2992 "The player wasn't responsible for this.");
2993
2994 if (!information_revealed) {
2995 /* The player already had enough information to determine that this
2996 * action is illegal. Don't punish a client error or an accident. */
2997 return FALSE;
2998 }
2999
3000 /* The mistake may have a cost. */
3001
3002 /* HP cost */
3005
3006 /* Stay in range */
3008
3009 /* Punish the unit's hit points. */
3010 act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
3011
3012 if (punishment_hp != 0) {
3015 /* The consolation prize is some information about the potentially
3016 * distant target tile and maybe some contacts. */
3017 map_show_circle(pplayer, tgt_tile,
3018 unit_type_get(act_unit)->vision_radius_sq);
3019 maybe_make_contact(tgt_tile, pplayer);
3020 }
3021
3022 if (act_unit->hp > 0) {
3023 /* The actor unit survived */
3024
3025 /* The player probably wants to be disturbed if their unit was punished
3026 * with the loss of hit points. */
3029 /* TRANS: Spy ... 5 ... Drop Paratrooper */
3030 _("Your %s lost %d hit points while attempting to"
3031 " do %s."),
3035 } else {
3036 /* The unit didn't survive */
3037
3038 /* The player probably wants to be disturbed if their unit was punished
3039 * with death. */
3042 /* TRANS: Spy ... Drop Paratrooper */
3043 _("Your %s was killed while attempting to do %s."),
3046
3048 act_unit = NULL;
3049
3050 return TRUE;
3051 }
3052 }
3053
3054 /* MP cost */
3057
3058 /* Stay in range */
3060
3061 /* Punish the unit's move fragments. */
3062 act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
3064
3065 if (punishment_mp != 0) {
3066 /* The player probably wants to be disturbed if their unit was punished
3067 * with the loss of movement points. */
3070 /* TRANS: Spy ... movement point text that may include
3071 * fractions. */
3072 _("Your %s lost %s MP for attempting an illegal action."),
3075 }
3076
3077 return punishment_mp != 0 || punishment_hp != 0;
3078}
3079
3080/**********************************************************************/
3085static void illegal_action(struct player *pplayer,
3086 struct unit *actor,
3088 struct player *tgt_player,
3089 struct tile *target_tile,
3090 const struct city *target_city,
3091 const struct unit *target_unit,
3092 int request_kind,
3093 const enum action_requester requester)
3094{
3096 bool was_punished;
3097 const struct civ_map *nmap = &(wld.map);
3098
3100
3101 /* Why didn't the game check before trying something illegal? Did a good
3102 * reason to not call is_action_enabled_unit_on...() appear? The game is
3103 * omniscient... */
3105
3106
3108 nmap,
3110 actor,
3112 target_tile, NULL));
3113
3114 if (request_kind == REQEST_PLAYER_INITIATED) {
3115 /* This is a foreground request. */
3120 }
3121
3125 requester);
3126
3127 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3128 /* FIXME: Temporary work around to prevent wrong information and/or
3129 * crashes. See hrm Bug #879880 */
3130 /* TODO: Get the explanation before the punishment and show it here.
3131 * See hrm Bug #879881 */
3132 notify_player(pplayer, unit_tile(actor),
3135 _("No explanation why you couldn't do %s. This is a bug."
3136 " Sorry about that. -- Sveinung"),
3138 }
3139}
3140
3141/**********************************************************************/
3145 const int actor_id,
3146 const int target_id,
3147 int request_kind)
3148{
3150 actor_id, target_id,
3151 0,
3153 request_kind);
3154}
3155
3156/**********************************************************************/
3164 const int actor_id,
3165 const int target_id,
3166 const action_id action_type,
3167 int request_kind)
3168{
3169 struct player *pplayer = pc->playing;
3170 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3171 struct action *paction = action_by_number(action_type);
3172 struct unit *punit = game_unit_by_number(target_id);
3173 struct city *pcity = game_city_by_number(target_id);
3174 const struct civ_map *nmap = &(wld.map);
3175
3176 if (NULL == paction) {
3177 /* Non existing action */
3178 log_error("handle_unit_action_query() the action %d doesn't exist.",
3179 action_type);
3180
3181 unit_query_impossible(pc, actor_id, target_id, request_kind);
3182 return;
3183 }
3184
3185 if (NULL == pactor) {
3186 /* Probably died or bribed. */
3187 log_verbose("handle_unit_action_query() invalid actor %d",
3188 actor_id);
3189 unit_query_impossible(pc, actor_id, target_id, request_kind);
3190 return;
3191 }
3192
3193 switch (paction->result) {
3195 if (punit
3196 && is_action_enabled_unit_on_unit(nmap, action_type,
3197 pactor, punit)) {
3199 actor_id, target_id,
3200 unit_bribe_cost(punit, pplayer),
3201 action_type, request_kind);
3202 } else {
3203 illegal_action(pplayer, pactor, action_type,
3205 NULL, NULL, punit, request_kind, ACT_REQ_PLAYER);
3206 unit_query_impossible(pc, actor_id, target_id, request_kind);
3207 return;
3208 }
3209 break;
3211 if (pcity
3212 && is_action_enabled_unit_on_city(nmap, action_type,
3213 pactor, pcity)) {
3215 actor_id, target_id,
3216 city_incite_cost(pplayer, pcity),
3217 action_type, request_kind);
3218 } else {
3219 illegal_action(pplayer, pactor, action_type,
3220 pcity ? city_owner(pcity) : NULL,
3221 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3222 unit_query_impossible(pc, actor_id, target_id, request_kind);
3223 return;
3224 }
3225 break;
3227 if (pcity
3228 && is_action_enabled_unit_on_city(nmap, action_type,
3229 pactor, pcity)) {
3230 const struct unit_type *tgt_utype;
3231 int upgr_cost;
3232
3234 /* Already checked via is_action_enabled_unit_on_city() */
3236 upgr_cost = unit_upgrade_price(pplayer,
3238
3240 actor_id, target_id,
3241 upgr_cost, action_type,
3242 request_kind);
3243 } else {
3244 illegal_action(pplayer, pactor, action_type,
3245 pcity ? city_owner(pcity) : NULL,
3246 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3247 unit_query_impossible(pc, actor_id, target_id, request_kind);
3248 return;
3249 }
3250 break;
3253 if (pcity
3254 && is_action_enabled_unit_on_city(nmap, action_type,
3255 pactor, pcity)) {
3257 action_by_number(action_type), request_kind);
3258 } else {
3259 illegal_action(pplayer, pactor, action_type,
3260 pcity ? city_owner(pcity) : NULL,
3261 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3262 unit_query_impossible(pc, actor_id, target_id, request_kind);
3263 return;
3264 }
3265 break;
3266 default:
3267 unit_query_impossible(pc, actor_id, target_id, request_kind);
3268 return;
3269 };
3270}
3271
3272/**********************************************************************/
3277void handle_unit_do_action(struct player *pplayer,
3278 const int actor_id,
3279 const int target_id,
3280 const int sub_tgt_id,
3281 const char *name,
3282 const action_id action_type)
3283{
3284 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3285 action_type, ACT_REQ_PLAYER);
3286}
3287
3288/**********************************************************************/
3293void unit_do_action(struct player *pplayer,
3294 const int actor_id,
3295 const int target_id,
3296 const int sub_tgt_id,
3297 const char *name,
3298 const action_id action_type)
3299{
3300 unit_perform_action(pplayer, actor_id, target_id,
3301 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3302}
3303
3304/**********************************************************************/
3313bool unit_perform_action(struct player *pplayer,
3314 const int actor_id,
3315 const int target_id,
3316 const int sub_tgt_id_incoming,
3317 const char *name,
3318 const action_id action_type,
3319 const enum action_requester requester)
3320{
3321 struct action *paction;
3322 int sub_tgt_id;
3323 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3324 struct tile *target_tile = NULL;
3325 struct extra_type *target_extra;
3326 struct impr_type *sub_tgt_impr;
3327 struct unit *punit = NULL;
3328 struct city *pcity = NULL;
3329 const struct civ_map *nmap = &(wld.map);
3330
3331 if (!action_id_exists(action_type)) {
3332 /* Non existing action */
3333 log_error("unit_perform_action() the action %d doesn't exist.",
3334 action_type);
3335
3336 return FALSE;
3337 }
3338
3339 paction = action_by_number(action_type);
3340
3341 if (NULL == actor_unit) {
3342 /* Probably died or bribed. */
3343 log_verbose("unit_perform_action() invalid actor %d",
3344 actor_id);
3345 return FALSE;
3346 }
3347
3349 case ATK_CITY:
3350 pcity = game_city_by_number(target_id);
3351 if (pcity == NULL) {
3352 log_verbose("unit_perform_action() invalid target city %d",
3353 target_id);
3354 return FALSE;
3355 }
3356 target_tile = city_tile(pcity);
3358 break;
3359 case ATK_UNIT:
3360 punit = game_unit_by_number(target_id);
3361 if (punit == NULL) {
3362 log_verbose("unit_perform_action() invalid target unit %d",
3363 target_id);
3364 return FALSE;
3365 }
3368 pcity = tile_city(target_tile);
3369 break;
3370 case ATK_UNITS:
3371 case ATK_TILE:
3372 case ATK_EXTRAS:
3373 target_tile = index_to_tile(nmap, target_id);
3374 if (target_tile == NULL) {
3375 log_verbose("unit_perform_action() invalid target tile %d",
3376 target_id);
3377 return FALSE;
3378 }
3379 pcity = tile_city(target_tile);
3380 break;
3381 case ATK_SELF:
3384 pcity = tile_city(target_tile);
3385 break;
3386 case ATK_COUNT:
3388 break;
3389 }
3390
3391 /* Server side sub target assignment */
3392 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3395 } else {
3396 sub_tgt_id = sub_tgt_id_incoming;
3397 }
3398
3399 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3400 && sub_tgt_id != NO_TARGET) {
3401 target_extra = extra_by_number(sub_tgt_id);
3402 fc_assert(!(target_extra->ruledit_disabled));
3403 } else {
3405 }
3406
3407 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3408
3409 /* Sub targets should now be assigned */
3410 switch (paction->sub_target_kind) {
3411 case ASTK_NONE:
3412 /* No sub target. */
3413 break;
3414 case ASTK_BUILDING:
3415 if (sub_tgt_impr == NULL) {
3416 /* Missing sub target */
3417 return FALSE;
3418 }
3419 break;
3420 case ASTK_TECH:
3421 /* Not handled here yet */
3422 break;
3423 case ASTK_EXTRA:
3425 if (target_extra == NULL) {
3426 /* Missing sub target */
3427 return FALSE;
3428 }
3429 break;
3430 case ASTK_COUNT:
3431 break;
3432 }
3433
3437 && target_extra == NULL) {
3438 /* Missing required action extra target. */
3439 log_verbose("unit_perform_action() action %d requires action "
3440 "but extra id %d is invalid.",
3441 action_type, sub_tgt_id);
3442 return FALSE;
3443 }
3444
3445 if (paction->actor.is_unit.unitwaittime_controlled
3447 /* Action not possible due to unitwaittime setting. */
3448 return FALSE;
3449 }
3450
3451#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3452 if (pcity \
3453 && is_action_enabled_unit_on_city(nmap, action_type, \
3454 actor_unit, pcity)) { \
3455 bool success; \
3456 script_server_signal_emit("action_started_unit_city", \
3457 action_by_number(action), actor, target); \
3458 if (!actor || !unit_is_alive(actor_id)) { \
3459 /* Actor unit was destroyed during pre action Lua. */ \
3460 return FALSE; \
3461 } \
3462 if (!target || !city_exist(target_id)) { \
3463 /* Target city was destroyed during pre action Lua. */ \
3464 return FALSE; \
3465 } \
3466 success = action_performer; \
3467 if (success) { \
3468 action_success_actor_price(paction, actor_id, actor); \
3469 } \
3470 script_server_signal_emit("action_finished_unit_city", \
3471 action_by_number(action), success, \
3472 unit_is_alive(actor_id) ? actor : NULL, \
3473 city_exist(target_id) ? target : NULL); \
3474 return success; \
3475 } else { \
3476 illegal_action(pplayer, actor_unit, action_type, \
3477 pcity ? city_owner(pcity) : NULL, NULL, pcity, NULL, \
3478 TRUE, requester); \
3479 }
3480
3481#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3482 if (actor_unit \
3483 && is_action_enabled_unit_on_self(nmap, action_type, actor_unit)) { \
3484 bool success; \
3485 script_server_signal_emit("action_started_unit_self", \
3486 action_by_number(action), actor); \
3487 if (!actor || !unit_is_alive(actor_id)) { \
3488 /* Actor unit was destroyed during pre action Lua. */ \
3489 return FALSE; \
3490 } \
3491 success = action_performer; \
3492 if (success) { \
3493 action_success_actor_price(paction, actor_id, actor); \
3494 } \
3495 script_server_signal_emit("action_finished_unit_self", \
3496 action_by_number(action), success, \
3497 unit_is_alive(actor_id) ? actor : NULL); \
3498 return success; \
3499 } else { \
3500 illegal_action(pplayer, actor_unit, action_type, \
3501 unit_owner(actor_unit), NULL, NULL, actor_unit, \
3502 TRUE, requester); \
3503 }
3504
3505#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3506 if (punit \
3507 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3508 bool success; \
3509 script_server_signal_emit("action_started_unit_unit", \
3510 action_by_number(action), actor, target); \
3511 if (!actor || !unit_is_alive(actor_id)) { \
3512 /* Actor unit was destroyed during pre action Lua. */ \
3513 return FALSE; \
3514 } \
3515 if (!target || !unit_is_alive(target_id)) { \
3516 /* Target unit was destroyed during pre action Lua. */ \
3517 return FALSE; \
3518 } \
3519 success = action_performer; \
3520 if (success) { \
3521 action_success_actor_price(paction, actor_id, actor); \
3522 action_success_target_pay_mp(paction, target_id, punit); \
3523 } \
3524 script_server_signal_emit("action_finished_unit_unit", \
3525 action_by_number(action), success, \
3526 unit_is_alive(actor_id) ? actor : NULL, \
3527 unit_is_alive(target_id) ? target : NULL); \
3528 return success; \
3529 } else { \
3530 illegal_action(pplayer, actor_unit, action_type, \
3531 punit ? unit_owner(punit) : NULL, NULL, NULL, punit, \
3532 TRUE, requester); \
3533 }
3534
3535#define ACTION_PERFORM_UNIT_UNITS(action, actor, target, action_performer)\
3536 if (target_tile \
3537 && is_action_enabled_unit_on_stack(nmap, action_type, \
3538 actor_unit, target_tile)) { \
3539 bool success; \
3540 script_server_signal_emit("action_started_unit_units", \
3541 action_by_number(action), actor, target); \
3542 if (!actor || !unit_is_alive(actor_id)) { \
3543 /* Actor unit was destroyed during pre action Lua. */ \
3544 return FALSE; \
3545 } \
3546 success = action_performer; \
3547 if (success) { \
3548 action_success_actor_price(paction, actor_id, actor); \
3549 } \
3550 script_server_signal_emit("action_finished_unit_units", \
3551 action_by_number(action), success, \
3552 unit_is_alive(actor_id) ? actor : NULL, \
3553 target); \
3554 return success; \
3555 } else { \
3556 illegal_action(pplayer, actor_unit, action_type, \
3557 NULL, target_tile, NULL, NULL, \
3558 TRUE, requester); \
3559 }
3560
3561#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3562 if (target_tile \
3563 && is_action_enabled_unit_on_tile(nmap, action_type, \
3564 actor_unit, target_tile, \
3565 target_extra)) { \
3566 bool success; \
3567 script_server_signal_emit("action_started_unit_tile", \
3568 action_by_number(action), actor, target); \
3569 if (!actor || !unit_is_alive(actor_id)) { \
3570 /* Actor unit was destroyed during pre action Lua. */ \
3571 return FALSE; \
3572 } \
3573 success = action_performer; \
3574 if (success) { \
3575 action_success_actor_price(paction, actor_id, actor); \
3576 } \
3577 script_server_signal_emit("action_finished_unit_tile", \
3578 action_by_number(action), success, \
3579 unit_is_alive(actor_id) ? actor : NULL, \
3580 target); \
3581 return success; \
3582 } else { \
3583 illegal_action(pplayer, actor_unit, action_type, \
3584 target_tile ? tile_owner(target_tile) : NULL, \
3585 target_tile, NULL, NULL, \
3586 TRUE, requester); \
3587 }
3588
3589#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3590 if (target_tile \
3591 && is_action_enabled_unit_on_extras(nmap, action_type, \
3592 actor_unit, target_tile, \
3593 target_extra)) { \
3594 bool success; \
3595 script_server_signal_emit("action_started_unit_extras", \
3596 action_by_number(action), actor, target); \
3597 if (!actor || !unit_is_alive(actor_id)) { \
3598 /* Actor unit was destroyed during pre action Lua. */ \
3599 return FALSE; \
3600 } \
3601 success = action_performer; \
3602 if (success) { \
3603 action_success_actor_price(paction, actor_id, actor); \
3604 } \
3605 script_server_signal_emit("action_finished_unit_extras", \
3606 action_by_number(action), success, \
3607 unit_is_alive(actor_id) ? actor : NULL, \
3608 target); \
3609 return success; \
3610 } else { \
3611 illegal_action(pplayer, actor_unit, action_type, \
3612 target_tile ? target_tile->extras_owner : NULL, \
3613 target_tile, NULL, NULL, \
3614 TRUE, requester); \
3615 }
3616
3617#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3618 target_city, target_unit, target_tile, \
3619 action_performer) \
3620 switch (action_get_target_kind(paction)) { \
3621 case ATK_CITY: \
3622 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3623 action_performer); \
3624 break; \
3625 case ATK_UNIT: \
3626 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3627 action_performer); \
3628 break; \
3629 case ATK_UNITS: \
3630 ACTION_PERFORM_UNIT_UNITS(paction->id, actor, target_tile, \
3631 action_performer); \
3632 break; \
3633 case ATK_TILE: \
3634 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3635 action_performer); \
3636 break; \
3637 case ATK_EXTRAS: \
3638 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3639 action_performer); \
3640 break; \
3641 case ATK_SELF: \
3642 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3643 break; \
3644 case ATK_COUNT: \
3645 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3646 break; \
3647 }
3648
3649 switch (paction->result) {
3653 paction));
3654 break;
3656 /* Difference is caused by data in the action structure. */
3659 punit, paction));
3660 break;
3661 case ACTRES_EXPEL_UNIT:
3663 do_expel_unit(pplayer, actor_unit, punit,
3664 paction));
3665 break;
3666 case ACTRES_HEAL_UNIT:
3668 do_heal_unit(pplayer, actor_unit, punit,
3669 paction));
3670 break;
3674 paction));
3675 break;
3679 paction));
3680 break;
3683 do_unit_board(pplayer, actor_unit, punit,
3684 paction));
3685 break;
3688 do_unit_load(pplayer, actor_unit, punit,
3689 paction));
3690 break;
3694 paction));
3695 break;
3697 /* All consequences are handled by the action system. */
3699 break;
3700 case ACTRES_FORTIFY:
3703 break;
3704 case ACTRES_CONVERT:
3707 break;
3708 case ACTRES_HOMELESS:
3711 break;
3712 case ACTRES_SPY_ESCAPE:
3713 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3714 spy_escape(pplayer, actor_unit,
3715 pcity, target_tile, paction));
3716 break;
3718 /* Difference is caused by data in the action structure. */
3719 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3720 diplomat_sabotage(pplayer, actor_unit, pcity,
3721 B_LAST, paction));
3722 break;
3724 /* Difference is caused by data in the action structure. */
3725 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3726 diplomat_sabotage(pplayer, actor_unit, pcity,
3727 sub_tgt_impr->item_number,
3728 paction));
3729 break;
3731 /* Difference is caused by data in the action structure. */
3732 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3733 diplomat_sabotage(pplayer, actor_unit, pcity,
3734 -1, paction));
3735 break;
3736 case ACTRES_SPY_POISON:
3737 /* Difference is caused by data in the action structure. */
3738 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3739 spy_poison(pplayer, actor_unit, pcity,
3740 paction));
3741 break;
3743 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3744 spy_spread_plague(pplayer, actor_unit, pcity,
3745 paction));
3746 break;
3748 /* Difference is caused by data in the action structure. */
3749 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3750 diplomat_investigate(pplayer,
3751 actor_unit, pcity,
3752 paction));
3753 break;
3755 /* Difference is caused by data in the action structure. */
3756 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3757 diplomat_embassy(pplayer, actor_unit, pcity,
3758 paction));
3759 break;
3761 /* Difference is caused by data in the action structure. */
3762 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3763 diplomat_incite(pplayer, actor_unit, pcity,
3764 paction));
3765 break;
3767 /* Difference is caused by data in the action structure. */
3768 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3769 diplomat_get_tech(pplayer, actor_unit, pcity,
3770 A_UNSET, paction));
3771 break;
3773 /* Difference is caused by data in the action structure. */
3774 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3775 diplomat_get_tech(pplayer, actor_unit, pcity,
3776 sub_tgt_id, paction));
3777 break;
3779 /* Difference is caused by data in the action structure. */
3780 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3781 spy_steal_gold(pplayer, actor_unit, pcity,
3782 paction));
3783 break;
3784 case ACTRES_STEAL_MAPS:
3785 /* Difference is caused by data in the action structure. */
3786 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3788 pcity, paction));
3789 break;
3790 case ACTRES_TRADE_ROUTE:
3791 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3793 pcity, paction));
3794 break;
3795 case ACTRES_MARKETPLACE:
3796 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3798 pcity, paction));
3799 break;
3800 case ACTRES_HELP_WONDER:
3801 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3802 unit_do_help_build(pplayer,
3803 actor_unit, pcity,
3804 paction));
3805 break;
3806 case ACTRES_SPY_NUKE:
3807 /* Difference is caused by data in the action structure. */
3808 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3809 spy_nuke_city(pplayer, actor_unit, pcity,
3810 paction));
3811 break;
3812 case ACTRES_JOIN_CITY:
3813 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3814 city_add_unit(pplayer, actor_unit, pcity,
3815 paction));
3816 break;
3818 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3819 unit_do_destroy_city(pplayer,
3820 actor_unit, pcity,
3821 paction));
3822 break;
3824 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3825 unit_do_help_build(pplayer, actor_unit, pcity,
3826 paction));
3827 break;
3828 case ACTRES_HOME_CITY:
3829 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3831 paction));
3832 break;
3834 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3835 do_unit_upgrade(pplayer, actor_unit,
3836 pcity, requester, paction));
3837 break;
3839 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3840 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3842 pcity, paction));
3843 break;
3845 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3847 actor_unit,
3848 pcity,
3849 sub_tgt_impr->item_number,
3850 paction));
3851 break;
3853 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3855 actor_unit,
3856 pcity,
3857 paction));
3858 break;
3863 break;
3864 case ACTRES_AIRLIFT:
3865 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3866 do_airline(actor_unit, pcity, paction));
3867 break;
3872 break;
3873 case ACTRES_BOMBARD:
3874 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3877 paction));
3878 break;
3879 case ACTRES_ATTACK:
3881 /* Difference is caused by data in the action structure. */
3884 break;
3885 case ACTRES_WIPE_UNITS:
3888 break;
3889 case ACTRES_NUKE_UNITS:
3892 paction));
3893 break;
3894 case ACTRES_SPY_ATTACK:
3897 paction));
3898 break;
3899 case ACTRES_FOUND_CITY:
3901 city_build(pplayer, actor_unit,
3903 break;
3904 case ACTRES_NUKE:
3906 pcity, punit, target_tile,
3908 paction));
3909 break;
3910 case ACTRES_PARADROP:
3914 break;
3916 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3918 do_disembark(pplayer, actor_unit,
3920 break;
3921 case ACTRES_HUT_ENTER:
3923 do_unit_hut(pplayer, actor_unit,
3925 break;
3928 do_unit_hut(pplayer, actor_unit,
3930 break;
3931 case ACTRES_UNIT_MOVE:
3935 break;
3936 case ACTRES_TELEPORT:
3940 NULL, FALSE,
3943 FALSE, FALSE));
3944 break;
3948 break;
3949 case ACTRES_CULTIVATE:
3952 break;
3953 case ACTRES_PLANT:
3956 break;
3957 case ACTRES_PILLAGE:
3960 paction,
3961 &target_extra));
3962 break;
3963 case ACTRES_CLEAN:
3966 paction,
3967 &target_extra));
3968 break;
3969 case ACTRES_ROAD:
3972 paction,
3973 &target_extra));
3974 break;
3975 case ACTRES_BASE:
3978 paction,
3979 &target_extra));
3980 break;
3981 case ACTRES_MINE:
3984 paction,
3985 &target_extra));
3986 break;
3987 case ACTRES_IRRIGATE:
3990 paction,
3991 &target_extra));
3992 break;
3993 case ACTRES_NONE:
3994 /* 100% ruleset defined. */
3996 TRUE);
3997 break;
4000 return FALSE;
4001
4003 }
4004
4005 /* Something must have gone wrong. */
4006 return FALSE;
4007}
4008
4009/**********************************************************************/
4017 bool rehome)
4018{
4020 struct player *old_owner = unit_owner(punit);
4021 struct player *new_owner = (new_pcity == NULL ? old_owner
4023 const struct civ_map *nmap = &(wld.map);
4024
4025 /* Calling this function when new_pcity is same as old_pcity should
4026 * be safe with current implementation, but it is not meant to
4027 * be used that way. */
4029
4030 /* If 'rehome' is not set, this function should only be used to change
4031 * which player owns the unit */
4033
4034 if (old_owner != new_owner) {
4035 struct city *pcity = tile_city(punit->tile);
4036
4039
4042
4043 if (pcity != NULL
4045 /* Special case when city is being transferred. At this point city
4046 * itself has changed owner, so it's enemy city now that old owner
4047 * cannot see inside. All the normal methods of removing transferred
4048 * unit from previous owner's client think that there's no need to
4049 * remove unit as client shouldn't have it in first place. */
4051 }
4052
4053 /* Remove AI control of the old owner. */
4054 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4055
4059
4060 /* Activate AI control of the new owner. */
4061 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4062
4065 }
4066
4067 if (rehome) {
4068 /* Remove from old city first and add to new city only after that. */
4069 if (old_pcity) {
4070 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4071 unit_list_remove(old_pcity->units_supported, punit);
4072 /* update unit upkeep */
4074 }
4075
4076 if (new_pcity != NULL) {
4077 unit_list_prepend(new_pcity->units_supported, punit);
4078
4079 /* update unit upkeep */
4081
4082 punit->homecity = new_pcity->id;
4083 } else {
4085 }
4086 }
4087
4089 /* This is mainly for cases where unit owner changes to one not knowing
4090 * Railroad tech when unit is already building railroad.
4091 * Does also send_unit_info() */
4093 } else {
4094 /* Send info to players and observers. */
4096 }
4097
4098 if (new_pcity != NULL) {
4102 }
4103
4104 if (old_pcity) {
4108 }
4109
4111}
4112
4113/**********************************************************************/
4119 struct city *pcity,
4120 const struct action *paction)
4121{
4122 const char *giver = NULL;
4123
4124 if (unit_owner(punit) != city_owner(pcity)) {
4125 /* This is a gift. Tell the receiver. */
4126 giver = player_name(unit_owner(punit));
4127 }
4128
4130
4131 if (punit->homecity == pcity->id && giver) {
4132 /* Notify the city owner about the gift they received. */
4134 ftc_server,
4135 /* TRANS: other player ... unit type ... city name. */
4136 _("%s transferred control over a %s to you in %s."),
4137 giver,
4139 city_link(pcity));;
4140 }
4141
4142 return punit->homecity == pcity->id;
4143}
4144
4145/**********************************************************************/
4152static bool city_add_unit(struct player *pplayer, struct unit *punit,
4153 struct city *pcity, const struct action *paction)
4154{
4156 const struct unit_type *act_utype;
4157
4158 /* Sanity check: The actor is still alive. */
4160
4162
4163 /* Sanity check: The target city still exists. */
4164 fc_assert_ret_val(pcity, FALSE);
4165
4167
4168 city_size_add(pcity, amount);
4169 /* Make the new people something, otherwise city fails the checks */
4172 /* Refresh the city data. */
4173 city_refresh(pcity);
4174
4175 /* Notify the unit owner that the unit successfully joined the city. */
4177 _("%s added to aid %s in growing."),
4179 city_link(pcity));
4180 if (pplayer != city_owner(pcity)) {
4181 /* Notify the city owner when a foreign unit joins a city. */
4183 ftc_server,
4184 /* TRANS: another player had their unit join your city. */
4185 _("%s adds %s to your city %s."),
4188 city_link(pcity));;
4189 }
4190
4192 city_owner(pcity), city_tile(pcity),
4193 city_link(pcity));
4194
4195 sanity_check_city(pcity);
4196
4197 send_city_info(NULL, pcity);
4198
4199 script_server_signal_emit("city_size_change", pcity,
4200 (lua_Integer)amount, "unit_added");
4201
4202 return TRUE;
4203}
4204
4205/**********************************************************************/
4214static bool city_build(struct player *pplayer, struct unit *punit,
4215 struct tile *ptile, const char *name,
4216 const struct action *paction)
4217{
4218 char message[1024];
4219 int size;
4220 struct player *nationality;
4221 struct player *towner;
4222 const struct unit_type *act_utype;
4223
4224 /* Sanity check: The actor still exists. */
4225 fc_assert_ret_val(pplayer, FALSE);
4227
4228 towner = tile_owner(ptile);
4229
4230 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4231 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4232 "%s", message);
4233 return FALSE;
4234 }
4235
4237
4238 nationality = unit_nationality(punit);
4239
4240 create_city(pplayer, ptile, name, nationality);
4242 if (size > 1) {
4243 struct city *pcity = tile_city(ptile);
4244
4245 fc_assert_ret_val(pcity != NULL, FALSE);
4246
4248 }
4249
4250 /* May cause an incident even if the target tile is unclaimed. A ruleset
4251 * could give everyone a casus belli against the city founder. A rule
4252 * like that would make sense in a story where deep ecology is on the
4253 * table. (See also Voluntary Human Extinction Movement) */
4255 ptile, tile_link(ptile));
4256
4257 return TRUE;
4258}
4259
4260/**********************************************************************/
4263static void handle_unit_change_activity_real(struct player *pplayer,
4264 int unit_id,
4265 enum unit_activity activity,
4266 struct extra_type *activity_target)
4267{
4268 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4269
4270 if (NULL == punit) {
4271 /* Probably died or bribed. */
4272 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4273 return;
4274 }
4275
4276 if (punit->activity == activity
4278 return;
4279 }
4280
4281 /* Remove city spot reservations for AI settlers on city founding
4282 * mission, before goto_tile reset. */
4283 if (punit->server.adv->task != AUT_NONE) {
4285 }
4286
4287 punit->goto_tile = NULL;
4288
4289 if (activity == ACTIVITY_GOTO) {
4290 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4291 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4292 * it is going somewhere while it is standing still. The appearance of
4293 * the unit doing something can trick the user to not make use of it.
4294 *
4295 * Handled here because adv_follow_path() uses unit_activity_handling()
4296 * to set a unit's activity to ACTIVITY_GOTO. */
4297 return;
4298 }
4299
4300 if (activity == ACTIVITY_EXPLORE) {
4301 /* Please use unit_server_side_agent_set. */
4302 return;
4303 }
4304
4305 /* The activity can now be set. */
4307}
4308
4309/**********************************************************************/
4312void handle_unit_change_activity(struct player *pplayer, int unit_id,
4314 int target_id)
4315{
4316 struct extra_type *activity_target;
4317
4319 activity_target = NULL;
4320 } else {
4321 activity_target = extra_by_number(target_id);
4322 }
4323
4324#ifdef FREECIV_WEB
4325 /* Web-client is not capable of selecting target, so we do it server side */
4326 if (activity_target == NULL) {
4327 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4328 bool required = TRUE;
4329
4330 if (punit == NULL) {
4331 return;
4332 }
4333
4334 if (activity == ACTIVITY_IRRIGATE) {
4335 struct tile *ptile = unit_tile(punit);
4336
4337 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4338 pplayer, punit);
4339 } else if (activity == ACTIVITY_MINE) {
4340 struct tile *ptile = unit_tile(punit);
4341
4342 activity_target = next_extra_for_tile(ptile, EC_MINE,
4343 pplayer, punit);
4344 } else if (activity == ACTIVITY_BASE) {
4345 struct tile *ptile = unit_tile(punit);
4346 struct base_type *pbase =
4348
4349 if (pbase != NULL) {
4350 activity_target = base_extra_get(pbase);
4351 }
4352
4353 } else if (activity == ACTIVITY_CLEAN) {
4354 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4355 pplayer, punit);
4356 } else {
4357 required = FALSE;
4358 }
4359
4360 if (activity_target == NULL && required) {
4361 /* Nothing more we can do */
4362 return;
4363 }
4364 }
4365#endif /* FREECIV_WEB */
4366
4367 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target);
4368}
4369
4370/**********************************************************************/
4373static void see_combat(struct unit *pattacker, struct unit *pdefender)
4374{
4377
4378 /*
4379 * Special case for attacking/defending:
4380 *
4381 * Normally the player doesn't get the information about the units inside a
4382 * city. However for attacking/defending the player has to know the unit of
4383 * the other side. After the combat a remove_unit packet will be sent
4384 * to the client to tidy up.
4385 *
4386 * Note these packets must be sent out before unit_versus_unit() is called,
4387 * so that the original unit stats (HP) will be sent.
4388 */
4395
4397 struct player *pplayer = pconn->playing;
4398
4399 if (pplayer != NULL) {
4400
4401 /* NOTE: this means the player can see combat between submarines even
4402 * if neither sub is visible. See similar comment in send_combat. */
4405 V_MAIN)) {
4406
4407 /* Units are sent even if they were visible already. They may
4408 * have changed orientation for combat. */
4409 if (pplayer == unit_owner(pattacker)) {
4411 } else {
4413 }
4414
4415 if (pplayer == unit_owner(pdefender)) {
4417 } else {
4419 }
4420 }
4421 } else if (pconn->observer) {
4422 /* Global observer sees everything... */
4425 }
4427}
4428
4429/**********************************************************************/
4432static void send_combat(struct unit *pattacker, struct unit *pdefender,
4433 int att_veteran, int def_veteran, int bombard)
4434{
4436
4438 combat.defender_unit_id = pdefender->id;
4439 combat.attacker_hp = pattacker->hp;
4440 combat.defender_hp = pdefender->hp;
4441 combat.make_att_veteran = att_veteran;
4442 combat.make_def_veteran = def_veteran;
4443
4444 players_iterate(other_player) {
4445 /* NOTE: this means the player can see combat between submarines even
4446 * if neither sub is visible. See similar comment in see_combat. */
4447 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4448 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4449 V_MAIN)) {
4450 lsend_packet_unit_combat_info(other_player->connections, &combat);
4451
4452 /*
4453 * Remove the client knowledge of the units. This corresponds to the
4454 * send_packet_unit_short_info calls up above.
4455 */
4456 if (!can_player_see_unit(other_player, pattacker)) {
4457 unit_goes_out_of_sight(other_player, pattacker);
4458 }
4459 if (!can_player_see_unit(other_player, pdefender)) {
4460 unit_goes_out_of_sight(other_player, pdefender);
4461 }
4462 }
4464
4465 /* Send combat info to non-player observers as well. They already know
4466 * about the unit so no unit_info is needed. */
4468 if (NULL == pconn->playing && pconn->observer) {
4470 }
4472}
4473
4474/**********************************************************************/
4478 struct city *pcity,
4479 const struct action *paction,
4480 const char *reason)
4481{
4482 struct player *pplayer = unit_owner(punit);
4483
4484 if (pcity
4486 &(const struct req_context) {
4487 .player = city_owner(pcity),
4488 .city = pcity,
4489 .tile = city_tile(pcity),
4490 .unit = punit,
4491 .unittype = unit_type_get(punit),
4492 .action = paction,
4493 },
4497 struct player *cplayer = city_owner(pcity);
4498 struct tile *ctile = city_tile(pcity);
4499 const char *clink = city_link(pcity);
4500
4501 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4502 city_refresh(pcity);
4503 send_city_info(NULL, pcity);
4504 } else {
4506 /* TRANS: Battleship ... Los Angeles ... Bombard */
4507 _("Your %s destroyed %s by doing %s."),
4512 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4513 _("%s destroyed %s by doing %s."),
4514 player_name(pplayer), clink,
4516 }
4517 }
4518}
4519
4520/**********************************************************************/
4527static bool unit_bombard(struct unit *punit, struct tile *ptile,
4528 const struct action *paction)
4529{
4530 struct player *pplayer = unit_owner(punit);
4531 struct city *pcity = tile_city(ptile);
4532 const struct unit_type *act_utype;
4533 const struct civ_map *nmap = &(wld.map);
4534
4535 /* Sanity check: The actor still exists. */
4536 fc_assert_ret_val(pplayer, FALSE);
4538
4540
4541 log_debug("Start bombard: %s %s to %d, %d.",
4543 unit_rule_name(punit), TILE_XY(ptile));
4544
4546 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4547 bool adj;
4548 enum direction8 facing;
4549 int att_hp, def_hp;
4550
4552 punit->tile, pdefender->tile, &facing);
4553
4554 if (adj) {
4555 punit->facing = facing;
4556
4557 /* Unlike with normal attack, we don't change orientation of
4558 * defenders when bombarding */
4559 }
4560
4561 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4562
4563 if (def_hp <= 0) {
4564 notify_player(pplayer, ptile,
4566 /* TRANS: Your Bomber killed the English Rifleman by
4567 * doing Bombard. */
4568 _("Your %s killed the %s %s by doing %s."),
4575 /* TRANS: Your Rifleman was killed by the French
4576 * Bomber doing Bombard. */
4577 _("Your %s was killed by the %s %s doing %s."),
4582 } else {
4583 notify_player(pplayer, ptile,
4585 /* TRANS: Your Bomber bombards the English Rifleman. */
4586 _("Your %s bombards the %s %s."),
4592 /* TRANS: Your Rifleman is bombarded by the French
4593 * Bomber. */
4594 _("Your %s is bombarded by the %s %s."),
4598 }
4599
4601
4602 punit->hp = att_hp;
4603 pdefender->hp = def_hp;
4604
4605 send_combat(punit, pdefender, 0, 0, 1);
4606
4607 /* May cause an incident */
4613
4614 if (def_hp <= 0) {
4616 } else {
4618 }
4619 }
4620
4622
4625
4626 unit_attack_civilian_casualties(punit, pcity, paction, "bombard");
4627
4629
4630 return TRUE;
4631}
4632
4633/**********************************************************************/
4644static bool unit_nuke(struct player *pplayer, struct unit *punit,
4645 struct tile *def_tile, const struct action *paction)
4646{
4647 struct city *pcity;
4648 const struct unit_type *act_utype;
4649 struct civ_map *nmap = &(wld.map);
4650
4651 /* Sanity check: The actor still exists. */
4652 fc_assert_ret_val(pplayer, FALSE);
4654
4656
4657 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4660 TILE_XY(def_tile));
4661
4662 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4663 /* FIXME: Remove the hard coded reference to SDI defense. */
4665 _("Your %s was shot down by "
4666 "SDI defenses, what a waste."), unit_tile_link(punit));
4668 _("The nuclear attack on %s was avoided by"
4669 " your SDI defense."), city_link(pcity));
4670
4671 /* Trying to nuke something this close can be... unpopular. */
4673 city_owner(pcity),
4675
4676 /* Remove the destroyed nuke. */
4678
4679 return FALSE;
4680 }
4681
4683
4684
4685 /* The nuke must be wiped here so it won't be seen as a victim of its own
4686 * detonation. */
4687 if (paction->actor_consuming_always) {
4689 }
4690
4692
4693 /* May cause an incident even if the target tile is unclaimed. A ruleset
4694 * could give everyone a casus belli against the tile nuker. A rule
4695 * like that would make sense in a story where detonating any nuke at all
4696 * could be forbidden. */
4699 def_tile,
4701
4702 return TRUE;
4703}
4704
4705/**********************************************************************/
4715 struct unit *act_unit,
4716 struct city *tgt_city,
4717 const struct action *paction)
4718{
4719 int tgt_city_id;
4720 struct player *tgt_player;
4721 bool capital;
4722 bool try_civil_war = FALSE;
4723 const struct unit_type *act_utype;
4724
4725 /* Sanity check: The actor still exists. */
4728
4730
4731 /* Sanity check: The target city still exists. */
4733
4735
4736 /* How can a city be ownerless? */
4738
4739 /* Save city ID. */
4740 tgt_city_id = tgt_city->id;
4741
4743
4744 if (capital
4745 && (tgt_player->spaceship.state == SSHIP_STARTED
4746 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4747 /* Destroying this city destroys the victim's space ship. */
4749 }
4750
4751 if (capital
4755 /* Destroying this city can trigger a civil war. */
4757 }
4758
4759 /* Let the actor know. */
4762 _("You destroy %s completely."),
4764
4765 if (tgt_player != act_player) {
4766 /* This was done to a foreign city. Inform the victim player. */
4769 _("%s has been destroyed by %s."),
4772 }
4773
4774 /* May cause an incident */
4778
4779 /* Run post city destruction Lua script. */
4781 act_player);
4782
4783 /* Can't be sure of city existence after running script. */
4784 if (city_exist(tgt_city_id)) {
4786 }
4787
4788 if (try_civil_war) {
4789 /* Try to start the civil war. */
4791 }
4792
4793 /* The city is no more. */
4794 return TRUE;
4795}
4796
4797/**********************************************************************/
4802static const char *unit_veteran_level_string(const struct unit *punit)
4803{
4804 static char buf[MAX_LEN_LINK];
4805 const struct veteran_level *vlevel;
4806
4807 if (!punit) {
4808 buf[0] = '\0'; /* If no unit, return empty string */
4809 return buf;
4810 }
4811
4813 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4814
4815 return buf;
4816}
4817
4818/**********************************************************************/
4823static const char *unit_achieved_rank_string(const struct unit *punit)
4824{
4825 static char buf[MAX_LEN_LINK];
4826
4827 fc_snprintf(buf, sizeof(buf),
4828 /* TRANS: " and achieved the rank of <veteran level>";
4829 * preserve leading space */
4830 _(" and achieved the rank of %s"),
4832 return buf;
4833}
4834
4835/**********************************************************************/
4840static const char *unit_tired_attack_string(const struct unit *punit)
4841{
4842 static char buf[MAX_LEN_LINK];
4843
4845 fc_snprintf(buf, sizeof(buf),
4846 /* TRANS: tired; note trailing space */
4847 _("tired "));
4848 } else {
4849 buf[0] = '\0';
4850 }
4851
4852 return buf;
4853}
4854
4855/**********************************************************************/
4862static const char *unit_firepower_if_not_one(int firepower)
4863{
4864 static char buf[MAX_LEN_LINK];
4865
4866 if (firepower == 1) {
4867 buf[0] = '\0';
4868 } else {
4869 fc_snprintf(buf, sizeof(buf),
4870 /* TRANS: FP = Firepower of a unit; note trailing space */
4871 _("FP:%d "),
4872 firepower);
4873 }
4874
4875 return buf;
4876}
4877
4878/**********************************************************************/
4887static bool do_attack(struct unit *punit, struct tile *def_tile,
4888 const struct action *paction)
4889{
4894 struct unit *ploser, *pwinner;
4897 int winner_id;
4898 struct player *pplayer = unit_owner(punit);
4899 bool adj;
4900 enum direction8 facing;
4901 int att_hp, def_hp, att_fp, def_fp;
4903 int def_power, att_power;
4904 int att_vet, def_vet;
4905 struct unit *pdefender;
4906 const struct unit_type *act_utype = unit_type_get(punit);
4907 struct civ_map *nmap = &(wld.map);
4908 bool powerless;
4909
4911 /* Can't fight air... */
4912 return FALSE;
4913 }
4914
4916 def_hp_start = pdefender->hp;
4920
4921 log_debug("Start attack: %s %s against %s %s.",
4926
4927 /* Sanity checks */
4930 FALSE,
4931 "Trying to attack a unit with which you have peace "
4932 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
4934 FALSE,
4935 "Trying to attack a unit with which you have "
4936 "alliance at (%d, %d).", TILE_XY(def_tile));
4937
4940
4942 punit->tile, pdefender->tile, &facing);
4943
4944 fc_assert(adj);
4945 if (adj) {
4946 punit->facing = facing;
4947 pdefender->facing = opposite_direction(facing);
4948 }
4949
4951 old_defender_vet = pdefender->veteran;
4952
4953 /* N.B.: unit_veteran_level_string always returns the same pointer. */
4956
4957 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
4960
4961 /* Record tired attack string before attack */
4963
4964 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
4965 &att_vet, &def_vet, paction);
4966
4967 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
4968 && unit_transported(punit)) {
4969 /* Dying attacker must be first unloaded so it doesn't die inside transport */
4971 }
4972
4974
4975 punit->hp = att_hp;
4976 pdefender->hp = def_hp;
4977
4979
4980 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
4981 * the movement attack modifier is correct! --dwp
4982 *
4983 * For greater Civ2 compatibility (and game balance issues), we recompute
4984 * the new total MP based on the HP the unit has left after being damaged,
4985 * and subtract the MPs that had been used before the combat (plus the
4986 * points used in the attack itself, for the attacker). -GJW, Glip
4987 */
4990
4991 if (punit->moves_left < 0) {
4992 punit->moves_left = 0;
4993 }
4994 if (pdefender->moves_left < 0) {
4995 pdefender->moves_left = 0;
4996 }
4999
5000 /* This may cause a diplomatic incident. */
5004
5005 if (punit->hp > 0 && pdefender->hp > 0) {
5006 /* Neither died */
5008 pdefender->veteran - old_defender_vet, 0);
5009 return TRUE;
5010 }
5011 pwinner = (punit->hp > 0) ? punit : pdefender;
5012 winner_id = pwinner->id;
5013 ploser = (pdefender->hp > 0) ? punit : pdefender;
5014
5015 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5016 old_defender_vet)) ? 0 : 1;
5017
5019 pdefender->veteran - old_defender_vet, 0);
5020
5021 /* N.B.: unit_link always returns the same pointer. */
5026
5027 if (punit == ploser) {
5028 /* The attacker lost */
5029 log_debug("Attacker lost: %s %s against %s %s.",
5034
5037 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5038 * 9 HP remaining] survived the pathetic ...attack from the
5039 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5040 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5041 " survived the pathetic %sattack from the %s %s %s "
5042 "[id:%d %sA:%.1f HP:%d]."),
5045 pdefender->id,
5047 (float)def_power/POWER_FACTOR,
5048 def_hp_start - pdefender->hp,
5049 pdefender->hp,
5053 loser_link,
5054 punit->id,
5056 (float)att_power/POWER_FACTOR,
5057 att_hp_start);
5058
5059 if (vet) {
5061 }
5064 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5065 * failed against the Polish green Destroyer [id:200 lost
5066 * 27 HP, 3 HP remaining%s]!";
5067 * last %s is either "and ..." or empty string */
5068 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5069 "against the %s %s %s [id:%d lost %d HP, %d HP "
5070 "remaining%s]!"),
5072 loser_link,
5073 punit->id,
5075 (float)att_power/POWER_FACTOR,
5080 pdefender->id,
5081 def_hp_start - pdefender->hp,
5082 pdefender->hp,
5084
5086 } else {
5087 /* The defender lost, the attacker punit lives! */
5088 struct city *pcity;
5089
5090 log_debug("Defender lost: %s %s against %s %s.",
5095
5098 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5099 * lost to an attack by the Greek green Legion
5100 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5101 * last %s is either "and ..." or empty string */
5102 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5103 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5104 "remaining%s]."),
5106 loser_link,
5107 pdefender->id,
5109 (float)def_power/POWER_FACTOR,
5114 punit->id,
5116 (float)att_power/POWER_FACTOR,
5117 att_hp_start - pwinner->hp,
5118 pwinner->hp,
5120
5123 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5124 * lost 1 HP, has 9 HP remaining] succeeded against the
5125 * Greek green Warriors [id:100 HP:10]." */
5126 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5127 "has %d remaining] succeeded against the %s %s %s "
5128 "[id:%d HP:%d]."),
5131 punit->id,
5134 (float)att_power/POWER_FACTOR,
5135 att_hp_start - pwinner->hp,
5136 pwinner->hp,
5139 loser_link,
5140 pdefender->id,
5141 def_hp_start);
5142
5143 punit->moved = TRUE; /* We moved */
5144
5145 if (paction->result == ACTRES_COLLECT_RANSOM) {
5148 } else {
5151 }
5152
5153 /* Now that dead defender is certainly no longer listed as unit
5154 * supported by the city, we may even remove the city
5155 * (if it shrinks from size 1) */
5156 pcity = tile_city(def_tile);
5157 if (pcity != NULL) {
5159 }
5160 if (unit_is_alive(winner_id)) {
5162 return TRUE;
5163 }
5164 } else {
5165 return TRUE;
5166 }
5167 }
5168
5169 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5170 * if there are enemy units in the tile (a fortress, city or air base with
5171 * multiple defenders and unstacked combat). Note that this could mean
5172 * capturing (or destroying) a city. */
5173
5174 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5176 }
5177
5178 /* The attacker may have died for many reasons */
5181 }
5182
5183 return TRUE;
5184}
5185
5186/**********************************************************************/
5197 struct unit *act_unit,
5198 struct city *tgt_city,
5199 const struct action *paction)
5200{
5201 struct player *tgt_player;
5202 char prod[256];
5203 const struct unit_type *act_utype;
5204 const struct tile *tgt_tile;
5205 const char *clink;
5206
5207 /* Sanity checks */
5212
5215
5217
5218 /* The surgical strike may miss. */
5219 {
5220 /* Roll the dice. */
5223 paction)) {
5224 /* Notify the player. */
5227 /* TRANS: unit, action, city */
5228 _("Your %s failed to do %s in %s."),
5232
5233 /* Make the failed attempt cost a single move. */
5234 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5235
5236 return FALSE;
5237 }
5238 }
5239
5240 /* Get name of the production */
5241 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5242
5243 /* Destroy the production */
5244 tgt_city->shield_stock = 0;
5246
5247 /* Let the players know. */
5248 clink = city_link(tgt_city); /* Be careful not to call city_link()
5249 * again as long as we need clink */
5252 _("Your %s succeeded in destroying"
5253 " the production of %s in %s."),
5255 prod, clink);
5258 _("The production of %s was destroyed in %s,"
5259 " %s are suspected."),
5260 prod, clink,
5262
5264
5265 /* May cause an incident */
5268 clink);
5269
5270 return TRUE;
5271}
5272
5273/**********************************************************************/
5284 struct unit *act_unit,
5285 struct city *tgt_city,
5287 const struct action *paction)
5288{
5289 struct player *tgt_player;
5291 const struct tile *tgt_tile;
5292 const struct unit_type *act_utype;
5293 const char *clink;
5294
5295 /* Sanity checks */
5300
5302
5305
5306 /* The surgical strike may miss. */
5307 {
5308 /* Roll the dice. */
5311 paction)) {
5312 /* Notify the player. */
5315 /* TRANS: unit, action, city */
5316 _("Your %s failed to do %s in %s."),
5320
5321 /* Make the failed attempt cost a single move. */
5322 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5323
5324 return FALSE;
5325 }
5326 }
5327
5329 /* Nothing to destroy here. */
5330
5331 /* Notify the player. */
5334 _("Your %s didn't find a %s to %s in %s."),
5339
5340 /* Punish the player for blindly attacking a building. */
5341 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5342
5343 return FALSE;
5344 }
5345
5347
5348 /* Destroy the building. */
5349 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5350
5351 /* Update the player's view of the city. */
5353
5354 /* Let the players know. */
5355 clink = city_link(tgt_city); /* Be careful not to call city_link()
5356 * again as long as we need clink */
5359 _("Your %s destroyed the %s in %s."),
5362 clink);
5365 _("The %s destroyed the %s in %s."),
5368 clink);
5369
5370 /* May cause an incident */
5373
5374 return TRUE;
5375}
5376
5377/**********************************************************************/
5387 struct unit *act_unit,
5388 struct city *tgt_city,
5389 struct action *paction)
5390{
5391 bool success;
5392 struct tile *tgt_tile = city_tile(tgt_city);
5393 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5394 int tgt_city_id = tgt_city->id;
5396 const char *victim_link = city_link(tgt_city);
5397
5398 /* Sanity check */
5400
5401 unit_move(act_unit, tgt_tile, move_cost, NULL, FALSE, TRUE, TRUE,
5402 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5404
5405 /* The city may have been destroyed during the conquest. */
5408
5409 if (success) {
5410 const struct unit_type *act_utype = unit_type_get(act_unit);
5411
5412 /* May cause an incident */
5415 victim_link);
5416 }
5417
5418 return success;
5419}
5420
5421/**********************************************************************/
5425 struct tile *dest_tile,
5426 bool igzoc,
5427 struct unit *embark_to,
5428 bool enter_enemy_city)
5429{
5430 struct tile *src_tile = unit_tile(punit);
5433 src_tile, dest_tile, igzoc, TRUE, embark_to,
5435
5436 switch (reason) {
5437 case MR_OK:
5438 return TRUE;
5439
5440 case MR_NO_WAR:
5442 _("Cannot attack unless you declare war first."));
5443 break;
5444
5445 case MR_ZOC:
5447 _("%s can only move into your own zone of control."),
5448 unit_link(punit));
5449 break;
5450
5451 case MR_TRIREME:
5453 _("%s cannot move that far from the coast line."),
5454 unit_link(punit));
5455 break;
5456
5457 case MR_PEACE:
5458 if (tile_owner(dest_tile)) {
5460 _("Cannot invade unless you break peace with "
5461 "%s first."),
5462 player_name(tile_owner(dest_tile)));
5463 }
5464 break;
5465
5468 _("%s cannot disembark outside of a city or a native base "
5469 "for %s."),
5473 break;
5474
5475 case MR_NON_NATIVE_MOVE:
5477 _("Terrain is unsuitable for %s units."),
5479 break;
5480
5481 default:
5482 /* FIXME: need more explanations someday! */
5483 break;
5484 };
5485
5486 return FALSE;
5487}
5488
5489/**********************************************************************/
5496 struct unit *actor_unit,
5497 struct tile *target_tile,
5498 const struct action *paction)
5499{
5501 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5502
5503 unit_move(actor_unit, target_tile, move_cost,
5505 /* Don't override "Conquer City" */
5506 FALSE,
5507 /* Don't override "Conquer Extras" */
5508 FALSE,
5509 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5511
5512 /* May cause an incident */
5516
5517 return TRUE;
5518}
5519
5520/**********************************************************************/
5534 bool move_do_not_act)
5535{
5536 struct player *pplayer = unit_owner(punit);
5537 struct unit *ptrans;
5538 const struct civ_map *nmap = &(wld.map);
5539
5540 /*** Phase 1: Attempted action interpretation checks ***/
5541
5542 /* Check if the move should be interpreted as an attempt to perform an
5543 * enabler controlled action to the target tile. When the move may be an
5544 * action attempt the server stops moving the unit, marks it as wanting a
5545 * decision based on its own movement to the tile it attempted to move to
5546 * and notifies the client.
5547 *
5548 * In response to the unit being marked as wanting a decision the client
5549 * can query the server for what actions the unit, given the player's
5550 * knowledge, may be able to perform against a target at the tile it tried
5551 * to move to. The server will respond to the query with the actions that
5552 * may be enabled and, when all actions are known to be illegal given the
5553 * player's knowledge, an explanation why no action could be done. The
5554 * client will probably use the list of potentially legal actions, if any,
5555 * to pop up an action selection dialog. See handle_unit_action_query()
5556 *
5557 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5558 * to perform an enabler controlled action.
5559 * Examples of where this is useful is for AI moves, goto, when the player
5560 * attempts to move to a tile occupied by potential targets like allied
5561 * cities or units and during rule forced moves.
5562 *
5563 * A move is not interpreted as an attempted action because the unit is
5564 * able to do a self targeted action.
5565 *
5566 * A move is not interpreted as an attempted action because an action
5567 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5568 * perform a regular move to the tile.
5569 *
5570 * An attempted move to a tile a unit can't move to is always interpreted
5571 * as trying to perform an action (unless move_do_not_act is TRUE) */
5572 if (!move_do_not_act) {
5575 FALSE, FALSE, FALSE);
5579 /* A legal action with an extra sub target is a legal action */
5581 /* Tile target actions with extra sub targets are handled above */
5583
5585 /* There is a target punit, from the player's point of view, may be
5586 * able to act against OR punit can't do any non action move. The
5587 * client should therefore ask what action(s) the unit can perform
5588 * to any targets at pdesttile.
5589 *
5590 * In the first case the unit needs a decision about what action, if
5591 * any at all, to take. Asking what actions the unit can perform
5592 * will return a list of actions that may, from the players point of
5593 * view, be possible. The client can then show this list to the
5594 * player or, if configured to do so, make the choice it self.
5595 *
5596 * In the last case the player may need an explanation about why no
5597 * action could be taken. Asking what actions the unit can perform
5598 * will provide this explanation. */
5602
5603 /* The move wasn't done because the unit wanted the player to
5604 * decide what to do or because the unit couldn't move to the
5605 * target tile. */
5606 return FALSE;
5607 }
5608 }
5609
5610 /*** Phase 2: OK now move the unit ***/
5611 /* This is a regular move, subject to the rules. */
5613 punit, pdesttile, NULL)) {
5614 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5618 punit, pdesttile, NULL)) {
5619 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5623 punit, pdesttile, NULL)) {
5624 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5630 punit, ptrans)) {
5631 /* "Transport Embark". */
5632 return unit_perform_action(pplayer, punit->id, ptrans->id,
5638 punit, ptrans)) {
5639 /* "Transport Embark 2". */
5640 return unit_perform_action(pplayer, punit->id, ptrans->id,
5646 punit, ptrans)) {
5647 /* "Transport Embark 3". */
5648 return unit_perform_action(pplayer, punit->id, ptrans->id,
5654 punit, ptrans)) {
5655 /* "Transport Embark 4". */
5656 return unit_perform_action(pplayer, punit->id, ptrans->id,
5660 punit, pdesttile, NULL)) {
5661 /* "Transport Disembark". */
5662 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5666 punit, pdesttile, NULL)) {
5667 /* "Transport Disembark 2". */
5668 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5672 punit, pdesttile, NULL)) {
5673 /* "Transport Disembark 3". */
5674 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5678 punit, pdesttile, NULL)) {
5679 /* "Transport Disembark 4". */
5680 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5684 punit, pdesttile, NULL)) {
5685 /* "Enter Hut". */
5686 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5690 punit, pdesttile, NULL)) {
5691 /* "Enter Hut 2". */
5692 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5696 punit, pdesttile, NULL)) {
5697 /* "Frighten Hut". */
5698 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5702 punit, pdesttile, NULL)) {
5703 /* "Frighten Hut 2". */
5704 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5707 } else {
5708 /* TODO: Extend the action not enabled explanation system to cover all
5709 * existing reasons and switch to using it. See hrm Feature #920229 */
5711 NULL, FALSE);
5712 return FALSE;
5713 }
5714}
5715
5716/**********************************************************************/
5726static bool unit_do_help_build(struct player *pplayer,
5727 struct unit *punit,
5728 struct city *pcity_dest,
5729 const struct action *paction)
5730{
5731 const char *work;
5732 const char *prod;
5733 int shields;
5734 const struct unit_type *act_utype;
5735 struct player *cowner;
5736
5737 /* Sanity check: The actor still exists. */
5738 fc_assert_ret_val(pplayer, FALSE);
5740
5741 /* Sanity check: The target city still exists. */
5743
5746
5748 /* Add the caravan shields */
5749 pcity_dest->shield_stock += shields;
5750
5751 /* Will be punished for changing production to something that can't
5752 * receive "Help Wonder" help. */
5754 &pcity_dest->production));
5755 pcity_dest->caravan_shields += shields;
5756 } else {
5758 /* Add the shields from recycling the unit to the city's current
5759 * production. */
5760 pcity_dest->shield_stock += shields;
5761
5762 /* If we change production later at this turn. No penalty is added. */
5763 pcity_dest->disbanded_shields += shields;
5764 }
5765
5767
5768 conn_list_do_buffer(cowner->connections);
5769
5771 /* Let the player that just donated shields with "Help Wonder" know
5772 * the result of their donation. */
5774 } else {
5776 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
5777 * current production in Bergen (4 surplus).
5778 * "Disband Unit Recover" says "current production" rather than its name. */
5779 prod = _("current production");
5780 }
5781
5782 if (build_points_left(pcity_dest) >= 0) {
5783 /* TRANS: Your Caravan does "Help Wonder" to help build the
5784 * Pyramids in Bergen (4 remaining).
5785 * You can reorder '4' and 'remaining' in the actual format string. */
5786 work = _("remaining");
5787 } else {
5788 /* TRANS: Your Caravan does "Help Wonder" to help build the
5789 * Pyramids in Bergen (4 surplus).
5790 * You can reorder '4' and 'surplus' in the actual format string. */
5791 work = _("surplus");
5792 }
5793
5795 ftc_server,
5796 /* TRANS: Your Caravan does "Help Wonder" to help build the
5797 * Pyramids in Bergen (4 surplus). */
5798 _("Your %s does %s to help build the %s in %s (%d %s)."),
5801 prod,
5804 work);
5805
5806 /* May cause an incident */
5809
5810 if (cowner != unit_owner(punit)) {
5811 /* Tell the city owner about the gift they just received. */
5812
5815 /* TRANS: Help building the Pyramids in Bergen received
5816 * from Persian Caravan (4 surplus). */
5817 _("Help building the %s in %s received from %s %s "
5818 "(%d %s)."),
5824 work);
5825 }
5826
5829 conn_list_do_unbuffer(cowner->connections);
5830
5831 return TRUE;
5832}
5833
5834/**********************************************************************/
5841static bool do_unit_establish_trade(struct player *pplayer,
5842 struct unit *punit,
5843 struct city *pcity_dest,
5844 const struct action *paction)
5845{
5848 int revenue;
5849 bool can_establish;
5850 int home_overbooked = 0;
5851 int dest_overbooked = 0;
5852 int home_max;
5853 int dest_max;
5854 struct city *pcity_homecity;
5857 enum trade_route_bonus_type bonus_type;
5858 struct goods_type *goods;
5859 const char *goods_str;
5860 const struct unit_type *act_utype;
5861
5862 /* Sanity check: The actor still exists. */
5863 fc_assert_ret_val(pplayer, FALSE);
5865
5866 /* Sanity check: The target city still exists. */
5868
5870
5871 if (!pcity_homecity) {
5873 _("Sorry, your %s cannot establish"
5874 " a trade route because it has no home city."),
5875 unit_link(punit));
5876 return FALSE;
5877 }
5878
5881 } else {
5882 goods = punit->carrying;
5883 }
5884 if (goods == NULL) {
5886 _("Sorry, your %s cannot establish"
5887 " a trade route because it's not carrying any goods."),
5888 unit_link(punit));
5889 return FALSE;
5890 }
5891
5894
5897 _("Sorry, your %s cannot establish"
5898 " a trade route between %s and %s."),
5902 return FALSE;
5903 }
5904
5906
5910
5911 /* This part of code works like can_establish_trade_route, except
5912 * that we actually do the action of making the trade route. */
5913
5914 /* If we can't make a new trade route we can still get the trade bonus. */
5917
5918 if (can_establish) {
5923 }
5924
5925 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
5927
5928 /* See if there's a trade route we can cancel at the home city. */
5929 if (home_overbooked >= 0) {
5930 if (home_max <= 0
5932 >= trade)) {
5935 _("Sorry, your %s cannot establish"
5936 " a trade route here!"),
5937 punit_link);
5938 if (home_max > 0) {
5941 PL_(" The city of %s already has %d "
5942 "better trade route!",
5943 " The city of %s already has %d "
5944 "better trade routes!", home_max),
5946 home_max);
5947 }
5949 }
5950 }
5951
5952 /* See if there's a trade route we can cancel at the dest city. */
5953 if (can_establish && dest_overbooked >= 0) {
5954 if (dest_max <= 0
5956 >= trade)) {
5959 _("Sorry, your %s cannot establish"
5960 " a trade route here!"),
5961 punit_link);
5962 if (dest_max > 0) {
5965 PL_(" The city of %s already has %d "
5966 "better trade route!",
5967 " The city of %s already has %d "
5968 "better trade routes!", dest_max),
5970 dest_max);
5971 }
5973 }
5974 }
5975 }
5976
5977 /* We now know for sure whether we can establish a trade route. */
5978
5979 /* Calculate and announce initial revenue. */
5980 revenue
5983
5984 bonus_type = trade_route_settings_by_type
5986
5988
5990
5991 /* We want to keep the bonus type string as the part of the format of the PL_() strings
5992 * for supporting proper pluralization for it. */
5993 switch (bonus_type) {
5994 case TBONUS_NONE:
5997 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
5998 _("Your %s from %s has arrived in %s carrying %s."),
5999 punit_link,
6002 goods_str);
6003 break;
6004 case TBONUS_GOLD:
6007 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6008 PL_("Your %s from %s has arrived in %s carrying %s,"
6009 " and revenues amount to %d in gold.",
6010 "Your %s from %s has arrived in %s carrying %s,"
6011 " and revenues amount to %d in gold.",
6012 revenue),
6013 punit_link,
6016 goods_str,
6017 revenue);
6018 break;
6019 case TBONUS_SCIENCE:
6022 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6023 PL_("Your %s from %s has arrived in %s carrying %s,"
6024 " and revenues amount to %d in research.",
6025 "Your %s from %s has arrived in %s carrying %s,"
6026 " and revenues amount to %d in research.",
6027 revenue),
6028 punit_link,
6031 goods_str,
6032 revenue);
6033 break;
6034 case TBONUS_BOTH:
6037 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6038 PL_("Your %s from %s has arrived in %s carrying %s,"
6039 " and revenues amount to %d in gold and research.",
6040 "Your %s from %s has arrived in %s carrying %s,"
6041 " and revenues amount to %d in gold and research.",
6042 revenue),
6043 punit_link,
6046 goods_str,
6047 revenue);
6048 break;
6049 }
6050
6051 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6052 pplayer->economic.gold += revenue;
6053
6054 send_player_info_c(pplayer, pplayer->connections);
6055 }
6056
6057 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6058 /* add bulbs and check for finished research */
6059 update_bulbs(pplayer, revenue, TRUE, TRUE);
6060
6061 /* Inform everyone about tech changes */
6063 }
6064
6065 if (can_establish) {
6067 struct city_list *cities_out_of_home;
6068 struct city_list *cities_out_of_dest;
6069 struct player *partner_player;
6070
6071 /* Announce creation of trade route (it's not actually created until
6072 * later in this function, as we have to cancel existing routes, but
6073 * it makes more sense to announce in this order) */
6074
6076
6077 /* Always tell the unit owner */
6078 notify_player(pplayer, NULL,
6080 _("New trade route established from %s to %s."),
6083 if (pplayer != partner_player) {
6086 _("The %s established a trade route between their "
6087 "city %s and %s."),
6088 nation_plural_for_player(pplayer),
6091 }
6092
6095
6096 /* Now cancel any less profitable trade route from the home city. */
6098 struct trade_route *pback;
6099
6101
6103 free(premove);
6104 free(pback);
6106
6107 /* And the same for the dest city. */
6109 struct trade_route *pback;
6110
6112
6114 free(premove);
6115 free(pback);
6117
6118 /* Actually create the new trade route */
6119 proute_from = fc_malloc(sizeof(struct trade_route));
6120 proute_from->partner = pcity_dest->id;
6121 proute_from->goods = goods;
6122
6123 proute_to = fc_malloc(sizeof(struct trade_route));
6124 proute_to->partner = pcity_homecity->id;
6125 proute_to->goods = goods;
6126
6130 } else {
6131 proute_from->dir = RDIR_FROM;
6132 proute_to->dir = RDIR_TO;
6133 }
6136
6137 /* Refresh the cities. */
6141 city_refresh(pcity);
6144 city_refresh(pcity);
6146
6147 /* Notify the owners of the cities. */
6151 send_city_info(city_owner(pcity), pcity);
6154 send_city_info(city_owner(pcity), pcity);
6156
6157 /* Notify each player about the other's cities. */
6158 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6162 send_city_info(pplayer, pcity_dest);
6163 }
6164
6166 if (partner_player != city_owner(pcity)) {
6169 }
6170 if (pplayer != city_owner(pcity)) {
6171 send_city_info(pplayer, pcity);
6173 }
6175
6177 if (partner_player != city_owner(pcity)) {
6180 }
6181 if (pplayer != city_owner(pcity)) {
6182 send_city_info(pplayer, pcity);
6184 }
6186
6189 }
6190
6191 /* May cause an incident */
6193 pplayer, act_utype, city_owner(pcity_dest),
6196
6198
6199 /* Free data. */
6202
6203 return TRUE;
6204}
6205
6206/**********************************************************************/
6214void handle_unit_sscs_set(struct player *pplayer,
6215 int unit_id,
6217 int value)
6218{
6219 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6220 const struct civ_map *nmap = &(wld.map);
6221
6222 if (NULL == punit) {
6223 /* Being asked to unqueue a "spent" unit because the client haven't
6224 * been told that it's gone is expected. */
6225 if (type != USSDT_UNQUEUE) {
6226 /* Probably died or bribed. */
6227 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6228 }
6229
6230 return;
6231 }
6232
6233 switch (type) {
6234 case USSDT_QUEUE:
6235 /* Reminds the client to ask the server about what actions the unit can
6236 * perform against the target tile. Action decision state can be set by
6237 * the server it self too. */
6238
6239 if (index_to_tile(nmap, value) == NULL) {
6240 /* Asked to be reminded to ask what actions the unit can do to a non
6241 * existing target tile. */
6242 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6243 value, unit_id);
6244 break;
6245 }
6246
6249
6250 /* Let the client know that this unit needs the player to decide
6251 * what to do. */
6253
6254 break;
6255 case USSDT_UNQUEUE:
6256 /* Delete the reminder for the client to ask the server about what
6257 * actions the unit can perform against a certain target tile.
6258 * Action decision state can be set by the server it self too. */
6259
6262
6263 /* Let the client know that this unit no longer needs the player to
6264 * decide what to do. */
6265 send_unit_info(pplayer->connections, punit);
6266
6267 break;
6268 case USSDT_BATTLE_GROUP:
6269 /* Battlegroups are handled entirely by the client, so all we have to
6270 do here is save the battlegroup ID so that it'll be persistent. */
6271
6273
6274 break;
6275 case USSDT_SENTRY:
6276 if (value == 0) {
6277 if (punit->activity != ACTIVITY_SENTRY) {
6278 return;
6279 }
6280
6282 /* Impossible to set to Idle? */
6284 }
6285 } else if (value == 1) {
6287 return;
6288 }
6289
6291 /* Should have been caught above */
6293 }
6294 } else {
6295 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6297 }
6298 break;
6299 }
6300}
6301
6302/**********************************************************************/
6305static void unit_plans_clear(struct unit *punit)
6306{
6307 /* Remove city spot reservations for AI settlers on city founding
6308 * mission. */
6310
6311 /* Get rid of old orders. */
6313
6314 /* Make sure that no old goto_tile remains. */
6315 punit->goto_tile = NULL;
6316}
6317
6318/**********************************************************************/
6322 int unit_id,
6324{
6325 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6326
6327 if (NULL == punit) {
6328 /* Probably died or bribed. */
6329 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6330 unit_id);
6331 return;
6332 }
6333
6335 /* Client error. */
6336 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6337 agent);
6338 return;
6339 }
6340
6341 /* Set the state or exit */
6342 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6343 return;
6344 }
6345
6346 /* Give the new agent a blank slate */
6348
6349 if (agent == SSA_AUTOEXPLORE) {
6351 /* Should have been caught above */
6354 }
6355
6356 /* Exploring is handled here explicitly, since the player expects to
6357 * see an immediate response from setting a unit to auto-explore.
6358 * Handling it deeper in the code leads to some tricky recursive loops -
6359 * see PR#2631. */
6360 if (punit->moves_left > 0) {
6362 }
6363 }
6364}
6365
6366/**********************************************************************/
6371 struct unit *punit,
6373{
6374 const struct civ_map *nmap = &(wld.map);
6375
6376 /* Check that the agent can be activated for this unit. */
6377 switch (agent) {
6378 case SSA_AUTOSETTLER:
6380 return FALSE;
6381 }
6382 break;
6383 case SSA_AUTOEXPLORE:
6385 return FALSE;
6386 }
6387 break;
6388 case SSA_NONE:
6389 /* Always possible. */
6390 break;
6391 case SSA_COUNT:
6393 break;
6394 }
6395
6396 if (punit->ssa_controller != agent) {
6399 }
6400
6401 return TRUE;
6402}
6403
6404/**********************************************************************/
6410 struct extra_type *old_target)
6411{
6412 switch (punit->activity) {
6413 case ACTIVITY_IDLE:
6414 switch (old_activity) {
6415 case ACTIVITY_PILLAGE:
6416 {
6417 if (old_target != NULL) {
6419 if (punit2->activity == ACTIVITY_PILLAGE) {
6420 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6421 if (pdep == old_target) {
6424 break;
6425 }
6427 }
6429 }
6430 break;
6431 }
6432 case ACTIVITY_EXPLORE:
6433 /* Restore unit's control status */
6435 break;
6436 default:
6437 ; /* do nothing */
6438 }
6439 break;
6440 case ACTIVITY_EXPLORE:
6444 break;
6445 default:
6446 /* do nothing */
6447 break;
6448 }
6449}
6450
6451/**********************************************************************/
6467
6468/**********************************************************************/
6473{
6474 const struct civ_map *nmap = &(wld.map);
6475
6476 /* Must specify target for ACTIVITY_BASE */
6479
6481 struct extra_type *target = NULL;
6482
6483 /* Assume untargeted pillaging if no target specified */
6488 }
6489
6490 return TRUE;
6491}
6492
6493/**********************************************************************/
6501{
6503 return FALSE;
6504 } else {
6507
6511
6512 return TRUE;
6513 }
6514}
6515
6516/**********************************************************************/
6534
6535/**********************************************************************/
6540 struct extra_type **new_target)
6541{
6547
6549
6550 if (list != NULL && action_list_size(list) > 0) {
6551 /* Trigger action system */
6553 (*new_target) != NULL ? (*new_target)->id : NO_TARGET,
6555 } else {
6557 }
6558 }
6559
6560 return TRUE;
6561}
6562
6563/**********************************************************************/
6571 struct extra_type **new_target)
6572{
6575 return FALSE;
6576 } else {
6580
6585 /* unit_assign_specific_activity_target() changed our target activity
6586 * (to ACTIVITY_IDLE in practice) */
6588 } else {
6592
6594 /* Casus Belli for when the activity successfully begins. */
6595 /* TODO: is it more logical to change Casus_Belli_Complete to
6596 * Casus_Belli_Successful_Beginning and trigger it here? */
6602 }
6603 }
6604
6605 return TRUE;
6606 }
6607}
6608
6609/**********************************************************************/
6612void handle_unit_orders(struct player *pplayer,
6613 const struct packet_unit_orders *packet)
6614{
6615 int length = packet->length;
6616 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6617 const struct civ_map *nmap = &(wld.map);
6618 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6619 struct unit_order *order_list;
6620#ifdef FREECIV_DEBUG
6621 int i;
6622#endif
6623
6624 if (NULL == punit) {
6625 /* Probably died or bribed. */
6626 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6627 return;
6628 }
6629
6630 if (0 > length || MAX_LEN_ROUTE < length) {
6631 /* Shouldn't happen */
6632 log_error("handle_unit_orders() invalid %s (%d) "
6633 "packet length %d (max %d)", unit_rule_name(punit),
6634 packet->unit_id, length, MAX_LEN_ROUTE);
6635 return;
6636 }
6637
6638 if (src_tile != unit_tile(punit)) {
6639 /* Failed sanity check. Usually this happens if the orders were sent
6640 * in the previous turn, and the client thought the unit was in a
6641 * different position than it's actually in. The easy solution is to
6642 * discard the packet. We don't send an error message to the client
6643 * here (though maybe we should?). */
6644 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6645 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6646 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6647 return;
6648 }
6649
6650 if (ACTIVITY_IDLE != punit->activity) {
6651 /* New orders implicitly abandon current activity */
6653 }
6654
6655 if (length) {
6656 order_list = create_unit_orders(nmap, length, packet->orders);
6657 if (!order_list) {
6658 log_error("received invalid orders from %s for %s (%d).",
6659 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6660 return;
6661 }
6662 }
6663
6664 /* This must be before old orders are freed. If this is
6665 * settlers on city founding mission, city spot reservation
6666 * from goto_tile must be freed, and free_unit_orders() loses
6667 * goto_tile information */
6669
6671 /* If we waited on a tile, reset punit->done_moving */
6672 punit->done_moving = (punit->moves_left <= 0);
6673
6674 if (length == 0) {
6677 return;
6678 }
6679
6681 punit->orders.length = length;
6682 punit->orders.index = 0;
6683 punit->orders.repeat = packet->repeat;
6684 punit->orders.vigilant = packet->vigilant;
6685 if (length) {
6687 }
6688
6689 if (!packet->repeat) {
6691 } else {
6692 /* Make sure that no old goto_tile remains. */
6693 punit->goto_tile = NULL;
6694 }
6695
6696#ifdef FREECIV_DEBUG
6697 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6698 for (i = 0; i < length; i++) {
6699 log_debug(" %d,%s,%s,%d,%d",
6700 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6701 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6703 packet->orders[i].order == ORDER_ACTIVITY ?
6705 "no action/activity required",
6706 packet->orders[i].target,
6707 packet->orders[i].sub_target);
6708 }
6709#endif /* FREECIV_DEBUG */
6710
6712 || execute_orders(punit, TRUE)) {
6713 /* Looks like the unit survived. */
6715 }
6716}
6717
6718/**********************************************************************/
6721void handle_worker_task(struct player *pplayer,
6722 const struct packet_worker_task *packet)
6723{
6724 struct city *pcity = game_city_by_number(packet->city_id);
6725 struct worker_task *ptask = NULL;
6726 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
6727
6728 if (pcity == NULL || pcity->owner != pplayer || ptile == NULL) {
6729 return;
6730 }
6731
6733 if (tile_index(ptask_old->ptile) == packet->tile_id) {
6734 ptask = ptask_old;
6735 }
6737
6738 if (ptask == NULL) {
6739 if (packet->activity == ACTIVITY_LAST) {
6740 return;
6741 }
6742
6743 ptask = fc_malloc(sizeof(struct worker_task));
6746 } else {
6747 if (packet->activity == ACTIVITY_LAST) {
6749 free(ptask);
6750 ptask = NULL;
6751 }
6752 }
6753
6754 if (ptask != NULL) {
6755 ptask->ptile = ptile;
6756 ptask->act = packet->activity;
6757 if (packet->tgt >= 0) {
6758 if (packet->tgt < MAX_EXTRA_TYPES) {
6759 ptask->tgt = extra_by_number(packet->tgt);
6760 } else {
6761 log_debug("Illegal worker task target %d", packet->tgt);
6762 ptask->tgt = NULL;
6763 }
6764 } else {
6765 ptask->tgt = NULL;
6766 }
6767 ptask->want = packet->want;
6768 }
6769
6770 if (ptask && !worker_task_is_sane(ptask)) {
6771 log_debug("Bad worker task");
6773 free(ptask);
6774 ptask = NULL;
6775 return;
6776 }
6777
6778 lsend_packet_worker_task(pplayer->connections, packet);
6779}
const char * action_name_translation(const struct action *action)
Definition actions.c:1991
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1934
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:6292
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2011
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5821
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3356
struct act_prob action_prob_vs_tile(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5342
const char * action_id_rule_name(action_id act_id)
Definition actions.c:2000
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:8145
int action_number(const struct action *action)
Definition actions.c:1969
bool is_action_enabled_unit_on_tile(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4082
struct act_prob action_prob_vs_extras(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5425
struct act_prob action_prob_self(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id)
Definition actions.c:5495
bool is_action_enabled_unit_on_city(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Definition actions.c:3841
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:3918
struct act_prob action_prob_vs_city(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:4984
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:6237
struct action * action_is_blocked_by(const struct civ_map *nmap, const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:3036
bool action_id_exists(const action_id act_id)
Definition actions.c:1829
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1869
struct act_prob action_prob_unit_vs_tgt(const struct civ_map *nmap, 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)
Definition actions.c:5517
struct act_prob action_prob_vs_stack(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:5259
struct act_prob action_prob_vs_unit(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5067
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2315
#define ACTPROB_NA
Definition actions.h:924
static struct action * action_by_number(action_id act_id)
Definition actions.h:635
#define action_has_result(_act_, _res_)
Definition actions.h:431
#define action_enabler_list_iterate_end
Definition actions.h:441
#define action_id_get_role(act_id)
Definition actions.h:696
#define action_iterate_end
Definition actions.h:465
#define MAX_NUM_ACTIONS
Definition actions.h:314
#define action_id_get_actor_kind(act_id)
Definition actions.h:648
#define ACTPROB_NOT_KNOWN
Definition actions.h:926
#define action_get_activity(_pact_)
Definition actions.h:699
#define action_has_result_safe(paction, result)
Definition actions.h:663
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:439
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:684
#define ACTPROB_IMPOSSIBLE
Definition actions.h:922
#define action_iterate(_act_)
Definition actions.h:461
#define ACTION_ANY
Definition actions.h:308
#define action_id_get_target_kind(act_id)
Definition actions.h:652
#define action_id_has_result_safe(act_id, result)
Definition actions.h:665
#define action_id_has_complex_target(act_id)
Definition actions.h:670
#define ACTION_NONE
Definition actions.h:311
struct tile * action_tgt_tile(struct unit *actor, struct tile *target, const struct extra_type *target_extra, bool accept_all_actions)
void action_consequence_caught(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
const struct action * action_auto_perf_unit_do(const enum action_auto_perf_cause cause, struct unit *actor, const struct player *other_player, const struct output_type *eval_output, const struct action *eval_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, const struct extra_type *target_extra)
struct unit * action_tgt_unit(struct unit *actor, struct tile *target_tile, bool accept_all_actions)
void action_consequence_success(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
struct city * action_tgt_city(struct unit *actor, struct tile *target_tile, bool accept_all_actions)
struct extra_type * action_tgt_tile_extra(const struct unit *actor, const struct tile *target_tile, bool accept_all_actions)
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)
int action_sub_target_id_for_action(const struct action *paction, struct unit *actor_unit)
#define ASSERT_UNUSED_ACTRES_CASES
Definition actres.h:37
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:377
void astr_free(struct astring *astr)
Definition astring.c:153
const char * astr_build_or_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:329
#define n
Definition astring.c:77
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:101
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:139
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
void citizens_update(struct city *pcity, struct player *plr)
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1860
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
bool is_capital(const struct city *pcity)
Definition city.c:1579
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1465
void city_size_add(struct city *pcity, int add)
Definition city.c:1164
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2012
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2051
bool city_exist(int id)
Definition city.c:3572
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:700
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:770
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_owner(_pcity_)
Definition city.h:563
#define city_list_iterate_end
Definition city.h:510
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2363
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1519
int build_points_left(struct city *pcity)
Definition citytools.c:576
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3068
void city_units_upkeep(const struct city *pcity)
Definition citytools.c:3156
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:374
void remove_city(struct city *pcity)
Definition citytools.c:1708
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Definition citytools.c:2936
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3544
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, const char *reason)
Definition cityturn.c:1032
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3432
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:763
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
static struct fc_sockaddr_list * list
Definition clinet.c:102
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Definition combat.c:85
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:256
struct city * sdi_try_defend(const struct civ_map *nmap, const struct player *owner, const struct tile *ptile)
Definition combat.c:501
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:767
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:610
bool is_tired_attack(int moves_left)
Definition combat.c:527
enum unit_attack_result unit_wipe_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Definition combat.c:271
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:836
void get_modified_firepower(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, int *att_fp, int *def_fp)
Definition combat.c:409
#define POWER_FACTOR
Definition combat.h:32
@ ATT_NOT_WIPABLE
Definition combat.h:40
@ ATT_NONNATIVE_DST
Definition combat.h:39
@ ATT_OK
Definition combat.h:35
@ ATT_NON_ATTACK
Definition combat.h:36
@ ATT_UNREACHABLE
Definition combat.h:37
@ ATT_NONNATIVE_SRC
Definition combat.h:38
char * incite_cost
Definition comments.c:75
#define MAX_LEN_MSG
Definition conn_types.h:37
#define MAX_LEN_ROUTE
Definition conn_types.h:38
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:366
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:356
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
#define conn_list_iterate_end
Definition connection.h:110
static void bombard(QVariant data1, QVariant data2)
Definition dialogs.cpp:2766
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:56
struct unit * actor_unit
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city * target_city
Definition dialogs_g.h:56
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:57
bool spy_escape(struct player *pplayer, struct unit *actor_unit, struct city *target_city, struct tile *target_tile, const struct action *paction)
Definition diplomats.c:2346
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1698
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:548
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:483
void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat, struct city *pcity, const struct action *paction, int request_kind)
Definition diplomats.c:429
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Definition diplomats.c:891
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1284
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1135
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1556
bool spy_spread_plague(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:214
bool spy_nuke_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1834
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:324
bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:643
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:807
bool spy_poison(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:97
int int id
Definition editgui_g.h:28
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:748
enum event_type event
Definition events.c:81
ane_kind
Definition explanation.h:22
@ ANEK_IS_CITY_CENTER
Definition explanation.h:62
@ ANEK_ACTION_BLOCKS
Definition explanation.h:98
@ ANEK_DOMESTIC
Definition explanation.h:50
@ ANEK_LOW_MP
Definition explanation.h:60
@ ANEK_TGT_TILE_UNKNOWN
Definition explanation.h:94
@ ANEK_BAD_TERRAIN_TGT
Definition explanation.h:32
@ ANEK_TRIREME_MOVE
Definition explanation.h:74
@ ANEK_CITY_TOO_CLOSE_TGT
Definition explanation.h:83
@ ANEK_CITY_NO_CAPACITY
Definition explanation.h:89
@ ANEK_NATION_TGT
Definition explanation.h:58
@ ANEK_BAD_TARGET
Definition explanation.h:28
@ ANEK_MISSING_TARGET
Definition explanation.h:26
@ ANEK_TGT_IS_CLAIMED
Definition explanation.h:66
@ ANEK_FOREIGN
Definition explanation.h:52
@ ANEK_DISEMBARK_ACT
Definition explanation.h:77
@ ANEK_IS_TRANSPORTED
Definition explanation.h:34
@ ANEK_IS_NOT_CITY_CENTER
Definition explanation.h:64
@ ANEK_TGT_IS_UNCLAIMED
Definition explanation.h:68
@ ANEK_TGT_NON_ALLIED_UNITS_ON_TILE
Definition explanation.h:54
@ ANEK_BAD_TERRAIN_ACT
Definition explanation.h:30
@ ANEK_SCENARIO_DISABLED
Definition explanation.h:81
@ ANEK_ACTOR_HAS_HOME_CITY
Definition explanation.h:42
@ ANEK_PEACE
Definition explanation.h:48
@ ANEK_DISTANCE_NEAR
Definition explanation.h:70
@ ANEK_UNKNOWN
@ ANEK_ACT_NOT_ENOUGH_MONEY
Definition explanation.h:96
@ ANEK_IS_NOT_TRANSPORTING
Definition explanation.h:40
@ ANEK_TGT_UNREACHABLE
Definition explanation.h:79
@ ANEK_ACTOR_HAS_NO_HOME_CITY
Definition explanation.h:44
@ ANEK_NOT_WIPABLE
@ ANEK_CITY_TOO_BIG
Definition explanation.h:85
@ ANEK_NO_WAR
Definition explanation.h:46
@ ANEK_DISTANCE_FAR
Definition explanation.h:72
@ ANEK_ACTOR_UNIT
Definition explanation.h:24
@ ANEK_NATION_ACT
Definition explanation.h:56
@ ANEK_IS_NOT_TRANSPORTED
Definition explanation.h:36
@ ANEK_IS_TRANSPORTING
Definition explanation.h:38
@ ANEK_CITY_POP_LIMIT
Definition explanation.h:87
@ ANEK_TGT_IS_UNIQUE_ACT_HAS
Definition explanation.h:92
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:765
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1114
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:790
struct extra_type * extra_by_number(int id)
Definition extras.c:183
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:371
#define extra_deps_iterate_end
Definition extras.h:379
#define EXTRA_NONE
Definition extras.h:85
#define NO_TARGET
Definition fc_types.h:354
int Impr_type_id
Definition fc_types.h:376
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:370
int action_id
Definition fc_types.h:389
#define ACTRES_NONE
Definition fc_types.h:327
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:66
int Unit_type_id
Definition fc_types.h:382
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:92
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * city_tile_link(const struct city *pcity)
const char * tile_link(const struct tile *ptile)
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
const char * unit_link(const struct unit *punit)
const char * unit_tile_link(const struct unit *punit)
#define MAX_LEN_LINK
struct civ_game game
Definition game.c:62
bool is_player_phase(const struct player *pplayer, int phase)
Definition game.c:707
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:116
struct city * game_city_by_number(int id)
Definition game.c:107
static int actor_unit_id
static int target_extra_id
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
struct impr_type * improvement_by_number(const Impr_type_id id)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:1937
const char * dir_get_name(enum direction8 dir)
Definition map.c:1146
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:456
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:630
bool base_get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile, enum direction8 *dir)
Definition map.c:1328
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:293
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2533
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:894
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:768
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:920
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:864
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1382
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1015
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, bool enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:630
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:319
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:331
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:911
enum unit_move_result unit_teleport_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 enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:774
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:491
bool unit_can_move_to_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *dst_tile, bool igzoc, bool enter_transport, bool enter_enemy_city)
Definition movement.c:572
#define SINGLE_MOVE
Definition movement.h:26
unit_move_result
Definition movement.h:34
@ MR_CANNOT_DISEMBARK
Definition movement.h:48
@ MR_OK
Definition movement.h:35
@ MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT
Definition movement.h:45
@ MR_TRIREME
Definition movement.h:47
@ MR_NON_NATIVE_MOVE
Definition movement.h:49
@ MR_PEACE
Definition movement.h:39
@ MR_ZOC
Definition movement.h:40
@ MR_NO_WAR
Definition movement.h:38
static const char * name_translation_get(const struct name_translation *ptrans)
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:463
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
const char * nation_adjective_translation(const struct nation_type *pnation)
Definition nation.c:149
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
@ UNIT_INFO_IDENTITY
Definition packets.h:67
void dlsend_packet_nuke_tile_info(struct conn_list *dest, int tile)
void lsend_packet_worker_task(struct conn_list *dest, const struct packet_worker_task *packet)
int dsend_packet_unit_actions(struct connection *pc, int actor_unit_id, int target_unit_id, int target_city_id, int target_tile_id, int target_extra_id, int request_kind, const struct act_prob *action_probabilities)
int send_packet_unit_short_info(struct connection *pc, const struct packet_unit_short_info *packet, bool force_to_send)
void lsend_packet_unit_combat_info(struct conn_list *dest, const struct packet_unit_combat_info *packet)
int dsend_packet_unit_action_answer(struct connection *pc, int actor_id, int target_id, int cost, action_id action_type, int request_kind)
int send_packet_unit_info(struct connection *pc, const struct packet_unit_info *packet)
int send_packet_unit_combat_info(struct connection *pc, const struct packet_unit_combat_info *packet)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
const char * player_name(const struct player *pplayer)
Definition player.c:895
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1104
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1337
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1459
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1133
#define players_iterate_end
Definition player.h:537
#define players_iterate(_pplayer)
Definition player.h:532
int normal_player_count(void)
Definition plrhand.c:3204
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2955
void maybe_make_contact(struct tile *ptile, struct player *pplayer)
Definition plrhand.c:2361
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1146
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3005
struct conn_list * player_reply_dest(struct player *pplayer)
Definition plrhand.c:1593
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2908
#define fc_rand(_size)
Definition rand.h:56
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
#define requirement_fulfilled_by_terrain(_ter_, _rqs_)
#define requirement_fulfilled_by_nation(_nat_, _rqs_)
struct research * research_get(const struct player *pplayer)
Definition research.c:128
#define sanity_check_city(x)
Definition sanitycheck.h:41
void script_server_signal_emit(const char *signal_name,...)
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
void spaceship_lost(struct player *pplayer)
Definition spacerace.c:431
@ SSHIP_STARTED
Definition spaceship.h:84
@ SSHIP_LAUNCHED
Definition spaceship.h:85
#define DEFAULT_SPECIALIST
Definition specialist.h:43
size_t size
Definition specvec.h:72
Definition agents.h:40
int distance
Definition unithand.c:107
struct player * no_war_with
Definition unithand.c:92
struct action * blocker
Definition unithand.c:104
const struct unit_type * no_tgt_utype
Definition unithand.c:101
struct terrain * no_act_terrain
Definition unithand.c:89
struct city * capacity_city
Definition unithand.c:86
struct player * peace_with
Definition unithand.c:95
struct nation_type * no_act_nation
Definition unithand.c:98
int gold_needed
Definition unithand.c:110
enum ane_kind kind
Definition unithand.c:82
Definition city.h:320
struct worker_task_list * task_reqs
Definition city.h:412
int id
Definition city.h:326
struct player * owner
Definition city.h:323
citizens * nationality
Definition city.h:341
citizens specialists[SP_MAX]
Definition city.h:336
struct tile * tile
Definition city.h:322
int upgrade_veteran_loss
Definition game.h:203
struct packet_ruleset_control control
Definition game.h:83
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
int occupychance
Definition game.h:174
struct civ_game::@31::@35 server
bool homecaughtunits
Definition game.h:192
enum goods_selection_method goods_selection
struct unit_order orders[MAX_LEN_ROUTE]
enum unit_activity activity
enum diplstate_type type
Definition player.h:197
int units_lost
Definition player.h:104
struct unit_list * units
Definition player.h:280
struct conn_list * connections
Definition player.h:296
struct player_economic economic
Definition player.h:282
struct player_score score
Definition player.h:281
const struct player * player
Definition tile.h:50
int index
Definition tile.h:51
struct unit_list * units
Definition tile.h:58
enum trade_route_bonus_type bonus_type
Definition traderoutes.h:78
enum adv_unit_task task
Definition unit.h:89
enum unit_activity activity
Definition unit.h:94
enum unit_orders order
Definition unit.h:93
int action
Definition unit.h:100
enum direction8 dir
Definition unit.h:102
int target
Definition unit.h:97
int sub_target
Definition unit.h:98
int paratroopers_range
Definition unittype.h:541
int city_size
Definition unittype.h:550
Definition unit.h:138
int length
Definition unit.h:195
bool has_orders
Definition unit.h:193
struct unit::@80 orders
enum action_decision action_decision_want
Definition unit.h:202
int battlegroup
Definition unit.h:191
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
bool moved
Definition unit.h:173
int index
Definition unit.h:195
struct vision * vision
Definition unit.h:244
bool vigilant
Definition unit.h:197
int hp
Definition unit.h:151
enum direction8 facing
Definition unit.h:142
struct unit::@81::@84 server
struct tile * tile
Definition unit.h:140
struct extra_type * activity_target
Definition unit.h:164
struct unit_order * list
Definition unit.h:198
struct unit_adv * adv
Definition unit.h:236
bool repeat
Definition unit.h:196
int homecity
Definition unit.h:146
bool done_moving
Definition unit.h:181
struct goods_type * carrying
Definition unit.h:186
struct tile * goto_tile
Definition unit.h:155
struct tile * action_decision_tile
Definition unit.h:203
const struct unit_type * utype
Definition unit.h:139
int veteran
Definition unit.h:152
struct player * owner
Definition unit.h:143
enum server_side_agent ssa_controller
Definition unit.h:172
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define bool
Definition support.h:71
#define fc__fallthrough
Definition support.h:119
#define A_UNSET
Definition tech.h:48
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Definition techtools.c:293
void update_bulbs(struct player *pplayer, int bulbs, bool check_tech, bool free_bulbs)
Definition techtools.c:654
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:238
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c:407
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:88
#define tile_terrain(_tile)
Definition tile.h:110
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_owner(_tile)
Definition tile.h:96
struct goods_type * goods_from_city_to_unit(struct city *src, struct unit *punit)
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
enum trade_route_type cities_trade_route_type(const struct city *pcity1, const struct city *pcity2)
Definition traderoutes.c:58
int trade_base_between_cities(const struct city *pc1, const struct city *pc2)
int city_num_trade_routes(const struct city *pcity)
static struct goods_type goods[MAX_GOODS_TYPES]
Definition traderoutes.c:43
bool goods_has_flag(const struct goods_type *pgood, enum goods_flag_id flag)
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
unsigned max_trade_routes(const struct city *pcity)
Definition traderoutes.c:48
const char * goods_name_translation(struct goods_type *pgood)
int city_trade_removable(const struct city *pcity, struct trade_route_list *would_remove)
bool have_cities_trade_route(const struct city *pc1, const struct city *pc2)
int get_caravan_enter_city_trade_bonus(const struct city *pc1, const struct city *pc2, const struct unit_type *ut, struct goods_type *pgood, const bool establish_trade)
#define trade_route_list_iterate(trade_route_list, proute)
Definition traderoutes.h:95
#define trade_route_list_iterate_end
Definition traderoutes.h:97
struct unit_order * create_unit_orders(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2834
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:214
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1783
void free_unit_orders(struct unit *punit)
Definition unit.c:1769
bool unit_is_alive(int id)
Definition unit.c:2253
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1922
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1088
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1245
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2441
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2390
enum unit_airlift_result test_unit_can_airlift_to(const struct civ_map *nmap, const struct player *restriction, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:81
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:841
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2304
bool can_unit_do_autosettlers(const struct unit *punit)
Definition unit.c:606
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:359
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1105
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:868
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1988
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2425
bool unit_has_orders(const struct unit *punit)
Definition unit.c:202
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:566
bool can_unit_do_activity_targeted(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, struct extra_type *target)
Definition unit.c:907
#define unit_tile(_pu)
Definition unit.h:397
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_owner(_pu)
Definition unit.h:396
@ UU_NO_MONEY
Definition unit.h:63
#define MAX_NUM_BATTLEGROUPS
Definition unit.h:189
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:432
@ AR_SRC_NO_FLIGHTS
Definition unit.h:84
@ AR_DST_NO_FLIGHTS
Definition unit.h:85
#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer)
static bool rel_may_become_war(const struct player *pplayer, const struct player *oplayer)
Definition unithand.c:1013
static bool do_unit_change_homecity(struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4118
static bool do_unit_upgrade(struct player *pplayer, struct unit *punit, struct city *pcity, enum action_requester ordered_by, const struct action *paction)
Definition unithand.c:255
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)
Definition unithand.c:3277
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4887
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4432
#define ACTION_PERFORM_UNIT_UNITS(action, actor, target, action_performer)
static bool do_unit_make_homeless(struct unit *punit, const struct action *paction)
Definition unithand.c:998
static bool non_allied_not_listed_at(const struct player *pplayer, const int *list, int n, const struct tile *ptile)
Definition unithand.c:285
void handle_unit_orders(struct player *pplayer, const struct packet_unit_orders *packet)
Definition unithand.c:6612
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)
Definition unithand.c:2492
static bool do_heal_unit(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:724
static bool do_capture_units(struct player *pplayer, struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:314
static bool do_expel_unit(struct player *pplayer, struct unit *actor, struct unit *target, const struct action *paction)
Definition unithand.c:595
static bool do_unit_conquer_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, struct action *paction)
Definition unithand.c:5386
static bool does_nation_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct nation_type *pnation)
Definition unithand.c:1387
#define ACTION_PERFORM_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)
Definition unithand.c:4312
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:6721
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6471
static bool occupy_move(struct tile *def_tile, struct unit *punit, const struct action *paction)
Definition unithand.c:498
static bool do_unit_embark(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:961
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)
Definition unithand.c:3313
#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer)
static bool do_unit_strike_city_production(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition unithand.c:5196
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)
Definition unithand.c:2968
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)
Definition unithand.c:1933
static const char * unit_tired_attack_string(const struct unit *punit)
Definition unithand.c:4840
static bool do_unit_deboard(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:823
static bool does_terrain_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct terrain *pterrain)
Definition unithand.c:1345
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Definition unithand.c:6408
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3144
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4527
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5533
static bool unit_do_destroy_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition unithand.c:4714
static void handle_unit_change_activity_real(struct player *pplayer, int unit_id, enum unit_activity activity, struct extra_type *activity_target)
Definition unithand.c:4263
#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer)
void handle_unit_server_side_agent_set(struct player *pplayer, int unit_id, enum server_side_agent agent)
Definition unithand.c:6321
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)
Definition unithand.c:3293
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)
Definition unithand.c:1429
static bool do_action_activity(struct unit *punit, const struct action *paction)
Definition unithand.c:6457
static bool do_unit_strike_city_building(struct player *act_player, struct unit *act_unit, struct city *tgt_city, Impr_type_id tgt_bld_id, const struct action *paction)
Definition unithand.c:5283
static bool need_war_enabler(const struct unit_type *actor_utype, const struct action *paction, struct player *player1, struct player *player2, bool act_if_diplrel_kind(const struct unit_type *, const action_id, const int, const bool))
Definition unithand.c:1037
static bool do_unit_unload(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:886
void unit_change_homecity_handling(struct unit *punit, struct city *new_pcity, bool rehome)
Definition unithand.c:4016
static bool unit_activity_targeted_internal(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Definition unithand.c:6569
static bool tile_has_units_not_allied_to_but_seen_by(const struct tile *ptile, const struct player *pplayer)
Definition unithand.c:1327
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Definition unithand.c:6522
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)
Definition unithand.c:1291
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5726
void handle_unit_type_upgrade(struct player *pplayer, Unit_type_id uti)
Definition unithand.c:185
static bool city_add_unit(struct player *pplayer, struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4152
static bool do_unit_load(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:865
static bool unit_activity_internal(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6499
void handle_unit_action_query(struct connection *pc, const int actor_id, const int target_id, const action_id action_type, int request_kind)
Definition unithand.c:3163
static bool do_wipe_units(struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:542
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Definition unithand.c:6538
static bool unit_nuke(struct player *pplayer, struct unit *punit, struct tile *def_tile, const struct action *paction)
Definition unithand.c:4644
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)
Definition unithand.c:5424
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 int request_kind)
Definition unithand.c:2228
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Definition unithand.c:6214
static bool do_unit_board(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:842
static void see_combat(struct unit *pattacker, struct unit *pdefender)
Definition unithand.c:4373
#define ACTION_PERFORM_UNIT_ANY(paction, actor, target_city, target_unit, target_tile, action_performer)
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)
Definition unithand.c:1078
static const char * unit_achieved_rank_string(const struct unit *punit)
Definition unithand.c:4823
static bool unit_do_regular_move(struct player *actor_player, struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:5495
static bool do_conquer_extras(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:685
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6370
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5841
static bool do_disembark(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:903
static void unit_plans_clear(struct unit *punit)
Definition unithand.c:6305
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4214
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4477
static bool do_unit_hut(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:931
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)
Definition unithand.c:1913
#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)
static const char * unit_firepower_if_not_one(int firepower)
Definition unithand.c:4862
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4802
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, int request_kind, const enum action_requester requester)
Definition unithand.c:3085
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void unit_bombs_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp, const struct action *paction)
Definition unittools.c:355
void unit_did_action(struct unit *punit)
Definition unittools.c:4901
void collect_ransom(struct unit *pcollector, struct unit *punit, bool vet)
Definition unittools.c:2494
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Definition unittools.c:2911
bool execute_orders(struct unit *punit, const bool fresh)
Definition unittools.c:4354
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1545
bool unit_versus_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp, int *att_vet, int *def_vet, const struct action *paction)
Definition unittools.c:288
void combat_veterans(struct unit *attacker, struct unit *defender, bool powerless, int att_vet, int def_vet)
Definition unittools.c:400
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:2879
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Definition unittools.c:2584
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2709
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2722
void notify_unit_experience(struct unit *punit)
Definition unittools.c:743
void unit_activities_cancel(struct unit *punit)
Definition unittools.c:796
void package_short_unit(struct unit *punit, struct packet_unit_short_info *packet, enum unit_info_use packet_use, int info_city_id)
Definition unittools.c:2665
void unit_forget_last_activity(struct unit *punit)
Definition unittools.c:1049
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:4840
void do_explore(struct unit *punit)
Definition unittools.c:2944
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3229
bool unit_can_do_action_now(const struct unit *punit)
Definition unittools.c:4868
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2131
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unittools.c:2980
void unit_transport_unload_send(struct unit *punit)
Definition unittools.c:3281
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2191
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1183
void unit_assign_specific_activity_target(struct unit *punit, enum unit_activity *activity, struct extra_type **target)
Definition unittools.c:1078
void unit_get_goods(struct unit *punit)
Definition unittools.c:1608
bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed, bool conquer_extras_allowed, bool enter_hut, bool frighten_hut)
Definition unittools.c:3918
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Definition unittools.c:2258
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1221
bool unit_activity_needs_target_from_client(enum unit_activity activity)
Definition unittools.c:1058
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)
Definition unittype.c:1124
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1632
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1569
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1249
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1927
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1703
Unit_type_id utype_count(void)
Definition unittype.c:80
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)
Definition unittype.c:955
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2499
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2597
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1219
bool utype_can_act_if_tgt_diplrel_tile_other(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1036
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1543
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
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)
Definition unittype.c:1017
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1668
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1731
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:766
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_type_iterate(_p)
Definition unittype.h:855
#define unit_type_iterate_end
Definition unittype.h:862
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Definition vision.c:33
void vision_free(struct vision *vision)
Definition vision.c:50
bool worker_task_is_sane(struct worker_task *ptask)
Definition workertask.c:40
void worker_task_init(struct worker_task *ptask)
Definition workertask.c:31
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35