1 /********************************************************************** 2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold 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 #ifndef FC__TECH_H 14 #define FC__TECH_H 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif /* __cplusplus */ 19 20 /* utility */ 21 #include "bitvector.h" 22 #include "shared.h" 23 24 /* common */ 25 #include "fc_types.h" 26 #include "name_translation.h" 27 28 struct strvec; /* Actually defined in "utility/string_vector.h". */ 29 30 /* 31 [kept for amusement and posterity] 32 typedef int Tech_type_id; 33 Above typedef replaces old "enum tech_type_id"; see comments about 34 Unit_type_id in unit.h, since mainly apply here too, except don't 35 use Tech_type_id very widely, and don't use (-1) flag values. (?) 36 */ 37 /* [more accurately] 38 * Unlike most other indices, the Tech_type_id is widely used, because it 39 * so frequently passed to packet and scripting. The client menu routines 40 * sometimes add and substract these numbers. 41 */ 42 #define A_NONE 0 43 #define A_FIRST 1 44 #define A_LAST MAX_NUM_ITEMS /* Used in the network protocol. */ 45 #define A_FUTURE (A_LAST + 1) 46 #define A_ARRAY_SIZE (A_FUTURE + 1) 47 #define A_UNSET (A_LAST + 2) 48 #define A_UNKNOWN (A_LAST + 3) 49 50 #define A_NEVER (NULL) 51 52 /* 53 A_NONE is the root tech. All players always know this tech. It is 54 used as a flag in various cases where there is no tech-requirement. 55 56 A_FIRST is the first real tech id value 57 58 A_UNSET indicates that no tech is selected (for research). 59 60 A_FUTURE indicates that the player is researching a future tech. 61 62 A_UNKNOWN may be passed to other players instead of the actual value. 63 64 A_LAST is a value that is guaranteed to be larger than all 65 actual Tech_type_id values. It is used as a flag value; it can 66 also be used for fixed allocations to ensure ability to hold the 67 full number of techs. 68 69 A_NEVER is the pointer equivalent replacement for A_LAST flag value. 70 */ 71 72 /* Changing these breaks network compatibility. */ 73 /* If a new flag is added techtools.c:research_tech_lost() should be checked */ 74 #define SPECENUM_NAME tech_flag_id 75 /* player gets extra tech if rearched first */ 76 #define SPECENUM_VALUE0 TF_BONUS_TECH 77 /* TRANS: this and following strings are 'tech flags', which may rarely 78 * be presented to the player in ruleset help text */ 79 #define SPECENUM_VALUE0NAME N_("Bonus_Tech") 80 /* "Settler" unit types can build bridges over rivers */ 81 #define SPECENUM_VALUE1 TF_BRIDGE 82 #define SPECENUM_VALUE1NAME N_("Bridge") 83 /* Player can build air units */ 84 #define SPECENUM_VALUE2 TF_BUILD_AIRBORNE 85 #define SPECENUM_VALUE2NAME N_("Build_Airborne") 86 /* Player can claim ocean tiles non-adjacent to border source */ 87 #define SPECENUM_VALUE3 TF_CLAIM_OCEAN 88 #define SPECENUM_VALUE3NAME N_("Claim_Ocean") 89 /* Player can claim ocean tiles non-adjacent to border source as long 90 * as source is ocean tile */ 91 #define SPECENUM_VALUE4 TF_CLAIM_OCEAN_LIMITED 92 #define SPECENUM_VALUE4NAME N_("Claim_Ocean_Limited") 93 #define SPECENUM_VALUE5 TECH_USER_1 94 #define SPECENUM_VALUE6 TECH_USER_2 95 #define SPECENUM_VALUE7 TECH_USER_3 96 #define SPECENUM_VALUE8 TECH_USER_4 97 #define SPECENUM_VALUE9 TECH_USER_5 98 #define SPECENUM_VALUE10 TECH_USER_6 99 #define SPECENUM_VALUE11 TECH_USER_7 100 #define SPECENUM_VALUE12 TECH_USER_LAST 101 /* Keep this last. */ 102 #define SPECENUM_COUNT TF_COUNT 103 #define SPECENUM_BITVECTOR bv_tech_flags 104 #define SPECENUM_NAMEOVERRIDE 105 #include "specenum_gen.h" 106 107 #define MAX_NUM_USER_TECH_FLAGS (TECH_USER_LAST - TECH_USER_1 + 1) 108 109 enum tech_req { 110 AR_ONE = 0, 111 AR_TWO = 1, 112 AR_ROOT = 2, 113 AR_SIZE 114 }; 115 116 struct advance { 117 Tech_type_id item_number; 118 struct name_translation name; 119 char graphic_str[MAX_LEN_NAME]; /* which named sprite to use */ 120 char graphic_alt[MAX_LEN_NAME]; /* alternate icon name */ 121 122 struct advance *require[AR_SIZE]; 123 bool inherited_root_req; 124 bv_tech_flags flags; 125 struct strvec *helptext; 126 127 /* 128 * Message displayed to the first player to get a bonus tech 129 */ 130 char *bonus_message; 131 132 /* Cost of advance in bulbs. It may be specified in ruleset, or 133 * calculated in techs_precalc_data(). However, this value wouldn't 134 * be right if game.info.tech_cost_style is TECH_COST_CIV1CIV2. */ 135 double cost; 136 137 /* 138 * Number of requirements this technology has _including_ 139 * itself. Precalculated at server then send to client. 140 */ 141 int num_reqs; 142 }; 143 144 BV_DEFINE(bv_techs, A_LAST); 145 146 /* General advance/technology accessor functions. */ 147 Tech_type_id advance_count(void); 148 Tech_type_id advance_index(const struct advance *padvance); 149 Tech_type_id advance_number(const struct advance *padvance); 150 151 struct advance *advance_by_number(const Tech_type_id atype); 152 153 struct advance *valid_advance(struct advance *padvance); 154 struct advance *valid_advance_by_number(const Tech_type_id atype); 155 156 struct advance *advance_by_rule_name(const char *name); 157 struct advance *advance_by_translated_name(const char *name); 158 159 const char *advance_rule_name(const struct advance *padvance); 160 const char *advance_name_translation(const struct advance *padvance); 161 162 void user_tech_flags_init(void); 163 void user_tech_flags_free(void); 164 void set_user_tech_flag_name(enum tech_flag_id id, const char *name, const char *helptxt); 165 const char *tech_flag_helptxt(enum tech_flag_id id); 166 167 /* General advance/technology flag accessor routines */ 168 bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag); 169 170 /* Ancillary routines */ 171 Tech_type_id advance_required(const Tech_type_id tech, 172 enum tech_req require); 173 struct advance *advance_requires(const struct advance *padvance, 174 enum tech_req require); 175 176 bool techs_have_fixed_costs(void); 177 178 bool is_future_tech(Tech_type_id tech); 179 180 /* Initialization */ 181 void techs_init(void); 182 void techs_free(void); 183 184 void techs_precalc_data(void); 185 186 /* Iteration */ 187 188 /* This iterates over almost all technologies. It includes non-existent 189 * technologies, but not A_FUTURE. */ 190 #define advance_index_iterate(_start, _index) \ 191 { \ 192 Tech_type_id _index = (_start); \ 193 Tech_type_id _aco_##_index = advance_count(); \ 194 for (; _index < _aco_##_index; _index++) { 195 196 #define advance_index_iterate_end \ 197 } \ 198 } 199 200 const struct advance *advance_array_last(void); 201 202 #define advance_iterate(_start, _p) \ 203 { \ 204 struct advance *_p = advance_by_number(_start); \ 205 if (NULL != _p) { \ 206 for (; _p <= advance_array_last(); _p++) { 207 208 #define advance_iterate_end \ 209 } \ 210 } \ 211 } 212 213 #define advance_active_iterate(_p) \ 214 advance_iterate(A_FIRST, _p) { \ 215 if (_p->require[AR_ONE] != A_NEVER) { 216 217 #define advance_active_iterate_end \ 218 } \ 219 } advance_iterate_end; 220 221 222 /* Advance requirements iterator. 223 * Iterates over 'goal' and all its requirements (including root_reqs), 224 * recursively. */ 225 struct advance_req_iter; 226 227 size_t advance_req_iter_sizeof(void); 228 struct iterator *advance_req_iter_init(struct advance_req_iter *it, 229 const struct advance *goal); 230 231 #define advance_req_iterate(_goal, _padvance) \ 232 generic_iterate(struct advance_req_iter, const struct advance *, \ 233 _padvance, advance_req_iter_sizeof, advance_req_iter_init,\ 234 _goal) 235 #define advance_req_iterate_end generic_iterate_end 236 237 /* Iterates over all the root requirements of 'goal'. 238 * (Not including 'goal' itself, unless it is the special case of a 239 * self-root-req technology.) */ 240 struct advance_root_req_iter; 241 242 size_t advance_root_req_iter_sizeof(void); 243 struct iterator *advance_root_req_iter_init(struct advance_root_req_iter *it, 244 const struct advance *goal); 245 246 #define advance_root_req_iterate(_goal, _padvance) \ 247 generic_iterate(struct advance_root_req_iter, const struct advance *, \ 248 _padvance, advance_root_req_iter_sizeof, \ 249 advance_root_req_iter_init, \ 250 _goal) 251 #define advance_root_req_iterate_end generic_iterate_end 252 253 #ifdef __cplusplus 254 } 255 #endif /* __cplusplus */ 256 257 #endif /* FC__TECH_H */ 258