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 bool do_scout(struct unit *punit, struct tile *ptile,
181 const struct action *paction);
182static inline bool
183non_allied_not_listed_at(const struct player *pplayer,
184 const int *list, int n, const struct tile *ptile);
185
186/**********************************************************************/
190{
191 const struct unit_type *to_unittype;
195 const struct civ_map *nmap = &(wld.map);
196
197 if (from_unittype == nullptr) {
198 /* Probably died or bribed. */
199 log_verbose("handle_unit_type_upgrade() invalid unit type %d", uti);
200 return;
201 }
202
204 if (!to_unittype) {
205 notify_player(pplayer, nullptr, E_BAD_COMMAND, ftc_server,
206 _("Illegal packet, can't upgrade %s (yet)."),
208 return;
209 }
210
211 /*
212 * Try to upgrade units. The order we upgrade in is arbitrary (if
213 * the player really cared they should have done it manually).
214 */
216 unit_list_iterate(pplayer->units, punit) {
218 struct city *pcity = tile_city(unit_tile(punit));
219
221 && unit_perform_action(pplayer, punit->id, pcity->id, 0, "",
224 } else if (UU_NO_MONEY == unit_upgrade_test(nmap, punit, FALSE)) {
225 break;
226 }
227 }
230
231 /* Alert the player about what happened. */
232 if (number_of_upgraded_units > 0) {
233 const int cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
234
235 notify_player(pplayer, nullptr, E_UNIT_UPGRADED, ftc_server,
236 /* FIXME: plurality of number_of_upgraded_units ignored!
237 * (Plurality of unit names is messed up anyway.) */
238 /* TRANS: "2 Musketeers upgraded to Riflemen for 100 gold."
239 * Plurality is in gold (second %d), not units. */
240 PL_("%d %s upgraded to %s for %d gold.",
241 "%d %s upgraded to %s for %d gold.",
247 send_player_info_c(pplayer, pplayer->connections);
248 } else {
249 notify_player(pplayer, nullptr, E_UNIT_UPGRADED, ftc_server,
250 _("No units could be upgraded."));
251 }
252}
253
254/**********************************************************************/
260static bool do_unit_upgrade(struct player *pplayer,
261 struct unit *punit, struct city *pcity,
263 const struct action *paction)
264{
265 const struct unit_type *from_unit = unit_type_get(punit);
266 const struct unit_type *to_unit = can_upgrade_unittype(pplayer, from_unit);
267 int cost = unit_upgrade_price(pplayer, from_unit, to_unit);
268
270 pplayer->economic.gold -= cost;
271 send_player_info_c(pplayer, pplayer->connections);
272
273 if (ordered_by == ACT_REQ_PLAYER) {
275 PL_("%s upgraded to %s for %d gold.",
276 "%s upgraded to %s for %d gold.", cost),
279 cost);
280 }
281
282 return TRUE;
283}
284
285/**********************************************************************/
289static inline bool
290non_allied_not_listed_at(const struct player *pplayer,
291 const int *list, int n, const struct tile *ptile)
292{
293 unit_list_iterate(ptile->units, punit) {
294 if (!pplayers_allied(pplayer, unit_owner(punit))) {
295 bool listed = FALSE;
296 int id = punit->id;
297 int i;
298
299 for (i = 0; i < n; i++) {
300 if (id == list[i]) {
301 listed = TRUE;
302 break;
303 }
304 }
305 if (!listed) {
306 return TRUE;
307 }
308 }
310 return FALSE;
311}
312
313/**********************************************************************/
319static bool do_capture_units(struct player *pplayer,
320 struct unit *punit,
321 struct tile *pdesttile,
322 const struct action *paction)
323{
324 struct city *pcity;
326 char hcity_name[MAX_LEN_NAME] = {'\0'};
327 const char *capturer_nation = nation_plural_for_player(pplayer);
329 const struct unit_type *act_utype;
330 int id, hcity;
331 int n = 0, capt[unit_list_size(pdesttile->units)];
332 bool lost_with_city = FALSE;
333 int i;
334
335 /* Sanity check: The actor still exists. */
336 fc_assert_ret_val(pplayer, FALSE);
338 id = punit->id;
339
341
342 /* Sanity check: make sure that the capture won't result in the actor
343 * ending up with more than one unit of each unique unit type. */
346 bool unique_conflict = FALSE;
347
348 /* Check what the player already has. */
351 /* The player already has a unit of this kind. */
353 }
354
356 /* The type of the units at the tile must also be checked. Two allied
357 * players can both have their unique unit at the same tile.
358 * Capturing them both would give the actor two units of a kind that
359 * is supposed to be unique. */
360
362 /* There is another unit of the same kind at this tile. */
364 } else {
365 /* Remember the unit type in case another unit of the same kind is
366 * encountered later. */
368 }
369 }
370
371 if (unique_conflict) {
372 log_debug("capture units: already got unique unit");
374 /* TRANS: You can only have one Leader. */
375 _("You can only have one %s."),
377
378 return FALSE;
379 }
380 /* Remember the units here
381 * for the mess callbacks may do in the process of transferring */
382 capt[n++] = to_capture->id;
384
385 /* N.B: unit_link() always returns the same pointer. */
387
391 if (hcity) {
392 /* Rarely, we'll need it... */
394 }
395
396 for (i = 0; i < n; i++) {
398 struct player *uplayer;
399 const char *victim_link;
400 const struct unit_type *utype;
401 struct tile *ptile = nullptr;
402 bool really_lost = FALSE;
403
404 if (!to_capture) {
405 continue;
406 }
408 if (uplayer == pplayer) {
409 /* Somehow transferred by scripts (e.g. diplomat incited a city) */
410 continue;
411 }
412 utype = unit_type_get(to_capture);
414 uplayer->score.units_lost++;
415 if (!really_lost) {
416 /* A hack: if the captured unit is lost with a capturer's city,
417 * we link the old unit, otherwise the new one */
420 }
421 if (!to_capture) {
422 /* Lost during capturing */
424 } else {
425 /* As unit_change_owner() currently remove the old unit and
426 * replace by a new one (with a new id), we want to make link to
427 * the new unit. */
429 ptile = unit_tile(to_capture);
430 /* Notify capturer only if there is a gain */
432 /* TRANS: <unit> ... <unit> */
433 _("Your %s succeeded in capturing the %s %s."),
436 }
437
438 /* Notify loser */
441 /* TRANS: <unit> ... <Poles> */
442 _("Your %s was captured by the %s."),
444
445 /* May cause an incident */
448
449 if (really_lost) {
450 /* The city for which the unit was captured has perished! */
451 /* Nobody actually gets the unit. */
452 pplayer->score.units_lost++;
453 notify_player(pplayer, pdesttile,
455 _("%s lost along with control of %s."),
457 /* As in unit_change_owner(), don't say pplayer is killer */
459 continue;
460 }
461
462 if (to_capture != nullptr) {
464
465 if (pcity != nullptr /* Keep old behavior */
467 || (new_owner == pplayer
468 ? non_allied_not_listed_at(pplayer, capt + (i + 1),
469 n - (i + 1), ptile)
470 : (bool)
473 UTYF_FLAGLESS)))) {
474 /* The captured unit is in a city or with a foreign unit
475 * that its owner is not capturing. Bounce it. */
477 }
478 }
479
480 /* Check if the city we are going to home units in stays. */
481 if (hcity && i + 1 < n && !player_city_by_number(pplayer, hcity)) {
482 /* Oops, it's lost. Maybe the capturer is rehomed? */
483 if (player_unit_by_number(pplayer, id)) {
484 /* Well, it's natural to home them here now */
486 } else {
487 /* Removing the rest of the stack (except "NoHome" units) */
489 }
490 }
491 }
492
493 if (!unit_is_alive(id)) {
494 /* Callbacks took the capturer, nothing more to do */
495 return TRUE;
496 }
499
500 send_unit_info(nullptr, punit);
501
502 return TRUE;
503}
504
505/**********************************************************************/
508static bool occupy_move(struct tile *def_tile, struct unit *punit,
509 const struct action *paction)
510{
513 /* Hack: make sure the unit has enough moves_left for the move to succeed,
514 * and adjust moves_left to afterward (if successful). */
517 int id = punit->id;
518
520 /* Post attack occupy move. */
522 nullptr, nullptr, paction,
524 nullptr, nullptr) != nullptr) {
525 if (unit_is_alive(id)) {
526 int mcost = MAX(0, full_moves - punit->moves_left - SINGLE_MOVE);
527
528 /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
529 * Attack SINGLE_COST is already calculated in to old_moves. */
530 punit->moves_left = old_moves - mcost;
531 if (punit->moves_left < 0) {
532 punit->moves_left = 0;
533 }
534 } else {
535 return FALSE;
536 }
537 } else if (unit_is_alive(id)) {
539 } else {
540 return FALSE;
541 }
542 }
543
544 return TRUE;
545}
546
547/**********************************************************************/
553static bool do_wipe_units(struct unit *punit,
554 struct tile *pdesttile,
555 const struct action *paction)
556{
557 struct player *wiper = unit_owner(punit);
558 int wid = punit->id;
561 const struct unit_type *act_utype = unit_type_get(punit);
562
563 /* N.B: unit_link() always returns the same pointer. */
565
567 struct player *owner = unit_owner(to_wipe);
568 const char *victim_link = unit_link(to_wipe);
569
571
572 /* Notify players */
574 /* TRANS: <unit> ... <unit> */
575 _("Your %s wiped the %s %s."),
580 /* TRANS: <unit> ... <Poles> */
581 _("Your %s was wiped by the %s."),
583
584 /* May cause an incident */
587
589
593
594 send_unit_info(nullptr, punit);
595 }
596
597 return TRUE;
598}
599
600/**********************************************************************/
606static bool do_expel_unit(struct player *pplayer,
607 struct unit *actor,
608 struct unit *target,
609 const struct action *paction)
610{
612 struct player *uplayer;
613 struct tile *target_tile;
614 struct city *pcity;
615 const struct unit_type *act_utype;
616
617 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
618 * the caller? Check in the code that emits the signal. */
619 fc_assert_ret_val(target, FALSE);
620
621 uplayer = unit_owner(target);
622
623 /* A unit is supposed to have an owner. */
625
626 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
627 * the caller? Check in the code that emits the signal. */
630
631 /* Where is the actor player? */
632 fc_assert_ret_val(pplayer, FALSE);
633
634 target_tile = unit_tile(target);
635
636 /* Expel the target unit to its owner's primary capital. */
637 /* TODO: Could be also nearest secondary capital */
639
640 /* N.B: unit_link() always returns the same pointer. */
642
643 if (pcity == nullptr) {
644 /* No where to send the expelled unit. */
645
646 /* The price of failing an expulsion is a single move. */
648 send_unit_info(nullptr, actor);
649
650 /* Notify the actor player. */
652 /* TRANS: <Poles> <Spy> */
653 _("The %s don't have a capital to expel their %s to."),
655
656 /* Nothing more could be done. */
657 return FALSE;
658 }
659
660 /* Please review the code below and above (including the strings sent to
661 * the players) before allowing expulsion to non capital cities. */
663
664 /* Notify everybody involved. */
666 /* TRANS: <Border Patrol> ... <Spy> */
667 _("Your %s succeeded in expelling the %s %s."),
671 /* TRANS: <unit> ... <Poles> */
672 _("Your %s was expelled by the %s."),
674
675 /* Being expelled destroys all remaining movement. */
676 if (!teleport_unit_to_city(target, pcity, 0, FALSE)) {
677 log_error("Bug in unit expulsion: unit can't teleport.");
678
679 return FALSE;
680 }
681
682 /* This may cause a diplomatic incident */
685
686 /* Mission accomplished. */
687 return TRUE;
688}
689
690/**********************************************************************/
697 struct unit *act_unit,
698 struct tile *tgt_tile,
699 const struct action *paction)
700{
701 bool success;
702 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
704
705 /* Sanity check */
708
709 unit_move(act_unit, tgt_tile, move_cost,
710 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
711 FALSE, TRUE,
714
716
717 if (success) {
718 const struct unit_type *act_utype = unit_type_get(act_unit);
719
720 /* May cause an incident */
724 }
725
726 return success;
727}
728
729/**********************************************************************/
735static bool do_heal_unit(struct player *act_player,
736 struct unit *act_unit,
737 struct unit *tgt_unit,
738 const struct action *paction)
739{
740 int healing_limit;
741 int tgt_hp_max;
742 struct player *tgt_player;
743 struct tile *tgt_tile;
746 const char *tgt_unit_owner;
747 const struct unit_type *act_utype;
748
749 /* Sanity checks: got all the needed input. */
753
755
756 /* The target unit can't have more HP than this. */
758
759 /* Sanity check: target isn't at full health and can therefore can be
760 * healed. */
762
763 /* Fetch the target unit's owner. */
766
767 /* Fetch the target unit's tile. */
770
771 /* The max amount of HP that can be added. */
773 nullptr,
774 &(const struct req_context) {
775 .player = unit_owner(act_unit),
776 .city = tile_city(unit_tile(act_unit)),
778 .unit = act_unit,
779 .unittype = unit_type_get(act_unit),
780 .action = paction,
781 },
782 &(const struct req_context) {
783 .player = unit_owner(tgt_unit),
784 .city = tile_city(unit_tile(tgt_unit)),
786 .unit = tgt_unit,
787 .unittype = unit_type_get(tgt_unit),
788 },
790 ) + 100)
791 * tgt_hp_max) / 100;
792
793 /* Heal the target unit. */
795 send_unit_info(nullptr, tgt_unit);
796
797 send_unit_info(nullptr, act_unit);
798
799 /* Every call to unit_link() overwrites the previous. Two units are being
800 * linked to. */
803
804 /* Notify everybody involved. */
805 if (act_player == tgt_player) {
806 /* TRANS: used instead of nation adjective when the nation is
807 * domestic. */
808 tgt_unit_owner = _("your");
809 } else {
811 }
812
814 /* TRANS: If foreign: Your Leader heals Finnish Warrior.
815 * If domestic: Your Leader heals your Warrior. */
816 _("Your %s heals %s %s."),
818
819 if (act_player != tgt_player) {
821 /* TRANS: Norwegian ... Leader ... Warrior */
822 _("%s %s heals your %s."),
825 }
826
827 /* This may have diplomatic consequences. */
830
831 return TRUE;
832}
833
834/**********************************************************************/
841 struct unit *act_unit,
842 struct unit *tgt_unit,
843 const struct action *paction)
844{
845 /* Unload the unit and send out info to clients. */
847
848 return TRUE;
849}
850
851/**********************************************************************/
859static bool do_unit_board(struct player *act_player,
860 struct unit *act_unit,
861 struct unit *tgt_unit,
862 const struct action *paction)
863{
866 }
867
868 /* Load the unit and send out info to clients. */
870
871 return TRUE;
872}
873
874/**********************************************************************/
882static bool do_unit_load(struct player *act_player,
883 struct unit *act_unit,
884 struct unit *tgt_unit,
885 const struct action *paction)
886{
889 }
890
891 /* Load the unit and send out info to clients. */
893
894 return TRUE;
895}
896
897/**********************************************************************/
903static bool do_unit_unload(struct player *act_player,
904 struct unit *act_unit,
905 struct unit *tgt_unit,
906 const struct action *paction)
907{
908 /* Unload the unit and send out info to clients. */
910
911 return TRUE;
912}
913
914/**********************************************************************/
920static bool do_disembark(struct player *act_player,
921 struct unit *act_unit,
922 struct tile *tgt_tile,
923 const struct action *paction)
924{
925 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
926
927 /* Sanity checks */
932
933 unit_move(act_unit, tgt_tile, move_cost,
934 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
935 FALSE, FALSE,
938
939 return TRUE;
940}
941
942/**********************************************************************/
948static bool do_unit_hut(struct player *act_player,
949 struct unit *act_unit,
950 struct tile *tgt_tile,
951 const struct action *paction)
952{
953 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
954
955 /* Sanity checks */
960
961 unit_move(act_unit, tgt_tile, move_cost,
962 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
963 FALSE, FALSE,
966
967 return TRUE;
968}
969
970/**********************************************************************/
978static bool do_unit_embark(struct player *act_player,
979 struct unit *act_unit,
980 struct unit *tgt_unit,
981 const struct action *paction)
982{
983 struct tile *tgt_tile;
984 int move_cost;
985
986 /* Sanity checks */
991
993 /* Assumed to be legal. */
995 }
996
997 /* Do it. */
999 move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
1000 unit_move(act_unit, tgt_tile, move_cost,
1001 tgt_unit, BV_ISSET(paction->sub_results,
1003 FALSE, FALSE,
1004 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
1006
1007 return TRUE;
1008}
1009
1010/**********************************************************************/
1016 const struct action *paction)
1017{
1019
1021}
1022
1023/**********************************************************************/
1030static bool rel_may_become_war(const struct player *pplayer,
1031 const struct player *oplayer)
1032{
1033 enum diplstate_type ds;
1034
1035 fc_assert_ret_val(pplayer, FALSE);
1037
1038 ds = player_diplstate_get(pplayer, oplayer)->type;
1039
1040 /* The player can't declare war on
1041 * someone they already are at war with. */
1042 return ds != DS_WAR
1043 /* The player can't declare war on a teammate or on themself. */
1044 && ds != DS_TEAM && pplayer != oplayer;
1045}
1046
1047/**********************************************************************/
1053static bool
1055 const struct action *paction,
1056 struct player *player1,
1057 struct player *player2,
1058 bool act_if_diplrel_kind(const struct unit_type *,
1059 const action_id,
1060 const int,
1061 const bool))
1062{
1063 if (player2 == nullptr) {
1064 /* No one to declare war on */
1065 return FALSE;
1066 }
1067
1069 /* Can't declare war. */
1070 return FALSE;
1071 }
1072
1075 player2)->type,
1076 TRUE)) {
1077 /* The current diplrel isn't the problem. */
1078 return FALSE;
1079 }
1080
1082 /* War won't make this action legal. */
1083 return FALSE;
1084 }
1085
1086 return TRUE;
1087}
1088
1089/**********************************************************************/
1095static struct player *need_war_player_hlp(const struct unit *actor,
1096 const action_id act,
1097 const struct tile *target_tile,
1098 const struct city *target_city,
1099 const struct unit *target_unit)
1100{
1101 struct player *target_player = nullptr;
1103 struct action *paction = action_by_number(act);
1104
1105 fc_assert_ret_val(paction != nullptr, nullptr);
1106
1107 if (action_id_get_actor_kind(act) != AAK_UNIT) {
1108 /* No unit can ever do this action so it isn't relevant. */
1109 return nullptr;
1110 }
1111
1112 if (!unit_can_do_action(actor, act)) {
1113 /* The unit can't do the action no matter if there is war or not. */
1114 return nullptr;
1115 }
1116
1117 /* Look for hard coded war requirements without support for looking up in
1118 * an action enabler requirement. */
1119 switch (paction->result) {
1120 case ACTRES_ATTACK:
1121 case ACTRES_WIPE_UNITS:
1124 /* Target is a unit stack but a city can block it. */
1126
1128 if (target_tile != nullptr) {
1129 struct city *tcity;
1130
1131 if ((tcity = tile_city(target_tile))
1133 return city_owner(tcity);
1134 }
1135 }
1136 }
1137 break;
1138
1139 case ACTRES_PARADROP:
1141 /* Target is a tile but a city can block it. */
1143
1144 if (target_tile != nullptr
1146 /* Seen tile unit savers */
1147
1148 struct city *tcity;
1149
1151 return city_owner(tcity);
1152 }
1153 }
1154 break;
1158 case ACTRES_SPY_POISON:
1167 case ACTRES_TRADE_ROUTE:
1168 case ACTRES_MARKETPLACE:
1169 case ACTRES_HELP_WONDER:
1172 case ACTRES_CAPTURE_UNITS: /* Only foreign is a hard req. */
1173 case ACTRES_FOUND_CITY:
1174 case ACTRES_JOIN_CITY:
1175 case ACTRES_STEAL_MAPS:
1176 case ACTRES_SPY_NUKE:
1177 case ACTRES_NUKE:
1178 case ACTRES_NUKE_UNITS:
1180 case ACTRES_EXPEL_UNIT:
1183 case ACTRES_HOME_CITY:
1184 case ACTRES_HOMELESS:
1186 case ACTRES_AIRLIFT:
1187 case ACTRES_HEAL_UNIT:
1190 case ACTRES_BOMBARD:
1193 case ACTRES_CULTIVATE:
1194 case ACTRES_PLANT:
1195 case ACTRES_PILLAGE:
1196 case ACTRES_CLEAN:
1197 case ACTRES_FORTIFY:
1198 case ACTRES_CONVERT:
1199 case ACTRES_ROAD:
1200 case ACTRES_BASE:
1201 case ACTRES_MINE:
1202 case ACTRES_IRRIGATE:
1209 case ACTRES_SPY_ATTACK:
1210 case ACTRES_HUT_ENTER:
1212 case ACTRES_UNIT_MOVE:
1213 case ACTRES_TELEPORT:
1215 case ACTRES_SCOUT:
1217 case ACTRES_SPY_ESCAPE:
1218 case ACTRES_NONE:
1219 /* No special help. */
1220 break;
1221
1223 }
1224
1225 /* Look for war requirements from the action enablers. */
1227 case ATK_CITY:
1228 if (target_city == nullptr) {
1229 /* No target city. */
1230 return nullptr;
1231 }
1232
1234 break;
1235 case ATK_UNIT:
1236 if (target_unit == nullptr) {
1237 /* No target unit. */
1238 return nullptr;
1239 }
1241 /* Target unit is flagless anyway - no war needed */
1242 return nullptr;
1243 }
1244
1246 break;
1247 case ATK_STACK:
1248 if (target_tile == nullptr) {
1249 /* No target units since no target tile. */
1250 return nullptr;
1251 }
1252
1253 unit_list_iterate(target_tile->units, tunit) {
1256 target_player = unit_owner(tunit);
1257 break;
1258 }
1260 break;
1261 case ATK_TILE:
1262 if (target_tile == nullptr) {
1263 /* No target tile. */
1264 return nullptr;
1265 }
1267 break;
1268 case ATK_EXTRAS:
1269 if (target_tile == nullptr) {
1270 /* No target tile. */
1271 return nullptr;
1272 }
1274 break;
1275 case ATK_SELF:
1276 /* Can't declare war on itself. */
1277 return nullptr;
1278 break;
1279 case ATK_COUNT:
1280 /* Nothing to check. */
1282 return nullptr;
1283 }
1284
1285 if (target_player == nullptr) {
1286 /* Declaring war won't enable the specified action. */
1287 return nullptr;
1288 }
1289
1290 /* Look for DiplRelTileOther war requirements from the action enablers. */
1291 if (target_tile != nullptr
1295 return tile_owner(target_tile);
1296 }
1297
1298 /* Look for DiplRel war requirements from the action enablers. */
1302 return target_player;
1303 }
1304
1305 /* No check if other, non war, diplomatic states also could make the
1306 * action legal. This is need_war_player() so war is always the answer.
1307 * If you disagree and decide to add support please check that
1308 * rules like former webperimental ruleset's
1309 * "can't found a city on a tile belonging to a non enemy"
1310 * are still detected. */
1311
1312 return nullptr;
1313}
1314
1315/**********************************************************************/
1320static struct player *need_war_player(const struct unit *actor,
1321 const action_id act_id,
1322 const struct tile *target_tile,
1323 const struct city *target_city,
1324 const struct unit *target_unit)
1325{
1326 if (act_id == ACTION_ANY) {
1327 /* Any action at all will do. */
1328 action_iterate(act) {
1329 struct player *war_player;
1330
1333 target_unit);
1334
1335 if (war_player != nullptr) {
1336 /* Declaring war on this player may enable this action. */
1337 return war_player;
1338 }
1340
1341 /* No action at all may be enabled by declaring war. */
1342 return nullptr;
1343 } else {
1344 /* Look for the specified action. */
1345 return need_war_player_hlp(actor, act_id,
1347 target_unit);
1348 }
1349}
1350
1351/**********************************************************************/
1355static bool
1357 const struct player *pplayer)
1358{
1359 unit_list_iterate(ptile->units, pother) {
1360 if (can_player_see_unit(pplayer, pother)
1361 && !pplayers_allied(pplayer, unit_owner(pother))) {
1362 return TRUE;
1363 }
1365
1366 return FALSE;
1367}
1368
1369/**********************************************************************/
1374static bool does_terrain_block_action(const action_id act_id,
1375 bool is_target,
1376 struct unit *actor_unit,
1377 struct terrain *pterrain)
1378{
1379 if (act_id == ACTION_ANY) {
1380 /* Any action is OK. */
1383 && !does_terrain_block_action(alt_act, is_target,
1384 actor_unit, pterrain)) {
1385 /* Only one action has to be possible. */
1386 return FALSE;
1387 }
1389
1390 /* No action enabled. */
1391 return TRUE;
1392 }
1393
1394 /* ACTION_ANY is handled above. */
1396
1398 enabler) {
1400 (is_target ? &enabler->target_reqs : &enabler->actor_reqs))
1402 &enabler->actor_reqs)) {
1403 /* This terrain kind doesn't block this action enabler. */
1404 return FALSE;
1405 }
1407
1408 return TRUE;
1409}
1410
1411/**********************************************************************/
1416static bool does_nation_block_action(const action_id act_id,
1417 bool is_target,
1418 struct unit *actor_unit,
1419 struct nation_type *pnation)
1420{
1421 if (act_id == ACTION_ANY) {
1422 /* Any action is OK. */
1425 && !does_nation_block_action(alt_act, is_target,
1426 actor_unit, pnation)) {
1427 /* Only one action has to be possible. */
1428 return FALSE;
1429 }
1431
1432 /* No action enabled. */
1433 return TRUE;
1434 }
1435
1436 /* ACTION_ANY is handled above. */
1438
1440 enabler) {
1442 (is_target ? &enabler->target_reqs
1443 : &enabler->actor_reqs))
1445 &enabler->actor_reqs)) {
1446 /* This nation doesn't block this action enabler. */
1447 return FALSE;
1448 }
1450
1451 return TRUE;
1452}
1453
1454/**********************************************************************/
1458static struct ane_expl *expl_act_not_enabl(struct unit *punit,
1459 const action_id act_id,
1460 const struct tile *target_tile,
1461 const struct city *target_city,
1462 const struct unit *target_unit)
1463{
1464 struct player *must_war_player;
1465 const struct action *paction;
1466 struct action *blocker;
1467 struct player *act_player = unit_owner(punit);
1468 struct player *tgt_player = nullptr;
1469 struct ane_expl *explnat = fc_malloc(sizeof(struct ane_expl));
1470 struct civ_map *nmap = &(wld.map);
1473 int action_custom;
1474
1475 /* Not know yet. (Initialize before the below check.) */
1476 explnat->kind = ANEK_UNKNOWN;
1477
1478 paction = action_by_number(act_id);
1479
1480 if (act_id != ACTION_ANY) {
1481 /* A specific action should have a suitable target. */
1483 case ATK_CITY:
1484 if (target_city == nullptr) {
1486 }
1487 break;
1488 case ATK_UNIT:
1489 if (target_unit == nullptr) {
1491 }
1492 break;
1493 case ATK_STACK:
1494 case ATK_TILE:
1495 case ATK_EXTRAS:
1496 if (target_tile == nullptr) {
1498 }
1499 break;
1500 case ATK_SELF:
1501 /* No other target. */
1502 break;
1503 case ATK_COUNT:
1505 break;
1506 }
1507 }
1508
1509 if (explnat->kind == ANEK_MISSING_TARGET) {
1510 /* No point continuing. */
1511 return explnat;
1512 }
1513
1514 if (act_id == ACTION_ANY) {
1515 /* Find the target player of some actions. */
1516 if (target_city) {
1517 /* Individual city targets have the highest priority. */
1519 } else if (target_unit) {
1520 /* Individual unit targets have the next priority. */
1522 } else if (target_tile) {
1523 /* Tile targets have the lowest priority. */
1525 }
1526 } else {
1527 /* Find the target player of this action. */
1529 case ATK_CITY:
1531 break;
1532 case ATK_UNIT:
1534 break;
1535 case ATK_TILE:
1537 break;
1538 case ATK_EXTRAS:
1539 tgt_player = target_tile->extras_owner;
1540 break;
1541 case ATK_STACK:
1542 /* A unit stack may contain units with multiple owners. Pick the
1543 * first one. */
1544 if (target_tile
1545 && unit_list_size(target_tile->units) > 0) {
1547 }
1548 break;
1549 case ATK_SELF:
1550 /* A unit acting against itself. */
1552 break;
1553 case ATK_COUNT:
1555 break;
1556 }
1557 }
1558
1559 if (act_id == ACTION_ANY) {
1560 action_custom = 0;
1561 } else {
1562 switch (paction->result) {
1565 break;
1566 case ACTRES_AIRLIFT:
1568 target_city);
1569 break;
1570 case ACTRES_NUKE_UNITS:
1572 target_tile);
1573 break;
1574 case ACTRES_ATTACK:
1576 target_tile);
1577 break;
1578 case ACTRES_WIPE_UNITS:
1580 break;
1582 if (target_city) {
1584 punit->activity,
1587 FALSE, FALSE, nullptr, TRUE);
1588 } else {
1590 }
1591 break;
1593 if (target_unit) {
1595 punit->activity,
1598 FALSE, TRUE, nullptr, FALSE);
1599 } else {
1601 }
1602 break;
1604 case ACTRES_HUT_ENTER:
1607 case ACTRES_UNIT_MOVE:
1608 if (target_tile) {
1610 punit->activity,
1613 FALSE, FALSE, nullptr, FALSE);
1614 } else {
1616 }
1617 break;
1618 case ACTRES_TELEPORT:
1619 if (target_tile != nullptr) {
1621 punit->activity,
1624 FALSE, nullptr, FALSE);
1625 } else {
1627 }
1628 break;
1629 default:
1630 action_custom = 0;
1631 break;
1632 }
1633 }
1634
1635 if (!unit_can_do_action(punit, act_id)) {
1636 explnat->kind = ANEK_ACTOR_UNIT;
1638 && tile_city(target_tile)) {
1639 explnat->kind = ANEK_BAD_TARGET;
1643 act_player)) {
1645 } else if ((!can_exist
1648 || (can_exist
1652 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1653 } else if ((!on_native
1656 || (on_native
1658 USP_NATIVE_TILE, TRUE))) {
1660 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1661 } else if (punit
1664 /* No action enabler allows acting against this terrain kind. */
1666 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1668 && target_tile
1670 TER_NO_CITIES)) {
1672 explnat->no_act_terrain = tile_terrain(target_tile);
1675 && target_tile != nullptr
1677 V_MAIN)
1679 && (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
1682 explnat->no_act_terrain = tile_terrain(target_tile);
1683 } else if (target_tile
1686 /* No action enabler allows acting against this terrain kind. */
1688 explnat->no_act_terrain = tile_terrain(target_tile);
1689 } else if (unit_transported(punit)
1693 } else if (!unit_transported(punit)
1697 } else if (0 < get_transporter_occupancy(punit)
1701 } else if (!(0 < get_transporter_occupancy(punit))
1705 } else if ((punit->homecity > 0)
1709 } else if ((punit->homecity <= 0)
1713 } else if ((punit->homecity <= 0)
1717 } else if (act_player && tgt_player
1719 == DS_PEACE)
1721 act_id,
1722 DS_PEACE,
1723 FALSE)
1725 act_id,
1726 DS_PEACE,
1727 TRUE)) {
1728 explnat->kind = ANEK_PEACE;
1729 explnat->peace_with = tgt_player;
1731 act_id,
1734 target_unit)) != nullptr) {
1735 explnat->kind = ANEK_NO_WAR;
1736 explnat->no_war_with = must_war_player;
1737 } else if (action_mp_full_makes_legal(punit, act_id)) {
1738 explnat->kind = ANEK_LOW_MP;
1739 } else if (tgt_player != nullptr
1742 act_id,
1744 TRUE)) {
1745 explnat->kind = ANEK_FOREIGN;
1746 } else if (tgt_player != nullptr
1749 act_id,
1751 FALSE)) {
1752 explnat->kind = ANEK_DOMESTIC;
1753 } else if (punit != nullptr
1755 punit, act_player->nation)) {
1756 explnat->kind = ANEK_NATION_ACT;
1757 explnat->no_act_nation = act_player->nation;
1758 } else if (tgt_player
1759 && does_nation_block_action(act_id, TRUE,
1760 punit, tgt_player->nation)) {
1761 explnat->kind = ANEK_NATION_TGT;
1762 explnat->no_act_nation = tgt_player->nation;
1763 } else if ((target_tile && tile_city(target_tile))
1765 act_id,
1767 TRUE)) {
1769 } else if ((target_tile && !tile_city(target_tile))
1771 act_id,
1773 FALSE)) {
1775 } else if ((target_tile && tile_owner(target_tile) != nullptr)
1777 act_id,
1779 TRUE)) {
1781 } else if ((target_tile && tile_owner(target_tile) == nullptr)
1783 act_id,
1785 FALSE)) {
1787 } else if (paction && punit
1788 && ((target_tile
1791 || (target_city
1795 || (target_unit
1798 unit_tile(target_unit)))))) {
1799 explnat->kind = ANEK_DISTANCE_FAR;
1800 explnat->distance = paction->max_distance;
1803 && punit && target_tile
1805 > unit_type_get(punit)->paratroopers_range) {
1806 explnat->kind = ANEK_DISTANCE_FAR;
1808 } else if (paction && punit
1809 && ((target_tile
1811 < paction->min_distance)
1812 || (target_city
1815 < paction->min_distance)
1816 || (target_unit
1819 < paction->min_distance))) {
1821 explnat->distance = paction->min_distance;
1822 } else if (target_city
1828 /* TODO: Check max city size requirements from action enabler target
1829 * vectors. */
1830 explnat->kind = ANEK_CITY_TOO_BIG;
1831 } else if (target_city
1837 + unit_pop_value(punit))))) {
1839 } else if (target_city
1844 && MAX_CITY_SIZE
1845 <= target_city->specialists
1846 [specialist_index(unit_type_get(punit)->spec_type)])) {
1851 && action_custom != ATT_OK) {
1852 switch (action_custom) {
1853 case ATT_NON_ATTACK:
1854 explnat->kind = ANEK_ACTOR_UNIT;
1855 break;
1856 case ATT_UNREACHABLE:
1858 break;
1859 case ATT_NONNATIVE_SRC:
1861 explnat->no_act_terrain = tile_terrain(unit_tile(punit));
1862 break;
1863 case ATT_NONNATIVE_DST:
1865 explnat->no_act_terrain = tile_terrain(target_tile);
1866 break;
1867 case ATT_NOT_WIPABLE:
1868 explnat->kind = ANEK_NOT_WIPABLE;
1869 break;
1870 default:
1872 explnat->kind = ANEK_UNKNOWN;
1873 break;
1874 }
1878 explnat->capacity_city = tile_city(unit_tile(punit));
1882 explnat->capacity_city = game_city_by_number(target_city->id);
1888 && target_tile != nullptr
1900 && action_custom != MR_OK) {
1901 switch (action_custom) {
1904 break;
1905 case MR_TRIREME:
1906 explnat->kind = ANEK_TRIREME_MOVE;
1907 break;
1910 break;
1911 default:
1913 explnat->kind = ANEK_UNKNOWN;
1914 break;
1915 }
1920 explnat->no_tgt_utype = unit_type_get(target_unit);
1921 } else if ((game.scenario.prevent_new_cities
1924 || act_id == ACTION_ANY)) {
1925 /* Please add a check for any new action forbidding scenario setting
1926 * above this comment. */
1929 && action_custom == UU_NO_MONEY) {
1930 const struct unit_type *act_utype = unit_type_get(punit);
1931
1936 } else if (paction
1937 && (blocker = action_is_blocked_by(nmap, paction, punit,
1939 target_unit))) {
1941 explnat->blocker = blocker;
1942 } else {
1943 explnat->kind = ANEK_UNKNOWN;
1944 }
1945
1946 return explnat;
1947}
1948
1949/**********************************************************************/
1953 action_id act_id,
1954 const struct tile *target_tile,
1955 const struct city *target_city,
1956 const struct unit *target_unit)
1957{
1958 struct ane_expl *explnat = expl_act_not_enabl(punit, act_id,
1961 enum ane_kind out = explnat->kind;
1962
1963 free(explnat);
1964
1965 return out;
1966}
1967
1968/**********************************************************************/
1973 const struct tile *target_tile,
1974 const struct city *target_city,
1975 const struct unit *target_unit)
1976{
1977 struct player *pplayer = unit_owner(punit);
1981 const struct civ_map *nmap = &(wld.map);
1982
1983 switch (explnat->kind) {
1984 case ANEK_ACTOR_UNIT:
1985 /* This shouldn't happen unless the client is buggy given the current
1986 * users. */
1988 "Asked to explain why a non actor can't act.");
1989
1991 _("Unit cannot do anything."));
1992 break;
1995 _("Your %s found no suitable target."),
1997 break;
1998 case ANEK_BAD_TARGET:
1999 /* This shouldn't happen at the moment. Only specific action checks
2000 * will trigger bad target checks. This is a reply to a question about
2001 * any action. */
2003
2005 _("Your %s found no suitable target."),
2007 break;
2009 {
2010 const char *types[utype_count()];
2011 int i = 0;
2012
2015 FALSE)
2017 unit_type_iterate(utype) {
2020 types[i++] = utype_name_translation(utype);
2021 }
2023 }
2024
2025 if (0 < i) {
2026 struct astring astr = ASTRING_INIT;
2027
2028 notify_player(pplayer, unit_tile(punit),
2030 /* TRANS: terrain name
2031 * "Your Diplomat cannot act from Ocean. Only
2032 * Spy or Partisan ... */
2033 _("Your %s cannot act from %s. "
2034 "Only %s can act from a non livable tile."),
2036 terrain_name_translation(explnat->no_act_terrain),
2037 astr_build_or_list(&astr, types, i));
2038
2039 astr_free(&astr);
2040 } else {
2042 /* TRANS: terrain name */
2043 _("Unit cannot act from %s."),
2044 terrain_name_translation(explnat->no_act_terrain));
2045 }
2046 }
2047 break;
2050 /* TRANS: terrain name */
2051 _("Unit cannot act against %s."),
2052 terrain_name_translation(explnat->no_act_terrain));
2053 break;
2056 _("This unit is being transported, and"
2057 " so cannot act."));
2058 break;
2061 _("This unit cannot act when it isn't being "
2062 "transported."));
2063 break;
2066 _("This unit is transporting, and"
2067 " so cannot act."));
2068 break;
2071 _("This unit cannot act when it isn't transporting."));
2072 break;
2075 _("This unit has a home city, and so cannot act."));
2076 break;
2079 _("This unit cannot act unless it has a home city."));
2080 break;
2081 case ANEK_NO_WAR:
2083 _("You must declare war on %s first. Try using "
2084 "the Nations report"
2086 " (F3)"
2087#endif /* FREECIV_WEB */
2088 "."),
2089 player_name(explnat->no_war_with));
2090 break;
2091 case ANEK_PEACE:
2093 _("You must break peace with %s first. Try using "
2094 "the Nations report to declare war"
2096 " (F3)"
2097#endif /* FREECIV_WEB */
2098 "."),
2099 player_name(explnat->peace_with));
2100 break;
2101 case ANEK_DOMESTIC:
2103 _("This unit cannot act against domestic targets."));
2104 break;
2105 case ANEK_FOREIGN:
2107 _("This unit cannot act against foreign targets."));
2108 break;
2111 /* TRANS: Riflemen */
2112 _("%s cannot act against tiles with non allied units."),
2114 break;
2115 case ANEK_NATION_ACT:
2117 /* TRANS: Swedish ... Riflemen */
2118 _("%s %s cannot act."),
2119 nation_adjective_translation(explnat->no_act_nation),
2121 break;
2122 case ANEK_NATION_TGT:
2124 /* TRANS: ... Pirate ... */
2125 _("This unit cannot act against %s targets."),
2126 nation_adjective_translation(explnat->no_act_nation));
2127 break;
2128 case ANEK_LOW_MP:
2130 _("This unit has too few moves left to act."));
2131 break;
2134 _("This unit cannot act against city centers."));
2135 break;
2138 _("This unit cannot act against non city centers."));
2139 break;
2142 _("This unit cannot act against claimed tiles."));
2143 break;
2146 _("This unit cannot act against unclaimed tiles."));
2147 break;
2148 case ANEK_DISTANCE_NEAR:
2150 _("This unit is too near its target to act."));
2151 break;
2152 case ANEK_DISTANCE_FAR:
2154 _("This unit is too far away from its target to act."));
2155 break;
2158 _("Can't perform any action this scenario permits."));
2159 break;
2162 _("Can't perform any action this close to a city."));
2163 break;
2164 case ANEK_CITY_TOO_BIG:
2166 /* TRANS: Settler ... Berlin */
2167 _("%s can't do anything to %s. It is too big."),
2170 break;
2173 /* TRANS: London ... Settlers */
2174 _("%s needs an improvement to grow, so "
2175 "%s cannot do anything to it."),
2178 break;
2181 /* TRANS: Paris ... Warriors (think: airlift) */
2182 _("%s don't have enough capacity, so "
2183 "%s cannot do anything."),
2184 city_name_get(explnat->capacity_city),
2186 break;
2189 /* TRANS: Paratroopers ... */
2190 _("%s can't do anything to an unknown target tile."),
2192 break;
2194 {
2195 char tbuf[MAX_LEN_MSG];
2196
2197 /* TRANS: Used below. Separate so treasury content too can determine
2198 * if this is plural. */
2199 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2200 "Treasury contains %d gold.",
2201 pplayer->economic.gold),
2202 pplayer->economic.gold);
2203
2205 /* TRANS: "Spy can't do anything. 154 gold may help.
2206 * Treasury contains 100 gold." */
2207 PL_("%s can't do anything. %d gold may help. %s",
2208 "%s can't do anything. %d gold may help. %s",
2209 explnat->gold_needed),
2211 explnat->gold_needed, tbuf);
2212 }
2213 break;
2214 case ANEK_TRIREME_MOVE:
2216 _("%s cannot move that far from the coast line."),
2217 unit_link(punit));
2218 break;
2219 case ANEK_DISEMBARK_ACT:
2221 _("%s cannot disembark outside of a city or a native base "
2222 "for %s."),
2226 break;
2229 _("%s can't do anything since there is an unreachable "
2230 "unit."),
2232 break;
2233 case ANEK_NOT_WIPABLE:
2235 _("%s can't do anything since there is unit with a positive "
2236 "defense value."),
2238 break;
2241 _("%s can't do anything since you already have a %s."),
2243 utype_name_translation(explnat->no_tgt_utype));
2244 break;
2245 case ANEK_ACTION_BLOCKS:
2246 /* If an action blocked another action the blocking action must be
2247 * possible. */
2249 fc__fallthrough; /* Fall through to unknown cause. */
2250 case ANEK_UNKNOWN:
2252 _("No action possible."));
2253 break;
2254 }
2255
2256 free(explnat);
2257}
2258
2259/**********************************************************************/
2268 const int actor_unit_id,
2269 const int target_unit_id_client,
2270 const int target_tile_id,
2271 const int target_extra_id_client,
2272 const int request_kind)
2273{
2274 struct player *actor_player;
2275 struct unit *actor_unit;
2276 struct tile *target_tile;
2278 struct unit *target_unit;
2279 struct city *target_city;
2280 struct extra_type *target_extra;
2282 const struct player_tile *plrtile;
2284 const struct civ_map *nmap = &(wld.map);
2285
2286 /* No potentially legal action is known yet. If none is found the player
2287 * should get an explanation. */
2289
2290 /* A target should only be sent if it is possible to act against it */
2291 int target_city_id = IDENTITY_NUMBER_ZERO;
2292 int target_unit_id = IDENTITY_NUMBER_ZERO;
2293
2294 actor_player = pc->playing;
2296 target_tile = index_to_tile(nmap, target_tile_id);
2297
2298 /* Initialize the action probabilities. */
2299 action_iterate(act) {
2302
2303 /* Check if the request is valid. */
2305 || actor_unit->owner != actor_player) {
2308 target_tile_id, target_extra_id,
2309 request_kind,
2311 return;
2312 }
2313
2314 /* Select the targets. */
2315
2317 /* Find a new target unit. */
2319 } else {
2320 /* Prepare the client selected target unit. */
2322 }
2323
2324 /* Find the target city. */
2326
2327 /* The specified target unit must be located at the target tile. */
2331 _("Target not at target tile."));
2334 target_tile_id, target_extra_id,
2335 request_kind,
2337 return;
2338 }
2339
2341 /* See if a target extra can be found. */
2343 } else {
2344 /* Use the client selected target extra. */
2346 }
2347
2348 /* The player may have outdated information about the target tile.
2349 * Limiting the player knowledge look up to the target tile is OK since
2350 * all targets must be located at it. */
2352
2353 /* Distance between actor and target tile. */
2355 target_tile);
2356
2357 /* Find out what can be done to the targets. */
2358
2359 /* Set the probability for the actions. */
2361 if (action_id_get_actor_kind(act) != AAK_UNIT) {
2362 /* Not relevant. */
2363 continue;
2364 }
2365
2366 switch (action_id_get_target_kind(act)) {
2367 case ATK_CITY:
2368 if (plrtile && plrtile->site) {
2369 /* Only a known city may be targeted. */
2370 if (target_city) {
2371 /* Calculate the probabilities. */
2373 target_city);
2378 /* The target city is non existing. The player isn't aware of this
2379 * fact because they can't see the tile it was located on. The
2380 * actor unit it self doesn't contradict the requirements to
2381 * perform the action. The (no longer existing) target city was
2382 * known to be close enough. */
2384 } else {
2385 /* The actor unit is known to be unable to act or the target city
2386 * is known to be too far away. */
2388 }
2389 } else {
2390 /* No target to act against. */
2392 }
2393 break;
2394 case ATK_UNIT:
2395 if (target_unit) {
2396 /* Calculate the probabilities. */
2398 target_unit);
2399 } else {
2400 /* No target to act against. */
2402 }
2403 break;
2404 case ATK_STACK:
2405 if (target_tile) {
2406 /* Calculate the probabilities. */
2408 target_tile);
2409 } else {
2410 /* No target to act against. */
2412 }
2413 break;
2414 case ATK_TILE:
2415 if (target_tile) {
2416 /* Calculate the probabilities. */
2419 } else {
2420 /* No target to act against. */
2422 }
2423 break;
2424 case ATK_EXTRAS:
2425 if (target_tile) {
2426 /* Calculate the probabilities. */
2429 target_extra);
2430 } else {
2431 /* No target to act against. */
2433 }
2434 break;
2435 case ATK_SELF:
2436 if (actor_target_distance == 0) {
2437 /* Calculate the probabilities. */
2439 } else {
2440 /* Don't bother with self targeted actions unless the actor is
2441 * asking about what can be done to its own tile. */
2443 }
2444 break;
2445 case ATK_COUNT:
2448 break;
2449 }
2451
2452 /* Analyze the probabilities. Decide what targets to send and if an
2453 * explanation is needed. */
2456 /* An action can be done. No need to explain why no action can be
2457 * done. */
2459
2460 switch (action_id_get_target_kind(act)) {
2461 case ATK_CITY:
2462 /* The city should be sent as a target since it is possible to act
2463 * against it. */
2464
2465 /* All city targeted actions requires that the player is aware of
2466 * the target city. It is therefore in the player's map. */
2467 fc_assert_action(plrtile, continue);
2468 fc_assert_action(plrtile->site, continue);
2469
2470 target_city_id = plrtile->site->identity;
2471 break;
2472 case ATK_UNIT:
2473 /* The unit should be sent as a target since it is possible to act
2474 * against it. */
2475 fc_assert(target_unit != nullptr);
2476 target_unit_id = target_unit->id;
2477 break;
2478 case ATK_TILE:
2479 case ATK_EXTRAS:
2480 /* The target tile isn't selected here so it hasn't changed. */
2481 fc_assert(target_tile != nullptr);
2482
2484 /* The target extra may have been set here. */
2486 }
2487 break;
2488 case ATK_STACK:
2489 /* The target tile isn't selected here so it hasn't changed. */
2490 fc_assert(target_tile != nullptr);
2491 break;
2492 case ATK_SELF:
2493 /* The target unit is the actor unit. It is already sent. */
2494 fc_assert(actor_unit != nullptr);
2495 break;
2496 case ATK_COUNT:
2498 "Invalid action target kind.");
2499 break;
2500 }
2501
2502 if (target_city_id != IDENTITY_NUMBER_ZERO
2503 && target_unit_id != IDENTITY_NUMBER_ZERO) {
2504 /* No need to find out more. */
2505 break;
2506 }
2507 }
2509
2510 /* Send possible actions and targets. */
2512 actor_unit_id, target_unit_id, target_city_id,
2513 target_tile_id, target_extra_id,
2514 request_kind,
2516
2517 if (request_kind == REQEST_PLAYER_INITIATED && !at_least_one_action) {
2518 /* The user should get an explanation why no action is possible. */
2521 }
2522}
2523
2524/**********************************************************************/
2531void illegal_action_msg(struct player *pplayer,
2532 const enum event_type event,
2533 struct unit *actor,
2535 const struct tile *target_tile,
2536 const struct city *target_city,
2537 const struct unit *target_unit)
2538{
2539 struct ane_expl *explnat;
2540 const struct civ_map *nmap = &(wld.map);
2541
2542 /* Explain why the action was illegal. */
2545 switch (explnat->kind) {
2546 case ANEK_ACTOR_UNIT:
2547 {
2548 struct astring astr = ASTRING_INIT;
2549
2552 TRUE)) {
2553 notify_player(pplayer, unit_tile(actor),
2555 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
2556 _("Only %s can do %s."),
2557 astr_str(&astr),
2559 astr_free(&astr);
2560 } else {
2561 notify_player(pplayer, unit_tile(actor),
2563 /* TRANS: Spy can't do Capture Units. */
2564 _("%s can't do %s."),
2567 }
2568 }
2569 break;
2572 /* TRANS: "Your Spy found ... suitable for
2573 * Bribe Enemy Unit." */
2574 _("Your %s found no target suitable for %s."),
2577 break;
2578 case ANEK_BAD_TARGET:
2580 /* TRANS: "Having your Spy do Bribe Enemy Unit to
2581 * this target ..." */
2582 _("Having your %s do %s to this target is redundant."),
2585 break;
2587 {
2588 const char *types[utype_count()];
2589 int i = 0;
2590
2593 FALSE)
2595 unit_type_iterate(utype) {
2598 types[i++] = utype_name_translation(utype);
2599 }
2601 }
2602
2603 if (0 < i) {
2604 struct astring astr = ASTRING_INIT;
2605
2606 notify_player(pplayer, unit_tile(actor),
2608 /* TRANS: action name.
2609 * "Your Spy can't do Steal Gold from Ocean.
2610 * Only Explorer or Partisan can do Steal Gold ..." */
2611 _("Your %s can't do %s from %s. "
2612 "Only %s can do %s from a non livable tile."),
2615 terrain_name_translation(explnat->no_act_terrain),
2616 astr_build_or_list(&astr, types, i),
2618
2619 astr_free(&astr);
2620 } else {
2621 notify_player(pplayer, unit_tile(actor),
2623 /* TRANS: action name.
2624 * "Your Spy can't do Steal Gold from Ocean." */
2625 _("Your %s can't do %s from %s."),
2628 terrain_name_translation(explnat->no_act_terrain));
2629 }
2630 }
2631 break;
2633 notify_player(pplayer, unit_tile(actor),
2635 /* TRANS: action name.
2636 * "Your Spy can't do Industrial Sabotage to Mountains." */
2637 _("Your %s can't do %s to %s."),
2640 terrain_name_translation(explnat->no_act_terrain));
2641 break;
2643 notify_player(pplayer, unit_tile(actor),
2645 /* TRANS: action name.
2646 * "Your Spy can't do Industrial Sabotage while ..." */
2647 _("Your %s can't do %s while being transported."),
2650 break;
2652 notify_player(pplayer, unit_tile(actor),
2654 /* TRANS: action name.
2655 * "Your Spy can't do Industrial Sabotage while ..." */
2656 _("Your %s can't do %s while not being transported."),
2659 break;
2661 notify_player(pplayer, unit_tile(actor),
2663 /* TRANS: action name.
2664 * "Your Spy can't do Industrial Sabotage while ..." */
2665 _("Your %s can't do %s while transporting."),
2668 break;
2670 notify_player(pplayer, unit_tile(actor),
2672 /* TRANS: action name.
2673 * "Your Spy can't do Industrial Sabotage while ..." */
2674 _("Your %s can't do %s while not transporting."),
2677 break;
2679 notify_player(pplayer, unit_tile(actor),
2681 /* TRANS: action name.
2682 * "Your Spy can't do Industrial Sabotage because ..." */
2683 _("Your %s can't do %s because it has a home city."),
2686 break;
2688 notify_player(pplayer, unit_tile(actor),
2690 /* TRANS: action name.
2691 * "Your Spy can't do Industrial Sabotage because ..." */
2692 _("Your %s can't do %s because it is homeless."),
2695 break;
2696 case ANEK_NO_WAR:
2697 notify_player(pplayer, unit_tile(actor),
2699 /* TRANS: action name.
2700 * "Your Spy can't do Industrial Sabotage while you
2701 * aren't at war with Prester John." */
2702 _("Your %s can't do %s while you"
2703 " aren't at war with %s."),
2706 player_name(explnat->no_war_with));
2707 break;
2708 case ANEK_PEACE:
2709 notify_player(pplayer, unit_tile(actor),
2711 /* TRANS: action name.
2712 * "Your Spy can't do Industrial Sabotage while you
2713 * are at peace with Prester John. Try using the
2714 * Nations report (F3)." */
2715 _("Your %s can't do %s while you "
2716 "are at peace with %s. Try using "
2717 "the Nations report to declare war"
2719 " (F3)"
2720#endif /* FREECIV_WEB */
2721 "."),
2724 player_name(explnat->peace_with));
2725 break;
2726 case ANEK_DOMESTIC:
2727 notify_player(pplayer, unit_tile(actor),
2729 /* TRANS: action name.
2730 * "Your Riflemen can't do Expel Unit to domestic
2731 * unit stacks." */
2732 _("Your %s can't do %s to domestic %s."),
2737 break;
2738 case ANEK_FOREIGN:
2739 notify_player(pplayer, unit_tile(actor),
2741 /* TRANS: action name.
2742 * "Your Leader can't do Use Court Physician to foreign
2743 * unit stacks." */
2744 _("Your %s can't do %s to foreign %s."),
2749 break;
2751 notify_player(pplayer, unit_tile(actor),
2753 /* TRANS: Paratroopers ... Drop Paratrooper */
2754 _("Your %s can't do %s to tiles with non allied units."),
2757 break;
2758 case ANEK_NATION_ACT:
2759 notify_player(pplayer, unit_tile(actor),
2761 /* TRANS: action name.
2762 * "Swedish Riflemen can't do Expel Unit." */
2763 _("%s %s can't do %s."),
2764 nation_adjective_translation(explnat->no_act_nation),
2767 break;
2768 case ANEK_NATION_TGT:
2769 notify_player(pplayer, unit_tile(actor),
2771 /* TRANS: action name.
2772 * "Riflemen... Expel Unit... Pirate Migrants." */
2773 _("Your %s can't do %s to %s %s."),
2776 nation_adjective_translation(explnat->no_act_nation),
2779 break;
2780 case ANEK_LOW_MP:
2781 notify_player(pplayer, unit_tile(actor),
2783 /* TRANS: action name.
2784 * "Your Spy has ... to do Bribe Enemy Unit." */
2785 _("Your %s has too few moves left to do %s."),
2788 break;
2790 notify_player(pplayer, unit_tile(actor),
2792 /* TRANS: action name.
2793 * "Your Spy can't do Bribe Enemy Unit to city centers." */
2794 _("Your %s can't do %s to city centers."),
2797 break;
2799 notify_player(pplayer, unit_tile(actor),
2801 /* TRANS: action name.
2802 * "Your Spy can only do Investigate City to
2803 * city centers." */
2804 _("Your %s can only do %s to city centers."),
2807 break;
2809 notify_player(pplayer, unit_tile(actor),
2811 /* TRANS: action name.
2812 * "Your Settlers can't do Build City to claimed tiles." */
2813 _("Your %s can't do %s to claimed tiles."),
2816 break;
2818 notify_player(pplayer, unit_tile(actor),
2820 /* TRANS: action name.
2821 * "Your Spy can't do Bribe Enemy Unit to
2822 * unclaimed tiles." */
2823 _("Your %s can't do %s to unclaimed tiles."),
2826 break;
2827 case ANEK_DISTANCE_NEAR:
2828 notify_player(pplayer, unit_tile(actor),
2830 /* TRANS: action name.
2831 * "Your Spy must be at least 2 tiles away to do
2832 * Incite a Revolt and Escape." */
2833 PL_("Your %s must be at least %d tile away to do %s.",
2834 "Your %s must be at least %d tiles away to do %s.",
2835 explnat->distance),
2837 explnat->distance,
2839 break;
2840 case ANEK_DISTANCE_FAR:
2841 notify_player(pplayer, unit_tile(actor),
2843 /* TRANS: action name.
2844 * "Your Diplomat can't be more than 1 tile away to do
2845 * Establish Embassy." */
2846 PL_("Your %s can't be more than %d tile away to do %s.",
2847 "Your %s can't be more than %d tiles away to do %s.",
2848 explnat->distance),
2850 explnat->distance,
2852 break;
2854 notify_player(pplayer, unit_tile(actor),
2856 /* TRANS: Can't do Build City in this scenario. */
2857 _("Can't do %s in this scenario."),
2859 break;
2861 notify_player(pplayer, unit_tile(actor),
2863 /* TRANS: Can't do Build City this close to a city. */
2864 _("Can't do %s this close to a city."),
2866 break;
2867 case ANEK_CITY_TOO_BIG:
2868 notify_player(pplayer, unit_tile(actor),
2870 /* TRANS: Settlers ... Join City ... London */
2871 _("%s can't do %s to %s. It is too big."),
2875 break;
2877 notify_player(pplayer, unit_tile(actor),
2879 /* TRANS: London ... Settlers ... Join City */
2880 _("%s needs an improvement to grow, so "
2881 "%s cannot do %s."),
2885 break;
2887 notify_player(pplayer, unit_tile(actor),
2889 /* TRANS: Paris ... Airlift to City ... Warriors */
2890 _("%s has no capacity to %s %s."),
2891 city_name_get(explnat->capacity_city),
2894 break;
2896 notify_player(pplayer, unit_tile(actor),
2898 /* TRANS: Paratroopers ... Drop Paratrooper */
2899 _("%s can't do %s to an unknown tile."),
2902 break;
2904 {
2905 char tbuf[MAX_LEN_MSG];
2906
2907 /* TRANS: Used below. Separate so treasury content too can determine
2908 * if this is plural. */
2909 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2910 "Treasury contains %d gold.",
2911 pplayer->economic.gold),
2912 pplayer->economic.gold);
2913
2914 notify_player(pplayer, unit_tile(actor),
2916 /* TRANS: "Spy can't do Bribe Unit for 154 gold.
2917 * Treasury contains 100 gold." */
2918 PL_("%s can't do %s for %d gold. %s",
2919 "%s can't do %s for %d gold. %s",
2920 explnat->gold_needed),
2923 explnat->gold_needed, tbuf);
2924 }
2925 break;
2926 case ANEK_TRIREME_MOVE:
2928 /* TRANS: "Trireme cannot move ..." */
2929 _("%s cannot move that far from the coast line."),
2930 unit_link(actor));
2931 break;
2932 case ANEK_DISEMBARK_ACT:
2934 /* TRANS: "Riflemen cannot disembark ... native base
2935 * for Helicopter." */
2936 _("%s cannot disembark outside of a city or a native base "
2937 "for %s."),
2941 break;
2943 notify_player(pplayer, target_tile,
2945 /* TRANS: "Your Spy can't do Bribe Enemy Unit there ..." */
2946 _("Your %s can't do %s there since there's an "
2947 "unreachable unit."),
2950 break;
2951 case ANEK_NOT_WIPABLE:
2952 notify_player(pplayer, target_tile,
2954 /* TRANS: "Your Legion can't do Wipe Units there ..." */
2955 _("Your %s can't do %s there since there's an "
2956 "unit with positive defense value."),
2959 break;
2962 /* TRANS: "You already have a Leader." */
2963 _("You already have a %s."),
2964 utype_name_translation(explnat->no_tgt_utype));
2965 break;
2966 case ANEK_ACTION_BLOCKS:
2967 {
2969
2970 notify_player(pplayer, unit_tile(actor),
2972 /* TRANS: Freight ... Disband Unit Recover ... Help Wonder ... */
2973 _("Your %s can't do %s when %s is legal."),
2976 action_id_name_translation(explnat->blocker->id));
2978 }
2979 break;
2980 case ANEK_UNKNOWN:
2981 notify_player(pplayer, unit_tile(actor),
2983 /* TRANS: action name.
2984 * "Your Spy was unable to do Bribe Enemy Unit." */
2985 _("Your %s was unable to do %s."),
2988 break;
2989 }
2990
2991 free(explnat);
2992}
2993
2994/**********************************************************************/
3007static bool illegal_action_pay_price(struct player *pplayer,
3009 struct unit *act_unit,
3010 struct action *stopped_action,
3011 struct player *tgt_player,
3012 struct tile *tgt_tile,
3013 const enum action_requester requester)
3014{
3015 int punishment_mp;
3016 int punishment_hp;
3017
3018 const struct req_context actor_ctxt = {
3020 .unit = act_unit,
3021 .unittype = unit_type_get(act_unit),
3022 .action = stopped_action,
3023 };
3024 const struct req_context tgt_ctxt = {
3025 .player = tgt_player,
3026 };
3027
3028 /* Don't punish the player for something the game did. Don't tell the
3029 * player that the rules required the game to try to do something
3030 * illegal. */
3033 FALSE,
3034 "The player wasn't responsible for this.");
3035
3036 if (!information_revealed) {
3037 /* The player already had enough information to determine that this
3038 * action is illegal. Don't punish a client error or an accident. */
3039 return FALSE;
3040 }
3041
3042 /* The mistake may have a cost. */
3043
3044 /* HP cost */
3047
3048 /* Stay in range */
3050
3051 /* Punish the unit's hit points. */
3052 act_unit->hp = MAX(0, act_unit->hp - punishment_hp);
3053
3054 if (punishment_hp != 0) {
3057 /* The consolation prize is some information about the potentially
3058 * distant target tile and maybe some contacts. */
3059 map_show_circle(pplayer, tgt_tile,
3060 unit_type_get(act_unit)->vision_radius_sq);
3062 }
3063
3064 if (act_unit->hp > 0) {
3065 /* The actor unit survived */
3066
3067 /* The player probably wants to be disturbed if their unit was punished
3068 * with the loss of hit points. */
3071 /* TRANS: Spy ... 5 ... Drop Paratrooper */
3072 _("Your %s lost %d hit points while attempting to"
3073 " do %s."),
3076 send_unit_info(nullptr, act_unit);
3077 } else {
3078 /* The unit didn't survive */
3079
3080 /* The player probably wants to be disturbed if their unit was punished
3081 * with death. */
3084 /* TRANS: Spy ... Drop Paratrooper */
3085 _("Your %s was killed while attempting to do %s."),
3088
3089 wipe_unit(act_unit, ULR_KILLED, nullptr);
3090 act_unit = nullptr;
3091
3092 return TRUE;
3093 }
3094 }
3095
3096 /* MP cost */
3099
3100 /* Stay in range */
3102
3103 /* Punish the unit's move fragments. */
3104 act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
3105 send_unit_info(nullptr, act_unit);
3106
3107 if (punishment_mp != 0) {
3108 /* The player probably wants to be disturbed if their unit was punished
3109 * with the loss of movement points. */
3112 /* TRANS: Spy ... movement point text that may include
3113 * fractions. */
3114 _("Your %s lost %s MP for attempting an illegal action."),
3117 }
3118
3119 return punishment_mp != 0 || punishment_hp != 0;
3120}
3121
3122/**********************************************************************/
3127static void illegal_action(struct player *pplayer,
3128 struct unit *actor,
3130 struct player *tgt_player,
3131 struct tile *target_tile,
3132 const struct city *target_city,
3133 const struct unit *target_unit,
3134 int request_kind,
3135 const enum action_requester requester)
3136{
3138 bool was_punished;
3139 const struct civ_map *nmap = &(wld.map);
3140
3142
3143 /* Why didn't the game check before trying something illegal? Did a good
3144 * reason to not call is_action_enabled_unit_on...() appear? The game is
3145 * omniscient... */
3147
3148
3150 nmap,
3152 actor,
3154 target_tile, nullptr));
3155
3156 if (request_kind == REQEST_PLAYER_INITIATED) {
3157 /* This is a foreground request. */
3162 }
3163
3167 requester);
3168
3169 if (request_kind != REQEST_PLAYER_INITIATED && was_punished) {
3170 /* FIXME: Temporary work around to prevent wrong information and/or
3171 * crashes. See hrm Bug #879880 */
3172 /* TODO: Get the explanation before the punishment and show it here.
3173 * See hrm Bug #879881 */
3174 notify_player(pplayer, unit_tile(actor),
3177 _("No explanation why you couldn't do %s. This is a bug."
3178 " Sorry about that. -- Sveinung"),
3180 }
3181}
3182
3183/**********************************************************************/
3187 const int actor_id,
3188 const int target_id,
3189 int request_kind)
3190{
3192 actor_id, target_id,
3193 0,
3195 request_kind);
3196}
3197
3198/**********************************************************************/
3206 const int actor_id,
3207 const int target_id,
3208 const action_id action_type,
3209 int request_kind)
3210{
3211 struct player *pplayer = pc->playing;
3212 struct unit *pactor = player_unit_by_number(pplayer, actor_id);
3213 struct action *paction = action_by_number(action_type);
3214 struct unit *punit = game_unit_by_number(target_id);
3215 struct city *pcity = game_city_by_number(target_id);
3216 struct tile *ptile = index_to_tile(&(wld.map), target_id);
3217 const struct civ_map *nmap = &(wld.map);
3218
3219 if (paction == nullptr) {
3220 /* Non existing action */
3221 log_error("handle_unit_action_query() the action %d doesn't exist.",
3222 action_type);
3223
3224 unit_query_impossible(pc, actor_id, target_id, request_kind);
3225 return;
3226 }
3227
3228 if (pactor == nullptr) {
3229 /* Probably died or bribed. */
3230 log_verbose("handle_unit_action_query() invalid actor %d",
3231 actor_id);
3232 unit_query_impossible(pc, actor_id, target_id, request_kind);
3233 return;
3234 }
3235
3236 switch (paction->result) {
3238 if (punit != nullptr
3239 && is_action_enabled_unit_on_unit(nmap, action_type,
3240 pactor, punit)) {
3242 actor_id, target_id,
3243 unit_bribe_cost(punit, pplayer,
3244 pactor),
3245 action_type, request_kind);
3246 } else {
3247 illegal_action(pplayer, pactor, action_type,
3248 punit ? unit_owner(punit) : nullptr,
3249 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3250 unit_query_impossible(pc, actor_id, target_id, request_kind);
3251 return;
3252 }
3253 break;
3255 if (ptile != nullptr
3256 && is_action_enabled_unit_on_stack(nmap, action_type,
3257 pactor, ptile)) {
3259 actor_id, target_id,
3260 stack_bribe_cost(ptile, pplayer,
3261 pactor),
3262 action_type, request_kind);
3263 } else {
3264 illegal_action(pplayer, pactor, action_type,
3265 punit ? unit_owner(punit) : nullptr,
3266 nullptr, nullptr, punit, request_kind, ACT_REQ_PLAYER);
3267 unit_query_impossible(pc, actor_id, target_id, request_kind);
3268 return;
3269 }
3270 break;
3272 if (pcity
3273 && is_action_enabled_unit_on_city(nmap, action_type,
3274 pactor, pcity)) {
3276 actor_id, target_id,
3277 city_incite_cost(pplayer, pcity),
3278 action_type, request_kind);
3279 } else {
3280 illegal_action(pplayer, pactor, action_type,
3281 pcity ? city_owner(pcity) : nullptr,
3282 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3283 unit_query_impossible(pc, actor_id, target_id, request_kind);
3284 return;
3285 }
3286 break;
3288 if (pcity
3289 && is_action_enabled_unit_on_city(nmap, action_type,
3290 pactor, pcity)) {
3291 const struct unit_type *tgt_utype;
3292 int upgr_cost;
3293
3295 /* Already checked via is_action_enabled_unit_on_city() */
3297 upgr_cost = unit_upgrade_price(pplayer,
3299
3301 actor_id, target_id,
3302 upgr_cost, action_type,
3303 request_kind);
3304 } else {
3305 illegal_action(pplayer, pactor, action_type,
3306 pcity ? city_owner(pcity) : nullptr,
3307 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3308 unit_query_impossible(pc, actor_id, target_id, request_kind);
3309 return;
3310 }
3311 break;
3314 if (pcity
3315 && is_action_enabled_unit_on_city(nmap, action_type,
3316 pactor, pcity)) {
3318 action_by_number(action_type), request_kind);
3319 } else {
3320 illegal_action(pplayer, pactor, action_type,
3321 pcity ? city_owner(pcity) : nullptr,
3322 nullptr, pcity, nullptr, request_kind, ACT_REQ_PLAYER);
3323 unit_query_impossible(pc, actor_id, target_id, request_kind);
3324 return;
3325 }
3326 break;
3327 default:
3328 unit_query_impossible(pc, actor_id, target_id, request_kind);
3329 return;
3330 };
3331}
3332
3333/**********************************************************************/
3338void handle_unit_do_action(struct player *pplayer,
3339 const int actor_id,
3340 const int target_id,
3341 const int sub_tgt_id,
3342 const char *name,
3343 const action_id action_type)
3344{
3345 (void) unit_perform_action(pplayer, actor_id, target_id, sub_tgt_id, name,
3346 action_type, ACT_REQ_PLAYER);
3347}
3348
3349/**********************************************************************/
3354void unit_do_action(struct player *pplayer,
3355 const int actor_id,
3356 const int target_id,
3357 const int sub_tgt_id,
3358 const char *name,
3359 const action_id action_type)
3360{
3361 unit_perform_action(pplayer, actor_id, target_id,
3362 sub_tgt_id, name, action_type, ACT_REQ_PLAYER);
3363}
3364
3365/**********************************************************************/
3374bool unit_perform_action(struct player *pplayer,
3375 const int actor_id,
3376 const int target_id,
3377 const int sub_tgt_id_incoming,
3378 const char *name,
3379 const action_id action_type,
3380 const enum action_requester requester)
3381{
3382 struct action *paction;
3383 int sub_tgt_id;
3384 struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
3385 struct tile *target_tile = nullptr;
3386 struct extra_type *target_extra;
3387 struct impr_type *sub_tgt_impr;
3388 struct unit *punit = nullptr;
3389 struct city *pcity = nullptr;
3390 struct specialist *sub_tgt_spec = nullptr;
3391 const struct civ_map *nmap = &(wld.map);
3392
3393 if (!action_id_exists(action_type)) {
3394 /* Non existing action */
3395 log_error("unit_perform_action() the action %d doesn't exist.",
3396 action_type);
3397
3398 return FALSE;
3399 }
3400
3401 paction = action_by_number(action_type);
3402
3403 if (actor_unit == nullptr) {
3404 /* Probably died or bribed. */
3405 log_verbose("unit_perform_action() invalid actor %d",
3406 actor_id);
3407 return FALSE;
3408 }
3409
3411 case ATK_CITY:
3412 pcity = game_city_by_number(target_id);
3413 if (pcity == nullptr) {
3414 log_verbose("unit_perform_action() invalid target city %d",
3415 target_id);
3416 return FALSE;
3417 }
3419 fc_assert_ret_val(target_tile != nullptr, FALSE);
3420 break;
3421 case ATK_UNIT:
3422 punit = game_unit_by_number(target_id);
3423 if (punit == nullptr) {
3424 log_verbose("unit_perform_action() invalid target unit %d",
3425 target_id);
3426 return FALSE;
3427 }
3429 fc_assert_ret_val(target_tile != nullptr, FALSE);
3431 break;
3432 case ATK_STACK:
3433 case ATK_TILE:
3434 case ATK_EXTRAS:
3435 target_tile = index_to_tile(nmap, target_id);
3436 if (target_tile == nullptr) {
3437 log_verbose("unit_perform_action() invalid target tile %d",
3438 target_id);
3439 return FALSE;
3440 }
3442 break;
3443 case ATK_SELF:
3445 fc_assert_ret_val(target_tile != nullptr, FALSE);
3447 break;
3448 case ATK_COUNT:
3450 break;
3451 }
3452
3453 /* Server side sub target assignment */
3454 if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
3457 } else {
3458 sub_tgt_id = sub_tgt_id_incoming;
3459 }
3460
3461 if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
3462 && sub_tgt_id != NO_TARGET) {
3463 target_extra = extra_by_number(sub_tgt_id);
3464 fc_assert(!(target_extra->ruledit_disabled));
3465 } else {
3466 target_extra = nullptr;
3467 }
3468
3469 sub_tgt_impr = improvement_by_number(sub_tgt_id);
3470 sub_tgt_spec = specialist_by_number(sub_tgt_id);
3471
3472 /* Sub targets should now be assigned */
3473 switch (paction->sub_target_kind) {
3474 case ASTK_NONE:
3475 /* No sub target. */
3476 break;
3477 case ASTK_BUILDING:
3478 if (sub_tgt_impr == nullptr) {
3479 /* Missing sub target */
3480 return FALSE;
3481 }
3482 break;
3483 case ASTK_TECH:
3484 /* Not handled here yet */
3485 break;
3486 case ASTK_EXTRA:
3488 if (target_extra == nullptr) {
3489 /* Missing sub target */
3490 return FALSE;
3491 }
3492 break;
3493 case ASTK_SPECIALIST:
3494 if (sub_tgt_spec == nullptr) {
3495 /* Missing sub target */
3496 return FALSE;
3497 }
3498 break;
3499 case ASTK_COUNT:
3500 break;
3501 }
3502
3506 && target_extra == nullptr) {
3507 /* Missing required action extra target. */
3508 log_verbose("unit_perform_action() action %d requires action "
3509 "but extra id %d is invalid.",
3510 action_type, sub_tgt_id);
3511 return FALSE;
3512 }
3513
3514 if (paction->actor.is_unit.unitwaittime_controlled
3516 /* Action not possible due to unitwaittime setting. */
3517 return FALSE;
3518 }
3519
3520#define ACTION_PERFORM_UNIT_CITY(action, actor, target, action_performer) \
3521 if (pcity \
3522 && is_action_enabled_unit_on_city(nmap, action_type, \
3523 actor_unit, pcity)) { \
3524 bool success; \
3525 script_server_signal_emit("action_started_unit_city", \
3526 action_by_number(action), actor, target); \
3527 if (!actor || !unit_is_alive(actor_id)) { \
3528 /* Actor unit was destroyed during pre action Lua. */ \
3529 return FALSE; \
3530 } \
3531 if (!target || !city_exist(target_id)) { \
3532 /* Target city was destroyed during pre action Lua. */ \
3533 return FALSE; \
3534 } \
3535 success = action_performer; \
3536 if (success) { \
3537 action_success_actor_price(paction, actor_id, actor); \
3538 } \
3539 script_server_signal_emit("action_finished_unit_city", \
3540 action_by_number(action), success, \
3541 unit_is_alive(actor_id) ? actor : nullptr, \
3542 city_exist(target_id) ? target : nullptr); \
3543 return success; \
3544 } else { \
3545 illegal_action(pplayer, actor_unit, action_type, \
3546 pcity ? city_owner(pcity) : nullptr, nullptr, pcity, \
3547 nullptr, TRUE, requester); \
3548 }
3549
3550#define ACTION_PERFORM_UNIT_SELF(action, actor, action_performer) \
3551 if (actor_unit \
3552 && is_action_enabled_unit_on_self(nmap, action_type, actor_unit)) { \
3553 bool success; \
3554 script_server_signal_emit("action_started_unit_self", \
3555 action_by_number(action), actor); \
3556 if (!actor || !unit_is_alive(actor_id)) { \
3557 /* Actor unit was destroyed during pre action Lua. */ \
3558 return FALSE; \
3559 } \
3560 success = action_performer; \
3561 if (success) { \
3562 action_success_actor_price(paction, actor_id, actor); \
3563 } \
3564 script_server_signal_emit("action_finished_unit_self", \
3565 action_by_number(action), success, \
3566 unit_is_alive(actor_id) ? actor : nullptr); \
3567 return success; \
3568 } else { \
3569 illegal_action(pplayer, actor_unit, action_type, \
3570 unit_owner(actor_unit), nullptr, nullptr, actor_unit, \
3571 TRUE, requester); \
3572 }
3573
3574#define ACTION_PERFORM_UNIT_UNIT(action, actor, target, action_performer) \
3575 if (punit \
3576 && is_action_enabled_unit_on_unit(nmap, action_type, actor_unit, punit)) { \
3577 bool success; \
3578 script_server_signal_emit("action_started_unit_unit", \
3579 action_by_number(action), actor, target); \
3580 if (!actor || !unit_is_alive(actor_id)) { \
3581 /* Actor unit was destroyed during pre action Lua. */ \
3582 return FALSE; \
3583 } \
3584 if (!target || !unit_is_alive(target_id)) { \
3585 /* Target unit was destroyed during pre action Lua. */ \
3586 return FALSE; \
3587 } \
3588 success = action_performer; \
3589 if (success) { \
3590 action_success_actor_price(paction, actor_id, actor); \
3591 action_success_target_pay_mp(paction, target_id, punit); \
3592 } \
3593 script_server_signal_emit("action_finished_unit_unit", \
3594 action_by_number(action), success, \
3595 unit_is_alive(actor_id) ? actor : nullptr, \
3596 unit_is_alive(target_id) ? target \
3597 : nullptr); \
3598 return success; \
3599 } else { \
3600 illegal_action(pplayer, actor_unit, action_type, \
3601 punit ? unit_owner(punit) : nullptr, nullptr, nullptr, \
3602 punit, TRUE, requester); \
3603 }
3604
3605#define ACTION_PERFORM_UNIT_STACK(action, actor, target, action_performer)\
3606 if (target_tile \
3607 && is_action_enabled_unit_on_stack(nmap, action_type, \
3608 actor_unit, target_tile)) { \
3609 bool success; \
3610 script_server_signal_emit("action_started_unit_stack", \
3611 action_by_number(action), actor, target); \
3612 script_server_signal_emit("action_started_unit_units", \
3613 action_by_number(action), actor, target); \
3614 if (!actor || !unit_is_alive(actor_id)) { \
3615 /* Actor unit was destroyed during pre action Lua. */ \
3616 return FALSE; \
3617 } \
3618 success = action_performer; \
3619 if (success) { \
3620 action_success_actor_price(paction, actor_id, actor); \
3621 } \
3622 script_server_signal_emit("action_finished_unit_stack", \
3623 action_by_number(action), success, \
3624 unit_is_alive(actor_id) ? actor : nullptr, \
3625 target); \
3626 script_server_signal_emit("action_finished_unit_units", \
3627 action_by_number(action), success, \
3628 unit_is_alive(actor_id) ? actor : nullptr, \
3629 target); \
3630 return success; \
3631 } else { \
3632 illegal_action(pplayer, actor_unit, action_type, \
3633 nullptr, target_tile, nullptr, nullptr, \
3634 TRUE, requester); \
3635 }
3636
3637#define ACTION_PERFORM_UNIT_TILE(action, actor, target, action_performer) \
3638 if (target_tile \
3639 && is_action_enabled_unit_on_tile(nmap, action_type, \
3640 actor_unit, target_tile, \
3641 target_extra)) { \
3642 bool success; \
3643 script_server_signal_emit("action_started_unit_tile", \
3644 action_by_number(action), actor, target); \
3645 if (!actor || !unit_is_alive(actor_id)) { \
3646 /* Actor unit was destroyed during pre action Lua. */ \
3647 return FALSE; \
3648 } \
3649 success = action_performer; \
3650 if (success) { \
3651 action_success_actor_price(paction, actor_id, actor); \
3652 } \
3653 script_server_signal_emit("action_finished_unit_tile", \
3654 action_by_number(action), success, \
3655 unit_is_alive(actor_id) ? actor : nullptr, \
3656 target); \
3657 return success; \
3658 } else { \
3659 illegal_action(pplayer, actor_unit, action_type, \
3660 target_tile ? tile_owner(target_tile) : nullptr, \
3661 target_tile, nullptr, nullptr, \
3662 TRUE, requester); \
3663 }
3664
3665#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)\
3666 if (target_tile \
3667 && is_action_enabled_unit_on_extras(nmap, action_type, \
3668 actor_unit, target_tile, \
3669 target_extra)) { \
3670 bool success; \
3671 script_server_signal_emit("action_started_unit_extras", \
3672 action_by_number(action), actor, target); \
3673 if (!actor || !unit_is_alive(actor_id)) { \
3674 /* Actor unit was destroyed during pre action Lua. */ \
3675 return FALSE; \
3676 } \
3677 success = action_performer; \
3678 if (success) { \
3679 action_success_actor_price(paction, actor_id, actor); \
3680 } \
3681 script_server_signal_emit("action_finished_unit_extras", \
3682 action_by_number(action), success, \
3683 unit_is_alive(actor_id) ? actor : nullptr, \
3684 target); \
3685 return success; \
3686 } else { \
3687 illegal_action(pplayer, actor_unit, action_type, \
3688 target_tile ? target_tile->extras_owner : nullptr, \
3689 target_tile, nullptr, nullptr, \
3690 TRUE, requester); \
3691 }
3692
3693#define ACTION_PERFORM_UNIT_ANY(paction, actor, \
3694 target_city, target_unit, target_tile, \
3695 action_performer) \
3696 switch (action_get_target_kind(paction)) { \
3697 case ATK_CITY: \
3698 ACTION_PERFORM_UNIT_CITY(paction->id, actor, target_city, \
3699 action_performer); \
3700 break; \
3701 case ATK_UNIT: \
3702 ACTION_PERFORM_UNIT_UNIT(paction->id, actor, target_unit, \
3703 action_performer); \
3704 break; \
3705 case ATK_STACK: \
3706 ACTION_PERFORM_UNIT_STACK(paction->id, actor, target_tile, \
3707 action_performer); \
3708 break; \
3709 case ATK_TILE: \
3710 ACTION_PERFORM_UNIT_TILE(paction->id, actor, target_tile, \
3711 action_performer); \
3712 break; \
3713 case ATK_EXTRAS: \
3714 ACTION_PERFORM_UNIT_EXTRAS(paction->id, actor, target_tile, \
3715 action_performer); \
3716 break; \
3717 case ATK_SELF: \
3718 ACTION_PERFORM_UNIT_SELF(paction->id, actor, TRUE); \
3719 break; \
3720 case ATK_COUNT: \
3721 fc_assert(action_get_target_kind(paction) != ATK_COUNT); \
3722 break; \
3723 }
3724
3725 switch (paction->result) {
3729 paction));
3730 break;
3732 /* Difference is caused by data in the action structure. */
3735 punit, paction));
3736 break;
3737 case ACTRES_EXPEL_UNIT:
3739 do_expel_unit(pplayer, actor_unit, punit,
3740 paction));
3741 break;
3742 case ACTRES_HEAL_UNIT:
3744 do_heal_unit(pplayer, actor_unit, punit,
3745 paction));
3746 break;
3750 paction));
3751 break;
3755 paction));
3756 break;
3759 do_unit_board(pplayer, actor_unit, punit,
3760 paction));
3761 break;
3764 do_unit_load(pplayer, actor_unit, punit,
3765 paction));
3766 break;
3770 paction));
3771 break;
3773 /* All consequences are handled by the action system. */
3775 break;
3776 case ACTRES_FORTIFY:
3779 break;
3780 case ACTRES_CONVERT:
3783 break;
3784 case ACTRES_HOMELESS:
3787 break;
3788 case ACTRES_SPY_ESCAPE:
3790 spy_escape(pplayer, actor_unit,
3792 break;
3794 /* Difference is caused by data in the action structure. */
3797 B_LAST, paction));
3798 break;
3800 /* Difference is caused by data in the action structure. */
3803 sub_tgt_impr->item_number,
3804 paction));
3805 break;
3807 /* Difference is caused by data in the action structure. */
3810 -1, paction));
3811 break;
3812 case ACTRES_SPY_POISON:
3813 /* Difference is caused by data in the action structure. */
3815 spy_poison(pplayer, actor_unit, pcity,
3816 paction));
3817 break;
3821 paction));
3822 break;
3824 /* Difference is caused by data in the action structure. */
3826 diplomat_investigate(pplayer,
3828 paction));
3829 break;
3831 /* Difference is caused by data in the action structure. */
3834 paction));
3835 break;
3837 /* Difference is caused by data in the action structure. */
3840 paction));
3841 break;
3843 /* Difference is caused by data in the action structure. */
3846 A_UNSET, paction));
3847 break;
3849 /* Difference is caused by data in the action structure. */
3852 sub_tgt_id, paction));
3853 break;
3855 /* Difference is caused by data in the action structure. */
3858 paction));
3859 break;
3860 case ACTRES_STEAL_MAPS:
3861 /* Difference is caused by data in the action structure. */
3864 pcity, paction));
3865 break;
3866 case ACTRES_TRADE_ROUTE:
3869 pcity, paction));
3870 break;
3871 case ACTRES_MARKETPLACE:
3874 pcity, paction));
3875 break;
3876 case ACTRES_HELP_WONDER:
3878 unit_do_help_build(pplayer,
3880 paction));
3881 break;
3882 case ACTRES_SPY_NUKE:
3883 /* Difference is caused by data in the action structure. */
3885 spy_nuke_city(pplayer, actor_unit, pcity,
3886 paction));
3887 break;
3888 case ACTRES_JOIN_CITY:
3890 city_add_unit(pplayer, actor_unit, pcity,
3891 paction));
3892 break;
3895 unit_do_destroy_city(pplayer,
3897 paction));
3898 break;
3902 paction));
3903 break;
3904 case ACTRES_HOME_CITY:
3907 paction));
3908 break;
3911 do_unit_upgrade(pplayer, actor_unit,
3913 break;
3915 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3918 pcity, paction));
3919 break;
3923 actor_unit,
3924 pcity,
3925 sub_tgt_impr->item_number,
3926 paction));
3927 break;
3931 actor_unit,
3932 pcity,
3933 paction));
3934 break;
3939 break;
3940 case ACTRES_AIRLIFT:
3943 break;
3948 break;
3949 case ACTRES_BOMBARD:
3950 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3953 paction));
3954 break;
3955 case ACTRES_ATTACK:
3957 /* Difference is caused by data in the action structure. */
3960 break;
3961 case ACTRES_WIPE_UNITS:
3964 break;
3969 break;
3970 case ACTRES_NUKE_UNITS:
3973 paction));
3974 break;
3975 case ACTRES_SPY_ATTACK:
3978 paction));
3979 break;
3980 case ACTRES_FOUND_CITY:
3982 city_build(pplayer, actor_unit,
3984 break;
3985 case ACTRES_NUKE:
3989 paction));
3990 break;
3991 case ACTRES_PARADROP:
3995 break;
3997 /* Difference is caused by the ruleset. ("Fake generalized" actions) */
3999 do_disembark(pplayer, actor_unit,
4001 break;
4002 case ACTRES_HUT_ENTER:
4004 do_unit_hut(pplayer, actor_unit,
4006 break;
4009 do_unit_hut(pplayer, actor_unit,
4011 break;
4012 case ACTRES_UNIT_MOVE:
4016 break;
4017 case ACTRES_TELEPORT:
4021 nullptr, FALSE,
4024 FALSE, FALSE));
4025 break;
4026 case ACTRES_SCOUT:
4029 break;
4033 break;
4034 case ACTRES_CULTIVATE:
4037 break;
4038 case ACTRES_PLANT:
4041 break;
4042 case ACTRES_PILLAGE:
4045 paction,
4046 &target_extra));
4047 break;
4048 case ACTRES_CLEAN:
4051 paction,
4052 &target_extra));
4053 break;
4054 case ACTRES_ROAD:
4057 paction,
4058 &target_extra));
4059 break;
4060 case ACTRES_BASE:
4063 paction,
4064 &target_extra));
4065 break;
4066 case ACTRES_MINE:
4069 paction,
4070 &target_extra));
4071 break;
4072 case ACTRES_IRRIGATE:
4075 paction,
4076 &target_extra));
4077 break;
4078 case ACTRES_NONE:
4079 /* 100% ruleset defined. */
4081 TRUE);
4082 break;
4085 return FALSE;
4086
4088 }
4089
4090 /* Something must have gone wrong. */
4091 return FALSE;
4092}
4093
4094/**********************************************************************/
4102 bool rehome)
4103{
4105 struct player *old_owner = unit_owner(punit);
4106 struct player *new_owner = (new_pcity == nullptr ? old_owner
4108 const struct civ_map *nmap = &(wld.map);
4109
4110 /* Calling this function when new_pcity is same as old_pcity should
4111 * be safe with current implementation, but it is not meant to
4112 * be used that way. */
4114
4115 /* If 'rehome' is not set, this function should only be used to change
4116 * which player owns the unit */
4118
4119 if (old_owner != new_owner) {
4120 struct city *pcity = tile_city(punit->tile);
4121
4124
4127
4128 if (pcity != nullptr
4130 /* Special case when city is being transferred. At this point city
4131 * itself has changed owner, so it's enemy city now that old owner
4132 * cannot see inside. All the normal methods of removing transferred
4133 * unit from previous owner's client think that there's no need to
4134 * remove unit as client shouldn't have it in first place. */
4136 }
4137
4138 /* Remove AI control of the old owner. */
4139 CALL_PLR_AI_FUNC(unit_lost, old_owner, punit);
4140
4144
4145 /* Activate AI control of the new owner. */
4146 CALL_PLR_AI_FUNC(unit_got, new_owner, punit);
4147
4150 }
4151
4152 if (rehome) {
4153 /* Remove from old city first and add to new city only after that. */
4154 if (old_pcity) {
4155 /* Even if unit is dead, we have to unlink unit pointer (punit). */
4156 unit_list_remove(old_pcity->units_supported, punit);
4157 /* Update unit upkeep */
4159 }
4160
4161 if (new_pcity != nullptr) {
4162 unit_list_prepend(new_pcity->units_supported, punit);
4163
4164 /* Update unit upkeep */
4166
4167 punit->homecity = new_pcity->id;
4168 } else {
4170 }
4171 }
4172
4174 /* This is mainly for cases where unit owner changes to one not knowing
4175 * Railroad tech when unit is already building railroad.
4176 * Does also send_unit_info() */
4178 } else {
4179 /* Send info to players and observers. */
4180 send_unit_info(nullptr, punit);
4181 }
4182
4183 if (new_pcity != nullptr) {
4187 }
4188
4189 if (old_pcity) {
4193 }
4194
4196
4197 if (old_owner != new_owner) {
4198 script_server_signal_emit("unit_transferred", punit, old_owner);
4199 }
4200}
4201
4202/**********************************************************************/
4208 struct city *pcity,
4209 const struct action *paction)
4210{
4211 const char *giver = nullptr;
4212
4213 if (unit_owner(punit) != city_owner(pcity)) {
4214 /* This is a gift. Tell the receiver. */
4215 giver = player_name(unit_owner(punit));
4216 }
4217
4219
4220 if (punit->homecity == pcity->id && giver) {
4221 /* Notify the city owner about the gift they received. */
4223 ftc_server,
4224 /* TRANS: other player ... unit type ... city name. */
4225 _("%s transferred control over a %s to you in %s."),
4226 giver,
4228 city_link(pcity));
4229 }
4230
4231 return punit->homecity == pcity->id;
4232}
4233
4234/**********************************************************************/
4241static bool city_add_unit(struct player *pplayer, struct unit *punit,
4242 struct city *pcity, const struct action *paction)
4243{
4245 const struct unit_type *act_utype;
4246 int new_food;
4248
4249 /* Sanity check: The actor is still alive. */
4251
4253
4254 /* Sanity check: The target city still exists. */
4256
4258
4260 /* Preserve old food stock, unless granary effect gives us more. */
4261 pcity->food_stock = MAX(pcity->food_stock, new_food);
4262
4264
4265 if (is_super_specialist(act_utype->spec_type)) {
4267
4269 pcity->specialists[sspec]++;
4270 /* Refresh the city data. */
4272 } else {
4274 /* Make the new people something, otherwise city fails the checks */
4275 pcity->specialists[DEFAULT_SPECIALIST] += amount;
4276 /* Make the new people do something useful */
4277 auto_arrange_workers(pcity); /* this calls city_refresh(pcity) */
4278 }
4279
4280 /* Notify the unit owner that the unit successfully joined the city. */
4282 _("%s added to aid %s in growing."),
4284 city_link(pcity));
4285 if (pplayer != city_owner(pcity)) {
4286 /* Notify the city owner when a foreign unit joins a city. */
4288 ftc_server,
4289 /* TRANS: another player had their unit join your city. */
4290 _("%s adds %s to your city %s."),
4293 city_link(pcity));
4294 }
4295
4298 city_link(pcity));
4299
4301
4302 send_city_info(nullptr, pcity);
4303
4304 script_server_signal_emit("city_size_change", pcity,
4305 (lua_Integer)amount, "unit_added");
4306
4307 return TRUE;
4308}
4309
4310/**********************************************************************/
4319static bool city_build(struct player *pplayer, struct unit *punit,
4320 struct tile *ptile, const char *name,
4321 const struct action *paction)
4322{
4323 char message[1024];
4324 int size;
4325 struct player *nationality;
4326 struct player *towner;
4327 const struct unit_type *act_utype;
4329 struct city *pcity;
4330
4331 /* Sanity check: The actor still exists. */
4332 fc_assert_ret_val(pplayer, FALSE);
4334
4335 towner = tile_owner(ptile);
4336
4337 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
4338 notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
4339 "%s", message);
4340 return FALSE;
4341 }
4342
4344 sid = specialist_index(act_utype->spec_type);
4346
4347 create_city(pplayer, ptile, name, nationality);
4348 size = act_utype->city_size;
4349 pcity = tile_city(ptile); /* A callback may destroy or replace it any time */
4350 if (nullptr != pcity) {
4351 if (is_super_specialist_id(sid) && pcity->specialists[sid] < MAX_CITY_SIZE) {
4352 pcity->specialists[sid]++;
4353 }
4354 if (size > 1) {
4355 city_change_size(pcity, size, nationality, -1, nullptr);
4356 }
4357 }
4358
4359 /* May cause an incident even if the target tile is unclaimed. A ruleset
4360 * could give everyone a casus belli against the city founder. A rule
4361 * like that would make sense in a story where deep ecology is on the
4362 * table. (See also Voluntary Human Extinction Movement) */
4364 ptile, tile_link(ptile));
4365
4366 return TRUE;
4367}
4368
4369/**********************************************************************/
4372static void handle_unit_change_activity_real(struct player *pplayer,
4373 int unit_id,
4374 enum unit_activity activity,
4375 struct extra_type *activity_target,
4377{
4378 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4379
4380 if (punit == nullptr) {
4381 /* Probably died or bribed. */
4382 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id);
4383 return;
4384 }
4385
4386 if (punit->activity == activity
4388 return;
4389 }
4390
4391 /* Remove city spot reservations for AI settlers on city founding
4392 * mission, before goto_tile reset. */
4393 if (punit->server.adv->task != AUT_NONE) {
4394 adv_unit_new_task(punit, AUT_NONE, nullptr);
4395 }
4396
4397 if (activity == ACTIVITY_GOTO) {
4398 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
4399 * Setting ACTIVITY_GOTO from the client results in a unit indicating
4400 * it is going somewhere while it is standing still. The appearance of
4401 * the unit doing something can trick the user to not make use of it.
4402 *
4403 * Handled here because adv_follow_path() uses unit_activity_handling()
4404 * to set a unit's activity to ACTIVITY_GOTO. */
4405 return;
4406 }
4407
4408 if (activity == ACTIVITY_EXPLORE) {
4409 /* Please use unit_server_side_agent_set(). */
4410 return;
4411 }
4412
4413 punit->goto_tile = nullptr;
4414
4415 /* The activity can now be set. */
4418}
4419
4420/**********************************************************************/
4423void handle_unit_change_activity(struct player *pplayer, int unit_id,
4425 int target_id)
4426{
4427 struct extra_type *activity_target;
4428
4430 activity_target = nullptr;
4431 } else {
4432 activity_target = extra_by_number(target_id);
4433 }
4434
4435#ifdef FREECIV_WEB
4436 /* Web-client is not capable of selecting target, so we do it server side */
4437 if (activity_target == nullptr) {
4438 struct unit *punit = player_unit_by_number(pplayer, unit_id);
4439 bool required = TRUE;
4440
4441 if (punit == nullptr) {
4442 return;
4443 }
4444
4445 if (activity == ACTIVITY_IRRIGATE) {
4446 struct tile *ptile = unit_tile(punit);
4447
4448 activity_target = next_extra_for_tile(ptile, EC_IRRIGATION,
4449 pplayer, punit);
4450 } else if (activity == ACTIVITY_MINE) {
4451 struct tile *ptile = unit_tile(punit);
4452
4453 activity_target = next_extra_for_tile(ptile, EC_MINE,
4454 pplayer, punit);
4455 } else if (activity == ACTIVITY_BASE) {
4456 struct tile *ptile = unit_tile(punit);
4457 struct base_type *pbase =
4459
4460 if (pbase != nullptr) {
4461 activity_target = base_extra_get(pbase);
4462 }
4463
4464 } else if (activity == ACTIVITY_CLEAN) {
4465 activity_target = prev_extra_in_tile(unit_tile(punit), ERM_CLEAN,
4466 pplayer, punit);
4467 } else {
4468 required = FALSE;
4469 }
4470
4471 if (activity_target == nullptr && required) {
4472 /* Nothing more we can do */
4473 return;
4474 }
4475 }
4476#endif /* FREECIV_WEB */
4477
4478 handle_unit_change_activity_real(pplayer, unit_id, activity, activity_target,
4479 activity_default_action(activity));
4480}
4481
4482/**********************************************************************/
4485static void see_combat(struct unit *pattacker, struct unit *pdefender)
4486{
4489
4490 /*
4491 * Special case for attacking/defending:
4492 *
4493 * Normally the player doesn't get the information about the units inside a
4494 * city. However for attacking/defending the player has to know the unit of
4495 * the other side. After the combat a remove_unit packet will be sent
4496 * to the client to tidy up.
4497 *
4498 * Note these packets must be sent out before unit_versus_unit() is called,
4499 * so that the original unit stats (HP) will be sent.
4500 */
4507
4509 struct player *pplayer = pconn->playing;
4510
4511 if (pplayer != nullptr) {
4512
4513 /* NOTE: this means the player can see combat between submarines even
4514 * if neither sub is visible. See similar comment in send_combat(). */
4517 V_MAIN)) {
4518
4519 /* Units are sent even if they were visible already. They may
4520 * have changed orientation for combat. */
4521 if (pplayer == unit_owner(pattacker)) {
4523 } else {
4525 }
4526
4527 if (pplayer == unit_owner(pdefender)) {
4529 } else {
4531 }
4532 }
4533 } else if (pconn->observer) {
4534 /* Global observer sees everything... */
4537 }
4539}
4540
4541/**********************************************************************/
4544static void send_combat(struct unit *pattacker, struct unit *pdefender,
4545 int att_veteran, int def_veteran, int bombard)
4546{
4548
4550 combat.defender_unit_id = pdefender->id;
4551 combat.attacker_hp = pattacker->hp;
4552 combat.defender_hp = pdefender->hp;
4553 combat.make_att_veteran = att_veteran;
4554 combat.make_def_veteran = def_veteran;
4555
4556 players_iterate(other_player) {
4557 /* NOTE: this means the player can see combat between submarines even
4558 * if neither sub is visible. See similar comment in see_combat. */
4559 if (map_is_known_and_seen(unit_tile(pattacker), other_player, V_MAIN)
4560 || map_is_known_and_seen(unit_tile(pdefender), other_player,
4561 V_MAIN)) {
4562 lsend_packet_unit_combat_info(other_player->connections, &combat);
4563
4564 /*
4565 * Remove the client knowledge of the units. This corresponds to the
4566 * send_packet_unit_short_info() calls up above.
4567 */
4568 if (!can_player_see_unit(other_player, pattacker)) {
4569 unit_goes_out_of_sight(other_player, pattacker);
4570 }
4571 if (!can_player_see_unit(other_player, pdefender)) {
4572 unit_goes_out_of_sight(other_player, pdefender);
4573 }
4574 }
4576
4577 /* Send combat info to non-player observers as well. They already know
4578 * about the unit so no unit_info is needed. */
4580 if (pconn->playing == nullptr && pconn->observer) {
4582 }
4584}
4585
4586/**********************************************************************/
4590 struct city *pcity,
4591 const struct action *paction,
4592 const char *reason)
4593{
4594 struct player *pplayer = unit_owner(punit);
4595
4596 if (pcity
4597 && get_target_bonus_effects(nullptr,
4598 &(const struct req_context) {
4599 .player = city_owner(pcity),
4600 .city = pcity,
4601 .tile = city_tile(pcity),
4602 .unit = punit,
4603 .unittype = unit_type_get(punit),
4604 .action = paction,
4605 },
4606 nullptr, EFT_UNIT_NO_LOSE_POP) <= 0
4609 struct player *cplayer = city_owner(pcity);
4610 struct tile *ctile = city_tile(pcity);
4611 const char *clink = city_link(pcity);
4612
4613 if (city_reduce_size(pcity, 1, pplayer, reason)) {
4615 send_city_info(nullptr, pcity);
4616 } else {
4618 /* TRANS: Battleship ... Los Angeles ... Bombard */
4619 _("Your %s destroyed %s by doing %s."),
4624 /* TRANS: Sigurd I Magnusson ... Alkasse ... Attack */
4625 _("%s destroyed %s by doing %s."),
4626 player_name(pplayer), clink,
4628 }
4629 }
4630}
4631
4632/**********************************************************************/
4639static bool unit_bombard(struct unit *punit, struct tile *ptile,
4640 const struct action *paction)
4641{
4642 struct player *pplayer = unit_owner(punit);
4643 struct city *pcity = tile_city(ptile);
4644 const struct unit_type *act_utype;
4645 const struct civ_map *nmap = &(wld.map);
4646
4647 /* Sanity check: The actor still exists. */
4648 fc_assert_ret_val(pplayer, FALSE);
4650
4652
4653 log_debug("Start bombard: %s %s to %d, %d.",
4655 unit_rule_name(punit), TILE_XY(ptile));
4656
4658 if (is_unit_reachable_at(pdefender, punit, ptile)) {
4659 bool adj;
4660 enum direction8 facing;
4661 int att_hp, def_hp;
4662
4664 punit->tile, pdefender->tile, &facing);
4665
4666 if (adj) {
4667 punit->facing = facing;
4668
4669 /* Unlike with normal attack, we don't change orientation of
4670 * defenders when bombarding */
4671 }
4672
4673 unit_bombs_unit(punit, pdefender, &att_hp, &def_hp, paction);
4674
4675 if (def_hp <= 0) {
4676 notify_player(pplayer, ptile,
4678 /* TRANS: Your Bomber killed the English Rifleman by
4679 * doing Bombard. */
4680 _("Your %s killed the %s %s by doing %s."),
4687 /* TRANS: Your Rifleman was killed by the French
4688 * Bomber doing Bombard. */
4689 _("Your %s was killed by the %s %s doing %s."),
4694 } else {
4695 notify_player(pplayer, ptile,
4697 /* TRANS: Your Bomber bombards the English Rifleman. */
4698 _("Your %s bombards the %s %s."),
4704 /* TRANS: Your Rifleman is bombarded by the French
4705 * Bomber. */
4706 _("Your %s is bombarded by the %s %s."),
4710 }
4711
4713
4714 punit->hp = att_hp;
4715 pdefender->hp = def_hp;
4716
4717 send_combat(punit, pdefender, 0, 0, 1);
4718
4719 /* May cause an incident */
4725
4726 if (def_hp <= 0) {
4728 } else {
4729 send_unit_info(nullptr, pdefender);
4730 }
4731 }
4732
4734
4737
4739
4740 send_unit_info(nullptr, punit);
4741
4742 return TRUE;
4743}
4744
4745/**********************************************************************/
4756static bool unit_nuke(struct player *pplayer, struct unit *punit,
4757 struct tile *def_tile, const struct action *paction)
4758{
4759 struct city *pcity;
4760 const struct unit_type *act_utype;
4761 struct civ_map *nmap = &(wld.map);
4762
4763 /* Sanity check: The actor still exists. */
4764 fc_assert_ret_val(pplayer, FALSE);
4766
4768
4769 log_debug("Start nuclear attack: %s %s against (%d, %d).",
4772 TILE_XY(def_tile));
4773
4774 if ((pcity = sdi_try_defend(nmap, pplayer, def_tile))) {
4775 /* FIXME: Remove the hard coded reference to SDI defense. */
4777 _("Your %s was shot down by "
4778 "SDI defenses, what a waste."), unit_tile_link(punit));
4780 _("The nuclear attack on %s was avoided by"
4781 " your SDI defense."), city_link(pcity));
4782
4783 /* Trying to nuke something this close can be... unpopular. */
4787
4788 /* Remove the destroyed nuke. */
4790
4791 return FALSE;
4792 }
4793
4795
4796
4797 /* The nuke must be wiped here so it won't be seen as a victim of its own
4798 * detonation. */
4799 if (paction->actor_consuming_always) {
4800 wipe_unit(punit, ULR_DETONATED, nullptr);
4801 }
4802
4804
4805 /* May cause an incident even if the target tile is unclaimed. A ruleset
4806 * could give everyone a casus belli against the tile nuker. A rule
4807 * like that would make sense in a story where detonating any nuke at all
4808 * could be forbidden. */
4811 def_tile,
4813
4814 return TRUE;
4815}
4816
4817/**********************************************************************/
4827 struct unit *act_unit,
4828 struct city *tgt_city,
4829 const struct action *paction)
4830{
4831 int tgt_city_id;
4832 struct player *tgt_player;
4833 bool capital;
4834 bool try_civil_war = FALSE;
4835 const struct unit_type *act_utype;
4836
4837 /* Sanity check: The actor still exists. */
4840
4842
4843 /* Sanity check: The target city still exists. */
4845
4847
4848 /* How can a city be ownerless? */
4850
4851 /* Save city ID. */
4852 tgt_city_id = tgt_city->id;
4853
4855
4856 if (capital
4857 && (tgt_player->spaceship.state == SSHIP_STARTED
4858 || tgt_player->spaceship.state == SSHIP_LAUNCHED)) {
4859 /* Destroying this city destroys the victim's space ship. */
4861 }
4862
4863 if (capital
4867 /* Destroying this city can trigger a civil war. */
4869 }
4870
4871 /* Let the actor know. */
4874 _("You destroy %s completely."),
4876
4877 if (tgt_player != act_player) {
4878 /* This was done to a foreign city. Inform the victim player. */
4881 _("%s has been destroyed by %s."),
4884 }
4885
4886 /* May cause an incident */
4890
4891 /* Run post city destruction Lua script. */
4893 act_player);
4894
4895 /* Can't be sure of city existence after running script. */
4896 if (city_exist(tgt_city_id)) {
4898 }
4899
4900 if (try_civil_war) {
4901 /* Try to start the civil war. */
4903 }
4904
4905 /* The city is no more. */
4906 return TRUE;
4907}
4908
4909/**********************************************************************/
4914static const char *unit_veteran_level_string(const struct unit *punit)
4915{
4916 static char buf[MAX_LEN_LINK];
4917 const struct veteran_level *vlevel;
4918
4919 if (!punit) {
4920 buf[0] = '\0'; /* If no unit, return empty string */
4921 return buf;
4922 }
4923
4925 fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
4926
4927 return buf;
4928}
4929
4930/**********************************************************************/
4935static const char *unit_achieved_rank_string(const struct unit *punit)
4936{
4937 static char buf[MAX_LEN_LINK];
4938
4939 fc_snprintf(buf, sizeof(buf),
4940 /* TRANS: " and achieved the rank of <veteran level>";
4941 * preserve leading space */
4942 _(" and achieved the rank of %s"),
4944 return buf;
4945}
4946
4947/**********************************************************************/
4952static const char *unit_tired_attack_string(const struct unit *punit)
4953{
4954 static char buf[MAX_LEN_LINK];
4955
4957 fc_snprintf(buf, sizeof(buf),
4958 /* TRANS: tired; note trailing space */
4959 _("tired "));
4960 } else {
4961 buf[0] = '\0';
4962 }
4963
4964 return buf;
4965}
4966
4967/**********************************************************************/
4974static const char *unit_firepower_if_not_one(int firepower)
4975{
4976 static char buf[MAX_LEN_LINK];
4977
4978 if (firepower == 1) {
4979 buf[0] = '\0';
4980 } else {
4981 fc_snprintf(buf, sizeof(buf),
4982 /* TRANS: FP = Firepower of a unit; note trailing space */
4983 _("FP:%d "),
4984 firepower);
4985 }
4986
4987 return buf;
4988}
4989
4990/**********************************************************************/
4999static bool do_attack(struct unit *punit, struct tile *def_tile,
5000 const struct action *paction)
5001{
5006 struct unit *ploser, *pwinner;
5009 int winner_id;
5010 struct player *pplayer = unit_owner(punit);
5011 bool adj;
5012 enum direction8 facing;
5013 int att_hp, def_hp, att_fp, def_fp;
5015 int def_power, att_power;
5016 int att_vet, def_vet;
5017 struct unit *pdefender;
5018 const struct unit_type *act_utype = unit_type_get(punit);
5019 struct civ_map *nmap = &(wld.map);
5020 bool powerless;
5021
5023 /* Can't fight air... */
5024 return FALSE;
5025 }
5026
5028 def_hp_start = pdefender->hp;
5032
5033 log_debug("Start attack: %s %s against %s %s.",
5038
5039 /* Sanity checks */
5044 FALSE,
5045 "Trying to attack a unit with which you have peace "
5046 "or cease-fire at (%d, %d).", TILE_XY(def_tile));
5050 FALSE,
5051 "Trying to attack a unit with which you have "
5052 "alliance at (%d, %d).", TILE_XY(def_tile));
5053
5056
5058 punit->tile, pdefender->tile, &facing);
5059
5060 fc_assert(adj);
5061 if (adj) {
5062 punit->facing = facing;
5063 pdefender->facing = opposite_direction(facing);
5064 }
5065
5067 old_defender_vet = pdefender->veteran;
5068
5069 /* N.B.: unit_veteran_level_string always returns the same pointer. */
5072
5073 /* N.B.: unit_firepower_if_not_one always returns the same pointer. */
5076
5077 /* Record tired attack string before attack */
5079
5080 powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp,
5081 &att_vet, &def_vet, paction);
5082
5083 if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype))
5084 && unit_transported(punit)) {
5085 /* Dying attacker must be first unloaded so it doesn't die inside transport */
5087 }
5088
5090
5091 punit->hp = att_hp;
5092 pdefender->hp = def_hp;
5093
5095
5096 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
5097 * the movement attack modifier is correct! --dwp
5098 *
5099 * For greater Civ2 compatibility (and game balance issues), we recompute
5100 * the new total MP based on the HP the unit has left after being damaged,
5101 * and subtract the MPs that had been used before the combat (plus the
5102 * points used in the attack itself, for the attacker). -GJW, Glip
5103 */
5106
5107 if (punit->moves_left < 0) {
5108 punit->moves_left = 0;
5109 }
5110 if (pdefender->moves_left < 0) {
5111 pdefender->moves_left = 0;
5112 }
5115
5116 /* This may cause a diplomatic incident. */
5120
5121 if (punit->hp > 0 && pdefender->hp > 0) {
5122 /* Neither died */
5124 pdefender->veteran - old_defender_vet, 0);
5125 return TRUE;
5126 }
5127 pwinner = (punit->hp > 0) ? punit : pdefender;
5128 winner_id = pwinner->id;
5129 ploser = (pdefender->hp > 0) ? punit : pdefender;
5130
5131 vet = (pwinner->veteran == ((punit->hp > 0) ? old_unit_vet :
5132 old_defender_vet)) ? 0 : 1;
5133
5135 pdefender->veteran - old_defender_vet, 0);
5136
5137 /* N.B.: unit_link always returns the same pointer. */
5142
5143 if (punit == ploser) {
5144 /* The attacker lost */
5145 log_debug("Attacker lost: %s %s against %s %s.",
5150
5154 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5155 * 9 HP remaining] survived the pathetic ...attack from
5156 * green Warriors [id:90 ...A:1.0 HP:10]. */
5157 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5158 " survived the pathetic %sattack from %s %s "
5159 "[id:%d %sA:%.1f HP:%d]."),
5162 pdefender->id,
5164 (float)def_power/POWER_FACTOR,
5165 def_hp_start - pdefender->hp,
5166 pdefender->hp,
5169 loser_link,
5170 punit->id,
5172 (float)att_power/POWER_FACTOR,
5173 att_hp_start);
5174 } else {
5177 /* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
5178 * 9 HP remaining] survived the pathetic ...attack from the
5179 * Greek green Warriors [id:90 ...A:1.0 HP:10]. */
5180 _("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
5181 " survived the pathetic %sattack from the %s %s %s "
5182 "[id:%d %sA:%.1f HP:%d]."),
5185 pdefender->id,
5187 (float)def_power/POWER_FACTOR,
5188 def_hp_start - pdefender->hp,
5189 pdefender->hp,
5193 loser_link,
5194 punit->id,
5196 (float)att_power/POWER_FACTOR,
5197 att_hp_start);
5198 }
5199
5200 if (vet) {
5202 }
5203
5207 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5208 * failed against green Destroyer [id:200 lost
5209 * 27 HP, 3 HP remaining%s]!";
5210 * last %s is either "and ..." or empty string */
5211 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5212 "against %s %s [id:%d lost %d HP, %d HP "
5213 "remaining%s]!"),
5215 loser_link,
5216 punit->id,
5218 (float)att_power/POWER_FACTOR,
5222 pdefender->id,
5223 def_hp_start - pdefender->hp,
5224 pdefender->hp,
5226 } else {
5229 /* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
5230 * failed against the Polish green Destroyer [id:200 lost
5231 * 27 HP, 3 HP remaining%s]!";
5232 * last %s is either "and ..." or empty string */
5233 _("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
5234 "against the %s %s %s [id:%d lost %d HP, %d HP "
5235 "remaining%s]!"),
5237 loser_link,
5238 punit->id,
5240 (float)att_power/POWER_FACTOR,
5245 pdefender->id,
5246 def_hp_start - pdefender->hp,
5247 pdefender->hp,
5249 }
5250
5252 } else {
5253 /* The defender lost, the attacker punit lives! */
5254 struct city *pcity;
5255
5256 log_debug("Defender lost: %s %s against %s %s.",
5261
5265 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5266 * lost to an attack by green Legion
5267 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5268 * last %s is either "and ..." or empty string */
5269 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5270 "%s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5271 "remaining%s]."),
5273 loser_link,
5274 pdefender->id,
5276 (float)def_power/POWER_FACTOR,
5280 punit->id,
5282 (float)att_power/POWER_FACTOR,
5283 att_hp_start - pwinner->hp,
5284 pwinner->hp,
5286 } else {
5289 /* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
5290 * lost to an attack by the Greek green Legion
5291 * [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
5292 * last %s is either "and ..." or empty string */
5293 _("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
5294 "the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
5295 "remaining%s]."),
5297 loser_link,
5298 pdefender->id,
5300 (float)def_power/POWER_FACTOR,
5305 punit->id,
5307 (float)att_power/POWER_FACTOR,
5308 att_hp_start - pwinner->hp,
5309 pwinner->hp,
5311 }
5312
5316 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5317 * lost 1 HP, has 9 HP remaining] succeeded against
5318 * green Warriors [id:100 HP:10]." */
5319 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5320 "has %d remaining] succeeded against %s %s "
5321 "[id:%d HP:%d]."),
5324 punit->id,
5327 (float)att_power/POWER_FACTOR,
5328 att_hp_start - pwinner->hp,
5329 pwinner->hp,
5331 loser_link,
5332 pdefender->id,
5333 def_hp_start);
5334 } else {
5337 /* TRANS: "Your attacking green Legion [id:200 ...A:4.0
5338 * lost 1 HP, has 9 HP remaining] succeeded against the
5339 * Greek green Warriors [id:100 HP:10]." */
5340 _("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
5341 "has %d remaining] succeeded against the %s %s %s "
5342 "[id:%d HP:%d]."),
5345 punit->id,
5348 (float)att_power/POWER_FACTOR,
5349 att_hp_start - pwinner->hp,
5350 pwinner->hp,
5353 loser_link,
5354 pdefender->id,
5355 def_hp_start);
5356 }
5357
5358 punit->moved = TRUE; /* We moved */
5359
5360 if (paction->result == ACTRES_COLLECT_RANSOM) {
5363 } else {
5366 }
5367
5368 /* Now that dead defender is certainly no longer listed as unit
5369 * supported by the city, we may even remove the city
5370 * (if it shrinks from size 1) */
5372 if (pcity != nullptr) {
5374 }
5375 if (unit_is_alive(winner_id)) {
5377 return TRUE;
5378 }
5379 } else {
5380 return TRUE;
5381 }
5382 }
5383
5384 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
5385 * if there are enemy units in the tile (a fortress, city or air base with
5386 * multiple defenders and unstacked combat). Note that this could mean
5387 * capturing (or destroying) a city. */
5388
5389 if (pwinner == punit && fc_rand(100) < game.server.occupychance) {
5391 }
5392
5393 /* The attacker may have died for many reasons */
5394 if (game_unit_by_number(winner_id) != nullptr) {
5395 send_unit_info(nullptr, pwinner);
5396 }
5397
5398 return TRUE;
5399}
5400
5401/**********************************************************************/
5412 struct unit *act_unit,
5413 struct city *tgt_city,
5414 const struct action *paction)
5415{
5416 struct player *tgt_player;
5417 char prod[256];
5418 const struct unit_type *act_utype;
5419 const struct tile *tgt_tile;
5420 const char *clink;
5421
5422 /* Sanity checks */
5427
5430
5432
5433 /* The surgical strike may miss. */
5434 {
5435 /* Roll the dice. */
5438 paction)) {
5439 /* Notify the player. */
5442 /* TRANS: unit, action, city */
5443 _("Your %s failed to do %s in %s."),
5447
5448 /* Make the failed attempt cost a single move. */
5449 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5450
5451 return FALSE;
5452 }
5453 }
5454
5455 /* Get name of the production */
5456 universal_name_translation(&tgt_city->production, prod, sizeof(prod));
5457
5458 /* Destroy the production */
5459 tgt_city->shield_stock = 0;
5461
5462 /* Let the players know. */
5463 clink = city_link(tgt_city); /* Be careful not to call city_link()
5464 * again as long as we need clink */
5467 _("Your %s succeeded in destroying"
5468 " the production of %s in %s."),
5470 prod, clink);
5473 _("The production of %s was destroyed in %s,"
5474 " %s are suspected."),
5475 prod, clink,
5477
5479
5480 /* May cause an incident */
5483 clink);
5484
5485 return TRUE;
5486}
5487
5488/**********************************************************************/
5499 struct unit *act_unit,
5500 struct city *tgt_city,
5502 const struct action *paction)
5503{
5504 struct player *tgt_player;
5506 const struct tile *tgt_tile;
5507 const struct unit_type *act_utype;
5508 const char *clink;
5509
5510 /* Sanity checks */
5515
5517
5520
5521 /* The surgical strike may miss. */
5522 {
5523 /* Roll the dice. */
5526 paction)) {
5527 /* Notify the player. */
5530 /* TRANS: unit, action, city */
5531 _("Your %s failed to do %s in %s."),
5535
5536 /* Make the failed attempt cost a single move. */
5537 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5538
5539 return FALSE;
5540 }
5541 }
5542
5544 /* Nothing to destroy here. */
5545
5546 /* Notify the player. */
5549 _("Your %s didn't find a %s to %s in %s."),
5554
5555 /* Punish the player for blindly attacking a building. */
5556 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5557
5558 return FALSE;
5559 }
5560
5562 /* Notify the player. */
5565 _("Your %s cannot do %s to %s in %s."),
5570
5571 /* Punish the player for blindly attacking a building. */
5572 act_unit->moves_left = MAX(0, act_unit->moves_left - SINGLE_MOVE);
5573
5574 return FALSE;
5575 }
5576
5578
5579 /* Destroy the building. */
5580 building_lost(tgt_city, tgt_bld, "attacked", act_unit);
5581
5582 /* Update the player's view of the city. */
5583 send_city_info(nullptr, tgt_city);
5584
5585 /* Let the players know. */
5586 clink = city_link(tgt_city); /* Be careful not to call city_link()
5587 * again as long as we need clink */
5590 _("Your %s destroyed the %s in %s."),
5593 clink);
5596 _("The %s destroyed the %s in %s."),
5599 clink);
5600
5601 /* May cause an incident */
5604
5605 return TRUE;
5606}
5607
5608/**********************************************************************/
5618 struct unit *act_unit,
5619 struct city *tgt_city,
5620 struct action *paction)
5621{
5622 bool success;
5623 struct tile *tgt_tile = city_tile(tgt_city);
5624 int move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile);
5625 int tgt_city_id = tgt_city->id;
5627 const char *victim_link = city_link(tgt_city);
5628
5629 /* Sanity check */
5631
5632 unit_move(act_unit, tgt_tile, move_cost, nullptr, FALSE, TRUE, TRUE,
5633 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5635
5636 /* The city may have been destroyed during the conquest. */
5639
5640 if (success) {
5641 const struct unit_type *act_utype = unit_type_get(act_unit);
5642
5643 /* May cause an incident */
5646 victim_link);
5647 }
5648
5649 return success;
5650}
5651
5652/**********************************************************************/
5656 struct tile *dest_tile,
5657 bool igzoc,
5658 struct unit *embark_to,
5659 bool enter_enemy_city)
5660{
5661 struct tile *src_tile = unit_tile(punit);
5664 src_tile, dest_tile, igzoc, TRUE, embark_to,
5666
5667 switch (reason) {
5668 case MR_OK:
5669 return TRUE;
5670
5671 case MR_NO_WAR:
5673 _("Cannot attack unless you declare war first."));
5674 break;
5675
5676 case MR_ZOC:
5678 _("%s can only move into your own zone of control."),
5679 unit_link(punit));
5680 break;
5681
5682 case MR_TRIREME:
5684 _("%s cannot move that far from the coast line."),
5685 unit_link(punit));
5686 break;
5687
5688 case MR_PEACE:
5689 if (tile_owner(dest_tile)) {
5691 _("Cannot invade unless you break peace with "
5692 "%s first."),
5693 player_name(tile_owner(dest_tile)));
5694 }
5695 break;
5696
5699 _("%s cannot disembark outside of a city or a native base "
5700 "for %s."),
5704 break;
5705
5706 case MR_NON_NATIVE_MOVE:
5708 _("Terrain is unsuitable for %s units."),
5710 break;
5711
5712 default:
5713 /* FIXME: need more explanations someday! */
5714 break;
5715 };
5716
5717 return FALSE;
5718}
5719
5720/**********************************************************************/
5727 struct unit *actor_unit,
5728 struct tile *target_tile,
5729 const struct action *paction)
5730{
5732 int move_cost = map_move_cost_unit(&(wld.map), actor_unit, target_tile);
5733
5734 unit_move(actor_unit, target_tile, move_cost,
5735 nullptr, BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK),
5736 /* Don't override "Conquer City" */
5737 FALSE,
5738 /* Don't override "Conquer Extras" */
5739 FALSE,
5740 BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER),
5742
5743 /* May cause an incident */
5747
5748 return TRUE;
5749}
5750
5751/**********************************************************************/
5765 bool move_do_not_act)
5766{
5767 struct player *pplayer = unit_owner(punit);
5768 struct unit *ptrans;
5769 const struct civ_map *nmap = &(wld.map);
5770
5771 /*** Phase 1: Attempted action interpretation checks ***/
5772
5773 /* Check if the move should be interpreted as an attempt to perform an
5774 * enabler controlled action to the target tile. When the move may be an
5775 * action attempt the server stops moving the unit, marks it as wanting a
5776 * decision based on its own movement to the tile it attempted to move to
5777 * and notifies the client.
5778 *
5779 * In response to the unit being marked as wanting a decision the client
5780 * can query the server for what actions the unit, given the player's
5781 * knowledge, may be able to perform against a target at the tile it tried
5782 * to move to. The server will respond to the query with the actions that
5783 * may be enabled and, when all actions are known to be illegal given the
5784 * player's knowledge, an explanation why no action could be done. The
5785 * client will probably use the list of potentially legal actions, if any,
5786 * to pop up an action selection dialog. See handle_unit_action_query()
5787 *
5788 * If move_do_not_act is TRUE the move is never interpreted as an attempt
5789 * to perform an enabler controlled action.
5790 * Examples of where this is useful is for AI moves, goto, when the player
5791 * attempts to move to a tile occupied by potential targets like allied
5792 * cities or units and during rule forced moves.
5793 *
5794 * A move is not interpreted as an attempted action because the unit is
5795 * able to do a self targeted action.
5796 *
5797 * A move is not interpreted as an attempted action because an action
5798 * with rare_pop_up set to TRUE is legal unless the unit is unable to
5799 * perform a regular move to the tile.
5800 *
5801 * An attempted move to a tile a unit can't move to is always interpreted
5802 * as trying to perform an action (unless move_do_not_act is TRUE) */
5803 if (!move_do_not_act) {
5806 FALSE, FALSE, FALSE);
5810 /* A legal action with an extra sub target is a legal action */
5812 /* Tile target actions with extra sub targets are handled above */
5814
5816 /* There is a target punit, from the player's point of view, may be
5817 * able to act against OR punit can't do any non action move. The
5818 * client should therefore ask what action(s) the unit can perform
5819 * to any targets at pdesttile.
5820 *
5821 * In the first case the unit needs a decision about what action, if
5822 * any at all, to take. Asking what actions the unit can perform
5823 * will return a list of actions that may, from the players point of
5824 * view, be possible. The client can then show this list to the
5825 * player or, if configured to do so, make the choice it self.
5826 *
5827 * In the last case the player may need an explanation about why no
5828 * action could be taken. Asking what actions the unit can perform
5829 * will provide this explanation. */
5833
5834 /* The move wasn't done because the unit wanted the player to
5835 * decide what to do or because the unit couldn't move to the
5836 * target tile. */
5837 return FALSE;
5838 }
5839 }
5840
5841 /*** Phase 2: OK now move the unit ***/
5842 /* This is a regular move, subject to the rules. */
5844 punit, pdesttile, nullptr)) {
5845 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5849 punit, pdesttile, nullptr)) {
5850 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5854 punit, pdesttile, nullptr)) {
5855 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5861 punit, ptrans)) {
5862 /* "Transport Embark". */
5863 return unit_perform_action(pplayer, punit->id, ptrans->id,
5869 punit, ptrans)) {
5870 /* "Transport Embark 2". */
5871 return unit_perform_action(pplayer, punit->id, ptrans->id,
5877 punit, ptrans)) {
5878 /* "Transport Embark 3". */
5879 return unit_perform_action(pplayer, punit->id, ptrans->id,
5885 punit, ptrans)) {
5886 /* "Transport Embark 4". */
5887 return unit_perform_action(pplayer, punit->id, ptrans->id,
5891 punit, pdesttile, nullptr)) {
5892 /* "Transport Disembark". */
5893 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5897 punit, pdesttile, nullptr)) {
5898 /* "Transport Disembark 2". */
5899 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5903 punit, pdesttile, nullptr)) {
5904 /* "Transport Disembark 3". */
5905 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5909 punit, pdesttile, nullptr)) {
5910 /* "Transport Disembark 4". */
5911 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5915 punit, pdesttile, nullptr)) {
5916 /* "Enter Hut". */
5917 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5921 punit, pdesttile, nullptr)) {
5922 /* "Enter Hut 2". */
5923 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5927 punit, pdesttile, nullptr)) {
5928 /* "Frighten Hut". */
5929 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5933 punit, pdesttile, nullptr)) {
5934 /* "Frighten Hut 2". */
5935 return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
5938 } else {
5939 /* TODO: Extend the action not enabled explanation system to cover all
5940 * existing reasons and switch to using it. See hrm Feature #920229 */
5942 nullptr, FALSE);
5943 return FALSE;
5944 }
5945}
5946
5947/**********************************************************************/
5957static bool unit_do_help_build(struct player *pplayer,
5958 struct unit *punit,
5959 struct city *pcity_dest,
5960 const struct action *paction)
5961{
5962 const char *work;
5963 const char *prod;
5964 int shields;
5965 const struct unit_type *act_utype;
5966 struct player *cowner;
5967
5968 /* Sanity check: The actor still exists. */
5969 fc_assert_ret_val(pplayer, FALSE);
5971
5972 /* Sanity check: The target city still exists. */
5974
5977
5979 /* Add the caravan shields */
5980 pcity_dest->shield_stock += shields;
5981
5982 /* Will be punished for changing production to something that can't
5983 * receive "Help Wonder" help. */
5985 &pcity_dest->production));
5986 pcity_dest->caravan_shields += shields;
5987 } else {
5989 /* Add the shields from recycling the unit to the city's current
5990 * production. */
5991 pcity_dest->shield_stock += shields;
5992
5993 /* If we change production later at this turn. No penalty is added. */
5994 pcity_dest->disbanded_shields += shields;
5995 }
5996
5998
5999 conn_list_do_buffer(cowner->connections);
6000
6002 /* Let the player that just donated shields with "Help Wonder" know
6003 * the result of their donation. */
6005 } else {
6007 /* TRANS: Your Caravan does "Disband Unit Recover" to help build the
6008 * current production in Bergen (4 surplus).
6009 * "Disband Unit Recover" says "current production" rather than its name. */
6010 prod = _("current production");
6011 }
6012
6013 if (build_points_left(pcity_dest) >= 0) {
6014 /* TRANS: Your Caravan does "Help Wonder" to help build the
6015 * Pyramids in Bergen (4 remaining).
6016 * You can reorder '4' and 'remaining' in the actual format string. */
6017 work = _("remaining");
6018 } else {
6019 /* TRANS: Your Caravan does "Help Wonder" to help build the
6020 * Pyramids in Bergen (4 surplus).
6021 * You can reorder '4' and 'surplus' in the actual format string. */
6022 work = _("surplus");
6023 }
6024
6026 ftc_server,
6027 /* TRANS: Your Caravan does "Help Wonder" to help build the
6028 * Pyramids in Bergen (4 surplus). */
6029 _("Your %s does %s to help build the %s in %s (%d %s)."),
6032 prod,
6035 work);
6036
6037 /* May cause an incident */
6040
6041 if (cowner != unit_owner(punit)) {
6042 /* Tell the city owner about the gift they just received. */
6043
6046 /* TRANS: Help building the Pyramids in Bergen received
6047 * from Persian Caravan (4 surplus). */
6048 _("Help building the %s in %s received from %s %s "
6049 "(%d %s)."),
6055 work);
6056 }
6057
6060 conn_list_do_unbuffer(cowner->connections);
6061
6062 return TRUE;
6063}
6064
6065/**********************************************************************/
6072static bool do_unit_establish_trade(struct player *pplayer,
6073 struct unit *punit,
6074 struct city *pcity_dest,
6075 const struct action *paction)
6076{
6079 int revenue;
6080 bool can_establish;
6081 int home_overbooked = 0;
6082 int dest_overbooked = 0;
6083 int home_max;
6084 int dest_max;
6085 struct city *pcity_homecity;
6088 enum trade_route_bonus_type bonus_type;
6089 struct goods_type *goods;
6090 const char *goods_str;
6091 const struct unit_type *act_utype;
6092
6093 /* Sanity check: The actor still exists. */
6094 fc_assert_ret_val(pplayer, FALSE);
6096
6097 /* Sanity check: The target city still exists. */
6099
6101
6102 if (!pcity_homecity) {
6104 _("Sorry, your %s cannot establish"
6105 " a trade route because it has no home city."),
6106 unit_link(punit));
6107 return FALSE;
6108 }
6109
6111
6112 if (goods == nullptr) {
6114 _("Sorry, your %s cannot establish"
6115 " a trade route because it's not carrying any goods."),
6116 unit_link(punit));
6117 return FALSE;
6118 }
6119
6122
6125 _("Sorry, your %s cannot establish"
6126 " a trade route between %s and %s."),
6130 return FALSE;
6131 }
6132
6134
6138
6139 /* This part of code works like can_establish_trade_route(), except
6140 * that we actually do the action of making the trade route. */
6141
6142 /* If we can't make a new trade route we can still get the trade bonus. */
6145
6146 if (can_establish) {
6151 }
6152
6153 if (can_establish && (home_overbooked >= 0 || dest_overbooked >= 0)) {
6155
6156 /* See if there's a trade route we can cancel at the home city. */
6157 if (home_overbooked >= 0) {
6158 if (home_max <= 0
6161 >= trade)) {
6164 _("Sorry, your %s cannot establish"
6165 " a trade route here!"),
6166 punit_link);
6167 if (home_max > 0) {
6170 PL_(" The city of %s already has %d "
6171 "better trade route!",
6172 " The city of %s already has %d "
6173 "better trade routes!", home_max),
6175 home_max);
6176 }
6178 }
6179 }
6180
6181 /* See if there's a trade route we can cancel at the dest city. */
6182 if (can_establish && dest_overbooked >= 0) {
6183 if (dest_max <= 0
6186 >= trade)) {
6189 _("Sorry, your %s cannot establish"
6190 " a trade route here!"),
6191 punit_link);
6192 if (dest_max > 0) {
6195 PL_(" The city of %s already has %d "
6196 "better trade route!",
6197 " The city of %s already has %d "
6198 "better trade routes!", dest_max),
6200 dest_max);
6201 }
6203 }
6204 }
6205 }
6206
6207 /* We now know for sure whether we can establish a trade route. */
6208
6209 /* Calculate and announce initial revenue. */
6210 revenue
6213
6214 bonus_type = trade_route_settings_by_type
6216
6218
6220
6221 /* We want to keep the bonus type string as the part of the format of the PL_() strings
6222 * for supporting proper pluralization for it. */
6223 switch (bonus_type) {
6224 case TBONUS_NONE:
6227 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
6228 _("Your %s from %s has arrived in %s carrying %s."),
6229 punit_link,
6232 goods_str);
6233 break;
6234 case TBONUS_GOLD:
6237 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6238 PL_("Your %s from %s has arrived in %s carrying %s,"
6239 " and revenues amount to %d in gold.",
6240 "Your %s from %s has arrived in %s carrying %s,"
6241 " and revenues amount to %d in gold.",
6242 revenue),
6243 punit_link,
6246 goods_str,
6247 revenue);
6248 break;
6249 case TBONUS_SCIENCE:
6252 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6253 PL_("Your %s from %s has arrived in %s carrying %s,"
6254 " and revenues amount to %d in research.",
6255 "Your %s from %s has arrived in %s carrying %s,"
6256 " and revenues amount to %d in research.",
6257 revenue),
6258 punit_link,
6261 goods_str,
6262 revenue);
6263 break;
6264 case TBONUS_BOTH:
6267 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... */
6268 PL_("Your %s from %s has arrived in %s carrying %s,"
6269 " and revenues amount to %d in gold and research.",
6270 "Your %s from %s has arrived in %s carrying %s,"
6271 " and revenues amount to %d in gold and research.",
6272 revenue),
6273 punit_link,
6276 goods_str,
6277 revenue);
6278 break;
6279 }
6280
6281 if (bonus_type == TBONUS_GOLD || bonus_type == TBONUS_BOTH) {
6282 pplayer->economic.gold += revenue;
6283
6284 send_player_info_c(pplayer, pplayer->connections);
6285 }
6286
6287 if (bonus_type == TBONUS_SCIENCE || bonus_type == TBONUS_BOTH) {
6288 /* add bulbs and check for finished research */
6289 update_bulbs(pplayer, revenue, TRUE, TRUE);
6290
6291 /* Inform everyone about tech changes */
6292 send_research_info(research_get(pplayer), nullptr);
6293 }
6294
6295 if (can_establish) {
6296 struct city_list *cities_out_of_home;
6297 struct city_list *cities_out_of_dest;
6298 struct player *partner_player;
6299
6300 /* Announce creation of trade route (it's not actually created until
6301 * later in this function, as we have to cancel existing routes, but
6302 * it makes more sense to announce in this order) */
6303
6305
6306 /* Always tell the unit owner */
6307 notify_player(pplayer, nullptr,
6309 _("New trade route established from %s to %s."),
6312 if (pplayer != partner_player) {
6315 _("The %s established a trade route between their "
6316 "city %s and %s."),
6317 nation_plural_for_player(pplayer),
6320 }
6321
6324
6325 /* Now cancel any less profitable trade route from the home city. */
6327 struct trade_route *pback;
6328
6330
6332 free(premove);
6333 free(pback);
6335
6336 /* And the same for the dest city. */
6338 struct trade_route *pback;
6339
6341
6343 free(premove);
6344 free(pback);
6346
6348
6349 /* Refresh the cities. */
6358
6359 /* Notify the owners of the cities. */
6368
6369 /* Notify each player about the other's cities. */
6370 if (pplayer != partner_player && game.info.reveal_trade_partner) {
6374 send_city_info(pplayer, pcity_dest);
6375 }
6376
6381 }
6382 if (pplayer != city_owner(pcity)) {
6383 send_city_info(pplayer, pcity);
6385 }
6387
6392 }
6393 if (pplayer != city_owner(pcity)) {
6394 send_city_info(pplayer, pcity);
6396 }
6398
6401 }
6402
6403 /* May cause an incident */
6405 pplayer, act_utype, city_owner(pcity_dest),
6408
6410
6411 /* Free data. */
6414
6415 return TRUE;
6416}
6417
6418/**********************************************************************/
6422void create_trade_route(struct city *from, struct city *to,
6423 struct goods_type *goods)
6424{
6426
6427 /* Actually create the new trade route */
6428 proute_from = fc_malloc(sizeof(struct trade_route));
6429 proute_from->partner = to->id;
6430 proute_from->goods = goods;
6431
6432 proute_to = fc_malloc(sizeof(struct trade_route));
6433 proute_to->partner = from->id;
6434 proute_to->goods = goods;
6435
6439 } else {
6440 proute_from->dir = RDIR_FROM;
6441 proute_to->dir = RDIR_TO;
6442 }
6445}
6446
6447/**********************************************************************/
6455void handle_unit_sscs_set(struct player *pplayer,
6456 int unit_id,
6458 int value)
6459{
6460 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6461 const struct civ_map *nmap = &(wld.map);
6462
6463 if (punit == nullptr) {
6464 /* Being asked to unqueue a "spent" unit because the client haven't
6465 * been told that it's gone is expected. */
6466 if (type != USSDT_UNQUEUE) {
6467 /* Probably died or bribed. */
6468 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id);
6469 }
6470
6471 return;
6472 }
6473
6474 switch (type) {
6475 case USSDT_QUEUE:
6476 /* Reminds the client to ask the server about what actions the unit can
6477 * perform against the target tile. Action decision state can be set by
6478 * the server it self too. */
6479
6480 if (index_to_tile(nmap, value) == nullptr) {
6481 /* Asked to be reminded to ask what actions the unit can do to a non
6482 * existing target tile. */
6483 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
6484 value, unit_id);
6485 break;
6486 }
6487
6490
6491 /* Let the client know that this unit needs the player to decide
6492 * what to do. */
6494
6495 break;
6496 case USSDT_UNQUEUE:
6497 /* Delete the reminder for the client to ask the server about what
6498 * actions the unit can perform against a certain target tile.
6499 * Action decision state can be set by the server it self too. */
6500
6502 punit->action_decision_tile = nullptr;
6503
6504 /* Let the client know that this unit no longer needs the player to
6505 * decide what to do. */
6506 send_unit_info(pplayer->connections, punit);
6507
6508 break;
6509 case USSDT_BATTLE_GROUP:
6510 /* Battlegroups are handled entirely by the client, so all we have to
6511 do here is save the battlegroup ID so that it'll be persistent. */
6512
6514
6515 break;
6516 case USSDT_SENTRY:
6517 if (value == 0) {
6518 if (punit->activity != ACTIVITY_SENTRY) {
6519 return;
6520 }
6521
6523 /* Impossible to set to Idle? */
6525 }
6526 } else if (value == 1) {
6529 return;
6530 }
6531
6533 /* Should have been caught above */
6535 }
6536 } else {
6537 log_verbose("handle_unit_sscs_set(): illegal sentry state for %s %d",
6539 }
6540 break;
6541 }
6542}
6543
6544/**********************************************************************/
6547static void unit_plans_clear(struct unit *punit)
6548{
6549 /* Remove city spot reservations for AI settlers on city founding
6550 * mission. */
6551 adv_unit_new_task(punit, AUT_NONE, nullptr);
6552
6553 /* Get rid of old orders. */
6555
6556 /* Make sure that no old goto_tile remains. */
6557 punit->goto_tile = nullptr;
6558}
6559
6560/**********************************************************************/
6564 int unit_id,
6566{
6567 struct unit *punit = player_unit_by_number(pplayer, unit_id);
6568
6569 if (punit == nullptr) {
6570 /* Probably died or bribed. */
6571 log_verbose("handle_unit_server_side_agent_set() invalid unit %d",
6572 unit_id);
6573 return;
6574 }
6575
6577 /* Client error. */
6578 log_verbose("handle_unit_server_side_agent_set() invalid agent %d",
6579 agent);
6580 return;
6581 }
6582
6583 /* Set the state or exit */
6584 if (!unit_server_side_agent_set(pplayer, punit, agent)) {
6585 return;
6586 }
6587
6588 /* Give the new agent a blank slate */
6590
6591 if (agent == SSA_AUTOEXPLORE) {
6593 /* Should have been caught above */
6596 }
6597
6598 /* Exploring is handled here explicitly, since the player expects to
6599 * see an immediate response from setting a unit to auto-explore.
6600 * Handling it deeper in the code leads to some tricky recursive loops -
6601 * see PR#2631. */
6602 if (punit->moves_left > 0) {
6604 }
6605 }
6606}
6607
6608/**********************************************************************/
6613 struct unit *punit,
6615{
6616 const struct civ_map *nmap = &(wld.map);
6617
6618 /* Check that the agent can be activated for this unit. */
6619 switch (agent) {
6620 case SSA_AUTOWORKER:
6622 return FALSE;
6623 }
6624 break;
6625 case SSA_AUTOEXPLORE:
6628 return FALSE;
6629 }
6630 break;
6631 case SSA_NONE:
6632 /* Always possible. */
6633 break;
6634 case SSA_COUNT:
6636 break;
6637 }
6638
6639 if (punit->ssa_controller != agent) {
6641 send_unit_info(nullptr, punit);
6642 }
6643
6644 return TRUE;
6645}
6646
6647/**********************************************************************/
6653 struct extra_type *old_target)
6654{
6655 switch (punit->activity) {
6656 case ACTIVITY_IDLE:
6657 switch (old_activity) {
6658 case ACTIVITY_PILLAGE:
6659 {
6660 if (old_target != nullptr) {
6662 if (punit2->activity == ACTIVITY_PILLAGE) {
6663 extra_deps_iterate(&(punit2->activity_target->reqs), pdep) {
6664 if (pdep == old_target) {
6666 send_unit_info(nullptr, punit2);
6667 break;
6668 }
6670 }
6672 }
6673 break;
6674 }
6675 case ACTIVITY_EXPLORE:
6676 /* Restore unit's control status */
6678 break;
6679 default:
6680 ; /* Do nothing */
6681 }
6682 break;
6683 case ACTIVITY_EXPLORE:
6686 send_unit_info(nullptr, punit);
6687 break;
6688 default:
6689 /* Do nothing */
6690 break;
6691 }
6692}
6693
6694/**********************************************************************/
6710
6711/**********************************************************************/
6717{
6718 const struct civ_map *nmap = &(wld.map);
6719
6720 /* Must specify target for ACTIVITY_BASE */
6723
6725 struct extra_type *target = nullptr;
6726
6727 /* Assume untargeted pillaging if no target specified */
6731 trigger_action)) {
6734 }
6735
6736 return TRUE;
6737}
6738
6739/**********************************************************************/
6748{
6749 const struct civ_map *nmap = &(wld.map);
6750
6752 trigger_action)) {
6753 return FALSE;
6754 } else {
6757
6759 send_unit_info(nullptr, punit);
6761
6762 return TRUE;
6763 }
6764}
6765
6766/**********************************************************************/
6786
6787/**********************************************************************/
6792 struct extra_type **new_target,
6794{
6795 const struct civ_map *nmap = &(wld.map);
6796
6801 *new_target)) {
6803
6805
6806 if (list != nullptr && action_list_size(list) > 0) {
6807 /* Trigger action system */
6809 (*new_target) != nullptr ? (*new_target)->id : NO_TARGET,
6811 } else {
6814 }
6815 }
6816
6817 return TRUE;
6818}
6819
6820/**********************************************************************/
6828 struct extra_type **new_target,
6830{
6831 const struct civ_map *nmap = &(wld.map);
6832
6835 *new_target)) {
6836 return FALSE;
6837 } else {
6841
6844 new_target);
6847 /* unit_assign_specific_activity_target() changed our target activity
6848 * (to ACTIVITY_IDLE in practice) */
6850 } else {
6853 send_unit_info(nullptr, punit);
6855
6857 /* Casus Belli for when the activity successfully begins. */
6858 /* TODO: is it more logical to change Casus_Belli_Complete to
6859 * Casus_Belli_Successful_Beginning and trigger it here? */
6865 }
6866 }
6867
6868 return TRUE;
6869 }
6870}
6871
6872/**********************************************************************/
6878static bool do_scout(struct unit *punit, struct tile *ptile,
6879 const struct action *paction)
6880{
6881 struct player *owner = unit_owner(punit);
6882
6883 if (punit->server.scout_vision != nullptr
6884 && punit->server.scout_vision->tile != ptile) {
6886 punit->server.scout_vision = nullptr;
6887 }
6888
6889 if (punit->server.scout_vision == nullptr) {
6890 const v_radius_t radius_sq = V_RADIUS(5, 0, 0);
6891
6895 }
6896
6897 return TRUE;
6898}
6899
6900/**********************************************************************/
6903void handle_unit_orders(struct player *pplayer,
6904 const struct packet_unit_orders *packet)
6905{
6906 int length = packet->length;
6907 struct unit *punit = player_unit_by_number(pplayer, packet->unit_id);
6908 const struct civ_map *nmap = &(wld.map);
6909 struct tile *src_tile = index_to_tile(nmap, packet->src_tile);
6910 struct unit_order *order_list;
6911#ifdef FREECIV_DEBUG
6912 int i;
6913#endif
6914
6915 if (punit == nullptr) {
6916 /* Probably died or bribed. */
6917 log_verbose("handle_unit_orders() invalid unit %d", packet->unit_id);
6918 return;
6919 }
6920
6921 if (0 > length || MAX_LEN_ROUTE < length) {
6922 /* Shouldn't happen */
6923 log_error("handle_unit_orders() invalid %s (%d) "
6924 "packet length %d (max %d)", unit_rule_name(punit),
6925 packet->unit_id, length, MAX_LEN_ROUTE);
6926 return;
6927 }
6928
6929 if (src_tile != unit_tile(punit)) {
6930 /* Failed sanity check. Usually this happens if the orders were sent
6931 * in the previous turn, and the client thought the unit was in a
6932 * different position than it's actually in. The easy solution is to
6933 * discard the packet. We don't send an error message to the client
6934 * here (though maybe we should?). */
6935 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
6936 "!= (%d, %d)", unit_rule_name(punit), punit->id,
6937 TILE_XY(src_tile), TILE_XY(unit_tile(punit)));
6938 return;
6939 }
6940
6941 if (ACTIVITY_IDLE != punit->activity) {
6942 /* New orders implicitly abandon current activity */
6944 }
6945
6946 if (length) {
6947 order_list = create_unit_orders(nmap, length, packet->orders);
6948 if (!order_list) {
6949 log_error("received invalid orders from %s for %s (%d).",
6950 player_name(pplayer), unit_rule_name(punit), packet->unit_id);
6951 return;
6952 }
6953 }
6954
6955 /* This must be before old orders are freed. If this is
6956 * settlers on city founding mission, city spot reservation
6957 * from goto_tile must be freed, and free_unit_orders() loses
6958 * goto_tile information */
6959 adv_unit_new_task(punit, AUT_NONE, nullptr);
6960
6962 /* If we waited on a tile, reset punit->done_moving */
6963 punit->done_moving = (punit->moves_left <= 0);
6964
6965 if (length == 0) {
6967 send_unit_info(nullptr, punit);
6968 return;
6969 }
6970
6972 punit->orders.length = length;
6973 punit->orders.index = 0;
6974 punit->orders.repeat = packet->repeat;
6975 punit->orders.vigilant = packet->vigilant;
6976 if (length) {
6978 }
6979
6980 if (!packet->repeat) {
6982 } else {
6983 /* Make sure that no old goto_tile remains. */
6984 punit->goto_tile = nullptr;
6985 }
6986
6987#ifdef FREECIV_DEBUG
6988 log_debug("Orders for unit %d: length:%d", packet->unit_id, length);
6989 for (i = 0; i < length; i++) {
6990 log_debug(" %d,%s,%s,%d,%d",
6991 packet->orders[i].order, dir_get_name(packet->orders[i].dir),
6992 packet->orders[i].order == ORDER_PERFORM_ACTION ?
6994 packet->orders[i].order == ORDER_ACTIVITY ?
6996 "no action/activity required",
6997 packet->orders[i].target,
6998 packet->orders[i].sub_target);
6999 }
7000#endif /* FREECIV_DEBUG */
7001
7003 || execute_orders(punit, TRUE)) {
7004 /* Looks like the unit survived. */
7005 send_unit_info(nullptr, punit);
7006 }
7007}
7008
7009/**********************************************************************/
7012void handle_worker_task(struct player *pplayer,
7013 const struct packet_worker_task *packet)
7014{
7015 struct city *pcity = game_city_by_number(packet->city_id);
7016 struct worker_task *ptask = nullptr;
7017 struct tile *ptile = index_to_tile(&(wld.map), packet->tile_id);
7018
7019 if (pcity == nullptr || pcity->owner != pplayer || ptile == nullptr) {
7020 return;
7021 }
7022
7024 if (tile_index(ptask_old->ptile) == packet->tile_id) {
7025 ptask = ptask_old;
7026 }
7028
7029 if (ptask == nullptr) {
7030 if (packet->activity == ACTIVITY_LAST) {
7031 return;
7032 }
7033
7034 ptask = fc_malloc(sizeof(struct worker_task));
7036 worker_task_list_append(pcity->task_reqs, ptask);
7037 } else {
7038 if (packet->activity == ACTIVITY_LAST) {
7039 worker_task_list_remove(pcity->task_reqs, ptask);
7040 free(ptask);
7041 ptask = nullptr;
7042 }
7043 }
7044
7045 if (ptask != nullptr) {
7046 ptask->ptile = ptile;
7047 ptask->act = packet->activity;
7048 if (packet->tgt >= 0) {
7049 if (packet->tgt < MAX_EXTRA_TYPES) {
7050 ptask->tgt = extra_by_number(packet->tgt);
7051 } else {
7052 log_debug("Illegal worker task target %d", packet->tgt);
7053 ptask->tgt = nullptr;
7054 }
7055 } else {
7056 ptask->tgt = nullptr;
7057 }
7058 ptask->want = packet->want;
7059 }
7060
7061 if (ptask && !worker_task_is_sane(ptask)) {
7062 log_debug("Bad worker task");
7063 worker_task_list_remove(pcity->task_reqs, ptask);
7064 free(ptask);
7065 ptask = nullptr;
7066
7067 return;
7068 }
7069
7070 lsend_packet_worker_task(pplayer->connections, packet);
7071}
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:5800
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:5322
bool action_actor_utype_hard_reqs_ok(const struct action *paction, const struct unit_type *actor_unittype)
Definition actions.c:2606
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:4843
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:3270
struct action_list * action_list_by_activity(enum unit_activity activity)
Definition actions.c:7555
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:3346
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:4926
struct act_prob action_prob_self(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id)
Definition actions.c:4996
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:3105
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:3182
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:4485
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:5745
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:5018
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:4760
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:4568
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:380
void astr_free(struct astring *astr)
Definition astring.c:148
const char * astr_build_or_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:313
#define n
Definition astring.c:77
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:106
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:144
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
void citizens_update(struct city *pcity, struct player *plr)
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1913
int city_granary_size(int city_size)
Definition city.c:2199
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1292
bool is_capital(const struct city *pcity)
Definition city.c:1632
const char * city_name_get(const struct city *pcity)
Definition city.c:1157
bool citymindist_prevents_city_on_tile(const struct civ_map *nmap, const struct tile *ptile)
Definition city.c:1518
void city_size_add(struct city *pcity, int add)
Definition city.c:1216
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2079
struct city * tile_non_attack_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2118
bool city_exist(int id)
Definition city.c:3689
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:703
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:778
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:565
static citizens city_size_get(const struct city *pcity)
Definition city.h:570
#define city_owner(_pcity_)
Definition city.h:564
#define MAX_CITY_SIZE
Definition city.h:104
#define city_list_iterate_end
Definition city.h:510
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2374
void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1526
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:3088
void city_units_upkeep(const struct city *pcity)
Definition citytools.c:3174
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:1719
struct trade_route * remove_trade_route(struct city *pc1, struct trade_route *proute, bool announce, bool source_gone)
Definition citytools.c:2954
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
void nullify_prechange_production(struct city *pcity)
Definition cityturn.c:3743
int city_incite_cost(struct player *pplayer, struct city *pcity)
Definition cityturn.c:3631
bool city_reduce_size(struct city *pcity, citizens pop_loss, struct player *destroyer, const char *reason)
Definition cityturn.c:764
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, Specialist_type_id sid, const char *reason)
Definition cityturn.c:1069
int city_growth_granary_savings(const struct city *pcity)
Definition cityturn.c:880
static struct fc_sockaddr_list * list
Definition clinet.c:102
bool is_unit_reachable_at(const struct unit *defender, const struct unit *attacker, const struct tile *location)
Definition combat.c:86
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:257
struct city * sdi_try_defend(const struct civ_map *nmap, const struct player *owner, const struct tile *ptile)
Definition combat.c:503
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:772
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:615
bool is_tired_attack(int moves_left)
Definition combat.c:532
enum unit_attack_result unit_wipe_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Definition combat.c:272
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
void get_modified_firepower(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, int *att_fp, int *def_fp)
Definition combat.c:411
#define POWER_FACTOR
Definition combat.h:32
@ ATT_NOT_WIPABLE
Definition combat.h:40
@ ATT_NONNATIVE_DST
Definition combat.h:39
@ ATT_OK
Definition combat.h:35
@ ATT_NON_ATTACK
Definition combat.h:36
@ ATT_UNREACHABLE
Definition combat.h:37
@ ATT_NONNATIVE_SRC
Definition combat.h:38
char * incite_cost
Definition comments.c:77
#define MAX_LEN_MSG
Definition conn_types.h:37
#define MAX_LEN_ROUTE
Definition conn_types.h:38
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:368
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:358
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
#define conn_list_iterate_end
Definition connection.h:110
static void bombard(QVariant data1, QVariant data2)
Definition dialogs.cpp:3021
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:72
struct unit * actor_unit
Definition dialogs_g.h:54
struct unit struct city struct unit struct tile * target_tile
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 * punit
Definition dialogs_g.h:73
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:77
struct unit struct city * target_city
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:56
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:2470
bool spy_steal_some_maps(struct player *act_player, struct unit *act_unit, struct city *tgt_city, const struct action *paction)
Definition diplomats.c:1820
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:1678
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:1958
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:82
ane_kind
Definition explanation.h:22
@ ANEK_IS_CITY_CENTER
Definition explanation.h:62
@ ANEK_ACTION_BLOCKS
Definition explanation.h:98
@ ANEK_DOMESTIC
Definition explanation.h:50
@ ANEK_LOW_MP
Definition explanation.h:60
@ ANEK_TGT_TILE_UNKNOWN
Definition explanation.h:94
@ ANEK_BAD_TERRAIN_TGT
Definition explanation.h:32
@ ANEK_TRIREME_MOVE
Definition explanation.h:74
@ ANEK_CITY_TOO_CLOSE_TGT
Definition explanation.h:83
@ ANEK_CITY_NO_CAPACITY
Definition explanation.h:89
@ ANEK_NATION_TGT
Definition explanation.h:58
@ ANEK_BAD_TARGET
Definition explanation.h:28
@ ANEK_MISSING_TARGET
Definition explanation.h:26
@ ANEK_TGT_IS_CLAIMED
Definition explanation.h:66
@ ANEK_FOREIGN
Definition explanation.h:52
@ ANEK_DISEMBARK_ACT
Definition explanation.h:77
@ ANEK_IS_TRANSPORTED
Definition explanation.h:34
@ ANEK_IS_NOT_CITY_CENTER
Definition explanation.h:64
@ ANEK_TGT_IS_UNCLAIMED
Definition explanation.h:68
@ ANEK_TGT_NON_ALLIED_UNITS_ON_TILE
Definition explanation.h:54
@ ANEK_BAD_TERRAIN_ACT
Definition explanation.h:30
@ ANEK_SCENARIO_DISABLED
Definition explanation.h:81
@ ANEK_ACTOR_HAS_HOME_CITY
Definition explanation.h:42
@ ANEK_PEACE
Definition explanation.h:48
@ ANEK_DISTANCE_NEAR
Definition explanation.h:70
@ ANEK_UNKNOWN
@ ANEK_ACT_NOT_ENOUGH_MONEY
Definition explanation.h:96
@ ANEK_IS_NOT_TRANSPORTING
Definition explanation.h:40
@ ANEK_TGT_UNREACHABLE
Definition explanation.h:79
@ ANEK_ACTOR_HAS_NO_HOME_CITY
Definition explanation.h:44
@ ANEK_NOT_WIPABLE
@ ANEK_CITY_TOO_BIG
Definition explanation.h:85
@ ANEK_NO_WAR
Definition explanation.h:46
@ ANEK_DISTANCE_FAR
Definition explanation.h:72
@ ANEK_ACTOR_UNIT
Definition explanation.h:24
@ ANEK_NATION_ACT
Definition explanation.h:56
@ ANEK_IS_NOT_TRANSPORTED
Definition explanation.h:36
@ ANEK_IS_TRANSPORTING
Definition explanation.h:38
@ ANEK_CITY_POP_LIMIT
Definition explanation.h:87
@ ANEK_TGT_IS_UNIQUE_ACT_HAS
Definition explanation.h:92
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:779
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:804
struct extra_type * extra_by_number(int id)
Definition extras.c:183
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:372
#define extra_deps_iterate_end
Definition extras.h:380
#define EXTRA_NONE
Definition extras.h:85
#define NO_TARGET
Definition fc_types.h:215
int Impr_type_id
Definition fc_types.h:237
#define MAX_NUM_PLAYERS
Definition fc_types.h:36
@ AUT_NONE
Definition fc_types.h:231
int action_id
Definition fc_types.h:250
int Specialist_type_id
Definition fc_types.h:236
#define ACTRES_NONE
Definition fc_types.h:188
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:68
int Unit_type_id
Definition fc_types.h:243
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:94
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * city_tile_link(const struct city *pcity)
const char * tile_link(const struct tile *ptile)
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
const char * unit_link(const struct unit *punit)
const char * unit_tile_link(const struct unit *punit)
#define MAX_LEN_LINK
struct civ_game game
Definition game.c:62
bool is_player_phase(const struct player *pplayer, int phase)
Definition game.c:716
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:115
struct city * game_city_by_number(int id)
Definition game.c:106
static int actor_unit_id
static int target_extra_id
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
struct impr_type * improvement_by_number(const Impr_type_id id)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:182
#define fc_assert_ret(condition)
Definition log.h:192
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define fc_assert_action(condition, action)
Definition log.h:188
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:209
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:2101
const char * dir_get_name(enum direction8 dir)
Definition map.c:1296
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:1478
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:299
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2492
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:901
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:775
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:927
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:871
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1390
void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
Definition maphand.c:2480
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1066
enum unit_move_result unit_move_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool igzoc, bool enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:661
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:362
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Definition movement.c:962
enum unit_move_result unit_teleport_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:815
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:522
bool unit_can_move_to_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *dst_tile, bool igzoc, bool enter_transport, bool enter_enemy_city)
Definition movement.c:603
#define SINGLE_MOVE
Definition movement.h:26
unit_move_result
Definition movement.h:34
@ MR_CANNOT_DISEMBARK
Definition movement.h:48
@ MR_OK
Definition movement.h:35
@ MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT
Definition movement.h:45
@ MR_TRIREME
Definition movement.h:47
@ MR_NON_NATIVE_MOVE
Definition movement.h:49
@ MR_PEACE
Definition movement.h:39
@ MR_ZOC
Definition movement.h:40
@ MR_NO_WAR
Definition movement.h:38
static const char * name_translation_get(const struct name_translation *ptrans)
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:461
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
const char * nation_adjective_translation(const struct nation_type *pnation)
Definition nation.c:149
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
@ UNIT_INFO_IDENTITY
Definition packets.h:67
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1217
const char * player_name(const struct player *pplayer)
Definition player.c:885
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1095
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1191
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1325
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:325
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1397
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1451
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1124
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
int normal_player_count(void)
Definition plrhand.c:3217
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2971
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:3016
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:2923
#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:42
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:89
enum unit_activity activity
Definition unit.h:94
enum unit_orders order
Definition unit.h:93
int action
Definition unit.h:101
enum direction8 dir
Definition unit.h:103
int target
Definition unit.h:97
int sub_target
Definition unit.h:98
int paratroopers_range
Definition unittype.h:548
Definition unit.h:139
int length
Definition unit.h:197
bool has_orders
Definition unit.h:195
enum action_decision action_decision_want
Definition unit.h:204
int battlegroup
Definition unit.h:193
enum unit_activity activity
Definition unit.h:158
int moves_left
Definition unit.h:151
int id
Definition unit.h:146
struct unit::@83 orders
bool moved
Definition unit.h:175
int index
Definition unit.h:197
struct vision * vision
Definition unit.h:246
bool vigilant
Definition unit.h:199
int hp
Definition unit.h:152
enum direction8 facing
Definition unit.h:143
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:141
struct extra_type * activity_target
Definition unit.h:166
struct unit_order * list
Definition unit.h:200
struct vision * scout_vision
Definition unit.h:247
struct unit_adv * adv
Definition unit.h:238
bool repeat
Definition unit.h:198
int homecity
Definition unit.h:147
bool done_moving
Definition unit.h:183
struct tile * goto_tile
Definition unit.h:156
struct tile * action_decision_tile
Definition unit.h:205
const struct unit_type * utype
Definition unit.h:140
int veteran
Definition unit.h:153
struct player * owner
Definition unit.h:144
enum server_side_agent ssa_controller
Definition unit.h:174
struct tile * tile
Definition vision.h:87
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:925
#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:726
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:240
#define terrain_has_flag(terr, flag)
Definition terrain.h:177
bool tile_is_seen(const struct tile *target_tile, const struct player *pow_player)
Definition tile.c:408
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:89
#define tile_terrain(_tile)
Definition tile.h:115
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_owner(_tile)
Definition tile.h:97
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
enum trade_route_type cities_trade_route_type(const struct city *pcity1, const struct city *pcity2)
Definition traderoutes.c:58
int trade_base_between_cities(const struct city *pc1, const struct city *pc2)
int city_num_trade_routes(const struct city *pcity)
static struct goods_type goods[MAX_GOODS_TYPES]
Definition traderoutes.c:43
bool goods_has_flag(const struct goods_type *pgood, enum goods_flag_id flag)
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
struct goods_type * unit_current_goods(const struct unit *punit, const struct city *homecity)
unsigned max_trade_routes(const struct city *pcity)
Definition traderoutes.c:48
const char * goods_name_translation(struct goods_type *pgood)
int city_trade_removable(const struct city *pcity, int priority, struct trade_route_list *would_remove)
bool have_cities_trade_route(const struct city *pc1, const struct city *pc2)
int get_caravan_enter_city_trade_bonus(const struct city *pc1, const struct city *pc2, const struct unit_type *ut, struct goods_type *pgood, const bool establish_trade)
#define trade_route_list_iterate(trade_route_list, proute)
Definition traderoutes.h:95
#define trade_route_list_iterate_end
Definition traderoutes.h:97
struct unit_order * create_unit_orders(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2924
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:1841
void free_unit_orders(struct unit *punit)
Definition unit.c:1827
bool unit_is_alive(int id)
Definition unit.c:2307
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1978
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1299
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2526
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2479
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2361
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:882
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:2943
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:912
bool can_unit_do_autoworker(const struct unit *punit)
Definition unit.c:647
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:1157
int stack_bribe_cost(const struct tile *ptile, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2447
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1139
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:2042
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2512
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:607
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:953
#define unit_tile(_pu)
Definition unit.h:408
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_owner(_pu)
Definition unit.h:407
@ UU_NO_MONEY
Definition unit.h:63
#define MAX_NUM_BATTLEGROUPS
Definition unit.h:191
@ AR_SRC_NO_FLIGHTS
Definition unit.h:84
@ AR_DST_NO_FLIGHTS
Definition unit.h:85
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:446
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:6790
#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:1030
static bool do_unit_change_homecity(struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4207
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:260
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:3338
static bool do_attack(struct unit *actor_unit, struct tile *target_tile, const struct action *paction)
Definition unithand.c:4999
static void send_combat(struct unit *pattacker, struct unit *pdefender, int att_veteran, int def_veteran, int bombard)
Definition unithand.c:4544
static bool do_unit_make_homeless(struct unit *punit, const struct action *paction)
Definition unithand.c:1015
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:4372
static bool non_allied_not_listed_at(const struct player *pplayer, const int *list, int n, const struct tile *ptile)
Definition unithand.c:290
void handle_unit_orders(struct player *pplayer, const struct packet_unit_orders *packet)
Definition unithand.c:6903
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:2531
static bool do_heal_unit(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:735
static bool do_capture_units(struct player *pplayer, struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:319
static bool do_expel_unit(struct player *pplayer, struct unit *actor, struct unit *target, const struct action *paction)
Definition unithand.c:606
static bool do_unit_conquer_city(struct player *act_player, struct unit *act_unit, struct city *tgt_city, struct action *paction)
Definition unithand.c:5617
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:1416
#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:4423
void handle_worker_task(struct player *pplayer, const struct packet_worker_task *packet)
Definition unithand.c:7012
static bool occupy_move(struct tile *def_tile, struct unit *punit, const struct action *paction)
Definition unithand.c:508
static bool do_unit_embark(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:978
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6714
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:3374
#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:5411
#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:3007
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:1972
static const char * unit_tired_attack_string(const struct unit *punit)
Definition unithand.c:4952
static bool do_unit_deboard(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:840
static bool does_terrain_block_action(const action_id act_id, bool is_target, struct unit *actor_unit, struct terrain *pterrain)
Definition unithand.c:1374
static void unit_activity_dependencies(struct unit *punit, enum unit_activity old_activity, struct extra_type *old_target)
Definition unithand.c:6651
static void unit_query_impossible(struct connection *pc, const int actor_id, const int target_id, int request_kind)
Definition unithand.c:3186
static bool unit_bombard(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:4639
bool unit_move_handling(struct unit *punit, struct tile *pdesttile, bool move_do_not_act)
Definition unithand.c:5764
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:4826
#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:6563
void create_trade_route(struct city *from, struct city *to, struct goods_type *goods)
Definition unithand.c:6422
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:3354
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:1458
static bool do_action_activity(struct unit *punit, const struct action *paction)
Definition unithand.c:6700
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:6826
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:5498
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:1054
static bool do_unit_unload(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:903
void unit_change_homecity_handling(struct unit *punit, struct city *new_pcity, bool rehome)
Definition unithand.c:4101
static bool tile_has_units_not_allied_to_but_seen_by(const struct tile *ptile, const struct player *pplayer)
Definition unithand.c:1356
static bool do_action_activity_targeted(struct unit *punit, const struct action *paction, struct extra_type **new_target)
Definition unithand.c:6772
static bool do_scout(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unithand.c:6878
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:1320
static bool unit_do_help_build(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:5957
void handle_unit_type_upgrade(struct player *pplayer, Unit_type_id uti)
Definition unithand.c:189
static bool city_add_unit(struct player *pplayer, struct unit *punit, struct city *pcity, const struct action *paction)
Definition unithand.c:4241
static bool do_unit_load(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:882
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:3205
static bool do_wipe_units(struct unit *punit, struct tile *pdesttile, const struct action *paction)
Definition unithand.c:553
static bool unit_nuke(struct player *pplayer, struct unit *punit, struct tile *def_tile, const struct action *paction)
Definition unithand.c:4756
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:5655
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:2267
void handle_unit_sscs_set(struct player *pplayer, int unit_id, enum unit_ss_data_type type, int value)
Definition unithand.c:6455
static bool do_unit_board(struct player *act_player, struct unit *act_unit, struct unit *tgt_unit, const struct action *paction)
Definition unithand.c:859
static void see_combat(struct unit *pattacker, struct unit *pdefender)
Definition unithand.c:4485
#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:1095
static const char * unit_achieved_rank_string(const struct unit *punit)
Definition unithand.c:4935
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:5726
static bool do_conquer_extras(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:696
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6612
static bool do_unit_establish_trade(struct player *pplayer, struct unit *punit, struct city *pcity_dest, const struct action *paction)
Definition unithand.c:6072
static bool do_disembark(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:920
static bool unit_activity_internal(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6745
static void unit_plans_clear(struct unit *punit)
Definition unithand.c:6547
static bool city_build(struct player *pplayer, struct unit *punit, struct tile *ptile, const char *name, const struct action *paction)
Definition unithand.c:4319
static void unit_attack_civilian_casualties(const struct unit *punit, struct city *pcity, const struct action *paction, const char *reason)
Definition unithand.c:4589
static bool do_unit_hut(struct player *act_player, struct unit *act_unit, struct tile *tgt_tile, const struct action *paction)
Definition unithand.c:948
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:1952
#define ACTION_PERFORM_UNIT_EXTRAS(action, actor, target, action_performer)
static const char * unit_firepower_if_not_one(int firepower)
Definition unithand.c:4974
static const char * unit_veteran_level_string(const struct unit *punit)
Definition unithand.c:4914
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:3127
#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:361
void unit_did_action(struct unit *punit)
Definition unittools.c:5090
void collect_ransom(struct unit *pcollector, struct unit *punit, bool vet)
Definition unittools.c:2661
bool do_airline(struct unit *punit, struct city *pdest_city, const struct action *paction)
Definition unittools.c:3084
void unit_make_contact(const struct unit *punit, struct tile *ptile, struct player *pplayer)
Definition unittools.c:5207
bool execute_orders(struct unit *punit, const bool fresh)
Definition unittools.c:4543
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1566
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:293
void combat_veterans(struct unit *attacker, struct unit *defender, bool powerless, int att_vet, int def_vet)
Definition unittools.c:406
void do_nuclear_explosion(const struct action *paction, const struct unit_type *act_utype, struct player *pplayer, struct tile *ptile)
Definition unittools.c:3052
void package_unit(struct unit *punit, struct packet_unit_info *packet)
Definition unittools.c:2751
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2882
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2895
void notify_unit_experience(struct unit *punit)
Definition unittools.c:756
void unit_activities_cancel(struct unit *punit)
Definition unittools.c:809
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:2832
void unit_forget_last_activity(struct unit *punit)
Definition unittools.c:1062
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:5029
void do_explore(struct unit *punit)
Definition unittools.c:3117
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3407
bool unit_can_do_action_now(const struct unit *punit)
Definition unittools.c:5057
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2157
bool do_paradrop(struct unit *punit, struct tile *ptile, const struct action *paction)
Definition unittools.c:3153
void unit_transport_unload_send(struct unit *punit)
Definition unittools.c:3459
void unit_assign_specific_activity_target(struct unit *punit, enum unit_activity *activity, enum gen_action action, struct extra_type **target)
Definition unittools.c:1091
struct unit * unit_change_owner(struct unit *punit, struct player *pplayer, int homecity, enum unit_loss_reason reason)
Definition unittools.c:2217
bool teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, bool verbose)
Definition unittools.c:1200
void unit_get_goods(struct unit *punit)
Definition unittools.c:1629
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:4096
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
Definition unittools.c:2284
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1238
bool unit_activity_needs_target_from_client(enum unit_activity activity)
Definition unittools.c:1071
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:1954
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:2535
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:2634
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:1758
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:865
#define unit_type_iterate_end
Definition unittype.h:872
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Definition vision.c:33
bool vision_reveal_tiles(struct vision *vision, bool reveal_tiles)
Definition vision.c:62
void vision_free(struct vision *vision)
Definition vision.c:50
#define V_RADIUS(main_sq, invis_sq, subs_sq)
Definition vision.h:95
short int v_radius_t[V_COUNT]
Definition vision.h:82
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