Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/improvement.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
improvement.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "fcintl.h"
20#include "log.h"
21#include "mem.h"
22#include "shared.h" /* ARRAY_SIZE */
23#include "string_vector.h"
24#include "support.h"
25
26/* common */
27#include "game.h"
28#include "map.h"
29#include "tech.h"
30#include "victory.h"
31
32#include "improvement.h"
33
34/**************************************************************************
35All the city improvements:
36Use improvement_by_number(id) to access the array.
37The improvement_types array is now setup in:
38 server/ruleset.c (for the server)
39 client/packhand.c (for the client)
40**************************************************************************/
41 static struct impr_type improvement_types[B_LAST];
42
43/**********************************************************************/
46 void improvements_init(void)
47{
48 int i;
49
50 /* Can't use improvement_iterate() or improvement_by_number() here
51 * because num_impr_types isn't known yet. */
52 for (i = 0; i < ARRAY_SIZE(improvement_types); i++) {
53 struct impr_type *p = &improvement_types[i];
54
55 p->item_number = i;
56 requirement_vector_init(&p->reqs);
57 requirement_vector_init(&p->obsolete_by);
58 p->ruledit_disabled = FALSE;
59 p->ruledit_dlg = NULL;
60 }
61}
62
63/**********************************************************************/
66 static void improvement_free(struct impr_type *p)
67{
68 if (NULL != p->helptext) {
69 strvec_destroy(p->helptext);
70 p->helptext = NULL;
71 }
72
73 requirement_vector_free(&p->reqs);
74 requirement_vector_free(&p->obsolete_by);
75}
76
77/**********************************************************************/
80 void improvements_free(void)
81{
82 improvement_iterate(p) {
83 improvement_free(p);
84 } improvement_iterate_end;
85}
86
87/**********************************************************************/
90 void improvement_feature_cache_init(void)
91{
92 improvement_iterate(pimprove) {
93 pimprove->allows_units = FALSE;
94 unit_type_iterate(putype) {
95 if (requirement_needs_improvement(pimprove, &putype->build_reqs)) {
96 pimprove->allows_units = TRUE;
97 break;
98 }
99 } unit_type_iterate_end;
100
101 pimprove->allows_extras = FALSE;
102 extra_type_iterate(pextra) {
103 if (requirement_needs_improvement(pimprove, &pextra->reqs)) {
104 pimprove->allows_extras = TRUE;
105 break;
106 }
107 } extra_type_iterate_end;
108
109 pimprove->prevents_disaster = FALSE;
110 disaster_type_iterate(pdis) {
111 if (!requirement_fulfilled_by_improvement(pimprove, &pdis->reqs)) {
112 pimprove->prevents_disaster = TRUE;
113 break;
114 }
115 } disaster_type_iterate_end;
116
117 pimprove->protects_vs_actions = FALSE;
118 action_enablers_iterate(act) {
119 if (!requirement_fulfilled_by_improvement(pimprove,
120 &act->target_reqs)) {
121 pimprove->protects_vs_actions = TRUE;
122 break;
123 }
124 } action_enablers_iterate_end;
125
126 pimprove->allows_actions = FALSE;
127 action_enablers_iterate(act) {
128 if (requirement_needs_improvement(pimprove, &act->actor_reqs)) {
129 pimprove->allows_actions = TRUE;
130 break;
131 }
132 } action_enablers_iterate_end;
133
134 } improvement_iterate_end;
135}
136
137/**********************************************************************/
140 struct impr_type *improvement_array_first(void)
141{
142 if (game.control.num_impr_types > 0) {
143 return improvement_types;
144 }
145 return NULL;
146}
147
148/**********************************************************************/
151 const struct impr_type *improvement_array_last(void)
152{
153 if (game.control.num_impr_types > 0) {
154 return &improvement_types[game.control.num_impr_types - 1];
155 }
156 return NULL;
157}
158
159/**********************************************************************/
162 Impr_type_id improvement_count(void)
163{
164 return game.control.num_impr_types;
165}
166
167/**********************************************************************/
173 Impr_type_id improvement_index(const struct impr_type *pimprove)
174{
175 fc_assert_ret_val(NULL != pimprove, -1);
176 return pimprove - improvement_types;
177}
178
179/**********************************************************************/
182 Impr_type_id improvement_number(const struct impr_type *pimprove)
183{
184 fc_assert_ret_val(NULL != pimprove, -1);
185 return pimprove->item_number;
186}
187
188/**********************************************************************/
192 struct impr_type *improvement_by_number(const Impr_type_id id)
193{
194 if (id < 0 || id >= improvement_count()) {
195 return NULL;
196 }
197 return &improvement_types[id];
198}
199
200/**********************************************************************/
209 const struct impr_type *valid_improvement(const struct impr_type *pimprove)
210{
211 if (NULL == pimprove) {
212 return NULL;
213 }
214
215 if (!victory_enabled(VC_SPACERACE)
216 && (building_has_effect(pimprove, EFT_SS_STRUCTURAL)
217 || building_has_effect(pimprove, EFT_SS_COMPONENT)
218 || building_has_effect(pimprove, EFT_SS_MODULE))) {
219 /* This assumes that space parts don't have any other effects. */
220 return NULL;
221 }
222
223 return pimprove;
224}
225
226/**********************************************************************/
232 const struct impr_type *valid_improvement_by_number(const Impr_type_id id)
233{
234 return valid_improvement(improvement_by_number(id));
235}
236
237/**********************************************************************/
241 const char *improvement_name_translation(const struct impr_type *pimprove)
242{
243 return name_translation_get(&pimprove->name);
244}
245
246/**********************************************************************/
250 const char *improvement_rule_name(const struct impr_type *pimprove)
251{
252 return rule_name_get(&pimprove->name);
253}
254
255/**********************************************************************/
259 int impr_base_build_shield_cost(const struct impr_type *pimprove)
260{
261 int base = pimprove->build_cost;
262
263 return MAX(base * game.info.shieldbox / 100, 1);
264}
265
266/**********************************************************************/
271 int impr_estimate_build_shield_cost(const struct player *pplayer,
272 const struct tile *ptile,
273 const struct impr_type *pimprove)
274{
275 int base = pimprove->build_cost
276 * (100 +
277 get_target_bonus_effects(NULL,
278 &(const struct req_context) {
279 .player = pplayer,
280 .building = pimprove,
281 .tile = ptile,
282 },
283 NULL,
284 EFT_IMPR_BUILD_COST_PCT)) / 100;
285
286 return MAX(base * game.info.shieldbox / 100, 1);
287}
288
289/**********************************************************************/
292 int impr_build_shield_cost(const struct city *pcity,
293 const struct impr_type *pimprove)
294{
295 int base = pimprove->build_cost
296 * (100 + get_building_bonus(pcity, pimprove, EFT_IMPR_BUILD_COST_PCT)) / 100;
297
298 return MAX(base * game.info.shieldbox / 100, 1);
299}
300
301/**********************************************************************/
304 int impr_buy_gold_cost(const struct city *pcity,
305 const struct impr_type *pimprove, int shields_in_stock)
306{
307 int cost = 0;
308 const int missing = impr_build_shield_cost(pcity, pimprove) - shields_in_stock;
309
310 if (improvement_has_flag(pimprove, IF_GOLD)) {
311 /* Can't buy capitalization. */
312 return 0;
313 }
314
315 if (missing > 0) {
316 cost = 2 * missing;
317 }
318
319 if (shields_in_stock == 0) {
320 cost *= 2;
321 }
322
323 cost = cost
324 * (100 + get_building_bonus(pcity, pimprove, EFT_IMPR_BUY_COST_PCT)) / 100;
325
326 return cost;
327}
328
329/**********************************************************************/
332 int impr_sell_gold(const struct impr_type *pimprove)
333{
334 return MAX(pimprove->build_cost * game.info.shieldbox / 100, 1);
335}
336
337/**********************************************************************/
341 bool is_wonder(const struct impr_type *pimprove)
342{
343 return (is_great_wonder(pimprove) || is_small_wonder(pimprove));
344}
345
346/**********************************************************************/
350 struct impr_type *improvement_by_translated_name(const char *name)
351{
352 improvement_iterate(pimprove) {
353 if (0 == strcmp(improvement_name_translation(pimprove), name)) {
354 return pimprove;
355 }
356 } improvement_iterate_end;
357
358 return NULL;
359}
360
361/**********************************************************************/
365 struct impr_type *improvement_by_rule_name(const char *name)
366{
367 const char *qname = Qn_(name);
368
369 improvement_iterate(pimprove) {
370 if (0 == fc_strcasecmp(improvement_rule_name(pimprove), qname)) {
371 return pimprove;
372 }
373 } improvement_iterate_end;
374
375 return NULL;
376}
377
378/**********************************************************************/
381 bool improvement_has_flag(const struct impr_type *pimprove,
382 enum impr_flag_id flag)
383{
384 fc_assert_ret_val(impr_flag_id_is_valid(flag), FALSE);
385 return BV_ISSET(pimprove->flags, flag);
386}
387
388/**********************************************************************/
391 bool is_improvement_visible(const struct impr_type *pimprove)
392{
393 return (is_wonder(pimprove)
394 || improvement_has_flag(pimprove, IF_VISIBLE_BY_OTHERS));
395}
396
397/**********************************************************************/
401 bool can_improvement_go_obsolete(const struct impr_type *pimprove)
402{
403 return requirement_vector_size(&pimprove->obsolete_by) > 0;
404}
405
406/**********************************************************************/
409 bool improvement_obsolete(const struct player *pplayer,
410 const struct impr_type *pimprove,
411 const struct city *pcity)
412{
413 const struct req_context context = {
414 .player = pplayer,
415 .city = pcity,
416 .tile = pcity ? city_tile(pcity) : NULL,
417 .building = pimprove,
418 };
419
420 requirement_vector_iterate(&pimprove->obsolete_by, preq) {
421 if (is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
422 return TRUE;
423 }
424 } requirement_vector_iterate_end;
425
426 return FALSE;
427}
428
429/**********************************************************************/
432 static bool impr_provides_buildable_units(const struct city *pcity,
433 const struct impr_type *pimprove)
434{
435 /* Fast check */
436 if (!pimprove->allows_units) {
437 return FALSE;
438 }
439
440 unit_type_iterate(ut) {
441 if (requirement_needs_improvement(pimprove, &ut->build_reqs)
442 && can_city_build_unit_now(pcity, ut)) {
443 return TRUE;
444 }
445 } unit_type_iterate_end;
446
447 return FALSE;
448}
449
450/**********************************************************************/
453 static bool impr_provides_buildable_extras(const struct city *pcity,
454 const struct impr_type *pimprove)
455{
456 const struct civ_map *nmap = &(wld.map);
457
458 /* Fast check */
459 if (!pimprove->allows_extras) {
460 return FALSE;
461 }
462
463 extra_type_iterate(pextra) {
464 if (requirement_needs_improvement(pimprove, &pextra->reqs)) {
465 city_tile_iterate(nmap, city_map_radius_sq_get(pcity),
466 city_tile(pcity), ptile) {
467 if (player_can_build_extra(pextra, city_owner(pcity), ptile)) {
468 return TRUE;
469 }
470 } city_tile_iterate_end;
471 }
472 } extra_type_iterate_end;
473
474 return FALSE;
475}
476
477/**********************************************************************/
480 static bool impr_prevents_disaster(const struct city *pcity,
481 const struct impr_type *pimprove)
482{
483 /* Fast check */
484 if (!pimprove->prevents_disaster) {
485 return FALSE;
486 }
487
488 disaster_type_iterate(pdis) {
489 if (!requirement_fulfilled_by_improvement(pimprove, &pdis->reqs)
490 && !can_disaster_happen(pdis, pcity)) {
491 return TRUE;
492 }
493 } disaster_type_iterate_end;
494
495 return FALSE;
496}
497
498/**********************************************************************/
504 static bool impr_protects_vs_actions(const struct city *pcity,
505 const struct impr_type *pimprove)
506{
507 /* Fast check */
508 if (!pimprove->protects_vs_actions) {
509 return FALSE;
510 }
511
512 action_enablers_iterate(act) {
513 if (!requirement_fulfilled_by_improvement(pimprove, &act->target_reqs)
514 && !is_action_possible_on_city(act->action, NULL, pcity)) {
515 return TRUE;
516 }
517 } action_enablers_iterate_end;
518
519 return FALSE;
520}
521
522/**********************************************************************/
525 static bool impr_allows_actions(const struct city *pcity,
526 const struct impr_type *pimprove)
527{
528 /* Fast check */
529 if (!pimprove->allows_actions) {
530 return FALSE;
531 }
532
533 action_enablers_iterate(act) {
534 if (requirement_needs_improvement(pimprove, &act->actor_reqs)) {
535 switch (action_id_get_actor_kind(act->action)) {
536 case AAK_UNIT:
537 unit_type_iterate(ut) {
538 if (!utype_can_do_action(ut, act->action)) {
539 /* Not relevant */
540 continue;
541 }
542
543 if (utype_player_already_has_this(city_owner(pcity), ut)) {
544 /* The player has a unit that may use the building */
545 return TRUE;
546 }
547
548 if (can_city_build_unit_now(pcity, ut)) {
549 /* This city can build a unit that uses the building */
550 return TRUE;
551 }
552 } unit_type_iterate_end;
553 break;
554 case AAK_COUNT:
555 fc_assert(action_id_get_actor_kind(act->action) != AAK_COUNT);
556 break;
557 }
558 }
559 } action_enablers_iterate_end;
560
561 return FALSE;
562}
563
564/**********************************************************************/
574 static bool improvement_has_side_effects(const struct city *pcity,
575 const struct impr_type *pimprove)
576{
577 return (impr_provides_buildable_units(pcity, pimprove)
578 || impr_provides_buildable_extras(pcity, pimprove)
579 || impr_prevents_disaster(pcity, pimprove)
580 || impr_allows_actions(pcity, pimprove)
581 || impr_protects_vs_actions(pcity, pimprove));
582}
583
584/**********************************************************************/
587 static bool improvement_has_effects(const struct city *pcity,
588 const struct impr_type *pimprove)
589{
590 struct universal source = { .kind = VUT_IMPROVEMENT,
591 .value = { .building = pimprove } };
592 struct effect_list *plist = get_req_source_effects(&source);
593
594 if (!plist || improvement_obsolete(city_owner(pcity), pimprove, pcity)) {
595 return FALSE;
596 }
597
598 effect_list_iterate(plist, peffect) {
599 if (0 != get_potential_improvement_bonus(pimprove, pcity,
600 peffect->type, RPT_CERTAIN, TRUE)) {
601 return TRUE;
602 }
603 } effect_list_iterate_end;
604
605 return FALSE;
606}
607
608/**********************************************************************/
615 bool is_improvement_productive(const struct city *pcity,
616 const struct impr_type *pimprove)
617{
618 return (!improvement_obsolete(city_owner(pcity), pimprove, pcity)
619 && (improvement_has_flag(pimprove, IF_GOLD)
620 || improvement_has_side_effects(pcity, pimprove)
621 || improvement_has_effects(pcity, pimprove)));
622}
623
624/**********************************************************************/
636 bool is_improvement_redundant(const struct city *pcity,
637 const struct impr_type *pimprove)
638{
639 /* A capitalization production is never redundant. */
640 if (improvement_has_flag(pimprove, IF_GOLD)) {
641 return FALSE;
642 }
643
644 /* If an improvement has side effects, don't claim it's redundant. */
645 if (improvement_has_side_effects(pcity, pimprove)) {
646 return FALSE;
647 }
648
649 /* Otherwise, it's redundant if its effects are available by other means,
650 * or if it's an obsolete wonder (great or small). */
651 return is_building_replaced(pcity, pimprove, RPT_CERTAIN)
652 || improvement_obsolete(city_owner(pcity), pimprove, pcity);
653}
654
655/**********************************************************************/
659 bool can_player_build_improvement_direct(const struct player *p,
660 const struct impr_type *pimprove)
661{
662 const struct req_context context = { .player = p };
663
664 bool space_part = FALSE;
665
666 if (!valid_improvement(pimprove)) {
667 return FALSE;
668 }
669
670 requirement_vector_iterate(&pimprove->reqs, preq) {
671 if (preq->range >= REQ_RANGE_PLAYER
672 && !is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
673 return FALSE;
674 }
675 } requirement_vector_iterate_end;
676
677 /* Check for space part construction. This assumes that space parts have
678 * no other effects. */
679 if (building_has_effect(pimprove, EFT_SS_STRUCTURAL)) {
680 space_part = TRUE;
681 if (p->spaceship.structurals >= NUM_SS_STRUCTURALS) {
682 return FALSE;
683 }
684 }
685 if (building_has_effect(pimprove, EFT_SS_COMPONENT)) {
686 space_part = TRUE;
687 if (p->spaceship.components >= NUM_SS_COMPONENTS) {
688 return FALSE;
689 }
690 }
691 if (building_has_effect(pimprove, EFT_SS_MODULE)) {
692 space_part = TRUE;
693 if (p->spaceship.modules >= NUM_SS_MODULES) {
694 return FALSE;
695 }
696 }
697 if (space_part
698 && (get_player_bonus(p, EFT_ENABLE_SPACE) <= 0
699 || p->spaceship.state >= SSHIP_LAUNCHED)) {
700 return FALSE;
701 }
702
703 if (is_great_wonder(pimprove)) {
704 /* Can't build wonder if already built */
705 if (!great_wonder_is_available(pimprove)) {
706 return FALSE;
707 }
708 }
709
710 return TRUE;
711}
712
713/**********************************************************************/
717 bool can_player_build_improvement_now(const struct player *p,
718 struct impr_type *pimprove)
719{
720 if (!can_player_build_improvement_direct(p, pimprove)) {
721 return FALSE;
722 }
723 if (improvement_obsolete(p, pimprove, NULL)) {
724 return FALSE;
725 }
726 return TRUE;
727}
728
729/**********************************************************************/
734 bool can_player_build_improvement_later(const struct player *p,
735 const struct impr_type *pimprove)
736{
737 const struct req_context context = { .player = p };
738
739 if (!valid_improvement(pimprove)) {
740 return FALSE;
741 }
742 if (improvement_obsolete(p, pimprove, NULL)) {
743 return FALSE;
744 }
745 if (is_great_wonder(pimprove) && !great_wonder_is_available(pimprove)) {
746 /* Can't build wonder if already built */
747 return FALSE;
748 }
749
750 /* Check for requirements that aren't met and that are unchanging (so
751 * they can never be met). */
752 requirement_vector_iterate(&pimprove->reqs, preq) {
753 if (preq->range >= REQ_RANGE_PLAYER
754 && is_req_preventing(&context, NULL, preq, RPT_POSSIBLE)) {
755 return FALSE;
756 }
757 } requirement_vector_iterate_end;
758 /* FIXME: should check some "unchanging" reqs here - like if there's
759 * a nation requirement, we can go ahead and check it now. */
760
761 return TRUE;
762}
763
764/**********************************************************************/
767 bool is_great_wonder(const struct impr_type *pimprove)
768{
769 return (pimprove->genus == IG_GREAT_WONDER);
770}
771
772/**********************************************************************/
775 bool is_small_wonder(const struct impr_type *pimprove)
776{
777 return (pimprove->genus == IG_SMALL_WONDER);
778}
779
780/**********************************************************************/
783 bool is_improvement(const struct impr_type *pimprove)
784{
785 return (pimprove->genus == IG_IMPROVEMENT);
786}
787
788/**********************************************************************/
792 bool is_special_improvement(const struct impr_type *pimprove)
793{
794 return pimprove->genus == IG_SPECIAL;
795}
796
797/**********************************************************************/
800 void wonder_built(const struct city *pcity, const struct impr_type *pimprove)
801{
802 struct player *pplayer;
803 int windex = improvement_number(pimprove);
804
805 fc_assert_ret(NULL != pcity);
806 fc_assert_ret(is_wonder(pimprove));
807
808 pplayer = city_owner(pcity);
809 pplayer->wonders[windex] = pcity->id;
810
811 if (is_great_wonder(pimprove)) {
812 game.info.great_wonder_owners[windex] = player_number(pplayer);
813 }
814}
815
816/**********************************************************************/
820 void wonder_destroyed(const struct city *pcity,
821 const struct impr_type *pimprove)
822{
823 struct player *pplayer;
824 int windex = improvement_number(pimprove);
825
826 fc_assert_ret(NULL != pcity);
827 fc_assert_ret(is_wonder(pimprove));
828
829 pplayer = city_owner(pcity);
830 fc_assert_ret(pplayer->wonders[windex] == pcity->id);
831 pplayer->wonders[windex] = WONDER_LOST;
832
833 if (is_great_wonder(pimprove)) {
834 fc_assert_ret(game.info.great_wonder_owners[windex]
835 == player_number(pplayer));
836 game.info.great_wonder_owners[windex] = WONDER_DESTROYED;
837 }
838}
839
840/**********************************************************************/
844 bool wonder_is_lost(const struct player *pplayer,
845 const struct impr_type *pimprove)
846{
847 fc_assert_ret_val(NULL != pplayer, FALSE);
848 fc_assert_ret_val(is_wonder(pimprove), FALSE);
849
850 return pplayer->wonders[improvement_index(pimprove)] == WONDER_LOST;
851}
852
853/**********************************************************************/
857 bool wonder_is_built(const struct player *pplayer,
858 const struct impr_type *pimprove)
859{
860 fc_assert_ret_val(NULL != pplayer, FALSE);
861 fc_assert_ret_val(is_wonder(pimprove), FALSE);
862
863 return WONDER_BUILT(pplayer->wonders[improvement_index(pimprove)]);
864}
865
866/**********************************************************************/
872 struct city *city_from_wonder(const struct player *pplayer,
873 const struct impr_type *pimprove)
874{
875 int idx = improvement_index(pimprove);
876 int city_id;
877
878 if (idx < 0) {
879 return NULL;
880 }
881
882 city_id = pplayer->wonders[idx];
883
884 fc_assert_ret_val(NULL != pplayer, NULL);
885 fc_assert_ret_val(is_wonder(pimprove), NULL);
886
887 if (!WONDER_BUILT(city_id)) {
888 return NULL;
889 }
890
891#ifdef FREECIV_DEBUG
892 if (is_server()) {
893 /* On client side, this info is not always known. */
894 struct city *pcity = player_city_by_number(pplayer, city_id);
895
896 if (NULL == pcity) {
897 log_error("Player %s (nb %d) has outdated wonder info for "
898 "%s (nb %d), it points to city nb %d.",
899 player_name(pplayer), player_number(pplayer),
900 improvement_rule_name(pimprove),
901 improvement_number(pimprove), city_id);
902 } else if (!city_has_building(pcity, pimprove)) {
903 log_error("Player %s (nb %d) has outdated wonder info for "
904 "%s (nb %d), the city %s (nb %d) doesn't have this wonder.",
905 player_name(pplayer), player_number(pplayer),
906 improvement_rule_name(pimprove),
907 improvement_number(pimprove), city_name_get(pcity), pcity->id);
908 return NULL;
909 }
910
911 return pcity;
912 }
913#endif /* FREECIV_DEBUG */
914
915 return player_city_by_number(pplayer, city_id);
916}
917
918/**********************************************************************/
921 bool wonder_visible_to_player(const struct impr_type *wonder,
922 const struct player *pplayer,
923 const struct player *owner)
924{
925 if (pplayer == owner) {
926 /* Can see all own wonders,
927 * even improvements if that matters. */
928 return TRUE;
929 }
930
931 if (is_great_wonder(wonder)) {
932 return TRUE;
933 }
934
935 if (is_small_wonder(wonder)) {
936 switch (game.info.small_wonder_visibility) {
937 case WV_ALWAYS:
938 return TRUE;
939 case WV_NEVER:
940 return FALSE;
941 }
942
943 fc_assert(FALSE);
944
945 return FALSE;
946 }
947
948 /* Now a wonder, but regular improvement */
949 return FALSE;
950}
951
952/**********************************************************************/
955 bool great_wonder_is_built(const struct impr_type *pimprove)
956{
957 fc_assert_ret_val(is_great_wonder(pimprove), FALSE);
958
959 return WONDER_OWNED(game.info.great_wonder_owners
960 [improvement_index(pimprove)]);
961}
962
963/**********************************************************************/
966 bool great_wonder_is_destroyed(const struct impr_type *pimprove)
967{
968 fc_assert_ret_val(is_great_wonder(pimprove), FALSE);
969
970 return (WONDER_DESTROYED
971 == game.info.great_wonder_owners[improvement_index(pimprove)]);
972}
973
974/**********************************************************************/
977 bool great_wonder_is_available(const struct impr_type *pimprove)
978{
979 fc_assert_ret_val(is_great_wonder(pimprove), FALSE);
980
981 return (WONDER_NOT_OWNED
982 == game.info.great_wonder_owners[improvement_index(pimprove)]);
983}
984
985/**********************************************************************/
989 struct city *city_from_great_wonder(const struct impr_type *pimprove)
990{
991 int player_id = game.info.great_wonder_owners[improvement_index(pimprove)];
992
993 fc_assert_ret_val(is_great_wonder(pimprove), NULL);
994
995 if (WONDER_OWNED(player_id)) {
996#ifdef FREECIV_DEBUG
997 const struct player *pplayer = player_by_number(player_id);
998 struct city *pcity = city_from_wonder(pplayer, pimprove);
999
1000 if (is_server() && NULL == pcity) {
1001 log_error("Game has outdated wonder info for %s (nb %d), "
1002 "the player %s (nb %d) doesn't have this wonder.",
1003 improvement_rule_name(pimprove),
1004 improvement_number(pimprove),
1005 player_name(pplayer), player_number(pplayer));
1006 }
1007
1008 return pcity;
1009#else
1010 return city_from_wonder(player_by_number(player_id), pimprove);
1011#endif /* FREECIV_DEBUG */
1012 } else {
1013 return NULL;
1014 }
1015}
1016
1017/**********************************************************************/
1021 struct player *great_wonder_owner(const struct impr_type *pimprove)
1022{
1023 int player_id = game.info.great_wonder_owners[improvement_index(pimprove)];
1024
1025 fc_assert_ret_val(is_great_wonder(pimprove), NULL);
1026
1027 if (WONDER_OWNED(player_id)) {
1028 return player_by_number(player_id);
1029 } else {
1030 return NULL;
1031 }
1032}
1033
1034/**********************************************************************/
1037 bool small_wonder_is_built(const struct player *pplayer,
1038 const struct impr_type *pimprove)
1039{
1040 fc_assert_ret_val(is_small_wonder(pimprove), FALSE);
1041
1042 return (NULL != pplayer
1043 && wonder_is_built(pplayer, pimprove));
1044}
1045
1046/**********************************************************************/
1049 struct city *city_from_small_wonder(const struct player *pplayer,
1050 const struct impr_type *pimprove)
1051{
1052 fc_assert_ret_val(is_small_wonder(pimprove), NULL);
1053
1054 if (NULL == pplayer) {
1055 return NULL; /* Used in some places in the client. */
1056 } else {
1057 return city_from_wonder(pplayer, pimprove);
1058 }
1059}
1060
1061/**********************************************************************/
1064 bool can_sell_building(const struct impr_type *pimprove)
1065{
1066 return (valid_improvement(pimprove) && is_improvement(pimprove));
1067}
1068
1069/**********************************************************************/
1072 bool can_city_sell_building(const struct city *pcity,
1073 const struct impr_type *pimprove)
1074{
1075 return (city_has_building(pcity, pimprove) && is_improvement(pimprove));
1076}
1077
1078/**********************************************************************/
1083 enum test_result test_player_sell_building_now(struct player *pplayer,
1084 struct city *pcity,
1085 const struct impr_type *pimprove)
1086{
1087 /* Check if player can sell anything from this city */
1088 if (pcity->owner != pplayer) {
1089 return TR_OTHER_FAILURE;
1090 }
1091
1092 if (pcity->did_sell) {
1093 return TR_ALREADY_SOLD;
1094 }
1095
1096 /* Check if particular building can be solt */
1097 if (pimprove != NULL
1098 && !can_city_sell_building(pcity, pimprove)) {
1099 return TR_OTHER_FAILURE;
1100 }
1101
1102 return TR_SUCCESS;
1103}
1104
1105/**********************************************************************/
1109 const struct impr_type *improvement_replacement(const struct impr_type *pimprove)
1110{
1111 requirement_vector_iterate(&pimprove->obsolete_by, pobs) {
1112 if (pobs->source.kind == VUT_IMPROVEMENT && pobs->present) {
1113 return pobs->source.value.building;
1114 }
1115 } requirement_vector_iterate_end;
1116
1117 return NULL;
1118}
is_action_possible_on_city
bool is_action_possible_on_city(action_id act_id, const struct player *actor_player, const struct city *target_city)
Definition actions.c:7146
action_enablers_iterate_end
#define action_enablers_iterate_end
Definition actions.h:526
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
action_enablers_iterate
#define action_enablers_iterate(_enabler_)
Definition actions.h:520
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
city_has_building
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1212
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1111
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
can_city_build_unit_now
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Definition city.c:928
city_tile
#define city_tile(_pcity_)
Definition city.h:544
city_owner
#define city_owner(_pcity_)
Definition city.h:543
city_tile_iterate
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:222
city_tile_iterate_end
#define city_tile_iterate_end
Definition city.h:230
base
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2839
cost
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 cost
Definition dialogs_g.h:73
can_disaster_happen
bool can_disaster_happen(const struct disaster_type *pdis, const struct city *pcity)
Definition disaster.c:139
disaster_type_iterate
#define disaster_type_iterate(_p)
Definition disaster.h:80
disaster_type_iterate_end
#define disaster_type_iterate_end
Definition disaster.h:86
id
int int id
Definition editgui_g.h:28
get_req_source_effects
struct effect_list * get_req_source_effects(struct universal *psource)
Definition effects.c:146
is_building_replaced
bool is_building_replaced(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Definition effects.c:641
get_target_bonus_effects
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:691
get_potential_improvement_bonus
int get_potential_improvement_bonus(const struct impr_type *pimprove, const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type, bool consider_multipliers)
Definition effects.c:1126
get_building_bonus
int get_building_bonus(const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
Definition effects.c:930
building_has_effect
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:587
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:375
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
player_can_build_extra
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:442
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:291
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:297
is_server
static bool is_server(void)
Definition fc_interface.h:69
Impr_type_id
int Impr_type_id
Definition fc_types.h:346
RPT_CERTAIN
@ RPT_CERTAIN
Definition fc_types.h:586
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:585
test_result
test_result
Definition fc_types.h:1097
TR_ALREADY_SOLD
@ TR_ALREADY_SOLD
Definition fc_types.h:1100
TR_OTHER_FAILURE
@ TR_OTHER_FAILURE
Definition fc_types.h:1099
TR_SUCCESS
@ TR_SUCCESS
Definition fc_types.h:1098
VC_SPACERACE
@ VC_SPACERACE
Definition fc_types.h:1123
fcintl.h
Qn_
#define Qn_(String)
Definition fcintl.h:89
game
struct civ_game game
Definition game.c:57
wld
struct world wld
Definition game.c:58
game.h
owner
struct city * owner
Definition citydlg.c:219
source
static GtkWidget * source
Definition gotodlg.c:58
valid_improvement
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
Definition improvement.c:209
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:192
can_sell_building
bool can_sell_building(const struct impr_type *pimprove)
Definition improvement.c:1064
impr_sell_gold
int impr_sell_gold(const struct impr_type *pimprove)
Definition improvement.c:332
improvements_init
void improvements_init(void)
Definition improvement.c:46
improvement_array_last
const struct impr_type * improvement_array_last(void)
Definition improvement.c:151
valid_improvement_by_number
const struct impr_type * valid_improvement_by_number(const Impr_type_id id)
Definition improvement.c:232
can_city_sell_building
bool can_city_sell_building(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:1072
can_player_build_improvement_direct
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
Definition improvement.c:659
great_wonder_is_built
bool great_wonder_is_built(const struct impr_type *pimprove)
Definition improvement.c:955
improvement_has_side_effects
static bool improvement_has_side_effects(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:574
test_player_sell_building_now
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:1083
is_special_improvement
bool is_special_improvement(const struct impr_type *pimprove)
Definition improvement.c:792
impr_prevents_disaster
static bool impr_prevents_disaster(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:480
is_improvement_redundant
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:636
can_player_build_improvement_later
bool can_player_build_improvement_later(const struct player *p, const struct impr_type *pimprove)
Definition improvement.c:734
wonder_built
void wonder_built(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:800
great_wonder_is_destroyed
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
Definition improvement.c:966
wonder_is_lost
bool wonder_is_lost(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:844
can_player_build_improvement_now
bool can_player_build_improvement_now(const struct player *p, struct impr_type *pimprove)
Definition improvement.c:717
is_improvement
bool is_improvement(const struct impr_type *pimprove)
Definition improvement.c:783
improvement_has_effects
static bool improvement_has_effects(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:587
wonder_is_built
bool wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:857
impr_base_build_shield_cost
int impr_base_build_shield_cost(const struct impr_type *pimprove)
Definition improvement.c:259
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:182
impr_provides_buildable_extras
static bool impr_provides_buildable_extras(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:453
small_wonder_is_built
bool small_wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:1037
can_improvement_go_obsolete
bool can_improvement_go_obsolete(const struct impr_type *pimprove)
Definition improvement.c:401
improvement_rule_name
const char * improvement_rule_name(const struct impr_type *pimprove)
Definition improvement.c:250
is_improvement_visible
bool is_improvement_visible(const struct impr_type *pimprove)
Definition improvement.c:391
city_from_wonder
struct city * city_from_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:872
improvement_index
Impr_type_id improvement_index(const struct impr_type *pimprove)
Definition improvement.c:173
impr_buy_gold_cost
int impr_buy_gold_cost(const struct city *pcity, const struct impr_type *pimprove, int shields_in_stock)
Definition improvement.c:304
impr_build_shield_cost
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:292
improvement_free
static void improvement_free(struct impr_type *p)
Definition improvement.c:66
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:341
impr_protects_vs_actions
static bool impr_protects_vs_actions(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:504
is_great_wonder
bool is_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:767
improvement_obsolete
bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity)
Definition improvement.c:409
impr_allows_actions
static bool impr_allows_actions(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:525
improvement_by_translated_name
struct impr_type * improvement_by_translated_name(const char *name)
Definition improvement.c:350
improvement_feature_cache_init
void improvement_feature_cache_init(void)
Definition improvement.c:90
improvement_has_flag
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Definition improvement.c:381
improvement_by_rule_name
struct impr_type * improvement_by_rule_name(const char *name)
Definition improvement.c:365
city_from_small_wonder
struct city * city_from_small_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:1049
wonder_destroyed
void wonder_destroyed(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:820
improvement_types
static struct impr_type improvement_types[B_LAST]
Definition improvement.c:41
improvement_name_translation
const char * improvement_name_translation(const struct impr_type *pimprove)
Definition improvement.c:241
city_from_great_wonder
struct city * city_from_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:989
improvement_count
Impr_type_id improvement_count(void)
Definition improvement.c:162
impr_provides_buildable_units
static bool impr_provides_buildable_units(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:432
is_small_wonder
bool is_small_wonder(const struct impr_type *pimprove)
Definition improvement.c:775
improvement_array_first
struct impr_type * improvement_array_first(void)
Definition improvement.c:140
impr_estimate_build_shield_cost
int impr_estimate_build_shield_cost(const struct player *pplayer, const struct tile *ptile, const struct impr_type *pimprove)
Definition improvement.c:271
wonder_visible_to_player
bool wonder_visible_to_player(const struct impr_type *wonder, const struct player *pplayer, const struct player *owner)
Definition improvement.c:921
improvement_replacement
const struct impr_type * improvement_replacement(const struct impr_type *pimprove)
Definition improvement.c:1109
great_wonder_owner
struct player * great_wonder_owner(const struct impr_type *pimprove)
Definition improvement.c:1021
great_wonder_is_available
bool great_wonder_is_available(const struct impr_type *pimprove)
Definition improvement.c:977
improvements_free
void improvements_free(void)
Definition improvement.c:80
is_improvement_productive
bool is_improvement_productive(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:615
improvement.h
WONDER_NOT_OWNED
#define WONDER_NOT_OWNED
Definition improvement.h:147
WONDER_BUILT
#define WONDER_BUILT(city_id)
Definition improvement.h:153
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:211
WONDER_DESTROYED
#define WONDER_DESTROYED
Definition improvement.h:146
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:205
WONDER_LOST
#define WONDER_LOST
Definition improvement.h:151
B_LAST
#define B_LAST
Definition improvement.h:42
WONDER_OWNED
#define WONDER_OWNED(player_id)
Definition improvement.h:148
name
const char * name
Definition inputfile.c:127
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_error
#define log_error(message,...)
Definition log.h:103
map.h
mem.h
rule_name_get
static const char * rule_name_get(const struct name_translation *ptrans)
Definition name_translation.h:112
name_translation_get
static const char * name_translation_get(const struct name_translation *ptrans)
Definition name_translation.h:121
player_by_number
struct player * player_by_number(const int player_id)
Definition player.c:840
player_number
int player_number(const struct player *pplayer)
Definition player.c:828
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:886
player_city_by_number
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1179
is_req_active
bool is_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req, const enum req_problem_type prob_type)
Definition requirements.c:4268
is_req_preventing
enum req_unchanging_status is_req_preventing(const struct req_context *context, const struct player *other_player, const struct requirement *req, enum req_problem_type prob_type)
Definition requirements.c:4619
requirement_fulfilled_by_improvement
#define requirement_fulfilled_by_improvement(_imp_, _rqs_)
Definition requirements.h:407
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:93
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:91
requirement_needs_improvement
#define requirement_needs_improvement(_imp_, _rqs_)
Definition requirements.h:431
shared.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MAX
#define MAX(x, y)
Definition shared.h:54
NUM_SS_MODULES
#define NUM_SS_MODULES
Definition spaceship.h:89
NUM_SS_COMPONENTS
#define NUM_SS_COMPONENTS
Definition spaceship.h:88
NUM_SS_STRUCTURALS
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
SSHIP_LAUNCHED
@ SSHIP_LAUNCHED
Definition spaceship.h:85
strvec_destroy
void strvec_destroy(struct strvec *psv)
Definition string_vector.c:71
string_vector.h
city
Definition city.h:309
city::did_sell
bool did_sell
Definition city.h:367
city::id
int id
Definition city.h:315
city::owner
struct player * owner
Definition city.h:312
city::tile
struct tile * tile
Definition city.h:311
civ_game::control
struct packet_ruleset_control control
Definition game.h:83
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_map
Definition map_types.h:71
impr_type
Definition improvement.h:68
impr_type::allows_actions
bool allows_actions
Definition improvement.h:91
impr_type::build_cost
int build_cost
Definition improvement.h:77
impr_type::genus
enum impr_genus_id genus
Definition improvement.h:80
impr_type::ruledit_disabled
bool ruledit_disabled
Definition improvement.h:71
impr_type::protects_vs_actions
bool protects_vs_actions
Definition improvement.h:90
impr_type::obsolete_by
struct requirement_vector obsolete_by
Definition improvement.h:76
impr_type::item_number
Impr_type_id item_number
Definition improvement.h:69
impr_type::prevents_disaster
bool prevents_disaster
Definition improvement.h:89
impr_type::reqs
struct requirement_vector reqs
Definition improvement.h:75
impr_type::allows_extras
bool allows_extras
Definition improvement.h:88
impr_type::helptext
struct strvec * helptext
Definition improvement.h:82
impr_type::allows_units
bool allows_units
Definition improvement.h:87
impr_type::name
struct name_translation name
Definition improvement.h:70
impr_type::flags
bv_impr_flags flags
Definition improvement.h:81
impr_type::ruledit_dlg
void * ruledit_dlg
Definition improvement.h:72
packet_game_info::shieldbox
int shieldbox
Definition packets_gen.h:221
packet_game_info::great_wonder_owners
int great_wonder_owners[B_LAST]
Definition packets_gen.h:175
packet_game_info::small_wonder_visibility
enum wonder_visib_type small_wonder_visibility
Definition packets_gen.h:250
packet_ruleset_control::num_impr_types
int num_impr_types
Definition packets_gen.h:1457
player_spaceship::modules
int modules
Definition spaceship.h:98
player_spaceship::components
int components
Definition spaceship.h:97
player_spaceship::state
enum spaceship_state state
Definition spaceship.h:108
player_spaceship::structurals
int structurals
Definition spaceship.h:96
player
Definition player.h:249
player::wonders
int wonders[B_LAST]
Definition player.h:301
player::spaceship
struct player_spaceship spaceship
Definition player.h:286
req_context
Definition requirements.h:99
req_context::player
const struct player * player
Definition requirements.h:100
tile
Definition tile.h:49
universal
Definition fc_types.h:756
universal::kind
enum universals_n kind
Definition fc_types.h:758
world::map
struct civ_map map
Definition world_object.h:38
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
tech.h
utype_player_already_has_this
bool utype_player_already_has_this(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1993
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:838
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:845
victory_enabled
bool victory_enabled(enum victory_condition_type victory)
Definition victory.c:26
victory.h