Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / base.c
blobdce26bb137f23c25f949e2f435a8a502c7835196
1 /****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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 /* common */
19 #include "extras.h"
20 #include "game.h"
21 #include "map.h"
22 #include "tile.h"
23 #include "unit.h"
25 #include "base.h"
27 /****************************************************************************
28 Check if base provides effect
29 ****************************************************************************/
30 bool base_has_flag(const struct base_type *pbase, enum base_flag_id flag)
32 return BV_ISSET(pbase->flags, flag);
35 /****************************************************************************
36 Returns TRUE iff any cardinally adjacent tile contains a base with
37 the given flag (does not check ptile itself)
38 ****************************************************************************/
39 bool is_base_flag_card_near(const struct tile *ptile, enum base_flag_id flag)
41 extra_type_by_cause_iterate(EC_BASE, pextra) {
42 if (base_has_flag(extra_base_get(pextra), flag)) {
43 cardinal_adjc_iterate(ptile, adjc_tile) {
44 if (tile_has_extra(adjc_tile, pextra)) {
45 return TRUE;
47 } cardinal_adjc_iterate_end;
49 } extra_type_by_cause_iterate_end;
51 return FALSE;
54 /****************************************************************************
55 Returns TRUE iff any adjacent tile contains a base with the given flag
56 (does not check ptile itself)
57 ****************************************************************************/
58 bool is_base_flag_near_tile(const struct tile *ptile, enum base_flag_id flag)
60 extra_type_by_cause_iterate(EC_BASE, pextra) {
61 if (base_has_flag(extra_base_get(pextra), flag)) {
62 adjc_iterate(ptile, adjc_tile) {
63 if (tile_has_extra(adjc_tile, pextra)) {
64 return TRUE;
66 } adjc_iterate_end;
68 } extra_type_by_cause_iterate_end;
70 return FALSE;
73 /***************************************************************************
74 Returns TRUE iff the given flag is retired.
76 If a base flag is retired without being replaced by an extra flag before
77 3.0 is released rscompat_req_type_name_3_0() must be updated.
78 ***************************************************************************/
79 bool base_flag_is_retired(enum base_flag_id flag)
81 /* All base flags after BF_RETIRED_NO_STACK_DEATH are retired. */
82 return flag >= BF_RETIRED_NO_STACK_DEATH;
85 /****************************************************************************
86 Is tile native to base?
87 ****************************************************************************/
88 bool is_native_tile_to_base(const struct base_type *pbase,
89 const struct tile *ptile)
91 struct extra_type *pextra;
93 pextra = base_extra_get(pbase);
95 return are_reqs_active(NULL, NULL, NULL, NULL, ptile,
96 NULL, NULL, NULL, NULL, NULL,
97 &pextra->reqs, RPT_POSSIBLE);
100 /****************************************************************************
101 Base provides base flag for unit? Checks if base provides flag and if
102 base is native to unit.
103 ****************************************************************************/
104 bool base_has_flag_for_utype(const struct base_type *pbase,
105 enum base_flag_id flag,
106 const struct unit_type *punittype)
108 return base_has_flag(pbase, flag)
109 && is_native_extra_to_utype(base_extra_get(pbase), punittype);
112 /**************************************************************************
113 Can unit build base to given tile?
114 **************************************************************************/
115 bool base_can_be_built(const struct base_type *pbase,
116 const struct tile *ptile)
118 if (tile_terrain(ptile)->base_time == 0) {
119 /* Bases cannot be built on this terrain. */
120 return FALSE;
123 if (!(base_extra_get(pbase)->buildable)) {
124 /* Base type not buildable. */
125 return FALSE;
128 if (tile_has_base(ptile, pbase)) {
129 /* Exist already */
130 return FALSE;
133 if (tile_city(ptile) != NULL && pbase->border_sq >= 0) {
134 return FALSE;
137 return TRUE;
140 /****************************************************************************
141 Tells if player can build base to tile with suitable unit.
142 ****************************************************************************/
143 bool player_can_build_base(const struct base_type *pbase,
144 const struct player *pplayer,
145 const struct tile *ptile)
147 struct extra_type *pextra;
149 if (!base_can_be_built(pbase, ptile)) {
150 return FALSE;
153 pextra = base_extra_get(pbase);
155 return are_reqs_active(pplayer, tile_owner(ptile), NULL, NULL, ptile,
156 NULL, NULL, NULL, NULL, NULL,
157 &pextra->reqs, RPT_POSSIBLE);
160 /**************************************************************************
161 Can unit build base to given tile?
162 **************************************************************************/
163 bool can_build_base(const struct unit *punit, const struct base_type *pbase,
164 const struct tile *ptile)
166 struct extra_type *pextra;
168 if (!base_can_be_built(pbase, ptile)) {
169 return FALSE;
172 pextra = base_extra_get(pbase);
174 return are_reqs_active(unit_owner(punit), tile_owner(ptile), NULL, NULL,
175 ptile, punit, unit_type_get(punit), NULL, NULL, NULL,
176 &pextra->reqs, RPT_CERTAIN);
179 /****************************************************************************
180 Returns base_type entry for an ID value.
181 ****************************************************************************/
182 struct base_type *base_by_number(const Base_type_id id)
184 struct extra_type_list *bases;
186 bases = extra_type_list_by_cause(EC_BASE);
188 if (bases == NULL || id < 0 || id >= extra_type_list_size(bases)) {
189 return NULL;
192 return extra_base_get(extra_type_list_get(bases, id));
195 /**************************************************************************
196 Return the base index.
197 **************************************************************************/
198 Base_type_id base_number(const struct base_type *pbase)
200 fc_assert_ret_val(NULL != pbase, -1);
201 return pbase->item_number;
204 /**************************************************************************
205 Return extra that base is.
206 **************************************************************************/
207 struct extra_type *base_extra_get(const struct base_type *pbase)
209 return pbase->self;
212 /**************************************************************************
213 Return the number of base_types.
214 **************************************************************************/
215 Base_type_id base_count(void)
217 return game.control.num_base_types;
220 /****************************************************************************
221 Initialize base_type structures.
222 ****************************************************************************/
223 void base_type_init(struct extra_type *pextra, int idx)
225 struct base_type *pbase;
227 pbase = fc_malloc(sizeof(*pbase));
229 pextra->data.base = pbase;
231 pbase->item_number = idx;
232 pbase->self = pextra;
235 /****************************************************************************
236 Free the memory associated with base types
237 ****************************************************************************/
238 void base_types_free(void)
242 /**************************************************************************
243 Get best gui_type base for given parameters
244 **************************************************************************/
245 struct base_type *get_base_by_gui_type(enum base_gui_type type,
246 const struct unit *punit,
247 const struct tile *ptile)
249 extra_type_by_cause_iterate(EC_BASE, pextra) {
250 struct base_type *pbase = extra_base_get(pextra);
252 if (type == pbase->gui_type
253 && (punit == NULL || can_build_base(punit, pbase, ptile))) {
254 return pbase;
256 } extra_type_by_cause_iterate_end;
258 return NULL;
261 /**************************************************************************
262 Does this base type claim territory?
263 **************************************************************************/
264 bool territory_claiming_base(const struct base_type *pbase)
266 return pbase->border_sq >= 0;