webperimental: ally share J.S. Bach's Cathedral.
[freeciv.git] / common / requirements.h
blob545e6bac181e0c021b29ad60ecb850ca91e9c0e6
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)
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 #ifndef FC__REQUIREMENTS_H
15 #define FC__REQUIREMENTS_H
17 #ifdef __cplusplus
18 extern "C" {
19 #endif /* __cplusplus */
21 /* common */
22 #include "fc_types.h"
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_) \
59 { \
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 \
65 } \
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
72 * active.
73 * Used in the network protocol. */
74 struct requirement {
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
84 #include "specvec.h"
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,
92 const char *value);
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,
97 int *value);
98 struct requirement req_from_values(int type, int range,
99 bool survives, bool present, bool quiet,
100 int value);
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,
147 const int value);
148 struct universal universal_by_rule_name(const char *kind,
149 const char *value);
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,
211 const bool present,
212 const int max_value);
214 #define requirement_diplrel_ereq(_id_, _range_, _present_) \
215 requirement_kind_ereq(_id_, _range_, _present_, DRO_LAST)
217 #ifdef __cplusplus
219 #endif /* __cplusplus */
221 #endif /* FC__REQUIREMENTS_H */