Freeciv21
Develop your civilization from humble roots to a global empire
aitech.cpp
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 
14 #include <cstring>
15 
16 // utility
17 #include "log.h"
18 
19 // common
20 #include "game.h"
21 #include "government.h"
22 #include "player.h"
23 #include "research.h"
24 #include "tech.h"
25 
26 // server
27 #include "plrhand.h"
28 #include "srv_log.h"
29 #include "techtools.h"
30 
31 /* server/advisors */
32 #include "advdata.h"
33 
34 /* ai/default */
35 #include "aidata.h"
36 #include "ailog.h"
37 #include "aiplayer.h"
38 #include "aitools.h"
39 #include "daieffects.h"
40 
41 #include "aitech.h"
42 
44  Tech_type_id choice; // The id of the most needed tech
45  adv_want want; // Want of the most needed tech
46  adv_want current_want; /* Want of the tech which is currently researched
47  * or is our current goal */
48 };
49 
64 static void dai_select_tech(struct ai_type *ait, struct player *pplayer,
65  struct ai_tech_choice *choice,
66  struct ai_tech_choice *goal)
67 {
68  struct research *presearch = research_get(pplayer);
69  Tech_type_id newtech, newgoal;
70  int num_cities_nonzero = MAX(1, city_list_size(pplayer->cities));
71  int values[MAX(A_LAST, A_UNSET + 1)];
72  int goal_values[MAX(A_LAST, A_UNSET + 1)];
73  struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
74 
75  memset(values, 0, sizeof(values));
76  values[A_UNSET] = -1;
77  values[A_NONE] = -1;
78  goal_values[A_UNSET] = -1;
79  goal_values[A_NONE] = -1;
80 
81  /* if we are researching future techs, then simply continue with that.
82  * we don't need to do anything below. */
83  if (is_future_tech(presearch->researching)) {
84  if (choice) {
85  choice->choice = presearch->researching;
86  choice->want = 1;
87  choice->current_want = 1;
88  }
89  if (goal) {
90  goal->choice = A_UNSET;
91  goal->want = 1;
92  goal->current_want = 1;
93  }
94  return;
95  }
96 
97  /* Fill in values for the techs: want of the tech
98  * + average want of those we will discover en route */
100  {
101  if (valid_advance_by_number(i)) {
102  int steps = research_goal_unknown_techs(presearch, i);
103 
104  // We only want it if we haven't got it (so AI is human after all)
105  if (steps > 0) {
106  values[i] += plr_data->tech_want[i];
108  {
109  if (research_goal_tech_req(presearch, i, k)) {
110  values[k] += plr_data->tech_want[i] / steps;
111  }
112  }
114  }
115  }
116  }
118 
119  // Fill in the values for the tech goals
121  {
122  if (valid_advance_by_number(i)) {
123  int steps = research_goal_unknown_techs(presearch, i);
124 
125  if (steps == 0) {
126  // Can't be set as a goal any more
127  goal_values[i] = -1;
128  continue;
129  }
130 
131  goal_values[i] = values[i];
133  {
134  if (research_goal_tech_req(presearch, i, k)) {
135  goal_values[i] += values[k];
136  }
137  }
139 
140  /* This is the best I could do. It still sometimes does freaky stuff
141  * like setting goal to Republic and learning Monarchy, but that's what
142  * it's supposed to be doing; it just looks strange. -- Syela */
143  goal_values[i] /= steps;
144  if (steps < 6) {
145  log_debug("%s: want = " ADV_WANT_PRINTF
146  ", value = %d, goal_value = %d",
148  plr_data->tech_want[i], values[i], goal_values[i]);
149  }
150  }
151  }
153 
154  newtech = A_UNSET;
155  newgoal = A_UNSET;
157  {
158  if (valid_advance_by_number(i)) {
159  if (values[i] > values[newtech]
160  && research_invention_gettable(presearch, i, true)) {
161  newtech = i;
162  }
163  if (goal_values[i] > goal_values[newgoal]
164  && research_invention_reachable(presearch, i)) {
165  newgoal = i;
166  }
167  }
168  }
170 #ifdef REALLY_DEBUG_THIS
172  {
173  if (values[id] > 0
174  && research_invention_state(presearch, id) == TECH_PREREQS_KNOWN) {
175  TECH_LOG(ait, LOG_DEBUG, pplayer, advance_by_number(id),
176  "turn end want: %d", values[id]);
177  }
178  }
180 #endif // REALLY_DEBUG_THIS
181  if (choice) {
182  choice->choice = newtech;
183  choice->want = values[newtech] / num_cities_nonzero;
184  choice->current_want =
185  (values[presearch->researching] / num_cities_nonzero);
186  }
187 
188  if (goal) {
189  goal->choice = newgoal;
190  goal->want = goal_values[newgoal] / num_cities_nonzero;
191  goal->current_want =
192  (goal_values[presearch->tech_goal] / num_cities_nonzero);
193  log_debug(
194  "Goal->choice = %s, goal->want = " ADV_WANT_PRINTF
195  ", goal_value = %d, "
196  "num_cities_nonzero = %d",
197  qUtf8Printable(research_advance_rule_name(presearch, goal->choice)),
198  goal->want, goal_values[newgoal], num_cities_nonzero);
199  }
200 
201  /* we can't have this, which will happen in the circumstance
202  * where all ai.tech_wants are negative */
203  if (choice && choice->choice == A_UNSET) {
204  choice->choice = presearch->researching;
205  }
206 }
207 
213  struct player *pplayer,
214  struct city *pcity, struct advance *padv)
215 {
216  struct research *pres = research_get(pplayer);
217  Tech_type_id tech = advance_number(padv);
218  enum tech_state old_state = research_invention_state(pres, tech);
219  struct adv_data *adv = adv_data_get(pplayer, nullptr);
220  adv_want orig_want = dai_city_want(pplayer, pcity, adv, nullptr);
221  adv_want final_want;
222  bool world_knew = game.info.global_advances[tech];
223  int world_count = game.info.global_advance_count;
224 
225  research_invention_set(pres, tech, TECH_KNOWN);
226 
227  final_want = dai_city_want(pplayer, pcity, adv, nullptr);
228 
229  research_invention_set(pres, tech, old_state);
230  game.info.global_advances[tech] = world_knew;
231  game.info.global_advance_count = world_count;
232 
233  return final_want - orig_want;
234 }
235 
239 static void dai_tech_effect_values(struct ai_type *ait,
240  struct player *pplayer)
241 {
242  /* TODO: Currently this duplicates code from aicity.c improvement effect
243  * evaluating almost verbose - refactor so that they can share code.
244  */
245  struct government *gov = government_of_player(pplayer);
246  struct adv_data *adv = adv_data_get(pplayer, nullptr);
247  struct ai_plr *aip = def_ai_player_data(pplayer, ait);
248  int turns = 9999; // TODO: Set to correct value
249  int nplayers = normal_player_count();
250 
251  // Remove team members from the equation
252  players_iterate(aplayer)
253  {
254  if (aplayer->team && aplayer->team == pplayer->team
255  && aplayer != pplayer) {
256  nplayers--;
257  }
258  }
260 
261  advance_iterate(A_FIRST, padv)
262  {
264  != TECH_KNOWN) {
265  struct universal source = {
266  .value = {.advance = padv},
267  .kind = VUT_ADVANCE,
268  };
269 
270  city_list_iterate(pplayer->cities, pcity)
271  {
272  adv_want v;
273  adv_want tech_want;
274  bool capital;
275 
276  v = dai_tech_base_want(ait, pplayer, pcity, padv);
277  capital = is_capital(pcity);
278 
280  {
281  bool present = true;
282  bool active = true;
283 
284  requirement_vector_iterate(&peffect->reqs, preq)
285  {
286  /* Check if all the requirements for the currently evaluated
287  * effect are met, except for having the tech that we are
288  * evaluating.
289  * TODO: Consider requirements that could be met later. */
290  if (VUT_ADVANCE == preq->source.kind
291  && preq->source.value.advance == padv) {
292  present = preq->present;
293  continue;
294  }
295  if (!is_req_active(pplayer, nullptr, pcity, nullptr, nullptr,
296  nullptr, nullptr, nullptr, nullptr, nullptr,
297  preq, RPT_POSSIBLE)) {
298  active = false;
299  break; // presence doesn't matter for inactive effects.
300  }
301  }
303 
304  if (active) {
305  adv_want v1;
306 
307  v1 = dai_effect_value(pplayer, gov, adv, pcity, capital, turns,
308  peffect, 1, nplayers);
309 
310  if (!present) {
311  // Tech removes the effect
312  v -= v1;
313  } else {
314  v += v1;
315  }
316  }
317  }
319 
320  // Same conversion factor as in want_tech_for_improvement_effect()
321  tech_want = v * 14 / 8;
322 
323  aip->tech_want[advance_index(padv)] += tech_want;
324  }
326  }
327  }
329 }
330 
335 void 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
347  players_iterate(aplayer)
348  {
349  const struct player_diplstate *ds =
350  player_diplstate_get(pplayer, aplayer);
351 
352  if (ds->type == DS_TEAM) {
353  return;
354  }
355  }
357 
358  dai_select_tech(ait, pplayer, &choice, &goal);
359  if (choice.choice != research->researching) {
360  // changing
361  if (choice.want - choice.current_want > penalty
362  && (penalty + research->bulbs_researched
364  false))) {
365  TECH_LOG(ait, LOG_DEBUG, pplayer, advance_by_number(choice.choice),
366  "new research, was %s, penalty was %d",
367  qUtf8Printable(research_advance_rule_name(
369  penalty);
370  choose_tech(research, choice.choice);
371  }
372  }
373 
374  // crossing my fingers on this one! -- Syela (seems to have worked!)
375  /* It worked, in particular, because the value it sets
376  * (research->tech_goal) is practically never used, see the comment for
377  * ai_next_tech_goal */
378  if (goal.choice != research->tech_goal) {
379  log_debug(
380  "%s change goal from %s (want=" ADV_WANT_PRINTF
381  ") to %s (want=" ADV_WANT_PRINTF ")",
382  player_name(pplayer),
383  qUtf8Printable(
385  goal.current_want,
386  qUtf8Printable(research_advance_rule_name(research, goal.choice)),
387  goal.want);
389  }
390 }
391 
398  struct player *pplayer,
399  struct city *pcity,
400  const struct unit_type *att,
401  int want)
402 {
403  struct research *presearch = research_get(pplayer);
404  int best_avl_def = 0;
405  struct unit_type *best_avl = nullptr;
406  int best_cost = FC_INFINITY;
407  struct advance *best_tech = A_NEVER;
408  struct unit_type *best_unit = nullptr;
409  int def_values[U_LAST] = {0};
410  int att_idx = utype_index(att);
411 
412  unit_type_iterate(deftype)
413  {
414  int mp_pct = deftype->cache.defense_mp_bonuses_pct[att_idx] + 100;
415  int div_bonus_pct = 100
416  + combat_bonus_against(att->bonuses, deftype,
417  CBONUS_DEFENSE_DIVIDER_PCT)
418  + 100
419  * combat_bonus_against(att->bonuses, deftype,
420  CBONUS_DEFENSE_DIVIDER);
421  int def = deftype->defense_strength * mp_pct / div_bonus_pct;
422 
423  def_values[utype_index(deftype)] = def;
424 
425  if (can_city_build_unit_now(pcity, deftype)) {
426  if (def > best_avl_def) {
427  best_avl_def = def;
428  best_avl = deftype;
429  }
430  }
431  }
433 
434  unit_type_iterate(deftype)
435  {
436  if (def_values[utype_index(deftype)] > best_avl_def
437  && !can_city_build_unit_now(pcity, deftype)
438  && can_city_build_unit_later(pcity, deftype)) {
439  // It would be better than current best. Consider researching tech
440  const struct impr_type *building;
441  int cost = 0;
442  struct advance *itech = deftype->require_advance;
443  bool impossible_to_get = false;
444 
445  if (A_NEVER != itech
446  && research_invention_state(presearch, advance_number(itech))
447  != TECH_KNOWN) {
448  // See if we want to invent this.
449  cost =
450  research_goal_bulbs_required(presearch, advance_number(itech));
451  }
452  building = utype_needs_improvement(deftype, pcity);
453  if (building
454  && !can_player_build_improvement_direct(pplayer, building)) {
455  requirement_vector_iterate(&building->reqs, preq)
456  {
457  if (!is_req_active(pplayer, nullptr, pcity, building,
458  city_tile(pcity), nullptr, deftype, nullptr,
459  nullptr, nullptr, preq, RPT_CERTAIN)) {
460  if (VUT_ADVANCE == preq->source.kind && preq->present) {
461  int iimprtech = advance_number(preq->source.value.advance);
462  int imprcost =
463  research_goal_bulbs_required(presearch, iimprtech);
464 
465  if (imprcost < cost || cost == 0) {
466  /* If we already have the primary tech (cost == 0),
467  * or the building's tech is cheaper,
468  * go for the building's required tech. */
469  itech = preq->source.value.advance;
470  cost = 0;
471  }
472  cost += imprcost;
473  } else if (!dai_can_requirement_be_met_in_city(preq, pplayer,
474  pcity)) {
475  impossible_to_get = true;
476  }
477  }
478  }
480  }
481 
482  if (cost < best_cost && !impossible_to_get
483  && research_invention_reachable(presearch,
484  advance_number(itech))) {
485  best_tech = itech;
486  best_cost = cost;
487  best_unit = deftype;
488  }
489  }
490  }
492 
493  if (A_NEVER != best_tech) {
494  struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
495 
496  // Crank up chosen tech want
497  if (best_avl != nullptr
498  && def_values[utype_index(best_unit)] <= 1.5 * best_avl_def) {
499  /* We already have almost as good unit suitable for defending against
500  * this attacker */
501  want /= 2;
502  }
503 
504  plr_data->tech_want[advance_index(best_tech)] += want;
505  TECH_LOG(ait, LOG_DEBUG, pplayer, best_tech, "+ %d for %s by role", want,
506  utype_rule_name(best_unit));
507  }
508 
509  return best_avl;
510 }
511 
519  struct player *pplayer,
520  struct city *pcity, int role, int want)
521 {
522  struct research *presearch = research_get(pplayer);
523  int i, n;
524  int best_cost = FC_INFINITY;
525  struct advance *best_tech = A_NEVER;
526  struct unit_type *best_unit = nullptr;
527  struct unit_type *build_unit = nullptr;
528 
529  n = num_role_units(role);
530  for (i = n - 1; i >= 0; i--) {
531  struct unit_type *iunit = get_role_unit(role, i);
532  struct advance *itech = iunit->require_advance;
533 
534  if (can_city_build_unit_now(pcity, iunit)) {
535  build_unit = iunit;
536  break;
537  } else if (can_city_build_unit_later(pcity, iunit)) {
538  const struct impr_type *building;
539  int cost = 0;
540 
541  if (A_NEVER != itech
542  && research_invention_state(presearch, advance_number(itech))
543  != TECH_KNOWN) {
544  // See if we want to invent this.
545  cost =
546  research_goal_bulbs_required(presearch, advance_number(itech));
547  }
548  building = utype_needs_improvement(iunit, pcity);
549  if (building
550  && !can_player_build_improvement_direct(pplayer, building)) {
551  requirement_vector_iterate(&building->reqs, preq)
552  {
553  if (VUT_ADVANCE == preq->source.kind && preq->present) {
554  int iimprtech = advance_number(preq->source.value.advance);
555 
556  if (TECH_KNOWN
557  != research_invention_state(presearch, iimprtech)) {
558  int imprcost =
559  research_goal_bulbs_required(presearch, iimprtech);
560 
561  if (imprcost < cost || cost == 0) {
562  /* If we already have the primary tech (cost == 0),
563  * or the building's tech is cheaper,
564  * go for the building's required tech. */
565  itech = preq->source.value.advance;
566  cost = 0;
567  }
568  cost += imprcost;
569  }
570  }
571  }
573  }
574 
575  if (cost < best_cost
576  && research_invention_reachable(presearch,
577  advance_number(itech))) {
578  best_tech = itech;
579  best_cost = cost;
580  best_unit = iunit;
581  }
582  }
583  }
584 
585  if (A_NEVER != best_tech) {
586  struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
587 
588  // Crank up chosen tech want
589  if (build_unit != nullptr) {
590  // We already have a role unit of this kind
591  want /= 2;
592  }
593  plr_data->tech_want[advance_index(best_tech)] += want;
594  TECH_LOG(ait, LOG_DEBUG, pplayer, best_tech, "+ %d for %s by role", want,
595  utype_rule_name(best_unit));
596  }
597 
598  return build_unit;
599 }
600 
604 void dai_clear_tech_wants(struct ai_type *ait, struct player *pplayer)
605 {
606  struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
607 
608  advance_index_iterate(A_FIRST, i) { plr_data->tech_want[i] = 0; }
610 }
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Return a pointer to our data.
Definition: advdata.cpp:591
#define TECH_LOG(ait, _, pplayer, padvance, msg,...)
Definition: ailog.h:32
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition: aiplayer.h:47
struct unit_type * dai_wants_role_unit(struct ai_type *ait, struct player *pplayer, struct city *pcity, int role, int want)
Returns the best unit we can build, or nullptr if none.
Definition: aitech.cpp:518
static adv_want dai_tech_base_want(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct advance *padv)
Calculates want for some techs by actually adding the tech and measuring the effect.
Definition: aitech.cpp:212
struct unit_type * dai_wants_defender_against(struct ai_type *ait, struct player *pplayer, struct city *pcity, const struct unit_type *att, int want)
Returns the best defense multiplier unit we can build, or nullptr if none.
Definition: aitech.cpp:397
void dai_clear_tech_wants(struct ai_type *ait, struct player *pplayer)
Zero player tech wants.
Definition: aitech.cpp:604
void dai_manage_tech(struct ai_type *ait, struct player *pplayer)
Key AI research function.
Definition: aitech.cpp:335
static void dai_select_tech(struct ai_type *ait, struct player *pplayer, struct ai_tech_choice *choice, struct ai_tech_choice *goal)
Massage the numbers provided to us by ai.tech_want into unrecognizable pulp.
Definition: aitech.cpp:64
static void dai_tech_effect_values(struct ai_type *ait, struct player *pplayer)
Add effect values in to tech wants.
Definition: aitech.cpp:239
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Returns an improvement that will make it possible to build units of the specified type the specified ...
Definition: aiunit.cpp:2802
bool can_city_build_unit_later(const struct city *pcity, const struct unit_type *punittype)
Returns whether player can eventually build given unit in the city; returns FALSE if unit can never p...
Definition: city.cpp:912
bool is_capital(const struct city *pcity)
Return TRUE iff this city is its nation's capital.
Definition: city.cpp:1495
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Return whether given city can build given unit; returns FALSE if unit is obsolete.
Definition: city.cpp:894
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_list_iterate_end
Definition: city.h:484
int combat_bonus_against(const struct combat_bonus_list *list, const struct unit_type *enemy, enum combat_bonus_type type)
Get bonus value against given unit type from bonus list.
Definition: combat.cpp:852
adv_want dai_city_want(struct player *pplayer, struct city *acity, struct adv_data *adv, struct impr_type *pimprove)
Calculates city want from some input values.
Definition: daicity.cpp:1419
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Does the AI expect to ever be able to meet this requirement.
Definition: daieffects.cpp:723
adv_want dai_effect_value(struct player *pplayer, struct government *gov, const struct adv_data *adv, const struct city *pcity, const bool capital, int turns, const struct effect *peffect, const int c, const int nplayers)
How desirable is a particular effect for a particular city, given the number of cities in range (c).
Definition: daieffects.cpp:130
struct effect_list * get_req_source_effects(struct universal *psource)
Get a list of effects with this requirement source.
Definition: effects.cpp:132
#define effect_list_iterate_end
Definition: effects.h:349
#define effect_list_iterate(effect_list, peffect)
Definition: effects.h:347
float adv_want
Definition: fc_types.h:1144
int Tech_type_id
Definition: fc_types.h:294
@ RPT_CERTAIN
Definition: fc_types.h:568
@ RPT_POSSIBLE
Definition: fc_types.h:567
#define ADV_WANT_PRINTF
Definition: fc_types.h:1145
struct civ_game game
Definition: game.cpp:47
struct government * government_of_player(const struct player *pplayer)
Return the government of a player.
Definition: government.cpp:107
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
Whether player can build given building somewhere, ignoring whether it is obsolete.
constexpr auto LOG_DEBUG
Definition: log.h:27
#define log_debug(message,...)
Definition: log.h:65
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
int normal_player_count()
Return the number of non-barbarian players.
Definition: plrhand.cpp:3140
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, const enum national_intelligence nintel)
Checks the requirement to see if it is active on the given target.
#define requirement_vector_iterate_end
Definition: requirements.h:80
#define requirement_vector_iterate(req_vec, preq)
Definition: requirements.h:78
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Returns the number of technologies the player need to research to get the goal technology.
Definition: research.cpp:745
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Returns TRUE iff the given tech is ever reachable via research by the players sharing the research by...
Definition: research.cpp:659
bool research_goal_tech_req(const struct research *presearch, Tech_type_id goal, Tech_type_id tech)
Returns if the given tech has to be researched to reach the goal.
Definition: research.cpp:794
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Set research knowledge about tech to given state.
Definition: research.cpp:627
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
QString research_advance_rule_name(const struct research *presearch, Tech_type_id tech)
Store the rule name of the given tech (including A_FUTURE) in 'buf'.
Definition: research.cpp:233
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Function to determine cost (in bulbs) of reaching goal technology.
Definition: research.cpp:767
int research_total_bulbs_required(const struct research *presearch, Tech_type_id tech, bool loss_value)
Function to determine cost for technology.
Definition: research.cpp:855
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Returns TRUE iff the given tech can be given to the players sharing the research immediately.
Definition: research.cpp:686
#define FC_INFINITY
Definition: shared.h:32
#define MAX(x, y)
Definition: shared.h:48
Definition: tech.h:113
double cost
Definition: tech.h:138
Definition: aidata.h:63
adv_want tech_want[A_LAST+1]
Definition: aidata.h:95
Tech_type_id choice
Definition: aitech.cpp:44
adv_want want
Definition: aitech.cpp:45
adv_want current_want
Definition: aitech.cpp:46
Definition: ai.h:42
Definition: city.h:291
struct packet_game_info info
Definition: game.h:80
struct requirement_vector reqs
Definition: improvement.h:66
enum diplstate_type type
Definition: player.h:193
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
struct team * team
Definition: player.h:243
Tech_type_id researching
Definition: research.h:45
Tech_type_id tech_goal
Definition: research.h:78
bool got_tech
Definition: research.h:60
int bulbs_researched
Definition: research.h:46
struct advance * require_advance
Definition: unittype.h:484
struct combat_bonus_list * bonuses
Definition: unittype.h:491
universals_u value
Definition: fc_types.h:739
bool is_future_tech(Tech_type_id tech)
Is the given tech a future tech.
Definition: tech.cpp:268
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
struct advance * valid_advance_by_number(const Tech_type_id id)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:154
Tech_type_id advance_index(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:76
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
Definition: tech.cpp:85
#define A_NEVER
Definition: tech.h:44
#define advance_index_iterate_end
Definition: tech.h:226
#define advance_iterate(_start, _p)
Definition: tech.h:232
#define A_FIRST
Definition: tech.h:37
#define A_NONE
Definition: tech.h:36
#define A_UNSET
Definition: tech.h:41
#define advance_iterate_end
Definition: tech.h:238
#define A_LAST
Definition: tech.h:38
#define advance_index_iterate(_start, _index)
Definition: tech.h:221
void choose_tech_goal(struct research *presearch, Tech_type_id tech)
Called when a player chooses the tech goal he wants to research (or when the server chooses it for hi...
Definition: techtools.cpp:1055
void choose_tech(struct research *research, Tech_type_id tech)
Called when a player chooses the tech he wants to research (or when the server chooses it for him aut...
Definition: techtools.cpp:987
struct advance * advance
Definition: fc_types.h:577
const char * utype_rule_name(const struct unit_type *punittype)
Return the (untranslated) rule name of the unit type.
Definition: unittype.cpp:1274
int num_role_units(int role)
How many unit types have specified role/flag.
Definition: unittype.cpp:1866
struct unit_type * get_role_unit(int role, int role_index)
Return index-th unit with specified role/flag.
Definition: unittype.cpp:1900
Unit_type_id utype_index(const struct unit_type *punittype)
Return the unit type index.
Definition: unittype.cpp:82
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define U_LAST
Definition: unittype.h:31
#define unit_type_iterate_end
Definition: unittype.h:791