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)
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>
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
)) {
47 } cardinal_adjc_iterate_end
;
49 } extra_type_by_cause_iterate_end
;
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
)) {
68 } extra_type_by_cause_iterate_end
;
73 /****************************************************************************
74 Is tile native to base?
75 ****************************************************************************/
76 bool is_native_tile_to_base(const struct base_type
*pbase
,
77 const struct tile
*ptile
)
79 struct extra_type
*pextra
;
81 pextra
= base_extra_get(pbase
);
83 return are_reqs_active(NULL
, NULL
, NULL
, NULL
, ptile
,
84 NULL
, NULL
, NULL
, NULL
,
85 &pextra
->reqs
, RPT_POSSIBLE
);
88 /****************************************************************************
89 Base provides base flag for unit? Checks if base provides flag and if
90 base is native to unit.
91 ****************************************************************************/
92 bool base_has_flag_for_utype(const struct base_type
*pbase
,
93 enum base_flag_id flag
,
94 const struct unit_type
*punittype
)
96 return base_has_flag(pbase
, flag
)
97 && is_native_extra_to_utype(base_extra_get(pbase
), punittype
);
100 /**************************************************************************
101 Can unit build base to given tile?
102 **************************************************************************/
103 bool base_can_be_built(const struct base_type
*pbase
,
104 const struct tile
*ptile
)
106 if (tile_terrain(ptile
)->base_time
== 0) {
107 /* Bases cannot be built on this terrain. */
111 if (!(base_extra_get(pbase
)->buildable
)) {
112 /* Base type not buildable. */
116 if (tile_has_base(ptile
, pbase
)) {
121 if (tile_city(ptile
) != NULL
&& pbase
->border_sq
>= 0) {
128 /****************************************************************************
129 Tells if player can build base to tile with suitable unit.
130 ****************************************************************************/
131 bool player_can_build_base(const struct base_type
*pbase
,
132 const struct player
*pplayer
,
133 const struct tile
*ptile
)
135 struct extra_type
*pextra
;
137 if (!base_can_be_built(pbase
, ptile
)) {
141 pextra
= base_extra_get(pbase
);
143 return are_reqs_active(pplayer
, tile_owner(ptile
), NULL
, NULL
, ptile
,
144 NULL
, NULL
, NULL
, NULL
,
145 &pextra
->reqs
, RPT_POSSIBLE
);
148 /**************************************************************************
149 Can unit build base to given tile?
150 **************************************************************************/
151 bool can_build_base(const struct unit
*punit
, const struct base_type
*pbase
,
152 const struct tile
*ptile
)
154 struct extra_type
*pextra
;
156 if (!base_can_be_built(pbase
, ptile
)) {
160 pextra
= base_extra_get(pbase
);
162 return are_reqs_active(unit_owner(punit
), tile_owner(ptile
), NULL
, NULL
,
163 ptile
, punit
, unit_type_get(punit
), NULL
, NULL
,
164 &pextra
->reqs
, RPT_CERTAIN
);
167 /****************************************************************************
168 Returns base_type entry for an ID value.
169 ****************************************************************************/
170 struct base_type
*base_by_number(const Base_type_id id
)
172 struct extra_type_list
*bases
;
174 bases
= extra_type_list_by_cause(EC_BASE
);
176 if (bases
== NULL
|| id
< 0 || id
>= extra_type_list_size(bases
)) {
180 return extra_base_get(extra_type_list_get(bases
, id
));
183 /**************************************************************************
184 Return the base index.
185 **************************************************************************/
186 Base_type_id
base_number(const struct base_type
*pbase
)
188 fc_assert_ret_val(NULL
!= pbase
, -1);
189 return pbase
->item_number
;
192 /**************************************************************************
193 Return the base index.
195 Currently same as base_number(), paired with base_count()
196 indicates use as an array index.
197 **************************************************************************/
198 Base_type_id
base_index(const struct base_type
*pbase
)
200 fc_assert_ret_val(NULL
!= pbase
, -1);
203 /* return pbase - base_types; */
204 return base_number(pbase
);
207 /**************************************************************************
208 Return extra that base is.
209 **************************************************************************/
210 struct extra_type
*base_extra_get(const struct base_type
*pbase
)
215 /**************************************************************************
216 Return the number of base_types.
217 **************************************************************************/
218 Base_type_id
base_count(void)
220 return game
.control
.num_base_types
;
223 /****************************************************************************
224 Initialize base_type structures.
225 ****************************************************************************/
226 void base_type_init(struct extra_type
*pextra
, int idx
)
228 struct base_type
*pbase
;
230 pbase
= fc_malloc(sizeof(*pbase
));
232 pextra
->data
.base
= pbase
;
234 pbase
->item_number
= idx
;
235 pbase
->self
= pextra
;
238 /****************************************************************************
239 Free the memory associated with base types
240 ****************************************************************************/
241 void base_types_free(void)
245 /**************************************************************************
246 Get best gui_type base for given parameters
247 **************************************************************************/
248 struct base_type
*get_base_by_gui_type(enum base_gui_type type
,
249 const struct unit
*punit
,
250 const struct tile
*ptile
)
252 extra_type_by_cause_iterate(EC_BASE
, pextra
) {
253 struct base_type
*pbase
= extra_base_get(pextra
);
255 if (type
== pbase
->gui_type
256 && (punit
== NULL
|| can_build_base(punit
, pbase
, ptile
))) {
259 } extra_type_by_cause_iterate_end
;
264 /**************************************************************************
265 Does this base type claim territory?
266 **************************************************************************/
267 bool territory_claiming_base(const struct base_type
*pbase
)
269 return pbase
->border_sq
>= 0;