Freeciv-3.4
Loading...
Searching...
No Matches
requirements.h
Go to the documentation of this file.
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.
7
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***********************************************************************/
13
14#ifndef FC__REQUIREMENTS_H
15#define FC__REQUIREMENTS_H
16
17#ifdef __cplusplus
18extern "C" {
19#endif /* __cplusplus */
20
21/* common */
22#include "fc_types.h"
23#include "map_types.h"
24
25struct astring;
26
27/* Range of requirements.
28 * Used in the network protocol.
29 * Order is important -- wider ranges should come later -- some code
30 * assumes a total order, or tests for e.g. >= REQ_RANGE_PLAYER.
31 * Ranges of similar types should be supersets, for example:
32 * - the set of Adjacent tiles contains the set of CAdjacent tiles,
33 * and both contain the center Local tile (a requirement on the local
34 * tile is also within Adjacent range);
35 * - World contains Alliance contains Player (a requirement we ourselves
36 * have is also within Alliance range). */
37#define SPECENUM_NAME req_range
38#define SPECENUM_VALUE0 REQ_RANGE_LOCAL
39#define SPECENUM_VALUE0NAME "Local"
40#define SPECENUM_VALUE1 REQ_RANGE_TILE
41#define SPECENUM_VALUE1NAME "Tile"
42#define SPECENUM_VALUE2 REQ_RANGE_CADJACENT
43#define SPECENUM_VALUE2NAME "CAdjacent"
44#define SPECENUM_VALUE3 REQ_RANGE_ADJACENT
45#define SPECENUM_VALUE3NAME "Adjacent"
46#define SPECENUM_VALUE4 REQ_RANGE_CITY
47#define SPECENUM_VALUE4NAME "City"
48#define SPECENUM_VALUE5 REQ_RANGE_TRADE_ROUTE
49/* FIXME: -> "Trade Route" */
50#define SPECENUM_VALUE5NAME "Traderoute"
51#define SPECENUM_VALUE6 REQ_RANGE_CONTINENT
52#define SPECENUM_VALUE6NAME "Continent"
53#define SPECENUM_VALUE7 REQ_RANGE_PLAYER
54#define SPECENUM_VALUE7NAME "Player"
55#define SPECENUM_VALUE8 REQ_RANGE_TEAM
56#define SPECENUM_VALUE8NAME "Team"
57#define SPECENUM_VALUE9 REQ_RANGE_ALLIANCE
58#define SPECENUM_VALUE9NAME "Alliance"
59#define SPECENUM_VALUE10 REQ_RANGE_WORLD
60#define SPECENUM_VALUE10NAME "World"
61#define SPECENUM_COUNT REQ_RANGE_COUNT /* Keep this last */
62#define REQ_RANGE_MAX (REQ_RANGE_COUNT - 1) /* REQ_RANGE_WORLD */
63#include "specenum_gen.h"
64
65#define req_range_iterate(_range_) \
66 { \
67 enum req_range _range_; \
68 for (_range_ = REQ_RANGE_LOCAL ; _range_ < REQ_RANGE_COUNT ; \
69 _range_ = (enum req_range)(_range_ + 1)) {
70
71#define req_range_iterate_end \
72 } \
73 }
74
75/* A requirement. This requirement is basically a conditional; it may or
76 * may not be active on a target. If it is active then something happens.
77 * For instance units and buildings have requirements to be built, techs
78 * have requirements to be researched, and effects have requirements to be
79 * active.
80 * Used in the network protocol. */
82 struct universal source; /* Requirement source */
83 enum req_range range; /* Requirement range */
84 bool survives; /* Set if destroyed sources satisfy the req*/
85 bool present; /* Set if the requirement is to be present */
86 bool quiet; /* Do not list this in helptext */
87};
88
89#define SPECVEC_TAG requirement
90#define SPECVEC_TYPE struct requirement
91#include "specvec.h"
92#define requirement_vector_iterate(req_vec, preq) \
93 TYPED_VECTOR_ITERATE(struct requirement, req_vec, preq)
94#define requirement_vector_iterate_end VECTOR_ITERATE_END
95
96/* A set of targets to evaluate requirements against. Depending on what the
97 * requirements in question are for, most of these entries will usually be
98 * nullptr. For instance, when evaluating the construction requirements for a
99 * building, there is no target unit, specialist etc. */
101 const struct player *player;
102 const struct city *city;
103 const struct tile *tile;
104
105 /* For local-ranged requirements only */
106 const struct unit *unit;
107 const struct unit_type *unittype;
108 const struct impr_type *building;
109 const struct extra_type *extra;
110 const struct output_type *output;
111 const struct specialist *specialist;
112 const struct action *action;
114};
115
117 REQUCH_NO = 0, /* Changes regularly */
118 REQUCH_CTRL, /* Can't be changed by game means as long as target player
119 * is in control of target city or unit */
120 REQUCH_ACT, /* Can't be easily changed by expected player's activity
121 * (without destroying teammates, inducing global warming...) */
122 REQUCH_SCRIPTS, /* May be changed by script callbacks */
123 REQUCH_HACK, /* May be changed by server commands/editor */
124 REQUCH_YES /* Really never changes unless savegame is edited */
126
127/* A callback that may transform kind-specific default unchanging status
128 * to another one (usually higher but not always)
129 * Passing other_context is just not needed for it in any known cases */
130typedef enum req_unchanging_status
131 (*req_unchanging_cond_cb)(const struct civ_map *nmap,
132 enum req_unchanging_status def,
133 const struct req_context *context,
134 const struct requirement *req);
135
136/* req_context-related functions */
137const struct req_context *req_context_empty(void);
138
139void requirements_init(void);
140void requirements_free(void);
141
142/* General requirement functions. */
143struct requirement req_from_str(const char *type, const char *range,
144 bool survives, bool present, bool quiet,
145 const char *value);
146const char *req_to_fstring(const struct requirement *req,
147 struct astring *astr);
148
149void req_get_values(const struct requirement *req, int *type,
150 int *range, bool *survives, bool *present, bool *quiet,
151 int *value);
154 int value);
155
156void req_copy(struct requirement *dst, const struct requirement *src);
157
158bool are_requirements_equal(const struct requirement *req1,
159 const struct requirement *req2);
160
161bool are_requirements_contradictions(const struct requirement *req1,
162 const struct requirement *req2);
163
164bool req_implies_req(const struct requirement *req1,
165 const struct requirement *req2);
166
167struct requirement *
169 const struct requirement_vector *vec);
170bool does_req_contradicts_reqs(const struct requirement *req,
171 const struct requirement_vector *vec);
172
174 const struct req_context *other_context,
175 const struct requirement *req);
176bool is_req_active(const struct req_context *context,
177 const struct req_context *other_context,
178 const struct requirement *req,
179 const enum req_problem_type prob_type);
180bool are_reqs_active(const struct req_context *context,
181 const struct req_context *other_context,
182 const struct requirement_vector *reqs,
183 const enum req_problem_type prob_type);
185 const enum req_range max_range,
186 const struct req_context *context,
187 const struct req_context *other_context,
188 const struct requirement_vector *reqs,
189 const enum req_problem_type prob_type);
190enum fc_tristate
192 const struct req_context *context,
193 const struct req_context *other_context,
194 const struct requirement *req);
195
196/* Type of a callback that tests requirements due to a context
197 * and something else in some manner different from tri_req_active() */
198typedef enum fc_tristate
199 (*req_tester_cb)(const struct req_context *context,
200 const struct req_context *other_context,
201 const struct requirement *req,
202 void *data, int n_data);
203
204enum fc_tristate
206 const struct req_context *other_context,
207 const struct requirement *req,
208 void *data, int n_data);
209enum fc_tristate
211 const struct req_context *other_context,
212 const struct requirement_vector *reqs,
215 void *data, int n_data);
216
219 const struct requirement *req);
222 const struct req_context *other_context,
223 const struct requirement *req,
225
226bool is_req_in_vec(const struct requirement *req,
227 const struct requirement_vector *vec);
228
230 enum universals_n kind);
231
232bool universal_never_there(const struct universal *source);
233bool req_is_impossible_to_fulfill(const struct requirement *req);
235
243typedef signed char req_vec_num_in_item;
244
245/**********************************************************************/
256 const struct requirement_vector *vec);
257
258/********************************************************************/
267typedef struct requirement_vector *
268(*requirement_vector_by_number)(const void *parent_item,
269 req_vec_num_in_item number);
270
271/*********************************************************************/
279typedef const char *(*requirement_vector_namer)(req_vec_num_in_item number);
280
283 const struct requirement_vector *vec);
284struct requirement_vector *
286
287/* Interactive friendly requirement vector change suggestions and
288 * reasoning. */
289#define SPECENUM_NAME req_vec_change_operation
290#define SPECENUM_VALUE0 RVCO_REMOVE
291#define SPECENUM_VALUE0NAME N_("Remove")
292#define SPECENUM_VALUE1 RVCO_APPEND
293#define SPECENUM_VALUE1NAME N_("Append")
294#define SPECENUM_COUNT RVCO_NOOP
295#include "specenum_gen.h"
296
303
305 /* Can't use name_translation because it is MAX_LEN_NAME long and a
306 * description may contain more than one name. */
307 char description[500];
309
312};
313
314const char *req_vec_change_translation(const struct req_vec_change *change,
316
319 const void *parent_item);
320
322 const char *description, ...);
323struct req_vec_problem *
325 const char *description,
326 const char *description_translated);
328
329struct req_vec_problem *
332 const void *parent_item);
333struct req_vec_problem *
336 const void *parent_item);
337struct req_vec_problem *
340 const void *parent_item);
341struct req_vec_problem *
344 const void *parent_item);
345struct req_vec_problem *
348 const void *parent_item);
349
350
351/* General universal functions. */
352int universal_number(const struct universal *source);
353
355 const int value);
357 const char *value);
358void universal_value_from_str(struct universal *source, const char *value);
359void universal_copy(struct universal *dst, const struct universal *src);
360void universal_extraction(const struct universal *source,
361 int *kind, int *value);
362
363bool are_universals_equal(const struct universal *psource1,
364 const struct universal *psource2);
365
366const char *universal_rule_name(const struct universal *psource);
367const char *universal_name_translation(const struct universal *psource,
368 char *buf, size_t bufsz);
369const char *universal_type_rule_name(const struct universal *psource);
370
371int universal_build_shield_cost(const struct city *pcity,
372 const struct universal *target);
373
375 const struct universal *to_replace,
376 const struct universal *replacement);
377
378bool universal_is_legal_in_requirement(const struct universal *univ);
379
380#define universal_is_mentioned_by_requirement(preq, psource) \
381 are_universals_equal(&preq->source, psource)
383 const struct requirement_vector *reqs,
384 const struct universal *psource);
385
386/* An item contradicts, fulfills or is irrelevant to the requirement */
388
392 const struct universal *source);
394 const struct requirement_vector *reqs,
395 const struct universal *source);
397 const struct universal *source);
399 struct universal *unis,
400 size_t n_unis);
402 struct universal *unis,
403 size_t n_unis);
404
405#define universals_iterate(_univ_) \
406 { \
407 enum universals_n _univ_; \
408 for (_univ_ = VUT_NONE; _univ_ < VUT_COUNT; _univ_ = (enum universals_n)(_univ_ + 1)) {
409
410#define universals_iterate_end \
411 } \
412 }
413
414/* Accessors to determine if a universal fulfills a requirement vector.
415 * When adding an additional accessor, be sure to add the appropriate
416 * item_found function in universal_found_functions_init(). */
417/* XXX Some versions of g++ can't cope with the struct literals */
418#define requirement_fulfilled_by_government(_gov_, _rqs_) \
419 universal_fulfills_requirements(FALSE, (_rqs_), \
420 &(struct universal){.kind = VUT_GOVERNMENT, .value = {.govern = (_gov_)}})
421#define requirement_fulfilled_by_nation(_nat_, _rqs_) \
422 universal_fulfills_requirements(FALSE, (_rqs_), \
423 &(struct universal){.kind = VUT_NATION, .value = {.nation = (_nat_)}})
424#define requirement_fulfilled_by_improvement(_imp_, _rqs_) \
425 universal_fulfills_requirements(FALSE, (_rqs_), \
426 &(struct universal){.kind = VUT_IMPROVEMENT, \
427 .value = {.building = (_imp_)}})
428#define requirement_fulfilled_by_terrain(_ter_, _rqs_) \
429 universal_fulfills_requirements(FALSE, (_rqs_), \
430 &(struct universal){.kind = VUT_TERRAIN, \
431 .value = {.terrain = (_ter_)}})
432#define requirement_fulfilled_by_unit_class(_uc_, _rqs_) \
433 universal_fulfills_requirements(FALSE, (_rqs_), \
434 &(struct universal){.kind = VUT_UCLASS, .value = {.uclass = (_uc_)}})
435#define requirement_fulfilled_by_unit_type(_ut_, _rqs_) \
436 universal_fulfills_requirements(FALSE, (_rqs_), \
437 &(struct universal){.kind = VUT_UTYPE, .value = {.utype = (_ut_)}})
438#define requirement_fulfilled_by_extra(_ex_, _rqs_) \
439 universal_fulfills_requirements(FALSE, (_rqs_), \
440 &(struct universal){.kind = VUT_EXTRA, .value = {.extra = (_ex_)}})
441#define requirement_fulfilled_by_output_type(_o_, _rqs_) \
442 universal_fulfills_requirements(FALSE, (_rqs_), \
443 &(struct universal){.kind = VUT_OTYPE, .value = {.outputtype = (_o_)}})
444#define requirement_fulfilled_by_action(_act_, _rqs_) \
445 universal_fulfills_requirements(FALSE, (_rqs_), \
446 &(struct universal){.kind = VUT_ACTION, .value = {.action = (_act_)}})
447
448#define requirement_needs_improvement(_imp_, _rqs_) \
449 universal_fulfills_requirements(TRUE, (_rqs_), \
450 &(struct universal){.kind = VUT_IMPROVEMENT, \
451 .value = {.building = (_imp_)}})
452
453int requirement_kind_ereq(const int value,
454 const enum req_range range,
455 const bool present,
456 const int max_value);
457
458#define requirement_diplrel_ereq(_id_, _range_, _present_) \
459 requirement_kind_ereq(_id_, _range_, _present_, DRO_LAST)
460
461#ifdef __cplusplus
462}
463#endif /* __cplusplus */
464
465#endif /* FC__REQUIREMENTS_H */
char * incite_cost
Definition comments.c:77
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
struct @22::@23 reqs
req_problem_type
Definition fc_types.h:514
static GtkWidget * source
Definition gotodlg.c:58
GType type
Definition repodlgs.c:1313
static const int bufsz
Definition helpdlg.c:70
bool universal_never_there(const struct universal *source)
struct req_vec_problem * req_vec_problem_new(int num_suggested_solutions, const char *description,...)
bool universal_is_relevant_to_requirement(const struct requirement *req, const struct universal *source)
bool is_req_in_vec(const struct requirement *req, const struct requirement_vector *vec)
int universal_build_shield_cost(const struct city *pcity, const struct universal *target)
struct req_vec_problem * req_vec_get_first_contradiction(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
enum fc_tristate(* req_tester_cb)(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, void *data, int n_data)
const struct req_context * req_context_empty(void)
signed char req_vec_num_in_item
req_vec_num_in_item a requirement vectors number in an item.
void universal_extraction(const struct universal *source, int *kind, int *value)
req_vec_num_in_item(* requirement_vector_number)(const void *parent_item, const struct requirement_vector *vec)
const char * req_to_fstring(const struct requirement *req, struct astring *astr)
const char *(* requirement_vector_namer)(req_vec_num_in_item number)
req_vec_num_in_item req_vec_vector_number(const void *parent_item, const struct requirement_vector *vec)
enum fc_tristate tri_req_active(const struct req_context *context, const struct req_context *other_context, const struct requirement *req)
struct requirement_vector * req_vec_by_number(const void *parent_item, req_vec_num_in_item number)
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
enum fc_tristate tri_reqs_cb_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, struct requirement_vector *maybe_reqs, req_tester_cb tester, void *data, int n_data)
bool req_vec_change_apply(const struct req_vec_change *modification, requirement_vector_by_number getter, const void *parent_item)
void universal_copy(struct universal *dst, const struct universal *src)
enum req_unchanging_status(* req_unchanging_cond_cb)(const struct civ_map *nmap, enum req_unchanging_status def, const struct req_context *context, const struct requirement *req)
bool are_requirements_equal(const struct requirement *req1, const struct requirement *req2)
const char * req_vec_change_translation(const struct req_vec_change *change, const requirement_vector_namer namer)
struct requirement req_from_str(const char *type, const char *range, bool survives, bool present, bool quiet, const char *value)
struct req_vec_problem * req_vec_suggest_repair(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
void universal_value_from_str(struct universal *source, const char *value)
void req_get_values(const struct requirement *req, int *type, int *range, bool *survives, bool *present, bool *quiet, int *value)
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
const char * universal_rule_name(const struct universal *psource)
bool universal_replace_in_req_vec(struct requirement_vector *reqs, const struct universal *to_replace, const struct universal *replacement)
bool are_requirements_contradictions(const struct requirement *req1, const struct requirement *req2)
bool is_req_active(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, const enum req_problem_type prob_type)
bool universal_is_legal_in_requirement(const struct universal *univ)
enum fc_tristate default_tester_cb(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, void *data, int n_data)
int requirement_kind_ereq(const int value, const enum req_range range, const bool present, const int max_value)
void req_vec_problem_free(struct req_vec_problem *issue)
bool are_reqs_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
struct req_vec_problem * req_vec_get_first_missing_univ(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
enum req_unchanging_status is_req_preventing(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, enum req_problem_type prob_type)
struct requirement * req_vec_first_contradiction_in_vec(const struct requirement *req, const struct requirement_vector *vec)
struct universal universal_by_number(const enum universals_n kind, const int value)
enum req_item_found universal_fulfills_requirement(const struct requirement *preq, const struct universal *source)
void requirements_free(void)
bool are_reqs_active_ranges(const enum req_range min_range, const enum req_range max_range, const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
bool req_vec_wants_type(const struct requirement_vector *reqs, enum universals_n kind)
struct requirement_vector *(* requirement_vector_by_number)(const void *parent_item, req_vec_num_in_item number)
struct req_vec_problem * req_vec_get_first_redundant_req(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
bool does_req_contradicts_reqs(const struct requirement *req, const struct requirement_vector *vec)
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
struct req_vec_problem * req_vec_problem_new_transl(int num_suggested_solutions, const char *description, const char *description_translated)
enum fc_tristate tri_req_active_turns(int pass, int period, const struct req_context *context, const struct req_context *other_context, const struct requirement *req)
bool universals_say_everything(struct requirement_vector *reqs, struct universal *unis, size_t n_unis)
const char * universal_type_rule_name(const struct universal *psource)
void universal_found_functions_init(void)
int universal_number(const struct universal *source)
bool universal_is_mentioned_by_requirements(const struct requirement_vector *reqs, const struct universal *psource)
bool req_vec_is_impossible_to_fulfill(const struct requirement_vector *reqs)
void requirements_init(void)
bool req_implies_req(const struct requirement *req1, const struct requirement *req2)
void req_copy(struct requirement *dst, const struct requirement *src)
enum req_unchanging_status is_req_unchanging(const struct req_context *context, const struct requirement *req)
req_item_found
@ ITF_NO
@ ITF_YES
@ ITF_NOT_APPLICABLE
bool req_is_impossible_to_fulfill(const struct requirement *req)
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
struct universal universal_by_rule_name(const char *kind, const char *value)
req_unchanging_status
@ REQUCH_ACT
@ REQUCH_NO
@ REQUCH_SCRIPTS
@ REQUCH_YES
@ REQUCH_HACK
@ REQUCH_CTRL
bool universals_mean_unfulfilled(struct requirement_vector *reqs, struct universal *unis, size_t n_unis)
struct req_vec_problem * req_vec_suggest_improvement(const struct requirement_vector *vec, requirement_vector_number get_num, const void *parent_item)
fc_tristate
Definition shared.h:46
Definition city.h:318
const struct impr_type * building
const struct action * action
const struct tile * tile
const struct player * player
enum unit_activity activity
const struct output_type * output
const struct unit_type * unittype
const struct unit * unit
const struct extra_type * extra
const struct city * city
const struct specialist * specialist
req_vec_num_in_item vector_number
enum req_vec_change_operation operation
struct requirement req
char description[500]
char description_translated[500]
struct req_vec_change * suggested_solutions
enum req_range range
struct universal source
Definition tile.h:50
Definition unit.h:140
enum universals_n kind
Definition fc_types.h:595
universals_u value
Definition fc_types.h:594
#define bool
Definition support.h:71