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 * webperimental's "can't found a city on a tile belonging to a non enemy"
1305 * rule still is detected. */
1306
1307 return nullptr;
1308}
1309
1310/**********************************************************************/
1315static struct player *need_war_player(const struct unit *actor,
1316 const action_id act_id,
1317 const struct tile *target_tile,
1318 const struct city *target_city,
1319 const struct unit *target_unit)
1320{
1321 if (act_id == ACTION_ANY) {
1322 /* Any action at all will do. */
1323 action_iterate(act) {
1324 struct player *war_player;
1325
1328 target_unit);
1329
1330 if (war_player != nullptr) {
1331 /* Declaring war on this player may enable this action. */
1332 return war_player;
1333 }
1335
1336 /* No action at all may be enabled by declaring war. */
1337 return nullptr;
1338 } else {
1339 /* Look for the specified action. */
1340 return need_war_player_hlp(actor, act_id,
1342 target_unit);
1343 }
1344}
1345
1346/**********************************************************************/
1350static bool
1352 const struct player *pplayer)
1353{
1354 unit_list_iterate(ptile->units, pother) {
1355 if (can_player_see_unit(pplayer, pother)
1356 && !pplayers_allied(pplayer, unit_owner(pother))) {
1357 return TRUE;
1358 }
1360
1361 return FALSE;
1362}
1363
1364/**********************************************************************/
1369static bool does_terrain_block_action(const action_id act_id,
1370 bool is_target,
1371 struct unit *actor_unit,
1372 struct terrain *pterrain)
1373{
1374 if (act_id == ACTION_ANY) {
1375 /* Any action is OK. */
1378 && !does_terrain_block_action(alt_act, is_target,
1379 actor_unit, pterrain)) {
1380 /* Only one action has to be possible. */
1381 return FALSE;
1382 }
1384
1385 /* No action enabled. */
1386 return TRUE;
1387 }
1388
1389 /* ACTION_ANY is handled above. */
1391
1393 enabler) {
1395 (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1397 &enabler->actor_reqs)) {
1398 /* This terrain kind doesn't block this action enabler. */
1399 return FALSE;
1400 }
1402
1403 return TRUE;
1404}
1405
1406/**********************************************************************/
1411static bool does_nation_block_action(const action_id act_id,
1412 bool is_target,
1413 struct unit *actor_unit,
1414 struct nation_type *pnation)
1415{
1416 if (act_id == ACTION_ANY) {
1417 /* Any action is OK. */
1420 && !does_nation_block_action(alt_act, is_target,
1421 actor_unit, pnation)) {
1422 /* Only one action has to be possible. */
1423 return FALSE;
1424 }
1426
1427 /* No action enabled. */
1428 return TRUE;
1429 }
1430
1431 /* ACTION_ANY is handled above. */
1433
1435 enabler) {
1437 (is_target ? &enabler->target_reqs
1438 : &enabler->actor_reqs))
1440 &enabler->actor_reqs)) {
1441 /* This nation doesn't block this action enabler. */
1442 return FALSE;
1443 }
1445
1446 return TRUE;
1447}
1448
1449/**********************************************************************/
1453static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1454 const action_id act_id,
1455 const struct tile *target_tile,
1456 const struct city *target_city,
1457 const struct unit *target_unit)
1458{
1459 struct player *must_war_player;
1460 const struct action *paction;
1461 struct action *blocker;
1462 struct player *act_player = unit_owner(punit);
1463 struct player *tgt_player = nullptr;
1464 struct ane_expl *explnat = fc_malloc(sizeof(struct ane_expl));
1465 struct civ_map *nmap = &(wld.map);
1468 int action_custom;
1469
1470 /* Not know yet. (Initialize before the below check.) */
1471 explnat->kind = ANEK_UNKNOWN;
1472
1473 paction = action_by_number(act_id);
1474
1475 if (act_id != ACTION_ANY) {
1476 /* A specific action should have a suitable target. */
1478 case ATK_CITY:
1479 if (target_city == nullptr) {
1481 }
1482 break;
1483 case ATK_UNIT:
1484 if (target_unit == nullptr) {
1486 }
1487 break;
1488 case ATK_STACK:
1489 case ATK_TILE:
1490 case ATK_EXTRAS:
1491 if (target_tile == nullptr) {
1493 }
1494 break;
1495 case ATK_SELF:
1496 /* No other target. */
1497 break;
1498 case ATK_COUNT:
1500 break;
1501 }
1502 }
1503
1504 if (explnat->kind == ANEK_MISSING_TARGET) {
1505 /* No point continuing. */
1506 return explnat;
1507 }
1508
1509 if (act_id == ACTION_ANY) {
1510 /* Find the target player of some actions. */
1511 if (target_city) {
1512 /* Individual city targets have the highest priority. */
1514 } else if (target_unit) {
1515 /* Individual unit targets have the next priority. */
1517 } else if (target_tile) {
1518 /* Tile targets have the lowest priority. */
1520 }
1521 } else {
1522 /* Find the target player of this action. */
1524 case ATK_CITY:
1526 break;
1527 case ATK_UNIT:
1529 break;
1530 case ATK_TILE:
1532 break;
1533 case ATK_EXTRAS:
1534 tgt_player = target_tile->extras_owner;
1535 break;
1536 case ATK_STACK:
1537 /* A unit stack may contain units with multiple owners. Pick the
1538 * first one. */
1539 if (target_tile
1540 && unit_list_size(target_tile->units) > 0) {
1542 }
1543 break;
1544 case ATK_SELF:
1545 /* A unit acting against itself. */
1547 break;
1548 case ATK_COUNT:
1550 break;
1551 }
1552 }
1553
1554 if (act_id == ACTION_ANY) {
1555 action_custom = 0;
1556 } else {
1557 switch (paction->result) {
1560 break;
1561 case ACTRES_AIRLIFT:
1563 target_city);
1564 break;
1565 case ACTRES_NUKE_UNITS:
1567 target_tile);
1568 break;
1569 case ACTRES_ATTACK:
1571 target_tile);
1572 break;
1573 case ACTRES_WIPE_UNITS:
1575 break;
1577 if (target_city) {
1579 punit->activity,
1582 FALSE, FALSE, nullptr, TRUE);
1583 } else {
1585 }
1586 break;
1588 if (target_unit) {
1590 punit->activity,
1593 FALSE, TRUE, nullptr, FALSE);
1594 } else {
1596 }
1597 break;
1599 case ACTRES_HUT_ENTER:
1602 case ACTRES_UNIT_MOVE:
1603 if (target_tile) {
1605 punit->activity,
1608 FALSE, FALSE, nullptr, FALSE);
1609 } else {
1611 }
1612 break;
1613 case ACTRES_TELEPORT:
1614 if (target_tile != nullptr) {
1616 punit->activity,
1619 FALSE, nullptr, FALSE);
1620 } else {
1622 }
1623 break;
1624 default:
1625 action_custom = 0;
1626 break;
1627 }
1628 }
1629
1630 if (!unit_can_do_action(punit, act_id)) {
1631 explnat->kind = ANEK_ACTOR_UNIT;
1633 && tile_city(target_tile)) {
1634 explnat->kind = ANEK_BAD_TARGET;
1638 act_player)) {
1640 } else if ((!can_exist
1643 || (can_exist
1647 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1648 } else if ((!on_native
1651 || (on_native
1653 USP_NATIVE_TILE, TRUE))) {
1655 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1656 } else if (punit
1659 /* No action enabler allows acting against this terrain kind. */
1661 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1663 && target_tile
1665 TER_NO_CITIES)) {
1667 explnat->no_act_terrain = tile_terrain(target_tile);
1670 && target_tile != nullptr
1672 V_MAIN)
1674 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
1677 explnat->no_act_terrain = tile_terrain(target_tile);
1678 } else if (target_tile
1681 /* No action enabler allows acting against this terrain kind. */
1683 explnat->no_act_terrain = tile_terrain(target_tile);
1684 } else if (unit_transported(punit)
1688 } else if (!unit_transported(punit)
1692 } else if (0 < get_transporter_occupancy(punit)
1696 } else if (!(0 < get_transporter_occupancy(punit))
1700 } else if ((punit->homecity > 0)
1704 } else if ((punit->homecity <= 0)
1708 } else if ((punit->homecity <= 0)
1712 } else if (act_player && tgt_player
1714 == DS_PEACE)
1716 act_id,
1717 DS_PEACE,
1718 FALSE)
1720 act_id,
1721 DS_PEACE,
1722 TRUE)) {
1723 explnat->kind = ANEK_PEACE;
1724 explnat->peace_with = tgt_player;
1726 act_id,
1729 target_unit)) != nullptr) {
1730 explnat->kind = ANEK_NO_WAR;
1731 explnat->no_war_with = must_war_player;
1732 } else if (action_mp_full_makes_legal(punit, act_id)) {
1733 explnat->kind = ANEK_LOW_MP;
1734 } else if (tgt_player != nullptr
1737 act_id,
1739 TRUE)) {
1740 explnat->kind = ANEK_FOREIGN;
1741 } else if (tgt_player != nullptr
1744 act_id,
1746 FALSE)) {
1747 explnat->kind = ANEK_DOMESTIC;
1748 } else if (punit != nullptr
1750 punit, act_player->nation)) {
1751 explnat->kind = ANEK_NATION_ACT;
1752 explnat->no_act_nation = act_player->nation;
1753 } else if (tgt_player
1754 && does_nation_block_action(act_id, TRUE,
1755 punit, tgt_player->nation)) {
1756 explnat->kind = ANEK_NATION_TGT;
1757 explnat->no_act_nation = tgt_player->nation;
1758 } else if ((target_tile && tile_city(target_tile))
1760 act_id,
1762 TRUE)) {
1764 } else if ((target_tile && !tile_city(target_tile))
1766 act_id,
1768 FALSE)) {
1770 } else if ((target_tile && tile_owner(target_tile) != nullptr)
1772 act_id,
1774 TRUE)) {
1776 } else if ((target_tile && tile_owner(target_tile) == nullptr)
1778 act_id,
1780 FALSE)) {
1782 } else if (paction && punit
1783 && ((target_tile
1786 || (target_city
1790 || (target_unit
1793 unit_tile(target_unit)))))) {
1794 explnat->kind = ANEK_DISTANCE_FAR;
1795 explnat->distance = paction->max_distance;
1798 && punit && target_tile
1800 > unit_type_get(punit)->paratroopers_range) {
1801 explnat->kind = ANEK_DISTANCE_FAR;
1803 } else if (paction && punit
1804 && ((target_tile
1806 < paction->min_distance)
1807 || (target_city
1810 < paction->min_distance)
1811 || (target_unit
1814 < paction->min_distance))) {
1816 explnat->distance = paction->min_distance;
1817 } else if (target_city
1823 /* TODO: Check max city size requirements from action enabler target
1824 * vectors. */
1825 explnat->kind = ANEK_CITY_TOO_BIG;
1826 } else if (target_city
1832 + unit_pop_value(punit))))) {
1834 } else if (target_city
1839 && MAX_CITY_SIZE
1840 <= target_city->specialists
1841 [specialist_index(unit_type_get(punit)->spec_type)])) {
1846 && action_custom != ATT_OK) {
1847 switch (action_custom) {
1848 case ATT_NON_ATTACK:
1849 explnat->kind = ANEK_ACTOR_UNIT;
1850 break;
1851 case ATT_UNREACHABLE:
1853 break;
1854 case ATT_NONNATIVE_SRC:
1856 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1857 break;
1858 case ATT_NONNATIVE_DST:
1860 explnat->no_act_terrain = tile_terrain(target_tile);
1861 break;
1862 case ATT_NOT_WIPABLE:
1863 explnat->kind = ANEK_NOT_WIPABLE;
1864 break;
1865 default:
1867 explnat->kind = ANEK_UNKNOWN;
1868 break;
1869 }
1873 explnat->capacity_city = tile_city(unit_tile(punit));
1877 explnat->capacity_city = game_city_by_number(target_city->id);
1883 && target_tile != nullptr
1895 && action_custom != MR_OK) {
1896 switch (action_custom) {
1899 break;
1900 case MR_TRIREME:
1901 explnat->kind = ANEK_TRIREME_MOVE;
1902 break;
1905 break;
1906 default:
1908 explnat->kind = ANEK_UNKNOWN;
1909 break;
1910 }
1915 explnat->no_tgt_utype = unit_type_get(target_unit);
1916 } else if ((game.scenario.prevent_new_cities
1919 || act_id == ACTION_ANY)) {
1920 /* Please add a check for any new action forbidding scenario setting
1921 * above this comment. */
1924 && action_custom == UU_NO_MONEY) {
1925 const struct unit_type *act_utype = unit_type_get(punit);
1926
1931 } else if (paction
1932 && (blocker = action_is_blocked_by(nmap, paction, punit,
1934 target_unit))) {
1936 explnat->blocker = blocker;
1937 } else {
1938 explnat->kind = ANEK_UNKNOWN;
1939 }
1940
1941 return explnat;
1942}
1943
1944/**********************************************************************/
1948 action_id act_id,
1949 const struct tile *target_tile,
1950 const struct city *target_city,
1951 const struct unit *target_unit)
1952{
1953 struct ane_expl *explnat = expl_act_not_enabl(punit, act_id,
1956 enum ane_kind out = explnat->kind;
1957
1958 free(explnat);
1959
1960 return out;
1961}
1962
1963/**********************************************************************/
1968 const struct tile *target_tile,
1969 const struct city *target_city,
1970 const struct unit *target_unit)
1971{
1972 struct player *pplayer = unit_owner(punit);
1976 const struct civ_map *nmap = &(wld.map);
1977
1978 switch (explnat->kind) {
1979 case ANEK_ACTOR_UNIT:
1980 /* This shouldn't happen unless the client is buggy given the current
1981 * users. */
1983 "Asked to explain why a non actor can't act.");
1984
1986 _("Unit cannot do anything."));
1987 break;
1990 _("Your %s found no suitable target."),
1992 break;
1993 case ANEK_BAD_TARGET:
1994 /* This shouldn't happen at the moment. Only specific action checks
1995 * will trigger bad target checks. This is a reply to a question about
1996 * any action. */
1998
2000 _("Your %s found no suitable target."),
2002 break;
2004 {
2005 const char *types[utype_count()];
2006 int i = 0;
2007
2010 FALSE)
2012 unit_type_iterate(utype) {
2015 types[i++] = utype_name_translation(utype);
2016 }
2018 }
2019
2020 if (0 < i) {
2021 struct astring astr = ASTRING_INIT;
2022
2023 notify_player(pplayer, unit_tile(punit),
2025 /* TRANS: terrain name
2026 * "Your Diplomat cannot act from Ocean. Only
2027 * Spy or Partisan ... */
2028 _("Your %s cannot act from %s. "
2029 "Only %s can act from a non livable tile."),
2031 terrain_name_translation(explnat->no_act_terrain),
2032 astr_build_or_list(&astr, types, i));
2033
2034 astr_free(&astr);
2035 } else {
2037 /* TRANS: terrain name */
2038 _("Unit cannot act from %s."),
2039 terrain_name_translation(explnat->no_act_terrain));
2040 }
2041 }
2042 break;
2045 /* TRANS: terrain name */
2046 _("Unit cannot act against %s."),
2047 terrain_name_translation(explnat->no_act_terrain));
2048 break;
2051 _("This unit is being transported, and"
2052 " so cannot act."));
2053 break;
2056 _("This unit cannot act when it isn't being "
2057 "transported."));
2058 break;
2061 _("This unit is transporting, and"
2062 " so cannot act."));
2063 break;
2066 _("This unit cannot act when it isn't transporting."));
2067 break;
2070 _("This unit has a home city, and so cannot act."));
2071 break;
2074 _("This unit cannot act unless it has a home city."));
2075 break;
2076 case ANEK_NO_WAR:
2078 _("You must declare war on %s first. Try using "
2079 "the Nations report"
2081 " (F3)"
2082#endif /* FREECIV_WEB */
2083 "."),
2084 player_name(explnat->no_war_with));
2085 break;
2086 case ANEK_PEACE:
2088 _("You must break peace with %s first. Try using "
2089 "the Nations report to declare war"
2091 " (F3)"
2092#endif /* FREECIV_WEB */
2093 "."),
2094 player_name(explnat->peace_with));
2095 break;
2096 case ANEK_DOMESTIC:
2098 _("This unit cannot act against domestic targets."));
2099 break;
2100 case ANEK_FOREIGN:
2102 _("This unit cannot act against foreign targets."));
2103 break;
2106 /* TRANS: Riflemen */
2107 _("%s cannot act against tiles with non allied units."),
2109 break;
2110 case ANEK_NATION_ACT:
2112 /* TRANS: Swedish ... Riflemen */
2113 _("%s %s cannot act."),
2114 nation_adjective_translation(explnat->no_act_nation),
2116 break;
2117 case ANEK_NATION_TGT:
2119 /* TRANS: ... Pirate ... */
2120 _("This unit cannot act against %s targets."),
2121 nation_adjective_translation(explnat->no_act_nation));
2122 break;
2123 case ANEK_LOW_MP:
2125 _("This unit has too few moves left to act."));
2126 break;
2129 _("This unit cannot act against city centers."));
2130 break;
2133 _("This unit cannot act against non city centers."));
2134 break;
2137 _("This unit cannot act against claimed tiles."));
2138 break;
2141 _("This unit cannot act against unclaimed tiles."));
2142 break;
2143 case ANEK_DISTANCE_NEAR:
2145 _("This unit is too near its target to act."));
2146 break;
2147 case ANEK_DISTANCE_FAR:
2149 _("This unit is too far away from its target to act."));
2150 break;
2153 _("Can't perform any action this scenario permits."));
2154 break;
2157 _("Can't perform any action this close to a city."));
2158 break;
2159 case ANEK_CITY_TOO_BIG:
2161 /* TRANS: Settler ... Berlin */
2162 _("%s can't do anything to %s. It is too big."),
2165 break;
2168 /* TRANS: London ... Settlers */
2169 _("%s needs an improvement to grow, so "
2170 "%s cannot do anything to it."),
2173 break;
2176 /* TRANS: Paris ... Warriors (think: airlift) */
2177 _("%s don't have enough capacity, so "
2178 "%s cannot do anything."),
2179 city_name_get(explnat->capacity_city),
2181 break;
2184 /* TRANS: Paratroopers ... */
2185 _("%s can't do anything to an unknown target tile."),
2187 break;
2189 {
2190 char tbuf[MAX_LEN_MSG];
2191
2192 /* TRANS: Used below. Separate so treasury content too can determine
2193 * if this is plural. */
2194 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2195 "Treasury contains %d gold.",
2196 pplayer->economic.gold),
2197 pplayer->economic.gold);
2198
2200 /* TRANS: "Spy can't do anything. 154 gold may help.
2201 * Treasury contains 100 gold." */
2202 PL_("%s can't do anything. %d gold may help. %s",
2203 "%s can't do anything. %d gold may help. %s",
2204 explnat->gold_needed),
2206 explnat->gold_needed, tbuf);
2207 }
2208 break;
2209 case ANEK_TRIREME_MOVE:
2211 _("%s cannot move that far from the coast line."),
2212 unit_link(punit));
2213 break;
2214 case ANEK_DISEMBARK_ACT:
2216 _("%s cannot disembark outside of a city or a native base "
2217 "for %s."),
2221 break;
2224 _("%s can't do anything since there is an unreachable "
2225 "unit."),
2227 break;
2228 case ANEK_NOT_WIPABLE:
2230 _("%s can't do anything since there is unit with a positive "
2231 "defense value."),
2233 break;
2236 _("%s can't do anything since you already have a %s."),
2238 utype_name_translation(explnat->no_tgt_utype));
2239 break;
2240 case ANEK_ACTION_BLOCKS:
2241 /* If an action blocked another action the blocking action must be
2242 * possible. */
2244 fc__fallthrough; /* Fall through to unknown cause. */
2245 case ANEK_UNKNOWN:
2247 _("No action possible."));
2248 break;
2249 }
2250
2251 free(explnat);
2252}
2253
2254/**********************************************************************/
2263 const int actor_unit_id,
2264 const int target_unit_id_client,
2265 const int target_tile_id,
2266 const int target_extra_id_client,
2267 const int request_kind)
2268{
2269 struct player *actor_player;
2270 struct unit *actor_unit;
2271 struct tile *target_tile;
2273 struct unit *target_unit;
2274 struct city *target_city;
2275 struct extra_type *target_extra;
2277 const struct player_tile *plrtile;
2279 const struct civ_map *nmap = &(wld.map);
2280
2281 /* No potentially legal action is known yet. If none is found the player
2282 * should get an explanation. */
2284
2285 /* A target should only be sent if it is possible to act against it */
2286 int target_city_id = IDENTITY_NUMBER_ZERO;
2287 int target_unit_id = IDENTITY_NUMBER_ZERO;
2288
2289 actor_player = pc->playing;
2291 target_tile = index_to_tile(nmap, target_tile_id);
2292
2293 /* Initialize the action probabilities. */
2294 action_iterate(act) {
2297
2298 /* Check if the request is valid. */
2300 || actor_unit->owner != actor_player) {
2303 target_tile_id, target_extra_id,
2304 request_kind,
2306 return;
2307 }
2308
2309 /* Select the targets. */
2310
2312 /* Find a new target unit. */
2314 } else {
2315 /* Prepare the client selected target unit. */
2317 }
2318
2319 /* Find the target city. */
2321
2322 /* The specified target unit must be located at the target tile. */
2326 _("Target not at target tile."));
2329 target_tile_id, target_extra_id,
2330 request_kind,
2332 return;
2333 }
2334
2336 /* See if a target extra can be found. */
2338 } else {
2339 /* Use the client selected target extra. */
2341 }
2342
2343 /* The player may have outdated information about the target tile.
2344 * Limiting the player knowledge look up to the target tile is OK since
2345 * all targets must be located at it. */
2347
2348 /* Distance between actor and target tile. */
2350 target_tile);
2351
2352 /* Find out what can be done to the targets. */
2353
2354 /* Set the probability for the actions. */
2356 if (action_id_get_actor_kind(act) != AAK_UNIT) {
2357 /* Not relevant. */
2358 continue;
2359 }
2360
2361 switch (action_id_get_target_kind(act)) {
2362 case ATK_CITY:
2363 if (plrtile && plrtile->site) {
2364 /* Only a known city may be targeted. */
2365 if (target_city) {
2366 /* Calculate the probabilities. */
2368 target_city);
2373 /* The target city is non existing. The player isn't aware of this
2374 * fact because they can't see the tile it was located on. The
2375 * actor unit it self doesn't contradict the requirements to
2376 * perform the action. The (no longer existing) target city was
2377 * known to be close enough. */
2379 } else {
2380 /* The actor unit is known to be unable to act or the target city
2381 * is known to be too far away. */
2383 }
2384 } else {
2385 /* No target to act against. */
2387 }
2388 break;
2389 case ATK_UNIT:
2390 if (target_unit) {
2391 /* Calculate the probabilities. */
2393 target_unit);
2394 } else {
2395 /* No target to act against. */
2397 }
2398 break;
2399 case ATK_STACK:
2400 if (target_tile) {
2401 /* Calculate the probabilities. */
2403 target_tile);
2404 } else {
2405 /* No target to act against. */
2407 }
2408 break;
2409 case ATK_TILE:
2410 if (target_tile) {
2411 /* Calculate the probabilities. */
2414 } else {
2415 /* No target to act against. */
2417 }
2418 break;
2419 case ATK_EXTRAS:
2420 if (target_tile) {
2421 /* Calculate the probabilities. */
2424 target_extra);
2425 } else {
2426 /* No target to act against. */
2428 }
2429 break;
2430 case ATK_SELF:
2431 if (actor_target_distance == 0) {
2432 /* Calculate the probabilities. */
2434 } else {
2435 /* Don't bother with self targeted actions unless the actor is
2436 * asking about what can be done to its own tile. */
2438 }
2439 break;
2440 case ATK_COUNT:
2443 break;
2444 }
2446
2447 /* Analyze the probabilities. Decide what targets to send and if an
2448 * explanation is needed. */
2451 /* An action can be done. No need to explain why no action can be
2452 * done. */
2454
2455 switch (action_id_get_target_kind(act)) {
2456 case ATK_CITY:
2457 /* The city should be sent as a target since it is possible to act
2458 * against it. */
2459
2460 /* All city targeted actions requires that the player is aware of
2461 * the target city. It is therefore in the player's map. */
2462 fc_assert_action(plrtile, continue);
2463 fc_assert_action(plrtile->site, continue);
2464
2465 target_city_id = plrtile->site->identity;
2466 break;
2467 case ATK_UNIT:
2468 /* The unit should be sent as a target since it is possible to act
2469 * against it. */
2470 fc_assert(target_unit != nullptr);
2471 target_unit_id = target_unit->id;
2472 break;
2473 case ATK_TILE:
2474 case ATK_EXTRAS:
2475 /* The target tile isn't selected here so it hasn't changed. */
2476 fc_assert(target_tile != nullptr);
2477
2479 /* The target extra may have been set here. */
2481 }
2482 break;
2483 case ATK_STACK:
2484 /* The target tile isn't selected here so it hasn't changed. */
2485 fc_assert(target_tile != nullptr);
2486 break;
2487 case ATK_SELF:
2488 /* The target unit is the actor unit. It is already sent. */
2489 fc_assert(actor_unit != nullptr);
2490 break;
2491 case ATK_COUNT:
2493 "Invalid action target kind.");
2494 break;
2495 }
2496
2497 if (target_city_id != IDENTITY_NUMBER_ZERO
2498 && target_unit_id != IDENTITY_NUMBER_ZERO) {
2499 /* No need to find out more. */
2500 break;
2501 }
2502 }
2504
2505 /* Send possible actions and targets. */
2507 actor_unit_id, target_unit_id, target_city_id,
2508 target_tile_id, target_extra_id,
2509 request_kind,
2511
2512 if (request_kind == REQEST_PLAYER_INITIATED && !at_least_one_action) {
2513 /* The user should get an explanation why no action is possible. */
2516 }
2517}
2518
2519/**********************************************************************/
2526void illegal_action_msg(struct player *pplayer,
2527 const enum event_type event,
2528 struct unit *actor,
2530 const struct tile *target_tile,
2531 const struct city *target_city,
2532 const struct unit *target_unit)
2533{
2534 struct ane_expl *explnat;
2535 const struct civ_map *nmap = &(wld.map);
2536
2537 /* Explain why the action was illegal. */
2540 switch (explnat->kind) {
2541 case ANEK_ACTOR_UNIT:
2542 {
2543 struct astring astr = ASTRING_INIT;
2544
2547 TRUE)) {
2548 notify_player(pplayer, unit_tile(actor),
2550 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
2551 _("Only %s can do %s."),
2552 astr_str(&astr),
2554 astr_free(&astr);
2555 } else {
2556 notify_player(pplayer, unit_tile(actor),
2558 /* TRANS: Spy can't do Capture Units. */
2559 _("%s can't do %s."),
2562 }
2563 }
2564 break;
2567 /* TRANS: "Your Spy found ... suitable for
2568 * Bribe Enemy Unit." */
2569 _("Your %s found no target suitable for %s."),
2572 break;
2573 case ANEK_BAD_TARGET:
2575 /* TRANS: "Having your Spy do Bribe Enemy Unit to
2576 * this target ..." */
2577 _("Having your %s do %s to this target is redundant."),
2580 break;
2582 {
2583 const char *types[utype_count()];
2584 int i = 0;
2585
2588 FALSE)
2590 unit_type_iterate(utype) {
2593 types[i++] = utype_name_translation(utype);
2594 }
2596 }
2597
2598 if (0 < i) {
2599 struct astring astr = ASTRING_INIT;
2600
2601 notify_player(pplayer, unit_tile(actor),
2603 /* TRANS: action name.
2604 * "Your Spy can't do Steal Gold from Ocean.
2605 * Only Explorer or Partisan can do Steal Gold ..." */
2606 _("Your %s can't do %s from %s. "
2607 "Only %s can do %s from a non livable tile."),
2610 terrain_name_translation(explnat->no_act_terrain),
2611 astr_build_or_list(&astr, types, i),
2613
2614 astr_free(&astr);
2615 } else {
2616 notify_player(pplayer, unit_tile(actor),
2618 /* TRANS: action name.
2619 * "Your Spy can't do Steal Gold from Ocean." */
2620 _("Your %s can't do %s from %s."),
2623 terrain_name_translation(explnat->no_act_terrain));
2624 }
2625 }
2626 break;
2628 notify_player(pplayer, unit_tile(actor),
2630 /* TRANS: action name.
2631 * "Your Spy can't do Industrial Sabotage to Mountains." */
2632 _("Your %s can't do %s to %s."),
2635 terrain_name_translation(explnat->no_act_terrain));
2636 break;
2638 notify_player(pplayer, unit_tile(actor),
2640 /* TRANS: action name.
2641 * "Your Spy can't do Industrial Sabotage while ..." */
2642 _("Your %s can't do %s while being transported."),
2645 break;
2647 notify_player(pplayer, unit_tile(actor),
2649 /* TRANS: action name.
2650 * "Your Spy can't do Industrial Sabotage while ..." */
2651 _("Your %s can't do %s while not being transported."),
2654 break;
2656 notify_player(pplayer, unit_tile(actor),
2658 /* TRANS: action name.
2659 * "Your Spy can't do Industrial Sabotage while ..." */
2660 _("Your %s can't do %s while transporting."),
2663 break;
2665 notify_player(pplayer, unit_tile(actor),
2667 /* TRANS: action name.
2668 * "Your Spy can't do Industrial Sabotage while ..." */
2669 _("Your %s can't do %s while not transporting."),
2672 break;
2674 notify_player(pplayer, unit_tile(actor),
2676 /* TRANS: action name.
2677 * "Your Spy can't do Industrial Sabotage because ..." */
2678 _("Your %s can't do %s because it has a home city."),
2681 break;
2683 notify_player(pplayer, unit_tile(actor),
2685 /* TRANS: action name.
2686 * "Your Spy can't do Industrial Sabotage because ..." */
2687 _("Your %s can't do %s because it is homeless."),
2690 break;
2691 case ANEK_NO_WAR:
2692 notify_player(pplayer, unit_tile(actor),
2694 /* TRANS: action name.
2695 * "Your Spy can't do Industrial Sabotage while you
2696 * aren't at war with Prester John." */
2697 _("Your %s can't do %s while you"
2698 " aren't at war with %s."),
2701 player_name(explnat->no_war_with));
2702 break;
2703 case ANEK_PEACE:
2704 notify_player(pplayer, unit_tile(actor),
2706 /* TRANS: action name.
2707 * "Your Spy can't do Industrial Sabotage while you
2708 * are at peace with Prester John. Try using the
2709 * Nations report (F3)." */
2710 _("Your %s can't do %s while you "
2711 "are at peace with %s. Try using "
2712 "the Nations report to declare war"
2714 " (F3)"
2715#endif /* FREECIV_WEB */
2716 "."),
2719 player_name(explnat->peace_with));
2720 break;
2721 case ANEK_DOMESTIC:
2722 notify_player(pplayer, unit_tile(actor),
2724 /* TRANS: action name.
2725 * "Your Riflemen can't do Expel Unit to domestic
2726 * unit stacks." */
2727 _("Your %s can't do %s to domestic %s."),
2732 break;
2733 case ANEK_FOREIGN:
2734 notify_player(pplayer, unit_tile(actor),
2736 /* TRANS: action name.
2737 * "Your Leader can't do Use Court Physician to foreign
2738 * unit stacks." */
2739 _("Your %s can't do %s to foreign %s."),
2744 break;
2746 notify_player(pplayer, unit_tile(actor),
2748 /* TRANS: Paratroopers ... Drop Paratrooper */
2749 _("Your %s can't do %s to tiles with non allied units."),
2752 break;
2753 case ANEK_NATION_ACT:
2754 notify_player(pplayer, unit_tile(actor),
2756 /* TRANS: action name.
2757 * "Swedish Riflemen can't do Expel Unit." */
2758 _("%s %s can't do %s."),
2759 nation_adjective_translation(explnat->no_act_nation),
2762 break;
2763 case ANEK_NATION_TGT:
2764 notify_player(pplayer, unit_tile(actor),
2766 /* TRANS: action name.
2767 * "Riflemen... Expel Unit... Pirate Migrants." */
2768 _("Your %s can't do %s to %s %s."),
2771 nation_adjective_translation(explnat->no_act_nation),
2774 break;
2775 case ANEK_LOW_MP:
2776 notify_player(pplayer, unit_tile(actor),
2778 /* TRANS: action name.
2779 * "Your Spy has ... to do Bribe Enemy Unit." */
2780 _("Your %s has too few moves left to do %s."),
2783 break;
2785 notify_player(pplayer, unit_tile(actor),
2787 /* TRANS: action name.
2788 * "Your Spy can't do Bribe Enemy Unit to city centers." */
2789 _("Your %s can't do %s to city centers."),
2792 break;
2794 notify_player(pplayer, unit_tile(actor),
2796 /* TRANS: action name.
2797 * "Your Spy can only do Investigate City to
2798 * city centers." */
2799 _("Your %s can only do %s to city centers."),
2802 break;
2804 notify_player(pplayer, unit_tile(actor),
2806 /* TRANS: action name.
2807 * "Your Settlers can't do Build City to claimed tiles." */
2808 _("Your %s can't do %s to claimed tiles."),
2811 break;
2813 notify_player(pplayer, unit_tile(actor),
2815 /* TRANS: action name.
2816 * "Your Spy can't do Bribe Enemy Unit to
2817 * unclaimed tiles." */
2818 _("Your %s can't do %s to unclaimed tiles."),
2821 break;
2822 case ANEK_DISTANCE_NEAR:
2823 notify_player(pplayer, unit_tile(actor),
2825 /* TRANS: action name.
2826 * "Your Spy must be at least 2 tiles away to do
2827 * Incite a Revolt and Escape." */
2828 PL_("Your %s must be at least %d tile away to do %s.",
2829 "Your %s must be at least %d tiles away to do %s.",
2830 explnat->distance),
2832 explnat->distance,
2834 break;
2835 case ANEK_DISTANCE_FAR:
2836 notify_player(pplayer, unit_tile(actor),
2838 /* TRANS: action name.
2839 * "Your Diplomat can't be more than 1 tile away to do
2840 * Establish Embassy." */
2841 PL_("Your %s can't be more than %d tile away to do %s.",
2842 "Your %s can't be more than %d tiles away to do %s.",
2843 explnat->distance),
2845 explnat->distance,
2847 break;
2849 notify_player(pplayer, unit_tile(actor),
2851 /* TRANS: Can't do Build City in this scenario. */
2852 _("Can't do %s in this scenario."),
2854 break;
2856 notify_player(pplayer, unit_tile(actor),
2858 /* TRANS: Can't do Build City this close to a city. */
2859 _("Can't do %s this close to a city."),
2861 break;
2862 case ANEK_CITY_TOO_BIG:
2863 notify_player(pplayer, unit_tile(actor),
2865 /* TRANS: Settlers ... Join City ... London */
2866 _("%s can't do %s to %s. It is too big."),
2870 break;
2872 notify_player(pplayer, unit_tile(actor),
2874 /* TRANS: London ... Settlers ... Join City */
2875 _("%s needs an improvement to grow, so "
2876 "%s cannot do %s."),
2880 break;
2882 notify_player(pplayer, unit_tile(actor),
2884 /* TRANS: Paris ... Airlift to City ... Warriors */
2885 _("%s has no capacity to %s %s."),
2886 city_name_get(explnat->capacity_city),
2889 break;
2891 notify_player(pplayer, unit_tile(actor),
2893 /* TRANS: Paratroopers ... Drop Paratrooper */
2894 _("%s can't do %s to an unknown tile."),
2897 break;
2899 {
2900 char tbuf[MAX_LEN_MSG];
2901
2902 /* TRANS: Used below. Separate so treasury content too can determine
2903 * if this is plural. */
2904 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2905 "Treasury contains %d gold.",
2906 pplayer->economic.gold),
2907 pplayer->economic.gold);
2908
2909 notify_player(pplayer, unit_tile(actor),
2911 /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2912 * Treasury contains 100 gold." */
2913 PL_("%s can't do %s for %d gold. %s",
2914 "%s can't do %s for %d gold. %s",
2915 explnat->gold_needed),
2918 explnat->gold_needed, tbuf);
2919 }
2920 break;
2921 case ANEK_TRIREME_MOVE:
2923 /* TRANS: "Trireme cannot move ..." */
2924 _("%s cannot move that far from the coast line."),
2925 unit_link(actor));
2926 break;
2927 case ANEK_DISEMBARK_ACT:
2929 /* TRANS: "Riflemen cannot disembark ... native base
2930 * for Helicopter." */
2931 _("%s cannot disembark outside of a city or a native base "
2932 "for %s."),
2936 break;
2938 notify_player(pplayer, target_tile,
2940 /* TRANS: "Your Spy can't do Bribe Enemy Unit there ..." */
2941 _("Your %s can't do %s there since there's an "
2942 "unreachable unit."),
2945 break;
2946 case ANEK_NOT_WIPABLE:
2947 notify_player(pplayer, target_tile,
2949 /* TRANS: "Your Legion can't do Wipe Units there ..." */
2950 _("Your %s can't do %s there since there's an "
2951 "unit with positive defense value."),
2954 break;
2957 /* TRANS: "You already have a Leader." */
2958 _("You already have a %s."),
2959 utype_name_translation(explnat->no_tgt_utype));
2960 break;
2961 case ANEK_ACTION_BLOCKS:
2962 {
2964
2965 notify_player(pplayer, unit_tile(actor),
2967 /* TRANS: Freight ... Disband Unit Recover ... Help Wonder ... */
2968 _("Your %s can't do %s when %s is legal."),
2971 action_id_name_translation(explnat->blocker->id));
2973 }
2974 break;
2975 case ANEK_UNKNOWN:
2976 notify_player(pplayer, unit_tile(actor),
2978 /* TRANS: action name.
2979 * "Your Spy was unable to do Bribe Enemy Unit." */
2980 _("Your %s was unable to do %s."),
2983 break;
2984 }
2985
2986 free(explnat);
2987}
2988
2989/**********************************************************************/
3002static bool illegal_action_pay_price(struct player *pplayer,
3004 struct unit *act_unit,
3005 struct action *stopped_action,
3006 struct player *tgt_player,
3007 struct tile *tgt_tile,
3008 const enum action_requester requester)
3009{
3010 int punishment_mp;
3011 int punishment_hp;
3012
3013 const struct req_context actor_ctxt = {
3015 .unit = act_unit,
3016 .unittype = unit_type_get(act_unit),
3017 .action = stopped_action,
3018 };
3019 const struct req_context tgt_ctxt = {
3020 .player = tgt_player,
3021 };
3022
3023 /* Don't punish the player for something the game did. Don't tell the
3024 * player that the rules required the game to try to do something
3025 * illegal. */
3028 FALSE,
3029 "The player wasn't responsible for this.");
3030
3031 if (!information_revealed) {
3032 /* The player already had enough information to determine that this
3033 * action is illegal. Don't punish a client error or an accident. */
3034 return FALSE;
3035 }
3036
3037 /* The mistake may have a cost. */
3038
3039 /* HP cost */
3042
3043 /* Stay in range */
3045
3046 /* Punish the unit's hit points. */
3047 act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
3048
3049 if (punishment_hp != 0) {
3052 /* The consolation prize is some information about the potentially
3053 * distant target tile and maybe some contacts. */
3054 map_show_circle(pplayer, tgt_tile,
3055 unit_type_get(act_unit)->vision_radius_sq);
3057 }
3058
3059 if (act_unit->hp > 0) {
3060 /* The actor unit survived */
3061
3062 /* The player probably wants to be disturbed if their unit was punished
3063 * with the loss of hit points. */
3066 /* TRANS: Spy ... 5 ... Drop Paratrooper */
3067 _("Your %s lost %d hit points while attempting to"
3068 " do %s."),
3071 send_unit_info(nullptr, act_unit);
3072 } else {
3073 /* The unit didn't survive */
3074
3075 /* The player probably wants to be disturbed if their unit was punished
3076 * with death. */
3079 /* TRANS: Spy ... Drop Paratrooper */
3080 _("Your %s was killed while attempting to do %s."),
3083
3084 wipe_unit(act_unit, ULR_KILLED, nullptr);
3085 act_unit = nullptr;
3086
3087 return TRUE;
3088 }
3089 }
3090
3091 /* MP cost */
3094
3095 /* Stay in range */
3097
3098 /* Punish the unit's move fragments. */
3099 act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
3100 send_unit_info(nullptr, act_unit);
3101
3102 if (punishment_mp != 0) {
3103 /* The player probably wants to be disturbed if their unit was punished
3104 * with the loss of movement points. */
3107 /* TRANS: Spy ... movement point text that may include
3108 * fractions. */
3109 _("Your %s lost %s MP for attempting an illegal action."),
3112 }
3113
3114 return punishment_mp != 0 || punishment_hp != 0;
3115}
3116
3117/**********************************************************************/
3122static void illegal_action(struct player *pplayer,
3123 struct unit *actor,
3125 struct player *tgt_player,
3126 struct tile *target_tile,
3127 const struct city *target_city,
3128 const struct unit *target_unit,
3129 int request_kind,
3130 const enum action_requester requester)
3131{
3133 bool was_punished;
3134 const struct civ_map *nmap = &(wld.map);
3135
3137
3138 /* Why didn't the game check before trying something illegal? Did a good
3139 * reason to not call is_action_enabled_unit_on...() appear? The game is
3140 * omniscient... */
3142
3143
3145 nmap,
3147 actor,
3149 target_tile, nullptr));
3150
3151 if (request_kind == REQEST_PLAYER_INITIATED) {
3152 /* This is a foreground request. */
3157 }
3158
3162 requester);
3163
3164 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3165 /* FIXME: Temporary work around to prevent wrong information and/or
3166 * crashes. See hrm Bug #879880 */
3167 /* TODO: Get the explanation before the punishment and show it here.
3168 * See hrm Bug #879881 */
3169 notify_player(pplayer, unit_tile(actor),
3172 _("No explanation why you couldn't do %s. This is a bug."
3173 " Sorry about that. -- Sveinung"),
3175 }
3176}
3177
3178/**********************************************************************/
3182 const int actor_id,
3183 const int target_id,
3184 int request_kind)
3185{
3187 actor_id, target_id,
3188 0,
3190 request_kind);
3191}
3192
3193/**********************************************************************/
3201 const int actor_id,
3202 const int target_id,
3203 const action_id action_type,
3204 int request_kind)
3205{
3206 struct player *pplayer = pc->playing;
3207 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3208 struct action *paction = action_by_number(action_type);
3209 struct unit *punit = game_unit_by_number(target_id);
3210 struct city *pcity = game_city_by_number(target_id);
3211 struct tile *ptile = index_to_tile(&(wld.map), target_id);
3212 const struct civ_map *nmap = &(wld.map);
3213
3214 if (paction == nullptr) {
3215 /* Non existing action */
3216 log_error("handle_unit_action_query() the action %d doesn't exist.",
3217 action_type);
3218
3219 unit_query_impossible(pc, actor_id, target_id, request_kind);
3220 return;
3221 }
3222
3223 if (pactor == nullptr) {
3224 /* Probably died or bribed. */
3225 log_verbose("handle_unit_action_query() invalid actor %d",
3226 actor_id);
3227 unit_query_impossible(pc, actor_id, target_id, request_kind);
3228 return;
3229 }
3230
3231 switch (paction->result) {
3233 if (punit != nullptr
3234 && is_action_enabled_unit_on_unit(nmap, action_type,
3235 pactor, punit)) {
3237 actor_id, target_id,
3238 unit_bribe_cost(punit, pplayer,
3239 pactor),
3240 action_type, request_kind);
3241 } else {
3242 illegal_action(pplayer, pactor, action_type,
3243 punit ? unit_owner(punit) : nullptr,
3244 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3245 unit_query_impossible(pc, actor_id, target_id, request_kind);
3246 return;
3247 }
3248 break;
3250 if (ptile != nullptr
3251 && is_action_enabled_unit_on_stack(nmap, action_type,
3252 pactor, ptile)) {
3254 actor_id, target_id,
3255 stack_bribe_cost(ptile, pplayer,
3256 pactor),
3257 action_type, request_kind);
3258 } else {
3259 illegal_action(pplayer, pactor, action_type,
3260 punit ? unit_owner(punit) : nullptr,
3261 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3262 unit_query_impossible(pc, actor_id, target_id, request_kind);
3263 return;
3264 }
3265 break;
3267 if (pcity
3268 && is_action_enabled_unit_on_city(nmap, action_type,
3269 pactor, pcity)) {
3271 actor_id, target_id,
3272 city_incite_cost(pplayer, pcity),
3273 action_type, request_kind);
3274 } else {
3275 illegal_action(pplayer, pactor, action_type,
3276 pcity ? city_owner(pcity) : nullptr,
3277 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3278 unit_query_impossible(pc, actor_id, target_id, request_kind);
3279 return;
3280 }
3281 break;
3283 if (pcity
3284 && is_action_enabled_unit_on_city(nmap, action_type,
3285 pactor, pcity)) {
3286 const struct unit_type *tgt_utype;
3287 int upgr_cost;
3288
3290 /* Already checked via is_action_enabled_unit_on_city() */
3292 upgr_cost = unit_upgrade_price(pplayer,
3294
3296 actor_id, target_id,
3297 upgr_cost, action_type,
3298 request_kind);
3299 } else {
3300 illegal_action(pplayer, pactor, action_type,
3301 pcity ? city_owner(pcity) : nullptr,
3302 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3303 unit_query_impossible(pc, actor_id, target_id, request_kind);
3304 return;
3305 }
3306 break;
3309 if (pcity
3310 && is_action_enabled_unit_on_city(nmap, action_type,
3311 pactor, pcity)) {
3313 action_by_number(action_type), request_kind);
3314 } else {
3315 illegal_action(pplayer, pactor, action_type,
3316 pcity ? city_owner(pcity) : nullptr,
3317 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3318 unit_query_impossible(pc, actor_id, target_id, request_kind);
3319 return;
3320 }
3321 break;
3322 default:
3323 unit_query_impossible(pc, actor_id, target_id, request_kind);
3324 return;
3325 };
3326}
3327
3328/**********************************************************************/
3333void handle_unit_do_action(struct player *pplayer,
3334 const int actor_id,
3335 const int target_id,
3336 const int sub_tgt_id,
3337 const char *name,
3338 const action_id action_type)
3339{
3340 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3341 action_type, ACT_REQ_PLAYER);
3342}
3343
3344/**********************************************************************/
3349void unit_do_action(struct player *pplayer,
3350 const int actor_id,
3351 const int target_id,
3352 const int sub_tgt_id,
3353 const char *name,
3354 const action_id action_type)
3355{
3356 unit_perform_action(pplayer, actor_id, target_id,
3357 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3358}
3359
3360/**********************************************************************/
3369bool unit_perform_action(struct player *pplayer,
3370 const int actor_id,
3371 const int target_id,
3372 const int sub_tgt_id_incoming,
3373 const char *name,
3374 const action_id action_type,
3375 const enum action_requester requester)
3376{
3377 struct action *paction;
3378 int sub_tgt_id;
3379 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3380 struct tile *target_tile = nullptr;
3381 struct extra_type *target_extra;
3382 struct impr_type *sub_tgt_impr;
3383 struct unit *punit = nullptr;
3384 struct city *pcity = nullptr;
3385 struct specialist *sub_tgt_spec = nullptr;
3386 const struct civ_map *nmap = &(wld.map);
3387
3388 if (!action_id_exists(action_type)) {
3389 /* Non existing action */
3390 log_error("unit_perform_action() the action %d doesn't exist.",
3391 action_type);
3392
3393 return FALSE;
3394 }
3395
3396 paction = action_by_number(action_type);
3397
3398 if (actor_unit == nullptr) {
3399 /* Probably died or bribed. */
3400 log_verbose("unit_perform_action() invalid actor %d",
3401 actor_id);
3402 return FALSE;
3403 }
3404
3406 case ATK_CITY:
3407 pcity = game_city_by_number(target_id);
3408 if (pcity == nullptr) {
3409 log_verbose("unit_perform_action() invalid target city %d",
3410 target_id);
3411 return FALSE;
3412 }
3414 fc_assert_ret_val(target_tile != nullptr, FALSE);
3415 break;
3416 case ATK_UNIT:
3417 punit = game_unit_by_number(target_id);
3418 if (punit == nullptr) {
3419 log_verbose("unit_perform_action() invalid target unit %d",
3420 target_id);
3421 return FALSE;
3422 }
3424 fc_assert_ret_val(target_tile != nullptr, FALSE);
3426 break;
3427 case ATK_STACK:
3428 case ATK_TILE:
3429 case ATK_EXTRAS:
3430 target_tile = index_to_tile(nmap, target_id);
3431 if (target_tile == nullptr) {
3432 log_verbose("unit_perform_action() invalid target tile %d",
3433 target_id);
3434 return FALSE;
3435 }
3437 break;
3438 case ATK_SELF:
3440 fc_assert_ret_val(target_tile != nullptr, FALSE);
3442 break;
3443 case ATK_COUNT:
3445 break;
3446 }
3447
3448 /* Server side sub target assignment */
3449 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3452 } else {
3453 sub_tgt_id = sub_tgt_id_incoming;
3454 }
3455
3456 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3457 && sub_tgt_id != NO_TARGET) {
3458 target_extra = extra_by_number(sub_tgt_id);
3459 fc_assert(!(target_extra->ruledit_disabled));
3460 } else {
3461 target_extra = nullptr;
3462 }
3463
3464 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3465 sub_tgt_spec = specialist_by_number(sub_tgt_id);
3466
3467 /* Sub targets should now be assigned */
3468 switch (paction->sub_target_kind) {
3469 case ASTK_NONE:
3470 /* No sub target. */
3471 break;
3472 case ASTK_BUILDING:
3473 if (sub_tgt_impr == nullptr) {
3474 /* Missing sub target */
3475 return FALSE;
3476 }
3477 break;
3478 case ASTK_TECH:
3479 /* Not handled here yet */
3480 break;
3481 case ASTK_EXTRA:
3483 if (target_extra == nullptr) {
3484 /* Missing sub target */
3485 return FALSE;
3486 }
3487 break;
3488 case ASTK_SPECIALIST:
3489 if (sub_tgt_spec == nullptr) {
3490 /* Missing sub target */
3491 return FALSE;
3492 }
3493 break;
3494 case ASTK_COUNT:
3495 break;
3496 }
3497
3501 && target_extra == nullptr) {
3502 /* Missing required action extra target. */
3503 log_verbose("unit_perform_action() action %d requires action "
3504 "but extra id %d is invalid.",
3505 action_type, sub_tgt_id);
3506 return FALSE;
3507 }
3508
3509 if (paction->actor.is_unit.unitwaittime_controlled
3511 /* Action not possible due to unitwaittime setting. */
3512 return FALSE;
3513 }
3514
3515#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3516 if (pcity \
3517 && is_action_enabled_unit_on_city(nmap, action_type, \
3518 actor_unit, pcity)) { \
3519 bool success; \
3520 script_server_signal_emit("action_started_unit_city", \
3521 action_by_number(action), actor, target); \
3522 if (!actor || !unit_is_alive(actor_id)) { \
3523 /* Actor unit was destroyed during pre action Lua. */ \
3524 return FALSE; \
3525 } \
3526 if (!target || !city_exist(target_id)) { \
3527 /* Target city was destroyed during pre action Lua. */ \
3528 return FALSE; \
3529 } \
3530 success = action_performer; \
3531 if (success) { \
3532 action_success_actor_price(paction, actor_id, actor); \
3533 } \
3534 script_server_signal_emit("action_finished_unit_city", \
3535 action_by_number(action), success, \
3536 unit_is_alive(actor_id) ? actor : nullptr, \
3537 city_exist(target_id) ? target : nullptr); \
3538 return success; \
3539 } else { \
3540 illegal_action(pplayer, actor_unit, action_type, \
3541 pcity ? city_owner(pcity) : nullptr, nullptr, pcity, \
3542 nullptr, TRUE, requester); \
3543 }
3544
3545#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3546 if (actor_unit \
3547 && is_action_enabled_unit_on_self(nmap, action_type, actor_unit)) { \
3548 bool success; \
3549 script_server_signal_emit("action_started_unit_self", \
3550 action_by_number(action), actor); \
3551 if (!actor || !unit_is_alive(actor_id)) { \
3552 /* Actor unit was destroyed during pre action Lua. */ \
3553 return FALSE; \
3554 } \
3555 success = action_performer; \
3556 if (success) { \
3557 action_success_actor_price(paction, actor_id, actor); \
3558 } \
3559 script_server_signal_emit("action_finished_unit_self", \
3560 action_by_number(action), success, \
3561 unit_is_alive(actor_id) ? actor : nullptr); \
3562 return success; \
3563 } else { \
3564 illegal_action(pplayer, actor_unit, action_type, \
3565 unit_owner(actor_unit), nullptr, nullptr, actor_unit, \
3566 TRUE, requester); \
3567 }
3568
3569#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3570 if (punit \
3571 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3572 bool success; \
3573 script_server_signal_emit("action_started_unit_unit", \
3574 action_by_number(action), actor, target); \
3575 if (!actor || !unit_is_alive(actor_id)) { \
3576 /* Actor unit was destroyed during pre action Lua. */ \
3577 return FALSE; \
3578 } \
3579 if (!target || !unit_is_alive(target_id)) { \
3580 /* Target unit was destroyed during pre action Lua. */ \
3581 return FALSE; \
3582 } \
3583 success = action_performer; \
3584 if (success) { \
3585 action_success_actor_price(paction, actor_id, actor); \
3586 action_success_target_pay_mp(paction, target_id, punit); \
3587 } \
3588 script_server_signal_emit("action_finished_unit_unit", \
3589 action_by_number(action), success, \
3590 unit_is_alive(actor_id) ? actor : nullptr, \
3591 unit_is_alive(target_id) ? target \
3592 : nullptr); \
3593 return success; \
3594 } else { \
3595 illegal_action(pplayer, actor_unit, action_type, \
3596 punit ? unit_owner(punit) : nullptr, nullptr, nullptr, \
3597 punit, TRUE, requester); \
3598 }
3599
3600#define ACTION_PERFORM_UNIT_STACK(action, actor, target, action_performer)\
3601 if (target_tile \
3602 && is_action_enabled_unit_on_stack(nmap, action_type, \
3603 actor_unit, target_tile)) { \
3604 bool success; \
3605 script_server_signal_emit("action_started_unit_stack", \
3606 action_by_number(action), actor, target); \
3607 script_server_signal_emit("action_started_unit_units", \
3608 action_by_number(action), actor, target); \
3609 if (!actor || !unit_is_alive(actor_id)) { \
3610 /* Actor unit was destroyed during pre action Lua. */ \
3611 return FALSE; \
3612 } \
3613 success = action_performer; \
3614 if (success) { \
3615 action_success_actor_price(paction, actor_id, actor); \
3616 } \
3617 script_server_signal_emit("action_finished_unit_stack", \
3618 action_by_number(action), success, \
3619 unit_is_alive(actor_id) ? actor : nullptr, \
3620 target); \
3621 script_server_signal_emit("action_finished_unit_units", \
3622 action_by_number(action), success, \
3623 unit_is_alive(actor_id) ? actor : nullptr, \
3624 target); \
3625 return success; \
3626 } else { \
3627 illegal_action(pplayer, actor_unit, action_type, \
3628 nullptr, target_tile, nullptr, nullptr, \
3629 TRUE, requester); \
3630 }
3631
3632#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3633 if (target_tile \
3634 && is_action_enabled_unit_on_tile(nmap, action_type, \
3635 actor_unit, target_tile, \
3636 target_extra)) { \
3637 bool success; \
3638 script_server_signal_emit("action_started_unit_tile", \
3639 action_by_number(action), actor, target); \
3640 if (!actor || !unit_is_alive(actor_id)) { \
3641 /* Actor unit was destroyed during pre action Lua. */ \
3642 return FALSE; \
3643 } \
3644 success = action_performer; \
3645 if (success) { \
3646 action_success_actor_price(paction, actor_id, actor); \
3647 } \
3648 script_server_signal_emit("action_finished_unit_tile", \
3649 action_by_number(action), success, \
3650 unit_is_alive(actor_id) ? actor : nullptr, \
3651 target); \
3652 return success; \
3653 } else { \
3654 illegal_action(pplayer, actor_unit, action_type, \
3655 target_tile ? tile_owner(target_tile) : nullptr, \
3656 target_tile, nullptr, nullptr, \
3657 TRUE, requester); \
3658 }
3659
3660#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3661 if (target_tile \
3662 && is_action_enabled_unit_on_extras(nmap, action_type, \
3663 actor_unit, target_tile, \
3664 target_extra)) { \
3665 bool success; \
3666 script_server_signal_emit("action_started_unit_extras", \
3667 action_by_number(action), actor, target); \
3668 if (!actor || !unit_is_alive(actor_id)) { \
3669 /* Actor unit was destroyed during pre action Lua. */ \
3670 return FALSE; \
3671 } \
3672 success = action_performer; \
3673 if (success) { \
3674 action_success_actor_price(paction, actor_id, actor); \
3675 } \
3676 script_server_signal_emit("action_finished_unit_extras", \
3677 action_by_number(action), success, \
3678 unit_is_alive(actor_id) ? actor : nullptr, \
3679 target); \
3680 return success; \
3681 } else { \
3682 illegal_action(pplayer, actor_unit, action_type, \
3683 target_tile ? target_tile->extras_owner : nullptr, \
3684 target_tile, nullptr, nullptr, \
3685 TRUE, requester); \
3686 }
3687
3688#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3689 target_city, target_unit, target_tile, \
3690 action_performer) \
3691 switch (action_get_target_kind(paction)) { \
3692 case ATK_CITY: \
3693 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3694 action_performer); \
3695 break; \
3696 case ATK_UNIT: \
3697 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3698 action_performer); \
3699 break; \
3700 case ATK_STACK: \
3701 ACTION_PERFORM_UNIT_STACK(paction->id, actor, target_tile, \
3702 action_performer); \
3703 break; \
3704 case ATK_TILE: \
3705 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3706 action_performer); \
3707 break; \
3708 case ATK_EXTRAS: \
3709 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3710 action_performer); \
3711 break; \
3712 case ATK_SELF: \
3713 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3714 break; \
3715 case ATK_COUNT: \
3716 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3717 break; \
3718 }
3719
3720 switch (paction->result) {
3724 paction));
3725 break;
3727 /* Difference is caused by data in the action structure. */
3730 punit, paction));
3731 break;
3732 case ACTRES_EXPEL_UNIT:
3734 do_expel_unit(pplayer, actor_unit, punit,
3735 paction));
3736 break;
3737 case ACTRES_HEAL_UNIT:
3739 do_heal_unit(pplayer, actor_unit, punit,
3740 paction));
3741 break;
3745 paction));
3746 break;
3750 paction));
3751 break;
3754 do_unit_board(pplayer, actor_unit, punit,
3755 paction));
3756 break;
3759 do_unit_load(pplayer, actor_unit, punit,
3760 paction));
3761 break;
3765 paction));
3766 break;
3768 /* All consequences are handled by the action system. */
3770 break;
3771 case ACTRES_FORTIFY:
3774 break;
3775 case ACTRES_CONVERT:
3778 break;
3779 case ACTRES_HOMELESS:
3782 break;
3783 case ACTRES_SPY_ESCAPE:
3785 spy_escape(pplayer, actor_unit,
3787 break;
3789 /* Difference is caused by data in the action structure. */
3792 B_LAST, paction));
3793 break;
3795 /* Difference is caused by data in the action structure. */
3798 sub_tgt_impr->item_number,
3799 paction));
3800 break;
3802 /* Difference is caused by data in the action structure. */
3805 -1, paction));
3806 break;
3807 case ACTRES_SPY_POISON:
3808 /* Difference is caused by data in the action structure. */
3810 spy_poison(pplayer, actor_unit, pcity,
3811 paction));
3812 break;
3816 paction));
3817 break;
3819 /* Difference is caused by data in the action structure. */
3821 diplomat_investigate(pplayer,
3823 paction));
3824 break;
3826 /* Difference is caused by data in the action structure. */
3829 paction));
3830 break;
3832 /* Difference is caused by data in the action structure. */
3835 paction));
3836 break;
3838 /* Difference is caused by data in the action structure. */
3841 A_UNSET, paction));
3842 break;
3844 /* Difference is caused by data in the action structure. */
3847 sub_tgt_id, paction));
3848 break;
3850 /* Difference is caused by data in the action structure. */
3853 paction));
3854 break;
3855 case ACTRES_STEAL_MAPS:
3856 /* Difference is caused by data in the action structure. */
3859 pcity, paction));
3860 break;
3861 case ACTRES_TRADE_ROUTE:
3864 pcity, paction));
3865 break;
3866 case ACTRES_MARKETPLACE:
3869 pcity, paction));
3870 break;
3871 case ACTRES_HELP_WONDER:
3873 unit_do_help_build(pplayer,
3875 paction));
3876 break;
3877 case ACTRES_SPY_NUKE:
3878 /* Difference is caused by data in the action structure. */
3880 spy_nuke_city(pplayer, actor_unit, pcity,
3881 paction));
3882 break;
3883 case ACTRES_JOIN_CITY:
3885 city_add_unit(pplayer, actor_unit, pcity,
3886 paction));
3887 break;
3890 unit_do_destroy_city(pplayer,
3892 paction));
3893 break;
3897 paction));
3898 break;
3899 case ACTRES_HOME_CITY:
3902 paction));
3903 break;
3906 do_unit_upgrade(pplayer, actor_unit,
3908 break;
3910 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3913 pcity, paction));
3914 break;
3918 actor_unit,
3919 pcity,
3920 sub_tgt_impr->item_number,
3921 paction));
3922 break;
3926 actor_unit,
3927 pcity,
3928 paction));
3929 break;
3934 break;
3935 case ACTRES_AIRLIFT:
3938 break;
3943 break;
3944 case ACTRES_BOMBARD:
3945 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3948 paction));
3949 break;
3950 case ACTRES_ATTACK:
3952 /* Difference is caused by data in the action structure. */
3955 break;
3956 case ACTRES_WIPE_UNITS:
3959 break;
3964 break;
3965 case ACTRES_NUKE_UNITS:
3968 paction));
3969 break;
3970 case ACTRES_SPY_ATTACK:
3973 paction));
3974 break;
3975 case ACTRES_FOUND_CITY:
3977 city_build(pplayer, actor_unit,
3979 break;
3980 case ACTRES_NUKE:
3984 paction));
3985 break;
3986 case ACTRES_PARADROP:
3990 break;
3992 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3994 do_disembark(pplayer, actor_unit,
3996 break;
3997 case ACTRES_HUT_ENTER:
3999 do_unit_hut(pplayer, actor_unit,
4001 break;
4004 do_unit_hut(pplayer, actor_unit,
4006 break;
4007 case ACTRES_UNIT_MOVE:
4011 break;
4012 case ACTRES_TELEPORT:
4016 nullptr, FALSE,
4019 FALSE, FALSE));
4020 break;
4024 break;
4025 case ACTRES_CULTIVATE:
4028 break;
4029 case ACTRES_PLANT:
4032 break;
4033 case ACTRES_PILLAGE:
4036 paction,
4037 &target_extra));
4038 break;
4039 case ACTRES_CLEAN:
4042 paction,
4043 &target_extra));
4044 break;
4045 case ACTRES_ROAD:
4048 paction,
4049 &target_extra));
4050 break;
4051 case ACTRES_BASE:
4054 paction,
4055 &target_extra));
4056 break;
4057 case ACTRES_MINE:
4060 paction,
4061 &target_extra));
4062 break;
4063 case ACTRES_IRRIGATE:
4066 paction,
4067 &target_extra));
4068 break;
4069 case ACTRES_NONE:
4070 /* 100% ruleset defined. */
4072 TRUE);
4073 break;
4076 return FALSE;
4077
4079 }
4080
4081 /* Something must have gone wrong. */
4082 return FALSE;
4083}
4084
4085/**********************************************************************/
4093 bool rehome)
4094{
4096 struct player *old_owner = unit_owner(punit);
4097 struct player *new_owner = (new_pcity == nullptr ? old_owner
4099 const struct civ_map *nmap = &(wld.map);
4100
4101 /* Calling this function when new_pcity is same as old_pcity should
4102 * be safe with current implementation, but it is not meant to
4103 * be used that way. */
4105
4106 /* If 'rehome' is not set, this function should only be used to change
4107 * which player owns the unit */
4109
4110 if (old_owner != new_owner) {
4111 struct city *pcity = tile_city(punit->tile);
4112
4115
4118
4119 if (pcity != nullptr
4121 /* Special case when city is being transferred. At this point city
4122 * itself has changed owner, so it's enemy city now that old owner
4123 * cannot see inside. All the normal methods of removing transferred
4124 * unit from previous owner's client think that there's no need to
4125 * remove unit as client shouldn't have it in first place. */
4127 }
4128
4129 /* Remove AI control of the old owner. */
4130 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4131
4135
4136 /* Activate AI control of the new owner. */
4137 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4138
4141 }
4142
4143 if (rehome) {
4144 /* Remove from old city first and add to new city only after that. */
4145 if (old_pcity) {
4146 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4147 unit_list_remove(old_pcity->units_supported, punit);
4148 /* Update unit upkeep */
4150 }
4151
4152 if (new_pcity != nullptr) {
4153 unit_list_prepend(new_pcity->units_supported, punit);
4154
4155 /* Update unit upkeep */
4157
4158 punit->homecity = new_pcity->id;
4159 } else {
4161 }
4162 }
4163
4165 /* This is mainly for cases where unit owner changes to one not knowing
4166 * Railroad tech when unit is already building railroad.
4167 * Does also send_unit_info() */
4169 } else {
4170 /* Send info to players and observers. */
4171 send_unit_info(nullptr, punit);
4172 }
4173
4174 if (new_pcity != nullptr) {
4178 }
4179
4180 if (old_pcity) {
4184 }
4185
4187
4188 if (old_owner != new_owner) {
4189 script_server_signal_emit("unit_transferred", punit, old_owner);
4190 }
4191}
4192
4193/**********************************************************************/
4199 struct city *pcity,
4200 const struct action *paction)
4201{
4202 const char *giver = nullptr;
4203
4204 if (unit_owner(punit) != city_owner(pcity)) {
4205 /* This is a gift. Tell the receiver. */
4206 giver = player_name(unit_owner(punit));
4207 }
4208
4210
4211 if (punit->homecity == pcity->id && giver) {
4212 /* Notify the city owner about the gift they received. */
4214 ftc_server,
4215 /* TRANS: other player ... unit type ... city name. */
4216 _("%s transferred control over a %s to you in %s."),
4217 giver,
4219 city_link(pcity));
4220 }
4221
4222 return punit->homecity == pcity->id;
4223}
4224
4225/**********************************************************************/
4232static bool city_add_unit(struct player *pplayer, struct unit *punit,
4233 struct city *pcity, const struct action *paction)
4234{
4236 const struct unit_type *act_utype;
4238 int new_food;
4240
4241 /* Sanity check: The actor is still alive. */
4243
4245
4246 /* Sanity check: The target city still exists. */
4248
4250
4252 /* Preserve old food stock, unless granary effect gives us more. */
4253 pcity->food_stock = MAX(pcity->food_stock, new_food);
4254
4255 if (is_super_specialist(act_utype->spec_type)) {
4257
4259 pcity->specialists[sspec]++;
4260 } else {
4262 /* Hardly much needed but let it be */
4263 spec_id = specialist_index(act_utype->spec_type);
4264 }
4265 /* Make the new people something, otherwise city fails the checks */
4267 FALSE);
4268 pcity->specialists[spec_id] += amount;
4270 /* Refresh the city data. */
4272
4273 /* Notify the unit owner that the unit successfully joined the city. */
4275 _("%s added to aid %s in growing."),
4277 city_link(pcity));
4278 if (pplayer != city_owner(pcity)) {
4279 /* Notify the city owner when a foreign unit joins a city. */
4281 ftc_server,
4282 /* TRANS: another player had their unit join your city. */
4283 _("%s adds %s to your city %s."),
4286 city_link(pcity));
4287 }
4288
4291 city_link(pcity));
4292
4294
4295 send_city_info(nullptr, pcity);
4296
4297 script_server_signal_emit("city_size_change", pcity,
4298 (lua_Integer)amount, "unit_added");
4299
4300 return TRUE;
4301}
4302
4303/**********************************************************************/
4312static bool city_build(struct player *pplayer, struct unit *punit,
4313 struct tile *ptile, const char *name,
4314 const struct action *paction)
4315{
4316 char message[1024];
4317 int size;
4318 struct player *nationality;
4319 struct player *towner;
4320 const struct unit_type *act_utype;
4322 struct city *pcity;
4323
4324 /* Sanity check: The actor still exists. */
4325 fc_assert_ret_val(pplayer, FALSE);
4327
4328 towner = tile_owner(ptile);
4329
4330 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4331 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4332 "%s", message);
4333 return FALSE;
4334 }
4335
4337 sid = specialist_index(act_utype->spec_type);
4339
4340 create_city(pplayer, ptile, name, nationality);
4341 size = act_utype->city_size;
4342 pcity = tile_city(ptile); /* A callback may destroy or replace it any time */
4343 if (nullptr != pcity) {
4344 if (is_super_specialist_id(sid) && pcity->specialists[sid] < MAX_CITY_SIZE) {
4345 pcity->specialists[sid]++;
4346 }
4347 if (size > 1) {
4348 city_change_size(pcity, size, nationality, -1, nullptr);
4349 }
4350 }
4351
4352 /* May cause an incident even if the target tile is unclaimed. A ruleset
4353 * could give everyone a casus belli against the city founder. A rule
4354 * like that would make sense in a story where deep ecology is on the
4355 * table. (See also Voluntary Human Extinction Movement) */
4357 ptile, tile_link(ptile));
4358
4359 return TRUE;
4360}
4361
4362/**********************************************************************/
4365static void handle_unit_change_activity_real(struct player *pplayer,
4366 int unit_id,
4367 enum unit_activity activity,
4368 struct extra_type *activity_target,
4370{
4371 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4372
4373 if (punit == nullptr) {
4374 /* Probably died or bribed. */
4375 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4376 return;
4377 }
4378
4379 if (punit->activity == activity
4381 return;
4382 }
4383
4384 /* Remove city spot reservations for AI settlers on city founding
4385 * mission, before goto_tile reset. */
4386 if (punit->server.adv->task != AUT_NONE) {
4387 adv_unit_new_task(punit, AUT_NONE, nullptr);
4388 }
4389
4390 punit->goto_tile = nullptr;
4391
4392 if (activity == ACTIVITY_GOTO) {
4393 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4394 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4395 * it is going somewhere while it is standing still. The appearance of
4396 * the unit doing something can trick the user to not make use of it.
4397 *
4398 * Handled here because adv_follow_path() uses unit_activity_handling()
4399 * to set a unit's activity to ACTIVITY_GOTO. */
4400 return;
4401 }
4402
4403 if (activity == ACTIVITY_EXPLORE) {
4404 /* Please use unit_server_side_agent_set(). */
4405 return;
4406 }
4407
4408 /* The activity can now be set. */
4411}
4412
4413/**********************************************************************/
4416void handle_unit_change_activity(struct player *pplayer, int unit_id,
4418 int target_id)
4419{
4420 struct extra_type *activity_target;
4421
4423 activity_target = nullptr;
4424 } else {
4425 activity_target = extra_by_number(target_id);
4426 }
4427
4428#ifdef FREECIV_WEB
4429 /* Web-client is not capable of selecting target, so we do it server side */
4430 if (activity_target == nullptr) {
4431 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4432 bool required = TRUE;
4433
4434 if (punit == nullptr) {
4435 return;
4436 }
4437
4438 if (activity == ACTIVITY_IRRIGATE) {
4439 struct tile *ptile = unit_tile(punit);
4440
4441 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4442 pplayer, punit);
4443 } else if (activity == ACTIVITY_MINE) {
4444 struct tile *ptile = unit_tile(punit);
4445
4446 activity_target = next_extra_for_tile(ptile, EC_MINE,
4447 pplayer, punit);
4448 } else if (activity == ACTIVITY_BASE) {
4449 struct tile *ptile = unit_tile(punit);
4450 struct base_type *pbase =
4452
4453 if (pbase != nullptr) {
4454 activity_target = base_extra_get(pbase);
4455 }
4456
4457 } else if (activity == ACTIVITY_CLEAN) {
4458 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4459 pplayer, punit);
4460 } else {
4461 required = FALSE;
4462 }
4463
4464 if (activity_target == nullptr && required) {
4465 /* Nothing more we can do */
4466 return;
4467 }
4468 }
4469#endif /* FREECIV_WEB */
4470
4471 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target,
4472 activity_default_action(activity));
4473}
4474
4475/**********************************************************************/
4478static void see_combat(struct unit *pattacker, struct unit *pdefender)
4479{
4482
4483 /*
4484 * Special case for attacking/defending:
4485 *
4486 * Normally the player doesn't get the information about the units inside a
4487 * city. However for attacking/defending the player has to know the unit of
4488 * the other side. After the combat a remove_unit packet will be sent
4489 * to the client to tidy up.
4490 *
4491 * Note these packets must be sent out before unit_versus_unit() is called,
4492 * so that the original unit stats (HP) will be sent.
4493 */
4500
4502 struct player *pplayer = pconn->playing;
4503
4504 if (pplayer != nullptr) {
4505
4506 /* NOTE: this means the player can see combat between submarines even
4507 * if neither sub is visible. See similar comment in send_combat(). */
4510 V_MAIN)) {
4511
4512 /* Units are sent even if they were visible already. They may
4513 * have changed orientation for combat. */
4514 if (pplayer == unit_owner(pattacker)) {
4516 } else {
4518 }
4519
4520 if (pplayer == unit_owner(pdefender)) {
4522 } else {
4524 }
4525 }
4526 } else if (pconn->observer) {
4527 /* Global observer sees everything... */
4530 }
4532}
4533
4534/**********************************************************************/
4537static void send_combat(struct unit *pattacker, struct unit *pdefender,
4538 int att_veteran, int def_veteran, int bombard)
4539{
4541
4543 combat.defender_unit_id = pdefender->id;
4544 combat.attacker_hp = pattacker->hp;
4545 combat.defender_hp = pdefender->hp;
4546 combat.make_att_veteran = att_veteran;
4547 combat.make_def_veteran = def_veteran;
4548
4549 players_iterate(other_player) {
4550 /* NOTE: this means the player can see combat between submarines even
4551 * if neither sub is visible. See similar comment in see_combat. */
4552 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4553 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4554 V_MAIN)) {
4555 lsend_packet_unit_combat_info(other_player->connections, &combat);
4556
4557 /*
4558 * Remove the client knowledge of the units. This corresponds to the
4559 * send_packet_unit_short_info() calls up above.
4560 */
4561 if (!can_player_see_unit(other_player, pattacker)) {
4562 unit_goes_out_of_sight(other_player, pattacker);
4563 }
4564 if (!can_player_see_unit(other_player, pdefender)) {
4565 unit_goes_out_of_sight(other_player, pdefender);
4566 }
4567 }
4569
4570 /* Send combat info to non-player observers as well. They already know
4571 * about the unit so no unit_info is needed. */
4573 if (pconn->playing == nullptr && pconn->observer) {
4575 }
4577}
4578
4579/**********************************************************************/
4583 struct city *pcity,
4584 const struct action *paction,
4585 const char *reason)
4586{
4587 struct player *pplayer = unit_owner(punit);
4588
4589 if (pcity
4590 && get_target_bonus_effects(nullptr,
4591 &(const struct req_context) {
4592 .player = city_owner(pcity),
4593 .city = pcity,
4594 .tile = city_tile(pcity),
4595 .unit = punit,
4596 .unittype = unit_type_get(punit),
4597 .action = paction,
4598 },
4599 nullptr, EFT_UNIT_NO_LOSE_POP) <= 0
4602 struct player *cplayer = city_owner(pcity);
4603 struct tile *ctile = city_tile(pcity);
4604 const char *clink = city_link(pcity);
4605
4606 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4608 send_city_info(nullptr, pcity);
4609 } else {
4611 /* TRANS: Battleship ... Los Angeles ... Bombard */
4612 _("Your %s destroyed %s by doing %s."),
4617 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4618 _("%s destroyed %s by doing %s."),
4619 player_name(pplayer), clink,
4621 }
4622 }
4623}
4624
4625/**********************************************************************/
4632static bool unit_bombard(struct unit *punit, struct tile *ptile,
4633 const struct action *paction)
4634{
4635 struct player *pplayer = unit_owner(punit);
4636 struct city *pcity = tile_city(ptile);
4637 const struct unit_type *act_utype;
4638 const struct civ_map *nmap = &(wld.map);
4639
4640 /* Sanity check: The actor still exists. */
4641 fc_assert_ret_val(pplayer, FALSE);
4643
4645
4646 log_debug("Start bombard: %s %s to %d, %d.",
4648 unit_rule_name(punit), TILE_XY(ptile));
4649
4651 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4652 bool adj;
4653 enum direction8 facing;
4654 int att_hp, def_hp;
4655
4657 punit->tile, pdefender->tile, &facing);
4658
4659 if (adj) {
4660 punit->facing = facing;
4661
4662 /* Unlike with normal attack, we don't change orientation of
4663 * defenders when bombarding */
4664 }
4665
4666 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4667
4668 if (def_hp <= 0) {
4669 notify_player(pplayer, ptile,
4671 /* TRANS: Your Bomber killed the English Rifleman by
4672 * doing Bombard. */
4673 _("Your %s killed the %s %s by doing %s."),
4680 /* TRANS: Your Rifleman was killed by the French
4681 * Bomber doing Bombard. */
4682 _("Your %s was killed by the %s %s doing %s."),
4687 } else {
4688 notify_player(pplayer, ptile,
4690 /* TRANS: Your Bomber bombards the English Rifleman. */
4691 _("Your %s bombards the %s %s."),
4697 /* TRANS: Your Rifleman is bombarded by the French
4698 * Bomber. */
4699 _("Your %s is bombarded by the %s %s."),
4703 }
4704
4706
4707 punit->hp = att_hp;
4708 pdefender->hp = def_hp;
4709
4710 send_combat(punit, pdefender, 0, 0, 1);
4711
4712 /* May cause an incident */
4718
4719 if (def_hp <= 0) {
4721 } else {
4722 send_unit_info(nullptr, pdefender);
4723 }
4724 }
4725
4727
4730
4732
4733 send_unit_info(nullptr, punit);
4734
4735 return TRUE;
4736}
4737
4738/**********************************************************************/
4749static bool unit_nuke(struct player *pplayer, struct unit *punit,
4750 struct tile *def_tile, const struct action *paction)
4751{
4752 struct city *pcity;
4753 const struct unit_type *act_utype;
4754 struct civ_map *nmap = &(wld.map);
4755
4756 /* Sanity check: The actor still exists. */
4757 fc_assert_ret_val(pplayer, FALSE);
4759
4761
4762 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4765 TILE_XY(def_tile));
4766
4767 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4768 /* FIXME: Remove the hard coded reference to SDI defense. */
4770 _("Your %s was shot down by "
4771 "SDI defenses, what a waste."), unit_tile_link(punit));
4773 _("The nuclear attack on %s was avoided by"
4774 " your SDI defense."), city_link(pcity));
4775
4776 /* Trying to nuke something this close can be... unpopular. */
4780
4781 /* Remove the destroyed nuke. */
4783
4784 return FALSE;
4785 }
4786
4788
4789
4790 /* The nuke must be wiped here so it won't be seen as a victim of its own
4791 * detonation. */
4792 if (paction->actor_consuming_always) {
4793 wipe_unit(punit, ULR_DETONATED, nullptr);
4794 }
4795
4797
4798 /* May cause an incident even if the target tile is unclaimed. A ruleset
4799 * could give everyone a casus belli against the tile nuker. A rule
4800 * like that would make sense in a story where detonating any nuke at all
4801 * could be forbidden. */
4804 def_tile,
4806
4807 return TRUE;
4808}
4809
4810/**********************************************************************/
4820 struct unit *act_unit,
4821 struct city *tgt_city,
4822 const struct action *paction)
4823{
4824 int tgt_city_id;
4825 struct player *tgt_player;
4826 bool capital;
4827 bool try_civil_war = FALSE;
4828 const struct unit_type *act_utype;
4829
4830 /* Sanity check: The actor still exists. */
4833
4835
4836 /* Sanity check: The target city still exists. */
4838
4840
4841 /* How can a city be ownerless? */
4843
4844 /* Save city ID. */
4845 tgt_city_id = tgt_city->id;
4846
4848
4849 if (capital
4850 && (tgt_player->spaceship.state == SSHIP_STARTED
4851 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4852 /* Destroying this city destroys the victim's space ship. */
4854 }
4855
4856 if (capital
4860 /* Destroying this city can trigger a civil war. */
4862 }
4863
4864 /* Let the actor know. */
4867 _("You destroy %s completely."),
4869
4870 if (tgt_player != act_player) {
4871 /* This was done to a foreign city. Inform the victim player. */
4874 _("%s has been destroyed by %s."),
4877 }
4878
4879 /* May cause an incident */
4883
4884 /* Run post city destruction Lua script. */
4886 act_player);
4887
4888 /* Can't be sure of city existence after running script. */
4889 if (city_exist(tgt_city_id)) {
4891 }
4892
4893 if (try_civil_war) {
4894 /* Try to start the civil war. */
4896 }
4897
4898 /* The city is no more. */
4899 return TRUE;
4900}
4901
4902/**********************************************************************/
4907static const char *unit_veteran_level_string(const struct unit *punit)
4908{
4909 static char buf[MAX_LEN_LINK];
4910 const struct veteran_level *vlevel;
4911
4912 if (!punit) {
4913 buf[0] = '\0'; /* If no unit, return empty string */
4914 return buf;
4915 }
4916
4918 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4919
4920 return buf;
4921}
4922
4923/**********************************************************************/
4928static const char *unit_achieved_rank_string(const struct unit *punit)
4929{
4930 static char buf[MAX_LEN_LINK];
4931
4932 fc_snprintf(buf, sizeof(buf),
4933 /* TRANS: " and achieved the rank of <veteran level>";
4934 * preserve leading space */
4935 _(" and achieved the rank of %s"),
4937 return buf;
4938}
4939
4940/**********************************************************************/
4945static const char *unit_tired_attack_string(const struct unit *punit)
4946{
4947 static char buf[MAX_LEN_LINK];
4948
4950 fc_snprintf(buf, sizeof(buf),
4951 /* TRANS: tired; note trailing space */
4952 _("tired "));
4953 } else {
4954 buf[0] = '\0';
4955 }
4956
4957 return buf;
4958}
4959
4960/**********************************************************************/
4967static const char *unit_firepower_if_not_one(int firepower)
4968{
4969 static char buf[MAX_LEN_LINK];
4970
4971 if (firepower == 1) {
4972 buf[0] = '\0';
4973 } else {
4974 fc_snprintf(buf, sizeof(buf),
4975 /* TRANS: FP = Firepower of a unit; note trailing space */
4976 _("FP:%d "),
4977 firepower);
4978 }
4979
4980 return buf;
4981}
4982
4983/**********************************************************************/
4992static bool do_attack(struct unit *punit, struct tile *def_tile,
4993 const struct action *paction)
4994{
4999 struct unit *ploser, *pwinner;
5002 int winner_id;
5003 struct player *pplayer = unit_owner(punit);
5004 bool adj;
5005 enum direction8 facing;
5006 int att_hp, def_hp, att_fp, def_fp;
5008 int def_power, att_power;
5009 int att_vet, def_vet;
5010 struct unit *pdefender;
5011 const struct unit_type *act_utype = unit_type_get(punit);
5012 struct civ_map *nmap = &(wld.map);
5013 bool powerless;
5014
5016 /* Can't fight air... */
5017 return FALSE;
5018 }
5019
5021 def_hp_start = pdefender->hp;
5025
5026 log_debug("Start attack: %s %s against %s %s.",
5031
5032 /* Sanity checks */
5037 FALSE,
5038 "Trying to attack a unit with which you have peace "
5039 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
5043 FALSE,
5044 "Trying to attack a unit with which you have "
5045 "alliance at (%d, %d).", TILE_XY(def_tile));
5046
5049
5051 punit->tile, pdefender->tile, &facing);
5052
5053 fc_assert(adj);
5054 if (adj) {
5055 punit->facing = facing;
5056 pdefender->facing = opposite_direction(facing);
5057 }
5058
5060 old_defender_vet = pdefender->veteran;
5061
5062 /* N.B.: unit_veteran_level_string always returns the same pointer. */
5065
5066 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
5069
5070 /* Record tired attack string before attack */
5072
5073 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
5074 &att_vet, &def_vet, paction);
5075
5076 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
5077 && unit_transported(punit)) {
5078 /* Dying attacker must be first unloaded so it doesn't die inside transport */
5080 }
5081
5083
5084 punit->hp = att_hp;
5085 pdefender->hp = def_hp;
5086
5088
5089 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
5090 * the movement attack modifier is correct! --dwp
5091 *
5092 * For greater Civ2 compatibility (and game balance issues), we recompute
5093 * the new total MP based on the HP the unit has left after being damaged,
5094 * and subtract the MPs that had been used before the combat (plus the
5095 * points used in the attack itself, for the attacker). -GJW, Glip
5096 */
5099
5100 if (punit->moves_left < 0) {
5101 punit->moves_left = 0;
5102 }
5103 if (pdefender->moves_left < 0) {
5104 pdefender->moves_left = 0;
5105 }
5108
5109 /* This may cause a diplomatic incident. */
5113
5114 if (punit->hp > 0 && pdefender->hp > 0) {
5115 /* Neither died */
5117 pdefender->veteran - old_defender_vet, 0);
5118 return TRUE;
5119 }
5120 pwinner = (punit->hp > 0) ? punit : pdefender;
5121 winner_id = pwinner->id;
5122 ploser = (pdefender->hp > 0) ? punit : pdefender;
5123
5124 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5125 old_defender_vet)) ? 0 : 1;
5126
5128 pdefender->veteran - old_defender_vet, 0);
5129
5130 /* N.B.: unit_link always returns the same pointer. */
5135
5136 if (punit == ploser) {
5137 /* The attacker lost */
5138 log_debug("Attacker lost: %s %s against %s %s.",
5143
5147 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5148 * 9 HP remaining] survived the pathetic ...attack from
5149 * green Warriors [id:90 ...A:1.0 HP:10]. */
5150 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5151 " survived the pathetic %sattack from %s %s "
5152 "[id:%d %sA:%.1f HP:%d]."),
5155 pdefender->id,
5157 (float)def_power/POWER_FACTOR,
5158 def_hp_start - pdefender->hp,
5159 pdefender->hp,
5162 loser_link,
5163 punit->id,
5165 (float)att_power/POWER_FACTOR,
5166 att_hp_start);
5167 } else {
5170 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5171 * 9 HP remaining] survived the pathetic ...attack from the
5172 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5173 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5174 " survived the pathetic %sattack from the %s %s %s "
5175 "[id:%d %sA:%.1f HP:%d]."),
5178 pdefender->id,
5180 (float)def_power/POWER_FACTOR,
5181 def_hp_start - pdefender->hp,
5182 pdefender->hp,
5186 loser_link,
5187 punit->id,
5189 (float)att_power/POWER_FACTOR,
5190 att_hp_start);
5191 }
5192
5193 if (vet) {
5195 }
5196
5200 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5201 * failed against green Destroyer [id:200 lost
5202 * 27 HP, 3 HP remaining%s]!";
5203 * last %s is either "and ..." or empty string */
5204 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5205 "against %s %s [id:%d lost %d HP, %d HP "
5206 "remaining%s]!"),
5208 loser_link,
5209 punit->id,
5211 (float)att_power/POWER_FACTOR,
5215 pdefender->id,
5216 def_hp_start - pdefender->hp,
5217 pdefender->hp,
5219 } else {
5222 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5223 * failed against the Polish green Destroyer [id:200 lost
5224 * 27 HP, 3 HP remaining%s]!";
5225 * last %s is either "and ..." or empty string */
5226 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5227 "against the %s %s %s [id:%d lost %d HP, %d HP "
5228 "remaining%s]!"),
5230 loser_link,
5231 punit->id,
5233 (float)att_power/POWER_FACTOR,
5238 pdefender->id,
5239 def_hp_start - pdefender->hp,
5240 pdefender->hp,
5242 }
5243
5245 } else {
5246 /* The defender lost, the attacker punit lives! */
5247 struct city *pcity;
5248
5249 log_debug("Defender lost: %s %s against %s %s.",
5254
5258 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5259 * lost to an attack by green Legion
5260 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5261 * last %s is either "and ..." or empty string */
5262 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5263 "%s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5264 "remaining%s]."),
5266 loser_link,
5267 pdefender->id,
5269 (float)def_power/POWER_FACTOR,
5273 punit->id,
5275 (float)att_power/POWER_FACTOR,
5276 att_hp_start - pwinner->hp,
5277 pwinner->hp,
5279 } else {
5282 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5283 * lost to an attack by the Greek green Legion
5284 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5285 * last %s is either "and ..." or empty string */
5286 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5287 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5288 "remaining%s]."),
5290 loser_link,
5291 pdefender->id,
5293 (float)def_power/POWER_FACTOR,
5298 punit->id,
5300 (float)att_power/POWER_FACTOR,
5301 att_hp_start - pwinner->hp,
5302 pwinner->hp,
5304 }
5305
5309 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5310 * lost 1 HP, has 9 HP remaining] succeeded against
5311 * green Warriors [id:100 HP:10]." */
5312 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5313 "has %d remaining] succeeded against %s %s "
5314 "[id:%d HP:%d]."),
5317 punit->id,
5320 (float)att_power/POWER_FACTOR,
5321 att_hp_start - pwinner->hp,
5322 pwinner->hp,
5324 loser_link,
5325 pdefender->id,
5326 def_hp_start);
5327 } else {
5330 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5331 * lost 1 HP, has 9 HP remaining] succeeded against the
5332 * Greek green Warriors [id:100 HP:10]." */
5333 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5334 "has %d remaining] succeeded against the %s %s %s "
5335 "[id:%d HP:%d]."),
5338 punit->id,
5341 (float)att_power/POWER_FACTOR,
5342 att_hp_start - pwinner->hp,
5343 pwinner->hp,
5346 loser_link,
5347 pdefender->id,
5348 def_hp_start);
5349 }
5350
5351 punit->moved = TRUE; /* We moved */
5352
5353 if (paction->result == ACTRES_COLLECT_RANSOM) {
5356 } else {
5359 }
5360
5361 /* Now that dead defender is certainly no longer listed as unit
5362 * supported by the city, we may even remove the city
5363 * (if it shrinks from size 1) */
5365 if (pcity != nullptr) {
5367 }
5368 if (unit_is_alive(winner_id)) {
5370 return TRUE;
5371 }
5372 } else {
5373 return TRUE;
5374 }
5375 }
5376
5377 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5378 * if there are enemy units in the tile (a fortress, city or air base with
5379 * multiple defenders and unstacked combat). Note that this could mean
5380 * capturing (or destroying) a city. */
5381
5382 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5384 }
5385
5386 /* The attacker may have died for many reasons */
5387 if (game_unit_by_number(winner_id) != nullptr) {
5388 send_unit_info(nullptr, pwinner);
5389 }
5390
5391 return TRUE;
5392}
5393
5394/**********************************************************************/
5405 struct unit *act_unit,
5406 struct city *tgt_city,
5407 const struct action *paction)
5408{
5409 struct player *tgt_player;
5410 char prod[256];
5411 const struct unit_type *act_utype;
5412 const struct tile *tgt_tile;
5413 const char *clink;
5414
5415 /* Sanity checks */
5420
5423
5425
5426 /* The surgical strike may miss. */
5427 {
5428 /* Roll the dice. */
5431 paction)) {
5432 /* Notify the player. */
5435 /* TRANS: unit, action, city */
5436 _("Your %s failed to do %s in %s."),
5440
5441 /* Make the failed attempt cost a single move. */
5442 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5443
5444 return FALSE;
5445 }
5446 }
5447
5448 /* Get name of the production */
5449 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5450
5451 /* Destroy the production */
5452 tgt_city->shield_stock = 0;
5454
5455 /* Let the players know. */
5456 clink = city_link(tgt_city); /* Be careful not to call city_link()
5457 * again as long as we need clink */
5460 _("Your %s succeeded in destroying"
5461 " the production of %s in %s."),
5463 prod, clink);
5466 _("The production of %s was destroyed in %s,"
5467 " %s are suspected."),
5468 prod, clink,
5470
5472
5473 /* May cause an incident */
5476 clink);
5477
5478 return TRUE;
5479}
5480
5481/**********************************************************************/
5492 struct unit *act_unit,
5493 struct city *tgt_city,
5495 const struct action *paction)
5496{
5497 struct player *tgt_player;
5499 const struct tile *tgt_tile;
5500 const struct unit_type *act_utype;
5501 const char *clink;
5502
5503 /* Sanity checks */
5508
5510
5513
5514 /* The surgical strike may miss. */
5515 {
5516 /* Roll the dice. */
5519 paction)) {
5520 /* Notify the player. */
5523 /* TRANS: unit, action, city */
5524 _("Your %s failed to do %s in %s."),
5528
5529 /* Make the failed attempt cost a single move. */
5530 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5531
5532 return FALSE;
5533 }
5534 }
5535
5537 /* Nothing to destroy here. */
5538
5539 /* Notify the player. */
5542 _("Your %s didn't find a %s to %s in %s."),
5547
5548 /* Punish the player for blindly attacking a building. */
5549 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5550
5551 return FALSE;
5552 }
5553
5555 /* Notify the player. */
5558 _("Your %s cannot do %s to %s in %s."),
5563
5564 /* Punish the player for blindly attacking a building. */
5565 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5566
5567 return FALSE;
5568 }
5569
5571
5572 /* Destroy the building. */
5573 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5574
5575 /* Update the player's view of the city. */
5576 send_city_info(nullptr, tgt_city);
5577
5578 /* Let the players know. */
5579 clink = city_link(tgt_city); /* Be careful not to call city_link()
5580 * again as long as we need clink */
5583 _("Your %s destroyed the %s in %s."),
5586 clink);
5589 _("The %s destroyed the %s in %s."),
5592 clink);
5593
5594 /* May cause an incident */
5597
5598 return TRUE;
5599}
5600
5601/**********************************************************************/
5611 struct unit *act_unit,
5612 struct city *tgt_city,
5613 struct action *paction)
5614{
5615 bool success;
5616 struct tile *tgt_tile = city_tile(tgt_city);
5617 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5618 int tgt_city_id = tgt_city->id;
5620 const char *victim_link = city_link(tgt_city);
5621
5622 /* Sanity check */
5624
5625 unit_move(act_unit, tgt_tile, move_cost, nullptr, FALSE, TRUE, TRUE,
5626 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5628
5629 /* The city may have been destroyed during the conquest. */
5632
5633 if (success) {
5634 const struct unit_type *act_utype = unit_type_get(act_unit);
5635
5636 /* May cause an incident */
5639 victim_link);
5640 }
5641
5642 return success;
5643}
5644
5645/**********************************************************************/
5649 struct tile *dest_tile,
5650 bool igzoc,
5651 struct unit *embark_to,
5652 bool enter_enemy_city)
5653{
5654 struct tile *src_tile = unit_tile(punit);
5657 src_tile, dest_tile, igzoc, TRUE, embark_to,
5659
5660 switch (reason) {
5661 case MR_OK:
5662 return TRUE;
5663
5664 case MR_NO_WAR:
5666 _("Cannot attack unless you declare war first."));
5667 break;
5668
5669 case MR_ZOC:
5671 _("%s can only move into your own zone of control."),
5672 unit_link(punit));
5673 break;
5674
5675 case MR_TRIREME:
5677 _("%s cannot move that far from the coast line."),
5678 unit_link(punit));
5679 break;
5680
5681 case MR_PEACE:
5682 if (tile_owner(dest_tile)) {
5684 _("Cannot invade unless you break peace with "
5685 "%s first."),
5686 player_name(tile_owner(dest_tile)));
5687 }
5688 break;
5689
5692 _("%s cannot disembark outside of a city or a native base "
5693 "for %s."),
5697 break;
5698
5699 case MR_NON_NATIVE_MOVE:
5701 _("Terrain is unsuitable for %s units."),
5703 break;
5704
5705 default:
5706 /* FIXME: need more explanations someday! */
5707 break;
5708 };
5709
5710 return FALSE;
5711}
5712
5713/**********************************************************************/
5720 struct unit *actor_unit,
5721 struct tile *target_tile,
5722 const struct action *paction)
5723{
5725 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5726
5727 unit_move(actor_unit, target_tile, move_cost,
5728 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
5729 /* Don't override "Conquer City" */
5730 FALSE,
5731 /* Don't override "Conquer Extras" */
5732 FALSE,
5733 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5735
5736 /* May cause an incident */
5740
5741 return TRUE;
5742}
5743
5744/**********************************************************************/
5758 bool move_do_not_act)
5759{
5760 struct player *pplayer = unit_owner(punit);
5761 struct unit *ptrans;
5762 const struct civ_map *nmap = &(wld.map);
5763
5764 /*** Phase 1: Attempted action interpretation checks ***/
5765
5766 /* Check if the move should be interpreted as an attempt to perform an
5767 * enabler controlled action to the target tile. When the move may be an
5768 * action attempt the server stops moving the unit, marks it as wanting a
5769 * decision based on its own movement to the tile it attempted to move to
5770 * and notifies the client.
5771 *
5772 * In response to the unit being marked as wanting a decision the client
5773 * can query the server for what actions the unit, given the player's
5774 * knowledge, may be able to perform against a target at the tile it tried
5775 * to move to. The server will respond to the query with the actions that
5776 * may be enabled and, when all actions are known to be illegal given the
5777 * player's knowledge, an explanation why no action could be done. The
5778 * client will probably use the list of potentially legal actions, if any,
5779 * to pop up an action selection dialog. See handle_unit_action_query()
5780 *
5781 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5782 * to perform an enabler controlled action.
5783 * Examples of where this is useful is for AI moves, goto, when the player
5784 * attempts to move to a tile occupied by potential targets like allied
5785 * cities or units and during rule forced moves.
5786 *
5787 * A move is not interpreted as an attempted action because the unit is
5788 * able to do a self targeted action.
5789 *
5790 * A move is not interpreted as an attempted action because an action
5791 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5792 * perform a regular move to the tile.
5793 *
5794 * An attempted move to a tile a unit can't move to is always interpreted
5795 * as trying to perform an action (unless move_do_not_act is TRUE) */
5796 if (!move_do_not_act) {
5799 FALSE, FALSE, FALSE);
5803 /* A legal action with an extra sub target is a legal action */
5805 /* Tile target actions with extra sub targets are handled above */
5807
5809 /* There is a target punit, from the player's point of view, may be
5810 * able to act against OR punit can't do any non action move. The
5811 * client should therefore ask what action(s) the unit can perform
5812 * to any targets at pdesttile.
5813 *
5814 * In the first case the unit needs a decision about what action, if
5815 * any at all, to take. Asking what actions the unit can perform
5816 * will return a list of actions that may, from the players point of
5817 * view, be possible. The client can then show this list to the
5818 * player or, if configured to do so, make the choice it self.
5819 *
5820 * In the last case the player may need an explanation about why no
5821 * action could be taken. Asking what actions the unit can perform
5822 * will provide this explanation. */
5826
5827 /* The move wasn't done because the unit wanted the player to
5828 * decide what to do or because the unit couldn't move to the
5829 * target tile. */
5830 return FALSE;
5831 }
5832 }
5833
5834 /*** Phase 2: OK now move the unit ***/
5835 /* This is a regular move, subject to the rules. */
5837 punit, pdesttile, nullptr)) {
5838 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5842 punit, pdesttile, nullptr)) {
5843 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5847 punit, pdesttile, nullptr)) {
5848 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5854 punit, ptrans)) {
5855 /* "Transport Embark". */
5856 return unit_perform_action(pplayer, punit->id, ptrans->id,
5862 punit, ptrans)) {
5863 /* "Transport Embark 2". */
5864 return unit_perform_action(pplayer, punit->id, ptrans->id,
5870 punit, ptrans)) {
5871 /* "Transport Embark 3". */
5872 return unit_perform_action(pplayer, punit->id, ptrans->id,
5878 punit, ptrans)) {
5879 /* "Transport Embark 4". */
5880 return unit_perform_action(pplayer, punit->id, ptrans->id,
5884 punit, pdesttile, nullptr)) {
5885 /* "Transport Disembark". */
5886 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5890 punit, pdesttile, nullptr)) {
5891 /* "Transport Disembark 2". */
5892 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5896 punit, pdesttile, nullptr)) {
5897 /* "Transport Disembark 3". */
5898 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5902 punit, pdesttile, nullptr)) {
5903 /* "Transport Disembark 4". */
5904 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5908 punit, pdesttile, nullptr)) {
5909 /* "Enter Hut". */
5910 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5914 punit, pdesttile, nullptr)) {
5915 /* "Enter Hut 2". */
5916 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5920 punit, pdesttile, nullptr)) {
5921 /* "Frighten Hut". */
5922 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5926 punit, pdesttile, nullptr)) {
5927 /* "Frighten Hut 2". */
5928 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5931 } else {
5932 /* TODO: Extend the action not enabled explanation system to cover all
5933 * existing reasons and switch to using it. See hrm Feature #920229 */
5935 nullptr, FALSE);
5936 return FALSE;
5937 }
5938}
5939
5940/**********************************************************************/
5950static bool unit_do_help_build(struct player *pplayer,
5951 struct unit *punit,
5952 struct city *pcity_dest,
5953 const struct action *paction)
5954{
5955 const char *work;
5956 const char *prod;
5957 int shields;
5958 const struct unit_type *act_utype;
5959 struct player *cowner;
5960
5961 /* Sanity check: The actor still exists. */
5962 fc_assert_ret_val(pplayer, FALSE);
5964
5965 /* Sanity check: The target city still exists. */
5967
5970
5972 /* Add the caravan shields */
5973 pcity_dest->shield_stock += shields;
5974
5975 /* Will be punished for changing production to something that can't
5976 * receive "Help Wonder" help. */
5978 &pcity_dest->production));
5979 pcity_dest->caravan_shields += shields;
5980 } else {
5982 /* Add the shields from recycling the unit to the city's current
5983 * production. */
5984 pcity_dest->shield_stock += shields;
5985
5986 /* If we change production later at this turn. No penalty is added. */
5987 pcity_dest->disbanded_shields += shields;
5988 }
5989
5991
5992 conn_list_do_buffer(cowner->connections);
5993
5995 /* Let the player that just donated shields with "Help Wonder" know
5996 * the result of their donation. */
5998 } else {
6000 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
6001 * current production in Bergen (4 surplus).
6002 * "Disband Unit Recover" says "current production" rather than its name. */
6003 prod = _("current production");
6004 }
6005
6006 if (build_points_left(pcity_dest) >= 0) {
6007 /* TRANS: Your Caravan does "Help Wonder" to help build the
6008 * Pyramids in Bergen (4 remaining).
6009 * You can reorder '4' and 'remaining' in the actual format string. */
6010 work = _("remaining");
6011 } else {
6012 /* TRANS: Your Caravan does "Help Wonder" to help build the
6013 * Pyramids in Bergen (4 surplus).
6014 * You can reorder '4' and 'surplus' in the actual format string. */
6015 work = _("surplus");
6016 }
6017
6019 ftc_server,
6020 /* TRANS: Your Caravan does "Help Wonder" to help build the
6021 * Pyramids in Bergen (4 surplus). */
6022 _("Your %s does %s to help build the %s in %s (%d %s)."),
6025 prod,
6028 work);
6029
6030 /* May cause an incident */
6033
6034 if (cowner != unit_owner(punit)) {
6035 /* Tell the city owner about the gift they just received. */
6036
6039 /* TRANS: Help building the Pyramids in Bergen received
6040 * from Persian Caravan (4 surplus). */
6041 _("Help building the %s in %s received from %s %s "
6042 "(%d %s)."),
6048 work);
6049 }
6050
6053 conn_list_do_unbuffer(cowner->connections);
6054
6055 return TRUE;
6056}
6057
6058/**********************************************************************/
6065static bool do_unit_establish_trade(struct player *pplayer,
6066 struct unit *punit,
6067 struct city *pcity_dest,
6068 const struct action *paction)
6069{
6072 int revenue;
6073 bool can_establish;
6074 int home_overbooked = 0;
6075 int dest_overbooked = 0;
6076 int home_max;
6077 int dest_max;
6078 struct city *pcity_homecity;
6081 enum trade_route_bonus_type bonus_type;
6082 struct goods_type *goods;
6083 const char *goods_str;
6084 const struct unit_type *act_utype;
6085
6086 /* Sanity check: The actor still exists. */
6087 fc_assert_ret_val(pplayer, FALSE);
6089
6090 /* Sanity check: The target city still exists. */
6092
6094
6095 if (!pcity_homecity) {
6097 _("Sorry, your %s cannot establish"
6098 " a trade route because it has no home city."),
6099 unit_link(punit));
6100 return FALSE;
6101 }
6102
6104
6105 if (goods == nullptr) {
6107 _("Sorry, your %s cannot establish"
6108 " a trade route because it's not carrying any goods."),
6109 unit_link(punit));
6110 return FALSE;
6111 }
6112
6115
6118 _("Sorry, your %s cannot establish"
6119 " a trade route between %s and %s."),
6123 return FALSE;
6124 }
6125
6127
6131
6132 /* This part of code works like can_establish_trade_route(), except
6133 * that we actually do the action of making the trade route. */
6134
6135 /* If we can't make a new trade route we can still get the trade bonus. */
6138
6139 if (can_establish) {
6144 }
6145
6146 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
6148
6149 /* See if there's a trade route we can cancel at the home city. */
6150 if (home_overbooked >= 0) {
6151 if (home_max <= 0
6154 >= trade)) {
6157 _("Sorry, your %s cannot establish"
6158 " a trade route here!"),
6159 punit_link);
6160 if (home_max > 0) {
6163 PL_(" The city of %s already has %d "
6164 "better trade route!",
6165 " The city of %s already has %d "
6166 "better trade routes!", home_max),
6168 home_max);
6169 }
6171 }
6172 }
6173
6174 /* See if there's a trade route we can cancel at the dest city. */
6175 if (can_establish && dest_overbooked >= 0) {
6176 if (dest_max <= 0
6179 >= trade)) {
6182 _("Sorry, your %s cannot establish"
6183 " a trade route here!"),
6184 punit_link);
6185 if (dest_max > 0) {
6188 PL_(" The city of %s already has %d "
6189 "better trade route!",
6190 " The city of %s already has %d "
6191 "better trade routes!", dest_max),
6193 dest_max);
6194 }
6196 }
6197 }
6198 }
6199
6200 /* We now know for sure whether we can establish a trade route. */
6201
6202 /* Calculate and announce initial revenue. */
6203 revenue
6206
6207 bonus_type = trade_route_settings_by_type
6209
6211
6213
6214 /* We want to keep the bonus type string as the part of the format of the PL_() strings
6215 * for supporting proper pluralization for it. */
6216 switch (bonus_type) {
6217 case TBONUS_NONE:
6220 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
6221 _("Your %s from %s has arrived in %s carrying %s."),
6222 punit_link,
6225 goods_str);
6226 break;
6227 case TBONUS_GOLD:
6230 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6231 PL_("Your %s from %s has arrived in %s carrying %s,"
6232 " and revenues amount to %d in gold.",
6233 "Your %s from %s has arrived in %s carrying %s,"
6234 " and revenues amount to %d in gold.",
6235 revenue),
6236 punit_link,
6239 goods_str,
6240 revenue);
6241 break;
6242 case TBONUS_SCIENCE:
6245 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6246 PL_("Your %s from %s has arrived in %s carrying %s,"
6247 " and revenues amount to %d in research.",
6248 "Your %s from %s has arrived in %s carrying %s,"
6249 " and revenues amount to %d in research.",
6250 revenue),
6251 punit_link,
6254 goods_str,
6255 revenue);
6256 break;
6257 case TBONUS_BOTH:
6260 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6261 PL_("Your %s from %s has arrived in %s carrying %s,"
6262 " and revenues amount to %d in gold and research.",
6263 "Your %s from %s has arrived in %s carrying %s,"
6264 " and revenues amount to %d in gold and research.",
6265 revenue),
6266 punit_link,
6269 goods_str,
6270 revenue);
6271 break;
6272 }
6273
6274 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6275 pplayer->economic.gold += revenue;
6276
6277 send_player_info_c(pplayer, pplayer->connections);
6278 }
6279
6280 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6281 /* add bulbs and check for finished research */
6282 update_bulbs(pplayer, revenue, TRUE, TRUE);
6283
6284 /* Inform everyone about tech changes */
6285 send_research_info(research_get(pplayer), nullptr);
6286 }
6287
6288 if (can_establish) {
6289 struct city_list *cities_out_of_home;
6290 struct city_list *cities_out_of_dest;
6291 struct player *partner_player;
6292
6293 /* Announce creation of trade route (it's not actually created until
6294 * later in this function, as we have to cancel existing routes, but
6295 * it makes more sense to announce in this order) */
6296
6298
6299 /* Always tell the unit owner */
6300 notify_player(pplayer, nullptr,
6302 _("New trade route established from %s to %s."),
6305 if (pplayer != partner_player) {
6308 _("The %s established a trade route between their "
6309 "city %s and %s."),
6310 nation_plural_for_player(pplayer),
6313 }
6314
6317
6318 /* Now cancel any less profitable trade route from the home city. */
6320 struct trade_route *pback;
6321
6323
6325 free(premove);
6326 free(pback);
6328
6329 /* And the same for the dest city. */
6331 struct trade_route *pback;
6332
6334
6336 free(premove);
6337 free(pback);
6339
6341
6342 /* Refresh the cities. */
6351
6352 /* Notify the owners of the cities. */
6361
6362 /* Notify each player about the other's cities. */
6363 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6367 send_city_info(pplayer, pcity_dest);
6368 }
6369
6374 }
6375 if (pplayer != city_owner(pcity)) {
6376 send_city_info(pplayer, pcity);
6378 }
6380
6385 }
6386 if (pplayer != city_owner(pcity)) {
6387 send_city_info(pplayer, pcity);
6389 }
6391
6394 }
6395
6396 /* May cause an incident */
6398 pplayer, act_utype, city_owner(pcity_dest),
6401
6403
6404 /* Free data. */
6407
6408 return TRUE;
6409}
6410
6411/**********************************************************************/
6415void create_trade_route(struct city *from, struct city *to,
6416 struct goods_type *goods)
6417{
6419
6420 /* Actually create the new trade route */
6421 proute_from = fc_malloc(sizeof(struct trade_route));
6422 proute_from->partner = to->id;
6423 proute_from->goods = goods;
6424
6425 proute_to = fc_malloc(sizeof(struct trade_route));
6426 proute_to->partner = from->id;
6427 proute_to->goods = goods;
6428
6432 } else {
6433 proute_from->dir = RDIR_FROM;
6434 proute_to->dir = RDIR_TO;
6435 }
6438}
6439
6440/**********************************************************************/
6448void handle_unit_sscs_set(struct player *pplayer,
6449 int unit_id,
6451 int value)
6452{
6453 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6454 const struct civ_map *nmap = &(wld.map);
6455
6456 if (punit == nullptr) {
6457 /* Being asked to unqueue a "spent" unit because the client haven't
6458 * been told that it's gone is expected. */
6459 if (type != USSDT_UNQUEUE) {
6460 /* Probably died or bribed. */
6461 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6462 }
6463
6464 return;
6465 }
6466
6467 switch (type) {
6468 case USSDT_QUEUE:
6469 /* Reminds the client to ask the server about what actions the unit can
6470 * perform against the target tile. Action decision state can be set by
6471 * the server it self too. */
6472
6473 if (index_to_tile(nmap, value) == nullptr) {
6474 /* Asked to be reminded to ask what actions the unit can do to a non
6475 * existing target tile. */
6476 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6477 value, unit_id);
6478 break;
6479 }
6480
6483
6484 /* Let the client know that this unit needs the player to decide
6485 * what to do. */
6487
6488 break;
6489 case USSDT_UNQUEUE:
6490 /* Delete the reminder for the client to ask the server about what
6491 * actions the unit can perform against a certain target tile.
6492 * Action decision state can be set by the server it self too. */
6493
6495 punit->action_decision_tile = nullptr;
6496
6497 /* Let the client know that this unit no longer needs the player to
6498 * decide what to do. */
6499 send_unit_info(pplayer->connections, punit);
6500
6501 break;
6502 case USSDT_BATTLE_GROUP:
6503 /* Battlegroups are handled entirely by the client, so all we have to
6504 do here is save the battlegroup ID so that it'll be persistent. */
6505
6507
6508 break;
6509 case USSDT_SENTRY:
6510 if (value == 0) {
6511 if (punit->activity != ACTIVITY_SENTRY) {
6512 return;
6513 }
6514
6516 /* Impossible to set to Idle? */
6518 }
6519 } else if (value == 1) {
6522 return;
6523 }
6524
6526 /* Should have been caught above */
6528 }
6529 } else {
6530 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6532 }
6533 break;
6534 }
6535}
6536
6537/**********************************************************************/
6540static void unit_plans_clear(struct unit *punit)
6541{
6542 /* Remove city spot reservations for AI settlers on city founding
6543 * mission. */
6544 adv_unit_new_task(punit, AUT_NONE, nullptr);
6545
6546 /* Get rid of old orders. */
6548
6549 /* Make sure that no old goto_tile remains. */
6550 punit->goto_tile = nullptr;
6551}
6552
6553/**********************************************************************/
6557 int unit_id,
6559{
6560 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6561
6562 if (punit == nullptr) {
6563 /* Probably died or bribed. */
6564 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6565 unit_id);
6566 return;
6567 }
6568
6570 /* Client error. */
6571 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6572 agent);
6573 return;
6574 }
6575
6576 /* Set the state or exit */
6577 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6578 return;
6579 }
6580
6581 /* Give the new agent a blank slate */
6583
6584 if (agent == SSA_AUTOEXPLORE) {
6586 /* Should have been caught above */
6589 }
6590
6591 /* Exploring is handled here explicitly, since the player expects to
6592 * see an immediate response from setting a unit to auto-explore.
6593 * Handling it deeper in the code leads to some tricky recursive loops -
6594 * see PR#2631. */
6595 if (punit->moves_left > 0) {
6597 }
6598 }
6599}
6600
6601/**********************************************************************/
6606 struct unit *punit,
6608{
6609 const struct civ_map *nmap = &(wld.map);
6610
6611 /* Check that the agent can be activated for this unit. */
6612 switch (agent) {
6613 case SSA_AUTOWORKER:
6615 return FALSE;
6616 }
6617 break;
6618 case SSA_AUTOEXPLORE:
6621 return FALSE;
6622 }
6623 break;
6624 case SSA_NONE:
6625 /* Always possible. */
6626 break;
6627 case SSA_COUNT:
6629 break;
6630 }
6631
6632 if (punit->ssa_controller != agent) {
6634 send_unit_info(nullptr, punit);
6635 }
6636
6637 return TRUE;
6638}
6639
6640/**********************************************************************/
6646 struct extra_type *old_target)
6647{
6648 switch (punit->activity) {
6649 case ACTIVITY_IDLE:
6650 switch (old_activity) {
6651 case ACTIVITY_PILLAGE:
6652 {
6653 if (old_target != nullptr) {
6655 if (punit2->activity == ACTIVITY_PILLAGE) {
6656 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6657 if (pdep == old_target) {
6659 send_unit_info(nullptr, punit2);
6660 break;
6661 }
6663 }
6665 }
6666 break;
6667 }
6668 case ACTIVITY_EXPLORE:
6669 /* Restore unit's control status */
6671 break;
6672 default:
6673 ; /* Do nothing */
6674 }
6675 break;
6676 case ACTIVITY_EXPLORE:
6679 send_unit_info(nullptr, punit);
6680 break;
6681 default:
6682 /* Do nothing */
6683 break;
6684 }
6685}
6686
6687/**********************************************************************/
6703
6704/**********************************************************************/
6710{
6711 const struct civ_map *nmap = &(wld.map);
6712
6713 /* Must specify target for ACTIVITY_BASE */
6716
6718 struct extra_type *target = nullptr;
6719
6720 /* Assume untargeted pillaging if no target specified */
6724 trigger_action)) {
6727 }
6728
6729 return TRUE;
6730}
6731
6732/**********************************************************************/
6741{
6742 const struct civ_map *nmap = &(wld.map);
6743
6745 trigger_action)) {
6746 return FALSE;
6747 } else {
6750
6752 send_unit_info(nullptr, punit);
6754
6755 return TRUE;
6756 }
6757}
6758
6759/**********************************************************************/
6779
6780/**********************************************************************/
6785 struct extra_type **new_target,
6787{
6788 const struct civ_map *nmap = &(wld.map);
6789
6794 *new_target)) {
6796
6798
6799 if (list != nullptr && action_list_size(list) > 0) {
6800 /* Trigger action system */
6802 (*new_target) != nullptr ? (*new_target)->id : NO_TARGET,
6804 } else {
6807 }
6808 }
6809
6810 return TRUE;
6811}
6812
6813/**********************************************************************/
6821 struct extra_type **new_target,
6823{
6824 const struct civ_map *nmap = &(wld.map);
6825
6828 *new_target)) {
6829 return FALSE;
6830 } else {
6834
6837 new_target);
6840 /* unit_assign_specific_activity_target() changed our target activity
6841 * (to ACTIVITY_IDLE in practice) */
6843 } else {
6846 send_unit_info(nullptr, punit);
6848
6850 /* Casus Belli for when the activity successfully begins. */
6851 /* TODO: is it more logical to change Casus_Belli_Complete to
6852 * Casus_Belli_Successful_Beginning and trigger it here? */
6858 }
6859 }
6860
6861 return TRUE;
6862 }
6863}
6864
6865/**********************************************************************/
6868void handle_unit_orders(struct player *pplayer,
6869 const struct packet_unit_orders *packet)
6870{
6871 int length = packet->length;
6872 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6873 const struct civ_map *nmap = &(wld.map);
6874 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6875 struct unit_order *order_list;
6876#ifdef FREECIV_DEBUG
6877 int i;
6878#endif
6879
6880 if (punit == nullptr) {
6881 /* Probably died or bribed. */
6882 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6883 return;
6884 }
6885
6886 if (0 > length || MAX_LEN_ROUTE < length) {
6887 /* Shouldn't happen */
6888 log_error("handle_unit_orders() invalid %s (%d) "
6889 "packet length %d (max %d)", unit_rule_name(punit),
6890 packet->unit_id, length, MAX_LEN_ROUTE);
6891 return;
6892 }
6893
6894 if (src_tile != unit_tile(punit)) {
6895 /* Failed sanity check. Usually this happens if the orders were sent
6896 * in the previous turn, and the client thought the unit was in a
6897 * different position than it's actually in. The easy solution is to
6898 * discard the packet. We don't send an error message to the client
6899 * here (though maybe we should?). */
6900 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6901 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6902 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6903 return;
6904 }
6905
6906 if (ACTIVITY_IDLE != punit->activity) {
6907 /* New orders implicitly abandon current activity */
6909 }
6910
6911 if (length) {
6912 order_list = create_unit_orders(nmap, length, packet->orders);
6913 if (!order_list) {
6914 log_error("received invalid orders from %s for %s (%d).",
6915 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6916 return;
6917 }
6918 }
6919
6920 /* This must be before old orders are freed. If this is
6921 * settlers on city founding mission, city spot reservation
6922 * from goto_tile must be freed, and free_unit_orders() loses
6923 * goto_tile information */
6924 adv_unit_new_task(punit, AUT_NONE, nullptr);
6925
6927 /* If we waited on a tile, reset punit->done_moving */
6928 punit->done_moving = (punit->moves_left <= 0);
6929
6930 if (length == 0) {
6932 send_unit_info(nullptr, punit);
6933 return;
6934 }
6935
6937 punit->orders.length = length;
6938 punit->orders.index = 0;
6939 punit->orders.repeat = packet->repeat;
6940 punit->orders.vigilant = packet->vigilant;
6941 if (length) {
6943 }
6944
6945 if (!packet->repeat) {
6947 } else {
6948 /* Make sure that no old goto_tile remains. */
6949 punit->goto_tile = nullptr;
6950 }
6951
6952#ifdef FREECIV_DEBUG
6953 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6954 for (i = 0; i < length; i++) {
6955 log_debug(" %d,%s,%s,%d,%d",
6956 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6957 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6959 packet->orders[i].order == ORDER_ACTIVITY ?
6961 "no action/activity required",
6962 packet->orders[i].target,
6963 packet->orders[i].sub_target);
6964 }
6965#endif /* FREECIV_DEBUG */
6966
6968 || execute_orders(punit, TRUE)) {
6969 /* Looks like the unit survived. */
6970 send_unit_info(nullptr, punit);
6971 }
6972}
6973
6974/**********************************************************************/
6977void handle_worker_task(struct player *pplayer,
6978 const struct packet_worker_task *packet)
6979{
6980 struct city *pcity = game_city_by_number(packet->city_id);
6981 struct worker_task *ptask = nullptr;
6982 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
6983
6984 if (pcity == nullptr || pcity->owner != pplayer || ptile == nullptr) {
6985 return;
6986 }
6987
6989 if (tile_index(ptask_old->ptile) == packet->tile_id) {
6990 ptask = ptask_old;
6991 }
6993
6994 if (ptask == nullptr) {
6995 if (packet->activity == ACTIVITY_LAST) {
6996 return;
6997 }
6998
6999 ptask = fc_malloc(sizeof(struct worker_task));
7001 worker_task_list_append(pcity->task_reqs, ptask);
7002 } else {
7003 if (packet->activity == ACTIVITY_LAST) {
7004 worker_task_list_remove(pcity->task_reqs, ptask);
7005 free(ptask);
7006 ptask = nullptr;
7007 }
7008 }
7009
7010 if (ptask != nullptr) {
7011 ptask->ptile = ptile;
7012 ptask->act = packet->activity;
7013 if (packet->tgt >= 0) {
7014 if (packet->tgt < MAX_EXTRA_TYPES) {
7015 ptask->tgt = extra_by_number(packet->tgt);
7016 } else {
7017 log_debug("Illegal worker task target %d", packet->tgt);
7018 ptask->tgt = nullptr;
7019 }
7020 } else {
7021 ptask->tgt = nullptr;
7022 }
7023 ptask->want = packet->want;
7024 }
7025
7026 if (ptask && !worker_task_is_sane(ptask)) {
7027 log_debug("Bad worker task");
7028 worker_task_list_remove(pcity->task_reqs, ptask);
7029 free(ptask);
7030 ptask = nullptr;
7031
7032 return;
7033 }
7034
7035 lsend_packet_worker_task(pplayer->connections, packet);
7036}
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:5784
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:5306
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:4827
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:3257
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:7539
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:3333
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:4910
struct act_prob action_prob_self(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id)
Definition actions.c:4980
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:3092
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:3169
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:4469
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:5729
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:5002
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:4744
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:4552
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:105
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:143
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
void citizens_update(struct city *pcity, struct player *plr)
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1860
int city_granary_size(int city_size)
Definition city.c:2132
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
bool is_capital(const struct city *pcity)
Definition city.c:1579
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1465
void city_size_add(struct city *pcity, int add)
Definition city.c:1164
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2012
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2051
bool city_exist(int id)
Definition city.c:3612
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:771
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_owner(_pcity_)
Definition city.h:563
#define 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:3691
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3579
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:762
bool city_refresh(struct city *pcity)
Definition cityturn.c:158
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, Specialist_type_id sid, const char *reason)
Definition cityturn.c:1067
int city_growth_granary_savings(const struct city *pcity)
Definition cityturn.c:878
static struct fc_sockaddr_list * list
Definition clinet.c:102
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Definition combat.c:86
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:257
struct city * sdi_try_defend(const struct civ_map *nmap, const struct player *owner, const struct tile *ptile)
Definition combat.c:503
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:772
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:615
bool is_tired_attack(int moves_left)
Definition combat.c:532
enum unit_attack_result unit_wipe_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Definition combat.c:272
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
void get_modified_firepower(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, int *att_fp, int *def_fp)
Definition combat.c:411
#define POWER_FACTOR
Definition combat.h:32
@ ATT_NOT_WIPABLE
Definition combat.h:40
@ ATT_NONNATIVE_DST
Definition combat.h:39
@ ATT_OK
Definition combat.h:35
@ ATT_NON_ATTACK
Definition combat.h:36
@ ATT_UNREACHABLE
Definition combat.h:37
@ ATT_NONNATIVE_SRC
Definition combat.h:38
char * incite_cost
Definition comments.c:76
#define MAX_LEN_MSG
Definition conn_types.h:37
#define MAX_LEN_ROUTE
Definition conn_types.h:38
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c: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:371
#define extra_deps_iterate_end
Definition extras.h:379
#define EXTRA_NONE
Definition extras.h:85
#define NO_TARGET
Definition fc_types.h:214
int Impr_type_id
Definition fc_types.h:236
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:230
int action_id
Definition fc_types.h:249
int Specialist_type_id
Definition fc_types.h:235
#define ACTRES_NONE
Definition fc_types.h:187
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:67
int Unit_type_id
Definition fc_types.h:242
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:93
#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:715
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:1048
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:944
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:806
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:480
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:458
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:1237
const char * player_name(const struct player *pplayer)
Definition player.c:900
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1112
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1211
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1345
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1417
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1471
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1141
#define players_iterate_end
Definition player.h:542
#define players_iterate(_pplayer)
Definition player.h:537
int normal_player_count(void)
Definition plrhand.c:3209
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2963
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3008
struct conn_list * player_reply_dest(struct player *pplayer)
Definition plrhand.c:1595
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2915
#define fc_rand(_size)
Definition rand.h:56
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
#define requirement_fulfilled_by_unit_type(_ut_, _rqs_)
#define requirement_fulfilled_by_terrain(_ter_, _rqs_)
#define requirement_fulfilled_by_nation(_nat_, _rqs_)
struct research * research_get(const struct player *pplayer)
Definition research.c: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:241
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c: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:6783
#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:4198
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:3333
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4992
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4537
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:4365
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:6868
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:2526
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:5610
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:1411
#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:4416
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:6977
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:6707
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:3369
#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:5404
#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:3002
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:1967
static const char * unit_tired_attack_string(const struct unit *punit)
Definition unithand.c:4945
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:1369
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Definition unithand.c:6644
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3181
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4632
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5757
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:4819
#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:6556
void create_trade_route(struct city *from, struct city *to, struct goods_type *goods)
Definition unithand.c:6415
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:3349
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:1453
static bool do_action_activity(struct unit *punit, const struct action *paction)
Definition unithand.c:6693
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:6819
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:5491
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:4092
static bool tile_has_units_not_allied_to_but_seen_by(const struct tile *ptile, const struct player *pplayer)
Definition unithand.c:1351
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Definition unithand.c:6765
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:1315
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5950
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:4232
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:3200
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:4749
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:5648
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:2262
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Definition unithand.c:6448
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:4478
#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:4928
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:5719
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:6605
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:6065
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:6738
static void unit_plans_clear(struct unit *punit)
Definition unithand.c:6540
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4312
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4582
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:1947
#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)
static const char * unit_firepower_if_not_one(int firepower)
Definition unithand.c:4967
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4907
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:3122
#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