Freeciv-3.1
Loading...
Searching...
No Matches
aitech.c
Go to the documentation of this file.
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
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <string.h>
19
20/* utility */
21#include "log.h"
22
23/* common */
24#include "game.h"
25#include "government.h"
26#include "player.h"
27#include "research.h"
28#include "tech.h"
29
30/* server */
31#include "plrhand.h"
32#include "srv_log.h"
33#include "techtools.h"
34
35/* server/advisors */
36#include "advdata.h"
37
38/* ai/default */
39#include "aidata.h"
40#include "ailog.h"
41#include "aiplayer.h"
42#include "aitools.h"
43#include "daicity.h"
44#include "daieffects.h"
45
46#include "aitech.h"
47
49 Tech_type_id choice; /* The id of the most needed tech */
50 adv_want want; /* Want of the most needed tech */
51 adv_want current_want; /* Want of the tech which is currently researched
52 * or is our current goal */
53};
54
55/**********************************************************************/
70static void dai_select_tech(struct ai_type *ait,
71 struct player *pplayer,
72 struct ai_tech_choice *choice,
73 struct ai_tech_choice *goal)
74{
75 struct research *presearch = research_get(pplayer);
76 Tech_type_id newtech, newgoal;
77 int num_cities_nonzero = MAX(1, city_list_size(pplayer->cities));
78 int values[MAX(A_ARRAY_SIZE, A_UNSET + 1)];
79 int goal_values[MAX(A_ARRAY_SIZE, A_UNSET + 1)];
80 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
81 size_t acount = advance_count();
82
83 memset(values, 0, sizeof(values));
84 values[A_UNSET] = -1;
85 values[A_NONE] = -1;
86 goal_values[A_UNSET] = -1;
87 goal_values[A_NONE] = -1;
88
89 /* If we are researching future techs, then simply continue with that
90 * when possible. */
91 if (is_future_tech(presearch->researching)) {
92 bool real_found = FALSE;
93
95 if (research_invention_state(presearch, i) == TECH_PREREQS_KNOWN) {
96 real_found = TRUE;
97 break;
98 }
100
101 if (!real_found) {
102 if (choice) {
103 choice->choice = presearch->researching;
104 choice->want = 1;
105 choice->current_want = 1;
106 }
107 if (goal) {
108 goal->choice = A_UNSET;
109 goal->want = 1;
110 goal->current_want = 1;
111 }
112 return;
113 }
114 }
115
116 /* Fill in values for the techs: want of the tech
117 * + average want of those we will discover en route */
120 int steps = research_goal_unknown_techs(presearch, i);
121
122 /* We only want it if we haven't got it (so AI is human after all) */
123 if (steps > 0) {
124 values[i] += plr_data->tech_want[i];
126 if (research_goal_tech_req(presearch, i, k)) {
127 values[k] += plr_data->tech_want[i] / steps;
128 }
130 }
131 }
133
134 /* Fill in the values for the tech goals */
137 int steps = research_goal_unknown_techs(presearch, i);
138
139 if (steps == 0) {
140 /* Can't be set as a goal any more */
141 goal_values[i] = -1;
142 continue;
143 }
144
145 goal_values[i] = values[i];
147 if (research_goal_tech_req(presearch, i, k)) {
148 goal_values[i] += values[k];
149 }
151
152 /* This is the best I could do. It still sometimes does freaky stuff
153 * like setting goal to Republic and learning Monarchy, but that's what
154 * it's supposed to be doing; it just looks strange. -- Syela */
155 goal_values[i] /= steps;
156 if (steps < 6) {
157 log_debug("%s: want = " ADV_WANT_PRINTF ", value = %d, goal_value = %d",
159 plr_data->tech_want[i],
160 values[i], goal_values[i]);
161 }
162 } else {
163 goal_values[i] = -1;
164 }
166
167 newtech = A_UNSET;
168 newgoal = A_UNSET;
171 if (values[i] > values[newtech]
172 && research_invention_gettable(presearch, i, TRUE)) {
173 newtech = i;
174 }
175 if (goal_values[i] > goal_values[newgoal]
176 && research_invention_reachable(presearch, i)) {
177 newgoal = i;
178 }
179 }
181
182#ifdef REALLY_DEBUG_THIS
184 if (values[id] > 0
185 && research_invention_state(presearch, id) == TECH_PREREQS_KNOWN) {
186 TECH_LOG(ait, LOG_DEBUG, pplayer, advance_by_number(id),
187 "turn end want: %d", values[id]);
188 }
190#endif /* REALLY_DEBUG_THIS */
191
192 if (choice) {
193 choice->choice = newtech;
194 choice->want = values[newtech] / num_cities_nonzero;
195 choice->current_want = (values[presearch->researching]
196 / num_cities_nonzero);
197 }
198
199 if (goal) {
200 goal->choice = newgoal;
201 goal->want = goal_values[newgoal] / num_cities_nonzero;
202 goal->current_want = (goal_values[presearch->tech_goal]
203 / num_cities_nonzero);
204 log_debug("Goal->choice = %s, goal->want = " ADV_WANT_PRINTF ", goal_value = %d, "
205 "num_cities_nonzero = %d",
206 research_advance_rule_name(presearch, goal->choice),
207 goal->want,
208 goal_values[newgoal],
209 num_cities_nonzero);
210 }
211
212 /* We can't have this, which will happen in the circumstance
213 * where all ai.tech_wants are negative */
214 if (choice && choice->choice == A_UNSET) {
215 choice->choice = presearch->researching;
216 }
217
218 return;
219}
220
221/**********************************************************************/
225static adv_want dai_tech_base_want(struct ai_type *ait, struct player *pplayer,
226 struct city *pcity, struct advance *padv)
227{
228 struct research *pres = research_get(pplayer);
229 Tech_type_id tech = advance_number(padv);
230 enum tech_state old_state = research_invention_state(pres, tech);
231 struct adv_data *adv = adv_data_get(pplayer, NULL);
232 adv_want orig_want = dai_city_want(pplayer, pcity, adv, NULL);
233 adv_want final_want;
234 bool world_knew = game.info.global_advances[tech];
235 int world_count = game.info.global_advance_count;
236
237 research_invention_set(pres, tech, TECH_KNOWN);
238
239 final_want = dai_city_want(pplayer, pcity, adv, NULL);
240
241 research_invention_set(pres, tech, old_state);
242 game.info.global_advances[tech] = world_knew;
243 game.info.global_advance_count = world_count;
244
245 return final_want - orig_want;
246}
247
248/**********************************************************************/
251static void dai_tech_effect_values(struct ai_type *ait, struct player *pplayer)
252{
253 /* TODO: Currently this duplicates code from daicity.c improvement effect
254 * evaluating almost verbose - refactor so that they can share code. */
255 struct adv_data *adv = adv_data_get(pplayer, NULL);
256 struct ai_plr *aip = def_ai_player_data(pplayer, ait);
257 int turns = 9999; /* TODO: Set to correct value */
258 int nplayers = normal_player_count();
259
260 /* Remove team members from the equation */
261 players_iterate(aplayer) {
262 if (aplayer->team
263 && aplayer->team == pplayer->team
264 && aplayer != pplayer) {
265 nplayers--;
266 }
268
269 advance_iterate(A_FIRST, padv) {
271 != TECH_KNOWN) {
272 struct universal source = { .kind = VUT_ADVANCE, .value.advance = padv };
273
274 city_list_iterate(pplayer->cities, pcity) {
275 adv_want v;
276 adv_want tech_want;
277 bool capital;
278 const struct req_context context = {
279 .player = pplayer,
280 .city = pcity,
281 };
282
283 v = dai_tech_base_want(ait, pplayer, pcity, padv);
284 capital = is_capital(pcity);
285
287 bool present = TRUE;
288 bool active = TRUE;
289
290 requirement_vector_iterate(&peffect->reqs, preq) {
291 /* Check if all the requirements for the currently evaluated effect
292 * are met, except for having the tech that we are evaluating.
293 * TODO: Consider requirements that could be met later. */
294 if (VUT_ADVANCE == preq->source.kind
295 && preq->source.value.advance == padv) {
296 present = preq->present;
297 continue;
298 }
299 if (!is_req_active(&context, NULL, preq, RPT_POSSIBLE)) {
300 active = FALSE;
301 break; /* presence doesn't matter for inactive effects. */
302
303 }
305
306 if (active) {
307 adv_want v1;
308
309 v1 = dai_effect_value(pplayer, adv, pcity, capital,
310 turns, peffect, 1,
311 nplayers);
312
313 if (!present) {
314 /* Tech removes the effect */
315 v -= v1;
316 } else {
317 v += v1;
318 }
319 }
321
322 /* Same conversion factor as in want_tech_for_improvement_effect() */
323 tech_want = v * 14 / 8;
324
325 aip->tech_want[advance_index(padv)] += tech_want;
327 }
329}
330
331/**********************************************************************/
335void dai_manage_tech(struct ai_type *ait, struct player *pplayer)
336{
337 struct ai_tech_choice choice, goal;
338 struct research *research = research_get(pplayer);
339 /* Penalty for switching research */
340 int penalty = (research->got_tech ? 0 : research->bulbs_researched);
341
342 /* Even when we let human to do the final decision, we keep our
343 * wants correctly calculated. Add effect values in */
344 dai_tech_effect_values(ait, pplayer);
345
346 /* If there are humans in our team, they will choose the techs */
348 if (!is_ai(aplayer)) {
349 return;
350 }
352
353 dai_select_tech(ait, pplayer, &choice, &goal);
354 if (choice.choice != research->researching) {
355 /* changing */
356 if (choice.want - choice.current_want > penalty
357 && (penalty + research->bulbs_researched
359 FALSE))) {
360 TECH_LOG(ait, LOG_DEBUG, pplayer, advance_by_number(choice.choice),
361 "new research, was %s, penalty was %d",
363 penalty);
364 choose_tech(research, choice.choice);
365 }
366 }
367
368 /* crossing my fingers on this one! -- Syela (seems to have worked!) */
369 /* It worked, in particular, because the value it sets (research->tech_goal)
370 * is practically never used, see the comment for ai_next_tech_goal */
371 if (goal.choice != research->tech_goal) {
372 log_debug("%s change goal from %s (want=" ADV_WANT_PRINTF
373 ") to %s (want=" ADV_WANT_PRINTF ")",
374 player_name(pplayer),
376 goal.current_want,
378 goal.want);
380 }
381}
382
383/**********************************************************************/
389 const struct civ_map *nmap,
390 struct player *pplayer,
391 struct city *pcity,
392 const struct unit_type *att, int want)
393{
394 struct research *presearch = research_get(pplayer);
395 int best_avl_def = 0;
396 struct unit_type *best_avl = NULL;
397 int best_cost = FC_INFINITY;
398 struct advance *best_tech = A_NEVER;
399 struct unit_type *best_unit = NULL;
400 struct tile *ptile = city_tile(pcity);
401 int def_values[U_LAST];
402 int att_idx = utype_index(att);
403 int defbonus = 100
404 + get_unittype_bonus(pplayer, ptile, att, NULL, EFT_DEFEND_BONUS);
405
406 unit_type_iterate(deftype) {
407 int mp_pct = deftype->cache.defense_mp_bonuses_pct[att_idx] + 100;
408 int scramble = deftype->cache.scramble_coeff[att_idx];
409 int div_bonus_pct = 100 + combat_bonus_against(att->bonuses, deftype,
410 CBONUS_DEFENSE_DIVIDER_PCT)
411 + 100 * combat_bonus_against(att->bonuses, deftype,
412 CBONUS_DEFENSE_DIVIDER);
413 /* Either the unit uses city defense bonus, or scrambles with its own one */
414 int def = deftype->defense_strength
415 * (scramble ? scramble : defbonus * mp_pct) / div_bonus_pct;
416
417 def_values[utype_index(deftype)] = def;
418
419 if (can_city_build_unit_now(nmap, pcity, deftype)) {
420 if (def > best_avl_def) {
421 best_avl_def = def;
422 best_avl = deftype;
423 }
424 }
426
427 unit_type_iterate(deftype) {
428 if (def_values[utype_index(deftype)] > best_avl_def
429 && !can_city_build_unit_now(nmap, pcity, deftype)
430 && can_city_build_unit_later(nmap, pcity, deftype)) {
431 /* It would be better than current best. Consider researching tech */
432 const struct impr_type *building;
433 int cost = 0;
434 struct advance *itech = deftype->require_advance;
435 bool impossible_to_get = FALSE;
436
437 if (A_NEVER != itech
438 && research_invention_state(presearch,
439 advance_number(itech)) != TECH_KNOWN) {
440 /* See if we want to invent this. */
442 advance_number(itech));
443 }
444 if (((building = utype_needs_improvement(deftype, pcity)))
445 && !can_player_build_improvement_direct(pplayer, building)) {
446 const struct req_context context = {
447 .player = pplayer,
448 .city = pcity,
449 .tile = city_tile(pcity),
450 .unittype = deftype,
451 .building = building,
452 };
453
455 if (!is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
456
457 if (VUT_ADVANCE == preq->source.kind && preq->present) {
458 int iimprtech = advance_number(preq->source.value.advance);
459 int imprcost = research_goal_bulbs_required(presearch,
460 iimprtech);
461
462 if (imprcost < cost || cost == 0) {
463 /* If we already have the primary tech (cost == 0),
464 * or the building's tech is cheaper,
465 * go for the building's required tech. */
466 itech = preq->source.value.advance;
467 cost = 0;
468 }
469 cost += imprcost;
470 } else if (!dai_can_requirement_be_met_in_city(preq, pplayer,
471 pcity)) {
472 impossible_to_get = TRUE;
473 }
474 }
476 }
477
478 if (cost < best_cost && !impossible_to_get
479 && research_invention_reachable(presearch, advance_number(itech))) {
480 best_tech = itech;
481 best_cost = cost;
482 best_unit = deftype;
483 }
484 }
486
487 if (A_NEVER != best_tech) {
488 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
489
490 /* Crank up chosen tech want */
491 if (best_avl != NULL
492 && def_values[utype_index(best_unit)] <= 1.5 * best_avl_def) {
493 /* We already have almost as good unit suitable for defending against this attacker */
494 want /= 2;
495 }
496
497 plr_data->tech_want[advance_index(best_tech)] += want;
498 TECH_LOG(ait, LOG_DEBUG, pplayer, best_tech,
499 "+ %d for %s by role",
500 want,
501 utype_rule_name(best_unit));
502 }
503
504 return best_avl;
505}
506
507/**********************************************************************/
513struct unit_type *dai_wants_role_unit(struct ai_type *ait, struct player *pplayer,
514 struct city *pcity, int role, int want)
515{
516 struct research *presearch = research_get(pplayer);
517 int i, n;
518 int best_cost = FC_INFINITY;
519 struct advance *best_tech = A_NEVER;
520 struct unit_type *best_unit = NULL;
521 struct unit_type *build_unit = NULL;
522 const struct civ_map *nmap = &(wld.map);
523
524 n = num_role_units(role);
525 for (i = n - 1; i >= 0; i--) {
526 struct unit_type *iunit = get_role_unit(role, i);
527 struct advance *itech = iunit->require_advance;
528
529 if (can_city_build_unit_now(nmap, pcity, iunit)) {
530 build_unit = iunit;
531 break;
532 } else if (can_city_build_unit_later(nmap, pcity, iunit)) {
533 const struct impr_type *building;
534 int cost = 0;
535
536 if (A_NEVER != itech
537 && research_invention_state(presearch,
538 advance_number(itech)) != TECH_KNOWN) {
539 /* See if we want to invent this. */
541 advance_number(itech));
542 }
543 if (((building = utype_needs_improvement(iunit, pcity)))
544 && !can_player_build_improvement_direct(pplayer, building)) {
545 requirement_vector_iterate(&building->reqs, preq) {
546 if (VUT_ADVANCE == preq->source.kind && preq->present) {
547 int iimprtech = advance_number(preq->source.value.advance);
548
549 if (TECH_KNOWN != research_invention_state(presearch,
550 iimprtech)) {
551 int imprcost = research_goal_bulbs_required(presearch,
552 iimprtech);
553
554 if (imprcost < cost || cost == 0) {
555 /* If we already have the primary tech (cost == 0),
556 * or the building's tech is cheaper,
557 * go for the building's required tech. */
558 itech = preq->source.value.advance;
559 cost = 0;
560 }
561 cost += imprcost;
562 }
563 }
565 }
566
567 if (cost < best_cost
568 && research_invention_reachable(presearch, advance_number(itech))) {
569 best_tech = itech;
570 best_cost = cost;
571 best_unit = iunit;
572 }
573 }
574 }
575
576 if (A_NEVER != best_tech) {
577 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
578
579 /* Crank up chosen tech want */
580 if (build_unit != NULL) {
581 /* We already have a role unit of this kind */
582 want /= 2;
583 }
584 plr_data->tech_want[advance_index(best_tech)] += want;
585 TECH_LOG(ait, LOG_DEBUG, pplayer, best_tech,
586 "+ %d for %s by role",
587 want,
588 utype_rule_name(best_unit));
589 }
590
591 return build_unit;
592}
593
594/**********************************************************************/
597void dai_clear_tech_wants(struct ai_type *ait, struct player *pplayer)
598{
599 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
600
602 plr_data->tech_want[i] = 0;
604}
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:593
#define TECH_LOG(ait, loglevel, pplayer, padvance, msg,...)
Definition ailog.h:36
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition aiplayer.h:54
static adv_want dai_tech_base_want(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct advance *padv)
Definition aitech.c:225
struct unit_type * dai_wants_defender_against(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, const struct unit_type *att, int want)
Definition aitech.c:388
void dai_clear_tech_wants(struct ai_type *ait, struct player *pplayer)
Definition aitech.c:597
void dai_manage_tech(struct ai_type *ait, struct player *pplayer)
Definition aitech.c:335
static void dai_select_tech(struct ai_type *ait, struct player *pplayer, struct ai_tech_choice *choice, struct ai_tech_choice *goal)
Definition aitech.c:70
static void dai_tech_effect_values(struct ai_type *ait, struct player *pplayer)
Definition aitech.c:251
struct unit_type * dai_wants_role_unit(struct ai_type *ait, struct player *pplayer, struct city *pcity, int role, int want)
Definition aitech.c:513
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition aiunit.c:2894
#define n
Definition astring.c:77
bool is_capital(const struct city *pcity)
Definition city.c:1552
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:927
bool can_city_build_unit_later(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:948
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
#define city_list_iterate_end
Definition city.h:490
int combat_bonus_against(const struct combat_bonus_list *list, const struct unit_type *enemy, enum combat_bonus_type type)
Definition combat.c:943
adv_want dai_city_want(struct player *pplayer, struct city *acity, struct adv_data *adv, struct impr_type *pimprove)
Definition daicity.c:1419
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Definition daieffects.c:718
adv_want dai_effect_value(struct player *pplayer, const struct adv_data *adv, const struct city *pcity, const bool capital, int turns, const struct effect *peffect, const int c, const int nplayers)
Definition daieffects.c:138
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 cost
Definition dialogs_g.h:73
struct effect_list * get_req_source_effects(struct universal *psource)
Definition effects.c:146
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:957
#define effect_list_iterate_end
Definition effects.h:375
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
float adv_want
Definition fc_types.h:1206
int Tech_type_id
Definition fc_types.h:347
@ RPT_CERTAIN
Definition fc_types.h:586
@ RPT_POSSIBLE
Definition fc_types.h:585
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
static GtkWidget * source
Definition gotodlg.c:58
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
#define log_debug(message,...)
Definition log.h:115
@ LOG_DEBUG
Definition log.h:34
const char * player_name(const struct player *pplayer)
Definition player.c:886
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
#define is_ai(plr)
Definition player.h:234
int normal_player_count(void)
Definition plrhand.c:3034
bool is_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req, const enum req_problem_type prob_type)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:747
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c:665
bool research_goal_tech_req(const struct research *presearch, Tech_type_id goal, Tech_type_id tech)
Definition research.c:797
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:634
const char * research_advance_rule_name(const struct research *presearch, Tech_type_id tech)
Definition research.c:238
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:769
int research_total_bulbs_required(const struct research *presearch, Tech_type_id tech, bool loss_value)
Definition research.c:858
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
#define research_players_iterate(_presearch, _pplayer)
Definition research.h:168
#define research_players_iterate_end
Definition research.h:172
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
adv_want tech_want[A_LAST+1]
Definition aidata.h:103
Tech_type_id choice
Definition aitech.c:49
adv_want want
Definition aitech.c:50
adv_want current_want
Definition aitech.c:51
Definition ai.h:50
Definition city.h:309
struct tile * tile
Definition city.h:311
struct packet_game_info info
Definition game.h:89
struct requirement_vector reqs
Definition improvement.h:75
bool global_advances[A_LAST]
struct city_list * cities
Definition player.h:281
struct team * team
Definition player.h:261
const struct impr_type * building
const struct player * player
Tech_type_id researching
Definition research.h:52
Tech_type_id tech_goal
Definition research.h:85
bool got_tech
Definition research.h:67
int bulbs_researched
Definition research.h:53
Definition tile.h:49
struct advance * require_advance
Definition unittype.h:500
struct combat_bonus_list * bonuses
Definition unittype.h:507
enum universals_n kind
Definition fc_types.h:758
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define A_ARRAY_SIZE
Definition tech.h:47
#define advance_index_iterate_max(_start, _index, _max)
Definition tech.h:252
#define A_NEVER
Definition tech.h:51
#define advance_index_iterate_end
Definition tech.h:248
#define advance_index_iterate_max_end
Definition tech.h:258
#define advance_iterate(_start, _p)
Definition tech.h:264
static Tech_type_id advance_count(void)
Definition tech.h:170
#define A_FIRST
Definition tech.h:44
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
#define advance_iterate_end
Definition tech.h:270
#define advance_index_iterate(_start, _index)
Definition tech.h:244
void choose_tech_goal(struct research *presearch, Tech_type_id tech)
Definition techtools.c:1051
void choose_tech(struct research *research, Tech_type_id tech)
Definition techtools.c:983
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2301
int num_role_units(int role)
Definition unittype.c:2251
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
#define unit_type_iterate(_p)
Definition unittype.h:841
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:848