Freeciv-3.1
Loading...
Searching...
No Matches
unit.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/* utility */
19#include "astring.h"
20#include "bitvector.h"
21#include "fcintl.h"
22#include "mem.h"
23#include "shared.h"
24#include "support.h"
25
26/* common */
27#include "ai.h"
28#include "actions.h"
29#include "base.h"
30#include "city.h"
31#include "game.h"
32#include "log.h"
33#include "map.h"
34#include "movement.h"
35#include "packets.h"
36#include "player.h"
37#include "road.h"
38#include "tech.h"
39#include "traderoutes.h"
40#include "unitlist.h"
41
42#include "unit.h"
43
45
47 { ACTIVITY_PILLAGE, ACTIVITY_GEN_ROAD, ACTIVITY_IRRIGATE, ACTIVITY_MINE,
48 ACTIVITY_BASE, ACTIVITY_CULTIVATE, ACTIVITY_PLANT, ACTIVITY_TRANSFORM,
49 ACTIVITY_POLLUTION, ACTIVITY_FALLOUT, ACTIVITY_LAST };
50
51struct cargo_iter {
53 const struct unit_list_link *links[GAME_TRANSPORT_MAX_RECURSIVE];
54 int depth;
55};
56#define CARGO_ITER(iter) ((struct cargo_iter *) (iter))
57
58/**********************************************************************/
61bool are_unit_orders_equal(const struct unit_order *order1,
62 const struct unit_order *order2)
63{
64 return order1->order == order2->order
65 && order1->activity == order2->activity
66 && order1->target == order2->target
67 && order1->sub_target == order2->sub_target
68 && order1->action == order2->action
69 && order1->dir == order2->dir;
70}
71
72/**********************************************************************/
88 const struct player *restriction,
89 const struct unit *punit,
90 const struct city *pdest_city)
91{
92 const struct city *psrc_city = tile_city(unit_tile(punit));
93 const struct player *punit_owner;
94 const struct tile *dst_tile = NULL;
95 const struct unit_type *putype = unit_type_get(punit);
96 enum unit_airlift_result ok_result = AR_OK;
97
98 if (0 == punit->moves_left
99 && !utype_may_act_move_frags(putype, ACTION_AIRLIFT, 0)) {
100 /* No moves left. */
101 return AR_NO_MOVES;
102 }
103
104 if (!unit_can_do_action(punit, ACTION_AIRLIFT)) {
105 return AR_WRONG_UNITTYPE;
106 }
107
109 /* Units with occupants can't be airlifted currently. */
110 return AR_OCCUPIED;
111 }
112
113 if (NULL == psrc_city) {
114 /* No city there. */
115 return AR_NOT_IN_CITY;
116 }
117
118 if (psrc_city == pdest_city) {
119 /* Airlifting to our current position doesn't make sense. */
120 return AR_BAD_DST_CITY;
121 }
122
123 if (NULL != pdest_city) {
124 dst_tile = city_tile(pdest_city);
125
126 if (NULL != restriction
127 ? !could_exist_in_city(nmap, restriction, putype, pdest_city)
128 : !can_exist_at_tile(nmap, putype, dst_tile)) {
129 /* Can't exist at the destination tile. */
130 return AR_BAD_DST_CITY;
131 }
132 }
133
134 punit_owner = unit_owner(punit);
135
136 /* Check validity of both source and destination before checking capacity,
137 * to avoid misleadingly optimistic returns. */
138
139 if (punit_owner != city_owner(psrc_city)
140 && !(game.info.airlifting_style & AIRLIFTING_ALLIED_SRC
141 && pplayers_allied(punit_owner, city_owner(psrc_city)))) {
142 /* Not allowed to airlift from this source. */
143 return AR_BAD_SRC_CITY;
144 }
145
146 if (NULL != pdest_city && punit_owner != city_owner(pdest_city)
147 && (!(game.info.airlifting_style & AIRLIFTING_ALLIED_DEST
148 && pplayers_allied(punit_owner, city_owner(pdest_city)))
149 || is_non_allied_unit_tile(dst_tile, punit_owner))) {
150 /* Not allowed to airlift to this destination. */
151 return AR_BAD_DST_CITY;
152 }
153
154 /* Check airlift capacities */
156 if (NULL == restriction || city_owner(psrc_city) == restriction) {
157 /* We know for sure whether or not src can airlift this turn. */
158 if (0 >= psrc_city->airlift
159 && !(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)) {
160 /* The source cannot airlift for this turn (maybe already airlifted
161 * or no airport).
162 * See also do_airline() in server/unittools.h. */
163 return AR_SRC_NO_FLIGHTS;
164 } /* else, there is capacity; continue to other checks */
165 } else {
166 /* We don't have access to the 'airlift' field. Assume it's OK; can
167 * only find out for sure by trying it. */
168 ok_result = AR_OK_SRC_UNKNOWN;
169 }
170 }
171
172 if (NULL != pdest_city && !game.info.airlift_to_always_enabled) {
173 if (NULL == restriction || city_owner(pdest_city) == restriction) {
174 if (0 >= pdest_city->airlift
175 && !(game.info.airlifting_style & AIRLIFTING_UNLIMITED_DEST)) {
176 /* The destination cannot support airlifted units for this turn
177 * (maybe already airlifted or no airport).
178 * See also do_airline() in server/unittools.h. */
179 return AR_DST_NO_FLIGHTS;
180 } /* else continue */
181 } else {
182 ok_result = AR_OK_DST_UNKNOWN;
183 }
184 }
185
186 return ok_result;
187}
188
189/**********************************************************************/
196bool unit_can_airlift_to(const struct civ_map *nmap,
197 const struct unit *punit,
198 const struct city *pdest_city)
199{
200 if (is_server()) {
201 return is_action_enabled_unit_on_city(nmap, ACTION_AIRLIFT,
202 punit, pdest_city);
203 } else {
204 return action_prob_possible(action_prob_vs_city(nmap, punit, ACTION_AIRLIFT,
205 pdest_city));
206 }
207}
208
209/**********************************************************************/
212bool unit_has_orders(const struct unit *punit)
213{
214 return punit->has_orders;
215}
216
217/**********************************************************************/
224int unit_shield_value(const struct unit *punit,
225 const struct unit_type *punittype,
226 const struct action *paction)
227{
228 int value;
229
230 bool has_unit;
231 const struct player *act_player;
232
233 has_unit = punit != NULL;
234
235 if (has_unit && punittype == NULL) {
236 punittype = unit_type_get(punit);
237 }
238
239 fc_assert_ret_val(punittype != NULL, 0);
240 fc_assert(punit == NULL || unit_type_get(punit) == punittype);
241 fc_assert_ret_val(paction != NULL, 0);
242
243 act_player = has_unit ? unit_owner(punit) : NULL;
244 /* TODO: determine if tile and city should be where the unit currently is
245 * located or the target city. Those two may differ. Wait for ruleset
246 * author feed back. */
247
248 value = utype_build_shield_cost_base(punittype);
249 value += ((value
251 &(const struct req_context) {
252 .player = act_player,
253 .unit = punit,
254 .unittype = punittype,
255 .action = paction,
256 },
257 NULL,
258 EFT_UNIT_SHIELD_VALUE_PCT))
259 / 100);
260
261 return value;
262}
263
264/**********************************************************************/
269 const struct unit *punit)
270{
271 struct city *pcity = tile_city(unit_tile(punit));
272
273 if (pcity == NULL) {
274 /* No city to help at this tile. */
275 return FALSE;
276 }
277
278 if (!utype_can_do_action(unit_type_get(punit), ACTION_HELP_WONDER)) {
279 /* This unit can never do help wonder. */
280 return FALSE;
281 }
282
283 /* Evaluate all action enablers for extra accuracy. */
284 /* TODO: Is it worth it? */
286 ACTION_HELP_WONDER,
287 pcity));
288}
289
290/**********************************************************************/
295{
296 struct city *phomecity, *pdestcity;
297
298 return (utype_can_do_action(unit_type_get(punit), ACTION_TRADE_ROUTE)
299 && (pdestcity = tile_city(unit_tile(punit)))
300 && (phomecity = game_city_by_number(punit->homecity))
301 && can_cities_trade(phomecity, pdestcity));
302}
303
304/**********************************************************************/
308{
310}
311
312/**********************************************************************/
315bool is_attack_unit(const struct unit *punit)
316{
317 return ((unit_can_do_action_result(punit, ACTRES_ATTACK)
318 || unit_can_do_action_result(punit, ACTRES_BOMBARD))
319 && unit_type_get(punit)->attack_strength > 0);
320}
321
322/**********************************************************************/
327bool is_military_unit(const struct unit *punit)
328{
329 return !unit_has_type_flag(punit, UTYF_CIVILIAN);
330}
331
332/**********************************************************************/
336bool unit_can_do_action(const struct unit *punit,
337 const action_id act_id)
338{
339 return utype_can_do_action(unit_type_get(punit), act_id);
340}
341
342/**********************************************************************/
347 enum action_result result)
348{
350}
351
352/**********************************************************************/
357 enum action_sub_result sub_result)
358{
360}
361
362/**********************************************************************/
365bool is_square_threatened(const struct civ_map *nmap,
366 const struct player *pplayer,
367 const struct tile *ptile, bool omniscient)
368{
369 square_iterate(nmap, ptile, 2, ptile1) {
370 unit_list_iterate(ptile1->units, punit) {
371 if ((omniscient
372 || can_player_see_unit(pplayer, punit))
373 && pplayers_at_war(pplayer, unit_owner(punit))
377 && is_native_near_tile(nmap,
378 unit_class_get(punit), ptile)))) {
379 return TRUE;
380 }
383
384 return FALSE;
385}
386
387/**********************************************************************/
391bool is_field_unit(const struct unit *punit)
392{
393 return unit_has_type_flag(punit, UTYF_FIELDUNIT);
394}
395
396/**********************************************************************/
403bool is_hiding_unit(const struct unit *punit)
404{
405 enum vision_layer vl = unit_type_get(punit)->vlayer;
406
407 if (vl == V_INVIS || vl == V_SUBSURFACE) {
408 return TRUE;
409 }
410
411 if (unit_transported(punit)) {
413 if (vl == V_INVIS || vl == V_SUBSURFACE) {
414 return TRUE;
415 }
416 }
417
418 return FALSE;
419}
420
421/**********************************************************************/
426{
427 return game.info.killcitizen
428 && uclass_has_flag(unit_class_get(punit), UCF_KILLCITIZEN);
429}
430
431/**********************************************************************/
435bool unit_can_add_or_build_city(const struct civ_map *nmap,
436 const struct unit *punit)
437{
438 struct city *tgt_city;
439
440 if ((tgt_city = tile_city(unit_tile(punit)))) {
442 ACTION_JOIN_CITY, tgt_city));
443 } else {
445 ACTION_FOUND_CITY, unit_tile(punit), NULL));
446 }
447}
448
449/**********************************************************************/
452bool can_unit_change_homecity_to(const struct civ_map *nmap,
453 const struct unit *punit,
454 const struct city *pcity)
455{
456 if (pcity == NULL) {
457 /* Can't change home city to a non existing city. */
458 return FALSE;
459 }
460
461 return action_prob_possible(action_prob_vs_city(nmap, punit, ACTION_HOME_CITY,
462 pcity));
463}
464
465/**********************************************************************/
468bool can_unit_change_homecity(const struct civ_map *nmap,
469 const struct unit *punit)
470{
472}
473
474/**********************************************************************/
482int get_activity_rate(const struct unit *punit)
483{
484 const struct veteran_level *vlevel;
485 const struct unit_type *ptype;
486 int move_rate;
487
488 fc_assert_ret_val(punit != NULL, 0);
489
490 ptype = unit_type_get(punit);
491 vlevel = utype_veteran_level(ptype, punit->veteran);
492 fc_assert_ret_val(vlevel != NULL, 0);
493
494 /* The speed of the settler depends on its base move_rate, not on
495 * the number of moves actually remaining or the adjusted move rate.
496 * This means sea formers won't have their activity rate increased by
497 * Magellan's, and it means injured units work just as fast as
498 * uninjured ones. Note the value is never less than SINGLE_MOVE. */
500
501 /* All settler actions are multiplied by ACTIVITY_FACTOR. */
502 return ACTIVITY_FACTOR
503 * (float)vlevel->power_fact / 100
505}
506
507/**********************************************************************/
514{
515 /* This logic is also coded in client/goto.c. */
516 if (punit->moves_left > 0) {
517 return get_activity_rate(punit);
518 } else {
519 return 0;
520 }
521}
522
523/**********************************************************************/
530 enum unit_activity activity,
531 const struct tile *ptile,
532 struct extra_type *tgt)
533{
534 /* FIXME: This is just an approximation since we don't account for
535 * get_activity_rate_this_turn. */
536 int speed = get_activity_rate(punit);
537 int points_needed = tile_activity_time(activity, ptile, tgt);
538
539 if (points_needed >= 0 && speed > 0) {
540 return (points_needed - 1) / speed + 1; /* round up */
541 } else {
542 return FC_INFINITY;
543 }
544}
545
546/**********************************************************************/
549bool activity_requires_target(enum unit_activity activity)
550{
551 switch (activity) {
552 case ACTIVITY_PILLAGE:
553 case ACTIVITY_BASE:
554 case ACTIVITY_GEN_ROAD:
555 case ACTIVITY_IRRIGATE:
556 case ACTIVITY_MINE:
557 case ACTIVITY_POLLUTION:
558 case ACTIVITY_FALLOUT:
559 return TRUE;
560 case ACTIVITY_IDLE:
561 case ACTIVITY_FORTIFIED:
562 case ACTIVITY_SENTRY:
563 case ACTIVITY_GOTO:
564 case ACTIVITY_EXPLORE:
565 case ACTIVITY_TRANSFORM:
566 case ACTIVITY_CULTIVATE:
567 case ACTIVITY_PLANT:
568 case ACTIVITY_FORTIFYING:
569 case ACTIVITY_CONVERT:
570 return FALSE;
571 /* These shouldn't be kicking around internally. */
572 case ACTIVITY_FORTRESS:
573 case ACTIVITY_AIRBASE:
574 case ACTIVITY_PATROL_UNUSED:
575 default:
577 }
578
579 return FALSE;
580}
581
582/**********************************************************************/
592{
593 return unit_type_get(punit)->adv.worker;
594}
595
596/**********************************************************************/
600{
602 int i = 0;
603
604 for (act = 0; act < ACTIVITY_LAST; act++) {
605 if (is_real_activity(act)) {
606 real_activities[i++] = act;
607 }
608 }
609
610 real_activities[i] = ACTIVITY_LAST;
611}
612
613/**********************************************************************/
617bool is_real_activity(enum unit_activity activity)
618{
619 /* ACTIVITY_FORTRESS, ACTIVITY_AIRBASE, ACTIVITY_OLD_ROAD, and
620 * ACTIVITY_OLD_RAILROAD are deprecated */
621 return (activity < ACTIVITY_LAST)
622 && activity != ACTIVITY_FORTRESS
623 && activity != ACTIVITY_AIRBASE
624 && activity != ACTIVITY_OLD_ROAD
625 && activity != ACTIVITY_OLD_RAILROAD
626 && activity != ACTIVITY_UNKNOWN
627 && activity != ACTIVITY_PATROL_UNUSED;
628}
629
630/**********************************************************************/
633const char *get_activity_text(enum unit_activity activity)
634{
635 /* The switch statement has just the activities listed with no "default"
636 * handling. This enables the compiler to detect missing entries
637 * automatically, and still handles everything correctly. */
638 switch (activity) {
639 case ACTIVITY_IDLE:
640 return _("Idle");
641 case ACTIVITY_POLLUTION:
642 return _("Pollution");
643 case ACTIVITY_MINE:
644 /* TRANS: Activity name, verb in English */
645 return Q_("?act:Mine");
646 case ACTIVITY_PLANT:
647 /* TRANS: Activity name, verb in English */
648 return _("Plant");
649 case ACTIVITY_IRRIGATE:
650 return _("Irrigate");
651 case ACTIVITY_CULTIVATE:
652 return _("Cultivate");
653 case ACTIVITY_FORTIFYING:
654 return _("Fortifying");
655 case ACTIVITY_FORTIFIED:
656 return _("Fortified");
657 case ACTIVITY_SENTRY:
658 return _("Sentry");
659 case ACTIVITY_PILLAGE:
660 return _("Pillage");
661 case ACTIVITY_GOTO:
662 return _("Goto");
663 case ACTIVITY_EXPLORE:
664 return _("Explore");
665 case ACTIVITY_TRANSFORM:
666 return _("Transform");
667 case ACTIVITY_FALLOUT:
668 return _("Fallout");
669 case ACTIVITY_BASE:
670 return _("Base");
671 case ACTIVITY_GEN_ROAD:
672 return _("Road");
673 case ACTIVITY_CONVERT:
674 return _("Convert");
675 case ACTIVITY_OLD_ROAD:
676 case ACTIVITY_OLD_RAILROAD:
677 case ACTIVITY_FORTRESS:
678 case ACTIVITY_AIRBASE:
679 case ACTIVITY_UNKNOWN:
680 case ACTIVITY_PATROL_UNUSED:
681 case ACTIVITY_LAST:
682 break;
683 }
684
686 return _("Unknown");
687}
688
689/**********************************************************************/
695bool could_unit_be_in_transport(const struct unit *pcargo,
696 const struct unit *ptrans)
697{
698 /* Make sure this transporter can carry this type of unit. */
699 if (!can_unit_transport(ptrans, pcargo)) {
700 return FALSE;
701 }
702
703 /* Make sure there's room in the transporter. */
704 if (get_transporter_occupancy(ptrans)
705 >= get_transporter_capacity(ptrans)) {
706 return FALSE;
707 }
708
709 /* Check iff this is a valid transport. */
710 if (!unit_transport_check(pcargo, ptrans)) {
711 return FALSE;
712 }
713
714 /* Check transport depth. */
716 < 1 + unit_transport_depth(ptrans) + unit_cargo_depth(pcargo)) {
717 return FALSE;
718 }
719
720 return TRUE;
721}
722
723/**********************************************************************/
727bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
728{
729 if (!pcargo || !ptrans || pcargo == ptrans) {
730 return FALSE;
731 }
732
733 /* Double-check ownership of the units: you can load into an allied unit
734 * (of course only allied units can be on the same tile). */
735 if (!pplayers_allied(unit_owner(pcargo), unit_owner(ptrans))) {
736 return FALSE;
737 }
738
739 /* Un-embarkable transport must be in city or base to load cargo. */
741 && !tile_city(unit_tile(ptrans))
742 && !tile_has_native_base(unit_tile(ptrans), unit_type_get(ptrans))) {
743 return FALSE;
744 }
745
746 return could_unit_be_in_transport(pcargo, ptrans);
747}
748
749/**********************************************************************/
752bool can_unit_load(const struct unit *pcargo, const struct unit *ptrans)
753{
754 /* This function needs to check EVERYTHING. */
755
756 /* Check positions of the units. Of course you can't load a unit onto
757 * a transporter on a different tile... */
758 if (!same_pos(unit_tile(pcargo), unit_tile(ptrans))) {
759 return FALSE;
760 }
761
762 /* Cannot load if cargo is already loaded onto something else. */
763 if (unit_transported(pcargo)) {
764 return FALSE;
765 }
766
767 return could_unit_load(pcargo, ptrans);
768}
769
770/**********************************************************************/
779bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
780{
781 if (!pcargo || !ptrans) {
782 return FALSE;
783 }
784
785 /* Make sure the unit's transporter exists and is known. */
786 if (unit_transport_get(pcargo) != ptrans) {
787 return FALSE;
788 }
789
790 /* Un-disembarkable transport must be in city or base to unload cargo. */
792 && !tile_city(unit_tile(ptrans))
793 && !tile_has_native_base(unit_tile(ptrans), unit_type_get(ptrans))) {
794 return FALSE;
795 }
796
797 return TRUE;
798}
799
800/**********************************************************************/
805 const struct unit *pcargo,
806 const struct unit *ptrans)
807{
808 if (!pcargo || !ptrans) {
809 return FALSE;
810 }
811
812 fc_assert_ret_val(unit_transport_get(pcargo) == ptrans, FALSE);
813
814 if (is_server()) {
815 return (is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_ALIGHT,
816 pcargo, ptrans)
817 || is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_UNLOAD,
818 ptrans, pcargo));
819 } else {
820 return (action_prob_possible(
821 action_prob_vs_unit(nmap, pcargo, ACTION_TRANSPORT_ALIGHT, ptrans))
823 action_prob_vs_unit(nmap, ptrans, ACTION_TRANSPORT_UNLOAD,
824 pcargo)));
825 }
826}
827
828
829/**********************************************************************/
834bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
835{
836 action_by_result_iterate(paction, ACTRES_PARADROP) {
837 if (action_maybe_possible_actor_unit(nmap, paction->id, punit)) {
838 return TRUE;
839 }
841 action_by_result_iterate(paction, ACTRES_PARADROP_CONQUER) {
842 if (action_maybe_possible_actor_unit(nmap, paction->id, punit)) {
843 return TRUE;
844 }
846
847 return FALSE;
848}
849
850/**********************************************************************/
854 struct unit *punit)
855{
856 enum unit_activity current = punit->activity;
857 struct extra_type *target = punit->activity_target;
858 enum unit_activity current2 =
859 (current == ACTIVITY_FORTIFIED) ? ACTIVITY_FORTIFYING : current;
860 bool result;
861
862 punit->activity = ACTIVITY_IDLE;
863 punit->activity_target = NULL;
864
865 result = can_unit_do_activity_targeted(nmap, punit, current2, target);
866
867 punit->activity = current;
868 punit->activity_target = target;
869
870 return result;
871}
872
873/**********************************************************************/
880bool can_unit_do_activity(const struct civ_map *nmap,
881 const struct unit *punit,
882 enum unit_activity activity)
883{
884 struct extra_type *target = NULL;
885
886 /* FIXME: Lots of callers (usually client real_menus_update()) rely on
887 * being able to find out whether an activity is in general possible.
888 * Find one for them, but when they come to do the activity, they will
889 * have to determine the target themselves */
890 {
891 struct tile *ptile = unit_tile(punit);
892
893 if (activity == ACTIVITY_IRRIGATE) {
894 target = next_extra_for_tile(ptile,
895 EC_IRRIGATION,
897 punit);
898 if (NULL == target) {
899 return FALSE; /* No more irrigation extras available. */
900 }
901 } else if (activity == ACTIVITY_MINE) {
902 target = next_extra_for_tile(ptile,
903 EC_MINE,
905 punit);
906 if (NULL == target) {
907 return FALSE; /* No more mine extras available. */
908 }
909 }
910 }
911
912 return can_unit_do_activity_targeted(nmap, punit, activity, target);
913}
914
915/**********************************************************************/
920 const struct unit *punit,
921 enum unit_activity activity,
922 struct extra_type *target)
923{
924 return can_unit_do_activity_targeted_at(nmap, punit, activity, target,
926}
927
928/**********************************************************************/
933 const struct unit *punit,
934 enum unit_activity activity,
935 struct extra_type *target,
936 const struct tile *ptile)
937{
938 /* Check that no build activity conflicting with one already in progress
939 * gets executed. */
940 /* FIXME: Should check also the cases where one of the activities is terrain
941 * change that destroys the target of the other activity */
942 if (target != NULL && is_build_activity(activity)) {
943 if (tile_is_placing(ptile)) {
944 return FALSE;
945 }
946
947 unit_list_iterate(ptile->units, tunit) {
948 if (is_build_activity(tunit->activity)
949 && !can_extras_coexist(target, tunit->activity_target)) {
950 return FALSE;
951 }
953 }
954
955#define RETURN_IS_ACTIVITY_ENABLED_UNIT_ON(paction) \
956{ \
957 switch (action_get_target_kind(paction)) { \
958 case ATK_TILE: \
959 return is_action_enabled_unit_on_tile(nmap, paction->id, \
960 punit, ptile, target); \
961 case ATK_EXTRAS: \
962 return is_action_enabled_unit_on_extras(nmap, paction->id, \
963 punit, ptile, target); \
964 case ATK_CITY: \
965 case ATK_UNIT: \
966 case ATK_UNITS: \
967 case ATK_SELF: \
968 return FALSE; \
969 case ATK_COUNT: \
970 break; /* Handle outside switch */ \
971 } \
972 fc_assert(action_target_kind_is_valid( \
973 action_get_target_kind(paction))); \
974 return FALSE; \
975 }
976
977 switch (activity) {
978 case ACTIVITY_IDLE:
979 case ACTIVITY_GOTO:
980 return TRUE;
981
982 case ACTIVITY_POLLUTION:
983 /* The call below doesn't support actor tile speculation. */
984 fc_assert_msg(unit_tile(punit) == ptile,
985 "Please use action_speculate_unit_on_tile()");
986 return is_action_enabled_unit_on_tile(nmap, ACTION_CLEAN_POLLUTION,
987 punit, ptile, target);
988
989 case ACTIVITY_FALLOUT:
990 /* The call below doesn't support actor tile speculation. */
991 fc_assert_msg(unit_tile(punit) == ptile,
992 "Please use action_speculate_unit_on_tile()");
993 return is_action_enabled_unit_on_tile(nmap, ACTION_CLEAN_FALLOUT,
994 punit, ptile, target);
995
996 case ACTIVITY_MINE:
997 /* The call below doesn't support actor tile speculation. */
998 fc_assert_msg(unit_tile(punit) == ptile,
999 "Please use action_speculate_unit_on_tile()");
1000 return is_action_enabled_unit_on_tile(nmap, ACTION_MINE, punit,
1001 ptile, target);
1002
1003 case ACTIVITY_PLANT:
1004 /* The call below doesn't support actor tile speculation. */
1005 fc_assert_msg(unit_tile(punit) == ptile,
1006 "Please use action_speculate_unit_on_tile()");
1007 return is_action_enabled_unit_on_tile(nmap, ACTION_PLANT,
1008 punit, ptile, NULL);
1009
1010 case ACTIVITY_IRRIGATE:
1011 /* The call below doesn't support actor tile speculation. */
1012 fc_assert_msg(unit_tile(punit) == ptile,
1013 "Please use action_speculate_unit_on_tile()");
1014 return is_action_enabled_unit_on_tile(nmap, ACTION_IRRIGATE, punit,
1015 ptile, target);
1016
1017 case ACTIVITY_CULTIVATE:
1018 /* The call below doesn't support actor tile speculation. */
1019 fc_assert_msg(unit_tile(punit) == ptile,
1020 "Please use action_speculate_unit_on_tile()");
1021 return is_action_enabled_unit_on_tile(nmap, ACTION_CULTIVATE,
1022 punit, ptile, NULL);
1023
1024 case ACTIVITY_FORTIFYING:
1025 /* The call below doesn't support actor tile speculation. */
1026 fc_assert_msg(unit_tile(punit) == ptile,
1027 "Please use action_speculate_unit_on_self()");
1028 return is_action_enabled_unit_on_self(nmap, ACTION_FORTIFY,
1029 punit);
1030
1031 case ACTIVITY_FORTIFIED:
1032 return FALSE;
1033
1034 case ACTIVITY_BASE:
1035 /* The call below doesn't support actor tile speculation. */
1036 fc_assert_msg(unit_tile(punit) == ptile,
1037 "Please use action_speculate_unit_on_tile()");
1038 return is_action_enabled_unit_on_tile(nmap, ACTION_BASE,
1039 punit, ptile, target);
1040
1041 case ACTIVITY_GEN_ROAD:
1042 /* The call below doesn't support actor tile speculation. */
1043 fc_assert_msg(unit_tile(punit) == ptile,
1044 "Please use action_speculate_unit_on_tile()");
1045 return is_action_enabled_unit_on_tile(nmap, ACTION_ROAD,
1046 punit, ptile, target);
1047
1048 case ACTIVITY_SENTRY:
1050 && !unit_transported(punit)) {
1051 /* Don't let units sentry on tiles they will die on. */
1052 return FALSE;
1053 }
1054 return TRUE;
1055
1056 case ACTIVITY_PILLAGE:
1057 /* The call below doesn't support actor tile speculation. */
1058 fc_assert_msg(unit_tile(punit) == ptile,
1059 "Please use action_speculate_unit_on_tile()");
1061
1062 case ACTIVITY_EXPLORE:
1063 return (!unit_type_get(punit)->fuel && !is_losing_hp(punit));
1064
1065 case ACTIVITY_TRANSFORM:
1066 /* The call below doesn't support actor tile speculation. */
1067 fc_assert_msg(unit_tile(punit) == ptile,
1068 "Please use action_speculate_unit_on_tile()");
1069 return is_action_enabled_unit_on_tile(nmap, ACTION_TRANSFORM_TERRAIN,
1070 punit, ptile, NULL);
1071
1072 case ACTIVITY_CONVERT:
1073 /* The call below doesn't support actor tile speculation. */
1074 fc_assert_msg(unit_tile(punit) == ptile,
1075 "Please use action_speculate_unit_on_self()");
1076 return is_action_enabled_unit_on_self(nmap, ACTION_CONVERT, punit);
1077
1078 case ACTIVITY_OLD_ROAD:
1079 case ACTIVITY_OLD_RAILROAD:
1080 case ACTIVITY_FORTRESS:
1081 case ACTIVITY_AIRBASE:
1082 case ACTIVITY_PATROL_UNUSED:
1083 case ACTIVITY_LAST:
1084 case ACTIVITY_UNKNOWN:
1085 break;
1086 }
1087 log_error("can_unit_do_activity_targeted_at() unknown activity %d",
1088 activity);
1089 return FALSE;
1090
1091#undef RETURN_IS_ACTIVITY_ENABLED_UNIT_ON
1092}
1093
1094/**********************************************************************/
1098 enum unit_activity new_activity)
1099{
1100 fc_assert_ret(new_activity != ACTIVITY_FORTRESS
1101 && new_activity != ACTIVITY_AIRBASE);
1102
1103 punit->activity = new_activity;
1104 punit->activity_count = 0;
1105 punit->activity_target = NULL;
1106 if (new_activity == ACTIVITY_IDLE && punit->moves_left > 0) {
1107 /* No longer done. */
1109 }
1110}
1111
1112/**********************************************************************/
1115void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
1116{
1118
1119 if (new_activity == ACTIVITY_FORTIFYING
1120 && punit->changed_from == ACTIVITY_FORTIFIED) {
1121 new_activity = ACTIVITY_FORTIFIED;
1122 }
1123 set_unit_activity_internal(punit, new_activity);
1124 if (new_activity == punit->changed_from) {
1126 }
1127}
1128
1129/**********************************************************************/
1133 enum unit_activity new_activity,
1134 struct extra_type *new_target)
1135{
1137 || new_target == NULL);
1138
1139 set_unit_activity_internal(punit, new_activity);
1140 punit->activity_target = new_target;
1141 if (new_activity == punit->changed_from
1142 && new_target == punit->changed_from_target) {
1144 }
1145}
1146
1147/**********************************************************************/
1150bool is_unit_activity_on_tile(enum unit_activity activity,
1151 const struct tile *ptile)
1152{
1153 unit_list_iterate(ptile->units, punit) {
1154 if (punit->activity == activity) {
1155 return TRUE;
1156 }
1158 return FALSE;
1159}
1160
1161/**********************************************************************/
1165bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
1166{
1167 bv_extras tgt_ret;
1168
1169 BV_CLR_ALL(tgt_ret);
1170 unit_list_iterate(ptile->units, punit) {
1171 if (punit->activity == ACTIVITY_PILLAGE) {
1173 }
1175
1176 return tgt_ret;
1177}
1178
1179/**********************************************************************/
1182void unit_activity_astr(const struct unit *punit, struct astring *astr)
1183{
1184 if (!punit || !astr) {
1185 return;
1186 }
1187
1188 switch (punit->activity) {
1189 case ACTIVITY_IDLE:
1191 int rate, f;
1192
1193 rate = unit_type_get(punit)->move_rate;
1194 f = ((punit->fuel) - 1);
1195
1196 /* Add in two parts as move_points_text() returns ptr to static
1197 * End result: "Moves: (fuel)moves_left" */
1198 astr_add_line(astr, "%s: (%s)", _("Moves"),
1199 move_points_text((rate * f) + punit->moves_left, FALSE));
1200 astr_add(astr, "%s",
1202 } else {
1203 astr_add_line(astr, "%s: %s", _("Moves"),
1205 }
1206 return;
1207 case ACTIVITY_POLLUTION:
1208 case ACTIVITY_FALLOUT:
1209 case ACTIVITY_OLD_ROAD:
1210 case ACTIVITY_OLD_RAILROAD:
1211 case ACTIVITY_TRANSFORM:
1212 case ACTIVITY_FORTIFYING:
1213 case ACTIVITY_FORTIFIED:
1214 case ACTIVITY_AIRBASE:
1215 case ACTIVITY_FORTRESS:
1216 case ACTIVITY_SENTRY:
1217 case ACTIVITY_GOTO:
1218 case ACTIVITY_EXPLORE:
1219 case ACTIVITY_CONVERT:
1220 case ACTIVITY_CULTIVATE:
1221 case ACTIVITY_PLANT:
1223 return;
1224 case ACTIVITY_MINE:
1225 case ACTIVITY_IRRIGATE:
1226 if (punit->activity_target == NULL) {
1228 } else {
1229 astr_add_line(astr, "Building %s",
1231 }
1232 return;
1233 case ACTIVITY_PILLAGE:
1234 if (punit->activity_target != NULL) {
1237 } else {
1239 }
1240 return;
1241 case ACTIVITY_BASE:
1244 return;
1245 case ACTIVITY_GEN_ROAD:
1248 return;
1249 case ACTIVITY_UNKNOWN:
1250 case ACTIVITY_PATROL_UNUSED:
1251 case ACTIVITY_LAST:
1252 break;
1253 }
1254
1255 log_error("Unknown unit activity %d for %s (nb %d) in %s()",
1256 punit->activity, unit_rule_name(punit), punit->id, __FUNCTION__);
1257}
1258
1259/**********************************************************************/
1265void unit_upkeep_astr(const struct unit *punit, struct astring *astr)
1266{
1267 if (!punit || !astr) {
1268 return;
1269 }
1270
1271 astr_add_line(astr, "%s %d/%d/%d", _("Food/Shield/Gold:"),
1273 punit->upkeep[O_GOLD]);
1274}
1275
1276/**********************************************************************/
1279struct player *unit_nationality(const struct unit *punit)
1280{
1281 fc_assert_ret_val(NULL != punit, NULL);
1282 return punit->nationality;
1283}
1284
1285/**********************************************************************/
1289void unit_tile_set(struct unit *punit, struct tile *ptile)
1290{
1291 fc_assert_ret(NULL != punit);
1292 punit->tile = ptile;
1293}
1294
1295/**********************************************************************/
1302struct unit *tile_allied_unit(const struct tile *ptile,
1303 const struct player *pplayer)
1304{
1305 struct unit *punit = NULL;
1306
1307 unit_list_iterate(ptile->units, cunit) {
1308 if (pplayers_allied(pplayer, unit_owner(cunit))) {
1309 punit = cunit;
1310 } else {
1311 return NULL;
1312 }
1313 }
1315
1316 return punit;
1317}
1318
1319/**********************************************************************/
1325struct unit *tile_enemy_unit(const struct tile *ptile,
1326 const struct player *pplayer)
1327{
1328 unit_list_iterate(ptile->units, punit) {
1329 if (pplayers_at_war(unit_owner(punit), pplayer)) {
1330 return punit;
1331 }
1333
1334 return NULL;
1335}
1336
1337/**********************************************************************/
1340struct unit *tile_non_allied_unit(const struct tile *ptile,
1341 const struct player *pplayer)
1342{
1343 unit_list_iterate(ptile->units, punit) {
1344 if (!pplayers_allied(unit_owner(punit), pplayer)) {
1345 return punit;
1346 }
1347 }
1349
1350 return NULL;
1351}
1352
1353/**********************************************************************/
1357struct unit *tile_other_players_unit(const struct tile *ptile,
1358 const struct player *pplayer)
1359{
1360 unit_list_iterate(ptile->units, punit) {
1361 if (unit_owner(punit) != pplayer) {
1362 return punit;
1363 }
1365
1366 return NULL;
1367}
1368
1369/**********************************************************************/
1373struct unit *tile_non_attack_unit(const struct tile *ptile,
1374 const struct player *pplayer)
1375{
1376 unit_list_iterate(ptile->units, punit) {
1377 if (pplayers_non_attack(unit_owner(punit), pplayer)) {
1378 return punit;
1379 }
1380 }
1382
1383 return NULL;
1384}
1385
1386/**********************************************************************/
1394struct unit *unit_occupies_tile(const struct tile *ptile,
1395 const struct player *pplayer)
1396{
1397 unit_list_iterate(ptile->units, punit) {
1398 if (!is_military_unit(punit)) {
1399 continue;
1400 }
1401
1402 if (uclass_has_flag(unit_class_get(punit), UCF_DOESNT_OCCUPY_TILE)) {
1403 continue;
1404 }
1405
1406 if (pplayers_at_war(unit_owner(punit), pplayer)) {
1407 return punit;
1408 }
1410
1411 return NULL;
1412}
1413
1414/**********************************************************************/
1421bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0,
1422 const struct civ_map *zmap)
1423{
1424 square_iterate(zmap, ptile0, 1, ptile) {
1425 struct terrain *pterrain;
1426 struct city *pcity;
1427
1428 pterrain = tile_terrain(ptile);
1429 if (terrain_has_flag(pterrain, TER_NO_ZOC)) {
1430 continue;
1431 }
1432
1433 pcity = tile_non_allied_city(ptile, pplayer);
1434 if (pcity != NULL) {
1435 if (unit_list_size(ptile->units) > 0) {
1436 /* Occupied enemy city, it doesn't matter if units inside have
1437 * UTYF_NOZOC or not. */
1438 return FALSE;
1439 }
1440 } else {
1441 unit_list_iterate(ptile->units, punit) {
1442 if (!pplayers_allied(unit_owner(punit), pplayer)
1443 && !unit_has_type_flag(punit, UTYF_NOZOC)
1445 bool hidden = FALSE;
1446
1447 /* We do NOT check the possibility that player is allied with an extra owner,
1448 * and should thus see inside the extra.
1449 * This is to avoid the situation where having an alliance with third player
1450 * suddenly causes ZoC from a unit that would not cause it without the alliance. */
1452 if (tile_has_extra(ptile, pextra)) {
1453 hidden = TRUE;
1454 break;
1455 }
1457
1458 if (!hidden) {
1459 return FALSE;
1460 }
1461 }
1463 }
1465
1466 return TRUE;
1467}
1468
1469/**********************************************************************/
1480bool is_plr_zoc_client(const struct player *pplayer, const struct tile *ptile0,
1481 const struct civ_map *zmap)
1482{
1483 square_iterate(zmap, ptile0, 1, ptile) {
1484 struct terrain *pterrain;
1485 struct city *pcity;
1486
1487 pterrain = tile_terrain(ptile);
1488 if (T_UNKNOWN == pterrain
1489 || terrain_has_flag(pterrain, TER_NO_ZOC)) {
1490 continue;
1491 }
1492
1493 pcity = tile_non_allied_city(ptile, pplayer);
1494 if (pcity != NULL) {
1495 if (pcity->client.occupied
1496 || TILE_KNOWN_UNSEEN == tile_get_known(ptile, pplayer)) {
1497 /* Occupied enemy city, it doesn't matter if units inside have
1498 * UTYF_NOZOC or not. Fogged city is assumed to be occupied. */
1499 return FALSE;
1500 }
1501 } else {
1502 unit_list_iterate(ptile->units, punit) {
1504 && !pplayers_allied(unit_owner(punit), pplayer)
1505 && !unit_has_type_flag(punit, UTYF_NOZOC)) {
1506 return FALSE;
1507 }
1509 }
1511
1512 return TRUE;
1513}
1514
1515/**********************************************************************/
1518bool unit_type_really_ignores_zoc(const struct unit_type *punittype)
1519{
1520 return (!uclass_has_flag(utype_class(punittype), UCF_ZOC)
1521 || utype_has_flag(punittype, UTYF_IGZOC));
1522}
1523
1524/**********************************************************************/
1532bool unit_being_aggressive(const struct civ_map *nmap,
1533 const struct unit *punit)
1534{
1535 if (!is_attack_unit(punit)) {
1536 return FALSE;
1537 }
1538 if (tile_city(unit_tile(punit))) {
1539 return FALSE;
1540 }
1542 switch (game.info.happyborders) {
1543 case HB_DISABLED:
1544 break;
1545 case HB_NATIONAL:
1547 return FALSE;
1548 }
1549 break;
1550 case HB_ALLIANCE:
1552 return FALSE;
1553 }
1554 break;
1555 }
1556 }
1558 unit_type_get(punit))) {
1559 return !is_unit_near_a_friendly_city(nmap, punit);
1560 }
1561
1562 return TRUE;
1563}
1564
1565/**********************************************************************/
1568bool is_build_activity(enum unit_activity activity)
1569{
1570 switch (activity) {
1571 case ACTIVITY_MINE:
1572 case ACTIVITY_IRRIGATE:
1573 case ACTIVITY_BASE:
1574 case ACTIVITY_GEN_ROAD:
1575 return TRUE;
1576 default:
1577 return FALSE;
1578 }
1579}
1580
1581/**********************************************************************/
1584bool is_clean_activity(enum unit_activity activity)
1585{
1586 switch (activity) {
1587 case ACTIVITY_PILLAGE:
1588 case ACTIVITY_POLLUTION:
1589 case ACTIVITY_FALLOUT:
1590 return TRUE;
1591 default:
1592 return FALSE;
1593 }
1594}
1595
1596/**********************************************************************/
1599bool is_terrain_change_activity(enum unit_activity activity)
1600{
1601 switch (activity) {
1602 case ACTIVITY_CULTIVATE:
1603 case ACTIVITY_PLANT:
1604 case ACTIVITY_TRANSFORM:
1605 return TRUE;
1606 default:
1607 return FALSE;
1608 }
1609}
1610
1611/**********************************************************************/
1614bool is_tile_activity(enum unit_activity activity)
1615{
1616 return is_build_activity(activity)
1617 || is_clean_activity(activity)
1618 || is_terrain_change_activity(activity);
1619}
1620
1621/**********************************************************************/
1625struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity,
1626 const struct unit_type *punittype,
1627 int veteran_level)
1628{
1629 /* Make sure that contents of unit structure are correctly initialized,
1630 * if you ever allocate it by some other mean than fc_calloc() */
1631 struct unit *punit = fc_calloc(1, sizeof(*punit));
1632 int max_vet_lvl;
1633
1634 /* It does not register the unit so the id is set to 0. */
1636
1637 fc_assert_ret_val(NULL != punittype, NULL); /* No untyped units! */
1638 punit->utype = punittype;
1639
1640 fc_assert_ret_val(NULL != pplayer, NULL); /* No unowned units! */
1641 punit->owner = pplayer;
1642 punit->nationality = pplayer;
1643
1644 punit->refcount = 1;
1646
1647 if (pcity) {
1648 unit_tile_set(punit, pcity->tile);
1649 punit->homecity = pcity->id;
1650 } else {
1651 unit_tile_set(punit, NULL);
1653 }
1654
1655 memset(punit->upkeep, 0, O_LAST * sizeof(*punit->upkeep));
1656 punit->goto_tile = NULL;
1657 max_vet_lvl = utype_veteran_levels(punittype) - 1;
1658 punit->veteran = MIN(veteran_level, max_vet_lvl);
1659 /* A unit new and fresh ... */
1663 punit->moved = FALSE;
1664
1665 punit->ssa_controller = SSA_NONE;
1668
1669 punit->transporter = NULL;
1670 punit->transporting = unit_list_new();
1671
1672 punit->carrying = NULL;
1673
1674 set_unit_activity(punit, ACTIVITY_IDLE);
1677
1678 punit->action_decision_want = ACT_DEC_NOTHING;
1680
1681 punit->stay = FALSE;
1682
1683 if (is_server()) {
1686
1688
1690
1691 memset(punit->server.upkeep_paid, 0,
1692 O_LAST * sizeof(*punit->server.upkeep_paid));
1693
1694 punit->server.ord_map = 0;
1695 punit->server.ord_city = 0;
1696
1697 punit->server.vision = NULL; /* No vision. */
1699 /* Must be an invalid turn number, and an invalid previous turn
1700 * number. */
1701 punit->server.action_turn = -2;
1702 /* punit->server.moving = NULL; set by fc_calloc(). */
1703
1704 punit->server.adv = fc_calloc(1, sizeof(*punit->server.adv));
1705
1706 CALL_FUNC_EACH_AI(unit_alloc, punit);
1707 } else {
1711 punit->client.act_prob_cache = NULL;
1712 }
1713
1714 return punit;
1715}
1716
1717/**********************************************************************/
1722{
1724
1725 /* Unload unit if transported. */
1728
1729 /* Check for transported units. Use direct access to the list. */
1730 if (unit_list_size(punit->transporting) != 0) {
1731 /* Unload all units. */
1733 unit_transport_unload(pcargo);
1735 }
1736 fc_assert(unit_list_size(punit->transporting) == 0);
1737
1738 if (punit->transporting) {
1739 unit_list_destroy(punit->transporting);
1740 }
1741
1742 CALL_FUNC_EACH_AI(unit_free, punit);
1743
1744 if (is_server() && punit->server.adv) {
1746 } else {
1749 }
1750 }
1751
1752 if (--punit->refcount <= 0) {
1753 FC_FREE(punit);
1754 }
1755}
1756
1757/**********************************************************************/
1762{
1763 if (punit->has_orders) {
1764 punit->goto_tile = NULL;
1765 free(punit->orders.list);
1766 punit->orders.list = NULL;
1767 }
1768 punit->orders.length = 0;
1770}
1771
1772/**********************************************************************/
1775int get_transporter_occupancy(const struct unit *ptrans)
1776{
1777 fc_assert_ret_val(ptrans, -1);
1778
1779 return unit_list_size(ptrans->transporting);
1780}
1781
1782/**********************************************************************/
1785static struct unit *base_transporter_for_unit(const struct unit *pcargo,
1786 const struct tile *ptile,
1787 bool (*unit_load_test)
1788 (const struct unit *pc,
1789 const struct unit *pt))
1790{
1791 struct unit *best_trans = NULL;
1792 struct {
1793 bool has_orders, is_idle, can_freely_unload;
1794 int depth, outermost_moves_left, total_moves;
1795 } cur, best = { FALSE };
1796
1797 unit_list_iterate(ptile->units, ptrans) {
1798 if (!unit_load_test(pcargo, ptrans)) {
1799 continue;
1800 } else if (best_trans == NULL) {
1801 best_trans = ptrans;
1802 }
1803
1804 /* Gather data from transport stack in a single pass, for use in
1805 * various conditions below. */
1806 cur.has_orders = unit_has_orders(ptrans);
1807 cur.outermost_moves_left = ptrans->moves_left;
1808 cur.total_moves = ptrans->moves_left + unit_move_rate(ptrans);
1809 unit_transports_iterate(ptrans, ptranstrans) {
1810 if (unit_has_orders(ptranstrans)) {
1811 cur.has_orders = TRUE;
1812 }
1813 cur.outermost_moves_left = ptranstrans->moves_left;
1814 cur.total_moves += ptranstrans->moves_left + unit_move_rate(ptranstrans);
1816
1817 /* Criteria for deciding the 'best' transport to load onto.
1818 * The following tests are applied in order; earlier ones have
1819 * lexicographically greater significance than later ones. */
1820
1821 /* Transports which have orders, or are on transports with orders,
1822 * are less preferable to transport stacks without orders (to
1823 * avoid loading on units that are just passing through). */
1824 if (best_trans != ptrans) {
1825 if (!cur.has_orders && best.has_orders) {
1826 best_trans = ptrans;
1827 } else if (cur.has_orders && !best.has_orders) {
1828 continue;
1829 }
1830 }
1831
1832 /* Else, transports which are idle are preferable (giving players
1833 * some control over loading) -- this does not check transports
1834 * of transports. */
1835 cur.is_idle = (ptrans->activity == ACTIVITY_IDLE);
1836 if (best_trans != ptrans) {
1837 if (cur.is_idle && !best.is_idle) {
1838 best_trans = ptrans;
1839 } else if (!cur.is_idle && best.is_idle) {
1840 continue;
1841 }
1842 }
1843
1844 /* Else, transports from which the cargo could unload at any time
1845 * are preferable to those where the cargo can only disembark in
1846 * cities/bases. */
1847 cur.can_freely_unload = utype_can_freely_unload(unit_type_get(pcargo),
1848 unit_type_get(ptrans));
1849 if (best_trans != ptrans) {
1850 if (cur.can_freely_unload && !best.can_freely_unload) {
1851 best_trans = ptrans;
1852 } else if (!cur.can_freely_unload && best.can_freely_unload) {
1853 continue;
1854 }
1855 }
1856
1857 /* Else, transports which are less deeply nested are preferable. */
1858 cur.depth = unit_transport_depth(ptrans);
1859 if (best_trans != ptrans) {
1860 if (cur.depth < best.depth) {
1861 best_trans = ptrans;
1862 } else if (cur.depth > best.depth) {
1863 continue;
1864 }
1865 }
1866
1867 /* Else, transport stacks where the outermost transport has more
1868 * moves left are preferable (on the assumption that it's the
1869 * outermost transport that's about to move). */
1870 if (best_trans != ptrans) {
1871 if (cur.outermost_moves_left > best.outermost_moves_left) {
1872 best_trans = ptrans;
1873 } else if (cur.outermost_moves_left < best.outermost_moves_left) {
1874 continue;
1875 }
1876 }
1877
1878 /* All other things being equal, as a tie-breaker, compare the total
1879 * moves left (this turn) and move rate (future turns) for the whole
1880 * stack, to take into account total potential movement for both
1881 * short and long journeys (we don't know which the cargo intends to
1882 * make). Doesn't try to account for whether transports can unload,
1883 * etc. */
1884 if (best_trans != ptrans) {
1885 if (cur.total_moves > best.total_moves) {
1886 best_trans = ptrans;
1887 } else {
1888 continue;
1889 }
1890 }
1891
1892 fc_assert(best_trans == ptrans);
1893 best = cur;
1895
1896 return best_trans;
1897}
1898
1899/**********************************************************************/
1904struct unit *transporter_for_unit(const struct unit *pcargo)
1905{
1906 return base_transporter_for_unit(pcargo, unit_tile(pcargo), can_unit_load);
1907}
1908
1909/**********************************************************************/
1914struct unit *transporter_for_unit_at(const struct unit *pcargo,
1915 const struct tile *ptile)
1916{
1917 return base_transporter_for_unit(pcargo, ptile, could_unit_load);
1918}
1919
1920/**********************************************************************/
1925 const struct unit *punit)
1926{
1928 return FALSE;
1929 }
1930
1933 return FALSE;
1934 }
1936
1937 return TRUE;
1938}
1939
1940/**********************************************************************/
1949 const struct unit *punit,
1950 const struct unit_type *to_unittype)
1951{
1952 fc_assert_ret_val(NULL != to_unittype, UU_NO_UNITTYPE);
1953
1954 if (!can_type_transport_units_cargo(to_unittype, punit)) {
1955 return UU_NOT_ENOUGH_ROOM;
1956 }
1957
1958 if (punit->transporter != NULL) {
1960 utype_class(to_unittype))) {
1962 }
1963 } else if (!can_exist_at_tile(nmap, to_unittype, unit_tile(punit))) {
1964 /* The new unit type can't survive on this terrain. */
1965 return UU_NOT_TERRAIN;
1966 }
1967
1968 return UU_OK;
1969}
1970
1971/**********************************************************************/
1981 const struct unit *punit,
1982 bool is_free)
1983{
1984 struct player *pplayer = unit_owner(punit);
1985 const struct unit_type *to_unittype = can_upgrade_unittype(pplayer,
1987 struct city *pcity;
1988 int cost;
1989
1990 if (!to_unittype) {
1991 return UU_NO_UNITTYPE;
1992 }
1993
1994 if (punit->activity == ACTIVITY_CONVERT) {
1995 /* TODO: There may be other activities that the upgraded unit is not
1996 allowed to do, which we could also test.
1997 -
1998 If convert were legal for new unit_type we could allow, but then it
1999 has a 'head start' getting activity time from the old conversion. */
2000 return UU_NOT_ACTIVITY;
2001 }
2002
2003 if (!is_free) {
2004 cost = unit_upgrade_price(pplayer, unit_type_get(punit), to_unittype);
2005 if (pplayer->economic.gold < cost) {
2006 return UU_NO_MONEY;
2007 }
2008
2009 pcity = tile_city(unit_tile(punit));
2010 if (!pcity) {
2011 return UU_NOT_IN_CITY;
2012 }
2013 if (city_owner(pcity) != pplayer) {
2014 /* TODO: Should upgrades in allied cities be possible? */
2015 return UU_NOT_CITY_OWNER;
2016 }
2017 }
2018
2019 /* TODO: Allow transported units to be reassigned. Check here
2020 * and make changes to upgrade_unit. */
2021 return unit_transform_result(nmap, punit, to_unittype);
2022}
2023
2024/**********************************************************************/
2027bool unit_can_convert(const struct civ_map *nmap,
2028 const struct unit *punit)
2029{
2030 const struct unit_type *tgt = unit_type_get(punit)->converted_to;
2031
2032 if (tgt == NULL) {
2033 return FALSE;
2034 }
2035
2036 return UU_OK == unit_transform_result(nmap, punit, tgt);
2037}
2038
2039/**********************************************************************/
2044 const struct unit *punit,
2045 char *buf, size_t bufsz)
2046{
2047 struct player *pplayer = unit_owner(punit);
2048 enum unit_upgrade_result result = unit_upgrade_test(nmap, punit, FALSE);
2049 int upgrade_cost;
2050 const struct unit_type *from_unittype = unit_type_get(punit);
2051 const struct unit_type *to_unittype = can_upgrade_unittype(pplayer,
2053 char tbuf[MAX_LEN_MSG];
2054
2055 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2056 "Treasury contains %d gold.",
2057 pplayer->economic.gold),
2058 pplayer->economic.gold);
2059
2060 switch (result) {
2061 case UU_OK:
2062 upgrade_cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
2063 /* This message is targeted toward the GUI callers. */
2064 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
2065 fc_snprintf(buf, bufsz, PL_("Upgrade %s to %s for %d gold?\n%s",
2066 "Upgrade %s to %s for %d gold?\n%s",
2067 upgrade_cost),
2068 utype_name_translation(from_unittype),
2069 utype_name_translation(to_unittype),
2070 upgrade_cost, tbuf);
2071 break;
2072 case UU_NO_UNITTYPE:
2073 fc_snprintf(buf, bufsz,
2074 _("Sorry, cannot upgrade %s (yet)."),
2075 utype_name_translation(from_unittype));
2076 break;
2077 case UU_NO_MONEY:
2078 upgrade_cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
2079 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
2080 fc_snprintf(buf, bufsz, PL_("Upgrading %s to %s costs %d gold.\n%s",
2081 "Upgrading %s to %s costs %d gold.\n%s",
2082 upgrade_cost),
2083 utype_name_translation(from_unittype),
2084 utype_name_translation(to_unittype),
2085 upgrade_cost, tbuf);
2086 break;
2087 case UU_NOT_IN_CITY:
2088 case UU_NOT_CITY_OWNER:
2089 fc_snprintf(buf, bufsz,
2090 _("You can only upgrade units in your cities."));
2091 break;
2092 case UU_NOT_ENOUGH_ROOM:
2093 fc_snprintf(buf, bufsz,
2094 _("Upgrading this %s would strand units it transports."),
2095 utype_name_translation(from_unittype));
2096 break;
2097 case UU_NOT_TERRAIN:
2098 fc_snprintf(buf, bufsz,
2099 _("Upgrading this %s would result in a %s which can not "
2100 "survive at this place."),
2101 utype_name_translation(from_unittype),
2102 utype_name_translation(to_unittype));
2103 break;
2105 fc_snprintf(buf, bufsz,
2106 _("Upgrading this %s would result in a %s which its "
2107 "current transport, %s, could not transport."),
2108 utype_name_translation(from_unittype),
2109 utype_name_translation(to_unittype),
2111 break;
2112 case UU_NOT_ACTIVITY:
2113 fc_snprintf(buf, bufsz,
2114 _("Cannot upgrade %s while doing '%s'."),
2115 utype_name_translation(from_unittype),
2116 unit_activity_name(punit->activity));
2117 break;
2118 }
2119
2120 return result;
2121}
2122
2123/**********************************************************************/
2127int unit_pays_mp_for_action(const struct action *paction,
2128 const struct unit *punit)
2129{
2130 int mpco;
2131
2132 mpco = get_target_bonus_effects(NULL,
2133 &(const struct req_context) {
2134 .player = unit_owner(punit),
2135 .city = unit_tile(punit)
2137 : NULL,
2138 .tile = unit_tile(punit),
2139 .unit = punit,
2140 .unittype = unit_type_get(punit),
2141 .action = paction,
2142 },
2143 NULL,
2144 EFT_ACTION_SUCCESS_MOVE_COST);
2145
2147
2148 return mpco;
2149}
2150
2151/**********************************************************************/
2154int hp_gain_coord(const struct unit *punit)
2155{
2156 int hp = 0;
2157 const int base = unit_type_get(punit)->hp;
2158 int min = base * get_unit_bonus(punit, EFT_MIN_HP_PCT) / 100;
2159
2160 /* Includes barracks (100%), fortress (25%), etc. */
2161 hp += base * get_unit_bonus(punit, EFT_HP_REGEN) / 100;
2162
2163 /* Minimum HP after regen effects applied. */
2164 hp = MAX(hp, min);
2165
2166 /* Regen2 effects that apply after there's at least Min HP */
2167 hp += ceil(base / 10) * get_unit_bonus(punit, EFT_HP_REGEN_2) / 10;
2168
2169 return MAX(hp, 0);
2170}
2171
2172/**********************************************************************/
2176{
2177 const struct unit_type *utype = unit_type_get(punit);
2178 struct unit_class *pclass = unit_class_get(punit);
2179 struct city *pcity = tile_city(unit_tile(punit));
2180 int gain;
2181
2182 if (!punit->moved) {
2183 gain = hp_gain_coord(punit);
2184 } else {
2185 gain = 0;
2186 }
2187
2188 gain += get_unit_bonus(punit, EFT_UNIT_RECOVER);
2189
2190 if (!punit->homecity && 0 < game.server.killunhomed
2191 && !unit_has_type_flag(punit, UTYF_GAMELOSS)) {
2192 /* Hit point loss of units without homecity; at least 1 hp! */
2193 /* Gameloss units are immune to this effect. */
2194 int hp_loss = MAX(utype->hp * game.server.killunhomed / 100, 1);
2195
2196 if (gain > hp_loss) {
2197 gain = -1;
2198 } else {
2199 gain -= hp_loss;
2200 }
2201 }
2202
2203 if (pcity == NULL && !tile_has_native_base(unit_tile(punit), utype)
2204 && !unit_transported(punit)) {
2205 gain -= utype->hp * pclass->hp_loss_pct / 100;
2206 }
2207
2208 if (punit->hp + gain > utype->hp) {
2209 gain = utype->hp - punit->hp;
2210 } else if (punit->hp + gain < 0) {
2211 gain = -punit->hp;
2212 }
2213
2214 return gain;
2215}
2216
2217/**********************************************************************/
2220bool is_losing_hp(const struct unit *punit)
2221{
2222 const struct unit_type *punittype = unit_type_get(punit);
2223
2224 return get_unit_bonus(punit, EFT_UNIT_RECOVER)
2225 < (punittype->hp *
2226 utype_class(punittype)->hp_loss_pct / 100);
2227}
2228
2229/**********************************************************************/
2232bool unit_type_is_losing_hp(const struct player *pplayer,
2233 const struct unit_type *punittype)
2234{
2235 return get_unittype_bonus(pplayer, NULL, punittype, NULL,
2236 EFT_UNIT_RECOVER)
2237 < (punittype->hp *
2238 utype_class(punittype)->hp_loss_pct / 100);
2239}
2240
2241/**********************************************************************/
2245bool unit_is_alive(int id)
2246{
2247 /* Check if unit exist in game */
2248 if (game_unit_by_number(id)) {
2249 return TRUE;
2250 }
2251
2252 return FALSE;
2253}
2254
2255/**********************************************************************/
2262bool unit_is_virtual(const struct unit *punit)
2263{
2264 if (!punit) {
2265 return FALSE;
2266 }
2267
2268 return punit != game_unit_by_number(punit->id);
2269}
2270
2271/**********************************************************************/
2274void *unit_ai_data(const struct unit *punit, const struct ai_type *ai)
2275{
2276 return punit->server.ais[ai_type_number(ai)];
2277}
2278
2279/**********************************************************************/
2282void unit_set_ai_data(struct unit *punit, const struct ai_type *ai,
2283 void *data)
2284{
2285 punit->server.ais[ai_type_number(ai)] = data;
2286}
2287
2288/**********************************************************************/
2296int unit_bribe_cost(struct unit *punit, struct player *briber)
2297{
2298 int cost, default_hp, dist = 0;
2299 struct tile *ptile = unit_tile(punit);
2300
2301 fc_assert_ret_val(punit != NULL, 0);
2302
2303 default_hp = unit_type_get(punit)->hp;
2304 cost = unit_owner(punit)->economic.gold + game.info.base_bribe_cost;
2305
2306 /* Consider the distance to the capital. */
2309 if (is_capital(capital)) {
2310 int tmp = map_distance(capital->tile, ptile);
2311
2312 if (tmp < dist) {
2313 dist = tmp;
2314 }
2315 }
2317
2318 cost /= dist + 2;
2319
2320 /* Consider the build cost. */
2322
2323 /* Rule set specific cost modification */
2324 cost += (cost
2326 &(const struct req_context) {
2327 .player = unit_owner(punit),
2328 .city = game_city_by_number(
2330 ),
2331 .tile = ptile,
2332 .unit = punit,
2333 .unittype = unit_type_get(punit),
2334 },
2335 briber,
2336 EFT_UNIT_BRIBE_COST_PCT))
2337 / 100;
2338
2339 /* Veterans are not cheap. */
2340 {
2341 const struct veteran_level *vlevel
2343
2344 fc_assert_ret_val(vlevel != NULL, 0);
2345 cost = cost * vlevel->power_fact / 100;
2346 if (unit_type_get(punit)->move_rate > 0) {
2348 } else {
2349 cost += cost * vlevel->move_bonus / SINGLE_MOVE;
2350 }
2351 }
2352
2353 /* Cost now contains the basic bribe cost. We now reduce it by:
2354 * bribecost = cost/2 + cost/2 * damage/hp
2355 * = cost/2 * (1 + damage/hp) */
2356 return ((float)cost / 2 * (1.0 + (float)punit->hp / default_hp));
2357}
2358
2359/**********************************************************************/
2362bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
2363{
2364 fc_assert_ret_val(ptrans != NULL, FALSE);
2365 fc_assert_ret_val(pcargo != NULL, FALSE);
2366
2367 fc_assert_ret_val(!unit_list_search(ptrans->transporting, pcargo), FALSE);
2368
2369 if (force || can_unit_load(pcargo, ptrans)) {
2370 pcargo->transporter = ptrans;
2371 unit_list_append(ptrans->transporting, pcargo);
2372
2373 return TRUE;
2374 }
2375
2376 return FALSE;
2377}
2378
2379/**********************************************************************/
2382bool unit_transport_unload(struct unit *pcargo)
2383{
2384 struct unit *ptrans;
2385
2386 fc_assert_ret_val(pcargo != NULL, FALSE);
2387
2388 if (!unit_transported(pcargo)) {
2389 /* 'pcargo' is not transported. */
2390 return FALSE;
2391 }
2392
2393 /* Get the transporter; must not be defined on the client! */
2394 ptrans = unit_transport_get(pcargo);
2395 if (ptrans) {
2396 /* 'pcargo' and 'ptrans' should be on the same tile. */
2397 fc_assert(same_pos(unit_tile(pcargo), unit_tile(ptrans)));
2398
2399#ifndef FREECIV_NDEBUG
2400 bool success =
2401#endif
2402 unit_list_remove(ptrans->transporting, pcargo);
2403
2404 /* It is an error if 'pcargo' can not be removed from the 'ptrans'. */
2405 fc_assert(success);
2406 }
2407
2408 /* For the server (also safe for the client). */
2409 pcargo->transporter = NULL;
2410
2411 return TRUE;
2412}
2413
2414/**********************************************************************/
2417bool unit_transported(const struct unit *pcargo)
2418{
2419 fc_assert_ret_val(pcargo != NULL, FALSE);
2420
2421 /* The unit is transported if a transporter unit is set or, (for the client)
2422 * if the transported_by field is set. */
2423 if (is_server()) {
2424 return unit_transported_server(pcargo);
2425 } else {
2426 return unit_transported_client(pcargo);
2427 }
2428}
2429
2430/**********************************************************************/
2433struct unit *unit_transport_get(const struct unit *pcargo)
2434{
2435 fc_assert_ret_val(pcargo != NULL, NULL);
2436
2437 return pcargo->transporter;
2438}
2439
2440/**********************************************************************/
2443struct unit_list *unit_transport_cargo(const struct unit *ptrans)
2444{
2445 fc_assert_ret_val(ptrans != NULL, NULL);
2446 fc_assert_ret_val(ptrans->transporting != NULL, NULL);
2447
2448 return ptrans->transporting;
2449}
2450
2451/**********************************************************************/
2454static inline bool
2455unit_transport_check_one(const struct unit_type *cargo_utype,
2456 const struct unit_type *trans_utype)
2457{
2458 return (trans_utype != cargo_utype
2459 && !can_unit_type_transport(cargo_utype,
2460 utype_class(trans_utype)));
2461}
2462
2463/**********************************************************************/
2471bool unit_transport_check(const struct unit *pcargo,
2472 const struct unit *ptrans)
2473{
2474 const struct unit_type *cargo_utype = unit_type_get(pcargo);
2475
2476 /* Check 'pcargo' against 'ptrans'. */
2477 if (!unit_transport_check_one(cargo_utype, unit_type_get(ptrans))) {
2478 return FALSE;
2479 }
2480
2481 /* Check 'pcargo' against 'ptrans' parents. */
2482 unit_transports_iterate(ptrans, pparent) {
2483 if (!unit_transport_check_one(cargo_utype, unit_type_get(pparent))) {
2484 return FALSE;
2485 }
2487
2488 /* Check cargo children... */
2489 unit_cargo_iterate(pcargo, pchild) {
2490 cargo_utype = unit_type_get(pchild);
2491
2492 /* ...against 'ptrans'. */
2493 if (!unit_transport_check_one(cargo_utype, unit_type_get(ptrans))) {
2494 return FALSE;
2495 }
2496
2497 /* ...and against 'ptrans' parents. */
2498 unit_transports_iterate(ptrans, pparent) {
2499 if (!unit_transport_check_one(cargo_utype, unit_type_get(pparent))) {
2500 return FALSE;
2501 }
2504
2505 return TRUE;
2506}
2507
2508/**********************************************************************/
2512bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
2513{
2514 unit_transports_iterate(pcargo, plevel) {
2515 if (ptrans == plevel) {
2516 return TRUE;
2517 }
2519 return FALSE;
2520}
2521
2522/**********************************************************************/
2525int unit_cargo_depth(const struct unit *ptrans)
2526{
2527 struct cargo_iter iter;
2528 struct iterator *it;
2529 int depth = 0;
2530
2531 for (it = cargo_iter_init(&iter, ptrans); iterator_valid(it);
2532 iterator_next(it)) {
2533 if (iter.depth > depth) {
2534 depth = iter.depth;
2535 }
2536 }
2537 return depth;
2538}
2539
2540/**********************************************************************/
2543int unit_transport_depth(const struct unit *pcargo)
2544{
2545 int level = 0;
2546
2547 unit_transports_iterate(pcargo, plevel) {
2548 level++;
2550 return level;
2551}
2552
2553/**********************************************************************/
2557{
2558 return sizeof(struct cargo_iter);
2559}
2560
2561/**********************************************************************/
2564static void *cargo_iter_get(const struct iterator *it)
2565{
2566 const struct cargo_iter *iter = CARGO_ITER(it);
2567
2568 return unit_list_link_data(iter->links[iter->depth - 1]);
2569}
2570
2571/**********************************************************************/
2574static void cargo_iter_next(struct iterator *it)
2575{
2576 struct cargo_iter *iter = CARGO_ITER(it);
2577 const struct unit_list_link *piter;
2578 const struct unit_list_link *pnext;
2579
2580 /* Variant 1: unit has cargo. */
2581 pnext = unit_list_head(unit_transport_cargo(cargo_iter_get(it)));
2582 if (NULL != pnext) {
2583 fc_assert(iter->depth < ARRAY_SIZE(iter->links));
2584 iter->links[iter->depth++] = pnext;
2585 return;
2586 }
2587
2588 while (iter->depth > 0) {
2589 piter = iter->links[iter->depth - 1];
2590
2591 /* Variant 2: there are other cargo units at same level. */
2592 pnext = unit_list_link_next(piter);
2593 if (NULL != pnext) {
2594 iter->links[iter->depth - 1] = pnext;
2595 return;
2596 }
2597
2598 /* Variant 3: return to previous level, and do same tests. */
2599 iter->depth--;
2600 }
2601}
2602
2603/**********************************************************************/
2606static bool cargo_iter_valid(const struct iterator *it)
2607{
2608 return (0 < CARGO_ITER(it)->depth);
2609}
2610
2611/**********************************************************************/
2615 const struct unit *ptrans)
2616{
2617 struct iterator *it = ITERATOR(iter);
2618
2619 it->get = cargo_iter_get;
2620 it->next = cargo_iter_next;
2621 it->valid = cargo_iter_valid;
2622 iter->links[0] = unit_list_head(unit_transport_cargo(ptrans));
2623 iter->depth = (NULL != iter->links[0] ? 1 : 0);
2624
2625 return it;
2626}
2627
2628/**********************************************************************/
2631bool unit_is_cityfounder(const struct unit *punit)
2632{
2634}
2635
2636
2637/**********************************************************************/
2640bool unit_order_list_is_sane(const struct civ_map *nmap,
2641 int length, const struct unit_order *orders)
2642{
2643 int i;
2644
2645 for (i = 0; i < length; i++) {
2646 struct action *paction;
2647 struct extra_type *pextra;
2648
2649 if (orders[i].order > ORDER_LAST) {
2650 log_error("invalid order %d at index %d", orders[i].order, i);
2651 return FALSE;
2652 }
2653 switch (orders[i].order) {
2654 case ORDER_MOVE:
2655 case ORDER_ACTION_MOVE:
2656 if (!map_untrusted_dir_is_valid(orders[i].dir)) {
2657 log_error("in order %d, invalid move direction %d.", i, orders[i].dir);
2658 return FALSE;
2659 }
2660 break;
2661 case ORDER_ACTIVITY:
2662 switch (orders[i].activity) {
2663 case ACTIVITY_SENTRY:
2664 if (i != length - 1) {
2665 /* Only allowed as the last order. */
2666 log_error("activity %d is not allowed at index %d.", orders[i].activity,
2667 i);
2668 return FALSE;
2669 }
2670 break;
2671 /* Replaced by action orders */
2672 case ACTIVITY_BASE:
2673 case ACTIVITY_GEN_ROAD:
2674 case ACTIVITY_FALLOUT:
2675 case ACTIVITY_POLLUTION:
2676 case ACTIVITY_PILLAGE:
2677 case ACTIVITY_MINE:
2678 case ACTIVITY_IRRIGATE:
2679 case ACTIVITY_PLANT:
2680 case ACTIVITY_CULTIVATE:
2681 case ACTIVITY_TRANSFORM:
2682 case ACTIVITY_CONVERT:
2683 case ACTIVITY_FORTIFYING:
2684 log_error("at index %d, use action rather than activity %d.",
2685 i, orders[i].activity);
2686 return FALSE;
2687 /* Not supported. */
2688 case ACTIVITY_EXPLORE:
2689 case ACTIVITY_IDLE:
2690 /* Not set from the client. */
2691 case ACTIVITY_GOTO:
2692 case ACTIVITY_FORTIFIED:
2693 /* Compatiblity, used in savegames. */
2694 case ACTIVITY_OLD_ROAD:
2695 case ACTIVITY_OLD_RAILROAD:
2696 case ACTIVITY_FORTRESS:
2697 case ACTIVITY_AIRBASE:
2698 /* Unused. */
2699 case ACTIVITY_PATROL_UNUSED:
2700 case ACTIVITY_LAST:
2701 case ACTIVITY_UNKNOWN:
2702 log_error("at index %d, unsupported activity %d.", i, orders[i].activity);
2703 return FALSE;
2704 }
2705
2706 break;
2708 if (!action_id_exists(orders[i].action)) {
2709 /* Non-existent action. */
2710 log_error("at index %d, the action %d doesn't exist.", i, orders[i].action);
2711 return FALSE;
2712 }
2713
2714 paction = action_by_number(orders[i].action);
2715
2716 /* Validate main target. */
2717 if (index_to_tile(nmap, orders[i].target) == NULL) {
2718 log_error("at index %d, invalid tile target %d for the action %d.",
2719 i, orders[i].target, orders[i].action);
2720 return FALSE;
2721 }
2722
2723 if (orders[i].dir != DIR8_ORIGIN) {
2724 log_error("at index %d, the action %d sets the outdated target"
2725 " specification dir.",
2726 i, orders[i].action);
2727 }
2728
2729 /* Validate sub target. */
2730 switch (action_id_get_sub_target_kind(orders[i].action)) {
2731 case ASTK_BUILDING:
2732 /* Sub target is a building. */
2733 if (!improvement_by_number(orders[i].sub_target)) {
2734 /* Sub target is invalid. */
2735 log_error("at index %d, cannot do %s without a target.", i,
2736 action_id_rule_name(orders[i].action));
2737 return FALSE;
2738 }
2739 break;
2740 case ASTK_TECH:
2741 /* Sub target is a technology. */
2742 if (orders[i].sub_target == A_NONE
2743 || (!valid_advance_by_number(orders[i].sub_target)
2744 && orders[i].sub_target != A_FUTURE)) {
2745 /* Target tech is invalid. */
2746 log_error("at index %d, cannot do %s without a target.", i,
2747 action_id_rule_name(orders[i].action));
2748 return FALSE;
2749 }
2750 break;
2751 case ASTK_EXTRA:
2752 case ASTK_EXTRA_NOT_THERE:
2753 /* Sub target is an extra. */
2754 pextra = (!(orders[i].sub_target == NO_TARGET
2755 || (orders[i].sub_target < 0
2756 || (orders[i].sub_target
2758 ? extra_by_number(orders[i].sub_target) : NULL);
2759 fc_assert(pextra == NULL || !(pextra->ruledit_disabled));
2760 if (pextra == NULL) {
2761 if (paction->target_complexity != ACT_TGT_COMPL_FLEXIBLE) {
2762 /* Target extra is invalid. */
2763 log_error("at index %d, cannot do %s without a target.", i,
2764 action_id_rule_name(orders[i].action));
2765 return FALSE;
2766 }
2767 } else {
2768 if (!(action_removes_extra(paction, pextra)
2769 || action_creates_extra(paction, pextra))) {
2770 /* Target extra is irrelevant for the action. */
2771 log_error("at index %d, cannot do %s to %s.", i,
2772 action_id_rule_name(orders[i].action),
2773 extra_rule_name(pextra));
2774 return FALSE;
2775 }
2776 }
2777 break;
2778 case ASTK_NONE:
2779 /* No validation required. */
2780 break;
2781 /* Invalid action? */
2782 case ASTK_COUNT:
2784 action_id_get_sub_target_kind(orders[i].action) != ASTK_COUNT,
2785 FALSE,
2786 "Bad action %d in order number %d.", orders[i].action, i);
2787 }
2788
2789 /* Some action orders are sane only in the last order. */
2790 if (i != length - 1) {
2791 /* If the unit is dead, */
2792 if (utype_is_consumed_by_action(paction, NULL)
2793 /* or if Freeciv has no idea where the unit will end up after it
2794 * has performed this action, */
2795 || !(utype_is_unmoved_by_action(paction, NULL)
2796 || utype_is_moved_to_tgt_by_action(paction, NULL))
2797 /* or if the unit will end up standing still, */
2798 || action_has_result(paction, ACTRES_FORTIFY)) {
2799 /* than having this action in the middle of a unit's orders is
2800 * probably wrong. */
2801 log_error("action %d is not allowed at index %d.",
2802 orders[i].action, i);
2803 return FALSE;
2804 }
2805 }
2806
2807 /* Don't validate that the target tile really contains a target or
2808 * that the actor player's map think the target tile has one.
2809 * The player may target something from their player map that isn't
2810 * there any more, a target they think is there even if their player
2811 * map doesn't have it, or even a target they assume will be there
2812 * when the unit reaches the target tile.
2813 *
2814 * With that said: The client should probably at least have an
2815 * option to only aim city targeted actions at cities. */
2816
2817 break;
2818 case ORDER_FULL_MP:
2819 break;
2820 case ORDER_LAST:
2821 /* An invalid order. This is handled above. */
2822 break;
2823 }
2824 }
2825
2826 return TRUE;
2827}
2828
2829/**********************************************************************/
2833struct unit_order *create_unit_orders(const struct civ_map *nmap,
2834 int length,
2835 const struct unit_order *orders)
2836{
2837 struct unit_order *unit_orders;
2838
2839 if (!unit_order_list_is_sane(nmap, length, orders)) {
2840 return NULL;
2841 }
2842
2843 unit_orders = fc_malloc(length * sizeof(*(unit_orders)));
2844 memcpy(unit_orders, orders, length * sizeof(*(unit_orders)));
2845
2846 return unit_orders;
2847}
bool action_removes_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2312
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6703
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:6224
const char * action_id_rule_name(action_id act_id)
Definition actions.c:1899
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: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:4755
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:4832
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:5870
bool action_maybe_possible_actor_unit(const struct civ_map *nmap, const action_id act_id, const struct unit *actor_unit)
Definition actions.c:7165
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
bool action_creates_extra(const struct action *paction, const struct extra_type *pextra)
Definition actions.c:2224
bool is_action_enabled_unit_on_self(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit)
Definition actions.c:5145
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:5953
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:490
#define action_id_get_sub_target_kind(act_id)
Definition actions.h:661
static struct action * action_by_number(action_id act_id)
Definition actions.h:640
#define action_has_result(_act_, _res_)
Definition actions.h:450
#define action_by_result_iterate_end
Definition actions.h:494
int ai_type_number(const struct ai_type *ai)
Definition ai.c:272
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:384
void astr_add_line(struct astring *astr, const char *format,...)
Definition astring.c:299
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
bool is_capital(const struct city *pcity)
Definition city.c:1552
struct city * tile_non_allied_city(const struct tile *ptile, const struct player *pplayer)
Definition city.c:2039
bool is_unit_near_a_friendly_city(const struct civ_map *nmap, const struct unit *punit)
Definition city.c:2055
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
#define city_owner(_pcity_)
Definition city.h:543
#define city_list_iterate_end
Definition city.h:490
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2840
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 cost
Definition dialogs_g.h:73
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:691
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:992
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:957
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:740
struct extra_type * extra_by_number(int id)
Definition extras.c:175
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:952
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:195
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:186
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:159
#define extra_index(_e_)
Definition extras.h:177
#define extra_type_list_iterate_end
Definition extras.h:161
static bool is_server(void)
#define NO_TARGET
Definition fc_types.h:324
enum unit_activity Activity_type_id
Definition fc_types.h:349
#define DIR8_ORIGIN
Definition fc_types.h:427
int action_id
Definition fc_types.h:359
@ HB_ALLIANCE
Definition fc_types.h:1144
@ HB_DISABLED
Definition fc_types.h:1142
@ HB_NATIONAL
Definition fc_types.h:1143
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
@ O_LAST
Definition fc_types.h:91
@ BORDERS_DISABLED
Definition fc_types.h:891
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:82
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:57
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct city * game_city_by_number(int id)
Definition game.c:102
#define GAME_UNIT_BRIBE_DIST_MAX
Definition game.h:727
#define GAME_TRANSPORT_MAX_RECURSIVE
Definition game.h:730
static const int bufsz
Definition helpdlg.c:70
struct impr_type * improvement_by_number(const Impr_type_id id)
static bool iterator_valid(const struct iterator *it)
Definition iterator.h:61
#define ITERATOR(p)
Definition iterator.h:37
static void iterator_next(struct iterator *it)
Definition iterator.h:42
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
bool map_untrusted_dir_is_valid(enum direction8 dir)
Definition map.c:1271
enum direction8 rand_direction(void)
Definition map.c:1732
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:652
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:385
#define square_iterate_end
Definition map.h:388
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1005
bool can_exist_at_tile(const struct civ_map *nmap, const struct unit_type *utype, const struct tile *ptile)
Definition movement.c:264
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:348
bool could_exist_in_city(const struct civ_map *nmap, const struct player *pov_player, const struct unit_type *utype, const struct city *pcity)
Definition movement.c:295
bool can_unit_transport(const struct unit *transporter, const struct unit *transported)
Definition movement.c:845
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:508
bool is_native_near_tile(const struct civ_map *nmap, const struct unit_class *uclass, const struct tile *ptile)
Definition movement.c:482
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:858
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:202
#define SINGLE_MOVE
Definition movement.h:24
#define MAX_LEN_MSG
Definition packets.h:43
struct city_list * cities
Definition packhand.c:117
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1084
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1435
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
enum act_tgt_compl target_complexity
Definition actions.h:392
Definition ai.h:50
struct iterator vtable
Definition unit.c:52
int depth
Definition unit.c:54
const struct unit_list_link * links[GAME_TRANSPORT_MAX_RECURSIVE]
Definition unit.c:53
Definition city.h:309
int id
Definition city.h:315
int airlift
Definition city.h:365
bool occupied
Definition city.h:443
struct tile * tile
Definition city.h:311
struct city::@17::@20 client
struct civ_game::@30::@34 server
struct packet_ruleset_control control
Definition game.h:83
struct packet_game_info info
Definition game.h:89
int killunhomed
Definition game.h:153
bool ruledit_disabled
Definition extras.h:88
bool(* valid)(const struct iterator *it)
Definition iterator.h:34
void *(* get)(const struct iterator *it)
Definition iterator.h:33
void(* next)(struct iterator *it)
Definition iterator.h:32
enum borders_mode borders
enum happyborders_type happyborders
enum airlifting_style airlifting_style
bool airlift_from_always_enabled
bool airlift_to_always_enabled
struct player_economic economic
Definition player.h:284
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
int hp_loss_pct
Definition unittype.h:142
struct extra_type_list * hiding_extras
Definition unittype.h:159
enum unit_activity activity
Definition unit.h:94
enum unit_orders order
Definition unit.h:93
int action
Definition unit.h:100
enum direction8 dir
Definition unit.h:102
int target
Definition unit.h:97
int sub_target
Definition unit.h:98
int transport_capacity
Definition unittype.h:504
struct unit_type::@87 adv
bool worker
Definition unittype.h:556
int move_rate
Definition unittype.h:497
enum vision_layer vlayer
Definition unittype.h:550
const struct unit_type * converted_to
Definition unittype.h:511
Definition unit.h:138
time_t action_timestamp
Definition unit.h:243
int length
Definition unit.h:195
int upkeep[O_LAST]
Definition unit.h:148
bool has_orders
Definition unit.h:193
enum action_decision action_decision_want
Definition unit.h:202
int battlegroup
Definition unit.h:191
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int refcount
Definition unit.h:141
int id
Definition unit.h:145
struct unit_list * transporting
Definition unit.h:184
int ord_city
Definition unit.h:240
bool moved
Definition unit.h:173
int ord_map
Definition unit.h:239
bool debug
Definition unit.h:231
struct vision * vision
Definition unit.h:242
int hp
Definition unit.h:151
struct unit::@80::@82 client
struct unit::@79 orders
int fuel
Definition unit.h:153
struct extra_type * changed_from_target
Definition unit.h:170
bool stay
Definition unit.h:205
bool colored
Definition unit.h:219
enum direction8 facing
Definition unit.h:142
struct tile * tile
Definition unit.h:140
struct extra_type * activity_target
Definition unit.h:164
struct act_prob * act_prob_cache
Definition unit.h:225
int activity_count
Definition unit.h:162
struct unit_order * list
Definition unit.h:198
enum unit_activity changed_from
Definition unit.h:168
struct unit_adv * adv
Definition unit.h:233
struct player * nationality
Definition unit.h:144
int transported_by
Definition unit.h:213
void(* removal_callback)(struct unit *punit)
Definition unit.h:251
void * ais[FREECIV_AI_MOD_LAST]
Definition unit.h:234
int action_turn
Definition unit.h:244
struct unit::@80::@83 server
int homecity
Definition unit.h:146
int upkeep_paid[O_LAST]
Definition unit.h:254
bool paradropped
Definition unit.h:174
bool done_moving
Definition unit.h:181
struct unit * transporter
Definition unit.h:183
int birth_turn
Definition unit.h:235
struct goods_type * carrying
Definition unit.h:186
struct tile * goto_tile
Definition unit.h:155
struct tile * action_decision_tile
Definition unit.h:203
const struct unit_type * utype
Definition unit.h:139
int veteran
Definition unit.h:152
int changed_from_count
Definition unit.h:169
struct player * owner
Definition unit.h:143
bool dying
Definition unit.h:248
enum unit_focus_status focus_status
Definition unit.h:211
enum server_side_agent ssa_controller
Definition unit.h:172
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
#define A_FUTURE
Definition tech.h:46
#define A_NONE
Definition tech.h:43
#define T_UNKNOWN
Definition terrain.h:57
#define terrain_has_flag(terr, flag)
Definition terrain.h:269
bool tile_has_not_aggressive_extra_for_unit(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:193
bool tile_is_placing(const struct tile *ptile)
Definition tile.c:1114
int tile_activity_time(enum unit_activity activity, const struct tile *ptile, const struct extra_type *tgt)
Definition tile.c:412
bool tile_has_native_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:318
enum known_type tile_get_known(const struct tile *ptile, const struct player *pplayer)
Definition tile.c:386
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
@ TILE_KNOWN_UNSEEN
Definition tile.h:36
#define ACTIVITY_FACTOR
Definition tile.h:168
#define tile_terrain(_tile)
Definition tile.h:113
#define tile_has_extra(ptile, pextra)
Definition tile.h:150
#define tile_owner(_tile)
Definition tile.h:95
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
bool unit_can_do_action_sub_result(const struct unit *punit, enum action_sub_result sub_result)
Definition unit.c:356
size_t cargo_iter_sizeof(void)
Definition unit.c:2556
Activity_type_id real_activities[ACTIVITY_LAST]
Definition unit.c:44
bool is_real_activity(enum unit_activity activity)
Definition unit.c:617
bool can_unit_do_activity_targeted_at(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, struct extra_type *target, const struct tile *ptile)
Definition unit.c:932
bool is_tile_activity(enum unit_activity activity)
Definition unit.c:1614
struct unit_order * create_unit_orders(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2833
enum unit_upgrade_result unit_transform_result(const struct civ_map *nmap, const struct unit *punit, const struct unit_type *to_unittype)
Definition unit.c:1948
bool unit_type_really_ignores_zoc(const struct unit_type *punittype)
Definition unit.c:1518
bool unit_type_is_losing_hp(const struct player *pplayer, const struct unit_type *punittype)
Definition unit.c:2232
bool is_terrain_change_activity(enum unit_activity activity)
Definition unit.c:1599
struct unit * tile_non_allied_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1340
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:224
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1775
static void cargo_iter_next(struct iterator *it)
Definition unit.c:2574
bool can_unit_change_homecity_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pcity)
Definition unit.c:452
void free_unit_orders(struct unit *punit)
Definition unit.c:1761
void unit_set_ai_data(struct unit *punit, const struct ai_type *ai, void *data)
Definition unit.c:2282
bool unit_is_alive(int id)
Definition unit.c:2245
bool unit_can_est_trade_route_here(const struct unit *punit)
Definition unit.c:294
bool is_hiding_unit(const struct unit *punit)
Definition unit.c:403
int get_activity_rate_this_turn(const struct unit *punit)
Definition unit.c:513
int unit_pays_mp_for_action(const struct action *paction, const struct unit *punit)
Definition unit.c:2127
int get_turns_for_activity_at(const struct unit *punit, enum unit_activity activity, const struct tile *ptile, struct extra_type *tgt)
Definition unit.c:529
bool is_plr_zoc_client(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Definition unit.c:1480
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2362
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1914
struct iterator * cargo_iter_init(struct cargo_iter *iter, const struct unit *ptrans)
Definition unit.c:2614
enum unit_upgrade_result unit_upgrade_info(const struct civ_map *nmap, const struct unit *punit, char *buf, size_t bufsz)
Definition unit.c:2043
int unit_transport_depth(const struct unit *pcargo)
Definition unit.c:2543
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1115
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2220
bool can_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:752
bool unit_can_add_or_build_city(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:435
struct unit * tile_non_attack_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1373
int hp_gain_coord(const struct unit *punit)
Definition unit.c:2154
bool can_unit_change_homecity(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:468
static void * cargo_iter_get(const struct iterator *it)
Definition unit.c:2564
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1279
bool unit_being_aggressive(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:1532
int get_activity_rate(const struct unit *punit)
Definition unit.c:482
bool unit_transport_check(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2471
bool is_attack_unit(const struct unit *punit)
Definition unit.c:315
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:196
const Activity_type_id tile_changing_activities[]
Definition unit.c:46
void setup_real_activities_array(void)
Definition unit.c:599
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2433
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2382
bool is_build_activity(enum unit_activity activity)
Definition unit.c:1568
bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2512
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2175
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:87
bool is_military_unit(const struct unit *punit)
Definition unit.c:327
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:853
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2296
void unit_upkeep_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1265
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:727
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2631
bool is_unit_activity_on_tile(enum unit_activity activity, const struct tile *ptile)
Definition unit.c:1150
bool can_unit_do_autosettlers(const struct unit *punit)
Definition unit.c:591
bool is_field_unit(const struct unit *punit)
Definition unit.c:391
static bool cargo_iter_valid(const struct iterator *it)
Definition unit.c:2606
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:336
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:346
#define RETURN_IS_ACTIVITY_ENABLED_UNIT_ON(paction)
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1132
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1625
int unit_cargo_depth(const struct unit *ptrans)
Definition unit.c:2525
static bool unit_transport_check_one(const struct unit_type *cargo_utype, const struct unit_type *trans_utype)
Definition unit.c:2455
#define CARGO_ITER(iter)
Definition unit.c:56
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2640
const char * get_activity_text(enum unit_activity activity)
Definition unit.c:633
bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
Definition unit.c:1165
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:307
bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Definition unit.c:1421
bool is_clean_activity(enum unit_activity activity)
Definition unit.c:1584
bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:834
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1182
bool unit_can_help_build_wonder_here(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:268
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:880
struct unit * tile_other_players_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1357
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1721
struct unit * tile_enemy_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1325
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1289
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1980
bool kills_citizen_after_attack(const struct unit *punit)
Definition unit.c:425
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2417
bool are_unit_orders_equal(const struct unit_order *order1, const struct unit_order *order2)
Definition unit.c:61
bool unit_is_virtual(const struct unit *punit)
Definition unit.c:2262
static void set_unit_activity_internal(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1097
bool is_square_threatened(const struct civ_map *nmap, const struct player *pplayer, const struct tile *ptile, bool omniscient)
Definition unit.c:365
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:779
struct unit * unit_occupies_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1394
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Definition unit.c:2443
static bool can_type_transport_units_cargo(const struct unit_type *utype, const struct unit *punit)
Definition unit.c:1924
void * unit_ai_data(const struct unit *punit, const struct ai_type *ai)
Definition unit.c:2274
bool unit_has_orders(const struct unit *punit)
Definition unit.c:212
struct unit * tile_allied_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1302
struct unit * transporter_for_unit(const struct unit *pcargo)
Definition unit.c:1904
static struct unit * base_transporter_for_unit(const struct unit *pcargo, const struct tile *ptile, bool(*unit_load_test)(const struct unit *pc, const struct unit *pt))
Definition unit.c:1785
bool unit_can_convert(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:2027
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:549
bool could_unit_be_in_transport(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:695
bool can_unit_do_activity_targeted(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, struct extra_type *target)
Definition unit.c:919
bool can_unit_alight_or_be_unloaded(const struct civ_map *nmap, const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:804
#define unit_tile(_pu)
Definition unit.h:395
#define unit_transports_iterate_end
Definition unit.h:560
#define unit_cargo_iterate_end
Definition unit.h:570
@ FOCUS_AVAIL
Definition unit.h:53
#define BATTLEGROUP_NONE
Definition unit.h:190
unit_orders
Definition unit.h:37
@ ORDER_ACTION_MOVE
Definition unit.h:45
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_FULL_MP
Definition unit.h:43
@ ORDER_MOVE
Definition unit.h:39
@ ORDER_LAST
Definition unit.h:49
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_transported_server(_pcargo_)
Definition unit.h:538
#define unit_cargo_iterate(_ptrans, _pcargo)
Definition unit.h:567
#define unit_owner(_pu)
Definition unit.h:394
#define unit_transports_iterate(_pcargo, _ptrans)
Definition unit.h:556
unit_upgrade_result
Definition unit.h:60
@ UU_NO_MONEY
Definition unit.h:63
@ UU_NOT_IN_CITY
Definition unit.h:64
@ UU_NO_UNITTYPE
Definition unit.h:62
@ UU_NOT_TERRAIN
Definition unit.h:67
@ UU_UNSUITABLE_TRANSPORT
Definition unit.h:68
@ UU_NOT_CITY_OWNER
Definition unit.h:65
@ UU_NOT_ENOUGH_ROOM
Definition unit.h:66
@ UU_OK
Definition unit.h:61
@ UU_NOT_ACTIVITY
Definition unit.h:69
#define unit_transported_client(_pcargo_)
Definition unit.h:541
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:430
unit_airlift_result
Definition unit.h:72
@ AR_SRC_NO_FLIGHTS
Definition unit.h:84
@ AR_OK_SRC_UNKNOWN
Definition unit.h:75
@ AR_OK_DST_UNKNOWN
Definition unit.h:76
@ AR_NO_MOVES
Definition unit.h:78
@ AR_BAD_DST_CITY
Definition unit.h:83
@ AR_NOT_IN_CITY
Definition unit.h:81
@ AR_OCCUPIED
Definition unit.h:80
@ AR_OK
Definition unit.h:74
@ AR_DST_NO_FLIGHTS
Definition unit.h:85
@ AR_WRONG_UNITTYPE
Definition unit.h:79
@ AR_BAD_SRC_CITY
Definition unit.h:82
#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
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
int utype_pays_mp_for_action_base(const struct action *paction, const struct unit_type *putype)
Definition unittype.c:1433
bool utype_can_freely_unload(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:294
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1621
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1301
bool utype_is_cityfounder(const struct unit_type *utype)
Definition unittype.c:2981
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1520
bool utype_may_act_move_frags(const struct unit_type *punit_type, const action_id act_id, const int move_fragments)
Definition unittype.c:1110
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1755
bool utype_can_freely_load(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Definition unittype.c:282
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2673
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2547
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:459
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2645
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
bool utype_is_consumed_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1271
bool utype_can_do_action_sub_result(const struct unit_type *putype, enum action_sub_result sub_result)
Definition unittype.c:480
bool utype_is_unmoved_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1340
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:515
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1783
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:753
#define utype_class(_t_)
Definition unittype.h:736
#define utype_fuel(ptype)
Definition unittype.h:825
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604