1 /****************************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
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)
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 ****************************************************************************/
15 #include <fc_config.h>
26 /****************************************************************************
27 Look for a unit with the given ID in the unit list. Returns NULL if none
29 ****************************************************************************/
30 struct unit
*unit_list_find(const struct unit_list
*punitlist
, int unit_id
)
32 unit_list_iterate(punitlist
, punit
) {
33 if (punit
->id
== unit_id
) {
36 } unit_list_iterate_end
;
41 /****************************************************************************
42 Comparison function for unit_list_sort, sorting by ord_map:
43 The indirection is a bit gory:
45 1. cast arg "a" to "ptr to void*" (we're sorting a list of "void*"'s)
46 2. dereference to get the "void*"
47 3. cast that "void*" to a "struct unit*"
49 Only used in server/savegame.c.
50 ****************************************************************************/
51 static int compar_unit_ord_map(const struct unit
*const *ua
,
52 const struct unit
*const *ub
)
54 return (*ua
)->server
.ord_map
- (*ub
)->server
.ord_map
;
57 /****************************************************************************
58 Comparison function for unit_list_sort, sorting by ord_city: see above.
60 Only used in server/savegame.c.
61 ****************************************************************************/
62 static int compar_unit_ord_city(const struct unit
*const *ua
,
63 const struct unit
*const *ub
)
65 return (*ua
)->server
.ord_city
- (*ub
)->server
.ord_city
;
68 /****************************************************************************
69 Sorts the unit list by punit->server.ord_map values.
71 Only used in server/savegame.c.
72 ****************************************************************************/
73 void unit_list_sort_ord_map(struct unit_list
*punitlist
)
75 fc_assert_ret(is_server());
76 unit_list_sort(punitlist
, compar_unit_ord_map
);
79 /****************************************************************************
80 Sorts the unit list by punit->server.ord_city values.
82 Only used in server/savegame.c.
83 ****************************************************************************/
84 void unit_list_sort_ord_city(struct unit_list
*punitlist
)
86 fc_assert_ret(is_server());
87 unit_list_sort(punitlist
, compar_unit_ord_city
);
91 /****************************************************************************
92 Return TRUE if the function returns true for any of the units.
93 ****************************************************************************/
94 bool can_units_do(const struct unit_list
*punits
,
95 bool (can_fn
)(const struct unit
*punit
))
97 unit_list_iterate(punits
, punit
) {
101 } unit_list_iterate_end
;
106 /****************************************************************************
107 Returns TRUE if any of the units can do the activity.
108 ****************************************************************************/
109 bool can_units_do_activity(const struct unit_list
*punits
,
110 enum unit_activity activity
)
112 /* Make sure nobody uses these old activities any more */
113 fc_assert_ret_val(activity
!= ACTIVITY_FORTRESS
114 && activity
!= ACTIVITY_AIRBASE
, FALSE
);
116 unit_list_iterate(punits
, punit
) {
117 if (can_unit_do_activity(punit
, activity
)) {
120 } unit_list_iterate_end
;
125 /****************************************************************************
126 Returns TRUE if any of the units can do the targeted activity.
127 ****************************************************************************/
128 bool can_units_do_activity_targeted(const struct unit_list
*punits
,
129 enum unit_activity activity
,
130 struct extra_type
*pextra
)
132 unit_list_iterate(punits
, punit
) {
133 if (can_unit_do_activity_targeted(punit
, activity
, pextra
)) {
136 } unit_list_iterate_end
;
141 /****************************************************************************
142 Returns TRUE if any of the units can build any road.
143 ****************************************************************************/
144 bool can_units_do_any_road(const struct unit_list
*punits
)
146 unit_list_iterate(punits
, punit
) {
147 extra_type_by_cause_iterate(EC_ROAD
, pextra
) {
148 struct road_type
*proad
= extra_road_get(pextra
);
150 if (can_build_road(proad
, punit
, unit_tile(punit
))) {
153 } extra_type_by_cause_iterate_end
;
154 } unit_list_iterate_end
;
159 /****************************************************************************
160 Returns TRUE if any of the units can build base with given gui_type.
161 ****************************************************************************/
162 bool can_units_do_base_gui(const struct unit_list
*punits
,
163 enum base_gui_type base_gui
)
165 unit_list_iterate(punits
, punit
) {
166 struct base_type
*pbase
= get_base_by_gui_type(base_gui
, punit
,
170 /* Some unit can build base of given gui_type */
173 } unit_list_iterate_end
;
178 /****************************************************************************
179 If has_flag is true, returns true iff any of the units have the flag.
181 If has_flag is false, returns true iff any of the units don't have the
183 ****************************************************************************/
184 bool units_have_type_flag(const struct unit_list
*punits
,
185 enum unit_type_flag_id flag
, bool has_flag
)
187 unit_list_iterate(punits
, punit
) {
188 if (EQ(has_flag
, unit_has_type_flag(punit
, flag
))) {
191 } unit_list_iterate_end
;
196 /****************************************************************************
197 Does the list contain any cityfounder units
198 ****************************************************************************/
199 bool units_contain_cityfounder(const struct unit_list
*punits
)
201 if (game
.scenario
.prevent_new_cities
) {
205 unit_list_iterate(punits
, punit
) {
206 if (EQ(TRUE
, unit_can_do_action(punit
, ACTION_FOUND_CITY
))) {
209 } unit_list_iterate_end
;
214 /**************************************************************************
215 If has_flag is true, returns true iff any of the units are able to do
216 the specified action.
218 If has_flag is false, returns true iff any of the units are unable do
219 the specified action.
220 **************************************************************************/
221 bool units_can_do_action(const struct unit_list
*punits
,
222 int action_id
, bool can_do
)
224 unit_list_iterate(punits
, punit
) {
225 if (EQ(can_do
, unit_can_do_action(punit
, action_id
))) {
228 } unit_list_iterate_end
;
233 /****************************************************************************
234 Return TRUE iff any of the units is a transporter that is occupied.
235 ****************************************************************************/
236 bool units_are_occupied(const struct unit_list
*punits
)
238 unit_list_iterate(punits
, punit
) {
239 if (get_transporter_occupancy(punit
) > 0) {
242 } unit_list_iterate_end
;
247 /****************************************************************************
248 Returns TRUE iff any of these units can load.
249 ****************************************************************************/
250 bool units_can_load(const struct unit_list
*punits
)
252 unit_list_iterate(punits
, punit
) {
253 if (unit_can_load(punit
)) {
256 } unit_list_iterate_end
;
261 /****************************************************************************
262 Return TRUE iff any of these units can unload.
263 ****************************************************************************/
264 bool units_can_unload(const struct unit_list
*punits
)
266 unit_list_iterate(punits
, punit
) {
267 if (unit_transported(punit
)
268 && can_unit_unload(punit
, unit_transport_get(punit
))
269 && can_unit_exist_at_tile(&(wld
.map
), punit
, unit_tile(punit
))) {
272 } unit_list_iterate_end
;
277 /****************************************************************************
278 Return TRUE iff any of the units' tiles have the activity running
280 ****************************************************************************/
281 bool units_have_activity_on_tile(const struct unit_list
*punits
,
282 enum unit_activity activity
)
284 unit_list_iterate(punits
, punit
) {
285 if (is_unit_activity_on_tile(activity
, unit_tile(punit
))) {
288 } unit_list_iterate_end
;
293 /****************************************************************************
294 Return TRUE iff any of the units can be upgraded to another unit type
296 ****************************************************************************/
297 bool units_can_upgrade(const struct unit_list
*punits
)
299 unit_list_iterate(punits
, punit
) {
300 if (UU_OK
== unit_upgrade_test(punit
, FALSE
)) {
303 } unit_list_iterate_end
;
308 /****************************************************************************
309 Return TRUE iff any of the units can convert to another unit type
310 ****************************************************************************/
311 bool units_can_convert(const struct unit_list
*punits
)
313 unit_list_iterate(punits
, punit
) {
314 if (unit_can_convert(punit
)) {
317 } unit_list_iterate_end
;