Freeciv-3.2
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
42static bool initialized = FALSE;
43
45 enum effect_type ai_value_as;
46};
47
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. */
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.) */
128
129 struct {
130 /* This cache shows for each building, which effects it provides. */
132 /* Same for governments */
134 /* ...advances... */
138
139
140/**********************************************************************/
143struct effect_list *get_effects(enum effect_type effect_type)
144{
145 return ruleset_cache.effects[effect_type];
146}
147
148/**********************************************************************/
154{
155 int type, value;
156
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/**********************************************************************/
186struct 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
198
199 /* Now add the effect to the ruleset cache. */
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/**********************************************************************/
217{
219 if (peffect->rulesave.comment != NULL) {
220 free(peffect->rulesave.comment);
221 }
222 free(peffect);
223}
224
225/**********************************************************************/
235
236/**********************************************************************/
246struct 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)
252 : old->type);
253
254 new_eff = effect_new(type, old->value, old->multiplier);
255
259
260 return new_eff;
261}
262
263/**********************************************************************/
267{
269
271
272 if (eff_list != NULL) {
274 }
275
276 if (req.source.kind == VUT_IMPR_FLAG) {
277 improvement_iterate(impr) {
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) {
286 }
287 }
289 }
290}
291
292/**********************************************************************/
298{
299 int i;
300
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++) {
322 }
323}
324
325/**********************************************************************/
330{
331 int i;
332 struct effect_list *tracker_list = ruleset_cache.tracker;
333
334 if (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) {
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) {
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) {
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) {
374 ruleset_cache.reqs.advances[i] = NULL;
375 }
376 }
377
379}
380
381/**********************************************************************/
388int 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) {
400 if (peffect->type == type) {
401 if (peffect->value > 0) {
402 if (unis == NULL
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 }
412 }
413
414 return value;
415}
416
417/**********************************************************************/
424int 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) {
431 if (peffect->type == type) {
432 if (peffect->value < 0) {
433 if (for_uni == NULL
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 }
444 }
445
446 return value;
447}
448
449/**********************************************************************/
460 struct universal *unis, size_t n_unis)
461{
462 int value = 0;
463 struct effect_list *el = get_effects(type);
464
466 bool effect_applies = TRUE;
468
469 if (peffect->multiplier) {
470 /* Discount any effects with multipliers; we are looking for constant
471 * effects */
472 continue;
473 }
474
476 int i;
478
479 for (i = 0; effect_applies && i < n_unis; i++) {
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. */
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) {
497 }
498 /* keep looking */
499 } else /* !present */ {
500 /* Requirement contradicts template. Effect doesn't apply. */
502 }
503 break;
504 }
505 }
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. */
510 }
511 if (!effect_applies) {
512 /* Already known to be irrelevant, bail out early */
513 break;
514 }
516
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 }
526
527 return value;
528}
529
530/**********************************************************************/
546 struct universal *unis,
547 size_t n_unis,
548 int min_value)
549{
551
554 /* Not relevant. */
555 continue;
556 }
557
558 if (peffect->multiplier) {
559 /* Multipliers may change during the game. */
560 return FALSE;
561 }
562
564 /* This value is guaranteed to be there since the universals alone
565 * fulfill all the requirements in the vector. */
567 } else if (peffect->value < 0) {
568 /* Can't be ignored. It may apply. It subtracts. */
570 }
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/**********************************************************************/
583{
584 return 1 + (effect_cumulative_min(type, NULL) * -1);
585}
586
587/**********************************************************************/
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/**********************************************************************/
611{
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;
630 effect_packet.reqs_count = counter;
631
634}
635
636/**********************************************************************/
644bool building_has_effect(const struct impr_type *pimprove,
646{
647 struct universal source = {
649 /* just to bamboozle the annoying compiler warning */
650 .value = {.building = improvement_by_number(improvement_number(pimprove))}
651 };
653
654 if (!plist) {
655 return FALSE;
656 }
657
659 if (peffect->type == effect_type) {
660 return TRUE;
661 }
663
664 return FALSE;
665}
666
667/**********************************************************************/
675static 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{
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,
686 return TRUE;
687 }
689
690 return FALSE;
691}
692
693/**********************************************************************/
698bool 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 = {
705 .value = {.building = pimprove}
706 };
707
709
710 /* A building with no effects and no flags is always redundant! */
711 if (!plist) {
712 return TRUE;
713 }
714
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 }
731
732 return TRUE;
733}
734
735/**********************************************************************/
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) {
757 }
758
759 /* Loop over all effects of this type. */
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
771 peffect->multiplier)) / 100;
772 }
773 } else {
774 bonus += peffect->value;
775 }
776
777 if (plist) {
779 }
780 }
782
783 return bonus;
784}
785
786/**********************************************************************/
794 const struct player *other_player,
795 enum effect_type effect_type,
797 void *data, int n_data)
798{
799 double sum = 0.;
800
801 if (context == NULL) {
803 }
804
805 /* Loop over all effects of this type. */
807 sum += weighter(peffect, context, other_player, data, n_data);
809
810 return sum;
811}
812
813/**********************************************************************/
816int 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/**********************************************************************/
828int get_player_bonus(const struct player *pplayer,
829 enum effect_type effect_type)
830{
831 if (!initialized) {
832 return 0;
833 }
834
836 &(const struct req_context) {
837 .player = pplayer,
838 },
839 NULL,
840 effect_type);
841}
842
843/**********************************************************************/
846int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
847{
848 if (!initialized) {
849 return 0;
850 }
851
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/**********************************************************************/
866int get_tile_bonus(const struct tile *ptile, enum effect_type effect_type)
867{
868 if (!initialized) {
869 return 0;
870 }
871
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/**********************************************************************/
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);
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/**********************************************************************/
916int 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);
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/**********************************************************************/
940int 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
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/**********************************************************************/
961int 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);
971 fc_assert_ret_val(effect_type != EFT_COUNT, 0);
973 &(const struct req_context) {
974 .player = pplayer,
975 .output= poutput,
976 },
977 NULL,
978 effect_type);
979}
980
981/**********************************************************************/
984int 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);
994 fc_assert_ret_val(effect_type != EFT_COUNT, 0);
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/**********************************************************************/
1008int 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);
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/**********************************************************************/
1035int 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(pplayer != NULL && punittype != NULL, 0);
1048
1049 if (ptile != NULL) {
1050 pcity = tile_city(ptile);
1051 } else {
1052 pcity = NULL;
1053 }
1054
1056 &(const struct req_context) {
1057 .player = pplayer,
1058 .city = pcity,
1059 .tile = ptile,
1060 .unittype = punittype,
1061 .action = paction,
1062 },
1063 NULL,
1064 effect_type);
1065}
1066
1067/**********************************************************************/
1070int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
1071{
1072 if (!initialized) {
1073 return 0;
1074 }
1075
1078 &(const struct req_context) {
1079 .player = unit_owner(punit),
1080 .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/**********************************************************************/
1094int 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
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/**********************************************************************/
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);
1140 &(const struct req_context) {
1141 .player = pplayer,
1142 },
1143 NULL,
1144 effect_type);
1145}
1146
1147/**********************************************************************/
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);
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/**********************************************************************/
1182int 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) {
1192 pcity, effect_type, prob_type, TRUE);
1193 }
1194
1195 return 0;
1196}
1197
1198/**********************************************************************/
1205 const struct city *pcity,
1206 enum effect_type effect_type,
1207 const enum req_problem_type prob_type,
1209{
1210 struct universal source = { .kind = VUT_IMPROVEMENT,
1211 .value = {.building = pimprove}};
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
1228 bool present = TRUE;
1229 bool useful = TRUE;
1230
1231 if (peffect->type != effect_type) {
1232 continue;
1233 }
1234
1236 if (VUT_IMPROVEMENT == preq->source.kind
1237 && preq->source.value.building == pimprove) {
1238 present = preq->present;
1239 continue;
1240 }
1241
1243 useful = FALSE;
1244 break;
1245 }
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 }
1264
1265 return power;
1266 }
1267
1268 return 0;
1269}
1270
1271/**********************************************************************/
1276 char *buf, size_t buf_len)
1277{
1278 buf[0] = '\0';
1279
1280 if (peffect->multiplier) {
1282 }
1283
1284 /* FIXME: should we do something for present FALSE reqs?
1285 * Currently we just ignore them. */
1287 if (!preq->present) {
1288 continue;
1289 }
1290 if (buf[0] != '\0') {
1291 fc_strlcat(buf, Q_("?req-list-separator:+"), buf_len);
1292 }
1293
1295 buf + strlen(buf), buf_len - strlen(buf));
1297}
1298
1299/**********************************************************************/
1304 struct astring *astr)
1305{
1306 struct strvec *psv = strvec_new();
1307 char req_text[512];
1308
1313
1316}
1317
1318/**********************************************************************/
1323bool iterate_effect_cache(iec_cb cb, void *data)
1324{
1326
1328 if (!cb(peffect, data)) {
1329 return FALSE;
1330 }
1332
1333 return TRUE;
1334}
1335
1336/**********************************************************************/
1339bool is_user_effect(enum effect_type eff)
1340{
1342}
1343
1344/**********************************************************************/
1348void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
1349{
1351
1353}
1354
1355/**********************************************************************/
1359enum effect_type user_effect_ai_valued_as(enum effect_type real)
1360{
1361 /* Client doesn't know these. */
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)) {
1370 }
1371
1372 return real;
1373}
#define city_tile(_pcity_)
Definition city.h:564
#define city_owner(_pcity_)
Definition city.h:563
char * incite_cost
Definition comments.c:75
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
void effect_remove(struct effect *peffect)
Definition effects.c:230
void recv_ruleset_effect(const struct packet_ruleset_effect *packet)
Definition effects.c:591
struct effect_list * effects[EFT_COUNT]
Definition effects.c:127
struct effect_list * govs[G_LAST]
Definition effects.c:133
struct effect_list * tracker
Definition effects.c:123
struct user_effect ueffects[EFT_USER_EFFECT_LAST+1 - EFT_USER_EFFECT_1]
Definition effects.c:48
bool effect_universals_value_never_below(enum effect_type type, struct universal *unis, size_t n_unis, int min_value)
Definition effects.c:545
struct @21::@22 reqs
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
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:961
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
bool is_building_replaced(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Definition effects.c:698
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
int get_player_bonus_effects(struct effect_list *plist, const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:1130
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1323
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:846
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
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
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
int get_unit_vs_tile_bonus(const struct tile *ptile, const struct unit *punit, enum effect_type etype)
Definition effects.c:1094
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:1070
int get_city_output_bonus(const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:984
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
void send_ruleset_cache(struct conn_list *dest)
Definition effects.c:610
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Definition effects.c:1275
static struct @21 ruleset_cache
struct effect_list * buildings[B_LAST]
Definition effects.c:131
void ruleset_cache_free(void)
Definition effects.c:329
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Definition effects.c:186
int get_building_bonus(const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
Definition effects.c:1008
int effect_value_from_universals(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:459
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
void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
Definition effects.c:1348
struct effect * effect_copy(struct effect *old, enum effect_type override_type)
Definition effects.c:246
int effect_cumulative_max(enum effect_type type, struct universal *unis, size_t n_unis)
Definition effects.c:388
void effect_free(struct effect *peffect)
Definition effects.c:216
void ruleset_cache_init(void)
Definition effects.c:297
struct effect_list * advances[A_LAST]
Definition effects.c:135
int get_world_bonus(enum effect_type effect_type)
Definition effects.c:816
int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
Definition effects.c:424
struct effect_list * get_effects(enum effect_type effect_type)
Definition effects.c:143
struct effect_list * get_req_source_effects(const struct universal *psource)
Definition effects.c:153
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1359
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:644
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
static bool initialized
Definition effects.c:42
void effect_req_append(struct effect *peffect, struct requirement req)
Definition effects.c:266
int get_tile_bonus(const struct tile *ptile, enum effect_type effect_type)
Definition effects.c:866
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
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
void get_effect_list_req_text(const struct effect_list *plist, struct astring *astr)
Definition effects.c:1303
bool is_user_effect(enum effect_type eff)
Definition effects.c:1339
int effect_value_will_make_positive(enum effect_type type)
Definition effects.c:582
#define effect_list_iterate_end
Definition effects.h:406
#define USER_EFFECT_NUMBER(eff)
Definition effects.h:360
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:395
bool(* iec_cb)(struct effect *, void *data)
Definition effects.h:519
#define EFT_USER_EFFECT_LAST
Definition effects.h:358
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:404
static bool is_server(void)
req_problem_type
Definition fc_types.h:699
@ RPT_CERTAIN
Definition fc_types.h:701
#define REVERSED_RPT(x)
Definition fc_types.h:704
#define Q_(String)
Definition fcintl.h:70
Government_type_id government_count(void)
Definition government.c:71
#define G_LAST
Definition government.h:48
struct city * owner
Definition citydlg.c:226
static GtkWidget * source
Definition gotodlg.c:58
GType type
Definition repodlgs.c:1313
struct impr_type * improvement_by_number(const Impr_type_id id)
Impr_type_id improvement_number(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Impr_type_id improvement_count(void)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define B_LAST
Definition improvement.h:42
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define fc_malloc(sz)
Definition mem.h:34
const char * multiplier_name_translation(const struct multiplier *pmul)
Definition multipliers.c:97
Multiplier_type_id multiplier_number(const struct multiplier *pmul)
Definition multipliers.c:67
struct multiplier * multiplier_by_number(Multiplier_type_id id)
Definition multipliers.c:57
void lsend_packet_ruleset_effect(struct conn_list *dest, const struct packet_ruleset_effect *packet)
int player_multiplier_effect_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1969
const struct req_context * req_context_empty(void)
void universal_extraction(const struct universal *source, int *kind, int *value)
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
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)
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)
enum req_item_found universal_fulfills_requirement(const struct requirement *preq, const struct universal *source)
bool universals_say_everything(struct requirement_vector *reqs, struct universal *unis, size_t n_unis)
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
bool universals_mean_unfulfilled(struct requirement_vector *reqs, struct universal *unis, size_t n_unis)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
@ ITF_NO
@ ITF_YES
@ ITF_NOT_APPLICABLE
#define ARRAY_SIZE(x)
Definition shared.h:85
void strvec_destroy(struct strvec *psv)
void strvec_append(struct strvec *psv, const char *string)
struct strvec * strvec_new(void)
const char * strvec_to_and_list(const struct strvec *psv, struct astring *astr)
Definition city.h:320
struct universal production
Definition city.h:396
struct tile * tile
Definition city.h:322
enum counter_behaviour type
Definition counters.h:31
int value
Definition effects.h:374
struct multiplier * multiplier
Definition effects.h:369
struct requirement_vector reqs
Definition effects.h:378
enum effect_type type
Definition effects.h:366
struct requirement reqs[MAX_NUM_REQS]
Multiplier_type_id multiplier
enum effect_type effect_type
const struct player * player
struct universal source
Definition tile.h:50
Definition unit.h:138
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
enum effect_type ai_value_as
Definition effects.c:45
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:836
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
static Tech_type_id advance_count(void)
Definition tech.h:170
#define A_LAST
Definition tech.h:45
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_owner(_tile)
Definition tile.h:96
enum impr_flag_id impr_flag
Definition fc_types.h:752
const struct impr_type * building
Definition fc_types.h:714
#define unit_tile(_pu)
Definition unit.h:397
#define unit_owner(_pu)
Definition unit.h:396
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123