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(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
3099
3100 /* Why didn't the game check before trying something illegal? Did a good
3101 * reason to not call is_action_enabled_unit_on...() appear? The game is
3102 * omniscient... */
3104
3105
3108 actor,
3110 target_tile, NULL));
3111
3112 if (request_kind == REQEST_PLAYER_INITIATED) {
3113 /* This is a foreground request. */
3118 }
3119
3123 requester);
3124
3125 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3126 /* FIXME: Temporary work around to prevent wrong information and/or
3127 * crashes. See hrm Bug #879880 */
3128 /* TODO: Get the explanation before the punishment and show it here.
3129 * See hrm Bug #879881 */
3130 notify_player(pplayer, unit_tile(actor),
3133 _("No explanation why you couldn't do %s. This is a bug."
3134 " Sorry about that. -- Sveinung"),
3136 }
3137}
3138
3139/**********************************************************************/
3143 const int actor_id,
3144 const int target_id,
3145 int request_kind)
3146{
3148 actor_id, target_id,
3149 0,
3151 request_kind);
3152}
3153
3154/**********************************************************************/
3162 const int actor_id,
3163 const int target_id,
3164 const action_id action_type,
3165 int request_kind)
3166{
3167 struct player *pplayer = pc->playing;
3168 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3169 struct action *paction = action_by_number(action_type);
3170 struct unit *punit = game_unit_by_number(target_id);
3171 struct city *pcity = game_city_by_number(target_id);
3172 const struct civ_map *nmap = &(wld.map);
3173
3174 if (NULL == paction) {
3175 /* Non existing action */
3176 log_error("handle_unit_action_query() the action %d doesn't exist.",
3177 action_type);
3178
3179 unit_query_impossible(pc, actor_id, target_id, request_kind);
3180 return;
3181 }
3182
3183 if (NULL == pactor) {
3184 /* Probably died or bribed. */
3185 log_verbose("handle_unit_action_query() invalid actor %d",
3186 actor_id);
3187 unit_query_impossible(pc, actor_id, target_id, request_kind);
3188 return;
3189 }
3190
3191 switch (paction->result) {
3193 if (punit
3194 && is_action_enabled_unit_on_unit(nmap, action_type,
3195 pactor, punit)) {
3197 actor_id, target_id,
3198 unit_bribe_cost(punit, pplayer),
3199 action_type, request_kind);
3200 } else {
3201 illegal_action(pplayer, pactor, action_type,
3203 NULL, NULL, punit, request_kind, ACT_REQ_PLAYER);
3204 unit_query_impossible(pc, actor_id, target_id, request_kind);
3205 return;
3206 }
3207 break;
3209 if (pcity
3210 && is_action_enabled_unit_on_city(nmap, action_type,
3211 pactor, pcity)) {
3213 actor_id, target_id,
3214 city_incite_cost(pplayer, pcity),
3215 action_type, request_kind);
3216 } else {
3217 illegal_action(pplayer, pactor, action_type,
3218 pcity ? city_owner(pcity) : NULL,
3219 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3220 unit_query_impossible(pc, actor_id, target_id, request_kind);
3221 return;
3222 }
3223 break;
3225 if (pcity
3226 && is_action_enabled_unit_on_city(nmap, action_type,
3227 pactor, pcity)) {
3228 const struct unit_type *tgt_utype;
3229 int upgr_cost;
3230
3232 /* Already checked via is_action_enabled_unit_on_city() */
3234 upgr_cost = unit_upgrade_price(pplayer,
3236
3238 actor_id, target_id,
3239 upgr_cost, action_type,
3240 request_kind);
3241 } else {
3242 illegal_action(pplayer, pactor, action_type,
3243 pcity ? city_owner(pcity) : NULL,
3244 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3245 unit_query_impossible(pc, actor_id, target_id, request_kind);
3246 return;
3247 }
3248 break;
3251 if (pcity
3252 && is_action_enabled_unit_on_city(nmap, action_type,
3253 pactor, pcity)) {
3255 action_by_number(action_type), request_kind);
3256 } else {
3257 illegal_action(pplayer, pactor, action_type,
3258 pcity ? city_owner(pcity) : NULL,
3259 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3260 unit_query_impossible(pc, actor_id, target_id, request_kind);
3261 return;
3262 }
3263 break;
3264 default:
3265 unit_query_impossible(pc, actor_id, target_id, request_kind);
3266 return;
3267 };
3268}
3269
3270/**********************************************************************/
3275void handle_unit_do_action(struct player *pplayer,
3276 const int actor_id,
3277 const int target_id,
3278 const int sub_tgt_id,
3279 const char *name,
3280 const action_id action_type)
3281{
3282 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3283 action_type, ACT_REQ_PLAYER);
3284}
3285
3286/**********************************************************************/
3291void unit_do_action(struct player *pplayer,
3292 const int actor_id,
3293 const int target_id,
3294 const int sub_tgt_id,
3295 const char *name,
3296 const action_id action_type)
3297{
3298 unit_perform_action(pplayer, actor_id, target_id,
3299 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3300}
3301
3302/**********************************************************************/
3311bool unit_perform_action(struct player *pplayer,
3312 const int actor_id,
3313 const int target_id,
3314 const int sub_tgt_id_incoming,
3315 const char *name,
3316 const action_id action_type,
3317 const enum action_requester requester)
3318{
3319 struct action *paction;
3320 int sub_tgt_id;
3321 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3322 struct tile *target_tile = NULL;
3323 struct extra_type *target_extra;
3324 struct impr_type *sub_tgt_impr;
3325 struct unit *punit = NULL;
3326 struct city *pcity = NULL;
3327 const struct civ_map *nmap = &(wld.map);
3328
3329 if (!action_id_exists(action_type)) {
3330 /* Non existing action */
3331 log_error("unit_perform_action() the action %d doesn't exist.",
3332 action_type);
3333
3334 return FALSE;
3335 }
3336
3337 paction = action_by_number(action_type);
3338
3339 if (NULL == actor_unit) {
3340 /* Probably died or bribed. */
3341 log_verbose("unit_perform_action() invalid actor %d",
3342 actor_id);
3343 return FALSE;
3344 }
3345
3347 case ATK_CITY:
3348 pcity = game_city_by_number(target_id);
3349 if (pcity == NULL) {
3350 log_verbose("unit_perform_action() invalid target city %d",
3351 target_id);
3352 return FALSE;
3353 }
3354 target_tile = city_tile(pcity);
3356 break;
3357 case ATK_UNIT:
3358 punit = game_unit_by_number(target_id);
3359 if (punit == NULL) {
3360 log_verbose("unit_perform_action() invalid target unit %d",
3361 target_id);
3362 return FALSE;
3363 }
3366 pcity = tile_city(target_tile);
3367 break;
3368 case ATK_UNITS:
3369 case ATK_TILE:
3370 case ATK_EXTRAS:
3371 target_tile = index_to_tile(nmap, target_id);
3372 if (target_tile == NULL) {
3373 log_verbose("unit_perform_action() invalid target tile %d",
3374 target_id);
3375 return FALSE;
3376 }
3377 pcity = tile_city(target_tile);
3378 break;
3379 case ATK_SELF:
3382 pcity = tile_city(target_tile);
3383 break;
3384 case ATK_COUNT:
3386 break;
3387 }
3388
3389 /* Server side sub target assignment */
3390 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3393 } else {
3394 sub_tgt_id = sub_tgt_id_incoming;
3395 }
3396
3397 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3398 && sub_tgt_id != NO_TARGET) {
3399 target_extra = extra_by_number(sub_tgt_id);
3400 fc_assert(!(target_extra->ruledit_disabled));
3401 } else {
3403 }
3404
3405 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3406
3407 /* Sub targets should now be assigned */
3408 switch (paction->sub_target_kind) {
3409 case ASTK_NONE:
3410 /* No sub target. */
3411 break;
3412 case ASTK_BUILDING:
3413 if (sub_tgt_impr == NULL) {
3414 /* Missing sub target */
3415 return FALSE;
3416 }
3417 break;
3418 case ASTK_TECH:
3419 /* Not handled here yet */
3420 break;
3421 case ASTK_EXTRA:
3423 if (target_extra == NULL) {
3424 /* Missing sub target */
3425 return FALSE;
3426 }
3427 break;
3428 case ASTK_COUNT:
3429 break;
3430 }
3431
3435 && target_extra == NULL) {
3436 /* Missing required action extra target. */
3437 log_verbose("unit_perform_action() action %d requires action "
3438 "but extra id %d is invalid.",
3439 action_type, sub_tgt_id);
3440 return FALSE;
3441 }
3442
3443 if (paction->actor.is_unit.unitwaittime_controlled
3445 /* Action not possible due to unitwaittime setting. */
3446 return FALSE;
3447 }
3448
3449#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3450 if (pcity \
3451 && is_action_enabled_unit_on_city(nmap, action_type, \
3452 actor_unit, pcity)) { \
3453 bool success; \
3454 script_server_signal_emit("action_started_unit_city", \
3455 action_by_number(action), actor, target); \
3456 if (!actor || !unit_is_alive(actor_id)) { \
3457 /* Actor unit was destroyed during pre action Lua. */ \
3458 return FALSE; \
3459 } \
3460 if (!target || !city_exist(target_id)) { \
3461 /* Target city was destroyed during pre action Lua. */ \
3462 return FALSE; \
3463 } \
3464 success = action_performer; \
3465 if (success) { \
3466 action_success_actor_price(paction, actor_id, actor); \
3467 } \
3468 script_server_signal_emit("action_finished_unit_city", \
3469 action_by_number(action), success, \
3470 unit_is_alive(actor_id) ? actor : NULL, \
3471 city_exist(target_id) ? target : NULL); \
3472 return success; \
3473 } else { \
3474 illegal_action(pplayer, actor_unit, action_type, \
3475 pcity ? city_owner(pcity) : NULL, NULL, pcity, NULL, \
3476 TRUE, requester); \
3477 }
3478
3479#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3480 if (actor_unit \
3481 && is_action_enabled_unit_on_self(action_type, actor_unit)) { \
3482 bool success; \
3483 script_server_signal_emit("action_started_unit_self", \
3484 action_by_number(action), actor); \
3485 if (!actor || !unit_is_alive(actor_id)) { \
3486 /* Actor unit was destroyed during pre action Lua. */ \
3487 return FALSE; \
3488 } \
3489 success = action_performer; \
3490 if (success) { \
3491 action_success_actor_price(paction, actor_id, actor); \
3492 } \
3493 script_server_signal_emit("action_finished_unit_self", \
3494 action_by_number(action), success, \
3495 unit_is_alive(actor_id) ? actor : NULL); \
3496 return success; \
3497 } else { \
3498 illegal_action(pplayer, actor_unit, action_type, \
3499 unit_owner(actor_unit), NULL, NULL, actor_unit, \
3500 TRUE, requester); \
3501 }
3502
3503#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3504 if (punit \
3505 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3506 bool success; \
3507 script_server_signal_emit("action_started_unit_unit", \
3508 action_by_number(action), actor, target); \
3509 if (!actor || !unit_is_alive(actor_id)) { \
3510 /* Actor unit was destroyed during pre action Lua. */ \
3511 return FALSE; \
3512 } \
3513 if (!target || !unit_is_alive(target_id)) { \
3514 /* Target unit was destroyed during pre action Lua. */ \
3515 return FALSE; \
3516 } \
3517 success = action_performer; \
3518 if (success) { \
3519 action_success_actor_price(paction, actor_id, actor); \
3520 action_success_target_pay_mp(paction, target_id, punit); \
3521 } \
3522 script_server_signal_emit("action_finished_unit_unit", \
3523 action_by_number(action), success, \
3524 unit_is_alive(actor_id) ? actor : NULL, \
3525 unit_is_alive(target_id) ? target : NULL); \
3526 return success; \
3527 } else { \
3528 illegal_action(pplayer, actor_unit, action_type, \
3529 punit ? unit_owner(punit) : NULL, NULL, NULL, punit, \
3530 TRUE, requester); \
3531 }
3532
3533#define ACTION_PERFORM_UNIT_UNITS(action, actor, target, action_performer)\
3534 if (target_tile \
3535 && is_action_enabled_unit_on_stack(nmap, action_type, \
3536 actor_unit, target_tile)) { \
3537 bool success; \
3538 script_server_signal_emit("action_started_unit_units", \
3539 action_by_number(action), actor, target); \
3540 if (!actor || !unit_is_alive(actor_id)) { \
3541 /* Actor unit was destroyed during pre action Lua. */ \
3542 return FALSE; \
3543 } \
3544 success = action_performer; \
3545 if (success) { \
3546 action_success_actor_price(paction, actor_id, actor); \
3547 } \
3548 script_server_signal_emit("action_finished_unit_units", \
3549 action_by_number(action), success, \
3550 unit_is_alive(actor_id) ? actor : NULL, \
3551 target); \
3552 return success; \
3553 } else { \
3554 illegal_action(pplayer, actor_unit, action_type, \
3555 NULL, target_tile, NULL, NULL, \
3556 TRUE, requester); \
3557 }
3558
3559#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3560 if (target_tile \
3561 && is_action_enabled_unit_on_tile(nmap, action_type, \
3562 actor_unit, target_tile, \
3563 target_extra)) { \
3564 bool success; \
3565 script_server_signal_emit("action_started_unit_tile", \
3566 action_by_number(action), actor, target); \
3567 if (!actor || !unit_is_alive(actor_id)) { \
3568 /* Actor unit was destroyed during pre action Lua. */ \
3569 return FALSE; \
3570 } \
3571 success = action_performer; \
3572 if (success) { \
3573 action_success_actor_price(paction, actor_id, actor); \
3574 } \
3575 script_server_signal_emit("action_finished_unit_tile", \
3576 action_by_number(action), success, \
3577 unit_is_alive(actor_id) ? actor : NULL, \
3578 target); \
3579 return success; \
3580 } else { \
3581 illegal_action(pplayer, actor_unit, action_type, \
3582 target_tile ? tile_owner(target_tile) : NULL, \
3583 target_tile, NULL, NULL, \
3584 TRUE, requester); \
3585 }
3586
3587#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3588 if (target_tile \
3589 && is_action_enabled_unit_on_extras(action_type, \
3590 actor_unit, target_tile, \
3591 target_extra)) { \
3592 bool success; \
3593 script_server_signal_emit("action_started_unit_extras", \
3594 action_by_number(action), actor, target); \
3595 if (!actor || !unit_is_alive(actor_id)) { \
3596 /* Actor unit was destroyed during pre action Lua. */ \
3597 return FALSE; \
3598 } \
3599 success = action_performer; \
3600 if (success) { \
3601 action_success_actor_price(paction, actor_id, actor); \
3602 } \
3603 script_server_signal_emit("action_finished_unit_extras", \
3604 action_by_number(action), success, \
3605 unit_is_alive(actor_id) ? actor : NULL, \
3606 target); \
3607 return success; \
3608 } else { \
3609 illegal_action(pplayer, actor_unit, action_type, \
3610 target_tile ? target_tile->extras_owner : NULL, \
3611 target_tile, NULL, NULL, \
3612 TRUE, requester); \
3613 }
3614
3615#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3616 target_city, target_unit, target_tile, \
3617 action_performer) \
3618 switch (action_get_target_kind(paction)) { \
3619 case ATK_CITY: \
3620 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3621 action_performer); \
3622 break; \
3623 case ATK_UNIT: \
3624 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3625 action_performer); \
3626 break; \
3627 case ATK_UNITS: \
3628 ACTION_PERFORM_UNIT_UNITS(paction->id, actor, target_tile, \
3629 action_performer); \
3630 break; \
3631 case ATK_TILE: \
3632 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3633 action_performer); \
3634 break; \
3635 case ATK_EXTRAS: \
3636 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3637 action_performer); \
3638 break; \
3639 case ATK_SELF: \
3640 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3641 break; \
3642 case ATK_COUNT: \
3643 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3644 break; \
3645 }
3646
3647 switch (paction->result) {
3651 paction));
3652 break;
3654 /* Difference is caused by data in the action structure. */
3657 punit, paction));
3658 break;
3659 case ACTRES_EXPEL_UNIT:
3661 do_expel_unit(pplayer, actor_unit, punit,
3662 paction));
3663 break;
3664 case ACTRES_HEAL_UNIT:
3666 do_heal_unit(pplayer, actor_unit, punit,
3667 paction));
3668 break;
3672 paction));
3673 break;
3677 paction));
3678 break;
3681 do_unit_board(pplayer, actor_unit, punit,
3682 paction));
3683 break;
3686 do_unit_load(pplayer, actor_unit, punit,
3687 paction));
3688 break;
3692 paction));
3693 break;
3695 /* All consequences are handled by the action system. */
3697 break;
3698 case ACTRES_FORTIFY:
3701 break;
3702 case ACTRES_CONVERT:
3705 break;
3706 case ACTRES_HOMELESS:
3709 break;
3710 case ACTRES_SPY_ESCAPE:
3711 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3712 spy_escape(pplayer, actor_unit,
3713 pcity, target_tile, paction));
3714 break;
3716 /* Difference is caused by data in the action structure. */
3717 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3718 diplomat_sabotage(pplayer, actor_unit, pcity,
3719 B_LAST, paction));
3720 break;
3722 /* Difference is caused by data in the action structure. */
3723 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3724 diplomat_sabotage(pplayer, actor_unit, pcity,
3725 sub_tgt_impr->item_number,
3726 paction));
3727 break;
3729 /* Difference is caused by data in the action structure. */
3730 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3731 diplomat_sabotage(pplayer, actor_unit, pcity,
3732 -1, paction));
3733 break;
3734 case ACTRES_SPY_POISON:
3735 /* Difference is caused by data in the action structure. */
3736 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3737 spy_poison(pplayer, actor_unit, pcity,
3738 paction));
3739 break;
3741 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3742 spy_spread_plague(pplayer, actor_unit, pcity,
3743 paction));
3744 break;
3746 /* Difference is caused by data in the action structure. */
3747 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3748 diplomat_investigate(pplayer,
3749 actor_unit, pcity,
3750 paction));
3751 break;
3753 /* Difference is caused by data in the action structure. */
3754 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3755 diplomat_embassy(pplayer, actor_unit, pcity,
3756 paction));
3757 break;
3759 /* Difference is caused by data in the action structure. */
3760 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3761 diplomat_incite(pplayer, actor_unit, pcity,
3762 paction));
3763 break;
3765 /* Difference is caused by data in the action structure. */
3766 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3767 diplomat_get_tech(pplayer, actor_unit, pcity,
3768 A_UNSET, paction));
3769 break;
3771 /* Difference is caused by data in the action structure. */
3772 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3773 diplomat_get_tech(pplayer, actor_unit, pcity,
3774 sub_tgt_id, paction));
3775 break;
3777 /* Difference is caused by data in the action structure. */
3778 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3779 spy_steal_gold(pplayer, actor_unit, pcity,
3780 paction));
3781 break;
3782 case ACTRES_STEAL_MAPS:
3783 /* Difference is caused by data in the action structure. */
3784 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3786 pcity, paction));
3787 break;
3788 case ACTRES_TRADE_ROUTE:
3789 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3791 pcity, paction));
3792 break;
3793 case ACTRES_MARKETPLACE:
3794 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3796 pcity, paction));
3797 break;
3798 case ACTRES_HELP_WONDER:
3799 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3800 unit_do_help_build(pplayer,
3801 actor_unit, pcity,
3802 paction));
3803 break;
3804 case ACTRES_SPY_NUKE:
3805 /* Difference is caused by data in the action structure. */
3806 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3807 spy_nuke_city(pplayer, actor_unit, pcity,
3808 paction));
3809 break;
3810 case ACTRES_JOIN_CITY:
3811 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3812 city_add_unit(pplayer, actor_unit, pcity,
3813 paction));
3814 break;
3816 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3817 unit_do_destroy_city(pplayer,
3818 actor_unit, pcity,
3819 paction));
3820 break;
3822 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3823 unit_do_help_build(pplayer, actor_unit, pcity,
3824 paction));
3825 break;
3826 case ACTRES_HOME_CITY:
3827 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3829 paction));
3830 break;
3832 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3833 do_unit_upgrade(pplayer, actor_unit,
3834 pcity, requester, paction));
3835 break;
3837 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3838 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3840 pcity, paction));
3841 break;
3843 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3845 actor_unit,
3846 pcity,
3847 sub_tgt_impr->item_number,
3848 paction));
3849 break;
3851 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3853 actor_unit,
3854 pcity,
3855 paction));
3856 break;
3861 break;
3862 case ACTRES_AIRLIFT:
3863 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3864 do_airline(actor_unit, pcity, paction));
3865 break;
3870 break;
3871 case ACTRES_BOMBARD:
3872 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3875 paction));
3876 break;
3877 case ACTRES_ATTACK:
3879 /* Difference is caused by data in the action structure. */
3882 break;
3883 case ACTRES_WIPE_UNITS:
3886 break;
3887 case ACTRES_NUKE_UNITS:
3890 paction));
3891 break;
3892 case ACTRES_SPY_ATTACK:
3895 paction));
3896 break;
3897 case ACTRES_FOUND_CITY:
3899 city_build(pplayer, actor_unit,
3901 break;
3902 case ACTRES_NUKE:
3904 pcity, punit, target_tile,
3906 paction));
3907 break;
3908 case ACTRES_PARADROP:
3912 break;
3914 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3916 do_disembark(pplayer, actor_unit,
3918 break;
3919 case ACTRES_HUT_ENTER:
3921 do_unit_hut(pplayer, actor_unit,
3923 break;
3926 do_unit_hut(pplayer, actor_unit,
3928 break;
3929 case ACTRES_UNIT_MOVE:
3933 break;
3934 case ACTRES_TELEPORT:
3938 NULL, FALSE,
3941 FALSE, FALSE));
3942 break;
3946 break;
3947 case ACTRES_CULTIVATE:
3950 break;
3951 case ACTRES_PLANT:
3954 break;
3955 case ACTRES_PILLAGE:
3958 paction,
3959 &target_extra));
3960 break;
3961 case ACTRES_CLEAN:
3964 paction,
3965 &target_extra));
3966 break;
3967 case ACTRES_ROAD:
3970 paction,
3971 &target_extra));
3972 break;
3973 case ACTRES_BASE:
3976 paction,
3977 &target_extra));
3978 break;
3979 case ACTRES_MINE:
3982 paction,
3983 &target_extra));
3984 break;
3985 case ACTRES_IRRIGATE:
3988 paction,
3989 &target_extra));
3990 break;
3991 case ACTRES_NONE:
3992 /* 100% ruleset defined. */
3994 TRUE);
3995 break;
3998 return FALSE;
3999
4001 }
4002
4003 /* Something must have gone wrong. */
4004 return FALSE;
4005}
4006
4007/**********************************************************************/
4015 bool rehome)
4016{
4018 struct player *old_owner = unit_owner(punit);
4019 struct player *new_owner = (new_pcity == NULL ? old_owner
4021 const struct civ_map *nmap = &(wld.map);
4022
4023 /* Calling this function when new_pcity is same as old_pcity should
4024 * be safe with current implementation, but it is not meant to
4025 * be used that way. */
4027
4028 /* If 'rehome' is not set, this function should only be used to change
4029 * which player owns the unit */
4031
4032 if (old_owner != new_owner) {
4033 struct city *pcity = tile_city(punit->tile);
4034
4037
4040
4041 if (pcity != NULL
4043 /* Special case when city is being transferred. At this point city
4044 * itself has changed owner, so it's enemy city now that old owner
4045 * cannot see inside. All the normal methods of removing transferred
4046 * unit from previous owner's client think that there's no need to
4047 * remove unit as client shouldn't have it in first place. */
4049 }
4050
4051 /* Remove AI control of the old owner. */
4052 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4053
4057
4058 /* Activate AI control of the new owner. */
4059 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4060
4063 }
4064
4065 if (rehome) {
4066 /* Remove from old city first and add to new city only after that. */
4067 if (old_pcity) {
4068 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4069 unit_list_remove(old_pcity->units_supported, punit);
4070 /* update unit upkeep */
4072 }
4073
4074 if (new_pcity != NULL) {
4075 unit_list_prepend(new_pcity->units_supported, punit);
4076
4077 /* update unit upkeep */
4079
4080 punit->homecity = new_pcity->id;
4081 } else {
4083 }
4084 }
4085
4087 /* This is mainly for cases where unit owner changes to one not knowing
4088 * Railroad tech when unit is already building railroad.
4089 * Does also send_unit_info() */
4091 } else {
4092 /* Send info to players and observers. */
4094 }
4095
4096 if (new_pcity != NULL) {
4100 }
4101
4102 if (old_pcity) {
4106 }
4107
4109}
4110
4111/**********************************************************************/
4117 struct city *pcity,
4118 const struct action *paction)
4119{
4120 const char *giver = NULL;
4121
4122 if (unit_owner(punit) != city_owner(pcity)) {
4123 /* This is a gift. Tell the receiver. */
4124 giver = player_name(unit_owner(punit));
4125 }
4126
4128
4129 if (punit->homecity == pcity->id && giver) {
4130 /* Notify the city owner about the gift they received. */
4132 ftc_server,
4133 /* TRANS: other player ... unit type ... city name. */
4134 _("%s transferred control over a %s to you in %s."),
4135 giver,
4137 city_link(pcity));;
4138 }
4139
4140 return punit->homecity == pcity->id;
4141}
4142
4143/**********************************************************************/
4150static bool city_add_unit(struct player *pplayer, struct unit *punit,
4151 struct city *pcity, const struct action *paction)
4152{
4154 const struct unit_type *act_utype;
4155
4156 /* Sanity check: The actor is still alive. */
4158
4160
4161 /* Sanity check: The target city still exists. */
4162 fc_assert_ret_val(pcity, FALSE);
4163
4165
4166 city_size_add(pcity, amount);
4167 /* Make the new people something, otherwise city fails the checks */
4170 /* Refresh the city data. */
4171 city_refresh(pcity);
4172
4173 /* Notify the unit owner that the unit successfully joined the city. */
4175 _("%s added to aid %s in growing."),
4177 city_link(pcity));
4178 if (pplayer != city_owner(pcity)) {
4179 /* Notify the city owner when a foreign unit joins a city. */
4181 ftc_server,
4182 /* TRANS: another player had their unit join your city. */
4183 _("%s adds %s to your city %s."),
4186 city_link(pcity));;
4187 }
4188
4190 city_owner(pcity), city_tile(pcity),
4191 city_link(pcity));
4192
4193 sanity_check_city(pcity);
4194
4195 send_city_info(NULL, pcity);
4196
4197 script_server_signal_emit("city_size_change", pcity,
4198 (lua_Integer)amount, "unit_added");
4199
4200 return TRUE;
4201}
4202
4203/**********************************************************************/
4212static bool city_build(struct player *pplayer, struct unit *punit,
4213 struct tile *ptile, const char *name,
4214 const struct action *paction)
4215{
4216 char message[1024];
4217 int size;
4218 struct player *nationality;
4219 struct player *towner;
4220 const struct unit_type *act_utype;
4221
4222 /* Sanity check: The actor still exists. */
4223 fc_assert_ret_val(pplayer, FALSE);
4225
4226 towner = tile_owner(ptile);
4227
4228 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4229 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4230 "%s", message);
4231 return FALSE;
4232 }
4233
4235
4236 nationality = unit_nationality(punit);
4237
4238 create_city(pplayer, ptile, name, nationality);
4240 if (size > 1) {
4241 struct city *pcity = tile_city(ptile);
4242
4243 fc_assert_ret_val(pcity != NULL, FALSE);
4244
4246 }
4247
4248 /* May cause an incident even if the target tile is unclaimed. A ruleset
4249 * could give everyone a casus belli against the city founder. A rule
4250 * like that would make sense in a story where deep ecology is on the
4251 * table. (See also Voluntary Human Extinction Movement) */
4253 ptile, tile_link(ptile));
4254
4255 return TRUE;
4256}
4257
4258/**********************************************************************/
4261static void handle_unit_change_activity_real(struct player *pplayer,
4262 int unit_id,
4263 enum unit_activity activity,
4264 struct extra_type *activity_target)
4265{
4266 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4267
4268 if (NULL == punit) {
4269 /* Probably died or bribed. */
4270 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4271 return;
4272 }
4273
4274 if (punit->activity == activity
4276 return;
4277 }
4278
4279 /* Remove city spot reservations for AI settlers on city founding
4280 * mission, before goto_tile reset. */
4281 if (punit->server.adv->task != AUT_NONE) {
4283 }
4284
4285 punit->goto_tile = NULL;
4286
4287 if (activity == ACTIVITY_GOTO) {
4288 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4289 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4290 * it is going somewhere while it is standing still. The appearance of
4291 * the unit doing something can trick the user to not make use of it.
4292 *
4293 * Handled here because adv_follow_path() uses unit_activity_handling()
4294 * to set a unit's activity to ACTIVITY_GOTO. */
4295 return;
4296 }
4297
4298 if (activity == ACTIVITY_EXPLORE) {
4299 /* Please use unit_server_side_agent_set. */
4300 return;
4301 }
4302
4303 /* The activity can now be set. */
4305}
4306
4307/**********************************************************************/
4310void handle_unit_change_activity(struct player *pplayer, int unit_id,
4312 int target_id)
4313{
4314 struct extra_type *activity_target;
4315
4317 activity_target = NULL;
4318 } else {
4319 activity_target = extra_by_number(target_id);
4320 }
4321
4322#ifdef FREECIV_WEB
4323 /* Web-client is not capable of selecting target, so we do it server side */
4324 if (activity_target == NULL) {
4325 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4326 bool required = TRUE;
4327
4328 if (punit == NULL) {
4329 return;
4330 }
4331
4332 if (activity == ACTIVITY_IRRIGATE) {
4333 struct tile *ptile = unit_tile(punit);
4334
4335 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4336 pplayer, punit);
4337 } else if (activity == ACTIVITY_MINE) {
4338 struct tile *ptile = unit_tile(punit);
4339
4340 activity_target = next_extra_for_tile(ptile, EC_MINE,
4341 pplayer, punit);
4342 } else if (activity == ACTIVITY_BASE) {
4343 struct tile *ptile = unit_tile(punit);
4344 struct base_type *pbase =
4346
4347 if (pbase != NULL) {
4348 activity_target = base_extra_get(pbase);
4349 }
4350
4351 } else if (activity == ACTIVITY_CLEAN) {
4352 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4353 pplayer, punit);
4354 } else {
4355 required = FALSE;
4356 }
4357
4358 if (activity_target == NULL && required) {
4359 /* Nothing more we can do */
4360 return;
4361 }
4362 }
4363#endif /* FREECIV_WEB */
4364
4365 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target);
4366}
4367
4368/**********************************************************************/
4371static void see_combat(struct unit *pattacker, struct unit *pdefender)
4372{
4375
4376 /*
4377 * Special case for attacking/defending:
4378 *
4379 * Normally the player doesn't get the information about the units inside a
4380 * city. However for attacking/defending the player has to know the unit of
4381 * the other side. After the combat a remove_unit packet will be sent
4382 * to the client to tidy up.
4383 *
4384 * Note these packets must be sent out before unit_versus_unit() is called,
4385 * so that the original unit stats (HP) will be sent.
4386 */
4393
4395 struct player *pplayer = pconn->playing;
4396
4397 if (pplayer != NULL) {
4398
4399 /* NOTE: this means the player can see combat between submarines even
4400 * if neither sub is visible. See similar comment in send_combat. */
4403 V_MAIN)) {
4404
4405 /* Units are sent even if they were visible already. They may
4406 * have changed orientation for combat. */
4407 if (pplayer == unit_owner(pattacker)) {
4409 } else {
4411 }
4412
4413 if (pplayer == unit_owner(pdefender)) {
4415 } else {
4417 }
4418 }
4419 } else if (pconn->observer) {
4420 /* Global observer sees everything... */
4423 }
4425}
4426
4427/**********************************************************************/
4430static void send_combat(struct unit *pattacker, struct unit *pdefender,
4431 int att_veteran, int def_veteran, int bombard)
4432{
4434
4436 combat.defender_unit_id = pdefender->id;
4437 combat.attacker_hp = pattacker->hp;
4438 combat.defender_hp = pdefender->hp;
4439 combat.make_att_veteran = att_veteran;
4440 combat.make_def_veteran = def_veteran;
4441
4442 players_iterate(other_player) {
4443 /* NOTE: this means the player can see combat between submarines even
4444 * if neither sub is visible. See similar comment in see_combat. */
4445 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4446 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4447 V_MAIN)) {
4448 lsend_packet_unit_combat_info(other_player->connections, &combat);
4449
4450 /*
4451 * Remove the client knowledge of the units. This corresponds to the
4452 * send_packet_unit_short_info calls up above.
4453 */
4454 if (!can_player_see_unit(other_player, pattacker)) {
4455 unit_goes_out_of_sight(other_player, pattacker);
4456 }
4457 if (!can_player_see_unit(other_player, pdefender)) {
4458 unit_goes_out_of_sight(other_player, pdefender);
4459 }
4460 }
4462
4463 /* Send combat info to non-player observers as well. They already know
4464 * about the unit so no unit_info is needed. */
4466 if (NULL == pconn->playing && pconn->observer) {
4468 }
4470}
4471
4472/**********************************************************************/
4476 struct city *pcity,
4477 const struct action *paction,
4478 const char *reason)
4479{
4480 struct player *pplayer = unit_owner(punit);
4481
4482 if (pcity
4484 &(const struct req_context) {
4485 .player = city_owner(pcity),
4486 .city = pcity,
4487 .tile = city_tile(pcity),
4488 .unit = punit,
4489 .unittype = unit_type_get(punit),
4490 .action = paction,
4491 },
4495 struct player *cplayer = city_owner(pcity);
4496 struct tile *ctile = city_tile(pcity);
4497 const char *clink = city_link(pcity);
4498
4499 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4500 city_refresh(pcity);
4501 send_city_info(NULL, pcity);
4502 } else {
4504 /* TRANS: Battleship ... Los Angeles ... Bombard */
4505 _("Your %s destroyed %s by doing %s."),
4510 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4511 _("%s destroyed %s by doing %s."),
4512 player_name(pplayer), clink,
4514 }
4515 }
4516}
4517
4518/**********************************************************************/
4525static bool unit_bombard(struct unit *punit, struct tile *ptile,
4526 const struct action *paction)
4527{
4528 struct player *pplayer = unit_owner(punit);
4529 struct city *pcity = tile_city(ptile);
4530 const struct unit_type *act_utype;
4531 const struct civ_map *nmap = &(wld.map);
4532
4533 /* Sanity check: The actor still exists. */
4534 fc_assert_ret_val(pplayer, FALSE);
4536
4538
4539 log_debug("Start bombard: %s %s to %d, %d.",
4541 unit_rule_name(punit), TILE_XY(ptile));
4542
4544 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4545 bool adj;
4546 enum direction8 facing;
4547 int att_hp, def_hp;
4548
4550 punit->tile, pdefender->tile, &facing);
4551
4552 if (adj) {
4553 punit->facing = facing;
4554
4555 /* Unlike with normal attack, we don't change orientation of
4556 * defenders when bombarding */
4557 }
4558
4559 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4560
4561 if (def_hp <= 0) {
4562 notify_player(pplayer, ptile,
4564 /* TRANS: Your Bomber killed the English Rifleman by
4565 * doing Bombard. */
4566 _("Your %s killed the %s %s by doing %s."),
4573 /* TRANS: Your Rifleman was killed by the French
4574 * Bomber doing Bombard. */
4575 _("Your %s was killed by the %s %s doing %s."),
4580 } else {
4581 notify_player(pplayer, ptile,
4583 /* TRANS: Your Bomber bombards the English Rifleman. */
4584 _("Your %s bombards the %s %s."),
4590 /* TRANS: Your Rifleman is bombarded by the French
4591 * Bomber. */
4592 _("Your %s is bombarded by the %s %s."),
4596 }
4597
4599
4600 punit->hp = att_hp;
4601 pdefender->hp = def_hp;
4602
4603 send_combat(punit, pdefender, 0, 0, 1);
4604
4605 /* May cause an incident */
4611
4612 if (def_hp <= 0) {
4614 } else {
4616 }
4617 }
4618
4620
4623
4624 unit_attack_civilian_casualties(punit, pcity, paction, "bombard");
4625
4627
4628 return TRUE;
4629}
4630
4631/**********************************************************************/
4642static bool unit_nuke(struct player *pplayer, struct unit *punit,
4643 struct tile *def_tile, const struct action *paction)
4644{
4645 struct city *pcity;
4646 const struct unit_type *act_utype;
4647 struct civ_map *nmap = &(wld.map);
4648
4649 /* Sanity check: The actor still exists. */
4650 fc_assert_ret_val(pplayer, FALSE);
4652
4654
4655 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4658 TILE_XY(def_tile));
4659
4660 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4661 /* FIXME: Remove the hard coded reference to SDI defense. */
4663 _("Your %s was shot down by "
4664 "SDI defenses, what a waste."), unit_tile_link(punit));
4666 _("The nuclear attack on %s was avoided by"
4667 " your SDI defense."), city_link(pcity));
4668
4669 /* Trying to nuke something this close can be... unpopular. */
4671 city_owner(pcity),
4673
4674 /* Remove the destroyed nuke. */
4676
4677 return FALSE;
4678 }
4679
4681
4682
4683 /* The nuke must be wiped here so it won't be seen as a victim of its own
4684 * detonation. */
4685 if (paction->actor_consuming_always) {
4687 }
4688
4690
4691 /* May cause an incident even if the target tile is unclaimed. A ruleset
4692 * could give everyone a casus belli against the tile nuker. A rule
4693 * like that would make sense in a story where detonating any nuke at all
4694 * could be forbidden. */
4697 def_tile,
4699
4700 return TRUE;
4701}
4702
4703/**********************************************************************/
4713 struct unit *act_unit,
4714 struct city *tgt_city,
4715 const struct action *paction)
4716{
4717 int tgt_city_id;
4718 struct player *tgt_player;
4719 bool capital;
4720 bool try_civil_war = FALSE;
4721 const struct unit_type *act_utype;
4722
4723 /* Sanity check: The actor still exists. */
4726
4728
4729 /* Sanity check: The target city still exists. */
4731
4733
4734 /* How can a city be ownerless? */
4736
4737 /* Save city ID. */
4738 tgt_city_id = tgt_city->id;
4739
4741
4742 if (capital
4743 && (tgt_player->spaceship.state == SSHIP_STARTED
4744 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4745 /* Destroying this city destroys the victim's space ship. */
4747 }
4748
4749 if (capital
4753 /* Destroying this city can trigger a civil war. */
4755 }
4756
4757 /* Let the actor know. */
4760 _("You destroy %s completely."),
4762
4763 if (tgt_player != act_player) {
4764 /* This was done to a foreign city. Inform the victim player. */
4767 _("%s has been destroyed by %s."),
4770 }
4771
4772 /* May cause an incident */
4776
4777 /* Run post city destruction Lua script. */
4779 act_player);
4780
4781 /* Can't be sure of city existence after running script. */
4782 if (city_exist(tgt_city_id)) {
4784 }
4785
4786 if (try_civil_war) {
4787 /* Try to start the civil war. */
4789 }
4790
4791 /* The city is no more. */
4792 return TRUE;
4793}
4794
4795/**********************************************************************/
4800static const char *unit_veteran_level_string(const struct unit *punit)
4801{
4802 static char buf[MAX_LEN_LINK];
4803 const struct veteran_level *vlevel;
4804
4805 if (!punit) {
4806 buf[0] = '\0'; /* If no unit, return empty string */
4807 return buf;
4808 }
4809
4811 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4812
4813 return buf;
4814}
4815
4816/**********************************************************************/
4821static const char *unit_achieved_rank_string(const struct unit *punit)
4822{
4823 static char buf[MAX_LEN_LINK];
4824
4825 fc_snprintf(buf, sizeof(buf),
4826 /* TRANS: " and achieved the rank of <veteran level>";
4827 * preserve leading space */
4828 _(" and achieved the rank of %s"),
4830 return buf;
4831}
4832
4833/**********************************************************************/
4838static const char *unit_tired_attack_string(const struct unit *punit)
4839{
4840 static char buf[MAX_LEN_LINK];
4841
4843 fc_snprintf(buf, sizeof(buf),
4844 /* TRANS: tired; note trailing space */
4845 _("tired "));
4846 } else {
4847 buf[0] = '\0';
4848 }
4849
4850 return buf;
4851}
4852
4853/**********************************************************************/
4860static const char *unit_firepower_if_not_one(int firepower)
4861{
4862 static char buf[MAX_LEN_LINK];
4863
4864 if (firepower == 1) {
4865 buf[0] = '\0';
4866 } else {
4867 fc_snprintf(buf, sizeof(buf),
4868 /* TRANS: FP = Firepower of a unit; note trailing space */
4869 _("FP:%d "),
4870 firepower);
4871 }
4872
4873 return buf;
4874}
4875
4876/**********************************************************************/
4885static bool do_attack(struct unit *punit, struct tile *def_tile,
4886 const struct action *paction)
4887{
4892 struct unit *ploser, *pwinner;
4895 int winner_id;
4896 struct player *pplayer = unit_owner(punit);
4897 bool adj;
4898 enum direction8 facing;
4899 int att_hp, def_hp, att_fp, def_fp;
4901 int def_power, att_power;
4902 int att_vet, def_vet;
4903 struct unit *pdefender;
4904 const struct unit_type *act_utype = unit_type_get(punit);
4905 struct civ_map *nmap = &(wld.map);
4906 bool powerless;
4907
4909 /* Can't fight air... */
4910 return FALSE;
4911 }
4912
4914 def_hp_start = pdefender->hp;
4918
4919 log_debug("Start attack: %s %s against %s %s.",
4924
4925 /* Sanity checks */
4928 FALSE,
4929 "Trying to attack a unit with which you have peace "
4930 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
4932 FALSE,
4933 "Trying to attack a unit with which you have "
4934 "alliance at (%d, %d).", TILE_XY(def_tile));
4935
4938
4940 punit->tile, pdefender->tile, &facing);
4941
4942 fc_assert(adj);
4943 if (adj) {
4944 punit->facing = facing;
4945 pdefender->facing = opposite_direction(facing);
4946 }
4947
4949 old_defender_vet = pdefender->veteran;
4950
4951 /* N.B.: unit_veteran_level_string always returns the same pointer. */
4954
4955 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
4958
4959 /* Record tired attack string before attack */
4961
4962 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
4963 &att_vet, &def_vet, paction);
4964
4965 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
4966 && unit_transported(punit)) {
4967 /* Dying attacker must be first unloaded so it doesn't die inside transport */
4969 }
4970
4972
4973 punit->hp = att_hp;
4974 pdefender->hp = def_hp;
4975
4977
4978 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
4979 * the movement attack modifier is correct! --dwp
4980 *
4981 * For greater Civ2 compatibility (and game balance issues), we recompute
4982 * the new total MP based on the HP the unit has left after being damaged,
4983 * and subtract the MPs that had been used before the combat (plus the
4984 * points used in the attack itself, for the attacker). -GJW, Glip
4985 */
4988
4989 if (punit->moves_left < 0) {
4990 punit->moves_left = 0;
4991 }
4992 if (pdefender->moves_left < 0) {
4993 pdefender->moves_left = 0;
4994 }
4997
4998 /* This may cause a diplomatic incident. */
5002
5003 if (punit->hp > 0 && pdefender->hp > 0) {
5004 /* Neither died */
5006 pdefender->veteran - old_defender_vet, 0);
5007 return TRUE;
5008 }
5009 pwinner = (punit->hp > 0) ? punit : pdefender;
5010 winner_id = pwinner->id;
5011 ploser = (pdefender->hp > 0) ? punit : pdefender;
5012
5013 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5014 old_defender_vet)) ? 0 : 1;
5015
5017 pdefender->veteran - old_defender_vet, 0);
5018
5019 /* N.B.: unit_link always returns the same pointer. */
5024
5025 if (punit == ploser) {
5026 /* The attacker lost */
5027 log_debug("Attacker lost: %s %s against %s %s.",
5032
5035 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5036 * 9 HP remaining] survived the pathetic ...attack from the
5037 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5038 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5039 " survived the pathetic %sattack from the %s %s %s "
5040 "[id:%d %sA:%.1f HP:%d]."),
5043 pdefender->id,
5045 (float)def_power/POWER_FACTOR,
5046 def_hp_start - pdefender->hp,
5047 pdefender->hp,
5051 loser_link,
5052 punit->id,
5054 (float)att_power/POWER_FACTOR,
5055 att_hp_start);
5056
5057 if (vet) {
5059 }
5062 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5063 * failed against the Polish green Destroyer [id:200 lost
5064 * 27 HP, 3 HP remaining%s]!";
5065 * last %s is either "and ..." or empty string */
5066 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5067 "against the %s %s %s [id:%d lost %d HP, %d HP "
5068 "remaining%s]!"),
5070 loser_link,
5071 punit->id,
5073 (float)att_power/POWER_FACTOR,
5078 pdefender->id,
5079 def_hp_start - pdefender->hp,
5080 pdefender->hp,
5082
5084 } else {
5085 /* The defender lost, the attacker punit lives! */
5086 struct city *pcity;
5087
5088 log_debug("Defender lost: %s %s against %s %s.",
5093
5096 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5097 * lost to an attack by the Greek green Legion
5098 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5099 * last %s is either "and ..." or empty string */
5100 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5101 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5102 "remaining%s]."),
5104 loser_link,
5105 pdefender->id,
5107 (float)def_power/POWER_FACTOR,
5112 punit->id,
5114 (float)att_power/POWER_FACTOR,
5115 att_hp_start - pwinner->hp,
5116 pwinner->hp,
5118
5121 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5122 * lost 1 HP, has 9 HP remaining] succeeded against the
5123 * Greek green Warriors [id:100 HP:10]." */
5124 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5125 "has %d remaining] succeeded against the %s %s %s "
5126 "[id:%d HP:%d]."),
5129 punit->id,
5132 (float)att_power/POWER_FACTOR,
5133 att_hp_start - pwinner->hp,
5134 pwinner->hp,
5137 loser_link,
5138 pdefender->id,
5139 def_hp_start);
5140
5141 punit->moved = TRUE; /* We moved */
5142
5143 if (paction->result == ACTRES_COLLECT_RANSOM) {
5146 } else {
5149 }
5150
5151 /* Now that dead defender is certainly no longer listed as unit
5152 * supported by the city, we may even remove the city
5153 * (if it shrinks from size 1) */
5154 pcity = tile_city(def_tile);
5155 if (pcity != NULL) {
5157 }
5158 if (unit_is_alive(winner_id)) {
5160 return TRUE;
5161 }
5162 } else {
5163 return TRUE;
5164 }
5165 }
5166
5167 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5168 * if there are enemy units in the tile (a fortress, city or air base with
5169 * multiple defenders and unstacked combat). Note that this could mean
5170 * capturing (or destroying) a city. */
5171
5172 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5174 }
5175
5176 /* The attacker may have died for many reasons */
5179 }
5180
5181 return TRUE;
5182}
5183
5184/**********************************************************************/
5195 struct unit *act_unit,
5196 struct city *tgt_city,
5197 const struct action *paction)
5198{
5199 struct player *tgt_player;
5200 char prod[256];
5201 const struct unit_type *act_utype;
5202 const struct tile *tgt_tile;
5203 const char *clink;
5204
5205 /* Sanity checks */
5210
5213
5215
5216 /* The surgical strike may miss. */
5217 {
5218 /* Roll the dice. */
5221 paction)) {
5222 /* Notify the player. */
5225 /* TRANS: unit, action, city */
5226 _("Your %s failed to do %s in %s."),
5230
5231 /* Make the failed attempt cost a single move. */
5232 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5233
5234 return FALSE;
5235 }
5236 }
5237
5238 /* Get name of the production */
5239 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5240
5241 /* Destroy the production */
5242 tgt_city->shield_stock = 0;
5244
5245 /* Let the players know. */
5246 clink = city_link(tgt_city); /* Be careful not to call city_link()
5247 * again as long as we need clink */
5250 _("Your %s succeeded in destroying"
5251 " the production of %s in %s."),
5253 prod, clink);
5256 _("The production of %s was destroyed in %s,"
5257 " %s are suspected."),
5258 prod, clink,
5260
5262
5263 /* May cause an incident */
5266 clink);
5267
5268 return TRUE;
5269}
5270
5271/**********************************************************************/
5282 struct unit *act_unit,
5283 struct city *tgt_city,
5285 const struct action *paction)
5286{
5287 struct player *tgt_player;
5289 const struct tile *tgt_tile;
5290 const struct unit_type *act_utype;
5291 const char *clink;
5292
5293 /* Sanity checks */
5298
5300
5303
5304 /* The surgical strike may miss. */
5305 {
5306 /* Roll the dice. */
5309 paction)) {
5310 /* Notify the player. */
5313 /* TRANS: unit, action, city */
5314 _("Your %s failed to do %s in %s."),
5318
5319 /* Make the failed attempt cost a single move. */
5320 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5321
5322 return FALSE;
5323 }
5324 }
5325
5327 /* Nothing to destroy here. */
5328
5329 /* Notify the player. */
5332 _("Your %s didn't find a %s to %s in %s."),
5337
5338 /* Punish the player for blindly attacking a building. */
5339 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5340
5341 return FALSE;
5342 }
5343
5345
5346 /* Destroy the building. */
5347 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5348
5349 /* Update the player's view of the city. */
5351
5352 /* Let the players know. */
5353 clink = city_link(tgt_city); /* Be careful not to call city_link()
5354 * again as long as we need clink */
5357 _("Your %s destroyed the %s in %s."),
5360 clink);
5363 _("The %s destroyed the %s in %s."),
5366 clink);
5367
5368 /* May cause an incident */
5371
5372 return TRUE;
5373}
5374
5375/**********************************************************************/
5385 struct unit *act_unit,
5386 struct city *tgt_city,
5387 struct action *paction)
5388{
5389 bool success;
5390 struct tile *tgt_tile = city_tile(tgt_city);
5391 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5392 int tgt_city_id = tgt_city->id;
5394 const char *victim_link = city_link(tgt_city);
5395
5396 /* Sanity check */
5398
5399 unit_move(act_unit, tgt_tile, move_cost, NULL, FALSE, TRUE, TRUE,
5400 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5402
5403 /* The city may have been destroyed during the conquest. */
5406
5407 if (success) {
5408 const struct unit_type *act_utype = unit_type_get(act_unit);
5409
5410 /* May cause an incident */
5413 victim_link);
5414 }
5415
5416 return success;
5417}
5418
5419/**********************************************************************/
5423 struct tile *dest_tile,
5424 bool igzoc,
5425 struct unit *embark_to,
5426 bool enter_enemy_city)
5427{
5428 struct tile *src_tile = unit_tile(punit);
5431 src_tile, dest_tile, igzoc, TRUE, embark_to,
5433
5434 switch (reason) {
5435 case MR_OK:
5436 return TRUE;
5437
5438 case MR_NO_WAR:
5440 _("Cannot attack unless you declare war first."));
5441 break;
5442
5443 case MR_ZOC:
5445 _("%s can only move into your own zone of control."),
5446 unit_link(punit));
5447 break;
5448
5449 case MR_TRIREME:
5451 _("%s cannot move that far from the coast line."),
5452 unit_link(punit));
5453 break;
5454
5455 case MR_PEACE:
5456 if (tile_owner(dest_tile)) {
5458 _("Cannot invade unless you break peace with "
5459 "%s first."),
5460 player_name(tile_owner(dest_tile)));
5461 }
5462 break;
5463
5466 _("%s cannot disembark outside of a city or a native base "
5467 "for %s."),
5471 break;
5472
5473 case MR_NON_NATIVE_MOVE:
5475 _("Terrain is unsuitable for %s units."),
5477 break;
5478
5479 default:
5480 /* FIXME: need more explanations someday! */
5481 break;
5482 };
5483
5484 return FALSE;
5485}
5486
5487/**********************************************************************/
5494 struct unit *actor_unit,
5495 struct tile *target_tile,
5496 const struct action *paction)
5497{
5499 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5500
5501 unit_move(actor_unit, target_tile, move_cost,
5503 /* Don't override "Conquer City" */
5504 FALSE,
5505 /* Don't override "Conquer Extras" */
5506 FALSE,
5507 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5509
5510 /* May cause an incident */
5514
5515 return TRUE;
5516}
5517
5518/**********************************************************************/
5532 bool move_do_not_act)
5533{
5534 struct player *pplayer = unit_owner(punit);
5535 struct unit *ptrans;
5536 const struct civ_map *nmap = &(wld.map);
5537
5538 /*** Phase 1: Attempted action interpretation checks ***/
5539
5540 /* Check if the move should be interpreted as an attempt to perform an
5541 * enabler controlled action to the target tile. When the move may be an
5542 * action attempt the server stops moving the unit, marks it as wanting a
5543 * decision based on its own movement to the tile it attempted to move to
5544 * and notifies the client.
5545 *
5546 * In response to the unit being marked as wanting a decision the client
5547 * can query the server for what actions the unit, given the player's
5548 * knowledge, may be able to perform against a target at the tile it tried
5549 * to move to. The server will respond to the query with the actions that
5550 * may be enabled and, when all actions are known to be illegal given the
5551 * player's knowledge, an explanation why no action could be done. The
5552 * client will probably use the list of potentially legal actions, if any,
5553 * to pop up an action selection dialog. See handle_unit_action_query()
5554 *
5555 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5556 * to perform an enabler controlled action.
5557 * Examples of where this is useful is for AI moves, goto, when the player
5558 * attempts to move to a tile occupied by potential targets like allied
5559 * cities or units and during rule forced moves.
5560 *
5561 * A move is not interpreted as an attempted action because the unit is
5562 * able to do a self targeted action.
5563 *
5564 * A move is not interpreted as an attempted action because an action
5565 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5566 * perform a regular move to the tile.
5567 *
5568 * An attempted move to a tile a unit can't move to is always interpreted
5569 * as trying to perform an action (unless move_do_not_act is TRUE) */
5570 if (!move_do_not_act) {
5573 FALSE, FALSE, FALSE);
5577 /* A legal action with an extra sub target is a legal action */
5579 /* Tile target actions with extra sub targets are handled above */
5581
5583 /* There is a target punit, from the player's point of view, may be
5584 * able to act against OR punit can't do any non action move. The
5585 * client should therefore ask what action(s) the unit can perform
5586 * to any targets at pdesttile.
5587 *
5588 * In the first case the unit needs a decision about what action, if
5589 * any at all, to take. Asking what actions the unit can perform
5590 * will return a list of actions that may, from the players point of
5591 * view, be possible. The client can then show this list to the
5592 * player or, if configured to do so, make the choice it self.
5593 *
5594 * In the last case the player may need an explanation about why no
5595 * action could be taken. Asking what actions the unit can perform
5596 * will provide this explanation. */
5600
5601 /* The move wasn't done because the unit wanted the player to
5602 * decide what to do or because the unit couldn't move to the
5603 * target tile. */
5604 return FALSE;
5605 }
5606 }
5607
5608 /*** Phase 2: OK now move the unit ***/
5609 /* This is a regular move, subject to the rules. */
5611 punit, pdesttile, NULL)) {
5612 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5616 punit, pdesttile, NULL)) {
5617 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5621 punit, pdesttile, NULL)) {
5622 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5628 punit, ptrans)) {
5629 /* "Transport Embark". */
5630 return unit_perform_action(pplayer, punit->id, ptrans->id,
5636 punit, ptrans)) {
5637 /* "Transport Embark 2". */
5638 return unit_perform_action(pplayer, punit->id, ptrans->id,
5644 punit, ptrans)) {
5645 /* "Transport Embark 3". */
5646 return unit_perform_action(pplayer, punit->id, ptrans->id,
5652 punit, ptrans)) {
5653 /* "Transport Embark 4". */
5654 return unit_perform_action(pplayer, punit->id, ptrans->id,
5658 punit, pdesttile, NULL)) {
5659 /* "Transport Disembark". */
5660 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5664 punit, pdesttile, NULL)) {
5665 /* "Transport Disembark 2". */
5666 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5670 punit, pdesttile, NULL)) {
5671 /* "Transport Disembark 3". */
5672 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5676 punit, pdesttile, NULL)) {
5677 /* "Transport Disembark 4". */
5678 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5682 punit, pdesttile, NULL)) {
5683 /* "Enter Hut". */
5684 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5688 punit, pdesttile, NULL)) {
5689 /* "Enter Hut 2". */
5690 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5694 punit, pdesttile, NULL)) {
5695 /* "Frighten Hut". */
5696 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5700 punit, pdesttile, NULL)) {
5701 /* "Frighten Hut 2". */
5702 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5705 } else {
5706 /* TODO: Extend the action not enabled explanation system to cover all
5707 * existing reasons and switch to using it. See hrm Feature #920229 */
5709 NULL, FALSE);
5710 return FALSE;
5711 }
5712}
5713
5714/**********************************************************************/
5724static bool unit_do_help_build(struct player *pplayer,
5725 struct unit *punit,
5726 struct city *pcity_dest,
5727 const struct action *paction)
5728{
5729 const char *work;
5730 const char *prod;
5731 int shields;
5732 const struct unit_type *act_utype;
5733 struct player *cowner;
5734
5735 /* Sanity check: The actor still exists. */
5736 fc_assert_ret_val(pplayer, FALSE);
5738
5739 /* Sanity check: The target city still exists. */
5741
5744
5746 /* Add the caravan shields */
5747 pcity_dest->shield_stock += shields;
5748
5749 /* Will be punished for changing production to something that can't
5750 * receive "Help Wonder" help. */
5752 &pcity_dest->production));
5753 pcity_dest->caravan_shields += shields;
5754 } else {
5756 /* Add the shields from recycling the unit to the city's current
5757 * production. */
5758 pcity_dest->shield_stock += shields;
5759
5760 /* If we change production later at this turn. No penalty is added. */
5761 pcity_dest->disbanded_shields += shields;
5762 }
5763
5765
5766 conn_list_do_buffer(cowner->connections);
5767
5769 /* Let the player that just donated shields with "Help Wonder" know
5770 * the result of their donation. */
5772 } else {
5774 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
5775 * current production in Bergen (4 surplus).
5776 * "Disband Unit Recover" says "current production" rather than its name. */
5777 prod = _("current production");
5778 }
5779
5780 if (build_points_left(pcity_dest) >= 0) {
5781 /* TRANS: Your Caravan does "Help Wonder" to help build the
5782 * Pyramids in Bergen (4 remaining).
5783 * You can reorder '4' and 'remaining' in the actual format string. */
5784 work = _("remaining");
5785 } else {
5786 /* TRANS: Your Caravan does "Help Wonder" to help build the
5787 * Pyramids in Bergen (4 surplus).
5788 * You can reorder '4' and 'surplus' in the actual format string. */
5789 work = _("surplus");
5790 }
5791
5793 ftc_server,
5794 /* TRANS: Your Caravan does "Help Wonder" to help build the
5795 * Pyramids in Bergen (4 surplus). */
5796 _("Your %s does %s to help build the %s in %s (%d %s)."),
5799 prod,
5802 work);
5803
5804 /* May cause an incident */
5807
5808 if (cowner != unit_owner(punit)) {
5809 /* Tell the city owner about the gift they just received. */
5810
5813 /* TRANS: Help building the Pyramids in Bergen received
5814 * from Persian Caravan (4 surplus). */
5815 _("Help building the %s in %s received from %s %s "
5816 "(%d %s)."),
5822 work);
5823 }
5824
5827 conn_list_do_unbuffer(cowner->connections);
5828
5829 return TRUE;
5830}
5831
5832/**********************************************************************/
5839static bool do_unit_establish_trade(struct player *pplayer,
5840 struct unit *punit,
5841 struct city *pcity_dest,
5842 const struct action *paction)
5843{
5846 int revenue;
5847 bool can_establish;
5848 int home_overbooked = 0;
5849 int dest_overbooked = 0;
5850 int home_max;
5851 int dest_max;
5852 struct city *pcity_homecity;
5855 enum trade_route_bonus_type bonus_type;
5856 struct goods_type *goods;
5857 const char *goods_str;
5858 const struct unit_type *act_utype;
5859
5860 /* Sanity check: The actor still exists. */
5861 fc_assert_ret_val(pplayer, FALSE);
5863
5864 /* Sanity check: The target city still exists. */
5866
5868
5869 if (!pcity_homecity) {
5871 _("Sorry, your %s cannot establish"
5872 " a trade route because it has no home city."),
5873 unit_link(punit));
5874 return FALSE;
5875 }
5876
5879 } else {
5880 goods = punit->carrying;
5881 }
5882 if (goods == NULL) {
5884 _("Sorry, your %s cannot establish"
5885 " a trade route because it's not carrying any goods."),
5886 unit_link(punit));
5887 return FALSE;
5888 }
5889
5892
5895 _("Sorry, your %s cannot establish"
5896 " a trade route between %s and %s."),
5900 return FALSE;
5901 }
5902
5904
5908
5909 /* This part of code works like can_establish_trade_route, except
5910 * that we actually do the action of making the trade route. */
5911
5912 /* If we can't make a new trade route we can still get the trade bonus. */
5915
5916 if (can_establish) {
5921 }
5922
5923 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
5925
5926 /* See if there's a trade route we can cancel at the home city. */
5927 if (home_overbooked >= 0) {
5928 if (home_max <= 0
5930 >= trade)) {
5933 _("Sorry, your %s cannot establish"
5934 " a trade route here!"),
5935 punit_link);
5936 if (home_max > 0) {
5939 PL_(" The city of %s already has %d "
5940 "better trade route!",
5941 " The city of %s already has %d "
5942 "better trade routes!", home_max),
5944 home_max);
5945 }
5947 }
5948 }
5949
5950 /* See if there's a trade route we can cancel at the dest city. */
5951 if (can_establish && dest_overbooked >= 0) {
5952 if (dest_max <= 0
5954 >= trade)) {
5957 _("Sorry, your %s cannot establish"
5958 " a trade route here!"),
5959 punit_link);
5960 if (dest_max > 0) {
5963 PL_(" The city of %s already has %d "
5964 "better trade route!",
5965 " The city of %s already has %d "
5966 "better trade routes!", dest_max),
5968 dest_max);
5969 }
5971 }
5972 }
5973 }
5974
5975 /* We now know for sure whether we can establish a trade route. */
5976
5977 /* Calculate and announce initial revenue. */
5978 revenue
5981
5982 bonus_type = trade_route_settings_by_type
5984
5986
5988
5989 /* We want to keep the bonus type string as the part of the format of the PL_() strings
5990 * for supporting proper pluralization for it. */
5991 switch (bonus_type) {
5992 case TBONUS_NONE:
5995 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
5996 _("Your %s from %s has arrived in %s carrying %s."),
5997 punit_link,
6000 goods_str);
6001 break;
6002 case TBONUS_GOLD:
6005 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6006 PL_("Your %s from %s has arrived in %s carrying %s,"
6007 " and revenues amount to %d in gold.",
6008 "Your %s from %s has arrived in %s carrying %s,"
6009 " and revenues amount to %d in gold.",
6010 revenue),
6011 punit_link,
6014 goods_str,
6015 revenue);
6016 break;
6017 case TBONUS_SCIENCE:
6020 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6021 PL_("Your %s from %s has arrived in %s carrying %s,"
6022 " and revenues amount to %d in research.",
6023 "Your %s from %s has arrived in %s carrying %s,"
6024 " and revenues amount to %d in research.",
6025 revenue),
6026 punit_link,
6029 goods_str,
6030 revenue);
6031 break;
6032 case TBONUS_BOTH:
6035 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6036 PL_("Your %s from %s has arrived in %s carrying %s,"
6037 " and revenues amount to %d in gold and research.",
6038 "Your %s from %s has arrived in %s carrying %s,"
6039 " and revenues amount to %d in gold and research.",
6040 revenue),
6041 punit_link,
6044 goods_str,
6045 revenue);
6046 break;
6047 }
6048
6049 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6050 pplayer->economic.gold += revenue;
6051
6052 send_player_info_c(pplayer, pplayer->connections);
6053 }
6054
6055 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6056 /* add bulbs and check for finished research */
6057 update_bulbs(pplayer, revenue, TRUE, TRUE);
6058
6059 /* Inform everyone about tech changes */
6061 }
6062
6063 if (can_establish) {
6065 struct city_list *cities_out_of_home;
6066 struct city_list *cities_out_of_dest;
6067 struct player *partner_player;
6068
6069 /* Announce creation of trade route (it's not actually created until
6070 * later in this function, as we have to cancel existing routes, but
6071 * it makes more sense to announce in this order) */
6072
6074
6075 /* Always tell the unit owner */
6076 notify_player(pplayer, NULL,
6078 _("New trade route established from %s to %s."),
6081 if (pplayer != partner_player) {
6084 _("The %s established a trade route between their "
6085 "city %s and %s."),
6086 nation_plural_for_player(pplayer),
6089 }
6090
6093
6094 /* Now cancel any less profitable trade route from the home city. */
6096 struct trade_route *pback;
6097
6099
6101 free(premove);
6102 free(pback);
6104
6105 /* And the same for the dest city. */
6107 struct trade_route *pback;
6108
6110
6112 free(premove);
6113 free(pback);
6115
6116 /* Actually create the new trade route */
6117 proute_from = fc_malloc(sizeof(struct trade_route));
6118 proute_from->partner = pcity_dest->id;
6119 proute_from->goods = goods;
6120
6121 proute_to = fc_malloc(sizeof(struct trade_route));
6122 proute_to->partner = pcity_homecity->id;
6123 proute_to->goods = goods;
6124
6128 } else {
6129 proute_from->dir = RDIR_FROM;
6130 proute_to->dir = RDIR_TO;
6131 }
6134
6135 /* Refresh the cities. */
6139 city_refresh(pcity);
6142 city_refresh(pcity);
6144
6145 /* Notify the owners of the cities. */
6149 send_city_info(city_owner(pcity), pcity);
6152 send_city_info(city_owner(pcity), pcity);
6154
6155 /* Notify each player about the other's cities. */
6156 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6160 send_city_info(pplayer, pcity_dest);
6161 }
6162
6164 if (partner_player != city_owner(pcity)) {
6167 }
6168 if (pplayer != city_owner(pcity)) {
6169 send_city_info(pplayer, pcity);
6171 }
6173
6175 if (partner_player != city_owner(pcity)) {
6178 }
6179 if (pplayer != city_owner(pcity)) {
6180 send_city_info(pplayer, pcity);
6182 }
6184
6187 }
6188
6189 /* May cause an incident */
6191 pplayer, act_utype, city_owner(pcity_dest),
6194
6196
6197 /* Free data. */
6200
6201 return TRUE;
6202}
6203
6204/**********************************************************************/
6212void handle_unit_sscs_set(struct player *pplayer,
6213 int unit_id,
6215 int value)
6216{
6217 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6218 const struct civ_map *nmap = &(wld.map);
6219
6220 if (NULL == punit) {
6221 /* Being asked to unqueue a "spent" unit because the client haven't
6222 * been told that it's gone is expected. */
6223 if (type != USSDT_UNQUEUE) {
6224 /* Probably died or bribed. */
6225 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6226 }
6227
6228 return;
6229 }
6230
6231 switch (type) {
6232 case USSDT_QUEUE:
6233 /* Reminds the client to ask the server about what actions the unit can
6234 * perform against the target tile. Action decision state can be set by
6235 * the server it self too. */
6236
6237 if (index_to_tile(nmap, value) == NULL) {
6238 /* Asked to be reminded to ask what actions the unit can do to a non
6239 * existing target tile. */
6240 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6241 value, unit_id);
6242 break;
6243 }
6244
6247
6248 /* Let the client know that this unit needs the player to decide
6249 * what to do. */
6251
6252 break;
6253 case USSDT_UNQUEUE:
6254 /* Delete the reminder for the client to ask the server about what
6255 * actions the unit can perform against a certain target tile.
6256 * Action decision state can be set by the server it self too. */
6257
6260
6261 /* Let the client know that this unit no longer needs the player to
6262 * decide what to do. */
6264
6265 break;
6266 case USSDT_BATTLE_GROUP:
6267 /* Battlegroups are handled entirely by the client, so all we have to
6268 do here is save the battlegroup ID so that it'll be persistent. */
6269
6271
6272 break;
6273 case USSDT_SENTRY:
6274 if (value == 0) {
6275 if (punit->activity != ACTIVITY_SENTRY) {
6276 return;
6277 }
6278
6280 /* Impossible to set to Idle? */
6282 }
6283 } else if (value == 1) {
6285 return;
6286 }
6287
6289 /* Should have been caught above */
6291 }
6292 } else {
6293 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6295 }
6296 break;
6297 }
6298}
6299
6300/**********************************************************************/
6303static void unit_plans_clear(struct unit *punit)
6304{
6305 /* Remove city spot reservations for AI settlers on city founding
6306 * mission. */
6308
6309 /* Get rid of old orders. */
6311
6312 /* Make sure that no old goto_tile remains. */
6313 punit->goto_tile = NULL;
6314}
6315
6316/**********************************************************************/
6320 int unit_id,
6322{
6323 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6324
6325 if (NULL == punit) {
6326 /* Probably died or bribed. */
6327 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6328 unit_id);
6329 return;
6330 }
6331
6333 /* Client error. */
6334 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6335 agent);
6336 return;
6337 }
6338
6339 /* Set the state or exit */
6340 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6341 return;
6342 }
6343
6344 /* Give the new agent a blank slate */
6346
6347 if (agent == SSA_AUTOEXPLORE) {
6349 /* Should have been caught above */
6352 }
6353
6354 /* Exploring is handled here explicitly, since the player expects to
6355 * see an immediate response from setting a unit to auto-explore.
6356 * Handling it deeper in the code leads to some tricky recursive loops -
6357 * see PR#2631. */
6358 if (punit->moves_left > 0) {
6360 }
6361 }
6362}
6363
6364/**********************************************************************/
6369 struct unit *punit,
6371{
6372 const struct civ_map *nmap = &(wld.map);
6373
6374 /* Check that the agent can be activated for this unit. */
6375 switch (agent) {
6376 case SSA_AUTOSETTLER:
6378 return FALSE;
6379 }
6380 break;
6381 case SSA_AUTOEXPLORE:
6383 return FALSE;
6384 }
6385 break;
6386 case SSA_NONE:
6387 /* Always possible. */
6388 break;
6389 case SSA_COUNT:
6391 break;
6392 }
6393
6395
6397
6398 return TRUE;
6399}
6400
6401/**********************************************************************/
6407 struct extra_type *old_target)
6408{
6409 switch (punit->activity) {
6410 case ACTIVITY_IDLE:
6411 switch (old_activity) {
6412 case ACTIVITY_PILLAGE:
6413 {
6414 if (old_target != NULL) {
6416 if (punit2->activity == ACTIVITY_PILLAGE) {
6417 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6418 if (pdep == old_target) {
6421 break;
6422 }
6424 }
6426 }
6427 break;
6428 }
6429 case ACTIVITY_EXPLORE:
6430 /* Restore unit's control status */
6432 break;
6433 default:
6434 ; /* do nothing */
6435 }
6436 break;
6437 case ACTIVITY_EXPLORE:
6441 break;
6442 default:
6443 /* do nothing */
6444 break;
6445 }
6446}
6447
6448/**********************************************************************/
6464
6465/**********************************************************************/
6470{
6471 const struct civ_map *nmap = &(wld.map);
6472
6473 /* Must specify target for ACTIVITY_BASE */
6476
6478 struct extra_type *target = NULL;
6479
6480 /* Assume untargeted pillaging if no target specified */
6485 }
6486
6487 return TRUE;
6488}
6489
6490/**********************************************************************/
6498{
6500 return FALSE;
6501 } else {
6504
6508
6509 return TRUE;
6510 }
6511}
6512
6513/**********************************************************************/
6531
6532/**********************************************************************/
6549
6550/**********************************************************************/
6558 struct extra_type **new_target)
6559{
6562 return FALSE;
6563 } else {
6567
6572 /* unit_assign_specific_activity_target() changed our target activity
6573 * (to ACTIVITY_IDLE in practice) */
6575 } else {
6579
6581 /* Casus Belli for when the activity successfully begins. */
6582 /* TODO: is it more logical to change Casus_Belli_Complete to
6583 * Casus_Belli_Successful_Beginning and trigger it here? */
6589 }
6590 }
6591
6592 return TRUE;
6593 }
6594}
6595
6596/**********************************************************************/
6599void handle_unit_orders(struct player *pplayer,
6600 const struct packet_unit_orders *packet)
6601{
6602 int length = packet->length;
6603 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6604 const struct civ_map *nmap = &(wld.map);
6605 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6606 struct unit_order *order_list;
6607#ifdef FREECIV_DEBUG
6608 int i;
6609#endif
6610
6611 if (NULL == punit) {
6612 /* Probably died or bribed. */
6613 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6614 return;
6615 }
6616
6617 if (0 > length || MAX_LEN_ROUTE < length) {
6618 /* Shouldn't happen */
6619 log_error("handle_unit_orders() invalid %s (%d) "
6620 "packet length %d (max %d)", unit_rule_name(punit),
6621 packet->unit_id, length, MAX_LEN_ROUTE);
6622 return;
6623 }
6624
6625 if (src_tile != unit_tile(punit)) {
6626 /* Failed sanity check. Usually this happens if the orders were sent
6627 * in the previous turn, and the client thought the unit was in a
6628 * different position than it's actually in. The easy solution is to
6629 * discard the packet. We don't send an error message to the client
6630 * here (though maybe we should?). */
6631 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6632 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6633 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6634 return;
6635 }
6636
6637 if (ACTIVITY_IDLE != punit->activity) {
6638 /* New orders implicitly abandon current activity */
6640 }
6641
6642 if (length) {
6643 order_list = create_unit_orders(nmap, length, packet->orders);
6644 if (!order_list) {
6645 log_error("received invalid orders from %s for %s (%d).",
6646 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6647 return;
6648 }
6649 }
6650
6651 /* This must be before old orders are freed. If this is
6652 * settlers on city founding mission, city spot reservation
6653 * from goto_tile must be freed, and free_unit_orders() loses
6654 * goto_tile information */
6656
6658 /* If we waited on a tile, reset punit->done_moving */
6659 punit->done_moving = (punit->moves_left <= 0);
6660
6661 if (length == 0) {
6664 return;
6665 }
6666
6668 punit->orders.length = length;
6669 punit->orders.index = 0;
6670 punit->orders.repeat = packet->repeat;
6671 punit->orders.vigilant = packet->vigilant;
6672 if (length) {
6674 }
6675
6676 if (!packet->repeat) {
6678 } else {
6679 /* Make sure that no old goto_tile remains. */
6680 punit->goto_tile = NULL;
6681 }
6682
6683#ifdef FREECIV_DEBUG
6684 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6685 for (i = 0; i < length; i++) {
6686 log_debug(" %d,%s,%s,%d,%d",
6687 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6688 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6690 packet->orders[i].order == ORDER_ACTIVITY ?
6692 "no action/activity required",
6693 packet->orders[i].target,
6694 packet->orders[i].sub_target);
6695 }
6696#endif /* FREECIV_DEBUG */
6697
6699 || execute_orders(punit, TRUE)) {
6700 /* Looks like the unit survived. */
6702 }
6703}
6704
6705/**********************************************************************/
6708void handle_worker_task(struct player *pplayer,
6709 const struct packet_worker_task *packet)
6710{
6711 struct city *pcity = game_city_by_number(packet->city_id);
6712 struct worker_task *ptask = NULL;
6713 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
6714
6715 if (pcity == NULL || pcity->owner != pplayer || ptile == NULL) {
6716 return;
6717 }
6718
6720 if (tile_index(ptask_old->ptile) == packet->tile_id) {
6721 ptask = ptask_old;
6722 }
6724
6725 if (ptask == NULL) {
6726 if (packet->activity == ACTIVITY_LAST) {
6727 return;
6728 }
6729
6730 ptask = fc_malloc(sizeof(struct worker_task));
6733 } else {
6734 if (packet->activity == ACTIVITY_LAST) {
6736 free(ptask);
6737 ptask = NULL;
6738 }
6739 }
6740
6741 if (ptask != NULL) {
6742 ptask->ptile = ptile;
6743 ptask->act = packet->activity;
6744 if (packet->tgt >= 0) {
6745 if (packet->tgt < MAX_EXTRA_TYPES) {
6746 ptask->tgt = extra_by_number(packet->tgt);
6747 } else {
6748 log_debug("Illegal worker task target %d", packet->tgt);
6749 ptask->tgt = NULL;
6750 }
6751 } else {
6752 ptask->tgt = NULL;
6753 }
6754 ptask->want = packet->want;
6755 }
6756
6757 if (ptask && !worker_task_is_sane(ptask)) {
6758 log_debug("Bad worker task");
6760 free(ptask);
6761 ptask = NULL;
6762 return;
6763 }
6764
6765 lsend_packet_worker_task(pplayer->connections, packet);
6766}
const char * action_name_translation(const struct action *action)
Definition actions.c:1982
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1925
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:6294
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2002
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:5497
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5823
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:3347
struct act_prob action_prob_unit_vs_tgt(const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:5519
struct act_prob action_prob_vs_city(const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:4981
struct act_prob action_prob_vs_unit(const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5065
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1991
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5342
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:4073
struct action * action_is_blocked_by(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:3027
struct act_prob action_prob_vs_stack(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:5258
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:3832
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:3909
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:6239
struct act_prob action_prob_vs_extras(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5426
bool action_id_exists(const action_id act_id)
Definition actions.c:1820
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1860
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2306
#define ACTPROB_NA
Definition actions.h:906
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
#define action_has_result(_act_, _res_)
Definition actions.h:429
#define action_enabler_list_iterate_end
Definition actions.h:439
#define action_id_get_role(act_id)
Definition actions.h:694
#define action_iterate_end
Definition actions.h:463
#define MAX_NUM_ACTIONS
Definition actions.h:312
#define action_id_get_actor_kind(act_id)
Definition actions.h:646
#define ACTPROB_NOT_KNOWN
Definition actions.h:908
#define action_get_activity(_pact_)
Definition actions.h:697
#define action_has_result_safe(paction, result)
Definition actions.h:661
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:437
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:682
#define ACTPROB_IMPOSSIBLE
Definition actions.h:904
#define action_iterate(_act_)
Definition actions.h:459
#define ACTION_ANY
Definition actions.h:306
#define action_id_get_target_kind(act_id)
Definition actions.h:650
#define action_id_has_result_safe(act_id, result)
Definition actions.h:663
#define action_id_has_complex_target(act_id)
Definition actions.h:668
#define ACTION_NONE
Definition actions.h:309
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:374
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:1852
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1231
bool is_capital(const struct city *pcity)
Definition city.c:1571
const char * city_name_get(const struct city *pcity)
Definition city.c:1128
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1456
void city_size_add(struct city *pcity, int add)
Definition city.c:1155
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2004
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2043
bool city_exist(int id)
Definition city.c:3560
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:699
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:762
#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:2343
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1513
int build_points_left(struct city *pcity)
Definition citytools.c:571
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3039
void city_units_upkeep(const struct city *pcity)
Definition citytools.c:3127
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:369
void remove_city(struct city *pcity)
Definition citytools.c:1699
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Definition citytools.c:2907
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3536
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, const char *reason)
Definition cityturn.c:1031
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3424
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:762
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:765
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:608
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:834
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:74
#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:2343
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:357
int Impr_type_id
Definition fc_types.h:379
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:373
int action_id
Definition fc_types.h:392
#define ACTRES_NONE
Definition fc_types.h:330
#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:385
#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:705
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:220
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:2511
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:1379
#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:292
#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:3200
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2951
void maybe_make_contact(struct tile *ptile, struct player *pplayer)
Definition plrhand.c:2357
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1142
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3001
struct conn_list * player_reply_dest(struct player *pplayer)
Definition plrhand.c:1589
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2904
#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:199
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:170
struct civ_game::@31::@35 server
bool homecaughtunits
Definition game.h:188
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
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:189
#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:2830
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:217
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1779
void free_unit_orders(struct unit *punit)
Definition unit.c:1765
bool unit_is_alive(int id)
Definition unit.c:2249
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1918
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1085
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1242
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2437
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2386
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:838
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2300
bool can_unit_do_autosettlers(const struct unit *punit)
Definition unit.c:602
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:361
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1102
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:865
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1984
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2421
bool unit_has_orders(const struct unit *punit)
Definition unit.c:205
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:562
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:904
#define unit_tile(_pu)
Definition unit.h:390
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_owner(_pu)
Definition unit.h:389
@ 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:425
@ 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:4116
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:3275
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4885
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4430
#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:6599
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:5384
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:4310
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:6708
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6468
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:3311
#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:5194
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:4838
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:6405
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3142
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4525
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5531
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:4712
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:4261
#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:6319
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:3291
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:6454
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:5281
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:4014
static bool unit_activity_targeted_internal(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Definition unithand.c:6556
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:6519
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:5724
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:4150
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:6496
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:3161
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:6535
static bool unit_nuke(struct player *pplayer, struct unit *punit, struct tile *def_tile, const struct action *paction)
Definition unithand.c:4642
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:5422
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:6212
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:4371
#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:4821
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:5493
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:6368
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5839
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:6303
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4212
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4475
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:4860
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4800
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:4899
void collect_ransom(struct unit *pcollector, struct unit *punit, bool vet)
Definition unittools.c:2497
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Definition unittools.c:2914
bool execute_orders(struct unit *punit, const bool fresh)
Definition unittools.c:4352
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1549
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:2882
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Definition unittools.c:2587
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2712
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2725
void notify_unit_experience(struct unit *punit)
Definition unittools.c:743
void unit_activities_cancel(struct unit *punit)
Definition unittools.c:800
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:2668
void unit_forget_last_activity(struct unit *punit)
Definition unittools.c:1053
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:4838
void do_explore(struct unit *punit)
Definition unittools.c:2947
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3228
bool unit_can_do_action_now(const struct unit *punit)
Definition unittools.c:4866
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2135
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unittools.c:2983
void unit_transport_unload_send(struct unit *punit)
Definition unittools.c:3280
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2195
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1187
void unit_assign_specific_activity_target(struct unit *punit, enum unit_activity *activity, struct extra_type **target)
Definition unittools.c:1082
void unit_get_goods(struct unit *punit)
Definition unittools.c:1612
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:3916
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Definition unittools.c:2262
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1225
bool unit_activity_needs_target_from_client(enum unit_activity activity)
Definition unittools.c:1062
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:2498
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:2583
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:852
#define unit_type_iterate_end
Definition unittype.h:859
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