Freeciv21
Develop your civilization from humble roots to a global empire
effects.cpp
Go to the documentation of this file.
1 /*
2 _ ._ Copyright (c) 1996-2021 Freeciv21 and Freeciv contributors.
3  \ | This file is part of Freeciv21. Freeciv21 is free software: you
4  \_| can redistribute it and/or modify it under the terms of the
5  .' '. GNU General Public License as published by the Free
6  :O O: Software Foundation, either version 3 of the License,
7  '/ \' or (at your option) any later version. You should have
8  :X: received a copy of the GNU General Public License along with
9  :X: Freeciv21. If not, see https://www.gnu.org/licenses/.
10  */
11 #include <cstring>
12 
13 // utility
14 #include "astring.h"
15 #include "fcintl.h"
16 #include "log.h"
17 #include "shared.h" // ARRAY_SIZE
18 #include "support.h"
19 
20 // common
21 #include "city.h"
22 #include "government.h"
23 #include "improvement.h"
24 #include "map.h"
25 #include "multipliers.h"
26 #include "packets.h"
27 #include "player.h"
28 #include "tech.h"
29 
30 #include "effects.h"
31 
32 static bool initialized = false;
33 
96 static struct {
97  // A single list containing every effect.
98  struct effect_list *tracker;
99 
100  /* This array provides a full list of the effects of this type
101  * (It's not really a cache, it's the real data.) */
102  struct effect_list *effects[EFT_COUNT];
103 
104  struct {
105  // This cache shows for each building, which effects it provides.
106  struct effect_list *buildings[B_LAST];
107  // Same for governments
108  struct effect_list *govs[G_LAST];
109  // ...advances...
110  struct effect_list *advances[A_LAST];
111  } reqs;
113 
117 const effect_list *get_effects() { return ruleset_cache.tracker; }
118 
122 struct effect_list *get_effects(enum effect_type effect_type)
123 {
124  return ruleset_cache.effects[effect_type];
125 }
126 
132 struct effect_list *get_req_source_effects(struct universal *psource)
133 {
134  int type, value;
135 
136  universal_extraction(psource, &type, &value);
137 
138  switch (type) {
139  case VUT_GOVERNMENT:
140  if (value >= 0 && value < government_count()) {
141  return ruleset_cache.reqs.govs[value];
142  } else {
143  return nullptr;
144  }
145  case VUT_IMPROVEMENT:
146  if (value >= 0 && value < improvement_count()) {
147  return ruleset_cache.reqs.buildings[value];
148  } else {
149  return nullptr;
150  }
151  case VUT_ADVANCE:
152  if (value >= 0 && value < advance_count()) {
153  return ruleset_cache.reqs.advances[value];
154  } else {
155  return nullptr;
156  }
157  default:
158  return nullptr;
159  }
160 }
161 
165 struct effect *effect_new(enum effect_type type, int value,
166  struct multiplier *pmul)
167 {
168  // Create the effect.
169  auto *peffect = new effect;
170  peffect->type = type;
171  peffect->value = value;
172  peffect->multiplier = pmul;
173 
174  requirement_vector_init(&peffect->reqs);
175 
176  // Now add the effect to the ruleset cache.
177  effect_list_append(ruleset_cache.tracker, peffect);
178  effect_list_append(get_effects(type), peffect);
179 
180  return peffect;
181 }
182 
186 struct effect *effect_copy(struct effect *old)
187 {
188  struct effect *new_eff =
189  effect_new(old->type, old->value, old->multiplier);
190 
191  requirement_vector_iterate(&old->reqs, preq)
192  {
193  effect_req_append(new_eff, *preq);
194  }
196 
197  return new_eff;
198 }
199 
203 void effect_req_append(struct effect *peffect, struct requirement req)
204 {
205  struct effect_list *eff_list = get_req_source_effects(&req.source);
206 
207  requirement_vector_append(&peffect->reqs, req);
208 
209  if (eff_list) {
210  effect_list_append(eff_list, peffect);
211  }
212 }
213 
220 {
221  int i;
222 
223  initialized = true;
224 
225  ruleset_cache.tracker = effect_list_new();
226 
227  for (i = 0; i < ARRAY_SIZE(ruleset_cache.effects); i++) {
228  ruleset_cache.effects[i] = effect_list_new();
229  }
230  for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.buildings); i++) {
231  ruleset_cache.reqs.buildings[i] = effect_list_new();
232  }
233  for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.govs); i++) {
234  ruleset_cache.reqs.govs[i] = effect_list_new();
235  }
236  for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.advances); i++) {
237  ruleset_cache.reqs.advances[i] = effect_list_new();
238  }
239 }
240 
246 {
247  int i;
248  struct effect_list *tracker_list = ruleset_cache.tracker;
249 
250  if (tracker_list) {
251  effect_list_iterate(tracker_list, peffect)
252  {
253  requirement_vector_free(&peffect->reqs);
254  delete peffect;
255  }
257  effect_list_destroy(tracker_list);
258  ruleset_cache.tracker = nullptr;
259  }
260 
261  for (i = 0; i < ARRAY_SIZE(ruleset_cache.effects); i++) {
262  struct effect_list *plist = ruleset_cache.effects[i];
263 
264  if (plist) {
265  effect_list_destroy(plist);
266  ruleset_cache.effects[i] = nullptr;
267  }
268  }
269 
270  for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.buildings); i++) {
271  struct effect_list *plist = ruleset_cache.reqs.buildings[i];
272 
273  if (plist) {
274  effect_list_destroy(plist);
275  ruleset_cache.reqs.buildings[i] = nullptr;
276  }
277  }
278 
279  for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.govs); i++) {
280  struct effect_list *plist = ruleset_cache.reqs.govs[i];
281 
282  if (plist) {
283  effect_list_destroy(plist);
284  ruleset_cache.reqs.govs[i] = nullptr;
285  }
286  }
287 
288  for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.advances); i++) {
289  struct effect_list *plist = ruleset_cache.reqs.advances[i];
290 
291  if (plist) {
292  effect_list_destroy(plist);
293  ruleset_cache.reqs.advances[i] = nullptr;
294  }
295  }
296 
297  initialized = false;
298 }
299 
307 int effect_cumulative_max(enum effect_type type, struct universal *for_uni)
308 {
309  struct effect_list *plist = ruleset_cache.tracker;
310  int value = 0;
311 
312  if (plist) {
313  effect_list_iterate(plist, peffect)
314  {
315  if (peffect->type == type && peffect->value > 0) {
316  if (for_uni == nullptr
317  || universal_fulfills_requirements(false, &(peffect->reqs),
318  for_uni)) {
319  value += peffect->value;
320  }
321  }
322  }
324  }
325 
326  return value;
327 }
328 
336 int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
337 {
338  struct effect_list *plist = ruleset_cache.tracker;
339  int value = 0;
340 
341  if (plist) {
342  effect_list_iterate(plist, peffect)
343  {
344  if (peffect->type == type && peffect->value < 0) {
345  if (for_uni == nullptr
346  || universal_fulfills_requirements(false, &(peffect->reqs),
347  for_uni)) {
348  value += peffect->value;
349  }
350  }
351  }
353  }
354 
355  return value;
356 }
357 
368 int effect_value_from_universals(enum effect_type type,
369  struct universal *unis, size_t n_unis)
370 {
371  int value = 0;
372  struct effect_list *el = get_effects(type);
373 
374  effect_list_iterate(el, peffect)
375  {
376  bool effect_applies = true;
377  bool first_source_mentioned = false;
378 
379  if (peffect->multiplier) {
380  /* Discount any effects with multipliers; we are looking for constant
381  * effects */
382  continue;
383  }
384 
385  requirement_vector_iterate(&(peffect->reqs), preq)
386  {
387  int i;
388  bool req_mentioned_a_source = false;
389 
390  for (i = 0; effect_applies && i < n_unis; i++) {
391  switch (universal_fulfills_requirement(preq, &(unis[i]))) {
392  case ITF_NOT_APPLICABLE:
393  /* This req not applicable to this source (but might be relevant
394  * to another source in our template). Keep looking. */
395  break;
396  case ITF_NO:
397  req_mentioned_a_source = true; // this req matched this source
398  if (preq->present) {
399  // Requirement contradicts template. Effect doesn't apply.
400  effect_applies = false;
401  } // but negative req doesn't count for first_source_mentioned
402  break;
403  case ITF_YES:
404  req_mentioned_a_source = true; // this req matched this source
405  if (preq->present) {
406  if (i == 0) {
407  first_source_mentioned = true;
408  }
409  // keep looking
410  } else /* !present */ {
411  // Requirement contradicts template. Effect doesn't apply.
412  effect_applies = false;
413  }
414  break;
415  }
416  }
417  if (!req_mentioned_a_source) {
418  /* This requirement isn't relevant to any source in our template,
419  * so it's an extra condition and the effect should be ignored. */
420  effect_applies = false;
421  }
422  if (!effect_applies) {
423  // Already known to be irrelevant, bail out early
424  break;
425  }
426  }
428 
429  if (!first_source_mentioned) {
430  /* First source not positively mentioned anywhere in requirements,
431  * so ignore this effect */
432  continue;
433  }
434  if (effect_applies) {
435  value += peffect->value;
436  }
437  }
439 
440  return value;
441 }
442 
447 void recv_ruleset_effect(const struct packet_ruleset_effect *packet)
448 {
449  struct effect *peffect;
450  struct multiplier *pmul;
451  int i;
452 
453  pmul = packet->has_multiplier ? multiplier_by_number(packet->multiplier)
454  : nullptr;
455  peffect = effect_new(packet->effect_type, packet->effect_value, pmul);
456 
457  for (i = 0; i < packet->reqs_count; i++) {
458  effect_req_append(peffect, packet->reqs[i]);
459  }
460  fc_assert(peffect->reqs.size == packet->reqs_count);
461 }
462 
466 void send_ruleset_cache(struct conn_list *dest)
467 {
468  effect_list_iterate(ruleset_cache.tracker, peffect)
469  {
470  struct packet_ruleset_effect effect_packet;
471  int counter;
472 
473  effect_packet.effect_type = peffect->type;
474  effect_packet.effect_value = peffect->value;
475  if (peffect->multiplier) {
476  effect_packet.has_multiplier = true;
477  effect_packet.multiplier = multiplier_number(peffect->multiplier);
478  } else {
479  effect_packet.has_multiplier = false;
480  effect_packet.multiplier = 0; // arbitrary
481  }
482 
483  counter = 0;
484  requirement_vector_iterate(&(peffect->reqs), req)
485  {
486  effect_packet.reqs[counter++] = *req;
487  }
489  effect_packet.reqs_count = counter;
490 
491  lsend_packet_ruleset_effect(dest, &effect_packet);
492  }
494 }
495 
504 bool building_has_effect(const struct impr_type *pimprove,
505  enum effect_type effect_type)
506 {
507  struct universal source = {
508  // just to bamboozle the annoying compiler warning
509  .value = {.building =
511  .kind = VUT_IMPROVEMENT};
512  struct effect_list *plist = get_req_source_effects(&source);
513 
514  if (!plist) {
515  return false;
516  }
517 
518  effect_list_iterate(plist, peffect)
519  {
520  if (peffect->type == effect_type) {
521  return true;
522  }
523  }
525 
526  return false;
527 }
528 
536  const struct player *target_player, const struct player *other_player,
537  const struct city *target_city, const struct impr_type *target_building,
538  const struct tile *target_tile, const struct unit *target_unit,
539  const struct unit_type *target_unittype,
540  const struct output_type *target_output,
541  const struct specialist *target_specialist, const struct effect *peffect,
542  const enum req_problem_type prob_type)
543 {
544  requirement_vector_iterate(&peffect->reqs, preq)
545  {
546  /* Only check present=FALSE requirements; these will return _FALSE_
547  * from is_req_active() if met, and need reversed prob_type */
548  if (!preq->present
549  && !is_req_active(target_player, other_player, target_city,
550  target_building, target_tile, target_unit,
551  target_unittype, target_output, target_specialist,
552  nullptr, preq, REVERSED_RPT(prob_type))) {
553  return true;
554  }
555  }
557 
558  return false;
559 }
560 
566 bool is_building_replaced(const struct city *pcity,
567  const struct impr_type *pimprove,
568  const enum req_problem_type prob_type)
569 {
570  struct effect_list *plist;
571  struct universal source = {.value = {.building = pimprove},
572  .kind = VUT_IMPROVEMENT};
573 
574  plist = get_req_source_effects(&source);
575 
576  // A building with no effects and no flags is always redundant!
577  if (!plist) {
578  return true;
579  }
580 
581  effect_list_iterate(plist, peffect)
582  {
583  /* We use TARGET_BUILDING as the lowest common denominator. Note that
584  * the building is its own target - but whether this is actually
585  * checked depends on the range of the effect. */
586  /* Prob_type is not reversed here. disabled is equal to replaced, not
587  * reverse */
588  if (!is_effect_prevented(city_owner(pcity), nullptr, pcity, pimprove,
589  nullptr, nullptr, nullptr, nullptr, nullptr,
590  peffect, prob_type)) {
591  return false;
592  }
593  }
595 
596  return true;
597 }
598 
612  struct effect_list *plist, const struct player *target_player,
613  const struct player *other_player, const struct city *target_city,
614  const struct impr_type *target_building, const struct tile *target_tile,
615  const struct unit *target_unit, const struct unit_type *target_unittype,
616  const struct output_type *target_output,
617  const struct specialist *target_specialist,
618  const struct action *target_action, enum effect_type effect_type,
619  enum vision_layer vision_layer, enum national_intelligence nintel)
620 {
621  int bonus = 0;
622 
623  // Loop over all effects of this type.
624  effect_list_iterate(get_effects(effect_type), peffect)
625  {
626  // For each effect, see if it is active.
627  if (are_reqs_active(target_player, other_player, target_city,
628  target_building, target_tile, target_unit,
629  target_unittype, target_output, target_specialist,
630  target_action, &peffect->reqs, RPT_CERTAIN,
631  vision_layer, nintel)) {
632  /* This code will add value of effect. If there's multiplier for
633  * effect and target_player aren't null, then value is multiplied
634  * by player's multiplier factor. */
635  if (peffect->multiplier) {
636  if (target_player) {
637  bonus += (peffect->value
638  * player_multiplier_effect_value(target_player,
639  peffect->multiplier))
640  / 100;
641  }
642  } else {
643  bonus += peffect->value;
644  }
645 
646  if (plist) {
647  effect_list_append(plist, peffect);
648  }
649  }
650  }
652 
653  return bonus;
654 }
655 
659 int get_world_bonus(enum effect_type effect_type)
660 {
661  if (!initialized) {
662  return 0;
663  }
664 
665  return get_target_bonus_effects(nullptr, nullptr, nullptr, nullptr,
666  nullptr, nullptr, nullptr, nullptr,
667  nullptr, nullptr, nullptr, effect_type);
668 }
669 
673 int get_player_bonus(const struct player *pplayer,
674  enum effect_type effect_type)
675 {
676  if (!initialized) {
677  return 0;
678  }
679 
680  return get_target_bonus_effects(nullptr, pplayer, nullptr, nullptr,
681  nullptr, nullptr, nullptr, nullptr,
682  nullptr, nullptr, nullptr, effect_type);
683 }
684 
688 int get_city_bonus(const struct city *pcity, enum effect_type effect_type,
689  enum vision_layer vlayer)
690 {
691  if (!initialized) {
692  return 0;
693  }
694 
696  nullptr, city_owner(pcity), nullptr, pcity, nullptr, city_tile(pcity),
697  nullptr, nullptr, nullptr, nullptr, nullptr, effect_type, vlayer);
698 }
699 
703 int get_city_specialist_output_bonus(const struct city *pcity,
704  const struct specialist *pspecialist,
705  const struct output_type *poutput,
706  enum effect_type effect_type)
707 {
708  fc_assert_ret_val(pcity != nullptr, 0);
709  fc_assert_ret_val(pspecialist != nullptr, 0);
710  fc_assert_ret_val(poutput != nullptr, 0);
712  nullptr, city_owner(pcity), nullptr, pcity, nullptr, nullptr, nullptr,
713  nullptr, poutput, pspecialist, nullptr, effect_type);
714 }
715 
728 int get_city_tile_output_bonus(const struct city *pcity,
729  const struct tile *ptile,
730  const struct output_type *poutput,
731  enum effect_type effect_type)
732 {
733  fc_assert_ret_val(pcity != nullptr, 0);
734  return get_target_bonus_effects(nullptr, city_owner(pcity), nullptr, pcity,
735  nullptr, ptile, nullptr, nullptr, poutput,
736  nullptr, nullptr, effect_type);
737 }
738 
746 int get_tile_output_bonus(const struct city *pcity, const struct tile *ptile,
747  const struct output_type *poutput,
748  enum effect_type effect_type)
749 {
750  const struct player *pplayer = pcity ? city_owner(pcity) : nullptr;
751 
752  return get_target_bonus_effects(nullptr, pplayer, nullptr, pcity, nullptr,
753  ptile, nullptr, nullptr, poutput, nullptr,
754  nullptr, effect_type);
755 }
756 
760 int get_player_output_bonus(const struct player *pplayer,
761  const struct output_type *poutput,
762  enum effect_type effect_type)
763 {
764  if (!initialized) {
765  return 0;
766  }
767 
768  fc_assert_ret_val(pplayer != nullptr, 0);
769  fc_assert_ret_val(poutput != nullptr, 0);
770  fc_assert_ret_val(effect_type != EFT_COUNT, 0);
771  return get_target_bonus_effects(nullptr, pplayer, nullptr, nullptr,
772  nullptr, nullptr, nullptr, nullptr,
773  poutput, nullptr, nullptr, effect_type);
774 }
775 
779 int get_player_intel_bonus(const struct player *pplayer,
780  const struct player *pother,
781  enum national_intelligence nintel,
782  enum effect_type effect_type)
783 {
784  if (!initialized) {
785  return 0;
786  }
787 
788  fc_assert_ret_val(pplayer != nullptr, 0);
789  fc_assert_ret_val(pother != nullptr, 0);
790  fc_assert_ret_val(national_intelligence_is_valid(nintel), 0);
791  fc_assert_ret_val(effect_type != EFT_COUNT, 0);
793  nullptr, pplayer, pother, nullptr, nullptr, nullptr, nullptr, nullptr,
794  nullptr, nullptr, nullptr, effect_type, V_COUNT, nintel);
795 }
796 
800 int get_city_output_bonus(const struct city *pcity,
801  const struct output_type *poutput,
802  enum effect_type effect_type)
803 {
804  if (!initialized) {
805  return 0;
806  }
807 
808  fc_assert_ret_val(pcity != nullptr, 0);
809  fc_assert_ret_val(poutput != nullptr, 0);
810  fc_assert_ret_val(effect_type != EFT_COUNT, 0);
811  return get_target_bonus_effects(nullptr, city_owner(pcity), nullptr, pcity,
812  nullptr, nullptr, nullptr, nullptr,
813  poutput, nullptr, nullptr, effect_type);
814 }
815 
819 int get_building_bonus(const struct city *pcity,
820  const struct impr_type *building,
821  enum effect_type effect_type)
822 {
823  if (!initialized) {
824  return 0;
825  }
826 
827  fc_assert_ret_val(nullptr != pcity && nullptr != building, 0);
828  return get_target_bonus_effects(nullptr, city_owner(pcity), nullptr, pcity,
829  building, nullptr, nullptr, nullptr,
830  nullptr, nullptr, nullptr, effect_type);
831 }
832 
841 int get_unittype_bonus(const struct player *pplayer,
842  const struct tile *ptile,
843  const struct unit_type *punittype,
844  enum effect_type effect_type,
845  enum vision_layer vision_layer)
846 {
847  struct city *pcity;
848 
849  if (!initialized) {
850  return 0;
851  }
852 
853  fc_assert_ret_val(punittype != nullptr, 0);
854 
855  if (ptile != nullptr) {
856  pcity = tile_city(ptile);
857  } else {
858  pcity = nullptr;
859  }
860 
862  nullptr, pplayer, nullptr, pcity, nullptr, ptile, nullptr, punittype,
863  nullptr, nullptr, nullptr, effect_type, vision_layer);
864 }
865 
869 int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
870 {
871  if (!initialized) {
872  return 0;
873  }
874 
875  fc_assert_ret_val(punit != nullptr, 0);
877  nullptr, unit_owner(punit), nullptr,
878  unit_tile(punit) ? tile_city(unit_tile(punit)) : nullptr, nullptr,
879  unit_tile(punit), punit, unit_type_get(punit), nullptr, nullptr,
880  nullptr, effect_type);
881 }
882 
889 int get_player_bonus_effects(struct effect_list *plist,
890  const struct player *pplayer,
891  enum effect_type effect_type)
892 {
893  if (!initialized) {
894  return 0;
895  }
896 
897  fc_assert_ret_val(pplayer != nullptr, 0);
898  return get_target_bonus_effects(plist, pplayer, nullptr, nullptr, nullptr,
899  nullptr, nullptr, nullptr, nullptr,
900  nullptr, nullptr, effect_type);
901 }
902 
909 int get_city_bonus_effects(struct effect_list *plist,
910  const struct city *pcity,
911  const struct output_type *poutput,
912  enum effect_type effect_type)
913 {
914  if (!initialized) {
915  return 0;
916  }
917 
918  fc_assert_ret_val(pcity != nullptr, 0);
919  return get_target_bonus_effects(plist, city_owner(pcity), nullptr, pcity,
920  nullptr, nullptr, nullptr, nullptr,
921  poutput, nullptr, nullptr, effect_type);
922 }
923 
933 int get_current_construction_bonus(const struct city *pcity,
934  enum effect_type effect_type,
935  const enum req_problem_type prob_type)
936 {
937  if (!initialized) {
938  return 0;
939  }
940 
941  if (VUT_IMPROVEMENT == pcity->production.kind) {
943  pcity, effect_type, prob_type);
944  }
945  return 0;
946 }
947 
954 int get_potential_improvement_bonus(const struct impr_type *pimprove,
955  const struct city *pcity,
956  enum effect_type effect_type,
957  const enum req_problem_type prob_type)
958 {
959  struct universal source = {.value = {.building = pimprove},
960  .kind = VUT_IMPROVEMENT};
961  struct effect_list *plist = get_req_source_effects(&source);
962 
963  if (plist) {
964  int power = 0;
965 
966  effect_list_iterate(plist, peffect)
967  {
968  bool present = true;
969  bool useful = true;
970 
971  if (peffect->type != effect_type) {
972  continue;
973  }
974 
975  requirement_vector_iterate(&peffect->reqs, preq)
976  {
977  if (VUT_IMPROVEMENT == preq->source.kind
978  && preq->source.value.building == pimprove) {
979  present = preq->present;
980  continue;
981  }
982 
983  if (!is_req_active(city_owner(pcity), nullptr, pcity, pimprove,
984  nullptr, nullptr, nullptr, nullptr, nullptr,
985  nullptr, preq, prob_type)) {
986  useful = false;
987  break;
988  }
989  }
991 
992  if (useful) {
993  if (present) {
994  power += peffect->value;
995  } else {
996  power -= peffect->value;
997  }
998  }
999  }
1001 
1002  return power;
1003  }
1004  return 0;
1005 }
1006 
1011 void get_effect_req_text(const struct effect *peffect, char *buf,
1012  size_t buf_len)
1013 {
1014  buf[0] = '\0';
1015 
1016  if (peffect->multiplier) {
1018  buf_len);
1019  }
1020 
1021  requirement_vector_iterate(&peffect->reqs, preq)
1022  {
1023  if (buf[0] != '\0') {
1024  fc_strlcat(buf, Q_("?req-list-separator:+"), buf_len);
1025  }
1026  if (!preq->present) {
1027  fc_strlcat(buf, Q_("?req-list-separator:not "), buf_len);
1028  }
1029 
1030  universal_name_translation(&preq->source, buf + qstrlen(buf),
1031  buf_len - qstrlen(buf));
1032  }
1034 }
1035 
1040 QString get_effect_list_req_text(const struct effect_list *plist)
1041 {
1042  QVector<QString> psv;
1043  char req_text[512];
1044 
1045  effect_list_iterate(plist, peffect)
1046  {
1047  get_effect_req_text(peffect, req_text, sizeof(req_text));
1048  psv.append(req_text);
1049  }
1051  return strvec_to_and_list(psv);
1052 }
1053 
1058 QString effect_type_unit_text(effect_type type, int value)
1059 {
1060  switch (type) {
1061  case EFT_TECH_PARASITE:
1062  return QString(PL_("%1 player", "%1 players", value)).arg(value);
1063  case EFT_AIRLIFT:
1064  case EFT_UPGRADE_UNIT:
1065  case EFT_MARTIAL_LAW_MAX:
1066  // TRANS: Units like warriors and settlers, not miles and kg
1067  return QString(PL_("%1 unit", "%1 units", value)).arg(value);
1068  case EFT_OUTPUT_BONUS:
1069  case EFT_OUTPUT_BONUS_2:
1070  case EFT_OUTPUT_PER_TILE:
1071  case EFT_OUTPUT_WASTE_PCT:
1072  case EFT_GROWTH_FOOD:
1073  case EFT_HEALTH_PCT:
1074  case EFT_POLLU_POP_PCT:
1075  case EFT_POLLU_POP_PCT_2:
1076  case EFT_POLLU_PROD_PCT:
1077  case EFT_POLLU_TRADE_PCT:
1078  case EFT_INCITE_COST_PCT:
1079  case EFT_SPY_RESISTANT:
1080  case EFT_VETERAN_COMBAT:
1081  case EFT_HP_REGEN:
1082  case EFT_HP_REGEN_MIN:
1083  case EFT_TRADEROUTE_PCT:
1084  case EFT_DEFEND_BONUS:
1085  case EFT_CIVIL_WAR_CHANCE:
1086  case EFT_MIGRATION_PCT:
1087  case EFT_MAX_RATES:
1088  case EFT_OUTPUT_WASTE:
1089  case EFT_UPGRADE_PRICE_PCT:
1090  case EFT_SHIELD2GOLD_FACTOR:
1091  case EFT_IMPR_BUILD_COST_PCT:
1092  case EFT_IMPR_BUY_COST_PCT:
1093  case EFT_NUKE_IMPROVEMENT_PCT:
1094  case EFT_UNIT_BUILD_COST_PCT:
1095  case EFT_UNIT_BUY_COST_PCT:
1096  case EFT_ENEMY_CITIZEN_UNHAPPY_PCT:
1097  case EFT_IRRIGATION_PCT:
1098  case EFT_MINING_PCT:
1099  case EFT_OUTPUT_TILE_PUNISH_PCT:
1100  case EFT_UNIT_BRIBE_COST_PCT:
1101  case EFT_RETIRE_PCT:
1102  case EFT_ACTION_ODDS_PCT:
1103  case EFT_OUTPUT_WASTE_BY_REL_DISTANCE: // Effectively % but not really
1104  // useful
1105  case EFT_SABOTEUR_RESISTANT:
1106  case EFT_ATTACK_BONUS:
1107  case EFT_CONQUEST_TECH_PCT:
1108  case EFT_FORTIFY_DEFENSE_BONUS:
1109  case EFT_MAPS_STOLEN_PCT:
1110  case EFT_UNIT_SHIELD_VALUE_PCT:
1111  case EFT_BOMBARD_LIMIT_PCT:
1112  case EFT_NUKE_INFRASTRUCTURE_PCT:
1113  case EFT_GROWTH_SURPLUS_PCT:
1114  // TRANS: per cent
1115  return QString(PL_("%1%", "%1%", value)).arg(value);
1116  case EFT_MAX_STOLEN_GOLD_PM:
1117  case EFT_THIEFS_SHARE_PM:
1118  // TRANS: per mille
1119  return QString(PL_("%1‰", "%1‰", value)).arg(value);
1120  case EFT_FORCE_CONTENT:
1121  case EFT_MAKE_CONTENT:
1122  case EFT_MAKE_CONTENT_MIL:
1123  case EFT_MAKE_HAPPY:
1124  case EFT_SIZE_ADJ:
1125  case EFT_MARTIAL_LAW_EACH:
1126  case EFT_CITY_UNHAPPY_SIZE:
1127  return QString(PL_("%1 citizen", "%1 citizens", value)).arg(value);
1128  case EFT_GIVE_IMM_TECH:
1129  return QString(PL_("%1 tech", "%1 techs", value)).arg(value);
1130  case EFT_MOVE_BONUS:
1131  case EFT_ILLEGAL_ACTION_MOVE_COST:
1132  case EFT_ACTION_SUCCESS_MOVE_COST:
1133  case EFT_ACTION_SUCCESS_TARGET_MOVE_COST:
1134  // TRANS: Movement points
1135  return QString(PL_("%1 MP", "%1 MP", value)).arg(value);
1136  case EFT_UNIT_RECOVER:
1137  case EFT_ILLEGAL_ACTION_HP_COST:
1138  // TRANS: Health/hit points
1139  return QString(PL_("%1 HP", "%1 HP", value)).arg(value);
1140  case EFT_UPKEEP_FREE:
1141  return QString(PL_("%1 building", "%1 buildings", value)).arg(value);
1142  case EFT_VETERAN_BUILD:
1143  // TRANS: Veteran levels
1144  return QString(PL_("%1 level", "%1 levels", value)).arg(value);
1145  case EFT_CITY_VISION_RADIUS_SQ:
1146  case EFT_UNIT_VISION_RADIUS_SQ:
1147  case EFT_CITY_RADIUS_SQ:
1148  // TRANS: sq. = squared, as in sq. meter
1149  return QString(PL_("%1 sq. tile", "%1 sq. tiles", value)).arg(value);
1150  case EFT_GAIN_AI_LOVE:
1151  // TRANS: "AI love" is what makes the AI friendly
1152  return QString(PL_("%1 love", "%1 love", value)).arg(value);
1153  case EFT_TURN_YEARS:
1154  // TRANS: Year/turn
1155  return QString(PL_("%1 yr/turn", "%1 yr/turn", value)).arg(value);
1156  case EFT_EMPIRE_SIZE_BASE:
1157  case EFT_EMPIRE_SIZE_STEP:
1158  return QString(PL_("%1 city", "%1 cities", value)).arg(value);
1159  case EFT_REVOLUTION_UNHAPPINESS:
1160  return QString(PL_("%1 turn", "%1 turns", value)).arg(value);
1161  case EFT_TRADE_REVENUE_BONUS: {
1162  // Complicated arithmetics... and this effect is multiplicative
1163  int factor = 100 * std::pow(2.0, value / 1000.);
1164  return QString(PL_("%1%", "%1%", factor)).arg(factor);
1165  }
1166  case EFT_TRADE_REVENUE_EXPONENT: {
1167  // additive in the exponent, which means... compositive??
1168  float factor = 1.0f + value / 1000.0f;
1169  return QString(PL_("**%1", "**%1", factor)).arg(factor);
1170  }
1171  case EFT_OUTPUT_WASTE_BY_DISTANCE: {
1172  float waste = value / 100.0f;
1173  return QString(PL_("%1%/tile", "%1%/tile", waste)).arg(waste);
1174  }
1175  case EFT_CITY_BUILD_SLOTS:
1176  return QString(PL_("%1 slot", "%1 slots", value)).arg(value);
1177  case EFT_MAX_TRADE_ROUTES:
1178  // TRANS: Trade routes
1179  return QString(PL_("%1 route", "%1 routes", value)).arg(value);
1180  case EFT_COMBAT_ROUNDS:
1181  // TRANS: Combat rounds
1182  return QString(PL_("%1 round", "%1 rounds", value)).arg(value);
1183  case EFT_PERFORMANCE:
1184  case EFT_HISTORY:
1185  case EFT_NATION_PERFORMANCE:
1186  case EFT_NATION_HISTORY:
1187  return QString(PL_("%1 culture point", "%1 culture points", value))
1188  .arg(value);
1189  case EFT_TURN_FRAGMENTS:
1190  return QString(PL_("%1 fragment", "%1 fragments", value)).arg(value);
1191  case EFT_UNIT_SLOTS:
1192  // TRANS: Unit slots
1193  return QString(PL_("%1 slot", "%1 slots", value)).arg(value);
1194  case EFT_INFRA_POINTS:
1195  return QString(PL_("%1 infrastructure point", "%1 infrastructure points",
1196  value))
1197  .arg(value);
1198  case EFT_ANY_GOVERNMENT:
1199  case EFT_CAPITAL_CITY:
1200  case EFT_ENABLE_NUKE:
1201  case EFT_ENABLE_SPACE:
1202  case EFT_SPECIALIST_OUTPUT: // FIXME should use the name of the
1203  // OutputType...
1204  case EFT_OUTPUT_ADD_TILE:
1205  case EFT_OUTPUT_INC_TILE:
1206  case EFT_HAVE_EMBASSIES:
1207  case EFT_MAKE_CONTENT_MIL_PER: // FIXME ?
1208  case EFT_NO_ANARCHY:
1209  case EFT_NUKE_PROOF:
1210  case EFT_REVEAL_CITIES:
1211  case EFT_REVEAL_MAP:
1212  case EFT_SIZE_UNLIMIT:
1213  case EFT_SS_STRUCTURAL:
1214  case EFT_SS_COMPONENT:
1215  case EFT_SS_MODULE:
1216  case EFT_UNIT_NO_LOSE_POP:
1217  case EFT_TECH_UPKEEP_FREE:
1218  case EFT_NO_UNHAPPY:
1219  case EFT_SLOW_DOWN_TIMELINE:
1220  case EFT_RAPTURE_GROW:
1221  case EFT_HAS_SENATE:
1222  case EFT_INSPIRE_PARTISANS:
1223  case EFT_HAPPINESS_TO_GOLD:
1224  case EFT_FANATICS:
1225  case EFT_NO_DIPLOMACY:
1226  case EFT_UNHAPPY_FACTOR:
1227  case EFT_UPKEEP_FACTOR:
1228  case EFT_UNIT_UPKEEP_FREE_PER_CITY:
1229  case EFT_OUTPUT_PENALTY_TILE:
1230  case EFT_OUTPUT_INC_TILE_CELEBRATE:
1231  case EFT_VISIBLE_WALLS:
1232  case EFT_TECH_COST_FACTOR:
1233  case EFT_TILE_WORKABLE:
1234  case EFT_CITY_IMAGE:
1235  case EFT_GOV_CENTER:
1236  case EFT_NOT_TECH_SOURCE:
1237  case EFT_VICTORY:
1238  case EFT_HAVE_CONTACTS:
1239  case EFT_CASUS_BELLI_CAUGHT:
1240  case EFT_CASUS_BELLI_SUCCESS:
1241  case EFT_BORDER_VISION:
1242  case EFT_STEALINGS_IGNORE:
1243  case EFT_CASUS_BELLI_COMPLETE:
1244  case EFT_WONDER_VISIBLE:
1245  case EFT_NATION_INTELLIGENCE:
1246  case EFT_COUNT:
1247  return QStringLiteral("%1").arg(value);
1248  }
1249 
1250  fc_assert_ret_val(false, QString());
1251 }
1252 
1259 bool iterate_effect_cache(iec_cb cb, void *data)
1260 {
1261  fc_assert_ret_val(cb != nullptr, false);
1262 
1263  effect_list_iterate(ruleset_cache.tracker, peffect)
1264  {
1265  if (!cb(peffect, data)) {
1266  return false;
1267  }
1268  }
1270 
1271  return true;
1272 }
QString strvec_to_and_list(const QVector< QString > &psv)
Definition: astring.cpp:43
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
void recv_ruleset_effect(const struct packet_ruleset_effect *packet)
Receives a new effect.
Definition: effects.cpp:447
int get_target_bonus_effects(struct effect_list *plist, const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, enum effect_type effect_type, enum vision_layer vision_layer, enum national_intelligence nintel)
Returns the effect bonus of a given type for any target.
Definition: effects.cpp:611
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)
Returns the effect bonus the improvement would or does provide if present.
Definition: effects.cpp:954
struct effect_list * effects[EFT_COUNT]
Definition: effects.cpp:102
struct effect_list * govs[G_LAST]
Definition: effects.cpp:108
struct effect_list * tracker
Definition: effects.cpp:98
int get_tile_output_bonus(const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
Returns the effect bonus at a tile for given output type (or nullptr for output-type-independent bonu...
Definition: effects.cpp:746
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Returns the player effect bonus of an output.
Definition: effects.cpp:760
struct @19::@20 reqs
int get_city_specialist_output_bonus(const struct city *pcity, const struct specialist *pspecialist, const struct output_type *poutput, enum effect_type effect_type)
Returns the effect bonus of a specialist in a city.
Definition: effects.cpp:703
bool is_building_replaced(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Returns TRUE if a building is replaced.
Definition: effects.cpp:566
int get_player_bonus_effects(struct effect_list *plist, const struct player *pplayer, enum effect_type effect_type)
Returns the effect sources of this type currently active at the player.
Definition: effects.cpp:889
int get_player_intel_bonus(const struct player *pplayer, const struct player *pother, enum national_intelligence nintel, enum effect_type effect_type)
Gets the player effect bonus of a national intelligence.
Definition: effects.cpp:779
bool iterate_effect_cache(iec_cb cb, void *data)
Iterate through all the effects in cache, and call callback for each.
Definition: effects.cpp:1259
int get_current_construction_bonus(const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type)
Returns the effect bonus the currently-in-construction-item will provide.
Definition: effects.cpp:933
int get_city_bonus_effects(struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Returns the effect sources of this type currently active at the city.
Definition: effects.cpp:909
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, enum effect_type effect_type, enum vision_layer vision_layer)
Returns the effect bonus that applies at a tile for a given unittype.
Definition: effects.cpp:841
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Returns the effect bonus at a unit.
Definition: effects.cpp:869
void ruleset_cache_init()
Initialize the ruleset cache.
Definition: effects.cpp:219
int get_city_output_bonus(const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Returns the player effect bonus of an output.
Definition: effects.cpp:800
void ruleset_cache_free()
Free the ruleset cache.
Definition: effects.cpp:245
QString effect_type_unit_text(effect_type type, int value)
Returns a string describing an effect value as interpreted in the context of an effect_type,...
Definition: effects.cpp:1058
void send_ruleset_cache(struct conn_list *dest)
Send the ruleset cache data over the network.
Definition: effects.cpp:466
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Make user-friendly text for the source.
Definition: effects.cpp:1011
struct effect_list * get_req_source_effects(struct universal *psource)
Get a list of effects with this requirement source.
Definition: effects.cpp:132
struct effect_list * buildings[B_LAST]
Definition: effects.cpp:106
const effect_list * get_effects()
Get a list of all effects.
Definition: effects.cpp:117
int get_building_bonus(const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
Returns the effect bonus at a building.
Definition: effects.cpp:819
int effect_value_from_universals(enum effect_type type, struct universal *unis, size_t n_unis)
Return the base value of a given effect that can always be expected from just the sources in the list...
Definition: effects.cpp:368
int get_city_tile_output_bonus(const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
Returns the effect bonus at a city tile.
Definition: effects.cpp:728
struct effect * effect_copy(struct effect *old)
Return new copy of the effect.
Definition: effects.cpp:186
int effect_cumulative_max(enum effect_type type, struct universal *for_uni)
Get the maximum effect value in this ruleset for the universal (that is, the sum of all positive effe...
Definition: effects.cpp:307
struct effect * effect_new(enum effect_type type, int value, struct multiplier *pmul)
Add effect to ruleset cache.
Definition: effects.cpp:165
struct effect_list * advances[A_LAST]
Definition: effects.cpp:110
int get_world_bonus(enum effect_type effect_type)
Returns the effect bonus for the whole world.
Definition: effects.cpp:659
int effect_cumulative_min(enum effect_type type, struct universal *for_uni)
Get the minimum effect value in this ruleset for the universal (that is, the sum of all negative effe...
Definition: effects.cpp:336
QString get_effect_list_req_text(const struct effect_list *plist)
Make user-friendly text for an effect list.
Definition: effects.cpp:1040
static struct @19 ruleset_cache
The code creates a ruleset cache on ruleset load.
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Returns TRUE if the building has any effect bonuses of the given type.
Definition: effects.cpp:504
int get_city_bonus(const struct city *pcity, enum effect_type effect_type, enum vision_layer vlayer)
Returns the effect bonus at a city.
Definition: effects.cpp:688
static bool is_effect_prevented(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct effect *peffect, const enum req_problem_type prob_type)
Return TRUE iff any of the disabling requirements for this effect are active, which would prevent it ...
Definition: effects.cpp:535
static bool initialized
Definition: effects.cpp:32
void effect_req_append(struct effect *peffect, struct requirement req)
Append requirement to effect.
Definition: effects.cpp:203
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Returns the effect bonus for a player.
Definition: effects.cpp:673
#define effect_list_iterate_end
Definition: effects.h:349
bool(* iec_cb)(struct effect *, void *data)
Definition: effects.h:449
#define effect_list_iterate(effect_list, peffect)
Definition: effects.h:347
req_problem_type
Definition: fc_types.h:566
@ RPT_CERTAIN
Definition: fc_types.h:568
#define REVERSED_RPT(x)
Definition: fc_types.h:571
#define Q_(String)
Definition: fcintl.h:53
#define PL_(String1, String2, n)
Definition: fcintl.h:54
Government_type_id government_count()
Return the number of governments.
Definition: government.cpp:64
#define G_LAST
Definition: government.h:31
Impr_type_id improvement_count()
Return the number of improvements.
struct impr_type * improvement_by_number(const Impr_type_id id)
Returns the improvement type for the given index/ID.
Impr_type_id improvement_number(const struct impr_type *pimprove)
Return the improvement index.
#define B_LAST
Definition: improvement.h:33
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
struct multiplier * multiplier_by_number(Multiplier_type_id id)
Returns multiplier associated to given number.
Definition: multipliers.cpp:54
const char * multiplier_name_translation(const struct multiplier *pmul)
Return the (translated) name of the multiplier.
Definition: multipliers.cpp:94
Multiplier_type_id multiplier_number(const struct multiplier *pmul)
Returns multiplier number.
Definition: multipliers.cpp:64
int player_multiplier_effect_value(const struct player *pplayer, const struct multiplier *pmul)
Return the multiplier value currently in effect for pplayer, scaled from display units to the units u...
Definition: player.cpp:1867
void universal_extraction(const struct universal *source, int *kind, int *value)
Extract universal structure into its components for serialization; the opposite of universal_by_numbe...
bool universal_fulfills_requirements(bool check_necessary, const struct requirement_vector *reqs, const struct universal *source)
Will the universal 'source' fulfill the requirements in the list? If 'check_necessary' is FALSE: are ...
bool is_req_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement *req, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement to see if it is active on the given target.
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement(s) to see if they are active on the given target.
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Make user-friendly text for the source.
enum req_item_found universal_fulfills_requirement(const struct requirement *preq, const struct universal *source)
Will the universal 'source' fulfill this requirement?
#define requirement_vector_iterate_end
Definition: requirements.h:80
#define requirement_vector_iterate(req_vec, preq)
Definition: requirements.h:78
@ ITF_NO
Definition: requirements.h:254
@ ITF_YES
Definition: requirements.h:254
@ ITF_NOT_APPLICABLE
Definition: requirements.h:254
#define ARRAY_SIZE(x)
Definition: shared.h:79
Definition: city.h:291
struct universal production
Definition: city.h:368
int value
Definition: effects.h:336
struct multiplier * multiplier
Definition: effects.h:331
struct requirement_vector reqs
Definition: effects.h:340
enum effect_type type
Definition: effects.h:328
Definition: player.h:231
struct universal source
Definition: requirements.h:68
Definition: tile.h:42
Definition: unit.h:134
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739
size_t fc_strlcat(char *dest, const char *src, size_t n)
fc_strlcat() provides utf-8 version of (non-standard) function strlcat() It is intended as more user-...
Definition: support.cpp:448
Tech_type_id advance_count()
Return the number of advances/technologies.
Definition: tech.cpp:68
#define A_LAST
Definition: tech.h:38
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
const struct impr_type * building
Definition: fc_types.h:579
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114