Freeciv21
Develop your civilization from humble roots to a global empire
extras.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 
12 // utility
13 #include "fcintl.h"
14 #include "rand.h"
15 
16 // common
17 #include "base.h"
18 #include "game.h"
19 #include "map.h"
20 #include "research.h"
21 #include "road.h"
22 
23 #include "extras.h"
24 
25 static struct extra_type extras[MAX_EXTRA_TYPES];
26 
28 
29 static struct extra_type_list *caused_by[EC_LAST];
30 static struct extra_type_list *removed_by[ERM_COUNT];
31 static struct extra_type_list *unit_hidden;
32 
37 {
38  int i;
39 
40  for (i = 0; i < EC_LAST; i++) {
41  caused_by[i] = extra_type_list_new();
42  }
43  for (i = 0; i < ERM_COUNT; i++) {
44  removed_by[i] = extra_type_list_new();
45  }
46  unit_hidden = extra_type_list_new();
47 
48  for (i = 0; i < MAX_EXTRA_TYPES; i++) {
49  requirement_vector_init(&(extras[i].reqs));
50  requirement_vector_init(&(extras[i].rmreqs));
51  requirement_vector_init(&(extras[i].appearance_reqs));
52  requirement_vector_init(&(extras[i].disappearance_reqs));
53  extras[i].id = i;
54  extras[i].hiders = nullptr;
55  extras[i].bridged = nullptr;
56  extras[i].data.special_idx = -1;
57  extras[i].data.base = nullptr;
58  extras[i].data.road = nullptr;
59  extras[i].data.resource = nullptr;
60  extras[i].causes = 0;
61  extras[i].rmcauses = 0;
62  extras[i].helptext = nullptr;
63  extras[i].ruledit_disabled = false;
65  }
66 }
67 
72 {
73  int i;
74 
78 
79  for (i = 0; i < game.control.num_extra_types; i++) {
80  delete extras[i].data.base;
81  delete extras[i].data.road;
82  delete extras[i].data.resource;
83  extras[i].data.base = nullptr;
84  extras[i].data.road = nullptr;
85  extras[i].data.resource = nullptr;
86  }
87 
88  for (i = 0; i < EC_LAST; i++) {
89  extra_type_list_destroy(caused_by[i]);
90  caused_by[i] = nullptr;
91  }
92 
93  for (i = 0; i < ERM_COUNT; i++) {
94  extra_type_list_destroy(removed_by[i]);
95  removed_by[i] = nullptr;
96  }
97 
98  extra_type_list_destroy(unit_hidden);
99  unit_hidden = nullptr;
100 
101  for (i = 0; i < MAX_EXTRA_TYPES; i++) {
102  requirement_vector_free(&(extras[i].reqs));
103  requirement_vector_free(&(extras[i].rmreqs));
104  requirement_vector_free(&(extras[i].appearance_reqs));
105  requirement_vector_free(&(extras[i].disappearance_reqs));
106  delete extras[i].helptext;
107  extras[i].helptext = nullptr;
108  }
109 
110  extra_type_iterate(pextra)
111  {
112  if (pextra->hiders != nullptr) {
113  extra_type_list_destroy(pextra->hiders);
114  pextra->hiders = nullptr;
115  }
116  if (pextra->bridged != nullptr) {
117  extra_type_list_destroy(pextra->bridged);
118  pextra->bridged = nullptr;
119  }
120  }
122 }
123 
127 int extra_count() { return game.control.num_extra_types; }
128 
132 int extra_number(const struct extra_type *pextra)
133 {
134  fc_assert_ret_val(nullptr != pextra, 0);
135 
136  return pextra->id;
137 }
138 
139 #ifndef extra_index
143 int extra_index(const struct extra_type *pextra)
144 {
145  fc_assert_ret_val(nullptr != pextra, 0);
146 
147  return pextra - extras;
148 }
149 #endif // extra_index
150 
155 {
156  fc_assert_ret_val(id >= 0 && id < MAX_EXTRA_TYPES, nullptr);
157 
158  return &extras[id];
159 }
160 
165 const char *extra_name_translation(const struct extra_type *pextra)
166 {
167  return name_translation_get(&pextra->name);
168 }
169 
174 const char *extra_rule_name(const struct extra_type *pextra)
175 {
176  return rule_name_get(&pextra->name);
177 }
178 
184 {
185  const char *qs;
186 
187  if (name == nullptr) {
188  return nullptr;
189  }
190 
191  qs = Qn_(name);
192 
193  extra_type_iterate(pextra)
194  {
195  if (!fc_strcasecmp(extra_rule_name(pextra), qs)) {
196  return pextra;
197  }
198  }
200 
201  return nullptr;
202 }
203 
209 {
210  extra_type_iterate(pextra)
211  {
212  if (0 == strcmp(extra_name_translation(pextra), name)) {
213  return pextra;
214  }
215  }
217 
218  return nullptr;
219 }
220 
224 struct extra_type_list *extra_type_list_by_cause(enum extra_cause cause)
225 {
226  fc_assert(cause < EC_LAST);
227 
228  return caused_by[cause];
229 }
230 
234 struct extra_type_list *extra_type_list_of_unit_hiders()
235 {
236  return unit_hidden;
237 }
238 
242 struct extra_type *rand_extra_for_tile(struct tile *ptile,
243  enum extra_cause cause,
244  bool generated)
245 {
246  struct extra_type_list *full_list = extra_type_list_by_cause(cause);
247  struct extra_type_list *potential = extra_type_list_new();
248  int options;
249  struct extra_type *selected = nullptr;
250 
251  extra_type_list_iterate(full_list, pextra)
252  {
253  if ((!generated || pextra->generated)
254  && is_native_tile_to_extra(pextra, ptile)) {
255  extra_type_list_append(potential, pextra);
256  }
257  }
259 
260  options = extra_type_list_size(potential);
261 
262  if (options > 0) {
263  selected = extra_type_list_get(potential, fc_rand(options));
264  }
265 
266  extra_type_list_destroy(potential);
267 
268  return selected;
269 }
270 
275  enum extra_cause cause)
276 {
277  fc_assert(cause < EC_LAST);
278 
279  extra_type_list_append(caused_by[cause], pextra);
280 }
281 
285 struct extra_type_list *
286 extra_type_list_by_rmcause(enum extra_rmcause rmcause)
287 {
288  fc_assert(rmcause < ERM_COUNT);
289 
290  return removed_by[rmcause];
291 }
292 
297  enum extra_rmcause rmcause)
298 {
299  fc_assert(rmcause < ERM_COUNT);
300 
301  extra_type_list_append(removed_by[rmcause], pextra);
302 }
303 
307 bool is_extra_removed_by(const struct extra_type *pextra,
308  enum extra_rmcause rmcause)
309 {
310  return (pextra->rmcauses & (1 << rmcause));
311 }
312 
317 bool is_extra_card_near(const struct tile *ptile,
318  const struct extra_type *pextra)
319 {
320  cardinal_adjc_iterate(&(wld.map), ptile, adjc_tile)
321  {
322  if (tile_has_extra(adjc_tile, pextra)) {
323  return true;
324  }
325  }
327 
328  return false;
329 }
330 
335 bool is_extra_near_tile(const struct tile *ptile,
336  const struct extra_type *pextra)
337 {
338  adjc_iterate(&(wld.map), ptile, adjc_tile)
339  {
340  if (tile_has_extra(adjc_tile, pextra)) {
341  return true;
342  }
343  }
345 
346  return false;
347 }
348 
352 bool extra_can_be_built(const struct extra_type *pextra,
353  const struct tile *ptile)
354 {
355  if (!pextra->buildable) {
356  // Extra type not buildable
357  return false;
358  }
359 
360  if (tile_has_extra(ptile, pextra)) {
361  // Extra exist already
362  return false;
363  }
364 
365  return true;
366 }
367 
371 bool can_build_extra_base(const struct extra_type *pextra,
372  const struct player *pplayer,
373  const struct tile *ptile)
374 {
375  if (!extra_can_be_built(pextra, ptile)) {
376  return false;
377  }
378 
379  if (is_extra_caused_by(pextra, EC_BASE)) {
380  if (tile_terrain(ptile)->base_time == 0) {
381  return false;
382  }
383  if (tile_city(ptile) != nullptr
384  && extra_base_get(pextra)->border_sq >= 0) {
385  return false;
386  }
387  }
388 
389  if (is_extra_caused_by(pextra, EC_ROAD)
390  && tile_terrain(ptile)->road_time == 0) {
391  return false;
392  }
393 
394  if (pplayer != nullptr
395  && !player_knows_techs_with_flag(pplayer, TF_BRIDGE)) {
396  /* Player does not know technology to bridge over extras that require it.
397  */
398  extra_type_list_iterate(pextra->bridged, pbridged)
399  {
400  if (tile_has_extra(ptile, pbridged)) {
401  // Tile has extra that would require bridging over.
402  return false;
403  }
404  }
406  }
407 
408  return true;
409 }
410 
414 bool player_can_build_extra(const struct extra_type *pextra,
415  const struct player *pplayer,
416  const struct tile *ptile)
417 {
418  if (!can_build_extra_base(pextra, pplayer, ptile)) {
419  return false;
420  }
421 
422  return are_reqs_active(pplayer, tile_owner(ptile), nullptr, nullptr, ptile,
423  nullptr, nullptr, nullptr, nullptr, nullptr,
424  &pextra->reqs, RPT_POSSIBLE);
425 }
426 
430 bool player_can_place_extra(const struct extra_type *pextra,
431  const struct player *pplayer,
432  const struct tile *ptile)
433 {
434  if (ptile->placing != nullptr) {
435  // Already placing something
436  return false;
437  }
438 
439  if (tile_terrain(ptile)->placing_time <= 0) {
440  // Can't place to this terrain
441  return false;
442  }
443 
444  if (game.info.borders != BORDERS_DISABLED) {
445  if (tile_owner(ptile) != pplayer) {
446  return false;
447  }
448  } else {
449  struct city *pcity = tile_worked(ptile);
450 
451  if (pcity == nullptr || city_owner(pcity) != pplayer) {
452  return false;
453  }
454  }
455 
456  // Placing extras is not allowed to tiles where also workers do changes.
457  unit_list_iterate(ptile->units, punit)
458  {
460  {
461  if (punit->activity == act) {
462  return false;
463  }
464  }
466  }
468 
469  return player_can_build_extra(pextra, pplayer, ptile);
470 }
471 
475 bool can_build_extra(const struct extra_type *pextra,
476  const struct unit *punit, const struct tile *ptile)
477 {
478  struct player *pplayer = unit_owner(punit);
479 
480  if (!can_build_extra_base(pextra, pplayer, ptile)) {
481  return false;
482  }
483 
484  return are_reqs_active(pplayer, tile_owner(ptile), nullptr, nullptr, ptile,
485  punit, unit_type_get(punit), nullptr, nullptr,
486  nullptr, &pextra->reqs, RPT_CERTAIN);
487 }
488 
492 static bool can_extra_be_removed(const struct extra_type *pextra,
493  const struct tile *ptile)
494 {
495  struct city *pcity = tile_city(ptile);
496 
497  // Cannot remove EF_ALWAYS_ON_CITY_CENTER extras from city center.
498  if (pcity != nullptr) {
499  if (extra_has_flag(pextra, EF_ALWAYS_ON_CITY_CENTER)) {
500  return false;
501  }
502  if (extra_has_flag(pextra, EF_AUTO_ON_CITY_CENTER)) {
503  struct tile *vtile = tile_virtual_new(ptile);
504 
505  // Would extra get rebuilt if removed
506  tile_remove_extra(vtile, pextra);
507  if (player_can_build_extra(pextra, city_owner(pcity), vtile)) {
508  /* No need to worry about conflicting extras - extra would had
509  * not been here if conflicting one is. */
510  tile_virtual_destroy(vtile);
511 
512  return false;
513  }
514 
515  tile_virtual_destroy(vtile);
516  }
517  }
518 
519  return true;
520 }
521 
525 bool player_can_remove_extra(const struct extra_type *pextra,
526  const struct player *pplayer,
527  const struct tile *ptile)
528 {
529  if (!can_extra_be_removed(pextra, ptile)) {
530  return false;
531  }
532 
533  // For huts, it's not checked if player has any non-HUT_NOTHING units
534  return are_reqs_active(pplayer, tile_owner(ptile), nullptr, nullptr, ptile,
535  nullptr, nullptr, nullptr, nullptr, nullptr,
536  &pextra->rmreqs, RPT_POSSIBLE);
537 }
538 
543 bool can_remove_extra(const struct extra_type *pextra,
544  const struct unit *punit, const struct tile *ptile)
545 {
546  if (!can_extra_be_removed(pextra, ptile)) {
547  return false;
548  }
549 
550  return are_reqs_active(unit_owner(punit), tile_owner(ptile), nullptr,
551  nullptr, ptile, punit, unit_type_get(punit),
552  nullptr, nullptr, nullptr, &pextra->rmreqs,
553  RPT_CERTAIN);
554 }
555 
559 bool is_native_tile_to_extra(const struct extra_type *pextra,
560  const struct tile *ptile)
561 {
562  struct terrain *pterr = tile_terrain(ptile);
563 
564  if (terrain_has_resource(pterr, pextra)) {
565  return true;
566  }
567 
568  if (is_extra_caused_by(pextra, EC_IRRIGATION)
569  && pterr->irrigation_result != pterr) {
570  return false;
571  }
572 
573  if (is_extra_caused_by(pextra, EC_MINE) && pterr->mining_result != pterr) {
574  return false;
575  }
576 
577  if (is_extra_caused_by(pextra, EC_BASE)) {
578  if (pterr->base_time == 0) {
579  return false;
580  }
581  if (tile_city(ptile) != nullptr
582  && extra_base_get(pextra)->border_sq >= 0) {
583  return false;
584  }
585  }
586 
587  if (is_extra_caused_by(pextra, EC_ROAD)) {
588  struct road_type *proad = extra_road_get(pextra);
589 
590  if (road_has_flag(proad, RF_RIVER)) {
591  if (!terrain_has_flag(pterr, TER_CAN_HAVE_RIVER)) {
592  return false;
593  }
594  } else if (pterr->road_time == 0) {
595  return false;
596  }
597  }
598 
599  return are_reqs_active(nullptr, nullptr, nullptr, nullptr, ptile, nullptr,
600  nullptr, nullptr, nullptr, nullptr, &pextra->reqs,
601  RPT_POSSIBLE);
602 }
603 
607 bool extra_conflicting_on_tile(const struct extra_type *pextra,
608  const struct tile *ptile)
609 {
610  extra_type_iterate(old_extra)
611  {
612  if (tile_has_extra(ptile, old_extra)
613  && !can_extras_coexist(old_extra, pextra)) {
614  return true;
615  }
616  }
618 
619  return false;
620 }
621 
626 bool hut_on_tile(const struct tile *ptile)
627 {
628  extra_type_by_rmcause_iterate(ERM_ENTER, extra)
629  {
630  if (tile_has_extra(ptile, extra)) {
631  return true;
632  }
633  }
635 
636  return false;
637 }
638 
643 bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
644 {
645  if (HUT_NORMAL != unit_class_get(punit)->hut_behavior) {
646  return false;
647  }
648  extra_type_by_rmcause_iterate(ERM_ENTER, extra)
649  {
650  if (tile_has_extra(ptile, extra)
651  && are_reqs_active(unit_owner(punit), tile_owner(ptile), nullptr,
652  nullptr, ptile, nullptr, nullptr, nullptr,
653  nullptr, nullptr, &extra->rmreqs, RPT_POSSIBLE)) {
654  return true;
655  }
656  }
658  return false;
659 }
660 
665 bool unit_can_displace_hut(const struct unit *punit,
666  const struct tile *ptile)
667 {
668  if (HUT_NOTHING == unit_class_get(punit)->hut_behavior) {
669  return false;
670  }
671  extra_type_by_rmcause_iterate(ERM_ENTER, extra)
672  {
673  if (tile_has_extra(ptile, extra)
674  && are_reqs_active(unit_owner(punit), tile_owner(ptile), nullptr,
675  nullptr, ptile, nullptr, nullptr, nullptr,
676  nullptr, nullptr, &extra->rmreqs, RPT_POSSIBLE)) {
677  return true;
678  }
679  }
681  return false;
682 }
683 
687 struct extra_type *next_extra_for_tile(const struct tile *ptile,
688  enum extra_cause cause,
689  const struct player *pplayer,
690  const struct unit *punit)
691 {
692  if (cause == EC_IRRIGATION) {
693  struct terrain *pterrain = tile_terrain(ptile);
694 
695  if (pterrain->irrigation_result != pterrain) {
696  // No extra can be created by irrigation the tile
697  return nullptr;
698  }
699  }
700  if (cause == EC_MINE) {
701  struct terrain *pterrain = tile_terrain(ptile);
702 
703  if (pterrain->mining_result != pterrain) {
704  // No extra can be created by mining the tile
705  return nullptr;
706  }
707  }
708 
709  extra_type_by_cause_iterate(cause, pextra)
710  {
711  if (!tile_has_extra(ptile, pextra)) {
712  if (punit != nullptr) {
713  if (can_build_extra(pextra, punit, ptile)) {
714  return pextra;
715  }
716  } else {
717  // punit is certainly nullptr, pplayer can be too
718  if (player_can_build_extra(pextra, pplayer, ptile)) {
719  return pextra;
720  }
721  }
722  }
723  }
725 
726  return nullptr;
727 }
728 
732 struct extra_type *prev_extra_in_tile(const struct tile *ptile,
733  enum extra_rmcause rmcause,
734  const struct player *pplayer,
735  const struct unit *punit)
736 {
737  fc_assert(punit != nullptr || pplayer != nullptr);
738 
739  extra_type_by_rmcause_iterate(rmcause, pextra)
740  {
741  if (tile_has_extra(ptile, pextra)) {
742  if (punit != nullptr) {
743  if (can_remove_extra(pextra, punit, ptile)) {
744  return pextra;
745  }
746  } else {
747  if (player_can_remove_extra(pextra, pplayer, ptile)) {
748  return pextra;
749  }
750  }
751  }
752  }
754 
755  return nullptr;
756 }
757 
761 bool is_native_extra_to_uclass(const struct extra_type *pextra,
762  const struct unit_class *pclass)
763 {
764  return BV_ISSET(pextra->native_to, uclass_index(pclass));
765 }
766 
770 bool is_native_extra_to_utype(const struct extra_type *pextra,
771  const struct unit_type *punittype)
772 {
773  return is_native_extra_to_uclass(pextra, utype_class(punittype));
774 }
775 
779 bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
780 {
781  return BV_ISSET(pextra->flags, flag);
782 }
783 
788 bool is_extra_flag_card_near(const struct tile *ptile,
789  enum extra_flag_id flag)
790 {
791  extra_type_iterate(pextra)
792  {
793  if (extra_has_flag(pextra, flag)) {
794  cardinal_adjc_iterate(&(wld.map), ptile, adjc_tile)
795  {
796  if (tile_has_extra(adjc_tile, pextra)) {
797  return true;
798  }
799  }
801  }
802  }
804 
805  return false;
806 }
807 
812 bool is_extra_flag_near_tile(const struct tile *ptile,
813  enum extra_flag_id flag)
814 {
815  extra_type_iterate(pextra)
816  {
817  if (extra_has_flag(pextra, flag)) {
818  adjc_iterate(&(wld.map), ptile, adjc_tile)
819  {
820  if (tile_has_extra(adjc_tile, pextra)) {
821  return true;
822  }
823  }
825  }
826  }
828 
829  return false;
830 }
831 
836 {
837  int i;
838 
839  for (i = 0; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
841  }
842 }
843 
848 {
849  int i;
850 
851  for (i = 0; i < MAX_NUM_USER_EXTRA_FLAGS; i++) {
853  }
854 }
855 
859 void set_user_extra_flag_name(enum extra_flag_id id, const char *name,
860  const char *helptxt)
861 {
862  int efid = id - EF_USER_FLAG_1;
863 
864  fc_assert_ret(id >= EF_USER_FLAG_1 && id <= EF_LAST_USER_FLAG);
865  delete[] user_extra_flags[efid].name;
866  user_extra_flags[efid].name = nullptr;
867  if (name && name[0] != '\0') {
869  }
870  delete[] user_extra_flags[efid].helptxt;
871  user_extra_flags[efid].helptxt = nullptr;
872  if (helptxt && helptxt[0] != '\0') {
873  user_extra_flags[efid].helptxt = fc_strdup(helptxt);
874  }
875 }
876 
880 const char *extra_flag_id_name_cb(enum extra_flag_id flag)
881 {
882  if (flag < EF_USER_FLAG_1 || flag > EF_LAST_USER_FLAG) {
883  return nullptr;
884  }
885 
886  return user_extra_flags[flag - EF_USER_FLAG_1].name;
887 }
888 
892 const char *extra_flag_helptxt(enum extra_flag_id id)
893 {
894  fc_assert(id >= EF_USER_FLAG_1 && id <= EF_LAST_USER_FLAG);
895 
896  return user_extra_flags[id - EF_USER_FLAG_1].helptxt;
897 }
898 
902 bool can_extras_coexist(const struct extra_type *pextra1,
903  const struct extra_type *pextra2)
904 {
905  if (pextra1 == pextra2) {
906  return true;
907  }
908 
909  return !BV_ISSET(pextra1->conflicts, extra_index(pextra2));
910 }
911 
915 bool extra_causes_env_upset(struct extra_type *pextra,
916  enum environment_upset_type upset)
917 {
918  switch (upset) {
919  case EUT_GLOBAL_WARMING:
920  return extra_has_flag(pextra, EF_GLOBAL_WARMING);
921  case EUT_NUCLEAR_WINTER:
922  return extra_has_flag(pextra, EF_NUCLEAR_WINTER);
923  }
924 
925  return false;
926 }
927 
932 {
933  // Is any of the worker build action bits set?
934  return (
935  pextra->causes
936  & (1 << EC_IRRIGATION | 1 << EC_MINE | 1 << EC_BASE | 1 << EC_ROAD));
937 }
938 
943 {
944  // Is any of the worker remove action bits set?
945  return (pextra->rmcauses
946  & (1 << ERM_CLEANPOLLUTION | 1 << ERM_CLEANFALLOUT
947  | 1 << ERM_PILLAGE));
948 }
949 
953 bool is_extra_caused_by_action(const struct extra_type *pextra,
954  const struct action *paction)
955 {
956  enum unit_activity act = action_get_activity(paction);
957  return is_extra_caused_by(pextra, activity_to_extra_cause(act));
958 }
959 
963 bool is_extra_removed_by_action(const struct extra_type *pextra,
964  const struct action *paction)
965 {
966  enum unit_activity act = action_get_activity(paction);
967  return is_extra_removed_by(pextra, activity_to_extra_rmcause(act));
968 }
969 
973 enum extra_cause activity_to_extra_cause(enum unit_activity act)
974 {
975  switch (act) {
976  case ACTIVITY_IRRIGATE:
977  return EC_IRRIGATION;
978  case ACTIVITY_MINE:
979  return EC_MINE;
980  case ACTIVITY_BASE:
981  return EC_BASE;
982  case ACTIVITY_GEN_ROAD:
983  return EC_ROAD;
984  default:
985  break;
986  }
987 
988  return EC_NONE;
989 }
990 
994 enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
995 {
996  switch (act) {
997  case ACTIVITY_PILLAGE:
998  return ERM_PILLAGE;
999  case ACTIVITY_POLLUTION:
1000  return ERM_CLEANPOLLUTION;
1001  case ACTIVITY_FALLOUT:
1002  return ERM_CLEANFALLOUT;
1003  default:
1004  break;
1005  }
1006 
1007  return ERM_NONE;
1008 }
1009 
1013 struct player *extra_owner(const struct tile *ptile)
1014 {
1015  return ptile->extras_owner;
1016 }
1017 
1021 bool can_extra_appear(const struct extra_type *pextra,
1022  const struct tile *ptile)
1023 {
1024  return !tile_has_extra(ptile, pextra)
1025  && is_extra_caused_by(pextra, EC_APPEARANCE)
1026  && is_native_tile_to_extra(pextra, ptile)
1027  && !extra_conflicting_on_tile(pextra, ptile)
1028  && are_reqs_active(nullptr, tile_owner(ptile), nullptr, nullptr,
1029  ptile, nullptr, nullptr, nullptr, nullptr,
1030  nullptr, &pextra->appearance_reqs, RPT_CERTAIN);
1031 }
1032 
1036 bool can_extra_disappear(const struct extra_type *pextra,
1037  const struct tile *ptile)
1038 {
1039  return tile_has_extra(ptile, pextra)
1040  && is_extra_removed_by(pextra, ERM_DISAPPEARANCE)
1041  && can_extra_be_removed(pextra, ptile)
1042  && are_reqs_active(nullptr, tile_owner(ptile), nullptr, nullptr,
1043  ptile, nullptr, nullptr, nullptr, nullptr,
1044  nullptr, &pextra->disappearance_reqs,
1045  RPT_CERTAIN);
1046 }
1047 
1051 bool player_knows_extra_exist(const struct player *pplayer,
1052  const struct extra_type *pextra,
1053  const struct tile *ptile)
1054 {
1055  if (!tile_has_extra(ptile, pextra)) {
1056  return false;
1057  }
1058 
1059  return research_invention_state(research_get(pplayer),
1060  pextra->visibility_req)
1061  == TECH_KNOWN;
1062 }
enum unit_activity action_get_activity(const struct action *paction)
Returns the unit activity this action may cause or ACTIVITY_LAST if the action doesn't result in a un...
Definition: actions.cpp:1557
void base_types_free()
Free the memory associated with base types.
Definition: base.cpp:170
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
struct @19::@20 reqs
bool is_extra_removed_by_worker_action(const struct extra_type *pextra)
Is the extra removed by some kind of worker action?
Definition: extras.cpp:942
struct extra_type_list * extra_type_list_of_unit_hiders()
Returns extra types that hide units.
Definition: extras.cpp:234
bool extra_causes_env_upset(struct extra_type *pextra, enum environment_upset_type upset)
Does the extra count toward environment upset?
Definition: extras.cpp:915
bool can_build_extra_base(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Tells if player can build extra to tile with suitable unit.
Definition: extras.cpp:371
bool unit_can_displace_hut(const struct unit *punit, const struct tile *ptile)
Returns TRUE iff the unit can enter or frighten any hut on the tile.
Definition: extras.cpp:665
bool player_can_place_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Tells if player can place extra on tile.
Definition: extras.cpp:430
struct extra_type * rand_extra_for_tile(struct tile *ptile, enum extra_cause cause, bool generated)
Return random extra type for given cause that is native to the tile.
Definition: extras.cpp:242
struct extra_type * extra_type_by_rule_name(const char *name)
Returns extra type matching rule name or nullptr if there is no extra type with such name.
Definition: extras.cpp:183
void set_user_extra_flag_name(enum extra_flag_id id, const char *name, const char *helptxt)
Sets user defined name for extra flag.
Definition: extras.cpp:859
struct extra_type * extra_by_number(int id)
Return extras type of given id.
Definition: extras.cpp:154
static struct extra_type_list * removed_by[ERM_COUNT]
Definition: extras.cpp:30
bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
Returns TRUE iff the unit can enter any hut on the tile.
Definition: extras.cpp:643
bool is_extra_caused_by_worker_action(const struct extra_type *pextra)
Is the extra caused by some kind of worker action?
Definition: extras.cpp:931
bool can_extra_appear(const struct extra_type *pextra, const struct tile *ptile)
Are all the requirements for extra to appear on tile fulfilled.
Definition: extras.cpp:1021
struct player * extra_owner(const struct tile *ptile)
Who owns extras on tile.
Definition: extras.cpp:1013
int extra_number(const struct extra_type *pextra)
Return the extra id.
Definition: extras.cpp:132
bool is_extra_flag_card_near(const struct tile *ptile, enum extra_flag_id flag)
Returns TRUE iff any cardinally adjacent tile contains an extra with the given flag (does not check p...
Definition: extras.cpp:788
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Check if extra has given flag.
Definition: extras.cpp:779
static struct extra_type_list * caused_by[EC_LAST]
Definition: extras.cpp:29
bool is_native_tile_to_extra(const struct extra_type *pextra, const struct tile *ptile)
Is tile native to extra?
Definition: extras.cpp:559
const char * extra_flag_id_name_cb(enum extra_flag_id flag)
Extra flag name callback, called from specenum code.
Definition: extras.cpp:880
void extra_flags_free()
Frees the memory associated with all extra flags.
Definition: extras.cpp:847
bool hut_on_tile(const struct tile *ptile)
Returns TRUE iff an extra on the tile is a hut (removed by entering).
Definition: extras.cpp:626
const char * extra_name_translation(const struct extra_type *pextra)
Return the (translated) name of the extra type.
Definition: extras.cpp:165
void extra_to_caused_by_list(struct extra_type *pextra, enum extra_cause cause)
Add extra type to list of extra caused by given cause.
Definition: extras.cpp:274
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Tells if player can build extra to tile with suitable unit.
Definition: extras.cpp:414
enum extra_cause activity_to_extra_cause(enum unit_activity act)
What extra cause activity is considered to be?
Definition: extras.cpp:973
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition: extras.cpp:25
bool extra_can_be_built(const struct extra_type *pextra, const struct tile *ptile)
Tells if extra can build to tile if all other requirements are met.
Definition: extras.cpp:352
bool is_native_extra_to_utype(const struct extra_type *pextra, const struct unit_type *punittype)
Is extra native to unit type?
Definition: extras.cpp:770
bool extra_conflicting_on_tile(const struct extra_type *pextra, const struct tile *ptile)
Returns TRUE iff an extra that conflicts with pextra exists at ptile.
Definition: extras.cpp:607
static struct user_flag user_extra_flags[MAX_NUM_USER_EXTRA_FLAGS]
Definition: extras.cpp:27
void extras_init()
Initialize extras structures.
Definition: extras.cpp:36
void extra_to_removed_by_list(struct extra_type *pextra, enum extra_rmcause rmcause)
Add extra type to list of extra removed by given cause.
Definition: extras.cpp:296
struct extra_type * extra_type_by_translated_name(const char *name)
Returns extra type matching the translated name, or nullptr if there is no extra type with that name.
Definition: extras.cpp:208
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Returns prev extra by cause that unit or player can remove from tile.
Definition: extras.cpp:732
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Can two extras coexist in same tile?
Definition: extras.cpp:902
bool is_extra_near_tile(const struct tile *ptile, const struct extra_type *pextra)
Is there extra of the given type near tile? (Does not check ptile itself.)
Definition: extras.cpp:335
struct extra_type_list * extra_type_list_by_cause(enum extra_cause cause)
Returns extra type for given cause.
Definition: extras.cpp:224
bool can_remove_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Tells if unit can remove extra from tile.
Definition: extras.cpp:543
struct extra_type_list * extra_type_list_by_rmcause(enum extra_rmcause rmcause)
Returns extra type for given rmcause.
Definition: extras.cpp:286
static struct extra_type_list * unit_hidden
Definition: extras.cpp:31
bool is_extra_flag_near_tile(const struct tile *ptile, enum extra_flag_id flag)
Returns TRUE iff any adjacent tile contains an extra with the given flag (does not check ptile itself...
Definition: extras.cpp:812
bool is_extra_caused_by_action(const struct extra_type *pextra, const struct action *paction)
Is the extra caused by specific worker action?
Definition: extras.cpp:953
const char * extra_flag_helptxt(enum extra_flag_id id)
Return the (untranslated) help text of the user extra flag.
Definition: extras.cpp:892
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Is given cause one of the removal causes for the given extra?
Definition: extras.cpp:307
void extras_free()
Free the memory associated with extras.
Definition: extras.cpp:71
bool is_extra_removed_by_action(const struct extra_type *pextra, const struct action *paction)
Is the extra removed by specific worker action?
Definition: extras.cpp:963
int extra_count()
Return the number of extra_types.
Definition: extras.cpp:127
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
What extra rmcause activity is considered to be?
Definition: extras.cpp:994
bool is_extra_card_near(const struct tile *ptile, const struct extra_type *pextra)
Is there extra of the given type cardinally near tile? (Does not check ptile itself....
Definition: extras.cpp:317
bool player_can_remove_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Tells if player can remove extra from tile with suitable unit.
Definition: extras.cpp:525
void user_extra_flags_init()
Initialize user extra flags.
Definition: extras.cpp:835
const char * extra_rule_name(const struct extra_type *pextra)
Return the (untranslated) rule name of the extra type.
Definition: extras.cpp:174
static bool can_extra_be_removed(const struct extra_type *pextra, const struct tile *ptile)
Is it possible at all to remove this extra now.
Definition: extras.cpp:492
bool player_knows_extra_exist(const struct player *pplayer, const struct extra_type *pextra, const struct tile *ptile)
Extra is not hidden from the user.
Definition: extras.cpp:1051
bool can_build_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Tells if unit can build extra on tile.
Definition: extras.cpp:475
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Is extra native to unit class?
Definition: extras.cpp:761
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Returns next extra by cause that unit or player can build to tile.
Definition: extras.cpp:687
bool can_extra_disappear(const struct extra_type *pextra, const struct tile *ptile)
Are all the requirements for extra to disappear from tile fulfilled.
Definition: extras.cpp:1036
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_list_iterate(extralist, pextra)
Definition: extras.h:145
#define extra_type_iterate_end
Definition: extras.h:285
#define extra_type_by_rmcause_iterate_end
Definition: extras.h:330
#define is_extra_caused_by(e, c)
Definition: extras.h:182
#define extra_index(_e_)
Definition: extras.h:163
#define extra_type_by_rmcause_iterate(_rmcause, _extra)
Definition: extras.h:324
#define extra_type_list_iterate_end
Definition: extras.h:147
#define extra_base_get(_e_)
Definition: extras.h:170
#define extra_road_get(_e_)
Definition: extras.h:171
#define extra_type_by_cause_iterate_end
Definition: extras.h:307
#define EF_LAST_USER_FLAG
Definition: extras.h:69
#define MAX_NUM_USER_EXTRA_FLAGS
Definition: extras.h:70
#define extra_type_by_cause_iterate(_cause, _extra)
Definition: extras.h:299
#define EC_LAST
Definition: fc_types.h:938
environment_upset_type
Definition: fc_types.h:1085
@ EUT_NUCLEAR_WINTER
Definition: fc_types.h:1085
@ EUT_GLOBAL_WARMING
Definition: fc_types.h:1085
@ RPT_CERTAIN
Definition: fc_types.h:568
@ RPT_POSSIBLE
Definition: fc_types.h:567
#define EC_NONE
Definition: fc_types.h:934
#define MAX_EXTRA_TYPES
Definition: fc_types.h:42
#define ERM_NONE
Definition: fc_types.h:958
@ BORDERS_DISABLED
Definition: fc_types.h:863
#define Qn_(String)
Definition: fcintl.h:66
void user_flag_init(struct user_flag *flag)
Initialize user flag.
Definition: game.cpp:788
void user_flag_free(struct user_flag *flag)
Free user flag.
Definition: game.cpp:797
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
const char * name
Definition: inputfile.cpp:118
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define adjc_iterate_end
Definition: map.h:358
#define cardinal_adjc_iterate_end
Definition: map.h:384
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:380
static const char * rule_name_get(const struct name_translation *ptrans)
static const char * name_translation_get(const struct name_translation *ptrans)
bool player_knows_techs_with_flag(const struct player *pplayer, enum tech_flag_id flag)
Returns TRUE iff the player knows at least one tech which has the given flag.
Definition: player.cpp:1238
#define fc_rand(_size)
Definition: rand.h:16
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.
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Check if road provides effect.
Definition: road.cpp:367
void road_types_free()
Free the memory associated with road types.
Definition: road.cpp:124
Definition: city.h:291
struct packet_ruleset_control control
Definition: game.h:74
struct packet_game_info info
Definition: game.h:80
bv_unit_classes native_to
Definition: extras.h:113
bv_extras conflicts
Definition: extras.h:116
uint8_t rmcauses
Definition: extras.h:80
struct requirement_vector appearance_reqs
Definition: extras.h:92
bv_extra_flags flags
Definition: extras.h:115
struct extra_type_list * hiders
Definition: extras.h:125
uint16_t causes
Definition: extras.h:79
struct road_type * road
Definition: extras.h:135
struct resource_type * resource
Definition: extras.h:136
struct extra_type_list * bridged
Definition: extras.h:128
bool ruledit_disabled
Definition: extras.h:77
struct requirement_vector disappearance_reqs
Definition: extras.h:93
bool generated
Definition: extras.h:101
int special_idx
Definition: extras.h:133
struct requirement_vector rmreqs
Definition: extras.h:91
Tech_type_id visibility_req
Definition: extras.h:120
int id
Definition: extras.h:75
struct extra_type::@22 data
struct requirement_vector reqs
Definition: extras.h:90
bool buildable
Definition: extras.h:100
QVector< QString > * helptext
Definition: extras.h:130
struct name_translation name
Definition: extras.h:76
struct base_type * base
Definition: extras.h:134
Definition: player.h:231
Definition: road.h:54
int road_time
Definition: terrain.h:194
struct terrain * irrigation_result
Definition: terrain.h:200
struct terrain * mining_result
Definition: terrain.h:204
int base_time
Definition: terrain.h:193
Definition: tile.h:42
struct unit_list * units
Definition: tile.h:50
struct player * extras_owner
Definition: tile.h:55
struct extra_type * placing
Definition: tile.h:53
Definition: unit.h:134
Definition: game.h:64
char * name
Definition: game.h:65
char * helptxt
Definition: game.h:66
struct civ_map map
Definition: world_object.h:21
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
Definition: support.cpp:89
#define fc_strdup(str)
Definition: support.h:111
#define A_NONE
Definition: tech.h:36
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Check for resource in terrain resources list.
Definition: terrain.cpp:192
void resource_types_free()
Free the memory associated with resource types.
Definition: terrain.cpp:223
#define terrain_has_flag(terr, flag)
Definition: terrain.h:260
void tile_virtual_destroy(struct tile *vtile)
Frees all memory used by the virtual tile, including freeing virtual units in the tile's unit list an...
Definition: tile.cpp:1051
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Removes extra from tile if such exist.
Definition: tile.cpp:984
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
struct tile * tile_virtual_new(const struct tile *ptile)
Returns a virtual tile.
Definition: tile.cpp:997
#define tile_worked(_tile)
Definition: tile.h:97
#define tile_terrain(_tile)
Definition: tile.h:93
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130
#define tile_owner(_tile)
Definition: tile.h:78
#define tile_changing_activities_iterate_end
Definition: unit.h:296
#define unit_owner(_pu)
Definition: unit.h:370
#define tile_changing_activities_iterate(_act_)
Definition: unit.h:292
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
struct unit_class * unit_class_get(const struct unit *punit)
Returns unit class pointer for a unit.
Definition: unittype.cpp:2151
#define utype_class(_t_)
Definition: unittype.h:691
hut_behavior
Definition: unittype.h:113
@ HUT_NOTHING
Definition: unittype.h:113
@ HUT_NORMAL
Definition: unittype.h:113
#define uclass_index(_c_)
Definition: unittype.h:684