Freeciv21
Develop your civilization from humble roots to a global empire
unitlist.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 // utility
13 #include "log.h"
14 
15 // common
16 #include "game.h"
17 #include "movement.h"
18 #include "unitlist.h"
19 
24 struct unit *unit_list_find(const struct unit_list *punitlist, int unit_id)
25 {
26  unit_list_iterate(punitlist, punit)
27  {
28  if (punit->id == unit_id) {
29  return punit;
30  }
31  }
33 
34  return nullptr;
35 }
36 
47 static int compar_unit_ord_map(const struct unit *const *ua,
48  const struct unit *const *ub)
49 {
50  return (*ua)->server.ord_map - (*ub)->server.ord_map;
51 }
52 
58 static int compar_unit_ord_city(const struct unit *const *ua,
59  const struct unit *const *ub)
60 {
61  return (*ua)->server.ord_city - (*ub)->server.ord_city;
62 }
63 
69 void unit_list_sort_ord_map(struct unit_list *punitlist)
70 {
72  unit_list_sort(punitlist, compar_unit_ord_map);
73 }
74 
80 void unit_list_sort_ord_city(struct unit_list *punitlist)
81 {
83  unit_list_sort(punitlist, compar_unit_ord_city);
84 }
85 
89 bool can_units_do(const std::vector<unit *> &units,
90  bool(can_fn)(const struct unit *punit))
91 {
92  for (const auto punit : units) {
93  if (can_fn(punit)) {
94  return true;
95  }
96  }
97 
98  return false;
99 }
100 
104 bool can_units_do_activity(const std::vector<unit *> &units,
105  enum unit_activity activity)
106 {
107  // Make sure nobody uses these old activities any more
109  activity != ACTIVITY_FORTRESS && activity != ACTIVITY_AIRBASE, false);
110 
111  for (const auto punit : units) {
112  if (can_unit_do_activity(punit, activity)) {
113  return true;
114  }
115  }
116 
117  return false;
118 }
119 
123 bool can_units_do_activity_targeted(const std::vector<unit *> &units,
124  enum unit_activity activity,
125  struct extra_type *pextra)
126 {
127  for (const auto punit : units) {
128  if (can_unit_do_activity_targeted(punit, activity, pextra)) {
129  return true;
130  }
131  }
132 
133  return false;
134 }
135 
139 bool can_units_do_any_road(const std::vector<unit *> &units)
140 {
141  for (const auto punit : units) {
142  extra_type_by_cause_iterate(EC_ROAD, pextra)
143  {
144  struct road_type *proad = extra_road_get(pextra);
145 
146  if (can_build_road(proad, punit, unit_tile(punit))) {
147  return true;
148  }
149  }
151  }
152 
153  return false;
154 }
155 
159 bool can_units_do_base_gui(const std::vector<unit *> &units,
160  enum base_gui_type base_gui)
161 {
162  for (const auto punit : units) {
163  struct base_type *pbase =
164  get_base_by_gui_type(base_gui, punit, unit_tile(punit));
165 
166  if (pbase) {
167  // Some unit can build base of given gui_type
168  return true;
169  }
170  }
171 
172  return false;
173 }
174 
181 bool units_have_type_flag(const std::vector<unit *> &units,
182  enum unit_type_flag_id flag, bool has_flag)
183 {
184  for (const auto punit : units) {
185  if (EQ(has_flag, unit_has_type_flag(punit, flag))) {
186  return true;
187  }
188  }
189 
190  return false;
191 }
192 
196 bool units_contain_cityfounder(const std::vector<unit *> &units)
197 {
198  if (game.scenario.prevent_new_cities) {
199  return false;
200  }
201 
202  for (const auto punit : units) {
203  if (EQ(true, unit_can_do_action(punit, ACTION_FOUND_CITY))) {
204  return true;
205  }
206  }
207 
208  return false;
209 }
210 
218 bool units_can_do_action(const std::vector<unit *> &units, action_id act_id,
219  bool can_do)
220 {
221  for (const auto punit : units) {
222  if (EQ(can_do, unit_can_do_action(punit, act_id))) {
223  return true;
224  }
225  }
226 
227  return false;
228 }
229 
233 bool units_are_occupied(const std::vector<unit *> &units)
234 {
235  for (const auto punit : units) {
236  if (get_transporter_occupancy(punit) > 0) {
237  return true;
238  }
239  }
240 
241  return false;
242 }
243 
247 bool units_can_load(const std::vector<unit *> &units)
248 {
249  for (const auto punit : units) {
250  if (unit_can_load(punit)) {
251  return true;
252  }
253  }
254 
255  return false;
256 }
257 
261 bool units_can_unload(const std::vector<unit *> &units)
262 {
263  for (const auto punit : units) {
264  if (unit_transported(punit)
265  && can_unit_unload(punit, unit_transport_get(punit))
266  && can_unit_exist_at_tile(&(wld.map), punit, unit_tile(punit))) {
267  return true;
268  }
269  }
270 
271  return false;
272 }
273 
278 bool units_have_activity_on_tile(const std::vector<unit *> &units,
279  enum unit_activity activity)
280 {
281  for (const auto punit : units) {
282  if (is_unit_activity_on_tile(activity, unit_tile(punit))) {
283  return true;
284  }
285  }
286 
287  return false;
288 }
289 
294 bool units_can_upgrade(const std::vector<unit *> &units)
295 {
296  for (const auto punit : units) {
297  if (UU_OK == unit_upgrade_test(punit, false)) {
298  return true;
299  }
300  }
301 
302  return false;
303 }
304 
308 bool units_can_convert(const std::vector<unit *> &units)
309 {
310  for (const auto punit : units) {
311  if (utype_can_do_action(unit_type_get(punit), ACTION_CONVERT)
312  && unit_can_convert(punit)) {
313  return true;
314  }
315  }
316 
317  return false;
318 }
319 
320 // Return TRUE if any of the units is in city
321 bool any_unit_in_city(const std::vector<unit *> &units)
322 {
323  for (const auto punit : units) {
324  if (tile_city(unit_tile(punit))) {
325  return true;
326  }
327  }
328 
329  return false;
330 }
331 
332 bool units_on_the_same_tile(const std::vector<unit *> &units)
333 {
334  struct tile *ptile = nullptr;
335 
336  for (const auto punit : units) {
337  if (!ptile) {
338  ptile = punit->tile;
339  }
340  if (punit->tile != ptile) {
341  return false;
342  }
343  }
344 
345  return true;
346 }
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Get best gui_type base for given parameters.
Definition: base.cpp:175
#define extra_road_get(_e_)
Definition: extras.h:171
#define extra_type_by_cause_iterate_end
Definition: extras.h:307
#define extra_type_by_cause_iterate(_cause, _extra)
Definition: extras.h:299
int action_id
Definition: fc_types.h:306
struct civ_game game
Definition: game.cpp:47
bool is_server()
Is program type server?
Definition: game.cpp:57
struct world wld
Definition: game.cpp:48
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "exist" at this location.
Definition: movement.cpp:267
bool unit_can_load(const struct unit *punit)
Return whether we can find a suitable transporter for given unit at current location.
Definition: movement.cpp:713
bool can_build_road(struct road_type *proad, const struct unit *punit, const struct tile *ptile)
Tells if unit can build road on tile.
Definition: road.cpp:275
#define EQ(p, q)
Definition: shared.h:65
Definition: base.h:43
struct packet_scenario_info scenario
Definition: game.h:78
Definition: road.h:54
Definition: tile.h:42
struct unit_list * units
Definition: tile.h:50
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
struct civ_map map
Definition: world_object.h:21
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
int get_transporter_occupancy(const struct unit *ptrans)
Return how many units are in the transport.
Definition: unit.cpp:1647
enum unit_upgrade_result unit_upgrade_test(const struct unit *punit, bool is_free)
Tests if the unit could be updated.
Definition: unit.cpp:1826
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
Definition: unit.cpp:2189
bool is_unit_activity_on_tile(enum unit_activity activity, const struct tile *ptile)
Return whether any units on the tile are doing this activity.
Definition: unit.cpp:1046
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Return TRUE iff this unit can do the specified generalized (ruleset defined) action enabler controlle...
Definition: unit.cpp:309
bool unit_can_convert(const struct unit *punit)
Tests if unit can be converted to another type.
Definition: unit.cpp:1877
bool can_unit_do_activity_targeted(const struct unit *punit, enum unit_activity activity, struct extra_type *target)
Return whether the unit can do the targeted activity at its current location.
Definition: unit.cpp:842
bool can_unit_do_activity(const struct unit *punit, enum unit_activity activity)
Return TRUE iff the unit can do the given untargeted activity at its current location.
Definition: unit.cpp:806
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Return TRUE iff the given unit can be unloaded from its current transporter.
Definition: unit.cpp:720
#define unit_tile(_pu)
Definition: unit.h:371
@ UU_OK
Definition: unit.h:49
bool units_can_load(const std::vector< unit * > &units)
Returns TRUE iff any of these units can load.
Definition: unitlist.cpp:247
static int compar_unit_ord_city(const struct unit *const *ua, const struct unit *const *ub)
Comparison function for unit_list_sort, sorting by ord_city: see above.
Definition: unitlist.cpp:58
bool can_units_do_base_gui(const std::vector< unit * > &units, enum base_gui_type base_gui)
Returns TRUE if any of the units can build base with given gui_type.
Definition: unitlist.cpp:159
bool can_units_do_any_road(const std::vector< unit * > &units)
Returns TRUE if any of the units can build any road.
Definition: unitlist.cpp:139
bool units_can_do_action(const std::vector< unit * > &units, action_id act_id, bool can_do)
If has_flag is true, returns true iff any of the units are able to do the specified action.
Definition: unitlist.cpp:218
bool any_unit_in_city(const std::vector< unit * > &units)
Definition: unitlist.cpp:321
bool can_units_do(const std::vector< unit * > &units, bool(can_fn)(const struct unit *punit))
Return TRUE if the function returns true for any of the units.
Definition: unitlist.cpp:89
void unit_list_sort_ord_map(struct unit_list *punitlist)
Sorts the unit list by punit->server.ord_map values.
Definition: unitlist.cpp:69
bool can_units_do_activity_targeted(const std::vector< unit * > &units, enum unit_activity activity, struct extra_type *pextra)
Returns TRUE if any of the units can do the targeted activity.
Definition: unitlist.cpp:123
bool units_are_occupied(const std::vector< unit * > &units)
Return TRUE iff any of the units is a transporter that is occupied.
Definition: unitlist.cpp:233
bool units_can_unload(const std::vector< unit * > &units)
Return TRUE iff any of these units can unload.
Definition: unitlist.cpp:261
static int compar_unit_ord_map(const struct unit *const *ua, const struct unit *const *ub)
Comparison function for unit_list_sort, sorting by ord_map: The indirection is a bit gory: Read from ...
Definition: unitlist.cpp:47
bool units_contain_cityfounder(const std::vector< unit * > &units)
Does the list contain any cityfounder units.
Definition: unitlist.cpp:196
bool can_units_do_activity(const std::vector< unit * > &units, enum unit_activity activity)
Returns TRUE if any of the units can do the activity.
Definition: unitlist.cpp:104
bool units_have_activity_on_tile(const std::vector< unit * > &units, enum unit_activity activity)
Return TRUE iff any of the units' tiles have the activity running on them.
Definition: unitlist.cpp:278
bool units_can_upgrade(const std::vector< unit * > &units)
Return TRUE iff any of the units can be upgraded to another unit type (for money)
Definition: unitlist.cpp:294
bool units_can_convert(const std::vector< unit * > &units)
Return TRUE iff any of the units can convert to another unit type.
Definition: unitlist.cpp:308
bool units_have_type_flag(const std::vector< unit * > &units, enum unit_type_flag_id flag, bool has_flag)
If has_flag is true, returns true iff any of the units have the flag.
Definition: unitlist.cpp:181
struct unit * unit_list_find(const struct unit_list *punitlist, int unit_id)
Look for a unit with the given ID in the unit list.
Definition: unitlist.cpp:24
bool units_on_the_same_tile(const std::vector< unit * > &units)
Definition: unitlist.cpp:332
void unit_list_sort_ord_city(struct unit_list *punitlist)
Sorts the unit list by punit->server.ord_city values.
Definition: unitlist.cpp:80
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Return TRUE iff units of the given type can do the specified generalized (ruleset defined) action ena...
Definition: unittype.cpp:386