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/**********************************************************************/
187void city_dialog_redraw_map(struct city *pcity,
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) {
205 citydlg_iterate(pcity, ptile, pedge, pcorner, canvas_x, canvas_y) {
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/**********************************************************************/
224char *city_production_cost_str(const struct city *pcity)
225{
226 static char cost_str[50];
228 int build_slots = city_build_slots(pcity);
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 if (city_production_has_flag(pcity, IF_GOLD)) {
283 int gold = MAX(0, pcity->surplus[O_SHIELD]);
284
285 fc_snprintf(buffer, buffer_len,
286 PL_("%3d gold per turn", "%3d gold per turn", gold),
287 gold);
288 } else {
289 fc_strlcpy(buffer, "---", buffer_len);
290 }
291 return;
292 }
293
294 turns = city_production_turns_to_build(pcity, TRUE);
295 stock = pcity->shield_stock;
297
298 if (turns < FC_INFINITY) {
300 fc_snprintf(time_str, sizeof(time_str), "%3d", turns);
301 } else {
303 PL_("%3d turn", "%3d turns", turns), turns);
304 }
305 } else {
306 fc_snprintf(time_str, sizeof(time_str), "%s",
307 gui_options.concise_city_production ? "-" : _("never"));
308 }
309
311 fc_snprintf(buffer, buffer_len, _("%3d/%s:%s"), stock, cost_str,
312 time_str);
313 } else {
314 fc_snprintf(buffer, buffer_len, _("%3d/%s %s"), stock, cost_str,
315 time_str);
316 }
317}
318
319/**********************************************************************/
330 struct universal *target,
331 struct city *pcity)
332{
333 int turns = city_turns_to_build(pcity, target, TRUE);
334 int cost = universal_build_shield_cost(pcity, target);
335
336 switch (target->kind) {
337 case VUT_IMPROVEMENT:
338 fc_strlcpy(buffer,
340 buffer_len);
341
343 fc_strlcat(buffer, " (--) ", buffer_len);
345 cat_snprintf(buffer, buffer_len, _("%d/turn"),
346 MAX(0, pcity->surplus[O_SHIELD]));
347 } else {
348 fc_strlcat(buffer, "---", buffer_len);
349 }
350 return;
351 }
352 break;
353 default:
354 universal_name_translation(target, buffer, buffer_len);
355 break;
356 };
357 cat_snprintf(buffer, buffer_len, " (%d) ", cost);
358
359 if (turns < FC_INFINITY) {
360 cat_snprintf(buffer, buffer_len,
361 PL_("%d turn", "%d turns", turns),
362 turns);
363 } else {
364 cat_snprintf(buffer, buffer_len, _("never"));
365 }
366}
367
368/**********************************************************************/
374 struct universal *target,
375 struct city *pcity)
376{
377 struct player *pplayer = pcity ? city_owner(pcity) : client_player();
378
380
381 switch (target->kind) {
382 case VUT_UTYPE:
383 {
384 const struct unit_type *ptype = target->value.utype;
385
387 fc_snprintf(buf[2], column_size, "(%d)",
388 utype_build_shield_cost(pcity, pplayer, ptype));
389 break;
390 }
391 case VUT_IMPROVEMENT:
392 {
393 const struct impr_type *pimprove = target->value.building;
394
395 /* Total & turns left meaningless on coinage-like improvements */
396 if (is_convert_improvement(pimprove)) {
397 buf[1][0] = '\0';
398 fc_snprintf(buf[2], column_size, "---");
399 } else {
400 int upkeep = pcity ? city_improvement_upkeep(pcity, pimprove)
401 : pimprove->upkeep;
402 /* From city.c city_improvement_name_translation() */
403 if (pcity && is_improvement_redundant(pcity, pimprove)) {
404 fc_snprintf(buf[1], column_size, "%d*", upkeep);
405 } else {
406 const char *state = NULL;
407
408 if (is_great_wonder(pimprove)) {
409 if (improvement_obsolete(pplayer, pimprove, pcity)) {
410 state = _("Obsolete");
411 } else if (great_wonder_is_built(pimprove)) {
412 state = _("Built");
413 } else if (great_wonder_is_destroyed(pimprove)) {
414 state = _("Destroyed");
415 } else {
416 state = _("Great Wonder");
417 }
418 } else if (is_small_wonder(pimprove)) {
419 if (improvement_obsolete(pplayer, pimprove, pcity)) {
420 state = _("Obsolete");
421 } else if (wonder_is_built(pplayer, target->value.building)) {
422 state = _("Built");
423 } else {
424 state = _("Small Wonder");
425 }
426 }
427 if (state) {
428 fc_strlcpy(buf[1], state, column_size);
429 } else {
430 fc_snprintf(buf[1], column_size, "%d", upkeep);
431 }
432 }
433
434 if (pcity != NULL) {
435 fc_snprintf(buf[2], column_size, "%d",
436 impr_build_shield_cost(pcity, pimprove));
437 } else {
438 fc_snprintf(buf[2], column_size, "%d",
439 impr_estimate_build_shield_cost(pplayer, NULL, pimprove));
440 }
441 }
442 break;
443 }
444 default:
445 buf[1][0] = '\0';
446 buf[2][0] = '\0';
447 break;
448 };
449
450 /* Add the turns-to-build entry in the 4th position */
451 if (pcity) {
452 if (VUT_IMPROVEMENT == target->kind
454 /* Coinage-like improvements: print yield-per-turn instead */
456 fc_snprintf(buf[3], column_size, _("%d/turn"),
457 MAX(0, pcity->surplus[O_SHIELD]));
458 } else {
459 buf[3][0] = '\0';
460 }
461 } else {
462 int turns = city_turns_to_build(pcity, target, FALSE);
463
464 if (turns < FC_INFINITY) {
465 fc_snprintf(buf[3], column_size, "%d", turns);
466 } else {
467 fc_snprintf(buf[3], column_size, _("never"));
468 }
469 }
470 } else {
471 fc_snprintf(buf[3], column_size, "---");
472 }
473}
474
475/**********************************************************************/
480struct city_sum {
481 const char *format;
482 size_t n;
483 struct {
484 /* The net value that is accumulated. */
485 double value;
486 /* Description; compared for duplicate-merging.
487 * Both of these are maintained/compared until the net 'value' is known;
488 * then posdesc is used if value>=0, negdesc if value<0 */
490 /* Whether posdesc is printed for total==0 */
492 /* An auxiliary value that is also accumulated, but not tested */
493 double aux;
494 /* ...and the format string for the net aux value (appended to *desc) */
495 const char *auxfmt;
497};
498
499/**********************************************************************/
505static struct city_sum *city_sum_new(const char *format)
506{
507 struct city_sum *sum = fc_malloc(sizeof(struct city_sum));
508
509 sum->format = format;
510 sum->n = 0;
511 sum->sums = NULL;
512
513 return sum;
514}
515
516/**********************************************************************/
521static void city_sum_add_real(struct city_sum *sum, double value,
522 bool suppress_if_zero,
523 const char *auxfmt,
524 double aux,
525 char *posdesc,
526 char *negdesc)
527{
528 size_t i;
529
530 /* Likely to lead to quadratic behaviour, but who cares: */
531 for (i = 0; i < sum->n; i++) {
532 fc_assert(sum->sums != NULL);
533 if ((strcmp(sum->sums[i].posdesc, posdesc) == 0)
534 && (strcmp(sum->sums[i].negdesc, negdesc) == 0)
535 && ((sum->sums[i].auxfmt == auxfmt)
536 || (auxfmt != NULL && !strcmp(sum->sums[i].auxfmt, auxfmt)))
538 /* Looks like we already have an entry like this. Accumulate values. */
539 sum->sums[i].value += value;
540 sum->sums[i].aux += aux;
543 return;
544 }
545 }
546
547 /* Didn't find description already, so add it to the end. */
548 sum->sums = fc_realloc(sum->sums, (sum->n + 1) * sizeof(sum->sums[0]));
549 sum->sums[sum->n].value = value;
550 sum->sums[sum->n].posdesc = posdesc;
551 sum->sums[sum->n].negdesc = negdesc;
553 sum->sums[sum->n].aux = aux;
554 sum->sums[sum->n].auxfmt = auxfmt;
555 sum->n++;
556}
557
558/**********************************************************************/
569static void
572 fc__attribute((nonnull (1, 6, 7)))
574 bool suppress_if_zero,
575 const char *auxfmt,
576 double aux,
577 const char *posfmt,
578 const char *negfmt,
579 ...)
580{
581 va_list args;
582 struct astring astr = ASTRING_INIT;
583 char *posdesc, *negdesc;
584
585 /* Format both descriptions */
586 va_start(args, negfmt); /* sic -- arguments follow negfmt */
587 astr_vadd(&astr, posfmt, args);
588 posdesc = astr_to_str(&astr);
589 va_end(args);
590 va_start(args, negfmt);
591 astr_vadd(&astr, negfmt, args);
592 negdesc = astr_to_str(&astr);
593 va_end(args);
594
595 city_sum_add_real(sum, value, suppress_if_zero, auxfmt, aux,
596 posdesc, negdesc);
597}
598
599/**********************************************************************/
606static void
608 fc__attribute((nonnull (1, 3)))
609 city_sum_add(struct city_sum *sum, double value,
610 const char *descfmt, ...)
611{
612 va_list args;
613 struct astring astr = ASTRING_INIT;
614 char *desc;
615
616 /* Format description (same used for positive or negative net value) */
617 va_start(args, descfmt);
618 astr_vadd(&astr, descfmt, args);
619 desc = astr_to_str(&astr);
620 va_end(args);
621
622 /* Descriptions will be freed individually, so need to fc_strdup() */
623 city_sum_add_real(sum, value, FALSE, NULL, 0, desc, fc_strdup(desc));
624}
625
626/**********************************************************************/
633static void
635 fc__attribute((nonnull (1, 3)))
636 city_sum_add_if_nonzero(struct city_sum *sum, double value,
637 const char *descfmt, ...)
638{
639 va_list args;
640 struct astring astr = ASTRING_INIT;
641 char *desc;
642
643 /* Format description (same used for positive or negative net value) */
644 va_start(args, descfmt);
645 astr_vadd(&astr, descfmt, args);
646 desc = astr_to_str(&astr);
647 va_end(args);
648
649 /* Descriptions will be freed individually, so need to fc_strdup() */
650 city_sum_add_real(sum, value, TRUE, NULL, 0, desc, fc_strdup(desc));
651}
652
653/**********************************************************************/
656static double city_sum_total(struct city_sum *sum)
657{
658 size_t i;
659 double total = 0;
660
661 for (i = 0; i < sum->n; i++) {
662 total += sum->sums[i].value;
663 }
664
665 return total;
666}
667
668/**********************************************************************/
674static inline int city_sum_compare(double val1, double val2)
675{
676 /* Fudgey epsilon -- probably the numbers we're dealing with have at
677 * most 1% or 0.1% real difference */
678 if (fabs(val1-val2) < 0.0000001) {
679 return 0;
680 }
681
682 return (val1 > val2 ? +1 : -1);
683}
684
685/**********************************************************************/
692static void
694 fc__attribute((nonnull (1, 2, 5)))
695 city_sum_print(struct city_sum *sum, char *buf, size_t bufsz,
697 const char *totalfmt, ...)
698{
699 va_list args;
700 size_t i;
701
702 /* This probably ought not to happen in well-designed rulesets, but it's
703 * possible for incomplete client knowledge to give an inaccurate
704 * breakdown. If it does happen, at least acknowledge to the user that
705 * we are confused, rather than displaying an incorrect sum. */
707 double total = city_sum_total(sum);
708 double actual_total;
709
710 va_start(args, totalfmt);
711 actual_total = va_arg(args, double);
712 va_end(args);
713
714 if (city_sum_compare(total, actual_total) != 0) {
715 city_sum_add(sum, actual_total - total,
716 /* TRANS: Client cannot explain some aspect of city
717 * output. Should never happen. */
718 Q_("?city_sum:(unknown)"));
719 }
720 }
721
722 for (i = 0; i < sum->n; i++) {
723 if (!sum->sums[i].suppress_if_zero
724 || city_sum_compare(sum->sums[i].value, 0) != 0) {
726 sum->format, sum->sums[i].value,
727 (sum->sums[i].value < 0) ? sum->sums[i].negdesc
728 : sum->sums[i].posdesc);
729 if (sum->sums[i].auxfmt) {
730 cat_snprintf(buf, bufsz, sum->sums[i].auxfmt, sum->sums[i].aux);
731 }
732 cat_snprintf(buf, bufsz, "\n");
733 }
734 FC_FREE(sum->sums[i].posdesc);
735 FC_FREE(sum->sums[i].negdesc);
736 }
737
738 va_start(args, totalfmt);
740 va_end(args);
741
742 FC_FREE(sum->sums);
743 FC_FREE(sum);
744}
745
746/**********************************************************************/
749void get_city_dialog_output_text(const struct city *pcity,
751 char *buf, size_t bufsz)
752{
753 int priority;
754 int tax[O_LAST];
755 struct output_type *output = &output_types[otype];
756 /* TRANS: format string for a row of the city output sum that adds up
757 * to "Total surplus" */
758 struct city_sum *sum = city_sum_new(Q_("?city_surplus:%+4.0f : %s"));
759
760 buf[0] = '\0';
761
762 city_sum_add(sum, pcity->citizen_base[otype],
763 Q_("?city_surplus:Citizens"));
764
765 /* Hack to get around the ugliness of add_tax_income(). */
766 memset(tax, 0, O_LAST * sizeof(*tax));
767 add_tax_income(city_owner(pcity), pcity->prod[O_TRADE], tax);
769 Q_("?city_surplus:Taxed from trade"));
770
771 /* Special cases for "bonus" production. See set_city_production() in
772 * city.c. */
773 if (otype == O_TRADE) {
775 /* NB: (proute->value == 0) is valid case. The trade route
776 * is established but doesn't give trade surplus. */
777 struct city *trade_city = game_city_by_number(proute->partner);
778 /* TRANS: Trade partner unknown to client */
779 const char *name
780 = trade_city ? city_name_get(trade_city) : _("(unknown)");
781 int value = proute->value
782 * (100 + get_city_bonus(pcity, EFT_TRADE_ROUTE_PCT)) / 100;
783
784 switch (proute->dir) {
786 city_sum_add(sum, value, Q_("?city_surplus:Trading %s with %s"),
788 name);
789 break;
790 case RDIR_FROM:
791 city_sum_add(sum, value, Q_("?city_surplus:Trading %s to %s"),
793 name);
794 break;
795 case RDIR_TO:
796 city_sum_add(sum, value, Q_("?city_surplus:Trading %s from %s"),
798 name);
799 break;
800 case RDIR_NONE:
801 fc_assert(proute->dir != RDIR_NONE);
802 break;
803 }
805 } else if (otype == O_GOLD) {
806 int tithes = get_city_tithes_bonus(pcity);
807
809 Q_("?city_surplus:Building tithes"));
810 }
811
812 for (priority = 0; priority < 3; priority++) {
813 enum effect_type eft[] = {EFT_OUTPUT_BONUS, EFT_OUTPUT_BONUS_2,
815
816 {
817 int base = city_sum_total(sum), bonus = 100;
819
820 (void) get_city_bonus_effects(plist, pcity, output, eft[priority]);
821
823 char buf2[512];
824 int delta;
825 int new_total;
826
828
829 if (peffect->multiplier) {
831 peffect->multiplier);
832
833 if (mul == 0) {
834 /* Suppress text when multiplier setting suppresses effect
835 * (this will also suppress it when the city owner's policy
836 * settings are not known to us) */
837 continue;
838 }
839 delta = (peffect->value * mul) / 100;
840 } else {
841 delta = peffect->value;
842 }
843
845 new_total = bonus * base / 100 + delta;
847 NULL, 0,
848 Q_("?city_surplus:Bonus from %s"),
849 Q_("?city_surplus:Loss from %s"), buf2);
850 } else {
851 bonus += delta;
852 new_total = bonus * base / 100;
854 /* TRANS: percentage city output bonus/loss from
855 * some source; preserve leading space */
856 Q_("?city_surplus: (%+.0f%%)"), delta,
857 Q_("?city_surplus:Bonus from %s"),
858 Q_("?city_surplus:Loss from %s"), buf2);
859 }
862 }
863 }
864
865 if (pcity->waste[otype] != 0) {
867 bool breakdown_ok;
868 int regular_waste;
869 /* FIXME: this will give the wrong answer in rulesets with waste on
870 * taxed outputs, such as 'science waste', as our total so far includes
871 * contributions taxed from trade, whereas the equivalent bit in
872 * set_city_production() does not */
873 if (city_waste(pcity, otype, city_sum_total(sum), wastetypes)
874 == pcity->waste[otype]) {
875 /* Our calculation matches the server's, so we trust our breakdown. */
877 Q_("?city_surplus:Size penalty"));
880 } else {
881 /* Our calculation doesn't match what the server sent. Account it all
882 * to corruption/waste. */
883 regular_waste = pcity->waste[otype];
885 }
886 if (regular_waste > 0) {
887 const char *fmt;
888 switch (otype) {
889 case O_SHIELD:
890 default: /* FIXME other output types? */
891 /* TRANS: %s is normally empty, but becomes '?' if client is
892 * uncertain about its accounting (should never happen) */
893 fmt = Q_("?city_surplus:Waste%s");
894 break;
895 case O_TRADE:
896 /* TRANS: %s is normally empty, but becomes '?' if client is
897 * uncertain about its accounting (should never happen) */
898 fmt = Q_("?city_surplus:Corruption%s");
899 break;
900 }
901 city_sum_add(sum, -regular_waste, fmt, breakdown_ok ? "" : "?");
902 }
903 }
904
906 Q_("?city_surplus:Disorder"));
907
908 if (pcity->usage[otype] > 0) {
909 city_sum_add(sum, -pcity->usage[otype],
910 Q_("?city_surplus:Used"));
911 }
912
914 Q_("?city_surplus:"
915 "==== : Adds up to\n"
916 "%4.0f : Total surplus"), (double) pcity->surplus[otype]);
917}
918
919/**********************************************************************/
922void get_city_dialog_illness_text(const struct city *pcity,
923 char *buf, size_t bufsz)
924{
926 struct effect_list *plist;
927 struct city_sum *sum;
928
929 buf[0] = '\0';
930
931 if (!game.info.illness_on) {
932 cat_snprintf(buf, bufsz, _("Illness deactivated in ruleset."));
933 return;
934 }
935
936 sum = city_sum_new(Q_("?city_plague:%+5.1f%% : %s"));
937
938 illness = city_illness_calc(pcity, &ill_base, &ill_size, &ill_trade,
940
941 city_sum_add(sum, (float)(ill_size) / 10.0,
942 Q_("?city_plague:Risk from overcrowding"));
943 city_sum_add(sum, (float)(ill_trade) / 10.0,
944 Q_("?city_plague:Risk from trade"));
945 city_sum_add(sum, (float)(ill_pollution) / 10.0,
946 Q_("?city_plague:Risk from pollution"));
947
949
951
953 char buf2[512];
954 int delta;
955
957
958 if (peffect->multiplier) {
960 peffect->multiplier);
961
962 if (mul == 0) {
963 /* Suppress text when multiplier setting suppresses effect
964 * (this will also suppress it when the city owner's policy
965 * settings are not known to us) */
966 continue;
967 }
968 delta = (peffect->value * mul) / 100;
969 } else {
970 delta = peffect->value;
971 }
972
973 city_sum_add_full(sum, -(0.1 * ill_base * delta / 100), TRUE,
974 Q_("?city_plague: (%+.0f%%)"), -delta,
975 Q_("?city_plague:Risk from %s"),
976 Q_("?city_plague:Bonus from %s"), buf2);
979
980 /* XXX: account_for_unknown==FALSE: the displayed sum can fail to
981 * add up due to rounding. Making it always add up probably requires
982 * arbitrary assignment of 0.1% rounding figures to particular
983 * effects with something like distribute(). */
985 Q_("?city_plague:"
986 "====== : Adds up to\n"
987 "%5.1f%% : Plague chance per turn"),
988 ((double)(illness) / 10.0));
989}
990
991/**********************************************************************/
994void get_city_dialog_pollution_text(const struct city *pcity,
995 char *buf, size_t bufsz)
996{
997 int pollu, prod, pop, mod;
998 struct city_sum *sum = city_sum_new(Q_("?city_pollution:%+4.0f : %s"));
999
1000 /* On the server, pollution is calculated before production is deducted
1001 * for disorder; we need to compensate for that */
1003 pcity->prod[O_SHIELD]
1004 + pcity->unhappy_penalty[O_SHIELD],
1005 &prod, &pop, &mod);
1006 buf[0] = '\0';
1007
1008 city_sum_add(sum, prod, Q_("?city_pollution:Pollution from shields"));
1009 city_sum_add(sum, pop, Q_("?city_pollution:Pollution from citizens"));
1010 city_sum_add(sum, mod, Q_("?city_pollution:Pollution modifier"));
1012 Q_("?city_pollution:"
1013 "==== : Adds up to\n"
1014 "%4.0f : Total surplus"), (double)pollu);
1015}
1016
1017/**********************************************************************/
1020void get_city_dialog_culture_text(const struct city *pcity,
1021 char *buf, size_t bufsz)
1022{
1023 struct effect_list *plist;
1024 struct city_sum *sum = city_sum_new(Q_("?city_culture:%4.0f : %s"));
1025
1026 buf[0] = '\0';
1027
1028 /* XXX: no way to check whether client's idea of gain/turn is accurate */
1029 city_sum_add(sum, pcity->history, Q_("?city_culture:History (%+d/turn)"),
1030 city_history_gain(pcity));
1031
1033
1035
1037 char buf2[512];
1038 int mul = 100;
1039 int value;
1040
1042
1043 if (peffect->multiplier) {
1045 peffect->multiplier);
1046
1047 if (mul == 0) {
1048 /* Suppress text when multiplier setting suppresses effect
1049 * (this will also suppress it when the city owner's policy
1050 * settings are not known to us) */
1051 continue;
1052 }
1053 }
1054
1055 value = (peffect->value * mul) / 100;
1056 /* TRANS: Text describing source of culture bonus ("Library+Republic") */
1057 city_sum_add_if_nonzero(sum, value, Q_("?city_culture:%s"), buf2);
1060
1062 Q_("?city_culture:"
1063 "==== : Adds up to\n"
1064 "%4.0f : Total culture"), (double)pcity->client.culture);
1065}
1066
1067/**********************************************************************/
1070void get_city_dialog_airlift_text(const struct city *pcity,
1071 char *buf, size_t bufsz)
1072{
1073 char src[512];
1074 char dest[512];
1075 int unlimited = 0;
1076
1078 && (pcity->airlift >= 1 || game.info.airlift_from_always_enabled)) {
1079
1080 unlimited++;
1081
1082 /* TRANS: airlift. Possible take offs text. String is a
1083 * proviso that take offs can't occur if landings spend all the
1084 * remaining airlift when landings are limited and empty when they
1085 * aren't limited. */
1086 fc_snprintf(src, sizeof(src), _("unlimited take offs%s"),
1088 /* TRANS: Airlift unlimited take offs proviso used above.
1089 * Plural based on remaining airlift capacity. */
1090 ? "" : PL_(" (until the landing has been spent)",
1091 " (until all landings have been spent)",
1092 pcity->airlift));
1093 } else {
1094 fc_snprintf(src, sizeof(src),
1095 /* TRANS: Airlift. Possible take offs text. Number is
1096 * airlift capacity. */
1097 PL_("%d take off", "%d take offs", pcity->airlift),
1098 pcity->airlift);
1099 }
1100
1102 && (pcity->airlift >= 1 || game.info.airlift_to_always_enabled)){
1103
1104 unlimited++;
1105
1106 /* TRANS: Airlift. Possible landings text. */
1107 fc_snprintf(dest, sizeof(dest), _("unlimited landings"));
1108 } else {
1109 fc_snprintf(dest, sizeof(dest),
1110 /* TRANS: Airlift. Possible landings text.
1111 * Number is airlift capacity. */
1112 PL_("%d landing", "%d landings", pcity->airlift),
1113 pcity->airlift);
1114 }
1115
1116 switch (unlimited) {
1117 case 2:
1118 /* TRANS: Airlift take offs and landings */
1119 fc_snprintf(buf, bufsz, _("unlimited take offs and landings"));
1120 break;
1121 case 1:
1122 /* TRANS: Airlift take offs and landings. One is unlimited. The first
1123 * string is the take offs text. The 2nd string is the landings text. */
1124 fc_snprintf(buf, bufsz, _("%s and %s"), src, dest);
1125 break;
1126 default:
1128 /* TRANS: Airlift take offs or landings, no unlimited.
1129 * Number is airlift capacity. */
1130 PL_("%d take off or landing", "%d take offs or landings",
1131 pcity->airlift),
1132 pcity->airlift);
1133 break;
1134 }
1135}
1136
1137/**********************************************************************/
1140void get_city_dialog_airlift_value(const struct city *pcity,
1141 char *buf, size_t bufsz)
1142{
1143 char src[512];
1144 char dest[512];
1145 int unlimited = 0;
1146
1148 && (pcity->airlift >= 1 || game.info.airlift_from_always_enabled)) {
1149
1150 unlimited++;
1151
1152 /* TRANS: Airlift. Possible take offs text. String is a symbol that
1153 * indicates that terms and conditions apply when landings are limited
1154 * and empty when they aren't limited. */
1155 fc_snprintf(src, sizeof(src), _(" ∞%s"),
1157 /* TRANS: airlift unlimited take offs may be spent symbol
1158 * used above. */
1159 ? "" : Q_("?landings:*"));
1160 } else {
1161 /* TRANS: Airlift. Possible take offs text. Number is
1162 * airlift capacity. */
1163 fc_snprintf(src, sizeof(src), Q_("?takeoffs:%4d"), pcity->airlift);
1164 }
1165
1167 && (pcity->airlift >= 1 || game.info.airlift_to_always_enabled)){
1168
1169 unlimited++;
1170
1171 /* TRANS: Airlift. Possible landings text. */
1172 fc_snprintf(dest, sizeof(dest), _(" ∞"));
1173 } else {
1174 /* TRANS: Airlift. Possible landings text. */
1175 fc_snprintf(dest, sizeof(dest), Q_("?landings:%4d"), pcity->airlift);
1176 }
1177
1178 switch (unlimited) {
1179 case 2:
1180 /* TRANS: Unlimited airlift take offs and landings */
1181 fc_snprintf(buf, bufsz, _(" ∞"));
1182 break;
1183 case 1:
1184 /* TRANS: Airlift take offs and landings. One is unlimited. The first
1185 * string is the take offs text. The 2nd string is the landings text.
1186 * For English, initials of d)epartures and a)rrivals were chosen. */
1187 fc_snprintf(buf, bufsz, _("d: %s a: %s"), src, dest);
1188 break;
1189 default:
1190 /* TRANS: Airlift take offs or landings, no unlimited */
1191 fc_snprintf(buf, bufsz, Q_("?airlifts:%s"), src);
1192 break;
1193 }
1194}
1195
1196/**********************************************************************/
1202int get_city_citizen_types(struct city *pcity, enum citizen_feeling idx,
1203 enum citizen_category *categories)
1204{
1205 int i = 0, n;
1206
1207 fc_assert(idx >= 0 && idx < FEELING_LAST);
1208
1209 for (n = 0; n < pcity->feel[CITIZEN_HAPPY][idx]; n++, i++) {
1210 categories[i] = CITIZEN_HAPPY;
1211 }
1212 for (n = 0; n < pcity->feel[CITIZEN_CONTENT][idx]; n++, i++) {
1213 categories[i] = CITIZEN_CONTENT;
1214 }
1215 for (n = 0; n < pcity->feel[CITIZEN_UNHAPPY][idx]; n++, i++) {
1216 categories[i] = CITIZEN_UNHAPPY;
1217 }
1218 for (n = 0; n < pcity->feel[CITIZEN_ANGRY][idx]; n++, i++) {
1219 categories[i] = CITIZEN_ANGRY;
1220 }
1221
1223 for (n = 0; n < pcity->specialists[sp]; n++, i++) {
1224 categories[i] = CITIZEN_SPECIALIST + sp;
1225 }
1227
1228 if (city_size_get(pcity) != i) {
1229 log_error("get_city_citizen_types() %d citizens "
1230 "not equal %d city size in \"%s\".",
1231 i, city_size_get(pcity), city_name_get(pcity));
1232 }
1233
1234 return i;
1235}
1236
1237/**********************************************************************/
1241{
1242 enum citizen_category categories[MAX_CITY_SIZE];
1243 Specialist_type_id from, to;
1244 int num_citizens = get_city_citizen_types(pcity, FEELING_FINAL, categories);
1245
1247 || categories[citizen_index] < CITIZEN_SPECIALIST) {
1248 return;
1249 }
1250 from = categories[citizen_index] - CITIZEN_SPECIALIST;
1251
1252 /* Loop through all specialists in order until we find a usable one
1253 * (or run out of choices). */
1254 to = from;
1255 fc_assert(to >= 0 && to < specialist_count());
1256 do {
1257 to = (to + 1) % specialist_count();
1258 } while (to != from && !city_can_use_specialist(pcity, to));
1259
1260 if (from != to) {
1261 city_change_specialist(pcity, from, to);
1262 }
1263}
1264
1265/**********************************************************************/
1268void activate_all_units(struct tile *ptile)
1269{
1270 struct unit_list *punit_list = ptile->units;
1271 struct unit *pmyunit = NULL;
1272
1275 /* Activate this unit. */
1276 pmyunit = punit;
1278 }
1280 if (pmyunit) {
1281 /* Put the focus on one of the activated units. */
1283 }
1284}
1285
1286/**********************************************************************/
1289int city_change_production(struct city *pcity, struct universal *target)
1290{
1291 return dsend_packet_city_change(&client.conn, pcity->id,
1292 target->kind,
1293 universal_number(target));
1294}
1295
1296/**********************************************************************/
1301int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
1302{
1304}
1305
1306/**********************************************************************/
1309void city_worklist_commit(struct city *pcity, struct worklist *pwl)
1310{
1311 int k;
1312
1313 /* Update the worklist. Remember, though -- the current build
1314 target really isn't in the worklist; don't send it to the server
1315 as part of the worklist. Of course, we have to search through
1316 the current worklist to find the first _now_available_ build
1317 target (to cope with players who try mean things like adding a
1318 Battleship to a city worklist when the player doesn't even yet
1319 have the Map Making tech). */
1320
1321 for (k = 0; k < MAX_LEN_WORKLIST; k++) {
1323 struct universal target;
1324
1325 if (!worklist_peek_ith(pwl, &target, k)) {
1326 break;
1327 }
1328
1330
1331 /* Very special case: If we are currently building a wonder we
1332 allow the construction to continue, even if we the wonder is
1333 finished elsewhere, i.e., unbuildable. */
1334 if (k == 0
1335 && VUT_IMPROVEMENT == target.kind
1336 && is_wonder(target.value.building)
1338 worklist_remove(pwl, k);
1339 break;
1340 }
1341
1342 /* If it can be built... */
1343 if (can_city_build_now(pcity, &target)) {
1344 /* ...but we're not yet building it, then switch. */
1345 if (!same_as_current_build) {
1346 /* Change the current target */
1347 city_change_production(pcity, &target);
1348 }
1349
1350 /* This item is now (and may have always been) the current
1351 build target. Drop it out of the worklist. */
1352 worklist_remove(pwl, k);
1353 break;
1354 }
1355 }
1356
1357 /* Send the rest of the worklist on its way. */
1358 city_set_worklist(pcity, pwl);
1359}
1360
1361/**********************************************************************/
1369static bool base_city_queue_insert(struct city *pcity, int position,
1370 struct universal *item)
1371{
1372 if (position == 0) {
1373 struct universal old = pcity->production;
1374
1375 /* Insert as current production. */
1376 if (!can_city_build_direct(pcity, item)) {
1377 return FALSE;
1378 }
1379
1380 if (!worklist_insert(&pcity->worklist, &old, 0)) {
1381 return FALSE;
1382 }
1383
1385 } else if (position >= 1
1386 && position <= worklist_length(&pcity->worklist)) {
1387 /* Insert into middle. */
1388 if (!can_city_build_later(pcity, item)) {
1389 return FALSE;
1390 }
1391 if (!worklist_insert(&pcity->worklist, item, position - 1)) {
1392 return FALSE;
1393 }
1394 } else {
1395 /* Insert at end. */
1396 if (!can_city_build_later(pcity, item)) {
1397 return FALSE;
1398 }
1399 if (!worklist_append(&pcity->worklist, item)) {
1400 return FALSE;
1401 }
1402 }
1403 return TRUE;
1404}
1405
1406/**********************************************************************/
1411bool city_queue_insert(struct city *pcity, int position,
1412 struct universal *item)
1413{
1414 if (base_city_queue_insert(pcity, position, item)) {
1415 city_set_worklist(pcity, &pcity->worklist);
1416 return TRUE;
1417 }
1418 return FALSE;
1419}
1420
1421/**********************************************************************/
1427bool city_queue_clear(struct city *pcity)
1428{
1429 worklist_init(&pcity->worklist);
1430
1431 return TRUE;
1432}
1433
1434/**********************************************************************/
1439bool city_queue_insert_worklist(struct city *pcity, int position,
1440 const struct worklist *worklist)
1441{
1442 bool success = FALSE;
1443
1444 if (worklist_length(worklist) == 0) {
1445 return TRUE;
1446 }
1447
1448 worklist_iterate(worklist, target) {
1449 if (base_city_queue_insert(pcity, position, &target)) {
1450 if (position > 0) {
1451 /* Move to the next position (unless position == -1 in which case
1452 * we're appending. */
1453 position++;
1454 }
1455 success = TRUE;
1456 }
1458
1459 if (success) {
1460 city_set_worklist(pcity, &pcity->worklist);
1461 }
1462
1463 return success;
1464}
1465
1466/**********************************************************************/
1469void city_get_queue(struct city *pcity, struct worklist *pqueue)
1470{
1471 worklist_copy(pqueue, &pcity->worklist);
1472
1473 /* The GUI wants current production to be in the task list, but the
1474 worklist API wants it out for reasons unknown. Perhaps someone enjoyed
1475 making things more complicated than necessary? So I dance around it. */
1476
1477 /* We want the current production to be in the queue. Always. */
1479
1480 worklist_insert(pqueue, &pcity->production, 0);
1481}
1482
1483/**********************************************************************/
1486bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
1487{
1488 struct worklist copy;
1489 struct universal target;
1490
1491 worklist_copy(&copy, pqueue);
1492
1493 /* The GUI wants current production to be in the task list, but the
1494 worklist API wants it out for reasons unknown. Perhaps someone enjoyed
1495 making things more complicated than necessary? So I dance around it. */
1496 if (worklist_peek(&copy, &target)) {
1497
1498 if (!city_can_change_build(pcity)
1499 && !are_universals_equal(&pcity->production, &target)) {
1500 /* We cannot change production to one from worklist.
1501 * Do not replace old worklist with new one. */
1502 return FALSE;
1503 }
1504
1505 worklist_advance(&copy);
1506
1507 city_set_worklist(pcity, &copy);
1508 city_change_production(pcity, &target);
1509 } else {
1510 /* You naughty boy, you can't erase the current production. Nyah! */
1511 if (worklist_is_empty(&pcity->worklist)) {
1512 refresh_city_dialog(pcity);
1513 } else {
1514 city_set_worklist(pcity, &copy);
1515 }
1516 }
1517
1518 return TRUE;
1519}
1520
1521/**********************************************************************/
1524bool city_can_buy(const struct city *pcity)
1525{
1526 /* See really_handle_city_buy() in the server. However this function
1527 * doesn't allow for error messages. It doesn't check the cost of
1528 * buying; that's handled separately (and with an error message). */
1529 return (can_client_issue_orders()
1530 && NULL != pcity
1531 && city_owner(pcity) == client.conn.playing
1532 && pcity->turn_founded != game.info.turn
1533 && !pcity->did_buy
1534 && (VUT_UTYPE == pcity->production.kind
1536 && !(VUT_UTYPE == pcity->production.kind
1537 && pcity->anarchy != 0)
1538 && pcity->client.buy_cost > 0);
1539}
1540
1541/**********************************************************************/
1544int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
1545{
1546 return dsend_packet_city_sell(&client.conn, pcity->id, sell_id);
1547}
1548
1549/**********************************************************************/
1552int city_buy_production(struct city *pcity)
1553{
1554 return dsend_packet_city_buy(&client.conn, pcity->id);
1555}
1556
1557/**********************************************************************/
1562{
1563 return dsend_packet_city_change_specialist(&client.conn, pcity->id, from,
1564 to);
1565}
1566
1567/**********************************************************************/
1571int city_toggle_worker(struct city *pcity, int city_x, int city_y)
1572{
1573 int city_radius_sq;
1574 struct tile *ptile;
1575
1576 if (city_owner(pcity) != client_player()) {
1577 return 0;
1578 }
1579
1580 city_radius_sq = city_map_radius_sq_get(pcity);
1581 fc_assert(is_valid_city_coords(city_radius_sq, city_x, city_y));
1582 ptile = city_map_to_tile(&(wld.map), city_tile(pcity), city_radius_sq,
1583 city_x, city_y);
1584 if (NULL == ptile) {
1585 return 0;
1586 }
1587
1588 if (NULL != tile_worked(ptile) && tile_worked(ptile) == pcity) {
1590 pcity->id, ptile->index);
1591 } else if (city_can_work_tile(pcity, ptile)) {
1593 pcity->id, ptile->index);
1594 } else {
1595 return 0;
1596 }
1597}
1598
1599/**********************************************************************/
1602int city_rename(struct city *pcity, const char *name)
1603{
1604 return dsend_packet_city_rename(&client.conn, pcity->id, name);
1605}
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:1961
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:2784
bool can_city_build_now(const struct city *pcity, const struct universal *target)
Definition city.c:1011
int city_waste(const struct city *pcity, Output_type_id otype, int total, int *breakdown)
Definition city.c:3224
int city_build_slots(const struct city *pcity)
Definition city.c:2929
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:1133
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1251
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Definition city.c:1061
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:2242
int get_city_tithes_bonus(const struct city *pcity)
Definition city.c:2224
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:2867
bool is_valid_city_coords(const int city_radius_sq, const int city_map_x, const int city_map_y)
Definition city.c:188
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
bool can_city_build_direct(const struct city *pcity, const struct universal *target)
Definition city.c:993
int rs_max_city_radius_sq(void)
Definition city.c:159
bool can_city_build_later(const struct city *pcity, const struct universal *target)
Definition city.c:1028
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1452
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:1075
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
citizen_category
Definition city.h:267
@ CITIZEN_SPECIALIST
Definition city.h:273
@ CITIZEN_ANGRY
Definition city.h:271
@ CITIZEN_HAPPY
Definition city.h:268
@ CITIZEN_CONTENT
Definition city.h:269
@ CITIZEN_UNHAPPY
Definition city.h:270
#define CITY_REL2ABS(_coor)
Definition city.h:115
#define city_owner(_pcity_)
Definition city.h:563
#define MAX_CITY_SIZE
Definition city.h:106
citizen_feeling
Definition city.h:278
@ FEELING_FINAL
Definition city.h:284
@ FEELING_LAST
Definition city.h:285
@ OLOSS_SIZE
Definition city.h:291
@ OLOSS_WASTE
Definition city.h:290
@ OLOSS_LAST
Definition city.h:292
#define city_map_iterate_without_index_end
Definition city.h:184
#define CITY_ABS2REL(_coor)
Definition city.h:116
#define city_map_iterate_without_index(_radius_sq, _x, _y)
Definition city.h:180
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:74
void unit_focus_set(struct unit *punit)
Definition control.c:501
void request_new_unit_activity(struct unit *punit, enum unit_activity act)
Definition control.c:1903
int city_history_gain(const struct city *pcity)
Definition culture.c:39
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2938
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 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:380
int Specialist_type_id
Definition fc_types.h:379
@ 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:382
#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:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define log_error(message,...)
Definition log.h:103
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
struct city_sum::@129 * sums
const char * auxfmt
char * posdesc
char * negdesc
const char * format
bool suppress_if_zero
Definition city.h:320
int surplus[O_LAST]
Definition city.h:355
int history
Definition city.h:410
int id
Definition city.h:326
int waste[O_LAST]
Definition city.h:356
int turn_founded
Definition city.h:386
int airlift
Definition city.h:378
int citizen_base[O_LAST]
Definition city.h:359
bool did_buy
Definition city.h:379
int anarchy
Definition city.h:384
int usage[O_LAST]
Definition city.h:360
struct worklist worklist
Definition city.h:401
struct universal production
Definition city.h:396
int bonus[O_LAST]
Definition city.h:363
int unhappy_penalty[O_LAST]
Definition city.h:357
int culture
Definition city.h:465
int buy_cost
Definition city.h:466
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:333
citizens specialists[SP_MAX]
Definition city.h:336
int shield_stock
Definition city.h:368
int prod[O_LAST]
Definition city.h:358
struct city::@17::@20 client
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:80
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
enum universals_n kind
Definition fc_types.h:880
universals_u value
Definition fc_types.h:879
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:6603
struct tileset * get_tileset(void)
Definition tilespec.c:693
struct tileset * unscaled_tileset
Definition tilespec.c:569
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:713
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:766
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:754
#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:698
const struct impr_type * building
Definition fc_types.h:691
#define unit_owner(_pu)
Definition unit.h:396
#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:1596
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1438
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