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
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
596 pmul = packet->has_multiplier ? multiplier_by_number(packet->multiplier)
597 : NULL;
598 peffect = effect_new(packet->effect_type, packet->effect_value, pmul);
599
603 fc_assert(peffect->reqs.size == packet->reqs.size);
604}
605
606/**********************************************************************/
610{
613
615 effect_packet.effect_value = peffect->value;
616 if (peffect->multiplier) {
617 effect_packet.has_multiplier = TRUE;
618 effect_packet.multiplier = multiplier_number(peffect->multiplier);
619 } else {
620 effect_packet.has_multiplier = FALSE;
621 effect_packet.multiplier = 0; /* arbitrary */
622 }
623
624 /* Shallow-copy (borrow) requirement vector */
625 effect_packet.reqs = peffect->reqs;
626
629}
630
631/**********************************************************************/
639bool building_has_effect(const struct impr_type *pimprove,
641{
642 struct universal source = {
644 /* just to bamboozle the annoying compiler warning */
645 .value = {.building = improvement_by_number(improvement_number(pimprove))}
646 };
648
649 if (!plist) {
650 return FALSE;
651 }
652
654 if (peffect->type == effect_type) {
655 return TRUE;
656 }
658
659 return FALSE;
660}
661
662/**********************************************************************/
670static bool is_effect_prevented(const struct req_context *context,
671 const struct req_context *other_context,
672 const struct effect *peffect,
673 const enum req_problem_type prob_type)
674{
676 /* Only check present=FALSE requirements; these will return _FALSE_
677 * from is_req_active() if met, and need reversed prob_type */
678 if (!preq->present
681 return TRUE;
682 }
684
685 return FALSE;
686}
687
688/**********************************************************************/
693bool is_building_replaced(const struct city *pcity,
694 const struct impr_type *pimprove,
695 const enum req_problem_type prob_type)
696{
697 struct effect_list *plist;
698 struct universal source = {
700 .value = {.building = pimprove}
701 };
702
704
705 /* A building with no effects and no flags is always redundant! */
706 if (!plist) {
707 return TRUE;
708 }
709
711 /* We use TARGET_BUILDING as the lowest common denominator. Note that
712 * the building is its own target - but whether this is actually
713 * checked depends on the range of the effect. */
714 /* Prob_type is not reversed here. disabled is equal to replaced, not
715 * reverse */
716 if (!is_effect_prevented(&(const struct req_context) {
717 .player = city_owner(pcity),
718 .city = pcity,
719 .building = pimprove,
720 },
721 NULL,
722 peffect, prob_type)) {
723 return FALSE;
724 }
726
727 return TRUE;
728}
729
730/**********************************************************************/
745 const struct req_context *context,
746 const struct req_context *other_context,
747 enum effect_type effect_type)
748{
749 int bonus = 0;
750
751 if (context == NULL) {
753 }
754
755 /* Loop over all effects of this type. */
757 /* For each effect, see if it is active. */
759 &peffect->reqs, RPT_CERTAIN)) {
760 /* This code will add value of effect. If there's multiplier for
761 * effect and target_player aren't null, then value is multiplied
762 * by player's multiplier factor. */
763 if (peffect->multiplier) {
764 if (context->player) {
765 bonus += (peffect->value
767 peffect->multiplier)) / 100;
768 }
769 } else {
770 bonus += peffect->value;
771 }
772
773 if (plist) {
775 }
776 }
778
779 return bonus;
780}
781
782/**********************************************************************/
790 const struct player *other_player,
791 enum effect_type effect_type,
793 void *data, int n_data)
794{
795 double sum = 0.;
796
797 if (context == NULL) {
799 }
800
801 /* Loop over all effects of this type. */
803 sum += weighter(peffect, context, other_player, data, n_data);
805
806 return sum;
807}
808
809/**********************************************************************/
812int get_world_bonus(enum effect_type effect_type)
813{
814 if (!initialized) {
815 return 0;
816 }
817
818 return get_target_bonus_effects(NULL, NULL, NULL, effect_type);
819}
820
821/**********************************************************************/
824int get_player_bonus(const struct player *pplayer,
825 enum effect_type effect_type)
826{
827 if (!initialized) {
828 return 0;
829 }
830
832 &(const struct req_context) {
833 .player = pplayer,
834 },
835 NULL,
836 effect_type);
837}
838
839/**********************************************************************/
842int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
843{
844 if (!initialized) {
845 return 0;
846 }
847
849 &(const struct req_context) {
850 .player = city_owner(pcity),
851 .city = pcity,
852 .tile = city_tile(pcity),
853 },
854 NULL, effect_type);
855}
856
857/**********************************************************************/
862int get_tile_bonus(const struct tile *ptile, enum effect_type effect_type)
863{
864 if (!initialized) {
865 return 0;
866 }
867
869 &(const struct req_context) {
870 .player = tile_owner(ptile),
871 .city = tile_city(ptile),
872 .tile = ptile,
873 },
874 NULL,
875 effect_type);
876}
877
878/**********************************************************************/
882 const struct specialist *pspecialist,
883 const struct output_type *poutput,
884 enum effect_type effect_type)
885{
890 &(const struct req_context) {
891 .player = city_owner(pcity),
892 .city = pcity,
893 .output = poutput,
894 .specialist = pspecialist,
895 },
896 NULL,
897 effect_type);
898}
899
900/**********************************************************************/
913 const struct tile *ptile,
914 const struct output_type *poutput,
915 enum effect_type effect_type)
916{
919 &(const struct req_context) {
920 .player = city_owner(pcity),
921 .city = pcity,
922 .tile = ptile,
923 .output = poutput,
924 },
925 NULL,
926 effect_type);
927}
928
929/**********************************************************************/
937 const struct tile *ptile,
938 const struct output_type *poutput,
939 enum effect_type effect_type)
940{
941 const struct player *pplayer = pcity ? city_owner(pcity) : NULL;
942
944 &(const struct req_context) {
945 .player = pplayer,
946 .city = pcity,
947 .tile = ptile,
948 .output = poutput,
949 },
950 NULL,
951 effect_type);
952}
953
954/**********************************************************************/
957int get_player_output_bonus(const struct player *pplayer,
958 const struct output_type *poutput,
959 enum effect_type effect_type)
960{
961 if (!initialized) {
962 return 0;
963 }
964
965 fc_assert_ret_val(pplayer != NULL, 0);
967 fc_assert_ret_val(effect_type != EFT_COUNT, 0);
969 &(const struct req_context) {
970 .player = pplayer,
971 .output= poutput,
972 },
973 NULL,
974 effect_type);
975}
976
977/**********************************************************************/
981 const struct output_type *poutput,
982 enum effect_type effect_type)
983{
984 if (!initialized) {
985 return 0;
986 }
987
990 fc_assert_ret_val(effect_type != EFT_COUNT, 0);
992 &(const struct req_context) {
993 .player = city_owner(pcity),
994 .city = pcity,
995 .output = poutput,
996 },
997 NULL,
998 effect_type);
999}
1000
1001/**********************************************************************/
1005 const struct impr_type *building,
1006 enum effect_type effect_type)
1007{
1008 if (!initialized) {
1009 return 0;
1010 }
1011
1012 fc_assert_ret_val(NULL != pcity && NULL != building, 0);
1014 &(const struct req_context) {
1015 .player = city_owner(pcity),
1016 .city = pcity,
1017 .building = building,
1018 },
1019 NULL,
1020 effect_type);
1021}
1022
1023/**********************************************************************/
1031int get_unittype_bonus(const struct player *pplayer,
1032 const struct tile *ptile,
1033 const struct unit_type *punittype,
1034 const struct action *paction,
1035 enum effect_type effect_type)
1036{
1037 struct city *pcity;
1038
1039 if (!initialized) {
1040 return 0;
1041 }
1042
1043 fc_assert_ret_val(punittype != nullptr, 0);
1044
1045 if (ptile != nullptr) {
1046 pcity = tile_city(ptile);
1047 } else {
1048 pcity = nullptr;
1049 }
1050
1051 return get_target_bonus_effects(nullptr,
1052 &(const struct req_context) {
1053 .player = pplayer,
1054 .city = pcity,
1055 .tile = ptile,
1056 .unittype = punittype,
1057 .action = paction,
1058 },
1059 nullptr,
1060 effect_type);
1061}
1062
1063/**********************************************************************/
1066int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
1067{
1068 if (!initialized) {
1069 return 0;
1070 }
1071
1074 &(const struct req_context) {
1075 .player = unit_owner(punit),
1076 .city = unit_tile(punit)
1078 : NULL,
1079 .tile = unit_tile(punit),
1080 .unit = punit,
1081 .unittype = unit_type_get(punit),
1082 },
1083 NULL,
1084 effect_type);
1085}
1086
1087/**********************************************************************/
1090int get_unit_vs_tile_bonus(const struct tile *ptile,
1091 const struct unit *punit,
1092 enum effect_type etype)
1093{
1094 struct player *pplayer = NULL;
1095 const struct unit_type *utype = NULL;
1096
1097 if (!initialized) {
1098 return 0;
1099 }
1100
1101 fc_assert_ret_val(ptile != NULL, 0);
1102
1103 if (punit != NULL) {
1104 pplayer = unit_owner(punit);
1105 utype = unit_type_get(punit);
1106 }
1107
1109 &(const struct req_context) {
1110 .player = pplayer,
1111 .city = tile_city(ptile),
1112 .tile = ptile,
1113 .unit = punit,
1114 .unittype = utype,
1115 },
1116 &(const struct req_context) {
1117 .player = tile_owner(ptile),
1118 },
1119 etype);
1120}
1121
1122/**********************************************************************/
1129 const struct player *pplayer,
1130 enum effect_type effect_type)
1131{
1132 if (!initialized) {
1133 return 0;
1134 }
1135
1136 fc_assert_ret_val(pplayer != NULL, 0);
1138 &(const struct req_context) {
1139 .player = pplayer,
1140 },
1141 NULL,
1142 effect_type);
1143}
1144
1145/**********************************************************************/
1152 const struct city *pcity,
1153 const struct output_type *poutput,
1154 enum effect_type effect_type)
1155{
1156 if (!initialized) {
1157 return 0;
1158 }
1159
1162 &(const struct req_context) {
1163 .player = city_owner(pcity),
1164 .city = pcity,
1165 .output = poutput,
1166 },
1167 NULL,
1168 effect_type);
1169}
1170
1171/**********************************************************************/
1181 enum effect_type effect_type,
1182 const enum req_problem_type prob_type)
1183{
1184 if (!initialized) {
1185 return 0;
1186 }
1187
1188 if (VUT_IMPROVEMENT == pcity->production.kind) {
1189 return get_potential_improvement_bonus(pcity->production.value.building,
1190 pcity, effect_type, prob_type, TRUE);
1191 }
1192
1193 return 0;
1194}
1195
1196/**********************************************************************/
1203 const struct city *pcity,
1204 enum effect_type effect_type,
1205 const enum req_problem_type prob_type,
1207{
1208 struct universal source = { .kind = VUT_IMPROVEMENT,
1209 .value = {.building = pimprove}};
1211 struct player *owner = NULL;
1212
1213 if (pcity != NULL) {
1215 }
1216
1217 if (plist) {
1218 int power = 0;
1219 const struct req_context context = {
1220 .player = owner,
1221 .city = pcity,
1222 .building = pimprove,
1223 };
1224
1226 bool present = TRUE;
1227 bool useful = TRUE;
1228
1229 if (peffect->type != effect_type) {
1230 continue;
1231 }
1232
1234 if (VUT_IMPROVEMENT == preq->source.kind
1235 && preq->source.value.building == pimprove) {
1236 present = preq->present;
1237 continue;
1238 }
1239
1241 useful = FALSE;
1242 break;
1243 }
1245
1246 if (useful) {
1247 int val;
1248
1249 if (present) {
1250 val = peffect->value;
1251 } else {
1252 val = -peffect->value;
1253 }
1254
1255 if (consider_multipliers && peffect->multiplier) {
1256 val = val * player_multiplier_effect_value(owner, peffect->multiplier) / 100;
1257 }
1258
1259 power += val;
1260 }
1262
1263 return power;
1264 }
1265
1266 return 0;
1267}
1268
1269/**********************************************************************/
1274 char *buf, size_t buf_len)
1275{
1276 buf[0] = '\0';
1277
1278 if (peffect->multiplier) {
1280 }
1281
1282 /* FIXME: should we do something for present FALSE reqs?
1283 * Currently we just ignore them. */
1285 if (!preq->present) {
1286 continue;
1287 }
1288 if (buf[0] != '\0') {
1289 fc_strlcat(buf, Q_("?req-list-separator:+"), buf_len);
1290 }
1291
1293 buf + strlen(buf), buf_len - strlen(buf));
1295}
1296
1297/**********************************************************************/
1302 struct astring *astr)
1303{
1304 struct strvec *psv = strvec_new();
1305 char req_text[512];
1306
1311
1314}
1315
1316/**********************************************************************/
1321bool iterate_effect_cache(iec_cb cb, void *data)
1322{
1324
1326 if (!cb(peffect, data)) {
1327 return FALSE;
1328 }
1330
1331 return TRUE;
1332}
1333
1334/**********************************************************************/
1337bool is_user_effect(enum effect_type eff)
1338{
1340}
1341
1342/**********************************************************************/
1346void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
1347{
1349
1351}
1352
1353/**********************************************************************/
1357enum effect_type user_effect_ai_valued_as(enum effect_type real)
1358{
1359 /* Client doesn't know these. */
1361
1362 if (!is_user_effect(real)) {
1363 return real;
1364 }
1365
1366 if (!is_user_effect(ueffects[USER_EFFECT_NUMBER(real)].ai_value_as)) {
1368 }
1369
1370 return real;
1371}
#define city_tile(_pcity_)
Definition city.h:561
#define city_owner(_pcity_)
Definition city.h:560
char * incite_cost
Definition comments.c:76
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
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 int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
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 @22::@23 reqs
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
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:936
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:957
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:881
bool is_building_replaced(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Definition effects.c:693
int get_player_bonus_effects(struct effect_list *plist, const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:1128
bool iterate_effect_cache(iec_cb cb, void *data)
Definition effects.c:1321
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_current_construction_bonus(const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type)
Definition effects.c:1180
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:1151
int get_unit_vs_tile_bonus(const struct tile *ptile, const struct unit *punit, enum effect_type etype)
Definition effects.c:1090
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:1066
int get_city_output_bonus(const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:980
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:1202
void send_ruleset_cache(struct conn_list *dest)
Definition effects.c:609
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Definition effects.c:1273
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
static struct @22 ruleset_cache
int get_building_bonus(const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
Definition effects.c:1004
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:912
void user_effect_ai_valued_set(enum effect_type tgt, enum effect_type valued_as)
Definition effects.c:1346
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
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:812
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:1357
static bool is_effect_prevented(const struct req_context *context, const struct req_context *other_context, const struct effect *peffect, const enum req_problem_type prob_type)
Definition effects.c:670
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:639
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:789
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:862
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:1031
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:824
void get_effect_list_req_text(const struct effect_list *plist, struct astring *astr)
Definition effects.c:1301
bool is_user_effect(enum effect_type eff)
Definition effects.c:1337
int effect_value_will_make_positive(enum effect_type type)
Definition effects.c:582
#define effect_list_iterate_end
Definition effects.h:81
#define USER_EFFECT_NUMBER(eff)
Definition effects.h:35
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
bool(* iec_cb)(struct effect *, void *data)
Definition effects.h:194
#define EFT_USER_EFFECT_LAST
Definition effects.h:33
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:79
static bool is_server(void)
req_problem_type
Definition fc_types.h:531
@ RPT_CERTAIN
Definition fc_types.h:533
#define REVERSED_RPT(x)
Definition fc_types.h:536
#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:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#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:1975
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 req_context *other_context, const struct requirement *req, const enum req_problem_type prob_type)
bool are_reqs_active(const struct req_context *context, const struct req_context *other_context, 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:317
struct tile * tile
Definition city.h:319
int value
Definition effects.h:49
struct requirement_vector reqs
Multiplier_type_id multiplier
enum effect_type effect_type
const struct player * player
struct universal source
Definition tile.h:50
Definition unit.h:140
struct tile * tile
Definition unit.h:142
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
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:822
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
static Tech_type_id advance_count(void)
Definition tech.h:165
#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:97
enum impr_flag_id impr_flag
Definition fc_types.h:585
#define unit_tile(_pu)
Definition unit.h:404
#define unit_owner(_pu)
Definition unit.h:403
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123