Freeciv21
Develop your civilization from humble roots to a global empire
requirements.h
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 #pragma once
13 
14 // common
15 #include "fc_types.h"
16 
17 /* Range of requirements.
18  * Used in the network protocol.
19  * Order is important -- wider ranges should come later -- some code
20  * assumes a total order, or tests for e.g. >= REQ_RANGE_PLAYER.
21  * Ranges of similar types should be supersets, for example:
22  * - the set of Adjacent tiles contains the set of CAdjacent tiles,
23  * and both contain the center Local tile (a requirement on the local
24  * tile is also within Adjacent range);
25  * - World contains Alliance contains Player (a requirement we ourselves
26  * have is also within Alliance range). */
27 #define SPECENUM_NAME req_range
28 #define SPECENUM_VALUE0 REQ_RANGE_LOCAL
29 #define SPECENUM_VALUE0NAME "Local"
30 #define SPECENUM_VALUE1 REQ_RANGE_CADJACENT
31 #define SPECENUM_VALUE1NAME "CAdjacent"
32 #define SPECENUM_VALUE2 REQ_RANGE_ADJACENT
33 #define SPECENUM_VALUE2NAME "Adjacent"
34 #define SPECENUM_VALUE3 REQ_RANGE_CITY
35 #define SPECENUM_VALUE3NAME "City"
36 #define SPECENUM_VALUE4 REQ_RANGE_TRADEROUTE
37 #define SPECENUM_VALUE4NAME "Traderoute"
38 #define SPECENUM_VALUE5 REQ_RANGE_CONTINENT
39 #define SPECENUM_VALUE5NAME "Continent"
40 #define SPECENUM_VALUE6 REQ_RANGE_PLAYER
41 #define SPECENUM_VALUE6NAME "Player"
42 #define SPECENUM_VALUE7 REQ_RANGE_TEAM
43 #define SPECENUM_VALUE7NAME "Team"
44 #define SPECENUM_VALUE8 REQ_RANGE_ALLIANCE
45 #define SPECENUM_VALUE8NAME "Alliance"
46 #define SPECENUM_VALUE9 REQ_RANGE_WORLD
47 #define SPECENUM_VALUE9NAME "World"
48 #define SPECENUM_COUNT REQ_RANGE_COUNT // keep this last
49 #include "specenum_gen.h"
50 
51 #define req_range_iterate(_range_) \
52  { \
53  enum req_range _range_; \
54  for (_range_ = REQ_RANGE_LOCAL; _range_ < REQ_RANGE_COUNT; \
55  _range_ = (enum req_range)(_range_ + 1)) {
56 
57 #define req_range_iterate_end \
58  } \
59  }
60 
61 /* A requirement. This requirement is basically a conditional; it may or
62  * may not be active on a target. If it is active then something happens.
63  * For instance units and buildings have requirements to be built, techs
64  * have requirements to be researched, and effects have requirements to be
65  * active.
66  * Used in the network protocol. */
67 struct requirement {
68  struct universal source; // requirement source
69  enum req_range range; // requirement range
70  bool survives; /* set if destroyed sources satisfy the req*/
71  bool present; // set if the requirement is to be present
72  bool quiet; // do not list this in helptext
73 };
74 
75 #define SPECVEC_TAG requirement
76 #define SPECVEC_TYPE struct requirement
77 #include "specvec.h"
78 #define requirement_vector_iterate(req_vec, preq) \
79  TYPED_VECTOR_ITERATE(struct requirement, req_vec, preq)
80 #define requirement_vector_iterate_end VECTOR_ITERATE_END
81 
82 // General requirement functions.
83 struct requirement req_from_str(const char *type, const char *range,
84  bool survives, bool present, bool quiet,
85  const char *value);
86 QString req_to_fstring(const struct requirement *req);
87 
88 void req_get_values(const struct requirement *req, int *type, int *range,
89  bool *survives, bool *present, bool *quiet, int *value);
90 struct requirement req_from_values(int type, int range, bool survives,
91  bool present, bool quiet, int value);
92 
93 bool are_requirements_equal(const struct requirement *req1,
94  const struct requirement *req2);
95 
96 bool are_requirements_contradictions(const struct requirement *req1,
97  const struct requirement *req2);
98 
99 bool does_req_contradicts_reqs(const struct requirement *req,
100  const struct requirement_vector *vec);
101 
102 bool is_req_active(
103  const struct player *target_player, const struct player *other_player,
104  const struct city *target_city, const struct impr_type *target_building,
105  const struct tile *target_tile, const struct unit *target_unit,
106  const struct unit_type *target_unittype,
107  const struct output_type *target_output,
108  const struct specialist *target_specialist,
109  const struct action *target_action, const struct requirement *req,
110  const enum req_problem_type prob_type,
111  const enum vision_layer vision_layer = V_COUNT,
112  const enum national_intelligence nintel = NI_COUNT);
113 bool are_reqs_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_vector *reqs,
124  const enum req_problem_type prob_type,
125  const enum vision_layer vision_layer = V_COUNT,
126  const enum national_intelligence nintel = NI_COUNT);
127 
128 bool is_req_unchanging(const struct requirement *req);
129 
130 bool is_req_in_vec(const struct requirement *req,
131  const struct requirement_vector *vec);
132 
133 bool req_vec_wants_type(const struct requirement_vector *reqs,
134  enum universals_n kind);
135 
143 typedef signed char req_vec_num_in_item;
144 
154  const void *parent_item, const struct requirement_vector *vec);
155 
164 typedef struct requirement_vector *(*requirement_vector_by_number)(
165  const void *parent_item, req_vec_num_in_item number);
166 
174 typedef const char *(*requirement_vector_namer)(req_vec_num_in_item number);
175 
177 req_vec_vector_number(const void *parent_item,
178  const struct requirement_vector *vec);
179 
180 /* Interactive friendly requirement vector change suggestions and
181  * reasoning. */
182 #define SPECENUM_NAME req_vec_change_operation
183 #define SPECENUM_VALUE0 RVCO_REMOVE
184 #define SPECENUM_VALUE0NAME N_("Remove")
185 #define SPECENUM_VALUE1 RVCO_APPEND
186 #define SPECENUM_VALUE1NAME N_("Append")
187 #define SPECENUM_COUNT RVCO_NOOP
188 #include "specenum_gen.h"
189 
191  enum req_vec_change_operation operation;
192  struct requirement req;
193 
195 };
196 
198  /* Can't use name_translation because it is MAX_LEN_NAME long and a
199  * description may contain more than one name. */
200  char description[500];
202 
205 };
206 
207 const char *req_vec_change_translation(const struct req_vec_change *change,
208  const requirement_vector_namer namer);
209 
210 bool req_vec_change_apply(const struct req_vec_change *modification,
212  const void *parent_item);
213 
215  const char *description, ...);
216 void req_vec_problem_free(struct req_vec_problem *issue);
217 
218 struct req_vec_problem *
219 req_vec_get_first_contradiction(const struct requirement_vector *vec,
221  const void *parent_item);
222 
223 // General universal functions.
224 int universal_number(const struct universal *source);
225 
226 struct universal universal_by_number(const enum universals_n kind,
227  const int value);
228 struct universal universal_by_rule_name(const char *kind, const char *value);
229 void universal_value_from_str(struct universal *source, const char *value);
230 void universal_extraction(const struct universal *source, int *kind,
231  int *value);
232 
233 bool are_universals_equal(const struct universal *psource1,
234  const struct universal *psource2);
235 
236 const char *universal_rule_name(const struct universal *psource);
237 const char *universal_name_translation(const struct universal *psource,
238  char *buf, size_t bufsz);
239 const char *universal_type_rule_name(const struct universal *psource);
240 
241 int universal_build_shield_cost(const struct city *pcity,
242  const struct universal *target);
243 
244 bool universal_replace_in_req_vec(struct requirement_vector *reqs,
245  const struct universal *to_replace,
246  const struct universal *replacement);
247 
248 #define universal_is_mentioned_by_requirement(preq, psource) \
249  are_universals_equal(&preq->source, psource)
251  const struct requirement_vector *reqs, const struct universal *psource);
252 
253 // An item contradicts, fulfills or is irrelevant to the requirement
255 
257 enum req_item_found
259  const struct universal *source);
260 bool universal_fulfills_requirements(bool check_necessary,
261  const struct requirement_vector *reqs,
262  const struct universal *source);
264  bool check_necessary, const struct requirement_vector *reqs,
265  const struct universal source);
267  const struct universal *source);
268 
269 #define universals_iterate(_univ_) \
270  { \
271  enum universals_n _univ_; \
272  for (_univ_ = VUT_NONE; _univ_ < VUT_COUNT; \
273  _univ_ = (enum universals_n)(_univ_ + 1)) {
274 
275 #define universals_iterate_end \
276  } \
277  }
278 
279 /* Accessors to determine if a universal fulfills a requirement vector.
280  * When adding an additional accessor, be sure to add the appropriate
281  * item_found function in universal_found_functions_init(). */
282 // XXX Some versions of g++ can't cope with the struct literals
283 #define requirement_fulfilled_by_government(_gov_, _rqs_) \
284  sv_universal_fulfills_requirements( \
285  false, (_rqs_), \
286  (struct universal){.value = {.govern = (_gov_)}, \
287  .kind = VUT_GOVERNMENT})
288 #define requirement_fulfilled_by_nation(_nat_, _rqs_) \
289  sv_universal_fulfills_requirements( \
290  false, (_rqs_), \
291  (struct universal){.value = {.nation = (_nat_)}, .kind = VUT_NATION})
292 #define requirement_fulfilled_by_improvement(_imp_, _rqs_) \
293  sv_universal_fulfills_requirements( \
294  false, (_rqs_), \
295  (struct universal){.value = {.building = (_imp_)}, \
296  .kind = VUT_IMPROVEMENT})
297 #define requirement_fulfilled_by_terrain(_ter_, _rqs_) \
298  sv_universal_fulfills_requirements( \
299  false, (_rqs_), \
300  (struct universal){.value = {.terrain = (_ter_)}, \
301  .kind = VUT_TERRAIN})
302 #define requirement_fulfilled_by_unit_class(_uc_, _rqs_) \
303  sv_universal_fulfills_requirements( \
304  false, (_rqs_), \
305  (struct universal){.value = {.uclass = (_uc_)}, .kind = VUT_UCLASS})
306 #define requirement_fulfilled_by_unit_type(_ut_, _rqs_) \
307  sv_universal_fulfills_requirements( \
308  false, (_rqs_), \
309  (struct universal){.value = {.utype = (_ut_)}, .kind = VUT_UTYPE})
310 
311 #define requirement_needs_improvement(_imp_, _rqs_) \
312  sv_universal_fulfills_requirements( \
313  true, (_rqs_), \
314  (struct universal){.value = {.building = (_imp_)}, \
315  .kind = VUT_IMPROVEMENT})
316 
317 int requirement_kind_ereq(const int value, const enum req_range range,
318  const bool present, const int max_value);
319 
320 #define requirement_diplrel_ereq(_id_, _range_, _present_) \
321  requirement_kind_ereq(_id_, _range_, _present_, DRO_LAST)
struct @19::@20 reqs
req_problem_type
Definition: fc_types.h:566
bool universal_is_relevant_to_requirement(const struct requirement *req, const struct universal *source)
Returns TRUE iff the specified universal is relevant to fulfilling the specified requirement.
bool is_req_in_vec(const struct requirement *req, const struct requirement_vector *vec)
Returns TRUE iff the requirement vector vec contains the requirement req.
int universal_build_shield_cost(const struct city *pcity, const struct universal *target)
Return the number of shields it takes to build this universal.
struct req_vec_problem * req_vec_problem_new(int num_suggested_solutions, const char *description,...)
Returns a new requirement vector problem with the specified number of suggested solutions and the spe...
signed char req_vec_num_in_item
req_vec_num_in_item a requirement vectors number in an item.
Definition: requirements.h:143
void universal_extraction(const struct universal *source, int *kind, int *value)
Extract universal structure into its components for serialization; the opposite of universal_by_numbe...
req_vec_num_in_item(* requirement_vector_number)(const void *parent_item, const struct requirement_vector *vec)
Returns the requirement vector number of the specified requirement vector in the specified parent ite...
Definition: requirements.h:153
req_vec_num_in_item req_vec_vector_number(const void *parent_item, const struct requirement_vector *vec)
Returns the requirement vector number of the specified requirement vector in the specified requiremen...
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
Will the universal 'source' fulfill the requirements in the list? If 'check_necessary' is FALSE: are ...
bool sv_universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal source)
Version of universal_fulfills_requirements that takes the universal by value.
bool req_vec_change_apply(const struct req_vec_change *modification, requirement_vector_by_number getter, const void *parent_item)
Returns TRUE iff the specified requirement vector modification was successfully applied to the specif...
bool are_requirements_equal(const struct requirement *req1, const struct requirement *req2)
Returns TRUE if req1 and req2 are equal.
bool is_req_unchanging(const struct requirement *req)
Return TRUE if this is an "unchanging" requirement.
struct req_vec_problem * req_vec_get_first_contradiction(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
Returns the first self contradiction found in the specified requirement vector with suggested solutio...
struct requirement req_from_str(const char *type, const char *range, bool survives, bool present, bool quiet, const char *value)
Parse a requirement type and value string into a requirement structure.
void universal_value_from_str(struct universal *source, const char *value)
Parse requirement value strings into a universal structure.
bool is_req_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement *req, const enum req_problem_type prob_type, const enum vision_layer vision_layer=V_COUNT, const enum national_intelligence nintel=NI_COUNT)
Checks the requirement to see if it is active on the given target.
void req_get_values(const struct requirement *req, int *type, int *range, bool *survives, bool *present, bool *quiet, int *value)
Return the value of a req as a serializable integer.
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
Set the values of a req from serializable integers.
const char * universal_type_rule_name(const struct universal *psource)
Return untranslated name of the universal source name.
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Make user-friendly text for the source.
bool universal_replace_in_req_vec(struct requirement_vector *reqs, const struct universal *to_replace, const struct universal *replacement)
Replaces all instances of the universal to_replace with replacement in the requirement vector reqs an...
QString req_to_fstring(const struct requirement *req)
Returns the given requirement as a formatted string ready for printing.
bool are_requirements_contradictions(const struct requirement *req1, const struct requirement *req2)
Returns TRUE if req1 and req2 contradicts each other.
void universal_found_functions_init()
Initialise universal_found_function array.
int requirement_kind_ereq(const int value, const enum req_range range, const bool present, const int max_value)
Returns (the position of) the given requirement's enumerator in the enumeration of all possible requi...
void req_vec_problem_free(struct req_vec_problem *issue)
De-allocates resources associated with the given requirement vector problem.
struct universal universal_by_number(const enum universals_n kind, const int value)
Combine values into a universal structure.
enum req_item_found universal_fulfills_requirement(const struct requirement *preq, const struct universal *source)
Will the universal 'source' fulfill this requirement?
struct requirement_vector *(* requirement_vector_by_number)(const void *parent_item, req_vec_num_in_item number)
Returns a writable pointer to the specified requirement vector in the specified parent item or nullpt...
Definition: requirements.h:164
bool req_vec_wants_type(const struct requirement_vector *reqs, enum universals_n kind)
Returns TRUE iff the specified requirement vector has a positive requirement of the specified require...
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
Returns TRUE if the given requirement contradicts the given requirement vector.
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
Return TRUE iff the two sources are equivalent.
const char * universal_rule_name(const struct universal *psource)
Return the (untranslated) rule name of the universal.
int universal_number(const struct universal *source)
Return the universal number of the constituent.
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer=V_COUNT, const enum national_intelligence nintel=NI_COUNT)
Checks the requirement(s) to see if they are active on the given target.
bool universal_is_mentioned_by_requirements(const struct requirement_vector *reqs, const struct universal *psource)
Returns TRUE iff the universal 'psource' is directly mentioned by any of the requirements in 'reqs'.
req_item_found
Definition: requirements.h:254
@ ITF_NO
Definition: requirements.h:254
@ ITF_YES
Definition: requirements.h:254
@ ITF_NOT_APPLICABLE
Definition: requirements.h:254
const char *(* requirement_vector_namer)(req_vec_num_in_item number)
Returns the name of the specified requirement vector number in the parent item or nullptr if parent i...
Definition: requirements.h:174
struct universal universal_by_rule_name(const char *kind, const char *value)
Parse requirement type (kind) and value strings into a universal structure.
const char * req_vec_change_translation(const struct req_vec_change *change, const requirement_vector_namer namer)
Returns the specified requirement vector change as a translated string ready for use in the user inte...
Definition: city.h:291
Definition: player.h:231
req_vec_num_in_item vector_number
Definition: requirements.h:194
enum req_vec_change_operation operation
Definition: requirements.h:191
struct requirement req
Definition: requirements.h:192
int num_suggested_solutions
Definition: requirements.h:203
char description[500]
Definition: requirements.h:200
char description_translated[500]
Definition: requirements.h:201
struct req_vec_change * suggested_solutions
Definition: requirements.h:204
enum req_range range
Definition: requirements.h:69
struct universal source
Definition: requirements.h:68
Definition: tile.h:42
Definition: unit.h:134
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739