1 /***********************************************************************
2 Freeciv - Copyright (C) 1996-2004 - 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 ***********************************************************************/
14 #ifndef FC__REQUIREMENTS_H
15 #define FC__REQUIREMENTS_H
19 #endif /* __cplusplus */
24 /* Range of requirements.
25 * Used in the network protocol.
26 * Order is important -- wider ranges should come later -- some code
27 * assumes a total order, or tests for e.g. >= REQ_RANGE_PLAYER.
28 * Ranges of similar types should be supersets, for example:
29 * - the set of Adjacent tiles contains the set of CAdjacent tiles,
30 * and both contain the center Local tile (a requirement on the local
31 * tile is also within Adjacent range);
32 * - World contains Alliance contains Player (a requirement we ourselves
33 * have is also within Alliance range). */
34 #define SPECENUM_NAME req_range
35 #define SPECENUM_VALUE0 REQ_RANGE_LOCAL
36 #define SPECENUM_VALUE0NAME "Local"
37 #define SPECENUM_VALUE1 REQ_RANGE_CADJACENT
38 #define SPECENUM_VALUE1NAME "CAdjacent"
39 #define SPECENUM_VALUE2 REQ_RANGE_ADJACENT
40 #define SPECENUM_VALUE2NAME "Adjacent"
41 #define SPECENUM_VALUE3 REQ_RANGE_CITY
42 #define SPECENUM_VALUE3NAME "City"
43 #define SPECENUM_VALUE4 REQ_RANGE_TRADEROUTE
44 #define SPECENUM_VALUE4NAME "Traderoute"
45 #define SPECENUM_VALUE5 REQ_RANGE_CONTINENT
46 #define SPECENUM_VALUE5NAME "Continent"
47 #define SPECENUM_VALUE6 REQ_RANGE_PLAYER
48 #define SPECENUM_VALUE6NAME "Player"
49 #define SPECENUM_VALUE7 REQ_RANGE_TEAM
50 #define SPECENUM_VALUE7NAME "Team"
51 #define SPECENUM_VALUE8 REQ_RANGE_ALLIANCE
52 #define SPECENUM_VALUE8NAME "Alliance"
53 #define SPECENUM_VALUE9 REQ_RANGE_WORLD
54 #define SPECENUM_VALUE9NAME "World"
55 #define SPECENUM_COUNT REQ_RANGE_COUNT /* keep this last */
56 #include "specenum_gen.h"
58 #define req_range_iterate(_range_) \
60 enum req_range _range_; \
61 for (_range_ = REQ_RANGE_LOCAL ; _range_ < REQ_RANGE_COUNT ; \
62 _range_ = (enum req_range)(_range_ + 1)) {
64 #define req_range_iterate_end \
68 /* A requirement. This requirement is basically a conditional; it may or
69 * may not be active on a target. If it is active then something happens.
70 * For instance units and buildings have requirements to be built, techs
71 * have requirements to be researched, and effects have requirements to be
73 * Used in the network protocol. */
75 struct universal source
; /* requirement source */
76 enum req_range range
; /* requirement range */
77 bool survives
; /* set if destroyed sources satisfy the req*/
78 bool present
; /* set if the requirement is to be present */
79 bool quiet
; /* do not list this in helptext */
82 #define SPECVEC_TAG requirement
83 #define SPECVEC_TYPE struct requirement
85 #define requirement_vector_iterate(req_vec, preq) \
86 TYPED_VECTOR_ITERATE(struct requirement, req_vec, preq)
87 #define requirement_vector_iterate_end VECTOR_ITERATE_END
89 /* General requirement functions. */
90 struct requirement
req_from_str(const char *type
, const char *range
,
91 bool survives
, bool present
, bool quiet
,
93 const char *req_to_fstring(const struct requirement
*req
);
95 void req_get_values(const struct requirement
*req
, int *type
,
96 int *range
, bool *survives
, bool *present
, bool *quiet
,
98 struct requirement
req_from_values(int type
, int range
,
99 bool survives
, bool present
, bool quiet
,
102 bool are_requirements_equal(const struct requirement
*req1
,
103 const struct requirement
*req2
);
105 bool are_requirements_contradictions(const struct requirement
*req1
,
106 const struct requirement
*req2
);
108 bool does_req_contradicts_reqs(const struct requirement
*req
,
109 const struct requirement_vector
*vec
);
111 void requirement_vector_contradiction_clean(struct requirement_vector
*vec
);
113 bool is_req_active(const struct player
*target_player
,
114 const struct player
*other_player
,
115 const struct city
*target_city
,
116 const struct impr_type
*target_building
,
117 const struct tile
*target_tile
,
118 const struct unit
*target_unit
,
119 const struct unit_type
*target_unittype
,
120 const struct output_type
*target_output
,
121 const struct specialist
*target_specialist
,
122 const struct action
*target_action
,
123 const struct requirement
*req
,
124 const enum req_problem_type prob_type
);
125 bool are_reqs_active(const struct player
*target_player
,
126 const struct player
*other_player
,
127 const struct city
*target_city
,
128 const struct impr_type
*target_building
,
129 const struct tile
*target_tile
,
130 const struct unit
*target_unit
,
131 const struct unit_type
*target_unittype
,
132 const struct output_type
*target_output
,
133 const struct specialist
*target_specialist
,
134 const struct action
*target_action
,
135 const struct requirement_vector
*reqs
,
136 const enum req_problem_type prob_type
);
138 bool is_req_unchanging(const struct requirement
*req
);
140 bool is_req_in_vec(const struct requirement
*req
,
141 const struct requirement_vector
*vec
);
143 /* General universal functions. */
144 int universal_number(const struct universal
*source
);
146 struct universal
universal_by_number(const enum universals_n kind
,
148 struct universal
universal_by_rule_name(const char *kind
,
150 void universal_value_from_str(struct universal
*source
, const char *value
);
151 void universal_extraction(const struct universal
*source
,
152 int *kind
, int *value
);
154 bool are_universals_equal(const struct universal
*psource1
,
155 const struct universal
*psource2
);
157 const char *universal_rule_name(const struct universal
*psource
);
158 const char *universal_name_translation(const struct universal
*psource
,
159 char *buf
, size_t bufsz
);
160 const char *universal_type_rule_name(const struct universal
*psource
);
162 int universal_build_shield_cost(const struct universal
*target
);
164 void universal_found_functions_init(void);
165 bool universal_fulfills_requirement(bool check_necessary
,
166 const struct requirement_vector
*reqs
,
167 const struct universal
*source
);
168 bool universal_is_relevant_to_requirement(const struct requirement
*req
,
169 const struct universal
*source
);
171 #define universals_iterate(_univ_) \
173 enum universals_n _univ_; \
174 for (_univ_ = VUT_NONE; _univ_ < VUT_COUNT; _univ_ = (enum universals_n)(_univ_ + 1)) {
176 #define universals_iterate_end \
180 /* Accessors to determine if a universal fulfills a requirement vector.
181 * When adding an additional accessor, be sure to add the appropriate
182 * item_found function in universal_found_callbacks_init(). */
183 #define requirement_fulfilled_by_government(_gov_, _rqs_) \
184 universal_fulfills_requirement(FALSE, (_rqs_), \
185 &(struct universal){.kind = VUT_GOVERNMENT, .value = {.govern = (_gov_)}})
186 #define requirement_fulfilled_by_nation(_nat_, _rqs_) \
187 universal_fulfills_requirement(FALSE, (_rqs_), \
188 &(struct universal){.kind = VUT_NATION, .value = {.nation = (_nat_)}})
189 #define requirement_fulfilled_by_improvement(_imp_, _rqs_) \
190 universal_fulfills_requirement(FALSE, (_rqs_), \
191 &(struct universal){.kind = VUT_IMPROVEMENT, \
192 .value = {.building = (_imp_)}})
193 #define requirement_fulfilled_by_terrain(_ter_, _rqs_) \
194 universal_fulfills_requirement(FALSE, (_rqs_), \
195 &(struct universal){.kind = VUT_TERRAIN, \
196 .value = {.terrain = (_ter_)}})
197 #define requirement_fulfilled_by_unit_class(_uc_, _rqs_) \
198 universal_fulfills_requirement(FALSE, (_rqs_), \
199 &(struct universal){.kind = VUT_UCLASS, .value = {.uclass = (_uc_)}})
200 #define requirement_fulfilled_by_unit_type(_ut_, _rqs_) \
201 universal_fulfills_requirement(FALSE, (_rqs_), \
202 &(struct universal){.kind = VUT_UTYPE, .value = {.utype = (_ut_)}})
204 #define requirement_needs_improvement(_imp_, _rqs_) \
205 universal_fulfills_requirement(TRUE, (_rqs_), \
206 &(struct universal){.kind = VUT_IMPROVEMENT, \
207 .value = {.building = (_imp_)}})
209 int requirement_kind_ereq(const int value
,
210 const enum req_range range
,
212 const int max_value
);
214 #define requirement_diplrel_ereq(_id_, _range_, _present_) \
215 requirement_kind_ereq(_id_, _range_, _present_, DRO_LAST)
219 #endif /* __cplusplus */
221 #endif /* FC__REQUIREMENTS_H */