Freeciv-3.4
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 (from_unittype == nullptr) {
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) {
203 notify_player(pplayer, nullptr, E_BAD_COMMAND, ftc_server,
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);
232
233 notify_player(pplayer, nullptr, E_UNIT_UPGRADED, ftc_server,
234 /* FIXME: plurality of number_of_upgraded_units ignored!
235 * (Plurality of unit names is messed up anyway.) */
236 /* TRANS: "2 Musketeers upgraded to Riflemen for 100 gold."
237 * Plurality is in gold (second %d), not units. */
238 PL_("%d %s upgraded to %s for %d gold.",
239 "%d %s upgraded to %s for %d gold.",
245 send_player_info_c(pplayer, pplayer->connections);
246 } else {
247 notify_player(pplayer, nullptr, E_UNIT_UPGRADED, ftc_server,
248 _("No units could be upgraded."));
249 }
250}
251
252/**********************************************************************/
258static bool do_unit_upgrade(struct player *pplayer,
259 struct unit *punit, struct city *pcity,
261 const struct action *paction)
262{
263 const struct unit_type *from_unit = unit_type_get(punit);
264 const struct unit_type *to_unit = can_upgrade_unittype(pplayer, from_unit);
265 int cost = unit_upgrade_price(pplayer, from_unit, to_unit);
266
268 pplayer->economic.gold -= cost;
269 send_player_info_c(pplayer, pplayer->connections);
270
271 if (ordered_by == ACT_REQ_PLAYER) {
273 PL_("%s upgraded to %s for %d gold.",
274 "%s upgraded to %s for %d gold.", cost),
277 cost);
278 }
279
280 return TRUE;
281}
282
283/**********************************************************************/
287static inline bool
288non_allied_not_listed_at(const struct player *pplayer,
289 const int *list, int n, const struct tile *ptile)
290{
291 unit_list_iterate(ptile->units, punit) {
292 if (!pplayers_allied(pplayer, unit_owner(punit))) {
293 bool listed = FALSE;
294 int id = punit->id;
295 int i;
296
297 for (i = 0; i < n; i++) {
298 if (id == list[i]) {
299 listed = TRUE;
300 break;
301 }
302 }
303 if (!listed) {
304 return TRUE;
305 }
306 }
308 return FALSE;
309}
310
311/**********************************************************************/
317static bool do_capture_units(struct player *pplayer,
318 struct unit *punit,
319 struct tile *pdesttile,
320 const struct action *paction)
321{
322 struct city *pcity;
324 char hcity_name[MAX_LEN_NAME] = {'\0'};
325 const char *capturer_nation = nation_plural_for_player(pplayer);
327 const struct unit_type *act_utype;
328 int id, hcity;
329 int n = 0, capt[unit_list_size(pdesttile->units)];
330 bool lost_with_city = FALSE;
331 int i;
332
333 /* Sanity check: The actor still exists. */
334 fc_assert_ret_val(pplayer, FALSE);
336 id = punit->id;
337
339
340 /* Sanity check: make sure that the capture won't result in the actor
341 * ending up with more than one unit of each unique unit type. */
344 bool unique_conflict = FALSE;
345
346 /* Check what the player already has. */
349 /* The player already has a unit of this kind. */
351 }
352
354 /* The type of the units at the tile must also be checked. Two allied
355 * players can both have their unique unit at the same tile.
356 * Capturing them both would give the actor two units of a kind that
357 * is supposed to be unique. */
358
360 /* There is another unit of the same kind at this tile. */
362 } else {
363 /* Remember the unit type in case another unit of the same kind is
364 * encountered later. */
366 }
367 }
368
369 if (unique_conflict) {
370 log_debug("capture units: already got unique unit");
372 /* TRANS: You can only have one Leader. */
373 _("You can only have one %s."),
375
376 return FALSE;
377 }
378 /* Remember the units here
379 * for the mess callbacks may do in the process of transferring */
380 capt[n++] = to_capture->id;
382
383 /* N.B: unit_link() always returns the same pointer. */
385
389 if (hcity) {
390 /* Rarely, we'll need it... */
392 }
393
394 for (i = 0; i < n; i++) {
396 struct player *uplayer;
397 const char *victim_link;
398 const struct unit_type *utype;
399 struct tile *ptile = nullptr;
400 bool really_lost = FALSE;
401
402 if (!to_capture) {
403 continue;
404 }
406 if (uplayer == pplayer) {
407 /* Somehow transferred by scripts (e.g. diplomat incited a city) */
408 continue;
409 }
410 utype = unit_type_get(to_capture);
412 uplayer->score.units_lost++;
413 if (!really_lost) {
414 /* A hack: if the captured unit is lost with a capturer's city,
415 * we link the old unit, otherwise the new one */
418 }
419 if (!to_capture) {
420 /* Lost during capturing */
422 } else {
423 /* As unit_change_owner() currently remove the old unit and
424 * replace by a new one (with a new id), we want to make link to
425 * the new unit. */
427 ptile = unit_tile(to_capture);
428 /* Notify capturer only if there is a gain */
430 /* TRANS: <unit> ... <unit> */
431 _("Your %s succeeded in capturing the %s %s."),
434 }
435
436 /* Notify loser */
439 /* TRANS: <unit> ... <Poles> */
440 _("Your %s was captured by the %s."),
442
443 /* May cause an incident */
446
447 if (really_lost) {
448 /* The city for which the unit was captured has perished! */
449 /* Nobody actually gets the unit. */
450 pplayer->score.units_lost++;
451 notify_player(pplayer, pdesttile,
453 _("%s lost along with control of %s."),
455 /* As in unit_change_owner(), don't say pplayer is killer */
457 continue;
458 }
459
460 if (to_capture != nullptr) {
462
463 if (pcity != nullptr /* Keep old behavior */
465 || (new_owner == pplayer
466 ? non_allied_not_listed_at(pplayer, capt + (i + 1),
467 n - (i + 1), ptile)
468 : (bool)
471 UTYF_FLAGLESS)))) {
472 /* The captured unit is in a city or with a foreign unit
473 * that its owner is not capturing. Bounce it. */
475 }
476 }
477
478 /* Check if the city we are going to home units in stays. */
479 if (hcity && i + 1 < n && !player_city_by_number(pplayer, hcity)) {
480 /* Oops, it's lost. Maybe the capturer is rehomed? */
481 if (player_unit_by_number(pplayer, id)) {
482 /* Well, it's natural to home them here now */
484 } else {
485 /* Removing the rest of the stack (except "NoHome" units) */
487 }
488 }
489 }
490
491 if (!unit_is_alive(id)) {
492 /* Callbacks took the capturer, nothing more to do */
493 return TRUE;
494 }
497
498 send_unit_info(nullptr, punit);
499
500 return TRUE;
501}
502
503/**********************************************************************/
506static bool occupy_move(struct tile *def_tile, struct unit *punit,
507 const struct action *paction)
508{
511 /* Hack: make sure the unit has enough moves_left for the move to succeed,
512 * and adjust moves_left to afterward (if successful). */
515 int id = punit->id;
516
518 /* Post attack occupy move. */
520 nullptr, nullptr, paction,
522 nullptr, nullptr) != nullptr) {
523 if (unit_is_alive(id)) {
524 int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
525
526 /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
527 * Attack SINGLE_COST is already calculated in to old_moves. */
528 punit->moves_left = old_moves - mcost;
529 if (punit->moves_left < 0) {
530 punit->moves_left = 0;
531 }
532 } else {
533 return FALSE;
534 }
535 } else if (unit_is_alive(id)) {
537 } else {
538 return FALSE;
539 }
540 }
541
542 return TRUE;
543}
544
545/**********************************************************************/
551static bool do_wipe_units(struct unit *punit,
552 struct tile *pdesttile,
553 const struct action *paction)
554{
555 struct player *wiper = unit_owner(punit);
556 int wid = punit->id;
559 const struct unit_type *act_utype = unit_type_get(punit);
560
561 /* N.B: unit_link() always returns the same pointer. */
563
565 struct player *owner = unit_owner(to_wipe);
566 const char *victim_link = unit_link(to_wipe);
567
569
570 /* Notify players */
572 /* TRANS: <unit> ... <unit> */
573 _("Your %s wiped the %s %s."),
578 /* TRANS: <unit> ... <Poles> */
579 _("Your %s was wiped by the %s."),
581
582 /* May cause an incident */
585
587
591
592 send_unit_info(nullptr, punit);
593 }
594
595 return TRUE;
596}
597
598/**********************************************************************/
604static bool do_expel_unit(struct player *pplayer,
605 struct unit *actor,
606 struct unit *target,
607 const struct action *paction)
608{
610 struct player *uplayer;
611 struct tile *target_tile;
612 struct city *pcity;
613 const struct unit_type *act_utype;
614
615 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
616 * the caller? Check in the code that emits the signal. */
617 fc_assert_ret_val(target, FALSE);
618
619 uplayer = unit_owner(target);
620
621 /* A unit is supposed to have an owner. */
623
624 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
625 * the caller? Check in the code that emits the signal. */
628
629 /* Where is the actor player? */
630 fc_assert_ret_val(pplayer, FALSE);
631
632 target_tile = unit_tile(target);
633
634 /* Expel the target unit to its owner's primary capital. */
635 /* TODO: Could be also nearest secondary capital */
637
638 /* N.B: unit_link() always returns the same pointer. */
640
641 if (pcity == nullptr) {
642 /* No where to send the expelled unit. */
643
644 /* The price of failing an expulsion is a single move. */
646 send_unit_info(nullptr, actor);
647
648 /* Notify the actor player. */
650 /* TRANS: <Poles> <Spy> */
651 _("The %s don't have a capital to expel their %s to."),
653
654 /* Nothing more could be done. */
655 return FALSE;
656 }
657
658 /* Please review the code below and above (including the strings sent to
659 * the players) before allowing expulsion to non capital cities. */
661
662 /* Notify everybody involved. */
664 /* TRANS: <Border Patrol> ... <Spy> */
665 _("Your %s succeeded in expelling the %s %s."),
669 /* TRANS: <unit> ... <Poles> */
670 _("Your %s was expelled by the %s."),
672
673 /* Being expelled destroys all remaining movement. */
674 if (!teleport_unit_to_city(target, pcity, 0, FALSE)) {
675 log_error("Bug in unit expulsion: unit can't teleport.");
676
677 return FALSE;
678 }
679
680 /* This may cause a diplomatic incident */
683
684 /* Mission accomplished. */
685 return TRUE;
686}
687
688/**********************************************************************/
695 struct unit *act_unit,
696 struct tile *tgt_tile,
697 const struct action *paction)
698{
699 bool success;
700 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
702
703 /* Sanity check */
706
707 unit_move(act_unit, tgt_tile, move_cost,
708 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
709 FALSE, TRUE,
712
714
715 if (success) {
716 const struct unit_type *act_utype = unit_type_get(act_unit);
717
718 /* May cause an incident */
722 }
723
724 return success;
725}
726
727/**********************************************************************/
733static bool do_heal_unit(struct player *act_player,
734 struct unit *act_unit,
735 struct unit *tgt_unit,
736 const struct action *paction)
737{
738 int healing_limit;
739 int tgt_hp_max;
740 struct player *tgt_player;
741 struct tile *tgt_tile;
744 const char *tgt_unit_owner;
745 const struct unit_type *act_utype;
746
747 /* Sanity checks: got all the needed input. */
751
753
754 /* The target unit can't have more HP than this. */
756
757 /* Sanity check: target isn't at full health and can therefore can be
758 * healed. */
760
761 /* Fetch the target unit's owner. */
764
765 /* Fetch the target unit's tile. */
768
769 /* The max amount of HP that can be added. */
771 nullptr,
772 &(const struct req_context) {
773 .player = unit_owner(act_unit),
774 .city = tile_city(unit_tile(act_unit)),
776 .unit = act_unit,
777 .unittype = unit_type_get(act_unit),
778 .action = paction,
779 },
780 &(const struct req_context) {
781 .player = unit_owner(tgt_unit),
782 .city = tile_city(unit_tile(tgt_unit)),
784 .unit = tgt_unit,
785 .unittype = unit_type_get(tgt_unit),
786 },
788 ) + 100)
789 * tgt_hp_max) / 100;
790
791 /* Heal the target unit. */
793 send_unit_info(nullptr, tgt_unit);
794
795 send_unit_info(nullptr, act_unit);
796
797 /* Every call to unit_link() overwrites the previous. Two units are being
798 * linked to. */
801
802 /* Notify everybody involved. */
803 if (act_player == tgt_player) {
804 /* TRANS: used instead of nation adjective when the nation is
805 * domestic. */
806 tgt_unit_owner = _("your");
807 } else {
809 }
810
812 /* TRANS: If foreign: Your Leader heals Finnish Warrior.
813 * If domestic: Your Leader heals your Warrior. */
814 _("Your %s heals %s %s."),
816
817 if (act_player != tgt_player) {
819 /* TRANS: Norwegian ... Leader ... Warrior */
820 _("%s %s heals your %s."),
823 }
824
825 /* This may have diplomatic consequences. */
828
829 return TRUE;
830}
831
832/**********************************************************************/
839 struct unit *act_unit,
840 struct unit *tgt_unit,
841 const struct action *paction)
842{
843 /* Unload the unit and send out info to clients. */
845
846 return TRUE;
847}
848
849/**********************************************************************/
857static bool do_unit_board(struct player *act_player,
858 struct unit *act_unit,
859 struct unit *tgt_unit,
860 const struct action *paction)
861{
864 }
865
866 /* Load the unit and send out info to clients. */
868
869 return TRUE;
870}
871
872/**********************************************************************/
880static bool do_unit_load(struct player *act_player,
881 struct unit *act_unit,
882 struct unit *tgt_unit,
883 const struct action *paction)
884{
887 }
888
889 /* Load the unit and send out info to clients. */
891
892 return TRUE;
893}
894
895/**********************************************************************/
901static bool do_unit_unload(struct player *act_player,
902 struct unit *act_unit,
903 struct unit *tgt_unit,
904 const struct action *paction)
905{
906 /* Unload the unit and send out info to clients. */
908
909 return TRUE;
910}
911
912/**********************************************************************/
918static bool do_disembark(struct player *act_player,
919 struct unit *act_unit,
920 struct tile *tgt_tile,
921 const struct action *paction)
922{
923 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
924
925 /* Sanity checks */
930
931 unit_move(act_unit, tgt_tile, move_cost,
932 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
933 FALSE, FALSE,
936
937 return TRUE;
938}
939
940/**********************************************************************/
946static bool do_unit_hut(struct player *act_player,
947 struct unit *act_unit,
948 struct tile *tgt_tile,
949 const struct action *paction)
950{
951 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
952
953 /* Sanity checks */
958
959 unit_move(act_unit, tgt_tile, move_cost,
960 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
961 FALSE, FALSE,
964
965 return TRUE;
966}
967
968/**********************************************************************/
976static bool do_unit_embark(struct player *act_player,
977 struct unit *act_unit,
978 struct unit *tgt_unit,
979 const struct action *paction)
980{
981 struct tile *tgt_tile;
982 int move_cost;
983
984 /* Sanity checks */
989
991 /* Assumed to be legal. */
993 }
994
995 /* Do it. */
997 move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
998 unit_move(act_unit, tgt_tile, move_cost,
999 tgt_unit, BV_ISSET(paction->sub_results,
1001 FALSE, FALSE,
1002 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
1004
1005 return TRUE;
1006}
1007
1008/**********************************************************************/
1014 const struct action *paction)
1015{
1017
1019}
1020
1021/**********************************************************************/
1028static bool rel_may_become_war(const struct player *pplayer,
1029 const struct player *oplayer)
1030{
1031 enum diplstate_type ds;
1032
1033 fc_assert_ret_val(pplayer, FALSE);
1035
1036 ds = player_diplstate_get(pplayer, oplayer)->type;
1037
1038 /* The player can't declare war on
1039 * someone they already are at war with. */
1040 return ds != DS_WAR
1041 /* The player can't declare war on a teammate or on themself. */
1042 && ds != DS_TEAM && pplayer != oplayer;
1043}
1044
1045/**********************************************************************/
1051static bool
1053 const struct action *paction,
1054 struct player *player1,
1055 struct player *player2,
1056 bool act_if_diplrel_kind(const struct unit_type *,
1057 const action_id,
1058 const int,
1059 const bool))
1060{
1061 if (player2 == nullptr) {
1062 /* No one to declare war on */
1063 return FALSE;
1064 }
1065
1067 /* Can't declare war. */
1068 return FALSE;
1069 }
1070
1073 player2)->type,
1074 TRUE)) {
1075 /* The current diplrel isn't the problem. */
1076 return FALSE;
1077 }
1078
1080 /* War won't make this action legal. */
1081 return FALSE;
1082 }
1083
1084 return TRUE;
1085}
1086
1087/**********************************************************************/
1093static struct player *need_war_player_hlp(const struct unit *actor,
1094 const action_id act,
1095 const struct tile *target_tile,
1096 const struct city *target_city,
1097 const struct unit *target_unit)
1098{
1099 struct player *target_player = nullptr;
1101 struct action *paction = action_by_number(act);
1102
1103 fc_assert_ret_val(paction != nullptr, nullptr);
1104
1105 if (action_id_get_actor_kind(act) != AAK_UNIT) {
1106 /* No unit can ever do this action so it isn't relevant. */
1107 return nullptr;
1108 }
1109
1110 if (!unit_can_do_action(actor, act)) {
1111 /* The unit can't do the action no matter if there is war or not. */
1112 return nullptr;
1113 }
1114
1115 /* Look for hard coded war requirements without support for looking up in
1116 * an action enabler requirement. */
1117 switch (paction->result) {
1118 case ACTRES_ATTACK:
1119 case ACTRES_WIPE_UNITS:
1122 /* Target is a unit stack but a city can block it. */
1124
1126 if (target_tile != nullptr) {
1127 struct city *tcity;
1128
1129 if ((tcity = tile_city(target_tile))
1131 return city_owner(tcity);
1132 }
1133 }
1134 }
1135 break;
1136
1137 case ACTRES_PARADROP:
1139 /* Target is a tile but a city can block it. */
1141 if (target_tile != nullptr
1143 /* Seen tile unit savers */
1144
1145 struct city *tcity;
1146
1148 return city_owner(tcity);
1149 }
1150 }
1151 break;
1155 case ACTRES_SPY_POISON:
1164 case ACTRES_TRADE_ROUTE:
1165 case ACTRES_MARKETPLACE:
1166 case ACTRES_HELP_WONDER:
1169 case ACTRES_CAPTURE_UNITS: /* Only foreign is a hard req. */
1170 case ACTRES_FOUND_CITY:
1171 case ACTRES_JOIN_CITY:
1172 case ACTRES_STEAL_MAPS:
1173 case ACTRES_SPY_NUKE:
1174 case ACTRES_NUKE:
1175 case ACTRES_NUKE_UNITS:
1177 case ACTRES_EXPEL_UNIT:
1180 case ACTRES_HOME_CITY:
1181 case ACTRES_HOMELESS:
1183 case ACTRES_AIRLIFT:
1184 case ACTRES_HEAL_UNIT:
1187 case ACTRES_BOMBARD:
1190 case ACTRES_CULTIVATE:
1191 case ACTRES_PLANT:
1192 case ACTRES_PILLAGE:
1193 case ACTRES_CLEAN:
1194 case ACTRES_FORTIFY:
1195 case ACTRES_CONVERT:
1196 case ACTRES_ROAD:
1197 case ACTRES_BASE:
1198 case ACTRES_MINE:
1199 case ACTRES_IRRIGATE:
1206 case ACTRES_SPY_ATTACK:
1207 case ACTRES_HUT_ENTER:
1209 case ACTRES_UNIT_MOVE:
1210 case ACTRES_TELEPORT:
1213 case ACTRES_SPY_ESCAPE:
1214 case ACTRES_NONE:
1215 /* No special help. */
1216 break;
1217
1219 }
1220
1221 /* Look for war requirements from the action enablers. */
1223 case ATK_CITY:
1224 if (target_city == nullptr) {
1225 /* No target city. */
1226 return nullptr;
1227 }
1228
1230 break;
1231 case ATK_UNIT:
1232 if (target_unit == nullptr) {
1233 /* No target unit. */
1234 return nullptr;
1235 }
1237 /* Target unit is flagless anyway - no war needed */
1238 return nullptr;
1239 }
1240
1242 break;
1243 case ATK_STACK:
1244 if (target_tile == nullptr) {
1245 /* No target units since no target tile. */
1246 return nullptr;
1247 }
1248
1249 unit_list_iterate(target_tile->units, tunit) {
1252 target_player = unit_owner(tunit);
1253 break;
1254 }
1256 break;
1257 case ATK_TILE:
1258 if (target_tile == nullptr) {
1259 /* No target tile. */
1260 return nullptr;
1261 }
1263 break;
1264 case ATK_EXTRAS:
1265 if (target_tile == nullptr) {
1266 /* No target tile. */
1267 return nullptr;
1268 }
1270 break;
1271 case ATK_SELF:
1272 /* Can't declare war on itself. */
1273 return nullptr;
1274 break;
1275 case ATK_COUNT:
1276 /* Nothing to check. */
1278 return nullptr;
1279 }
1280
1281 if (target_player == nullptr) {
1282 /* Declaring war won't enable the specified action. */
1283 return nullptr;
1284 }
1285
1286 /* Look for DiplRelTileOther war requirements from the action enablers. */
1287 if (target_tile != nullptr
1291 return tile_owner(target_tile);
1292 }
1293
1294 /* Look for DiplRel war requirements from the action enablers. */
1298 return target_player;
1299 }
1300
1301 /* No check if other, non war, diplomatic states also could make the
1302 * action legal. This is need_war_player() so war is always the answer.
1303 * If you disagree and decide to add support please check that
1304 * rules like former webperimental ruleset's
1305 * "can't found a city on a tile belonging to a non enemy"
1306 * are still detected. */
1307
1308 return nullptr;
1309}
1310
1311/**********************************************************************/
1316static struct player *need_war_player(const struct unit *actor,
1317 const action_id act_id,
1318 const struct tile *target_tile,
1319 const struct city *target_city,
1320 const struct unit *target_unit)
1321{
1322 if (act_id == ACTION_ANY) {
1323 /* Any action at all will do. */
1324 action_iterate(act) {
1325 struct player *war_player;
1326
1329 target_unit);
1330
1331 if (war_player != nullptr) {
1332 /* Declaring war on this player may enable this action. */
1333 return war_player;
1334 }
1336
1337 /* No action at all may be enabled by declaring war. */
1338 return nullptr;
1339 } else {
1340 /* Look for the specified action. */
1341 return need_war_player_hlp(actor, act_id,
1343 target_unit);
1344 }
1345}
1346
1347/**********************************************************************/
1351static bool
1353 const struct player *pplayer)
1354{
1355 unit_list_iterate(ptile->units, pother) {
1356 if (can_player_see_unit(pplayer, pother)
1357 && !pplayers_allied(pplayer, unit_owner(pother))) {
1358 return TRUE;
1359 }
1361
1362 return FALSE;
1363}
1364
1365/**********************************************************************/
1370static bool does_terrain_block_action(const action_id act_id,
1371 bool is_target,
1372 struct unit *actor_unit,
1373 struct terrain *pterrain)
1374{
1375 if (act_id == ACTION_ANY) {
1376 /* Any action is OK. */
1379 && !does_terrain_block_action(alt_act, is_target,
1380 actor_unit, pterrain)) {
1381 /* Only one action has to be possible. */
1382 return FALSE;
1383 }
1385
1386 /* No action enabled. */
1387 return TRUE;
1388 }
1389
1390 /* ACTION_ANY is handled above. */
1392
1394 enabler) {
1396 (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1398 &enabler->actor_reqs)) {
1399 /* This terrain kind doesn't block this action enabler. */
1400 return FALSE;
1401 }
1403
1404 return TRUE;
1405}
1406
1407/**********************************************************************/
1412static bool does_nation_block_action(const action_id act_id,
1413 bool is_target,
1414 struct unit *actor_unit,
1415 struct nation_type *pnation)
1416{
1417 if (act_id == ACTION_ANY) {
1418 /* Any action is OK. */
1421 && !does_nation_block_action(alt_act, is_target,
1422 actor_unit, pnation)) {
1423 /* Only one action has to be possible. */
1424 return FALSE;
1425 }
1427
1428 /* No action enabled. */
1429 return TRUE;
1430 }
1431
1432 /* ACTION_ANY is handled above. */
1434
1436 enabler) {
1438 (is_target ? &enabler->target_reqs
1439 : &enabler->actor_reqs))
1441 &enabler->actor_reqs)) {
1442 /* This nation doesn't block this action enabler. */
1443 return FALSE;
1444 }
1446
1447 return TRUE;
1448}
1449
1450/**********************************************************************/
1454static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1455 const action_id act_id,
1456 const struct tile *target_tile,
1457 const struct city *target_city,
1458 const struct unit *target_unit)
1459{
1460 struct player *must_war_player;
1461 const struct action *paction;
1462 struct action *blocker;
1463 struct player *act_player = unit_owner(punit);
1464 struct player *tgt_player = nullptr;
1465 struct ane_expl *explnat = fc_malloc(sizeof(struct ane_expl));
1466 struct civ_map *nmap = &(wld.map);
1469 int action_custom;
1470
1471 /* Not know yet. (Initialize before the below check.) */
1472 explnat->kind = ANEK_UNKNOWN;
1473
1474 paction = action_by_number(act_id);
1475
1476 if (act_id != ACTION_ANY) {
1477 /* A specific action should have a suitable target. */
1479 case ATK_CITY:
1480 if (target_city == nullptr) {
1482 }
1483 break;
1484 case ATK_UNIT:
1485 if (target_unit == nullptr) {
1487 }
1488 break;
1489 case ATK_STACK:
1490 case ATK_TILE:
1491 case ATK_EXTRAS:
1492 if (target_tile == nullptr) {
1494 }
1495 break;
1496 case ATK_SELF:
1497 /* No other target. */
1498 break;
1499 case ATK_COUNT:
1501 break;
1502 }
1503 }
1504
1505 if (explnat->kind == ANEK_MISSING_TARGET) {
1506 /* No point continuing. */
1507 return explnat;
1508 }
1509
1510 if (act_id == ACTION_ANY) {
1511 /* Find the target player of some actions. */
1512 if (target_city) {
1513 /* Individual city targets have the highest priority. */
1515 } else if (target_unit) {
1516 /* Individual unit targets have the next priority. */
1518 } else if (target_tile) {
1519 /* Tile targets have the lowest priority. */
1521 }
1522 } else {
1523 /* Find the target player of this action. */
1525 case ATK_CITY:
1527 break;
1528 case ATK_UNIT:
1530 break;
1531 case ATK_TILE:
1533 break;
1534 case ATK_EXTRAS:
1535 tgt_player = target_tile->extras_owner;
1536 break;
1537 case ATK_STACK:
1538 /* A unit stack may contain units with multiple owners. Pick the
1539 * first one. */
1540 if (target_tile
1541 && unit_list_size(target_tile->units) > 0) {
1543 }
1544 break;
1545 case ATK_SELF:
1546 /* A unit acting against itself. */
1548 break;
1549 case ATK_COUNT:
1551 break;
1552 }
1553 }
1554
1555 if (act_id == ACTION_ANY) {
1556 action_custom = 0;
1557 } else {
1558 switch (paction->result) {
1561 break;
1562 case ACTRES_AIRLIFT:
1564 target_city);
1565 break;
1566 case ACTRES_NUKE_UNITS:
1568 target_tile);
1569 break;
1570 case ACTRES_ATTACK:
1572 target_tile);
1573 break;
1574 case ACTRES_WIPE_UNITS:
1576 break;
1578 if (target_city) {
1580 punit->activity,
1583 FALSE, FALSE, nullptr, TRUE);
1584 } else {
1586 }
1587 break;
1589 if (target_unit) {
1591 punit->activity,
1594 FALSE, TRUE, nullptr, FALSE);
1595 } else {
1597 }
1598 break;
1600 case ACTRES_HUT_ENTER:
1603 case ACTRES_UNIT_MOVE:
1604 if (target_tile) {
1606 punit->activity,
1609 FALSE, FALSE, nullptr, FALSE);
1610 } else {
1612 }
1613 break;
1614 case ACTRES_TELEPORT:
1615 if (target_tile != nullptr) {
1617 punit->activity,
1620 FALSE, nullptr, FALSE);
1621 } else {
1623 }
1624 break;
1625 default:
1626 action_custom = 0;
1627 break;
1628 }
1629 }
1630
1631 if (!unit_can_do_action(punit, act_id)) {
1632 explnat->kind = ANEK_ACTOR_UNIT;
1634 && tile_city(target_tile)) {
1635 explnat->kind = ANEK_BAD_TARGET;
1639 act_player)) {
1641 } else if ((!can_exist
1644 || (can_exist
1648 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1649 } else if ((!on_native
1652 || (on_native
1654 USP_NATIVE_TILE, TRUE))) {
1656 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1657 } else if (punit
1660 /* No action enabler allows acting against this terrain kind. */
1662 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1664 && target_tile
1666 TER_NO_CITIES)) {
1668 explnat->no_act_terrain = tile_terrain(target_tile);
1671 && target_tile != nullptr
1673 V_MAIN)
1675 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
1678 explnat->no_act_terrain = tile_terrain(target_tile);
1679 } else if (target_tile
1682 /* No action enabler allows acting against this terrain kind. */
1684 explnat->no_act_terrain = tile_terrain(target_tile);
1685 } else if (unit_transported(punit)
1689 } else if (!unit_transported(punit)
1693 } else if (0 < get_transporter_occupancy(punit)
1697 } else if (!(0 < get_transporter_occupancy(punit))
1701 } else if ((punit->homecity > 0)
1705 } else if ((punit->homecity <= 0)
1709 } else if ((punit->homecity <= 0)
1713 } else if (act_player && tgt_player
1715 == DS_PEACE)
1717 act_id,
1718 DS_PEACE,
1719 FALSE)
1721 act_id,
1722 DS_PEACE,
1723 TRUE)) {
1724 explnat->kind = ANEK_PEACE;
1725 explnat->peace_with = tgt_player;
1727 act_id,
1730 target_unit)) != nullptr) {
1731 explnat->kind = ANEK_NO_WAR;
1732 explnat->no_war_with = must_war_player;
1733 } else if (action_mp_full_makes_legal(punit, act_id)) {
1734 explnat->kind = ANEK_LOW_MP;
1735 } else if (tgt_player != nullptr
1738 act_id,
1740 TRUE)) {
1741 explnat->kind = ANEK_FOREIGN;
1742 } else if (tgt_player != nullptr
1745 act_id,
1747 FALSE)) {
1748 explnat->kind = ANEK_DOMESTIC;
1749 } else if (punit != nullptr
1751 punit, act_player->nation)) {
1752 explnat->kind = ANEK_NATION_ACT;
1753 explnat->no_act_nation = act_player->nation;
1754 } else if (tgt_player
1755 && does_nation_block_action(act_id, TRUE,
1756 punit, tgt_player->nation)) {
1757 explnat->kind = ANEK_NATION_TGT;
1758 explnat->no_act_nation = tgt_player->nation;
1759 } else if ((target_tile && tile_city(target_tile))
1761 act_id,
1763 TRUE)) {
1765 } else if ((target_tile && !tile_city(target_tile))
1767 act_id,
1769 FALSE)) {
1771 } else if ((target_tile && tile_owner(target_tile) != nullptr)
1773 act_id,
1775 TRUE)) {
1777 } else if ((target_tile && tile_owner(target_tile) == nullptr)
1779 act_id,
1781 FALSE)) {
1783 } else if (paction && punit
1784 && ((target_tile
1787 || (target_city
1791 || (target_unit
1794 unit_tile(target_unit)))))) {
1795 explnat->kind = ANEK_DISTANCE_FAR;
1796 explnat->distance = paction->max_distance;
1799 && punit && target_tile
1801 > unit_type_get(punit)->paratroopers_range) {
1802 explnat->kind = ANEK_DISTANCE_FAR;
1804 } else if (paction && punit
1805 && ((target_tile
1807 < paction->min_distance)
1808 || (target_city
1811 < paction->min_distance)
1812 || (target_unit
1815 < paction->min_distance))) {
1817 explnat->distance = paction->min_distance;
1818 } else if (target_city
1824 /* TODO: Check max city size requirements from action enabler target
1825 * vectors. */
1826 explnat->kind = ANEK_CITY_TOO_BIG;
1827 } else if (target_city
1833 + unit_pop_value(punit))))) {
1835 } else if (target_city
1840 && MAX_CITY_SIZE
1841 <= target_city->specialists
1842 [specialist_index(unit_type_get(punit)->spec_type)])) {
1847 && action_custom != ATT_OK) {
1848 switch (action_custom) {
1849 case ATT_NON_ATTACK:
1850 explnat->kind = ANEK_ACTOR_UNIT;
1851 break;
1852 case ATT_UNREACHABLE:
1854 break;
1855 case ATT_NONNATIVE_SRC:
1857 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1858 break;
1859 case ATT_NONNATIVE_DST:
1861 explnat->no_act_terrain = tile_terrain(target_tile);
1862 break;
1863 case ATT_NOT_WIPABLE:
1864 explnat->kind = ANEK_NOT_WIPABLE;
1865 break;
1866 default:
1868 explnat->kind = ANEK_UNKNOWN;
1869 break;
1870 }
1874 explnat->capacity_city = tile_city(unit_tile(punit));
1878 explnat->capacity_city = game_city_by_number(target_city->id);
1884 && target_tile != nullptr
1896 && action_custom != MR_OK) {
1897 switch (action_custom) {
1900 break;
1901 case MR_TRIREME:
1902 explnat->kind = ANEK_TRIREME_MOVE;
1903 break;
1906 break;
1907 default:
1909 explnat->kind = ANEK_UNKNOWN;
1910 break;
1911 }
1916 explnat->no_tgt_utype = unit_type_get(target_unit);
1917 } else if ((game.scenario.prevent_new_cities
1920 || act_id == ACTION_ANY)) {
1921 /* Please add a check for any new action forbidding scenario setting
1922 * above this comment. */
1925 && action_custom == UU_NO_MONEY) {
1926 const struct unit_type *act_utype = unit_type_get(punit);
1927
1932 } else if (paction
1933 && (blocker = action_is_blocked_by(nmap, paction, punit,
1935 target_unit))) {
1937 explnat->blocker = blocker;
1938 } else {
1939 explnat->kind = ANEK_UNKNOWN;
1940 }
1941
1942 return explnat;
1943}
1944
1945/**********************************************************************/
1949 action_id act_id,
1950 const struct tile *target_tile,
1951 const struct city *target_city,
1952 const struct unit *target_unit)
1953{
1954 struct ane_expl *explnat = expl_act_not_enabl(punit, act_id,
1957 enum ane_kind out = explnat->kind;
1958
1959 free(explnat);
1960
1961 return out;
1962}
1963
1964/**********************************************************************/
1969 const struct tile *target_tile,
1970 const struct city *target_city,
1971 const struct unit *target_unit)
1972{
1973 struct player *pplayer = unit_owner(punit);
1977 const struct civ_map *nmap = &(wld.map);
1978
1979 switch (explnat->kind) {
1980 case ANEK_ACTOR_UNIT:
1981 /* This shouldn't happen unless the client is buggy given the current
1982 * users. */
1984 "Asked to explain why a non actor can't act.");
1985
1987 _("Unit cannot do anything."));
1988 break;
1991 _("Your %s found no suitable target."),
1993 break;
1994 case ANEK_BAD_TARGET:
1995 /* This shouldn't happen at the moment. Only specific action checks
1996 * will trigger bad target checks. This is a reply to a question about
1997 * any action. */
1999
2001 _("Your %s found no suitable target."),
2003 break;
2005 {
2006 const char *types[utype_count()];
2007 int i = 0;
2008
2011 FALSE)
2013 unit_type_iterate(utype) {
2016 types[i++] = utype_name_translation(utype);
2017 }
2019 }
2020
2021 if (0 < i) {
2022 struct astring astr = ASTRING_INIT;
2023
2024 notify_player(pplayer, unit_tile(punit),
2026 /* TRANS: terrain name
2027 * "Your Diplomat cannot act from Ocean. Only
2028 * Spy or Partisan ... */
2029 _("Your %s cannot act from %s. "
2030 "Only %s can act from a non livable tile."),
2032 terrain_name_translation(explnat->no_act_terrain),
2033 astr_build_or_list(&astr, types, i));
2034
2035 astr_free(&astr);
2036 } else {
2038 /* TRANS: terrain name */
2039 _("Unit cannot act from %s."),
2040 terrain_name_translation(explnat->no_act_terrain));
2041 }
2042 }
2043 break;
2046 /* TRANS: terrain name */
2047 _("Unit cannot act against %s."),
2048 terrain_name_translation(explnat->no_act_terrain));
2049 break;
2052 _("This unit is being transported, and"
2053 " so cannot act."));
2054 break;
2057 _("This unit cannot act when it isn't being "
2058 "transported."));
2059 break;
2062 _("This unit is transporting, and"
2063 " so cannot act."));
2064 break;
2067 _("This unit cannot act when it isn't transporting."));
2068 break;
2071 _("This unit has a home city, and so cannot act."));
2072 break;
2075 _("This unit cannot act unless it has a home city."));
2076 break;
2077 case ANEK_NO_WAR:
2079 _("You must declare war on %s first. Try using "
2080 "the Nations report"
2082 " (F3)"
2083#endif /* FREECIV_WEB */
2084 "."),
2085 player_name(explnat->no_war_with));
2086 break;
2087 case ANEK_PEACE:
2089 _("You must break peace with %s first. Try using "
2090 "the Nations report to declare war"
2092 " (F3)"
2093#endif /* FREECIV_WEB */
2094 "."),
2095 player_name(explnat->peace_with));
2096 break;
2097 case ANEK_DOMESTIC:
2099 _("This unit cannot act against domestic targets."));
2100 break;
2101 case ANEK_FOREIGN:
2103 _("This unit cannot act against foreign targets."));
2104 break;
2107 /* TRANS: Riflemen */
2108 _("%s cannot act against tiles with non allied units."),
2110 break;
2111 case ANEK_NATION_ACT:
2113 /* TRANS: Swedish ... Riflemen */
2114 _("%s %s cannot act."),
2115 nation_adjective_translation(explnat->no_act_nation),
2117 break;
2118 case ANEK_NATION_TGT:
2120 /* TRANS: ... Pirate ... */
2121 _("This unit cannot act against %s targets."),
2122 nation_adjective_translation(explnat->no_act_nation));
2123 break;
2124 case ANEK_LOW_MP:
2126 _("This unit has too few moves left to act."));
2127 break;
2130 _("This unit cannot act against city centers."));
2131 break;
2134 _("This unit cannot act against non city centers."));
2135 break;
2138 _("This unit cannot act against claimed tiles."));
2139 break;
2142 _("This unit cannot act against unclaimed tiles."));
2143 break;
2144 case ANEK_DISTANCE_NEAR:
2146 _("This unit is too near its target to act."));
2147 break;
2148 case ANEK_DISTANCE_FAR:
2150 _("This unit is too far away from its target to act."));
2151 break;
2154 _("Can't perform any action this scenario permits."));
2155 break;
2158 _("Can't perform any action this close to a city."));
2159 break;
2160 case ANEK_CITY_TOO_BIG:
2162 /* TRANS: Settler ... Berlin */
2163 _("%s can't do anything to %s. It is too big."),
2166 break;
2169 /* TRANS: London ... Settlers */
2170 _("%s needs an improvement to grow, so "
2171 "%s cannot do anything to it."),
2174 break;
2177 /* TRANS: Paris ... Warriors (think: airlift) */
2178 _("%s don't have enough capacity, so "
2179 "%s cannot do anything."),
2180 city_name_get(explnat->capacity_city),
2182 break;
2185 /* TRANS: Paratroopers ... */
2186 _("%s can't do anything to an unknown target tile."),
2188 break;
2190 {
2191 char tbuf[MAX_LEN_MSG];
2192
2193 /* TRANS: Used below. Separate so treasury content too can determine
2194 * if this is plural. */
2195 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2196 "Treasury contains %d gold.",
2197 pplayer->economic.gold),
2198 pplayer->economic.gold);
2199
2201 /* TRANS: "Spy can't do anything. 154 gold may help.
2202 * Treasury contains 100 gold." */
2203 PL_("%s can't do anything. %d gold may help. %s",
2204 "%s can't do anything. %d gold may help. %s",
2205 explnat->gold_needed),
2207 explnat->gold_needed, tbuf);
2208 }
2209 break;
2210 case ANEK_TRIREME_MOVE:
2212 _("%s cannot move that far from the coast line."),
2213 unit_link(punit));
2214 break;
2215 case ANEK_DISEMBARK_ACT:
2217 _("%s cannot disembark outside of a city or a native base "
2218 "for %s."),
2222 break;
2225 _("%s can't do anything since there is an unreachable "
2226 "unit."),
2228 break;
2229 case ANEK_NOT_WIPABLE:
2231 _("%s can't do anything since there is unit with a positive "
2232 "defense value."),
2234 break;
2237 _("%s can't do anything since you already have a %s."),
2239 utype_name_translation(explnat->no_tgt_utype));
2240 break;
2241 case ANEK_ACTION_BLOCKS:
2242 /* If an action blocked another action the blocking action must be
2243 * possible. */
2245 fc__fallthrough; /* Fall through to unknown cause. */
2246 case ANEK_UNKNOWN:
2248 _("No action possible."));
2249 break;
2250 }
2251
2252 free(explnat);
2253}
2254
2255/**********************************************************************/
2264 const int actor_unit_id,
2265 const int target_unit_id_client,
2266 const int target_tile_id,
2267 const int target_extra_id_client,
2268 const int request_kind)
2269{
2270 struct player *actor_player;
2271 struct unit *actor_unit;
2272 struct tile *target_tile;
2274 struct unit *target_unit;
2275 struct city *target_city;
2276 struct extra_type *target_extra;
2278 const struct player_tile *plrtile;
2280 const struct civ_map *nmap = &(wld.map);
2281
2282 /* No potentially legal action is known yet. If none is found the player
2283 * should get an explanation. */
2285
2286 /* A target should only be sent if it is possible to act against it */
2287 int target_city_id = IDENTITY_NUMBER_ZERO;
2288 int target_unit_id = IDENTITY_NUMBER_ZERO;
2289
2290 actor_player = pc->playing;
2292 target_tile = index_to_tile(nmap, target_tile_id);
2293
2294 /* Initialize the action probabilities. */
2295 action_iterate(act) {
2298
2299 /* Check if the request is valid. */
2301 || actor_unit->owner != actor_player) {
2304 target_tile_id, target_extra_id,
2305 request_kind,
2307 return;
2308 }
2309
2310 /* Select the targets. */
2311
2313 /* Find a new target unit. */
2315 } else {
2316 /* Prepare the client selected target unit. */
2318 }
2319
2320 /* Find the target city. */
2322
2323 /* The specified target unit must be located at the target tile. */
2327 _("Target not at target tile."));
2330 target_tile_id, target_extra_id,
2331 request_kind,
2333 return;
2334 }
2335
2337 /* See if a target extra can be found. */
2339 } else {
2340 /* Use the client selected target extra. */
2342 }
2343
2344 /* The player may have outdated information about the target tile.
2345 * Limiting the player knowledge look up to the target tile is OK since
2346 * all targets must be located at it. */
2348
2349 /* Distance between actor and target tile. */
2351 target_tile);
2352
2353 /* Find out what can be done to the targets. */
2354
2355 /* Set the probability for the actions. */
2357 if (action_id_get_actor_kind(act) != AAK_UNIT) {
2358 /* Not relevant. */
2359 continue;
2360 }
2361
2362 switch (action_id_get_target_kind(act)) {
2363 case ATK_CITY:
2364 if (plrtile && plrtile->site) {
2365 /* Only a known city may be targeted. */
2366 if (target_city) {
2367 /* Calculate the probabilities. */
2369 target_city);
2374 /* The target city is non existing. The player isn't aware of this
2375 * fact because they can't see the tile it was located on. The
2376 * actor unit it self doesn't contradict the requirements to
2377 * perform the action. The (no longer existing) target city was
2378 * known to be close enough. */
2380 } else {
2381 /* The actor unit is known to be unable to act or the target city
2382 * is known to be too far away. */
2384 }
2385 } else {
2386 /* No target to act against. */
2388 }
2389 break;
2390 case ATK_UNIT:
2391 if (target_unit) {
2392 /* Calculate the probabilities. */
2394 target_unit);
2395 } else {
2396 /* No target to act against. */
2398 }
2399 break;
2400 case ATK_STACK:
2401 if (target_tile) {
2402 /* Calculate the probabilities. */
2404 target_tile);
2405 } else {
2406 /* No target to act against. */
2408 }
2409 break;
2410 case ATK_TILE:
2411 if (target_tile) {
2412 /* Calculate the probabilities. */
2415 } else {
2416 /* No target to act against. */
2418 }
2419 break;
2420 case ATK_EXTRAS:
2421 if (target_tile) {
2422 /* Calculate the probabilities. */
2425 target_extra);
2426 } else {
2427 /* No target to act against. */
2429 }
2430 break;
2431 case ATK_SELF:
2432 if (actor_target_distance == 0) {
2433 /* Calculate the probabilities. */
2435 } else {
2436 /* Don't bother with self targeted actions unless the actor is
2437 * asking about what can be done to its own tile. */
2439 }
2440 break;
2441 case ATK_COUNT:
2444 break;
2445 }
2447
2448 /* Analyze the probabilities. Decide what targets to send and if an
2449 * explanation is needed. */
2452 /* An action can be done. No need to explain why no action can be
2453 * done. */
2455
2456 switch (action_id_get_target_kind(act)) {
2457 case ATK_CITY:
2458 /* The city should be sent as a target since it is possible to act
2459 * against it. */
2460
2461 /* All city targeted actions requires that the player is aware of
2462 * the target city. It is therefore in the player's map. */
2463 fc_assert_action(plrtile, continue);
2464 fc_assert_action(plrtile->site, continue);
2465
2466 target_city_id = plrtile->site->identity;
2467 break;
2468 case ATK_UNIT:
2469 /* The unit should be sent as a target since it is possible to act
2470 * against it. */
2471 fc_assert(target_unit != nullptr);
2472 target_unit_id = target_unit->id;
2473 break;
2474 case ATK_TILE:
2475 case ATK_EXTRAS:
2476 /* The target tile isn't selected here so it hasn't changed. */
2477 fc_assert(target_tile != nullptr);
2478
2480 /* The target extra may have been set here. */
2482 }
2483 break;
2484 case ATK_STACK:
2485 /* The target tile isn't selected here so it hasn't changed. */
2486 fc_assert(target_tile != nullptr);
2487 break;
2488 case ATK_SELF:
2489 /* The target unit is the actor unit. It is already sent. */
2490 fc_assert(actor_unit != nullptr);
2491 break;
2492 case ATK_COUNT:
2494 "Invalid action target kind.");
2495 break;
2496 }
2497
2498 if (target_city_id != IDENTITY_NUMBER_ZERO
2499 && target_unit_id != IDENTITY_NUMBER_ZERO) {
2500 /* No need to find out more. */
2501 break;
2502 }
2503 }
2505
2506 /* Send possible actions and targets. */
2508 actor_unit_id, target_unit_id, target_city_id,
2509 target_tile_id, target_extra_id,
2510 request_kind,
2512
2513 if (request_kind == REQEST_PLAYER_INITIATED && !at_least_one_action) {
2514 /* The user should get an explanation why no action is possible. */
2517 }
2518}
2519
2520/**********************************************************************/
2527void illegal_action_msg(struct player *pplayer,
2528 const enum event_type event,
2529 struct unit *actor,
2531 const struct tile *target_tile,
2532 const struct city *target_city,
2533 const struct unit *target_unit)
2534{
2535 struct ane_expl *explnat;
2536 const struct civ_map *nmap = &(wld.map);
2537
2538 /* Explain why the action was illegal. */
2541 switch (explnat->kind) {
2542 case ANEK_ACTOR_UNIT:
2543 {
2544 struct astring astr = ASTRING_INIT;
2545
2548 TRUE)) {
2549 notify_player(pplayer, unit_tile(actor),
2551 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
2552 _("Only %s can do %s."),
2553 astr_str(&astr),
2555 astr_free(&astr);
2556 } else {
2557 notify_player(pplayer, unit_tile(actor),
2559 /* TRANS: Spy can't do Capture Units. */
2560 _("%s can't do %s."),
2563 }
2564 }
2565 break;
2568 /* TRANS: "Your Spy found ... suitable for
2569 * Bribe Enemy Unit." */
2570 _("Your %s found no target suitable for %s."),
2573 break;
2574 case ANEK_BAD_TARGET:
2576 /* TRANS: "Having your Spy do Bribe Enemy Unit to
2577 * this target ..." */
2578 _("Having your %s do %s to this target is redundant."),
2581 break;
2583 {
2584 const char *types[utype_count()];
2585 int i = 0;
2586
2589 FALSE)
2591 unit_type_iterate(utype) {
2594 types[i++] = utype_name_translation(utype);
2595 }
2597 }
2598
2599 if (0 < i) {
2600 struct astring astr = ASTRING_INIT;
2601
2602 notify_player(pplayer, unit_tile(actor),
2604 /* TRANS: action name.
2605 * "Your Spy can't do Steal Gold from Ocean.
2606 * Only Explorer or Partisan can do Steal Gold ..." */
2607 _("Your %s can't do %s from %s. "
2608 "Only %s can do %s from a non livable tile."),
2611 terrain_name_translation(explnat->no_act_terrain),
2612 astr_build_or_list(&astr, types, i),
2614
2615 astr_free(&astr);
2616 } else {
2617 notify_player(pplayer, unit_tile(actor),
2619 /* TRANS: action name.
2620 * "Your Spy can't do Steal Gold from Ocean." */
2621 _("Your %s can't do %s from %s."),
2624 terrain_name_translation(explnat->no_act_terrain));
2625 }
2626 }
2627 break;
2629 notify_player(pplayer, unit_tile(actor),
2631 /* TRANS: action name.
2632 * "Your Spy can't do Industrial Sabotage to Mountains." */
2633 _("Your %s can't do %s to %s."),
2636 terrain_name_translation(explnat->no_act_terrain));
2637 break;
2639 notify_player(pplayer, unit_tile(actor),
2641 /* TRANS: action name.
2642 * "Your Spy can't do Industrial Sabotage while ..." */
2643 _("Your %s can't do %s while being transported."),
2646 break;
2648 notify_player(pplayer, unit_tile(actor),
2650 /* TRANS: action name.
2651 * "Your Spy can't do Industrial Sabotage while ..." */
2652 _("Your %s can't do %s while not being transported."),
2655 break;
2657 notify_player(pplayer, unit_tile(actor),
2659 /* TRANS: action name.
2660 * "Your Spy can't do Industrial Sabotage while ..." */
2661 _("Your %s can't do %s while transporting."),
2664 break;
2666 notify_player(pplayer, unit_tile(actor),
2668 /* TRANS: action name.
2669 * "Your Spy can't do Industrial Sabotage while ..." */
2670 _("Your %s can't do %s while not transporting."),
2673 break;
2675 notify_player(pplayer, unit_tile(actor),
2677 /* TRANS: action name.
2678 * "Your Spy can't do Industrial Sabotage because ..." */
2679 _("Your %s can't do %s because it has a home city."),
2682 break;
2684 notify_player(pplayer, unit_tile(actor),
2686 /* TRANS: action name.
2687 * "Your Spy can't do Industrial Sabotage because ..." */
2688 _("Your %s can't do %s because it is homeless."),
2691 break;
2692 case ANEK_NO_WAR:
2693 notify_player(pplayer, unit_tile(actor),
2695 /* TRANS: action name.
2696 * "Your Spy can't do Industrial Sabotage while you
2697 * aren't at war with Prester John." */
2698 _("Your %s can't do %s while you"
2699 " aren't at war with %s."),
2702 player_name(explnat->no_war_with));
2703 break;
2704 case ANEK_PEACE:
2705 notify_player(pplayer, unit_tile(actor),
2707 /* TRANS: action name.
2708 * "Your Spy can't do Industrial Sabotage while you
2709 * are at peace with Prester John. Try using the
2710 * Nations report (F3)." */
2711 _("Your %s can't do %s while you "
2712 "are at peace with %s. Try using "
2713 "the Nations report to declare war"
2715 " (F3)"
2716#endif /* FREECIV_WEB */
2717 "."),
2720 player_name(explnat->peace_with));
2721 break;
2722 case ANEK_DOMESTIC:
2723 notify_player(pplayer, unit_tile(actor),
2725 /* TRANS: action name.
2726 * "Your Riflemen can't do Expel Unit to domestic
2727 * unit stacks." */
2728 _("Your %s can't do %s to domestic %s."),
2733 break;
2734 case ANEK_FOREIGN:
2735 notify_player(pplayer, unit_tile(actor),
2737 /* TRANS: action name.
2738 * "Your Leader can't do Use Court Physician to foreign
2739 * unit stacks." */
2740 _("Your %s can't do %s to foreign %s."),
2745 break;
2747 notify_player(pplayer, unit_tile(actor),
2749 /* TRANS: Paratroopers ... Drop Paratrooper */
2750 _("Your %s can't do %s to tiles with non allied units."),
2753 break;
2754 case ANEK_NATION_ACT:
2755 notify_player(pplayer, unit_tile(actor),
2757 /* TRANS: action name.
2758 * "Swedish Riflemen can't do Expel Unit." */
2759 _("%s %s can't do %s."),
2760 nation_adjective_translation(explnat->no_act_nation),
2763 break;
2764 case ANEK_NATION_TGT:
2765 notify_player(pplayer, unit_tile(actor),
2767 /* TRANS: action name.
2768 * "Riflemen... Expel Unit... Pirate Migrants." */
2769 _("Your %s can't do %s to %s %s."),
2772 nation_adjective_translation(explnat->no_act_nation),
2775 break;
2776 case ANEK_LOW_MP:
2777 notify_player(pplayer, unit_tile(actor),
2779 /* TRANS: action name.
2780 * "Your Spy has ... to do Bribe Enemy Unit." */
2781 _("Your %s has too few moves left to do %s."),
2784 break;
2786 notify_player(pplayer, unit_tile(actor),
2788 /* TRANS: action name.
2789 * "Your Spy can't do Bribe Enemy Unit to city centers." */
2790 _("Your %s can't do %s to city centers."),
2793 break;
2795 notify_player(pplayer, unit_tile(actor),
2797 /* TRANS: action name.
2798 * "Your Spy can only do Investigate City to
2799 * city centers." */
2800 _("Your %s can only do %s to city centers."),
2803 break;
2805 notify_player(pplayer, unit_tile(actor),
2807 /* TRANS: action name.
2808 * "Your Settlers can't do Build City to claimed tiles." */
2809 _("Your %s can't do %s to claimed tiles."),
2812 break;
2814 notify_player(pplayer, unit_tile(actor),
2816 /* TRANS: action name.
2817 * "Your Spy can't do Bribe Enemy Unit to
2818 * unclaimed tiles." */
2819 _("Your %s can't do %s to unclaimed tiles."),
2822 break;
2823 case ANEK_DISTANCE_NEAR:
2824 notify_player(pplayer, unit_tile(actor),
2826 /* TRANS: action name.
2827 * "Your Spy must be at least 2 tiles away to do
2828 * Incite a Revolt and Escape." */
2829 PL_("Your %s must be at least %d tile away to do %s.",
2830 "Your %s must be at least %d tiles away to do %s.",
2831 explnat->distance),
2833 explnat->distance,
2835 break;
2836 case ANEK_DISTANCE_FAR:
2837 notify_player(pplayer, unit_tile(actor),
2839 /* TRANS: action name.
2840 * "Your Diplomat can't be more than 1 tile away to do
2841 * Establish Embassy." */
2842 PL_("Your %s can't be more than %d tile away to do %s.",
2843 "Your %s can't be more than %d tiles away to do %s.",
2844 explnat->distance),
2846 explnat->distance,
2848 break;
2850 notify_player(pplayer, unit_tile(actor),
2852 /* TRANS: Can't do Build City in this scenario. */
2853 _("Can't do %s in this scenario."),
2855 break;
2857 notify_player(pplayer, unit_tile(actor),
2859 /* TRANS: Can't do Build City this close to a city. */
2860 _("Can't do %s this close to a city."),
2862 break;
2863 case ANEK_CITY_TOO_BIG:
2864 notify_player(pplayer, unit_tile(actor),
2866 /* TRANS: Settlers ... Join City ... London */
2867 _("%s can't do %s to %s. It is too big."),
2871 break;
2873 notify_player(pplayer, unit_tile(actor),
2875 /* TRANS: London ... Settlers ... Join City */
2876 _("%s needs an improvement to grow, so "
2877 "%s cannot do %s."),
2881 break;
2883 notify_player(pplayer, unit_tile(actor),
2885 /* TRANS: Paris ... Airlift to City ... Warriors */
2886 _("%s has no capacity to %s %s."),
2887 city_name_get(explnat->capacity_city),
2890 break;
2892 notify_player(pplayer, unit_tile(actor),
2894 /* TRANS: Paratroopers ... Drop Paratrooper */
2895 _("%s can't do %s to an unknown tile."),
2898 break;
2900 {
2901 char tbuf[MAX_LEN_MSG];
2902
2903 /* TRANS: Used below. Separate so treasury content too can determine
2904 * if this is plural. */
2905 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2906 "Treasury contains %d gold.",
2907 pplayer->economic.gold),
2908 pplayer->economic.gold);
2909
2910 notify_player(pplayer, unit_tile(actor),
2912 /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2913 * Treasury contains 100 gold." */
2914 PL_("%s can't do %s for %d gold. %s",
2915 "%s can't do %s for %d gold. %s",
2916 explnat->gold_needed),
2919 explnat->gold_needed, tbuf);
2920 }
2921 break;
2922 case ANEK_TRIREME_MOVE:
2924 /* TRANS: "Trireme cannot move ..." */
2925 _("%s cannot move that far from the coast line."),
2926 unit_link(actor));
2927 break;
2928 case ANEK_DISEMBARK_ACT:
2930 /* TRANS: "Riflemen cannot disembark ... native base
2931 * for Helicopter." */
2932 _("%s cannot disembark outside of a city or a native base "
2933 "for %s."),
2937 break;
2939 notify_player(pplayer, target_tile,
2941 /* TRANS: "Your Spy can't do Bribe Enemy Unit there ..." */
2942 _("Your %s can't do %s there since there's an "
2943 "unreachable unit."),
2946 break;
2947 case ANEK_NOT_WIPABLE:
2948 notify_player(pplayer, target_tile,
2950 /* TRANS: "Your Legion can't do Wipe Units there ..." */
2951 _("Your %s can't do %s there since there's an "
2952 "unit with positive defense value."),
2955 break;
2958 /* TRANS: "You already have a Leader." */
2959 _("You already have a %s."),
2960 utype_name_translation(explnat->no_tgt_utype));
2961 break;
2962 case ANEK_ACTION_BLOCKS:
2963 {
2965
2966 notify_player(pplayer, unit_tile(actor),
2968 /* TRANS: Freight ... Disband Unit Recover ... Help Wonder ... */
2969 _("Your %s can't do %s when %s is legal."),
2972 action_id_name_translation(explnat->blocker->id));
2974 }
2975 break;
2976 case ANEK_UNKNOWN:
2977 notify_player(pplayer, unit_tile(actor),
2979 /* TRANS: action name.
2980 * "Your Spy was unable to do Bribe Enemy Unit." */
2981 _("Your %s was unable to do %s."),
2984 break;
2985 }
2986
2987 free(explnat);
2988}
2989
2990/**********************************************************************/
3003static bool illegal_action_pay_price(struct player *pplayer,
3005 struct unit *act_unit,
3006 struct action *stopped_action,
3007 struct player *tgt_player,
3008 struct tile *tgt_tile,
3009 const enum action_requester requester)
3010{
3011 int punishment_mp;
3012 int punishment_hp;
3013
3014 const struct req_context actor_ctxt = {
3016 .unit = act_unit,
3017 .unittype = unit_type_get(act_unit),
3018 .action = stopped_action,
3019 };
3020 const struct req_context tgt_ctxt = {
3021 .player = tgt_player,
3022 };
3023
3024 /* Don't punish the player for something the game did. Don't tell the
3025 * player that the rules required the game to try to do something
3026 * illegal. */
3029 FALSE,
3030 "The player wasn't responsible for this.");
3031
3032 if (!information_revealed) {
3033 /* The player already had enough information to determine that this
3034 * action is illegal. Don't punish a client error or an accident. */
3035 return FALSE;
3036 }
3037
3038 /* The mistake may have a cost. */
3039
3040 /* HP cost */
3043
3044 /* Stay in range */
3046
3047 /* Punish the unit's hit points. */
3048 act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
3049
3050 if (punishment_hp != 0) {
3053 /* The consolation prize is some information about the potentially
3054 * distant target tile and maybe some contacts. */
3055 map_show_circle(pplayer, tgt_tile,
3056 unit_type_get(act_unit)->vision_radius_sq);
3058 }
3059
3060 if (act_unit->hp > 0) {
3061 /* The actor unit survived */
3062
3063 /* The player probably wants to be disturbed if their unit was punished
3064 * with the loss of hit points. */
3067 /* TRANS: Spy ... 5 ... Drop Paratrooper */
3068 _("Your %s lost %d hit points while attempting to"
3069 " do %s."),
3072 send_unit_info(nullptr, act_unit);
3073 } else {
3074 /* The unit didn't survive */
3075
3076 /* The player probably wants to be disturbed if their unit was punished
3077 * with death. */
3080 /* TRANS: Spy ... Drop Paratrooper */
3081 _("Your %s was killed while attempting to do %s."),
3084
3085 wipe_unit(act_unit, ULR_KILLED, nullptr);
3086 act_unit = nullptr;
3087
3088 return TRUE;
3089 }
3090 }
3091
3092 /* MP cost */
3095
3096 /* Stay in range */
3098
3099 /* Punish the unit's move fragments. */
3100 act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
3101 send_unit_info(nullptr, act_unit);
3102
3103 if (punishment_mp != 0) {
3104 /* The player probably wants to be disturbed if their unit was punished
3105 * with the loss of movement points. */
3108 /* TRANS: Spy ... movement point text that may include
3109 * fractions. */
3110 _("Your %s lost %s MP for attempting an illegal action."),
3113 }
3114
3115 return punishment_mp != 0 || punishment_hp != 0;
3116}
3117
3118/**********************************************************************/
3123static void illegal_action(struct player *pplayer,
3124 struct unit *actor,
3126 struct player *tgt_player,
3127 struct tile *target_tile,
3128 const struct city *target_city,
3129 const struct unit *target_unit,
3130 int request_kind,
3131 const enum action_requester requester)
3132{
3134 bool was_punished;
3135 const struct civ_map *nmap = &(wld.map);
3136
3138
3139 /* Why didn't the game check before trying something illegal? Did a good
3140 * reason to not call is_action_enabled_unit_on...() appear? The game is
3141 * omniscient... */
3143
3144
3146 nmap,
3148 actor,
3150 target_tile, nullptr));
3151
3152 if (request_kind == REQEST_PLAYER_INITIATED) {
3153 /* This is a foreground request. */
3158 }
3159
3163 requester);
3164
3165 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3166 /* FIXME: Temporary work around to prevent wrong information and/or
3167 * crashes. See hrm Bug #879880 */
3168 /* TODO: Get the explanation before the punishment and show it here.
3169 * See hrm Bug #879881 */
3170 notify_player(pplayer, unit_tile(actor),
3173 _("No explanation why you couldn't do %s. This is a bug."
3174 " Sorry about that. -- Sveinung"),
3176 }
3177}
3178
3179/**********************************************************************/
3183 const int actor_id,
3184 const int target_id,
3185 int request_kind)
3186{
3188 actor_id, target_id,
3189 0,
3191 request_kind);
3192}
3193
3194/**********************************************************************/
3202 const int actor_id,
3203 const int target_id,
3204 const action_id action_type,
3205 int request_kind)
3206{
3207 struct player *pplayer = pc->playing;
3208 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3209 struct action *paction = action_by_number(action_type);
3210 struct unit *punit = game_unit_by_number(target_id);
3211 struct city *pcity = game_city_by_number(target_id);
3212 struct tile *ptile = index_to_tile(&(wld.map), target_id);
3213 const struct civ_map *nmap = &(wld.map);
3214
3215 if (paction == nullptr) {
3216 /* Non existing action */
3217 log_error("handle_unit_action_query() the action %d doesn't exist.",
3218 action_type);
3219
3220 unit_query_impossible(pc, actor_id, target_id, request_kind);
3221 return;
3222 }
3223
3224 if (pactor == nullptr) {
3225 /* Probably died or bribed. */
3226 log_verbose("handle_unit_action_query() invalid actor %d",
3227 actor_id);
3228 unit_query_impossible(pc, actor_id, target_id, request_kind);
3229 return;
3230 }
3231
3232 switch (paction->result) {
3234 if (punit != nullptr
3235 && is_action_enabled_unit_on_unit(nmap, action_type,
3236 pactor, punit)) {
3238 actor_id, target_id,
3239 unit_bribe_cost(punit, pplayer,
3240 pactor),
3241 action_type, request_kind);
3242 } else {
3243 illegal_action(pplayer, pactor, action_type,
3244 punit ? unit_owner(punit) : nullptr,
3245 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3246 unit_query_impossible(pc, actor_id, target_id, request_kind);
3247 return;
3248 }
3249 break;
3251 if (ptile != nullptr
3252 && is_action_enabled_unit_on_stack(nmap, action_type,
3253 pactor, ptile)) {
3255 actor_id, target_id,
3256 stack_bribe_cost(ptile, pplayer,
3257 pactor),
3258 action_type, request_kind);
3259 } else {
3260 illegal_action(pplayer, pactor, action_type,
3261 punit ? unit_owner(punit) : nullptr,
3262 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3263 unit_query_impossible(pc, actor_id, target_id, request_kind);
3264 return;
3265 }
3266 break;
3268 if (pcity
3269 && is_action_enabled_unit_on_city(nmap, action_type,
3270 pactor, pcity)) {
3272 actor_id, target_id,
3273 city_incite_cost(pplayer, pcity),
3274 action_type, request_kind);
3275 } else {
3276 illegal_action(pplayer, pactor, action_type,
3277 pcity ? city_owner(pcity) : nullptr,
3278 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3279 unit_query_impossible(pc, actor_id, target_id, request_kind);
3280 return;
3281 }
3282 break;
3284 if (pcity
3285 && is_action_enabled_unit_on_city(nmap, action_type,
3286 pactor, pcity)) {
3287 const struct unit_type *tgt_utype;
3288 int upgr_cost;
3289
3291 /* Already checked via is_action_enabled_unit_on_city() */
3293 upgr_cost = unit_upgrade_price(pplayer,
3295
3297 actor_id, target_id,
3298 upgr_cost, action_type,
3299 request_kind);
3300 } else {
3301 illegal_action(pplayer, pactor, action_type,
3302 pcity ? city_owner(pcity) : nullptr,
3303 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3304 unit_query_impossible(pc, actor_id, target_id, request_kind);
3305 return;
3306 }
3307 break;
3310 if (pcity
3311 && is_action_enabled_unit_on_city(nmap, action_type,
3312 pactor, pcity)) {
3314 action_by_number(action_type), request_kind);
3315 } else {
3316 illegal_action(pplayer, pactor, action_type,
3317 pcity ? city_owner(pcity) : nullptr,
3318 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3319 unit_query_impossible(pc, actor_id, target_id, request_kind);
3320 return;
3321 }
3322 break;
3323 default:
3324 unit_query_impossible(pc, actor_id, target_id, request_kind);
3325 return;
3326 };
3327}
3328
3329/**********************************************************************/
3334void handle_unit_do_action(struct player *pplayer,
3335 const int actor_id,
3336 const int target_id,
3337 const int sub_tgt_id,
3338 const char *name,
3339 const action_id action_type)
3340{
3341 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3342 action_type, ACT_REQ_PLAYER);
3343}
3344
3345/**********************************************************************/
3350void unit_do_action(struct player *pplayer,
3351 const int actor_id,
3352 const int target_id,
3353 const int sub_tgt_id,
3354 const char *name,
3355 const action_id action_type)
3356{
3357 unit_perform_action(pplayer, actor_id, target_id,
3358 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3359}
3360
3361/**********************************************************************/
3370bool unit_perform_action(struct player *pplayer,
3371 const int actor_id,
3372 const int target_id,
3373 const int sub_tgt_id_incoming,
3374 const char *name,
3375 const action_id action_type,
3376 const enum action_requester requester)
3377{
3378 struct action *paction;
3379 int sub_tgt_id;
3380 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3381 struct tile *target_tile = nullptr;
3382 struct extra_type *target_extra;
3383 struct impr_type *sub_tgt_impr;
3384 struct unit *punit = nullptr;
3385 struct city *pcity = nullptr;
3386 struct specialist *sub_tgt_spec = nullptr;
3387 const struct civ_map *nmap = &(wld.map);
3388
3389 if (!action_id_exists(action_type)) {
3390 /* Non existing action */
3391 log_error("unit_perform_action() the action %d doesn't exist.",
3392 action_type);
3393
3394 return FALSE;
3395 }
3396
3397 paction = action_by_number(action_type);
3398
3399 if (actor_unit == nullptr) {
3400 /* Probably died or bribed. */
3401 log_verbose("unit_perform_action() invalid actor %d",
3402 actor_id);
3403 return FALSE;
3404 }
3405
3407 case ATK_CITY:
3408 pcity = game_city_by_number(target_id);
3409 if (pcity == nullptr) {
3410 log_verbose("unit_perform_action() invalid target city %d",
3411 target_id);
3412 return FALSE;
3413 }
3415 fc_assert_ret_val(target_tile != nullptr, FALSE);
3416 break;
3417 case ATK_UNIT:
3418 punit = game_unit_by_number(target_id);
3419 if (punit == nullptr) {
3420 log_verbose("unit_perform_action() invalid target unit %d",
3421 target_id);
3422 return FALSE;
3423 }
3425 fc_assert_ret_val(target_tile != nullptr, FALSE);
3427 break;
3428 case ATK_STACK:
3429 case ATK_TILE:
3430 case ATK_EXTRAS:
3431 target_tile = index_to_tile(nmap, target_id);
3432 if (target_tile == nullptr) {
3433 log_verbose("unit_perform_action() invalid target tile %d",
3434 target_id);
3435 return FALSE;
3436 }
3438 break;
3439 case ATK_SELF:
3441 fc_assert_ret_val(target_tile != nullptr, FALSE);
3443 break;
3444 case ATK_COUNT:
3446 break;
3447 }
3448
3449 /* Server side sub target assignment */
3450 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3453 } else {
3454 sub_tgt_id = sub_tgt_id_incoming;
3455 }
3456
3457 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3458 && sub_tgt_id != NO_TARGET) {
3459 target_extra = extra_by_number(sub_tgt_id);
3460 fc_assert(!(target_extra->ruledit_disabled));
3461 } else {
3462 target_extra = nullptr;
3463 }
3464
3465 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3466 sub_tgt_spec = specialist_by_number(sub_tgt_id);
3467
3468 /* Sub targets should now be assigned */
3469 switch (paction->sub_target_kind) {
3470 case ASTK_NONE:
3471 /* No sub target. */
3472 break;
3473 case ASTK_BUILDING:
3474 if (sub_tgt_impr == nullptr) {
3475 /* Missing sub target */
3476 return FALSE;
3477 }
3478 break;
3479 case ASTK_TECH:
3480 /* Not handled here yet */
3481 break;
3482 case ASTK_EXTRA:
3484 if (target_extra == nullptr) {
3485 /* Missing sub target */
3486 return FALSE;
3487 }
3488 break;
3489 case ASTK_SPECIALIST:
3490 if (sub_tgt_spec == nullptr) {
3491 /* Missing sub target */
3492 return FALSE;
3493 }
3494 break;
3495 case ASTK_COUNT:
3496 break;
3497 }
3498
3502 && target_extra == nullptr) {
3503 /* Missing required action extra target. */
3504 log_verbose("unit_perform_action() action %d requires action "
3505 "but extra id %d is invalid.",
3506 action_type, sub_tgt_id);
3507 return FALSE;
3508 }
3509
3510 if (paction->actor.is_unit.unitwaittime_controlled
3512 /* Action not possible due to unitwaittime setting. */
3513 return FALSE;
3514 }
3515
3516#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3517 if (pcity \
3518 && is_action_enabled_unit_on_city(nmap, action_type, \
3519 actor_unit, pcity)) { \
3520 bool success; \
3521 script_server_signal_emit("action_started_unit_city", \
3522 action_by_number(action), actor, target); \
3523 if (!actor || !unit_is_alive(actor_id)) { \
3524 /* Actor unit was destroyed during pre action Lua. */ \
3525 return FALSE; \
3526 } \
3527 if (!target || !city_exist(target_id)) { \
3528 /* Target city was destroyed during pre action Lua. */ \
3529 return FALSE; \
3530 } \
3531 success = action_performer; \
3532 if (success) { \
3533 action_success_actor_price(paction, actor_id, actor); \
3534 } \
3535 script_server_signal_emit("action_finished_unit_city", \
3536 action_by_number(action), success, \
3537 unit_is_alive(actor_id) ? actor : nullptr, \
3538 city_exist(target_id) ? target : nullptr); \
3539 return success; \
3540 } else { \
3541 illegal_action(pplayer, actor_unit, action_type, \
3542 pcity ? city_owner(pcity) : nullptr, nullptr, pcity, \
3543 nullptr, TRUE, requester); \
3544 }
3545
3546#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3547 if (actor_unit \
3548 && is_action_enabled_unit_on_self(nmap, action_type, actor_unit)) { \
3549 bool success; \
3550 script_server_signal_emit("action_started_unit_self", \
3551 action_by_number(action), actor); \
3552 if (!actor || !unit_is_alive(actor_id)) { \
3553 /* Actor unit was destroyed during pre action Lua. */ \
3554 return FALSE; \
3555 } \
3556 success = action_performer; \
3557 if (success) { \
3558 action_success_actor_price(paction, actor_id, actor); \
3559 } \
3560 script_server_signal_emit("action_finished_unit_self", \
3561 action_by_number(action), success, \
3562 unit_is_alive(actor_id) ? actor : nullptr); \
3563 return success; \
3564 } else { \
3565 illegal_action(pplayer, actor_unit, action_type, \
3566 unit_owner(actor_unit), nullptr, nullptr, actor_unit, \
3567 TRUE, requester); \
3568 }
3569
3570#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3571 if (punit \
3572 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3573 bool success; \
3574 script_server_signal_emit("action_started_unit_unit", \
3575 action_by_number(action), actor, target); \
3576 if (!actor || !unit_is_alive(actor_id)) { \
3577 /* Actor unit was destroyed during pre action Lua. */ \
3578 return FALSE; \
3579 } \
3580 if (!target || !unit_is_alive(target_id)) { \
3581 /* Target unit was destroyed during pre action Lua. */ \
3582 return FALSE; \
3583 } \
3584 success = action_performer; \
3585 if (success) { \
3586 action_success_actor_price(paction, actor_id, actor); \
3587 action_success_target_pay_mp(paction, target_id, punit); \
3588 } \
3589 script_server_signal_emit("action_finished_unit_unit", \
3590 action_by_number(action), success, \
3591 unit_is_alive(actor_id) ? actor : nullptr, \
3592 unit_is_alive(target_id) ? target \
3593 : nullptr); \
3594 return success; \
3595 } else { \
3596 illegal_action(pplayer, actor_unit, action_type, \
3597 punit ? unit_owner(punit) : nullptr, nullptr, nullptr, \
3598 punit, TRUE, requester); \
3599 }
3600
3601#define ACTION_PERFORM_UNIT_STACK(action, actor, target, action_performer)\
3602 if (target_tile \
3603 && is_action_enabled_unit_on_stack(nmap, action_type, \
3604 actor_unit, target_tile)) { \
3605 bool success; \
3606 script_server_signal_emit("action_started_unit_stack", \
3607 action_by_number(action), actor, target); \
3608 script_server_signal_emit("action_started_unit_units", \
3609 action_by_number(action), actor, target); \
3610 if (!actor || !unit_is_alive(actor_id)) { \
3611 /* Actor unit was destroyed during pre action Lua. */ \
3612 return FALSE; \
3613 } \
3614 success = action_performer; \
3615 if (success) { \
3616 action_success_actor_price(paction, actor_id, actor); \
3617 } \
3618 script_server_signal_emit("action_finished_unit_stack", \
3619 action_by_number(action), success, \
3620 unit_is_alive(actor_id) ? actor : nullptr, \
3621 target); \
3622 script_server_signal_emit("action_finished_unit_units", \
3623 action_by_number(action), success, \
3624 unit_is_alive(actor_id) ? actor : nullptr, \
3625 target); \
3626 return success; \
3627 } else { \
3628 illegal_action(pplayer, actor_unit, action_type, \
3629 nullptr, target_tile, nullptr, nullptr, \
3630 TRUE, requester); \
3631 }
3632
3633#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3634 if (target_tile \
3635 && is_action_enabled_unit_on_tile(nmap, action_type, \
3636 actor_unit, target_tile, \
3637 target_extra)) { \
3638 bool success; \
3639 script_server_signal_emit("action_started_unit_tile", \
3640 action_by_number(action), actor, target); \
3641 if (!actor || !unit_is_alive(actor_id)) { \
3642 /* Actor unit was destroyed during pre action Lua. */ \
3643 return FALSE; \
3644 } \
3645 success = action_performer; \
3646 if (success) { \
3647 action_success_actor_price(paction, actor_id, actor); \
3648 } \
3649 script_server_signal_emit("action_finished_unit_tile", \
3650 action_by_number(action), success, \
3651 unit_is_alive(actor_id) ? actor : nullptr, \
3652 target); \
3653 return success; \
3654 } else { \
3655 illegal_action(pplayer, actor_unit, action_type, \
3656 target_tile ? tile_owner(target_tile) : nullptr, \
3657 target_tile, nullptr, nullptr, \
3658 TRUE, requester); \
3659 }
3660
3661#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3662 if (target_tile \
3663 && is_action_enabled_unit_on_extras(nmap, action_type, \
3664 actor_unit, target_tile, \
3665 target_extra)) { \
3666 bool success; \
3667 script_server_signal_emit("action_started_unit_extras", \
3668 action_by_number(action), actor, target); \
3669 if (!actor || !unit_is_alive(actor_id)) { \
3670 /* Actor unit was destroyed during pre action Lua. */ \
3671 return FALSE; \
3672 } \
3673 success = action_performer; \
3674 if (success) { \
3675 action_success_actor_price(paction, actor_id, actor); \
3676 } \
3677 script_server_signal_emit("action_finished_unit_extras", \
3678 action_by_number(action), success, \
3679 unit_is_alive(actor_id) ? actor : nullptr, \
3680 target); \
3681 return success; \
3682 } else { \
3683 illegal_action(pplayer, actor_unit, action_type, \
3684 target_tile ? target_tile->extras_owner : nullptr, \
3685 target_tile, nullptr, nullptr, \
3686 TRUE, requester); \
3687 }
3688
3689#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3690 target_city, target_unit, target_tile, \
3691 action_performer) \
3692 switch (action_get_target_kind(paction)) { \
3693 case ATK_CITY: \
3694 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3695 action_performer); \
3696 break; \
3697 case ATK_UNIT: \
3698 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3699 action_performer); \
3700 break; \
3701 case ATK_STACK: \
3702 ACTION_PERFORM_UNIT_STACK(paction->id, actor, target_tile, \
3703 action_performer); \
3704 break; \
3705 case ATK_TILE: \
3706 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3707 action_performer); \
3708 break; \
3709 case ATK_EXTRAS: \
3710 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3711 action_performer); \
3712 break; \
3713 case ATK_SELF: \
3714 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3715 break; \
3716 case ATK_COUNT: \
3717 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3718 break; \
3719 }
3720
3721 switch (paction->result) {
3725 paction));
3726 break;
3728 /* Difference is caused by data in the action structure. */
3731 punit, paction));
3732 break;
3733 case ACTRES_EXPEL_UNIT:
3735 do_expel_unit(pplayer, actor_unit, punit,
3736 paction));
3737 break;
3738 case ACTRES_HEAL_UNIT:
3740 do_heal_unit(pplayer, actor_unit, punit,
3741 paction));
3742 break;
3746 paction));
3747 break;
3751 paction));
3752 break;
3755 do_unit_board(pplayer, actor_unit, punit,
3756 paction));
3757 break;
3760 do_unit_load(pplayer, actor_unit, punit,
3761 paction));
3762 break;
3766 paction));
3767 break;
3769 /* All consequences are handled by the action system. */
3771 break;
3772 case ACTRES_FORTIFY:
3775 break;
3776 case ACTRES_CONVERT:
3779 break;
3780 case ACTRES_HOMELESS:
3783 break;
3784 case ACTRES_SPY_ESCAPE:
3786 spy_escape(pplayer, actor_unit,
3788 break;
3790 /* Difference is caused by data in the action structure. */
3793 B_LAST, paction));
3794 break;
3796 /* Difference is caused by data in the action structure. */
3799 sub_tgt_impr->item_number,
3800 paction));
3801 break;
3803 /* Difference is caused by data in the action structure. */
3806 -1, paction));
3807 break;
3808 case ACTRES_SPY_POISON:
3809 /* Difference is caused by data in the action structure. */
3811 spy_poison(pplayer, actor_unit, pcity,
3812 paction));
3813 break;
3817 paction));
3818 break;
3820 /* Difference is caused by data in the action structure. */
3822 diplomat_investigate(pplayer,
3824 paction));
3825 break;
3827 /* Difference is caused by data in the action structure. */
3830 paction));
3831 break;
3833 /* Difference is caused by data in the action structure. */
3836 paction));
3837 break;
3839 /* Difference is caused by data in the action structure. */
3842 A_UNSET, paction));
3843 break;
3845 /* Difference is caused by data in the action structure. */
3848 sub_tgt_id, paction));
3849 break;
3851 /* Difference is caused by data in the action structure. */
3854 paction));
3855 break;
3856 case ACTRES_STEAL_MAPS:
3857 /* Difference is caused by data in the action structure. */
3860 pcity, paction));
3861 break;
3862 case ACTRES_TRADE_ROUTE:
3865 pcity, paction));
3866 break;
3867 case ACTRES_MARKETPLACE:
3870 pcity, paction));
3871 break;
3872 case ACTRES_HELP_WONDER:
3874 unit_do_help_build(pplayer,
3876 paction));
3877 break;
3878 case ACTRES_SPY_NUKE:
3879 /* Difference is caused by data in the action structure. */
3881 spy_nuke_city(pplayer, actor_unit, pcity,
3882 paction));
3883 break;
3884 case ACTRES_JOIN_CITY:
3886 city_add_unit(pplayer, actor_unit, pcity,
3887 paction));
3888 break;
3891 unit_do_destroy_city(pplayer,
3893 paction));
3894 break;
3898 paction));
3899 break;
3900 case ACTRES_HOME_CITY:
3903 paction));
3904 break;
3907 do_unit_upgrade(pplayer, actor_unit,
3909 break;
3911 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3914 pcity, paction));
3915 break;
3919 actor_unit,
3920 pcity,
3921 sub_tgt_impr->item_number,
3922 paction));
3923 break;
3927 actor_unit,
3928 pcity,
3929 paction));
3930 break;
3935 break;
3936 case ACTRES_AIRLIFT:
3939 break;
3944 break;
3945 case ACTRES_BOMBARD:
3946 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3949 paction));
3950 break;
3951 case ACTRES_ATTACK:
3953 /* Difference is caused by data in the action structure. */
3956 break;
3957 case ACTRES_WIPE_UNITS:
3960 break;
3965 break;
3966 case ACTRES_NUKE_UNITS:
3969 paction));
3970 break;
3971 case ACTRES_SPY_ATTACK:
3974 paction));
3975 break;
3976 case ACTRES_FOUND_CITY:
3978 city_build(pplayer, actor_unit,
3980 break;
3981 case ACTRES_NUKE:
3985 paction));
3986 break;
3987 case ACTRES_PARADROP:
3991 break;
3993 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3995 do_disembark(pplayer, actor_unit,
3997 break;
3998 case ACTRES_HUT_ENTER:
4000 do_unit_hut(pplayer, actor_unit,
4002 break;
4005 do_unit_hut(pplayer, actor_unit,
4007 break;
4008 case ACTRES_UNIT_MOVE:
4012 break;
4013 case ACTRES_TELEPORT:
4017 nullptr, FALSE,
4020 FALSE, FALSE));
4021 break;
4025 break;
4026 case ACTRES_CULTIVATE:
4029 break;
4030 case ACTRES_PLANT:
4033 break;
4034 case ACTRES_PILLAGE:
4037 paction,
4038 &target_extra));
4039 break;
4040 case ACTRES_CLEAN:
4043 paction,
4044 &target_extra));
4045 break;
4046 case ACTRES_ROAD:
4049 paction,
4050 &target_extra));
4051 break;
4052 case ACTRES_BASE:
4055 paction,
4056 &target_extra));
4057 break;
4058 case ACTRES_MINE:
4061 paction,
4062 &target_extra));
4063 break;
4064 case ACTRES_IRRIGATE:
4067 paction,
4068 &target_extra));
4069 break;
4070 case ACTRES_NONE:
4071 /* 100% ruleset defined. */
4073 TRUE);
4074 break;
4077 return FALSE;
4078
4080 }
4081
4082 /* Something must have gone wrong. */
4083 return FALSE;
4084}
4085
4086/**********************************************************************/
4094 bool rehome)
4095{
4097 struct player *old_owner = unit_owner(punit);
4098 struct player *new_owner = (new_pcity == nullptr ? old_owner
4100 const struct civ_map *nmap = &(wld.map);
4101
4102 /* Calling this function when new_pcity is same as old_pcity should
4103 * be safe with current implementation, but it is not meant to
4104 * be used that way. */
4106
4107 /* If 'rehome' is not set, this function should only be used to change
4108 * which player owns the unit */
4110
4111 if (old_owner != new_owner) {
4112 struct city *pcity = tile_city(punit->tile);
4113
4116
4119
4120 if (pcity != nullptr
4122 /* Special case when city is being transferred. At this point city
4123 * itself has changed owner, so it's enemy city now that old owner
4124 * cannot see inside. All the normal methods of removing transferred
4125 * unit from previous owner's client think that there's no need to
4126 * remove unit as client shouldn't have it in first place. */
4128 }
4129
4130 /* Remove AI control of the old owner. */
4131 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4132
4136
4137 /* Activate AI control of the new owner. */
4138 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4139
4142 }
4143
4144 if (rehome) {
4145 /* Remove from old city first and add to new city only after that. */
4146 if (old_pcity) {
4147 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4148 unit_list_remove(old_pcity->units_supported, punit);
4149 /* Update unit upkeep */
4151 }
4152
4153 if (new_pcity != nullptr) {
4154 unit_list_prepend(new_pcity->units_supported, punit);
4155
4156 /* Update unit upkeep */
4158
4159 punit->homecity = new_pcity->id;
4160 } else {
4162 }
4163 }
4164
4166 /* This is mainly for cases where unit owner changes to one not knowing
4167 * Railroad tech when unit is already building railroad.
4168 * Does also send_unit_info() */
4170 } else {
4171 /* Send info to players and observers. */
4172 send_unit_info(nullptr, punit);
4173 }
4174
4175 if (new_pcity != nullptr) {
4179 }
4180
4181 if (old_pcity) {
4185 }
4186
4188
4189 if (old_owner != new_owner) {
4190 script_server_signal_emit("unit_transferred", punit, old_owner);
4191 }
4192}
4193
4194/**********************************************************************/
4200 struct city *pcity,
4201 const struct action *paction)
4202{
4203 const char *giver = nullptr;
4204
4205 if (unit_owner(punit) != city_owner(pcity)) {
4206 /* This is a gift. Tell the receiver. */
4207 giver = player_name(unit_owner(punit));
4208 }
4209
4211
4212 if (punit->homecity == pcity->id && giver) {
4213 /* Notify the city owner about the gift they received. */
4215 ftc_server,
4216 /* TRANS: other player ... unit type ... city name. */
4217 _("%s transferred control over a %s to you in %s."),
4218 giver,
4220 city_link(pcity));
4221 }
4222
4223 return punit->homecity == pcity->id;
4224}
4225
4226/**********************************************************************/
4233static bool city_add_unit(struct player *pplayer, struct unit *punit,
4234 struct city *pcity, const struct action *paction)
4235{
4237 const struct unit_type *act_utype;
4239 int new_food;
4241
4242 /* Sanity check: The actor is still alive. */
4244
4246
4247 /* Sanity check: The target city still exists. */
4249
4251
4253 /* Preserve old food stock, unless granary effect gives us more. */
4254 pcity->food_stock = MAX(pcity->food_stock, new_food);
4255
4256 if (is_super_specialist(act_utype->spec_type)) {
4258
4260 pcity->specialists[sspec]++;
4261 } else {
4263 /* Hardly much needed but let it be */
4264 spec_id = specialist_index(act_utype->spec_type);
4265 }
4266 /* Make the new people something, otherwise city fails the checks */
4268 FALSE);
4269 pcity->specialists[spec_id] += amount;
4271 /* Refresh the city data. */
4273
4274 /* Notify the unit owner that the unit successfully joined the city. */
4276 _("%s added to aid %s in growing."),
4278 city_link(pcity));
4279 if (pplayer != city_owner(pcity)) {
4280 /* Notify the city owner when a foreign unit joins a city. */
4282 ftc_server,
4283 /* TRANS: another player had their unit join your city. */
4284 _("%s adds %s to your city %s."),
4287 city_link(pcity));
4288 }
4289
4292 city_link(pcity));
4293
4295
4296 send_city_info(nullptr, pcity);
4297
4298 script_server_signal_emit("city_size_change", pcity,
4299 (lua_Integer)amount, "unit_added");
4300
4301 return TRUE;
4302}
4303
4304/**********************************************************************/
4313static bool city_build(struct player *pplayer, struct unit *punit,
4314 struct tile *ptile, const char *name,
4315 const struct action *paction)
4316{
4317 char message[1024];
4318 int size;
4319 struct player *nationality;
4320 struct player *towner;
4321 const struct unit_type *act_utype;
4323 struct city *pcity;
4324
4325 /* Sanity check: The actor still exists. */
4326 fc_assert_ret_val(pplayer, FALSE);
4328
4329 towner = tile_owner(ptile);
4330
4331 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4332 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4333 "%s", message);
4334 return FALSE;
4335 }
4336
4338 sid = specialist_index(act_utype->spec_type);
4340
4341 create_city(pplayer, ptile, name, nationality);
4342 size = act_utype->city_size;
4343 pcity = tile_city(ptile); /* A callback may destroy or replace it any time */
4344 if (nullptr != pcity) {
4345 if (is_super_specialist_id(sid) && pcity->specialists[sid] < MAX_CITY_SIZE) {
4346 pcity->specialists[sid]++;
4347 }
4348 if (size > 1) {
4349 city_change_size(pcity, size, nationality, -1, nullptr);
4350 }
4351 }
4352
4353 /* May cause an incident even if the target tile is unclaimed. A ruleset
4354 * could give everyone a casus belli against the city founder. A rule
4355 * like that would make sense in a story where deep ecology is on the
4356 * table. (See also Voluntary Human Extinction Movement) */
4358 ptile, tile_link(ptile));
4359
4360 return TRUE;
4361}
4362
4363/**********************************************************************/
4366static void handle_unit_change_activity_real(struct player *pplayer,
4367 int unit_id,
4368 enum unit_activity activity,
4369 struct extra_type *activity_target,
4371{
4372 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4373
4374 if (punit == nullptr) {
4375 /* Probably died or bribed. */
4376 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4377 return;
4378 }
4379
4380 if (punit->activity == activity
4382 return;
4383 }
4384
4385 /* Remove city spot reservations for AI settlers on city founding
4386 * mission, before goto_tile reset. */
4387 if (punit->server.adv->task != AUT_NONE) {
4388 adv_unit_new_task(punit, AUT_NONE, nullptr);
4389 }
4390
4391 if (activity == ACTIVITY_GOTO) {
4392 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4393 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4394 * it is going somewhere while it is standing still. The appearance of
4395 * the unit doing something can trick the user to not make use of it.
4396 *
4397 * Handled here because adv_follow_path() uses unit_activity_handling()
4398 * to set a unit's activity to ACTIVITY_GOTO. */
4399 return;
4400 }
4401
4402 if (activity == ACTIVITY_EXPLORE) {
4403 /* Please use unit_server_side_agent_set(). */
4404 return;
4405 }
4406
4407 punit->goto_tile = nullptr;
4408
4409 /* The activity can now be set. */
4412}
4413
4414/**********************************************************************/
4417void handle_unit_change_activity(struct player *pplayer, int unit_id,
4419 int target_id)
4420{
4421 struct extra_type *activity_target;
4422
4424 activity_target = nullptr;
4425 } else {
4426 activity_target = extra_by_number(target_id);
4427 }
4428
4429#ifdef FREECIV_WEB
4430 /* Web-client is not capable of selecting target, so we do it server side */
4431 if (activity_target == nullptr) {
4432 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4433 bool required = TRUE;
4434
4435 if (punit == nullptr) {
4436 return;
4437 }
4438
4439 if (activity == ACTIVITY_IRRIGATE) {
4440 struct tile *ptile = unit_tile(punit);
4441
4442 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4443 pplayer, punit);
4444 } else if (activity == ACTIVITY_MINE) {
4445 struct tile *ptile = unit_tile(punit);
4446
4447 activity_target = next_extra_for_tile(ptile, EC_MINE,
4448 pplayer, punit);
4449 } else if (activity == ACTIVITY_BASE) {
4450 struct tile *ptile = unit_tile(punit);
4451 struct base_type *pbase =
4453
4454 if (pbase != nullptr) {
4455 activity_target = base_extra_get(pbase);
4456 }
4457
4458 } else if (activity == ACTIVITY_CLEAN) {
4459 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4460 pplayer, punit);
4461 } else {
4462 required = FALSE;
4463 }
4464
4465 if (activity_target == nullptr && required) {
4466 /* Nothing more we can do */
4467 return;
4468 }
4469 }
4470#endif /* FREECIV_WEB */
4471
4472 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target,
4473 activity_default_action(activity));
4474}
4475
4476/**********************************************************************/
4479static void see_combat(struct unit *pattacker, struct unit *pdefender)
4480{
4483
4484 /*
4485 * Special case for attacking/defending:
4486 *
4487 * Normally the player doesn't get the information about the units inside a
4488 * city. However for attacking/defending the player has to know the unit of
4489 * the other side. After the combat a remove_unit packet will be sent
4490 * to the client to tidy up.
4491 *
4492 * Note these packets must be sent out before unit_versus_unit() is called,
4493 * so that the original unit stats (HP) will be sent.
4494 */
4501
4503 struct player *pplayer = pconn->playing;
4504
4505 if (pplayer != nullptr) {
4506
4507 /* NOTE: this means the player can see combat between submarines even
4508 * if neither sub is visible. See similar comment in send_combat(). */
4511 V_MAIN)) {
4512
4513 /* Units are sent even if they were visible already. They may
4514 * have changed orientation for combat. */
4515 if (pplayer == unit_owner(pattacker)) {
4517 } else {
4519 }
4520
4521 if (pplayer == unit_owner(pdefender)) {
4523 } else {
4525 }
4526 }
4527 } else if (pconn->observer) {
4528 /* Global observer sees everything... */
4531 }
4533}
4534
4535/**********************************************************************/
4538static void send_combat(struct unit *pattacker, struct unit *pdefender,
4539 int att_veteran, int def_veteran, int bombard)
4540{
4542
4544 combat.defender_unit_id = pdefender->id;
4545 combat.attacker_hp = pattacker->hp;
4546 combat.defender_hp = pdefender->hp;
4547 combat.make_att_veteran = att_veteran;
4548 combat.make_def_veteran = def_veteran;
4549
4550 players_iterate(other_player) {
4551 /* NOTE: this means the player can see combat between submarines even
4552 * if neither sub is visible. See similar comment in see_combat. */
4553 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4554 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4555 V_MAIN)) {
4556 lsend_packet_unit_combat_info(other_player->connections, &combat);
4557
4558 /*
4559 * Remove the client knowledge of the units. This corresponds to the
4560 * send_packet_unit_short_info() calls up above.
4561 */
4562 if (!can_player_see_unit(other_player, pattacker)) {
4563 unit_goes_out_of_sight(other_player, pattacker);
4564 }
4565 if (!can_player_see_unit(other_player, pdefender)) {
4566 unit_goes_out_of_sight(other_player, pdefender);
4567 }
4568 }
4570
4571 /* Send combat info to non-player observers as well. They already know
4572 * about the unit so no unit_info is needed. */
4574 if (pconn->playing == nullptr && pconn->observer) {
4576 }
4578}
4579
4580/**********************************************************************/
4584 struct city *pcity,
4585 const struct action *paction,
4586 const char *reason)
4587{
4588 struct player *pplayer = unit_owner(punit);
4589
4590 if (pcity
4591 && get_target_bonus_effects(nullptr,
4592 &(const struct req_context) {
4593 .player = city_owner(pcity),
4594 .city = pcity,
4595 .tile = city_tile(pcity),
4596 .unit = punit,
4597 .unittype = unit_type_get(punit),
4598 .action = paction,
4599 },
4600 nullptr, EFT_UNIT_NO_LOSE_POP) <= 0
4603 struct player *cplayer = city_owner(pcity);
4604 struct tile *ctile = city_tile(pcity);
4605 const char *clink = city_link(pcity);
4606
4607 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4609 send_city_info(nullptr, pcity);
4610 } else {
4612 /* TRANS: Battleship ... Los Angeles ... Bombard */
4613 _("Your %s destroyed %s by doing %s."),
4618 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4619 _("%s destroyed %s by doing %s."),
4620 player_name(pplayer), clink,
4622 }
4623 }
4624}
4625
4626/**********************************************************************/
4633static bool unit_bombard(struct unit *punit, struct tile *ptile,
4634 const struct action *paction)
4635{
4636 struct player *pplayer = unit_owner(punit);
4637 struct city *pcity = tile_city(ptile);
4638 const struct unit_type *act_utype;
4639 const struct civ_map *nmap = &(wld.map);
4640
4641 /* Sanity check: The actor still exists. */
4642 fc_assert_ret_val(pplayer, FALSE);
4644
4646
4647 log_debug("Start bombard: %s %s to %d, %d.",
4649 unit_rule_name(punit), TILE_XY(ptile));
4650
4652 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4653 bool adj;
4654 enum direction8 facing;
4655 int att_hp, def_hp;
4656
4658 punit->tile, pdefender->tile, &facing);
4659
4660 if (adj) {
4661 punit->facing = facing;
4662
4663 /* Unlike with normal attack, we don't change orientation of
4664 * defenders when bombarding */
4665 }
4666
4667 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4668
4669 if (def_hp <= 0) {
4670 notify_player(pplayer, ptile,
4672 /* TRANS: Your Bomber killed the English Rifleman by
4673 * doing Bombard. */
4674 _("Your %s killed the %s %s by doing %s."),
4681 /* TRANS: Your Rifleman was killed by the French
4682 * Bomber doing Bombard. */
4683 _("Your %s was killed by the %s %s doing %s."),
4688 } else {
4689 notify_player(pplayer, ptile,
4691 /* TRANS: Your Bomber bombards the English Rifleman. */
4692 _("Your %s bombards the %s %s."),
4698 /* TRANS: Your Rifleman is bombarded by the French
4699 * Bomber. */
4700 _("Your %s is bombarded by the %s %s."),
4704 }
4705
4707
4708 punit->hp = att_hp;
4709 pdefender->hp = def_hp;
4710
4711 send_combat(punit, pdefender, 0, 0, 1);
4712
4713 /* May cause an incident */
4719
4720 if (def_hp <= 0) {
4722 } else {
4723 send_unit_info(nullptr, pdefender);
4724 }
4725 }
4726
4728
4731
4733
4734 send_unit_info(nullptr, punit);
4735
4736 return TRUE;
4737}
4738
4739/**********************************************************************/
4750static bool unit_nuke(struct player *pplayer, struct unit *punit,
4751 struct tile *def_tile, const struct action *paction)
4752{
4753 struct city *pcity;
4754 const struct unit_type *act_utype;
4755 struct civ_map *nmap = &(wld.map);
4756
4757 /* Sanity check: The actor still exists. */
4758 fc_assert_ret_val(pplayer, FALSE);
4760
4762
4763 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4766 TILE_XY(def_tile));
4767
4768 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4769 /* FIXME: Remove the hard coded reference to SDI defense. */
4771 _("Your %s was shot down by "
4772 "SDI defenses, what a waste."), unit_tile_link(punit));
4774 _("The nuclear attack on %s was avoided by"
4775 " your SDI defense."), city_link(pcity));
4776
4777 /* Trying to nuke something this close can be... unpopular. */
4781
4782 /* Remove the destroyed nuke. */
4784
4785 return FALSE;
4786 }
4787
4789
4790
4791 /* The nuke must be wiped here so it won't be seen as a victim of its own
4792 * detonation. */
4793 if (paction->actor_consuming_always) {
4794 wipe_unit(punit, ULR_DETONATED, nullptr);
4795 }
4796
4798
4799 /* May cause an incident even if the target tile is unclaimed. A ruleset
4800 * could give everyone a casus belli against the tile nuker. A rule
4801 * like that would make sense in a story where detonating any nuke at all
4802 * could be forbidden. */
4805 def_tile,
4807
4808 return TRUE;
4809}
4810
4811/**********************************************************************/
4821 struct unit *act_unit,
4822 struct city *tgt_city,
4823 const struct action *paction)
4824{
4825 int tgt_city_id;
4826 struct player *tgt_player;
4827 bool capital;
4828 bool try_civil_war = FALSE;
4829 const struct unit_type *act_utype;
4830
4831 /* Sanity check: The actor still exists. */
4834
4836
4837 /* Sanity check: The target city still exists. */
4839
4841
4842 /* How can a city be ownerless? */
4844
4845 /* Save city ID. */
4846 tgt_city_id = tgt_city->id;
4847
4849
4850 if (capital
4851 && (tgt_player->spaceship.state == SSHIP_STARTED
4852 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4853 /* Destroying this city destroys the victim's space ship. */
4855 }
4856
4857 if (capital
4861 /* Destroying this city can trigger a civil war. */
4863 }
4864
4865 /* Let the actor know. */
4868 _("You destroy %s completely."),
4870
4871 if (tgt_player != act_player) {
4872 /* This was done to a foreign city. Inform the victim player. */
4875 _("%s has been destroyed by %s."),
4878 }
4879
4880 /* May cause an incident */
4884
4885 /* Run post city destruction Lua script. */
4887 act_player);
4888
4889 /* Can't be sure of city existence after running script. */
4890 if (city_exist(tgt_city_id)) {
4892 }
4893
4894 if (try_civil_war) {
4895 /* Try to start the civil war. */
4897 }
4898
4899 /* The city is no more. */
4900 return TRUE;
4901}
4902
4903/**********************************************************************/
4908static const char *unit_veteran_level_string(const struct unit *punit)
4909{
4910 static char buf[MAX_LEN_LINK];
4911 const struct veteran_level *vlevel;
4912
4913 if (!punit) {
4914 buf[0] = '\0'; /* If no unit, return empty string */
4915 return buf;
4916 }
4917
4919 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4920
4921 return buf;
4922}
4923
4924/**********************************************************************/
4929static const char *unit_achieved_rank_string(const struct unit *punit)
4930{
4931 static char buf[MAX_LEN_LINK];
4932
4933 fc_snprintf(buf, sizeof(buf),
4934 /* TRANS: " and achieved the rank of <veteran level>";
4935 * preserve leading space */
4936 _(" and achieved the rank of %s"),
4938 return buf;
4939}
4940
4941/**********************************************************************/
4946static const char *unit_tired_attack_string(const struct unit *punit)
4947{
4948 static char buf[MAX_LEN_LINK];
4949
4951 fc_snprintf(buf, sizeof(buf),
4952 /* TRANS: tired; note trailing space */
4953 _("tired "));
4954 } else {
4955 buf[0] = '\0';
4956 }
4957
4958 return buf;
4959}
4960
4961/**********************************************************************/
4968static const char *unit_firepower_if_not_one(int firepower)
4969{
4970 static char buf[MAX_LEN_LINK];
4971
4972 if (firepower == 1) {
4973 buf[0] = '\0';
4974 } else {
4975 fc_snprintf(buf, sizeof(buf),
4976 /* TRANS: FP = Firepower of a unit; note trailing space */
4977 _("FP:%d "),
4978 firepower);
4979 }
4980
4981 return buf;
4982}
4983
4984/**********************************************************************/
4993static bool do_attack(struct unit *punit, struct tile *def_tile,
4994 const struct action *paction)
4995{
5000 struct unit *ploser, *pwinner;
5003 int winner_id;
5004 struct player *pplayer = unit_owner(punit);
5005 bool adj;
5006 enum direction8 facing;
5007 int att_hp, def_hp, att_fp, def_fp;
5009 int def_power, att_power;
5010 int att_vet, def_vet;
5011 struct unit *pdefender;
5012 const struct unit_type *act_utype = unit_type_get(punit);
5013 struct civ_map *nmap = &(wld.map);
5014 bool powerless;
5015
5017 /* Can't fight air... */
5018 return FALSE;
5019 }
5020
5022 def_hp_start = pdefender->hp;
5026
5027 log_debug("Start attack: %s %s against %s %s.",
5032
5033 /* Sanity checks */
5038 FALSE,
5039 "Trying to attack a unit with which you have peace "
5040 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
5044 FALSE,
5045 "Trying to attack a unit with which you have "
5046 "alliance at (%d, %d).", TILE_XY(def_tile));
5047
5050
5052 punit->tile, pdefender->tile, &facing);
5053
5054 fc_assert(adj);
5055 if (adj) {
5056 punit->facing = facing;
5057 pdefender->facing = opposite_direction(facing);
5058 }
5059
5061 old_defender_vet = pdefender->veteran;
5062
5063 /* N.B.: unit_veteran_level_string always returns the same pointer. */
5066
5067 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
5070
5071 /* Record tired attack string before attack */
5073
5074 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
5075 &att_vet, &def_vet, paction);
5076
5077 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
5078 && unit_transported(punit)) {
5079 /* Dying attacker must be first unloaded so it doesn't die inside transport */
5081 }
5082
5084
5085 punit->hp = att_hp;
5086 pdefender->hp = def_hp;
5087
5089
5090 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
5091 * the movement attack modifier is correct! --dwp
5092 *
5093 * For greater Civ2 compatibility (and game balance issues), we recompute
5094 * the new total MP based on the HP the unit has left after being damaged,
5095 * and subtract the MPs that had been used before the combat (plus the
5096 * points used in the attack itself, for the attacker). -GJW, Glip
5097 */
5100
5101 if (punit->moves_left < 0) {
5102 punit->moves_left = 0;
5103 }
5104 if (pdefender->moves_left < 0) {
5105 pdefender->moves_left = 0;
5106 }
5109
5110 /* This may cause a diplomatic incident. */
5114
5115 if (punit->hp > 0 && pdefender->hp > 0) {
5116 /* Neither died */
5118 pdefender->veteran - old_defender_vet, 0);
5119 return TRUE;
5120 }
5121 pwinner = (punit->hp > 0) ? punit : pdefender;
5122 winner_id = pwinner->id;
5123 ploser = (pdefender->hp > 0) ? punit : pdefender;
5124
5125 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5126 old_defender_vet)) ? 0 : 1;
5127
5129 pdefender->veteran - old_defender_vet, 0);
5130
5131 /* N.B.: unit_link always returns the same pointer. */
5136
5137 if (punit == ploser) {
5138 /* The attacker lost */
5139 log_debug("Attacker lost: %s %s against %s %s.",
5144
5148 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5149 * 9 HP remaining] survived the pathetic ...attack from
5150 * green Warriors [id:90 ...A:1.0 HP:10]. */
5151 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5152 " survived the pathetic %sattack from %s %s "
5153 "[id:%d %sA:%.1f HP:%d]."),
5156 pdefender->id,
5158 (float)def_power/POWER_FACTOR,
5159 def_hp_start - pdefender->hp,
5160 pdefender->hp,
5163 loser_link,
5164 punit->id,
5166 (float)att_power/POWER_FACTOR,
5167 att_hp_start);
5168 } else {
5171 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5172 * 9 HP remaining] survived the pathetic ...attack from the
5173 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5174 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5175 " survived the pathetic %sattack from the %s %s %s "
5176 "[id:%d %sA:%.1f HP:%d]."),
5179 pdefender->id,
5181 (float)def_power/POWER_FACTOR,
5182 def_hp_start - pdefender->hp,
5183 pdefender->hp,
5187 loser_link,
5188 punit->id,
5190 (float)att_power/POWER_FACTOR,
5191 att_hp_start);
5192 }
5193
5194 if (vet) {
5196 }
5197
5201 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5202 * failed against green Destroyer [id:200 lost
5203 * 27 HP, 3 HP remaining%s]!";
5204 * last %s is either "and ..." or empty string */
5205 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5206 "against %s %s [id:%d lost %d HP, %d HP "
5207 "remaining%s]!"),
5209 loser_link,
5210 punit->id,
5212 (float)att_power/POWER_FACTOR,
5216 pdefender->id,
5217 def_hp_start - pdefender->hp,
5218 pdefender->hp,
5220 } else {
5223 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5224 * failed against the Polish green Destroyer [id:200 lost
5225 * 27 HP, 3 HP remaining%s]!";
5226 * last %s is either "and ..." or empty string */
5227 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5228 "against the %s %s %s [id:%d lost %d HP, %d HP "
5229 "remaining%s]!"),
5231 loser_link,
5232 punit->id,
5234 (float)att_power/POWER_FACTOR,
5239 pdefender->id,
5240 def_hp_start - pdefender->hp,
5241 pdefender->hp,
5243 }
5244
5246 } else {
5247 /* The defender lost, the attacker punit lives! */
5248 struct city *pcity;
5249
5250 log_debug("Defender lost: %s %s against %s %s.",
5255
5259 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5260 * lost to an attack by green Legion
5261 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5262 * last %s is either "and ..." or empty string */
5263 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5264 "%s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5265 "remaining%s]."),
5267 loser_link,
5268 pdefender->id,
5270 (float)def_power/POWER_FACTOR,
5274 punit->id,
5276 (float)att_power/POWER_FACTOR,
5277 att_hp_start - pwinner->hp,
5278 pwinner->hp,
5280 } else {
5283 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5284 * lost to an attack by the Greek green Legion
5285 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5286 * last %s is either "and ..." or empty string */
5287 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5288 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5289 "remaining%s]."),
5291 loser_link,
5292 pdefender->id,
5294 (float)def_power/POWER_FACTOR,
5299 punit->id,
5301 (float)att_power/POWER_FACTOR,
5302 att_hp_start - pwinner->hp,
5303 pwinner->hp,
5305 }
5306
5310 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5311 * lost 1 HP, has 9 HP remaining] succeeded against
5312 * green Warriors [id:100 HP:10]." */
5313 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5314 "has %d remaining] succeeded against %s %s "
5315 "[id:%d HP:%d]."),
5318 punit->id,
5321 (float)att_power/POWER_FACTOR,
5322 att_hp_start - pwinner->hp,
5323 pwinner->hp,
5325 loser_link,
5326 pdefender->id,
5327 def_hp_start);
5328 } else {
5331 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5332 * lost 1 HP, has 9 HP remaining] succeeded against the
5333 * Greek green Warriors [id:100 HP:10]." */
5334 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5335 "has %d remaining] succeeded against the %s %s %s "
5336 "[id:%d HP:%d]."),
5339 punit->id,
5342 (float)att_power/POWER_FACTOR,
5343 att_hp_start - pwinner->hp,
5344 pwinner->hp,
5347 loser_link,
5348 pdefender->id,
5349 def_hp_start);
5350 }
5351
5352 punit->moved = TRUE; /* We moved */
5353
5354 if (paction->result == ACTRES_COLLECT_RANSOM) {
5357 } else {
5360 }
5361
5362 /* Now that dead defender is certainly no longer listed as unit
5363 * supported by the city, we may even remove the city
5364 * (if it shrinks from size 1) */
5366 if (pcity != nullptr) {
5368 }
5369 if (unit_is_alive(winner_id)) {
5371 return TRUE;
5372 }
5373 } else {
5374 return TRUE;
5375 }
5376 }
5377
5378 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5379 * if there are enemy units in the tile (a fortress, city or air base with
5380 * multiple defenders and unstacked combat). Note that this could mean
5381 * capturing (or destroying) a city. */
5382
5383 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5385 }
5386
5387 /* The attacker may have died for many reasons */
5388 if (game_unit_by_number(winner_id) != nullptr) {
5389 send_unit_info(nullptr, pwinner);
5390 }
5391
5392 return TRUE;
5393}
5394
5395/**********************************************************************/
5406 struct unit *act_unit,
5407 struct city *tgt_city,
5408 const struct action *paction)
5409{
5410 struct player *tgt_player;
5411 char prod[256];
5412 const struct unit_type *act_utype;
5413 const struct tile *tgt_tile;
5414 const char *clink;
5415
5416 /* Sanity checks */
5421
5424
5426
5427 /* The surgical strike may miss. */
5428 {
5429 /* Roll the dice. */
5432 paction)) {
5433 /* Notify the player. */
5436 /* TRANS: unit, action, city */
5437 _("Your %s failed to do %s in %s."),
5441
5442 /* Make the failed attempt cost a single move. */
5443 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5444
5445 return FALSE;
5446 }
5447 }
5448
5449 /* Get name of the production */
5450 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5451
5452 /* Destroy the production */
5453 tgt_city->shield_stock = 0;
5455
5456 /* Let the players know. */
5457 clink = city_link(tgt_city); /* Be careful not to call city_link()
5458 * again as long as we need clink */
5461 _("Your %s succeeded in destroying"
5462 " the production of %s in %s."),
5464 prod, clink);
5467 _("The production of %s was destroyed in %s,"
5468 " %s are suspected."),
5469 prod, clink,
5471
5473
5474 /* May cause an incident */
5477 clink);
5478
5479 return TRUE;
5480}
5481
5482/**********************************************************************/
5493 struct unit *act_unit,
5494 struct city *tgt_city,
5496 const struct action *paction)
5497{
5498 struct player *tgt_player;
5500 const struct tile *tgt_tile;
5501 const struct unit_type *act_utype;
5502 const char *clink;
5503
5504 /* Sanity checks */
5509
5511
5514
5515 /* The surgical strike may miss. */
5516 {
5517 /* Roll the dice. */
5520 paction)) {
5521 /* Notify the player. */
5524 /* TRANS: unit, action, city */
5525 _("Your %s failed to do %s in %s."),
5529
5530 /* Make the failed attempt cost a single move. */
5531 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5532
5533 return FALSE;
5534 }
5535 }
5536
5538 /* Nothing to destroy here. */
5539
5540 /* Notify the player. */
5543 _("Your %s didn't find a %s to %s in %s."),
5548
5549 /* Punish the player for blindly attacking a building. */
5550 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5551
5552 return FALSE;
5553 }
5554
5556 /* Notify the player. */
5559 _("Your %s cannot do %s to %s in %s."),
5564
5565 /* Punish the player for blindly attacking a building. */
5566 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5567
5568 return FALSE;
5569 }
5570
5572
5573 /* Destroy the building. */
5574 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5575
5576 /* Update the player's view of the city. */
5577 send_city_info(nullptr, tgt_city);
5578
5579 /* Let the players know. */
5580 clink = city_link(tgt_city); /* Be careful not to call city_link()
5581 * again as long as we need clink */
5584 _("Your %s destroyed the %s in %s."),
5587 clink);
5590 _("The %s destroyed the %s in %s."),
5593 clink);
5594
5595 /* May cause an incident */
5598
5599 return TRUE;
5600}
5601
5602/**********************************************************************/
5612 struct unit *act_unit,
5613 struct city *tgt_city,
5614 struct action *paction)
5615{
5616 bool success;
5617 struct tile *tgt_tile = city_tile(tgt_city);
5618 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5619 int tgt_city_id = tgt_city->id;
5621 const char *victim_link = city_link(tgt_city);
5622
5623 /* Sanity check */
5625
5626 unit_move(act_unit, tgt_tile, move_cost, nullptr, FALSE, TRUE, TRUE,
5627 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5629
5630 /* The city may have been destroyed during the conquest. */
5633
5634 if (success) {
5635 const struct unit_type *act_utype = unit_type_get(act_unit);
5636
5637 /* May cause an incident */
5640 victim_link);
5641 }
5642
5643 return success;
5644}
5645
5646/**********************************************************************/
5650 struct tile *dest_tile,
5651 bool igzoc,
5652 struct unit *embark_to,
5653 bool enter_enemy_city)
5654{
5655 struct tile *src_tile = unit_tile(punit);
5658 src_tile, dest_tile, igzoc, TRUE, embark_to,
5660
5661 switch (reason) {
5662 case MR_OK:
5663 return TRUE;
5664
5665 case MR_NO_WAR:
5667 _("Cannot attack unless you declare war first."));
5668 break;
5669
5670 case MR_ZOC:
5672 _("%s can only move into your own zone of control."),
5673 unit_link(punit));
5674 break;
5675
5676 case MR_TRIREME:
5678 _("%s cannot move that far from the coast line."),
5679 unit_link(punit));
5680 break;
5681
5682 case MR_PEACE:
5683 if (tile_owner(dest_tile)) {
5685 _("Cannot invade unless you break peace with "
5686 "%s first."),
5687 player_name(tile_owner(dest_tile)));
5688 }
5689 break;
5690
5693 _("%s cannot disembark outside of a city or a native base "
5694 "for %s."),
5698 break;
5699
5700 case MR_NON_NATIVE_MOVE:
5702 _("Terrain is unsuitable for %s units."),
5704 break;
5705
5706 default:
5707 /* FIXME: need more explanations someday! */
5708 break;
5709 };
5710
5711 return FALSE;
5712}
5713
5714/**********************************************************************/
5721 struct unit *actor_unit,
5722 struct tile *target_tile,
5723 const struct action *paction)
5724{
5726 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5727
5728 unit_move(actor_unit, target_tile, move_cost,
5729 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
5730 /* Don't override "Conquer City" */
5731 FALSE,
5732 /* Don't override "Conquer Extras" */
5733 FALSE,
5734 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5736
5737 /* May cause an incident */
5741
5742 return TRUE;
5743}
5744
5745/**********************************************************************/
5759 bool move_do_not_act)
5760{
5761 struct player *pplayer = unit_owner(punit);
5762 struct unit *ptrans;
5763 const struct civ_map *nmap = &(wld.map);
5764
5765 /*** Phase 1: Attempted action interpretation checks ***/
5766
5767 /* Check if the move should be interpreted as an attempt to perform an
5768 * enabler controlled action to the target tile. When the move may be an
5769 * action attempt the server stops moving the unit, marks it as wanting a
5770 * decision based on its own movement to the tile it attempted to move to
5771 * and notifies the client.
5772 *
5773 * In response to the unit being marked as wanting a decision the client
5774 * can query the server for what actions the unit, given the player's
5775 * knowledge, may be able to perform against a target at the tile it tried
5776 * to move to. The server will respond to the query with the actions that
5777 * may be enabled and, when all actions are known to be illegal given the
5778 * player's knowledge, an explanation why no action could be done. The
5779 * client will probably use the list of potentially legal actions, if any,
5780 * to pop up an action selection dialog. See handle_unit_action_query()
5781 *
5782 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5783 * to perform an enabler controlled action.
5784 * Examples of where this is useful is for AI moves, goto, when the player
5785 * attempts to move to a tile occupied by potential targets like allied
5786 * cities or units and during rule forced moves.
5787 *
5788 * A move is not interpreted as an attempted action because the unit is
5789 * able to do a self targeted action.
5790 *
5791 * A move is not interpreted as an attempted action because an action
5792 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5793 * perform a regular move to the tile.
5794 *
5795 * An attempted move to a tile a unit can't move to is always interpreted
5796 * as trying to perform an action (unless move_do_not_act is TRUE) */
5797 if (!move_do_not_act) {
5800 FALSE, FALSE, FALSE);
5804 /* A legal action with an extra sub target is a legal action */
5806 /* Tile target actions with extra sub targets are handled above */
5808
5810 /* There is a target punit, from the player's point of view, may be
5811 * able to act against OR punit can't do any non action move. The
5812 * client should therefore ask what action(s) the unit can perform
5813 * to any targets at pdesttile.
5814 *
5815 * In the first case the unit needs a decision about what action, if
5816 * any at all, to take. Asking what actions the unit can perform
5817 * will return a list of actions that may, from the players point of
5818 * view, be possible. The client can then show this list to the
5819 * player or, if configured to do so, make the choice it self.
5820 *
5821 * In the last case the player may need an explanation about why no
5822 * action could be taken. Asking what actions the unit can perform
5823 * will provide this explanation. */
5827
5828 /* The move wasn't done because the unit wanted the player to
5829 * decide what to do or because the unit couldn't move to the
5830 * target tile. */
5831 return FALSE;
5832 }
5833 }
5834
5835 /*** Phase 2: OK now move the unit ***/
5836 /* This is a regular move, subject to the rules. */
5838 punit, pdesttile, nullptr)) {
5839 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5843 punit, pdesttile, nullptr)) {
5844 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5848 punit, pdesttile, nullptr)) {
5849 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5855 punit, ptrans)) {
5856 /* "Transport Embark". */
5857 return unit_perform_action(pplayer, punit->id, ptrans->id,
5863 punit, ptrans)) {
5864 /* "Transport Embark 2". */
5865 return unit_perform_action(pplayer, punit->id, ptrans->id,
5871 punit, ptrans)) {
5872 /* "Transport Embark 3". */
5873 return unit_perform_action(pplayer, punit->id, ptrans->id,
5879 punit, ptrans)) {
5880 /* "Transport Embark 4". */
5881 return unit_perform_action(pplayer, punit->id, ptrans->id,
5885 punit, pdesttile, nullptr)) {
5886 /* "Transport Disembark". */
5887 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5891 punit, pdesttile, nullptr)) {
5892 /* "Transport Disembark 2". */
5893 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5897 punit, pdesttile, nullptr)) {
5898 /* "Transport Disembark 3". */
5899 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5903 punit, pdesttile, nullptr)) {
5904 /* "Transport Disembark 4". */
5905 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5909 punit, pdesttile, nullptr)) {
5910 /* "Enter Hut". */
5911 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5915 punit, pdesttile, nullptr)) {
5916 /* "Enter Hut 2". */
5917 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5921 punit, pdesttile, nullptr)) {
5922 /* "Frighten Hut". */
5923 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5927 punit, pdesttile, nullptr)) {
5928 /* "Frighten Hut 2". */
5929 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5932 } else {
5933 /* TODO: Extend the action not enabled explanation system to cover all
5934 * existing reasons and switch to using it. See hrm Feature #920229 */
5936 nullptr, FALSE);
5937 return FALSE;
5938 }
5939}
5940
5941/**********************************************************************/
5951static bool unit_do_help_build(struct player *pplayer,
5952 struct unit *punit,
5953 struct city *pcity_dest,
5954 const struct action *paction)
5955{
5956 const char *work;
5957 const char *prod;
5958 int shields;
5959 const struct unit_type *act_utype;
5960 struct player *cowner;
5961
5962 /* Sanity check: The actor still exists. */
5963 fc_assert_ret_val(pplayer, FALSE);
5965
5966 /* Sanity check: The target city still exists. */
5968
5971
5973 /* Add the caravan shields */
5974 pcity_dest->shield_stock += shields;
5975
5976 /* Will be punished for changing production to something that can't
5977 * receive "Help Wonder" help. */
5979 &pcity_dest->production));
5980 pcity_dest->caravan_shields += shields;
5981 } else {
5983 /* Add the shields from recycling the unit to the city's current
5984 * production. */
5985 pcity_dest->shield_stock += shields;
5986
5987 /* If we change production later at this turn. No penalty is added. */
5988 pcity_dest->disbanded_shields += shields;
5989 }
5990
5992
5993 conn_list_do_buffer(cowner->connections);
5994
5996 /* Let the player that just donated shields with "Help Wonder" know
5997 * the result of their donation. */
5999 } else {
6001 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
6002 * current production in Bergen (4 surplus).
6003 * "Disband Unit Recover" says "current production" rather than its name. */
6004 prod = _("current production");
6005 }
6006
6007 if (build_points_left(pcity_dest) >= 0) {
6008 /* TRANS: Your Caravan does "Help Wonder" to help build the
6009 * Pyramids in Bergen (4 remaining).
6010 * You can reorder '4' and 'remaining' in the actual format string. */
6011 work = _("remaining");
6012 } else {
6013 /* TRANS: Your Caravan does "Help Wonder" to help build the
6014 * Pyramids in Bergen (4 surplus).
6015 * You can reorder '4' and 'surplus' in the actual format string. */
6016 work = _("surplus");
6017 }
6018
6020 ftc_server,
6021 /* TRANS: Your Caravan does "Help Wonder" to help build the
6022 * Pyramids in Bergen (4 surplus). */
6023 _("Your %s does %s to help build the %s in %s (%d %s)."),
6026 prod,
6029 work);
6030
6031 /* May cause an incident */
6034
6035 if (cowner != unit_owner(punit)) {
6036 /* Tell the city owner about the gift they just received. */
6037
6040 /* TRANS: Help building the Pyramids in Bergen received
6041 * from Persian Caravan (4 surplus). */
6042 _("Help building the %s in %s received from %s %s "
6043 "(%d %s)."),
6049 work);
6050 }
6051
6054 conn_list_do_unbuffer(cowner->connections);
6055
6056 return TRUE;
6057}
6058
6059/**********************************************************************/
6066static bool do_unit_establish_trade(struct player *pplayer,
6067 struct unit *punit,
6068 struct city *pcity_dest,
6069 const struct action *paction)
6070{
6073 int revenue;
6074 bool can_establish;
6075 int home_overbooked = 0;
6076 int dest_overbooked = 0;
6077 int home_max;
6078 int dest_max;
6079 struct city *pcity_homecity;
6082 enum trade_route_bonus_type bonus_type;
6083 struct goods_type *goods;
6084 const char *goods_str;
6085 const struct unit_type *act_utype;
6086
6087 /* Sanity check: The actor still exists. */
6088 fc_assert_ret_val(pplayer, FALSE);
6090
6091 /* Sanity check: The target city still exists. */
6093
6095
6096 if (!pcity_homecity) {
6098 _("Sorry, your %s cannot establish"
6099 " a trade route because it has no home city."),
6100 unit_link(punit));
6101 return FALSE;
6102 }
6103
6105
6106 if (goods == nullptr) {
6108 _("Sorry, your %s cannot establish"
6109 " a trade route because it's not carrying any goods."),
6110 unit_link(punit));
6111 return FALSE;
6112 }
6113
6116
6119 _("Sorry, your %s cannot establish"
6120 " a trade route between %s and %s."),
6124 return FALSE;
6125 }
6126
6128
6132
6133 /* This part of code works like can_establish_trade_route(), except
6134 * that we actually do the action of making the trade route. */
6135
6136 /* If we can't make a new trade route we can still get the trade bonus. */
6139
6140 if (can_establish) {
6145 }
6146
6147 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
6149
6150 /* See if there's a trade route we can cancel at the home city. */
6151 if (home_overbooked >= 0) {
6152 if (home_max <= 0
6155 >= trade)) {
6158 _("Sorry, your %s cannot establish"
6159 " a trade route here!"),
6160 punit_link);
6161 if (home_max > 0) {
6164 PL_(" The city of %s already has %d "
6165 "better trade route!",
6166 " The city of %s already has %d "
6167 "better trade routes!", home_max),
6169 home_max);
6170 }
6172 }
6173 }
6174
6175 /* See if there's a trade route we can cancel at the dest city. */
6176 if (can_establish && dest_overbooked >= 0) {
6177 if (dest_max <= 0
6180 >= trade)) {
6183 _("Sorry, your %s cannot establish"
6184 " a trade route here!"),
6185 punit_link);
6186 if (dest_max > 0) {
6189 PL_(" The city of %s already has %d "
6190 "better trade route!",
6191 " The city of %s already has %d "
6192 "better trade routes!", dest_max),
6194 dest_max);
6195 }
6197 }
6198 }
6199 }
6200
6201 /* We now know for sure whether we can establish a trade route. */
6202
6203 /* Calculate and announce initial revenue. */
6204 revenue
6207
6208 bonus_type = trade_route_settings_by_type
6210
6212
6214
6215 /* We want to keep the bonus type string as the part of the format of the PL_() strings
6216 * for supporting proper pluralization for it. */
6217 switch (bonus_type) {
6218 case TBONUS_NONE:
6221 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
6222 _("Your %s from %s has arrived in %s carrying %s."),
6223 punit_link,
6226 goods_str);
6227 break;
6228 case TBONUS_GOLD:
6231 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6232 PL_("Your %s from %s has arrived in %s carrying %s,"
6233 " and revenues amount to %d in gold.",
6234 "Your %s from %s has arrived in %s carrying %s,"
6235 " and revenues amount to %d in gold.",
6236 revenue),
6237 punit_link,
6240 goods_str,
6241 revenue);
6242 break;
6243 case TBONUS_SCIENCE:
6246 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6247 PL_("Your %s from %s has arrived in %s carrying %s,"
6248 " and revenues amount to %d in research.",
6249 "Your %s from %s has arrived in %s carrying %s,"
6250 " and revenues amount to %d in research.",
6251 revenue),
6252 punit_link,
6255 goods_str,
6256 revenue);
6257 break;
6258 case TBONUS_BOTH:
6261 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6262 PL_("Your %s from %s has arrived in %s carrying %s,"
6263 " and revenues amount to %d in gold and research.",
6264 "Your %s from %s has arrived in %s carrying %s,"
6265 " and revenues amount to %d in gold and research.",
6266 revenue),
6267 punit_link,
6270 goods_str,
6271 revenue);
6272 break;
6273 }
6274
6275 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6276 pplayer->economic.gold += revenue;
6277
6278 send_player_info_c(pplayer, pplayer->connections);
6279 }
6280
6281 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6282 /* add bulbs and check for finished research */
6283 update_bulbs(pplayer, revenue, TRUE, TRUE);
6284
6285 /* Inform everyone about tech changes */
6286 send_research_info(research_get(pplayer), nullptr);
6287 }
6288
6289 if (can_establish) {
6290 struct city_list *cities_out_of_home;
6291 struct city_list *cities_out_of_dest;
6292 struct player *partner_player;
6293
6294 /* Announce creation of trade route (it's not actually created until
6295 * later in this function, as we have to cancel existing routes, but
6296 * it makes more sense to announce in this order) */
6297
6299
6300 /* Always tell the unit owner */
6301 notify_player(pplayer, nullptr,
6303 _("New trade route established from %s to %s."),
6306 if (pplayer != partner_player) {
6309 _("The %s established a trade route between their "
6310 "city %s and %s."),
6311 nation_plural_for_player(pplayer),
6314 }
6315
6318
6319 /* Now cancel any less profitable trade route from the home city. */
6321 struct trade_route *pback;
6322
6324
6326 free(premove);
6327 free(pback);
6329
6330 /* And the same for the dest city. */
6332 struct trade_route *pback;
6333
6335
6337 free(premove);
6338 free(pback);
6340
6342
6343 /* Refresh the cities. */
6352
6353 /* Notify the owners of the cities. */
6362
6363 /* Notify each player about the other's cities. */
6364 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6368 send_city_info(pplayer, pcity_dest);
6369 }
6370
6375 }
6376 if (pplayer != city_owner(pcity)) {
6377 send_city_info(pplayer, pcity);
6379 }
6381
6386 }
6387 if (pplayer != city_owner(pcity)) {
6388 send_city_info(pplayer, pcity);
6390 }
6392
6395 }
6396
6397 /* May cause an incident */
6399 pplayer, act_utype, city_owner(pcity_dest),
6402
6404
6405 /* Free data. */
6408
6409 return TRUE;
6410}
6411
6412/**********************************************************************/
6416void create_trade_route(struct city *from, struct city *to,
6417 struct goods_type *goods)
6418{
6420
6421 /* Actually create the new trade route */
6422 proute_from = fc_malloc(sizeof(struct trade_route));
6423 proute_from->partner = to->id;
6424 proute_from->goods = goods;
6425
6426 proute_to = fc_malloc(sizeof(struct trade_route));
6427 proute_to->partner = from->id;
6428 proute_to->goods = goods;
6429
6433 } else {
6434 proute_from->dir = RDIR_FROM;
6435 proute_to->dir = RDIR_TO;
6436 }
6439}
6440
6441/**********************************************************************/
6449void handle_unit_sscs_set(struct player *pplayer,
6450 int unit_id,
6452 int value)
6453{
6454 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6455 const struct civ_map *nmap = &(wld.map);
6456
6457 if (punit == nullptr) {
6458 /* Being asked to unqueue a "spent" unit because the client haven't
6459 * been told that it's gone is expected. */
6460 if (type != USSDT_UNQUEUE) {
6461 /* Probably died or bribed. */
6462 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6463 }
6464
6465 return;
6466 }
6467
6468 switch (type) {
6469 case USSDT_QUEUE:
6470 /* Reminds the client to ask the server about what actions the unit can
6471 * perform against the target tile. Action decision state can be set by
6472 * the server it self too. */
6473
6474 if (index_to_tile(nmap, value) == nullptr) {
6475 /* Asked to be reminded to ask what actions the unit can do to a non
6476 * existing target tile. */
6477 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6478 value, unit_id);
6479 break;
6480 }
6481
6484
6485 /* Let the client know that this unit needs the player to decide
6486 * what to do. */
6488
6489 break;
6490 case USSDT_UNQUEUE:
6491 /* Delete the reminder for the client to ask the server about what
6492 * actions the unit can perform against a certain target tile.
6493 * Action decision state can be set by the server it self too. */
6494
6496 punit->action_decision_tile = nullptr;
6497
6498 /* Let the client know that this unit no longer needs the player to
6499 * decide what to do. */
6500 send_unit_info(pplayer->connections, punit);
6501
6502 break;
6503 case USSDT_BATTLE_GROUP:
6504 /* Battlegroups are handled entirely by the client, so all we have to
6505 do here is save the battlegroup ID so that it'll be persistent. */
6506
6508
6509 break;
6510 case USSDT_SENTRY:
6511 if (value == 0) {
6512 if (punit->activity != ACTIVITY_SENTRY) {
6513 return;
6514 }
6515
6517 /* Impossible to set to Idle? */
6519 }
6520 } else if (value == 1) {
6523 return;
6524 }
6525
6527 /* Should have been caught above */
6529 }
6530 } else {
6531 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6533 }
6534 break;
6535 }
6536}
6537
6538/**********************************************************************/
6541static void unit_plans_clear(struct unit *punit)
6542{
6543 /* Remove city spot reservations for AI settlers on city founding
6544 * mission. */
6545 adv_unit_new_task(punit, AUT_NONE, nullptr);
6546
6547 /* Get rid of old orders. */
6549
6550 /* Make sure that no old goto_tile remains. */
6551 punit->goto_tile = nullptr;
6552}
6553
6554/**********************************************************************/
6558 int unit_id,
6560{
6561 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6562
6563 if (punit == nullptr) {
6564 /* Probably died or bribed. */
6565 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6566 unit_id);
6567 return;
6568 }
6569
6571 /* Client error. */
6572 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6573 agent);
6574 return;
6575 }
6576
6577 /* Set the state or exit */
6578 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6579 return;
6580 }
6581
6582 /* Give the new agent a blank slate */
6584
6585 if (agent == SSA_AUTOEXPLORE) {
6587 /* Should have been caught above */
6590 }
6591
6592 /* Exploring is handled here explicitly, since the player expects to
6593 * see an immediate response from setting a unit to auto-explore.
6594 * Handling it deeper in the code leads to some tricky recursive loops -
6595 * see PR#2631. */
6596 if (punit->moves_left > 0) {
6598 }
6599 }
6600}
6601
6602/**********************************************************************/
6607 struct unit *punit,
6609{
6610 const struct civ_map *nmap = &(wld.map);
6611
6612 /* Check that the agent can be activated for this unit. */
6613 switch (agent) {
6614 case SSA_AUTOWORKER:
6616 return FALSE;
6617 }
6618 break;
6619 case SSA_AUTOEXPLORE:
6622 return FALSE;
6623 }
6624 break;
6625 case SSA_NONE:
6626 /* Always possible. */
6627 break;
6628 case SSA_COUNT:
6630 break;
6631 }
6632
6633 if (punit->ssa_controller != agent) {
6635 send_unit_info(nullptr, punit);
6636 }
6637
6638 return TRUE;
6639}
6640
6641/**********************************************************************/
6647 struct extra_type *old_target)
6648{
6649 switch (punit->activity) {
6650 case ACTIVITY_IDLE:
6651 switch (old_activity) {
6652 case ACTIVITY_PILLAGE:
6653 {
6654 if (old_target != nullptr) {
6656 if (punit2->activity == ACTIVITY_PILLAGE) {
6657 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6658 if (pdep == old_target) {
6660 send_unit_info(nullptr, punit2);
6661 break;
6662 }
6664 }
6666 }
6667 break;
6668 }
6669 case ACTIVITY_EXPLORE:
6670 /* Restore unit's control status */
6672 break;
6673 default:
6674 ; /* Do nothing */
6675 }
6676 break;
6677 case ACTIVITY_EXPLORE:
6680 send_unit_info(nullptr, punit);
6681 break;
6682 default:
6683 /* Do nothing */
6684 break;
6685 }
6686}
6687
6688/**********************************************************************/
6704
6705/**********************************************************************/
6711{
6712 const struct civ_map *nmap = &(wld.map);
6713
6714 /* Must specify target for ACTIVITY_BASE */
6717
6719 struct extra_type *target = nullptr;
6720
6721 /* Assume untargeted pillaging if no target specified */
6725 trigger_action)) {
6728 }
6729
6730 return TRUE;
6731}
6732
6733/**********************************************************************/
6742{
6743 const struct civ_map *nmap = &(wld.map);
6744
6746 trigger_action)) {
6747 return FALSE;
6748 } else {
6751
6753 send_unit_info(nullptr, punit);
6755
6756 return TRUE;
6757 }
6758}
6759
6760/**********************************************************************/
6780
6781/**********************************************************************/
6786 struct extra_type **new_target,
6788{
6789 const struct civ_map *nmap = &(wld.map);
6790
6795 *new_target)) {
6797
6799
6800 if (list != nullptr && action_list_size(list) > 0) {
6801 /* Trigger action system */
6803 (*new_target) != nullptr ? (*new_target)->id : NO_TARGET,
6805 } else {
6808 }
6809 }
6810
6811 return TRUE;
6812}
6813
6814/**********************************************************************/
6822 struct extra_type **new_target,
6824{
6825 const struct civ_map *nmap = &(wld.map);
6826
6829 *new_target)) {
6830 return FALSE;
6831 } else {
6835
6838 new_target);
6841 /* unit_assign_specific_activity_target() changed our target activity
6842 * (to ACTIVITY_IDLE in practice) */
6844 } else {
6847 send_unit_info(nullptr, punit);
6849
6851 /* Casus Belli for when the activity successfully begins. */
6852 /* TODO: is it more logical to change Casus_Belli_Complete to
6853 * Casus_Belli_Successful_Beginning and trigger it here? */
6859 }
6860 }
6861
6862 return TRUE;
6863 }
6864}
6865
6866/**********************************************************************/
6869void handle_unit_orders(struct player *pplayer,
6870 const struct packet_unit_orders *packet)
6871{
6872 int length = packet->length;
6873 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6874 const struct civ_map *nmap = &(wld.map);
6875 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6876 struct unit_order *order_list;
6877#ifdef FREECIV_DEBUG
6878 int i;
6879#endif
6880
6881 if (punit == nullptr) {
6882 /* Probably died or bribed. */
6883 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6884 return;
6885 }
6886
6887 if (0 > length || MAX_LEN_ROUTE < length) {
6888 /* Shouldn't happen */
6889 log_error("handle_unit_orders() invalid %s (%d) "
6890 "packet length %d (max %d)", unit_rule_name(punit),
6891 packet->unit_id, length, MAX_LEN_ROUTE);
6892 return;
6893 }
6894
6895 if (src_tile != unit_tile(punit)) {
6896 /* Failed sanity check. Usually this happens if the orders were sent
6897 * in the previous turn, and the client thought the unit was in a
6898 * different position than it's actually in. The easy solution is to
6899 * discard the packet. We don't send an error message to the client
6900 * here (though maybe we should?). */
6901 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6902 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6903 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6904 return;
6905 }
6906
6907 if (ACTIVITY_IDLE != punit->activity) {
6908 /* New orders implicitly abandon current activity */
6910 }
6911
6912 if (length) {
6913 order_list = create_unit_orders(nmap, length, packet->orders);
6914 if (!order_list) {
6915 log_error("received invalid orders from %s for %s (%d).",
6916 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6917 return;
6918 }
6919 }
6920
6921 /* This must be before old orders are freed. If this is
6922 * settlers on city founding mission, city spot reservation
6923 * from goto_tile must be freed, and free_unit_orders() loses
6924 * goto_tile information */
6925 adv_unit_new_task(punit, AUT_NONE, nullptr);
6926
6928 /* If we waited on a tile, reset punit->done_moving */
6929 punit->done_moving = (punit->moves_left <= 0);
6930
6931 if (length == 0) {
6933 send_unit_info(nullptr, punit);
6934 return;
6935 }
6936
6938 punit->orders.length = length;
6939 punit->orders.index = 0;
6940 punit->orders.repeat = packet->repeat;
6941 punit->orders.vigilant = packet->vigilant;
6942 if (length) {
6944 }
6945
6946 if (!packet->repeat) {
6948 } else {
6949 /* Make sure that no old goto_tile remains. */
6950 punit->goto_tile = nullptr;
6951 }
6952
6953#ifdef FREECIV_DEBUG
6954 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6955 for (i = 0; i < length; i++) {
6956 log_debug(" %d,%s,%s,%d,%d",
6957 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6958 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6960 packet->orders[i].order == ORDER_ACTIVITY ?
6962 "no action/activity required",
6963 packet->orders[i].target,
6964 packet->orders[i].sub_target);
6965 }
6966#endif /* FREECIV_DEBUG */
6967
6969 || execute_orders(punit, TRUE)) {
6970 /* Looks like the unit survived. */
6971 send_unit_info(nullptr, punit);
6972 }
6973}
6974
6975/**********************************************************************/
6978void handle_worker_task(struct player *pplayer,
6979 const struct packet_worker_task *packet)
6980{
6981 struct city *pcity = game_city_by_number(packet->city_id);
6982 struct worker_task *ptask = nullptr;
6983 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
6984
6985 if (pcity == nullptr || pcity->owner != pplayer || ptile == nullptr) {
6986 return;
6987 }
6988
6990 if (tile_index(ptask_old->ptile) == packet->tile_id) {
6991 ptask = ptask_old;
6992 }
6994
6995 if (ptask == nullptr) {
6996 if (packet->activity == ACTIVITY_LAST) {
6997 return;
6998 }
6999
7000 ptask = fc_malloc(sizeof(struct worker_task));
7002 worker_task_list_append(pcity->task_reqs, ptask);
7003 } else {
7004 if (packet->activity == ACTIVITY_LAST) {
7005 worker_task_list_remove(pcity->task_reqs, ptask);
7006 free(ptask);
7007 ptask = nullptr;
7008 }
7009 }
7010
7011 if (ptask != nullptr) {
7012 ptask->ptile = ptile;
7013 ptask->act = packet->activity;
7014 if (packet->tgt >= 0) {
7015 if (packet->tgt < MAX_EXTRA_TYPES) {
7016 ptask->tgt = extra_by_number(packet->tgt);
7017 } else {
7018 log_debug("Illegal worker task target %d", packet->tgt);
7019 ptask->tgt = nullptr;
7020 }
7021 } else {
7022 ptask->tgt = nullptr;
7023 }
7024 ptask->want = packet->want;
7025 }
7026
7027 if (ptask && !worker_task_is_sane(ptask)) {
7028 log_debug("Bad worker task");
7029 worker_task_list_remove(pcity->task_reqs, ptask);
7030 free(ptask);
7031 ptask = nullptr;
7032
7033 return;
7034 }
7035
7036 lsend_packet_worker_task(pplayer->connections, packet);
7037}
bool action_distance_inside_max(const struct action *action, const int distance)
Definition actions.c:1194
bool action_mp_full_makes_legal(const struct unit *actor, const action_id act_id)
Definition actions.c:5795
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1271
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5317
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:2605
const char * action_name_translation(const struct action *paction)
Definition actions.c:1251
struct act_prob action_prob_vs_tile(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4838
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1260
bool is_action_enabled_unit_on_stack(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Definition actions.c:3268
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:7550
int action_number(const struct action *action)
Definition actions.c:1229
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:3344
struct act_prob action_prob_vs_extras(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4921
struct act_prob action_prob_self(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id)
Definition actions.c:4991
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:3103
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:3180
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:4480
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:5740
struct action * action_is_blocked_by(const struct civ_map *nmap, const struct action *act, const struct unit *actor_unit, const struct tile *target_tile_arg, const struct city *target_city_arg, const struct unit *target_unit)
Definition actions.c:2282
bool action_id_exists(const action_id act_id)
Definition actions.c:1089
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1129
struct act_prob action_prob_unit_vs_tgt(const struct civ_map *nmap, const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:5013
struct act_prob action_prob_vs_stack(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:4755
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:4563
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1580
#define action_noninternal_iterate_end
Definition actions.h:240
#define ACTPROB_NA
Definition actions.h:719
static struct action * action_by_number(action_id act_id)
Definition actions.h:400
#define action_has_result(_act_, _res_)
Definition actions.h:184
#define action_enabler_list_iterate_end
Definition actions.h:194
#define action_id_get_role(act_id)
Definition actions.h:461
#define action_iterate_end
Definition actions.h:218
#define MAX_NUM_ACTIONS
Definition actions.h:62
#define action_id_get_actor_kind(act_id)
Definition actions.h:413
#define ACTPROB_NOT_KNOWN
Definition actions.h:721
#define action_get_activity(_pact_)
Definition actions.h:464
#define action_has_result_safe(paction, result)
Definition actions.h:428
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:192
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:449
#define ACTPROB_IMPOSSIBLE
Definition actions.h:717
#define action_id(_act_)
Definition actions.h:426
#define action_iterate(_act_)
Definition actions.h:214
#define ACTION_ANY
Definition actions.h:56
#define action_noninternal_iterate(_act_)
Definition actions.h:235
#define action_id_get_target_kind(act_id)
Definition actions.h:417
#define action_id_has_result_safe(act_id, result)
Definition actions.h:430
#define action_id_has_complex_target(act_id)
Definition actions.h:435
#define ACTION_NONE
Definition actions.h:59
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:106
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:144
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
void citizens_update(struct city *pcity, struct player *plr)
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1896
int city_granary_size(int city_size)
Definition city.c:2168
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1276
bool is_capital(const struct city *pcity)
Definition city.c:1615
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1501
void city_size_add(struct city *pcity, int add)
Definition city.c:1200
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2048
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2087
bool city_exist(int id)
Definition city.c:3648
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:772
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:565
static citizens city_size_get(const struct city *pcity)
Definition city.h:570
#define city_owner(_pcity_)
Definition city.h:564
#define MAX_CITY_SIZE
Definition city.h:104
#define city_list_iterate_end
Definition city.h:510
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2368
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1520
int build_points_left(struct city *pcity)
Definition citytools.c:576
void building_lost(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer)
Definition citytools.c:3082
void city_units_upkeep(const struct city *pcity)
Definition citytools.c:3168
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:374
void remove_city(struct city *pcity)
Definition citytools.c:1713
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Definition citytools.c:2948
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3715
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3603
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:763
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, Specialist_type_id sid, const char *reason)
Definition cityturn.c:1068
int city_growth_granary_savings(const struct city *pcity)
Definition cityturn.c:879
static struct fc_sockaddr_list * list
Definition clinet.c:102
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Definition combat.c:86
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:257
struct city * sdi_try_defend(const struct civ_map *nmap, const struct player *owner, const struct tile *ptile)
Definition combat.c:503
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:772
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:615
bool is_tired_attack(int moves_left)
Definition combat.c:532
enum unit_attack_result unit_wipe_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Definition combat.c:272
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
void get_modified_firepower(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, int *att_fp, int *def_fp)
Definition combat.c:411
#define POWER_FACTOR
Definition combat.h:32
@ ATT_NOT_WIPABLE
Definition combat.h:40
@ ATT_NONNATIVE_DST
Definition combat.h:39
@ ATT_OK
Definition combat.h:35
@ ATT_NON_ATTACK
Definition combat.h:36
@ ATT_UNREACHABLE
Definition combat.h:37
@ ATT_NONNATIVE_SRC
Definition combat.h:38
char * incite_cost
Definition comments.c:77
#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:368
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:358
#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:2801
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:56
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:73
struct unit * actor_unit
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
struct unit struct city * target_city
Definition dialogs_g.h:56
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:57
bool spy_escape(struct player *pplayer, struct unit *actor_unit, struct city *target_city, struct tile *target_tile, const struct action *paction)
Definition diplomats.c:2468
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1818
bool diplomat_bribe_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:644
bool spy_sabotage_unit(struct player *pplayer, struct unit *pdiplomat, struct unit *pvictim, const struct action *paction)
Definition diplomats.c:549
bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:484
bool diplomat_bribe_stack(struct player *pplayer, struct unit *pdiplomat, struct tile *pvictim, const struct action *paction)
Definition diplomats.c:812
void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat, struct city *pcity, const struct action *paction, int request_kind)
Definition diplomats.c:429
bool diplomat_get_tech(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Tech_type_id technology, const struct action *paction)
Definition diplomats.c:1011
bool diplomat_sabotage(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, Impr_type_id improvement, const struct action *paction)
Definition diplomats.c:1404
bool diplomat_incite(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:1255
bool spy_steal_gold(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1676
bool spy_spread_plague(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:214
bool spy_nuke_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1956
bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:324
bool spy_attack(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition diplomats.c:927
bool spy_poison(struct player *pplayer, struct unit *pdiplomat, struct city *pcity, const struct action *paction)
Definition diplomats.c:97
int int id
Definition editgui_g.h:28
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
enum event_type event
Definition events.c:81
ane_kind
Definition explanation.h:22
@ ANEK_IS_CITY_CENTER
Definition explanation.h:62
@ ANEK_ACTION_BLOCKS
Definition explanation.h:98
@ ANEK_DOMESTIC
Definition explanation.h:50
@ ANEK_LOW_MP
Definition explanation.h:60
@ ANEK_TGT_TILE_UNKNOWN
Definition explanation.h:94
@ ANEK_BAD_TERRAIN_TGT
Definition explanation.h:32
@ ANEK_TRIREME_MOVE
Definition explanation.h:74
@ ANEK_CITY_TOO_CLOSE_TGT
Definition explanation.h:83
@ ANEK_CITY_NO_CAPACITY
Definition explanation.h:89
@ ANEK_NATION_TGT
Definition explanation.h:58
@ ANEK_BAD_TARGET
Definition explanation.h:28
@ ANEK_MISSING_TARGET
Definition explanation.h:26
@ ANEK_TGT_IS_CLAIMED
Definition explanation.h:66
@ ANEK_FOREIGN
Definition explanation.h:52
@ ANEK_DISEMBARK_ACT
Definition explanation.h:77
@ ANEK_IS_TRANSPORTED
Definition explanation.h:34
@ ANEK_IS_NOT_CITY_CENTER
Definition explanation.h:64
@ ANEK_TGT_IS_UNCLAIMED
Definition explanation.h:68
@ ANEK_TGT_NON_ALLIED_UNITS_ON_TILE
Definition explanation.h:54
@ ANEK_BAD_TERRAIN_ACT
Definition explanation.h:30
@ ANEK_SCENARIO_DISABLED
Definition explanation.h:81
@ ANEK_ACTOR_HAS_HOME_CITY
Definition explanation.h:42
@ ANEK_PEACE
Definition explanation.h:48
@ ANEK_DISTANCE_NEAR
Definition explanation.h:70
@ ANEK_UNKNOWN
@ ANEK_ACT_NOT_ENOUGH_MONEY
Definition explanation.h:96
@ ANEK_IS_NOT_TRANSPORTING
Definition explanation.h:40
@ ANEK_TGT_UNREACHABLE
Definition explanation.h:79
@ ANEK_ACTOR_HAS_NO_HOME_CITY
Definition explanation.h:44
@ ANEK_NOT_WIPABLE
@ ANEK_CITY_TOO_BIG
Definition explanation.h:85
@ ANEK_NO_WAR
Definition explanation.h:46
@ ANEK_DISTANCE_FAR
Definition explanation.h:72
@ ANEK_ACTOR_UNIT
Definition explanation.h:24
@ ANEK_NATION_ACT
Definition explanation.h:56
@ ANEK_IS_NOT_TRANSPORTED
Definition explanation.h:36
@ ANEK_IS_TRANSPORTING
Definition explanation.h:38
@ ANEK_CITY_POP_LIMIT
Definition explanation.h:87
@ ANEK_TGT_IS_UNIQUE_ACT_HAS
Definition explanation.h:92
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:779
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:804
struct extra_type * extra_by_number(int id)
Definition extras.c:183
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:372
#define extra_deps_iterate_end
Definition extras.h:380
#define EXTRA_NONE
Definition extras.h:85
#define NO_TARGET
Definition fc_types.h:215
int Impr_type_id
Definition fc_types.h:237
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:231
int action_id
Definition fc_types.h:250
int Specialist_type_id
Definition fc_types.h:236
#define ACTRES_NONE
Definition fc_types.h:188
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:68
int Unit_type_id
Definition fc_types.h:243
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:94
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * city_tile_link(const struct city *pcity)
const char * tile_link(const struct tile *ptile)
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
const char * unit_link(const struct unit *punit)
const char * unit_tile_link(const struct unit *punit)
#define MAX_LEN_LINK
struct civ_game game
Definition game.c:62
bool is_player_phase(const struct player *pplayer, int phase)
Definition game.c:717
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:116
struct city * game_city_by_number(int id)
Definition game.c:107
static int actor_unit_id
static int target_extra_id
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
struct impr_type * improvement_by_number(const Impr_type_id id)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:182
#define fc_assert_ret(condition)
Definition log.h:192
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define fc_assert_action(condition, action)
Definition log.h:188
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:209
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)
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:2092
const char * dir_get_name(enum direction8 dir)
Definition map.c:1287
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:471
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:675
bool base_get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile, enum direction8 *dir)
Definition map.c:1469
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:290
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2489
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:899
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:773
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:925
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:869
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1387
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1066
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:661
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:362
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:962
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:815
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:522
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:603
#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:461
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:443
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
@ UNIT_INFO_IDENTITY
Definition packets.h:67
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1217
const char * player_name(const struct player *pplayer)
Definition player.c:885
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1095
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1191
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1325
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:325
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1397
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1451
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1124
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
int normal_player_count(void)
Definition plrhand.c:3212
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2966
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3011
struct conn_list * player_reply_dest(struct player *pplayer)
Definition plrhand.c:1595
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2918
#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:130
#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
struct specialist * specialist_by_number(const Specialist_type_id id)
Definition specialist.c:110
bool is_super_specialist_id(Specialist_type_id sp)
Definition specialist.c:184
Specialist_type_id specialist_index(const struct specialist *sp)
Definition specialist.c:90
bool is_super_specialist(const struct specialist *sp)
Definition specialist.c:208
#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:318
int id
Definition city.h:324
struct trade_route_list * routes
Definition city.h:342
citizens * nationality
Definition city.h:339
struct tile * tile
Definition city.h:320
int upgrade_veteran_loss
Definition game.h:206
struct packet_ruleset_control control
Definition game.h:83
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
int occupychance
Definition game.h:177
bool homecaughtunits
Definition game.h:195
struct civ_game::@32::@36 server
int replace_priority
struct unit_order orders[MAX_LEN_ROUTE]
enum unit_activity activity
enum diplstate_type type
Definition player.h:199
int units_lost
Definition player.h:106
struct unit_list * units
Definition player.h:282
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
struct player_score score
Definition player.h:283
const struct player * player
Definition tile.h:50
int index
Definition tile.h:51
struct unit_list * units
Definition tile.h:58
enum trade_route_bonus_type bonus_type
Definition traderoutes.h:78
enum adv_unit_task task
Definition unit.h:90
enum unit_activity activity
Definition unit.h:95
enum unit_orders order
Definition unit.h:94
int action
Definition unit.h:102
enum direction8 dir
Definition unit.h:104
int target
Definition unit.h:98
int sub_target
Definition unit.h:99
int paratroopers_range
Definition unittype.h:548
Definition unit.h:140
int length
Definition unit.h:198
bool has_orders
Definition unit.h:196
enum action_decision action_decision_want
Definition unit.h:205
int battlegroup
Definition unit.h:194
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
struct unit::@83 orders
bool moved
Definition unit.h:176
int index
Definition unit.h:198
struct vision * vision
Definition unit.h:247
bool vigilant
Definition unit.h:200
int hp
Definition unit.h:153
enum direction8 facing
Definition unit.h:144
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:142
struct extra_type * activity_target
Definition unit.h:167
struct unit_order * list
Definition unit.h:201
struct unit_adv * adv
Definition unit.h:239
bool repeat
Definition unit.h:199
int homecity
Definition unit.h:148
bool done_moving
Definition unit.h:184
struct tile * goto_tile
Definition unit.h:157
struct tile * action_decision_tile
Definition unit.h:206
const struct unit_type * utype
Definition unit.h:141
int veteran
Definition unit.h:154
struct player * owner
Definition unit.h:145
enum server_side_agent ssa_controller
Definition unit.h:175
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define bool
Definition support.h:71
#define fc__fallthrough
Definition support.h:119
#define A_UNSET
Definition tech.h:48
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Definition techtools.c:293
void update_bulbs(struct player *pplayer, int bulbs, bool check_tech, bool free_bulbs)
Definition techtools.c:654
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:240
#define terrain_has_flag(terr, flag)
Definition terrain.h:177
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c:408
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:115
#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:2945
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:233
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1847
void free_unit_orders(struct unit *punit)
Definition unit.c:1833
bool unit_is_alive(int id)
Definition unit.c:2317
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1986
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1301
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2545
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2494
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2371
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:86
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:884
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:402
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2964
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, enum gen_action action)
Definition unit.c:914
bool can_unit_do_autoworker(const struct unit *punit)
Definition unit.c:649
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:1159
int stack_bribe_cost(const struct tile *ptile, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2459
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1141
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:2052
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2529
bool is_flagless_to_player(const struct unit *punit, const struct player *pplayer)
Definition unit.c:382
bool unit_has_orders(const struct unit *punit)
Definition unit.c:221
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:609
bool can_unit_do_activity_targeted(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, enum gen_action action, struct extra_type *target)
Definition unit.c:955
#define unit_tile(_pu)
Definition unit.h:407
@ ORDER_ACTIVITY
Definition unit.h:42
@ ORDER_PERFORM_ACTION
Definition unit.h:48
#define unit_owner(_pu)
Definition unit.h:406
@ 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:443
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:6784
#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:1028
static bool do_unit_change_homecity(struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4199
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:258
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:3334
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4993
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4538
static bool do_unit_make_homeless(struct unit *punit, const struct action *paction)
Definition unithand.c:1013
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:4366
static bool non_allied_not_listed_at(const struct player *pplayer, const int *list, int n, const struct tile *ptile)
Definition unithand.c:288
void handle_unit_orders(struct player *pplayer, const struct packet_unit_orders *packet)
Definition unithand.c:6869
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:2527
static bool do_heal_unit(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:733
static bool do_capture_units(struct player *pplayer, struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:317
static bool do_expel_unit(struct player *pplayer, struct unit *actor, struct unit *target, const struct action *paction)
Definition unithand.c:604
static bool do_unit_conquer_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, struct action *paction)
Definition unithand.c:5611
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:1412
#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:4417
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:6978
static bool occupy_move(struct tile *def_tile, struct unit *punit, const struct action *paction)
Definition unithand.c:506
static bool do_unit_embark(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:976
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6708
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:3370
#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:5405
#define ACTION_PERFORM_UNIT_STACK(action, actor, target, action_performer)
static bool illegal_action_pay_price(struct player *pplayer, bool information_revealed, struct unit *act_unit, struct action *stopped_action, struct player *tgt_player, struct tile *tgt_tile, const enum action_requester requester)
Definition unithand.c:3003
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:1968
static const char * unit_tired_attack_string(const struct unit *punit)
Definition unithand.c:4946
static bool do_unit_deboard(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:838
static bool does_terrain_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct terrain *pterrain)
Definition unithand.c:1370
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Definition unithand.c:6645
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3182
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4633
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5758
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:4820
#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:6557
void create_trade_route(struct city *from, struct city *to, struct goods_type *goods)
Definition unithand.c:6416
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:3350
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:1454
static bool do_action_activity(struct unit *punit, const struct action *paction)
Definition unithand.c:6694
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:6820
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:5492
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:1052
static bool do_unit_unload(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:901
void unit_change_homecity_handling(struct unit *punit, struct city *new_pcity, bool rehome)
Definition unithand.c:4093
static bool tile_has_units_not_allied_to_but_seen_by(const struct tile *ptile, const struct player *pplayer)
Definition unithand.c:1352
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Definition unithand.c:6766
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:1316
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5951
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:4233
static bool do_unit_load(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:880
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:3201
static bool do_wipe_units(struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:551
static bool unit_nuke(struct player *pplayer, struct unit *punit, struct tile *def_tile, const struct action *paction)
Definition unithand.c:4750
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:5649
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:2263
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Definition unithand.c:6449
static bool do_unit_board(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:857
static void see_combat(struct unit *pattacker, struct unit *pdefender)
Definition unithand.c:4479
#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:1093
static const char * unit_achieved_rank_string(const struct unit *punit)
Definition unithand.c:4929
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:5720
static bool do_conquer_extras(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:694
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6606
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:6066
static bool do_disembark(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:918
static bool unit_activity_internal(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6739
static void unit_plans_clear(struct unit *punit)
Definition unithand.c:6541
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4313
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4583
static bool do_unit_hut(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:946
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:1948
#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)
static const char * unit_firepower_if_not_one(int firepower)
Definition unithand.c:4968
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4908
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:3123
#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:360
void unit_did_action(struct unit *punit)
Definition unittools.c:5077
void collect_ransom(struct unit *pcollector, struct unit *punit, bool vet)
Definition unittools.c:2648
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Definition unittools.c:3071
void unit_make_contact(const struct unit *punit, struct tile *ptile, struct player *pplayer)
Definition unittools.c:5192
bool execute_orders(struct unit *punit, const bool fresh)
Definition unittools.c:4530
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1558
bool unit_versus_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp, int *att_vet, int *def_vet, const struct action *paction)
Definition unittools.c:292
void combat_veterans(struct unit *attacker, struct unit *defender, bool powerless, int att_vet, int def_vet)
Definition unittools.c:405
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:3039
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Definition unittools.c:2738
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2869
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2882
void notify_unit_experience(struct unit *punit)
Definition unittools.c:748
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:2819
void unit_forget_last_activity(struct unit *punit)
Definition unittools.c:1054
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:5016
void do_explore(struct unit *punit)
Definition unittools.c:3104
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3394
bool unit_can_do_action_now(const struct unit *punit)
Definition unittools.c:5044
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2144
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unittools.c:3140
void unit_transport_unload_send(struct unit *punit)
Definition unittools.c:3446
void unit_assign_specific_activity_target(struct unit *punit, enum unit_activity *activity, enum gen_action action, struct extra_type **target)
Definition unittools.c:1083
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2204
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1192
void unit_get_goods(struct unit *punit)
Definition unittools.c:1621
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:4083
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Definition unittools.c:2271
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1230
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:1149
const char * uclass_name_translation(const struct unit_class *pclass)
Definition unittype.c:1658
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:126
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1595
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1274
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1613
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1953
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1729
Unit_type_id utype_count(void)
Definition unittype.c:82
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:980
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2530
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:114
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2629
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:215
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1244
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:1061
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:93
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1569
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1586
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:1042
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:396
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1694
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1757
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:863
#define unit_type_iterate_end
Definition unittype.h:870
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