Freeciv21
Develop your civilization from humble roots to a global empire
tech.h
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 #pragma once
14 
15 // utility
16 #include "bitvector.h"
17 #include "shared.h"
18 
19 // common
20 #include "fc_types.h"
21 #include "name_translation.h"
22 #include "requirements.h"
23 
24 /*
25  [kept for amusement and posterity]
26 typedef int Tech_type_id;
27  Above typedef replaces old "enum tech_type_id"; see comments about
28  Unit_type_id in unit.h, since mainly apply here too, except don't
29  use Tech_type_id very widely, and don't use (-1) flag values. (?)
30 */
31 /* [more accurately]
32  * Unlike most other indices, the Tech_type_id is widely used, because it
33  * so frequently passed to packet and scripting. The client menu routines
34  * sometimes add and substract these numbers.
35  */
36 #define A_NONE 0
37 #define A_FIRST 1
38 #define A_LAST (MAX_NUM_ADVANCES + 1) // Used in the network protocol.
39 #define A_FUTURE (A_LAST + 1)
40 #define A_ARRAY_SIZE (A_FUTURE + 1)
41 #define A_UNSET (A_LAST + 2)
42 #define A_UNKNOWN (A_LAST + 3)
43 
44 #define A_NEVER (nullptr)
45 
46 /*
47  A_NONE is the root tech. All players always know this tech. It is
48  used as a flag in various cases where there is no tech-requirement.
49 
50  A_FIRST is the first real tech id value
51 
52  A_UNSET indicates that no tech is selected (for research).
53 
54  A_FUTURE indicates that the player is researching a future tech.
55 
56  A_UNKNOWN may be passed to other players instead of the actual value.
57 
58  A_LAST is a value that is guaranteed to be larger than all
59  actual Tech_type_id values. It is used as a flag value; it can
60  also be used for fixed allocations to ensure ability to hold the
61  full number of techs.
62 
63  A_NEVER is the pointer equivalent replacement for A_LAST flag value.
64 */
65 
66 // Changing these breaks network compatibility.
67 /* If a new flag is added techtools.c:research_tech_lost() should be checked
68  */
69 #define SPECENUM_NAME tech_flag_id
70 // player gets extra tech if rearched first
71 #define SPECENUM_VALUE0 TF_BONUS_TECH
72 /* TRANS: this and following strings are 'tech flags', which may rarely
73  * be presented to the player in ruleset help text */
74 #define SPECENUM_VALUE0NAME N_("Bonus_Tech")
75 // "Settler" unit types can build bridges over rivers
76 #define SPECENUM_VALUE1 TF_BRIDGE
77 #define SPECENUM_VALUE1NAME N_("Bridge")
78 // Player can build air units
79 #define SPECENUM_VALUE2 TF_BUILD_AIRBORNE
80 #define SPECENUM_VALUE2NAME N_("Build_Airborne")
81 // Player can claim ocean tiles non-adjacent to border source
82 #define SPECENUM_VALUE3 TF_CLAIM_OCEAN
83 #define SPECENUM_VALUE3NAME N_("Claim_Ocean")
84 /* Player can claim ocean tiles non-adjacent to border source as long
85  * as source is ocean tile */
86 #define SPECENUM_VALUE4 TF_CLAIM_OCEAN_LIMITED
87 #define SPECENUM_VALUE4NAME N_("Claim_Ocean_Limited")
88 #define SPECENUM_VALUE5 TECH_USER_1
89 #define SPECENUM_VALUE6 TECH_USER_2
90 #define SPECENUM_VALUE7 TECH_USER_3
91 #define SPECENUM_VALUE8 TECH_USER_4
92 #define SPECENUM_VALUE9 TECH_USER_5
93 #define SPECENUM_VALUE10 TECH_USER_6
94 #define SPECENUM_VALUE11 TECH_USER_7
95 #define SPECENUM_VALUE12 TECH_USER_LAST
96 // Keep this last.
97 #define SPECENUM_COUNT TF_COUNT
98 #define SPECENUM_BITVECTOR bv_tech_flags
99 #define SPECENUM_NAMEOVERRIDE
100 #include "specenum_gen.h"
101 
102 #define MAX_NUM_USER_TECH_FLAGS (TECH_USER_LAST - TECH_USER_1 + 1)
103 
104 enum tech_req { AR_ONE = 0, AR_TWO = 1, AR_ROOT = 2, AR_SIZE };
105 
106 struct tech_class {
107  int idx;
108  struct name_translation name;
110  int cost_pct;
111 };
112 
113 struct advance {
115  struct name_translation name;
116  char graphic_str[MAX_LEN_NAME]; // which named sprite to use
117  char graphic_alt[MAX_LEN_NAME]; // alternate icon name
119 
122 
123  /* Required to start researching this tech. For shared research it must
124  * be fulfilled for at least one player that shares the research. */
125  struct requirement_vector research_reqs;
126 
127  bv_tech_flags flags;
129 
130  /*
131  * Message displayed to the first player to get a bonus tech
132  */
134 
135  /* Cost of advance in bulbs. It may be specified in ruleset, or
136  * calculated in techs_precalc_data(). However, this value wouldn't
137  * be right if game.info.tech_cost_style is TECH_COST_CIV1CIV2. */
138  double cost;
139 
140  /*
141  * Number of requirements this technology has _including_
142  * itself. Precalculated at server then send to client.
143  */
144  int num_reqs;
145 };
146 
147 BV_DEFINE(bv_techs, A_LAST);
148 
149 /* General advance/technology accessor functions. */
151 Tech_type_id advance_index(const struct advance *padvance);
152 Tech_type_id advance_number(const struct advance *padvance);
153 
154 struct advance *advance_by_number(const Tech_type_id atype);
155 
156 struct advance *valid_advance(struct advance *padvance);
157 struct advance *valid_advance_by_number(const Tech_type_id atype);
158 
159 struct advance *advance_by_rule_name(const char *name);
160 struct advance *advance_by_translated_name(const char *name);
161 
162 const char *advance_rule_name(const struct advance *padvance);
163 const char *advance_name_translation(const struct advance *padvance);
164 
165 void tech_classes_init();
166 struct tech_class *tech_class_by_number(const int idx);
167 #define tech_class_index(_ptclass_) (_ptclass_)->idx
168 const char *tech_class_name_translation(const struct tech_class *ptclass);
169 const char *tech_class_rule_name(const struct tech_class *ptclass);
170 struct tech_class *tech_class_by_rule_name(const char *name);
171 
172 #define tech_class_iterate(_p) \
173  { \
174  int _i_##_p; \
175  for (_i_##_p = 0; _i_##_p < game.control.num_tech_classes; _i_##_p++) { \
176  struct tech_class *_p = tech_class_by_number(_i_##_p);
177 
178 #define tech_class_iterate_end \
179  } \
180  }
181 
182 #define tech_class_re_active_iterate(_p) \
183  tech_class_iterate(_p) \
184  { \
185  if (!_p->ruledit_disabled) {
186 
187 #define tech_class_re_active_iterate_end \
188  } \
189  } \
190  tech_class_iterate_end;
191 
192 void user_tech_flags_init();
193 void user_tech_flags_free();
194 void set_user_tech_flag_name(enum tech_flag_id id, const char *name,
195  const char *helptxt);
196 const char *tech_flag_helptxt(enum tech_flag_id id);
197 
198 /* General advance/technology flag accessor routines */
199 bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag);
200 
201 // Ancillary routines
203  enum tech_req require);
204 struct advance *advance_requires(const struct advance *padvance,
205  enum tech_req require);
206 
208 
209 bool is_future_tech(Tech_type_id tech);
210 
211 // Initialization
212 void techs_init();
213 void techs_free();
214 
215 void techs_precalc_data();
216 
217 // Iteration
218 
219 /* This iterates over almost all technologies. It includes non-existent
220  * technologies, but not A_FUTURE. */
221 #define advance_index_iterate(_start, _index) \
222  { \
223  Tech_type_id _index = (_start); \
224  for (; _index < advance_count(); _index++) {
225 
226 #define advance_index_iterate_end \
227  } \
228  }
229 
230 const struct advance *advance_array_last();
231 
232 #define advance_iterate(_start, _p) \
233  { \
234  struct advance *_p = advance_by_number(_start); \
235  if (nullptr != _p) { \
236  for (; _p <= advance_array_last(); _p++) {
237 
238 #define advance_iterate_end \
239  } \
240  } \
241  }
242 
243 #define advance_re_active_iterate(_p) \
244  advance_iterate(A_FIRST, _p) \
245  { \
246  if (_p->require[AR_ONE] != A_NEVER) {
247 
248 #define advance_re_active_iterate_end \
249  } \
250  } \
251  advance_iterate_end;
252 
253 /* Advance requirements iterator.
254  * Iterates over 'goal' and all its requirements (including root_reqs),
255  * recursively. */
256 struct advance_req_iter;
257 
258 size_t advance_req_iter_sizeof();
260  const struct advance *goal);
261 
262 #define advance_req_iterate(_goal, _padvance) \
263  generic_iterate(struct advance_req_iter, const struct advance *, \
264  _padvance, advance_req_iter_sizeof, \
265  advance_req_iter_init, _goal)
266 #define advance_req_iterate_end generic_iterate_end
267 
268 /* Iterates over all the root requirements of 'goal'.
269  * (Not including 'goal' itself, unless it is the special case of a
270  * self-root-req technology.) */
271 struct advance_root_req_iter;
272 
275  const struct advance *goal);
276 
277 #define advance_root_req_iterate(_goal, _padvance) \
278  generic_iterate(struct advance_root_req_iter, const struct advance *, \
279  _padvance, advance_root_req_iter_sizeof, \
280  advance_root_req_iter_init, _goal)
281 #define advance_root_req_iterate_end generic_iterate_end
int Tech_type_id
Definition: fc_types.h:294
#define MAX_LEN_NAME
Definition: fc_types.h:61
const char * name
Definition: inputfile.cpp:118
Definition: tech.h:113
struct requirement_vector research_reqs
Definition: tech.h:125
struct tech_class * tclass
Definition: tech.h:118
double cost
Definition: tech.h:138
struct advance * require[AR_SIZE]
Definition: tech.h:120
struct name_translation name
Definition: tech.h:115
char * bonus_message
Definition: tech.h:133
bool inherited_root_req
Definition: tech.h:121
bv_tech_flags flags
Definition: tech.h:127
int num_reqs
Definition: tech.h:144
char graphic_str[MAX_LEN_NAME]
Definition: tech.h:116
char graphic_alt[MAX_LEN_NAME]
Definition: tech.h:117
Tech_type_id item_number
Definition: tech.h:114
QVector< QString > * helptext
Definition: tech.h:128
struct name_translation name
Definition: tech.h:108
int cost_pct
Definition: tech.h:110
bool ruledit_disabled
Definition: tech.h:109
int idx
Definition: tech.h:107
struct tech_class * tech_class_by_rule_name(const char *name)
Does a linear search of tech_classes[].name.vernacular Returns nullptr when none match.
Definition: tech.cpp:335
struct advance * advance_by_translated_name(const char *name)
Does a linear search of advances[].name.translated Returns nullptr when none match.
Definition: tech.cpp:163
void set_user_tech_flag_name(enum tech_flag_id id, const char *name, const char *helptxt)
Sets user defined name for tech flag.
Definition: tech.cpp:378
bool is_future_tech(Tech_type_id tech)
Is the given tech a future tech.
Definition: tech.cpp:268
const char * tech_class_name_translation(const struct tech_class *ptclass)
Return the (translated) name of the given tech_class You must not free the return pointer.
Definition: tech.cpp:317
struct tech_class * tech_class_by_number(const int idx)
Return the tech_class for the given index.
Definition: tech.cpp:304
struct iterator * advance_req_iter_init(struct advance_req_iter *it, const struct advance *goal)
Initialize an advance requirements iterator.
Definition: tech.cpp:547
struct iterator * advance_root_req_iter_init(struct advance_root_req_iter *it, const struct advance *goal)
Initialize a root requirements iterator.
Definition: tech.cpp:647
void tech_classes_init()
Initialize tech classes.
Definition: tech.cpp:291
bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag)
Return TRUE if the tech has this flag otherwise FALSE.
Definition: tech.cpp:198
struct advance * valid_advance(struct advance *padvance)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:138
struct advance * valid_advance_by_number(const Tech_type_id atype)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:154
struct advance * advance_requires(const struct advance *padvance, enum tech_req require)
Accessor for requirements.
Definition: tech.cpp:122
tech_req
Definition: tech.h:104
@ AR_TWO
Definition: tech.h:104
@ AR_ROOT
Definition: tech.h:104
@ AR_ONE
Definition: tech.h:104
@ AR_SIZE
Definition: tech.h:104
struct advance * advance_by_rule_name(const char *name)
Does a linear search of advances[].name.vernacular Returns nullptr when none match.
Definition: tech.cpp:180
const char * advance_rule_name(const struct advance *padvance)
Return the (untranslated) rule name of the advance/technology.
Definition: tech.cpp:283
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
Definition: tech.cpp:94
const char * tech_class_rule_name(const struct tech_class *ptclass)
Return the (untranslated) rule name of tech_class You must not free the return pointer.
Definition: tech.cpp:326
void techs_precalc_data()
Function to precalculate needed data for technologies.
Definition: tech.cpp:207
const char * tech_flag_helptxt(enum tech_flag_id id)
Return the (untranslated) helptxt of the user tech flag.
Definition: tech.cpp:413
Tech_type_id advance_required(const Tech_type_id tech, enum tech_req require)
Accessor for requirements.
Definition: tech.cpp:108
size_t advance_root_req_iter_sizeof()
Return the size of the advance root requirements iterator.
Definition: tech.cpp:567
size_t advance_req_iter_sizeof()
Return the size of the advance requirements iterator.
Definition: tech.cpp:496
Tech_type_id advance_index(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:76
bool techs_have_fixed_costs()
Returns true if the costs for the given technology will stay constant during the game.
Definition: tech.cpp:428
void user_tech_flags_init()
Initialize user tech flags.
Definition: tech.cpp:354
Tech_type_id advance_count()
Return the number of advances/technologies.
Definition: tech.cpp:68
const struct advance * advance_array_last()
Return the last item of advances/technologies.
Definition: tech.cpp:57
void techs_free()
De-allocate resources of all techs.
Definition: tech.cpp:481
void techs_init()
Initialize tech structures.
Definition: tech.cpp:437
#define A_LAST
Definition: tech.h:38
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:85
BV_DEFINE(bv_techs, A_LAST)
const char * advance_name_translation(const struct advance *padvance)
Return the (translated) name of the given advance/technology.
Definition: tech.cpp:274
void user_tech_flags_free()
Frees the memory associated with all user tech flags.
Definition: tech.cpp:366