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
385 pcity = tile_city(pdesttile);
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. */
659 fc_assert(is_capital(pcity));
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:
1120 /* Target is a unit stack but a city can block it. */
1122
1124 if (target_tile != NULL) {
1125 struct city *tcity;
1126
1127 if ((tcity = tile_city(target_tile))
1129 return city_owner(tcity);
1130 }
1131 }
1132 }
1133 break;
1134
1135 case ACTRES_PARADROP:
1137 /* Target is a tile but a city can block it. */
1139 if (target_tile != NULL
1141 /* Seen tile unit savers */
1142
1143 struct city *tcity;
1144
1146 return city_owner(tcity);
1147 }
1148 }
1149 break;
1153 case ACTRES_SPY_POISON:
1162 case ACTRES_TRADE_ROUTE:
1163 case ACTRES_MARKETPLACE:
1164 case ACTRES_HELP_WONDER:
1167 case ACTRES_CAPTURE_UNITS: /* Only foreign is a hard req. */
1168 case ACTRES_FOUND_CITY:
1169 case ACTRES_JOIN_CITY:
1170 case ACTRES_STEAL_MAPS:
1171 case ACTRES_SPY_NUKE:
1172 case ACTRES_NUKE:
1173 case ACTRES_NUKE_UNITS:
1175 case ACTRES_EXPEL_UNIT:
1178 case ACTRES_HOME_CITY:
1179 case ACTRES_HOMELESS:
1181 case ACTRES_AIRLIFT:
1182 case ACTRES_HEAL_UNIT:
1185 case ACTRES_BOMBARD:
1188 case ACTRES_CULTIVATE:
1189 case ACTRES_PLANT:
1190 case ACTRES_PILLAGE:
1191 case ACTRES_CLEAN:
1192 case ACTRES_FORTIFY:
1193 case ACTRES_CONVERT:
1194 case ACTRES_ROAD:
1195 case ACTRES_BASE:
1196 case ACTRES_MINE:
1197 case ACTRES_IRRIGATE:
1204 case ACTRES_SPY_ATTACK:
1205 case ACTRES_HUT_ENTER:
1207 case ACTRES_UNIT_MOVE:
1208 case ACTRES_TELEPORT:
1211 case ACTRES_SPY_ESCAPE:
1212 case ACTRES_NONE:
1213 /* No special help. */
1214 break;
1215
1217 }
1218
1219 /* Look for war requirements from the action enablers. */
1221 case ATK_CITY:
1222 if (target_city == NULL) {
1223 /* No target city. */
1224 return NULL;
1225 }
1226
1228 break;
1229 case ATK_UNIT:
1230 if (target_unit == NULL) {
1231 /* No target unit. */
1232 return NULL;
1233 }
1235 /* Target unit is flagless anyway - no war needed */
1236 return NULL;
1237 }
1238
1240 break;
1241 case ATK_UNITS:
1242 if (target_tile == NULL) {
1243 /* No target units since no target tile. */
1244 return NULL;
1245 }
1246
1247 unit_list_iterate(target_tile->units, tunit) {
1250 target_player = unit_owner(tunit);
1251 break;
1252 }
1254 break;
1255 case ATK_TILE:
1256 if (target_tile == NULL) {
1257 /* No target tile. */
1258 return NULL;
1259 }
1261 break;
1262 case ATK_EXTRAS:
1263 if (target_tile == NULL) {
1264 /* No target tile. */
1265 return NULL;
1266 }
1268 break;
1269 case ATK_SELF:
1270 /* Can't declare war on itself. */
1271 return NULL;
1272 break;
1273 case ATK_COUNT:
1274 /* Nothing to check. */
1276 return NULL;
1277 }
1278
1279 if (target_player == NULL) {
1280 /* Declaring war won't enable the specified action. */
1281 return NULL;
1282 }
1283
1284 /* Look for DiplRelTileOther war requirements from the action enablers. */
1285 if (target_tile != NULL
1289 return tile_owner(target_tile);
1290 }
1291
1292 /* Look for DiplRel war requirements from the action enablers. */
1296 return target_player;
1297 }
1298
1299 /* No check if other, non war, diplomatic states also could make the
1300 * action legal. This is need_war_player() so war is always the answer.
1301 * If you disagree and decide to add support please check that
1302 * webperimental's "can't found a city on a tile belonging to a non enemy"
1303 * rule still is detected. */
1304
1305 return NULL;
1306}
1307
1308/**********************************************************************/
1313static struct player *need_war_player(const struct unit *actor,
1314 const action_id act_id,
1315 const struct tile *target_tile,
1316 const struct city *target_city,
1317 const struct unit *target_unit)
1318{
1319 if (act_id == ACTION_ANY) {
1320 /* Any action at all will do. */
1321 action_iterate(act) {
1322 struct player *war_player;
1323
1326 target_unit);
1327
1328 if (war_player != NULL) {
1329 /* Declaring war on this player may enable this action. */
1330 return war_player;
1331 }
1333
1334 /* No action at all may be enabled by declaring war. */
1335 return NULL;
1336 } else {
1337 /* Look for the specified action. */
1338 return need_war_player_hlp(actor, act_id,
1340 target_unit);
1341 }
1342}
1343
1344/**********************************************************************/
1348static bool
1350 const struct player *pplayer)
1351{
1352 unit_list_iterate(ptile->units, pother) {
1353 if (can_player_see_unit(pplayer, pother)
1354 && !pplayers_allied(pplayer, unit_owner(pother))) {
1355 return TRUE;
1356 }
1358
1359 return FALSE;
1360}
1361
1362/**********************************************************************/
1367static bool does_terrain_block_action(const action_id act_id,
1368 bool is_target,
1369 struct unit *actor_unit,
1370 struct terrain *pterrain)
1371{
1372 if (act_id == ACTION_ANY) {
1373 /* Any action is OK. */
1376 && !does_terrain_block_action(alt_act, is_target,
1377 actor_unit, pterrain)) {
1378 /* Only one action has to be possible. */
1379 return FALSE;
1380 }
1382
1383 /* No action enabled. */
1384 return TRUE;
1385 }
1386
1387 /* ACTION_ANY is handled above. */
1389
1391 enabler) {
1393 (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1395 &enabler->actor_reqs)) {
1396 /* This terrain kind doesn't block this action enabler. */
1397 return FALSE;
1398 }
1400
1401 return TRUE;
1402}
1403
1404/**********************************************************************/
1409static bool does_nation_block_action(const action_id act_id,
1410 bool is_target,
1411 struct unit *actor_unit,
1412 struct nation_type *pnation)
1413{
1414 if (act_id == ACTION_ANY) {
1415 /* Any action is OK. */
1418 && !does_nation_block_action(alt_act, is_target,
1419 actor_unit, pnation)) {
1420 /* Only one action has to be possible. */
1421 return FALSE;
1422 }
1424
1425 /* No action enabled. */
1426 return TRUE;
1427 }
1428
1429 /* ACTION_ANY is handled above. */
1431
1433 enabler) {
1435 (is_target ? &enabler->target_reqs
1436 : &enabler->actor_reqs))
1438 &enabler->actor_reqs)) {
1439 /* This nation doesn't block this action enabler. */
1440 return FALSE;
1441 }
1443
1444 return TRUE;
1445}
1446
1447/**********************************************************************/
1451static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1452 const action_id act_id,
1453 const struct tile *target_tile,
1454 const struct city *target_city,
1455 const struct unit *target_unit)
1456{
1457 struct player *must_war_player;
1458 const struct action *paction;
1459 struct action *blocker;
1460 struct player *act_player = unit_owner(punit);
1461 struct player *tgt_player = NULL;
1462 struct ane_expl *explnat = fc_malloc(sizeof(struct ane_expl));
1463 struct civ_map *nmap = &(wld.map);
1466 int action_custom;
1467
1468 /* Not know yet. (Initialize before the below check.) */
1469 explnat->kind = ANEK_UNKNOWN;
1470
1471 paction = action_by_number(act_id);
1472
1473 if (act_id != ACTION_ANY) {
1474 /* A specific action should have a suitable target. */
1476 case ATK_CITY:
1477 if (target_city == NULL) {
1479 }
1480 break;
1481 case ATK_UNIT:
1482 if (target_unit == NULL) {
1484 }
1485 break;
1486 case ATK_UNITS:
1487 case ATK_TILE:
1488 case ATK_EXTRAS:
1489 if (target_tile == NULL) {
1491 }
1492 break;
1493 case ATK_SELF:
1494 /* No other target. */
1495 break;
1496 case ATK_COUNT:
1498 break;
1499 }
1500 }
1501
1502 if (explnat->kind == ANEK_MISSING_TARGET) {
1503 /* No point continuing. */
1504 return explnat;
1505 }
1506
1507 if (act_id == ACTION_ANY) {
1508 /* Find the target player of some actions. */
1509 if (target_city) {
1510 /* Individual city targets have the highest priority. */
1512 } else if (target_unit) {
1513 /* Individual unit targets have the next priority. */
1515 } else if (target_tile) {
1516 /* Tile targets have the lowest priority. */
1518 }
1519 } else {
1520 /* Find the target player of this action. */
1522 case ATK_CITY:
1524 break;
1525 case ATK_UNIT:
1527 break;
1528 case ATK_TILE:
1530 break;
1531 case ATK_EXTRAS:
1532 tgt_player = target_tile->extras_owner;
1533 break;
1534 case ATK_UNITS:
1535 /* A unit stack may contain units with multiple owners. Pick the
1536 * first one. */
1537 if (target_tile
1538 && unit_list_size(target_tile->units) > 0) {
1540 }
1541 break;
1542 case ATK_SELF:
1543 /* A unit acting against itself. */
1545 break;
1546 case ATK_COUNT:
1548 break;
1549 }
1550 }
1551
1552 if (act_id == ACTION_ANY) {
1553 action_custom = 0;
1554 } else {
1555 switch (paction->result) {
1558 break;
1559 case ACTRES_AIRLIFT:
1561 break;
1562 case ACTRES_NUKE_UNITS:
1564 target_tile);
1565 break;
1566 case ACTRES_ATTACK:
1568 target_tile);
1569 break;
1570 case ACTRES_WIPE_UNITS:
1572 break;
1574 if (target_city) {
1576 punit->activity,
1579 FALSE, FALSE, NULL, TRUE);
1580 } else {
1582 }
1583 break;
1585 if (target_unit) {
1587 punit->activity,
1590 FALSE, TRUE, NULL, FALSE);
1591 } else {
1593 }
1594 break;
1596 case ACTRES_HUT_ENTER:
1599 case ACTRES_UNIT_MOVE:
1600 if (target_tile) {
1602 punit->activity,
1605 FALSE, FALSE, NULL, FALSE);
1606 } else {
1608 }
1609 break;
1610 case ACTRES_TELEPORT:
1611 if (target_tile != NULL) {
1613 punit->activity,
1616 FALSE, NULL, FALSE);
1617 } else {
1619 }
1620 break;
1621 default:
1622 action_custom = 0;
1623 break;
1624 }
1625 }
1626
1627 if (!unit_can_do_action(punit, act_id)) {
1628 explnat->kind = ANEK_ACTOR_UNIT;
1630 && tile_city(target_tile)) {
1631 explnat->kind = ANEK_BAD_TARGET;
1635 act_player)) {
1637 } else if ((!can_exist
1640 || (can_exist
1644 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1645 } else if ((!on_native
1648 || (on_native
1650 USP_NATIVE_TILE, TRUE))) {
1652 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1653 } else if (punit
1656 /* No action enabler allows acting against this terrain kind. */
1658 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1660 && target_tile
1662 TER_NO_CITIES)) {
1664 explnat->no_act_terrain = tile_terrain(target_tile);
1667 && target_tile != NULL
1669 V_MAIN)
1671 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
1674 explnat->no_act_terrain = tile_terrain(target_tile);
1675 } else if (target_tile
1678 /* No action enabler allows acting against this terrain kind. */
1680 explnat->no_act_terrain = tile_terrain(target_tile);
1681 } else if (unit_transported(punit)
1685 } else if (!unit_transported(punit)
1689 } else if (0 < get_transporter_occupancy(punit)
1693 } else if (!(0 < get_transporter_occupancy(punit))
1697 } else if ((punit->homecity > 0)
1701 } else if ((punit->homecity <= 0)
1705 } else if ((punit->homecity <= 0)
1709 } else if (act_player && tgt_player
1711 == DS_PEACE)
1713 act_id,
1714 DS_PEACE,
1715 FALSE)
1717 act_id,
1718 DS_PEACE,
1719 TRUE)) {
1720 explnat->kind = ANEK_PEACE;
1721 explnat->peace_with = tgt_player;
1723 act_id,
1726 target_unit)) != NULL) {
1727 explnat->kind = ANEK_NO_WAR;
1728 explnat->no_war_with = must_war_player;
1729 } else if (action_mp_full_makes_legal(punit, act_id)) {
1730 explnat->kind = ANEK_LOW_MP;
1731 } else if (tgt_player != NULL
1734 act_id,
1736 TRUE)) {
1737 explnat->kind = ANEK_FOREIGN;
1738 } else if (tgt_player != NULL
1741 act_id,
1743 FALSE)) {
1744 explnat->kind = ANEK_DOMESTIC;
1745 } else if (punit != NULL
1747 punit, act_player->nation)) {
1748 explnat->kind = ANEK_NATION_ACT;
1749 explnat->no_act_nation = act_player->nation;
1750 } else if (tgt_player
1751 && does_nation_block_action(act_id, TRUE,
1752 punit, tgt_player->nation)) {
1753 explnat->kind = ANEK_NATION_TGT;
1754 explnat->no_act_nation = tgt_player->nation;
1755 } else if ((target_tile && tile_city(target_tile))
1757 act_id,
1759 TRUE)) {
1761 } else if ((target_tile && !tile_city(target_tile))
1763 act_id,
1765 FALSE)) {
1767 } else if ((target_tile && tile_owner(target_tile) != NULL)
1769 act_id,
1771 TRUE)) {
1773 } else if ((target_tile && tile_owner(target_tile) == NULL)
1775 act_id,
1777 FALSE)) {
1779 } else if (paction && punit
1780 && ((target_tile
1783 || (target_city
1787 || (target_unit
1790 unit_tile(target_unit)))))) {
1791 explnat->kind = ANEK_DISTANCE_FAR;
1792 explnat->distance = paction->max_distance;
1795 && punit && target_tile
1797 > unit_type_get(punit)->paratroopers_range) {
1798 explnat->kind = ANEK_DISTANCE_FAR;
1800 } else if (paction && punit
1801 && ((target_tile
1803 < paction->min_distance)
1804 || (target_city
1807 < paction->min_distance)
1808 || (target_unit
1811 < paction->min_distance))) {
1813 explnat->distance = paction->min_distance;
1814 } else if (target_city
1820 /* TODO: Check max city size requirements from action enabler target
1821 * vectors. */
1822 explnat->kind = ANEK_CITY_TOO_BIG;
1823 } else if (target_city
1829 + unit_pop_value(punit))))) {
1834 && action_custom != ATT_OK) {
1835 switch (action_custom) {
1836 case ATT_NON_ATTACK:
1837 explnat->kind = ANEK_ACTOR_UNIT;
1838 break;
1839 case ATT_UNREACHABLE:
1841 break;
1842 case ATT_NONNATIVE_SRC:
1844 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1845 break;
1846 case ATT_NONNATIVE_DST:
1848 explnat->no_act_terrain = tile_terrain(target_tile);
1849 break;
1850 case ATT_NOT_WIPABLE:
1851 explnat->kind = ANEK_NOT_WIPABLE;
1852 break;
1853 default:
1855 explnat->kind = ANEK_UNKNOWN;
1856 break;
1857 }
1861 explnat->capacity_city = tile_city(unit_tile(punit));
1865 explnat->capacity_city = game_city_by_number(target_city->id);
1871 && target_tile != NULL
1883 && action_custom != MR_OK) {
1884 switch (action_custom) {
1887 break;
1888 case MR_TRIREME:
1889 explnat->kind = ANEK_TRIREME_MOVE;
1890 break;
1893 break;
1894 default:
1896 explnat->kind = ANEK_UNKNOWN;
1897 break;
1898 }
1903 explnat->no_tgt_utype = unit_type_get(target_unit);
1904 } else if ((game.scenario.prevent_new_cities
1907 || act_id == ACTION_ANY)) {
1908 /* Please add a check for any new action forbidding scenario setting
1909 * above this comment. */
1912 && action_custom == UU_NO_MONEY) {
1913 const struct unit_type *act_utype = unit_type_get(punit);
1914
1919 } else if (paction
1920 && (blocker = action_is_blocked_by(paction, punit,
1922 target_unit))) {
1924 explnat->blocker = blocker;
1925 } else {
1926 explnat->kind = ANEK_UNKNOWN;
1927 }
1928
1929 return explnat;
1930}
1931
1932/**********************************************************************/
1936 action_id act_id,
1937 const struct tile *target_tile,
1938 const struct city *target_city,
1939 const struct unit *target_unit)
1940{
1941 struct ane_expl *explnat = expl_act_not_enabl(punit, act_id,
1944 enum ane_kind out = explnat->kind;
1945
1946 free(explnat);
1947
1948 return out;
1949}
1950
1951/**********************************************************************/
1956 const struct tile *target_tile,
1957 const struct city *target_city,
1958 const struct unit *target_unit)
1959{
1960 struct player *pplayer = unit_owner(punit);
1964 const struct civ_map *nmap = &(wld.map);
1965
1966 switch (explnat->kind) {
1967 case ANEK_ACTOR_UNIT:
1968 /* This shouldn't happen unless the client is buggy given the current
1969 * users. */
1971 "Asked to explain why a non actor can't act.");
1972
1974 _("Unit cannot do anything."));
1975 break;
1978 _("Your %s found no suitable target."),
1980 break;
1981 case ANEK_BAD_TARGET:
1982 /* This shouldn't happen at the moment. Only specific action checks
1983 * will trigger bad target checks. This is a reply to a question about
1984 * any action. */
1986
1988 _("Your %s found no suitable target."),
1990 break;
1992 {
1993 const char *types[utype_count()];
1994 int i = 0;
1995
1998 FALSE)
2000 unit_type_iterate(utype) {
2003 types[i++] = utype_name_translation(utype);
2004 }
2006 }
2007
2008 if (0 < i) {
2009 struct astring astr = ASTRING_INIT;
2010
2011 notify_player(pplayer, unit_tile(punit),
2013 /* TRANS: terrain name
2014 * "Your Diplomat cannot act from Ocean. Only
2015 * Spy or Partisan ... */
2016 _("Your %s cannot act from %s. "
2017 "Only %s can act from a non livable tile."),
2019 terrain_name_translation(explnat->no_act_terrain),
2020 astr_build_or_list(&astr, types, i));
2021
2022 astr_free(&astr);
2023 } else {
2025 /* TRANS: terrain name */
2026 _("Unit cannot act from %s."),
2027 terrain_name_translation(explnat->no_act_terrain));
2028 }
2029 }
2030 break;
2033 /* TRANS: terrain name */
2034 _("Unit cannot act against %s."),
2035 terrain_name_translation(explnat->no_act_terrain));
2036 break;
2039 _("This unit is being transported, and"
2040 " so cannot act."));
2041 break;
2044 _("This unit cannot act when it isn't being "
2045 "transported."));
2046 break;
2049 _("This unit is transporting, and"
2050 " so cannot act."));
2051 break;
2054 _("This unit cannot act when it isn't transporting."));
2055 break;
2058 _("This unit has a home city, and so cannot act."));
2059 break;
2062 _("This unit cannot act unless it has a home city."));
2063 break;
2064 case ANEK_NO_WAR:
2066 _("You must declare war on %s first. Try using "
2067 "the Nations report"
2069 " (F3)"
2070#endif /* FREECIV_WEB */
2071 "."),
2072 player_name(explnat->no_war_with));
2073 break;
2074 case ANEK_PEACE:
2076 _("You must break peace with %s first. Try using "
2077 "the Nations report to declare war"
2079 " (F3)"
2080#endif /* FREECIV_WEB */
2081 "."),
2082 player_name(explnat->peace_with));
2083 break;
2084 case ANEK_DOMESTIC:
2086 _("This unit cannot act against domestic targets."));
2087 break;
2088 case ANEK_FOREIGN:
2090 _("This unit cannot act against foreign targets."));
2091 break;
2094 /* TRANS: Riflemen */
2095 _("%s cannot act against tiles with non allied units."),
2097 break;
2098 case ANEK_NATION_ACT:
2100 /* TRANS: Swedish ... Riflemen */
2101 _("%s %s cannot act."),
2102 nation_adjective_translation(explnat->no_act_nation),
2104 break;
2105 case ANEK_NATION_TGT:
2107 /* TRANS: ... Pirate ... */
2108 _("This unit cannot act against %s targets."),
2109 nation_adjective_translation(explnat->no_act_nation));
2110 break;
2111 case ANEK_LOW_MP:
2113 _("This unit has too few moves left to act."));
2114 break;
2117 _("This unit cannot act against city centers."));
2118 break;
2121 _("This unit cannot act against non city centers."));
2122 break;
2125 _("This unit cannot act against claimed tiles."));
2126 break;
2129 _("This unit cannot act against unclaimed tiles."));
2130 break;
2131 case ANEK_DISTANCE_NEAR:
2133 _("This unit is too near its target to act."));
2134 break;
2135 case ANEK_DISTANCE_FAR:
2137 _("This unit is too far away from its target to act."));
2138 break;
2141 _("Can't perform any action this scenario permits."));
2142 break;
2145 _("Can't perform any action this close to a city."));
2146 break;
2147 case ANEK_CITY_TOO_BIG:
2149 /* TRANS: Settler ... Berlin */
2150 _("%s can't do anything to %s. It is too big."),
2153 break;
2156 /* TRANS: London ... Settlers */
2157 _("%s needs an improvement to grow, so "
2158 "%s cannot do anything to it."),
2161 break;
2164 /* TRANS: Paris ... Warriors (think: airlift) */
2165 _("%s don't have enough capacity, so "
2166 "%s cannot do anything."),
2167 city_name_get(explnat->capacity_city),
2169 break;
2172 /* TRANS: Paratroopers ... */
2173 _("%s can't do anything to an unknown target tile."),
2175 break;
2177 {
2178 char tbuf[MAX_LEN_MSG];
2179
2180 /* TRANS: Used below. Separate so treasury content too can determine
2181 * if this is plural. */
2182 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2183 "Treasury contains %d gold.",
2184 pplayer->economic.gold),
2185 pplayer->economic.gold);
2186
2188 /* TRANS: "Spy can't do anything. 154 gold may help.
2189 * Treasury contains 100 gold." */
2190 PL_("%s can't do anything. %d gold may help. %s",
2191 "%s can't do anything. %d gold may help. %s",
2192 explnat->gold_needed),
2194 explnat->gold_needed, tbuf);
2195 }
2196 break;
2197 case ANEK_TRIREME_MOVE:
2199 _("%s cannot move that far from the coast line."),
2200 unit_link(punit));
2201 break;
2202 case ANEK_DISEMBARK_ACT:
2204 _("%s cannot disembark outside of a city or a native base "
2205 "for %s."),
2209 break;
2212 _("%s can't do anything since there is an unreachable "
2213 "unit."),
2215 break;
2216 case ANEK_NOT_WIPABLE:
2218 _("%s can't do anything since there is unit with a positive "
2219 "defense value."),
2221 break;
2224 _("%s can't do anything since you already have a %s."),
2226 utype_name_translation(explnat->no_tgt_utype));
2227 break;
2228 case ANEK_ACTION_BLOCKS:
2229 /* If an action blocked another action the blocking action must be
2230 * possible. */
2232 fc__fallthrough; /* Fall through to unknown cause. */
2233 case ANEK_UNKNOWN:
2235 _("No action possible."));
2236 break;
2237 }
2238
2239 free(explnat);
2240}
2241
2242/**********************************************************************/
2251 const int actor_unit_id,
2252 const int target_unit_id_client,
2253 const int target_tile_id,
2254 const int target_extra_id_client,
2255 const int request_kind)
2256{
2257 struct player *actor_player;
2258 struct unit *actor_unit;
2259 struct tile *target_tile;
2261 struct unit *target_unit;
2262 struct city *target_city;
2263 struct extra_type *target_extra;
2265 const struct player_tile *plrtile;
2267 const struct civ_map *nmap = &(wld.map);
2268
2269 /* No potentially legal action is known yet. If none is found the player
2270 * should get an explanation. */
2272
2273 /* A target should only be sent if it is possible to act against it */
2274 int target_city_id = IDENTITY_NUMBER_ZERO;
2275 int target_unit_id = IDENTITY_NUMBER_ZERO;
2276
2277 actor_player = pc->playing;
2279 target_tile = index_to_tile(nmap, target_tile_id);
2280
2281 /* Initialize the action probabilities. */
2282 action_iterate(act) {
2285
2286 /* Check if the request is valid. */
2288 || actor_unit->owner != actor_player) {
2291 target_tile_id, target_extra_id,
2292 request_kind,
2294 return;
2295 }
2296
2297 /* Select the targets. */
2298
2300 /* Find a new target unit. */
2302 } else {
2303 /* Prepare the client selected target unit. */
2305 }
2306
2307 /* Find the target city. */
2309
2310 /* The specified target unit must be located at the target tile. */
2314 _("Target not at target tile."));
2317 target_tile_id, target_extra_id,
2318 request_kind,
2320 return;
2321 }
2322
2324 /* See if a target extra can be found. */
2326 } else {
2327 /* Use the client selected target extra. */
2329 }
2330
2331 /* The player may have outdated information about the target tile.
2332 * Limiting the player knowledge look up to the target tile is OK since
2333 * all targets must be located at it. */
2335
2336 /* Distance between actor and target tile. */
2338 target_tile);
2339
2340 /* Find out what can be done to the targets. */
2341
2342 /* Set the probability for the actions. */
2344 if (action_id_get_actor_kind(act) != AAK_UNIT) {
2345 /* Not relevant. */
2346 continue;
2347 }
2348
2349 switch (action_id_get_target_kind(act)) {
2350 case ATK_CITY:
2351 if (plrtile && plrtile->site) {
2352 /* Only a known city may be targeted. */
2353 if (target_city) {
2354 /* Calculate the probabilities. */
2356 target_city);
2361 /* The target city is non existing. The player isn't aware of this
2362 * fact because they can't see the tile it was located on. The
2363 * actor unit it self doesn't contradict the requirements to
2364 * perform the action. The (no longer existing) target city was
2365 * known to be close enough. */
2367 } else {
2368 /* The actor unit is known to be unable to act or the target city
2369 * is known to be too far away. */
2371 }
2372 } else {
2373 /* No target to act against. */
2375 }
2376 break;
2377 case ATK_UNIT:
2378 if (target_unit) {
2379 /* Calculate the probabilities. */
2381 target_unit);
2382 } else {
2383 /* No target to act against. */
2385 }
2386 break;
2387 case ATK_UNITS:
2388 if (target_tile) {
2389 /* Calculate the probabilities. */
2391 target_tile);
2392 } else {
2393 /* No target to act against. */
2395 }
2396 break;
2397 case ATK_TILE:
2398 if (target_tile) {
2399 /* Calculate the probabilities. */
2402 } else {
2403 /* No target to act against. */
2405 }
2406 break;
2407 case ATK_EXTRAS:
2408 if (target_tile) {
2409 /* Calculate the probabilities. */
2412 target_extra);
2413 } else {
2414 /* No target to act against. */
2416 }
2417 break;
2418 case ATK_SELF:
2419 if (actor_target_distance == 0) {
2420 /* Calculate the probabilities. */
2422 } else {
2423 /* Don't bother with self targeted actions unless the actor is
2424 * asking about what can be done to its own tile. */
2426 }
2427 break;
2428 case ATK_COUNT:
2431 break;
2432 }
2434
2435 /* Analyze the probabilities. Decide what targets to send and if an
2436 * explanation is needed. */
2439 /* An action can be done. No need to explain why no action can be
2440 * done. */
2442
2443 switch (action_id_get_target_kind(act)) {
2444 case ATK_CITY:
2445 /* The city should be sent as a target since it is possible to act
2446 * against it. */
2447
2448 /* All city targeted actions requires that the player is aware of
2449 * the target city. It is therefore in the player's map. */
2450 fc_assert_action(plrtile, continue);
2451 fc_assert_action(plrtile->site, continue);
2452
2453 target_city_id = plrtile->site->identity;
2454 break;
2455 case ATK_UNIT:
2456 /* The unit should be sent as a target since it is possible to act
2457 * against it. */
2459 target_unit_id = target_unit->id;
2460 break;
2461 case ATK_TILE:
2462 case ATK_EXTRAS:
2463 /* The target tile isn't selected here so it hasn't changed. */
2465
2467 /* The target extra may have been set here. */
2469 }
2470 break;
2471 case ATK_UNITS:
2472 /* The target tile isn't selected here so it hasn't changed. */
2474 break;
2475 case ATK_SELF:
2476 /* The target unit is the actor unit. It is already sent. */
2478 break;
2479 case ATK_COUNT:
2481 "Invalid action target kind.");
2482 break;
2483 }
2484
2485 if (target_city_id != IDENTITY_NUMBER_ZERO
2486 && target_unit_id != IDENTITY_NUMBER_ZERO) {
2487 /* No need to find out more. */
2488 break;
2489 }
2490 }
2492
2493 /* Send possible actions and targets. */
2495 actor_unit_id, target_unit_id, target_city_id,
2496 target_tile_id, target_extra_id,
2497 request_kind,
2499
2500 if (request_kind == REQEST_PLAYER_INITIATED && !at_least_one_action) {
2501 /* The user should get an explanation why no action is possible. */
2504 }
2505}
2506
2507/**********************************************************************/
2514void illegal_action_msg(struct player *pplayer,
2515 const enum event_type event,
2516 struct unit *actor,
2518 const struct tile *target_tile,
2519 const struct city *target_city,
2520 const struct unit *target_unit)
2521{
2522 struct ane_expl *explnat;
2523 const struct civ_map *nmap = &(wld.map);
2524
2525 /* Explain why the action was illegal. */
2528 switch (explnat->kind) {
2529 case ANEK_ACTOR_UNIT:
2530 {
2531 struct astring astr = ASTRING_INIT;
2532
2535 TRUE)) {
2536 notify_player(pplayer, unit_tile(actor),
2538 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
2539 _("Only %s can do %s."),
2540 astr_str(&astr),
2542 astr_free(&astr);
2543 } else {
2544 notify_player(pplayer, unit_tile(actor),
2546 /* TRANS: Spy can't do Capture Units. */
2547 _("%s can't do %s."),
2550 }
2551 }
2552 break;
2555 /* TRANS: "Your Spy found ... suitable for
2556 * Bribe Enemy Unit." */
2557 _("Your %s found no target suitable for %s."),
2560 break;
2561 case ANEK_BAD_TARGET:
2563 /* TRANS: "Having your Spy do Bribe Enemy Unit to
2564 * this target ..." */
2565 _("Having your %s do %s to this target is redundant."),
2568 break;
2570 {
2571 const char *types[utype_count()];
2572 int i = 0;
2573
2576 FALSE)
2578 unit_type_iterate(utype) {
2581 types[i++] = utype_name_translation(utype);
2582 }
2584 }
2585
2586 if (0 < i) {
2587 struct astring astr = ASTRING_INIT;
2588
2589 notify_player(pplayer, unit_tile(actor),
2591 /* TRANS: action name.
2592 * "Your Spy can't do Steal Gold from Ocean.
2593 * Only Explorer or Partisan can do Steal Gold ..." */
2594 _("Your %s can't do %s from %s. "
2595 "Only %s can do %s from a non livable tile."),
2598 terrain_name_translation(explnat->no_act_terrain),
2599 astr_build_or_list(&astr, types, i),
2601
2602 astr_free(&astr);
2603 } else {
2604 notify_player(pplayer, unit_tile(actor),
2606 /* TRANS: action name.
2607 * "Your Spy can't do Steal Gold from Ocean." */
2608 _("Your %s can't do %s from %s."),
2611 terrain_name_translation(explnat->no_act_terrain));
2612 }
2613 }
2614 break;
2616 notify_player(pplayer, unit_tile(actor),
2618 /* TRANS: action name.
2619 * "Your Spy can't do Industrial Sabotage to Mountains." */
2620 _("Your %s can't do %s to %s."),
2623 terrain_name_translation(explnat->no_act_terrain));
2624 break;
2626 notify_player(pplayer, unit_tile(actor),
2628 /* TRANS: action name.
2629 * "Your Spy can't do Industrial Sabotage while ..." */
2630 _("Your %s can't do %s while being transported."),
2633 break;
2635 notify_player(pplayer, unit_tile(actor),
2637 /* TRANS: action name.
2638 * "Your Spy can't do Industrial Sabotage while ..." */
2639 _("Your %s can't do %s while not being transported."),
2642 break;
2644 notify_player(pplayer, unit_tile(actor),
2646 /* TRANS: action name.
2647 * "Your Spy can't do Industrial Sabotage while ..." */
2648 _("Your %s can't do %s while transporting."),
2651 break;
2653 notify_player(pplayer, unit_tile(actor),
2655 /* TRANS: action name.
2656 * "Your Spy can't do Industrial Sabotage while ..." */
2657 _("Your %s can't do %s while not transporting."),
2660 break;
2662 notify_player(pplayer, unit_tile(actor),
2664 /* TRANS: action name.
2665 * "Your Spy can't do Industrial Sabotage because ..." */
2666 _("Your %s can't do %s because it has a home city."),
2669 break;
2671 notify_player(pplayer, unit_tile(actor),
2673 /* TRANS: action name.
2674 * "Your Spy can't do Industrial Sabotage because ..." */
2675 _("Your %s can't do %s because it is homeless."),
2678 break;
2679 case ANEK_NO_WAR:
2680 notify_player(pplayer, unit_tile(actor),
2682 /* TRANS: action name.
2683 * "Your Spy can't do Industrial Sabotage while you
2684 * aren't at war with Prester John." */
2685 _("Your %s can't do %s while you"
2686 " aren't at war with %s."),
2689 player_name(explnat->no_war_with));
2690 break;
2691 case ANEK_PEACE:
2692 notify_player(pplayer, unit_tile(actor),
2694 /* TRANS: action name.
2695 * "Your Spy can't do Industrial Sabotage while you
2696 * are at peace with Prester John. Try using the
2697 * Nations report (F3)." */
2698 _("Your %s can't do %s while you "
2699 "are at peace with %s. Try using "
2700 "the Nations report to declare war"
2702 " (F3)"
2703#endif /* FREECIV_WEB */
2704 "."),
2707 player_name(explnat->peace_with));
2708 break;
2709 case ANEK_DOMESTIC:
2710 notify_player(pplayer, unit_tile(actor),
2712 /* TRANS: action name.
2713 * "Your Riflemen can't do Expel Unit to domestic
2714 * unit stacks." */
2715 _("Your %s can't do %s to domestic %s."),
2720 break;
2721 case ANEK_FOREIGN:
2722 notify_player(pplayer, unit_tile(actor),
2724 /* TRANS: action name.
2725 * "Your Leader can't do Use Court Physician to foreign
2726 * unit stacks." */
2727 _("Your %s can't do %s to foreign %s."),
2732 break;
2734 notify_player(pplayer, unit_tile(actor),
2736 /* TRANS: Paratroopers ... Drop Paratrooper */
2737 _("Your %s can't do %s to tiles with non allied units."),
2740 break;
2741 case ANEK_NATION_ACT:
2742 notify_player(pplayer, unit_tile(actor),
2744 /* TRANS: action name.
2745 * "Swedish Riflemen can't do Expel Unit." */
2746 _("%s %s can't do %s."),
2747 nation_adjective_translation(explnat->no_act_nation),
2750 break;
2751 case ANEK_NATION_TGT:
2752 notify_player(pplayer, unit_tile(actor),
2754 /* TRANS: action name.
2755 * "Riflemen... Expel Unit... Pirate Migrants." */
2756 _("Your %s can't do %s to %s %s."),
2759 nation_adjective_translation(explnat->no_act_nation),
2762 break;
2763 case ANEK_LOW_MP:
2764 notify_player(pplayer, unit_tile(actor),
2766 /* TRANS: action name.
2767 * "Your Spy has ... to do Bribe Enemy Unit." */
2768 _("Your %s has too few moves left to do %s."),
2771 break;
2773 notify_player(pplayer, unit_tile(actor),
2775 /* TRANS: action name.
2776 * "Your Spy can't do Bribe Enemy Unit to city centers." */
2777 _("Your %s can't do %s to city centers."),
2780 break;
2782 notify_player(pplayer, unit_tile(actor),
2784 /* TRANS: action name.
2785 * "Your Spy can only do Investigate City to
2786 * city centers." */
2787 _("Your %s can only do %s to city centers."),
2790 break;
2792 notify_player(pplayer, unit_tile(actor),
2794 /* TRANS: action name.
2795 * "Your Settlers can't do Build City to claimed tiles." */
2796 _("Your %s can't do %s to claimed tiles."),
2799 break;
2801 notify_player(pplayer, unit_tile(actor),
2803 /* TRANS: action name.
2804 * "Your Spy can't do Bribe Enemy Unit to
2805 * unclaimed tiles." */
2806 _("Your %s can't do %s to unclaimed tiles."),
2809 break;
2810 case ANEK_DISTANCE_NEAR:
2811 notify_player(pplayer, unit_tile(actor),
2813 /* TRANS: action name.
2814 * "Your Spy must be at least 2 tiles away to do
2815 * Incite a Revolt and Escape." */
2816 PL_("Your %s must be at least %d tile away to do %s.",
2817 "Your %s must be at least %d tiles away to do %s.",
2818 explnat->distance),
2820 explnat->distance,
2822 break;
2823 case ANEK_DISTANCE_FAR:
2824 notify_player(pplayer, unit_tile(actor),
2826 /* TRANS: action name.
2827 * "Your Diplomat can't be more than 1 tile away to do
2828 * Establish Embassy." */
2829 PL_("Your %s can't be more than %d tile away to do %s.",
2830 "Your %s can't be more than %d tiles away to do %s.",
2831 explnat->distance),
2833 explnat->distance,
2835 break;
2837 notify_player(pplayer, unit_tile(actor),
2839 /* TRANS: Can't do Build City in this scenario. */
2840 _("Can't do %s in this scenario."),
2842 break;
2844 notify_player(pplayer, unit_tile(actor),
2846 /* TRANS: Can't do Build City this close to a city. */
2847 _("Can't do %s this close to a city."),
2849 break;
2850 case ANEK_CITY_TOO_BIG:
2851 notify_player(pplayer, unit_tile(actor),
2853 /* TRANS: Settlers ... Join City ... London */
2854 _("%s can't do %s to %s. It is too big."),
2858 break;
2860 notify_player(pplayer, unit_tile(actor),
2862 /* TRANS: London ... Settlers ... Join City */
2863 _("%s needs an improvement to grow, so "
2864 "%s cannot do %s."),
2868 break;
2870 notify_player(pplayer, unit_tile(actor),
2872 /* TRANS: Paris ... Airlift to City ... Warriors */
2873 _("%s has no capacity to %s %s."),
2874 city_name_get(explnat->capacity_city),
2877 break;
2879 notify_player(pplayer, unit_tile(actor),
2881 /* TRANS: Paratroopers ... Drop Paratrooper */
2882 _("%s can't do %s to an unknown tile."),
2885 break;
2887 {
2888 char tbuf[MAX_LEN_MSG];
2889
2890 /* TRANS: Used below. Separate so treasury content too can determine
2891 * if this is plural. */
2892 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2893 "Treasury contains %d gold.",
2894 pplayer->economic.gold),
2895 pplayer->economic.gold);
2896
2897 notify_player(pplayer, unit_tile(actor),
2899 /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2900 * Treasury contains 100 gold." */
2901 PL_("%s can't do %s for %d gold. %s",
2902 "%s can't do %s for %d gold. %s",
2903 explnat->gold_needed),
2906 explnat->gold_needed, tbuf);
2907 }
2908 break;
2909 case ANEK_TRIREME_MOVE:
2911 /* TRANS: "Trireme cannot move ..." */
2912 _("%s cannot move that far from the coast line."),
2913 unit_link(actor));
2914 break;
2915 case ANEK_DISEMBARK_ACT:
2917 /* TRANS: "Riflemen cannot disembark ... native base
2918 * for Helicopter." */
2919 _("%s cannot disembark outside of a city or a native base "
2920 "for %s."),
2924 break;
2926 notify_player(pplayer, target_tile,
2928 /* TRANS: "Your Spy can't do Bribe Enemy Unit there ..." */
2929 _("Your %s can't do %s there since there's an "
2930 "unreachable unit."),
2933 break;
2934 case ANEK_NOT_WIPABLE:
2935 notify_player(pplayer, target_tile,
2937 /* TRANS: "Your Legion can't do Wipe Units there ..." */
2938 _("Your %s can't do %s there since there's an "
2939 "unit with positive defense value."),
2942 break;
2945 /* TRANS: "You already have a Leader." */
2946 _("You already have a %s."),
2947 utype_name_translation(explnat->no_tgt_utype));
2948 break;
2949 case ANEK_ACTION_BLOCKS:
2950 {
2952
2953 notify_player(pplayer, unit_tile(actor),
2955 /* TRANS: Freight ... Disband Unit Recover ... Help Wonder ... */
2956 _("Your %s can't do %s when %s is legal."),
2959 action_id_name_translation(explnat->blocker->id));
2961 }
2962 break;
2963 case ANEK_UNKNOWN:
2964 notify_player(pplayer, unit_tile(actor),
2966 /* TRANS: action name.
2967 * "Your Spy was unable to do Bribe Enemy Unit." */
2968 _("Your %s was unable to do %s."),
2971 break;
2972 }
2973
2974 free(explnat);
2975}
2976
2977/**********************************************************************/
2990static bool illegal_action_pay_price(struct player *pplayer,
2992 struct unit *act_unit,
2993 struct action *stopped_action,
2994 struct player *tgt_player,
2995 struct tile *tgt_tile,
2996 const enum action_requester requester)
2997{
2998 int punishment_mp;
2999 int punishment_hp;
3000
3001 const struct req_context actor_ctxt = {
3003 .unit = act_unit,
3004 .unittype = unit_type_get(act_unit),
3005 .action = stopped_action,
3006 };
3007 const struct req_context tgt_ctxt = {
3008 .player = tgt_player,
3009 };
3010
3011 /* Don't punish the player for something the game did. Don't tell the
3012 * player that the rules required the game to try to do something
3013 * illegal. */
3016 FALSE,
3017 "The player wasn't responsible for this.");
3018
3019 if (!information_revealed) {
3020 /* The player already had enough information to determine that this
3021 * action is illegal. Don't punish a client error or an accident. */
3022 return FALSE;
3023 }
3024
3025 /* The mistake may have a cost. */
3026
3027 /* HP cost */
3030
3031 /* Stay in range */
3033
3034 /* Punish the unit's hit points. */
3035 act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
3036
3037 if (punishment_hp != 0) {
3040 /* The consolation prize is some information about the potentially
3041 * distant target tile and maybe some contacts. */
3042 map_show_circle(pplayer, tgt_tile,
3043 unit_type_get(act_unit)->vision_radius_sq);
3045 }
3046
3047 if (act_unit->hp > 0) {
3048 /* The actor unit survived */
3049
3050 /* The player probably wants to be disturbed if their unit was punished
3051 * with the loss of hit points. */
3054 /* TRANS: Spy ... 5 ... Drop Paratrooper */
3055 _("Your %s lost %d hit points while attempting to"
3056 " do %s."),
3060 } else {
3061 /* The unit didn't survive */
3062
3063 /* The player probably wants to be disturbed if their unit was punished
3064 * with death. */
3067 /* TRANS: Spy ... Drop Paratrooper */
3068 _("Your %s was killed while attempting to do %s."),
3071
3073 act_unit = NULL;
3074
3075 return TRUE;
3076 }
3077 }
3078
3079 /* MP cost */
3082
3083 /* Stay in range */
3085
3086 /* Punish the unit's move fragments. */
3087 act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
3089
3090 if (punishment_mp != 0) {
3091 /* The player probably wants to be disturbed if their unit was punished
3092 * with the loss of movement points. */
3095 /* TRANS: Spy ... movement point text that may include
3096 * fractions. */
3097 _("Your %s lost %s MP for attempting an illegal action."),
3100 }
3101
3102 return punishment_mp != 0 || punishment_hp != 0;
3103}
3104
3105/**********************************************************************/
3110static void illegal_action(struct player *pplayer,
3111 struct unit *actor,
3113 struct player *tgt_player,
3114 struct tile *target_tile,
3115 const struct city *target_city,
3116 const struct unit *target_unit,
3117 int request_kind,
3118 const enum action_requester requester)
3119{
3121 bool was_punished;
3122
3124
3125 /* Why didn't the game check before trying something illegal? Did a good
3126 * reason to not call is_action_enabled_unit_on...() appear? The game is
3127 * omniscient... */
3129
3130
3133 actor,
3135 target_tile, NULL));
3136
3137 if (request_kind == REQEST_PLAYER_INITIATED) {
3138 /* This is a foreground request. */
3143 }
3144
3148 requester);
3149
3150 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3151 /* FIXME: Temporary work around to prevent wrong information and/or
3152 * crashes. See hrm Bug #879880 */
3153 /* TODO: Get the explanation before the punishment and show it here.
3154 * See hrm Bug #879881 */
3155 notify_player(pplayer, unit_tile(actor),
3158 _("No explanation why you couldn't do %s. This is a bug."
3159 " Sorry about that. -- Sveinung"),
3161 }
3162}
3163
3164/**********************************************************************/
3168 const int actor_id,
3169 const int target_id,
3170 int request_kind)
3171{
3173 actor_id, target_id,
3174 0,
3176 request_kind);
3177}
3178
3179/**********************************************************************/
3187 const int actor_id,
3188 const int target_id,
3189 const action_id action_type,
3190 int request_kind)
3191{
3192 struct player *pplayer = pc->playing;
3193 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3194 struct action *paction = action_by_number(action_type);
3195 struct unit *punit = game_unit_by_number(target_id);
3196 struct city *pcity = game_city_by_number(target_id);
3197 const struct civ_map *nmap = &(wld.map);
3198
3199 if (NULL == paction) {
3200 /* Non existing action */
3201 log_error("handle_unit_action_query() the action %d doesn't exist.",
3202 action_type);
3203
3204 unit_query_impossible(pc, actor_id, target_id, request_kind);
3205 return;
3206 }
3207
3208 if (NULL == pactor) {
3209 /* Probably died or bribed. */
3210 log_verbose("handle_unit_action_query() invalid actor %d",
3211 actor_id);
3212 unit_query_impossible(pc, actor_id, target_id, request_kind);
3213 return;
3214 }
3215
3216 switch (paction->result) {
3218 if (punit
3219 && is_action_enabled_unit_on_unit(nmap, action_type,
3220 pactor, punit)) {
3222 actor_id, target_id,
3223 unit_bribe_cost(punit, pplayer,
3224 pactor),
3225 action_type, request_kind);
3226 } else {
3227 illegal_action(pplayer, pactor, action_type,
3229 NULL, NULL, punit, request_kind, ACT_REQ_PLAYER);
3230 unit_query_impossible(pc, actor_id, target_id, request_kind);
3231 return;
3232 }
3233 break;
3235 if (pcity
3236 && is_action_enabled_unit_on_city(nmap, action_type,
3237 pactor, pcity)) {
3239 actor_id, target_id,
3240 city_incite_cost(pplayer, pcity),
3241 action_type, request_kind);
3242 } else {
3243 illegal_action(pplayer, pactor, action_type,
3244 pcity ? city_owner(pcity) : NULL,
3245 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3246 unit_query_impossible(pc, actor_id, target_id, request_kind);
3247 return;
3248 }
3249 break;
3251 if (pcity
3252 && is_action_enabled_unit_on_city(nmap, action_type,
3253 pactor, pcity)) {
3254 const struct unit_type *tgt_utype;
3255 int upgr_cost;
3256
3258 /* Already checked via is_action_enabled_unit_on_city() */
3260 upgr_cost = unit_upgrade_price(pplayer,
3262
3264 actor_id, target_id,
3265 upgr_cost, action_type,
3266 request_kind);
3267 } else {
3268 illegal_action(pplayer, pactor, action_type,
3269 pcity ? city_owner(pcity) : NULL,
3270 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3271 unit_query_impossible(pc, actor_id, target_id, request_kind);
3272 return;
3273 }
3274 break;
3277 if (pcity
3278 && is_action_enabled_unit_on_city(nmap, action_type,
3279 pactor, pcity)) {
3281 action_by_number(action_type), request_kind);
3282 } else {
3283 illegal_action(pplayer, pactor, action_type,
3284 pcity ? city_owner(pcity) : NULL,
3285 NULL, pcity, NULL, request_kind, ACT_REQ_PLAYER);
3286 unit_query_impossible(pc, actor_id, target_id, request_kind);
3287 return;
3288 }
3289 break;
3290 default:
3291 unit_query_impossible(pc, actor_id, target_id, request_kind);
3292 return;
3293 };
3294}
3295
3296/**********************************************************************/
3301void handle_unit_do_action(struct player *pplayer,
3302 const int actor_id,
3303 const int target_id,
3304 const int sub_tgt_id,
3305 const char *name,
3306 const action_id action_type)
3307{
3308 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3309 action_type, ACT_REQ_PLAYER);
3310}
3311
3312/**********************************************************************/
3317void unit_do_action(struct player *pplayer,
3318 const int actor_id,
3319 const int target_id,
3320 const int sub_tgt_id,
3321 const char *name,
3322 const action_id action_type)
3323{
3324 unit_perform_action(pplayer, actor_id, target_id,
3325 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3326}
3327
3328/**********************************************************************/
3337bool unit_perform_action(struct player *pplayer,
3338 const int actor_id,
3339 const int target_id,
3340 const int sub_tgt_id_incoming,
3341 const char *name,
3342 const action_id action_type,
3343 const enum action_requester requester)
3344{
3345 struct action *paction;
3346 int sub_tgt_id;
3347 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3348 struct tile *target_tile = NULL;
3349 struct extra_type *target_extra;
3350 struct impr_type *sub_tgt_impr;
3351 struct unit *punit = NULL;
3352 struct city *pcity = NULL;
3353 const struct civ_map *nmap = &(wld.map);
3354
3355 if (!action_id_exists(action_type)) {
3356 /* Non existing action */
3357 log_error("unit_perform_action() the action %d doesn't exist.",
3358 action_type);
3359
3360 return FALSE;
3361 }
3362
3363 paction = action_by_number(action_type);
3364
3365 if (NULL == actor_unit) {
3366 /* Probably died or bribed. */
3367 log_verbose("unit_perform_action() invalid actor %d",
3368 actor_id);
3369 return FALSE;
3370 }
3371
3373 case ATK_CITY:
3374 pcity = game_city_by_number(target_id);
3375 if (pcity == NULL) {
3376 log_verbose("unit_perform_action() invalid target city %d",
3377 target_id);
3378 return FALSE;
3379 }
3380 target_tile = city_tile(pcity);
3382 break;
3383 case ATK_UNIT:
3384 punit = game_unit_by_number(target_id);
3385 if (punit == NULL) {
3386 log_verbose("unit_perform_action() invalid target unit %d",
3387 target_id);
3388 return FALSE;
3389 }
3392 pcity = tile_city(target_tile);
3393 break;
3394 case ATK_UNITS:
3395 case ATK_TILE:
3396 case ATK_EXTRAS:
3397 target_tile = index_to_tile(nmap, target_id);
3398 if (target_tile == NULL) {
3399 log_verbose("unit_perform_action() invalid target tile %d",
3400 target_id);
3401 return FALSE;
3402 }
3403 pcity = tile_city(target_tile);
3404 break;
3405 case ATK_SELF:
3408 pcity = tile_city(target_tile);
3409 break;
3410 case ATK_COUNT:
3412 break;
3413 }
3414
3415 /* Server side sub target assignment */
3416 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3419 } else {
3420 sub_tgt_id = sub_tgt_id_incoming;
3421 }
3422
3423 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3424 && sub_tgt_id != NO_TARGET) {
3425 target_extra = extra_by_number(sub_tgt_id);
3426 fc_assert(!(target_extra->ruledit_disabled));
3427 } else {
3429 }
3430
3431 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3432
3433 /* Sub targets should now be assigned */
3434 switch (paction->sub_target_kind) {
3435 case ASTK_NONE:
3436 /* No sub target. */
3437 break;
3438 case ASTK_BUILDING:
3439 if (sub_tgt_impr == NULL) {
3440 /* Missing sub target */
3441 return FALSE;
3442 }
3443 break;
3444 case ASTK_TECH:
3445 /* Not handled here yet */
3446 break;
3447 case ASTK_EXTRA:
3449 if (target_extra == NULL) {
3450 /* Missing sub target */
3451 return FALSE;
3452 }
3453 break;
3454 case ASTK_COUNT:
3455 break;
3456 }
3457
3461 && target_extra == NULL) {
3462 /* Missing required action extra target. */
3463 log_verbose("unit_perform_action() action %d requires action "
3464 "but extra id %d is invalid.",
3465 action_type, sub_tgt_id);
3466 return FALSE;
3467 }
3468
3469 if (paction->actor.is_unit.unitwaittime_controlled
3471 /* Action not possible due to unitwaittime setting. */
3472 return FALSE;
3473 }
3474
3475#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3476 if (pcity \
3477 && is_action_enabled_unit_on_city(nmap, action_type, \
3478 actor_unit, pcity)) { \
3479 bool success; \
3480 script_server_signal_emit("action_started_unit_city", \
3481 action_by_number(action), actor, target); \
3482 if (!actor || !unit_is_alive(actor_id)) { \
3483 /* Actor unit was destroyed during pre action Lua. */ \
3484 return FALSE; \
3485 } \
3486 if (!target || !city_exist(target_id)) { \
3487 /* Target city was destroyed during pre action Lua. */ \
3488 return FALSE; \
3489 } \
3490 success = action_performer; \
3491 if (success) { \
3492 action_success_actor_price(paction, actor_id, actor); \
3493 } \
3494 script_server_signal_emit("action_finished_unit_city", \
3495 action_by_number(action), success, \
3496 unit_is_alive(actor_id) ? actor : NULL, \
3497 city_exist(target_id) ? target : NULL); \
3498 return success; \
3499 } else { \
3500 illegal_action(pplayer, actor_unit, action_type, \
3501 pcity ? city_owner(pcity) : NULL, NULL, pcity, NULL, \
3502 TRUE, requester); \
3503 }
3504
3505#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3506 if (actor_unit \
3507 && is_action_enabled_unit_on_self(nmap, action_type, actor_unit)) { \
3508 bool success; \
3509 script_server_signal_emit("action_started_unit_self", \
3510 action_by_number(action), actor); \
3511 if (!actor || !unit_is_alive(actor_id)) { \
3512 /* Actor unit was destroyed during pre action Lua. */ \
3513 return FALSE; \
3514 } \
3515 success = action_performer; \
3516 if (success) { \
3517 action_success_actor_price(paction, actor_id, actor); \
3518 } \
3519 script_server_signal_emit("action_finished_unit_self", \
3520 action_by_number(action), success, \
3521 unit_is_alive(actor_id) ? actor : NULL); \
3522 return success; \
3523 } else { \
3524 illegal_action(pplayer, actor_unit, action_type, \
3525 unit_owner(actor_unit), NULL, NULL, actor_unit, \
3526 TRUE, requester); \
3527 }
3528
3529#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3530 if (punit \
3531 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3532 bool success; \
3533 script_server_signal_emit("action_started_unit_unit", \
3534 action_by_number(action), actor, target); \
3535 if (!actor || !unit_is_alive(actor_id)) { \
3536 /* Actor unit was destroyed during pre action Lua. */ \
3537 return FALSE; \
3538 } \
3539 if (!target || !unit_is_alive(target_id)) { \
3540 /* Target unit was destroyed during pre action Lua. */ \
3541 return FALSE; \
3542 } \
3543 success = action_performer; \
3544 if (success) { \
3545 action_success_actor_price(paction, actor_id, actor); \
3546 action_success_target_pay_mp(paction, target_id, punit); \
3547 } \
3548 script_server_signal_emit("action_finished_unit_unit", \
3549 action_by_number(action), success, \
3550 unit_is_alive(actor_id) ? actor : NULL, \
3551 unit_is_alive(target_id) ? target : NULL); \
3552 return success; \
3553 } else { \
3554 illegal_action(pplayer, actor_unit, action_type, \
3555 punit ? unit_owner(punit) : NULL, NULL, NULL, punit, \
3556 TRUE, requester); \
3557 }
3558
3559#define ACTION_PERFORM_UNIT_UNITS(action, actor, target, action_performer)\
3560 if (target_tile \
3561 && is_action_enabled_unit_on_stack(nmap, action_type, \
3562 actor_unit, target_tile)) { \
3563 bool success; \
3564 script_server_signal_emit("action_started_unit_units", \
3565 action_by_number(action), actor, target); \
3566 if (!actor || !unit_is_alive(actor_id)) { \
3567 /* Actor unit was destroyed during pre action Lua. */ \
3568 return FALSE; \
3569 } \
3570 success = action_performer; \
3571 if (success) { \
3572 action_success_actor_price(paction, actor_id, actor); \
3573 } \
3574 script_server_signal_emit("action_finished_unit_units", \
3575 action_by_number(action), success, \
3576 unit_is_alive(actor_id) ? actor : NULL, \
3577 target); \
3578 return success; \
3579 } else { \
3580 illegal_action(pplayer, actor_unit, action_type, \
3581 NULL, target_tile, NULL, NULL, \
3582 TRUE, requester); \
3583 }
3584
3585#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3586 if (target_tile \
3587 && is_action_enabled_unit_on_tile(nmap, action_type, \
3588 actor_unit, target_tile, \
3589 target_extra)) { \
3590 bool success; \
3591 script_server_signal_emit("action_started_unit_tile", \
3592 action_by_number(action), actor, target); \
3593 if (!actor || !unit_is_alive(actor_id)) { \
3594 /* Actor unit was destroyed during pre action Lua. */ \
3595 return FALSE; \
3596 } \
3597 success = action_performer; \
3598 if (success) { \
3599 action_success_actor_price(paction, actor_id, actor); \
3600 } \
3601 script_server_signal_emit("action_finished_unit_tile", \
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 target_tile ? tile_owner(target_tile) : NULL, \
3609 target_tile, NULL, NULL, \
3610 TRUE, requester); \
3611 }
3612
3613#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3614 if (target_tile \
3615 && is_action_enabled_unit_on_extras(nmap, action_type, \
3616 actor_unit, target_tile, \
3617 target_extra)) { \
3618 bool success; \
3619 script_server_signal_emit("action_started_unit_extras", \
3620 action_by_number(action), actor, target); \
3621 if (!actor || !unit_is_alive(actor_id)) { \
3622 /* Actor unit was destroyed during pre action Lua. */ \
3623 return FALSE; \
3624 } \
3625 success = action_performer; \
3626 if (success) { \
3627 action_success_actor_price(paction, actor_id, actor); \
3628 } \
3629 script_server_signal_emit("action_finished_unit_extras", \
3630 action_by_number(action), success, \
3631 unit_is_alive(actor_id) ? actor : NULL, \
3632 target); \
3633 return success; \
3634 } else { \
3635 illegal_action(pplayer, actor_unit, action_type, \
3636 target_tile ? target_tile->extras_owner : NULL, \
3637 target_tile, NULL, NULL, \
3638 TRUE, requester); \
3639 }
3640
3641#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3642 target_city, target_unit, target_tile, \
3643 action_performer) \
3644 switch (action_get_target_kind(paction)) { \
3645 case ATK_CITY: \
3646 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3647 action_performer); \
3648 break; \
3649 case ATK_UNIT: \
3650 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3651 action_performer); \
3652 break; \
3653 case ATK_UNITS: \
3654 ACTION_PERFORM_UNIT_UNITS(paction->id, actor, target_tile, \
3655 action_performer); \
3656 break; \
3657 case ATK_TILE: \
3658 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3659 action_performer); \
3660 break; \
3661 case ATK_EXTRAS: \
3662 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3663 action_performer); \
3664 break; \
3665 case ATK_SELF: \
3666 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3667 break; \
3668 case ATK_COUNT: \
3669 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3670 break; \
3671 }
3672
3673 switch (paction->result) {
3677 paction));
3678 break;
3680 /* Difference is caused by data in the action structure. */
3683 punit, paction));
3684 break;
3685 case ACTRES_EXPEL_UNIT:
3687 do_expel_unit(pplayer, actor_unit, punit,
3688 paction));
3689 break;
3690 case ACTRES_HEAL_UNIT:
3692 do_heal_unit(pplayer, actor_unit, punit,
3693 paction));
3694 break;
3698 paction));
3699 break;
3703 paction));
3704 break;
3707 do_unit_board(pplayer, actor_unit, punit,
3708 paction));
3709 break;
3712 do_unit_load(pplayer, actor_unit, punit,
3713 paction));
3714 break;
3718 paction));
3719 break;
3721 /* All consequences are handled by the action system. */
3723 break;
3724 case ACTRES_FORTIFY:
3727 break;
3728 case ACTRES_CONVERT:
3731 break;
3732 case ACTRES_HOMELESS:
3735 break;
3736 case ACTRES_SPY_ESCAPE:
3737 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3738 spy_escape(pplayer, actor_unit,
3739 pcity, target_tile, paction));
3740 break;
3742 /* Difference is caused by data in the action structure. */
3743 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3744 diplomat_sabotage(pplayer, actor_unit, pcity,
3745 B_LAST, paction));
3746 break;
3748 /* Difference is caused by data in the action structure. */
3749 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3750 diplomat_sabotage(pplayer, actor_unit, pcity,
3751 sub_tgt_impr->item_number,
3752 paction));
3753 break;
3755 /* Difference is caused by data in the action structure. */
3756 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3757 diplomat_sabotage(pplayer, actor_unit, pcity,
3758 -1, paction));
3759 break;
3760 case ACTRES_SPY_POISON:
3761 /* Difference is caused by data in the action structure. */
3762 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3763 spy_poison(pplayer, actor_unit, pcity,
3764 paction));
3765 break;
3767 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3768 spy_spread_plague(pplayer, actor_unit, pcity,
3769 paction));
3770 break;
3772 /* Difference is caused by data in the action structure. */
3773 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3774 diplomat_investigate(pplayer,
3775 actor_unit, pcity,
3776 paction));
3777 break;
3779 /* Difference is caused by data in the action structure. */
3780 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3781 diplomat_embassy(pplayer, actor_unit, pcity,
3782 paction));
3783 break;
3785 /* Difference is caused by data in the action structure. */
3786 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3787 diplomat_incite(pplayer, actor_unit, pcity,
3788 paction));
3789 break;
3791 /* Difference is caused by data in the action structure. */
3792 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3793 diplomat_get_tech(pplayer, actor_unit, pcity,
3794 A_UNSET, paction));
3795 break;
3797 /* Difference is caused by data in the action structure. */
3798 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3799 diplomat_get_tech(pplayer, actor_unit, pcity,
3800 sub_tgt_id, paction));
3801 break;
3803 /* Difference is caused by data in the action structure. */
3804 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3805 spy_steal_gold(pplayer, actor_unit, pcity,
3806 paction));
3807 break;
3808 case ACTRES_STEAL_MAPS:
3809 /* Difference is caused by data in the action structure. */
3810 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3812 pcity, paction));
3813 break;
3814 case ACTRES_TRADE_ROUTE:
3815 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3817 pcity, paction));
3818 break;
3819 case ACTRES_MARKETPLACE:
3820 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3822 pcity, paction));
3823 break;
3824 case ACTRES_HELP_WONDER:
3825 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3826 unit_do_help_build(pplayer,
3827 actor_unit, pcity,
3828 paction));
3829 break;
3830 case ACTRES_SPY_NUKE:
3831 /* Difference is caused by data in the action structure. */
3832 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3833 spy_nuke_city(pplayer, actor_unit, pcity,
3834 paction));
3835 break;
3836 case ACTRES_JOIN_CITY:
3837 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3838 city_add_unit(pplayer, actor_unit, pcity,
3839 paction));
3840 break;
3842 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3843 unit_do_destroy_city(pplayer,
3844 actor_unit, pcity,
3845 paction));
3846 break;
3848 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3849 unit_do_help_build(pplayer, actor_unit, pcity,
3850 paction));
3851 break;
3852 case ACTRES_HOME_CITY:
3853 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3855 paction));
3856 break;
3858 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3859 do_unit_upgrade(pplayer, actor_unit,
3860 pcity, requester, paction));
3861 break;
3863 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3864 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3866 pcity, paction));
3867 break;
3869 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3871 actor_unit,
3872 pcity,
3873 sub_tgt_impr->item_number,
3874 paction));
3875 break;
3877 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3879 actor_unit,
3880 pcity,
3881 paction));
3882 break;
3887 break;
3888 case ACTRES_AIRLIFT:
3889 ACTION_PERFORM_UNIT_CITY(action_type, actor_unit, pcity,
3890 do_airline(actor_unit, pcity, paction));
3891 break;
3896 break;
3897 case ACTRES_BOMBARD:
3898 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3901 paction));
3902 break;
3903 case ACTRES_ATTACK:
3905 /* Difference is caused by data in the action structure. */
3908 break;
3909 case ACTRES_WIPE_UNITS:
3912 break;
3913 case ACTRES_NUKE_UNITS:
3916 paction));
3917 break;
3918 case ACTRES_SPY_ATTACK:
3921 paction));
3922 break;
3923 case ACTRES_FOUND_CITY:
3925 city_build(pplayer, actor_unit,
3927 break;
3928 case ACTRES_NUKE:
3930 pcity, punit, target_tile,
3932 paction));
3933 break;
3934 case ACTRES_PARADROP:
3938 break;
3940 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3942 do_disembark(pplayer, actor_unit,
3944 break;
3945 case ACTRES_HUT_ENTER:
3947 do_unit_hut(pplayer, actor_unit,
3949 break;
3952 do_unit_hut(pplayer, actor_unit,
3954 break;
3955 case ACTRES_UNIT_MOVE:
3959 break;
3960 case ACTRES_TELEPORT:
3964 NULL, FALSE,
3967 FALSE, FALSE));
3968 break;
3972 break;
3973 case ACTRES_CULTIVATE:
3976 break;
3977 case ACTRES_PLANT:
3980 break;
3981 case ACTRES_PILLAGE:
3984 paction,
3985 &target_extra));
3986 break;
3987 case ACTRES_CLEAN:
3990 paction,
3991 &target_extra));
3992 break;
3993 case ACTRES_ROAD:
3996 paction,
3997 &target_extra));
3998 break;
3999 case ACTRES_BASE:
4002 paction,
4003 &target_extra));
4004 break;
4005 case ACTRES_MINE:
4008 paction,
4009 &target_extra));
4010 break;
4011 case ACTRES_IRRIGATE:
4014 paction,
4015 &target_extra));
4016 break;
4017 case ACTRES_NONE:
4018 /* 100% ruleset defined. */
4020 TRUE);
4021 break;
4024 return FALSE;
4025
4027 }
4028
4029 /* Something must have gone wrong. */
4030 return FALSE;
4031}
4032
4033/**********************************************************************/
4041 bool rehome)
4042{
4044 struct player *old_owner = unit_owner(punit);
4045 struct player *new_owner = (new_pcity == NULL ? old_owner
4047 const struct civ_map *nmap = &(wld.map);
4048
4049 /* Calling this function when new_pcity is same as old_pcity should
4050 * be safe with current implementation, but it is not meant to
4051 * be used that way. */
4053
4054 /* If 'rehome' is not set, this function should only be used to change
4055 * which player owns the unit */
4057
4058 if (old_owner != new_owner) {
4059 struct city *pcity = tile_city(punit->tile);
4060
4063
4066
4067 if (pcity != NULL
4069 /* Special case when city is being transferred. At this point city
4070 * itself has changed owner, so it's enemy city now that old owner
4071 * cannot see inside. All the normal methods of removing transferred
4072 * unit from previous owner's client think that there's no need to
4073 * remove unit as client shouldn't have it in first place. */
4075 }
4076
4077 /* Remove AI control of the old owner. */
4078 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4079
4083
4084 /* Activate AI control of the new owner. */
4085 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4086
4089 }
4090
4091 if (rehome) {
4092 /* Remove from old city first and add to new city only after that. */
4093 if (old_pcity) {
4094 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4095 unit_list_remove(old_pcity->units_supported, punit);
4096 /* update unit upkeep */
4098 }
4099
4100 if (new_pcity != NULL) {
4101 unit_list_prepend(new_pcity->units_supported, punit);
4102
4103 /* update unit upkeep */
4105
4106 punit->homecity = new_pcity->id;
4107 } else {
4109 }
4110 }
4111
4113 /* This is mainly for cases where unit owner changes to one not knowing
4114 * Railroad tech when unit is already building railroad.
4115 * Does also send_unit_info() */
4117 } else {
4118 /* Send info to players and observers. */
4120 }
4121
4122 if (new_pcity != NULL) {
4126 }
4127
4128 if (old_pcity) {
4132 }
4133
4135}
4136
4137/**********************************************************************/
4143 struct city *pcity,
4144 const struct action *paction)
4145{
4146 const char *giver = NULL;
4147
4148 if (unit_owner(punit) != city_owner(pcity)) {
4149 /* This is a gift. Tell the receiver. */
4150 giver = player_name(unit_owner(punit));
4151 }
4152
4154
4155 if (punit->homecity == pcity->id && giver) {
4156 /* Notify the city owner about the gift they received. */
4158 ftc_server,
4159 /* TRANS: other player ... unit type ... city name. */
4160 _("%s transferred control over a %s to you in %s."),
4161 giver,
4163 city_link(pcity));
4164 }
4165
4166 return punit->homecity == pcity->id;
4167}
4168
4169/**********************************************************************/
4176static bool city_add_unit(struct player *pplayer, struct unit *punit,
4177 struct city *pcity, const struct action *paction)
4178{
4180 const struct unit_type *act_utype;
4181
4182 /* Sanity check: The actor is still alive. */
4184
4186
4187 /* Sanity check: The target city still exists. */
4188 fc_assert_ret_val(pcity, FALSE);
4189
4191
4192 city_size_add(pcity, amount);
4193 /* Make the new people something, otherwise city fails the checks */
4196 /* Refresh the city data. */
4197 city_refresh(pcity);
4198
4199 /* Notify the unit owner that the unit successfully joined the city. */
4201 _("%s added to aid %s in growing."),
4203 city_link(pcity));
4204 if (pplayer != city_owner(pcity)) {
4205 /* Notify the city owner when a foreign unit joins a city. */
4207 ftc_server,
4208 /* TRANS: another player had their unit join your city. */
4209 _("%s adds %s to your city %s."),
4212 city_link(pcity));
4213 }
4214
4216 city_owner(pcity), city_tile(pcity),
4217 city_link(pcity));
4218
4219 sanity_check_city(pcity);
4220
4221 send_city_info(NULL, pcity);
4222
4223 script_server_signal_emit("city_size_change", pcity,
4224 (lua_Integer)amount, "unit_added");
4225
4226 return TRUE;
4227}
4228
4229/**********************************************************************/
4238static bool city_build(struct player *pplayer, struct unit *punit,
4239 struct tile *ptile, const char *name,
4240 const struct action *paction)
4241{
4242 char message[1024];
4243 int size;
4244 struct player *nationality;
4245 struct player *towner;
4246 const struct unit_type *act_utype;
4247
4248 /* Sanity check: The actor still exists. */
4249 fc_assert_ret_val(pplayer, FALSE);
4251
4252 towner = tile_owner(ptile);
4253
4254 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4255 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4256 "%s", message);
4257 return FALSE;
4258 }
4259
4261
4262 nationality = unit_nationality(punit);
4263
4264 create_city(pplayer, ptile, name, nationality);
4266 if (size > 1) {
4267 struct city *pcity = tile_city(ptile);
4268
4269 fc_assert_ret_val(pcity != NULL, FALSE);
4270
4272 }
4273
4274 /* May cause an incident even if the target tile is unclaimed. A ruleset
4275 * could give everyone a casus belli against the city founder. A rule
4276 * like that would make sense in a story where deep ecology is on the
4277 * table. (See also Voluntary Human Extinction Movement) */
4279 ptile, tile_link(ptile));
4280
4281 return TRUE;
4282}
4283
4284/**********************************************************************/
4287static void handle_unit_change_activity_real(struct player *pplayer,
4288 int unit_id,
4289 enum unit_activity activity,
4290 struct extra_type *activity_target,
4292{
4293 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4294
4295 if (NULL == punit) {
4296 /* Probably died or bribed. */
4297 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4298 return;
4299 }
4300
4301 if (punit->activity == activity
4303 return;
4304 }
4305
4306 /* Remove city spot reservations for AI settlers on city founding
4307 * mission, before goto_tile reset. */
4308 if (punit->server.adv->task != AUT_NONE) {
4310 }
4311
4312 punit->goto_tile = NULL;
4313
4314 if (activity == ACTIVITY_GOTO) {
4315 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4316 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4317 * it is going somewhere while it is standing still. The appearance of
4318 * the unit doing something can trick the user to not make use of it.
4319 *
4320 * Handled here because adv_follow_path() uses unit_activity_handling()
4321 * to set a unit's activity to ACTIVITY_GOTO. */
4322 return;
4323 }
4324
4325 if (activity == ACTIVITY_EXPLORE) {
4326 /* Please use unit_server_side_agent_set(). */
4327 return;
4328 }
4329
4330 /* The activity can now be set. */
4333}
4334
4335/**********************************************************************/
4338void handle_unit_change_activity(struct player *pplayer, int unit_id,
4340 int target_id)
4341{
4342 struct extra_type *activity_target;
4343
4345 activity_target = NULL;
4346 } else {
4347 activity_target = extra_by_number(target_id);
4348 }
4349
4350#ifdef FREECIV_WEB
4351 /* Web-client is not capable of selecting target, so we do it server side */
4352 if (activity_target == NULL) {
4353 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4354 bool required = TRUE;
4355
4356 if (punit == NULL) {
4357 return;
4358 }
4359
4360 if (activity == ACTIVITY_IRRIGATE) {
4361 struct tile *ptile = unit_tile(punit);
4362
4363 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4364 pplayer, punit);
4365 } else if (activity == ACTIVITY_MINE) {
4366 struct tile *ptile = unit_tile(punit);
4367
4368 activity_target = next_extra_for_tile(ptile, EC_MINE,
4369 pplayer, punit);
4370 } else if (activity == ACTIVITY_BASE) {
4371 struct tile *ptile = unit_tile(punit);
4372 struct base_type *pbase =
4374
4375 if (pbase != NULL) {
4376 activity_target = base_extra_get(pbase);
4377 }
4378
4379 } else if (activity == ACTIVITY_CLEAN) {
4380 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4381 pplayer, punit);
4382 } else {
4383 required = FALSE;
4384 }
4385
4386 if (activity_target == NULL && required) {
4387 /* Nothing more we can do */
4388 return;
4389 }
4390 }
4391#endif /* FREECIV_WEB */
4392
4393 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target,
4394 activity_default_action(activity));
4395}
4396
4397/**********************************************************************/
4400static void see_combat(struct unit *pattacker, struct unit *pdefender)
4401{
4404
4405 /*
4406 * Special case for attacking/defending:
4407 *
4408 * Normally the player doesn't get the information about the units inside a
4409 * city. However for attacking/defending the player has to know the unit of
4410 * the other side. After the combat a remove_unit packet will be sent
4411 * to the client to tidy up.
4412 *
4413 * Note these packets must be sent out before unit_versus_unit() is called,
4414 * so that the original unit stats (HP) will be sent.
4415 */
4422
4424 struct player *pplayer = pconn->playing;
4425
4426 if (pplayer != NULL) {
4427
4428 /* NOTE: this means the player can see combat between submarines even
4429 * if neither sub is visible. See similar comment in send_combat. */
4432 V_MAIN)) {
4433
4434 /* Units are sent even if they were visible already. They may
4435 * have changed orientation for combat. */
4436 if (pplayer == unit_owner(pattacker)) {
4438 } else {
4440 }
4441
4442 if (pplayer == unit_owner(pdefender)) {
4444 } else {
4446 }
4447 }
4448 } else if (pconn->observer) {
4449 /* Global observer sees everything... */
4452 }
4454}
4455
4456/**********************************************************************/
4459static void send_combat(struct unit *pattacker, struct unit *pdefender,
4460 int att_veteran, int def_veteran, int bombard)
4461{
4463
4465 combat.defender_unit_id = pdefender->id;
4466 combat.attacker_hp = pattacker->hp;
4467 combat.defender_hp = pdefender->hp;
4468 combat.make_att_veteran = att_veteran;
4469 combat.make_def_veteran = def_veteran;
4470
4471 players_iterate(other_player) {
4472 /* NOTE: this means the player can see combat between submarines even
4473 * if neither sub is visible. See similar comment in see_combat. */
4474 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4475 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4476 V_MAIN)) {
4477 lsend_packet_unit_combat_info(other_player->connections, &combat);
4478
4479 /*
4480 * Remove the client knowledge of the units. This corresponds to the
4481 * send_packet_unit_short_info calls up above.
4482 */
4483 if (!can_player_see_unit(other_player, pattacker)) {
4484 unit_goes_out_of_sight(other_player, pattacker);
4485 }
4486 if (!can_player_see_unit(other_player, pdefender)) {
4487 unit_goes_out_of_sight(other_player, pdefender);
4488 }
4489 }
4491
4492 /* Send combat info to non-player observers as well. They already know
4493 * about the unit so no unit_info is needed. */
4495 if (NULL == pconn->playing && pconn->observer) {
4497 }
4499}
4500
4501/**********************************************************************/
4505 struct city *pcity,
4506 const struct action *paction,
4507 const char *reason)
4508{
4509 struct player *pplayer = unit_owner(punit);
4510
4511 if (pcity
4513 &(const struct req_context) {
4514 .player = city_owner(pcity),
4515 .city = pcity,
4516 .tile = city_tile(pcity),
4517 .unit = punit,
4518 .unittype = unit_type_get(punit),
4519 .action = paction,
4520 },
4524 struct player *cplayer = city_owner(pcity);
4525 struct tile *ctile = city_tile(pcity);
4526 const char *clink = city_link(pcity);
4527
4528 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4529 city_refresh(pcity);
4530 send_city_info(NULL, pcity);
4531 } else {
4533 /* TRANS: Battleship ... Los Angeles ... Bombard */
4534 _("Your %s destroyed %s by doing %s."),
4539 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4540 _("%s destroyed %s by doing %s."),
4541 player_name(pplayer), clink,
4543 }
4544 }
4545}
4546
4547/**********************************************************************/
4554static bool unit_bombard(struct unit *punit, struct tile *ptile,
4555 const struct action *paction)
4556{
4557 struct player *pplayer = unit_owner(punit);
4558 struct city *pcity = tile_city(ptile);
4559 const struct unit_type *act_utype;
4560 const struct civ_map *nmap = &(wld.map);
4561
4562 /* Sanity check: The actor still exists. */
4563 fc_assert_ret_val(pplayer, FALSE);
4565
4567
4568 log_debug("Start bombard: %s %s to %d, %d.",
4570 unit_rule_name(punit), TILE_XY(ptile));
4571
4573 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4574 bool adj;
4575 enum direction8 facing;
4576 int att_hp, def_hp;
4577
4579 punit->tile, pdefender->tile, &facing);
4580
4581 if (adj) {
4582 punit->facing = facing;
4583
4584 /* Unlike with normal attack, we don't change orientation of
4585 * defenders when bombarding */
4586 }
4587
4588 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4589
4590 if (def_hp <= 0) {
4591 notify_player(pplayer, ptile,
4593 /* TRANS: Your Bomber killed the English Rifleman by
4594 * doing Bombard. */
4595 _("Your %s killed the %s %s by doing %s."),
4602 /* TRANS: Your Rifleman was killed by the French
4603 * Bomber doing Bombard. */
4604 _("Your %s was killed by the %s %s doing %s."),
4609 } else {
4610 notify_player(pplayer, ptile,
4612 /* TRANS: Your Bomber bombards the English Rifleman. */
4613 _("Your %s bombards the %s %s."),
4619 /* TRANS: Your Rifleman is bombarded by the French
4620 * Bomber. */
4621 _("Your %s is bombarded by the %s %s."),
4625 }
4626
4628
4629 punit->hp = att_hp;
4630 pdefender->hp = def_hp;
4631
4632 send_combat(punit, pdefender, 0, 0, 1);
4633
4634 /* May cause an incident */
4640
4641 if (def_hp <= 0) {
4643 } else {
4645 }
4646 }
4647
4649
4652
4653 unit_attack_civilian_casualties(punit, pcity, paction, "bombard");
4654
4656
4657 return TRUE;
4658}
4659
4660/**********************************************************************/
4671static bool unit_nuke(struct player *pplayer, struct unit *punit,
4672 struct tile *def_tile, const struct action *paction)
4673{
4674 struct city *pcity;
4675 const struct unit_type *act_utype;
4676 struct civ_map *nmap = &(wld.map);
4677
4678 /* Sanity check: The actor still exists. */
4679 fc_assert_ret_val(pplayer, FALSE);
4681
4683
4684 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4687 TILE_XY(def_tile));
4688
4689 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4690 /* FIXME: Remove the hard coded reference to SDI defense. */
4692 _("Your %s was shot down by "
4693 "SDI defenses, what a waste."), unit_tile_link(punit));
4695 _("The nuclear attack on %s was avoided by"
4696 " your SDI defense."), city_link(pcity));
4697
4698 /* Trying to nuke something this close can be... unpopular. */
4700 city_owner(pcity),
4702
4703 /* Remove the destroyed nuke. */
4705
4706 return FALSE;
4707 }
4708
4710
4711
4712 /* The nuke must be wiped here so it won't be seen as a victim of its own
4713 * detonation. */
4714 if (paction->actor_consuming_always) {
4716 }
4717
4719
4720 /* May cause an incident even if the target tile is unclaimed. A ruleset
4721 * could give everyone a casus belli against the tile nuker. A rule
4722 * like that would make sense in a story where detonating any nuke at all
4723 * could be forbidden. */
4726 def_tile,
4728
4729 return TRUE;
4730}
4731
4732/**********************************************************************/
4742 struct unit *act_unit,
4743 struct city *tgt_city,
4744 const struct action *paction)
4745{
4746 int tgt_city_id;
4747 struct player *tgt_player;
4748 bool capital;
4749 bool try_civil_war = FALSE;
4750 const struct unit_type *act_utype;
4751
4752 /* Sanity check: The actor still exists. */
4755
4757
4758 /* Sanity check: The target city still exists. */
4760
4762
4763 /* How can a city be ownerless? */
4765
4766 /* Save city ID. */
4767 tgt_city_id = tgt_city->id;
4768
4770
4771 if (capital
4772 && (tgt_player->spaceship.state == SSHIP_STARTED
4773 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4774 /* Destroying this city destroys the victim's space ship. */
4776 }
4777
4778 if (capital
4782 /* Destroying this city can trigger a civil war. */
4784 }
4785
4786 /* Let the actor know. */
4789 _("You destroy %s completely."),
4791
4792 if (tgt_player != act_player) {
4793 /* This was done to a foreign city. Inform the victim player. */
4796 _("%s has been destroyed by %s."),
4799 }
4800
4801 /* May cause an incident */
4805
4806 /* Run post city destruction Lua script. */
4808 act_player);
4809
4810 /* Can't be sure of city existence after running script. */
4811 if (city_exist(tgt_city_id)) {
4813 }
4814
4815 if (try_civil_war) {
4816 /* Try to start the civil war. */
4818 }
4819
4820 /* The city is no more. */
4821 return TRUE;
4822}
4823
4824/**********************************************************************/
4829static const char *unit_veteran_level_string(const struct unit *punit)
4830{
4831 static char buf[MAX_LEN_LINK];
4832 const struct veteran_level *vlevel;
4833
4834 if (!punit) {
4835 buf[0] = '\0'; /* If no unit, return empty string */
4836 return buf;
4837 }
4838
4840 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4841
4842 return buf;
4843}
4844
4845/**********************************************************************/
4850static const char *unit_achieved_rank_string(const struct unit *punit)
4851{
4852 static char buf[MAX_LEN_LINK];
4853
4854 fc_snprintf(buf, sizeof(buf),
4855 /* TRANS: " and achieved the rank of <veteran level>";
4856 * preserve leading space */
4857 _(" and achieved the rank of %s"),
4859 return buf;
4860}
4861
4862/**********************************************************************/
4867static const char *unit_tired_attack_string(const struct unit *punit)
4868{
4869 static char buf[MAX_LEN_LINK];
4870
4872 fc_snprintf(buf, sizeof(buf),
4873 /* TRANS: tired; note trailing space */
4874 _("tired "));
4875 } else {
4876 buf[0] = '\0';
4877 }
4878
4879 return buf;
4880}
4881
4882/**********************************************************************/
4889static const char *unit_firepower_if_not_one(int firepower)
4890{
4891 static char buf[MAX_LEN_LINK];
4892
4893 if (firepower == 1) {
4894 buf[0] = '\0';
4895 } else {
4896 fc_snprintf(buf, sizeof(buf),
4897 /* TRANS: FP = Firepower of a unit; note trailing space */
4898 _("FP:%d "),
4899 firepower);
4900 }
4901
4902 return buf;
4903}
4904
4905/**********************************************************************/
4914static bool do_attack(struct unit *punit, struct tile *def_tile,
4915 const struct action *paction)
4916{
4921 struct unit *ploser, *pwinner;
4924 int winner_id;
4925 struct player *pplayer = unit_owner(punit);
4926 bool adj;
4927 enum direction8 facing;
4928 int att_hp, def_hp, att_fp, def_fp;
4930 int def_power, att_power;
4931 int att_vet, def_vet;
4932 struct unit *pdefender;
4933 const struct unit_type *act_utype = unit_type_get(punit);
4934 struct civ_map *nmap = &(wld.map);
4935 bool powerless;
4936
4938 /* Can't fight air... */
4939 return FALSE;
4940 }
4941
4943 def_hp_start = pdefender->hp;
4947
4948 log_debug("Start attack: %s %s against %s %s.",
4953
4954 /* Sanity checks */
4959 FALSE,
4960 "Trying to attack a unit with which you have peace "
4961 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
4965 FALSE,
4966 "Trying to attack a unit with which you have "
4967 "alliance at (%d, %d).", TILE_XY(def_tile));
4968
4971
4973 punit->tile, pdefender->tile, &facing);
4974
4975 fc_assert(adj);
4976 if (adj) {
4977 punit->facing = facing;
4978 pdefender->facing = opposite_direction(facing);
4979 }
4980
4982 old_defender_vet = pdefender->veteran;
4983
4984 /* N.B.: unit_veteran_level_string always returns the same pointer. */
4987
4988 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
4991
4992 /* Record tired attack string before attack */
4994
4995 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
4996 &att_vet, &def_vet, paction);
4997
4998 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
4999 && unit_transported(punit)) {
5000 /* Dying attacker must be first unloaded so it doesn't die inside transport */
5002 }
5003
5005
5006 punit->hp = att_hp;
5007 pdefender->hp = def_hp;
5008
5010
5011 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
5012 * the movement attack modifier is correct! --dwp
5013 *
5014 * For greater Civ2 compatibility (and game balance issues), we recompute
5015 * the new total MP based on the HP the unit has left after being damaged,
5016 * and subtract the MPs that had been used before the combat (plus the
5017 * points used in the attack itself, for the attacker). -GJW, Glip
5018 */
5021
5022 if (punit->moves_left < 0) {
5023 punit->moves_left = 0;
5024 }
5025 if (pdefender->moves_left < 0) {
5026 pdefender->moves_left = 0;
5027 }
5030
5031 /* This may cause a diplomatic incident. */
5035
5036 if (punit->hp > 0 && pdefender->hp > 0) {
5037 /* Neither died */
5039 pdefender->veteran - old_defender_vet, 0);
5040 return TRUE;
5041 }
5042 pwinner = (punit->hp > 0) ? punit : pdefender;
5043 winner_id = pwinner->id;
5044 ploser = (pdefender->hp > 0) ? punit : pdefender;
5045
5046 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5047 old_defender_vet)) ? 0 : 1;
5048
5050 pdefender->veteran - old_defender_vet, 0);
5051
5052 /* N.B.: unit_link always returns the same pointer. */
5057
5058 if (punit == ploser) {
5059 /* The attacker lost */
5060 log_debug("Attacker lost: %s %s against %s %s.",
5065
5069 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5070 * 9 HP remaining] survived the pathetic ...attack from
5071 * green Warriors [id:90 ...A:1.0 HP:10]. */
5072 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5073 " survived the pathetic %sattack from %s %s "
5074 "[id:%d %sA:%.1f HP:%d]."),
5077 pdefender->id,
5079 (float)def_power/POWER_FACTOR,
5080 def_hp_start - pdefender->hp,
5081 pdefender->hp,
5084 loser_link,
5085 punit->id,
5087 (float)att_power/POWER_FACTOR,
5088 att_hp_start);
5089 } else {
5092 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5093 * 9 HP remaining] survived the pathetic ...attack from the
5094 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5095 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5096 " survived the pathetic %sattack from the %s %s %s "
5097 "[id:%d %sA:%.1f HP:%d]."),
5100 pdefender->id,
5102 (float)def_power/POWER_FACTOR,
5103 def_hp_start - pdefender->hp,
5104 pdefender->hp,
5108 loser_link,
5109 punit->id,
5111 (float)att_power/POWER_FACTOR,
5112 att_hp_start);
5113 }
5114
5115 if (vet) {
5117 }
5118
5122 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5123 * failed against green Destroyer [id:200 lost
5124 * 27 HP, 3 HP remaining%s]!";
5125 * last %s is either "and ..." or empty string */
5126 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5127 "against %s %s [id:%d lost %d HP, %d HP "
5128 "remaining%s]!"),
5130 loser_link,
5131 punit->id,
5133 (float)att_power/POWER_FACTOR,
5137 pdefender->id,
5138 def_hp_start - pdefender->hp,
5139 pdefender->hp,
5141 } else {
5144 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5145 * failed against the Polish green Destroyer [id:200 lost
5146 * 27 HP, 3 HP remaining%s]!";
5147 * last %s is either "and ..." or empty string */
5148 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5149 "against the %s %s %s [id:%d lost %d HP, %d HP "
5150 "remaining%s]!"),
5152 loser_link,
5153 punit->id,
5155 (float)att_power/POWER_FACTOR,
5160 pdefender->id,
5161 def_hp_start - pdefender->hp,
5162 pdefender->hp,
5164 }
5165
5167 } else {
5168 /* The defender lost, the attacker punit lives! */
5169 struct city *pcity;
5170
5171 log_debug("Defender lost: %s %s against %s %s.",
5176
5180 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5181 * lost to an attack by green Legion
5182 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5183 * last %s is either "and ..." or empty string */
5184 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5185 "%s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5186 "remaining%s]."),
5188 loser_link,
5189 pdefender->id,
5191 (float)def_power/POWER_FACTOR,
5195 punit->id,
5197 (float)att_power/POWER_FACTOR,
5198 att_hp_start - pwinner->hp,
5199 pwinner->hp,
5201 } else {
5204 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5205 * lost to an attack by the Greek green Legion
5206 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5207 * last %s is either "and ..." or empty string */
5208 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5209 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5210 "remaining%s]."),
5212 loser_link,
5213 pdefender->id,
5215 (float)def_power/POWER_FACTOR,
5220 punit->id,
5222 (float)att_power/POWER_FACTOR,
5223 att_hp_start - pwinner->hp,
5224 pwinner->hp,
5226 }
5227
5231 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5232 * lost 1 HP, has 9 HP remaining] succeeded against
5233 * green Warriors [id:100 HP:10]." */
5234 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5235 "has %d remaining] succeeded against %s %s "
5236 "[id:%d HP:%d]."),
5239 punit->id,
5242 (float)att_power/POWER_FACTOR,
5243 att_hp_start - pwinner->hp,
5244 pwinner->hp,
5246 loser_link,
5247 pdefender->id,
5248 def_hp_start);
5249 } else {
5252 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5253 * lost 1 HP, has 9 HP remaining] succeeded against the
5254 * Greek green Warriors [id:100 HP:10]." */
5255 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5256 "has %d remaining] succeeded against the %s %s %s "
5257 "[id:%d HP:%d]."),
5260 punit->id,
5263 (float)att_power/POWER_FACTOR,
5264 att_hp_start - pwinner->hp,
5265 pwinner->hp,
5268 loser_link,
5269 pdefender->id,
5270 def_hp_start);
5271 }
5272
5273 punit->moved = TRUE; /* We moved */
5274
5275 if (paction->result == ACTRES_COLLECT_RANSOM) {
5278 } else {
5281 }
5282
5283 /* Now that dead defender is certainly no longer listed as unit
5284 * supported by the city, we may even remove the city
5285 * (if it shrinks from size 1) */
5286 pcity = tile_city(def_tile);
5287 if (pcity != NULL) {
5289 }
5290 if (unit_is_alive(winner_id)) {
5292 return TRUE;
5293 }
5294 } else {
5295 return TRUE;
5296 }
5297 }
5298
5299 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5300 * if there are enemy units in the tile (a fortress, city or air base with
5301 * multiple defenders and unstacked combat). Note that this could mean
5302 * capturing (or destroying) a city. */
5303
5304 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5306 }
5307
5308 /* The attacker may have died for many reasons */
5311 }
5312
5313 return TRUE;
5314}
5315
5316/**********************************************************************/
5327 struct unit *act_unit,
5328 struct city *tgt_city,
5329 const struct action *paction)
5330{
5331 struct player *tgt_player;
5332 char prod[256];
5333 const struct unit_type *act_utype;
5334 const struct tile *tgt_tile;
5335 const char *clink;
5336
5337 /* Sanity checks */
5342
5345
5347
5348 /* The surgical strike may miss. */
5349 {
5350 /* Roll the dice. */
5353 paction)) {
5354 /* Notify the player. */
5357 /* TRANS: unit, action, city */
5358 _("Your %s failed to do %s in %s."),
5362
5363 /* Make the failed attempt cost a single move. */
5364 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5365
5366 return FALSE;
5367 }
5368 }
5369
5370 /* Get name of the production */
5371 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5372
5373 /* Destroy the production */
5374 tgt_city->shield_stock = 0;
5376
5377 /* Let the players know. */
5378 clink = city_link(tgt_city); /* Be careful not to call city_link()
5379 * again as long as we need clink */
5382 _("Your %s succeeded in destroying"
5383 " the production of %s in %s."),
5385 prod, clink);
5388 _("The production of %s was destroyed in %s,"
5389 " %s are suspected."),
5390 prod, clink,
5392
5394
5395 /* May cause an incident */
5398 clink);
5399
5400 return TRUE;
5401}
5402
5403/**********************************************************************/
5414 struct unit *act_unit,
5415 struct city *tgt_city,
5417 const struct action *paction)
5418{
5419 struct player *tgt_player;
5421 const struct tile *tgt_tile;
5422 const struct unit_type *act_utype;
5423 const char *clink;
5424
5425 /* Sanity checks */
5430
5432
5435
5436 /* The surgical strike may miss. */
5437 {
5438 /* Roll the dice. */
5441 paction)) {
5442 /* Notify the player. */
5445 /* TRANS: unit, action, city */
5446 _("Your %s failed to do %s in %s."),
5450
5451 /* Make the failed attempt cost a single move. */
5452 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5453
5454 return FALSE;
5455 }
5456 }
5457
5459 /* Nothing to destroy here. */
5460
5461 /* Notify the player. */
5464 _("Your %s didn't find a %s to %s in %s."),
5469
5470 /* Punish the player for blindly attacking a building. */
5471 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5472
5473 return FALSE;
5474 }
5475
5477 /* Notify the player. */
5480 _("Your %s cannot do %s to %s in %s."),
5485
5486 /* Punish the player for blindly attacking a building. */
5487 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5488
5489 return FALSE;
5490 }
5491
5493
5494 /* Destroy the building. */
5495 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5496
5497 /* Update the player's view of the city. */
5499
5500 /* Let the players know. */
5501 clink = city_link(tgt_city); /* Be careful not to call city_link()
5502 * again as long as we need clink */
5505 _("Your %s destroyed the %s in %s."),
5508 clink);
5511 _("The %s destroyed the %s in %s."),
5514 clink);
5515
5516 /* May cause an incident */
5519
5520 return TRUE;
5521}
5522
5523/**********************************************************************/
5533 struct unit *act_unit,
5534 struct city *tgt_city,
5535 struct action *paction)
5536{
5537 bool success;
5538 struct tile *tgt_tile = city_tile(tgt_city);
5539 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5540 int tgt_city_id = tgt_city->id;
5542 const char *victim_link = city_link(tgt_city);
5543
5544 /* Sanity check */
5546
5547 unit_move(act_unit, tgt_tile, move_cost, NULL, FALSE, TRUE, TRUE,
5548 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5550
5551 /* The city may have been destroyed during the conquest. */
5554
5555 if (success) {
5556 const struct unit_type *act_utype = unit_type_get(act_unit);
5557
5558 /* May cause an incident */
5561 victim_link);
5562 }
5563
5564 return success;
5565}
5566
5567/**********************************************************************/
5571 struct tile *dest_tile,
5572 bool igzoc,
5573 struct unit *embark_to,
5574 bool enter_enemy_city)
5575{
5576 struct tile *src_tile = unit_tile(punit);
5579 src_tile, dest_tile, igzoc, TRUE, embark_to,
5581
5582 switch (reason) {
5583 case MR_OK:
5584 return TRUE;
5585
5586 case MR_NO_WAR:
5588 _("Cannot attack unless you declare war first."));
5589 break;
5590
5591 case MR_ZOC:
5593 _("%s can only move into your own zone of control."),
5594 unit_link(punit));
5595 break;
5596
5597 case MR_TRIREME:
5599 _("%s cannot move that far from the coast line."),
5600 unit_link(punit));
5601 break;
5602
5603 case MR_PEACE:
5604 if (tile_owner(dest_tile)) {
5606 _("Cannot invade unless you break peace with "
5607 "%s first."),
5608 player_name(tile_owner(dest_tile)));
5609 }
5610 break;
5611
5614 _("%s cannot disembark outside of a city or a native base "
5615 "for %s."),
5619 break;
5620
5621 case MR_NON_NATIVE_MOVE:
5623 _("Terrain is unsuitable for %s units."),
5625 break;
5626
5627 default:
5628 /* FIXME: need more explanations someday! */
5629 break;
5630 };
5631
5632 return FALSE;
5633}
5634
5635/**********************************************************************/
5642 struct unit *actor_unit,
5643 struct tile *target_tile,
5644 const struct action *paction)
5645{
5647 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5648
5649 unit_move(actor_unit, target_tile, move_cost,
5651 /* Don't override "Conquer City" */
5652 FALSE,
5653 /* Don't override "Conquer Extras" */
5654 FALSE,
5655 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5657
5658 /* May cause an incident */
5662
5663 return TRUE;
5664}
5665
5666/**********************************************************************/
5680 bool move_do_not_act)
5681{
5682 struct player *pplayer = unit_owner(punit);
5683 struct unit *ptrans;
5684 const struct civ_map *nmap = &(wld.map);
5685
5686 /*** Phase 1: Attempted action interpretation checks ***/
5687
5688 /* Check if the move should be interpreted as an attempt to perform an
5689 * enabler controlled action to the target tile. When the move may be an
5690 * action attempt the server stops moving the unit, marks it as wanting a
5691 * decision based on its own movement to the tile it attempted to move to
5692 * and notifies the client.
5693 *
5694 * In response to the unit being marked as wanting a decision the client
5695 * can query the server for what actions the unit, given the player's
5696 * knowledge, may be able to perform against a target at the tile it tried
5697 * to move to. The server will respond to the query with the actions that
5698 * may be enabled and, when all actions are known to be illegal given the
5699 * player's knowledge, an explanation why no action could be done. The
5700 * client will probably use the list of potentially legal actions, if any,
5701 * to pop up an action selection dialog. See handle_unit_action_query()
5702 *
5703 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5704 * to perform an enabler controlled action.
5705 * Examples of where this is useful is for AI moves, goto, when the player
5706 * attempts to move to a tile occupied by potential targets like allied
5707 * cities or units and during rule forced moves.
5708 *
5709 * A move is not interpreted as an attempted action because the unit is
5710 * able to do a self targeted action.
5711 *
5712 * A move is not interpreted as an attempted action because an action
5713 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5714 * perform a regular move to the tile.
5715 *
5716 * An attempted move to a tile a unit can't move to is always interpreted
5717 * as trying to perform an action (unless move_do_not_act is TRUE) */
5718 if (!move_do_not_act) {
5721 FALSE, FALSE, FALSE);
5725 /* A legal action with an extra sub target is a legal action */
5727 /* Tile target actions with extra sub targets are handled above */
5729
5731 /* There is a target punit, from the player's point of view, may be
5732 * able to act against OR punit can't do any non action move. The
5733 * client should therefore ask what action(s) the unit can perform
5734 * to any targets at pdesttile.
5735 *
5736 * In the first case the unit needs a decision about what action, if
5737 * any at all, to take. Asking what actions the unit can perform
5738 * will return a list of actions that may, from the players point of
5739 * view, be possible. The client can then show this list to the
5740 * player or, if configured to do so, make the choice it self.
5741 *
5742 * In the last case the player may need an explanation about why no
5743 * action could be taken. Asking what actions the unit can perform
5744 * will provide this explanation. */
5748
5749 /* The move wasn't done because the unit wanted the player to
5750 * decide what to do or because the unit couldn't move to the
5751 * target tile. */
5752 return FALSE;
5753 }
5754 }
5755
5756 /*** Phase 2: OK now move the unit ***/
5757 /* This is a regular move, subject to the rules. */
5759 punit, pdesttile, NULL)) {
5760 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5764 punit, pdesttile, NULL)) {
5765 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5769 punit, pdesttile, NULL)) {
5770 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5776 punit, ptrans)) {
5777 /* "Transport Embark". */
5778 return unit_perform_action(pplayer, punit->id, ptrans->id,
5784 punit, ptrans)) {
5785 /* "Transport Embark 2". */
5786 return unit_perform_action(pplayer, punit->id, ptrans->id,
5792 punit, ptrans)) {
5793 /* "Transport Embark 3". */
5794 return unit_perform_action(pplayer, punit->id, ptrans->id,
5800 punit, ptrans)) {
5801 /* "Transport Embark 4". */
5802 return unit_perform_action(pplayer, punit->id, ptrans->id,
5806 punit, pdesttile, NULL)) {
5807 /* "Transport Disembark". */
5808 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5812 punit, pdesttile, NULL)) {
5813 /* "Transport Disembark 2". */
5814 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5818 punit, pdesttile, NULL)) {
5819 /* "Transport Disembark 3". */
5820 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5824 punit, pdesttile, NULL)) {
5825 /* "Transport Disembark 4". */
5826 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5830 punit, pdesttile, NULL)) {
5831 /* "Enter Hut". */
5832 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5836 punit, pdesttile, NULL)) {
5837 /* "Enter Hut 2". */
5838 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5842 punit, pdesttile, NULL)) {
5843 /* "Frighten Hut". */
5844 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5848 punit, pdesttile, NULL)) {
5849 /* "Frighten Hut 2". */
5850 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5853 } else {
5854 /* TODO: Extend the action not enabled explanation system to cover all
5855 * existing reasons and switch to using it. See hrm Feature #920229 */
5857 NULL, FALSE);
5858 return FALSE;
5859 }
5860}
5861
5862/**********************************************************************/
5872static bool unit_do_help_build(struct player *pplayer,
5873 struct unit *punit,
5874 struct city *pcity_dest,
5875 const struct action *paction)
5876{
5877 const char *work;
5878 const char *prod;
5879 int shields;
5880 const struct unit_type *act_utype;
5881 struct player *cowner;
5882
5883 /* Sanity check: The actor still exists. */
5884 fc_assert_ret_val(pplayer, FALSE);
5886
5887 /* Sanity check: The target city still exists. */
5889
5892
5894 /* Add the caravan shields */
5895 pcity_dest->shield_stock += shields;
5896
5897 /* Will be punished for changing production to something that can't
5898 * receive "Help Wonder" help. */
5900 &pcity_dest->production));
5901 pcity_dest->caravan_shields += shields;
5902 } else {
5904 /* Add the shields from recycling the unit to the city's current
5905 * production. */
5906 pcity_dest->shield_stock += shields;
5907
5908 /* If we change production later at this turn. No penalty is added. */
5909 pcity_dest->disbanded_shields += shields;
5910 }
5911
5913
5914 conn_list_do_buffer(cowner->connections);
5915
5917 /* Let the player that just donated shields with "Help Wonder" know
5918 * the result of their donation. */
5920 } else {
5922 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
5923 * current production in Bergen (4 surplus).
5924 * "Disband Unit Recover" says "current production" rather than its name. */
5925 prod = _("current production");
5926 }
5927
5928 if (build_points_left(pcity_dest) >= 0) {
5929 /* TRANS: Your Caravan does "Help Wonder" to help build the
5930 * Pyramids in Bergen (4 remaining).
5931 * You can reorder '4' and 'remaining' in the actual format string. */
5932 work = _("remaining");
5933 } else {
5934 /* TRANS: Your Caravan does "Help Wonder" to help build the
5935 * Pyramids in Bergen (4 surplus).
5936 * You can reorder '4' and 'surplus' in the actual format string. */
5937 work = _("surplus");
5938 }
5939
5941 ftc_server,
5942 /* TRANS: Your Caravan does "Help Wonder" to help build the
5943 * Pyramids in Bergen (4 surplus). */
5944 _("Your %s does %s to help build the %s in %s (%d %s)."),
5947 prod,
5950 work);
5951
5952 /* May cause an incident */
5955
5956 if (cowner != unit_owner(punit)) {
5957 /* Tell the city owner about the gift they just received. */
5958
5961 /* TRANS: Help building the Pyramids in Bergen received
5962 * from Persian Caravan (4 surplus). */
5963 _("Help building the %s in %s received from %s %s "
5964 "(%d %s)."),
5970 work);
5971 }
5972
5975 conn_list_do_unbuffer(cowner->connections);
5976
5977 return TRUE;
5978}
5979
5980/**********************************************************************/
5987static bool do_unit_establish_trade(struct player *pplayer,
5988 struct unit *punit,
5989 struct city *pcity_dest,
5990 const struct action *paction)
5991{
5994 int revenue;
5995 bool can_establish;
5996 int home_overbooked = 0;
5997 int dest_overbooked = 0;
5998 int home_max;
5999 int dest_max;
6000 struct city *pcity_homecity;
6003 enum trade_route_bonus_type bonus_type;
6004 struct goods_type *goods;
6005 const char *goods_str;
6006 const struct unit_type *act_utype;
6007
6008 /* Sanity check: The actor still exists. */
6009 fc_assert_ret_val(pplayer, FALSE);
6011
6012 /* Sanity check: The target city still exists. */
6014
6016
6017 if (!pcity_homecity) {
6019 _("Sorry, your %s cannot establish"
6020 " a trade route because it has no home city."),
6021 unit_link(punit));
6022 return FALSE;
6023 }
6024
6026
6027 if (goods == NULL) {
6029 _("Sorry, your %s cannot establish"
6030 " a trade route because it's not carrying any goods."),
6031 unit_link(punit));
6032 return FALSE;
6033 }
6034
6037
6040 _("Sorry, your %s cannot establish"
6041 " a trade route between %s and %s."),
6045 return FALSE;
6046 }
6047
6049
6053
6054 /* This part of code works like can_establish_trade_route(), except
6055 * that we actually do the action of making the trade route. */
6056
6057 /* If we can't make a new trade route we can still get the trade bonus. */
6060
6061 if (can_establish) {
6066 }
6067
6068 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
6070
6071 /* See if there's a trade route we can cancel at the home city. */
6072 if (home_overbooked >= 0) {
6073 if (home_max <= 0
6075 >= trade)) {
6078 _("Sorry, your %s cannot establish"
6079 " a trade route here!"),
6080 punit_link);
6081 if (home_max > 0) {
6084 PL_(" The city of %s already has %d "
6085 "better trade route!",
6086 " The city of %s already has %d "
6087 "better trade routes!", home_max),
6089 home_max);
6090 }
6092 }
6093 }
6094
6095 /* See if there's a trade route we can cancel at the dest city. */
6096 if (can_establish && dest_overbooked >= 0) {
6097 if (dest_max <= 0
6099 >= trade)) {
6102 _("Sorry, your %s cannot establish"
6103 " a trade route here!"),
6104 punit_link);
6105 if (dest_max > 0) {
6108 PL_(" The city of %s already has %d "
6109 "better trade route!",
6110 " The city of %s already has %d "
6111 "better trade routes!", dest_max),
6113 dest_max);
6114 }
6116 }
6117 }
6118 }
6119
6120 /* We now know for sure whether we can establish a trade route. */
6121
6122 /* Calculate and announce initial revenue. */
6123 revenue
6126
6127 bonus_type = trade_route_settings_by_type
6129
6131
6133
6134 /* We want to keep the bonus type string as the part of the format of the PL_() strings
6135 * for supporting proper pluralization for it. */
6136 switch (bonus_type) {
6137 case TBONUS_NONE:
6140 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
6141 _("Your %s from %s has arrived in %s carrying %s."),
6142 punit_link,
6145 goods_str);
6146 break;
6147 case TBONUS_GOLD:
6150 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6151 PL_("Your %s from %s has arrived in %s carrying %s,"
6152 " and revenues amount to %d in gold.",
6153 "Your %s from %s has arrived in %s carrying %s,"
6154 " and revenues amount to %d in gold.",
6155 revenue),
6156 punit_link,
6159 goods_str,
6160 revenue);
6161 break;
6162 case TBONUS_SCIENCE:
6165 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6166 PL_("Your %s from %s has arrived in %s carrying %s,"
6167 " and revenues amount to %d in research.",
6168 "Your %s from %s has arrived in %s carrying %s,"
6169 " and revenues amount to %d in research.",
6170 revenue),
6171 punit_link,
6174 goods_str,
6175 revenue);
6176 break;
6177 case TBONUS_BOTH:
6180 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6181 PL_("Your %s from %s has arrived in %s carrying %s,"
6182 " and revenues amount to %d in gold and research.",
6183 "Your %s from %s has arrived in %s carrying %s,"
6184 " and revenues amount to %d in gold and research.",
6185 revenue),
6186 punit_link,
6189 goods_str,
6190 revenue);
6191 break;
6192 }
6193
6194 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6195 pplayer->economic.gold += revenue;
6196
6197 send_player_info_c(pplayer, pplayer->connections);
6198 }
6199
6200 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6201 /* add bulbs and check for finished research */
6202 update_bulbs(pplayer, revenue, TRUE, TRUE);
6203
6204 /* Inform everyone about tech changes */
6206 }
6207
6208 if (can_establish) {
6210 struct city_list *cities_out_of_home;
6211 struct city_list *cities_out_of_dest;
6212 struct player *partner_player;
6213
6214 /* Announce creation of trade route (it's not actually created until
6215 * later in this function, as we have to cancel existing routes, but
6216 * it makes more sense to announce in this order) */
6217
6219
6220 /* Always tell the unit owner */
6221 notify_player(pplayer, NULL,
6223 _("New trade route established from %s to %s."),
6226 if (pplayer != partner_player) {
6229 _("The %s established a trade route between their "
6230 "city %s and %s."),
6231 nation_plural_for_player(pplayer),
6234 }
6235
6238
6239 /* Now cancel any less profitable trade route from the home city. */
6241 struct trade_route *pback;
6242
6244
6246 free(premove);
6247 free(pback);
6249
6250 /* And the same for the dest city. */
6252 struct trade_route *pback;
6253
6255
6257 free(premove);
6258 free(pback);
6260
6261 /* Actually create the new trade route */
6262 proute_from = fc_malloc(sizeof(struct trade_route));
6263 proute_from->partner = pcity_dest->id;
6264 proute_from->goods = goods;
6265
6266 proute_to = fc_malloc(sizeof(struct trade_route));
6267 proute_to->partner = pcity_homecity->id;
6268 proute_to->goods = goods;
6269
6273 } else {
6274 proute_from->dir = RDIR_FROM;
6275 proute_to->dir = RDIR_TO;
6276 }
6279
6280 /* Refresh the cities. */
6284 city_refresh(pcity);
6287 city_refresh(pcity);
6289
6290 /* Notify the owners of the cities. */
6294 send_city_info(city_owner(pcity), pcity);
6297 send_city_info(city_owner(pcity), pcity);
6299
6300 /* Notify each player about the other's cities. */
6301 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6305 send_city_info(pplayer, pcity_dest);
6306 }
6307
6309 if (partner_player != city_owner(pcity)) {
6312 }
6313 if (pplayer != city_owner(pcity)) {
6314 send_city_info(pplayer, pcity);
6316 }
6318
6320 if (partner_player != city_owner(pcity)) {
6323 }
6324 if (pplayer != city_owner(pcity)) {
6325 send_city_info(pplayer, pcity);
6327 }
6329
6332 }
6333
6334 /* May cause an incident */
6336 pplayer, act_utype, city_owner(pcity_dest),
6339
6341
6342 /* Free data. */
6345
6346 return TRUE;
6347}
6348
6349/**********************************************************************/
6357void handle_unit_sscs_set(struct player *pplayer,
6358 int unit_id,
6360 int value)
6361{
6362 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6363 const struct civ_map *nmap = &(wld.map);
6364
6365 if (NULL == punit) {
6366 /* Being asked to unqueue a "spent" unit because the client haven't
6367 * been told that it's gone is expected. */
6368 if (type != USSDT_UNQUEUE) {
6369 /* Probably died or bribed. */
6370 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6371 }
6372
6373 return;
6374 }
6375
6376 switch (type) {
6377 case USSDT_QUEUE:
6378 /* Reminds the client to ask the server about what actions the unit can
6379 * perform against the target tile. Action decision state can be set by
6380 * the server it self too. */
6381
6382 if (index_to_tile(nmap, value) == NULL) {
6383 /* Asked to be reminded to ask what actions the unit can do to a non
6384 * existing target tile. */
6385 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6386 value, unit_id);
6387 break;
6388 }
6389
6392
6393 /* Let the client know that this unit needs the player to decide
6394 * what to do. */
6396
6397 break;
6398 case USSDT_UNQUEUE:
6399 /* Delete the reminder for the client to ask the server about what
6400 * actions the unit can perform against a certain target tile.
6401 * Action decision state can be set by the server it self too. */
6402
6405
6406 /* Let the client know that this unit no longer needs the player to
6407 * decide what to do. */
6409
6410 break;
6411 case USSDT_BATTLE_GROUP:
6412 /* Battlegroups are handled entirely by the client, so all we have to
6413 do here is save the battlegroup ID so that it'll be persistent. */
6414
6416
6417 break;
6418 case USSDT_SENTRY:
6419 if (value == 0) {
6420 if (punit->activity != ACTIVITY_SENTRY) {
6421 return;
6422 }
6423
6425 /* Impossible to set to Idle? */
6427 }
6428 } else if (value == 1) {
6430 return;
6431 }
6432
6434 /* Should have been caught above */
6436 }
6437 } else {
6438 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6440 }
6441 break;
6442 }
6443}
6444
6445/**********************************************************************/
6448static void unit_plans_clear(struct unit *punit)
6449{
6450 /* Remove city spot reservations for AI settlers on city founding
6451 * mission. */
6453
6454 /* Get rid of old orders. */
6456
6457 /* Make sure that no old goto_tile remains. */
6458 punit->goto_tile = NULL;
6459}
6460
6461/**********************************************************************/
6465 int unit_id,
6467{
6468 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6469
6470 if (NULL == punit) {
6471 /* Probably died or bribed. */
6472 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6473 unit_id);
6474 return;
6475 }
6476
6478 /* Client error. */
6479 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6480 agent);
6481 return;
6482 }
6483
6484 /* Set the state or exit */
6485 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6486 return;
6487 }
6488
6489 /* Give the new agent a blank slate */
6491
6492 if (agent == SSA_AUTOEXPLORE) {
6494 /* Should have been caught above */
6497 }
6498
6499 /* Exploring is handled here explicitly, since the player expects to
6500 * see an immediate response from setting a unit to auto-explore.
6501 * Handling it deeper in the code leads to some tricky recursive loops -
6502 * see PR#2631. */
6503 if (punit->moves_left > 0) {
6505 }
6506 }
6507}
6508
6509/**********************************************************************/
6514 struct unit *punit,
6516{
6517 const struct civ_map *nmap = &(wld.map);
6518
6519 /* Check that the agent can be activated for this unit. */
6520 switch (agent) {
6521 case SSA_AUTOWORKER:
6523 return FALSE;
6524 }
6525 break;
6526 case SSA_AUTOEXPLORE:
6528 return FALSE;
6529 }
6530 break;
6531 case SSA_NONE:
6532 /* Always possible. */
6533 break;
6534 case SSA_COUNT:
6536 break;
6537 }
6538
6540
6542
6543 return TRUE;
6544}
6545
6546/**********************************************************************/
6552 struct extra_type *old_target)
6553{
6554 switch (punit->activity) {
6555 case ACTIVITY_IDLE:
6556 switch (old_activity) {
6557 case ACTIVITY_PILLAGE:
6558 {
6559 if (old_target != NULL) {
6561 if (punit2->activity == ACTIVITY_PILLAGE) {
6562 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6563 if (pdep == old_target) {
6566 break;
6567 }
6569 }
6571 }
6572 break;
6573 }
6574 case ACTIVITY_EXPLORE:
6575 /* Restore unit's control status */
6577 break;
6578 default:
6579 ; /* Do nothing */
6580 }
6581 break;
6582 case ACTIVITY_EXPLORE:
6586 break;
6587 default:
6588 /* Do nothing */
6589 break;
6590 }
6591}
6592
6593/**********************************************************************/
6609
6610/**********************************************************************/
6616{
6617 const struct civ_map *nmap = &(wld.map);
6618
6619 /* Must specify target for ACTIVITY_BASE */
6622
6624 struct extra_type *target = NULL;
6625
6626 /* Assume untargeted pillaging if no target specified */
6632 }
6633
6634 return TRUE;
6635}
6636
6637/**********************************************************************/
6660
6661/**********************************************************************/
6681
6682/**********************************************************************/
6687 struct extra_type **new_target,
6689{
6695
6697
6698 if (list != NULL && action_list_size(list) > 0) {
6699 /* Trigger action system */
6701 (*new_target) != NULL ? (*new_target)->id : NO_TARGET,
6703 } else {
6706 }
6707 }
6708
6709 return TRUE;
6710}
6711
6712/**********************************************************************/
6720 struct extra_type **new_target,
6722{
6725 return FALSE;
6726 } else {
6730
6735 /* unit_assign_specific_activity_target() changed our target activity
6736 * (to ACTIVITY_IDLE in practice) */
6738 } else {
6743
6745 /* Casus Belli for when the activity successfully begins. */
6746 /* TODO: is it more logical to change Casus_Belli_Complete to
6747 * Casus_Belli_Successful_Beginning and trigger it here? */
6753 }
6754 }
6755
6756 return TRUE;
6757 }
6758}
6759
6760/**********************************************************************/
6763void handle_unit_orders(struct player *pplayer,
6764 const struct packet_unit_orders *packet)
6765{
6766 int length = packet->length;
6767 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6768 const struct civ_map *nmap = &(wld.map);
6769 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6770 struct unit_order *order_list;
6771#ifdef FREECIV_DEBUG
6772 int i;
6773#endif
6774
6775 if (NULL == punit) {
6776 /* Probably died or bribed. */
6777 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6778 return;
6779 }
6780
6781 if (0 > length || MAX_LEN_ROUTE < length) {
6782 /* Shouldn't happen */
6783 log_error("handle_unit_orders() invalid %s (%d) "
6784 "packet length %d (max %d)", unit_rule_name(punit),
6785 packet->unit_id, length, MAX_LEN_ROUTE);
6786 return;
6787 }
6788
6789 if (src_tile != unit_tile(punit)) {
6790 /* Failed sanity check. Usually this happens if the orders were sent
6791 * in the previous turn, and the client thought the unit was in a
6792 * different position than it's actually in. The easy solution is to
6793 * discard the packet. We don't send an error message to the client
6794 * here (though maybe we should?). */
6795 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6796 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6797 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6798 return;
6799 }
6800
6801 if (ACTIVITY_IDLE != punit->activity) {
6802 /* New orders implicitly abandon current activity */
6804 }
6805
6806 if (length) {
6807 order_list = create_unit_orders(nmap, length, packet->orders);
6808 if (!order_list) {
6809 log_error("received invalid orders from %s for %s (%d).",
6810 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6811 return;
6812 }
6813 }
6814
6815 /* This must be before old orders are freed. If this is
6816 * settlers on city founding mission, city spot reservation
6817 * from goto_tile must be freed, and free_unit_orders() loses
6818 * goto_tile information */
6820
6822 /* If we waited on a tile, reset punit->done_moving */
6823 punit->done_moving = (punit->moves_left <= 0);
6824
6825 if (length == 0) {
6828 return;
6829 }
6830
6832 punit->orders.length = length;
6833 punit->orders.index = 0;
6834 punit->orders.repeat = packet->repeat;
6835 punit->orders.vigilant = packet->vigilant;
6836 if (length) {
6838 }
6839
6840 if (!packet->repeat) {
6842 } else {
6843 /* Make sure that no old goto_tile remains. */
6844 punit->goto_tile = NULL;
6845 }
6846
6847#ifdef FREECIV_DEBUG
6848 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6849 for (i = 0; i < length; i++) {
6850 log_debug(" %d,%s,%s,%d,%d",
6851 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6852 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6854 packet->orders[i].order == ORDER_ACTIVITY ?
6856 "no action/activity required",
6857 packet->orders[i].target,
6858 packet->orders[i].sub_target);
6859 }
6860#endif /* FREECIV_DEBUG */
6861
6863 || execute_orders(punit, TRUE)) {
6864 /* Looks like the unit survived. */
6866 }
6867}
6868
6869/**********************************************************************/
6872void handle_worker_task(struct player *pplayer,
6873 const struct packet_worker_task *packet)
6874{
6875 struct city *pcity = game_city_by_number(packet->city_id);
6876 struct worker_task *ptask = NULL;
6877 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
6878
6879 if (pcity == NULL || pcity->owner != pplayer || ptile == NULL) {
6880 return;
6881 }
6882
6884 if (tile_index(ptask_old->ptile) == packet->tile_id) {
6885 ptask = ptask_old;
6886 }
6888
6889 if (ptask == NULL) {
6890 if (packet->activity == ACTIVITY_LAST) {
6891 return;
6892 }
6893
6894 ptask = fc_malloc(sizeof(struct worker_task));
6897 } else {
6898 if (packet->activity == ACTIVITY_LAST) {
6900 free(ptask);
6901 ptask = NULL;
6902 }
6903 }
6904
6905 if (ptask != NULL) {
6906 ptask->ptile = ptile;
6907 ptask->act = packet->activity;
6908 if (packet->tgt >= 0) {
6909 if (packet->tgt < MAX_EXTRA_TYPES) {
6910 ptask->tgt = extra_by_number(packet->tgt);
6911 } else {
6912 log_debug("Illegal worker task target %d", packet->tgt);
6913 ptask->tgt = NULL;
6914 }
6915 } else {
6916 ptask->tgt = NULL;
6917 }
6918 ptask->want = packet->want;
6919 }
6920
6921 if (ptask && !worker_task_is_sane(ptask)) {
6922 log_debug("Bad worker task");
6924 free(ptask);
6925 ptask = NULL;
6926 return;
6927 }
6928
6929 lsend_packet_worker_task(pplayer->connections, packet);
6930}
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1148
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:5522
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1225
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:4717
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5044
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:2569
const char * action_name_translation(const struct action *paction)
Definition actions.c:1205
struct act_prob action_prob_unit_vs_tgt(const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:4739
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1214
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4562
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:7535
int action_number(const struct action *action)
Definition actions.c:1183
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:3293
struct action * action_is_blocked_by(const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:2249
struct act_prob action_prob_vs_stack(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:4478
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:3052
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:3129
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:4203
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:5467
struct act_prob action_prob_vs_extras(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4646
bool action_id_exists(const action_id act_id)
Definition actions.c:1043
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1083
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:4286
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1529
#define action_noninternal_iterate_end
Definition actions.h:231
#define ACTPROB_NA
Definition actions.h:667
static struct action * action_by_number(action_id act_id)
Definition actions.h:390
#define action_has_result(_act_, _res_)
Definition actions.h:175
#define action_enabler_list_iterate_end
Definition actions.h:185
#define action_id_get_role(act_id)
Definition actions.h:451
#define action_iterate_end
Definition actions.h:209
#define MAX_NUM_ACTIONS
Definition actions.h:58
#define action_id_get_actor_kind(act_id)
Definition actions.h:403
#define ACTPROB_NOT_KNOWN
Definition actions.h:669
#define action_get_activity(_pact_)
Definition actions.h:454
#define action_has_result_safe(paction, result)
Definition actions.h:418
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:183
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:439
#define ACTPROB_IMPOSSIBLE
Definition actions.h:665
#define action_id(_act_)
Definition actions.h:416
#define action_iterate(_act_)
Definition actions.h:205
#define ACTION_ANY
Definition actions.h:52
#define action_noninternal_iterate(_act_)
Definition actions.h:226
#define action_id_get_target_kind(act_id)
Definition actions.h:407
#define action_id_has_result_safe(act_id, result)
Definition actions.h:420
#define action_id_has_complex_target(act_id)
Definition actions.h:425
#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:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
void citizens_update(struct city *pcity, struct player *plr)
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1856
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1236
bool is_capital(const struct city *pcity)
Definition city.c:1575
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1461
void city_size_add(struct city *pcity, int add)
Definition city.c:1160
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2008
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2047
bool city_exist(int id)
Definition city.c:3568
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:763
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_owner(_pcity_)
Definition city.h:563
#define city_list_iterate_end
Definition city.h:510
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2351
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1514
int build_points_left(struct city *pcity)
Definition citytools.c:571
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3052
void city_units_upkeep(const struct city *pcity)
Definition citytools.c:3140
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:369
void remove_city(struct city *pcity)
Definition citytools.c:1702
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Definition citytools.c:2918
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3550
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, const char *reason)
Definition cityturn.c:1030
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3438
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:761
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:770
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:613
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:839
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:74
#define MAX_LEN_MSG
Definition conn_types.h:37
#define MAX_LEN_ROUTE
Definition conn_types.h:38
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:366
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:356
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
#define conn_list_iterate_end
Definition connection.h:110
static void bombard(QVariant data1, QVariant data2)
Definition dialogs.cpp:2773
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:56
struct unit * actor_unit
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city * target_city
Definition dialogs_g.h:56
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:57
bool spy_escape(struct player *pplayer, struct unit *actor_unit, struct city *target_city, struct tile *target_tile, const struct action *paction)
Definition diplomats.c:2346
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1699
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
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:892
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1285
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1136
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1557
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:1837
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:324
bool diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:644
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:808
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:358
int Impr_type_id
Definition fc_types.h:380
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:374
int action_id
Definition fc_types.h:393
#define ACTRES_NONE
Definition fc_types.h:331
#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:386
#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:710
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:181
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:1966
const char * dir_get_name(enum direction8 dir)
Definition map.c:1161
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:462
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:636
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:1343
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:279
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2538
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:901
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:775
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:927
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:871
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1389
#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:292
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
@ UNIT_INFO_IDENTITY
Definition packets.h:67
void dlsend_packet_nuke_tile_info(struct conn_list *dest, int tile)
void lsend_packet_worker_task(struct conn_list *dest, const struct packet_worker_task *packet)
int dsend_packet_unit_actions(struct connection *pc, int actor_unit_id, int target_unit_id, int target_city_id, int target_tile_id, int target_extra_id, int request_kind, const struct act_prob *action_probabilities)
int send_packet_unit_short_info(struct connection *pc, const struct packet_unit_short_info *packet, bool force_to_send)
void lsend_packet_unit_combat_info(struct conn_list *dest, const struct packet_unit_combat_info *packet)
int dsend_packet_unit_action_answer(struct connection *pc, int actor_id, int target_id, int cost, action_id action_type, int request_kind)
int send_packet_unit_info(struct connection *pc, const struct packet_unit_info *packet)
int send_packet_unit_combat_info(struct connection *pc, const struct packet_unit_combat_info *packet)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
const char * player_name(const struct player *pplayer)
Definition player.c:895
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1104
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1337
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c: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:539
#define players_iterate(_pplayer)
Definition player.h:534
int normal_player_count(void)
Definition plrhand.c:3211
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2960
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1146
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3010
struct conn_list * player_reply_dest(struct player *pplayer)
Definition plrhand.c:1593
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2913
#define fc_rand(_size)
Definition rand.h:56
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
#define requirement_fulfilled_by_terrain(_ter_, _rqs_)
#define requirement_fulfilled_by_nation(_nat_, _rqs_)
struct research * research_get(const struct player *pplayer)
Definition research.c:128
#define sanity_check_city(x)
Definition sanitycheck.h:41
void script_server_signal_emit(const char *signal_name,...)
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
void spaceship_lost(struct player *pplayer)
Definition spacerace.c:431
@ SSHIP_STARTED
Definition spaceship.h:84
@ SSHIP_LAUNCHED
Definition spaceship.h:85
#define DEFAULT_SPECIALIST
Definition specialist.h:43
size_t size
Definition specvec.h:72
Definition agents.h:40
int distance
Definition unithand.c:107
struct player * no_war_with
Definition unithand.c:92
struct action * blocker
Definition unithand.c:104
const struct unit_type * no_tgt_utype
Definition unithand.c:101
struct terrain * no_act_terrain
Definition unithand.c:89
struct city * capacity_city
Definition unithand.c:86
struct player * peace_with
Definition unithand.c:95
struct nation_type * no_act_nation
Definition unithand.c:98
int gold_needed
Definition unithand.c:110
enum ane_kind kind
Definition unithand.c:82
Definition city.h:320
struct worker_task_list * task_reqs
Definition city.h:412
int id
Definition city.h:326
struct player * owner
Definition city.h:323
citizens * nationality
Definition city.h:341
citizens specialists[SP_MAX]
Definition city.h:336
struct tile * tile
Definition city.h:322
int upgrade_veteran_loss
Definition game.h:199
struct packet_ruleset_control control
Definition game.h:83
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
int occupychance
Definition game.h:170
struct civ_game::@31::@35 server
bool homecaughtunits
Definition game.h:188
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
struct unit::@80 orders
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
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::@81::@84 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:189
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define bool
Definition support.h:71
#define fc__fallthrough
Definition support.h:119
#define A_UNSET
Definition tech.h:48
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Definition techtools.c:293
void update_bulbs(struct player *pplayer, int bulbs, bool check_tech, bool free_bulbs)
Definition techtools.c:654
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:238
#define terrain_has_flag(terr, flag)
Definition terrain.h: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:2892
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:217
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1821
void free_unit_orders(struct unit *punit)
Definition unit.c:1807
bool unit_is_alive(int id)
Definition unit.c:2291
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1960
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1275
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2499
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2448
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2345
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:866
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:386
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2911
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:1133
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:893
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1115
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:2026
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2483
bool is_flagless_to_player(const struct unit *punit, const struct player *pplayer)
Definition unit.c:366
bool unit_has_orders(const struct unit *punit)
Definition unit.c:205
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:932
#define unit_tile(_pu)
Definition unit.h:397
@ ORDER_ACTIVITY
Definition unit.h:42
@ ORDER_PERFORM_ACTION
Definition unit.h:48
#define unit_owner(_pu)
Definition unit.h:396
@ 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:433
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:6685
#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:4142
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:3301
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4914
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4459
#define ACTION_PERFORM_UNIT_UNITS(action, actor, target, action_performer)
static bool do_unit_make_homeless(struct unit *punit, const struct action *paction)
Definition unithand.c: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:4287
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:6763
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:2514
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:5532
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:1409
#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:4338
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:6872
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:6613
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:3337
#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:5326
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:2990
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:1955
static const char * unit_tired_attack_string(const struct unit *punit)
Definition unithand.c:4867
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:1367
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Definition unithand.c:6550
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3167
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4554
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5679
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:4741
#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:6464
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:3317
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:1451
static bool do_action_activity(struct unit *punit, const struct action *paction)
Definition unithand.c:6599
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:6718
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:5413
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:4040
static bool tile_has_units_not_allied_to_but_seen_by(const struct tile *ptile, const struct player *pplayer)
Definition unithand.c:1349
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Definition unithand.c:6667
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:1313
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5872
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:4176
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:3186
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:4671
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:5570
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:2250
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Definition unithand.c:6357
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:4400
#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:4850
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:5641
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:6513
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5987
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:6643
static void unit_plans_clear(struct unit *punit)
Definition unithand.c:6448
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4238
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4504
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:1935
#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)
static const char * unit_firepower_if_not_one(int firepower)
Definition unithand.c:4889
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4829
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:3110
#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:356
void unit_did_action(struct unit *punit)
Definition unittools.c:5062
void collect_ransom(struct unit *pcollector, struct unit *punit, bool vet)
Definition unittools.c:2644
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Definition unittools.c:3067
void unit_make_contact(const struct unit *punit, struct tile *ptile, struct player *pplayer)
Definition unittools.c:5177
bool execute_orders(struct unit *punit, const bool fresh)
Definition unittools.c:4515
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1554
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:289
void combat_veterans(struct unit *attacker, struct unit *defender, bool powerless, int att_vet, int def_vet)
Definition unittools.c:401
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:3035
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Definition unittools.c:2734
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2865
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2878
void notify_unit_experience(struct unit *punit)
Definition unittools.c:744
void unit_activities_cancel(struct unit *punit)
Definition unittools.c:801
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:2815
void unit_forget_last_activity(struct unit *punit)
Definition unittools.c:1054
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:5001
void do_explore(struct unit *punit)
Definition unittools.c:3100
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3386
bool unit_can_do_action_now(const struct unit *punit)
Definition unittools.c:5029
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2140
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unittools.c:3136
void unit_transport_unload_send(struct unit *punit)
Definition unittools.c:3438
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2200
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1188
void unit_assign_specific_activity_target(struct unit *punit, enum unit_activity *activity, struct extra_type **target)
Definition unittools.c:1083
void unit_get_goods(struct unit *punit)
Definition unittools.c:1617
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:4075
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Definition unittools.c:2267
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1226
bool unit_activity_needs_target_from_client(enum unit_activity activity)
Definition unittools.c:1063
bool utype_may_act_tgt_city_tile(const struct unit_type *punit_type, const action_id act_id, const enum citytile_type prop, const bool is_there)
Definition unittype.c:1124
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1632
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1569
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1249
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1927
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1703
Unit_type_id utype_count(void)
Definition unittype.c:80
bool utype_can_do_act_when_ustate(const struct unit_type *punit_type, const action_id act_id, const enum ustate_prop prop, const bool is_there)
Definition unittype.c:955
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2498
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2583
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1219
bool utype_can_act_if_tgt_diplrel_tile_other(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1036
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1543
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1017
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1668
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1731
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h: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:859
#define unit_type_iterate_end
Definition unittype.h:866
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