Freeciv-3.3
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 "autoworkers.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,
117static bool unit_activity_targeted_internal(struct unit *punit,
119 struct extra_type **new_target,
121static void illegal_action(struct player *pplayer,
122 struct unit *actor,
124 struct player *tgt_player,
125 struct tile *target_tile,
126 const struct city *target_city,
127 const struct unit *target_unit,
128 int request_kind,
129 const enum action_requester requester);
130static bool city_add_unit(struct player *pplayer, struct unit *punit,
131 struct city *pcity, const struct action *paction);
132static bool city_build(struct player *pplayer, struct unit *punit,
133 struct tile *ptile, const char *name,
134 const struct action *paction);
135static bool do_unit_establish_trade(struct player *pplayer,
136 struct unit *punit,
137 struct city *pcity_dest,
138 const struct action *paction);
139
140static bool unit_do_help_build(struct player *pplayer,
141 struct unit *punit,
142 struct city *pcity_dest,
143 const struct action *paction);
144static bool unit_do_regular_move(struct player *actor_player,
145 struct unit *actor_unit,
146 struct tile *target_tile,
147 const struct action *paction);
148static bool unit_bombard(struct unit *punit, struct tile *ptile,
149 const struct action *paction);
150static bool unit_nuke(struct player *pplayer, struct unit *punit,
151 struct tile *def_tile,
152 const struct action *paction);
153static bool unit_do_destroy_city(struct player *act_player,
154 struct unit *act_unit,
155 struct city *tgt_city,
156 const struct action *paction);
157static bool do_unit_change_homecity(struct unit *punit,
158 struct city *pcity,
159 const struct action *paction);
160static bool do_attack(struct unit *actor_unit, struct tile *target_tile,
161 const struct action *paction);
163 struct unit *act_unit,
164 struct city *tgt_city,
165 const struct action *paction);
167 struct unit *act_unit,
168 struct city *tgt_city,
170 const struct action *paction);
171static bool do_unit_conquer_city(struct player *act_player,
172 struct unit *act_unit,
173 struct city *tgt_city,
174 struct action *paction);
175static bool do_action_activity(struct unit *punit,
176 const struct action *paction);
177static bool do_action_activity_targeted(struct unit *punit,
178 const struct action *paction,
179 struct extra_type **new_target);
180static inline bool
181non_allied_not_listed_at(const struct player *pplayer,
182 const int *list, int n, const struct tile *ptile);
183
184/**********************************************************************/
188{
189 const struct unit_type *to_unittype;
193 const struct civ_map *nmap = &(wld.map);
194
195 if (NULL == from_unittype) {
196 /* Probably died or bribed. */
197 log_verbose("handle_unit_type_upgrade() invalid unit type %d", uti);
198 return;
199 }
200
202 if (!to_unittype) {
204 _("Illegal packet, can't upgrade %s (yet)."),
206 return;
207 }
208
209 /*
210 * Try to upgrade units. The order we upgrade in is arbitrary (if
211 * the player really cared they should have done it manually).
212 */
214 unit_list_iterate(pplayer->units, punit) {
216 struct city *pcity = tile_city(unit_tile(punit));
217
219 && unit_perform_action(pplayer, punit->id, pcity->id, 0, "",
222 } else if (UU_NO_MONEY == unit_upgrade_test(nmap, punit, FALSE)) {
223 break;
224 }
225 }
228
229 /* Alert the player about what happened. */
230 if (number_of_upgraded_units > 0) {
231 const int cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
233 /* FIXME: plurality of number_of_upgraded_units ignored!
234 * (Plurality of unit names is messed up anyway.) */
235 /* TRANS: "2 Musketeers upgraded to Riflemen for 100 gold."
236 * Plurality is in gold (second %d), not units. */
237 PL_("%d %s upgraded to %s for %d gold.",
238 "%d %s upgraded to %s for %d gold.",
244 send_player_info_c(pplayer, pplayer->connections);
245 } else {
247 _("No units could be upgraded."));
248 }
249}
250
251/**********************************************************************/
257static bool do_unit_upgrade(struct player *pplayer,
258 struct unit *punit, struct city *pcity,
260 const struct action *paction)
261{
262 const struct unit_type *from_unit = unit_type_get(punit);
263 const struct unit_type *to_unit = can_upgrade_unittype(pplayer, from_unit);
264 int cost = unit_upgrade_price(pplayer, from_unit, to_unit);
265
267 pplayer->economic.gold -= cost;
268 send_player_info_c(pplayer, pplayer->connections);
269
270 if (ordered_by == ACT_REQ_PLAYER) {
272 PL_("%s upgraded to %s for %d gold.",
273 "%s upgraded to %s for %d gold.", cost),
276 cost);
277 }
278
279 return TRUE;
280}
281
282/**********************************************************************/
286static inline bool
287non_allied_not_listed_at(const struct player *pplayer,
288 const int *list, int n, const struct tile *ptile)
289{
290 unit_list_iterate(ptile->units, punit) {
291 if (!pplayers_allied(pplayer, unit_owner(punit))) {
292 bool listed = FALSE;
293 int id = punit->id;
294 int i;
295
296 for (i = 0; i < n; i++) {
297 if (id == list[i]) {
298 listed = TRUE;
299 break;
300 }
301 }
302 if (!listed) {
303 return TRUE;
304 }
305 }
307 return FALSE;
308}
309
310/**********************************************************************/
316static bool do_capture_units(struct player *pplayer,
317 struct unit *punit,
318 struct tile *pdesttile,
319 const struct action *paction)
320{
321 struct city *pcity;
323 char hcity_name[MAX_LEN_NAME] = {'\0'};
324 const char *capturer_nation = nation_plural_for_player(pplayer);
326 const struct unit_type *act_utype;
327 int id, hcity;
328 int n = 0, capt[unit_list_size(pdesttile->units)];
329 bool lost_with_city = FALSE;
330 int i;
331
332 /* Sanity check: The actor still exists. */
333 fc_assert_ret_val(pplayer, FALSE);
335 id = punit->id;
336
338
339 /* Sanity check: make sure that the capture won't result in the actor
340 * ending up with more than one unit of each unique unit type. */
343 bool unique_conflict = FALSE;
344
345 /* Check what the player already has. */
348 /* The player already has a unit of this kind. */
350 }
351
353 /* The type of the units at the tile must also be checked. Two allied
354 * players can both have their unique unit at the same tile.
355 * Capturing them both would give the actor two units of a kind that
356 * is supposed to be unique. */
357
359 /* There is another unit of the same kind at this tile. */
361 } else {
362 /* Remember the unit type in case another unit of the same kind is
363 * encountered later. */
365 }
366 }
367
368 if (unique_conflict) {
369 log_debug("capture units: already got unique unit");
371 /* TRANS: You can only have one Leader. */
372 _("You can only have one %s."),
374
375 return FALSE;
376 }
377 /* Remember the units here
378 * for the mess callbacks may do in the process of transferring */
379 capt[n++] = to_capture->id;
381
382 /* N.B: unit_link() always returns the same pointer. */
384
388 if (hcity) {
389 /* Rarely, we'll need it... */
391 }
392
393 for (i = 0; i < n; i++) {
395 struct player *uplayer;
396 const char *victim_link;
397 const struct unit_type *utype;
398 struct tile *ptile = NULL;
399 bool really_lost = FALSE;
400
401 if (!to_capture) {
402 continue;
403 }
405 if (uplayer == pplayer) {
406 /* Somehow transferred by scripts (e.g. diplomat incited a city) */
407 continue;
408 }
409 utype = unit_type_get(to_capture);
411 uplayer->score.units_lost++;
412 if (!really_lost) {
413 /* A hack: if the captured unit is lost with a capturer's city,
414 * we link the old unit, otherwise the new one */
417 }
418 if (!to_capture) {
419 /* Lost during capturing */
421 } else {
422 /* As unit_change_owner() currently remove the old unit and
423 * replace by a new one (with a new id), we want to make link to
424 * the new unit. */
426 ptile = unit_tile(to_capture);
427 /* Notify capturer only if there is a gain */
429 /* TRANS: <unit> ... <unit> */
430 _("Your %s succeeded in capturing the %s %s."),
433 }
434
435 /* Notify loser */
438 /* TRANS: <unit> ... <Poles> */
439 _("Your %s was captured by the %s."),
441
442 /* May cause an incident */
445
446 if (really_lost) {
447 /* The city for which the unit was captured has perished! */
448 /* Nobody actually gets the unit. */
449 pplayer->score.units_lost++;
450 notify_player(pplayer, pdesttile,
452 _("%s lost along with control of %s."),
454 /* As in unit_change_owner(), don't say pplayer is killer */
456 continue;
457 }
458
459 if (to_capture != NULL) {
461
462 if (NULL != pcity /* Keep old behavior */
464 || (new_owner == pplayer
465 ? non_allied_not_listed_at(pplayer, capt + (i + 1),
466 n - (i + 1), ptile)
467 : (bool)
470 UTYF_FLAGLESS)))) {
471 /* The captured unit is in a city or with a foreign unit
472 * that its owner is not capturing. Bounce it. */
474 }
475 }
476
477 /* Check if the city we are going to home units in stays. */
478 if (hcity && i + 1 < n && !player_city_by_number(pplayer, hcity)) {
479 /* Oops, it's lost. Maybe the capturer is rehomed? */
480 if (player_unit_by_number(pplayer, id)) {
481 /* Well, it's natural to home them here now */
483 } else {
484 /* Removing the rest of the stack (except "NoHome" units) */
486 }
487 }
488 }
489
490 if (!unit_is_alive(id)) {
491 /* Callbacks took the capturer, nothing more to do */
492 return TRUE;
493 }
496
498
499 return TRUE;
500}
501
502/**********************************************************************/
505static bool occupy_move(struct tile *def_tile, struct unit *punit,
506 const struct action *paction)
507{
510 /* Hack: make sure the unit has enough moves_left for the move to succeed,
511 * and adjust moves_left to afterward (if successful). */
514 int id = punit->id;
515
517 /* Post attack occupy move. */
519 NULL, NULL, paction,
521 NULL, NULL)) {
522 if (unit_is_alive(id)) {
523 int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
524
525 /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
526 * Attack SINGLE_COST is already calculated in to old_moves. */
527 punit->moves_left = old_moves - mcost;
528 if (punit->moves_left < 0) {
529 punit->moves_left = 0;
530 }
531 } else {
532 return FALSE;
533 }
534 } else if (unit_is_alive(id)) {
536 } else {
537 return FALSE;
538 }
539 }
540
541 return TRUE;
542}
543
544/**********************************************************************/
550static bool do_wipe_units(struct unit *punit,
551 struct tile *pdesttile,
552 const struct action *paction)
553{
554 struct player *wiper = unit_owner(punit);
555 int wid = punit->id;
558 const struct unit_type *act_utype = unit_type_get(punit);
559
560 /* N.B: unit_link() always returns the same pointer. */
562
564 struct player *owner = unit_owner(to_wipe);
565 const char *victim_link = unit_link(to_wipe);
566
568
569 /* Notify players */
571 /* TRANS: <unit> ... <unit> */
572 _("Your %s wiped the %s %s."),
577 /* TRANS: <unit> ... <Poles> */
578 _("Your %s was wiped by the %s."),
580
581 /* May cause an incident */
584
586
590
592 }
593
594 return TRUE;
595}
596
597/**********************************************************************/
603static bool do_expel_unit(struct player *pplayer,
604 struct unit *actor,
605 struct unit *target,
606 const struct action *paction)
607{
609 struct player *uplayer;
610 struct tile *target_tile;
611 struct city *pcity;
612 const struct unit_type *act_utype;
613
614 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
615 * the caller? Check in the code that emits the signal. */
616 fc_assert_ret_val(target, FALSE);
617
618 uplayer = unit_owner(target);
619
620 /* A unit is supposed to have an owner. */
622
623 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
624 * the caller? Check in the code that emits the signal. */
627
628 /* Where is the actor player? */
629 fc_assert_ret_val(pplayer, FALSE);
630
631 target_tile = unit_tile(target);
632
633 /* Expel the target unit to its owner's primary capital. */
634 /* TODO: Could be also nearest secondary capital */
636
637 /* N.B: unit_link() always returns the same pointer. */
639
640 if (pcity == NULL) {
641 /* No where to send the expelled unit. */
642
643 /* The price of failing an expulsion is a single move. */
646
647 /* Notify the actor player. */
649 /* TRANS: <Poles> <Spy> */
650 _("The %s don't have a capital to expel their %s to."),
652
653 /* Nothing more could be done. */
654 return FALSE;
655 }
656
657 /* Please review the code below and above (including the strings sent to
658 * the players) before allowing expulsion to non capital cities. */
660
661 /* Notify everybody involved. */
663 /* TRANS: <Border Patrol> ... <Spy> */
664 _("Your %s succeeded in expelling the %s %s."),
668 /* TRANS: <unit> ... <Poles> */
669 _("Your %s was expelled by the %s."),
671
672 /* Being expelled destroys all remaining movement. */
673 if (!teleport_unit_to_city(target, pcity, 0, FALSE)) {
674 log_error("Bug in unit expulsion: unit can't teleport.");
675
676 return FALSE;
677 }
678
679 /* This may cause a diplomatic incident */
682
683 /* Mission accomplished. */
684 return TRUE;
685}
686
687/**********************************************************************/
694 struct unit *act_unit,
695 struct tile *tgt_tile,
696 const struct action *paction)
697{
698 bool success;
699 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
701
702 /* Sanity check */
705
706 unit_move(act_unit, tgt_tile, move_cost,
708 FALSE, TRUE,
711
713
714 if (success) {
715 const struct unit_type *act_utype = unit_type_get(act_unit);
716
717 /* May cause an incident */
721 }
722
723 return success;
724}
725
726/**********************************************************************/
732static bool do_heal_unit(struct player *act_player,
733 struct unit *act_unit,
734 struct unit *tgt_unit,
735 const struct action *paction)
736{
737 int healing_limit;
738 int tgt_hp_max;
739 struct player *tgt_player;
740 struct tile *tgt_tile;
743 const char *tgt_unit_owner;
744 const struct unit_type *act_utype;
745
746 /* Sanity checks: got all the needed input. */
750
752
753 /* The target unit can't have more HP than this. */
755
756 /* Sanity check: target isn't at full health and can therefore can be
757 * healed. */
759
760 /* Fetch the target unit's owner. */
763
764 /* Fetch the target unit's tile. */
767
768 /* The max amount of HP that can be added. */
770 NULL,
771 &(const struct req_context) {
772 .player = unit_owner(act_unit),
773 .city = tile_city(unit_tile(act_unit)),
775 .unit = act_unit,
776 .unittype = unit_type_get(act_unit),
777 .action = paction,
778 },
779 &(const struct req_context) {
780 .player = unit_owner(tgt_unit),
781 .city = tile_city(unit_tile(tgt_unit)),
783 .unit = tgt_unit,
784 .unittype = unit_type_get(tgt_unit),
785 },
787 ) + 100)
788 * tgt_hp_max) / 100;
789
790 /* Heal the target unit. */
793
795
796 /* Every call to unit_link() overwrites the previous. Two units are being
797 * linked to. */
800
801 /* Notify everybody involved. */
802 if (act_player == tgt_player) {
803 /* TRANS: used instead of nation adjective when the nation is
804 * domestic. */
805 tgt_unit_owner = _("your");
806 } else {
808 }
809
811 /* TRANS: If foreign: Your Leader heals Finnish Warrior.
812 * If domestic: Your Leader heals your Warrior. */
813 _("Your %s heals %s %s."),
815
816 if (act_player != tgt_player) {
818 /* TRANS: Norwegian ... Leader ... Warrior */
819 _("%s %s heals your %s."),
822 }
823
824 /* This may have diplomatic consequences. */
827
828 return TRUE;
829}
830
831/**********************************************************************/
838 struct unit *act_unit,
839 struct unit *tgt_unit,
840 const struct action *paction)
841{
842 /* Unload the unit and send out info to clients. */
844
845 return TRUE;
846}
847
848/**********************************************************************/
856static bool do_unit_board(struct player *act_player,
857 struct unit *act_unit,
858 struct unit *tgt_unit,
859 const struct action *paction)
860{
863 }
864
865 /* Load the unit and send out info to clients. */
867
868 return TRUE;
869}
870
871/**********************************************************************/
879static bool do_unit_load(struct player *act_player,
880 struct unit *act_unit,
881 struct unit *tgt_unit,
882 const struct action *paction)
883{
886 }
887
888 /* Load the unit and send out info to clients. */
890
891 return TRUE;
892}
893
894/**********************************************************************/
900static bool do_unit_unload(struct player *act_player,
901 struct unit *act_unit,
902 struct unit *tgt_unit,
903 const struct action *paction)
904{
905 /* Unload the unit and send out info to clients. */
907
908 return TRUE;
909}
910
911/**********************************************************************/
917static bool do_disembark(struct player *act_player,
918 struct unit *act_unit,
919 struct tile *tgt_tile,
920 const struct action *paction)
921{
922 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
923
924 /* Sanity checks */
929
930 unit_move(act_unit, tgt_tile, move_cost,
932 FALSE, FALSE,
935
936 return TRUE;
937}
938
939/**********************************************************************/
945static bool do_unit_hut(struct player *act_player,
946 struct unit *act_unit,
947 struct tile *tgt_tile,
948 const struct action *paction)
949{
950 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
951
952 /* Sanity checks */
957
958 unit_move(act_unit, tgt_tile, move_cost,
960 FALSE, FALSE,
963
964 return TRUE;
965}
966
967/**********************************************************************/
975static bool do_unit_embark(struct player *act_player,
976 struct unit *act_unit,
977 struct unit *tgt_unit,
978 const struct action *paction)
979{
980 struct tile *tgt_tile;
981 int move_cost;
982
983 /* Sanity checks */
988
990 /* Assumed to be legal. */
992 }
993
994 /* Do it. */
996 move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
997 unit_move(act_unit, tgt_tile, move_cost,
998 tgt_unit, BV_ISSET(paction->sub_results,
1000 FALSE, FALSE,
1001 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
1003
1004 return TRUE;
1005}
1006
1007/**********************************************************************/
1013 const struct action *paction)
1014{
1016
1018}
1019
1020/**********************************************************************/
1027static bool rel_may_become_war(const struct player *pplayer,
1028 const struct player *oplayer)
1029{
1030 enum diplstate_type ds;
1031
1032 fc_assert_ret_val(pplayer, FALSE);
1034
1035 ds = player_diplstate_get(pplayer, oplayer)->type;
1036
1037 /* The player can't declare war on
1038 * someone they already are at war with. */
1039 return ds != DS_WAR
1040 /* The player can't declare war on a teammate or on themself. */
1041 && ds != DS_TEAM && pplayer != oplayer;
1042}
1043
1044/**********************************************************************/
1050static bool
1052 const struct action *paction,
1053 struct player *player1,
1054 struct player *player2,
1055 bool act_if_diplrel_kind(const struct unit_type *,
1056 const action_id,
1057 const int,
1058 const bool))
1059{
1060 if (player2 == NULL) {
1061 /* No one to declare war on */
1062 return FALSE;
1063 }
1064
1066 /* Can't declare war. */
1067 return FALSE;
1068 }
1069
1072 player2)->type,
1073 TRUE)) {
1074 /* The current diplrel isn't the problem. */
1075 return FALSE;
1076 }
1077
1079 /* War won't make this action legal. */
1080 return FALSE;
1081 }
1082
1083 return TRUE;
1084}
1085
1086/**********************************************************************/
1092static struct player *need_war_player_hlp(const struct unit *actor,
1093 const action_id act,
1094 const struct tile *target_tile,
1095 const struct city *target_city,
1096 const struct unit *target_unit)
1097{
1098 struct player *target_player = NULL;
1100 struct action *paction = action_by_number(act);
1101
1103
1104 if (action_id_get_actor_kind(act) != AAK_UNIT) {
1105 /* No unit can ever do this action so it isn't relevant. */
1106 return NULL;
1107 }
1108
1109 if (!unit_can_do_action(actor, act)) {
1110 /* The unit can't do the action no matter if there is war or not. */
1111 return NULL;
1112 }
1113
1114 /* Look for hard coded war requirements without support for looking up in
1115 * an action enabler requirement. */
1116 switch (paction->result) {
1117 case ACTRES_ATTACK:
1118 case ACTRES_WIPE_UNITS:
1121 /* Target is a unit stack but a city can block it. */
1123
1125 if (target_tile != NULL) {
1126 struct city *tcity;
1127
1128 if ((tcity = tile_city(target_tile))
1130 return city_owner(tcity);
1131 }
1132 }
1133 }
1134 break;
1135
1136 case ACTRES_PARADROP:
1138 /* Target is a tile but a city can block it. */
1140 if (target_tile != NULL
1142 /* Seen tile unit savers */
1143
1144 struct city *tcity;
1145
1147 return city_owner(tcity);
1148 }
1149 }
1150 break;
1154 case ACTRES_SPY_POISON:
1163 case ACTRES_TRADE_ROUTE:
1164 case ACTRES_MARKETPLACE:
1165 case ACTRES_HELP_WONDER:
1168 case ACTRES_CAPTURE_UNITS: /* Only foreign is a hard req. */
1169 case ACTRES_FOUND_CITY:
1170 case ACTRES_JOIN_CITY:
1171 case ACTRES_STEAL_MAPS:
1172 case ACTRES_SPY_NUKE:
1173 case ACTRES_NUKE:
1174 case ACTRES_NUKE_UNITS:
1176 case ACTRES_EXPEL_UNIT:
1179 case ACTRES_HOME_CITY:
1180 case ACTRES_HOMELESS:
1182 case ACTRES_AIRLIFT:
1183 case ACTRES_HEAL_UNIT:
1186 case ACTRES_BOMBARD:
1189 case ACTRES_CULTIVATE:
1190 case ACTRES_PLANT:
1191 case ACTRES_PILLAGE:
1192 case ACTRES_CLEAN:
1193 case ACTRES_FORTIFY:
1194 case ACTRES_CONVERT:
1195 case ACTRES_ROAD:
1196 case ACTRES_BASE:
1197 case ACTRES_MINE:
1198 case ACTRES_IRRIGATE:
1205 case ACTRES_SPY_ATTACK:
1206 case ACTRES_HUT_ENTER:
1208 case ACTRES_UNIT_MOVE:
1209 case ACTRES_TELEPORT:
1212 case ACTRES_SPY_ESCAPE:
1213 case ACTRES_NONE:
1214 /* No special help. */
1215 break;
1216
1218 }
1219
1220 /* Look for war requirements from the action enablers. */
1222 case ATK_CITY:
1223 if (target_city == NULL) {
1224 /* No target city. */
1225 return NULL;
1226 }
1227
1229 break;
1230 case ATK_UNIT:
1231 if (target_unit == NULL) {
1232 /* No target unit. */
1233 return NULL;
1234 }
1236 /* Target unit is flagless anyway - no war needed */
1237 return NULL;
1238 }
1239
1241 break;
1242 case ATK_STACK:
1243 if (target_tile == NULL) {
1244 /* No target units since no target tile. */
1245 return NULL;
1246 }
1247
1248 unit_list_iterate(target_tile->units, tunit) {
1251 target_player = unit_owner(tunit);
1252 break;
1253 }
1255 break;
1256 case ATK_TILE:
1257 if (target_tile == NULL) {
1258 /* No target tile. */
1259 return NULL;
1260 }
1262 break;
1263 case ATK_EXTRAS:
1264 if (target_tile == NULL) {
1265 /* No target tile. */
1266 return NULL;
1267 }
1269 break;
1270 case ATK_SELF:
1271 /* Can't declare war on itself. */
1272 return NULL;
1273 break;
1274 case ATK_COUNT:
1275 /* Nothing to check. */
1277 return NULL;
1278 }
1279
1280 if (target_player == NULL) {
1281 /* Declaring war won't enable the specified action. */
1282 return NULL;
1283 }
1284
1285 /* Look for DiplRelTileOther war requirements from the action enablers. */
1286 if (target_tile != NULL
1290 return tile_owner(target_tile);
1291 }
1292
1293 /* Look for DiplRel war requirements from the action enablers. */
1297 return target_player;
1298 }
1299
1300 /* No check if other, non war, diplomatic states also could make the
1301 * action legal. This is need_war_player() so war is always the answer.
1302 * If you disagree and decide to add support please check that
1303 * webperimental's "can't found a city on a tile belonging to a non enemy"
1304 * rule still is detected. */
1305
1306 return NULL;
1307}
1308
1309/**********************************************************************/
1314static struct player *need_war_player(const struct unit *actor,
1315 const action_id act_id,
1316 const struct tile *target_tile,
1317 const struct city *target_city,
1318 const struct unit *target_unit)
1319{
1320 if (act_id == ACTION_ANY) {
1321 /* Any action at all will do. */
1322 action_iterate(act) {
1323 struct player *war_player;
1324
1327 target_unit);
1328
1329 if (war_player != NULL) {
1330 /* Declaring war on this player may enable this action. */
1331 return war_player;
1332 }
1334
1335 /* No action at all may be enabled by declaring war. */
1336 return NULL;
1337 } else {
1338 /* Look for the specified action. */
1339 return need_war_player_hlp(actor, act_id,
1341 target_unit);
1342 }
1343}
1344
1345/**********************************************************************/
1349static bool
1351 const struct player *pplayer)
1352{
1353 unit_list_iterate(ptile->units, pother) {
1354 if (can_player_see_unit(pplayer, pother)
1355 && !pplayers_allied(pplayer, unit_owner(pother))) {
1356 return TRUE;
1357 }
1359
1360 return FALSE;
1361}
1362
1363/**********************************************************************/
1368static bool does_terrain_block_action(const action_id act_id,
1369 bool is_target,
1370 struct unit *actor_unit,
1371 struct terrain *pterrain)
1372{
1373 if (act_id == ACTION_ANY) {
1374 /* Any action is OK. */
1377 && !does_terrain_block_action(alt_act, is_target,
1378 actor_unit, pterrain)) {
1379 /* Only one action has to be possible. */
1380 return FALSE;
1381 }
1383
1384 /* No action enabled. */
1385 return TRUE;
1386 }
1387
1388 /* ACTION_ANY is handled above. */
1390
1392 enabler) {
1394 (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1396 &enabler->actor_reqs)) {
1397 /* This terrain kind doesn't block this action enabler. */
1398 return FALSE;
1399 }
1401
1402 return TRUE;
1403}
1404
1405/**********************************************************************/
1410static bool does_nation_block_action(const action_id act_id,
1411 bool is_target,
1412 struct unit *actor_unit,
1413 struct nation_type *pnation)
1414{
1415 if (act_id == ACTION_ANY) {
1416 /* Any action is OK. */
1419 && !does_nation_block_action(alt_act, is_target,
1420 actor_unit, pnation)) {
1421 /* Only one action has to be possible. */
1422 return FALSE;
1423 }
1425
1426 /* No action enabled. */
1427 return TRUE;
1428 }
1429
1430 /* ACTION_ANY is handled above. */
1432
1434 enabler) {
1436 (is_target ? &enabler->target_reqs
1437 : &enabler->actor_reqs))
1439 &enabler->actor_reqs)) {
1440 /* This nation doesn't block this action enabler. */
1441 return FALSE;
1442 }
1444
1445 return TRUE;
1446}
1447
1448/**********************************************************************/
1452static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1453 const action_id act_id,
1454 const struct tile *target_tile,
1455 const struct city *target_city,
1456 const struct unit *target_unit)
1457{
1458 struct player *must_war_player;
1459 const struct action *paction;
1460 struct action *blocker;
1461 struct player *act_player = unit_owner(punit);
1462 struct player *tgt_player = NULL;
1463 struct ane_expl *explnat = fc_malloc(sizeof(struct ane_expl));
1464 struct civ_map *nmap = &(wld.map);
1467 int action_custom;
1468
1469 /* Not know yet. (Initialize before the below check.) */
1470 explnat->kind = ANEK_UNKNOWN;
1471
1472 paction = action_by_number(act_id);
1473
1474 if (act_id != ACTION_ANY) {
1475 /* A specific action should have a suitable target. */
1477 case ATK_CITY:
1478 if (target_city == NULL) {
1480 }
1481 break;
1482 case ATK_UNIT:
1483 if (target_unit == NULL) {
1485 }
1486 break;
1487 case ATK_STACK:
1488 case ATK_TILE:
1489 case ATK_EXTRAS:
1490 if (target_tile == NULL) {
1492 }
1493 break;
1494 case ATK_SELF:
1495 /* No other target. */
1496 break;
1497 case ATK_COUNT:
1499 break;
1500 }
1501 }
1502
1503 if (explnat->kind == ANEK_MISSING_TARGET) {
1504 /* No point continuing. */
1505 return explnat;
1506 }
1507
1508 if (act_id == ACTION_ANY) {
1509 /* Find the target player of some actions. */
1510 if (target_city) {
1511 /* Individual city targets have the highest priority. */
1513 } else if (target_unit) {
1514 /* Individual unit targets have the next priority. */
1516 } else if (target_tile) {
1517 /* Tile targets have the lowest priority. */
1519 }
1520 } else {
1521 /* Find the target player of this action. */
1523 case ATK_CITY:
1525 break;
1526 case ATK_UNIT:
1528 break;
1529 case ATK_TILE:
1531 break;
1532 case ATK_EXTRAS:
1533 tgt_player = target_tile->extras_owner;
1534 break;
1535 case ATK_STACK:
1536 /* A unit stack may contain units with multiple owners. Pick the
1537 * first one. */
1538 if (target_tile
1539 && unit_list_size(target_tile->units) > 0) {
1541 }
1542 break;
1543 case ATK_SELF:
1544 /* A unit acting against itself. */
1546 break;
1547 case ATK_COUNT:
1549 break;
1550 }
1551 }
1552
1553 if (act_id == ACTION_ANY) {
1554 action_custom = 0;
1555 } else {
1556 switch (paction->result) {
1559 break;
1560 case ACTRES_AIRLIFT:
1562 break;
1563 case ACTRES_NUKE_UNITS:
1565 target_tile);
1566 break;
1567 case ACTRES_ATTACK:
1569 target_tile);
1570 break;
1571 case ACTRES_WIPE_UNITS:
1573 break;
1575 if (target_city) {
1577 punit->activity,
1580 FALSE, FALSE, NULL, TRUE);
1581 } else {
1583 }
1584 break;
1586 if (target_unit) {
1588 punit->activity,
1591 FALSE, TRUE, NULL, FALSE);
1592 } else {
1594 }
1595 break;
1597 case ACTRES_HUT_ENTER:
1600 case ACTRES_UNIT_MOVE:
1601 if (target_tile) {
1603 punit->activity,
1606 FALSE, FALSE, NULL, FALSE);
1607 } else {
1609 }
1610 break;
1611 case ACTRES_TELEPORT:
1612 if (target_tile != NULL) {
1614 punit->activity,
1617 FALSE, NULL, FALSE);
1618 } else {
1620 }
1621 break;
1622 default:
1623 action_custom = 0;
1624 break;
1625 }
1626 }
1627
1628 if (!unit_can_do_action(punit, act_id)) {
1629 explnat->kind = ANEK_ACTOR_UNIT;
1631 && tile_city(target_tile)) {
1632 explnat->kind = ANEK_BAD_TARGET;
1636 act_player)) {
1638 } else if ((!can_exist
1641 || (can_exist
1645 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1646 } else if ((!on_native
1649 || (on_native
1651 USP_NATIVE_TILE, TRUE))) {
1653 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1654 } else if (punit
1657 /* No action enabler allows acting against this terrain kind. */
1659 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1661 && target_tile
1663 TER_NO_CITIES)) {
1665 explnat->no_act_terrain = tile_terrain(target_tile);
1668 && target_tile != NULL
1670 V_MAIN)
1672 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
1675 explnat->no_act_terrain = tile_terrain(target_tile);
1676 } else if (target_tile
1679 /* No action enabler allows acting against this terrain kind. */
1681 explnat->no_act_terrain = tile_terrain(target_tile);
1682 } else if (unit_transported(punit)
1686 } else if (!unit_transported(punit)
1690 } else if (0 < get_transporter_occupancy(punit)
1694 } else if (!(0 < get_transporter_occupancy(punit))
1698 } else if ((punit->homecity > 0)
1702 } else if ((punit->homecity <= 0)
1706 } else if ((punit->homecity <= 0)
1710 } else if (act_player && tgt_player
1712 == DS_PEACE)
1714 act_id,
1715 DS_PEACE,
1716 FALSE)
1718 act_id,
1719 DS_PEACE,
1720 TRUE)) {
1721 explnat->kind = ANEK_PEACE;
1722 explnat->peace_with = tgt_player;
1724 act_id,
1727 target_unit)) != NULL) {
1728 explnat->kind = ANEK_NO_WAR;
1729 explnat->no_war_with = must_war_player;
1730 } else if (action_mp_full_makes_legal(punit, act_id)) {
1731 explnat->kind = ANEK_LOW_MP;
1732 } else if (tgt_player != NULL
1735 act_id,
1737 TRUE)) {
1738 explnat->kind = ANEK_FOREIGN;
1739 } else if (tgt_player != NULL
1742 act_id,
1744 FALSE)) {
1745 explnat->kind = ANEK_DOMESTIC;
1746 } else if (punit != NULL
1748 punit, act_player->nation)) {
1749 explnat->kind = ANEK_NATION_ACT;
1750 explnat->no_act_nation = act_player->nation;
1751 } else if (tgt_player
1752 && does_nation_block_action(act_id, TRUE,
1753 punit, tgt_player->nation)) {
1754 explnat->kind = ANEK_NATION_TGT;
1755 explnat->no_act_nation = tgt_player->nation;
1756 } else if ((target_tile && tile_city(target_tile))
1758 act_id,
1760 TRUE)) {
1762 } else if ((target_tile && !tile_city(target_tile))
1764 act_id,
1766 FALSE)) {
1768 } else if ((target_tile && tile_owner(target_tile) != NULL)
1770 act_id,
1772 TRUE)) {
1774 } else if ((target_tile && tile_owner(target_tile) == NULL)
1776 act_id,
1778 FALSE)) {
1780 } else if (paction && punit
1781 && ((target_tile
1784 || (target_city
1788 || (target_unit
1791 unit_tile(target_unit)))))) {
1792 explnat->kind = ANEK_DISTANCE_FAR;
1793 explnat->distance = paction->max_distance;
1796 && punit && target_tile
1798 > unit_type_get(punit)->paratroopers_range) {
1799 explnat->kind = ANEK_DISTANCE_FAR;
1801 } else if (paction && punit
1802 && ((target_tile
1804 < paction->min_distance)
1805 || (target_city
1808 < paction->min_distance)
1809 || (target_unit
1812 < paction->min_distance))) {
1814 explnat->distance = paction->min_distance;
1815 } else if (target_city
1821 /* TODO: Check max city size requirements from action enabler target
1822 * vectors. */
1823 explnat->kind = ANEK_CITY_TOO_BIG;
1824 } else if (target_city
1830 + unit_pop_value(punit))))) {
1835 && action_custom != ATT_OK) {
1836 switch (action_custom) {
1837 case ATT_NON_ATTACK:
1838 explnat->kind = ANEK_ACTOR_UNIT;
1839 break;
1840 case ATT_UNREACHABLE:
1842 break;
1843 case ATT_NONNATIVE_SRC:
1845 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1846 break;
1847 case ATT_NONNATIVE_DST:
1849 explnat->no_act_terrain = tile_terrain(target_tile);
1850 break;
1851 case ATT_NOT_WIPABLE:
1852 explnat->kind = ANEK_NOT_WIPABLE;
1853 break;
1854 default:
1856 explnat->kind = ANEK_UNKNOWN;
1857 break;
1858 }
1862 explnat->capacity_city = tile_city(unit_tile(punit));
1866 explnat->capacity_city = game_city_by_number(target_city->id);
1872 && target_tile != NULL
1884 && action_custom != MR_OK) {
1885 switch (action_custom) {
1888 break;
1889 case MR_TRIREME:
1890 explnat->kind = ANEK_TRIREME_MOVE;
1891 break;
1894 break;
1895 default:
1897 explnat->kind = ANEK_UNKNOWN;
1898 break;
1899 }
1904 explnat->no_tgt_utype = unit_type_get(target_unit);
1905 } else if ((game.scenario.prevent_new_cities
1908 || act_id == ACTION_ANY)) {
1909 /* Please add a check for any new action forbidding scenario setting
1910 * above this comment. */
1913 && action_custom == UU_NO_MONEY) {
1914 const struct unit_type *act_utype = unit_type_get(punit);
1915
1920 } else if (paction
1921 && (blocker = action_is_blocked_by(nmap, paction, punit,
1923 target_unit))) {
1925 explnat->blocker = blocker;
1926 } else {
1927 explnat->kind = ANEK_UNKNOWN;
1928 }
1929
1930 return explnat;
1931}
1932
1933/**********************************************************************/
1937 action_id act_id,
1938 const struct tile *target_tile,
1939 const struct city *target_city,
1940 const struct unit *target_unit)
1941{
1942 struct ane_expl *explnat = expl_act_not_enabl(punit, act_id,
1945 enum ane_kind out = explnat->kind;
1946
1947 free(explnat);
1948
1949 return out;
1950}
1951
1952/**********************************************************************/
1957 const struct tile *target_tile,
1958 const struct city *target_city,
1959 const struct unit *target_unit)
1960{
1961 struct player *pplayer = unit_owner(punit);
1965 const struct civ_map *nmap = &(wld.map);
1966
1967 switch (explnat->kind) {
1968 case ANEK_ACTOR_UNIT:
1969 /* This shouldn't happen unless the client is buggy given the current
1970 * users. */
1972 "Asked to explain why a non actor can't act.");
1973
1975 _("Unit cannot do anything."));
1976 break;
1979 _("Your %s found no suitable target."),
1981 break;
1982 case ANEK_BAD_TARGET:
1983 /* This shouldn't happen at the moment. Only specific action checks
1984 * will trigger bad target checks. This is a reply to a question about
1985 * any action. */
1987
1989 _("Your %s found no suitable target."),
1991 break;
1993 {
1994 const char *types[utype_count()];
1995 int i = 0;
1996
1999 FALSE)
2001 unit_type_iterate(utype) {
2004 types[i++] = utype_name_translation(utype);
2005 }
2007 }
2008
2009 if (0 < i) {
2010 struct astring astr = ASTRING_INIT;
2011
2012 notify_player(pplayer, unit_tile(punit),
2014 /* TRANS: terrain name
2015 * "Your Diplomat cannot act from Ocean. Only
2016 * Spy or Partisan ... */
2017 _("Your %s cannot act from %s. "
2018 "Only %s can act from a non livable tile."),
2020 terrain_name_translation(explnat->no_act_terrain),
2021 astr_build_or_list(&astr, types, i));
2022
2023 astr_free(&astr);
2024 } else {
2026 /* TRANS: terrain name */
2027 _("Unit cannot act from %s."),
2028 terrain_name_translation(explnat->no_act_terrain));
2029 }
2030 }
2031 break;
2034 /* TRANS: terrain name */
2035 _("Unit cannot act against %s."),
2036 terrain_name_translation(explnat->no_act_terrain));
2037 break;
2040 _("This unit is being transported, and"
2041 " so cannot act."));
2042 break;
2045 _("This unit cannot act when it isn't being "
2046 "transported."));
2047 break;
2050 _("This unit is transporting, and"
2051 " so cannot act."));
2052 break;
2055 _("This unit cannot act when it isn't transporting."));
2056 break;
2059 _("This unit has a home city, and so cannot act."));
2060 break;
2063 _("This unit cannot act unless it has a home city."));
2064 break;
2065 case ANEK_NO_WAR:
2067 _("You must declare war on %s first. Try using "
2068 "the Nations report"
2070 " (F3)"
2071#endif /* FREECIV_WEB */
2072 "."),
2073 player_name(explnat->no_war_with));
2074 break;
2075 case ANEK_PEACE:
2077 _("You must break peace with %s first. Try using "
2078 "the Nations report to declare war"
2080 " (F3)"
2081#endif /* FREECIV_WEB */
2082 "."),
2083 player_name(explnat->peace_with));
2084 break;
2085 case ANEK_DOMESTIC:
2087 _("This unit cannot act against domestic targets."));
2088 break;
2089 case ANEK_FOREIGN:
2091 _("This unit cannot act against foreign targets."));
2092 break;
2095 /* TRANS: Riflemen */
2096 _("%s cannot act against tiles with non allied units."),
2098 break;
2099 case ANEK_NATION_ACT:
2101 /* TRANS: Swedish ... Riflemen */
2102 _("%s %s cannot act."),
2103 nation_adjective_translation(explnat->no_act_nation),
2105 break;
2106 case ANEK_NATION_TGT:
2108 /* TRANS: ... Pirate ... */
2109 _("This unit cannot act against %s targets."),
2110 nation_adjective_translation(explnat->no_act_nation));
2111 break;
2112 case ANEK_LOW_MP:
2114 _("This unit has too few moves left to act."));
2115 break;
2118 _("This unit cannot act against city centers."));
2119 break;
2122 _("This unit cannot act against non city centers."));
2123 break;
2126 _("This unit cannot act against claimed tiles."));
2127 break;
2130 _("This unit cannot act against unclaimed tiles."));
2131 break;
2132 case ANEK_DISTANCE_NEAR:
2134 _("This unit is too near its target to act."));
2135 break;
2136 case ANEK_DISTANCE_FAR:
2138 _("This unit is too far away from its target to act."));
2139 break;
2142 _("Can't perform any action this scenario permits."));
2143 break;
2146 _("Can't perform any action this close to a city."));
2147 break;
2148 case ANEK_CITY_TOO_BIG:
2150 /* TRANS: Settler ... Berlin */
2151 _("%s can't do anything to %s. It is too big."),
2154 break;
2157 /* TRANS: London ... Settlers */
2158 _("%s needs an improvement to grow, so "
2159 "%s cannot do anything to it."),
2162 break;
2165 /* TRANS: Paris ... Warriors (think: airlift) */
2166 _("%s don't have enough capacity, so "
2167 "%s cannot do anything."),
2168 city_name_get(explnat->capacity_city),
2170 break;
2173 /* TRANS: Paratroopers ... */
2174 _("%s can't do anything to an unknown target tile."),
2176 break;
2178 {
2179 char tbuf[MAX_LEN_MSG];
2180
2181 /* TRANS: Used below. Separate so treasury content too can determine
2182 * if this is plural. */
2183 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2184 "Treasury contains %d gold.",
2185 pplayer->economic.gold),
2186 pplayer->economic.gold);
2187
2189 /* TRANS: "Spy can't do anything. 154 gold may help.
2190 * Treasury contains 100 gold." */
2191 PL_("%s can't do anything. %d gold may help. %s",
2192 "%s can't do anything. %d gold may help. %s",
2193 explnat->gold_needed),
2195 explnat->gold_needed, tbuf);
2196 }
2197 break;
2198 case ANEK_TRIREME_MOVE:
2200 _("%s cannot move that far from the coast line."),
2201 unit_link(punit));
2202 break;
2203 case ANEK_DISEMBARK_ACT:
2205 _("%s cannot disembark outside of a city or a native base "
2206 "for %s."),
2210 break;
2213 _("%s can't do anything since there is an unreachable "
2214 "unit."),
2216 break;
2217 case ANEK_NOT_WIPABLE:
2219 _("%s can't do anything since there is unit with a positive "
2220 "defense value."),
2222 break;
2225 _("%s can't do anything since you already have a %s."),
2227 utype_name_translation(explnat->no_tgt_utype));
2228 break;
2229 case ANEK_ACTION_BLOCKS:
2230 /* If an action blocked another action the blocking action must be
2231 * possible. */
2233 fc__fallthrough; /* Fall through to unknown cause. */
2234 case ANEK_UNKNOWN:
2236 _("No action possible."));
2237 break;
2238 }
2239
2240 free(explnat);
2241}
2242
2243/**********************************************************************/
2252 const int actor_unit_id,
2253 const int target_unit_id_client,
2254 const int target_tile_id,
2255 const int target_extra_id_client,
2256 const int request_kind)
2257{
2258 struct player *actor_player;
2259 struct unit *actor_unit;
2260 struct tile *target_tile;
2262 struct unit *target_unit;
2263 struct city *target_city;
2264 struct extra_type *target_extra;
2266 const struct player_tile *plrtile;
2268 const struct civ_map *nmap = &(wld.map);
2269
2270 /* No potentially legal action is known yet. If none is found the player
2271 * should get an explanation. */
2273
2274 /* A target should only be sent if it is possible to act against it */
2275 int target_city_id = IDENTITY_NUMBER_ZERO;
2276 int target_unit_id = IDENTITY_NUMBER_ZERO;
2277
2278 actor_player = pc->playing;
2280 target_tile = index_to_tile(nmap, target_tile_id);
2281
2282 /* Initialize the action probabilities. */
2283 action_iterate(act) {
2286
2287 /* Check if the request is valid. */
2289 || actor_unit->owner != actor_player) {
2292 target_tile_id, target_extra_id,
2293 request_kind,
2295 return;
2296 }
2297
2298 /* Select the targets. */
2299
2301 /* Find a new target unit. */
2303 } else {
2304 /* Prepare the client selected target unit. */
2306 }
2307
2308 /* Find the target city. */
2310
2311 /* The specified target unit must be located at the target tile. */
2315 _("Target not at target tile."));
2318 target_tile_id, target_extra_id,
2319 request_kind,
2321 return;
2322 }
2323
2325 /* See if a target extra can be found. */
2327 } else {
2328 /* Use the client selected target extra. */
2330 }
2331
2332 /* The player may have outdated information about the target tile.
2333 * Limiting the player knowledge look up to the target tile is OK since
2334 * all targets must be located at it. */
2336
2337 /* Distance between actor and target tile. */
2339 target_tile);
2340
2341 /* Find out what can be done to the targets. */
2342
2343 /* Set the probability for the actions. */
2345 if (action_id_get_actor_kind(act) != AAK_UNIT) {
2346 /* Not relevant. */
2347 continue;
2348 }
2349
2350 switch (action_id_get_target_kind(act)) {
2351 case ATK_CITY:
2352 if (plrtile && plrtile->site) {
2353 /* Only a known city may be targeted. */
2354 if (target_city) {
2355 /* Calculate the probabilities. */
2357 target_city);
2362 /* The target city is non existing. The player isn't aware of this
2363 * fact because they can't see the tile it was located on. The
2364 * actor unit it self doesn't contradict the requirements to
2365 * perform the action. The (no longer existing) target city was
2366 * known to be close enough. */
2368 } else {
2369 /* The actor unit is known to be unable to act or the target city
2370 * is known to be too far away. */
2372 }
2373 } else {
2374 /* No target to act against. */
2376 }
2377 break;
2378 case ATK_UNIT:
2379 if (target_unit) {
2380 /* Calculate the probabilities. */
2382 target_unit);
2383 } else {
2384 /* No target to act against. */
2386 }
2387 break;
2388 case ATK_STACK:
2389 if (target_tile) {
2390 /* Calculate the probabilities. */
2392 target_tile);
2393 } else {
2394 /* No target to act against. */
2396 }
2397 break;
2398 case ATK_TILE:
2399 if (target_tile) {
2400 /* Calculate the probabilities. */
2403 } else {
2404 /* No target to act against. */
2406 }
2407 break;
2408 case ATK_EXTRAS:
2409 if (target_tile) {
2410 /* Calculate the probabilities. */
2413 target_extra);
2414 } else {
2415 /* No target to act against. */
2417 }
2418 break;
2419 case ATK_SELF:
2420 if (actor_target_distance == 0) {
2421 /* Calculate the probabilities. */
2423 } else {
2424 /* Don't bother with self targeted actions unless the actor is
2425 * asking about what can be done to its own tile. */
2427 }
2428 break;
2429 case ATK_COUNT:
2432 break;
2433 }
2435
2436 /* Analyze the probabilities. Decide what targets to send and if an
2437 * explanation is needed. */
2440 /* An action can be done. No need to explain why no action can be
2441 * done. */
2443
2444 switch (action_id_get_target_kind(act)) {
2445 case ATK_CITY:
2446 /* The city should be sent as a target since it is possible to act
2447 * against it. */
2448
2449 /* All city targeted actions requires that the player is aware of
2450 * the target city. It is therefore in the player's map. */
2451 fc_assert_action(plrtile, continue);
2452 fc_assert_action(plrtile->site, continue);
2453
2454 target_city_id = plrtile->site->identity;
2455 break;
2456 case ATK_UNIT:
2457 /* The unit should be sent as a target since it is possible to act
2458 * against it. */
2460 target_unit_id = target_unit->id;
2461 break;
2462 case ATK_TILE:
2463 case ATK_EXTRAS:
2464 /* The target tile isn't selected here so it hasn't changed. */
2466
2468 /* The target extra may have been set here. */
2470 }
2471 break;
2472 case ATK_STACK:
2473 /* The target tile isn't selected here so it hasn't changed. */
2475 break;
2476 case ATK_SELF:
2477 /* The target unit is the actor unit. It is already sent. */
2479 break;
2480 case ATK_COUNT:
2482 "Invalid action target kind.");
2483 break;
2484 }
2485
2486 if (target_city_id != IDENTITY_NUMBER_ZERO
2487 && target_unit_id != IDENTITY_NUMBER_ZERO) {
2488 /* No need to find out more. */
2489 break;
2490 }
2491 }
2493
2494 /* Send possible actions and targets. */
2496 actor_unit_id, target_unit_id, target_city_id,
2497 target_tile_id, target_extra_id,
2498 request_kind,
2500
2501 if (request_kind == REQEST_PLAYER_INITIATED && !at_least_one_action) {
2502 /* The user should get an explanation why no action is possible. */
2505 }
2506}
2507
2508/**********************************************************************/
2515void illegal_action_msg(struct player *pplayer,
2516 const enum event_type event,
2517 struct unit *actor,
2519 const struct tile *target_tile,
2520 const struct city *target_city,
2521 const struct unit *target_unit)
2522{
2523 struct ane_expl *explnat;
2524 const struct civ_map *nmap = &(wld.map);
2525
2526 /* Explain why the action was illegal. */
2529 switch (explnat->kind) {
2530 case ANEK_ACTOR_UNIT:
2531 {
2532 struct astring astr = ASTRING_INIT;
2533
2536 TRUE)) {
2537 notify_player(pplayer, unit_tile(actor),
2539 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
2540 _("Only %s can do %s."),
2541 astr_str(&astr),
2543 astr_free(&astr);
2544 } else {
2545 notify_player(pplayer, unit_tile(actor),
2547 /* TRANS: Spy can't do Capture Units. */
2548 _("%s can't do %s."),
2551 }
2552 }
2553 break;
2556 /* TRANS: "Your Spy found ... suitable for
2557 * Bribe Enemy Unit." */
2558 _("Your %s found no target suitable for %s."),
2561 break;
2562 case ANEK_BAD_TARGET:
2564 /* TRANS: "Having your Spy do Bribe Enemy Unit to
2565 * this target ..." */
2566 _("Having your %s do %s to this target is redundant."),
2569 break;
2571 {
2572 const char *types[utype_count()];
2573 int i = 0;
2574
2577 FALSE)
2579 unit_type_iterate(utype) {
2582 types[i++] = utype_name_translation(utype);
2583 }
2585 }
2586
2587 if (0 < i) {
2588 struct astring astr = ASTRING_INIT;
2589
2590 notify_player(pplayer, unit_tile(actor),
2592 /* TRANS: action name.
2593 * "Your Spy can't do Steal Gold from Ocean.
2594 * Only Explorer or Partisan can do Steal Gold ..." */
2595 _("Your %s can't do %s from %s. "
2596 "Only %s can do %s from a non livable tile."),
2599 terrain_name_translation(explnat->no_act_terrain),
2600 astr_build_or_list(&astr, types, i),
2602
2603 astr_free(&astr);
2604 } else {
2605 notify_player(pplayer, unit_tile(actor),
2607 /* TRANS: action name.
2608 * "Your Spy can't do Steal Gold from Ocean." */
2609 _("Your %s can't do %s from %s."),
2612 terrain_name_translation(explnat->no_act_terrain));
2613 }
2614 }
2615 break;
2617 notify_player(pplayer, unit_tile(actor),
2619 /* TRANS: action name.
2620 * "Your Spy can't do Industrial Sabotage to Mountains." */
2621 _("Your %s can't do %s to %s."),
2624 terrain_name_translation(explnat->no_act_terrain));
2625 break;
2627 notify_player(pplayer, unit_tile(actor),
2629 /* TRANS: action name.
2630 * "Your Spy can't do Industrial Sabotage while ..." */
2631 _("Your %s can't do %s while being transported."),
2634 break;
2636 notify_player(pplayer, unit_tile(actor),
2638 /* TRANS: action name.
2639 * "Your Spy can't do Industrial Sabotage while ..." */
2640 _("Your %s can't do %s while not being transported."),
2643 break;
2645 notify_player(pplayer, unit_tile(actor),
2647 /* TRANS: action name.
2648 * "Your Spy can't do Industrial Sabotage while ..." */
2649 _("Your %s can't do %s while transporting."),
2652 break;
2654 notify_player(pplayer, unit_tile(actor),
2656 /* TRANS: action name.
2657 * "Your Spy can't do Industrial Sabotage while ..." */
2658 _("Your %s can't do %s while not transporting."),
2661 break;
2663 notify_player(pplayer, unit_tile(actor),
2665 /* TRANS: action name.
2666 * "Your Spy can't do Industrial Sabotage because ..." */
2667 _("Your %s can't do %s because it has a home city."),
2670 break;
2672 notify_player(pplayer, unit_tile(actor),
2674 /* TRANS: action name.
2675 * "Your Spy can't do Industrial Sabotage because ..." */
2676 _("Your %s can't do %s because it is homeless."),
2679 break;
2680 case ANEK_NO_WAR:
2681 notify_player(pplayer, unit_tile(actor),
2683 /* TRANS: action name.
2684 * "Your Spy can't do Industrial Sabotage while you
2685 * aren't at war with Prester John." */
2686 _("Your %s can't do %s while you"
2687 " aren't at war with %s."),
2690 player_name(explnat->no_war_with));
2691 break;
2692 case ANEK_PEACE:
2693 notify_player(pplayer, unit_tile(actor),
2695 /* TRANS: action name.
2696 * "Your Spy can't do Industrial Sabotage while you
2697 * are at peace with Prester John. Try using the
2698 * Nations report (F3)." */
2699 _("Your %s can't do %s while you "
2700 "are at peace with %s. Try using "
2701 "the Nations report to declare war"
2703 " (F3)"
2704#endif /* FREECIV_WEB */
2705 "."),
2708 player_name(explnat->peace_with));
2709 break;
2710 case ANEK_DOMESTIC:
2711 notify_player(pplayer, unit_tile(actor),
2713 /* TRANS: action name.
2714 * "Your Riflemen can't do Expel Unit to domestic
2715 * unit stacks." */
2716 _("Your %s can't do %s to domestic %s."),
2721 break;
2722 case ANEK_FOREIGN:
2723 notify_player(pplayer, unit_tile(actor),
2725 /* TRANS: action name.
2726 * "Your Leader can't do Use Court Physician to foreign
2727 * unit stacks." */
2728 _("Your %s can't do %s to foreign %s."),
2733 break;
2735 notify_player(pplayer, unit_tile(actor),
2737 /* TRANS: Paratroopers ... Drop Paratrooper */
2738 _("Your %s can't do %s to tiles with non allied units."),
2741 break;
2742 case ANEK_NATION_ACT:
2743 notify_player(pplayer, unit_tile(actor),
2745 /* TRANS: action name.
2746 * "Swedish Riflemen can't do Expel Unit." */
2747 _("%s %s can't do %s."),
2748 nation_adjective_translation(explnat->no_act_nation),
2751 break;
2752 case ANEK_NATION_TGT:
2753 notify_player(pplayer, unit_tile(actor),
2755 /* TRANS: action name.
2756 * "Riflemen... Expel Unit... Pirate Migrants." */
2757 _("Your %s can't do %s to %s %s."),
2760 nation_adjective_translation(explnat->no_act_nation),
2763 break;
2764 case ANEK_LOW_MP:
2765 notify_player(pplayer, unit_tile(actor),
2767 /* TRANS: action name.
2768 * "Your Spy has ... to do Bribe Enemy Unit." */
2769 _("Your %s has too few moves left to do %s."),
2772 break;
2774 notify_player(pplayer, unit_tile(actor),
2776 /* TRANS: action name.
2777 * "Your Spy can't do Bribe Enemy Unit to city centers." */
2778 _("Your %s can't do %s to city centers."),
2781 break;
2783 notify_player(pplayer, unit_tile(actor),
2785 /* TRANS: action name.
2786 * "Your Spy can only do Investigate City to
2787 * city centers." */
2788 _("Your %s can only do %s to city centers."),
2791 break;
2793 notify_player(pplayer, unit_tile(actor),
2795 /* TRANS: action name.
2796 * "Your Settlers can't do Build City to claimed tiles." */
2797 _("Your %s can't do %s to claimed tiles."),
2800 break;
2802 notify_player(pplayer, unit_tile(actor),
2804 /* TRANS: action name.
2805 * "Your Spy can't do Bribe Enemy Unit to
2806 * unclaimed tiles." */
2807 _("Your %s can't do %s to unclaimed tiles."),
2810 break;
2811 case ANEK_DISTANCE_NEAR:
2812 notify_player(pplayer, unit_tile(actor),
2814 /* TRANS: action name.
2815 * "Your Spy must be at least 2 tiles away to do
2816 * Incite a Revolt and Escape." */
2817 PL_("Your %s must be at least %d tile away to do %s.",
2818 "Your %s must be at least %d tiles away to do %s.",
2819 explnat->distance),
2821 explnat->distance,
2823 break;
2824 case ANEK_DISTANCE_FAR:
2825 notify_player(pplayer, unit_tile(actor),
2827 /* TRANS: action name.
2828 * "Your Diplomat can't be more than 1 tile away to do
2829 * Establish Embassy." */
2830 PL_("Your %s can't be more than %d tile away to do %s.",
2831 "Your %s can't be more than %d tiles away to do %s.",
2832 explnat->distance),
2834 explnat->distance,
2836 break;
2838 notify_player(pplayer, unit_tile(actor),
2840 /* TRANS: Can't do Build City in this scenario. */
2841 _("Can't do %s in this scenario."),
2843 break;
2845 notify_player(pplayer, unit_tile(actor),
2847 /* TRANS: Can't do Build City this close to a city. */
2848 _("Can't do %s this close to a city."),
2850 break;
2851 case ANEK_CITY_TOO_BIG:
2852 notify_player(pplayer, unit_tile(actor),
2854 /* TRANS: Settlers ... Join City ... London */
2855 _("%s can't do %s to %s. It is too big."),
2859 break;
2861 notify_player(pplayer, unit_tile(actor),
2863 /* TRANS: London ... Settlers ... Join City */
2864 _("%s needs an improvement to grow, so "
2865 "%s cannot do %s."),
2869 break;
2871 notify_player(pplayer, unit_tile(actor),
2873 /* TRANS: Paris ... Airlift to City ... Warriors */
2874 _("%s has no capacity to %s %s."),
2875 city_name_get(explnat->capacity_city),
2878 break;
2880 notify_player(pplayer, unit_tile(actor),
2882 /* TRANS: Paratroopers ... Drop Paratrooper */
2883 _("%s can't do %s to an unknown tile."),
2886 break;
2888 {
2889 char tbuf[MAX_LEN_MSG];
2890
2891 /* TRANS: Used below. Separate so treasury content too can determine
2892 * if this is plural. */
2893 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2894 "Treasury contains %d gold.",
2895 pplayer->economic.gold),
2896 pplayer->economic.gold);
2897
2898 notify_player(pplayer, unit_tile(actor),
2900 /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2901 * Treasury contains 100 gold." */
2902 PL_("%s can't do %s for %d gold. %s",
2903 "%s can't do %s for %d gold. %s",
2904 explnat->gold_needed),
2907 explnat->gold_needed, tbuf);
2908 }
2909 break;
2910 case ANEK_TRIREME_MOVE:
2912 /* TRANS: "Trireme cannot move ..." */
2913 _("%s cannot move that far from the coast line."),
2914 unit_link(actor));
2915 break;
2916 case ANEK_DISEMBARK_ACT:
2918 /* TRANS: "Riflemen cannot disembark ... native base
2919 * for Helicopter." */
2920 _("%s cannot disembark outside of a city or a native base "
2921 "for %s."),
2925 break;
2927 notify_player(pplayer, target_tile,
2929 /* TRANS: "Your Spy can't do Bribe Enemy Unit there ..." */
2930 _("Your %s can't do %s there since there's an "
2931 "unreachable unit."),
2934 break;
2935 case ANEK_NOT_WIPABLE:
2936 notify_player(pplayer, target_tile,
2938 /* TRANS: "Your Legion can't do Wipe Units there ..." */
2939 _("Your %s can't do %s there since there's an "
2940 "unit with positive defense value."),
2943 break;
2946 /* TRANS: "You already have a Leader." */
2947 _("You already have a %s."),
2948 utype_name_translation(explnat->no_tgt_utype));
2949 break;
2950 case ANEK_ACTION_BLOCKS:
2951 {
2953
2954 notify_player(pplayer, unit_tile(actor),
2956 /* TRANS: Freight ... Disband Unit Recover ... Help Wonder ... */
2957 _("Your %s can't do %s when %s is legal."),
2960 action_id_name_translation(explnat->blocker->id));
2962 }
2963 break;
2964 case ANEK_UNKNOWN:
2965 notify_player(pplayer, unit_tile(actor),
2967 /* TRANS: action name.
2968 * "Your Spy was unable to do Bribe Enemy Unit." */
2969 _("Your %s was unable to do %s."),
2972 break;
2973 }
2974
2975 free(explnat);
2976}
2977
2978/**********************************************************************/
2991static bool illegal_action_pay_price(struct player *pplayer,
2993 struct unit *act_unit,
2994 struct action *stopped_action,
2995 struct player *tgt_player,
2996 struct tile *tgt_tile,
2997 const enum action_requester requester)
2998{
2999 int punishment_mp;
3000 int punishment_hp;
3001
3002 const struct req_context actor_ctxt = {
3004 .unit = act_unit,
3005 .unittype = unit_type_get(act_unit),
3006 .action = stopped_action,
3007 };
3008 const struct req_context tgt_ctxt = {
3009 .player = tgt_player,
3010 };
3011
3012 /* Don't punish the player for something the game did. Don't tell the
3013 * player that the rules required the game to try to do something
3014 * illegal. */
3017 FALSE,
3018 "The player wasn't responsible for this.");
3019
3020 if (!information_revealed) {
3021 /* The player already had enough information to determine that this
3022 * action is illegal. Don't punish a client error or an accident. */
3023 return FALSE;
3024 }
3025
3026 /* The mistake may have a cost. */
3027
3028 /* HP cost */
3031
3032 /* Stay in range */
3034
3035 /* Punish the unit's hit points. */
3036 act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
3037
3038 if (punishment_hp != 0) {
3041 /* The consolation prize is some information about the potentially
3042 * distant target tile and maybe some contacts. */
3043 map_show_circle(pplayer, tgt_tile,
3044 unit_type_get(act_unit)->vision_radius_sq);
3046 }
3047
3048 if (act_unit->hp > 0) {
3049 /* The actor unit survived */
3050
3051 /* The player probably wants to be disturbed if their unit was punished
3052 * with the loss of hit points. */
3055 /* TRANS: Spy ... 5 ... Drop Paratrooper */
3056 _("Your %s lost %d hit points while attempting to"
3057 " do %s."),
3061 } else {
3062 /* The unit didn't survive */
3063
3064 /* The player probably wants to be disturbed if their unit was punished
3065 * with death. */
3068 /* TRANS: Spy ... Drop Paratrooper */
3069 _("Your %s was killed while attempting to do %s."),
3072
3074 act_unit = NULL;
3075
3076 return TRUE;
3077 }
3078 }
3079
3080 /* MP cost */
3083
3084 /* Stay in range */
3086
3087 /* Punish the unit's move fragments. */
3088 act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
3090
3091 if (punishment_mp != 0) {
3092 /* The player probably wants to be disturbed if their unit was punished
3093 * with the loss of movement points. */
3096 /* TRANS: Spy ... movement point text that may include
3097 * fractions. */
3098 _("Your %s lost %s MP for attempting an illegal action."),
3101 }
3102
3103 return punishment_mp != 0 || punishment_hp != 0;
3104}
3105
3106/**********************************************************************/
3111static void illegal_action(struct player *pplayer,
3112 struct unit *actor,
3114 struct player *tgt_player,
3115 struct tile *target_tile,
3116 const struct city *target_city,
3117 const struct unit *target_unit,
3118 int request_kind,
3119 const enum action_requester requester)
3120{
3122 bool was_punished;
3123 const struct civ_map *nmap = &(wld.map);
3124
3126
3127 /* Why didn't the game check before trying something illegal? Did a good
3128 * reason to not call is_action_enabled_unit_on...() appear? The game is
3129 * omniscient... */
3131
3132
3134 nmap,
3136 actor,
3138 target_tile, NULL));
3139
3140 if (request_kind == REQEST_PLAYER_INITIATED) {
3141 /* This is a foreground request. */
3146 }
3147
3151 requester);
3152
3153 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3154 /* FIXME: Temporary work around to prevent wrong information and/or
3155 * crashes. See hrm Bug #879880 */
3156 /* TODO: Get the explanation before the punishment and show it here.
3157 * See hrm Bug #879881 */
3158 notify_player(pplayer, unit_tile(actor),
3161 _("No explanation why you couldn't do %s. This is a bug."
3162 " Sorry about that. -- Sveinung"),
3164 }
3165}
3166
3167/**********************************************************************/
3171 const int actor_id,
3172 const int target_id,
3173 int request_kind)
3174{
3176 actor_id, target_id,
3177 0,
3179 request_kind);
3180}
3181
3182/**********************************************************************/
3190 const int actor_id,
3191 const int target_id,
3192 const action_id action_type,
3193 int request_kind)
3194{
3195 struct player *pplayer = pc->playing;
3196 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3197 struct action *paction = action_by_number(action_type);
3198 struct unit *punit = game_unit_by_number(target_id);
3199 struct city *pcity = game_city_by_number(target_id);
3200 struct tile *ptile = index_to_tile(&(wld.map), target_id);
3201 const struct civ_map *nmap = &(wld.map);
3202
3203 if (NULL == paction) {
3204 /* Non existing action */
3205 log_error("handle_unit_action_query() the action %d doesn't exist.",
3206 action_type);
3207
3208 unit_query_impossible(pc, actor_id, target_id, request_kind);
3209 return;
3210 }
3211
3212 if (NULL == pactor) {
3213 /* Probably died or bribed. */
3214 log_verbose("handle_unit_action_query() invalid actor %d",
3215 actor_id);
3216 unit_query_impossible(pc, actor_id, target_id, request_kind);
3217 return;
3218 }
3219
3220 switch (paction->result) {
3222 if (punit != nullptr
3223 && is_action_enabled_unit_on_unit(nmap, action_type,
3224 pactor, punit)) {
3226 actor_id, target_id,
3227 unit_bribe_cost(punit, pplayer,
3228 pactor),
3229 action_type, request_kind);
3230 } else {
3231 illegal_action(pplayer, pactor, action_type,
3232 punit ? unit_owner(punit) : nullptr,
3233 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3234 unit_query_impossible(pc, actor_id, target_id, request_kind);
3235 return;
3236 }
3237 break;
3239 if (ptile != nullptr
3240 && is_action_enabled_unit_on_stack(nmap, action_type,
3241 pactor, ptile)) {
3243 actor_id, target_id,
3244 stack_bribe_cost(ptile, pplayer,
3245 pactor),
3246 action_type, request_kind);
3247 } else {
3248 illegal_action(pplayer, pactor, action_type,
3249 punit ? unit_owner(punit) : nullptr,
3250 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3251 unit_query_impossible(pc, actor_id, target_id, request_kind);
3252 return;
3253 }
3254 break;
3256 if (pcity
3257 && is_action_enabled_unit_on_city(nmap, action_type,
3258 pactor, pcity)) {
3260 actor_id, target_id,
3261 city_incite_cost(pplayer, pcity),
3262 action_type, request_kind);
3263 } else {
3264 illegal_action(pplayer, pactor, action_type,
3266 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3267 unit_query_impossible(pc, actor_id, target_id, request_kind);
3268 return;
3269 }
3270 break;
3272 if (pcity
3273 && is_action_enabled_unit_on_city(nmap, action_type,
3274 pactor, pcity)) {
3275 const struct unit_type *tgt_utype;
3276 int upgr_cost;
3277
3279 /* Already checked via is_action_enabled_unit_on_city() */
3281 upgr_cost = unit_upgrade_price(pplayer,
3283
3285 actor_id, target_id,
3286 upgr_cost, action_type,
3287 request_kind);
3288 } else {
3289 illegal_action(pplayer, pactor, action_type,
3291 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3292 unit_query_impossible(pc, actor_id, target_id, request_kind);
3293 return;
3294 }
3295 break;
3298 if (pcity
3299 && is_action_enabled_unit_on_city(nmap, action_type,
3300 pactor, pcity)) {
3302 action_by_number(action_type), request_kind);
3303 } else {
3304 illegal_action(pplayer, pactor, action_type,
3306 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3307 unit_query_impossible(pc, actor_id, target_id, request_kind);
3308 return;
3309 }
3310 break;
3311 default:
3312 unit_query_impossible(pc, actor_id, target_id, request_kind);
3313 return;
3314 };
3315}
3316
3317/**********************************************************************/
3322void handle_unit_do_action(struct player *pplayer,
3323 const int actor_id,
3324 const int target_id,
3325 const int sub_tgt_id,
3326 const char *name,
3327 const action_id action_type)
3328{
3329 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3330 action_type, ACT_REQ_PLAYER);
3331}
3332
3333/**********************************************************************/
3338void unit_do_action(struct player *pplayer,
3339 const int actor_id,
3340 const int target_id,
3341 const int sub_tgt_id,
3342 const char *name,
3343 const action_id action_type)
3344{
3345 unit_perform_action(pplayer, actor_id, target_id,
3346 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3347}
3348
3349/**********************************************************************/
3358bool unit_perform_action(struct player *pplayer,
3359 const int actor_id,
3360 const int target_id,
3361 const int sub_tgt_id_incoming,
3362 const char *name,
3363 const action_id action_type,
3364 const enum action_requester requester)
3365{
3366 struct action *paction;
3367 int sub_tgt_id;
3368 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3369 struct tile *target_tile = NULL;
3370 struct extra_type *target_extra;
3371 struct impr_type *sub_tgt_impr;
3372 struct unit *punit = NULL;
3373 struct city *pcity = NULL;
3374 const struct civ_map *nmap = &(wld.map);
3375
3376 if (!action_id_exists(action_type)) {
3377 /* Non existing action */
3378 log_error("unit_perform_action() the action %d doesn't exist.",
3379 action_type);
3380
3381 return FALSE;
3382 }
3383
3384 paction = action_by_number(action_type);
3385
3386 if (NULL == actor_unit) {
3387 /* Probably died or bribed. */
3388 log_verbose("unit_perform_action() invalid actor %d",
3389 actor_id);
3390 return FALSE;
3391 }
3392
3394 case ATK_CITY:
3395 pcity = game_city_by_number(target_id);
3396 if (pcity == NULL) {
3397 log_verbose("unit_perform_action() invalid target city %d",
3398 target_id);
3399 return FALSE;
3400 }
3403 break;
3404 case ATK_UNIT:
3405 punit = game_unit_by_number(target_id);
3406 if (punit == NULL) {
3407 log_verbose("unit_perform_action() invalid target unit %d",
3408 target_id);
3409 return FALSE;
3410 }
3414 break;
3415 case ATK_STACK:
3416 case ATK_TILE:
3417 case ATK_EXTRAS:
3418 target_tile = index_to_tile(nmap, target_id);
3419 if (target_tile == NULL) {
3420 log_verbose("unit_perform_action() invalid target tile %d",
3421 target_id);
3422 return FALSE;
3423 }
3425 break;
3426 case ATK_SELF:
3430 break;
3431 case ATK_COUNT:
3433 break;
3434 }
3435
3436 /* Server side sub target assignment */
3437 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3440 } else {
3441 sub_tgt_id = sub_tgt_id_incoming;
3442 }
3443
3444 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3445 && sub_tgt_id != NO_TARGET) {
3446 target_extra = extra_by_number(sub_tgt_id);
3447 fc_assert(!(target_extra->ruledit_disabled));
3448 } else {
3450 }
3451
3452 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3453
3454 /* Sub targets should now be assigned */
3455 switch (paction->sub_target_kind) {
3456 case ASTK_NONE:
3457 /* No sub target. */
3458 break;
3459 case ASTK_BUILDING:
3460 if (sub_tgt_impr == NULL) {
3461 /* Missing sub target */
3462 return FALSE;
3463 }
3464 break;
3465 case ASTK_TECH:
3466 /* Not handled here yet */
3467 break;
3468 case ASTK_EXTRA:
3470 if (target_extra == NULL) {
3471 /* Missing sub target */
3472 return FALSE;
3473 }
3474 break;
3475 case ASTK_COUNT:
3476 break;
3477 }
3478
3482 && target_extra == NULL) {
3483 /* Missing required action extra target. */
3484 log_verbose("unit_perform_action() action %d requires action "
3485 "but extra id %d is invalid.",
3486 action_type, sub_tgt_id);
3487 return FALSE;
3488 }
3489
3490 if (paction->actor.is_unit.unitwaittime_controlled
3492 /* Action not possible due to unitwaittime setting. */
3493 return FALSE;
3494 }
3495
3496#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3497 if (pcity \
3498 && is_action_enabled_unit_on_city(nmap, action_type, \
3499 actor_unit, pcity)) { \
3500 bool success; \
3501 script_server_signal_emit("action_started_unit_city", \
3502 action_by_number(action), actor, target); \
3503 if (!actor || !unit_is_alive(actor_id)) { \
3504 /* Actor unit was destroyed during pre action Lua. */ \
3505 return FALSE; \
3506 } \
3507 if (!target || !city_exist(target_id)) { \
3508 /* Target city was destroyed during pre action Lua. */ \
3509 return FALSE; \
3510 } \
3511 success = action_performer; \
3512 if (success) { \
3513 action_success_actor_price(paction, actor_id, actor); \
3514 } \
3515 script_server_signal_emit("action_finished_unit_city", \
3516 action_by_number(action), success, \
3517 unit_is_alive(actor_id) ? actor : NULL, \
3518 city_exist(target_id) ? target : NULL); \
3519 return success; \
3520 } else { \
3521 illegal_action(pplayer, actor_unit, action_type, \
3522 pcity ? city_owner(pcity) : NULL, NULL, pcity, NULL, \
3523 TRUE, requester); \
3524 }
3525
3526#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3527 if (actor_unit \
3528 && is_action_enabled_unit_on_self(nmap, action_type, actor_unit)) { \
3529 bool success; \
3530 script_server_signal_emit("action_started_unit_self", \
3531 action_by_number(action), actor); \
3532 if (!actor || !unit_is_alive(actor_id)) { \
3533 /* Actor unit was destroyed during pre action Lua. */ \
3534 return FALSE; \
3535 } \
3536 success = action_performer; \
3537 if (success) { \
3538 action_success_actor_price(paction, actor_id, actor); \
3539 } \
3540 script_server_signal_emit("action_finished_unit_self", \
3541 action_by_number(action), success, \
3542 unit_is_alive(actor_id) ? actor : NULL); \
3543 return success; \
3544 } else { \
3545 illegal_action(pplayer, actor_unit, action_type, \
3546 unit_owner(actor_unit), NULL, NULL, actor_unit, \
3547 TRUE, requester); \
3548 }
3549
3550#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3551 if (punit \
3552 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3553 bool success; \
3554 script_server_signal_emit("action_started_unit_unit", \
3555 action_by_number(action), actor, target); \
3556 if (!actor || !unit_is_alive(actor_id)) { \
3557 /* Actor unit was destroyed during pre action Lua. */ \
3558 return FALSE; \
3559 } \
3560 if (!target || !unit_is_alive(target_id)) { \
3561 /* Target unit was destroyed during pre action Lua. */ \
3562 return FALSE; \
3563 } \
3564 success = action_performer; \
3565 if (success) { \
3566 action_success_actor_price(paction, actor_id, actor); \
3567 action_success_target_pay_mp(paction, target_id, punit); \
3568 } \
3569 script_server_signal_emit("action_finished_unit_unit", \
3570 action_by_number(action), success, \
3571 unit_is_alive(actor_id) ? actor : NULL, \
3572 unit_is_alive(target_id) ? target : NULL); \
3573 return success; \
3574 } else { \
3575 illegal_action(pplayer, actor_unit, action_type, \
3576 punit ? unit_owner(punit) : NULL, NULL, NULL, punit, \
3577 TRUE, requester); \
3578 }
3579
3580#define ACTION_PERFORM_UNIT_STACK(action, actor, target, action_performer)\
3581 if (target_tile \
3582 && is_action_enabled_unit_on_stack(nmap, action_type, \
3583 actor_unit, target_tile)) { \
3584 bool success; \
3585 script_server_signal_emit("action_started_unit_stack", \
3586 action_by_number(action), actor, target); \
3587 script_server_signal_emit("action_started_unit_units", \
3588 action_by_number(action), actor, target); \
3589 if (!actor || !unit_is_alive(actor_id)) { \
3590 /* Actor unit was destroyed during pre action Lua. */ \
3591 return FALSE; \
3592 } \
3593 success = action_performer; \
3594 if (success) { \
3595 action_success_actor_price(paction, actor_id, actor); \
3596 } \
3597 script_server_signal_emit("action_finished_unit_stack", \
3598 action_by_number(action), success, \
3599 unit_is_alive(actor_id) ? actor : NULL, \
3600 target); \
3601 script_server_signal_emit("action_finished_unit_units", \
3602 action_by_number(action), success, \
3603 unit_is_alive(actor_id) ? actor : NULL, \
3604 target); \
3605 return success; \
3606 } else { \
3607 illegal_action(pplayer, actor_unit, action_type, \
3608 NULL, target_tile, NULL, NULL, \
3609 TRUE, requester); \
3610 }
3611
3612#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3613 if (target_tile \
3614 && is_action_enabled_unit_on_tile(nmap, action_type, \
3615 actor_unit, target_tile, \
3616 target_extra)) { \
3617 bool success; \
3618 script_server_signal_emit("action_started_unit_tile", \
3619 action_by_number(action), actor, target); \
3620 if (!actor || !unit_is_alive(actor_id)) { \
3621 /* Actor unit was destroyed during pre action Lua. */ \
3622 return FALSE; \
3623 } \
3624 success = action_performer; \
3625 if (success) { \
3626 action_success_actor_price(paction, actor_id, actor); \
3627 } \
3628 script_server_signal_emit("action_finished_unit_tile", \
3629 action_by_number(action), success, \
3630 unit_is_alive(actor_id) ? actor : NULL, \
3631 target); \
3632 return success; \
3633 } else { \
3634 illegal_action(pplayer, actor_unit, action_type, \
3635 target_tile ? tile_owner(target_tile) : NULL, \
3636 target_tile, NULL, NULL, \
3637 TRUE, requester); \
3638 }
3639
3640#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3641 if (target_tile \
3642 && is_action_enabled_unit_on_extras(nmap, action_type, \
3643 actor_unit, target_tile, \
3644 target_extra)) { \
3645 bool success; \
3646 script_server_signal_emit("action_started_unit_extras", \
3647 action_by_number(action), actor, target); \
3648 if (!actor || !unit_is_alive(actor_id)) { \
3649 /* Actor unit was destroyed during pre action Lua. */ \
3650 return FALSE; \
3651 } \
3652 success = action_performer; \
3653 if (success) { \
3654 action_success_actor_price(paction, actor_id, actor); \
3655 } \
3656 script_server_signal_emit("action_finished_unit_extras", \
3657 action_by_number(action), success, \
3658 unit_is_alive(actor_id) ? actor : NULL, \
3659 target); \
3660 return success; \
3661 } else { \
3662 illegal_action(pplayer, actor_unit, action_type, \
3663 target_tile ? target_tile->extras_owner : NULL, \
3664 target_tile, NULL, NULL, \
3665 TRUE, requester); \
3666 }
3667
3668#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3669 target_city, target_unit, target_tile, \
3670 action_performer) \
3671 switch (action_get_target_kind(paction)) { \
3672 case ATK_CITY: \
3673 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3674 action_performer); \
3675 break; \
3676 case ATK_UNIT: \
3677 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3678 action_performer); \
3679 break; \
3680 case ATK_STACK: \
3681 ACTION_PERFORM_UNIT_STACK(paction->id, actor, target_tile, \
3682 action_performer); \
3683 break; \
3684 case ATK_TILE: \
3685 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3686 action_performer); \
3687 break; \
3688 case ATK_EXTRAS: \
3689 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3690 action_performer); \
3691 break; \
3692 case ATK_SELF: \
3693 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3694 break; \
3695 case ATK_COUNT: \
3696 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3697 break; \
3698 }
3699
3700 switch (paction->result) {
3704 paction));
3705 break;
3707 /* Difference is caused by data in the action structure. */
3710 punit, paction));
3711 break;
3712 case ACTRES_EXPEL_UNIT:
3714 do_expel_unit(pplayer, actor_unit, punit,
3715 paction));
3716 break;
3717 case ACTRES_HEAL_UNIT:
3719 do_heal_unit(pplayer, actor_unit, punit,
3720 paction));
3721 break;
3725 paction));
3726 break;
3730 paction));
3731 break;
3734 do_unit_board(pplayer, actor_unit, punit,
3735 paction));
3736 break;
3739 do_unit_load(pplayer, actor_unit, punit,
3740 paction));
3741 break;
3745 paction));
3746 break;
3748 /* All consequences are handled by the action system. */
3750 break;
3751 case ACTRES_FORTIFY:
3754 break;
3755 case ACTRES_CONVERT:
3758 break;
3759 case ACTRES_HOMELESS:
3762 break;
3763 case ACTRES_SPY_ESCAPE:
3765 spy_escape(pplayer, actor_unit,
3767 break;
3769 /* Difference is caused by data in the action structure. */
3772 B_LAST, paction));
3773 break;
3775 /* Difference is caused by data in the action structure. */
3778 sub_tgt_impr->item_number,
3779 paction));
3780 break;
3782 /* Difference is caused by data in the action structure. */
3785 -1, paction));
3786 break;
3787 case ACTRES_SPY_POISON:
3788 /* Difference is caused by data in the action structure. */
3790 spy_poison(pplayer, actor_unit, pcity,
3791 paction));
3792 break;
3796 paction));
3797 break;
3799 /* Difference is caused by data in the action structure. */
3801 diplomat_investigate(pplayer,
3803 paction));
3804 break;
3806 /* Difference is caused by data in the action structure. */
3809 paction));
3810 break;
3812 /* Difference is caused by data in the action structure. */
3815 paction));
3816 break;
3818 /* Difference is caused by data in the action structure. */
3821 A_UNSET, paction));
3822 break;
3824 /* Difference is caused by data in the action structure. */
3827 sub_tgt_id, paction));
3828 break;
3830 /* Difference is caused by data in the action structure. */
3833 paction));
3834 break;
3835 case ACTRES_STEAL_MAPS:
3836 /* Difference is caused by data in the action structure. */
3839 pcity, paction));
3840 break;
3841 case ACTRES_TRADE_ROUTE:
3844 pcity, paction));
3845 break;
3846 case ACTRES_MARKETPLACE:
3849 pcity, paction));
3850 break;
3851 case ACTRES_HELP_WONDER:
3853 unit_do_help_build(pplayer,
3855 paction));
3856 break;
3857 case ACTRES_SPY_NUKE:
3858 /* Difference is caused by data in the action structure. */
3860 spy_nuke_city(pplayer, actor_unit, pcity,
3861 paction));
3862 break;
3863 case ACTRES_JOIN_CITY:
3865 city_add_unit(pplayer, actor_unit, pcity,
3866 paction));
3867 break;
3870 unit_do_destroy_city(pplayer,
3872 paction));
3873 break;
3877 paction));
3878 break;
3879 case ACTRES_HOME_CITY:
3882 paction));
3883 break;
3886 do_unit_upgrade(pplayer, actor_unit,
3888 break;
3890 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3893 pcity, paction));
3894 break;
3898 actor_unit,
3899 pcity,
3900 sub_tgt_impr->item_number,
3901 paction));
3902 break;
3906 actor_unit,
3907 pcity,
3908 paction));
3909 break;
3914 break;
3915 case ACTRES_AIRLIFT:
3918 break;
3923 break;
3924 case ACTRES_BOMBARD:
3925 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3928 paction));
3929 break;
3930 case ACTRES_ATTACK:
3932 /* Difference is caused by data in the action structure. */
3935 break;
3936 case ACTRES_WIPE_UNITS:
3939 break;
3944 break;
3945 case ACTRES_NUKE_UNITS:
3948 paction));
3949 break;
3950 case ACTRES_SPY_ATTACK:
3953 paction));
3954 break;
3955 case ACTRES_FOUND_CITY:
3957 city_build(pplayer, actor_unit,
3959 break;
3960 case ACTRES_NUKE:
3964 paction));
3965 break;
3966 case ACTRES_PARADROP:
3970 break;
3972 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3974 do_disembark(pplayer, actor_unit,
3976 break;
3977 case ACTRES_HUT_ENTER:
3979 do_unit_hut(pplayer, actor_unit,
3981 break;
3984 do_unit_hut(pplayer, actor_unit,
3986 break;
3987 case ACTRES_UNIT_MOVE:
3991 break;
3992 case ACTRES_TELEPORT:
3996 NULL, FALSE,
3999 FALSE, FALSE));
4000 break;
4004 break;
4005 case ACTRES_CULTIVATE:
4008 break;
4009 case ACTRES_PLANT:
4012 break;
4013 case ACTRES_PILLAGE:
4016 paction,
4017 &target_extra));
4018 break;
4019 case ACTRES_CLEAN:
4022 paction,
4023 &target_extra));
4024 break;
4025 case ACTRES_ROAD:
4028 paction,
4029 &target_extra));
4030 break;
4031 case ACTRES_BASE:
4034 paction,
4035 &target_extra));
4036 break;
4037 case ACTRES_MINE:
4040 paction,
4041 &target_extra));
4042 break;
4043 case ACTRES_IRRIGATE:
4046 paction,
4047 &target_extra));
4048 break;
4049 case ACTRES_NONE:
4050 /* 100% ruleset defined. */
4052 TRUE);
4053 break;
4056 return FALSE;
4057
4059 }
4060
4061 /* Something must have gone wrong. */
4062 return FALSE;
4063}
4064
4065/**********************************************************************/
4073 bool rehome)
4074{
4076 struct player *old_owner = unit_owner(punit);
4077 struct player *new_owner = (new_pcity == NULL ? old_owner
4079 const struct civ_map *nmap = &(wld.map);
4080
4081 /* Calling this function when new_pcity is same as old_pcity should
4082 * be safe with current implementation, but it is not meant to
4083 * be used that way. */
4085
4086 /* If 'rehome' is not set, this function should only be used to change
4087 * which player owns the unit */
4089
4090 if (old_owner != new_owner) {
4091 struct city *pcity = tile_city(punit->tile);
4092
4095
4098
4099 if (pcity != NULL
4101 /* Special case when city is being transferred. At this point city
4102 * itself has changed owner, so it's enemy city now that old owner
4103 * cannot see inside. All the normal methods of removing transferred
4104 * unit from previous owner's client think that there's no need to
4105 * remove unit as client shouldn't have it in first place. */
4107 }
4108
4109 /* Remove AI control of the old owner. */
4110 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4111
4115
4116 /* Activate AI control of the new owner. */
4117 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4118
4121 }
4122
4123 if (rehome) {
4124 /* Remove from old city first and add to new city only after that. */
4125 if (old_pcity) {
4126 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4127 unit_list_remove(old_pcity->units_supported, punit);
4128 /* update unit upkeep */
4130 }
4131
4132 if (new_pcity != NULL) {
4133 unit_list_prepend(new_pcity->units_supported, punit);
4134
4135 /* update unit upkeep */
4137
4138 punit->homecity = new_pcity->id;
4139 } else {
4141 }
4142 }
4143
4145 /* This is mainly for cases where unit owner changes to one not knowing
4146 * Railroad tech when unit is already building railroad.
4147 * Does also send_unit_info() */
4149 } else {
4150 /* Send info to players and observers. */
4152 }
4153
4154 if (new_pcity != NULL) {
4158 }
4159
4160 if (old_pcity) {
4164 }
4165
4167
4168 if (old_owner != new_owner) {
4169 script_server_signal_emit("unit_transferred", punit, old_owner);
4170 }
4171}
4172
4173/**********************************************************************/
4179 struct city *pcity,
4180 const struct action *paction)
4181{
4182 const char *giver = NULL;
4183
4184 if (unit_owner(punit) != city_owner(pcity)) {
4185 /* This is a gift. Tell the receiver. */
4186 giver = player_name(unit_owner(punit));
4187 }
4188
4190
4191 if (punit->homecity == pcity->id && giver) {
4192 /* Notify the city owner about the gift they received. */
4194 ftc_server,
4195 /* TRANS: other player ... unit type ... city name. */
4196 _("%s transferred control over a %s to you in %s."),
4197 giver,
4199 city_link(pcity));
4200 }
4201
4202 return punit->homecity == pcity->id;
4203}
4204
4205/**********************************************************************/
4212static bool city_add_unit(struct player *pplayer, struct unit *punit,
4213 struct city *pcity, const struct action *paction)
4214{
4216 const struct unit_type *act_utype;
4217
4218 /* Sanity check: The actor is still alive. */
4220
4222
4223 /* Sanity check: The target city still exists. */
4225
4227
4229 /* Make the new people something, otherwise city fails the checks */
4230 pcity->specialists[DEFAULT_SPECIALIST] += amount;
4232 /* Refresh the city data. */
4234
4235 /* Notify the unit owner that the unit successfully joined the city. */
4237 _("%s added to aid %s in growing."),
4239 city_link(pcity));
4240 if (pplayer != city_owner(pcity)) {
4241 /* Notify the city owner when a foreign unit joins a city. */
4243 ftc_server,
4244 /* TRANS: another player had their unit join your city. */
4245 _("%s adds %s to your city %s."),
4248 city_link(pcity));
4249 }
4250
4253 city_link(pcity));
4254
4256
4258
4259 script_server_signal_emit("city_size_change", pcity,
4260 (lua_Integer)amount, "unit_added");
4261
4262 return TRUE;
4263}
4264
4265/**********************************************************************/
4274static bool city_build(struct player *pplayer, struct unit *punit,
4275 struct tile *ptile, const char *name,
4276 const struct action *paction)
4277{
4278 char message[1024];
4279 int size;
4280 struct player *nationality;
4281 struct player *towner;
4282 const struct unit_type *act_utype;
4283
4284 /* Sanity check: The actor still exists. */
4285 fc_assert_ret_val(pplayer, FALSE);
4287
4288 towner = tile_owner(ptile);
4289
4290 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4291 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4292 "%s", message);
4293 return FALSE;
4294 }
4295
4297
4298 nationality = unit_nationality(punit);
4299
4300 create_city(pplayer, ptile, name, nationality);
4302 if (size > 1) {
4303 struct city *pcity = tile_city(ptile);
4304
4306
4308 }
4309
4310 /* May cause an incident even if the target tile is unclaimed. A ruleset
4311 * could give everyone a casus belli against the city founder. A rule
4312 * like that would make sense in a story where deep ecology is on the
4313 * table. (See also Voluntary Human Extinction Movement) */
4315 ptile, tile_link(ptile));
4316
4317 return TRUE;
4318}
4319
4320/**********************************************************************/
4323static void handle_unit_change_activity_real(struct player *pplayer,
4324 int unit_id,
4325 enum unit_activity activity,
4326 struct extra_type *activity_target,
4328{
4329 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4330
4331 if (NULL == punit) {
4332 /* Probably died or bribed. */
4333 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4334 return;
4335 }
4336
4337 if (punit->activity == activity
4339 return;
4340 }
4341
4342 /* Remove city spot reservations for AI settlers on city founding
4343 * mission, before goto_tile reset. */
4344 if (punit->server.adv->task != AUT_NONE) {
4346 }
4347
4348 punit->goto_tile = NULL;
4349
4350 if (activity == ACTIVITY_GOTO) {
4351 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4352 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4353 * it is going somewhere while it is standing still. The appearance of
4354 * the unit doing something can trick the user to not make use of it.
4355 *
4356 * Handled here because adv_follow_path() uses unit_activity_handling()
4357 * to set a unit's activity to ACTIVITY_GOTO. */
4358 return;
4359 }
4360
4361 if (activity == ACTIVITY_EXPLORE) {
4362 /* Please use unit_server_side_agent_set(). */
4363 return;
4364 }
4365
4366 /* The activity can now be set. */
4369}
4370
4371/**********************************************************************/
4374void handle_unit_change_activity(struct player *pplayer, int unit_id,
4376 int target_id)
4377{
4378 struct extra_type *activity_target;
4379
4381 activity_target = NULL;
4382 } else {
4383 activity_target = extra_by_number(target_id);
4384 }
4385
4386#ifdef FREECIV_WEB
4387 /* Web-client is not capable of selecting target, so we do it server side */
4388 if (activity_target == NULL) {
4389 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4390 bool required = TRUE;
4391
4392 if (punit == NULL) {
4393 return;
4394 }
4395
4396 if (activity == ACTIVITY_IRRIGATE) {
4397 struct tile *ptile = unit_tile(punit);
4398
4399 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4400 pplayer, punit);
4401 } else if (activity == ACTIVITY_MINE) {
4402 struct tile *ptile = unit_tile(punit);
4403
4404 activity_target = next_extra_for_tile(ptile, EC_MINE,
4405 pplayer, punit);
4406 } else if (activity == ACTIVITY_BASE) {
4407 struct tile *ptile = unit_tile(punit);
4408 struct base_type *pbase =
4410
4411 if (pbase != NULL) {
4412 activity_target = base_extra_get(pbase);
4413 }
4414
4415 } else if (activity == ACTIVITY_CLEAN) {
4416 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4417 pplayer, punit);
4418 } else {
4419 required = FALSE;
4420 }
4421
4422 if (activity_target == NULL && required) {
4423 /* Nothing more we can do */
4424 return;
4425 }
4426 }
4427#endif /* FREECIV_WEB */
4428
4429 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target,
4430 activity_default_action(activity));
4431}
4432
4433/**********************************************************************/
4436static void see_combat(struct unit *pattacker, struct unit *pdefender)
4437{
4440
4441 /*
4442 * Special case for attacking/defending:
4443 *
4444 * Normally the player doesn't get the information about the units inside a
4445 * city. However for attacking/defending the player has to know the unit of
4446 * the other side. After the combat a remove_unit packet will be sent
4447 * to the client to tidy up.
4448 *
4449 * Note these packets must be sent out before unit_versus_unit() is called,
4450 * so that the original unit stats (HP) will be sent.
4451 */
4458
4460 struct player *pplayer = pconn->playing;
4461
4462 if (pplayer != NULL) {
4463
4464 /* NOTE: this means the player can see combat between submarines even
4465 * if neither sub is visible. See similar comment in send_combat. */
4468 V_MAIN)) {
4469
4470 /* Units are sent even if they were visible already. They may
4471 * have changed orientation for combat. */
4472 if (pplayer == unit_owner(pattacker)) {
4474 } else {
4476 }
4477
4478 if (pplayer == unit_owner(pdefender)) {
4480 } else {
4482 }
4483 }
4484 } else if (pconn->observer) {
4485 /* Global observer sees everything... */
4488 }
4490}
4491
4492/**********************************************************************/
4495static void send_combat(struct unit *pattacker, struct unit *pdefender,
4496 int att_veteran, int def_veteran, int bombard)
4497{
4499
4501 combat.defender_unit_id = pdefender->id;
4502 combat.attacker_hp = pattacker->hp;
4503 combat.defender_hp = pdefender->hp;
4504 combat.make_att_veteran = att_veteran;
4505 combat.make_def_veteran = def_veteran;
4506
4507 players_iterate(other_player) {
4508 /* NOTE: this means the player can see combat between submarines even
4509 * if neither sub is visible. See similar comment in see_combat. */
4510 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4511 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4512 V_MAIN)) {
4513 lsend_packet_unit_combat_info(other_player->connections, &combat);
4514
4515 /*
4516 * Remove the client knowledge of the units. This corresponds to the
4517 * send_packet_unit_short_info calls up above.
4518 */
4519 if (!can_player_see_unit(other_player, pattacker)) {
4520 unit_goes_out_of_sight(other_player, pattacker);
4521 }
4522 if (!can_player_see_unit(other_player, pdefender)) {
4523 unit_goes_out_of_sight(other_player, pdefender);
4524 }
4525 }
4527
4528 /* Send combat info to non-player observers as well. They already know
4529 * about the unit so no unit_info is needed. */
4531 if (NULL == pconn->playing && pconn->observer) {
4533 }
4535}
4536
4537/**********************************************************************/
4541 struct city *pcity,
4542 const struct action *paction,
4543 const char *reason)
4544{
4545 struct player *pplayer = unit_owner(punit);
4546
4547 if (pcity
4549 &(const struct req_context) {
4550 .player = city_owner(pcity),
4551 .city = pcity,
4552 .tile = city_tile(pcity),
4553 .unit = punit,
4554 .unittype = unit_type_get(punit),
4555 .action = paction,
4556 },
4560 struct player *cplayer = city_owner(pcity);
4561 struct tile *ctile = city_tile(pcity);
4562 const char *clink = city_link(pcity);
4563
4564 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4567 } else {
4569 /* TRANS: Battleship ... Los Angeles ... Bombard */
4570 _("Your %s destroyed %s by doing %s."),
4575 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4576 _("%s destroyed %s by doing %s."),
4577 player_name(pplayer), clink,
4579 }
4580 }
4581}
4582
4583/**********************************************************************/
4590static bool unit_bombard(struct unit *punit, struct tile *ptile,
4591 const struct action *paction)
4592{
4593 struct player *pplayer = unit_owner(punit);
4594 struct city *pcity = tile_city(ptile);
4595 const struct unit_type *act_utype;
4596 const struct civ_map *nmap = &(wld.map);
4597
4598 /* Sanity check: The actor still exists. */
4599 fc_assert_ret_val(pplayer, FALSE);
4601
4603
4604 log_debug("Start bombard: %s %s to %d, %d.",
4606 unit_rule_name(punit), TILE_XY(ptile));
4607
4609 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4610 bool adj;
4611 enum direction8 facing;
4612 int att_hp, def_hp;
4613
4615 punit->tile, pdefender->tile, &facing);
4616
4617 if (adj) {
4618 punit->facing = facing;
4619
4620 /* Unlike with normal attack, we don't change orientation of
4621 * defenders when bombarding */
4622 }
4623
4624 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4625
4626 if (def_hp <= 0) {
4627 notify_player(pplayer, ptile,
4629 /* TRANS: Your Bomber killed the English Rifleman by
4630 * doing Bombard. */
4631 _("Your %s killed the %s %s by doing %s."),
4638 /* TRANS: Your Rifleman was killed by the French
4639 * Bomber doing Bombard. */
4640 _("Your %s was killed by the %s %s doing %s."),
4645 } else {
4646 notify_player(pplayer, ptile,
4648 /* TRANS: Your Bomber bombards the English Rifleman. */
4649 _("Your %s bombards the %s %s."),
4655 /* TRANS: Your Rifleman is bombarded by the French
4656 * Bomber. */
4657 _("Your %s is bombarded by the %s %s."),
4661 }
4662
4664
4665 punit->hp = att_hp;
4666 pdefender->hp = def_hp;
4667
4668 send_combat(punit, pdefender, 0, 0, 1);
4669
4670 /* May cause an incident */
4676
4677 if (def_hp <= 0) {
4679 } else {
4681 }
4682 }
4683
4685
4688
4690
4692
4693 return TRUE;
4694}
4695
4696/**********************************************************************/
4707static bool unit_nuke(struct player *pplayer, struct unit *punit,
4708 struct tile *def_tile, const struct action *paction)
4709{
4710 struct city *pcity;
4711 const struct unit_type *act_utype;
4712 struct civ_map *nmap = &(wld.map);
4713
4714 /* Sanity check: The actor still exists. */
4715 fc_assert_ret_val(pplayer, FALSE);
4717
4719
4720 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4723 TILE_XY(def_tile));
4724
4725 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4726 /* FIXME: Remove the hard coded reference to SDI defense. */
4728 _("Your %s was shot down by "
4729 "SDI defenses, what a waste."), unit_tile_link(punit));
4731 _("The nuclear attack on %s was avoided by"
4732 " your SDI defense."), city_link(pcity));
4733
4734 /* Trying to nuke something this close can be... unpopular. */
4738
4739 /* Remove the destroyed nuke. */
4741
4742 return FALSE;
4743 }
4744
4746
4747
4748 /* The nuke must be wiped here so it won't be seen as a victim of its own
4749 * detonation. */
4750 if (paction->actor_consuming_always) {
4752 }
4753
4755
4756 /* May cause an incident even if the target tile is unclaimed. A ruleset
4757 * could give everyone a casus belli against the tile nuker. A rule
4758 * like that would make sense in a story where detonating any nuke at all
4759 * could be forbidden. */
4762 def_tile,
4764
4765 return TRUE;
4766}
4767
4768/**********************************************************************/
4778 struct unit *act_unit,
4779 struct city *tgt_city,
4780 const struct action *paction)
4781{
4782 int tgt_city_id;
4783 struct player *tgt_player;
4784 bool capital;
4785 bool try_civil_war = FALSE;
4786 const struct unit_type *act_utype;
4787
4788 /* Sanity check: The actor still exists. */
4791
4793
4794 /* Sanity check: The target city still exists. */
4796
4798
4799 /* How can a city be ownerless? */
4801
4802 /* Save city ID. */
4803 tgt_city_id = tgt_city->id;
4804
4806
4807 if (capital
4808 && (tgt_player->spaceship.state == SSHIP_STARTED
4809 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4810 /* Destroying this city destroys the victim's space ship. */
4812 }
4813
4814 if (capital
4818 /* Destroying this city can trigger a civil war. */
4820 }
4821
4822 /* Let the actor know. */
4825 _("You destroy %s completely."),
4827
4828 if (tgt_player != act_player) {
4829 /* This was done to a foreign city. Inform the victim player. */
4832 _("%s has been destroyed by %s."),
4835 }
4836
4837 /* May cause an incident */
4841
4842 /* Run post city destruction Lua script. */
4844 act_player);
4845
4846 /* Can't be sure of city existence after running script. */
4847 if (city_exist(tgt_city_id)) {
4849 }
4850
4851 if (try_civil_war) {
4852 /* Try to start the civil war. */
4854 }
4855
4856 /* The city is no more. */
4857 return TRUE;
4858}
4859
4860/**********************************************************************/
4865static const char *unit_veteran_level_string(const struct unit *punit)
4866{
4867 static char buf[MAX_LEN_LINK];
4868 const struct veteran_level *vlevel;
4869
4870 if (!punit) {
4871 buf[0] = '\0'; /* If no unit, return empty string */
4872 return buf;
4873 }
4874
4876 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4877
4878 return buf;
4879}
4880
4881/**********************************************************************/
4886static const char *unit_achieved_rank_string(const struct unit *punit)
4887{
4888 static char buf[MAX_LEN_LINK];
4889
4890 fc_snprintf(buf, sizeof(buf),
4891 /* TRANS: " and achieved the rank of <veteran level>";
4892 * preserve leading space */
4893 _(" and achieved the rank of %s"),
4895 return buf;
4896}
4897
4898/**********************************************************************/
4903static const char *unit_tired_attack_string(const struct unit *punit)
4904{
4905 static char buf[MAX_LEN_LINK];
4906
4908 fc_snprintf(buf, sizeof(buf),
4909 /* TRANS: tired; note trailing space */
4910 _("tired "));
4911 } else {
4912 buf[0] = '\0';
4913 }
4914
4915 return buf;
4916}
4917
4918/**********************************************************************/
4925static const char *unit_firepower_if_not_one(int firepower)
4926{
4927 static char buf[MAX_LEN_LINK];
4928
4929 if (firepower == 1) {
4930 buf[0] = '\0';
4931 } else {
4932 fc_snprintf(buf, sizeof(buf),
4933 /* TRANS: FP = Firepower of a unit; note trailing space */
4934 _("FP:%d "),
4935 firepower);
4936 }
4937
4938 return buf;
4939}
4940
4941/**********************************************************************/
4950static bool do_attack(struct unit *punit, struct tile *def_tile,
4951 const struct action *paction)
4952{
4957 struct unit *ploser, *pwinner;
4960 int winner_id;
4961 struct player *pplayer = unit_owner(punit);
4962 bool adj;
4963 enum direction8 facing;
4964 int att_hp, def_hp, att_fp, def_fp;
4966 int def_power, att_power;
4967 int att_vet, def_vet;
4968 struct unit *pdefender;
4969 const struct unit_type *act_utype = unit_type_get(punit);
4970 struct civ_map *nmap = &(wld.map);
4971 bool powerless;
4972
4974 /* Can't fight air... */
4975 return FALSE;
4976 }
4977
4979 def_hp_start = pdefender->hp;
4983
4984 log_debug("Start attack: %s %s against %s %s.",
4989
4990 /* Sanity checks */
4995 FALSE,
4996 "Trying to attack a unit with which you have peace "
4997 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
5001 FALSE,
5002 "Trying to attack a unit with which you have "
5003 "alliance at (%d, %d).", TILE_XY(def_tile));
5004
5007
5009 punit->tile, pdefender->tile, &facing);
5010
5011 fc_assert(adj);
5012 if (adj) {
5013 punit->facing = facing;
5014 pdefender->facing = opposite_direction(facing);
5015 }
5016
5018 old_defender_vet = pdefender->veteran;
5019
5020 /* N.B.: unit_veteran_level_string always returns the same pointer. */
5023
5024 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
5027
5028 /* Record tired attack string before attack */
5030
5031 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
5032 &att_vet, &def_vet, paction);
5033
5034 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
5035 && unit_transported(punit)) {
5036 /* Dying attacker must be first unloaded so it doesn't die inside transport */
5038 }
5039
5041
5042 punit->hp = att_hp;
5043 pdefender->hp = def_hp;
5044
5046
5047 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
5048 * the movement attack modifier is correct! --dwp
5049 *
5050 * For greater Civ2 compatibility (and game balance issues), we recompute
5051 * the new total MP based on the HP the unit has left after being damaged,
5052 * and subtract the MPs that had been used before the combat (plus the
5053 * points used in the attack itself, for the attacker). -GJW, Glip
5054 */
5057
5058 if (punit->moves_left < 0) {
5059 punit->moves_left = 0;
5060 }
5061 if (pdefender->moves_left < 0) {
5062 pdefender->moves_left = 0;
5063 }
5066
5067 /* This may cause a diplomatic incident. */
5071
5072 if (punit->hp > 0 && pdefender->hp > 0) {
5073 /* Neither died */
5075 pdefender->veteran - old_defender_vet, 0);
5076 return TRUE;
5077 }
5078 pwinner = (punit->hp > 0) ? punit : pdefender;
5079 winner_id = pwinner->id;
5080 ploser = (pdefender->hp > 0) ? punit : pdefender;
5081
5082 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5083 old_defender_vet)) ? 0 : 1;
5084
5086 pdefender->veteran - old_defender_vet, 0);
5087
5088 /* N.B.: unit_link always returns the same pointer. */
5093
5094 if (punit == ploser) {
5095 /* The attacker lost */
5096 log_debug("Attacker lost: %s %s against %s %s.",
5101
5105 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5106 * 9 HP remaining] survived the pathetic ...attack from
5107 * green Warriors [id:90 ...A:1.0 HP:10]. */
5108 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5109 " survived the pathetic %sattack from %s %s "
5110 "[id:%d %sA:%.1f HP:%d]."),
5113 pdefender->id,
5115 (float)def_power/POWER_FACTOR,
5116 def_hp_start - pdefender->hp,
5117 pdefender->hp,
5120 loser_link,
5121 punit->id,
5123 (float)att_power/POWER_FACTOR,
5124 att_hp_start);
5125 } else {
5128 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5129 * 9 HP remaining] survived the pathetic ...attack from the
5130 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5131 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5132 " survived the pathetic %sattack from the %s %s %s "
5133 "[id:%d %sA:%.1f HP:%d]."),
5136 pdefender->id,
5138 (float)def_power/POWER_FACTOR,
5139 def_hp_start - pdefender->hp,
5140 pdefender->hp,
5144 loser_link,
5145 punit->id,
5147 (float)att_power/POWER_FACTOR,
5148 att_hp_start);
5149 }
5150
5151 if (vet) {
5153 }
5154
5158 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5159 * failed against green Destroyer [id:200 lost
5160 * 27 HP, 3 HP remaining%s]!";
5161 * last %s is either "and ..." or empty string */
5162 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5163 "against %s %s [id:%d lost %d HP, %d HP "
5164 "remaining%s]!"),
5166 loser_link,
5167 punit->id,
5169 (float)att_power/POWER_FACTOR,
5173 pdefender->id,
5174 def_hp_start - pdefender->hp,
5175 pdefender->hp,
5177 } else {
5180 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5181 * failed against the Polish green Destroyer [id:200 lost
5182 * 27 HP, 3 HP remaining%s]!";
5183 * last %s is either "and ..." or empty string */
5184 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5185 "against the %s %s %s [id:%d lost %d HP, %d HP "
5186 "remaining%s]!"),
5188 loser_link,
5189 punit->id,
5191 (float)att_power/POWER_FACTOR,
5196 pdefender->id,
5197 def_hp_start - pdefender->hp,
5198 pdefender->hp,
5200 }
5201
5203 } else {
5204 /* The defender lost, the attacker punit lives! */
5205 struct city *pcity;
5206
5207 log_debug("Defender lost: %s %s against %s %s.",
5212
5216 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5217 * lost to an attack by green Legion
5218 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5219 * last %s is either "and ..." or empty string */
5220 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5221 "%s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5222 "remaining%s]."),
5224 loser_link,
5225 pdefender->id,
5227 (float)def_power/POWER_FACTOR,
5231 punit->id,
5233 (float)att_power/POWER_FACTOR,
5234 att_hp_start - pwinner->hp,
5235 pwinner->hp,
5237 } else {
5240 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5241 * lost to an attack by the Greek green Legion
5242 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5243 * last %s is either "and ..." or empty string */
5244 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5245 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5246 "remaining%s]."),
5248 loser_link,
5249 pdefender->id,
5251 (float)def_power/POWER_FACTOR,
5256 punit->id,
5258 (float)att_power/POWER_FACTOR,
5259 att_hp_start - pwinner->hp,
5260 pwinner->hp,
5262 }
5263
5267 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5268 * lost 1 HP, has 9 HP remaining] succeeded against
5269 * green Warriors [id:100 HP:10]." */
5270 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5271 "has %d remaining] succeeded against %s %s "
5272 "[id:%d HP:%d]."),
5275 punit->id,
5278 (float)att_power/POWER_FACTOR,
5279 att_hp_start - pwinner->hp,
5280 pwinner->hp,
5282 loser_link,
5283 pdefender->id,
5284 def_hp_start);
5285 } else {
5288 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5289 * lost 1 HP, has 9 HP remaining] succeeded against the
5290 * Greek green Warriors [id:100 HP:10]." */
5291 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5292 "has %d remaining] succeeded against the %s %s %s "
5293 "[id:%d HP:%d]."),
5296 punit->id,
5299 (float)att_power/POWER_FACTOR,
5300 att_hp_start - pwinner->hp,
5301 pwinner->hp,
5304 loser_link,
5305 pdefender->id,
5306 def_hp_start);
5307 }
5308
5309 punit->moved = TRUE; /* We moved */
5310
5311 if (paction->result == ACTRES_COLLECT_RANSOM) {
5314 } else {
5317 }
5318
5319 /* Now that dead defender is certainly no longer listed as unit
5320 * supported by the city, we may even remove the city
5321 * (if it shrinks from size 1) */
5323 if (pcity != NULL) {
5325 }
5326 if (unit_is_alive(winner_id)) {
5328 return TRUE;
5329 }
5330 } else {
5331 return TRUE;
5332 }
5333 }
5334
5335 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5336 * if there are enemy units in the tile (a fortress, city or air base with
5337 * multiple defenders and unstacked combat). Note that this could mean
5338 * capturing (or destroying) a city. */
5339
5340 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5342 }
5343
5344 /* The attacker may have died for many reasons */
5347 }
5348
5349 return TRUE;
5350}
5351
5352/**********************************************************************/
5363 struct unit *act_unit,
5364 struct city *tgt_city,
5365 const struct action *paction)
5366{
5367 struct player *tgt_player;
5368 char prod[256];
5369 const struct unit_type *act_utype;
5370 const struct tile *tgt_tile;
5371 const char *clink;
5372
5373 /* Sanity checks */
5378
5381
5383
5384 /* The surgical strike may miss. */
5385 {
5386 /* Roll the dice. */
5389 paction)) {
5390 /* Notify the player. */
5393 /* TRANS: unit, action, city */
5394 _("Your %s failed to do %s in %s."),
5398
5399 /* Make the failed attempt cost a single move. */
5400 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5401
5402 return FALSE;
5403 }
5404 }
5405
5406 /* Get name of the production */
5407 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5408
5409 /* Destroy the production */
5410 tgt_city->shield_stock = 0;
5412
5413 /* Let the players know. */
5414 clink = city_link(tgt_city); /* Be careful not to call city_link()
5415 * again as long as we need clink */
5418 _("Your %s succeeded in destroying"
5419 " the production of %s in %s."),
5421 prod, clink);
5424 _("The production of %s was destroyed in %s,"
5425 " %s are suspected."),
5426 prod, clink,
5428
5430
5431 /* May cause an incident */
5434 clink);
5435
5436 return TRUE;
5437}
5438
5439/**********************************************************************/
5450 struct unit *act_unit,
5451 struct city *tgt_city,
5453 const struct action *paction)
5454{
5455 struct player *tgt_player;
5457 const struct tile *tgt_tile;
5458 const struct unit_type *act_utype;
5459 const char *clink;
5460
5461 /* Sanity checks */
5466
5468
5471
5472 /* The surgical strike may miss. */
5473 {
5474 /* Roll the dice. */
5477 paction)) {
5478 /* Notify the player. */
5481 /* TRANS: unit, action, city */
5482 _("Your %s failed to do %s in %s."),
5486
5487 /* Make the failed attempt cost a single move. */
5488 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5489
5490 return FALSE;
5491 }
5492 }
5493
5495 /* Nothing to destroy here. */
5496
5497 /* Notify the player. */
5500 _("Your %s didn't find a %s to %s in %s."),
5505
5506 /* Punish the player for blindly attacking a building. */
5507 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5508
5509 return FALSE;
5510 }
5511
5513 /* Notify the player. */
5516 _("Your %s cannot do %s to %s in %s."),
5521
5522 /* Punish the player for blindly attacking a building. */
5523 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5524
5525 return FALSE;
5526 }
5527
5529
5530 /* Destroy the building. */
5531 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5532
5533 /* Update the player's view of the city. */
5535
5536 /* Let the players know. */
5537 clink = city_link(tgt_city); /* Be careful not to call city_link()
5538 * again as long as we need clink */
5541 _("Your %s destroyed the %s in %s."),
5544 clink);
5547 _("The %s destroyed the %s in %s."),
5550 clink);
5551
5552 /* May cause an incident */
5555
5556 return TRUE;
5557}
5558
5559/**********************************************************************/
5569 struct unit *act_unit,
5570 struct city *tgt_city,
5571 struct action *paction)
5572{
5573 bool success;
5574 struct tile *tgt_tile = city_tile(tgt_city);
5575 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5576 int tgt_city_id = tgt_city->id;
5578 const char *victim_link = city_link(tgt_city);
5579
5580 /* Sanity check */
5582
5583 unit_move(act_unit, tgt_tile, move_cost, NULL, FALSE, TRUE, TRUE,
5584 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5586
5587 /* The city may have been destroyed during the conquest. */
5590
5591 if (success) {
5592 const struct unit_type *act_utype = unit_type_get(act_unit);
5593
5594 /* May cause an incident */
5597 victim_link);
5598 }
5599
5600 return success;
5601}
5602
5603/**********************************************************************/
5607 struct tile *dest_tile,
5608 bool igzoc,
5609 struct unit *embark_to,
5610 bool enter_enemy_city)
5611{
5612 struct tile *src_tile = unit_tile(punit);
5615 src_tile, dest_tile, igzoc, TRUE, embark_to,
5617
5618 switch (reason) {
5619 case MR_OK:
5620 return TRUE;
5621
5622 case MR_NO_WAR:
5624 _("Cannot attack unless you declare war first."));
5625 break;
5626
5627 case MR_ZOC:
5629 _("%s can only move into your own zone of control."),
5630 unit_link(punit));
5631 break;
5632
5633 case MR_TRIREME:
5635 _("%s cannot move that far from the coast line."),
5636 unit_link(punit));
5637 break;
5638
5639 case MR_PEACE:
5640 if (tile_owner(dest_tile)) {
5642 _("Cannot invade unless you break peace with "
5643 "%s first."),
5644 player_name(tile_owner(dest_tile)));
5645 }
5646 break;
5647
5650 _("%s cannot disembark outside of a city or a native base "
5651 "for %s."),
5655 break;
5656
5657 case MR_NON_NATIVE_MOVE:
5659 _("Terrain is unsuitable for %s units."),
5661 break;
5662
5663 default:
5664 /* FIXME: need more explanations someday! */
5665 break;
5666 };
5667
5668 return FALSE;
5669}
5670
5671/**********************************************************************/
5678 struct unit *actor_unit,
5679 struct tile *target_tile,
5680 const struct action *paction)
5681{
5683 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5684
5685 unit_move(actor_unit, target_tile, move_cost,
5687 /* Don't override "Conquer City" */
5688 FALSE,
5689 /* Don't override "Conquer Extras" */
5690 FALSE,
5691 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5693
5694 /* May cause an incident */
5698
5699 return TRUE;
5700}
5701
5702/**********************************************************************/
5716 bool move_do_not_act)
5717{
5718 struct player *pplayer = unit_owner(punit);
5719 struct unit *ptrans;
5720 const struct civ_map *nmap = &(wld.map);
5721
5722 /*** Phase 1: Attempted action interpretation checks ***/
5723
5724 /* Check if the move should be interpreted as an attempt to perform an
5725 * enabler controlled action to the target tile. When the move may be an
5726 * action attempt the server stops moving the unit, marks it as wanting a
5727 * decision based on its own movement to the tile it attempted to move to
5728 * and notifies the client.
5729 *
5730 * In response to the unit being marked as wanting a decision the client
5731 * can query the server for what actions the unit, given the player's
5732 * knowledge, may be able to perform against a target at the tile it tried
5733 * to move to. The server will respond to the query with the actions that
5734 * may be enabled and, when all actions are known to be illegal given the
5735 * player's knowledge, an explanation why no action could be done. The
5736 * client will probably use the list of potentially legal actions, if any,
5737 * to pop up an action selection dialog. See handle_unit_action_query()
5738 *
5739 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5740 * to perform an enabler controlled action.
5741 * Examples of where this is useful is for AI moves, goto, when the player
5742 * attempts to move to a tile occupied by potential targets like allied
5743 * cities or units and during rule forced moves.
5744 *
5745 * A move is not interpreted as an attempted action because the unit is
5746 * able to do a self targeted action.
5747 *
5748 * A move is not interpreted as an attempted action because an action
5749 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5750 * perform a regular move to the tile.
5751 *
5752 * An attempted move to a tile a unit can't move to is always interpreted
5753 * as trying to perform an action (unless move_do_not_act is TRUE) */
5754 if (!move_do_not_act) {
5757 FALSE, FALSE, FALSE);
5761 /* A legal action with an extra sub target is a legal action */
5763 /* Tile target actions with extra sub targets are handled above */
5765
5767 /* There is a target punit, from the player's point of view, may be
5768 * able to act against OR punit can't do any non action move. The
5769 * client should therefore ask what action(s) the unit can perform
5770 * to any targets at pdesttile.
5771 *
5772 * In the first case the unit needs a decision about what action, if
5773 * any at all, to take. Asking what actions the unit can perform
5774 * will return a list of actions that may, from the players point of
5775 * view, be possible. The client can then show this list to the
5776 * player or, if configured to do so, make the choice it self.
5777 *
5778 * In the last case the player may need an explanation about why no
5779 * action could be taken. Asking what actions the unit can perform
5780 * will provide this explanation. */
5784
5785 /* The move wasn't done because the unit wanted the player to
5786 * decide what to do or because the unit couldn't move to the
5787 * target tile. */
5788 return FALSE;
5789 }
5790 }
5791
5792 /*** Phase 2: OK now move the unit ***/
5793 /* This is a regular move, subject to the rules. */
5795 punit, pdesttile, NULL)) {
5796 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5800 punit, pdesttile, NULL)) {
5801 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5805 punit, pdesttile, NULL)) {
5806 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5812 punit, ptrans)) {
5813 /* "Transport Embark". */
5814 return unit_perform_action(pplayer, punit->id, ptrans->id,
5820 punit, ptrans)) {
5821 /* "Transport Embark 2". */
5822 return unit_perform_action(pplayer, punit->id, ptrans->id,
5828 punit, ptrans)) {
5829 /* "Transport Embark 3". */
5830 return unit_perform_action(pplayer, punit->id, ptrans->id,
5836 punit, ptrans)) {
5837 /* "Transport Embark 4". */
5838 return unit_perform_action(pplayer, punit->id, ptrans->id,
5842 punit, pdesttile, NULL)) {
5843 /* "Transport Disembark". */
5844 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5848 punit, pdesttile, NULL)) {
5849 /* "Transport Disembark 2". */
5850 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5854 punit, pdesttile, NULL)) {
5855 /* "Transport Disembark 3". */
5856 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5860 punit, pdesttile, NULL)) {
5861 /* "Transport Disembark 4". */
5862 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5866 punit, pdesttile, NULL)) {
5867 /* "Enter Hut". */
5868 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5872 punit, pdesttile, NULL)) {
5873 /* "Enter Hut 2". */
5874 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5878 punit, pdesttile, NULL)) {
5879 /* "Frighten Hut". */
5880 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5884 punit, pdesttile, NULL)) {
5885 /* "Frighten Hut 2". */
5886 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5889 } else {
5890 /* TODO: Extend the action not enabled explanation system to cover all
5891 * existing reasons and switch to using it. See hrm Feature #920229 */
5893 NULL, FALSE);
5894 return FALSE;
5895 }
5896}
5897
5898/**********************************************************************/
5908static bool unit_do_help_build(struct player *pplayer,
5909 struct unit *punit,
5910 struct city *pcity_dest,
5911 const struct action *paction)
5912{
5913 const char *work;
5914 const char *prod;
5915 int shields;
5916 const struct unit_type *act_utype;
5917 struct player *cowner;
5918
5919 /* Sanity check: The actor still exists. */
5920 fc_assert_ret_val(pplayer, FALSE);
5922
5923 /* Sanity check: The target city still exists. */
5925
5928
5930 /* Add the caravan shields */
5931 pcity_dest->shield_stock += shields;
5932
5933 /* Will be punished for changing production to something that can't
5934 * receive "Help Wonder" help. */
5936 &pcity_dest->production));
5937 pcity_dest->caravan_shields += shields;
5938 } else {
5940 /* Add the shields from recycling the unit to the city's current
5941 * production. */
5942 pcity_dest->shield_stock += shields;
5943
5944 /* If we change production later at this turn. No penalty is added. */
5945 pcity_dest->disbanded_shields += shields;
5946 }
5947
5949
5950 conn_list_do_buffer(cowner->connections);
5951
5953 /* Let the player that just donated shields with "Help Wonder" know
5954 * the result of their donation. */
5956 } else {
5958 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
5959 * current production in Bergen (4 surplus).
5960 * "Disband Unit Recover" says "current production" rather than its name. */
5961 prod = _("current production");
5962 }
5963
5964 if (build_points_left(pcity_dest) >= 0) {
5965 /* TRANS: Your Caravan does "Help Wonder" to help build the
5966 * Pyramids in Bergen (4 remaining).
5967 * You can reorder '4' and 'remaining' in the actual format string. */
5968 work = _("remaining");
5969 } else {
5970 /* TRANS: Your Caravan does "Help Wonder" to help build the
5971 * Pyramids in Bergen (4 surplus).
5972 * You can reorder '4' and 'surplus' in the actual format string. */
5973 work = _("surplus");
5974 }
5975
5977 ftc_server,
5978 /* TRANS: Your Caravan does "Help Wonder" to help build the
5979 * Pyramids in Bergen (4 surplus). */
5980 _("Your %s does %s to help build the %s in %s (%d %s)."),
5983 prod,
5986 work);
5987
5988 /* May cause an incident */
5991
5992 if (cowner != unit_owner(punit)) {
5993 /* Tell the city owner about the gift they just received. */
5994
5997 /* TRANS: Help building the Pyramids in Bergen received
5998 * from Persian Caravan (4 surplus). */
5999 _("Help building the %s in %s received from %s %s "
6000 "(%d %s)."),
6006 work);
6007 }
6008
6011 conn_list_do_unbuffer(cowner->connections);
6012
6013 return TRUE;
6014}
6015
6016/**********************************************************************/
6023static bool do_unit_establish_trade(struct player *pplayer,
6024 struct unit *punit,
6025 struct city *pcity_dest,
6026 const struct action *paction)
6027{
6030 int revenue;
6031 bool can_establish;
6032 int home_overbooked = 0;
6033 int dest_overbooked = 0;
6034 int home_max;
6035 int dest_max;
6036 struct city *pcity_homecity;
6039 enum trade_route_bonus_type bonus_type;
6040 struct goods_type *goods;
6041 const char *goods_str;
6042 const struct unit_type *act_utype;
6043
6044 /* Sanity check: The actor still exists. */
6045 fc_assert_ret_val(pplayer, FALSE);
6047
6048 /* Sanity check: The target city still exists. */
6050
6052
6053 if (!pcity_homecity) {
6055 _("Sorry, your %s cannot establish"
6056 " a trade route because it has no home city."),
6057 unit_link(punit));
6058 return FALSE;
6059 }
6060
6062
6063 if (goods == NULL) {
6065 _("Sorry, your %s cannot establish"
6066 " a trade route because it's not carrying any goods."),
6067 unit_link(punit));
6068 return FALSE;
6069 }
6070
6073
6076 _("Sorry, your %s cannot establish"
6077 " a trade route between %s and %s."),
6081 return FALSE;
6082 }
6083
6085
6089
6090 /* This part of code works like can_establish_trade_route(), except
6091 * that we actually do the action of making the trade route. */
6092
6093 /* If we can't make a new trade route we can still get the trade bonus. */
6096
6097 if (can_establish) {
6102 }
6103
6104 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
6106
6107 /* See if there's a trade route we can cancel at the home city. */
6108 if (home_overbooked >= 0) {
6109 if (home_max <= 0
6112 >= trade)) {
6115 _("Sorry, your %s cannot establish"
6116 " a trade route here!"),
6117 punit_link);
6118 if (home_max > 0) {
6121 PL_(" The city of %s already has %d "
6122 "better trade route!",
6123 " The city of %s already has %d "
6124 "better trade routes!", home_max),
6126 home_max);
6127 }
6129 }
6130 }
6131
6132 /* See if there's a trade route we can cancel at the dest city. */
6133 if (can_establish && dest_overbooked >= 0) {
6134 if (dest_max <= 0
6137 >= trade)) {
6140 _("Sorry, your %s cannot establish"
6141 " a trade route here!"),
6142 punit_link);
6143 if (dest_max > 0) {
6146 PL_(" The city of %s already has %d "
6147 "better trade route!",
6148 " The city of %s already has %d "
6149 "better trade routes!", dest_max),
6151 dest_max);
6152 }
6154 }
6155 }
6156 }
6157
6158 /* We now know for sure whether we can establish a trade route. */
6159
6160 /* Calculate and announce initial revenue. */
6161 revenue
6164
6165 bonus_type = trade_route_settings_by_type
6167
6169
6171
6172 /* We want to keep the bonus type string as the part of the format of the PL_() strings
6173 * for supporting proper pluralization for it. */
6174 switch (bonus_type) {
6175 case TBONUS_NONE:
6178 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
6179 _("Your %s from %s has arrived in %s carrying %s."),
6180 punit_link,
6183 goods_str);
6184 break;
6185 case TBONUS_GOLD:
6188 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6189 PL_("Your %s from %s has arrived in %s carrying %s,"
6190 " and revenues amount to %d in gold.",
6191 "Your %s from %s has arrived in %s carrying %s,"
6192 " and revenues amount to %d in gold.",
6193 revenue),
6194 punit_link,
6197 goods_str,
6198 revenue);
6199 break;
6200 case TBONUS_SCIENCE:
6203 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6204 PL_("Your %s from %s has arrived in %s carrying %s,"
6205 " and revenues amount to %d in research.",
6206 "Your %s from %s has arrived in %s carrying %s,"
6207 " and revenues amount to %d in research.",
6208 revenue),
6209 punit_link,
6212 goods_str,
6213 revenue);
6214 break;
6215 case TBONUS_BOTH:
6218 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6219 PL_("Your %s from %s has arrived in %s carrying %s,"
6220 " and revenues amount to %d in gold and research.",
6221 "Your %s from %s has arrived in %s carrying %s,"
6222 " and revenues amount to %d in gold and research.",
6223 revenue),
6224 punit_link,
6227 goods_str,
6228 revenue);
6229 break;
6230 }
6231
6232 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6233 pplayer->economic.gold += revenue;
6234
6235 send_player_info_c(pplayer, pplayer->connections);
6236 }
6237
6238 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6239 /* add bulbs and check for finished research */
6240 update_bulbs(pplayer, revenue, TRUE, TRUE);
6241
6242 /* Inform everyone about tech changes */
6244 }
6245
6246 if (can_establish) {
6247 struct city_list *cities_out_of_home;
6248 struct city_list *cities_out_of_dest;
6249 struct player *partner_player;
6250
6251 /* Announce creation of trade route (it's not actually created until
6252 * later in this function, as we have to cancel existing routes, but
6253 * it makes more sense to announce in this order) */
6254
6256
6257 /* Always tell the unit owner */
6258 notify_player(pplayer, NULL,
6260 _("New trade route established from %s to %s."),
6263 if (pplayer != partner_player) {
6266 _("The %s established a trade route between their "
6267 "city %s and %s."),
6268 nation_plural_for_player(pplayer),
6271 }
6272
6275
6276 /* Now cancel any less profitable trade route from the home city. */
6278 struct trade_route *pback;
6279
6281
6283 free(premove);
6284 free(pback);
6286
6287 /* And the same for the dest city. */
6289 struct trade_route *pback;
6290
6292
6294 free(premove);
6295 free(pback);
6297
6299
6300 /* Refresh the cities. */
6309
6310 /* Notify the owners of the cities. */
6319
6320 /* Notify each player about the other's cities. */
6321 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6325 send_city_info(pplayer, pcity_dest);
6326 }
6327
6332 }
6333 if (pplayer != city_owner(pcity)) {
6334 send_city_info(pplayer, pcity);
6336 }
6338
6343 }
6344 if (pplayer != city_owner(pcity)) {
6345 send_city_info(pplayer, pcity);
6347 }
6349
6352 }
6353
6354 /* May cause an incident */
6356 pplayer, act_utype, city_owner(pcity_dest),
6359
6361
6362 /* Free data. */
6365
6366 return TRUE;
6367}
6368
6369/**********************************************************************/
6373void create_trade_route(struct city *from, struct city *to,
6374 struct goods_type *goods)
6375{
6377
6378 /* Actually create the new trade route */
6379 proute_from = fc_malloc(sizeof(struct trade_route));
6380 proute_from->partner = to->id;
6381 proute_from->goods = goods;
6382
6383 proute_to = fc_malloc(sizeof(struct trade_route));
6384 proute_to->partner = from->id;
6385 proute_to->goods = goods;
6386
6390 } else {
6391 proute_from->dir = RDIR_FROM;
6392 proute_to->dir = RDIR_TO;
6393 }
6396}
6397
6398/**********************************************************************/
6406void handle_unit_sscs_set(struct player *pplayer,
6407 int unit_id,
6409 int value)
6410{
6411 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6412 const struct civ_map *nmap = &(wld.map);
6413
6414 if (NULL == punit) {
6415 /* Being asked to unqueue a "spent" unit because the client haven't
6416 * been told that it's gone is expected. */
6417 if (type != USSDT_UNQUEUE) {
6418 /* Probably died or bribed. */
6419 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6420 }
6421
6422 return;
6423 }
6424
6425 switch (type) {
6426 case USSDT_QUEUE:
6427 /* Reminds the client to ask the server about what actions the unit can
6428 * perform against the target tile. Action decision state can be set by
6429 * the server it self too. */
6430
6431 if (index_to_tile(nmap, value) == NULL) {
6432 /* Asked to be reminded to ask what actions the unit can do to a non
6433 * existing target tile. */
6434 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6435 value, unit_id);
6436 break;
6437 }
6438
6441
6442 /* Let the client know that this unit needs the player to decide
6443 * what to do. */
6445
6446 break;
6447 case USSDT_UNQUEUE:
6448 /* Delete the reminder for the client to ask the server about what
6449 * actions the unit can perform against a certain target tile.
6450 * Action decision state can be set by the server it self too. */
6451
6454
6455 /* Let the client know that this unit no longer needs the player to
6456 * decide what to do. */
6457 send_unit_info(pplayer->connections, punit);
6458
6459 break;
6460 case USSDT_BATTLE_GROUP:
6461 /* Battlegroups are handled entirely by the client, so all we have to
6462 do here is save the battlegroup ID so that it'll be persistent. */
6463
6465
6466 break;
6467 case USSDT_SENTRY:
6468 if (value == 0) {
6469 if (punit->activity != ACTIVITY_SENTRY) {
6470 return;
6471 }
6472
6474 /* Impossible to set to Idle? */
6476 }
6477 } else if (value == 1) {
6479 return;
6480 }
6481
6483 /* Should have been caught above */
6485 }
6486 } else {
6487 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6489 }
6490 break;
6491 }
6492}
6493
6494/**********************************************************************/
6497static void unit_plans_clear(struct unit *punit)
6498{
6499 /* Remove city spot reservations for AI settlers on city founding
6500 * mission. */
6502
6503 /* Get rid of old orders. */
6505
6506 /* Make sure that no old goto_tile remains. */
6507 punit->goto_tile = NULL;
6508}
6509
6510/**********************************************************************/
6514 int unit_id,
6516{
6517 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6518
6519 if (NULL == punit) {
6520 /* Probably died or bribed. */
6521 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6522 unit_id);
6523 return;
6524 }
6525
6527 /* Client error. */
6528 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6529 agent);
6530 return;
6531 }
6532
6533 /* Set the state or exit */
6534 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6535 return;
6536 }
6537
6538 /* Give the new agent a blank slate */
6540
6541 if (agent == SSA_AUTOEXPLORE) {
6543 /* Should have been caught above */
6546 }
6547
6548 /* Exploring is handled here explicitly, since the player expects to
6549 * see an immediate response from setting a unit to auto-explore.
6550 * Handling it deeper in the code leads to some tricky recursive loops -
6551 * see PR#2631. */
6552 if (punit->moves_left > 0) {
6554 }
6555 }
6556}
6557
6558/**********************************************************************/
6563 struct unit *punit,
6565{
6566 const struct civ_map *nmap = &(wld.map);
6567
6568 /* Check that the agent can be activated for this unit. */
6569 switch (agent) {
6570 case SSA_AUTOWORKER:
6572 return FALSE;
6573 }
6574 break;
6575 case SSA_AUTOEXPLORE:
6577 return FALSE;
6578 }
6579 break;
6580 case SSA_NONE:
6581 /* Always possible. */
6582 break;
6583 case SSA_COUNT:
6585 break;
6586 }
6587
6588 if (punit->ssa_controller != agent) {
6591 }
6592
6593 return TRUE;
6594}
6595
6596/**********************************************************************/
6602 struct extra_type *old_target)
6603{
6604 switch (punit->activity) {
6605 case ACTIVITY_IDLE:
6606 switch (old_activity) {
6607 case ACTIVITY_PILLAGE:
6608 {
6609 if (old_target != NULL) {
6611 if (punit2->activity == ACTIVITY_PILLAGE) {
6612 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6613 if (pdep == old_target) {
6616 break;
6617 }
6619 }
6621 }
6622 break;
6623 }
6624 case ACTIVITY_EXPLORE:
6625 /* Restore unit's control status */
6627 break;
6628 default:
6629 ; /* Do nothing */
6630 }
6631 break;
6632 case ACTIVITY_EXPLORE:
6636 break;
6637 default:
6638 /* Do nothing */
6639 break;
6640 }
6641}
6642
6643/**********************************************************************/
6659
6660/**********************************************************************/
6666{
6667 const struct civ_map *nmap = &(wld.map);
6668
6669 /* Must specify target for ACTIVITY_BASE */
6672
6674 struct extra_type *target = NULL;
6675
6676 /* Assume untargeted pillaging if no target specified */
6682 }
6683
6684 return TRUE;
6685}
6686
6687/**********************************************************************/
6710
6711/**********************************************************************/
6731
6732/**********************************************************************/
6737 struct extra_type **new_target,
6739{
6745
6747
6748 if (list != NULL && action_list_size(list) > 0) {
6749 /* Trigger action system */
6751 (*new_target) != NULL ? (*new_target)->id : NO_TARGET,
6753 } else {
6756 }
6757 }
6758
6759 return TRUE;
6760}
6761
6762/**********************************************************************/
6770 struct extra_type **new_target,
6772{
6775 return FALSE;
6776 } else {
6780
6785 /* unit_assign_specific_activity_target() changed our target activity
6786 * (to ACTIVITY_IDLE in practice) */
6788 } else {
6793
6795 /* Casus Belli for when the activity successfully begins. */
6796 /* TODO: is it more logical to change Casus_Belli_Complete to
6797 * Casus_Belli_Successful_Beginning and trigger it here? */
6803 }
6804 }
6805
6806 return TRUE;
6807 }
6808}
6809
6810/**********************************************************************/
6813void handle_unit_orders(struct player *pplayer,
6814 const struct packet_unit_orders *packet)
6815{
6816 int length = packet->length;
6817 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6818 const struct civ_map *nmap = &(wld.map);
6819 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6820 struct unit_order *order_list;
6821#ifdef FREECIV_DEBUG
6822 int i;
6823#endif
6824
6825 if (NULL == punit) {
6826 /* Probably died or bribed. */
6827 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6828 return;
6829 }
6830
6831 if (0 > length || MAX_LEN_ROUTE < length) {
6832 /* Shouldn't happen */
6833 log_error("handle_unit_orders() invalid %s (%d) "
6834 "packet length %d (max %d)", unit_rule_name(punit),
6835 packet->unit_id, length, MAX_LEN_ROUTE);
6836 return;
6837 }
6838
6839 if (src_tile != unit_tile(punit)) {
6840 /* Failed sanity check. Usually this happens if the orders were sent
6841 * in the previous turn, and the client thought the unit was in a
6842 * different position than it's actually in. The easy solution is to
6843 * discard the packet. We don't send an error message to the client
6844 * here (though maybe we should?). */
6845 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6846 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6847 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6848 return;
6849 }
6850
6851 if (ACTIVITY_IDLE != punit->activity) {
6852 /* New orders implicitly abandon current activity */
6854 }
6855
6856 if (length) {
6857 order_list = create_unit_orders(nmap, length, packet->orders);
6858 if (!order_list) {
6859 log_error("received invalid orders from %s for %s (%d).",
6860 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6861 return;
6862 }
6863 }
6864
6865 /* This must be before old orders are freed. If this is
6866 * settlers on city founding mission, city spot reservation
6867 * from goto_tile must be freed, and free_unit_orders() loses
6868 * goto_tile information */
6870
6872 /* If we waited on a tile, reset punit->done_moving */
6873 punit->done_moving = (punit->moves_left <= 0);
6874
6875 if (length == 0) {
6878 return;
6879 }
6880
6882 punit->orders.length = length;
6883 punit->orders.index = 0;
6884 punit->orders.repeat = packet->repeat;
6885 punit->orders.vigilant = packet->vigilant;
6886 if (length) {
6888 }
6889
6890 if (!packet->repeat) {
6892 } else {
6893 /* Make sure that no old goto_tile remains. */
6894 punit->goto_tile = NULL;
6895 }
6896
6897#ifdef FREECIV_DEBUG
6898 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6899 for (i = 0; i < length; i++) {
6900 log_debug(" %d,%s,%s,%d,%d",
6901 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6902 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6904 packet->orders[i].order == ORDER_ACTIVITY ?
6906 "no action/activity required",
6907 packet->orders[i].target,
6908 packet->orders[i].sub_target);
6909 }
6910#endif /* FREECIV_DEBUG */
6911
6913 || execute_orders(punit, TRUE)) {
6914 /* Looks like the unit survived. */
6916 }
6917}
6918
6919/**********************************************************************/
6922void handle_worker_task(struct player *pplayer,
6923 const struct packet_worker_task *packet)
6924{
6925 struct city *pcity = game_city_by_number(packet->city_id);
6926 struct worker_task *ptask = NULL;
6927 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
6928
6929 if (pcity == NULL || pcity->owner != pplayer || ptile == NULL) {
6930 return;
6931 }
6932
6934 if (tile_index(ptask_old->ptile) == packet->tile_id) {
6935 ptask = ptask_old;
6936 }
6938
6939 if (ptask == NULL) {
6940 if (packet->activity == ACTIVITY_LAST) {
6941 return;
6942 }
6943
6944 ptask = fc_malloc(sizeof(struct worker_task));
6946 worker_task_list_append(pcity->task_reqs, ptask);
6947 } else {
6948 if (packet->activity == ACTIVITY_LAST) {
6949 worker_task_list_remove(pcity->task_reqs, ptask);
6950 free(ptask);
6951 ptask = NULL;
6952 }
6953 }
6954
6955 if (ptask != NULL) {
6956 ptask->ptile = ptile;
6957 ptask->act = packet->activity;
6958 if (packet->tgt >= 0) {
6959 if (packet->tgt < MAX_EXTRA_TYPES) {
6960 ptask->tgt = extra_by_number(packet->tgt);
6961 } else {
6962 log_debug("Illegal worker task target %d", packet->tgt);
6963 ptask->tgt = NULL;
6964 }
6965 } else {
6966 ptask->tgt = NULL;
6967 }
6968 ptask->want = packet->want;
6969 }
6970
6971 if (ptask && !worker_task_is_sane(ptask)) {
6972 log_debug("Bad worker task");
6973 worker_task_list_remove(pcity->task_reqs, ptask);
6974 free(ptask);
6975 ptask = NULL;
6976 return;
6977 }
6978
6979 lsend_packet_worker_task(pplayer->connections, packet);
6980}
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1173
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:5569
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1250
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5091
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:2607
const char * action_name_translation(const struct action *paction)
Definition actions.c:1230
struct act_prob action_prob_vs_tile(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4612
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1239
bool is_action_enabled_unit_on_stack(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Definition actions.c:3256
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:7612
int action_number(const struct action *action)
Definition actions.c:1208
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:3332
struct act_prob action_prob_vs_extras(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4695
struct act_prob action_prob_self(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id)
Definition actions.c:4765
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:3091
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:3168
struct act_prob action_prob_vs_city(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:4254
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:5514
struct action * action_is_blocked_by(const struct civ_map *nmap, const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:2286
bool action_id_exists(const action_id act_id)
Definition actions.c:1068
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1108
struct act_prob action_prob_unit_vs_tgt(const struct civ_map *nmap, const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:4787
struct act_prob action_prob_vs_stack(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:4529
struct act_prob action_prob_vs_unit(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:4337
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1559
#define action_noninternal_iterate_end
Definition actions.h:236
#define ACTPROB_NA
Definition actions.h:689
static struct action * action_by_number(action_id act_id)
Definition actions.h:396
#define action_has_result(_act_, _res_)
Definition actions.h:180
#define action_enabler_list_iterate_end
Definition actions.h:190
#define action_id_get_role(act_id)
Definition actions.h:457
#define action_iterate_end
Definition actions.h:214
#define MAX_NUM_ACTIONS
Definition actions.h:58
#define action_id_get_actor_kind(act_id)
Definition actions.h:409
#define ACTPROB_NOT_KNOWN
Definition actions.h:691
#define action_get_activity(_pact_)
Definition actions.h:460
#define action_has_result_safe(paction, result)
Definition actions.h:424
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:188
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:445
#define ACTPROB_IMPOSSIBLE
Definition actions.h:687
#define action_id(_act_)
Definition actions.h:422
#define action_iterate(_act_)
Definition actions.h:210
#define ACTION_ANY
Definition actions.h:52
#define action_noninternal_iterate(_act_)
Definition actions.h:231
#define action_id_get_target_kind(act_id)
Definition actions.h:413
#define action_id_has_result_safe(act_id, result)
Definition actions.h:426
#define action_id_has_complex_target(act_id)
Definition actions.h:431
#define ACTION_NONE
Definition actions.h:55
struct tile * action_tgt_tile(struct unit *actor, struct tile *target, const struct extra_type *target_extra, bool accept_all_actions)
void action_consequence_caught(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
const struct action * action_auto_perf_unit_do(const enum action_auto_perf_cause cause, struct unit *actor, const struct player *other_player, const struct output_type *eval_output, const struct action *eval_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit, const struct extra_type *target_extra)
struct unit * action_tgt_unit(struct unit *actor, struct tile *target_tile, bool accept_all_actions)
void action_consequence_success(const struct action *paction, struct player *offender, const struct unit_type *offender_utype, struct player *victim_player, const struct tile *victim_tile, const char *victim_link)
struct city * action_tgt_city(struct unit *actor, struct tile *target_tile, bool accept_all_actions)
struct extra_type * action_tgt_tile_extra(const struct unit *actor, const struct tile *target_tile, bool accept_all_actions)
bool action_failed_dice_roll(const struct player *act_player, const struct unit *act_unit, const struct city *tgt_city, const struct player *tgt_player, const struct action *paction)
int action_sub_target_id_for_action(const struct action *paction, struct unit *actor_unit)
#define ASSERT_UNUSED_ACTRES_CASES
Definition actres.h:37
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:377
void astr_free(struct astring *astr)
Definition astring.c:148
const char * astr_build_or_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:313
#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:105
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:143
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
void citizens_update(struct city *pcity, struct player *plr)
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1860
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
bool is_capital(const struct city *pcity)
Definition city.c:1579
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1465
void city_size_add(struct city *pcity, int add)
Definition city.c:1164
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2012
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2051
bool city_exist(int id)
Definition city.c:3597
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:700
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:767
#define city_list_iterate(citylist, pcity)
Definition city.h:505
#define city_tile(_pcity_)
Definition city.h:561
static citizens city_size_get(const struct city *pcity)
Definition city.h:566
#define city_owner(_pcity_)
Definition city.h:560
#define city_list_iterate_end
Definition city.h:507
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2368
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1520
int build_points_left(struct city *pcity)
Definition citytools.c:576
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3077
void city_units_upkeep(const struct city *pcity)
Definition citytools.c:3165
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:374
void remove_city(struct city *pcity)
Definition citytools.c:1713
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Definition citytools.c:2943
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3567
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:3455
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:158
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:86
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:257
struct city * sdi_try_defend(const struct civ_map *nmap, const struct player *owner, const struct tile *ptile)
Definition combat.c:503
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:772
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:615
bool is_tired_attack(int moves_left)
Definition combat.c:532
enum unit_attack_result unit_wipe_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Definition combat.c:272
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
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:411
#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:76
#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:2791
struct unit struct city struct unit * target_unit
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 * actor
Definition dialogs_g.h:73
struct unit * actor_unit
Definition dialogs_g.h:55
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 struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
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:2468
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1818
bool diplomat_bribe_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:644
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:549
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:484
bool diplomat_bribe_stack(struct player *pplayer, struct unit *pdiplomat, struct tile *pvictim, const struct action *paction)
Definition diplomats.c:812
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:1011
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1404
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1255
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1676
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:1956
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:324
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:927
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 req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
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:779
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
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:804
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:213
int Impr_type_id
Definition fc_types.h:235
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:229
int action_id
Definition fc_types.h:248
#define ACTRES_NONE
Definition fc_types.h:186
#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:241
#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:61
bool is_player_phase(const struct player *pplayer, int phase)
Definition game.c:712
struct world wld
Definition game.c:62
struct unit * game_unit_by_number(int id)
Definition game.c:115
struct city * game_city_by_number(int id)
Definition game.c:106
static int actor_unit_id
static int target_extra_id
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
struct impr_type * improvement_by_number(const Impr_type_id id)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
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:182
#define fc_assert_ret(condition)
Definition log.h:192
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define fc_assert_action(condition, action)
Definition log.h:188
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:209
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:2092
const char * dir_get_name(enum direction8 dir)
Definition map.c:1287
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:471
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:675
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:1469
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:290
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2489
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:899
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:773
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:925
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:869
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1387
#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:1016
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:629
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:318
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:330
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:912
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:490
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:571
#define SINGLE_MOVE
Definition movement.h:26
unit_move_result
Definition movement.h:34
@ MR_CANNOT_DISEMBARK
Definition movement.h:48
@ MR_OK
Definition movement.h:35
@ MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT
Definition movement.h:45
@ MR_TRIREME
Definition movement.h:47
@ MR_NON_NATIVE_MOVE
Definition movement.h:49
@ MR_PEACE
Definition movement.h:39
@ MR_ZOC
Definition movement.h:40
@ MR_NO_WAR
Definition movement.h:38
static const char * name_translation_get(const struct name_translation *ptrans)
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:463
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
const char * nation_adjective_translation(const struct nation_type *pnation)
Definition nation.c:149
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
@ UNIT_INFO_IDENTITY
Definition packets.h:67
void dlsend_packet_nuke_tile_info(struct conn_list *dest, int tile)
void lsend_packet_worker_task(struct conn_list *dest, const struct packet_worker_task *packet)
int dsend_packet_unit_actions(struct connection *pc, int actor_unit_id, int target_unit_id, int target_city_id, int target_tile_id, int target_extra_id, int request_kind, const struct act_prob *action_probabilities)
int send_packet_unit_short_info(struct connection *pc, const struct packet_unit_short_info *packet, bool force_to_send)
void lsend_packet_unit_combat_info(struct conn_list *dest, const struct packet_unit_combat_info *packet)
int dsend_packet_unit_action_answer(struct connection *pc, int actor_id, int target_id, int cost, action_id action_type, int request_kind)
int send_packet_unit_info(struct connection *pc, const struct packet_unit_info *packet)
int send_packet_unit_combat_info(struct connection *pc, const struct packet_unit_combat_info *packet)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
const char * player_name(const struct player *pplayer)
Definition player.c:895
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1104
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1337
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1409
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1463
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:542
#define players_iterate(_pplayer)
Definition player.h:537
int normal_player_count(void)
Definition plrhand.c:3209
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2963
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3008
struct conn_list * player_reply_dest(struct player *pplayer)
Definition plrhand.c:1595
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2915
#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:317
int id
Definition city.h:323
struct trade_route_list * routes
Definition city.h:341
citizens * nationality
Definition city.h:338
struct tile * tile
Definition city.h:319
int upgrade_veteran_loss
Definition game.h:206
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:177
bool homecaughtunits
Definition game.h:195
struct civ_game::@32::@36 server
int replace_priority
struct unit_order orders[MAX_LEN_ROUTE]
enum unit_activity activity
enum diplstate_type type
Definition player.h:199
int units_lost
Definition player.h:106
struct unit_list * units
Definition player.h:282
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
struct player_score score
Definition player.h:283
const struct player * player
Definition tile.h:50
int index
Definition tile.h:51
struct unit_list * units
Definition tile.h:58
enum trade_route_bonus_type bonus_type
Definition traderoutes.h:78
enum adv_unit_task task
Definition unit.h:90
enum unit_activity activity
Definition unit.h:95
enum unit_orders order
Definition unit.h:94
int action
Definition unit.h:102
enum direction8 dir
Definition unit.h:104
int target
Definition unit.h:98
int sub_target
Definition unit.h:99
int paratroopers_range
Definition unittype.h:548
int city_size
Definition unittype.h:557
Definition unit.h:140
int length
Definition unit.h:198
bool has_orders
Definition unit.h:196
enum action_decision action_decision_want
Definition unit.h:205
int battlegroup
Definition unit.h:194
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
struct unit::@83 orders
bool moved
Definition unit.h:176
int index
Definition unit.h:198
struct vision * vision
Definition unit.h:247
bool vigilant
Definition unit.h:200
int hp
Definition unit.h:153
enum direction8 facing
Definition unit.h:144
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:142
struct extra_type * activity_target
Definition unit.h:167
struct unit_order * list
Definition unit.h:201
struct unit_adv * adv
Definition unit.h:239
bool repeat
Definition unit.h:199
int homecity
Definition unit.h:148
bool done_moving
Definition unit.h:184
struct tile * goto_tile
Definition unit.h:157
struct tile * action_decision_tile
Definition unit.h:206
const struct unit_type * utype
Definition unit.h:141
int veteran
Definition unit.h:154
struct player * owner
Definition unit.h:145
enum server_side_agent ssa_controller
Definition unit.h:175
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define bool
Definition support.h:71
#define fc__fallthrough
Definition support.h:119
#define A_UNSET
Definition tech.h:48
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Definition techtools.c:293
void update_bulbs(struct player *pplayer, int bulbs, bool check_tech, bool free_bulbs)
Definition techtools.c:654
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:238
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
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:89
#define tile_terrain(_tile)
Definition tile.h:111
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_owner(_tile)
Definition tile.h:97
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)
struct goods_type * unit_current_goods(const struct unit *punit, const struct city *homecity)
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, int priority, 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:2911
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:214
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1820
void free_unit_orders(struct unit *punit)
Definition unit.c:1806
bool unit_is_alive(int id)
Definition unit.c:2290
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1959
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1274
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2518
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2467
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2344
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:865
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:383
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2930
bool can_unit_do_autoworker(const struct unit *punit)
Definition unit.c:630
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target, enum gen_action trigger_action)
Definition unit.c:1132
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:892
int stack_bribe_cost(const struct tile *ptile, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2432
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1114
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:2025
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2502
bool is_flagless_to_player(const struct unit *punit, const struct player *pplayer)
Definition unit.c:363
bool unit_has_orders(const struct unit *punit)
Definition unit.c:202
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:590
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:931
#define unit_tile(_pu)
Definition unit.h:404
@ ORDER_ACTIVITY
Definition unit.h:42
@ ORDER_PERFORM_ACTION
Definition unit.h:48
#define unit_owner(_pu)
Definition unit.h:403
@ UU_NO_MONEY
Definition unit.h:64
#define MAX_NUM_BATTLEGROUPS
Definition unit.h:192
@ AR_SRC_NO_FLIGHTS
Definition unit.h:85
@ AR_DST_NO_FLIGHTS
Definition unit.h:86
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:440
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target, enum gen_action trigger_action)
Definition unithand.c:6735
#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:1027
static bool do_unit_change_homecity(struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4178
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:257
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:3322
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4950
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4495
static bool do_unit_make_homeless(struct unit *punit, const struct action *paction)
Definition unithand.c:1012
static void handle_unit_change_activity_real(struct player *pplayer, int unit_id, enum unit_activity activity, struct extra_type *activity_target, enum gen_action trigger_action)
Definition unithand.c:4323
static bool non_allied_not_listed_at(const struct player *pplayer, const int *list, int n, const struct tile *ptile)
Definition unithand.c:287
void handle_unit_orders(struct player *pplayer, const struct packet_unit_orders *packet)
Definition unithand.c:6813
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:2515
static bool do_heal_unit(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:732
static bool do_capture_units(struct player *pplayer, struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:316
static bool do_expel_unit(struct player *pplayer, struct unit *actor, struct unit *target, const struct action *paction)
Definition unithand.c:603
static bool do_unit_conquer_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, struct action *paction)
Definition unithand.c:5568
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:1410
#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:4374
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:6922
static bool occupy_move(struct tile *def_tile, struct unit *punit, const struct action *paction)
Definition unithand.c:505
static bool do_unit_embark(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:975
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6663
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:3358
#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:5362
#define ACTION_PERFORM_UNIT_STACK(action, actor, target, action_performer)
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:2991
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:1956
static const char * unit_tired_attack_string(const struct unit *punit)
Definition unithand.c:4903
static bool do_unit_deboard(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:837
static bool does_terrain_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct terrain *pterrain)
Definition unithand.c:1368
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Definition unithand.c:6600
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3170
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4590
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5715
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:4777
#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:6513
void create_trade_route(struct city *from, struct city *to, struct goods_type *goods)
Definition unithand.c:6373
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:3338
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:1452
static bool do_action_activity(struct unit *punit, const struct action *paction)
Definition unithand.c:6649
static bool unit_activity_targeted_internal(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target, enum gen_action trigger_action)
Definition unithand.c:6768
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:5449
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:1051
static bool do_unit_unload(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:900
void unit_change_homecity_handling(struct unit *punit, struct city *new_pcity, bool rehome)
Definition unithand.c:4072
static bool tile_has_units_not_allied_to_but_seen_by(const struct tile *ptile, const struct player *pplayer)
Definition unithand.c:1350
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Definition unithand.c:6717
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:1314
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5908
void handle_unit_type_upgrade(struct player *pplayer, Unit_type_id uti)
Definition unithand.c:187
static bool city_add_unit(struct player *pplayer, struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4212
static bool do_unit_load(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:879
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:3189
static bool do_wipe_units(struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:550
static bool unit_nuke(struct player *pplayer, struct unit *punit, struct tile *def_tile, const struct action *paction)
Definition unithand.c:4707
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:5606
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:2251
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Definition unithand.c:6406
static bool do_unit_board(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:856
static void see_combat(struct unit *pattacker, struct unit *pdefender)
Definition unithand.c:4436
#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:1092
static const char * unit_achieved_rank_string(const struct unit *punit)
Definition unithand.c:4886
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:5677
static bool do_conquer_extras(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:693
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6562
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:6023
static bool do_disembark(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:917
static bool unit_activity_internal(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6693
static void unit_plans_clear(struct unit *punit)
Definition unithand.c:6497
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4274
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4540
static bool do_unit_hut(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:945
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:1936
#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)
static const char * unit_firepower_if_not_one(int firepower)
Definition unithand.c:4925
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4865
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:3111
#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:359
void unit_did_action(struct unit *punit)
Definition unittools.c:5065
void collect_ransom(struct unit *pcollector, struct unit *punit, bool vet)
Definition unittools.c:2643
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Definition unittools.c:3066
void unit_make_contact(const struct unit *punit, struct tile *ptile, struct player *pplayer)
Definition unittools.c:5180
bool execute_orders(struct unit *punit, const bool fresh)
Definition unittools.c:4518
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1553
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:292
void combat_veterans(struct unit *attacker, struct unit *defender, bool powerless, int att_vet, int def_vet)
Definition unittools.c:404
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:3034
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Definition unittools.c:2733
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2864
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2877
void notify_unit_experience(struct unit *punit)
Definition unittools.c:747
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:2814
void unit_forget_last_activity(struct unit *punit)
Definition unittools.c:1053
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:5004
void do_explore(struct unit *punit)
Definition unittools.c:3099
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3389
bool unit_can_do_action_now(const struct unit *punit)
Definition unittools.c:5032
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2139
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unittools.c:3135
void unit_transport_unload_send(struct unit *punit)
Definition unittools.c:3441
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2199
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:1616
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:4078
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Definition unittools.c:2266
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:1130
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1638
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:1575
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1255
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1593
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1933
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1709
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:961
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2505
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:2603
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:196
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1225
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:1042
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:1549
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1566
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:1023
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:377
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1674
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1737
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:773
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_type_iterate(_p)
Definition unittype.h:862
#define unit_type_iterate_end
Definition unittype.h:869
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