Freeciv-3.3
Loading...
Searching...
No Matches
citydlg_common.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#include <stdarg.h>
19
20/* utility */
21#include "astring.h"
22#include "fcintl.h"
23#include "log.h"
24#include "support.h"
25
26/* common */
27#include "city.h"
28#include "culture.h"
29#include "game.h"
30#include "specialist.h"
31#include "unitlist.h"
32
33/* client/include */
34#include "citydlg_g.h"
35#include "mapview_g.h"
36
37/* client */
38#include "citydlg_common.h"
39#include "client_main.h" /* For can_client_issue_orders() */
40#include "climap.h"
41#include "control.h"
42#include "mapview_common.h"
43#include "options.h" /* For concise_city_production */
44#include "tilespec.h" /* For tileset_is_isometric(tileset) */
45
47
48/**********************************************************************/
52{
53 return citydlg_map_width;
54}
55
56/**********************************************************************/
60{
61 return citydlg_map_height;
62}
63
64/**********************************************************************/
88
89/**********************************************************************/
93bool city_to_canvas_pos(float *canvas_x, float *canvas_y, int city_x,
94 int city_y, int city_radius_sq)
95{
96 const int width = get_citydlg_canvas_width();
98
99 /* The citymap is centered over the center of the citydlg canvas. */
104
106 FALSE);
107
108 return TRUE;
109}
110
111/**********************************************************************/
115bool canvas_to_city_pos(int *city_x, int *city_y, int city_radius_sq,
116 int canvas_x, int canvas_y)
117{
118#ifdef FREECIV_DEBUG
120#endif
121 const int width = get_citydlg_canvas_width();
122 const int height = get_citydlg_canvas_height();
123
124 /* The citymap is centered over the center of the citydlg canvas. */
127
129 const int W = tileset_tile_width(get_tileset()),
131
132 /* Shift the tile left so the top corner of the origin tile is at
133 canvas position (0,0). */
134 canvas_x -= W / 2;
135
136 /* Perform a pi / 4 rotation, with scaling. See gui_to_map_pos()
137 for a full explanation. */
138 *city_x = DIVIDE(canvas_x * H + canvas_y * W, W * H);
139 *city_y = DIVIDE(canvas_y * W - canvas_x * H, W * H);
140 } else {
143 }
144
145 /* Add on the offset of the top-left corner to get the final
146 * coordinates (like in gui_to_map_pos()). */
149
150 log_debug("canvas_to_city_pos(pos=(%d,%d))=(%d,%d)@radius=%d",
151 orig_canvas_x, orig_canvas_y, *city_x, *city_y, city_radius_sq);
152
153 return is_valid_city_coords(city_radius_sq, *city_x, *city_y);
154}
155
156/* Iterate over all known tiles in the city. This iteration follows the
157 * painter's algorithm and can be used for drawing. */
158#define citydlg_iterate(pcity, ptile, pedge, pcorner, _x, _y) \
159{ \
160 float _x##_0, _y##_0; \
161 int _tile_x, _tile_y; \
162 const int _x##_w = get_citydlg_canvas_width(); \
163 const int _y##_h = get_citydlg_canvas_height(); \
164 index_to_map_pos(&_tile_x, &_tile_y, tile_index((pcity)->tile)); \
165 \
166 map_to_gui_vector(tileset, 1.0, &_x##_0, &_y##_0, _tile_x, _tile_y); \
167 _x##_0 -= (_x##_w - tileset_tile_width(tileset)) / 2; \
168 _y##_0 -= (_y##_h - tileset_tile_height(tileset)) / 2; \
169 log_debug("citydlg: %f,%f + %dx%d", \
170 _x##_0, _y##_0, _x##_w, _y##_h); \
171 \
172 gui_rect_iterate_coord(_x##_0, _y##_0, _x##_w, _y##_h, \
173 ptile, pedge, pcorner, _x##_g, _y##_g, 1.0) { \
174 const int _x = _x##_g - _x##_0; \
175 const int _y = _y##_g - _y##_0; \
176 {
177
178#define citydlg_iterate_end \
179 } \
180 } gui_rect_iterate_coord_end; \
181}
182
183/**********************************************************************/
188 struct canvas *pcanvas)
189{
190 struct tileset *tmp;
191
192 tmp = NULL;
193 if (unscaled_tileset) {
194 tmp = tileset;
196 }
197
198 /* First make it all black. */
200 0, 0,
203
204 mapview_layer_iterate(layer) {
206 struct unit *punit
207 = ptile ? get_drawable_unit(tileset, ptile, pcity) : NULL;
208 struct city *pcity_draw = ptile ? tile_city(ptile) : NULL;
209
210 put_one_element(pcanvas, 1.0, layer, ptile, pedge, pcorner,
214
215 if (tmp != NULL) {
216 tileset = tmp;
217 }
218}
219
220/**********************************************************************/
225{
226 static char cost_str[50];
229 int num_units;
230
231 if (build_slots > 1
233 /* The city could build more than one unit of the selected type */
234 if (num_units == 0) {
235 /* No unit will be finished this turn but one is build */
236 num_units++;
237 }
238
239 if (build_slots > num_units) {
240 /* Some build slots for units will be unused */
241 fc_snprintf(cost_str, sizeof(cost_str), "{%d*%d}", num_units, cost);
242 } else {
243 /* Maximal number of units will be build */
244 fc_snprintf(cost_str, sizeof(cost_str), "[%d*%d]", num_units, cost);
245 }
246 } else {
247 /* Nothing special */
248 fc_snprintf(cost_str, sizeof(cost_str), "%3d", cost);
249 }
250
251 return cost_str;
252}
253
254/**********************************************************************/
261 char *buffer, size_t buffer_len)
262{
263 char time_str[50], *cost_str;
264 int turns, stock;
265
266 if (pcity == NULL) {
267 /*
268 * Some GUIs use this to build a "filler string" so that they can
269 * properly size the widget to hold the string. This has some
270 * obvious problems; the big one is that we have two forms of time
271 * information: "XXX turns" and "never". Later this may need to
272 * be extended to return the longer of the two; in the meantime
273 * translators can fudge it by changing this "filler" string.
274 */
275 /* TRANS: Use longer of "XXX turns" and "never" */
276 fc_strlcpy(buffer, Q_("?filler:XXX/XXX XXX turns"), buffer_len);
277
278 return;
279 }
280
282 int output = MAX(0, pcity->surplus[O_SHIELD]);
283
285 fc_snprintf(buffer, buffer_len,
286 PL_("%3d gold per turn", "%3d gold per turn", output),
287 output);
289 fc_snprintf(buffer, buffer_len,
290 PL_("%3d infrapoint per turn", "%3d infrapoints per turn", output),
291 output);
292 } else {
293 fc_strlcpy(buffer, "---", buffer_len);
294 }
295 return;
296 }
297
299 stock = pcity->shield_stock;
301
302 if (turns < FC_INFINITY) {
304 fc_snprintf(time_str, sizeof(time_str), "%3d", turns);
305 } else {
307 PL_("%3d turn", "%3d turns", turns), turns);
308 }
309 } else {
310 fc_snprintf(time_str, sizeof(time_str), "%s",
311 gui_options.concise_city_production ? "-" : _("never"));
312 }
313
315 fc_snprintf(buffer, buffer_len, _("%3d/%s:%s"), stock, cost_str,
316 time_str);
317 } else {
318 fc_snprintf(buffer, buffer_len, _("%3d/%s %s"), stock, cost_str,
319 time_str);
320 }
321}
322
323/**********************************************************************/
334 struct universal *target,
335 struct city *pcity)
336{
337 int turns = city_turns_to_build(pcity, target, TRUE);
339
340 switch (target->kind) {
341 case VUT_IMPROVEMENT:
342 fc_strlcpy(buffer,
344 buffer_len);
345
347 fc_strlcat(buffer, " (--) ", buffer_len);
350 cat_snprintf(buffer, buffer_len, _("%d/turn"),
351 MAX(0, pcity->surplus[O_SHIELD]));
352 } else {
353 fc_strlcat(buffer, "---", buffer_len);
354 }
355 return;
356 }
357 break;
358 default:
359 universal_name_translation(target, buffer, buffer_len);
360 break;
361 };
362 cat_snprintf(buffer, buffer_len, " (%d) ", cost);
363
364 if (turns < FC_INFINITY) {
365 cat_snprintf(buffer, buffer_len,
366 PL_("%d turn", "%d turns", turns),
367 turns);
368 } else {
369 cat_snprintf(buffer, buffer_len, _("never"));
370 }
371}
372
373/**********************************************************************/
379 struct universal *target,
380 struct city *pcity)
381{
382 struct player *pplayer = pcity ? city_owner(pcity) : client_player();
383
385
386 switch (target->kind) {
387 case VUT_UTYPE:
388 {
389 const struct unit_type *ptype = target->value.utype;
390
392 fc_snprintf(buf[2], column_size, "(%d)",
394 break;
395 }
396 case VUT_IMPROVEMENT:
397 {
398 const struct impr_type *pimprove = target->value.building;
399
400 /* Total & turns left meaningless on coinage-like improvements */
401 if (is_convert_improvement(pimprove)) {
402 buf[1][0] = '\0';
403 fc_snprintf(buf[2], column_size, "---");
404 } else {
405 int upkeep = pcity ? city_improvement_upkeep(pcity, pimprove)
406 : pimprove->upkeep;
407 /* From city.c city_improvement_name_translation() */
408 if (pcity && is_improvement_redundant(pcity, pimprove)) {
409 fc_snprintf(buf[1], column_size, "%d*", upkeep);
410 } else {
411 const char *state = NULL;
412
413 if (is_great_wonder(pimprove)) {
414 if (improvement_obsolete(pplayer, pimprove, pcity)) {
415 state = _("Obsolete");
416 } else if (great_wonder_is_built(pimprove)) {
417 state = _("Built");
418 } else if (great_wonder_is_destroyed(pimprove)) {
419 state = _("Destroyed");
420 } else {
421 state = _("Great Wonder");
422 }
423 } else if (is_small_wonder(pimprove)) {
424 if (improvement_obsolete(pplayer, pimprove, pcity)) {
425 state = _("Obsolete");
426 } else if (wonder_is_built(pplayer, target->value.building)) {
427 state = _("Built");
428 } else {
429 state = _("Small Wonder");
430 }
431 }
432 if (state) {
433 fc_strlcpy(buf[1], state, column_size);
434 } else {
435 fc_snprintf(buf[1], column_size, "%d", upkeep);
436 }
437 }
438
439 if (pcity != NULL) {
440 fc_snprintf(buf[2], column_size, "%d",
441 impr_build_shield_cost(pcity, pimprove));
442 } else {
443 fc_snprintf(buf[2], column_size, "%d",
444 impr_estimate_build_shield_cost(pplayer, NULL, pimprove));
445 }
446 }
447 break;
448 }
449 default:
450 buf[1][0] = '\0';
451 buf[2][0] = '\0';
452 break;
453 };
454
455 /* Add the turns-to-build entry in the 4th position */
456 if (pcity) {
457 if (VUT_IMPROVEMENT == target->kind
459 /* Coinage-like improvements: print yield-per-turn instead */
462 fc_snprintf(buf[3], column_size, _("%d/turn"),
463 MAX(0, pcity->surplus[O_SHIELD]));
464 } else {
465 buf[3][0] = '\0';
466 }
467 } else {
468 int turns = city_turns_to_build(pcity, target, FALSE);
469
470 if (turns < FC_INFINITY) {
471 fc_snprintf(buf[3], column_size, "%d", turns);
472 } else {
473 fc_snprintf(buf[3], column_size, _("never"));
474 }
475 }
476 } else {
477 fc_snprintf(buf[3], column_size, "---");
478 }
479}
480
481/**********************************************************************/
486struct city_sum {
487 const char *format;
488 size_t n;
489 struct {
490 /* The net value that is accumulated. */
491 double value;
492 /* Description; compared for duplicate-merging.
493 * Both of these are maintained/compared until the net 'value' is known;
494 * then posdesc is used if value>=0, negdesc if value<0 */
496 /* Whether posdesc is printed for total==0 */
498 /* An auxiliary value that is also accumulated, but not tested */
499 double aux;
500 /* ...and the format string for the net aux value (appended to *desc) */
501 const char *auxfmt;
503};
504
505/**********************************************************************/
511static struct city_sum *city_sum_new(const char *format)
512{
513 struct city_sum *sum = fc_malloc(sizeof(struct city_sum));
514
515 sum->format = format;
516 sum->n = 0;
517 sum->sums = NULL;
518
519 return sum;
520}
521
522/**********************************************************************/
527static void city_sum_add_real(struct city_sum *sum, double value,
528 bool suppress_if_zero,
529 const char *auxfmt,
530 double aux,
531 char *posdesc,
532 char *negdesc)
533{
534 size_t i;
535
536 /* Likely to lead to quadratic behaviour, but who cares: */
537 for (i = 0; i < sum->n; i++) {
538 fc_assert(sum->sums != NULL);
539 if ((strcmp(sum->sums[i].posdesc, posdesc) == 0)
540 && (strcmp(sum->sums[i].negdesc, negdesc) == 0)
541 && ((sum->sums[i].auxfmt == auxfmt)
542 || (auxfmt != NULL && !strcmp(sum->sums[i].auxfmt, auxfmt)))
544 /* Looks like we already have an entry like this. Accumulate values. */
545 sum->sums[i].value += value;
546 sum->sums[i].aux += aux;
549 return;
550 }
551 }
552
553 /* Didn't find description already, so add it to the end. */
554 sum->sums = fc_realloc(sum->sums, (sum->n + 1) * sizeof(sum->sums[0]));
555 sum->sums[sum->n].value = value;
556 sum->sums[sum->n].posdesc = posdesc;
557 sum->sums[sum->n].negdesc = negdesc;
559 sum->sums[sum->n].aux = aux;
560 sum->sums[sum->n].auxfmt = auxfmt;
561 sum->n++;
562}
563
564/**********************************************************************/
575static void
578 fc__attribute((nonnull (1, 6, 7)))
580 bool suppress_if_zero,
581 const char *auxfmt,
582 double aux,
583 const char *posfmt,
584 const char *negfmt,
585 ...)
586{
587 va_list args;
588 struct astring astr = ASTRING_INIT;
589 char *posdesc, *negdesc;
590
591 /* Format both descriptions */
592 va_start(args, negfmt); /* sic -- arguments follow negfmt */
593 astr_vadd(&astr, posfmt, args);
594 posdesc = astr_to_str(&astr);
595 va_end(args);
596 va_start(args, negfmt);
597 astr_vadd(&astr, negfmt, args);
598 negdesc = astr_to_str(&astr);
599 va_end(args);
600
601 city_sum_add_real(sum, value, suppress_if_zero, auxfmt, aux,
602 posdesc, negdesc);
603}
604
605/**********************************************************************/
612static void
614 fc__attribute((nonnull (1, 3)))
615 city_sum_add(struct city_sum *sum, double value,
616 const char *descfmt, ...)
617{
618 va_list args;
619 struct astring astr = ASTRING_INIT;
620 char *desc;
621
622 /* Format description (same used for positive or negative net value) */
623 va_start(args, descfmt);
624 astr_vadd(&astr, descfmt, args);
625 desc = astr_to_str(&astr);
626 va_end(args);
627
628 /* Descriptions will be freed individually, so need to fc_strdup() */
629 city_sum_add_real(sum, value, FALSE, NULL, 0, desc, fc_strdup(desc));
630}
631
632/**********************************************************************/
639static void
641 fc__attribute((nonnull (1, 3)))
642 city_sum_add_if_nonzero(struct city_sum *sum, double value,
643 const char *descfmt, ...)
644{
645 va_list args;
646 struct astring astr = ASTRING_INIT;
647 char *desc;
648
649 /* Format description (same used for positive or negative net value) */
650 va_start(args, descfmt);
651 astr_vadd(&astr, descfmt, args);
652 desc = astr_to_str(&astr);
653 va_end(args);
654
655 /* Descriptions will be freed individually, so need to fc_strdup() */
656 city_sum_add_real(sum, value, TRUE, NULL, 0, desc, fc_strdup(desc));
657}
658
659/**********************************************************************/
662static double city_sum_total(struct city_sum *sum)
663{
664 size_t i;
665 double total = 0;
666
667 for (i = 0; i < sum->n; i++) {
668 total += sum->sums[i].value;
669 }
670
671 return total;
672}
673
674/**********************************************************************/
680static inline int city_sum_compare(double val1, double val2)
681{
682 /* Fudgey epsilon -- probably the numbers we're dealing with have at
683 * most 1% or 0.1% real difference */
684 if (fabs(val1-val2) < 0.0000001) {
685 return 0;
686 }
687
688 return (val1 > val2 ? +1 : -1);
689}
690
691/**********************************************************************/
698static void
700 fc__attribute((nonnull (1, 2, 5)))
701 city_sum_print(struct city_sum *sum, char *buf, size_t bufsz,
703 const char *totalfmt, ...)
704{
705 va_list args;
706 size_t i;
707
708 /* This probably ought not to happen in well-designed rulesets, but it's
709 * possible for incomplete client knowledge to give an inaccurate
710 * breakdown. If it does happen, at least acknowledge to the user that
711 * we are confused, rather than displaying an incorrect sum. */
713 double total = city_sum_total(sum);
714 double actual_total;
715
716 va_start(args, totalfmt);
717 actual_total = va_arg(args, double);
718 va_end(args);
719
720 if (city_sum_compare(total, actual_total) != 0) {
721 city_sum_add(sum, actual_total - total,
722 /* TRANS: Client cannot explain some aspect of city
723 * output. Should never happen. */
724 Q_("?city_sum:(unknown)"));
725 }
726 }
727
728 for (i = 0; i < sum->n; i++) {
729 if (!sum->sums[i].suppress_if_zero
730 || city_sum_compare(sum->sums[i].value, 0) != 0) {
732 sum->format, sum->sums[i].value,
733 (sum->sums[i].value < 0) ? sum->sums[i].negdesc
734 : sum->sums[i].posdesc);
735 if (sum->sums[i].auxfmt) {
736 cat_snprintf(buf, bufsz, sum->sums[i].auxfmt, sum->sums[i].aux);
737 }
738 cat_snprintf(buf, bufsz, "\n");
739 }
740 FC_FREE(sum->sums[i].posdesc);
741 FC_FREE(sum->sums[i].negdesc);
742 }
743
744 va_start(args, totalfmt);
746 va_end(args);
747
748 FC_FREE(sum->sums);
749 FC_FREE(sum);
750}
751
752/**********************************************************************/
757 char *buf, size_t bufsz)
758{
759 int priority;
760 int tax[O_LAST];
761 struct output_type *output = &output_types[otype];
762 /* TRANS: format string for a row of the city output sum that adds up
763 * to "Total surplus" */
764 struct city_sum *sum = city_sum_new(Q_("?city_surplus:%+4.0f : %s"));
765
766 buf[0] = '\0';
767
768 city_sum_add(sum, pcity->citizen_base[otype],
769 Q_("?city_surplus:Citizens"));
770
771 /* Hack to get around the ugliness of add_tax_income(). */
772 memset(tax, 0, O_LAST * sizeof(*tax));
775 Q_("?city_surplus:Taxed from trade"));
776
777 /* Special cases for "bonus" production. See set_city_production() in
778 * city.c. */
779 if (otype == O_TRADE) {
781 /* NB: (proute->value == 0) is valid case. The trade route
782 * is established but doesn't give trade surplus. */
783 struct city *trade_city = game_city_by_number(proute->partner);
784 /* TRANS: Trade partner unknown to client */
785 const char *name
786 = trade_city ? city_name_get(trade_city) : _("(unknown)");
787 int value = proute->value
788 * (100 + get_city_bonus(pcity, EFT_TRADE_ROUTE_PCT)) / 100;
789
790 switch (proute->dir) {
792 city_sum_add(sum, value, Q_("?city_surplus:Trading %s with %s"),
794 name);
795 break;
796 case RDIR_FROM:
797 city_sum_add(sum, value, Q_("?city_surplus:Trading %s to %s"),
799 name);
800 break;
801 case RDIR_TO:
802 city_sum_add(sum, value, Q_("?city_surplus:Trading %s from %s"),
804 name);
805 break;
806 case RDIR_NONE:
807 fc_assert(proute->dir != RDIR_NONE);
808 break;
809 }
811 } else if (otype == O_GOLD) {
813
815 Q_("?city_surplus:Building tithes"));
816 }
817
818 for (priority = 0; priority < 3; priority++) {
819 enum effect_type eft[] = {EFT_OUTPUT_BONUS, EFT_OUTPUT_BONUS_2,
821
822 {
823 int base = city_sum_total(sum), bonus = 100;
825
827
829 char buf2[512];
830 int delta;
831 int new_total;
832
834
835 if (peffect->multiplier) {
837 peffect->multiplier);
838
839 if (mul == 0) {
840 /* Suppress text when multiplier setting suppresses effect
841 * (this will also suppress it when the city owner's policy
842 * settings are not known to us) */
843 continue;
844 }
845 delta = (peffect->value * mul) / 100;
846 } else {
847 delta = peffect->value;
848 }
849
851 new_total = bonus * base / 100 + delta;
853 NULL, 0,
854 Q_("?city_surplus:Bonus from %s"),
855 Q_("?city_surplus:Loss from %s"), buf2);
856 } else {
857 bonus += delta;
858 new_total = bonus * base / 100;
860 /* TRANS: percentage city output bonus/loss from
861 * some source; preserve leading space */
862 Q_("?city_surplus: (%+.0f%%)"), delta,
863 Q_("?city_surplus:Bonus from %s"),
864 Q_("?city_surplus:Loss from %s"), buf2);
865 }
868 }
869 }
870
871 if (pcity->waste[otype] != 0) {
873 bool breakdown_ok;
874 int regular_waste;
875 /* FIXME: this will give the wrong answer in rulesets with waste on
876 * taxed outputs, such as 'science waste', as our total so far includes
877 * contributions taxed from trade, whereas the equivalent bit in
878 * set_city_production() does not */
880 == pcity->waste[otype]) {
881 /* Our calculation matches the server's, so we trust our breakdown. */
883 Q_("?city_surplus:Size penalty"));
886 } else {
887 /* Our calculation doesn't match what the server sent. Account it all
888 * to corruption/waste. */
889 regular_waste = pcity->waste[otype];
891 }
892 if (regular_waste > 0) {
893 const char *fmt;
894 switch (otype) {
895 case O_SHIELD:
896 default: /* FIXME other output types? */
897 /* TRANS: %s is normally empty, but becomes '?' if client is
898 * uncertain about its accounting (should never happen) */
899 fmt = Q_("?city_surplus:Waste%s");
900 break;
901 case O_TRADE:
902 /* TRANS: %s is normally empty, but becomes '?' if client is
903 * uncertain about its accounting (should never happen) */
904 fmt = Q_("?city_surplus:Corruption%s");
905 break;
906 }
907 city_sum_add(sum, -regular_waste, fmt, breakdown_ok ? "" : "?");
908 }
909 }
910
911 city_sum_add_if_nonzero(sum, -pcity->unhappy_penalty[otype],
912 Q_("?city_surplus:Disorder"));
913
914 if (pcity->usage[otype] > 0) {
915 city_sum_add(sum, -pcity->usage[otype],
916 Q_("?city_surplus:Used"));
917 }
918
920 Q_("?city_surplus:"
921 "==== : Adds up to\n"
922 "%4.0f : Total surplus"), (double) pcity->surplus[otype]);
923}
924
925/**********************************************************************/
929 char *buf, size_t bufsz)
930{
932 struct effect_list *plist;
933 struct city_sum *sum;
934
935 buf[0] = '\0';
936
937 if (!game.info.illness_on) {
938 cat_snprintf(buf, bufsz, _("Illness deactivated in ruleset."));
939 return;
940 }
941
942 sum = city_sum_new(Q_("?city_plague:%+5.1f%% : %s"));
943
946
947 city_sum_add(sum, (float)(ill_size) / 10.0,
948 Q_("?city_plague:Risk from overcrowding"));
949 city_sum_add(sum, (float)(ill_trade) / 10.0,
950 Q_("?city_plague:Risk from trade"));
951 city_sum_add(sum, (float)(ill_pollution) / 10.0,
952 Q_("?city_plague:Risk from pollution"));
953
955
957
959 char buf2[512];
960 int delta;
961
963
964 if (peffect->multiplier) {
966 peffect->multiplier);
967
968 if (mul == 0) {
969 /* Suppress text when multiplier setting suppresses effect
970 * (this will also suppress it when the city owner's policy
971 * settings are not known to us) */
972 continue;
973 }
974 delta = (peffect->value * mul) / 100;
975 } else {
976 delta = peffect->value;
977 }
978
979 city_sum_add_full(sum, -(0.1 * ill_base * delta / 100), TRUE,
980 Q_("?city_plague: (%+.0f%%)"), -delta,
981 Q_("?city_plague:Risk from %s"),
982 Q_("?city_plague:Bonus from %s"), buf2);
985
986 /* XXX: account_for_unknown==FALSE: the displayed sum can fail to
987 * add up due to rounding. Making it always add up probably requires
988 * arbitrary assignment of 0.1% rounding figures to particular
989 * effects with something like distribute(). */
991 Q_("?city_plague:"
992 "====== : Adds up to\n"
993 "%5.1f%% : Plague chance per turn"),
994 ((double)(illness) / 10.0));
995}
996
997/**********************************************************************/
1001 char *buf, size_t bufsz)
1002{
1003 int pollu, prod, pop, mod;
1004 struct city_sum *sum = city_sum_new(Q_("?city_pollution:%+4.0f : %s"));
1005
1006 /* On the server, pollution is calculated before production is deducted
1007 * for disorder; we need to compensate for that */
1009 pcity->prod[O_SHIELD]
1010 + pcity->unhappy_penalty[O_SHIELD],
1011 &prod, &pop, &mod);
1012 buf[0] = '\0';
1013
1014 city_sum_add(sum, prod, Q_("?city_pollution:Pollution from shields"));
1015 city_sum_add(sum, pop, Q_("?city_pollution:Pollution from citizens"));
1016 city_sum_add(sum, mod, Q_("?city_pollution:Pollution modifier"));
1018 Q_("?city_pollution:"
1019 "==== : Adds up to\n"
1020 "%4.0f : Total surplus"), (double)pollu);
1021}
1022
1023/**********************************************************************/
1027 char *buf, size_t bufsz)
1028{
1029 struct effect_list *plist;
1030 struct city_sum *sum = city_sum_new(Q_("?city_culture:%4.0f : %s"));
1031
1032 buf[0] = '\0';
1033
1034 /* XXX: no way to check whether client's idea of gain/turn is accurate */
1035 city_sum_add(sum, pcity->history, Q_("?city_culture:History (%+d/turn)"),
1037
1039
1041
1043 char buf2[512];
1044 int mul = 100;
1045 int value;
1046
1048
1049 if (peffect->multiplier) {
1051 peffect->multiplier);
1052
1053 if (mul == 0) {
1054 /* Suppress text when multiplier setting suppresses effect
1055 * (this will also suppress it when the city owner's policy
1056 * settings are not known to us) */
1057 continue;
1058 }
1059 }
1060
1061 value = (peffect->value * mul) / 100;
1062 /* TRANS: Text describing source of culture bonus ("Library+Republic") */
1063 city_sum_add_if_nonzero(sum, value, Q_("?city_culture:%s"), buf2);
1066
1068 Q_("?city_culture:"
1069 "==== : Adds up to\n"
1070 "%4.0f : Total culture"), (double)pcity->client.culture);
1071}
1072
1073/**********************************************************************/
1077 char *buf, size_t bufsz)
1078{
1079 char src[512];
1080 char dest[512];
1081 int unlimited = 0;
1082
1084 && (pcity->airlift >= 1 || game.info.airlift_from_always_enabled)) {
1085
1086 unlimited++;
1087
1088 /* TRANS: airlift. Possible take offs text. String is a
1089 * proviso that take offs can't occur if landings spend all the
1090 * remaining airlift when landings are limited and empty when they
1091 * aren't limited. */
1092 fc_snprintf(src, sizeof(src), _("unlimited take offs%s"),
1094 /* TRANS: Airlift unlimited take offs proviso used above.
1095 * Plural based on remaining airlift capacity. */
1096 ? "" : PL_(" (until the landing has been spent)",
1097 " (until all landings have been spent)",
1098 pcity->airlift));
1099 } else {
1100 fc_snprintf(src, sizeof(src),
1101 /* TRANS: Airlift. Possible take offs text. Number is
1102 * airlift capacity. */
1103 PL_("%d take off", "%d take offs", pcity->airlift),
1104 pcity->airlift);
1105 }
1106
1108 && (pcity->airlift >= 1 || game.info.airlift_to_always_enabled)){
1109
1110 unlimited++;
1111
1112 /* TRANS: Airlift. Possible landings text. */
1113 fc_snprintf(dest, sizeof(dest), _("unlimited landings"));
1114 } else {
1115 fc_snprintf(dest, sizeof(dest),
1116 /* TRANS: Airlift. Possible landings text.
1117 * Number is airlift capacity. */
1118 PL_("%d landing", "%d landings", pcity->airlift),
1119 pcity->airlift);
1120 }
1121
1122 switch (unlimited) {
1123 case 2:
1124 /* TRANS: Airlift take offs and landings */
1125 fc_snprintf(buf, bufsz, _("unlimited take offs and landings"));
1126 break;
1127 case 1:
1128 /* TRANS: Airlift take offs and landings. One is unlimited. The first
1129 * string is the take offs text. The 2nd string is the landings text. */
1130 fc_snprintf(buf, bufsz, _("%s and %s"), src, dest);
1131 break;
1132 default:
1134 /* TRANS: Airlift take offs or landings, no unlimited.
1135 * Number is airlift capacity. */
1136 PL_("%d take off or landing", "%d take offs or landings",
1137 pcity->airlift),
1138 pcity->airlift);
1139 break;
1140 }
1141}
1142
1143/**********************************************************************/
1147 char *buf, size_t bufsz)
1148{
1149 char src[512];
1150 char dest[512];
1151 int unlimited = 0;
1152
1154 && (pcity->airlift >= 1 || game.info.airlift_from_always_enabled)) {
1155
1156 unlimited++;
1157
1158 /* TRANS: Airlift. Possible take offs text. String is a symbol that
1159 * indicates that terms and conditions apply when landings are limited
1160 * and empty when they aren't limited. */
1161 fc_snprintf(src, sizeof(src), _(" ∞%s"),
1163 /* TRANS: airlift unlimited take offs may be spent symbol
1164 * used above. */
1165 ? "" : Q_("?landings:*"));
1166 } else {
1167 /* TRANS: Airlift. Possible take offs text. Number is
1168 * airlift capacity. */
1169 fc_snprintf(src, sizeof(src), Q_("?takeoffs:%4d"), pcity->airlift);
1170 }
1171
1173 && (pcity->airlift >= 1 || game.info.airlift_to_always_enabled)){
1174
1175 unlimited++;
1176
1177 /* TRANS: Airlift. Possible landings text. */
1178 fc_snprintf(dest, sizeof(dest), _(" ∞"));
1179 } else {
1180 /* TRANS: Airlift. Possible landings text. */
1181 fc_snprintf(dest, sizeof(dest), Q_("?landings:%4d"), pcity->airlift);
1182 }
1183
1184 switch (unlimited) {
1185 case 2:
1186 /* TRANS: Unlimited airlift take offs and landings */
1187 fc_snprintf(buf, bufsz, _(" ∞"));
1188 break;
1189 case 1:
1190 /* TRANS: Airlift take offs and landings. One is unlimited. The first
1191 * string is the take offs text. The 2nd string is the landings text.
1192 * For English, initials of d)epartures and a)rrivals were chosen. */
1193 fc_snprintf(buf, bufsz, _("d: %s a: %s"), src, dest);
1194 break;
1195 default:
1196 /* TRANS: Airlift take offs or landings, no unlimited */
1197 fc_snprintf(buf, bufsz, Q_("?airlifts:%s"), src);
1198 break;
1199 }
1200}
1201
1202/**********************************************************************/
1209 enum citizen_category *categories)
1210{
1211 int i = 0, n;
1212
1213 fc_assert(idx >= 0 && idx < FEELING_LAST);
1214
1215 for (n = 0; n < pcity->feel[CITIZEN_HAPPY][idx]; n++, i++) {
1216 categories[i] = CITIZEN_HAPPY;
1217 }
1218 for (n = 0; n < pcity->feel[CITIZEN_CONTENT][idx]; n++, i++) {
1219 categories[i] = CITIZEN_CONTENT;
1220 }
1221 for (n = 0; n < pcity->feel[CITIZEN_UNHAPPY][idx]; n++, i++) {
1222 categories[i] = CITIZEN_UNHAPPY;
1223 }
1224 for (n = 0; n < pcity->feel[CITIZEN_ANGRY][idx]; n++, i++) {
1225 categories[i] = CITIZEN_ANGRY;
1226 }
1227
1229 for (n = 0; n < pcity->specialists[sp]; n++, i++) {
1230 categories[i] = CITIZEN_SPECIALIST + sp;
1231 }
1233
1234 if (city_size_get(pcity) != i) {
1235 log_error("get_city_citizen_types() %d citizens "
1236 "not equal %d city size in \"%s\".",
1238 }
1239
1240 return i;
1241}
1242
1243/**********************************************************************/
1247{
1248 enum citizen_category categories[MAX_CITY_SIZE];
1249 Specialist_type_id from, to;
1251
1253 || categories[citizen_index] < CITIZEN_SPECIALIST) {
1254 return;
1255 }
1256 from = categories[citizen_index] - CITIZEN_SPECIALIST;
1257
1258 /* Loop through all specialists in order until we find a usable one
1259 * (or run out of choices). */
1260 to = from;
1261 fc_assert(to >= 0 && to < specialist_count());
1262 do {
1263 to = (to + 1) % specialist_count();
1264 } while (to != from && !city_can_use_specialist(pcity, to));
1265
1266 if (from != to) {
1267 city_change_specialist(pcity, from, to);
1268 }
1269}
1270
1271/**********************************************************************/
1274void activate_all_units(struct tile *ptile)
1275{
1276 struct unit_list *punit_list = ptile->units;
1277 struct unit *pmyunit = NULL;
1278
1281 /* Activate this unit. */
1282 pmyunit = punit;
1284 }
1286 if (pmyunit) {
1287 /* Put the focus on one of the activated units. */
1289 }
1290}
1291
1292/**********************************************************************/
1295int city_change_production(struct city *pcity, struct universal *target)
1296{
1298 target->kind,
1299 universal_number(target));
1300}
1301
1302/**********************************************************************/
1307int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
1308{
1310}
1311
1312/**********************************************************************/
1316{
1317 int k;
1318
1319 /* Update the worklist. Remember, though -- the current build
1320 target really isn't in the worklist; don't send it to the server
1321 as part of the worklist. Of course, we have to search through
1322 the current worklist to find the first _now_available_ build
1323 target (to cope with players who try mean things like adding a
1324 Battleship to a city worklist when the player doesn't even yet
1325 have the Map Making tech). */
1326
1327 for (k = 0; k < MAX_LEN_WORKLIST; k++) {
1329 struct universal target;
1330
1331 if (!worklist_peek_ith(pwl, &target, k)) {
1332 break;
1333 }
1334
1335 same_as_current_build = are_universals_equal(&pcity->production, &target);
1336
1337 /* Very special case: If we are currently building a wonder we
1338 allow the construction to continue, even if we the wonder is
1339 finished elsewhere, i.e., unbuildable. */
1340 if (k == 0
1341 && VUT_IMPROVEMENT == target.kind
1342 && is_wonder(target.value.building)
1344 worklist_remove(pwl, k);
1345 break;
1346 }
1347
1348 /* If it can be built... */
1349 if (can_city_build_now(&(wld.map), pcity, &target)) {
1350 /* ...but we're not yet building it, then switch. */
1351 if (!same_as_current_build) {
1352 /* Change the current target */
1353 city_change_production(pcity, &target);
1354 }
1355
1356 /* This item is now (and may have always been) the current
1357 build target. Drop it out of the worklist. */
1358 worklist_remove(pwl, k);
1359 break;
1360 }
1361 }
1362
1363 /* Send the rest of the worklist on its way. */
1365}
1366
1367/**********************************************************************/
1375static bool base_city_queue_insert(struct city *pcity, int position,
1376 struct universal *item)
1377{
1378 const struct civ_map *nmap = &(wld.map);
1379
1380 if (position == 0) {
1381 struct universal old = pcity->production;
1382
1383 /* Insert as current production. */
1385 return FALSE;
1386 }
1387
1388 if (!worklist_insert(&pcity->worklist, &old, 0)) {
1389 return FALSE;
1390 }
1391
1393 } else if (position >= 1
1394 && position <= worklist_length(&pcity->worklist)) {
1395 /* Insert into middle. */
1397 return FALSE;
1398 }
1399 if (!worklist_insert(&pcity->worklist, item, position - 1)) {
1400 return FALSE;
1401 }
1402 } else {
1403 /* Insert at end. */
1405 return FALSE;
1406 }
1407 if (!worklist_append(&pcity->worklist, item)) {
1408 return FALSE;
1409 }
1410 }
1411 return TRUE;
1412}
1413
1414/**********************************************************************/
1419bool city_queue_insert(struct city *pcity, int position,
1420 struct universal *item)
1421{
1422 if (base_city_queue_insert(pcity, position, item)) {
1423 city_set_worklist(pcity, &pcity->worklist);
1424 return TRUE;
1425 }
1426 return FALSE;
1427}
1428
1429/**********************************************************************/
1436{
1437 worklist_init(&pcity->worklist);
1438
1439 return TRUE;
1440}
1441
1442/**********************************************************************/
1447bool city_queue_insert_worklist(struct city *pcity, int position,
1448 const struct worklist *worklist)
1449{
1450 bool success = FALSE;
1451
1452 if (worklist_length(worklist) == 0) {
1453 return TRUE;
1454 }
1455
1456 worklist_iterate(worklist, target) {
1457 if (base_city_queue_insert(pcity, position, &target)) {
1458 if (position > 0) {
1459 /* Move to the next position (unless position == -1 in which case
1460 * we're appending. */
1461 position++;
1462 }
1463 success = TRUE;
1464 }
1466
1467 if (success) {
1468 city_set_worklist(pcity, &pcity->worklist);
1469 }
1470
1471 return success;
1472}
1473
1474/**********************************************************************/
1478{
1479 worklist_copy(pqueue, &pcity->worklist);
1480
1481 /* The GUI wants current production to be in the task list, but the
1482 worklist API wants it out for reasons unknown. Perhaps someone enjoyed
1483 making things more complicated than necessary? So I dance around it. */
1484
1485 /* We want the current production to be in the queue. Always. */
1487
1488 worklist_insert(pqueue, &pcity->production, 0);
1489}
1490
1491/**********************************************************************/
1494bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
1495{
1496 struct worklist copy;
1497 struct universal target;
1498
1499 worklist_copy(&copy, pqueue);
1500
1501 /* The GUI wants current production to be in the task list, but the
1502 worklist API wants it out for reasons unknown. Perhaps someone enjoyed
1503 making things more complicated than necessary? So I dance around it. */
1504 if (worklist_peek(&copy, &target)) {
1505
1507 && !are_universals_equal(&pcity->production, &target)) {
1508 /* We cannot change production to one from worklist.
1509 * Do not replace old worklist with new one. */
1510 return FALSE;
1511 }
1512
1513 worklist_advance(&copy);
1514
1515 city_set_worklist(pcity, &copy);
1516 city_change_production(pcity, &target);
1517 } else {
1518 /* You naughty boy, you can't erase the current production. Nyah! */
1519 if (worklist_is_empty(&pcity->worklist)) {
1521 } else {
1522 city_set_worklist(pcity, &copy);
1523 }
1524 }
1525
1526 return TRUE;
1527}
1528
1529/**********************************************************************/
1532bool city_can_buy(const struct city *pcity)
1533{
1534 /* See really_handle_city_buy() in the server. However this function
1535 * doesn't allow for error messages. It doesn't check the cost of
1536 * buying; that's handled separately (and with an error message). */
1537 return (can_client_issue_orders()
1538 && NULL != pcity
1540 && pcity->turn_founded != game.info.turn
1541 && !pcity->did_buy
1542 && (VUT_UTYPE == pcity->production.kind
1543 || !is_convert_improvement(pcity->production.value.building))
1544 && !(VUT_UTYPE == pcity->production.kind
1545 && pcity->anarchy != 0)
1546 && pcity->client.buy_cost > 0);
1547}
1548
1549/**********************************************************************/
1553{
1554 return dsend_packet_city_sell(&client.conn, pcity->id, sell_id);
1555}
1556
1557/**********************************************************************/
1561{
1563}
1564
1565/**********************************************************************/
1574
1575/**********************************************************************/
1580{
1581 int city_radius_sq;
1582 struct tile *ptile;
1583
1584 if (city_owner(pcity) != client_player()) {
1585 return 0;
1586 }
1587
1588 city_radius_sq = city_map_radius_sq_get(pcity);
1589 fc_assert(is_valid_city_coords(city_radius_sq, city_x, city_y));
1590 ptile = city_map_to_tile(&(wld.map), city_tile(pcity), city_radius_sq,
1591 city_x, city_y);
1592 if (NULL == ptile) {
1593 return 0;
1594 }
1595
1596 if (NULL != tile_worked(ptile) && tile_worked(ptile) == pcity) {
1598 pcity->id, ptile->index);
1599 } else if (city_can_work_tile(pcity, ptile)) {
1601 pcity->id, ptile->index);
1602 } else {
1603 return 0;
1604 }
1605}
1606
1607/**********************************************************************/
1610int city_rename(struct city *pcity, const char *name)
1611{
1613}
void astr_vadd(struct astring *astr, const char *format, va_list ap)
Definition astring.c:263
char * astr_to_str(struct astring *astr)
Definition astring.c:163
#define n
Definition astring.c:77
#define ASTRING_INIT
Definition astring.h:44
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int int int struct sprite *sprite canvas_put_rectangle
Definition canvas_g.h:55
struct canvas int int canvas_y
Definition canvas_g.h:43
struct canvas int canvas_x
Definition canvas_g.h:43
struct canvas * pcanvas
Definition canvas_g.h:42
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
int city_turns_to_build(const struct city *pcity, const struct universal *target, bool include_shield_stock)
Definition city.c:1965
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:663
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:737
int city_pollution_types(const struct city *pcity, int shield_total, int *pollu_prod, int *pollu_pop, int *pollu_mod)
Definition city.c:2787
int city_waste(const struct city *pcity, Output_type_id otype, int total, int *breakdown)
Definition city.c:3253
int city_build_slots(const struct city *pcity)
Definition city.c:2932
struct tile * city_map_to_tile(const struct civ_map *nmap, const struct tile *city_center, int city_radius_sq, int city_map_x, int city_map_y)
Definition city.c:305
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1255
bool can_city_build_later(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:1031
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Definition city.c:1065
bool city_production_has_flag(const struct city *pcity, enum impr_flag_id flag)
Definition city.c:727
void add_tax_income(const struct player *pplayer, int trade, int *output)
Definition city.c:2245
int get_city_tithes_bonus(const struct city *pcity)
Definition city.c:2227
int city_production_turns_to_build(const struct city *pcity, bool include_shield_stock)
Definition city.c:820
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2870
bool is_valid_city_coords(const int city_radius_sq, const int city_map_x, const int city_map_y)
Definition city.c:188
bool can_city_build_direct(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:994
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
int rs_max_city_radius_sq(void)
Definition city.c:159
bool can_city_build_now(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:1013
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1456
bool city_production_is_genus(const struct city *pcity, enum impr_genus_id genus)
Definition city.c:717
bool city_production_build_units(const struct city *pcity, bool add_production, int *num_units)
Definition city.c:747
struct output_type output_types[O_LAST]
Definition city.c:88
bool city_can_change_build(const struct city *pcity)
Definition city.c:1079
#define city_tile(_pcity_)
Definition city.h:561
static citizens city_size_get(const struct city *pcity)
Definition city.h:566
citizen_category
Definition city.h:264
@ CITIZEN_SPECIALIST
Definition city.h:270
@ CITIZEN_ANGRY
Definition city.h:268
@ CITIZEN_HAPPY
Definition city.h:265
@ CITIZEN_CONTENT
Definition city.h:266
@ CITIZEN_UNHAPPY
Definition city.h:267
#define CITY_REL2ABS(_coor)
Definition city.h:112
#define city_owner(_pcity_)
Definition city.h:560
#define MAX_CITY_SIZE
Definition city.h:103
citizen_feeling
Definition city.h:275
@ FEELING_FINAL
Definition city.h:281
@ FEELING_LAST
Definition city.h:282
@ OLOSS_SIZE
Definition city.h:288
@ OLOSS_WASTE
Definition city.h:287
@ OLOSS_LAST
Definition city.h:289
#define city_map_iterate_without_index_end
Definition city.h:181
#define CITY_ABS2REL(_coor)
Definition city.h:113
#define city_map_iterate_without_index(_radius_sq, _x, _y)
Definition city.h:177
static double city_sum_total(struct city_sum *sum)
void get_city_dialog_production_row(char *buf[], size_t column_size, struct universal *target, struct city *pcity)
void get_city_dialog_output_text(const struct city *pcity, Output_type_id otype, char *buf, size_t bufsz)
#define citydlg_iterate_end
void get_city_dialog_production(struct city *pcity, char *buffer, size_t buffer_len)
int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
int city_rename(struct city *pcity, const char *name)
void city_worklist_commit(struct city *pcity, struct worklist *pwl)
#define citydlg_iterate(pcity, ptile, pedge, pcorner, _x, _y)
int get_city_citizen_types(struct city *pcity, enum citizen_feeling idx, enum citizen_category *categories)
int city_buy_production(struct city *pcity)
char * city_production_cost_str(const struct city *pcity)
bool city_queue_insert(struct city *pcity, int position, struct universal *item)
bool city_queue_insert_worklist(struct city *pcity, int position, const struct worklist *worklist)
int city_toggle_worker(struct city *pcity, int city_x, int city_y)
void get_city_dialog_airlift_text(const struct city *pcity, char *buf, size_t bufsz)
static int city_sum_compare(double val1, double val2)
bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
int city_change_production(struct city *pcity, struct universal *target)
void get_city_dialog_production_full(char *buffer, size_t buffer_len, struct universal *target, struct city *pcity)
void city_rotate_specialist(struct city *pcity, int citizen_index)
int get_citydlg_canvas_width(void)
bool canvas_to_city_pos(int *city_x, int *city_y, int city_radius_sq, int canvas_x, int canvas_y)
static bool base_city_queue_insert(struct city *pcity, int position, struct universal *item)
void activate_all_units(struct tile *ptile)
bool city_queue_clear(struct city *pcity)
static void city_sum_add_real(struct city_sum *sum, double value, bool suppress_if_zero, const char *auxfmt, double aux, char *posdesc, char *negdesc)
void get_city_dialog_airlift_value(const struct city *pcity, char *buf, size_t bufsz)
static int citydlg_map_height
bool city_to_canvas_pos(float *canvas_x, float *canvas_y, int city_x, int city_y, int city_radius_sq)
void generate_citydlg_dimensions(void)
static struct city_sum * city_sum_new(const char *format)
void city_get_queue(struct city *pcity, struct worklist *pqueue)
void city_dialog_redraw_map(struct city *pcity, struct canvas *pcanvas)
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
void get_city_dialog_pollution_text(const struct city *pcity, char *buf, size_t bufsz)
int city_change_specialist(struct city *pcity, Specialist_type_id from, Specialist_type_id to)
void get_city_dialog_culture_text(const struct city *pcity, char *buf, size_t bufsz)
bool city_can_buy(const struct city *pcity)
int get_citydlg_canvas_height(void)
static int citydlg_map_width
void get_city_dialog_illness_text(const struct city *pcity, char *buf, size_t bufsz)
void refresh_city_dialog(struct city *pcity)
struct civclient client
bool can_client_issue_orders(void)
#define client_player()
struct color * get_color(const struct tileset *t, enum color_std stdcolor)
char * incite_cost
Definition comments.c:76
void unit_focus_set(struct unit *punit)
Definition control.c:506
void request_new_unit_activity(struct unit *punit, enum unit_activity act)
Definition control.c:1929
int city_history_gain(const struct city *pcity)
Definition culture.c:39
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2956
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
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:74
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_city_bonus_effects(struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:1151
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Definition effects.c:1273
#define effect_list_iterate_end
Definition effects.h:81
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:79
int Impr_type_id
Definition fc_types.h:235
int Specialist_type_id
Definition fc_types.h:234
@ O_SHIELD
Definition fc_types.h:101
@ O_TRADE
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
@ O_LAST
Definition fc_types.h:101
enum output_type_id Output_type_id
Definition fc_types.h:237
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
struct city * game_city_by_number(int id)
Definition game.c:106
static const int bufsz
Definition helpdlg.c:70
bool great_wonder_is_built(const struct impr_type *pimprove)
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
bool wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
bool is_wonder(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)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
bool is_convert_improvement(const struct impr_type *pimprove)
bool is_small_wonder(const struct impr_type *pimprove)
int impr_estimate_build_shield_cost(const struct player *pplayer, const struct tile *ptile, const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
void map_to_gui_vector(const struct tileset *t, float zoom, float *gui_dx, float *gui_dy, int map_dx, int map_dy)
void put_one_element(struct canvas *pcanvas, float zoom, enum mapview_layer layer, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner, const struct unit *punit, const struct city *pcity, int canvas_x, int canvas_y, const struct city *citymode, const struct unit_type *putype)
#define H(x, y, z)
Definition md5.c:92
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_realloc(ptr, sz)
Definition mem.h:36
#define fc_malloc(sz)
Definition mem.h:34
struct client_options gui_options
Definition options.c:71
int dsend_packet_city_sell(struct connection *pc, int city_id, int build_id)
int dsend_packet_city_worklist(struct connection *pc, int city_id, const struct worklist *worklist)
int dsend_packet_city_make_specialist(struct connection *pc, int city_id, int tile_id)
int dsend_packet_city_change(struct connection *pc, int city_id, int production_kind, int production_value)
int dsend_packet_city_change_specialist(struct connection *pc, int city_id, Specialist_type_id from, Specialist_type_id to)
int dsend_packet_city_make_worker(struct connection *pc, int city_id, int tile_id)
int dsend_packet_city_rename(struct connection *pc, int city_id, const char *name)
int dsend_packet_city_buy(struct connection *pc, int city_id)
int player_multiplier_effect_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1975
int universal_build_shield_cost(const struct city *pcity, const struct universal *target)
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
int universal_number(const struct universal *source)
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
#define DIVIDE(n, d)
Definition shared.h:78
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
Specialist_type_id specialist_count(void)
Definition specialist.c:71
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
SPECPQ_PRIORITY_TYPE priority
Definition specpq.h:86
const char * auxfmt
char * posdesc
char * negdesc
const char * format
bool suppress_if_zero
struct city_sum::@133 * sums
Definition city.h:317
int bonus[O_LAST]
Definition city.h:360
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
bool concise_city_production
Definition options.h:164
struct player * playing
Definition connection.h:151
Definition climisc.h:82
enum airlifting_style airlifting_style
bool airlift_from_always_enabled
bool airlift_to_always_enabled
Definition tile.h:50
int index
Definition tile.h:51
struct unit_list * units
Definition tile.h:58
Definition unit.h:140
int id
Definition unit.h:147
struct unit::@84::@86 client
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:822
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:986
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:886
#define fc__attribute(x)
Definition support.h:99
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_worked(_tile)
Definition tile.h:115
struct unit * get_drawable_unit(const struct tileset *t, struct tile *ptile, const struct city *citymode)
Definition tilespec.c:6766
struct tileset * get_tileset(void)
Definition tilespec.c:718
struct tileset * unscaled_tileset
Definition tilespec.c:592
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:738
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:791
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:779
#define mapview_layer_iterate(layer)
Definition tilespec.h:177
#define mapview_layer_iterate_end
Definition tilespec.h:185
const char * goods_name_translation(struct goods_type *pgood)
#define trade_routes_iterate_end
#define trade_routes_iterate(c, proute)
const struct unit_type * utype
Definition fc_types.h:553
const struct impr_type * building
Definition fc_types.h:546
#define unit_owner(_pu)
Definition unit.h:403
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const char * utype_values_string(const struct unit_type *punittype)
Definition unittype.c:1602
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1444
void worklist_advance(struct worklist *pwl)
Definition worklist.c:104
bool worklist_peek(const struct worklist *pwl, struct universal *prod)
Definition worklist.c:76
void worklist_copy(struct worklist *dst, const struct worklist *src)
Definition worklist.c:112
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
bool worklist_peek_ith(const struct worklist *pwl, struct universal *prod, int idx)
Definition worklist.c:86
bool worklist_is_empty(const struct worklist *pwl)
Definition worklist.c:66
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Definition worklist.c:147
bool worklist_insert(struct worklist *pwl, const struct universal *prod, int idx)
Definition worklist.c:167
void worklist_remove(struct worklist *pwl, int idx)
Definition worklist.c:122
int worklist_length(const struct worklist *pwl)
Definition worklist.c:57
#define worklist_iterate_end
Definition worklist.h:59
#define worklist_iterate(_list, _p)
Definition worklist.h:51
#define MAX_LEN_WORKLIST
Definition worklist.h:24