Freeciv-3.3: /fast/freeciv/nightly/main/common/research.c Source File

Freeciv-3.3

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