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

Freeciv-3.3

Loading...
Searching...
No Matches
effects.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#include <ctype.h>
18#include <string.h>
19
20/* utility */
21#include "astring.h"
22#include "fcintl.h"
23#include "log.h"
24#include "mem.h"
25#include "support.h"
26#include "shared.h" /* ARRAY_SIZE */
27#include "string_vector.h"
28
29/* common */
30#include "city.h"
31#include "game.h"
32#include "government.h"
33#include "improvement.h"
34#include "map.h"
35#include "packets.h"
36#include "player.h"
37#include "tech.h"
38
39#include "effects.h"
40
41
42 static bool initialized = FALSE;
43
44 struct user_effect {
45 enum effect_type ai_value_as;
46};
47
48 struct user_effect ueffects[EFT_USER_EFFECT_LAST + 1 - EFT_USER_EFFECT_1];
49
50/**************************************************************************
51 The code creates a ruleset cache on ruleset load. This constant cache
52 is used to speed up effects queries. After the cache is created it is
53 not modified again (though it may later be freed).
54
55 Since the cache is constant, the server only needs to send effects data to
56 the client upon connect. It also means that an AI can do fast searches in
57 the effects space by trying the possible combinations of addition or
58 removal of buildings with the effects it cares about.
59
60
61 To know how much a target is being affected, simply use the convenience
62 functions:
63
64 * get_world_bonus()
65 * get_player_bonus()
66 * get_player_output_bonus()
67 * get_city_bonus()
68 * get_city_output_bonus()
69 * get_city_tile_output_bonus()
70 * get_city_specialist_output_bonus()
71 * get_tile_bonus()
72 * get_tile_output_bonus()
73 * get_building_bonus()
74 * get_unittype_bonus()
75 * get_unit_bonus()
76 * get_unit_vs_tile_bonus()
77
78 These functions require as arguments the target and the effect type to be
79 queried.
80
81 Effect sources are unique and at a well known place in the
82 data structures. This allows the above queries to be fast:
83 - Look up the possible sources for the effect (O(1) lookup)
84 - For each source, find out if it is present (O(1) lookup per source).
85 The first is commonly called the "ruleset cache" and is stored statically
86 in this file. The second is the "sources cache" and is stored all over.
87
88 Any type of effect range and "survives" is possible if we have a sources
89 cache for that combination. For instance
90 - There is a sources cache of all existing buildings in a city; thus any
91 building effect in a city can have city range.
92 - There is a sources cache of all wonders in the world; thus any wonder
93 effect can have world range.
94 - There is a sources cache of all wonders for each player; thus any
95 wonder effect can have player range.
96 - There is a sources cache of all wonders ever built; thus any wonder
97 effect that survives can have world range.
98 However there is no sources cache for many of the possible sources. For
99 instance non-unique buildings do not have a world-range sources cache, so
100 you can't have a non-wonder building have a world-ranged effect.
101
102 The sources caches could easily be extended by generalizing it to a set
103 of arrays
104 game.buildings[], pplayer->buildings[],
105 pisland->buildings[], pcity->buildings[]
106 which would store the number of buildings of that type present by game,
107 player, island (continent) or city. This would allow non-surviving effects
108 to come from any building at any range. However to allow surviving effects
109 a second set of arrays would be needed. This should enable basic support
110 for small wonders and satellites.
111
112 No matter which sources caches are present, we should always know where
113 to look for a source and so the lookups will always be fast even as the
114 number of possible sources increases.
115**************************************************************************/
116
117/**************************************************************************
118 Ruleset cache. The cache is created during ruleset loading and the data
119 is organized to enable fast queries.
120**************************************************************************/
121static struct {
122 /* A single list containing every effect. */
123 struct effect_list *tracker;
124
125 /* This array provides a full list of the effects of this type
126 * (It's not really a cache, it's the real data.) */
127 struct effect_list *effects[EFT_COUNT];
128
129 struct {
130 /* This cache shows for each building, which effects it provides. */
131 struct effect_list *buildings[B_LAST];
132 /* Same for governments */
133 struct effect_list *govs[G_LAST];
134 /* ...advances... */
135 struct effect_list *advances[A_LAST];
136 } reqs;
137} ruleset_cache;
138
139
140/**********************************************************************/
143 struct effect_list *get_effects(enum effect_type effect_type)
144{
145 return ruleset_cache.effects[effect_type];
146}
147
148/**********************************************************************/
153 struct effect_list *get_req_source_effects(const struct universal *psource)
154{
155 int type, value;
156
157 universal_extraction(psource, &type, &value);
158
159 switch (type) {
160 case VUT_GOVERNMENT:
161 if (value >= 0 && value < government_count()) {
162 return ruleset_cache.reqs.govs[value];
163 } else {
164 return NULL;
165 }
166 case VUT_IMPROVEMENT:
167 if (value >= 0 && value < improvement_count()) {
168 return ruleset_cache.reqs.buildings[value];
169 } else {
170 return NULL;
171 }
172 case VUT_ADVANCE:
173 if (value >= 0 && value < advance_count()) {
174 return ruleset_cache.reqs.advances[value];
175 } else {
176 return NULL;
177 }
178 default:
179 return NULL;
180 }
181}
182
183/**********************************************************************/
186 struct effect *effect_new(enum effect_type type, int value,
187 struct multiplier *pmul)
188{
189 struct effect *peffect;
190
191 /* Create the effect. */
192 peffect = fc_malloc(sizeof(*peffect));
193 peffect->type = type;
194 peffect->value = value;
195 peffect->multiplier = pmul;
196
197 requirement_vector_init(&peffect->reqs);
198
199 /* Now add the effect to the ruleset cache. */
200 effect_list_append(ruleset_cache.tracker, peffect);
201 effect_list_append(get_effects(type), peffect);
202
203 /* Only relevant for ruledit and other rulesave users. */
204 peffect->rulesave.do_not_save = FALSE;
205 peffect->rulesave.comment = NULL;
206
207 return peffect;
208}
209
210/**********************************************************************/
216 void effect_free(struct effect *peffect)
217{
218 requirement_vector_free(&peffect->reqs);
219 if (peffect->rulesave.comment != NULL) {
220 free(peffect->rulesave.comment);
221 }
222 free(peffect);
223}
224
225/**********************************************************************/
230 void effect_remove(struct effect *peffect)
231{
232 effect_list_remove(ruleset_cache.tracker, peffect);
233 effect_list_remove(get_effects(peffect->type), peffect);
234}
235
236/**********************************************************************/
246 struct effect *effect_copy(struct effect *old,
247 enum effect_type override_type)
248{
249 struct effect *new_eff;
250 enum effect_type type = (effect_type_is_valid(override_type)
251 ? override_type
252 : old->type);
253
254 new_eff = effect_new(type, old->value, old->multiplier);
255
256 requirement_vector_iterate(&old->reqs, preq) {
257 effect_req_append(new_eff, *preq);
258 } requirement_vector_iterate_end;
259
260 return new_eff;
261}
262
263/**********************************************************************/
266 void effect_req_append(struct effect *peffect, struct requirement req)
267{
268 struct effect_list *eff_list = get_req_source_effects(&req.source);
269
270 requirement_vector_append(&peffect->reqs, req);
271
272 if (eff_list != NULL) {
273 effect_list_append(eff_list, peffect);
274 }
275
276 if (req.source.kind == VUT_IMPR_FLAG) {
277 improvement_iterate(impr) {
278 if (improvement_has_flag(impr, req.source.value.impr_flag)) {
279 eff_list = get_req_source_effects(&(const struct universal) {
280 .kind = VUT_IMPROVEMENT,
281 .value.building = impr
282 });
283
284 if (eff_list != NULL) {
285 effect_list_append(eff_list, peffect);
286 }
287 }
288 } improvement_iterate_end;
289 }
290}
291
292/**********************************************************************/
297 void ruleset_cache_init(void)
298{
299 int i;
300
301 initialized = TRUE;
302
303 ruleset_cache.tracker = effect_list_new();
304
305 for (i = 0; i < ARRAY_SIZE(ruleset_cache.effects); i++) {
306 ruleset_cache.effects[i] = effect_list_new();
307 }
308 for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.buildings); i++) {
309 ruleset_cache.reqs.buildings[i] = effect_list_new();
310 }
311 for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.govs); i++) {
312 ruleset_cache.reqs.govs[i] = effect_list_new();
313 }
314 for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.advances); i++) {
315 ruleset_cache.reqs.advances[i] = effect_list_new();
316 }
317
318 /* By default, user effects are valued as themselves
319 * (currently meaning that they get no value at all) */
320 for (i = EFT_USER_EFFECT_1 ; i <= EFT_USER_EFFECT_LAST; i++) {
321 ueffects[USER_EFFECT_NUMBER(i)].ai_value_as = i;
322 }
323}
324
325/**********************************************************************/
329 void ruleset_cache_free(void)
330{
331 int i;
332 struct effect_list *tracker_list = ruleset_cache.tracker;
333
334 if (tracker_list) {
335 effect_list_iterate(tracker_list, peffect) {
336 effect_free(peffect);
337 } effect_list_iterate_end;
338 effect_list_destroy(tracker_list);
339 ruleset_cache.tracker = NULL;
340 }
341
342 for (i = 0; i < ARRAY_SIZE(ruleset_cache.effects); i++) {
343 struct effect_list *plist = ruleset_cache.effects[i];
344
345 if (plist) {
346 effect_list_destroy(plist);
347 ruleset_cache.effects[i] = NULL;
348 }
349 }
350
351 for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.buildings); i++) {
352 struct effect_list *plist = ruleset_cache.reqs.buildings[i];
353
354 if (plist) {
355 effect_list_destroy(plist);
356 ruleset_cache.reqs.buildings[i] = NULL;
357 }
358 }
359
360 for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.govs); i++) {
361 struct effect_list *plist = ruleset_cache.reqs.govs[i];
362
363 if (plist) {
364 effect_list_destroy(plist);
365 ruleset_cache.reqs.govs[i] = NULL;
366 }
367 }
368
369 for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.advances); i++) {
370 struct effect_list *plist = ruleset_cache.reqs.advances[i];
371
372 if (plist) {
373 effect_list_destroy(plist);
374 ruleset_cache.reqs.advances[i] = NULL;
375 }
376 }
377
378 initialized = FALSE;
379}
380
381/**********************************************************************/
388 int effect_cumulative_max(enum effect_type type, struct universal *unis,
389 size_t n_unis)
390{
391 struct effect_list *plist = ruleset_cache.tracker;
392 int value = 0;
393
394 fc_assert_ret_val(((unis == NULL && n_unis == 0)
395 || (unis != NULL && n_unis > 0)),
396 0);
397
398 if (plist) {
399 effect_list_iterate(plist, peffect) {
400 if (peffect->type == type) {
401 if (peffect->value > 0) {
402 if (unis == NULL
403 || !universals_mean_unfulfilled(&(peffect->reqs), unis, n_unis)) {
404 value += peffect->value;
405 }
406 } else if (requirement_vector_size(&peffect->reqs) == 0) {
407 /* Always active negative effect */
408 value += peffect->value;
409 }
410 }
411 } effect_list_iterate_end;
412 }
413
414 return value;
415}
416
417/**********************************************************************/
424 int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
425{
426 struct effect_list *plist = ruleset_cache.tracker;
427 int value = 0;
428
429 if (plist) {
430 effect_list_iterate(plist, peffect) {
431 if (peffect->type == type) {
432 if (peffect->value < 0) {
433 if (for_uni == NULL
434 || universal_fulfills_requirements(FALSE, &(peffect->reqs),
435 for_uni)) {
436 value += peffect->value;
437 }
438 } else if (requirement_vector_size(&peffect->reqs) == 0) {
439 /* Always active positive effect */
440 value += peffect->value;
441 }
442 }
443 } effect_list_iterate_end;
444 }
445
446 return value;
447}
448
449/**********************************************************************/
459 int effect_value_from_universals(enum effect_type type,
460 struct universal *unis, size_t n_unis)
461{
462 int value = 0;
463 struct effect_list *el = get_effects(type);
464
465 effect_list_iterate(el, peffect) {
466 bool effect_applies = TRUE;
467 bool first_source_mentioned = FALSE;
468
469 if (peffect->multiplier) {
470 /* Discount any effects with multipliers; we are looking for constant
471 * effects */
472 continue;
473 }
474
475 requirement_vector_iterate(&(peffect->reqs), preq) {
476 int i;
477 bool req_mentioned_a_source = FALSE;
478
479 for (i = 0; effect_applies && i < n_unis; i++) {
480 switch (universal_fulfills_requirement(preq, &(unis[i]))) {
481 case ITF_NOT_APPLICABLE:
482 /* This req not applicable to this source (but might be relevant
483 * to another source in our template). Keep looking. */
484 break;
485 case ITF_NO:
486 req_mentioned_a_source = TRUE; /* this req matched this source */
487 if (preq->present) {
488 /* Requirement contradicts template. Effect doesn't apply. */
489 effect_applies = FALSE;
490 } /* but negative req doesn't count for first_source_mentioned */
491 break;
492 case ITF_YES:
493 req_mentioned_a_source = TRUE; /* this req matched this source */
494 if (preq->present) {
495 if (i == 0) {
496 first_source_mentioned = TRUE;
497 }
498 /* keep looking */
499 } else /* !present */ {
500 /* Requirement contradicts template. Effect doesn't apply. */
501 effect_applies = FALSE;
502 }
503 break;
504 }
505 }
506 if (!req_mentioned_a_source) {
507 /* This requirement isn't relevant to any source in our template,
508 * so it's an extra condition and the effect should be ignored. */
509 effect_applies = FALSE;
510 }
511 if (!effect_applies) {
512 /* Already known to be irrelevant, bail out early */
513 break;
514 }
515 } requirement_vector_iterate_end;
516
517 if (!first_source_mentioned) {
518 /* First source not positively mentioned anywhere in requirements,
519 * so ignore this effect */
520 continue;
521 }
522 if (effect_applies) {
523 value += peffect->value;
524 }
525 } effect_list_iterate_end;
526
527 return value;
528}
529
530/**********************************************************************/
545 bool effect_universals_value_never_below(enum effect_type type,
546 struct universal *unis,
547 size_t n_unis,
548 int min_value)
549{
550 int guaranteed_min_effect_value = 0;
551
552 effect_list_iterate(get_effects(type), peffect) {
553 if (universals_mean_unfulfilled(&peffect->reqs, unis, n_unis)) {
554 /* Not relevant. */
555 continue;
556 }
557
558 if (peffect->multiplier) {
559 /* Multipliers may change during the game. */
560 return FALSE;
561 }
562
563 if (universals_say_everything(&peffect->reqs, unis, n_unis)) {
564 /* This value is guaranteed to be there since the universals alone
565 * fulfill all the requirements in the vector. */
566 guaranteed_min_effect_value += peffect->value;
567 } else if (peffect->value < 0) {
568 /* Can't be ignored. It may apply. It subtracts. */
569 guaranteed_min_effect_value += peffect->value;
570 }
571 } effect_list_iterate_end;
572
573 /* The value of this effect type is never below the guaranteed
574 * minimum. */
575 return guaranteed_min_effect_value >= min_value;
576}
577
578/**********************************************************************/
582 int effect_value_will_make_positive(enum effect_type type)
583{
584 return 1 + (effect_cumulative_min(type, NULL) * -1);
585}
586
587/**********************************************************************/
591 void recv_ruleset_effect(const struct packet_ruleset_effect *packet)
592{
593 struct effect *peffect;
594 struct multiplier *pmul;
595 int i;
596
597 pmul = packet->has_multiplier ? multiplier_by_number(packet->multiplier)
598 : NULL;
599 peffect = effect_new(packet->effect_type, packet->effect_value, pmul);
600
601 for (i = 0; i < packet->reqs_count; i++) {
602 effect_req_append(peffect, packet->reqs[i]);
603 }
604 fc_assert(peffect->reqs.size == packet->reqs_count);
605}
606
607/**********************************************************************/
610 void send_ruleset_cache(struct conn_list *dest)
611{
612 effect_list_iterate(ruleset_cache.tracker, peffect) {
613 struct packet_ruleset_effect effect_packet;
614 int counter;
615
616 effect_packet.effect_type = peffect->type;
617 effect_packet.effect_value = peffect->value;
618 if (peffect->multiplier) {
619 effect_packet.has_multiplier = TRUE;
620 effect_packet.multiplier = multiplier_number(peffect->multiplier);
621 } else {
622 effect_packet.has_multiplier = FALSE;
623 effect_packet.multiplier = 0; /* arbitrary */
624 }
625
626 counter = 0;
627 requirement_vector_iterate(&(peffect->reqs), req) {
628 effect_packet.reqs[counter++] = *req;
629 } requirement_vector_iterate_end;
630 effect_packet.reqs_count = counter;
631
632 lsend_packet_ruleset_effect(dest, &effect_packet);
633 } effect_list_iterate_end;
634}
635
636/**********************************************************************/
644 bool building_has_effect(const struct impr_type *pimprove,
645 enum effect_type effect_type)
646{
647 struct universal source = {
648 .kind = VUT_IMPROVEMENT,
649 /* just to bamboozle the annoying compiler warning */
650 .value = {.building = improvement_by_number(improvement_number(pimprove))}
651 };
652 struct effect_list *plist = get_req_source_effects(&source);
653
654 if (!plist) {
655 return FALSE;
656 }
657
658 effect_list_iterate(plist, peffect) {
659 if (peffect->type == effect_type) {
660 return TRUE;
661 }
662 } effect_list_iterate_end;
663
664 return FALSE;
665}
666
667/**********************************************************************/
675 static bool is_effect_prevented(const struct req_context *context,
676 const struct player *other_player,
677 const struct effect *peffect,
678 const enum req_problem_type prob_type)
679{
680 requirement_vector_iterate(&peffect->reqs, preq) {
681 /* Only check present=FALSE requirements; these will return _FALSE_
682 * from is_req_active() if met, and need reversed prob_type */
683 if (!preq->present
684 && !is_req_active(context, other_player,
685 preq, REVERSED_RPT(prob_type))) {
686 return TRUE;
687 }
688 } requirement_vector_iterate_end;
689
690 return FALSE;
691}
692
693/**********************************************************************/
698 bool is_building_replaced(const struct city *pcity,
699 const struct impr_type *pimprove,
700 const enum req_problem_type prob_type)
701{
702 struct effect_list *plist;
703 struct universal source = {
704 .kind = VUT_IMPROVEMENT,
705 .value = {.building = pimprove}
706 };
707
708 plist = get_req_source_effects(&source);
709
710 /* A building with no effects and no flags is always redundant! */
711 if (!plist) {
712 return TRUE;
713 }
714
715 effect_list_iterate(plist, peffect) {
716 /* We use TARGET_BUILDING as the lowest common denominator. Note that
717 * the building is its own target - but whether this is actually
718 * checked depends on the range of the effect. */
719 /* Prob_type is not reversed here. disabled is equal to replaced, not
720 * reverse */
721 if (!is_effect_prevented(&(const struct req_context) {
722 .player = city_owner(pcity),
723 .city = pcity,
724 .building = pimprove,
725 },
726 NULL,
727 peffect, prob_type)) {
728 return FALSE;
729 }
730 } effect_list_iterate_end;
731
732 return TRUE;
733}
734
735/**********************************************************************/
748 int get_target_bonus_effects(struct effect_list *plist,
749 const struct req_context *context,
750 const struct player *other_player,
751 enum effect_type effect_type)
752{
753 int bonus = 0;
754
755 if (context == NULL) {
756 context = req_context_empty();
757 }
758
759 /* Loop over all effects of this type. */
760 effect_list_iterate(get_effects(effect_type), peffect) {
761 /* For each effect, see if it is active. */
762 if (are_reqs_active(context, other_player,
763 &peffect->reqs, RPT_CERTAIN)) {
764 /* This code will add value of effect. If there's multiplier for
765 * effect and target_player aren't null, then value is multiplied
766 * by player's multiplier factor. */
767 if (peffect->multiplier) {
768 if (context->player) {
769 bonus += (peffect->value
770 * player_multiplier_effect_value(context->player,
771 peffect->multiplier)) / 100;
772 }
773 } else {
774 bonus += peffect->value;
775 }
776
777 if (plist) {
778 effect_list_append(plist, peffect);
779 }
780 }
781 } effect_list_iterate_end;
782
783 return bonus;
784}
785
786/**********************************************************************/
793 double get_effect_expected_value(const struct req_context *context,
794 const struct player *other_player,
795 enum effect_type effect_type,
796 eft_value_filter_cb weighter,
797 void *data, int n_data)
798{
799 double sum = 0.;
800
801 if (context == NULL) {
802 context = req_context_empty();
803 }
804
805 /* Loop over all effects of this type. */
806 effect_list_iterate(get_effects(effect_type), peffect) {
807 sum += weighter(peffect, context, other_player, data, n_data);
808 } effect_list_iterate_end;
809
810 return sum;
811}
812
813/**********************************************************************/
816 int get_world_bonus(enum effect_type effect_type)
817{
818 if (!initialized) {
819 return 0;
820 }
821
822 return get_target_bonus_effects(NULL, NULL, NULL, effect_type);
823}
824
825/**********************************************************************/
828 int get_player_bonus(const struct player *pplayer,
829 enum effect_type effect_type)
830{
831 if (!initialized) {
832 return 0;
833 }
834
835 return get_target_bonus_effects(NULL,
836 &(const struct req_context) {
837 .player = pplayer,
838 },
839 NULL,
840 effect_type);
841}
842
843/**********************************************************************/
846 int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
847{
848 if (!initialized) {
849 return 0;
850 }
851
852 return get_target_bonus_effects(NULL,
853 &(const struct req_context) {
854 .player = city_owner(pcity),
855 .city = pcity,
856 .tile = city_tile(pcity),
857 },
858 NULL, effect_type);
859}
860
861/**********************************************************************/
866 int get_tile_bonus(const struct tile *ptile, enum effect_type effect_type)
867{
868 if (!initialized) {
869 return 0;
870 }
871
872 return get_target_bonus_effects(NULL,
873 &(const struct req_context) {
874 .player = tile_owner(ptile),
875 .city = tile_city(ptile),
876 .tile = ptile,
877 },
878 NULL,
879 effect_type);
880}
881
882/**********************************************************************/
885 int get_city_specialist_output_bonus(const struct city *pcity,
886 const struct specialist *pspecialist,
887 const struct output_type *poutput,
888 enum effect_type effect_type)
889{
890 fc_assert_ret_val(pcity != NULL, 0);
891 fc_assert_ret_val(pspecialist != NULL, 0);
892 fc_assert_ret_val(poutput != NULL, 0);
893 return get_target_bonus_effects(NULL,
894 &(const struct req_context) {
895 .player = city_owner(pcity),
896 .city = pcity,
897 .output = poutput,
898 .specialist = pspecialist,
899 },
900 NULL,
901 effect_type);
902}
903
904/**********************************************************************/
916 int get_city_tile_output_bonus(const struct city *pcity,
917 const struct tile *ptile,
918 const struct output_type *poutput,
919 enum effect_type effect_type)
920{
921 fc_assert_ret_val(pcity != NULL, 0);
922 return get_target_bonus_effects(NULL,
923 &(const struct req_context) {
924 .player = city_owner(pcity),
925 .city = pcity,
926 .tile = ptile,
927 .output = poutput,
928 },
929 NULL,
930 effect_type);
931}
932
933/**********************************************************************/
940 int get_tile_output_bonus(const struct city *pcity,
941 const struct tile *ptile,
942 const struct output_type *poutput,
943 enum effect_type effect_type)
944{
945 const struct player *pplayer = pcity ? city_owner(pcity) : NULL;
946
947 return get_target_bonus_effects(NULL,
948 &(const struct req_context) {
949 .player = pplayer,
950 .city = pcity,
951 .tile = ptile,
952 .output = poutput,
953 },
954 NULL,
955 effect_type);
956}
957
958/**********************************************************************/
961 int get_player_output_bonus(const struct player *pplayer,
962 const struct output_type *poutput,
963 enum effect_type effect_type)
964{
965 if (!initialized) {
966 return 0;
967 }
968
969 fc_assert_ret_val(pplayer != NULL, 0);
970 fc_assert_ret_val(poutput != NULL, 0);
971 fc_assert_ret_val(effect_type != EFT_COUNT, 0);
972 return get_target_bonus_effects(NULL,
973 &(const struct req_context) {
974 .player = pplayer,
975 .output= poutput,
976 },
977 NULL,
978 effect_type);
979}
980
981/**********************************************************************/
984 int get_city_output_bonus(const struct city *pcity,
985 const struct output_type *poutput,
986 enum effect_type effect_type)
987{
988 if (!initialized) {
989 return 0;
990 }
991
992 fc_assert_ret_val(pcity != NULL, 0);
993 fc_assert_ret_val(poutput != NULL, 0);
994 fc_assert_ret_val(effect_type != EFT_COUNT, 0);
995 return get_target_bonus_effects(NULL,
996 &(const struct req_context) {
997 .player = city_owner(pcity),
998 .city = pcity,
999 .output = poutput,
1000 },
1001 NULL,
1002 effect_type);
1003}
1004
1005/**********************************************************************/
1008 int get_building_bonus(const struct city *pcity,
1009 const struct impr_type *building,
1010 enum effect_type effect_type)
1011{
1012 if (!initialized) {
1013 return 0;
1014 }
1015
1016 fc_assert_ret_val(NULL != pcity && NULL != building, 0);
1017 return get_target_bonus_effects(NULL,
1018 &(const struct req_context) {
1019 .player = city_owner(pcity),
1020 .city = pcity,
1021 .building = building,
1022 },
1023 NULL,
1024 effect_type);
1025}
1026
1027/**********************************************************************/
1035 int get_unittype_bonus(const struct player *pplayer,
1036 const struct tile *ptile,
1037 const struct unit_type *punittype,
1038 const struct action *paction,
1039 enum effect_type effect_type)
1040{
1041 struct city *pcity;
1042
1043 if (!initialized) {
1044 return 0;
1045 }
1046
1047 fc_assert_ret_val(punittype != nullptr, 0);
1048
1049 if (ptile != nullptr) {
1050 pcity = tile_city(ptile);
1051 } else {
1052 pcity = nullptr;
1053 }
1054
1055 return get_target_bonus_effects(nullptr,
1056 &(const struct req_context) {
1057 .player = pplayer,
1058 .city = pcity,
1059 .tile = ptile,
1060 .unittype = punittype,
1061 .action = paction,
1062 },
1063 nullptr,
1064 effect_type);
1065}
1066
1067/**********************************************************************/
1070 int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
1071{
1072 if (!initialized) {
1073 return 0;
1074 }
1075
1076 fc_assert_ret_val(punit != NULL, 0);
1077 return get_target_bonus_effects(NULL,
1078 &(const struct req_context) {
1079 .player = unit_owner(punit),
1080 .city = unit_tile(punit)
1081 ? tile_city(unit_tile(punit))
1082 : NULL,
1083 .tile = unit_tile(punit),
1084 .unit = punit,
1085 .unittype = unit_type_get(punit),
1086 },
1087 NULL,
1088 effect_type);
1089}
1090
1091/**********************************************************************/
1094 int get_unit_vs_tile_bonus(const struct tile *ptile,
1095 const struct unit *punit,
1096 enum effect_type etype)
1097{
1098 struct player *pplayer = NULL;
1099 const struct unit_type *utype = NULL;
1100
1101 if (!initialized) {
1102 return 0;
1103 }
1104
1105 fc_assert_ret_val(ptile != NULL, 0);
1106
1107 if (punit != NULL) {
1108 pplayer = unit_owner(punit);
1109 utype = unit_type_get(punit);
1110 }
1111
1112 return get_target_bonus_effects(NULL,
1113 &(const struct req_context) {
1114 .player = pplayer,
1115 .city = tile_city(ptile),
1116 .tile = ptile,
1117 .unit = punit,
1118 .unittype = utype,
1119 },
1120 tile_owner(ptile),
1121 etype);
1122}
1123
1124/**********************************************************************/
1130 int get_player_bonus_effects(struct effect_list *plist,
1131 const struct player *pplayer,
1132 enum effect_type effect_type)
1133{
1134 if (!initialized) {
1135 return 0;
1136 }
1137
1138 fc_assert_ret_val(pplayer != NULL, 0);
1139 return get_target_bonus_effects(plist,
1140 &(const struct req_context) {
1141 .player = pplayer,
1142 },
1143 NULL,
1144 effect_type);
1145}
1146
1147/**********************************************************************/
1153 int get_city_bonus_effects(struct effect_list *plist,
1154 const struct city *pcity,
1155 const struct output_type *poutput,
1156 enum effect_type effect_type)
1157{
1158 if (!initialized) {
1159 return 0;
1160 }
1161
1162 fc_assert_ret_val(pcity != NULL, 0);
1163 return get_target_bonus_effects(plist,
1164 &(const struct req_context) {
1165 .player = city_owner(pcity),
1166 .city = pcity,
1167 .output = poutput,
1168 },
1169 NULL,
1170 effect_type);
1171}
1172
1173/**********************************************************************/
1182 int get_current_construction_bonus(const struct city *pcity,
1183 enum effect_type effect_type,
1184 const enum req_problem_type prob_type)
1185{
1186 if (!initialized) {
1187 return 0;
1188 }
1189
1190 if (VUT_IMPROVEMENT == pcity->production.kind) {
1191 return get_potential_improvement_bonus(pcity->production.value.building,
1192 pcity, effect_type, prob_type, TRUE);
1193 }
1194
1195 return 0;
1196}
1197
1198/**********************************************************************/
1204 int get_potential_improvement_bonus(const struct impr_type *pimprove,
1205 const struct city *pcity,
1206 enum effect_type effect_type,
1207 const enum req_problem_type prob_type,
1208 bool consider_multipliers)
1209{
1210 struct universal source = { .kind = VUT_IMPROVEMENT,
1211 .value = {.building = pimprove}};
1212 struct effect_list *plist = get_req_source_effects(&source);
1213 struct player *owner = NULL;
1214
1215 if (pcity != NULL) {
1216 owner = city_owner(pcity);
1217 }
1218
1219 if (plist) {
1220 int power = 0;
1221 const struct req_context context = {
1222 .player = owner,
1223 .city = pcity,
1224 .building = pimprove,
1225 };
1226
1227 effect_list_iterate(plist, peffect) {
1228 bool present = TRUE;
1229 bool useful = TRUE;
1230
1231 if (peffect->type != effect_type) {
1232 continue;
1233 }
1234
1235 requirement_vector_iterate(&peffect->reqs, preq) {
1236 if (VUT_IMPROVEMENT == preq->source.kind
1237 && preq->source.value.building == pimprove) {
1238 present = preq->present;
1239 continue;
1240 }
1241
1242 if (!is_req_active(&context, NULL, preq, prob_type)) {
1243 useful = FALSE;
1244 break;
1245 }
1246 } requirement_vector_iterate_end;
1247
1248 if (useful) {
1249 int val;
1250
1251 if (present) {
1252 val = peffect->value;
1253 } else {
1254 val = -peffect->value;
1255 }
1256
1257 if (consider_multipliers && peffect->multiplier) {
1258 val = val * player_multiplier_effect_value(owner, peffect->multiplier) / 100;
1259 }
1260
1261 power += val;
1262 }
1263 } effect_list_iterate_end;
1264
1265 return power;
1266 }
1267
1268 return 0;
1269}
1270
1271/**********************************************************************/
1275 void get_effect_req_text(const struct effect *peffect,
1276 char *buf, size_t buf_len)
1277{
1278 buf[0] = '\0';
1279
1280 if (peffect->multiplier) {
1281 fc_strlcat(buf, multiplier_name_translation(peffect->multiplier), buf_len);
1282 }
1283
1284 /* FIXME: should we do something for present FALSE reqs?
1285 * Currently we just ignore them. */
1286 requirement_vector_iterate(&peffect->reqs, preq) {
1287 if (!preq->present) {
1288 continue;
1289 }
1290 if (buf[0] != '\0') {
1291 fc_strlcat(buf, Q_("?req-list-separator:+"), buf_len);
1292 }
1293
1294 universal_name_translation(&preq->source,
1295 buf + strlen(buf), buf_len - strlen(buf));
1296 } requirement_vector_iterate_end;
1297}
1298
1299/**********************************************************************/
1303 void get_effect_list_req_text(const struct effect_list *plist,
1304 struct astring *astr)
1305{
1306 struct strvec *psv = strvec_new();
1307 char req_text[512];
1308
1309 effect_list_iterate(plist, peffect) {
1310 get_effect_req_text(peffect, req_text, sizeof(req_text));
1311 strvec_append(psv, req_text);
1312 } effect_list_iterate_end;
1313
1314 strvec_to_and_list(psv, astr);
1315 strvec_destroy(psv);
1316}
1317
1318/**********************************************************************/
1323 bool iterate_effect_cache(iec_cb cb, void *data)
1324{
1325 fc_assert_ret_val(cb != NULL, FALSE);
1326
1327 effect_list_iterate(ruleset_cache.tracker, peffect) {
1328 if (!cb(peffect, data)) {
1329 return FALSE;
1330 }
1331 } effect_list_iterate_end;
1332
1333 return TRUE;
1334}
1335
1336/**********************************************************************/
1339 bool is_user_effect(enum effect_type eff)
1340{
1341 return eff >= EFT_USER_EFFECT_1 && eff <= EFT_USER_EFFECT_LAST;
1342}
1343
1344/**********************************************************************/
1348 void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
1349{
1350 fc_assert(is_user_effect(tgt));
1351
1352 ueffects[USER_EFFECT_NUMBER(tgt)].ai_value_as = valued_as;
1353}
1354
1355/**********************************************************************/
1359 enum effect_type user_effect_ai_valued_as(enum effect_type real)
1360{
1361 /* Client doesn't know these. */
1362 fc_assert(is_server());
1363
1364 if (!is_user_effect(real)) {
1365 return real;
1366 }
1367
1368 if (!is_user_effect(ueffects[USER_EFFECT_NUMBER(real)].ai_value_as)) {
1369 return ueffects[USER_EFFECT_NUMBER(real)].ai_value_as;
1370 }
1371
1372 return real;
1373}
astring.h
city.h
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_owner
#define city_owner(_pcity_)
Definition city.h:563
incite_cost
char * incite_cost
Definition comments.c:74
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
effect_remove
void effect_remove(struct effect *peffect)
Definition effects.c:230
recv_ruleset_effect
void recv_ruleset_effect(const struct packet_ruleset_effect *packet)
Definition effects.c:591
effects
struct effect_list * effects[EFT_COUNT]
Definition effects.c:127
govs
struct effect_list * govs[G_LAST]
Definition effects.c:133
tracker
struct effect_list * tracker
Definition effects.c:123
ueffects
struct user_effect ueffects[EFT_USER_EFFECT_LAST+1 - EFT_USER_EFFECT_1]
Definition effects.c:48
effect_universals_value_never_below
bool effect_universals_value_never_below(enum effect_type type, struct universal *unis, size_t n_unis, int min_value)
Definition effects.c:545
reqs
struct @21::@22 reqs
get_tile_output_bonus
int get_tile_output_bonus(const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:940
get_player_output_bonus
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:961
get_city_specialist_output_bonus
int get_city_specialist_output_bonus(const struct city *pcity, const struct specialist *pspecialist, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:885
is_building_replaced
bool is_building_replaced(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Definition effects.c:698
get_target_bonus_effects
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:748
get_player_bonus_effects
int get_player_bonus_effects(struct effect_list *plist, const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:1130
iterate_effect_cache
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1323
get_city_bonus
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:846
get_current_construction_bonus
int get_current_construction_bonus(const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type)
Definition effects.c:1182
get_city_bonus_effects
int get_city_bonus_effects(struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:1153
is_effect_prevented
static bool is_effect_prevented(const struct req_context *context, const struct player *other_player, const struct effect *peffect, const enum req_problem_type prob_type)
Definition effects.c:675
get_unit_vs_tile_bonus
int get_unit_vs_tile_bonus(const struct tile *ptile, const struct unit *punit, enum effect_type etype)
Definition effects.c:1094
get_unit_bonus
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:1070
get_city_output_bonus
int get_city_output_bonus(const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:984
get_potential_improvement_bonus
int get_potential_improvement_bonus(const struct impr_type *pimprove, const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type, bool consider_multipliers)
Definition effects.c:1204
send_ruleset_cache
void send_ruleset_cache(struct conn_list *dest)
Definition effects.c:610
get_effect_req_text
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Definition effects.c:1275
ruleset_cache
static struct @21 ruleset_cache
buildings
struct effect_list * buildings[B_LAST]
Definition effects.c:131
ruleset_cache_free
void ruleset_cache_free(void)
Definition effects.c:329
effect_new
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Definition effects.c:186
get_building_bonus
int get_building_bonus(const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
Definition effects.c:1008
effect_value_from_universals
int effect_value_from_universals(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:459
get_city_tile_output_bonus
int get_city_tile_output_bonus(const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:916
user_effect_ai_valued_set
void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
Definition effects.c:1348
effect_copy
struct effect * effect_copy(struct effect *old, enum effect_type override_type)
Definition effects.c:246
effect_cumulative_max
int effect_cumulative_max(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:388
effect_free
void effect_free(struct effect *peffect)
Definition effects.c:216
ruleset_cache_init
void ruleset_cache_init(void)
Definition effects.c:297
advances
struct effect_list * advances[A_LAST]
Definition effects.c:135
get_world_bonus
int get_world_bonus(enum effect_type effect_type)
Definition effects.c:816
effect_cumulative_min
int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
Definition effects.c:424
get_effects
struct effect_list * get_effects(enum effect_type effect_type)
Definition effects.c:143
get_req_source_effects
struct effect_list * get_req_source_effects(const struct universal *psource)
Definition effects.c:153
user_effect_ai_valued_as
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1359
building_has_effect
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:644
get_effect_expected_value
double get_effect_expected_value(const struct req_context *context, const struct player *other_player, enum effect_type effect_type, eft_value_filter_cb weighter, void *data, int n_data)
Definition effects.c:793
initialized
static bool initialized
Definition effects.c:42
effect_req_append
void effect_req_append(struct effect *peffect, struct requirement req)
Definition effects.c:266
get_tile_bonus
int get_tile_bonus(const struct tile *ptile, enum effect_type effect_type)
Definition effects.c:866
get_unittype_bonus
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:1035
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
get_effect_list_req_text
void get_effect_list_req_text(const struct effect_list *plist, struct astring *astr)
Definition effects.c:1303
is_user_effect
bool is_user_effect(enum effect_type eff)
Definition effects.c:1339
effect_value_will_make_positive
int effect_value_will_make_positive(enum effect_type type)
Definition effects.c:582
effects.h
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:81
USER_EFFECT_NUMBER
#define USER_EFFECT_NUMBER(eff)
Definition effects.h:35
eft_value_filter_cb
double(* eft_value_filter_cb)(const struct effect *eft, const struct req_context *context, const struct player *other_player, void *data, int n_data)
Definition effects.h:70
iec_cb
bool(* iec_cb)(struct effect *, void *data)
Definition effects.h:194
EFT_USER_EFFECT_LAST
#define EFT_USER_EFFECT_LAST
Definition effects.h:33
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:79
is_server
static bool is_server(void)
Definition fc_interface.h:69
req_problem_type
req_problem_type
Definition fc_types.h:706
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:708
REVERSED_RPT
#define REVERSED_RPT(x)
Definition fc_types.h:711
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
game.h
government_count
Government_type_id government_count(void)
Definition government.c:71
government.h
G_LAST
#define G_LAST
Definition government.h:48
owner
struct city * owner
Definition citydlg.c:220
source
static GtkWidget * source
Definition gotodlg.c:58
type
GType type
Definition repodlgs.c:1313
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:194
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:184
improvement_has_flag
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Definition improvement.c:383
improvement_count
Impr_type_id improvement_count(void)
Definition improvement.c:164
improvement.h
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:205
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:199
B_LAST
#define B_LAST
Definition improvement.h:42
log.h
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
map.h
mem.h
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
multiplier_name_translation
const char * multiplier_name_translation(const struct multiplier *pmul)
Definition multipliers.c:97
multiplier_number
Multiplier_type_id multiplier_number(const struct multiplier *pmul)
Definition multipliers.c:67
multiplier_by_number
struct multiplier * multiplier_by_number(Multiplier_type_id id)
Definition multipliers.c:57
packets.h
lsend_packet_ruleset_effect
void lsend_packet_ruleset_effect(struct conn_list *dest, const struct packet_ruleset_effect *packet)
Definition packets_gen.c:78200
player_multiplier_effect_value
int player_multiplier_effect_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1973
player.h
req_context_empty
const struct req_context * req_context_empty(void)
Definition requirements.c:1011
universal_extraction
void universal_extraction(const struct universal *source, int *kind, int *value)
Definition requirements.c:871
universal_fulfills_requirements
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
Definition requirements.c:7473
is_req_active
bool is_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req, const enum req_problem_type prob_type)
Definition requirements.c:5616
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:5705
universal_fulfills_requirement
enum req_item_found universal_fulfills_requirement(const struct requirement *preq, const struct universal *source)
Definition requirements.c:7452
universals_say_everything
bool universals_say_everything(struct requirement_vector *reqs, struct universal *unis, size_t n_unis)
Definition requirements.c:7415
universal_name_translation
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Definition requirements.c:6962
universals_mean_unfulfilled
bool universals_mean_unfulfilled(struct requirement_vector *reqs, struct universal *unis, size_t n_unis)
Definition requirements.c:7382
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
ITF_NO
@ ITF_NO
Definition requirements.h:378
ITF_YES
@ ITF_YES
Definition requirements.h:378
ITF_NOT_APPLICABLE
@ ITF_NOT_APPLICABLE
Definition requirements.h:378
shared.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
strvec_destroy
void strvec_destroy(struct strvec *psv)
Definition string_vector.c:72
strvec_append
void strvec_append(struct strvec *psv, const char *string)
Definition string_vector.c:279
strvec_new
struct strvec * strvec_new(void)
Definition string_vector.c:59
strvec_to_and_list
const char * strvec_to_and_list(const struct strvec *psv, struct astring *astr)
Definition string_vector.c:443
string_vector.h
action
Definition actions.h:106
astring
Definition astring.h:36
city
Definition city.h:320
city::production
struct universal production
Definition city.h:396
city::tile
struct tile * tile
Definition city.h:322
counter
Definition counters.h:27
counter::type
enum counter_behaviour type
Definition counters.h:31
effect
Definition effects.h:40
effect::value
int value
Definition effects.h:49
effect::multiplier
struct multiplier * multiplier
Definition effects.h:44
effect::reqs
struct requirement_vector reqs
Definition effects.h:53
effect::type
enum effect_type type
Definition effects.h:41
impr_type
Definition improvement.h:50
multiplier
Definition multipliers.h:31
output_type
Definition city.h:259
packet_ruleset_effect
Definition packets_gen.h:1598
packet_ruleset_effect::reqs_count
int reqs_count
Definition packets_gen.h:1603
packet_ruleset_effect::reqs
struct requirement reqs[MAX_NUM_REQS]
Definition packets_gen.h:1604
packet_ruleset_effect::multiplier
Multiplier_type_id multiplier
Definition packets_gen.h:1602
packet_ruleset_effect::effect_value
int effect_value
Definition packets_gen.h:1600
packet_ruleset_effect::has_multiplier
bool has_multiplier
Definition packets_gen.h:1601
packet_ruleset_effect::effect_type
enum effect_type effect_type
Definition packets_gen.h:1599
player
Definition player.h:249
req_context
Definition requirements.h:100
req_context::player
const struct player * player
Definition requirements.h:101
requirement
Definition requirements.h:81
requirement::source
struct universal source
Definition requirements.h:82
specialist
Definition specialist.h:29
strvec
Definition string_vector.c:29
tile
Definition tile.h:50
unit_type
Definition unittype.h:507
unit
Definition unit.h:140
universal
Definition fc_types.h:908
universal::kind
enum universals_n kind
Definition fc_types.h:910
universal::value
universals_u value
Definition fc_types.h:909
user_effect
Definition effects.c:44
user_effect::ai_value_as
enum effect_type ai_value_as
Definition effects.c:45
fc_strlcat
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:822
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
tech.h
advance_count
static Tech_type_id advance_count(void)
Definition tech.h:170
A_LAST
#define A_LAST
Definition tech.h:45
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_owner
#define tile_owner(_tile)
Definition tile.h:97
universals_u::impr_flag
enum impr_flag_id impr_flag
Definition fc_types.h:759
universals_u::building
const struct impr_type * building
Definition fc_types.h:721
unit_tile
#define unit_tile(_pu)
Definition unit.h:397
unit_owner
#define unit_owner(_pu)
Definition unit.h:396
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123