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**************************************************************************/
42
43/**********************************************************************/
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);
59 p->ruledit_dlg = NULL;
60 }
61}
62
63/**********************************************************************/
66static void improvement_free(struct impr_type *p)
67{
68 if (NULL != p->helptext) {
70 p->helptext = NULL;
71 }
72
73 requirement_vector_free(&p->reqs);
74 requirement_vector_free(&p->obsolete_by);
75}
76
77/**********************************************************************/
86
87/**********************************************************************/
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 }
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 }
108
109 pimprove->prevents_disaster = FALSE;
111 if (!requirement_fulfilled_by_improvement(pimprove, &pdis->reqs)) {
112 pimprove->prevents_disaster = TRUE;
113 break;
114 }
116
117 pimprove->protects_vs_actions = FALSE;
120 &act->target_reqs)) {
121 pimprove->protects_vs_actions = TRUE;
122 break;
123 }
125
126 pimprove->allows_actions = FALSE;
128 if (requirement_needs_improvement(pimprove, &act->actor_reqs)) {
129 pimprove->allows_actions = TRUE;
130 break;
131 }
133
135}
136
137/**********************************************************************/
141{
142 if (game.control.num_impr_types > 0) {
143 return improvement_types;
144 }
145 return NULL;
146}
147
148/**********************************************************************/
152{
153 if (game.control.num_impr_types > 0) {
155 }
156 return NULL;
157}
158
159/**********************************************************************/
166
167/**********************************************************************/
174{
175 fc_assert_ret_val(NULL != pimprove, -1);
176 return pimprove - improvement_types;
177}
178
179/**********************************************************************/
183{
184 fc_assert_ret_val(NULL != pimprove, -1);
185 return pimprove->item_number;
186}
187
188/**********************************************************************/
193{
194 if (id < 0 || id >= improvement_count()) {
195 return NULL;
196 }
197 return &improvement_types[id];
198}
199
200/**********************************************************************/
209const struct impr_type *valid_improvement(const struct impr_type *pimprove)
210{
211 if (NULL == pimprove) {
212 return NULL;
213 }
214
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/**********************************************************************/
236
237/**********************************************************************/
241const char *improvement_name_translation(const struct impr_type *pimprove)
242{
243 return name_translation_get(&pimprove->name);
244}
245
246/**********************************************************************/
250const char *improvement_rule_name(const struct impr_type *pimprove)
251{
252 return rule_name_get(&pimprove->name);
253}
254
255/**********************************************************************/
259int 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/**********************************************************************/
271int 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 +
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/**********************************************************************/
292int 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/**********************************************************************/
304int 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/**********************************************************************/
332int impr_sell_gold(const struct impr_type *pimprove)
333{
334 return MAX(pimprove->build_cost * game.info.shieldbox / 100, 1);
335}
336
337/**********************************************************************/
341bool is_wonder(const struct impr_type *pimprove)
342{
343 return (is_great_wonder(pimprove) || is_small_wonder(pimprove));
344}
345
346/**********************************************************************/
351{
352 improvement_iterate(pimprove) {
353 if (0 == strcmp(improvement_name_translation(pimprove), name)) {
354 return pimprove;
355 }
357
358 return NULL;
359}
360
361/**********************************************************************/
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 }
374
375 return NULL;
376}
377
378/**********************************************************************/
381bool 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/**********************************************************************/
391bool 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/**********************************************************************/
401bool can_improvement_go_obsolete(const struct impr_type *pimprove)
402{
403 return requirement_vector_size(&pimprove->obsolete_by) > 0;
404}
405
406/**********************************************************************/
409bool 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 }
425
426 return FALSE;
427}
428
429/**********************************************************************/
432static bool impr_provides_buildable_units(const struct city *pcity,
433 const struct impr_type *pimprove)
434{
435 const struct civ_map *nmap = &(wld.map);
436
437 /* Fast check */
438 if (!pimprove->allows_units) {
439 return FALSE;
440 }
441
443 if (requirement_needs_improvement(pimprove, &ut->build_reqs)
444 && can_city_build_unit_now(nmap, pcity, ut)) {
445 return TRUE;
446 }
448
449 return FALSE;
450}
451
452/**********************************************************************/
455static bool impr_provides_buildable_extras(const struct city *pcity,
456 const struct impr_type *pimprove)
457{
458 const struct civ_map *nmap = &(wld.map);
459
460 /* Fast check */
461 if (!pimprove->allows_extras) {
462 return FALSE;
463 }
464
465 extra_type_iterate(pextra) {
466 if (requirement_needs_improvement(pimprove, &pextra->reqs)) {
468 city_tile(pcity), ptile) {
469 if (player_can_build_extra(pextra, city_owner(pcity), ptile)) {
470 return TRUE;
471 }
473 }
475
476 return FALSE;
477}
478
479/**********************************************************************/
482static bool impr_prevents_disaster(const struct city *pcity,
483 const struct impr_type *pimprove)
484{
485 /* Fast check */
486 if (!pimprove->prevents_disaster) {
487 return FALSE;
488 }
489
491 if (!requirement_fulfilled_by_improvement(pimprove, &pdis->reqs)
492 && !can_disaster_happen(pdis, pcity)) {
493 return TRUE;
494 }
496
497 return FALSE;
498}
499
500/**********************************************************************/
506static bool impr_protects_vs_actions(const struct city *pcity,
507 const struct impr_type *pimprove)
508{
509 /* Fast check */
510 if (!pimprove->protects_vs_actions) {
511 return FALSE;
512 }
513
515 if (!requirement_fulfilled_by_improvement(pimprove, &act->target_reqs)
516 && !is_action_possible_on_city(act->action, NULL, pcity)) {
517 return TRUE;
518 }
520
521 return FALSE;
522}
523
524/**********************************************************************/
527static bool impr_allows_actions(const struct city *pcity,
528 const struct impr_type *pimprove)
529{
530 const struct civ_map *nmap = &(wld.map);
531
532 /* Fast check */
533 if (!pimprove->allows_actions) {
534 return FALSE;
535 }
536
538 if (requirement_needs_improvement(pimprove, &act->actor_reqs)) {
539 switch (action_id_get_actor_kind(act->action)) {
540 case AAK_UNIT:
542 if (!utype_can_do_action(ut, act->action)) {
543 /* Not relevant */
544 continue;
545 }
546
548 /* The player has a unit that may use the building */
549 return TRUE;
550 }
551
552 if (can_city_build_unit_now(nmap, pcity, ut)) {
553 /* This city can build a unit that uses the building */
554 return TRUE;
555 }
557 break;
558 case AAK_COUNT:
559 fc_assert(action_id_get_actor_kind(act->action) != AAK_COUNT);
560 break;
561 }
562 }
564
565 return FALSE;
566}
567
568/**********************************************************************/
578static bool improvement_has_side_effects(const struct city *pcity,
579 const struct impr_type *pimprove)
580{
581 return (impr_provides_buildable_units(pcity, pimprove)
582 || impr_provides_buildable_extras(pcity, pimprove)
583 || impr_prevents_disaster(pcity, pimprove)
584 || impr_allows_actions(pcity, pimprove)
585 || impr_protects_vs_actions(pcity, pimprove));
586}
587
588/**********************************************************************/
591static bool improvement_has_effects(const struct city *pcity,
592 const struct impr_type *pimprove)
593{
594 struct universal source = { .kind = VUT_IMPROVEMENT,
595 .value = { .building = pimprove } };
596 struct effect_list *plist = get_req_source_effects(&source);
597
598 if (!plist || improvement_obsolete(city_owner(pcity), pimprove, pcity)) {
599 return FALSE;
600 }
601
602 effect_list_iterate(plist, peffect) {
603 if (0 != get_potential_improvement_bonus(pimprove, pcity,
604 peffect->type, RPT_CERTAIN, TRUE)) {
605 return TRUE;
606 }
608
609 return FALSE;
610}
611
612/**********************************************************************/
619bool is_improvement_productive(const struct city *pcity,
620 const struct impr_type *pimprove)
621{
622 return (!improvement_obsolete(city_owner(pcity), pimprove, pcity)
623 && (improvement_has_flag(pimprove, IF_GOLD)
624 || improvement_has_side_effects(pcity, pimprove)
625 || improvement_has_effects(pcity, pimprove)));
626}
627
628/**********************************************************************/
640bool is_improvement_redundant(const struct city *pcity,
641 const struct impr_type *pimprove)
642{
643 /* A capitalization production is never redundant. */
644 if (improvement_has_flag(pimprove, IF_GOLD)) {
645 return FALSE;
646 }
647
648 /* If an improvement has side effects, don't claim it's redundant. */
649 if (improvement_has_side_effects(pcity, pimprove)) {
650 return FALSE;
651 }
652
653 /* Otherwise, it's redundant if its effects are available by other means,
654 * or if it's an obsolete wonder (great or small). */
655 return is_building_replaced(pcity, pimprove, RPT_CERTAIN)
656 || improvement_obsolete(city_owner(pcity), pimprove, pcity);
657}
658
659/**********************************************************************/
664 const struct impr_type *pimprove)
665{
666 const struct req_context context = { .player = p };
667
668 bool space_part = FALSE;
669
670 if (!valid_improvement(pimprove)) {
671 return FALSE;
672 }
673
674 requirement_vector_iterate(&pimprove->reqs, preq) {
675 if (preq->range >= REQ_RANGE_PLAYER
676 && !is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
677 return FALSE;
678 }
680
681 /* Check for space part construction. This assumes that space parts have
682 * no other effects. */
683 if (building_has_effect(pimprove, EFT_SS_STRUCTURAL)) {
684 space_part = TRUE;
686 return FALSE;
687 }
688 }
689 if (building_has_effect(pimprove, EFT_SS_COMPONENT)) {
690 space_part = TRUE;
692 return FALSE;
693 }
694 }
695 if (building_has_effect(pimprove, EFT_SS_MODULE)) {
696 space_part = TRUE;
697 if (p->spaceship.modules >= NUM_SS_MODULES) {
698 return FALSE;
699 }
700 }
701 if (space_part
702 && (get_player_bonus(p, EFT_ENABLE_SPACE) <= 0
703 || p->spaceship.state >= SSHIP_LAUNCHED)) {
704 return FALSE;
705 }
706
707 if (is_great_wonder(pimprove)) {
708 /* Can't build wonder if already built */
709 if (!great_wonder_is_available(pimprove)) {
710 return FALSE;
711 }
712 }
713
714 return TRUE;
715}
716
717/**********************************************************************/
722 struct impr_type *pimprove)
723{
724 if (!can_player_build_improvement_direct(p, pimprove)) {
725 return FALSE;
726 }
727 if (improvement_obsolete(p, pimprove, NULL)) {
728 return FALSE;
729 }
730 return TRUE;
731}
732
733/**********************************************************************/
739 const struct impr_type *pimprove)
740{
741 const struct req_context context = { .player = p };
742
743 if (!valid_improvement(pimprove)) {
744 return FALSE;
745 }
746 if (improvement_obsolete(p, pimprove, NULL)) {
747 return FALSE;
748 }
749 if (is_great_wonder(pimprove) && !great_wonder_is_available(pimprove)) {
750 /* Can't build wonder if already built */
751 return FALSE;
752 }
753
754 /* Check for requirements that aren't met and that are unchanging (so
755 * they can never be met). */
756 requirement_vector_iterate(&pimprove->reqs, preq) {
757 if (preq->range >= REQ_RANGE_PLAYER
758 && is_req_preventing(&context, NULL, preq, RPT_POSSIBLE)) {
759 return FALSE;
760 }
762 /* FIXME: should check some "unchanging" reqs here - like if there's
763 * a nation requirement, we can go ahead and check it now. */
764
765 return TRUE;
766}
767
768/**********************************************************************/
771bool is_great_wonder(const struct impr_type *pimprove)
772{
773 return (pimprove->genus == IG_GREAT_WONDER);
774}
775
776/**********************************************************************/
779bool is_small_wonder(const struct impr_type *pimprove)
780{
781 return (pimprove->genus == IG_SMALL_WONDER);
782}
783
784/**********************************************************************/
787bool is_improvement(const struct impr_type *pimprove)
788{
789 return (pimprove->genus == IG_IMPROVEMENT);
790}
791
792/**********************************************************************/
796bool is_special_improvement(const struct impr_type *pimprove)
797{
798 return pimprove->genus == IG_SPECIAL;
799}
800
801/**********************************************************************/
804void wonder_built(const struct city *pcity, const struct impr_type *pimprove)
805{
806 struct player *pplayer;
807 int windex = improvement_number(pimprove);
808
809 fc_assert_ret(NULL != pcity);
810 fc_assert_ret(is_wonder(pimprove));
811
812 pplayer = city_owner(pcity);
813 pplayer->wonders[windex] = pcity->id;
814
815 if (is_great_wonder(pimprove)) {
816 game.info.great_wonder_owners[windex] = player_number(pplayer);
817 }
818}
819
820/**********************************************************************/
824void wonder_destroyed(const struct city *pcity,
825 const struct impr_type *pimprove)
826{
827 struct player *pplayer;
828 int windex = improvement_number(pimprove);
829
830 fc_assert_ret(NULL != pcity);
831 fc_assert_ret(is_wonder(pimprove));
832
833 pplayer = city_owner(pcity);
834 fc_assert_ret(pplayer->wonders[windex] == pcity->id);
835 pplayer->wonders[windex] = WONDER_LOST;
836
837 if (is_great_wonder(pimprove)) {
839 == player_number(pplayer));
841 }
842}
843
844/**********************************************************************/
848bool wonder_is_lost(const struct player *pplayer,
849 const struct impr_type *pimprove)
850{
851 fc_assert_ret_val(NULL != pplayer, FALSE);
853
854 return pplayer->wonders[improvement_index(pimprove)] == WONDER_LOST;
855}
856
857/**********************************************************************/
861bool wonder_is_built(const struct player *pplayer,
862 const struct impr_type *pimprove)
863{
864 fc_assert_ret_val(NULL != pplayer, FALSE);
866
867 return WONDER_BUILT(pplayer->wonders[improvement_index(pimprove)]);
868}
869
870/**********************************************************************/
876struct city *city_from_wonder(const struct player *pplayer,
877 const struct impr_type *pimprove)
878{
879 int idx = improvement_index(pimprove);
880 int city_id;
881
882 if (idx < 0) {
883 return NULL;
884 }
885
886 city_id = pplayer->wonders[idx];
887
888 fc_assert_ret_val(NULL != pplayer, NULL);
889 fc_assert_ret_val(is_wonder(pimprove), NULL);
890
891 if (!WONDER_BUILT(city_id)) {
892 return NULL;
893 }
894
895#ifdef FREECIV_DEBUG
896 if (is_server()) {
897 /* On client side, this info is not always known. */
898 struct city *pcity = player_city_by_number(pplayer, city_id);
899
900 if (NULL == pcity) {
901 log_error("Player %s (nb %d) has outdated wonder info for "
902 "%s (nb %d), it points to city nb %d.",
903 player_name(pplayer), player_number(pplayer),
904 improvement_rule_name(pimprove),
905 improvement_number(pimprove), city_id);
906 } else if (!city_has_building(pcity, pimprove)) {
907 log_error("Player %s (nb %d) has outdated wonder info for "
908 "%s (nb %d), the city %s (nb %d) doesn't have this wonder.",
909 player_name(pplayer), player_number(pplayer),
910 improvement_rule_name(pimprove),
911 improvement_number(pimprove), city_name_get(pcity), pcity->id);
912 return NULL;
913 }
914
915 return pcity;
916 }
917#endif /* FREECIV_DEBUG */
918
919 return player_city_by_number(pplayer, city_id);
920}
921
922/**********************************************************************/
925bool wonder_visible_to_player(const struct impr_type *wonder,
926 const struct player *pplayer,
927 const struct player *owner)
928{
929 if (pplayer == owner) {
930 /* Can see all own wonders,
931 * even improvements if that matters. */
932 return TRUE;
933 }
934
935 if (is_great_wonder(wonder)) {
936 return TRUE;
937 }
938
939 if (is_small_wonder(wonder)) {
941 case WV_ALWAYS:
942 return TRUE;
943 case WV_NEVER:
944 return FALSE;
945 }
946
948
949 return FALSE;
950 }
951
952 /* Now a wonder, but regular improvement */
953 return FALSE;
954}
955
956/**********************************************************************/
959bool great_wonder_is_built(const struct impr_type *pimprove)
960{
962
964 [improvement_index(pimprove)]);
965}
966
967/**********************************************************************/
970bool great_wonder_is_destroyed(const struct impr_type *pimprove)
971{
973
974 return (WONDER_DESTROYED
976}
977
978/**********************************************************************/
981bool great_wonder_is_available(const struct impr_type *pimprove)
982{
984
985 return (WONDER_NOT_OWNED
987}
988
989/**********************************************************************/
993struct city *city_from_great_wonder(const struct impr_type *pimprove)
994{
995 int player_id = game.info.great_wonder_owners[improvement_index(pimprove)];
996
997 fc_assert_ret_val(is_great_wonder(pimprove), NULL);
998
999 if (WONDER_OWNED(player_id)) {
1000#ifdef FREECIV_DEBUG
1001 const struct player *pplayer = player_by_number(player_id);
1002 struct city *pcity = city_from_wonder(pplayer, pimprove);
1003
1004 if (is_server() && NULL == pcity) {
1005 log_error("Game has outdated wonder info for %s (nb %d), "
1006 "the player %s (nb %d) doesn't have this wonder.",
1007 improvement_rule_name(pimprove),
1008 improvement_number(pimprove),
1009 player_name(pplayer), player_number(pplayer));
1010 }
1011
1012 return pcity;
1013#else
1014 return city_from_wonder(player_by_number(player_id), pimprove);
1015#endif /* FREECIV_DEBUG */
1016 } else {
1017 return NULL;
1018 }
1019}
1020
1021/**********************************************************************/
1025struct player *great_wonder_owner(const struct impr_type *pimprove)
1026{
1027 int player_id = game.info.great_wonder_owners[improvement_index(pimprove)];
1028
1029 fc_assert_ret_val(is_great_wonder(pimprove), NULL);
1030
1031 if (WONDER_OWNED(player_id)) {
1032 return player_by_number(player_id);
1033 } else {
1034 return NULL;
1035 }
1036}
1037
1038/**********************************************************************/
1041bool small_wonder_is_built(const struct player *pplayer,
1042 const struct impr_type *pimprove)
1043{
1045
1046 return (NULL != pplayer
1047 && wonder_is_built(pplayer, pimprove));
1048}
1049
1050/**********************************************************************/
1053struct city *city_from_small_wonder(const struct player *pplayer,
1054 const struct impr_type *pimprove)
1055{
1056 fc_assert_ret_val(is_small_wonder(pimprove), NULL);
1057
1058 if (NULL == pplayer) {
1059 return NULL; /* Used in some places in the client. */
1060 } else {
1061 return city_from_wonder(pplayer, pimprove);
1062 }
1063}
1064
1065/**********************************************************************/
1068bool can_sell_building(const struct impr_type *pimprove)
1069{
1070 return (valid_improvement(pimprove) && is_improvement(pimprove));
1071}
1072
1073/**********************************************************************/
1076bool can_city_sell_building(const struct city *pcity,
1077 const struct impr_type *pimprove)
1078{
1079 return (city_has_building(pcity, pimprove) && is_improvement(pimprove));
1080}
1081
1082/**********************************************************************/
1088 struct city *pcity,
1089 const struct impr_type *pimprove)
1090{
1091 /* Check if player can sell anything from this city */
1092 if (pcity->owner != pplayer) {
1093 return TR_OTHER_FAILURE;
1094 }
1095
1096 if (pcity->did_sell) {
1097 return TR_ALREADY_SOLD;
1098 }
1099
1100 /* Check if particular building can be solt */
1101 if (pimprove != NULL
1102 && !can_city_sell_building(pcity, pimprove)) {
1103 return TR_OTHER_FAILURE;
1104 }
1105
1106 return TR_SUCCESS;
1107}
1108
1109/**********************************************************************/
1113const struct impr_type *improvement_replacement(const struct impr_type *pimprove)
1114{
1115 requirement_vector_iterate(&pimprove->obsolete_by, pobs) {
1116 if (pobs->source.kind == VUT_IMPROVEMENT && pobs->present) {
1117 return pobs->source.value.building;
1118 }
1120
1121 return NULL;
1122}
bool is_action_possible_on_city(action_id act_id, const struct player *actor_player, const struct city *target_city)
Definition actions.c:7142
#define action_enablers_iterate_end
Definition actions.h:526
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
#define action_enablers_iterate(_enabler_)
Definition actions.h:520
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1216
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:927
#define city_tile(_pcity_)
Definition city.h:544
#define city_owner(_pcity_)
Definition city.h:543
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:222
#define city_tile_iterate_end
Definition city.h:230
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2840
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
bool can_disaster_happen(const struct disaster_type *pdis, const struct city *pcity)
Definition disaster.c:139
#define disaster_type_iterate(_p)
Definition disaster.h:80
#define disaster_type_iterate_end
Definition disaster.h:86
int int id
Definition editgui_g.h:28
struct effect_list * get_req_source_effects(struct universal *psource)
Definition effects.c:146
bool is_building_replaced(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Definition effects.c:641
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
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
int get_building_bonus(const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
Definition effects.c:930
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:587
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
#define effect_list_iterate_end
Definition effects.h:375
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:442
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_type_iterate_end
Definition extras.h:297
static bool is_server(void)
int Impr_type_id
Definition fc_types.h:346
@ RPT_CERTAIN
Definition fc_types.h:586
@ RPT_POSSIBLE
Definition fc_types.h:585
test_result
Definition fc_types.h:1097
@ TR_ALREADY_SOLD
Definition fc_types.h:1100
@ TR_OTHER_FAILURE
Definition fc_types.h:1099
@ TR_SUCCESS
Definition fc_types.h:1098
@ VC_SPACERACE
Definition fc_types.h:1123
#define Qn_(String)
Definition fcintl.h:89
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct city * owner
Definition citydlg.c:219
static GtkWidget * source
Definition gotodlg.c:58
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
struct impr_type * improvement_by_number(const Impr_type_id id)
bool can_sell_building(const struct impr_type *pimprove)
int impr_sell_gold(const struct impr_type *pimprove)
void improvements_init(void)
Definition improvement.c:46
const struct impr_type * improvement_array_last(void)
const struct impr_type * valid_improvement_by_number(const Impr_type_id id)
bool can_city_sell_building(const struct city *pcity, const struct impr_type *pimprove)
bool can_player_build_improvement_direct(const struct player *p, const struct impr_type *pimprove)
bool great_wonder_is_built(const struct impr_type *pimprove)
static bool improvement_has_side_effects(const struct city *pcity, const struct impr_type *pimprove)
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
bool is_special_improvement(const struct impr_type *pimprove)
static bool impr_prevents_disaster(const struct city *pcity, const struct impr_type *pimprove)
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
bool can_player_build_improvement_later(const struct player *p, const struct impr_type *pimprove)
void wonder_built(const struct city *pcity, const struct impr_type *pimprove)
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
bool wonder_is_lost(const struct player *pplayer, const struct impr_type *pimprove)
bool can_player_build_improvement_now(const struct player *p, struct impr_type *pimprove)
bool is_improvement(const struct impr_type *pimprove)
static bool improvement_has_effects(const struct city *pcity, const struct impr_type *pimprove)
bool wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
int impr_base_build_shield_cost(const struct impr_type *pimprove)
Impr_type_id improvement_number(const struct impr_type *pimprove)
static bool impr_provides_buildable_extras(const struct city *pcity, const struct impr_type *pimprove)
bool small_wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
bool can_improvement_go_obsolete(const struct impr_type *pimprove)
const char * improvement_rule_name(const struct impr_type *pimprove)
bool is_improvement_visible(const struct impr_type *pimprove)
struct city * city_from_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
int impr_buy_gold_cost(const struct city *pcity, const struct impr_type *pimprove, int shields_in_stock)
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
static void improvement_free(struct impr_type *p)
Definition improvement.c:66
bool is_wonder(const struct impr_type *pimprove)
static bool impr_protects_vs_actions(const struct city *pcity, const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity)
static bool impr_allows_actions(const struct city *pcity, const struct impr_type *pimprove)
struct impr_type * improvement_by_translated_name(const char *name)
void improvement_feature_cache_init(void)
Definition improvement.c:90
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
struct impr_type * improvement_by_rule_name(const char *name)
struct city * city_from_small_wonder(const struct player *pplayer, const struct impr_type *pimprove)
void wonder_destroyed(const struct city *pcity, const struct impr_type *pimprove)
static struct impr_type improvement_types[B_LAST]
Definition improvement.c:41
const char * improvement_name_translation(const struct impr_type *pimprove)
struct city * city_from_great_wonder(const struct impr_type *pimprove)
Impr_type_id improvement_count(void)
static bool impr_provides_buildable_units(const struct city *pcity, const struct impr_type *pimprove)
bool is_small_wonder(const struct impr_type *pimprove)
struct impr_type * improvement_array_first(void)
int impr_estimate_build_shield_cost(const struct player *pplayer, const struct tile *ptile, const struct impr_type *pimprove)
bool wonder_visible_to_player(const struct impr_type *wonder, const struct player *pplayer, const struct player *owner)
const struct impr_type * improvement_replacement(const struct impr_type *pimprove)
struct player * great_wonder_owner(const struct impr_type *pimprove)
bool great_wonder_is_available(const struct impr_type *pimprove)
void improvements_free(void)
Definition improvement.c:80
bool is_improvement_productive(const struct city *pcity, const struct impr_type *pimprove)
#define WONDER_NOT_OWNED
#define WONDER_BUILT(city_id)
#define improvement_iterate_end
#define WONDER_DESTROYED
#define improvement_iterate(_p)
#define WONDER_LOST
#define B_LAST
Definition improvement.h:42
#define WONDER_OWNED(player_id)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_error(message,...)
Definition log.h:103
static const char * rule_name_get(const struct name_translation *ptrans)
static const char * name_translation_get(const struct name_translation *ptrans)
struct player * player_by_number(const int player_id)
Definition player.c:840
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1179
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)
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)
#define requirement_fulfilled_by_improvement(_imp_, _rqs_)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
#define requirement_needs_improvement(_imp_, _rqs_)
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MAX(x, y)
Definition shared.h:54
#define NUM_SS_MODULES
Definition spaceship.h:89
#define NUM_SS_COMPONENTS
Definition spaceship.h:88
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
@ SSHIP_LAUNCHED
Definition spaceship.h:85
void strvec_destroy(struct strvec *psv)
Definition city.h:309
bool did_sell
Definition city.h:367
int id
Definition city.h:315
struct player * owner
Definition city.h:312
struct tile * tile
Definition city.h:311
struct packet_ruleset_control control
Definition game.h:83
struct packet_game_info info
Definition game.h:89
bool allows_actions
Definition improvement.h:91
int build_cost
Definition improvement.h:77
enum impr_genus_id genus
Definition improvement.h:80
bool ruledit_disabled
Definition improvement.h:71
bool protects_vs_actions
Definition improvement.h:90
struct requirement_vector obsolete_by
Definition improvement.h:76
Impr_type_id item_number
Definition improvement.h:69
bool prevents_disaster
Definition improvement.h:89
struct requirement_vector reqs
Definition improvement.h:75
bool allows_extras
Definition improvement.h:88
struct strvec * helptext
Definition improvement.h:82
bool allows_units
Definition improvement.h:87
struct name_translation name
Definition improvement.h:70
bv_impr_flags flags
Definition improvement.h:81
void * ruledit_dlg
Definition improvement.h:72
int great_wonder_owners[B_LAST]
enum wonder_visib_type small_wonder_visibility
enum spaceship_state state
Definition spaceship.h:108
int wonders[B_LAST]
Definition player.h:301
struct player_spaceship spaceship
Definition player.h:286
const struct player * player
Definition tile.h:49
enum universals_n kind
Definition fc_types.h:758
struct civ_map map
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
bool utype_player_already_has_this(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1993
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_iterate_end
Definition unittype.h:848
bool victory_enabled(enum victory_condition_type victory)
Definition victory.c:26