Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / unitlist.c
blob05072af186850b8c78b1d593a9a1ad6f9eb345a4
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)
6 any later version.
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 ****************************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "log.h"
21 /* common */
22 #include "game.h"
23 #include "movement.h"
24 #include "unitlist.h"
26 /****************************************************************************
27 Look for a unit with the given ID in the unit list. Returns NULL if none
28 is found.
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) {
34 return punit;
36 } unit_list_iterate_end;
38 return NULL;
41 /****************************************************************************
42 Comparison function for unit_list_sort, sorting by ord_map:
43 The indirection is a bit gory:
44 Read from the right:
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) {
98 if (can_fn(punit)) {
99 return TRUE;
101 } unit_list_iterate_end;
103 return FALSE;
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)) {
118 return TRUE;
120 } unit_list_iterate_end;
122 return FALSE;
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)) {
134 return TRUE;
136 } unit_list_iterate_end;
138 return FALSE;
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))) {
151 return TRUE;
153 } extra_type_by_cause_iterate_end;
154 } unit_list_iterate_end;
156 return FALSE;
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,
167 unit_tile(punit));
169 if (pbase) {
170 /* Some unit can build base of given gui_type */
171 return TRUE;
173 } unit_list_iterate_end;
175 return FALSE;
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
182 flag.
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))) {
189 return TRUE;
191 } unit_list_iterate_end;
193 return FALSE;
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) {
202 return FALSE;
205 unit_list_iterate(punits, punit) {
206 if (EQ(TRUE, unit_can_do_action(punit, ACTION_FOUND_CITY))) {
207 return TRUE;
209 } unit_list_iterate_end;
211 return FALSE;
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))) {
226 return TRUE;
228 } unit_list_iterate_end;
230 return FALSE;
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) {
240 return TRUE;
242 } unit_list_iterate_end;
244 return FALSE;
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)) {
254 return TRUE;
256 } unit_list_iterate_end;
258 return FALSE;
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(punit, unit_tile(punit))) {
270 return TRUE;
272 } unit_list_iterate_end;
274 return FALSE;
277 /****************************************************************************
278 Return TRUE iff any of the units' tiles have the activity running
279 on them.
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))) {
286 return TRUE;
288 } unit_list_iterate_end;
290 return FALSE;
293 /****************************************************************************
294 Return TRUE iff any of the units can be upgraded to another unit type
295 (for money)
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)) {
301 return TRUE;
303 } unit_list_iterate_end;
305 return FALSE;
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)) {
315 return TRUE;
317 } unit_list_iterate_end;
319 return FALSE;