Freeciv-3.2
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
320/**********************************************************************/
331 struct universal *target,
332 struct city *pcity)
333{
334 int turns = city_turns_to_build(pcity, target, TRUE);
335 int cost = universal_build_shield_cost(pcity, target);
336
337 switch (target->kind) {
338 case VUT_IMPROVEMENT:
339 fc_strlcpy(buffer,
341 buffer_len);
342
344 fc_strlcat(buffer, " (--) ", buffer_len);
346 cat_snprintf(buffer, buffer_len, _("%d/turn"),
347 MAX(0, pcity->surplus[O_SHIELD]));
348 } else {
349 fc_strlcat(buffer, "---", buffer_len);
350 }
351 return;
352 }
353 break;
354 default:
355 universal_name_translation(target, buffer, buffer_len);
356 break;
357 };
358 cat_snprintf(buffer, buffer_len, " (%d) ", cost);
359
360 if (turns < FC_INFINITY) {
361 cat_snprintf(buffer, buffer_len,
362 PL_("%d turn", "%d turns", turns),
363 turns);
364 } else {
365 cat_snprintf(buffer, buffer_len, _("never"));
366 }
367}
368
369/**********************************************************************/
375 struct universal *target,
376 struct city *pcity)
377{
378 struct player *pplayer = pcity ? city_owner(pcity) : client_player();
379
381
382 switch (target->kind) {
383 case VUT_UTYPE:
384 {
385 const struct unit_type *ptype = target->value.utype;
386
388 fc_snprintf(buf[2], column_size, "(%d)",
389 utype_build_shield_cost(pcity, pplayer, ptype));
390 break;
391 }
392 case VUT_IMPROVEMENT:
393 {
394 const struct impr_type *pimprove = target->value.building;
395
396 /* Total & turns left meaningless on coinage-like improvements */
397 if (is_convert_improvement(pimprove)) {
398 buf[1][0] = '\0';
399 fc_snprintf(buf[2], column_size, "---");
400 } else {
401 int upkeep = pcity ? city_improvement_upkeep(pcity, pimprove)
402 : pimprove->upkeep;
403 /* from city.c city_improvement_name_translation() */
404 if (pcity && is_improvement_redundant(pcity, pimprove)) {
405 fc_snprintf(buf[1], column_size, "%d*", upkeep);
406 } else {
407 const char *state = NULL;
408
409 if (is_great_wonder(pimprove)) {
410 if (improvement_obsolete(pplayer, pimprove, pcity)) {
411 state = _("Obsolete");
412 } else if (great_wonder_is_built(pimprove)) {
413 state = _("Built");
414 } else if (great_wonder_is_destroyed(pimprove)) {
415 state = _("Destroyed");
416 } else {
417 state = _("Great Wonder");
418 }
419 } else if (is_small_wonder(pimprove)) {
420 if (improvement_obsolete(pplayer, pimprove, pcity)) {
421 state = _("Obsolete");
422 } else if (wonder_is_built(pplayer, target->value.building)) {
423 state = _("Built");
424 } else {
425 state = _("Small Wonder");
426 }
427 }
428 if (state) {
429 fc_strlcpy(buf[1], state, column_size);
430 } else {
431 fc_snprintf(buf[1], column_size, "%d", upkeep);
432 }
433 }
434
435 if (pcity != NULL) {
436 fc_snprintf(buf[2], column_size, "%d",
437 impr_build_shield_cost(pcity, pimprove));
438 } else {
439 fc_snprintf(buf[2], column_size, "%d",
440 impr_estimate_build_shield_cost(pplayer, NULL, pimprove));
441 }
442 }
443 break;
444 }
445 default:
446 buf[1][0] = '\0';
447 buf[2][0] = '\0';
448 break;
449 };
450
451 /* Add the turns-to-build entry in the 4th position */
452 if (pcity) {
453 if (VUT_IMPROVEMENT == target->kind
455 /* Coinage-like improvements: print yield-per-turn instead */
457 fc_snprintf(buf[3], column_size, _("%d/turn"),
458 MAX(0, pcity->surplus[O_SHIELD]));
459 } else {
460 buf[3][0] = '\0';
461 }
462 } else {
463 int turns = city_turns_to_build(pcity, target, FALSE);
464
465 if (turns < FC_INFINITY) {
466 fc_snprintf(buf[3], column_size, "%d", turns);
467 } else {
468 fc_snprintf(buf[3], column_size, _("never"));
469 }
470 }
471 } else {
472 fc_snprintf(buf[3], column_size, "---");
473 }
474}
475
476/**********************************************************************/
481struct city_sum {
482 const char *format;
483 size_t n;
484 struct {
485 /* The net value that is accumulated. */
486 double value;
487 /* Description; compared for duplicate-merging.
488 * Both of these are maintained/compared until the net 'value' is known;
489 * then posdesc is used if value>=0, negdesc if value<0 */
491 /* Whether posdesc is printed for total==0 */
493 /* An auxiliary value that is also accumulated, but not tested */
494 double aux;
495 /* ...and the format string for the net aux value (appended to *desc) */
496 const char *auxfmt;
498};
499
500/**********************************************************************/
506static struct city_sum *city_sum_new(const char *format)
507{
508 struct city_sum *sum = fc_malloc(sizeof(struct city_sum));
509
510 sum->format = format;
511 sum->n = 0;
512 sum->sums = NULL;
513
514 return sum;
515}
516
517/**********************************************************************/
522static void city_sum_add_real(struct city_sum *sum, double value,
523 bool suppress_if_zero,
524 const char *auxfmt,
525 double aux,
526 char *posdesc,
527 char *negdesc)
528{
529 size_t i;
530
531 /* Likely to lead to quadratic behaviour, but who cares: */
532 for (i = 0; i < sum->n; i++) {
533 fc_assert(sum->sums != NULL);
534 if ((strcmp(sum->sums[i].posdesc, posdesc) == 0)
535 && (strcmp(sum->sums[i].negdesc, negdesc) == 0)
536 && ((sum->sums[i].auxfmt == auxfmt)
537 || (auxfmt != NULL && !strcmp(sum->sums[i].auxfmt, auxfmt)))
539 /* Looks like we already have an entry like this. Accumulate values. */
540 sum->sums[i].value += value;
541 sum->sums[i].aux += aux;
544 return;
545 }
546 }
547
548 /* Didn't find description already, so add it to the end. */
549 sum->sums = fc_realloc(sum->sums, (sum->n + 1) * sizeof(sum->sums[0]));
550 sum->sums[sum->n].value = value;
551 sum->sums[sum->n].posdesc = posdesc;
552 sum->sums[sum->n].negdesc = negdesc;
554 sum->sums[sum->n].aux = aux;
555 sum->sums[sum->n].auxfmt = auxfmt;
556 sum->n++;
557}
558
559/**********************************************************************/
570static void
573 fc__attribute((nonnull (1, 6, 7)))
575 bool suppress_if_zero,
576 const char *auxfmt,
577 double aux,
578 const char *posfmt,
579 const char *negfmt,
580 ...)
581{
582 va_list args;
583 struct astring astr = ASTRING_INIT;
584 char *posdesc, *negdesc;
585
586 /* Format both descriptions */
587 va_start(args, negfmt); /* sic -- arguments follow negfmt */
588 astr_vadd(&astr, posfmt, args);
589 posdesc = astr_to_str(&astr);
590 va_end(args);
591 va_start(args, negfmt);
592 astr_vadd(&astr, negfmt, args);
593 negdesc = astr_to_str(&astr);
594 va_end(args);
595
596 city_sum_add_real(sum, value, suppress_if_zero, auxfmt, aux,
597 posdesc, negdesc);
598}
599
600/**********************************************************************/
607static void
609 fc__attribute((nonnull (1, 3)))
610 city_sum_add(struct city_sum *sum, double value,
611 const char *descfmt, ...)
612{
613 va_list args;
614 struct astring astr = ASTRING_INIT;
615 char *desc;
616
617 /* Format description (same used for positive or negative net value) */
618 va_start(args, descfmt);
619 astr_vadd(&astr, descfmt, args);
620 desc = astr_to_str(&astr);
621 va_end(args);
622
623 /* Descriptions will be freed individually, so need to strdup */
624 city_sum_add_real(sum, value, FALSE, NULL, 0, desc, fc_strdup(desc));
625}
626
627/**********************************************************************/
634static void
636 fc__attribute((nonnull (1, 3)))
637 city_sum_add_if_nonzero(struct city_sum *sum, double value,
638 const char *descfmt, ...)
639{
640 va_list args;
641 struct astring astr = ASTRING_INIT;
642 char *desc;
643
644 /* Format description (same used for positive or negative net value) */
645 va_start(args, descfmt);
646 astr_vadd(&astr, descfmt, args);
647 desc = astr_to_str(&astr);
648 va_end(args);
649
650 /* Descriptions will be freed individually, so need to strdup */
651 city_sum_add_real(sum, value, TRUE, NULL, 0, desc, fc_strdup(desc));
652}
653
654/**********************************************************************/
657static double city_sum_total(struct city_sum *sum)
658{
659 size_t i;
660 double total = 0;
661
662 for (i = 0; i < sum->n; i++) {
663 total += sum->sums[i].value;
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 return (val1 > val2 ? +1 : -1);
682}
683
684/**********************************************************************/
691static void
693 fc__attribute((nonnull (1, 2, 5)))
694 city_sum_print(struct city_sum *sum, char *buf, size_t bufsz,
696 const char *totalfmt, ...)
697{
698 va_list args;
699 size_t i;
700
701 /* This probably ought not to happen in well-designed rulesets, but it's
702 * possible for incomplete client knowledge to give an inaccurate
703 * breakdown. If it does happen, at least acknowledge to the user that
704 * we are confused, rather than displaying an incorrect sum. */
706 double total = city_sum_total(sum);
707 double actual_total;
708
709 va_start(args, totalfmt);
710 actual_total = va_arg(args, double);
711 va_end(args);
712
713 if (city_sum_compare(total, actual_total) != 0) {
714 city_sum_add(sum, actual_total - total,
715 /* TRANS: Client cannot explain some aspect of city
716 * output. Should never happen. */
717 Q_("?city_sum:(unknown)"));
718 }
719 }
720
721 for (i = 0; i < sum->n; i++) {
722 if (!sum->sums[i].suppress_if_zero
723 || city_sum_compare(sum->sums[i].value, 0) != 0) {
725 sum->format, sum->sums[i].value,
726 (sum->sums[i].value < 0) ? sum->sums[i].negdesc
727 : sum->sums[i].posdesc);
728 if (sum->sums[i].auxfmt) {
729 cat_snprintf(buf, bufsz, sum->sums[i].auxfmt, sum->sums[i].aux);
730 }
731 cat_snprintf(buf, bufsz, "\n");
732 }
733 FC_FREE(sum->sums[i].posdesc);
734 FC_FREE(sum->sums[i].negdesc);
735 }
736
737 va_start(args, totalfmt);
739 va_end(args);
740
741 FC_FREE(sum->sums);
742 FC_FREE(sum);
743}
744
745/**********************************************************************/
748void get_city_dialog_output_text(const struct city *pcity,
750 char *buf, size_t bufsz)
751{
752 int priority;
753 int tax[O_LAST];
754 struct output_type *output = &output_types[otype];
755 /* TRANS: format string for a row of the city output sum that adds up
756 * to "Total surplus" */
757 struct city_sum *sum = city_sum_new(Q_("?city_surplus:%+4.0f : %s"));
758
759 buf[0] = '\0';
760
761 city_sum_add(sum, pcity->citizen_base[otype],
762 Q_("?city_surplus:Citizens"));
763
764 /* Hack to get around the ugliness of add_tax_income. */
765 memset(tax, 0, O_LAST * sizeof(*tax));
766 add_tax_income(city_owner(pcity), pcity->prod[O_TRADE], tax);
768 Q_("?city_surplus:Taxed from trade"));
769
770 /* Special cases for "bonus" production. See set_city_production in
771 * city.c. */
772 if (otype == O_TRADE) {
774 /* NB: (proute->value == 0) is valid case. The trade route
775 * is established but doesn't give trade surplus. */
776 struct city *trade_city = game_city_by_number(proute->partner);
777 /* TRANS: Trade partner unknown to client */
778 const char *name = trade_city ? city_name_get(trade_city) : _("(unknown)");
779 int value = proute->value
780 * (100 + get_city_bonus(pcity, EFT_TRADE_ROUTE_PCT)) / 100;
781
782 switch (proute->dir) {
784 city_sum_add(sum, value, Q_("?city_surplus:Trading %s with %s"),
786 name);
787 break;
788 case RDIR_FROM:
789 city_sum_add(sum, value, Q_("?city_surplus:Trading %s to %s"),
791 name);
792 break;
793 case RDIR_TO:
794 city_sum_add(sum, value, Q_("?city_surplus:Trading %s from %s"),
796 name);
797 break;
798 case RDIR_NONE:
799 fc_assert(proute->dir != RDIR_NONE);
800 break;
801 }
803 } else if (otype == O_GOLD) {
804 int tithes = get_city_tithes_bonus(pcity);
805
807 Q_("?city_surplus:Building tithes"));
808 }
809
810 for (priority = 0; priority < 3; priority++) {
811 enum effect_type eft[] = {EFT_OUTPUT_BONUS, EFT_OUTPUT_BONUS_2,
813
814 {
815 int base = city_sum_total(sum), bonus = 100;
817
818 (void) get_city_bonus_effects(plist, pcity, output, eft[priority]);
819
821 char buf2[512];
822 int delta;
823 int new_total;
824
826
827 if (peffect->multiplier) {
829 peffect->multiplier);
830
831 if (mul == 0) {
832 /* Suppress text when multiplier setting suppresses effect
833 * (this will also suppress it when the city owner's policy
834 * settings are not known to us) */
835 continue;
836 }
837 delta = (peffect->value * mul) / 100;
838 } else {
839 delta = peffect->value;
840 }
841
843 new_total = bonus * base / 100 + delta;
845 NULL, 0,
846 Q_("?city_surplus:Bonus from %s"),
847 Q_("?city_surplus:Loss from %s"), buf2);
848 } else {
849 bonus += delta;
850 new_total = bonus * base / 100;
852 /* TRANS: percentage city output bonus/loss from
853 * some source; preserve leading space */
854 Q_("?city_surplus: (%+.0f%%)"), delta,
855 Q_("?city_surplus:Bonus from %s"),
856 Q_("?city_surplus:Loss from %s"), buf2);
857 }
860 }
861 }
862
863 if (pcity->waste[otype] != 0) {
865 bool breakdown_ok;
866 int regular_waste;
867 /* FIXME: this will give the wrong answer in rulesets with waste on
868 * taxed outputs, such as 'science waste', as our total so far includes
869 * contributions taxed from trade, whereas the equivalent bit in
870 * set_city_production() does not */
871 if (city_waste(pcity, otype, city_sum_total(sum), wastetypes)
872 == pcity->waste[otype]) {
873 /* Our calculation matches the server's, so we trust our breakdown. */
875 Q_("?city_surplus:Size penalty"));
878 } else {
879 /* Our calculation doesn't match what the server sent. Account it all
880 * to corruption/waste. */
881 regular_waste = pcity->waste[otype];
883 }
884 if (regular_waste > 0) {
885 const char *fmt;
886 switch (otype) {
887 case O_SHIELD:
888 default: /* FIXME other output types? */
889 /* TRANS: %s is normally empty, but becomes '?' if client is
890 * uncertain about its accounting (should never happen) */
891 fmt = Q_("?city_surplus:Waste%s");
892 break;
893 case O_TRADE:
894 /* TRANS: %s is normally empty, but becomes '?' if client is
895 * uncertain about its accounting (should never happen) */
896 fmt = Q_("?city_surplus:Corruption%s");
897 break;
898 }
899 city_sum_add(sum, -regular_waste, fmt, breakdown_ok ? "" : "?");
900 }
901 }
902
904 Q_("?city_surplus:Disorder"));
905
906 if (pcity->usage[otype] > 0) {
907 city_sum_add(sum, -pcity->usage[otype],
908 Q_("?city_surplus:Used"));
909 }
910
912 Q_("?city_surplus:"
913 "==== : Adds up to\n"
914 "%4.0f : Total surplus"), (double) pcity->surplus[otype]);
915}
916
917/**********************************************************************/
920void get_city_dialog_illness_text(const struct city *pcity,
921 char *buf, size_t bufsz)
922{
924 struct effect_list *plist;
925 struct city_sum *sum;
926
927 buf[0] = '\0';
928
929 if (!game.info.illness_on) {
930 cat_snprintf(buf, bufsz, _("Illness deactivated in ruleset."));
931 return;
932 }
933
934 sum = city_sum_new(Q_("?city_plague:%+5.1f%% : %s"));
935
936 illness = city_illness_calc(pcity, &ill_base, &ill_size, &ill_trade,
938
939 city_sum_add(sum, (float)(ill_size) / 10.0,
940 Q_("?city_plague:Risk from overcrowding"));
941 city_sum_add(sum, (float)(ill_trade) / 10.0,
942 Q_("?city_plague:Risk from trade"));
943 city_sum_add(sum, (float)(ill_pollution) / 10.0,
944 Q_("?city_plague:Risk from pollution"));
945
947
949
951 char buf2[512];
952 int delta;
953
955
956 if (peffect->multiplier) {
958 peffect->multiplier);
959
960 if (mul == 0) {
961 /* Suppress text when multiplier setting suppresses effect
962 * (this will also suppress it when the city owner's policy
963 * settings are not known to us) */
964 continue;
965 }
966 delta = (peffect->value * mul) / 100;
967 } else {
968 delta = peffect->value;
969 }
970
971 city_sum_add_full(sum, -(0.1 * ill_base * delta / 100), TRUE,
972 Q_("?city_plague: (%+.0f%%)"), -delta,
973 Q_("?city_plague:Risk from %s"),
974 Q_("?city_plague:Bonus from %s"), buf2);
977
978 /* XXX: account_for_unknown==FALSE: the displayed sum can fail to
979 * add up due to rounding. Making it always add up probably requires
980 * arbitrary assignment of 0.1% rounding figures to particular
981 * effects with something like distribute(). */
983 Q_("?city_plague:"
984 "====== : Adds up to\n"
985 "%5.1f%% : Plague chance per turn"),
986 ((double)(illness) / 10.0));
987}
988
989/**********************************************************************/
992void get_city_dialog_pollution_text(const struct city *pcity,
993 char *buf, size_t bufsz)
994{
995 int pollu, prod, pop, mod;
996 struct city_sum *sum = city_sum_new(Q_("?city_pollution:%+4.0f : %s"));
997
998 /* On the server, pollution is calculated before production is deducted
999 * for disorder; we need to compensate for that */
1001 pcity->prod[O_SHIELD]
1002 + pcity->unhappy_penalty[O_SHIELD],
1003 &prod, &pop, &mod);
1004 buf[0] = '\0';
1005
1006 city_sum_add(sum, prod, Q_("?city_pollution:Pollution from shields"));
1007 city_sum_add(sum, pop, Q_("?city_pollution:Pollution from citizens"));
1008 city_sum_add(sum, mod, Q_("?city_pollution:Pollution modifier"));
1010 Q_("?city_pollution:"
1011 "==== : Adds up to\n"
1012 "%4.0f : Total surplus"), (double)pollu);
1013}
1014
1015/**********************************************************************/
1018void get_city_dialog_culture_text(const struct city *pcity,
1019 char *buf, size_t bufsz)
1020{
1021 struct effect_list *plist;
1022 struct city_sum *sum = city_sum_new(Q_("?city_culture:%4.0f : %s"));
1023
1024 buf[0] = '\0';
1025
1026 /* XXX: no way to check whether client's idea of gain/turn is accurate */
1027 city_sum_add(sum, pcity->history, Q_("?city_culture:History (%+d/turn)"),
1028 city_history_gain(pcity));
1029
1031
1033
1035 char buf2[512];
1036 int mul = 100;
1037 int value;
1038
1040
1041 if (peffect->multiplier) {
1043 peffect->multiplier);
1044
1045 if (mul == 0) {
1046 /* Suppress text when multiplier setting suppresses effect
1047 * (this will also suppress it when the city owner's policy
1048 * settings are not known to us) */
1049 continue;
1050 }
1051 }
1052
1053 value = (peffect->value * mul) / 100;
1054 /* TRANS: text describing source of culture bonus ("Library+Republic") */
1055 city_sum_add_if_nonzero(sum, value, Q_("?city_culture:%s"), buf2);
1058
1060 Q_("?city_culture:"
1061 "==== : Adds up to\n"
1062 "%4.0f : Total culture"), (double)pcity->client.culture);
1063}
1064
1065/**********************************************************************/
1068void get_city_dialog_airlift_text(const struct city *pcity,
1069 char *buf, size_t bufsz)
1070{
1071 char src[512];
1072 char dest[512];
1073 int unlimited = 0;
1074
1076 && (pcity->airlift >= 1 || game.info.airlift_from_always_enabled)) {
1077
1078 unlimited++;
1079
1080 /* TRANS: airlift. Possible take offs text. String is a
1081 * proviso that take offs can't occur if landings spend all the
1082 * remaining airlift when landings are limited and empty when they
1083 * aren't limited. */
1084 fc_snprintf(src, sizeof(src), _("unlimited take offs%s"),
1086 /* TRANS: airlift unlimited take offs proviso used above.
1087 * Plural based on remaining airlift capacity. */
1088 ? "" : PL_(" (until the landing has been spent)",
1089 " (until all landings have been spent)",
1090 pcity->airlift));
1091 } else {
1092 fc_snprintf(src, sizeof(src),
1093 /* TRANS: airlift. Possible take offs text. Number is
1094 * airlift capacity. */
1095 PL_("%d take off", "%d take offs", pcity->airlift),
1096 pcity->airlift);
1097 }
1098
1100 && (pcity->airlift >= 1 || game.info.airlift_to_always_enabled)){
1101
1102 unlimited++;
1103
1104 /* TRANS: airlift. Possible landings text. */
1105 fc_snprintf(dest, sizeof(dest), _("unlimited landings"));
1106 } else {
1107 fc_snprintf(dest, sizeof(dest),
1108 /* TRANS: airlift. Possible landings text.
1109 * Number is airlift capacity. */
1110 PL_("%d landing", "%d landings", pcity->airlift),
1111 pcity->airlift);
1112 }
1113
1114 switch (unlimited) {
1115 case 2:
1116 /* TRANS: airlift take offs and landings */
1117 fc_snprintf(buf, bufsz, _("unlimited take offs and landings"));
1118 break;
1119 case 1:
1120 /* TRANS: airlift take offs and landings. One is unlimited. The first
1121 * string is the take offs text. The 2nd string is the landings text. */
1122 fc_snprintf(buf, bufsz, _("%s and %s"), src, dest);
1123 break;
1124 default:
1126 /* TRANS: airlift take offs or landings, no unlimited.
1127 * Number is airlift capacity. */
1128 PL_("%d take off or landing", "%d take offs or landings",
1129 pcity->airlift),
1130 pcity->airlift);
1131 break;
1132 }
1133}
1134
1135/**********************************************************************/
1138void get_city_dialog_airlift_value(const struct city *pcity,
1139 char *buf, size_t bufsz)
1140{
1141 char src[512];
1142 char dest[512];
1143 int unlimited = 0;
1144
1146 && (pcity->airlift >= 1 || game.info.airlift_from_always_enabled)) {
1147
1148 unlimited++;
1149
1150 /* TRANS: airlift. Possible take offs text. String is a symbol that
1151 * indicates that terms and conditions apply when landings are limited
1152 * and empty when they aren't limited. */
1153 fc_snprintf(src, sizeof(src), _(" ∞%s"),
1155 /* TRANS: airlift unlimited take offs may be spent symbol
1156 * used above. */
1157 ? "" : Q_("?landings:*"));
1158 } else {
1159 /* TRANS: airlift. Possible take offs text. Number is
1160 * airlift capacity. */
1161 fc_snprintf(src, sizeof(src), Q_("?takeoffs:%4d"), pcity->airlift);
1162 }
1163
1165 && (pcity->airlift >= 1 || game.info.airlift_to_always_enabled)){
1166
1167 unlimited++;
1168
1169 /* TRANS: airlift. Possible landings text. */
1170 fc_snprintf(dest, sizeof(dest), _(" ∞"));
1171 } else {
1172 /* TRANS: airlift. Possible landings text. */
1173 fc_snprintf(dest, sizeof(dest), Q_("?landings:%4d"), pcity->airlift);
1174 }
1175
1176 switch (unlimited) {
1177 case 2:
1178 /* TRANS: unlimited airlift take offs and landings */
1179 fc_snprintf(buf, bufsz, _(" ∞"));
1180 break;
1181 case 1:
1182 /* TRANS: airlift take offs and landings. One is unlimited. The first
1183 * string is the take offs text. The 2nd string is the landings text.
1184 * For English, initials of d)epartures and a)rrivals were chosen. */
1185 fc_snprintf(buf, bufsz, _("d: %s a: %s"), src, dest);
1186 break;
1187 default:
1188 /* TRANS: airlift take offs or landings, no unlimited */
1189 fc_snprintf(buf, bufsz, Q_("?airlifts:%s"), src);
1190 break;
1191 }
1192}
1193
1194/**********************************************************************/
1200int get_city_citizen_types(struct city *pcity, enum citizen_feeling idx,
1201 enum citizen_category *categories)
1202{
1203 int i = 0, n;
1204
1205 fc_assert(idx >= 0 && idx < FEELING_LAST);
1206
1207 for (n = 0; n < pcity->feel[CITIZEN_HAPPY][idx]; n++, i++) {
1208 categories[i] = CITIZEN_HAPPY;
1209 }
1210 for (n = 0; n < pcity->feel[CITIZEN_CONTENT][idx]; n++, i++) {
1211 categories[i] = CITIZEN_CONTENT;
1212 }
1213 for (n = 0; n < pcity->feel[CITIZEN_UNHAPPY][idx]; n++, i++) {
1214 categories[i] = CITIZEN_UNHAPPY;
1215 }
1216 for (n = 0; n < pcity->feel[CITIZEN_ANGRY][idx]; n++, i++) {
1217 categories[i] = CITIZEN_ANGRY;
1218 }
1219
1221 for (n = 0; n < pcity->specialists[sp]; n++, i++) {
1222 categories[i] = CITIZEN_SPECIALIST + sp;
1223 }
1225
1226 if (city_size_get(pcity) != i) {
1227 log_error("get_city_citizen_types() %d citizens "
1228 "not equal %d city size in \"%s\".",
1229 i, city_size_get(pcity), city_name_get(pcity));
1230 }
1231 return i;
1232}
1233
1234/**********************************************************************/
1238{
1239 enum citizen_category categories[MAX_CITY_SIZE];
1240 Specialist_type_id from, to;
1241 int num_citizens = get_city_citizen_types(pcity, FEELING_FINAL, categories);
1242
1244 || categories[citizen_index] < CITIZEN_SPECIALIST) {
1245 return;
1246 }
1247 from = categories[citizen_index] - CITIZEN_SPECIALIST;
1248
1249 /* Loop through all specialists in order until we find a usable one
1250 * (or run out of choices). */
1251 to = from;
1252 fc_assert(to >= 0 && to < specialist_count());
1253 do {
1254 to = (to + 1) % specialist_count();
1255 } while (to != from && !city_can_use_specialist(pcity, to));
1256
1257 if (from != to) {
1258 city_change_specialist(pcity, from, to);
1259 }
1260}
1261
1262/**********************************************************************/
1265void activate_all_units(struct tile *ptile)
1266{
1267 struct unit_list *punit_list = ptile->units;
1268 struct unit *pmyunit = NULL;
1269
1272 /* Activate this unit. */
1273 pmyunit = punit;
1275 }
1277 if (pmyunit) {
1278 /* Put the focus on one of the activated units. */
1280 }
1281}
1282
1283/**********************************************************************/
1286int city_change_production(struct city *pcity, struct universal *target)
1287{
1288 return dsend_packet_city_change(&client.conn, pcity->id,
1289 target->kind,
1290 universal_number(target));
1291}
1292
1293/**********************************************************************/
1298int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
1299{
1301}
1302
1303/**********************************************************************/
1306void city_worklist_commit(struct city *pcity, struct worklist *pwl)
1307{
1308 int k;
1309
1310 /* Update the worklist. Remember, though -- the current build
1311 target really isn't in the worklist; don't send it to the server
1312 as part of the worklist. Of course, we have to search through
1313 the current worklist to find the first _now_available_ build
1314 target (to cope with players who try mean things like adding a
1315 Battleship to a city worklist when the player doesn't even yet
1316 have the Map Making tech). */
1317
1318 for (k = 0; k < MAX_LEN_WORKLIST; k++) {
1320 struct universal target;
1321
1322 if (!worklist_peek_ith(pwl, &target, k)) {
1323 break;
1324 }
1325
1327
1328 /* Very special case: If we are currently building a wonder we
1329 allow the construction to continue, even if we the wonder is
1330 finished elsewhere, ie unbuildable. */
1331 if (k == 0
1332 && VUT_IMPROVEMENT == target.kind
1333 && is_wonder(target.value.building)
1335 worklist_remove(pwl, k);
1336 break;
1337 }
1338
1339 /* If it can be built... */
1340 if (can_city_build_now(&(wld.map), pcity, &target)) {
1341 /* ...but we're not yet building it, then switch. */
1342 if (!same_as_current_build) {
1343 /* Change the current target */
1344 city_change_production(pcity, &target);
1345 }
1346
1347 /* This item is now (and may have always been) the current
1348 build target. Drop it out of the worklist. */
1349 worklist_remove(pwl, k);
1350 break;
1351 }
1352 }
1353
1354 /* Send the rest of the worklist on its way. */
1355 city_set_worklist(pcity, pwl);
1356}
1357
1358/**********************************************************************/
1366static bool base_city_queue_insert(struct city *pcity, int position,
1367 struct universal *item)
1368{
1369 const struct civ_map *nmap = &(wld.map);
1370
1371 if (position == 0) {
1372 struct universal old = pcity->production;
1373
1374 /* Insert as current production. */
1375 if (!can_city_build_direct(nmap, pcity, item)) {
1376 return FALSE;
1377 }
1378
1379 if (!worklist_insert(&pcity->worklist, &old, 0)) {
1380 return FALSE;
1381 }
1382
1384 } else if (position >= 1
1385 && position <= worklist_length(&pcity->worklist)) {
1386 /* Insert into middle. */
1387 if (!can_city_build_later(nmap, pcity, item)) {
1388 return FALSE;
1389 }
1390 if (!worklist_insert(&pcity->worklist, item, position - 1)) {
1391 return FALSE;
1392 }
1393 } else {
1394 /* Insert at end. */
1395 if (!can_city_build_later(nmap, pcity, item)) {
1396 return FALSE;
1397 }
1398 if (!worklist_append(&pcity->worklist, item)) {
1399 return FALSE;
1400 }
1401 }
1402 return TRUE;
1403}
1404
1405/**********************************************************************/
1410bool city_queue_insert(struct city *pcity, int position,
1411 struct universal *item)
1412{
1413 if (base_city_queue_insert(pcity, position, item)) {
1414 city_set_worklist(pcity, &pcity->worklist);
1415 return TRUE;
1416 }
1417 return FALSE;
1418}
1419
1420/**********************************************************************/
1426bool city_queue_clear(struct city *pcity)
1427{
1428 worklist_init(&pcity->worklist);
1429
1430 return TRUE;
1431}
1432
1433/**********************************************************************/
1438bool city_queue_insert_worklist(struct city *pcity, int position,
1439 const struct worklist *worklist)
1440{
1441 bool success = FALSE;
1442
1443 if (worklist_length(worklist) == 0) {
1444 return TRUE;
1445 }
1446
1447 worklist_iterate(worklist, target) {
1448 if (base_city_queue_insert(pcity, position, &target)) {
1449 if (position > 0) {
1450 /* Move to the next position (unless position == -1 in which case
1451 * we're appending. */
1452 position++;
1453 }
1454 success = TRUE;
1455 }
1457
1458 if (success) {
1459 city_set_worklist(pcity, &pcity->worklist);
1460 }
1461
1462 return success;
1463}
1464
1465/**********************************************************************/
1468void city_get_queue(struct city *pcity, struct worklist *pqueue)
1469{
1470 worklist_copy(pqueue, &pcity->worklist);
1471
1472 /* The GUI wants current production to be in the task list, but the
1473 worklist API wants it out for reasons unknown. Perhaps someone enjoyed
1474 making things more complicated than necessary? So I dance around it. */
1475
1476 /* We want the current production to be in the queue. Always. */
1478
1479 worklist_insert(pqueue, &pcity->production, 0);
1480}
1481
1482/**********************************************************************/
1485bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
1486{
1487 struct worklist copy;
1488 struct universal target;
1489
1490 worklist_copy(&copy, pqueue);
1491
1492 /* The GUI wants current production to be in the task list, but the
1493 worklist API wants it out for reasons unknown. Perhaps someone enjoyed
1494 making things more complicated than necessary? So I dance around it. */
1495 if (worklist_peek(&copy, &target)) {
1496
1497 if (!city_can_change_build(pcity)
1498 && !are_universals_equal(&pcity->production, &target)) {
1499 /* We cannot change production to one from worklist.
1500 * Do not replace old worklist with new one. */
1501 return FALSE;
1502 }
1503
1504 worklist_advance(&copy);
1505
1506 city_set_worklist(pcity, &copy);
1507 city_change_production(pcity, &target);
1508 } else {
1509 /* You naughty boy, you can't erase the current production. Nyah! */
1510 if (worklist_is_empty(&pcity->worklist)) {
1511 refresh_city_dialog(pcity);
1512 } else {
1513 city_set_worklist(pcity, &copy);
1514 }
1515 }
1516
1517 return TRUE;
1518}
1519
1520/**********************************************************************/
1523bool city_can_buy(const struct city *pcity)
1524{
1525 /* See really_handle_city_buy() in the server. However this function
1526 * doesn't allow for error messages. It doesn't check the cost of
1527 * buying; that's handled separately (and with an error message). */
1528 return (can_client_issue_orders()
1529 && NULL != pcity
1530 && city_owner(pcity) == client.conn.playing
1531 && pcity->turn_founded != game.info.turn
1532 && !pcity->did_buy
1533 && (VUT_UTYPE == pcity->production.kind
1535 && !(VUT_UTYPE == pcity->production.kind
1536 && pcity->anarchy != 0)
1537 && pcity->client.buy_cost > 0);
1538}
1539
1540/**********************************************************************/
1543int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
1544{
1545 return dsend_packet_city_sell(&client.conn, pcity->id, sell_id);
1546}
1547
1548/**********************************************************************/
1551int city_buy_production(struct city *pcity)
1552{
1553 return dsend_packet_city_buy(&client.conn, pcity->id);
1554}
1555
1556/**********************************************************************/
1561{
1562 return dsend_packet_city_change_specialist(&client.conn, pcity->id, from,
1563 to);
1564}
1565
1566/**********************************************************************/
1570int city_toggle_worker(struct city *pcity, int city_x, int city_y)
1571{
1572 int city_radius_sq;
1573 struct tile *ptile;
1574
1575 if (city_owner(pcity) != client_player()) {
1576 return 0;
1577 }
1578
1579 city_radius_sq = city_map_radius_sq_get(pcity);
1580 fc_assert(is_valid_city_coords(city_radius_sq, city_x, city_y));
1581 ptile = city_map_to_tile(&(wld.map), city_tile(pcity), city_radius_sq,
1582 city_x, city_y);
1583 if (NULL == ptile) {
1584 return 0;
1585 }
1586
1587 if (NULL != tile_worked(ptile) && tile_worked(ptile) == pcity) {
1589 pcity->id, ptile->index);
1590 } else if (city_can_work_tile(pcity, ptile)) {
1592 pcity->id, ptile->index);
1593 } else {
1594 return 0;
1595 }
1596}
1597
1598/**********************************************************************/
1601int city_rename(struct city *pcity, const char *name)
1602{
1603 return dsend_packet_city_rename(&client.conn, pcity->id, name);
1604}
void astr_vadd(struct astring *astr, const char *format, va_list ap)
Definition astring.c:279
char * astr_to_str(struct astring *astr)
Definition astring.c:167
#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:3228
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: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:75
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:37
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2931
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:846
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:1153
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Definition effects.c:1275
#define effect_list_iterate_end
Definition effects.h:406
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:404
int Impr_type_id
Definition fc_types.h:376
int Specialist_type_id
Definition fc_types.h:375
@ 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:378
#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:62
struct world wld
Definition game.c:63
struct city * game_city_by_number(int id)
Definition game.c:107
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:1969
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:163
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:138
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:791
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:836
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:900
#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:114
struct unit * get_drawable_unit(const struct tileset *t, struct tile *ptile, const struct city *citymode)
Definition tilespec.c:6564
struct tileset * get_tileset(void)
Definition tilespec.c:692
struct tileset * unscaled_tileset
Definition tilespec.c:568
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:712
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:765
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:753
#define mapview_layer_iterate(layer)
Definition tilespec.h:175
#define mapview_layer_iterate_end
Definition tilespec.h:183
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:721
const struct impr_type * building
Definition fc_types.h:714
#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