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/**********************************************************************/
84 const struct player *restriction,
85 const struct unit *punit,
86 const struct city *pdest_city)
87{
88 const struct city *psrc_city = tile_city(unit_tile(punit));
89 const struct player *punit_owner;
90 enum unit_airlift_result ok_result = AR_OK;
91
92 if (0 == punit->moves_left
94 ACTION_AIRLIFT, 0)) {
95 /* No moves left. */
96 return AR_NO_MOVES;
97 }
98
99 if (!unit_can_do_action(punit, ACTION_AIRLIFT)) {
100 return AR_WRONG_UNITTYPE;
101 }
102
104 /* Units with occupants can't be airlifted currently. */
105 return AR_OCCUPIED;
106 }
107
108 if (NULL == psrc_city) {
109 /* No city there. */
110 return AR_NOT_IN_CITY;
111 }
112
113 if (psrc_city == pdest_city) {
114 /* Airlifting to our current position doesn't make sense. */
115 return AR_BAD_DST_CITY;
116 }
117
118 if (pdest_city
119 && (NULL == restriction
120 || (tile_get_known(city_tile(pdest_city), restriction)
121 == TILE_KNOWN_SEEN))
122 && !can_unit_exist_at_tile(nmap, punit, city_tile(pdest_city))) {
123 /* Can't exist at the destination tile. */
124 return AR_BAD_DST_CITY;
125 }
126
127 punit_owner = unit_owner(punit);
128
129 /* Check validity of both source and destination before checking capacity,
130 * to avoid misleadingly optimistic returns. */
131
132 if (punit_owner != city_owner(psrc_city)
133 && !(game.info.airlifting_style & AIRLIFTING_ALLIED_SRC
134 && pplayers_allied(punit_owner, city_owner(psrc_city)))) {
135 /* Not allowed to airlift from this source. */
136 return AR_BAD_SRC_CITY;
137 }
138
139 if (pdest_city
140 && punit_owner != city_owner(pdest_city)
141 && !(game.info.airlifting_style & AIRLIFTING_ALLIED_DEST
142 && pplayers_allied(punit_owner, city_owner(pdest_city)))) {
143 /* Not allowed to airlift to this destination. */
144 return AR_BAD_DST_CITY;
145 }
146
147 if (NULL == restriction || city_owner(psrc_city) == restriction) {
148 /* We know for sure whether or not src can airlift this turn. */
149 if (0 >= psrc_city->airlift
150 && (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)
152 /* The source cannot airlift for this turn (maybe already airlifted
153 * or no airport).
154 * See also do_airline() in server/unittools.h. */
155 return AR_SRC_NO_FLIGHTS;
156 } /* else, there is capacity; continue to other checks */
157 } else {
158 /* We don't have access to the 'airlift' field. Assume it's OK; can
159 * only find out for sure by trying it. */
160 ok_result = AR_OK_SRC_UNKNOWN;
161 }
162
163 if (pdest_city) {
164 if (NULL == restriction || city_owner(pdest_city) == restriction) {
165 if (0 >= pdest_city->airlift
166 && (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_DEST)
168 /* The destination cannot support airlifted units for this turn
169 * (maybe already airlifted or no airport).
170 * See also do_airline() in server/unittools.h. */
171 return AR_DST_NO_FLIGHTS;
172 } /* else continue */
173 } else {
174 ok_result = AR_OK_DST_UNKNOWN;
175 }
176 }
177
178 return ok_result;
179}
180
181/**********************************************************************/
188bool unit_can_airlift_to(const struct civ_map *nmap,
189 const struct unit *punit,
190 const struct city *pdest_city)
191{
192 if (is_server()) {
193 return is_action_enabled_unit_on_city(nmap, ACTION_AIRLIFT,
194 punit, pdest_city);
195 } else {
196 return action_prob_possible(action_prob_vs_city(nmap, punit, ACTION_AIRLIFT,
197 pdest_city));
198 }
199}
200
201/**********************************************************************/
204bool unit_has_orders(const struct unit *punit)
205{
206 return punit->has_orders;
207}
208
209/**********************************************************************/
216int unit_shield_value(const struct unit *punit,
217 const struct unit_type *punittype,
218 const struct action *paction)
219{
220 int value;
221
222 bool has_unit;
223 const struct player *act_player;
224
225 has_unit = punit != NULL;
226
227 if (has_unit && punittype == NULL) {
228 punittype = unit_type_get(punit);
229 }
230
231 fc_assert_ret_val(punittype != NULL, 0);
232 fc_assert(punit == NULL || unit_type_get(punit) == punittype);
233 fc_assert_ret_val(paction != NULL, 0);
234
235 act_player = has_unit ? unit_owner(punit) : NULL;
236 /* TODO: determine if tile and city should be where the unit currently is
237 * located or the target city. Those two may differ. Wait for ruleset
238 * author feed back. */
239
240 value = utype_build_shield_cost_base(punittype);
241 value += ((value
243 &(const struct req_context) {
244 .player = act_player,
245 .unit = punit,
246 .unittype = punittype,
247 .action = paction,
248 },
249 NULL,
250 EFT_UNIT_SHIELD_VALUE_PCT))
251 / 100);
252
253 return value;
254}
255
256/**********************************************************************/
261 const struct unit *punit)
262{
263 struct city *pcity = tile_city(unit_tile(punit));
264
265 if (pcity == NULL) {
266 /* No city to help at this tile. */
267 return FALSE;
268 }
269
270 if (!utype_can_do_action(unit_type_get(punit), ACTION_HELP_WONDER)) {
271 /* This unit can never do help wonder. */
272 return FALSE;
273 }
274
275 /* Evaluate all action enablers for extra accuracy. */
276 /* TODO: Is it worth it? */
278 ACTION_HELP_WONDER,
279 pcity));
280}
281
282/**********************************************************************/
287{
288 struct city *phomecity, *pdestcity;
289
290 return (utype_can_do_action(unit_type_get(punit), ACTION_TRADE_ROUTE)
291 && (pdestcity = tile_city(unit_tile(punit)))
292 && (phomecity = game_city_by_number(punit->homecity))
293 && can_cities_trade(phomecity, pdestcity));
294}
295
296/**********************************************************************/
300{
302}
303
304/**********************************************************************/
307bool is_attack_unit(const struct unit *punit)
308{
309 return ((unit_can_do_action_result(punit, ACTRES_ATTACK)
310 || unit_can_do_action_result(punit, ACTRES_BOMBARD))
311 && unit_type_get(punit)->attack_strength > 0);
312}
313
314/**********************************************************************/
319bool is_military_unit(const struct unit *punit)
320{
321 return !unit_has_type_flag(punit, UTYF_CIVILIAN);
322}
323
324/**********************************************************************/
328bool unit_can_do_action(const struct unit *punit,
329 const action_id act_id)
330{
331 return utype_can_do_action(unit_type_get(punit), act_id);
332}
333
334/**********************************************************************/
339 enum action_result result)
340{
342}
343
344/**********************************************************************/
349 enum action_sub_result sub_result)
350{
352}
353
354/**********************************************************************/
357bool is_square_threatened(const struct civ_map *nmap,
358 const struct player *pplayer,
359 const struct tile *ptile, bool omniscient)
360{
361 square_iterate(nmap, ptile, 2, ptile1) {
362 unit_list_iterate(ptile1->units, punit) {
363 if ((omniscient
364 || can_player_see_unit(pplayer, punit))
365 && pplayers_at_war(pplayer, unit_owner(punit))
369 && is_native_near_tile(nmap,
370 unit_class_get(punit), ptile)))) {
371 return TRUE;
372 }
375
376 return FALSE;
377}
378
379/**********************************************************************/
383bool is_field_unit(const struct unit *punit)
384{
385 return unit_has_type_flag(punit, UTYF_FIELDUNIT);
386}
387
388/**********************************************************************/
395bool is_hiding_unit(const struct unit *punit)
396{
397 enum vision_layer vl = unit_type_get(punit)->vlayer;
398
399 if (vl == V_INVIS || vl == V_SUBSURFACE) {
400 return TRUE;
401 }
402
403 if (unit_transported(punit)) {
405 if (vl == V_INVIS || vl == V_SUBSURFACE) {
406 return TRUE;
407 }
408 }
409
410 return FALSE;
411}
412
413/**********************************************************************/
418{
419 return game.info.killcitizen
420 && uclass_has_flag(unit_class_get(punit), UCF_KILLCITIZEN);
421}
422
423/**********************************************************************/
427bool unit_can_add_or_build_city(const struct civ_map *nmap,
428 const struct unit *punit)
429{
430 struct city *tgt_city;
431
432 if ((tgt_city = tile_city(unit_tile(punit)))) {
434 ACTION_JOIN_CITY, tgt_city));
435 } else {
437 ACTION_FOUND_CITY, unit_tile(punit), NULL));
438 }
439}
440
441/**********************************************************************/
444bool can_unit_change_homecity_to(const struct civ_map *nmap,
445 const struct unit *punit,
446 const struct city *pcity)
447{
448 if (pcity == NULL) {
449 /* Can't change home city to a non existing city. */
450 return FALSE;
451 }
452
453 return action_prob_possible(action_prob_vs_city(nmap, punit, ACTION_HOME_CITY,
454 pcity));
455}
456
457/**********************************************************************/
460bool can_unit_change_homecity(const struct civ_map *nmap,
461 const struct unit *punit)
462{
464}
465
466/**********************************************************************/
474int get_activity_rate(const struct unit *punit)
475{
476 const struct veteran_level *vlevel;
477 const struct unit_type *ptype;
478 int move_rate;
479
480 fc_assert_ret_val(punit != NULL, 0);
481
482 ptype = unit_type_get(punit);
483 vlevel = utype_veteran_level(ptype, punit->veteran);
484 fc_assert_ret_val(vlevel != NULL, 0);
485
486 /* The speed of the settler depends on its base move_rate, not on
487 * the number of moves actually remaining or the adjusted move rate.
488 * This means sea formers won't have their activity rate increased by
489 * Magellan's, and it means injured units work just as fast as
490 * uninjured ones. Note the value is never less than SINGLE_MOVE. */
492
493 /* All settler actions are multiplied by ACTIVITY_FACTOR. */
494 return ACTIVITY_FACTOR
495 * (float)vlevel->power_fact / 100
497}
498
499/**********************************************************************/
506{
507 /* This logic is also coded in client/goto.c. */
508 if (punit->moves_left > 0) {
509 return get_activity_rate(punit);
510 } else {
511 return 0;
512 }
513}
514
515/**********************************************************************/
522 enum unit_activity activity,
523 const struct tile *ptile,
524 struct extra_type *tgt)
525{
526 /* FIXME: This is just an approximation since we don't account for
527 * get_activity_rate_this_turn. */
528 int speed = get_activity_rate(punit);
529 int points_needed = tile_activity_time(activity, ptile, tgt);
530
531 if (points_needed >= 0 && speed > 0) {
532 return (points_needed - 1) / speed + 1; /* round up */
533 } else {
534 return FC_INFINITY;
535 }
536}
537
538/**********************************************************************/
541bool activity_requires_target(enum unit_activity activity)
542{
543 switch (activity) {
544 case ACTIVITY_PILLAGE:
545 case ACTIVITY_BASE:
546 case ACTIVITY_GEN_ROAD:
547 case ACTIVITY_IRRIGATE:
548 case ACTIVITY_MINE:
549 case ACTIVITY_POLLUTION:
550 case ACTIVITY_FALLOUT:
551 return TRUE;
552 case ACTIVITY_IDLE:
553 case ACTIVITY_FORTIFIED:
554 case ACTIVITY_SENTRY:
555 case ACTIVITY_GOTO:
556 case ACTIVITY_EXPLORE:
557 case ACTIVITY_TRANSFORM:
558 case ACTIVITY_CULTIVATE:
559 case ACTIVITY_PLANT:
560 case ACTIVITY_FORTIFYING:
561 case ACTIVITY_CONVERT:
562 return FALSE;
563 /* These shouldn't be kicking around internally. */
564 case ACTIVITY_FORTRESS:
565 case ACTIVITY_AIRBASE:
566 case ACTIVITY_PATROL_UNUSED:
567 default:
569 }
570
571 return FALSE;
572}
573
574/**********************************************************************/
584{
585 return unit_type_get(punit)->adv.worker;
586}
587
588/**********************************************************************/
592{
594 int i = 0;
595
596 for (act = 0; act < ACTIVITY_LAST; act++) {
597 if (is_real_activity(act)) {
598 real_activities[i++] = act;
599 }
600 }
601
602 real_activities[i] = ACTIVITY_LAST;
603}
604
605/**********************************************************************/
609bool is_real_activity(enum unit_activity activity)
610{
611 /* ACTIVITY_FORTRESS, ACTIVITY_AIRBASE, ACTIVITY_OLD_ROAD, and
612 * ACTIVITY_OLD_RAILROAD are deprecated */
613 return (activity < ACTIVITY_LAST)
614 && activity != ACTIVITY_FORTRESS
615 && activity != ACTIVITY_AIRBASE
616 && activity != ACTIVITY_OLD_ROAD
617 && activity != ACTIVITY_OLD_RAILROAD
618 && activity != ACTIVITY_UNKNOWN
619 && activity != ACTIVITY_PATROL_UNUSED;
620}
621
622/**********************************************************************/
625const char *get_activity_text(enum unit_activity activity)
626{
627 /* The switch statement has just the activities listed with no "default"
628 * handling. This enables the compiler to detect missing entries
629 * automatically, and still handles everything correctly. */
630 switch (activity) {
631 case ACTIVITY_IDLE:
632 return _("Idle");
633 case ACTIVITY_POLLUTION:
634 return _("Pollution");
635 case ACTIVITY_MINE:
636 /* TRANS: Activity name, verb in English */
637 return Q_("?act:Mine");
638 case ACTIVITY_PLANT:
639 /* TRANS: Activity name, verb in English */
640 return _("Plant");
641 case ACTIVITY_IRRIGATE:
642 return _("Irrigate");
643 case ACTIVITY_CULTIVATE:
644 return _("Cultivate");
645 case ACTIVITY_FORTIFYING:
646 return _("Fortifying");
647 case ACTIVITY_FORTIFIED:
648 return _("Fortified");
649 case ACTIVITY_SENTRY:
650 return _("Sentry");
651 case ACTIVITY_PILLAGE:
652 return _("Pillage");
653 case ACTIVITY_GOTO:
654 return _("Goto");
655 case ACTIVITY_EXPLORE:
656 return _("Explore");
657 case ACTIVITY_TRANSFORM:
658 return _("Transform");
659 case ACTIVITY_FALLOUT:
660 return _("Fallout");
661 case ACTIVITY_BASE:
662 return _("Base");
663 case ACTIVITY_GEN_ROAD:
664 return _("Road");
665 case ACTIVITY_CONVERT:
666 return _("Convert");
667 case ACTIVITY_OLD_ROAD:
668 case ACTIVITY_OLD_RAILROAD:
669 case ACTIVITY_FORTRESS:
670 case ACTIVITY_AIRBASE:
671 case ACTIVITY_UNKNOWN:
672 case ACTIVITY_PATROL_UNUSED:
673 case ACTIVITY_LAST:
674 break;
675 }
676
678 return _("Unknown");
679}
680
681/**********************************************************************/
687bool could_unit_be_in_transport(const struct unit *pcargo,
688 const struct unit *ptrans)
689{
690 /* Make sure this transporter can carry this type of unit. */
691 if (!can_unit_transport(ptrans, pcargo)) {
692 return FALSE;
693 }
694
695 /* Make sure there's room in the transporter. */
696 if (get_transporter_occupancy(ptrans)
697 >= get_transporter_capacity(ptrans)) {
698 return FALSE;
699 }
700
701 /* Check iff this is a valid transport. */
702 if (!unit_transport_check(pcargo, ptrans)) {
703 return FALSE;
704 }
705
706 /* Check transport depth. */
708 < 1 + unit_transport_depth(ptrans) + unit_cargo_depth(pcargo)) {
709 return FALSE;
710 }
711
712 return TRUE;
713}
714
715/**********************************************************************/
719bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
720{
721 if (!pcargo || !ptrans || pcargo == ptrans) {
722 return FALSE;
723 }
724
725 /* Double-check ownership of the units: you can load into an allied unit
726 * (of course only allied units can be on the same tile). */
727 if (!pplayers_allied(unit_owner(pcargo), unit_owner(ptrans))) {
728 return FALSE;
729 }
730
731 /* Un-embarkable transport must be in city or base to load cargo. */
733 && !tile_city(unit_tile(ptrans))
734 && !tile_has_native_base(unit_tile(ptrans), unit_type_get(ptrans))) {
735 return FALSE;
736 }
737
738 return could_unit_be_in_transport(pcargo, ptrans);
739}
740
741/**********************************************************************/
744bool can_unit_load(const struct unit *pcargo, const struct unit *ptrans)
745{
746 /* This function needs to check EVERYTHING. */
747
748 /* Check positions of the units. Of course you can't load a unit onto
749 * a transporter on a different tile... */
750 if (!same_pos(unit_tile(pcargo), unit_tile(ptrans))) {
751 return FALSE;
752 }
753
754 /* Cannot load if cargo is already loaded onto something else. */
755 if (unit_transported(pcargo)) {
756 return FALSE;
757 }
758
759 return could_unit_load(pcargo, ptrans);
760}
761
762/**********************************************************************/
771bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
772{
773 if (!pcargo || !ptrans) {
774 return FALSE;
775 }
776
777 /* Make sure the unit's transporter exists and is known. */
778 if (unit_transport_get(pcargo) != ptrans) {
779 return FALSE;
780 }
781
782 /* Un-disembarkable transport must be in city or base to unload cargo. */
784 && !tile_city(unit_tile(ptrans))
785 && !tile_has_native_base(unit_tile(ptrans), unit_type_get(ptrans))) {
786 return FALSE;
787 }
788
789 return TRUE;
790}
791
792/**********************************************************************/
797 const struct unit *pcargo,
798 const struct unit *ptrans)
799{
800 if (!pcargo || !ptrans) {
801 return FALSE;
802 }
803
804 fc_assert_ret_val(unit_transport_get(pcargo) == ptrans, FALSE);
805
806 if (is_server()) {
807 return (is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_ALIGHT,
808 pcargo, ptrans)
809 || is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_UNLOAD,
810 ptrans, pcargo));
811 } else {
812 return (action_prob_possible(
813 action_prob_vs_unit(nmap, pcargo, ACTION_TRANSPORT_ALIGHT, ptrans))
815 action_prob_vs_unit(nmap, ptrans, ACTION_TRANSPORT_UNLOAD,
816 pcargo)));
817 }
818}
819
820
821/**********************************************************************/
826bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
827{
828 action_by_result_iterate(paction, ACTRES_PARADROP) {
829 if (action_maybe_possible_actor_unit(nmap, paction->id, punit)) {
830 return TRUE;
831 }
833 action_by_result_iterate(paction, ACTRES_PARADROP_CONQUER) {
834 if (action_maybe_possible_actor_unit(nmap, paction->id, punit)) {
835 return TRUE;
836 }
838
839 return FALSE;
840}
841
842/**********************************************************************/
846 struct unit *punit)
847{
848 enum unit_activity current = punit->activity;
849 struct extra_type *target = punit->activity_target;
850 enum unit_activity current2 =
851 (current == ACTIVITY_FORTIFIED) ? ACTIVITY_FORTIFYING : current;
852 bool result;
853
854 punit->activity = ACTIVITY_IDLE;
855 punit->activity_target = NULL;
856
857 result = can_unit_do_activity_targeted(nmap, punit, current2, target);
858
859 punit->activity = current;
860 punit->activity_target = target;
861
862 return result;
863}
864
865/**********************************************************************/
872bool can_unit_do_activity(const struct civ_map *nmap,
873 const struct unit *punit,
874 enum unit_activity activity)
875{
876 struct extra_type *target = NULL;
877
878 /* FIXME: Lots of callers (usually client real_menus_update()) rely on
879 * being able to find out whether an activity is in general possible.
880 * Find one for them, but when they come to do the activity, they will
881 * have to determine the target themselves */
882 {
883 struct tile *ptile = unit_tile(punit);
884
885 if (activity == ACTIVITY_IRRIGATE) {
886 target = next_extra_for_tile(ptile,
887 EC_IRRIGATION,
889 punit);
890 if (NULL == target) {
891 return FALSE; /* No more irrigation extras available. */
892 }
893 } else if (activity == ACTIVITY_MINE) {
894 target = next_extra_for_tile(ptile,
895 EC_MINE,
897 punit);
898 if (NULL == target) {
899 return FALSE; /* No more mine extras available. */
900 }
901 }
902 }
903
904 return can_unit_do_activity_targeted(nmap, punit, activity, target);
905}
906
907/**********************************************************************/
912 const struct unit *punit,
913 enum unit_activity activity,
914 struct extra_type *target)
915{
916 return can_unit_do_activity_targeted_at(nmap, punit, activity, target,
918}
919
920/**********************************************************************/
925 const struct unit *punit,
926 enum unit_activity activity,
927 struct extra_type *target,
928 const struct tile *ptile)
929{
930 /* Check that no build activity conflicting with one already in progress
931 * gets executed. */
932 /* FIXME: Should check also the cases where one of the activities is terrain
933 * change that destroys the target of the other activity */
934 if (target != NULL && is_build_activity(activity)) {
935 if (tile_is_placing(ptile)) {
936 return FALSE;
937 }
938
939 unit_list_iterate(ptile->units, tunit) {
940 if (is_build_activity(tunit->activity)
941 && !can_extras_coexist(target, tunit->activity_target)) {
942 return FALSE;
943 }
945 }
946
947#define RETURN_IS_ACTIVITY_ENABLED_UNIT_ON(paction) \
948{ \
949 switch (action_get_target_kind(paction)) { \
950 case ATK_TILE: \
951 return is_action_enabled_unit_on_tile(nmap, paction->id, \
952 punit, ptile, target); \
953 case ATK_EXTRAS: \
954 return is_action_enabled_unit_on_extras(nmap, paction->id, \
955 punit, ptile, target); \
956 case ATK_CITY: \
957 case ATK_UNIT: \
958 case ATK_UNITS: \
959 case ATK_SELF: \
960 return FALSE; \
961 case ATK_COUNT: \
962 break; /* Handle outside switch */ \
963 } \
964 fc_assert(action_target_kind_is_valid( \
965 action_get_target_kind(paction))); \
966 return FALSE; \
967 }
968
969 switch (activity) {
970 case ACTIVITY_IDLE:
971 case ACTIVITY_GOTO:
972 return TRUE;
973
974 case ACTIVITY_POLLUTION:
975 /* The call below doesn't support actor tile speculation. */
976 fc_assert_msg(unit_tile(punit) == ptile,
977 "Please use action_speculate_unit_on_tile()");
978 return is_action_enabled_unit_on_tile(nmap, ACTION_CLEAN_POLLUTION,
979 punit, ptile, target);
980
981 case ACTIVITY_FALLOUT:
982 /* The call below doesn't support actor tile speculation. */
983 fc_assert_msg(unit_tile(punit) == ptile,
984 "Please use action_speculate_unit_on_tile()");
985 return is_action_enabled_unit_on_tile(nmap, ACTION_CLEAN_FALLOUT,
986 punit, ptile, target);
987
988 case ACTIVITY_MINE:
989 /* The call below doesn't support actor tile speculation. */
990 fc_assert_msg(unit_tile(punit) == ptile,
991 "Please use action_speculate_unit_on_tile()");
992 return is_action_enabled_unit_on_tile(nmap, ACTION_MINE, punit,
993 ptile, target);
994
995 case ACTIVITY_PLANT:
996 /* The call below doesn't support actor tile speculation. */
997 fc_assert_msg(unit_tile(punit) == ptile,
998 "Please use action_speculate_unit_on_tile()");
999 return is_action_enabled_unit_on_tile(nmap, ACTION_PLANT,
1000 punit, ptile, NULL);
1001
1002 case ACTIVITY_IRRIGATE:
1003 /* The call below doesn't support actor tile speculation. */
1004 fc_assert_msg(unit_tile(punit) == ptile,
1005 "Please use action_speculate_unit_on_tile()");
1006 return is_action_enabled_unit_on_tile(nmap, ACTION_IRRIGATE, punit,
1007 ptile, target);
1008
1009 case ACTIVITY_CULTIVATE:
1010 /* The call below doesn't support actor tile speculation. */
1011 fc_assert_msg(unit_tile(punit) == ptile,
1012 "Please use action_speculate_unit_on_tile()");
1013 return is_action_enabled_unit_on_tile(nmap, ACTION_CULTIVATE,
1014 punit, ptile, NULL);
1015
1016 case ACTIVITY_FORTIFYING:
1017 /* The call below doesn't support actor tile speculation. */
1018 fc_assert_msg(unit_tile(punit) == ptile,
1019 "Please use action_speculate_unit_on_self()");
1020 return is_action_enabled_unit_on_self(nmap, ACTION_FORTIFY,
1021 punit);
1022
1023 case ACTIVITY_FORTIFIED:
1024 return FALSE;
1025
1026 case ACTIVITY_BASE:
1027 /* The call below doesn't support actor tile speculation. */
1028 fc_assert_msg(unit_tile(punit) == ptile,
1029 "Please use action_speculate_unit_on_tile()");
1030 return is_action_enabled_unit_on_tile(nmap, ACTION_BASE,
1031 punit, ptile, target);
1032
1033 case ACTIVITY_GEN_ROAD:
1034 /* The call below doesn't support actor tile speculation. */
1035 fc_assert_msg(unit_tile(punit) == ptile,
1036 "Please use action_speculate_unit_on_tile()");
1037 return is_action_enabled_unit_on_tile(nmap, ACTION_ROAD,
1038 punit, ptile, target);
1039
1040 case ACTIVITY_SENTRY:
1042 && !unit_transported(punit)) {
1043 /* Don't let units sentry on tiles they will die on. */
1044 return FALSE;
1045 }
1046 return TRUE;
1047
1048 case ACTIVITY_PILLAGE:
1049 /* The call below doesn't support actor tile speculation. */
1050 fc_assert_msg(unit_tile(punit) == ptile,
1051 "Please use action_speculate_unit_on_tile()");
1053
1054 case ACTIVITY_EXPLORE:
1055 return (!unit_type_get(punit)->fuel && !is_losing_hp(punit));
1056
1057 case ACTIVITY_TRANSFORM:
1058 /* The call below doesn't support actor tile speculation. */
1059 fc_assert_msg(unit_tile(punit) == ptile,
1060 "Please use action_speculate_unit_on_tile()");
1061 return is_action_enabled_unit_on_tile(nmap, ACTION_TRANSFORM_TERRAIN,
1062 punit, ptile, NULL);
1063
1064 case ACTIVITY_CONVERT:
1065 /* The call below doesn't support actor tile speculation. */
1066 fc_assert_msg(unit_tile(punit) == ptile,
1067 "Please use action_speculate_unit_on_self()");
1068 return is_action_enabled_unit_on_self(nmap, ACTION_CONVERT, punit);
1069
1070 case ACTIVITY_OLD_ROAD:
1071 case ACTIVITY_OLD_RAILROAD:
1072 case ACTIVITY_FORTRESS:
1073 case ACTIVITY_AIRBASE:
1074 case ACTIVITY_PATROL_UNUSED:
1075 case ACTIVITY_LAST:
1076 case ACTIVITY_UNKNOWN:
1077 break;
1078 }
1079 log_error("can_unit_do_activity_targeted_at() unknown activity %d",
1080 activity);
1081 return FALSE;
1082
1083#undef RETURN_IS_ACTIVITY_ENABLED_UNIT_ON
1084}
1085
1086/**********************************************************************/
1090 enum unit_activity new_activity)
1091{
1092 fc_assert_ret(new_activity != ACTIVITY_FORTRESS
1093 && new_activity != ACTIVITY_AIRBASE);
1094
1095 punit->activity = new_activity;
1096 punit->activity_count = 0;
1097 punit->activity_target = NULL;
1098 if (new_activity == ACTIVITY_IDLE && punit->moves_left > 0) {
1099 /* No longer done. */
1101 }
1102}
1103
1104/**********************************************************************/
1107void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
1108{
1110
1111 if (new_activity == ACTIVITY_FORTIFYING
1112 && punit->changed_from == ACTIVITY_FORTIFIED) {
1113 new_activity = ACTIVITY_FORTIFIED;
1114 }
1115 set_unit_activity_internal(punit, new_activity);
1116 if (new_activity == punit->changed_from) {
1118 }
1119}
1120
1121/**********************************************************************/
1125 enum unit_activity new_activity,
1126 struct extra_type *new_target)
1127{
1129 || new_target == NULL);
1130
1131 set_unit_activity_internal(punit, new_activity);
1132 punit->activity_target = new_target;
1133 if (new_activity == punit->changed_from
1134 && new_target == punit->changed_from_target) {
1136 }
1137}
1138
1139/**********************************************************************/
1142bool is_unit_activity_on_tile(enum unit_activity activity,
1143 const struct tile *ptile)
1144{
1145 unit_list_iterate(ptile->units, punit) {
1146 if (punit->activity == activity) {
1147 return TRUE;
1148 }
1150 return FALSE;
1151}
1152
1153/**********************************************************************/
1157bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
1158{
1159 bv_extras tgt_ret;
1160
1161 BV_CLR_ALL(tgt_ret);
1162 unit_list_iterate(ptile->units, punit) {
1163 if (punit->activity == ACTIVITY_PILLAGE) {
1165 }
1167
1168 return tgt_ret;
1169}
1170
1171/**********************************************************************/
1174void unit_activity_astr(const struct unit *punit, struct astring *astr)
1175{
1176 if (!punit || !astr) {
1177 return;
1178 }
1179
1180 switch (punit->activity) {
1181 case ACTIVITY_IDLE:
1183 int rate, f;
1184
1185 rate = unit_type_get(punit)->move_rate;
1186 f = ((punit->fuel) - 1);
1187
1188 /* Add in two parts as move_points_text() returns ptr to static
1189 * End result: "Moves: (fuel)moves_left" */
1190 astr_add_line(astr, "%s: (%s)", _("Moves"),
1191 move_points_text((rate * f) + punit->moves_left, FALSE));
1192 astr_add(astr, "%s",
1194 } else {
1195 astr_add_line(astr, "%s: %s", _("Moves"),
1197 }
1198 return;
1199 case ACTIVITY_POLLUTION:
1200 case ACTIVITY_FALLOUT:
1201 case ACTIVITY_OLD_ROAD:
1202 case ACTIVITY_OLD_RAILROAD:
1203 case ACTIVITY_TRANSFORM:
1204 case ACTIVITY_FORTIFYING:
1205 case ACTIVITY_FORTIFIED:
1206 case ACTIVITY_AIRBASE:
1207 case ACTIVITY_FORTRESS:
1208 case ACTIVITY_SENTRY:
1209 case ACTIVITY_GOTO:
1210 case ACTIVITY_EXPLORE:
1211 case ACTIVITY_CONVERT:
1212 case ACTIVITY_CULTIVATE:
1213 case ACTIVITY_PLANT:
1215 return;
1216 case ACTIVITY_MINE:
1217 case ACTIVITY_IRRIGATE:
1218 if (punit->activity_target == NULL) {
1220 } else {
1221 astr_add_line(astr, "Building %s",
1223 }
1224 return;
1225 case ACTIVITY_PILLAGE:
1226 if (punit->activity_target != NULL) {
1229 } else {
1231 }
1232 return;
1233 case ACTIVITY_BASE:
1236 return;
1237 case ACTIVITY_GEN_ROAD:
1240 return;
1241 case ACTIVITY_UNKNOWN:
1242 case ACTIVITY_PATROL_UNUSED:
1243 case ACTIVITY_LAST:
1244 break;
1245 }
1246
1247 log_error("Unknown unit activity %d for %s (nb %d) in %s()",
1248 punit->activity, unit_rule_name(punit), punit->id, __FUNCTION__);
1249}
1250
1251/**********************************************************************/
1257void unit_upkeep_astr(const struct unit *punit, struct astring *astr)
1258{
1259 if (!punit || !astr) {
1260 return;
1261 }
1262
1263 astr_add_line(astr, "%s %d/%d/%d", _("Food/Shield/Gold:"),
1265 punit->upkeep[O_GOLD]);
1266}
1267
1268/**********************************************************************/
1271struct player *unit_nationality(const struct unit *punit)
1272{
1273 fc_assert_ret_val(NULL != punit, NULL);
1274 return punit->nationality;
1275}
1276
1277/**********************************************************************/
1281void unit_tile_set(struct unit *punit, struct tile *ptile)
1282{
1283 fc_assert_ret(NULL != punit);
1284 punit->tile = ptile;
1285}
1286
1287/**********************************************************************/
1294struct unit *tile_allied_unit(const struct tile *ptile,
1295 const struct player *pplayer)
1296{
1297 struct unit *punit = NULL;
1298
1299 unit_list_iterate(ptile->units, cunit) {
1300 if (pplayers_allied(pplayer, unit_owner(cunit))) {
1301 punit = cunit;
1302 } else {
1303 return NULL;
1304 }
1305 }
1307
1308 return punit;
1309}
1310
1311/**********************************************************************/
1317struct unit *tile_enemy_unit(const struct tile *ptile,
1318 const struct player *pplayer)
1319{
1320 unit_list_iterate(ptile->units, punit) {
1321 if (pplayers_at_war(unit_owner(punit), pplayer)) {
1322 return punit;
1323 }
1325
1326 return NULL;
1327}
1328
1329/**********************************************************************/
1332struct unit *tile_non_allied_unit(const struct tile *ptile,
1333 const struct player *pplayer)
1334{
1335 unit_list_iterate(ptile->units, punit) {
1336 if (!pplayers_allied(unit_owner(punit), pplayer)) {
1337 return punit;
1338 }
1339 }
1341
1342 return NULL;
1343}
1344
1345/**********************************************************************/
1349struct unit *tile_other_players_unit(const struct tile *ptile,
1350 const struct player *pplayer)
1351{
1352 unit_list_iterate(ptile->units, punit) {
1353 if (unit_owner(punit) != pplayer) {
1354 return punit;
1355 }
1357
1358 return NULL;
1359}
1360
1361/**********************************************************************/
1365struct unit *tile_non_attack_unit(const struct tile *ptile,
1366 const struct player *pplayer)
1367{
1368 unit_list_iterate(ptile->units, punit) {
1369 if (pplayers_non_attack(unit_owner(punit), pplayer)) {
1370 return punit;
1371 }
1372 }
1374
1375 return NULL;
1376}
1377
1378/**********************************************************************/
1386struct unit *unit_occupies_tile(const struct tile *ptile,
1387 const struct player *pplayer)
1388{
1389 unit_list_iterate(ptile->units, punit) {
1390 if (!is_military_unit(punit)) {
1391 continue;
1392 }
1393
1394 if (uclass_has_flag(unit_class_get(punit), UCF_DOESNT_OCCUPY_TILE)) {
1395 continue;
1396 }
1397
1398 if (pplayers_at_war(unit_owner(punit), pplayer)) {
1399 return punit;
1400 }
1402
1403 return NULL;
1404}
1405
1406/**********************************************************************/
1413bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0,
1414 const struct civ_map *zmap)
1415{
1416 square_iterate(zmap, ptile0, 1, ptile) {
1417 struct terrain *pterrain;
1418 struct city *pcity;
1419
1420 pterrain = tile_terrain(ptile);
1421 if (terrain_has_flag(pterrain, TER_NO_ZOC)) {
1422 continue;
1423 }
1424
1425 pcity = tile_non_allied_city(ptile, pplayer);
1426 if (pcity != NULL) {
1427 if (unit_list_size(ptile->units) > 0) {
1428 /* Occupied enemy city, it doesn't matter if units inside have
1429 * UTYF_NOZOC or not. */
1430 return FALSE;
1431 }
1432 } else {
1433 unit_list_iterate(ptile->units, punit) {
1434 if (!pplayers_allied(unit_owner(punit), pplayer)
1435 && !unit_has_type_flag(punit, UTYF_NOZOC)
1437 bool hidden = FALSE;
1438
1439 /* We do NOT check the possibility that player is allied with an extra owner,
1440 * and should thus see inside the extra.
1441 * This is to avoid the situation where having an alliance with third player
1442 * suddenly causes ZoC from a unit that would not cause it without the alliance. */
1444 if (tile_has_extra(ptile, pextra)) {
1445 hidden = TRUE;
1446 break;
1447 }
1449
1450 if (!hidden) {
1451 return FALSE;
1452 }
1453 }
1455 }
1457
1458 return TRUE;
1459}
1460
1461/**********************************************************************/
1472bool is_plr_zoc_client(const struct player *pplayer, const struct tile *ptile0,
1473 const struct civ_map *zmap)
1474{
1475 square_iterate(zmap, ptile0, 1, ptile) {
1476 struct terrain *pterrain;
1477 struct city *pcity;
1478
1479 pterrain = tile_terrain(ptile);
1480 if (T_UNKNOWN == pterrain
1481 || terrain_has_flag(pterrain, TER_NO_ZOC)) {
1482 continue;
1483 }
1484
1485 pcity = tile_non_allied_city(ptile, pplayer);
1486 if (pcity != NULL) {
1487 if (pcity->client.occupied
1488 || TILE_KNOWN_UNSEEN == tile_get_known(ptile, pplayer)) {
1489 /* Occupied enemy city, it doesn't matter if units inside have
1490 * UTYF_NOZOC or not. Fogged city is assumed to be occupied. */
1491 return FALSE;
1492 }
1493 } else {
1494 unit_list_iterate(ptile->units, punit) {
1496 && !pplayers_allied(unit_owner(punit), pplayer)
1497 && !unit_has_type_flag(punit, UTYF_NOZOC)) {
1498 return FALSE;
1499 }
1501 }
1503
1504 return TRUE;
1505}
1506
1507/**********************************************************************/
1510bool unit_type_really_ignores_zoc(const struct unit_type *punittype)
1511{
1512 return (!uclass_has_flag(utype_class(punittype), UCF_ZOC)
1513 || utype_has_flag(punittype, UTYF_IGZOC));
1514}
1515
1516/**********************************************************************/
1524bool unit_being_aggressive(const struct civ_map *nmap,
1525 const struct unit *punit)
1526{
1527 if (!is_attack_unit(punit)) {
1528 return FALSE;
1529 }
1530 if (tile_city(unit_tile(punit))) {
1531 return FALSE;
1532 }
1534 switch (game.info.happyborders) {
1535 case HB_DISABLED:
1536 break;
1537 case HB_NATIONAL:
1539 return FALSE;
1540 }
1541 break;
1542 case HB_ALLIANCE:
1544 return FALSE;
1545 }
1546 break;
1547 }
1548 }
1550 unit_type_get(punit))) {
1551 return !is_unit_near_a_friendly_city(nmap, punit);
1552 }
1553
1554 return TRUE;
1555}
1556
1557/**********************************************************************/
1560bool is_build_activity(enum unit_activity activity)
1561{
1562 switch (activity) {
1563 case ACTIVITY_MINE:
1564 case ACTIVITY_IRRIGATE:
1565 case ACTIVITY_BASE:
1566 case ACTIVITY_GEN_ROAD:
1567 return TRUE;
1568 default:
1569 return FALSE;
1570 }
1571}
1572
1573/**********************************************************************/
1576bool is_clean_activity(enum unit_activity activity)
1577{
1578 switch (activity) {
1579 case ACTIVITY_PILLAGE:
1580 case ACTIVITY_POLLUTION:
1581 case ACTIVITY_FALLOUT:
1582 return TRUE;
1583 default:
1584 return FALSE;
1585 }
1586}
1587
1588/**********************************************************************/
1591bool is_terrain_change_activity(enum unit_activity activity)
1592{
1593 switch (activity) {
1594 case ACTIVITY_CULTIVATE:
1595 case ACTIVITY_PLANT:
1596 case ACTIVITY_TRANSFORM:
1597 return TRUE;
1598 default:
1599 return FALSE;
1600 }
1601}
1602
1603/**********************************************************************/
1606bool is_tile_activity(enum unit_activity activity)
1607{
1608 return is_build_activity(activity)
1609 || is_clean_activity(activity)
1610 || is_terrain_change_activity(activity);
1611}
1612
1613/**********************************************************************/
1617struct unit *unit_virtual_create(struct player *pplayer, struct city *pcity,
1618 const struct unit_type *punittype,
1619 int veteran_level)
1620{
1621 /* Make sure that contents of unit structure are correctly initialized,
1622 * if you ever allocate it by some other mean than fc_calloc() */
1623 struct unit *punit = fc_calloc(1, sizeof(*punit));
1624 int max_vet_lvl;
1625
1626 /* It does not register the unit so the id is set to 0. */
1628
1629 fc_assert_ret_val(NULL != punittype, NULL); /* No untyped units! */
1630 punit->utype = punittype;
1631
1632 fc_assert_ret_val(NULL != pplayer, NULL); /* No unowned units! */
1633 punit->owner = pplayer;
1634 punit->nationality = pplayer;
1635
1636 punit->refcount = 1;
1638
1639 if (pcity) {
1640 unit_tile_set(punit, pcity->tile);
1641 punit->homecity = pcity->id;
1642 } else {
1643 unit_tile_set(punit, NULL);
1645 }
1646
1647 memset(punit->upkeep, 0, O_LAST * sizeof(*punit->upkeep));
1648 punit->goto_tile = NULL;
1649 max_vet_lvl = utype_veteran_levels(punittype) - 1;
1650 punit->veteran = MIN(veteran_level, max_vet_lvl);
1651 /* A unit new and fresh ... */
1655 punit->moved = FALSE;
1656
1657 punit->ssa_controller = SSA_NONE;
1660
1661 punit->transporter = NULL;
1662 punit->transporting = unit_list_new();
1663
1664 punit->carrying = NULL;
1665
1666 set_unit_activity(punit, ACTIVITY_IDLE);
1669
1670 punit->action_decision_want = ACT_DEC_NOTHING;
1672
1673 punit->stay = FALSE;
1674
1675 if (is_server()) {
1678
1680
1682
1683 memset(punit->server.upkeep_paid, 0,
1684 O_LAST * sizeof(*punit->server.upkeep_paid));
1685
1686 punit->server.ord_map = 0;
1687 punit->server.ord_city = 0;
1688
1689 punit->server.vision = NULL; /* No vision. */
1691 /* Must be an invalid turn number, and an invalid previous turn
1692 * number. */
1693 punit->server.action_turn = -2;
1694 /* punit->server.moving = NULL; set by fc_calloc(). */
1695
1696 punit->server.adv = fc_calloc(1, sizeof(*punit->server.adv));
1697
1698 CALL_FUNC_EACH_AI(unit_alloc, punit);
1699 } else {
1703 punit->client.act_prob_cache = NULL;
1704 }
1705
1706 return punit;
1707}
1708
1709/**********************************************************************/
1714{
1716
1717 /* Unload unit if transported. */
1720
1721 /* Check for transported units. Use direct access to the list. */
1722 if (unit_list_size(punit->transporting) != 0) {
1723 /* Unload all units. */
1725 unit_transport_unload(pcargo);
1727 }
1728 fc_assert(unit_list_size(punit->transporting) == 0);
1729
1730 if (punit->transporting) {
1731 unit_list_destroy(punit->transporting);
1732 }
1733
1734 CALL_FUNC_EACH_AI(unit_free, punit);
1735
1736 if (is_server() && punit->server.adv) {
1738 } else {
1741 }
1742 }
1743
1744 if (--punit->refcount <= 0) {
1745 FC_FREE(punit);
1746 }
1747}
1748
1749/**********************************************************************/
1754{
1755 if (punit->has_orders) {
1756 punit->goto_tile = NULL;
1757 free(punit->orders.list);
1758 punit->orders.list = NULL;
1759 }
1760 punit->orders.length = 0;
1762}
1763
1764/**********************************************************************/
1767int get_transporter_occupancy(const struct unit *ptrans)
1768{
1769 fc_assert_ret_val(ptrans, -1);
1770
1771 return unit_list_size(ptrans->transporting);
1772}
1773
1774/**********************************************************************/
1777static struct unit *base_transporter_for_unit(const struct unit *pcargo,
1778 const struct tile *ptile,
1779 bool (*unit_load_test)
1780 (const struct unit *pc,
1781 const struct unit *pt))
1782{
1783 struct unit *best_trans = NULL;
1784 struct {
1785 bool has_orders, is_idle, can_freely_unload;
1786 int depth, outermost_moves_left, total_moves;
1787 } cur, best = { FALSE };
1788
1789 unit_list_iterate(ptile->units, ptrans) {
1790 if (!unit_load_test(pcargo, ptrans)) {
1791 continue;
1792 } else if (best_trans == NULL) {
1793 best_trans = ptrans;
1794 }
1795
1796 /* Gather data from transport stack in a single pass, for use in
1797 * various conditions below. */
1798 cur.has_orders = unit_has_orders(ptrans);
1799 cur.outermost_moves_left = ptrans->moves_left;
1800 cur.total_moves = ptrans->moves_left + unit_move_rate(ptrans);
1801 unit_transports_iterate(ptrans, ptranstrans) {
1802 if (unit_has_orders(ptranstrans)) {
1803 cur.has_orders = TRUE;
1804 }
1805 cur.outermost_moves_left = ptranstrans->moves_left;
1806 cur.total_moves += ptranstrans->moves_left + unit_move_rate(ptranstrans);
1808
1809 /* Criteria for deciding the 'best' transport to load onto.
1810 * The following tests are applied in order; earlier ones have
1811 * lexicographically greater significance than later ones. */
1812
1813 /* Transports which have orders, or are on transports with orders,
1814 * are less preferable to transport stacks without orders (to
1815 * avoid loading on units that are just passing through). */
1816 if (best_trans != ptrans) {
1817 if (!cur.has_orders && best.has_orders) {
1818 best_trans = ptrans;
1819 } else if (cur.has_orders && !best.has_orders) {
1820 continue;
1821 }
1822 }
1823
1824 /* Else, transports which are idle are preferable (giving players
1825 * some control over loading) -- this does not check transports
1826 * of transports. */
1827 cur.is_idle = (ptrans->activity == ACTIVITY_IDLE);
1828 if (best_trans != ptrans) {
1829 if (cur.is_idle && !best.is_idle) {
1830 best_trans = ptrans;
1831 } else if (!cur.is_idle && best.is_idle) {
1832 continue;
1833 }
1834 }
1835
1836 /* Else, transports from which the cargo could unload at any time
1837 * are preferable to those where the cargo can only disembark in
1838 * cities/bases. */
1839 cur.can_freely_unload = utype_can_freely_unload(unit_type_get(pcargo),
1840 unit_type_get(ptrans));
1841 if (best_trans != ptrans) {
1842 if (cur.can_freely_unload && !best.can_freely_unload) {
1843 best_trans = ptrans;
1844 } else if (!cur.can_freely_unload && best.can_freely_unload) {
1845 continue;
1846 }
1847 }
1848
1849 /* Else, transports which are less deeply nested are preferable. */
1850 cur.depth = unit_transport_depth(ptrans);
1851 if (best_trans != ptrans) {
1852 if (cur.depth < best.depth) {
1853 best_trans = ptrans;
1854 } else if (cur.depth > best.depth) {
1855 continue;
1856 }
1857 }
1858
1859 /* Else, transport stacks where the outermost transport has more
1860 * moves left are preferable (on the assumption that it's the
1861 * outermost transport that's about to move). */
1862 if (best_trans != ptrans) {
1863 if (cur.outermost_moves_left > best.outermost_moves_left) {
1864 best_trans = ptrans;
1865 } else if (cur.outermost_moves_left < best.outermost_moves_left) {
1866 continue;
1867 }
1868 }
1869
1870 /* All other things being equal, as a tie-breaker, compare the total
1871 * moves left (this turn) and move rate (future turns) for the whole
1872 * stack, to take into account total potential movement for both
1873 * short and long journeys (we don't know which the cargo intends to
1874 * make). Doesn't try to account for whether transports can unload,
1875 * etc. */
1876 if (best_trans != ptrans) {
1877 if (cur.total_moves > best.total_moves) {
1878 best_trans = ptrans;
1879 } else {
1880 continue;
1881 }
1882 }
1883
1884 fc_assert(best_trans == ptrans);
1885 best = cur;
1887
1888 return best_trans;
1889}
1890
1891/**********************************************************************/
1896struct unit *transporter_for_unit(const struct unit *pcargo)
1897{
1898 return base_transporter_for_unit(pcargo, unit_tile(pcargo), can_unit_load);
1899}
1900
1901/**********************************************************************/
1906struct unit *transporter_for_unit_at(const struct unit *pcargo,
1907 const struct tile *ptile)
1908{
1909 return base_transporter_for_unit(pcargo, ptile, could_unit_load);
1910}
1911
1912/**********************************************************************/
1917 const struct unit *punit)
1918{
1920 return FALSE;
1921 }
1922
1925 return FALSE;
1926 }
1928
1929 return TRUE;
1930}
1931
1932/**********************************************************************/
1941 const struct unit *punit,
1942 const struct unit_type *to_unittype)
1943{
1944 fc_assert_ret_val(NULL != to_unittype, UU_NO_UNITTYPE);
1945
1946 if (!can_type_transport_units_cargo(to_unittype, punit)) {
1947 return UU_NOT_ENOUGH_ROOM;
1948 }
1949
1950 if (punit->transporter != NULL) {
1952 utype_class(to_unittype))) {
1954 }
1955 } else if (!can_exist_at_tile(nmap, to_unittype, unit_tile(punit))) {
1956 /* The new unit type can't survive on this terrain. */
1957 return UU_NOT_TERRAIN;
1958 }
1959
1960 return UU_OK;
1961}
1962
1963/**********************************************************************/
1973 const struct unit *punit,
1974 bool is_free)
1975{
1976 struct player *pplayer = unit_owner(punit);
1977 const struct unit_type *to_unittype = can_upgrade_unittype(pplayer,
1979 struct city *pcity;
1980 int cost;
1981
1982 if (!to_unittype) {
1983 return UU_NO_UNITTYPE;
1984 }
1985
1986 if (punit->activity == ACTIVITY_CONVERT) {
1987 /* TODO: There may be other activities that the upgraded unit is not
1988 allowed to do, which we could also test.
1989 -
1990 If convert were legal for new unit_type we could allow, but then it
1991 has a 'head start' getting activity time from the old conversion. */
1992 return UU_NOT_ACTIVITY;
1993 }
1994
1995 if (!is_free) {
1996 cost = unit_upgrade_price(pplayer, unit_type_get(punit), to_unittype);
1997 if (pplayer->economic.gold < cost) {
1998 return UU_NO_MONEY;
1999 }
2000
2001 pcity = tile_city(unit_tile(punit));
2002 if (!pcity) {
2003 return UU_NOT_IN_CITY;
2004 }
2005 if (city_owner(pcity) != pplayer) {
2006 /* TODO: Should upgrades in allied cities be possible? */
2007 return UU_NOT_CITY_OWNER;
2008 }
2009 }
2010
2011 /* TODO: Allow transported units to be reassigned. Check here
2012 * and make changes to upgrade_unit. */
2013 return unit_transform_result(nmap, punit, to_unittype);
2014}
2015
2016/**********************************************************************/
2019bool unit_can_convert(const struct civ_map *nmap,
2020 const struct unit *punit)
2021{
2022 const struct unit_type *tgt = unit_type_get(punit)->converted_to;
2023
2024 if (tgt == NULL) {
2025 return FALSE;
2026 }
2027
2028 return UU_OK == unit_transform_result(nmap, punit, tgt);
2029}
2030
2031/**********************************************************************/
2036 const struct unit *punit,
2037 char *buf, size_t bufsz)
2038{
2039 struct player *pplayer = unit_owner(punit);
2040 enum unit_upgrade_result result = unit_upgrade_test(nmap, punit, FALSE);
2041 int upgrade_cost;
2042 const struct unit_type *from_unittype = unit_type_get(punit);
2043 const struct unit_type *to_unittype = can_upgrade_unittype(pplayer,
2045 char tbuf[MAX_LEN_MSG];
2046
2047 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
2048 "Treasury contains %d gold.",
2049 pplayer->economic.gold),
2050 pplayer->economic.gold);
2051
2052 switch (result) {
2053 case UU_OK:
2054 upgrade_cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
2055 /* This message is targeted toward the GUI callers. */
2056 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
2057 fc_snprintf(buf, bufsz, PL_("Upgrade %s to %s for %d gold?\n%s",
2058 "Upgrade %s to %s for %d gold?\n%s",
2059 upgrade_cost),
2060 utype_name_translation(from_unittype),
2061 utype_name_translation(to_unittype),
2062 upgrade_cost, tbuf);
2063 break;
2064 case UU_NO_UNITTYPE:
2065 fc_snprintf(buf, bufsz,
2066 _("Sorry, cannot upgrade %s (yet)."),
2067 utype_name_translation(from_unittype));
2068 break;
2069 case UU_NO_MONEY:
2070 upgrade_cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
2071 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
2072 fc_snprintf(buf, bufsz, PL_("Upgrading %s to %s costs %d gold.\n%s",
2073 "Upgrading %s to %s costs %d gold.\n%s",
2074 upgrade_cost),
2075 utype_name_translation(from_unittype),
2076 utype_name_translation(to_unittype),
2077 upgrade_cost, tbuf);
2078 break;
2079 case UU_NOT_IN_CITY:
2080 case UU_NOT_CITY_OWNER:
2081 fc_snprintf(buf, bufsz,
2082 _("You can only upgrade units in your cities."));
2083 break;
2084 case UU_NOT_ENOUGH_ROOM:
2085 fc_snprintf(buf, bufsz,
2086 _("Upgrading this %s would strand units it transports."),
2087 utype_name_translation(from_unittype));
2088 break;
2089 case UU_NOT_TERRAIN:
2090 fc_snprintf(buf, bufsz,
2091 _("Upgrading this %s would result in a %s which can not "
2092 "survive at this place."),
2093 utype_name_translation(from_unittype),
2094 utype_name_translation(to_unittype));
2095 break;
2097 fc_snprintf(buf, bufsz,
2098 _("Upgrading this %s would result in a %s which its "
2099 "current transport, %s, could not transport."),
2100 utype_name_translation(from_unittype),
2101 utype_name_translation(to_unittype),
2103 break;
2104 case UU_NOT_ACTIVITY:
2105 fc_snprintf(buf, bufsz,
2106 _("Cannot upgrade %s while doing '%s'."),
2107 utype_name_translation(from_unittype),
2108 unit_activity_name(punit->activity));
2109 break;
2110 }
2111
2112 return result;
2113}
2114
2115/**********************************************************************/
2119int unit_pays_mp_for_action(const struct action *paction,
2120 const struct unit *punit)
2121{
2122 int mpco;
2123
2124 mpco = get_target_bonus_effects(NULL,
2125 &(const struct req_context) {
2126 .player = unit_owner(punit),
2127 .city = unit_tile(punit)
2129 : NULL,
2130 .tile = unit_tile(punit),
2131 .unit = punit,
2132 .unittype = unit_type_get(punit),
2133 .action = paction,
2134 },
2135 NULL,
2136 EFT_ACTION_SUCCESS_MOVE_COST);
2137
2139
2140 return mpco;
2141}
2142
2143/**********************************************************************/
2146int hp_gain_coord(const struct unit *punit)
2147{
2148 int hp = 0;
2149 const int base = unit_type_get(punit)->hp;
2150 int min = base * get_unit_bonus(punit, EFT_MIN_HP_PCT) / 100;
2151
2152 /* Includes barracks (100%), fortress (25%), etc. */
2153 hp += base * get_unit_bonus(punit, EFT_HP_REGEN) / 100;
2154
2155 /* Minimum HP after regen effects applied. */
2156 hp = MAX(hp, min);
2157
2158 /* Regen2 effects that apply after there's at least Min HP */
2159 hp += ceil(base / 10) * get_unit_bonus(punit, EFT_HP_REGEN_2) / 10;
2160
2161 return MAX(hp, 0);
2162}
2163
2164/**********************************************************************/
2168{
2169 const struct unit_type *utype = unit_type_get(punit);
2170 struct unit_class *pclass = unit_class_get(punit);
2171 struct city *pcity = tile_city(unit_tile(punit));
2172 int gain;
2173
2174 if (!punit->moved) {
2175 gain = hp_gain_coord(punit);
2176 } else {
2177 gain = 0;
2178 }
2179
2180 gain += get_unit_bonus(punit, EFT_UNIT_RECOVER);
2181
2182 if (!punit->homecity && 0 < game.server.killunhomed
2183 && !unit_has_type_flag(punit, UTYF_GAMELOSS)) {
2184 /* Hit point loss of units without homecity; at least 1 hp! */
2185 /* Gameloss units are immune to this effect. */
2186 int hp_loss = MAX(utype->hp * game.server.killunhomed / 100, 1);
2187
2188 if (gain > hp_loss) {
2189 gain = -1;
2190 } else {
2191 gain -= hp_loss;
2192 }
2193 }
2194
2195 if (pcity == NULL && !tile_has_native_base(unit_tile(punit), utype)
2196 && !unit_transported(punit)) {
2197 gain -= utype->hp * pclass->hp_loss_pct / 100;
2198 }
2199
2200 if (punit->hp + gain > utype->hp) {
2201 gain = utype->hp - punit->hp;
2202 } else if (punit->hp + gain < 0) {
2203 gain = -punit->hp;
2204 }
2205
2206 return gain;
2207}
2208
2209/**********************************************************************/
2212bool is_losing_hp(const struct unit *punit)
2213{
2214 const struct unit_type *punittype = unit_type_get(punit);
2215
2216 return get_unit_bonus(punit, EFT_UNIT_RECOVER)
2217 < (punittype->hp *
2218 utype_class(punittype)->hp_loss_pct / 100);
2219}
2220
2221/**********************************************************************/
2224bool unit_type_is_losing_hp(const struct player *pplayer,
2225 const struct unit_type *punittype)
2226{
2227 return get_unittype_bonus(pplayer, NULL, punittype, NULL,
2228 EFT_UNIT_RECOVER)
2229 < (punittype->hp *
2230 utype_class(punittype)->hp_loss_pct / 100);
2231}
2232
2233/**********************************************************************/
2237bool unit_is_alive(int id)
2238{
2239 /* Check if unit exist in game */
2240 if (game_unit_by_number(id)) {
2241 return TRUE;
2242 }
2243
2244 return FALSE;
2245}
2246
2247/**********************************************************************/
2254bool unit_is_virtual(const struct unit *punit)
2255{
2256 if (!punit) {
2257 return FALSE;
2258 }
2259
2260 return punit != game_unit_by_number(punit->id);
2261}
2262
2263/**********************************************************************/
2266void *unit_ai_data(const struct unit *punit, const struct ai_type *ai)
2267{
2268 return punit->server.ais[ai_type_number(ai)];
2269}
2270
2271/**********************************************************************/
2274void unit_set_ai_data(struct unit *punit, const struct ai_type *ai,
2275 void *data)
2276{
2277 punit->server.ais[ai_type_number(ai)] = data;
2278}
2279
2280/**********************************************************************/
2288int unit_bribe_cost(struct unit *punit, struct player *briber)
2289{
2290 int cost, default_hp, dist = 0;
2291 struct tile *ptile = unit_tile(punit);
2292
2293 fc_assert_ret_val(punit != NULL, 0);
2294
2295 default_hp = unit_type_get(punit)->hp;
2296 cost = unit_owner(punit)->economic.gold + game.info.base_bribe_cost;
2297
2298 /* Consider the distance to the capital. */
2301 if (is_capital(capital)) {
2302 int tmp = map_distance(capital->tile, ptile);
2303
2304 if (tmp < dist) {
2305 dist = tmp;
2306 }
2307 }
2309
2310 cost /= dist + 2;
2311
2312 /* Consider the build cost. */
2314
2315 /* Rule set specific cost modification */
2316 cost += (cost
2318 &(const struct req_context) {
2319 .player = unit_owner(punit),
2320 .city = game_city_by_number(
2322 ),
2323 .tile = ptile,
2324 .unit = punit,
2325 .unittype = unit_type_get(punit),
2326 },
2327 briber,
2328 EFT_UNIT_BRIBE_COST_PCT))
2329 / 100;
2330
2331 /* Veterans are not cheap. */
2332 {
2333 const struct veteran_level *vlevel
2335
2336 fc_assert_ret_val(vlevel != NULL, 0);
2337 cost = cost * vlevel->power_fact / 100;
2338 if (unit_type_get(punit)->move_rate > 0) {
2340 } else {
2341 cost += cost * vlevel->move_bonus / SINGLE_MOVE;
2342 }
2343 }
2344
2345 /* Cost now contains the basic bribe cost. We now reduce it by:
2346 * bribecost = cost/2 + cost/2 * damage/hp
2347 * = cost/2 * (1 + damage/hp) */
2348 return ((float)cost / 2 * (1.0 + (float)punit->hp / default_hp));
2349}
2350
2351/**********************************************************************/
2354bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
2355{
2356 fc_assert_ret_val(ptrans != NULL, FALSE);
2357 fc_assert_ret_val(pcargo != NULL, FALSE);
2358
2359 fc_assert_ret_val(!unit_list_search(ptrans->transporting, pcargo), FALSE);
2360
2361 if (force || can_unit_load(pcargo, ptrans)) {
2362 pcargo->transporter = ptrans;
2363 unit_list_append(ptrans->transporting, pcargo);
2364
2365 return TRUE;
2366 }
2367
2368 return FALSE;
2369}
2370
2371/**********************************************************************/
2374bool unit_transport_unload(struct unit *pcargo)
2375{
2376 struct unit *ptrans;
2377
2378 fc_assert_ret_val(pcargo != NULL, FALSE);
2379
2380 if (!unit_transported(pcargo)) {
2381 /* 'pcargo' is not transported. */
2382 return FALSE;
2383 }
2384
2385 /* Get the transporter; must not be defined on the client! */
2386 ptrans = unit_transport_get(pcargo);
2387 if (ptrans) {
2388 /* 'pcargo' and 'ptrans' should be on the same tile. */
2389 fc_assert(same_pos(unit_tile(pcargo), unit_tile(ptrans)));
2390
2391#ifndef FREECIV_NDEBUG
2392 bool success =
2393#endif
2394 unit_list_remove(ptrans->transporting, pcargo);
2395
2396 /* It is an error if 'pcargo' can not be removed from the 'ptrans'. */
2397 fc_assert(success);
2398 }
2399
2400 /* For the server (also safe for the client). */
2401 pcargo->transporter = NULL;
2402
2403 return TRUE;
2404}
2405
2406/**********************************************************************/
2409bool unit_transported(const struct unit *pcargo)
2410{
2411 fc_assert_ret_val(pcargo != NULL, FALSE);
2412
2413 /* The unit is transported if a transporter unit is set or, (for the client)
2414 * if the transported_by field is set. */
2415 if (is_server()) {
2416 return unit_transported_server(pcargo);
2417 } else {
2418 return unit_transported_client(pcargo);
2419 }
2420}
2421
2422/**********************************************************************/
2425struct unit *unit_transport_get(const struct unit *pcargo)
2426{
2427 fc_assert_ret_val(pcargo != NULL, NULL);
2428
2429 return pcargo->transporter;
2430}
2431
2432/**********************************************************************/
2435struct unit_list *unit_transport_cargo(const struct unit *ptrans)
2436{
2437 fc_assert_ret_val(ptrans != NULL, NULL);
2438 fc_assert_ret_val(ptrans->transporting != NULL, NULL);
2439
2440 return ptrans->transporting;
2441}
2442
2443/**********************************************************************/
2446static inline bool
2447unit_transport_check_one(const struct unit_type *cargo_utype,
2448 const struct unit_type *trans_utype)
2449{
2450 return (trans_utype != cargo_utype
2451 && !can_unit_type_transport(cargo_utype,
2452 utype_class(trans_utype)));
2453}
2454
2455/**********************************************************************/
2463bool unit_transport_check(const struct unit *pcargo,
2464 const struct unit *ptrans)
2465{
2466 const struct unit_type *cargo_utype = unit_type_get(pcargo);
2467
2468 /* Check 'pcargo' against 'ptrans'. */
2469 if (!unit_transport_check_one(cargo_utype, unit_type_get(ptrans))) {
2470 return FALSE;
2471 }
2472
2473 /* Check 'pcargo' against 'ptrans' parents. */
2474 unit_transports_iterate(ptrans, pparent) {
2475 if (!unit_transport_check_one(cargo_utype, unit_type_get(pparent))) {
2476 return FALSE;
2477 }
2479
2480 /* Check cargo children... */
2481 unit_cargo_iterate(pcargo, pchild) {
2482 cargo_utype = unit_type_get(pchild);
2483
2484 /* ...against 'ptrans'. */
2485 if (!unit_transport_check_one(cargo_utype, unit_type_get(ptrans))) {
2486 return FALSE;
2487 }
2488
2489 /* ...and against 'ptrans' parents. */
2490 unit_transports_iterate(ptrans, pparent) {
2491 if (!unit_transport_check_one(cargo_utype, unit_type_get(pparent))) {
2492 return FALSE;
2493 }
2496
2497 return TRUE;
2498}
2499
2500/**********************************************************************/
2504bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
2505{
2506 unit_transports_iterate(pcargo, plevel) {
2507 if (ptrans == plevel) {
2508 return TRUE;
2509 }
2511 return FALSE;
2512}
2513
2514/**********************************************************************/
2517int unit_cargo_depth(const struct unit *ptrans)
2518{
2519 struct cargo_iter iter;
2520 struct iterator *it;
2521 int depth = 0;
2522
2523 for (it = cargo_iter_init(&iter, ptrans); iterator_valid(it);
2524 iterator_next(it)) {
2525 if (iter.depth > depth) {
2526 depth = iter.depth;
2527 }
2528 }
2529 return depth;
2530}
2531
2532/**********************************************************************/
2535int unit_transport_depth(const struct unit *pcargo)
2536{
2537 int level = 0;
2538
2539 unit_transports_iterate(pcargo, plevel) {
2540 level++;
2542 return level;
2543}
2544
2545/**********************************************************************/
2549{
2550 return sizeof(struct cargo_iter);
2551}
2552
2553/**********************************************************************/
2556static void *cargo_iter_get(const struct iterator *it)
2557{
2558 const struct cargo_iter *iter = CARGO_ITER(it);
2559
2560 return unit_list_link_data(iter->links[iter->depth - 1]);
2561}
2562
2563/**********************************************************************/
2566static void cargo_iter_next(struct iterator *it)
2567{
2568 struct cargo_iter *iter = CARGO_ITER(it);
2569 const struct unit_list_link *piter;
2570 const struct unit_list_link *pnext;
2571
2572 /* Variant 1: unit has cargo. */
2573 pnext = unit_list_head(unit_transport_cargo(cargo_iter_get(it)));
2574 if (NULL != pnext) {
2575 fc_assert(iter->depth < ARRAY_SIZE(iter->links));
2576 iter->links[iter->depth++] = pnext;
2577 return;
2578 }
2579
2580 while (iter->depth > 0) {
2581 piter = iter->links[iter->depth - 1];
2582
2583 /* Variant 2: there are other cargo units at same level. */
2584 pnext = unit_list_link_next(piter);
2585 if (NULL != pnext) {
2586 iter->links[iter->depth - 1] = pnext;
2587 return;
2588 }
2589
2590 /* Variant 3: return to previous level, and do same tests. */
2591 iter->depth--;
2592 }
2593}
2594
2595/**********************************************************************/
2598static bool cargo_iter_valid(const struct iterator *it)
2599{
2600 return (0 < CARGO_ITER(it)->depth);
2601}
2602
2603/**********************************************************************/
2607 const struct unit *ptrans)
2608{
2609 struct iterator *it = ITERATOR(iter);
2610
2611 it->get = cargo_iter_get;
2612 it->next = cargo_iter_next;
2613 it->valid = cargo_iter_valid;
2614 iter->links[0] = unit_list_head(unit_transport_cargo(ptrans));
2615 iter->depth = (NULL != iter->links[0] ? 1 : 0);
2616
2617 return it;
2618}
2619
2620/**********************************************************************/
2623bool unit_is_cityfounder(const struct unit *punit)
2624{
2626}
2627
2628
2629/**********************************************************************/
2632bool unit_order_list_is_sane(const struct civ_map *nmap,
2633 int length, const struct unit_order *orders)
2634{
2635 int i;
2636
2637 for (i = 0; i < length; i++) {
2638 struct action *paction;
2639 struct extra_type *pextra;
2640
2641 if (orders[i].order > ORDER_LAST) {
2642 log_error("invalid order %d at index %d", orders[i].order, i);
2643 return FALSE;
2644 }
2645 switch (orders[i].order) {
2646 case ORDER_MOVE:
2647 case ORDER_ACTION_MOVE:
2648 if (!map_untrusted_dir_is_valid(orders[i].dir)) {
2649 log_error("in order %d, invalid move direction %d.", i, orders[i].dir);
2650 return FALSE;
2651 }
2652 break;
2653 case ORDER_ACTIVITY:
2654 switch (orders[i].activity) {
2655 case ACTIVITY_SENTRY:
2656 if (i != length - 1) {
2657 /* Only allowed as the last order. */
2658 log_error("activity %d is not allowed at index %d.", orders[i].activity,
2659 i);
2660 return FALSE;
2661 }
2662 break;
2663 /* Replaced by action orders */
2664 case ACTIVITY_BASE:
2665 case ACTIVITY_GEN_ROAD:
2666 case ACTIVITY_FALLOUT:
2667 case ACTIVITY_POLLUTION:
2668 case ACTIVITY_PILLAGE:
2669 case ACTIVITY_MINE:
2670 case ACTIVITY_IRRIGATE:
2671 case ACTIVITY_PLANT:
2672 case ACTIVITY_CULTIVATE:
2673 case ACTIVITY_TRANSFORM:
2674 case ACTIVITY_CONVERT:
2675 case ACTIVITY_FORTIFYING:
2676 log_error("at index %d, use action rather than activity %d.",
2677 i, orders[i].activity);
2678 return FALSE;
2679 /* Not supported. */
2680 case ACTIVITY_EXPLORE:
2681 case ACTIVITY_IDLE:
2682 /* Not set from the client. */
2683 case ACTIVITY_GOTO:
2684 case ACTIVITY_FORTIFIED:
2685 /* Compatiblity, used in savegames. */
2686 case ACTIVITY_OLD_ROAD:
2687 case ACTIVITY_OLD_RAILROAD:
2688 case ACTIVITY_FORTRESS:
2689 case ACTIVITY_AIRBASE:
2690 /* Unused. */
2691 case ACTIVITY_PATROL_UNUSED:
2692 case ACTIVITY_LAST:
2693 case ACTIVITY_UNKNOWN:
2694 log_error("at index %d, unsupported activity %d.", i, orders[i].activity);
2695 return FALSE;
2696 }
2697
2698 break;
2700 if (!action_id_exists(orders[i].action)) {
2701 /* Non-existent action. */
2702 log_error("at index %d, the action %d doesn't exist.", i, orders[i].action);
2703 return FALSE;
2704 }
2705
2706 paction = action_by_number(orders[i].action);
2707
2708 /* Validate main target. */
2709 if (index_to_tile(nmap, orders[i].target) == NULL) {
2710 log_error("at index %d, invalid tile target %d for the action %d.",
2711 i, orders[i].target, orders[i].action);
2712 return FALSE;
2713 }
2714
2715 if (orders[i].dir != DIR8_ORIGIN) {
2716 log_error("at index %d, the action %d sets the outdated target"
2717 " specification dir.",
2718 i, orders[i].action);
2719 }
2720
2721 /* Validate sub target. */
2722 switch (action_id_get_sub_target_kind(orders[i].action)) {
2723 case ASTK_BUILDING:
2724 /* Sub target is a building. */
2725 if (!improvement_by_number(orders[i].sub_target)) {
2726 /* Sub target is invalid. */
2727 log_error("at index %d, cannot do %s without a target.", i,
2728 action_id_rule_name(orders[i].action));
2729 return FALSE;
2730 }
2731 break;
2732 case ASTK_TECH:
2733 /* Sub target is a technology. */
2734 if (orders[i].sub_target == A_NONE
2735 || (!valid_advance_by_number(orders[i].sub_target)
2736 && orders[i].sub_target != A_FUTURE)) {
2737 /* Target tech is invalid. */
2738 log_error("at index %d, cannot do %s without a target.", i,
2739 action_id_rule_name(orders[i].action));
2740 return FALSE;
2741 }
2742 break;
2743 case ASTK_EXTRA:
2744 case ASTK_EXTRA_NOT_THERE:
2745 /* Sub target is an extra. */
2746 pextra = (!(orders[i].sub_target == NO_TARGET
2747 || (orders[i].sub_target < 0
2748 || (orders[i].sub_target
2750 ? extra_by_number(orders[i].sub_target) : NULL);
2751 fc_assert(pextra == NULL || !(pextra->ruledit_disabled));
2752 if (pextra == NULL) {
2753 if (paction->target_complexity != ACT_TGT_COMPL_FLEXIBLE) {
2754 /* Target extra is invalid. */
2755 log_error("at index %d, cannot do %s without a target.", i,
2756 action_id_rule_name(orders[i].action));
2757 return FALSE;
2758 }
2759 } else {
2760 if (!(action_removes_extra(paction, pextra)
2761 || action_creates_extra(paction, pextra))) {
2762 /* Target extra is irrelevant for the action. */
2763 log_error("at index %d, cannot do %s to %s.", i,
2764 action_id_rule_name(orders[i].action),
2765 extra_rule_name(pextra));
2766 return FALSE;
2767 }
2768 }
2769 break;
2770 case ASTK_NONE:
2771 /* No validation required. */
2772 break;
2773 /* Invalid action? */
2774 case ASTK_COUNT:
2776 action_id_get_sub_target_kind(orders[i].action) != ASTK_COUNT,
2777 FALSE,
2778 "Bad action %d in order number %d.", orders[i].action, i);
2779 }
2780
2781 /* Some action orders are sane only in the last order. */
2782 if (i != length - 1) {
2783 /* If the unit is dead, */
2784 if (utype_is_consumed_by_action(paction, NULL)
2785 /* or if Freeciv has no idea where the unit will end up after it
2786 * has performed this action, */
2787 || !(utype_is_unmoved_by_action(paction, NULL)
2788 || utype_is_moved_to_tgt_by_action(paction, NULL))
2789 /* or if the unit will end up standing still, */
2790 || action_has_result(paction, ACTRES_FORTIFY)) {
2791 /* than having this action in the middle of a unit's orders is
2792 * probably wrong. */
2793 log_error("action %d is not allowed at index %d.",
2794 orders[i].action, i);
2795 return FALSE;
2796 }
2797 }
2798
2799 /* Don't validate that the target tile really contains a target or
2800 * that the actor player's map think the target tile has one.
2801 * The player may target something from their player map that isn't
2802 * there any more, a target they think is there even if their player
2803 * map doesn't have it, or even a target they assume will be there
2804 * when the unit reaches the target tile.
2805 *
2806 * With that said: The client should probably at least have an
2807 * option to only aim city targeted actions at cities. */
2808
2809 break;
2810 case ORDER_FULL_MP:
2811 break;
2812 case ORDER_LAST:
2813 /* An invalid order. This is handled above. */
2814 break;
2815 }
2816 }
2817
2818 return TRUE;
2819}
2820
2821/**********************************************************************/
2825struct unit_order *create_unit_orders(const struct civ_map *nmap,
2826 int length,
2827 const struct unit_order *orders)
2828{
2829 struct unit_order *unit_orders;
2830
2831 if (!unit_order_list_is_sane(nmap, length, orders)) {
2832 return NULL;
2833 }
2834
2835 unit_orders = fc_malloc(length * sizeof(*(unit_orders)));
2836 memcpy(unit_orders, orders, length * sizeof(*(unit_orders)));
2837
2838 return unit_orders;
2839}
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:488
#define action_id_get_sub_target_kind(act_id)
Definition actions.h:659
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define action_has_result(_act_, _res_)
Definition actions.h:448
#define action_by_result_iterate_end
Definition actions.h:492
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:973
bool can_exist_at_tile(const struct civ_map *nmap, const struct unit_type *utype, const struct tile *ptile)
Definition movement.c:275
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:304
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:316
bool can_unit_transport(const struct unit *transporter, const struct unit *transported)
Definition movement.c:813
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:476
bool is_native_near_tile(const struct civ_map *nmap, const struct unit_class *uclass, const struct tile *ptile)
Definition movement.c:450
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:826
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:390
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
@ TILE_KNOWN_SEEN
Definition tile.h:37
#define ACTIVITY_FACTOR
Definition tile.h:164
#define tile_terrain(_tile)
Definition tile.h:109
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
#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:348
size_t cargo_iter_sizeof(void)
Definition unit.c:2548
Activity_type_id real_activities[ACTIVITY_LAST]
Definition unit.c:44
bool is_real_activity(enum unit_activity activity)
Definition unit.c:609
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:924
bool is_tile_activity(enum unit_activity activity)
Definition unit.c:1606
struct unit_order * create_unit_orders(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2825
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:1940
bool unit_type_really_ignores_zoc(const struct unit_type *punittype)
Definition unit.c:1510
bool unit_type_is_losing_hp(const struct player *pplayer, const struct unit_type *punittype)
Definition unit.c:2224
bool is_terrain_change_activity(enum unit_activity activity)
Definition unit.c:1591
struct unit * tile_non_allied_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1332
int unit_shield_value(const struct unit *punit, const struct unit_type *punittype, const struct action *paction)
Definition unit.c:216
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1767
static void cargo_iter_next(struct iterator *it)
Definition unit.c:2566
bool can_unit_change_homecity_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pcity)
Definition unit.c:444
void free_unit_orders(struct unit *punit)
Definition unit.c:1753
void unit_set_ai_data(struct unit *punit, const struct ai_type *ai, void *data)
Definition unit.c:2274
bool unit_is_alive(int id)
Definition unit.c:2237
bool unit_can_est_trade_route_here(const struct unit *punit)
Definition unit.c:286
bool is_hiding_unit(const struct unit *punit)
Definition unit.c:395
int get_activity_rate_this_turn(const struct unit *punit)
Definition unit.c:505
int unit_pays_mp_for_action(const struct action *paction, const struct unit *punit)
Definition unit.c:2119
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:521
bool is_plr_zoc_client(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Definition unit.c:1472
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2354
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1906
struct iterator * cargo_iter_init(struct cargo_iter *iter, const struct unit *ptrans)
Definition unit.c:2606
enum unit_upgrade_result unit_upgrade_info(const struct civ_map *nmap, const struct unit *punit, char *buf, size_t bufsz)
Definition unit.c:2035
int unit_transport_depth(const struct unit *pcargo)
Definition unit.c:2535
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1107
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2212
bool can_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:744
bool unit_can_add_or_build_city(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:427
struct unit * tile_non_attack_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1365
int hp_gain_coord(const struct unit *punit)
Definition unit.c:2146
bool can_unit_change_homecity(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:460
static void * cargo_iter_get(const struct iterator *it)
Definition unit.c:2556
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1271
bool unit_being_aggressive(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:1524
int get_activity_rate(const struct unit *punit)
Definition unit.c:474
bool unit_transport_check(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2463
bool is_attack_unit(const struct unit *punit)
Definition unit.c:307
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:188
const Activity_type_id tile_changing_activities[]
Definition unit.c:46
void setup_real_activities_array(void)
Definition unit.c:591
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2425
bool unit_transport_unload(struct unit *pcargo)
Definition unit.c:2374
bool is_build_activity(enum unit_activity activity)
Definition unit.c:1560
bool unit_contained_in(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2504
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2167
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:83
bool is_military_unit(const struct unit *punit)
Definition unit.c:319
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:845
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2288
void unit_upkeep_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1257
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:719
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2623
bool is_unit_activity_on_tile(enum unit_activity activity, const struct tile *ptile)
Definition unit.c:1142
bool can_unit_do_autosettlers(const struct unit *punit)
Definition unit.c:583
bool is_field_unit(const struct unit *punit)
Definition unit.c:383
static bool cargo_iter_valid(const struct iterator *it)
Definition unit.c:2598
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:328
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:338
#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:1124
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1617
int unit_cargo_depth(const struct unit *ptrans)
Definition unit.c:2517
static bool unit_transport_check_one(const struct unit_type *cargo_utype, const struct unit_type *trans_utype)
Definition unit.c:2447
#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:2632
const char * get_activity_text(enum unit_activity activity)
Definition unit.c:625
bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
Definition unit.c:1157
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:299
bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Definition unit.c:1413
bool is_clean_activity(enum unit_activity activity)
Definition unit.c:1576
bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:826
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1174
bool unit_can_help_build_wonder_here(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:260
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:872
struct unit * tile_other_players_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1349
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1713
struct unit * tile_enemy_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1317
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1281
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1972
bool kills_citizen_after_attack(const struct unit *punit)
Definition unit.c:417
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
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:2254
static void set_unit_activity_internal(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1089
bool is_square_threatened(const struct civ_map *nmap, const struct player *pplayer, const struct tile *ptile, bool omniscient)
Definition unit.c:357
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:771
struct unit * unit_occupies_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1386
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Definition unit.c:2435
static bool can_type_transport_units_cargo(const struct unit_type *utype, const struct unit *punit)
Definition unit.c:1916
void * unit_ai_data(const struct unit *punit, const struct ai_type *ai)
Definition unit.c:2266
bool unit_has_orders(const struct unit *punit)
Definition unit.c:204
struct unit * tile_allied_unit(const struct tile *ptile, const struct player *pplayer)
Definition unit.c:1294
struct unit * transporter_for_unit(const struct unit *pcargo)
Definition unit.c:1896
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:1777
bool unit_can_convert(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:2019
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:541
bool could_unit_be_in_transport(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:687
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:911
bool can_unit_alight_or_be_unloaded(const struct civ_map *nmap, const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:796
#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
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