Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/research.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
research.c
Go to the documentation of this file.
1/****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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#ifdef HAVE_CONFIG_H
14#include <fc_config.h>
15#endif
16
17/* utility */
18#include "iterator.h"
19#include "log.h"
20#include "shared.h"
21#include "string_vector.h"
22#include "support.h"
23
24/* common */
25#include "fc_types.h"
26#include "game.h"
27#include "player.h"
28#include "name_translation.h"
29#include "team.h"
30#include "tech.h"
31
32#include "research.h"
33
34
35 struct research_iter {
36 struct iterator vtable;
37 int index;
38};
39#define RESEARCH_ITER(p) ((struct research_iter *) p)
40
41 struct research_player_iter {
42 struct iterator vtable;
43 union {
44 struct player *pplayer;
45 struct player_list_link *plink;
46 };
47};
48#define RESEARCH_PLAYER_ITER(p) ((struct research_player_iter *) p)
49
50 static struct research research_array[MAX_NUM_PLAYER_SLOTS];
51
52 static struct name_translation advance_unset_name = NAME_INIT;
53 static struct name_translation advance_future_name = NAME_INIT;
54 static struct name_translation advance_unknown_name = NAME_INIT;
55
56 static struct strvec *future_rule_name;
57 static struct strvec *future_name_translation;
58
59/************************************************************************/
62 void researches_init(void)
63{
64 int i;
65
66 /* Ensure we have enough space for players or teams. */
67 fc_assert(ARRAY_SIZE(research_array) >= team_slot_count());
68 fc_assert(ARRAY_SIZE(research_array) >= player_slot_count());
69
70 memset(research_array, 0, sizeof(research_array));
71 for (i = 0; i < ARRAY_SIZE(research_array); i++) {
72 research_array[i].tech_goal = A_UNSET;
73 research_array[i].researching = A_UNSET;
74 research_array[i].researching_saved = A_UNKNOWN;
75 research_array[i].future_tech = 0;
76 research_array[i].inventions[A_NONE].state = TECH_KNOWN;
77 advance_index_iterate(A_FIRST, j) {
78 research_array[i].inventions[j].bulbs_researched_saved = 0;
79 } advance_index_iterate_end;
80 }
81
82 game.info.global_advances[A_NONE] = TRUE;
83
84 /* Set technology names. */
85 /* TRANS: "None" tech */
86 name_set(&advance_unset_name, NULL, N_("?tech:None"));
87 name_set(&advance_future_name, NULL, N_("Future Tech."));
88 /* TRANS: "Unknown" advance/technology */
89 name_set(&advance_unknown_name, NULL, N_("(Unknown)"));
90
91 future_rule_name = strvec_new();
92 future_name_translation = strvec_new();
93}
94
95/************************************************************************/
98 void researches_free(void)
99{
100 strvec_destroy(future_rule_name);
101 strvec_destroy(future_name_translation);
102}
103
104/************************************************************************/
107 int research_number(const struct research *presearch)
108{
109 fc_assert_ret_val(NULL != presearch, -1);
110 return presearch - research_array;
111}
112
113/************************************************************************/
116 struct research *research_by_number(int number)
117{
118 fc_assert_ret_val(0 <= number, NULL);
119 fc_assert_ret_val(ARRAY_SIZE(research_array) > number, NULL);
120 return &research_array[number];
121}
122
123/************************************************************************/
126 struct research *research_get(const struct player *pplayer)
127{
128 if (NULL == pplayer) {
129 /* Special case used at client side. */
130 return NULL;
131 } else if (game.info.team_pooled_research) {
132 return &research_array[team_number(pplayer->team)];
133 } else {
134 return &research_array[player_number(pplayer)];
135 }
136}
137
138/************************************************************************/
141 const char *research_rule_name(const struct research *presearch)
142{
143 if (game.info.team_pooled_research) {
144 return team_rule_name(team_by_number(research_number(presearch)));
145 } else {
146 return player_name(player_by_number(research_number(presearch)));
147 }
148}
149
150/************************************************************************/
154 const char *research_name_translation(const struct research *presearch)
155{
156 if (game.info.team_pooled_research) {
157 return team_name_translation(team_by_number(research_number(presearch)));
158 } else {
159 return player_name(player_by_number(research_number(presearch)));
160 }
161}
162
163/************************************************************************/
167 int research_pretty_name(const struct research *presearch, char *buf,
168 size_t buf_len)
169{
170 const struct player *pplayer;
171
172 if (game.info.team_pooled_research) {
173 const struct team *pteam = team_by_number(research_number(presearch));
174
175 if (1 != player_list_size(team_members(pteam))) {
176 char buf2[buf_len];
177
178 team_pretty_name(pteam, buf2, sizeof(buf2));
179 /* TRANS: e.g. "members of team 1", or even "members of team Red".
180 * Used in many places where a nation plural might be used. */
181 return fc_snprintf(buf, buf_len, _("members of %s"), buf2);
182 } else {
183 pplayer = player_list_front(team_members(pteam));
184 }
185 } else {
186 pplayer = player_by_number(research_number(presearch));
187 }
188
189 return fc_strlcpy(buf, nation_plural_for_player(pplayer), buf_len);
190}
191
192/************************************************************************/
196static inline const struct name_translation *
197research_advance_name(Tech_type_id tech)
198{
199 if (A_UNSET == tech) {
200 return &advance_unset_name;
201 } else if (A_FUTURE == tech) {
202 return &advance_future_name;
203 } else if (A_UNKNOWN == tech) {
204 return &advance_unknown_name;
205 } else {
206 const struct advance *padvance = advance_by_number(tech);
207
208 fc_assert_ret_val(NULL != padvance, NULL);
209 return &padvance->name;
210 }
211}
212
213/************************************************************************/
217 static const char *research_future_set_name(struct strvec *psv, int no,
218 const char *new_name)
219{
220 if (strvec_size(psv) <= no) {
221 /* Increase the size of the vector if needed. */
222 strvec_reserve(psv, no + 1);
223 }
224
225 /* Set in vector. */
226 strvec_set(psv, no, new_name);
227
228 /* Return duplicate of 'new_name'. */
229 return strvec_get(psv, no);
230}
231
232/************************************************************************/
238 const char *research_advance_rule_name(const struct research *presearch,
239 Tech_type_id tech)
240{
241 if (A_FUTURE == tech && NULL != presearch) {
242 const int no = presearch->future_tech;
243 const char *name;
244
245 name = strvec_get(future_rule_name, no);
246 if (name == NULL) {
247 char buffer[256];
248
249 /* NB: 'presearch->future_tech == 0' means "Future Tech. 1". */
250 fc_snprintf(buffer, sizeof(buffer), "%s %d",
251 rule_name_get(&advance_future_name),
252 no + 1);
253 name = research_future_set_name(future_rule_name, no, buffer);
254 }
255
256 fc_assert(name != NULL);
257
258 return name;
259 }
260
261 return rule_name_get(research_advance_name(tech));
262}
263
264/************************************************************************/
270const char *
271research_advance_name_translation(const struct research *presearch,
272 Tech_type_id tech)
273{
274 if (A_FUTURE == tech && NULL != presearch) {
275 const int no = presearch->future_tech;
276 const char *name;
277
278 name = strvec_get(future_name_translation, no);
279 if (name == NULL) {
280 char buffer[256];
281
282 /* NB: 'presearch->future_tech == 0' means "Future Tech. 1". */
283 fc_snprintf(buffer, sizeof(buffer), _("Future Tech. %d"), no + 1);
284 name = research_future_set_name(future_name_translation, no, buffer);
285 }
286
287 fc_assert(name != NULL);
288
289 return name;
290 }
291
292 return name_translation_get(research_advance_name(tech));
293}
294
295/************************************************************************/
301 static bool reqs_may_activate(const struct req_context *context,
302 const struct player *other_player,
303 const struct requirement_vector *reqs,
304 const enum req_problem_type prob_type)
305{
306 requirement_vector_iterate(reqs, preq) {
307 if (is_req_preventing(context, other_player, preq, prob_type)) {
308 return FALSE;
309 }
310 } requirement_vector_iterate_end;
311 return TRUE;
312}
313
314/************************************************************************/
324static bool
325research_allowed(const struct research *presearch,
326 Tech_type_id tech,
327 bool (*reqs_eval)(const struct req_context *context,
328 const struct player *oplr,
329 const struct requirement_vector *reqs,
330 const enum req_problem_type ptype))
331{
332 struct advance *adv;
333
334 adv = valid_advance_by_number(tech);
335
336 if (adv == NULL) {
337 /* Not a valid advance. */
338 return FALSE;
339 }
340
341 research_players_iterate(presearch, pplayer) {
342 if (reqs_eval(&(const struct req_context) { .player = pplayer },
343 NULL, &(adv->research_reqs), RPT_CERTAIN)) {
344 /* It is enough that one player that shares research is allowed to
345 * research it.
346 * Reasoning: Imagine a tech with that requires a nation in the
347 * player range. If the requirement applies to all players sharing
348 * research it will be illegal in research sharing games. To require
349 * that the player that fulfills the requirement must order it to be
350 * researched creates unnecessary bureaucracy. */
351 return TRUE;
352 }
353 } research_players_iterate_end;
354
355 return FALSE;
356}
357
358/************************************************************************/
364#define research_is_allowed(presearch, tech) \
365 research_allowed(presearch, tech, are_reqs_active)
366
367/************************************************************************/
373#define research_may_become_allowed(presearch, tech) \
374 research_allowed(presearch, tech, reqs_may_activate)
375
376/************************************************************************/
382 static bool research_get_reachable_rreqs(const struct research *presearch,
383 Tech_type_id tech)
384{
385 bv_techs done;
386 Tech_type_id techs[game.control.num_tech_types];
387 enum tech_req req;
388 int techs_num;
389 int i;
390
391 techs[0] = tech;
392 BV_CLR_ALL(done);
393 BV_SET(done, A_NONE);
394 BV_SET(done, tech);
395 techs_num = 1;
396
397 /* Check that all recursive requirements have their research_reqs
398 * in order. */
399 for (i = 0; i < techs_num; i++) {
400 if (presearch->inventions[techs[i]].state == TECH_KNOWN) {
401 /* This tech is already reached. What is required to research it and
402 * the techs it depends on is therefore irrelevant. */
403 continue;
404 }
405
406 if (!research_may_become_allowed(presearch, techs[i])) {
407 /* It will always be illegal to start researching this tech because
408 * of unchanging requirements. Since it isn't already known and can't
409 * be researched it must be unreachable. */
410 return FALSE;
411 }
412
413 /* Check if required techs are research_reqs reachable. */
414 for (req = 0; req < AR_SIZE; req++) {
415 Tech_type_id req_tech = advance_required(techs[i], req);
416
417 if (valid_advance_by_number(req_tech) == NULL) {
418 return FALSE;
419 } else if (!BV_ISSET(done, req_tech)) {
420 fc_assert(techs_num < ARRAY_SIZE(techs));
421 techs[techs_num] = req_tech;
422 techs_num++;
423
424 BV_SET(done, req_tech);
425 }
426 }
427 }
428
429 return TRUE;
430}
431
432/************************************************************************/
438 static bool research_get_reachable(const struct research *presearch,
439 Tech_type_id tech)
440{
441 if (valid_advance_by_number(tech) == NULL) {
442 return FALSE;
443 } else {
444 advance_root_req_iterate(advance_by_number(tech), proot) {
445 if (advance_requires(proot, AR_ROOT) == proot) {
446 /* This tech requires itself; it can only be reached by special
447 * means (init_techs, lua script, ...).
448 * If you already know it, you can "reach" it; if not, not. (This
449 * case is needed for descendants of this tech.) */
450 if (presearch->inventions[advance_number(proot)].state != TECH_KNOWN) {
451 return FALSE;
452 }
453 } else {
454 enum tech_req req;
455
456 for (req = 0; req < AR_SIZE; req++) {
457 if (valid_advance(advance_requires(proot, req)) == NULL) {
458 return FALSE;
459 }
460 }
461 }
462 } advance_root_req_iterate_end;
463 }
464
465 /* Check research reqs reachability. */
466 if (!research_get_reachable_rreqs(presearch, tech)) {
467 return FALSE;
468 }
469
470 return TRUE;
471}
472
473/************************************************************************/
480 static bool research_get_root_reqs_known(const struct research *presearch,
481 Tech_type_id tech)
482{
483 advance_root_req_iterate(advance_by_number(tech), proot) {
484 if (presearch->inventions[advance_number(proot)].state != TECH_KNOWN) {
485 return FALSE;
486 }
487 } advance_root_req_iterate_end;
488
489 return TRUE;
490}
491
492/************************************************************************/
499 void research_update(struct research *presearch)
500{
501 enum tech_flag_id flag;
502 int techs_researched;
503
504 advance_index_iterate(A_FIRST, i) {
505 enum tech_state state = presearch->inventions[i].state;
506 bool root_reqs_known = TRUE;
507 bool reachable = research_get_reachable(presearch, i);
508
509 /* Finding if the root reqs of an unreachable tech isn't redundant.
510 * A tech can be unreachable via research but have known root reqs
511 * because of unfilfilled research_reqs. Unfulfilled research_reqs
512 * doesn't prevent the player from aquiring the tech by other means. */
513 root_reqs_known = research_get_root_reqs_known(presearch, i);
514
515 if (reachable) {
516 if (state != TECH_KNOWN) {
517 /* Update state. */
518 state = (root_reqs_known
519 && (presearch->inventions[advance_required(i, AR_ONE)].state
520 == TECH_KNOWN)
521 && (presearch->inventions[advance_required(i, AR_TWO)].state
522 == TECH_KNOWN)
523 && research_is_allowed(presearch, i)
524 ? TECH_PREREQS_KNOWN : TECH_UNKNOWN);
525 }
526 } else {
527 /* We used to assert here that state already is TECH_UNKNOWN. However, there is
528 * a special case where it can be e.g. TECH_PREREQS_KNOWN and still
529 * unreachable (like in above research_get_reachable() call) because
530 * player is dead. Dead player's don't research anything. More accurately
531 * research_players_iterate() for a dead player's research iterates over
532 * zero players in research_allowed(), so it falls through to default of FALSE.
533 *
534 * Now we set the state to TECH_UNKNOWN instead of asserting that it already is. */
535 state = TECH_UNKNOWN;
536 }
537 presearch->inventions[i].state = state;
538 presearch->inventions[i].reachable = reachable;
539 presearch->inventions[i].root_reqs_known = root_reqs_known;
540
541 /* Updates required_techs, num_required_techs and bulbs_required. */
542 BV_CLR_ALL(presearch->inventions[i].required_techs);
543 presearch->inventions[i].num_required_techs = 0;
544 presearch->inventions[i].bulbs_required = 0;
545
546 if (!reachable || state == TECH_KNOWN) {
547 continue;
548 }
549
550 techs_researched = presearch->techs_researched;
551 advance_req_iterate(valid_advance_by_number(i), preq) {
552 Tech_type_id j = advance_number(preq);
553
554 if (TECH_KNOWN == research_invention_state(presearch, j)) {
555 continue;
556 }
557
558 BV_SET(presearch->inventions[i].required_techs, j);
559 presearch->inventions[i].num_required_techs++;
560 presearch->inventions[i].bulbs_required +=
561 research_total_bulbs_required(presearch, j, FALSE);
562 /* This is needed to get a correct result for the
563 * research_total_bulbs_required() call when
564 * game.info.game.info.tech_cost_style is TECH_COST_CIV1CIV2. */
565 presearch->techs_researched++;
566 } advance_req_iterate_end;
567 presearch->techs_researched = techs_researched;
568 } advance_index_iterate_end;
569
570#ifdef FREECIV_DEBUG
571 advance_index_iterate(A_FIRST, i) {
572 char buf[advance_count() + 1];
573
574 advance_index_iterate(A_NONE, j) {
575 if (BV_ISSET(presearch->inventions[i].required_techs, j)) {
576 buf[j] = '1';
577 } else {
578 buf[j] = '0';
579 }
580 } advance_index_iterate_end;
581 buf[advance_count()] = '\0';
582
583 log_debug("%s: [%3d] %-25s => %s%s%s",
584 research_rule_name(presearch),
585 i,
586 advance_rule_name(advance_by_number(i)),
587 tech_state_name(research_invention_state(presearch, i)),
588 presearch->inventions[i].reachable ? "" : " [unrechable]",
589 presearch->inventions[i].root_reqs_known
590 ? "" : " [root reqs aren't known]");
591 log_debug("%s: [%3d] %s", research_rule_name(presearch), i, buf);
592 } advance_index_iterate_end;
593#endif /* FREECIV_DEBUG */
594
595 for (flag = 0; flag <= tech_flag_id_max(); flag++) {
596 /* Iterate over all possible tech flags (0..max). */
597 presearch->num_known_tech_with_flag[flag] = 0;
598
599 advance_index_iterate(A_NONE, i) {
600 if (TECH_KNOWN == research_invention_state(presearch, i)
601 && advance_has_flag(i, flag)) {
602 presearch->num_known_tech_with_flag[flag]++;
603 }
604 } advance_index_iterate_end;
605 }
606}
607
608/************************************************************************/
616 enum tech_state research_invention_state(const struct research *presearch,
617 Tech_type_id tech)
618{
619 fc_assert_ret_val(NULL != valid_advance_by_number(tech),
620 tech_state_invalid());
621
622 if (NULL != presearch) {
623 return presearch->inventions[tech].state;
624 } else if (game.info.global_advances[tech]) {
625 return TECH_KNOWN;
626 } else {
627 return TECH_UNKNOWN;
628 }
629}
630
631/************************************************************************/
634 enum tech_state research_invention_set(struct research *presearch,
635 Tech_type_id tech,
636 enum tech_state value)
637{
638 enum tech_state old;
639
640 fc_assert_ret_val(NULL != valid_advance_by_number(tech), -1);
641
642 old = presearch->inventions[tech].state;
643 if (old == value) {
644 return old;
645 }
646 presearch->inventions[tech].state = value;
647
648 if (value == TECH_KNOWN) {
649 if (!game.info.global_advances[tech]) {
650 game.info.global_advances[tech] = TRUE;
651 game.info.global_advance_count++;
652 }
653 }
654
655 return old;
656}
657
658/************************************************************************/
665 bool research_invention_reachable(const struct research *presearch,
666 const Tech_type_id tech)
667{
668 if (valid_advance_by_number(tech) == NULL) {
669 return FALSE;
670 } else if (presearch != NULL) {
671 return presearch->inventions[tech].reachable;
672 } else {
673 researches_iterate(research_iter) {
674 if (research_iter->inventions[tech].reachable) {
675 return TRUE;
676 }
677 } researches_iterate_end;
678
679 return FALSE;
680 }
681}
682
683/************************************************************************/
690 bool research_invention_gettable(const struct research *presearch,
691 const Tech_type_id tech,
692 bool allow_holes)
693{
694 if (valid_advance_by_number(tech) == NULL) {
695 return FALSE;
696 } else if (presearch != NULL) {
697 return (allow_holes
698 ? presearch->inventions[tech].root_reqs_known
699 : presearch->inventions[tech].state == TECH_PREREQS_KNOWN);
700 } else {
701 researches_iterate(research_iter) {
702 if (allow_holes
703 ? research_iter->inventions[tech].root_reqs_known
704 : research_iter->inventions[tech].state == TECH_PREREQS_KNOWN) {
705 return TRUE;
706 }
707 } researches_iterate_end;
708
709 return FALSE;
710 }
711}
712
713/************************************************************************/
717 Tech_type_id research_goal_step(const struct research *presearch,
718 Tech_type_id goal)
719{
720 const struct advance *pgoal = valid_advance_by_number(goal);
721
722 if (NULL == pgoal
723 || !research_invention_reachable(presearch, goal)) {
724 return A_UNSET;
725 }
726
727 advance_req_iterate(pgoal, preq) {
728 switch (research_invention_state(presearch, advance_number(preq))) {
729 case TECH_PREREQS_KNOWN:
730 return advance_number(preq);
731 case TECH_KNOWN:
732 case TECH_UNKNOWN:
733 break;
734 };
735 } advance_req_iterate_end;
736 return A_UNSET;
737}
738
739/************************************************************************/
747 int research_goal_unknown_techs(const struct research *presearch,
748 Tech_type_id goal)
749{
750 const struct advance *pgoal = valid_advance_by_number(goal);
751
752 if (NULL == pgoal) {
753 return 0;
754 } else if (NULL != presearch) {
755 return presearch->inventions[goal].num_required_techs;
756 } else {
757 return pgoal->num_reqs;
758 }
759}
760
761/************************************************************************/
769 int research_goal_bulbs_required(const struct research *presearch,
770 Tech_type_id goal)
771{
772 const struct advance *pgoal = valid_advance_by_number(goal);
773
774 if (NULL == pgoal) {
775 return 0;
776 } else if (NULL != presearch) {
777 return presearch->inventions[goal].bulbs_required;
778 } else if (game.info.tech_cost_style == TECH_COST_CIV1CIV2) {
779 return game.info.base_tech_cost * pgoal->num_reqs
780 * (pgoal->num_reqs + 1) / 2;
781 } else {
782 int bulbs_required = 0;
783
784 advance_req_iterate(pgoal, preq) {
785 bulbs_required += preq->cost;
786 } advance_req_iterate_end;
787 return bulbs_required;
788 }
789}
790
791/************************************************************************/
797 bool research_goal_tech_req(const struct research *presearch,
798 Tech_type_id goal, Tech_type_id tech)
799{
800 const struct advance *pgoal, *ptech;
801
802 if (tech == goal
803 || NULL == (pgoal = valid_advance_by_number(goal))
804 || NULL == (ptech = valid_advance_by_number(tech))) {
805 return FALSE;
806 } else if (NULL != presearch) {
807 return BV_ISSET(presearch->inventions[goal].required_techs, tech);
808 } else {
809 advance_req_iterate(pgoal, preq) {
810 if (preq == ptech) {
811 return TRUE;
812 }
813 } advance_req_iterate_end;
814 return FALSE;
815 }
816}
817
818/************************************************************************/
858 int research_total_bulbs_required(const struct research *presearch,
859 Tech_type_id tech, bool loss_value)
860{
861 enum tech_cost_style tech_cost_style = game.info.tech_cost_style;
862 int members;
863 double base_cost, total_cost;
864 double leak = 0.0;
865
866 if (valid_advance_by_number(tech) == NULL) {
867 return 0;
868 }
869
870 if (!loss_value
871 && NULL != presearch
872 && !is_future_tech(tech)
873 && research_invention_state(presearch, tech) == TECH_KNOWN) {
874 /* A non-future tech which is already known costs nothing. */
875 return 0;
876 }
877
878 if (is_future_tech(tech)) {
879 /* Future techs use style TECH_COST_CIV1CIV2. */
880 tech_cost_style = TECH_COST_CIV1CIV2;
881 }
882
883 fc_assert_msg(tech_cost_style_is_valid(tech_cost_style),
884 "Invalid tech_cost_style %d", tech_cost_style);
885 base_cost = 0.0;
886 switch (tech_cost_style) {
887 case TECH_COST_CIV1CIV2:
888 if (NULL != presearch) {
889 base_cost = game.info.base_tech_cost * presearch->techs_researched;
890 break;
891 }
892
893 fc_assert(presearch != NULL);
894 fc__fallthrough; /* No break; Fallback to using preset cost. */
895 case TECH_COST_CLASSIC:
896 case TECH_COST_CLASSIC_PRESET:
897 case TECH_COST_EXPERIMENTAL:
898 case TECH_COST_EXPERIMENTAL_PRESET:
899 case TECH_COST_LINEAR:
900 {
901 const struct advance *padvance = valid_advance_by_number(tech);
902
903 if (NULL != padvance) {
904 base_cost = padvance->cost;
905 } else {
906 fc_assert(NULL != padvance); /* Always fails. */
907 }
908 }
909 break;
910 }
911
912 total_cost = 0.0;
913 members = 0;
914 research_players_iterate(presearch, pplayer) {
915 members++;
916 total_cost += (base_cost
917 * get_player_bonus(pplayer, EFT_TECH_COST_FACTOR));
918 } research_players_iterate_end;
919 if (0 == members) {
920 /* There is no more alive players for this research, no need to apply
921 * complicated modifiers. */
922 return base_cost * (double) game.info.sciencebox / 100.0;
923 }
924 base_cost = total_cost / members;
925
926 fc_assert_msg(tech_leakage_style_is_valid(game.info.tech_leakage),
927 "Invalid tech_leakage %d", game.info.tech_leakage);
928 switch (game.info.tech_leakage) {
929 case TECH_LEAKAGE_NONE:
930 /* no change */
931 break;
932
933 case TECH_LEAKAGE_EMBASSIES:
934 {
935 int players = 0, players_with_tech_and_embassy = 0;
936
937 players_iterate_alive(aplayer) {
938 const struct research *aresearch = research_get(aplayer);
939
940 players++;
941 if (aresearch == presearch
942 || (A_FUTURE == tech
943 ? aresearch->future_tech <= presearch->future_tech
944 : TECH_KNOWN != research_invention_state(aresearch, tech))) {
945 continue;
946 }
947
948 research_players_iterate(presearch, pplayer) {
949 if (player_has_embassy(pplayer, aplayer)) {
950 players_with_tech_and_embassy++;
951 break;
952 }
953 } research_players_iterate_end;
954 } players_iterate_alive_end;
955
956 fc_assert_ret_val(0 < players, base_cost);
957 fc_assert(players >= players_with_tech_and_embassy);
958 leak = base_cost * players_with_tech_and_embassy
959 * game.info.tech_leak_pct / players / 100;
960 }
961 break;
962
963 case TECH_LEAKAGE_PLAYERS:
964 {
965 int players = 0, players_with_tech = 0;
966
967 players_iterate_alive(aplayer) {
968 players++;
969 if (A_FUTURE == tech
970 ? research_get(aplayer)->future_tech > presearch->future_tech
971 : TECH_KNOWN == research_invention_state(research_get(aplayer),
972 tech)) {
973 players_with_tech++;
974 }
975 } players_iterate_alive_end;
976
977 fc_assert_ret_val(0 < players, base_cost);
978 fc_assert(players >= players_with_tech);
979 leak = base_cost * players_with_tech * game.info.tech_leak_pct
980 / players / 100;
981 }
982 break;
983
984 case TECH_LEAKAGE_NO_BARBS:
985 {
986 int players = 0, players_with_tech = 0;
987
988 players_iterate_alive(aplayer) {
989 if (is_barbarian(aplayer)) {
990 continue;
991 }
992 players++;
993 if (A_FUTURE == tech
994 ? research_get(aplayer)->future_tech > presearch->future_tech
995 : TECH_KNOWN == research_invention_state(research_get(aplayer),
996 tech)) {
997 players_with_tech++;
998 }
999 } players_iterate_alive_end;
1000
1001 fc_assert_ret_val(0 < players, base_cost);
1002 fc_assert(players >= players_with_tech);
1003 leak = base_cost * players_with_tech * game.info.tech_leak_pct
1004 / players / 100;
1005 }
1006 break;
1007 }
1008
1009 if (leak > base_cost) {
1010 base_cost = 0.0;
1011 } else {
1012 base_cost -= leak;
1013 }
1014
1015 /* Assign a science penalty to the AI at easier skill levels. This code
1016 * can also be adopted to create an extra-hard AI skill level where the AI
1017 * gets science benefits. */
1018
1019 total_cost = 0.0;
1020 research_players_iterate(presearch, pplayer) {
1021 if (is_ai(pplayer)) {
1022 fc_assert(0 < pplayer->ai_common.science_cost);
1023 total_cost += base_cost * pplayer->ai_common.science_cost / 100.0;
1024 } else {
1025 total_cost += base_cost;
1026 }
1027 } research_players_iterate_end;
1028 base_cost = total_cost / members;
1029
1030 base_cost *= (double) game.info.sciencebox / 100.0;
1031
1032 return MAX(base_cost, 1);
1033}
1034
1035
1036/************************************************************************/
1040 int player_tech_upkeep(const struct player *pplayer)
1041{
1042 const struct research *presearch = research_get(pplayer);
1043 int f = presearch->future_tech, t = presearch->techs_researched;
1044 double tech_upkeep = 0.0;
1045 double total_research_factor;
1046 int members;
1047
1048 if (TECH_UPKEEP_NONE == game.info.tech_upkeep_style) {
1049 return 0;
1050 }
1051
1052 total_research_factor = 0.0;
1053 members = 0;
1054 research_players_iterate(presearch, contributor) {
1055 total_research_factor += (get_player_bonus(contributor, EFT_TECH_COST_FACTOR)
1056 + (is_ai(contributor)
1057 ? contributor->ai_common.science_cost / 100.0
1058 : 1));
1059 members++;
1060 } research_players_iterate_end;
1061 if (0 == members) {
1062 /* No player still alive. */
1063 return 0;
1064 }
1065
1066 /* Upkeep cost for 'normal' techs (t). */
1067 fc_assert_msg(tech_cost_style_is_valid(game.info.tech_cost_style),
1068 "Invalid tech_cost_style %d", game.info.tech_cost_style);
1069 switch (game.info.tech_cost_style) {
1070 case TECH_COST_CIV1CIV2:
1071 /* sum_1^t x = t * (t + 1) / 2 */
1072 tech_upkeep += game.info.base_tech_cost * t * (t + 1) / 2;
1073 break;
1074 case TECH_COST_CLASSIC:
1075 case TECH_COST_CLASSIC_PRESET:
1076 case TECH_COST_EXPERIMENTAL:
1077 case TECH_COST_EXPERIMENTAL_PRESET:
1078 case TECH_COST_LINEAR:
1079 advance_iterate(A_FIRST, padvance) {
1080 if (TECH_KNOWN == research_invention_state(presearch,
1081 advance_number(padvance))) {
1082 tech_upkeep += padvance->cost;
1083 }
1084 } advance_iterate_end;
1085 if (0 < f) {
1086 /* Upkeep cost for future techs (f) are calculated using style 0:
1087 * sum_t^(t+f) x = (f * (2 * t + f + 1) + 2 * t) / 2 */
1088 tech_upkeep += (double) (game.info.base_tech_cost
1089 * (f * (2 * t + f + 1) + 2 * t) / 2);
1090 }
1091 break;
1092 }
1093
1094 tech_upkeep *= total_research_factor / members;
1095 tech_upkeep *= (double) game.info.sciencebox / 100.0;
1096 /* We only want to calculate the upkeep part of one player, not the
1097 * whole team! */
1098 tech_upkeep /= members;
1099 tech_upkeep /= game.info.tech_upkeep_divider;
1100
1101 switch (game.info.tech_upkeep_style) {
1102 case TECH_UPKEEP_BASIC:
1103 tech_upkeep -= get_player_bonus(pplayer, EFT_TECH_UPKEEP_FREE);
1104 break;
1105 case TECH_UPKEEP_PER_CITY:
1106 tech_upkeep -= get_player_bonus(pplayer, EFT_TECH_UPKEEP_FREE);
1107 tech_upkeep *= city_list_size(pplayer->cities);
1108 break;
1109 case TECH_UPKEEP_NONE:
1110 fc_assert(game.info.tech_upkeep_style != TECH_UPKEEP_NONE);
1111 tech_upkeep = 0.0;
1112 }
1113
1114 if (0.0 > tech_upkeep) {
1115 tech_upkeep = 0.0;
1116 }
1117
1118 log_debug("[%s (%d)] tech upkeep: %d", player_name(pplayer),
1119 player_number(pplayer), (int) tech_upkeep);
1120 return (int) tech_upkeep;
1121}
1122
1123
1124/************************************************************************/
1127 size_t research_iter_sizeof(void)
1128{
1129 return sizeof(struct research_iter);
1130}
1131
1132/************************************************************************/
1135 static void *research_iter_get(const struct iterator *it)
1136{
1137 return &research_array[RESEARCH_ITER(it)->index];
1138}
1139
1140/************************************************************************/
1143 static void research_iter_team_next(struct iterator *it)
1144{
1145 struct research_iter *rit = RESEARCH_ITER(it);
1146
1147 if (team_slots_initialised()) {
1148 do {
1149 rit->index++;
1150 } while (rit->index < ARRAY_SIZE(research_array) && !it->valid(it));
1151 }
1152}
1153
1154/************************************************************************/
1157 static bool research_iter_team_valid(const struct iterator *it)
1158{
1159 struct research_iter *rit = RESEARCH_ITER(it);
1160
1161 return (0 <= rit->index
1162 && ARRAY_SIZE(research_array) > rit->index
1163 && NULL != team_by_number(rit->index));
1164}
1165
1166/************************************************************************/
1169 static void research_iter_player_next(struct iterator *it)
1170{
1171 struct research_iter *rit = RESEARCH_ITER(it);
1172
1173 if (player_slots_initialised()) {
1174 do {
1175 rit->index++;
1176 } while (rit->index < ARRAY_SIZE(research_array) && !it->valid(it));
1177 }
1178}
1179
1180/************************************************************************/
1183 static bool research_iter_player_valid(const struct iterator *it)
1184{
1185 struct research_iter *rit = RESEARCH_ITER(it);
1186
1187 return (0 <= rit->index
1188 && ARRAY_SIZE(research_array) > rit->index
1189 && NULL != player_by_number(rit->index));
1190}
1191
1192/************************************************************************/
1195 struct iterator *research_iter_init(struct research_iter *it)
1196{
1197 struct iterator *base = ITERATOR(it);
1198
1199 base->get = research_iter_get;
1200 it->index = -1;
1201
1202 if (game.info.team_pooled_research) {
1203 base->next = research_iter_team_next;
1204 base->valid = research_iter_team_valid;
1205 } else {
1206 base->next = research_iter_player_next;
1207 base->valid = research_iter_player_valid;
1208 }
1209
1210 base->next(base);
1211 return base;
1212}
1213
1214/************************************************************************/
1217 size_t research_player_iter_sizeof(void)
1218{
1219 return sizeof(struct research_player_iter);
1220}
1221
1222/************************************************************************/
1225 static inline bool research_player_iter_valid_state(struct iterator *it)
1226{
1227 const struct player *pplayer = iterator_get(it);
1228
1229 return (NULL == pplayer || pplayer->is_alive);
1230}
1231
1232/************************************************************************/
1235 static void *research_player_iter_pooled_get(const struct iterator *it)
1236{
1237 return player_list_link_data(RESEARCH_PLAYER_ITER(it)->plink);
1238}
1239
1240/************************************************************************/
1243 static void research_player_iter_pooled_next(struct iterator *it)
1244{
1245 struct research_player_iter *rpit = RESEARCH_PLAYER_ITER(it);
1246
1247 do {
1248 rpit->plink = player_list_link_next(rpit->plink);
1249 } while (!research_player_iter_valid_state(it));
1250}
1251
1252/************************************************************************/
1255 static bool research_player_iter_pooled_valid(const struct iterator *it)
1256{
1257 return NULL != RESEARCH_PLAYER_ITER(it)->plink;
1258}
1259
1260/************************************************************************/
1263 static void *research_player_iter_not_pooled_get(const struct iterator *it)
1264{
1265 return RESEARCH_PLAYER_ITER(it)->pplayer;
1266}
1267
1268/************************************************************************/
1271 static void research_player_iter_not_pooled_next(struct iterator *it)
1272{
1273 RESEARCH_PLAYER_ITER(it)->pplayer = NULL;
1274}
1275
1276/************************************************************************/
1279 static bool research_player_iter_not_pooled_valid(const struct iterator *it)
1280{
1281 return NULL != RESEARCH_PLAYER_ITER(it)->pplayer;
1282}
1283
1284/************************************************************************/
1287 struct iterator *research_player_iter_init(struct research_player_iter *it,
1288 const struct research *presearch)
1289{
1290 struct iterator *base = ITERATOR(it);
1291
1292 if (game.info.team_pooled_research && NULL != presearch) {
1293 base->get = research_player_iter_pooled_get;
1294 base->next = research_player_iter_pooled_next;
1295 base->valid = research_player_iter_pooled_valid;
1296 it->plink = player_list_head(team_members(team_by_number(research_number
1297 (presearch))));
1298 } else {
1299 base->get = research_player_iter_not_pooled_get;
1300 base->next = research_player_iter_not_pooled_next;
1301 base->valid = research_player_iter_not_pooled_valid;
1302 it->pplayer = (NULL != presearch
1303 ? player_by_number(research_number(presearch)) : NULL);
1304 }
1305
1306 /* Ensure we have consistent data. */
1307 if (!research_player_iter_valid_state(base)) {
1308 iterator_next(base);
1309 }
1310
1311 return base;
1312}
1313
1314/************************************************************************/
1318 int recalculate_techs_researched(const struct research *presearch)
1319{
1320 int techs = 1; /* A_NONE known, and not part of below iteration */
1321
1322 advance_iterate(A_FIRST, t) {
1323 if (valid_advance(t) != NULL
1324 && research_invention_state(presearch, advance_number(t)) == TECH_KNOWN) {
1325 techs++;
1326 }
1327 } advance_iterate_end;
1328
1329 return techs + presearch->future_tech;
1330}
1331
1332/************************************************************************/
1335 bool research_future_next(const struct research *presearch)
1336{
1337 advance_index_iterate(A_FIRST, i) {
1338 if (research_invention_state(presearch, i) != TECH_KNOWN) {
1339 return FALSE;
1340 }
1341 } advance_index_iterate_end;
1342
1343 return TRUE;
1344}
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
techs
char * techs
Definition comments.c:29
base
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2839
reqs
struct @21::@22 reqs
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
fc_types.h
Tech_type_id
int Tech_type_id
Definition fc_types.h:347
req_problem_type
req_problem_type
Definition fc_types.h:584
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:586
MAX_NUM_PLAYER_SLOTS
#define MAX_NUM_PLAYER_SLOTS
Definition fc_types.h:32
_
#define _(String)
Definition fcintl.h:67
N_
#define N_(String)
Definition fcintl.h:69
game
struct civ_game game
Definition game.c:57
game.h
name
const char * name
Definition inputfile.c:127
iterator.h
iterator_get
static void * iterator_get(const struct iterator *it)
Definition iterator.h:53
ITERATOR
#define ITERATOR(p)
Definition iterator.h:37
iterator_next
static void iterator_next(struct iterator *it)
Definition iterator.h:42
log.h
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
name_translation.h
NAME_INIT
#define NAME_INIT
Definition name_translation.h:44
name_set
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
Definition name_translation.h:88
rule_name_get
static const char * rule_name_get(const struct name_translation *ptrans)
Definition name_translation.h:112
name_translation_get
static const char * name_translation_get(const struct name_translation *ptrans)
Definition name_translation.h:121
nation_plural_for_player
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:177
player_by_number
struct player * player_by_number(const int player_id)
Definition player.c:840
player_slot_count
int player_slot_count(void)
Definition player.c:411
player_number
int player_number(const struct player *pplayer)
Definition player.c:828
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:886
player_slots_initialised
bool player_slots_initialised(void)
Definition player.c:371
player_has_embassy
bool player_has_embassy(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:202
player.h
is_barbarian
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
is_ai
#define is_ai(plr)
Definition player.h:234
players_iterate_alive_end
#define players_iterate_alive_end
Definition player.h:545
players_iterate_alive
#define players_iterate_alive(_pplayer)
Definition player.h:540
is_req_preventing
enum req_unchanging_status is_req_preventing(const struct req_context *context, const struct player *other_player, const struct requirement *req, enum req_problem_type prob_type)
Definition requirements.c:4619
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:93
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:91
research_array
static struct research research_array[MAX_NUM_PLAYER_SLOTS]
Definition research.c:50
research_goal_unknown_techs
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:747
research_invention_reachable
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c:665
research_goal_tech_req
bool research_goal_tech_req(const struct research *presearch, Tech_type_id goal, Tech_type_id tech)
Definition research.c:797
research_name_translation
const char * research_name_translation(const struct research *presearch)
Definition research.c:154
research_may_become_allowed
#define research_may_become_allowed(presearch, tech)
Definition research.c:373
research_invention_set
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:634
advance_unknown_name
static struct name_translation advance_unknown_name
Definition research.c:54
research_by_number
struct research * research_by_number(int number)
Definition research.c:116
research_advance_rule_name
const char * research_advance_rule_name(const struct research *presearch, Tech_type_id tech)
Definition research.c:238
player_tech_upkeep
int player_tech_upkeep(const struct player *pplayer)
Definition research.c:1040
research_future_next
bool research_future_next(const struct research *presearch)
Definition research.c:1335
research_player_iter_not_pooled_get
static void * research_player_iter_not_pooled_get(const struct iterator *it)
Definition research.c:1263
research_iter_get
static void * research_iter_get(const struct iterator *it)
Definition research.c:1135
research_iter_player_valid
static bool research_iter_player_valid(const struct iterator *it)
Definition research.c:1183
research_player_iter_pooled_get
static void * research_player_iter_pooled_get(const struct iterator *it)
Definition research.c:1235
advance_unset_name
static struct name_translation advance_unset_name
Definition research.c:52
research_player_iter_not_pooled_next
static void research_player_iter_not_pooled_next(struct iterator *it)
Definition research.c:1271
research_iter_sizeof
size_t research_iter_sizeof(void)
Definition research.c:1127
reqs_may_activate
static bool reqs_may_activate(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition research.c:301
research_is_allowed
#define research_is_allowed(presearch, tech)
Definition research.c:364
researches_init
void researches_init(void)
Definition research.c:62
research_player_iter_pooled_next
static void research_player_iter_pooled_next(struct iterator *it)
Definition research.c:1243
research_iter_player_next
static void research_iter_player_next(struct iterator *it)
Definition research.c:1169
advance_future_name
static struct name_translation advance_future_name
Definition research.c:53
research_get_root_reqs_known
static bool research_get_root_reqs_known(const struct research *presearch, Tech_type_id tech)
Definition research.c:480
research_number
int research_number(const struct research *presearch)
Definition research.c:107
research_player_iter_valid_state
static bool research_player_iter_valid_state(struct iterator *it)
Definition research.c:1225
research_goal_bulbs_required
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:769
research_advance_name_translation
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:271
research_total_bulbs_required
int research_total_bulbs_required(const struct research *presearch, Tech_type_id tech, bool loss_value)
Definition research.c:858
research_advance_name
static const struct name_translation * research_advance_name(Tech_type_id tech)
Definition research.c:197
research_iter_init
struct iterator * research_iter_init(struct research_iter *it)
Definition research.c:1195
recalculate_techs_researched
int recalculate_techs_researched(const struct research *presearch)
Definition research.c:1318
RESEARCH_ITER
#define RESEARCH_ITER(p)
Definition research.c:39
research_rule_name
const char * research_rule_name(const struct research *presearch)
Definition research.c:141
future_rule_name
static struct strvec * future_rule_name
Definition research.c:56
research_get_reachable_rreqs
static bool research_get_reachable_rreqs(const struct research *presearch, Tech_type_id tech)
Definition research.c:382
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:126
researches_free
void researches_free(void)
Definition research.c:98
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
research_get_reachable
static bool research_get_reachable(const struct research *presearch, Tech_type_id tech)
Definition research.c:438
research_player_iter_not_pooled_valid
static bool research_player_iter_not_pooled_valid(const struct iterator *it)
Definition research.c:1279
research_iter_team_valid
static bool research_iter_team_valid(const struct iterator *it)
Definition research.c:1157
research_goal_step
Tech_type_id research_goal_step(const struct research *presearch, Tech_type_id goal)
Definition research.c:717
research_invention_gettable
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
research_player_iter_pooled_valid
static bool research_player_iter_pooled_valid(const struct iterator *it)
Definition research.c:1255
RESEARCH_PLAYER_ITER
#define RESEARCH_PLAYER_ITER(p)
Definition research.c:48
research_player_iter_sizeof
size_t research_player_iter_sizeof(void)
Definition research.c:1217
research_future_set_name
static const char * research_future_set_name(struct strvec *psv, int no, const char *new_name)
Definition research.c:217
research_allowed
static bool research_allowed(const struct research *presearch, Tech_type_id tech, bool(*reqs_eval)(const struct req_context *context, const struct player *oplr, const struct requirement_vector *reqs, const enum req_problem_type ptype))
Definition research.c:325
research_player_iter_init
struct iterator * research_player_iter_init(struct research_player_iter *it, const struct research *presearch)
Definition research.c:1287
future_name_translation
static struct strvec * future_name_translation
Definition research.c:57
research_update
void research_update(struct research *presearch)
Definition research.c:499
research_iter_team_next
static void research_iter_team_next(struct iterator *it)
Definition research.c:1143
research_pretty_name
int research_pretty_name(const struct research *presearch, char *buf, size_t buf_len)
Definition research.c:167
research.h
research_players_iterate
#define research_players_iterate(_presearch, _pplayer)
Definition research.h:168
researches_iterate
#define researches_iterate(_presearch)
Definition research.h:157
research_players_iterate_end
#define research_players_iterate_end
Definition research.h:172
researches_iterate_end
#define researches_iterate_end
Definition research.h:160
shared.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MAX
#define MAX(x, y)
Definition shared.h:54
strvec_destroy
void strvec_destroy(struct strvec *psv)
Definition string_vector.c:71
strvec_set
bool strvec_set(struct strvec *psv, size_t svindex, const char *string)
Definition string_vector.c:305
strvec_reserve
void strvec_reserve(struct strvec *psv, size_t reserve)
Definition string_vector.c:80
strvec_get
const char * strvec_get(const struct strvec *psv, size_t svindex)
Definition string_vector.c:388
strvec_new
struct strvec * strvec_new(void)
Definition string_vector.c:58
strvec_size
size_t strvec_size(const struct strvec *psv)
Definition string_vector.c:343
string_vector.h
advance
Definition tech.h:124
advance::research_reqs
struct requirement_vector research_reqs
Definition tech.h:137
advance::cost
double cost
Definition tech.h:150
advance::name
struct name_translation name
Definition tech.h:126
advance::num_reqs
int num_reqs
Definition tech.h:156
civ_game::control
struct packet_ruleset_control control
Definition game.h:83
civ_game::info
struct packet_game_info info
Definition game.h:89
iterator
Definition iterator.h:31
iterator::valid
bool(* valid)(const struct iterator *it)
Definition iterator.h:34
name_translation
Definition name_translation.h:35
packet_game_info::team_pooled_research
bool team_pooled_research
Definition packets_gen.h:224
packet_game_info::tech_upkeep_style
enum tech_upkeep_style tech_upkeep_style
Definition packets_gen.h:229
packet_game_info::tech_leak_pct
int tech_leak_pct
Definition packets_gen.h:129
packet_game_info::global_advances
bool global_advances[A_LAST]
Definition packets_gen.h:163
packet_game_info::base_tech_cost
int base_tech_cost
Definition packets_gen.h:128
packet_game_info::tech_leakage
enum tech_leakage_style tech_leakage
Definition packets_gen.h:227
packet_game_info::tech_upkeep_divider
int tech_upkeep_divider
Definition packets_gen.h:228
packet_game_info::sciencebox
int sciencebox
Definition packets_gen.h:220
packet_game_info::tech_cost_style
enum tech_cost_style tech_cost_style
Definition packets_gen.h:226
packet_game_info::global_advance_count
int global_advance_count
Definition packets_gen.h:162
packet_ruleset_control::num_tech_types
int num_tech_types
Definition packets_gen.h:1459
player
Definition player.h:249
player::cities
struct city_list * cities
Definition player.h:281
player::team
struct team * team
Definition player.h:261
player::is_alive
bool is_alive
Definition player.h:268
req_context
Definition requirements.h:99
research::research_invention::bulbs_required
int bulbs_required
Definition research.h:80
research::research_invention::root_reqs_known
bool root_reqs_known
Definition research.h:78
research::research_invention::bulbs_researched_saved
int bulbs_researched_saved
Definition research.h:80
research::research_invention::state
enum tech_state state
Definition research.h:73
research::research_invention::num_required_techs
int num_required_techs
Definition research.h:80
research::research_invention::reachable
bool reachable
Definition research.h:77
research::research_invention::required_techs
bv_techs required_techs
Definition research.h:79
research_iter
Definition research.c:35
research_iter::vtable
struct iterator vtable
Definition research.c:36
research_iter::index
int index
Definition research.c:37
research_player_iter
Definition research.c:41
research_player_iter::vtable
struct iterator vtable
Definition research.c:42
research_player_iter::pplayer
struct player * pplayer
Definition research.c:44
research_player_iter::plink
struct player_list_link * plink
Definition research.c:45
research
Definition research.h:39
research::researching
Tech_type_id researching
Definition research.h:52
research::future_tech
int future_tech
Definition research.h:42
research::tech_goal
Tech_type_id tech_goal
Definition research.h:85
research::inventions
struct research::research_invention inventions[A_ARRAY_SIZE]
research::researching_saved
Tech_type_id researching_saved
Definition research.h:62
research::techs_researched
int techs_researched
Definition research.h:42
research::num_known_tech_with_flag
int num_known_tech_with_flag[TF_COUNT]
Definition research.h:90
strvec
Definition string_vector.c:29
team
Definition team.c:40
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:787
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc__fallthrough
#define fc__fallthrough
Definition support.h:109
team_by_number
struct team * team_by_number(const int team_id)
Definition team.c:400
team_name_translation
const char * team_name_translation(const struct team *pteam)
Definition team.c:420
team_rule_name
const char * team_rule_name(const struct team *pteam)
Definition team.c:410
team_number
int team_number(const struct team *pteam)
Definition team.c:391
team_slots_initialised
bool team_slots_initialised(void)
Definition team.c:77
team_pretty_name
int team_pretty_name(const struct team *pteam, char *buf, size_t buf_len)
Definition team.c:432
team_members
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
team_slot_count
int team_slot_count(void)
Definition team.c:112
team.h
advance_by_number
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
is_future_tech
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
valid_advance
struct advance * valid_advance(struct advance *padvance)
Definition tech.c:152
advance_has_flag
bool advance_has_flag(Tech_type_id tech, enum tech_flag_id flag)
Definition tech.c:216
advance_requires
struct advance * advance_requires(const struct advance *padvance, enum tech_req require)
Definition tech.c:136
valid_advance_by_number
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
advance_required
Tech_type_id advance_required(const Tech_type_id tech, enum tech_req require)
Definition tech.c:121
advance_rule_name
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:299
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
tech.h
A_FUTURE
#define A_FUTURE
Definition tech.h:46
advance_index_iterate_end
#define advance_index_iterate_end
Definition tech.h:248
advance_req_iterate
#define advance_req_iterate(_goal, _padvance)
Definition tech.h:293
tech_req
tech_req
Definition tech.h:110
AR_TWO
@ AR_TWO
Definition tech.h:112
AR_ROOT
@ AR_ROOT
Definition tech.h:113
AR_ONE
@ AR_ONE
Definition tech.h:111
AR_SIZE
@ AR_SIZE
Definition tech.h:114
advance_iterate
#define advance_iterate(_start, _p)
Definition tech.h:264
advance_req_iterate_end
#define advance_req_iterate_end
Definition tech.h:297
advance_count
static Tech_type_id advance_count(void)
Definition tech.h:170
A_FIRST
#define A_FIRST
Definition tech.h:44
A_NONE
#define A_NONE
Definition tech.h:43
advance_root_req_iterate_end
#define advance_root_req_iterate_end
Definition tech.h:313
A_UNSET
#define A_UNSET
Definition tech.h:48
advance_iterate_end
#define advance_iterate_end
Definition tech.h:270
A_UNKNOWN
#define A_UNKNOWN
Definition tech.h:49
advance_index_iterate
#define advance_index_iterate(_start, _index)
Definition tech.h:244
advance_root_req_iterate
#define advance_root_req_iterate(_goal, _padvance)
Definition tech.h:308