Freeciv-3.1
Loading...
Searching...
No Matches
citydlg.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/***********************************************************************
15 citydlg.c - description
16 -------------------
17 begin : Wed Sep 04 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20***********************************************************************/
21
22#ifdef HAVE_CONFIG_H
23#include <fc_config.h>
24#endif
25
26/* SDL2 */
27#ifdef SDL2_PLAIN_INCLUDE
28#include <SDL.h>
29#else /* SDL2_PLAIN_INCLUDE */
30#include <SDL2/SDL.h>
31#endif /* SDL2_PLAIN_INCLUDE */
32
33/* utility */
34#include "astring.h"
35#include "bitvector.h"
36#include "fcintl.h"
37#include "log.h"
38
39/* common */
40#include "game.h"
41#include "movement.h"
42#include "specialist.h"
43#include "unitlist.h"
44
45/* client */
46#include "client_main.h"
47#include "climisc.h"
48#include "control.h"
49#include "text.h"
50
51/* gui-sdl2 */
52#include "cityrep.h"
53#include "cma_fe.h"
54#include "colors.h"
55#include "dialogs.h"
56#include "graphics.h"
57#include "gui_id.h"
58#include "gui_main.h"
59#include "gui_tilespec.h"
60#include "mapview.h"
61#include "menu.h"
62#include "sprite.h"
63#include "themespec.h"
64#include "widget.h"
65#include "wldlg.h"
66
67#include "citydlg.h"
68
69/* ============================================================= */
70
71static struct city_dialog {
72 struct city *pcity;
73
74 enum {
81
82 /* main window group list */
85
86 /* Imprvm. vscrollbar */
88
89 /* Penel group list */
91
92 /* Menu imprv. dlg. */
95
96 /* shortcuts */
101
103
104 SDL_Rect spec_area;
105
106 bool lock;
108
112
113static float city_map_zoom = 1;
114
115static struct small_dialog *hurry_prog_dlg = NULL;
116
117static void popdown_hurry_production_dialog(void);
118static void disable_city_dlg_widgets(void);
119static void redraw_city_dialog(struct city *pcity);
120static void rebuild_imprm_list(struct city *pcity);
121static void rebuild_citydlg_title_str(struct widget *pwindow, struct city *pcity);
122
123/* ======================================================================= */
124
125/**********************************************************************/
132struct impr_type *get_building_for_effect(enum effect_type effect_type)
133{
134 improvement_iterate(pimprove) {
135 if (building_has_effect(pimprove, effect_type)) {
136 return pimprove;
137 }
139
140 return NULL;
141}
142
143/**********************************************************************/
146static void popdown_city_menu_dlg(bool enable_city_dialog_widgets)
147{
152 }
153 if (enable_city_dialog_widgets) {
154 /* enable city dlg */
156 }
157}
158
159/**********************************************************************/
194
195/**********************************************************************/
199static int city_dlg_callback(struct widget *pwindow)
200{
204
205 if (is_in_rect_area(main_data.event.motion.x, main_data.event.motion.y,
208 (main_data.event.motion.x - pcity_dlg->spec_area.x)
210
211 return -1;
212 }
213 }
214
215 if (!pcity_dlg->lock) {
216 if (pcity_dlg->panel) {
220 widget_flush(pwindow);
221 } else {
223 widget_flush(pwindow);
224 }
225 }
226 }
227 }
228
229 return -1;
230}
231
232/* ===================================================================== */
233/* ========================== Units Orders Menu ======================== */
234/* ===================================================================== */
235
236/**********************************************************************/
253
254/**********************************************************************/
258{
260 struct unit *punit = button->data.unit;
261
263 if (punit) {
265 }
266 }
267
268 return -1;
269}
270
271/**********************************************************************/
293
294/**********************************************************************/
298{
300 struct unit *punit = button->data.unit;
301
303 if (punit) {
305 }
306 }
307
308 return -1;
309}
310
311/**********************************************************************/
315{
317 struct unit *punit = button->data.unit;
318
320 if (punit) {
322 }
323 }
324
325 return -1;
326}
327
328/**********************************************************************/
332{
334 struct unit *punit = button->data.unit;
335
338 }
339
340 return -1;
341}
342
343/**********************************************************************/
347{
349 struct unit *punit = button->data.unit;
350
352 if (punit) {
354 }
355 }
356
357 return -1;
358}
359
360/**********************************************************************/
364{
366 struct unit *punit = button->data.unit;
367
370 }
371
372 return -1;
373}
374
375/**********************************************************************/
378static int units_orders_dlg_callback(struct widget *button)
379{
380 return -1;
381}
382
383/**********************************************************************/
386static int units_orders_city_dlg_callback(struct widget *button)
387{
388 bool right_button = (main_data.event.type == SDL_MOUSEBUTTONDOWN
389 && main_data.event.button.button == SDL_BUTTON_RIGHT);
390
391 if (PRESSED_EVENT(main_data.event) || right_button) {
392 utf8_str *pstr;
393 char cbuf[80];
394 struct widget *buf, *pwindow;
395 struct unit *punit;
396 const struct unit_type *putype;
397 Uint16 i = 0, hh = 0;
398 SDL_Rect area;
399
401
402 if (punit == NULL || !can_client_issue_orders()) {
403 return -1;
404 }
405
406 if (right_button) {
410
411 return -1;
412 }
413
414 /* Disable city dlg */
417
418 putype = unit_type_get(punit);
419
420 /* Window */
421 fc_snprintf(cbuf, sizeof(cbuf), "%s:", _("Unit commands"));
423 pstr->style |= TTF_STYLE_BOLD;
424 pwindow = create_window_skeleton(NULL, pstr, 0);
425
427 set_wstate(pwindow, FC_WS_NORMAL);
430
431 area = pwindow->area;
432
433 /* Unit description */
434 fc_snprintf(cbuf, sizeof(cbuf), "%s", unit_description(punit));
436 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
438 pwindow->dst, pstr, WF_FREE_THEME);
439 area.w = MAX(area.w, buf->size.w);
441
442 /* Activate unit */
443 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
444 _("Activate unit"),
445 FONTO_ATTENTION, 0);
446 i++;
447 area.w = MAX(area.w, buf->size.w);
448 hh = MAX(hh, buf->size.h);
450 buf->data = button->data;
452 add_to_gui_list(button->id, buf);
453
454 /* Activate unit, close dlg. */
455 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
456 _("Activate unit, close dialog"),
457 FONTO_ATTENTION, 0);
458 i++;
459 area.w = MAX(area.w, buf->size.w);
460 hh = MAX(hh, buf->size.h);
462 buf->data = button->data;
464 add_to_gui_list(button->id, buf);
465 /* ----- */
466
467 if (pcity_dlg->page == ARMY_PAGE) {
468 /* Sentry unit */
469 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
470 _("Sentry unit"),
471 FONTO_ATTENTION, 0);
472 i++;
473 area.w = MAX(area.w, buf->size.w);
474 hh = MAX(hh, buf->size.h);
475 buf->data = button->data;
477 if (punit->activity != ACTIVITY_SENTRY
478 && can_unit_do_activity_client(punit, ACTIVITY_SENTRY)) {
480 }
481 add_to_gui_list(button->id, buf);
482 /* ----- */
483
484 /* Fortify unit */
485 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
486 _("Fortify unit"),
487 FONTO_ATTENTION, 0);
488 i++;
489 area.w = MAX(area.w, buf->size.w);
490 hh = MAX(hh, buf->size.h);
491 buf->data = button->data;
493 if (punit->activity != ACTIVITY_FORTIFYING
494 && can_unit_do_activity_client(punit, ACTIVITY_FORTIFYING)) {
496 }
497 add_to_gui_list(button->id, buf);
498 }
499 /* ----- */
500
501 /* Disband unit */
502 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
503 _("Disband unit"),
504 FONTO_ATTENTION, 0);
505 i++;
506 area.w = MAX(area.w, buf->size.w);
507 hh = MAX(hh, buf->size.h);
508 buf->data = button->data;
511 add_to_gui_list(button->id, buf);
512 /* ----- */
513
514 if (pcity_dlg->page == ARMY_PAGE) {
515 if (punit->homecity != pcity_dlg->pcity->id) {
516 /* Make new Homecity */
517 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
518 action_id_name_translation(ACTION_HOME_CITY),
519 FONTO_ATTENTION, 0);
520 i++;
521 area.w = MAX(area.w, buf->size.w);
522 hh = MAX(hh, buf->size.h);
523 buf->data = button->data;
526 add_to_gui_list(button->id, buf);
527 }
528 /* ----- */
529
531 /* Upgrade unit */
532 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
533 _("Upgrade unit"),
534 FONTO_ATTENTION, 0);
535 i++;
536 area.w = MAX(area.w, buf->size.w);
537 hh = MAX(hh, buf->size.h);
538 buf->data = button->data;
541 add_to_gui_list(button->id, buf);
542 }
543 }
544
545 /* ----- */
546 /* Cancel */
547 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
548 _("Cancel"),
549 FONTO_ATTENTION, 0);
550 i++;
551 area.w = MAX(area.w, buf->size.w);
552 hh = MAX(hh, buf->size.h);
553 buf->key = SDLK_ESCAPE;
556 add_to_gui_list(button->id, buf);
558
559 /* ================================================== */
561 /* ================================================== */
562
563 area.w += adj_size(10);
564 hh += adj_size(4);
565
566 /* Create window background */
568 (pwindow->size.w - pwindow->area.w) + area.w,
569 (pwindow->size.h - pwindow->area.h) + pwindow->prev->size.h +
570 (i * hh) + adj_size(5));
571
572 area = pwindow->area;
573
574 widget_set_position(pwindow,
575 button->size.x + adj_size(2),
576 pwindow->area.y + button->size.y + 1);
577
578 /* Label */
579 buf = pwindow->prev;
580 buf->size.w = area.w;
581 buf->size.x = area.x;
582 buf->size.y = area.y + 1;
583 buf = buf->prev;
584
585 /* First button */
586 buf->size.w = area.w;
587 buf->size.h = hh;
588 buf->size.x = area.x;
589 buf->size.y = buf->next->size.y + buf->next->size.h + adj_size(5);
590 buf = buf->prev;
591
592 while (buf != NULL) {
593 buf->size.w = area.w;
594 buf->size.h = hh;
595 buf->size.x = buf->next->size.x;
596 buf->size.y = buf->next->size.y + buf->next->size.h;
598 break;
599 }
600 buf = buf->prev;
601 }
602
603 /* ================================================== */
604 /* Redraw */
606 widget_flush(pwindow);
607 }
608
609 return -1;
610}
611
612/* ======================================================================= */
613/* ======================= City Dlg. Panels ============================== */
614/* ======================================================================= */
615
616/**********************************************************************/
619static SDL_Surface *create_unit_surface(struct unit *punit, bool support,
620 int w, int h)
621{
622 SDL_Rect src_rect;
623 SDL_Surface *psurf;
624 struct canvas *destcanvas;
625
628
629 put_unit(punit, destcanvas, 1.0, 0, 0);
630
631 /* Get unit sprite width, and crop top. Bottom might get restored in 'support'
632 * case below. */
633 src_rect = get_smaller_surface_rect(destcanvas->surf);
634
635 if (support) {
636 int i, step;
637 int free_unhappy;
638 int happy_cost;
639 SDL_Rect dest;
641
642 /* Support also layouts placing support icons higher than unit. */
643 src_rect.y = MIN(src_rect.y, offset);
644 /* Restore bottom space when needed for support icons. */
645 src_rect.h = destcanvas->surf->h - src_rect.y;
646
647 free_unhappy = get_city_bonus(pcity_dlg->pcity, EFT_MAKE_CONTENT_MIL);
648 happy_cost = city_unit_unhappiness(punit, &free_unhappy);
649
651 punit->upkeep[O_GOLD] + happy_cost;
652
653 if (i * icons->food->w > src_rect.w / 2) {
654 step = (src_rect.w / 2 - icons->food->w) / (i - 1);
655 } else {
656 step = icons->food->w;
657 }
658
660 dest.x = src_rect.x + src_rect.w / 8;
661
662 for (i = 0; i < punit->upkeep[O_SHIELD]; i++) {
663 alphablit(icons->shield, NULL, destcanvas->surf, &dest, 255);
664 dest.x += step;
665 }
666
667 for (i = 0; i < punit->upkeep[O_FOOD]; i++) {
668 alphablit(icons->food, NULL, destcanvas->surf, &dest, 255);
669 dest.x += step;
670 }
671
672 for (i = 0; i < punit->upkeep[O_GOLD]; i++) {
673 alphablit(icons->coint, NULL, destcanvas->surf, &dest, 255);
674 dest.x += step;
675 }
676
677 for (i = 0; i < happy_cost; i++) {
678 alphablit(icons->face, NULL, destcanvas->surf, &dest, 255);
679 dest.x += step;
680 }
681
682 }
683
684 psurf = create_surf(src_rect.w, src_rect.h, SDL_SWSURFACE);
685 alphablit(destcanvas->surf, &src_rect, psurf, NULL, 255);
686
687 canvas_free(destcanvas);
688
689 if (w != src_rect.w || h != src_rect.h) {
690 SDL_Surface *pzoomed;
691
692 pzoomed = resize_surface_box(psurf, w, h, 1, TRUE, TRUE);
693 FREESURFACE(psurf);
694 psurf = pzoomed;
695 }
696
697 return psurf;
698}
699
700/**********************************************************************/
705static void create_present_supported_units_widget_list(struct unit_list *units)
706{
707 int i;
708 struct widget *buf = NULL;
709 struct widget *end = NULL;
710 struct widget *pwindow = pcity_dlg->end_city_widget_list;
711 struct city *home_city;
712 const struct unit_type *putype;
713 SDL_Surface *surf;
714 utf8_str *pstr;
715 char cbuf[256];
716 int num_x, num_y, w, h;
717
718 i = 0;
719
720 num_x = (adj_size(160) / (tileset_full_tile_width(tileset) + adj_size(4)));
721 if (num_x < 4) {
722 num_x = 4;
723 w = adj_size(160 - 4*4) / 4;
724 } else {
726 }
727
728 num_y = (adj_size(151) / (tileset_full_tile_height(tileset)+4));
729 if (num_y < 4) {
730 num_y = 4;
731 h = adj_size(151 - 4*4) / 4;
732 } else {
734 }
735
736 unit_list_iterate(units, punit) {
737 const char *vetname;
738 struct astring addition = ASTRING_INIT;
739
740 putype = unit_type_get(punit);
741 vetname = utype_veteran_name_translation(putype, punit->veteran);
742 home_city = game_city_by_number(punit->homecity);
743 unit_activity_astr(punit, &addition);
744 fc_snprintf(cbuf, sizeof(cbuf), "%s (%d,%d,%s)%s%s\n%s\n(%d/%d)\n%s",
746 putype->attack_strength,
747 putype->defense_strength,
749 (vetname != NULL ? "\n" : ""),
750 (vetname != NULL ? vetname : ""),
751 astr_str(&addition),
752 punit->hp, putype->hp,
753 home_city ? home_city->name : Q_("?homecity:None"));
754 astr_free(&addition);
755
756 if (pcity_dlg->page == SUPPORTED_UNITS_PAGE) {
757 int city_near_dist;
758 struct city *near_city = get_nearest_city(punit, &city_near_dist);
759
760 sz_strlcat(cbuf, "\n");
761 sz_strlcat(cbuf, get_nearest_city_text(near_city, city_near_dist));
762 surf = adj_surf(create_unit_surface(punit, TRUE, w, h));
763 } else {
764 surf = adj_surf(create_unit_surface(punit, FALSE, w, h));
765 }
766
768 pstr->style |= SF_CENTER;
769
770 buf = create_icon2(surf, pwindow->dst, WF_FREE_THEME
772 buf->info_label = pstr;
773 buf->data.unit = punit;
775
776 if (!end) {
777 end = buf;
778 }
779
780 if (++i > num_x * num_y) {
781 set_wflag(buf, WF_HIDDEN);
782 }
783
786 }
787
790
791 pcity_dlg->panel = fc_calloc(1, sizeof(struct advanced_dialog));
797
799 pwindow->area.x + adj_size(5),
800 pwindow->area.y + adj_size(44),
803
804 if (i > num_x * num_y) {
806 num_x, num_y, TRUE, TRUE);
807
809 pwindow->area.x + adj_size(185),
810 pwindow->area.y + adj_size(45),
811 adj_size(150), TRUE);
812 }
813}
814
815/**********************************************************************/
827
828/**********************************************************************/
831static int army_city_dlg_callback(struct widget *button)
832{
834 if (pcity_dlg->page != ARMY_PAGE) {
836 pcity_dlg->page = ARMY_PAGE;
838 flush_dirty();
839 } else {
840 widget_redraw(button);
841 widget_flush(button);
842 }
843 }
844
845 return -1;
846}
847
848/**********************************************************************/
851static int supported_unit_city_dlg_callback(struct widget *button)
852{
854 if (pcity_dlg->page != SUPPORTED_UNITS_PAGE) {
856 pcity_dlg->page = SUPPORTED_UNITS_PAGE;
858 flush_dirty();
859 } else {
860 widget_redraw(button);
861 widget_flush(button);
862 }
863 }
864
865 return -1;
866}
867
868/* ---------------------- */
869
870/**********************************************************************/
873static int info_city_dlg_callback(struct widget *button)
874{
876 if (pcity_dlg->page != INFO_PAGE) {
878 pcity_dlg->page = INFO_PAGE;
880 flush_dirty();
881 } else {
882 widget_redraw(button);
883 widget_flush(button);
884 }
885 }
886
887 return -1;
888}
889
890/* ---------------------- */
891/**********************************************************************/
894static int happy_city_dlg_callback(struct widget *button)
895{
897 if (pcity_dlg->page != HAPPINESS_PAGE) {
901 flush_dirty();
902 } else {
903 widget_redraw(button);
904 widget_flush(button);
905 }
906 }
907
908 return -1;
909}
910
911/**********************************************************************/
914static int misc_panel_city_dlg_callback(struct widget *pwidget)
915{
917 bv_city_options new_options = pcity_dlg->pcity->city_options;
918
919 switch (MAX_ID - pwidget->id) {
920 case 0x10:
921 if (BV_ISSET(new_options, CITYO_DISBAND)) {
922 BV_CLR(new_options, CITYO_DISBAND);
923 } else {
924 BV_SET(new_options, CITYO_DISBAND);
925 }
926 break;
927 case 0x20:
928 if (BV_ISSET(new_options, CITYO_SCIENCE_SPECIALISTS)) {
929 BV_CLR(new_options, CITYO_SCIENCE_SPECIALISTS);
930 } else {
931 BV_SET(new_options, CITYO_SCIENCE_SPECIALISTS);
932 }
933 if (BV_ISSET(new_options, CITYO_GOLD_SPECIALISTS)) {
934 BV_CLR(new_options, CITYO_GOLD_SPECIALISTS);
935 } else {
936 BV_SET(new_options, CITYO_GOLD_SPECIALISTS);
937 }
938
939 pwidget->theme2 = get_tax_surface(O_GOLD);
940 pwidget->id = MAX_ID - 0x40;
941 widget_redraw(pwidget);
942 widget_flush(pwidget);
943 break;
944 case 0x40:
945 BV_CLR(new_options, CITYO_SCIENCE_SPECIALISTS);
946 BV_CLR(new_options, CITYO_GOLD_SPECIALISTS);
947 pwidget->theme2 = get_tax_surface(O_LUXURY);
948 pwidget->id = MAX_ID - 0x60;
949 widget_redraw(pwidget);
950 widget_flush(pwidget);
951 break;
952 case 0x60:
953 if (BV_ISSET(new_options, CITYO_SCIENCE_SPECIALISTS)) {
954 BV_CLR(new_options, CITYO_SCIENCE_SPECIALISTS);
955 } else {
956 BV_SET(new_options, CITYO_SCIENCE_SPECIALISTS);
957 }
958
959 pwidget->theme2 = get_tax_surface(O_SCIENCE);
960 pwidget->id = MAX_ID - 0x20;
961 widget_redraw(pwidget);
962 widget_flush(pwidget);
963 break;
964 }
965
968 new_options);
969 }
970
971 return -1;
972}
973
974/**********************************************************************/
977static void create_city_options_widget_list(struct city *pcity)
978{
979 struct widget *buf, *pwindow = pcity_dlg->end_city_widget_list;
980 SDL_Surface *surf;
981 utf8_str *pstr;
982 char cbuf[80];
983
984 fc_snprintf(cbuf, sizeof(cbuf),
985 _("Allow unit production\nto disband city"));
987 pstr->style |= TTF_STYLE_BOLD;
989
990 buf =
995 add_to_gui_list(MAX_ID - 0x10, buf);
996 buf->size.x = pwindow->area.x + adj_size(7);
997 buf->size.y = pwindow->area.y + adj_size(45);
998
999 /* ----- */
1000
1001 pcity_dlg->panel = fc_calloc(1, sizeof(struct advanced_dialog));
1003
1004 /* ----- */
1005
1006 fc_snprintf(cbuf, sizeof(cbuf), "%s:", _("New citizens produce"));
1008 pstr->style |= SF_CENTER;
1009
1011 surf = get_tax_surface(O_SCIENCE);
1012 buf = create_icon_button(surf, pwindow->dst, pstr,
1014 add_to_gui_list(MAX_ID - 0x20, buf);
1015 } else {
1017 surf = get_tax_surface(O_GOLD);
1018 buf = create_icon_button(surf, pwindow->dst,
1020 add_to_gui_list(MAX_ID - 0x40, buf);
1021 } else {
1022 surf = get_tax_surface(O_LUXURY);
1023 buf = create_icon_button(surf, pwindow->dst,
1025 add_to_gui_list(MAX_ID - 0x60, buf);
1026 }
1027 }
1028
1029 buf->size.w = adj_size(177);
1032
1033 buf->size.x = buf->next->size.x;
1034 buf->size.y = buf->next->size.y + buf->next->size.h + adj_size(5);
1036}
1037
1038/**********************************************************************/
1041static int options_city_dlg_callback(struct widget *button)
1042{
1044 if (pcity_dlg->page != MISC_PAGE) {
1046 pcity_dlg->page = MISC_PAGE;
1048 flush_dirty();
1049 } else {
1050 widget_redraw(button);
1051 widget_flush(button);
1052 }
1053 }
1054
1055 return -1;
1056}
1057
1058/* ======================================================================= */
1059
1060/**********************************************************************/
1063static int cma_city_dlg_callback(struct widget *button)
1064{
1068 }
1069
1070 return -1;
1071}
1072
1073/**********************************************************************/
1076static int exit_city_dlg_callback(struct widget *button)
1077{
1080 }
1081
1082 return -1;
1083}
1084
1085/* ======================================================================= */
1086/* ======================== Buy Production Dlg. ========================== */
1087/* ======================================================================= */
1088
1089/**********************************************************************/
1093{
1096
1097 if (pcity_dlg) {
1098 /* enable city dlg */
1100 }
1101 }
1102
1103 return -1;
1104}
1105
1106/**********************************************************************/
1109static int ok_buy_prod_city_dlg_callback(struct widget *button)
1110{
1112 struct city *pcity = button->data.city; /* Save it. */
1113
1115 city_buy_production(pcity);
1116
1117 if (pcity_dlg) {
1118 /* enable city dlg */
1120
1121 /* disable buy button */
1125 flush_dirty();
1126 }
1127 }
1128
1129 return -1;
1130}
1131
1132/**********************************************************************/
1135static int buy_prod_city_dlg_callback(struct widget *button)
1136{
1138 widget_redraw(button);
1139 widget_flush(button);
1142 }
1143
1144 return -1;
1145}
1146
1147/**********************************************************************/
1159
1160/**********************************************************************/
1163static int hurry_production_window_callback(struct widget *pwindow)
1164{
1167 }
1168
1169 return -1;
1170}
1171
1172/**********************************************************************/
1175void popup_hurry_production_dialog(struct city *pcity, SDL_Surface *pdest)
1176{
1177 char tbuf[512], cbuf[512];
1178 struct widget *buf = NULL, *pwindow;
1179 utf8_str *pstr;
1180 SDL_Surface *text;
1181 SDL_Rect dst;
1182 int window_x = 0, window_y = 0;
1183 SDL_Rect area;
1184 const char *name = city_production_name_translation(pcity);
1185 int value = pcity->client.buy_cost;
1186
1187 if (hurry_prog_dlg) {
1188 return;
1189 }
1190
1191 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
1192 "Treasury contains %d gold.",
1193 client_player()->economic.gold),
1194 client_player()->economic.gold);
1195
1196 hurry_prog_dlg = fc_calloc(1, sizeof(struct small_dialog));
1197
1198 if (city_can_buy(pcity)) {
1199 if (value <= client_player()->economic.gold) {
1200 fc_snprintf(cbuf, sizeof(cbuf),
1201 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1202 PL_("Buy %s for %d gold?\n%s",
1203 "Buy %s for %d gold?\n%s", value),
1204 name, value, tbuf);
1205 } else {
1206 fc_snprintf(cbuf, sizeof(cbuf),
1207 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1208 PL_("%s costs %d gold.\n%s",
1209 "%s costs %d gold.\n%s", value),
1210 name, value, tbuf);
1211 }
1212 } else {
1213 if (pcity->did_buy) {
1214 fc_snprintf(cbuf, sizeof(cbuf),
1215 _("Sorry, you have already bought here in this turn."));
1216 } else {
1217 fc_snprintf(cbuf, sizeof(cbuf),
1218 _("Sorry, you can't buy here in this turn."));
1219 }
1220 }
1221
1223 pstr->style |= TTF_STYLE_BOLD;
1224 pwindow = create_window_skeleton(NULL, pstr, 0);
1225 pwindow->action = hurry_production_window_callback;
1226 set_wstate(pwindow, FC_WS_NORMAL);
1227 add_to_gui_list(ID_WINDOW, pwindow);
1228
1230
1231 area = pwindow->area;
1232
1233 area.h += 1;
1234
1235 /* ============================================================= */
1236
1237 /* Label */
1239 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1241
1244 area.w = MAX(area.w , text->w);
1245 area.h += text->h + adj_size(5);
1246
1248 pwindow->dst, _("No"),
1249 FONTO_ATTENTION, 0);
1250
1253 buf->key = SDLK_ESCAPE;
1254 area.h += buf->size.h;
1255
1257
1258 if (city_can_buy(pcity) && (value <= client.conn.playing->economic.gold)) {
1260 pwindow->dst,
1261 _("Yes"),
1262 FONTO_ATTENTION, 0);
1263
1266 buf->data.city = pcity;
1267 buf->key = SDLK_RETURN;
1269 buf->size.w = MAX(buf->next->size.w, buf->size.w);
1270 buf->next->size.w = buf->size.w;
1271 area.w = MAX(area.w , 2 * buf->size.w + adj_size(20));
1272 }
1273
1275
1276 /* Setup window size and start position */
1277 area.w += adj_size(10);
1278 area.h += adj_size(5);
1279
1281 (pwindow->size.w - pwindow->area.w) + area.w,
1282 (pwindow->size.h - pwindow->area.h) + area.h);
1283
1284 area = pwindow->area;
1285
1286 if (city_dialog_is_open(pcity)) {
1287 window_x = pcity_dlg->buy_button->size.x;
1288 window_y = pcity_dlg->buy_button->size.y - pwindow->size.h;
1289 } else if (is_city_report_open()) {
1291
1293 + pwindow->size.w > main_window_width()) {
1294 window_x = selected_widget->size.x - pwindow->size.w;
1295 } else {
1297 }
1298
1300 + (selected_widget->size.h - pwindow->size.h) / 2;
1301
1302 if (window_y + pwindow->size.h > main_window_height()) {
1303 window_y = main_window_height() - pwindow->size.h - 1;
1304 } else if (window_y < 0) {
1305 window_y = 0;
1306 }
1307 } else {
1308 put_window_near_map_tile(pwindow, pwindow->size.w, pwindow->size.h, pcity->tile);
1309 }
1310
1312
1313 /* Setup rest of widgets */
1314 /* Label */
1315 dst.x = area.x + (area.w - text->w) / 2;
1316 dst.y = area.y + 1;
1317 alphablit(text, NULL, pwindow->theme, &dst, 255);
1318 dst.y += text->h + adj_size(5);
1319 FREESURFACE(text);
1320
1321 /* No */
1322 buf = pwindow->prev;
1323 buf->size.y = dst.y;
1324
1325 if (city_can_buy(pcity) && value <= client.conn.playing->economic.gold) {
1326 /* Yes */
1327 buf = buf->prev;
1328 buf->size.x = area.x + (area.w - (2 * buf->size.w + adj_size(20))) / 2;
1329 buf->size.y = dst.y;
1330
1331 /* No */
1332 buf->next->size.x = buf->size.x + buf->size.w + adj_size(20);
1333 } else {
1334 /* No */
1335 buf->size.x = area.x + area.w - buf->size.w - adj_size(10);
1336 }
1337
1338 /* ================================================== */
1339 /* Redraw */
1341 widget_mark_dirty(pwindow);
1342 flush_dirty();
1343}
1344
1345/* =======================================================================*/
1346/* ========================== CHANGE PRODUCTION ==========================*/
1347/* =======================================================================*/
1348
1349/**********************************************************************/
1352static int change_prod_dlg_callback(struct widget *button)
1353{
1355 widget_redraw(button);
1356 widget_flush(button);
1357
1360 }
1361
1362 return -1;
1363}
1364
1365/* =======================================================================*/
1366/* ========================== SELL IMPROVEMENTS ==========================*/
1367/* =======================================================================*/
1368
1369/**********************************************************************/
1385
1386/**********************************************************************/
1389static int sell_imprvm_dlg_ok_callback(struct widget *ok_button)
1390{
1392 struct widget *tmp = (struct widget *)ok_button->data.ptr;
1393
1395
1396 /* popdown, we don't redraw and flush because this is made by redraw city dlg.
1397 when response from server comes */
1400
1402
1403 /* del imprv from widget list */
1405
1407
1411 }
1412
1414 flush_dirty();
1415 }
1416
1417 return -1;
1418}
1419
1420/**********************************************************************/
1423static int sell_imprvm_dlg_callback(struct widget *impr)
1424{
1426 utf8_str *pstr = NULL;
1427 struct widget *label = NULL;
1428 struct widget *pwindow = NULL;
1429 struct widget *cancel_button = NULL;
1430 struct widget *ok_button = NULL;
1431 char cbuf[80];
1432 int id;
1433 SDL_Rect area;
1434 int price;
1435
1438
1440 pstr->style |= TTF_STYLE_BOLD;
1441 pwindow = create_window_skeleton(NULL, pstr, 0);
1442 /*pwindow->action = move_sell_imprvm_dlg_callback; */
1443 /*set_wstate(pwindow, FC_WS_NORMAL); */
1444 add_to_gui_list(ID_WINDOW, pwindow);
1446
1447 area = pwindow->area;
1448
1449 /* Create text label */
1450 id = MAX_ID - 3000 - impr->id;
1451
1453 fc_snprintf(cbuf, sizeof(cbuf), PL_("Sell %s for %d gold?",
1454 "Sell %s for %d gold?", price),
1457 price);
1459 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1461 label = create_iconlabel(NULL, pwindow->dst, pstr, 0);
1462 add_to_gui_list(ID_LABEL, label);
1463
1464 /* Create cancel button */
1465 cancel_button =
1467 pwindow->dst, _("Cancel"),
1468 FONTO_DEFAULT, 0);
1469 cancel_button->action = sell_imprvm_dlg_cancel_callback;
1470 cancel_button->key = SDLK_ESCAPE;
1471 set_wstate(cancel_button, FC_WS_NORMAL);
1472 add_to_gui_list(ID_BUTTON, cancel_button);
1473
1474 /* create ok button */
1476 pwindow->dst, _("Sell"),
1477 FONTO_DEFAULT, 0);
1478 ok_button->data.ptr = (void *)impr;
1479 ok_button->size.w = cancel_button->size.w;
1481 ok_button->key = SDLK_RETURN;
1482 set_wstate(ok_button, FC_WS_NORMAL);
1483 add_to_gui_list(ID_BUTTON, ok_button);
1484
1486
1487 /* correct sizes */
1488 if ((ok_button->size.w + cancel_button->size.w + adj_size(30)) >
1489 label->size.w + adj_size(20)) {
1490 area.w = MAX(area.w, ok_button->size.w + cancel_button->size.w + adj_size(30));
1491 } else {
1492 area.w = MAX(area.w, label->size.w + adj_size(20));
1493 }
1494
1495 area.h = MAX(area.h, ok_button->size.h + label->size.h + adj_size(25));
1496
1497 /* create window background */
1499 (pwindow->size.w - pwindow->area.w) + area.w,
1500 (pwindow->size.h - pwindow->area.h) + area.h);
1501
1502 area = pwindow->area;
1503
1504 /* set start positions */
1505 widget_set_position(pwindow,
1506 (main_window_width() - pwindow->size.w) / 2,
1507 (main_window_height() - pwindow->size.h) / 2 + adj_size(10));
1508
1509 ok_button->size.x = area.x + adj_size(10);
1510 ok_button->size.y = area.y + area.h - ok_button->size.h - adj_size(10);
1511
1512 cancel_button->size.y = ok_button->size.y;
1513 cancel_button->size.x = area.x + area.w - cancel_button->size.w - adj_size(10);
1514
1515 label->size.x = area.x;
1516 label->size.y = area.y + adj_size(4);
1517 label->size.w = area.w;
1518
1519 /* redraw */
1522
1523 widget_mark_dirty(pwindow);
1524 flush_dirty();
1525 }
1526
1527 return -1;
1528}
1529/* ====================================================================== */
1530
1531/**********************************************************************/
1535{
1536 if (pcity_dlg) {
1539
1541 if (pcity_dlg->imprv->scroll) {
1545 }
1546
1547 /* There is common function test_player_sell_building_now(),
1548 * but we are not using it here, since we want to use set_group_state()
1549 * when possible */
1554 } else {
1556
1557 while (TRUE) {
1558 struct impr_type *pimpr = improvement_by_number(MAX_ID - 3000 -
1559 tmp_widget->id);
1560
1561 if (!can_city_sell_building(pcity_dlg->pcity, pimpr)) {
1562 set_wstate(tmp_widget, FC_WS_DISABLED);
1563 } else {
1564 set_wstate(tmp_widget, FC_WS_NORMAL);
1565 }
1566
1567 if (tmp_widget == pcity_dlg->imprv->begin_active_widget_list) {
1568 break;
1569 }
1570
1571 tmp_widget = tmp_widget->prev;
1572
1573 } /* while */
1574 }
1575 }
1576
1579 }
1580
1581 if (pcity_dlg->panel) {
1584 }
1585
1588 }
1589
1590 pcity_dlg->lock = FALSE;
1591 }
1592}
1593
1594/**********************************************************************/
1613
1614/* ======================================================================== */
1615
1616/**********************************************************************/
1619SDL_Surface *get_scaled_city_map(struct city *pcity)
1620{
1621 SDL_Surface *buf = create_city_map(pcity);
1622
1623 city_map_zoom = ((buf->w * 159 > buf->h * 249) ?
1624 (float)adj_size(249) / buf->w
1625 : (float)adj_size(159) / buf->h);
1626
1627 return zoomSurface(buf, city_map_zoom, city_map_zoom, 1);
1628}
1629
1630/**********************************************************************/
1634{
1636 int col, row;
1637
1638 if (canvas_to_city_pos(&col, &row,
1640 1 / city_map_zoom * (main_data.event.motion.x - map->dst->dest_rect.x
1641 - map->size.x),
1642 1 / city_map_zoom * (main_data.event.motion.y - map->dst->dest_rect.y
1643 - map->size.y))) {
1644
1646 }
1647 }
1648
1649 return -1;
1650}
1651
1652/* ====================================================================== */
1653
1654/**********************************************************************/
1657static int city_comp_by_turn_founded(const void *a, const void *b)
1658{
1659 struct city *pcity1 = *((struct city **) a);
1660 struct city *pcity2 = *((struct city **) b);
1661
1662 return pcity1->turn_founded - pcity2->turn_founded;
1663}
1664
1665/**********************************************************************/
1668static int next_prev_city_dlg_callback(struct widget *button)
1669{
1671 struct city **array;
1672 int i, dir, non_open_size;
1673 int size = city_list_size(client.conn.playing->cities);
1674
1675 fc_assert_ret_val(size >= 1, -1);
1677 == client.conn.playing, -1);
1678
1679 if (size == 1) {
1680 return -1;
1681 }
1682
1683 /* dir = 1 will advance to the city, dir = -1 will get previous */
1684 if (button->id == ID_CITY_DLG_NEXT_BUTTON) {
1685 dir = 1;
1686 } else {
1687 if (button->id == ID_CITY_DLG_PREV_BUTTON) {
1688 dir = -1;
1689 } else {
1690 /* Always fails. */
1692 || button->id != ID_CITY_DLG_PREV_BUTTON, -1);
1693 dir = 1;
1694 }
1695 }
1696
1697 array = fc_calloc(1, size * sizeof(struct city *));
1698
1699 non_open_size = 0;
1700 for (i = 0; i < size; i++) {
1701 array[non_open_size++] = city_list_get(client.conn.playing->cities, i);
1702 }
1703
1704 fc_assert_ret_val(non_open_size > 0, -1);
1705
1706 if (non_open_size <= 1) {
1707 FC_FREE(array);
1708 return -1;
1709 }
1710
1711 qsort(array, non_open_size, sizeof(struct city *),
1713
1714 for (i = 0; i < non_open_size; i++) {
1715 if (pcity_dlg->pcity == array[i]) {
1716 break;
1717 }
1718 }
1719
1720 fc_assert_ret_val(i < non_open_size, -1);
1721 pcity_dlg->pcity = array[(i + dir + non_open_size) % non_open_size];
1722 FC_FREE(array);
1723
1724 /* free panel widgets */
1726 /* refresh resource map */
1730
1731 /* redraw */
1733 flush_dirty();
1734 }
1735
1736 return -1;
1737}
1738
1739/**********************************************************************/
1742static int new_name_city_dlg_callback(struct widget *pedit)
1743{
1744 if (pedit->string_utf8->text != NULL) {
1745 if (strcmp(pedit->string_utf8->text, city_name_get(pcity_dlg->pcity))) {
1748 }
1749 } else {
1750 /* Empty input -> restore previous content */
1752 widget_redraw(pedit);
1753 widget_mark_dirty(pedit);
1754 flush_dirty();
1755 }
1756
1757 return -1;
1758}
1759
1760/* ======================================================================= */
1761/* ======================== Redrawing City Dlg. ========================== */
1762/* ======================================================================= */
1763
1764/**********************************************************************/
1767static void refresh_city_names(struct city *pcity)
1768{
1770 char name[MAX_LEN_NAME];
1771
1773 if ((strcmp(city_name_get(pcity), name) != 0)
1776 city_name_get(pcity));
1778 sdl2_client_flags &= ~CF_CHANGED_CITY_NAME;
1779 }
1780 }
1781}
1782
1783/**********************************************************************/
1787static void redraw_misc_city_dialog(struct widget *city_window,
1788 struct city *pcity)
1789{
1790 char cbuf[60];
1791 utf8_str *pstr;
1792 SDL_Surface *surf;
1793 SDL_Rect dest;
1794
1795 fc_snprintf(cbuf, sizeof(cbuf), _("City options"));
1796
1799 pstr->style |= TTF_STYLE_BOLD;
1800
1801 surf = create_text_surf_from_utf8(pstr);
1802
1803 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1804 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1805
1806 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1807
1808 FREESURFACE(surf);
1809 FREEUTF8STR(pstr);
1810
1811 if (!pcity_dlg->panel) {
1813 }
1816}
1817
1818/**********************************************************************/
1822static void redraw_supported_units_city_dialog(struct widget *city_window,
1823 struct city *pcity)
1824{
1825 char cbuf[60];
1826 utf8_str *pstr;
1827 SDL_Surface *surf;
1828 SDL_Rect dest;
1829 struct unit_list *units;
1830 int size;
1831
1834 } else {
1835 units = (pcity_dlg->pcity->units_supported);
1836 }
1837
1838 size = unit_list_size(units);
1839
1840 fc_snprintf(cbuf, sizeof(cbuf), _("Supported units: %d"), size);
1841
1844 pstr->style |= TTF_STYLE_BOLD;
1845
1846 surf = create_text_surf_from_utf8(pstr);
1847
1848 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1849 dest.y = city_window->area.y + + adj_size(4) + current_theme->info_icon->h;
1850
1851 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1852
1853 FREESURFACE(surf);
1854 FREEUTF8STR(pstr);
1855
1856 if (pcity_dlg->panel) {
1857 if (size > 0) {
1860 } else {
1865 }
1866 } else {
1867 if (size > 0) {
1871 }
1872 }
1873}
1874
1875/**********************************************************************/
1879static void redraw_army_city_dialog(struct widget *city_window,
1880 struct city *pcity)
1881{
1882 char cbuf[60];
1883 utf8_str *pstr;
1884 SDL_Surface *surf;
1885 SDL_Rect dest;
1886 struct unit_list *units;
1887 int size;
1888
1891 } else {
1892 units = pcity_dlg->pcity->tile->units;
1893 }
1894
1895 size = unit_list_size(units);
1896
1897 fc_snprintf(cbuf, sizeof(cbuf), _("Present units: %d"), size);
1898
1901 pstr->style |= TTF_STYLE_BOLD;
1902
1903 surf = create_text_surf_from_utf8(pstr);
1904
1905 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1906 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1907
1908 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1909
1910 FREESURFACE(surf);
1911 FREEUTF8STR(pstr);
1912
1913 if (pcity_dlg->panel) {
1914 if (size) {
1917 } else {
1922 }
1923 } else {
1924 if (size) {
1928 }
1929 }
1930}
1931
1932/**********************************************************************/
1936static void redraw_info_city_dialog(struct widget *city_window,
1937 struct city *pcity)
1938{
1939 char cbuf[30];
1940 struct city *trade_city = NULL;
1941 int step, i, xx;
1942 utf8_str *pstr = NULL;
1943 SDL_Surface *surf = NULL;
1944 SDL_Rect dest;
1945
1946 fc_snprintf(cbuf, sizeof(cbuf), _("City info"));
1949 pstr->style |= TTF_STYLE_BOLD;
1950
1951 surf = create_text_surf_from_utf8(pstr);
1952
1953 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1954 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1955
1956 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1957
1958 dest.x = city_window->size.x + adj_size(10);
1959 dest.y += surf->h + 1;
1960
1961 FREESURFACE(surf);
1962
1965
1966 if (pcity->pollution) {
1967 fc_snprintf(cbuf, sizeof(cbuf), _("Pollution: %d"),
1968 pcity->pollution);
1969
1970 copy_chars_to_utf8_str(pstr, cbuf);
1971
1972 surf = create_text_surf_from_utf8(pstr);
1973
1974 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1975
1976 dest.y += surf->h + adj_size(3);
1977
1978 FREESURFACE(surf);
1979
1980 if (((icons->pollution->w + 1) * pcity->pollution) > adj_size(187)) {
1981 step = (adj_size(187) - icons->pollution->w) / (pcity->pollution - 1);
1982 } else {
1983 step = icons->pollution->w + 1;
1984 }
1985
1986 for (i = 0; i < pcity->pollution; i++) {
1987 alphablit(icons->pollution, NULL, city_window->dst->surface, &dest, 255);
1988 dest.x += step;
1989 }
1990
1991 dest.x = city_window->size.x + adj_size(10);
1992 dest.y += icons->pollution->h + adj_size(3);
1993
1994 } else {
1995 fc_snprintf(cbuf, sizeof(cbuf), _("Pollution: none"));
1996
1997 copy_chars_to_utf8_str(pstr, cbuf);
1998
1999 surf = create_text_surf_from_utf8(pstr);
2000
2001 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2002
2003 dest.y += surf->h + adj_size(3);
2004
2005 FREESURFACE(surf);
2006 }
2007
2008 if (game.info.illness_on) {
2009 int risk_pml = city_illness_calc(pcity, NULL, NULL, NULL, NULL);
2010
2011 fc_snprintf(cbuf, sizeof(cbuf), _("Plague risk: %.1f%%"),
2012 (double)risk_pml / 10.0);
2013 } else {
2014 fc_snprintf(cbuf, sizeof(cbuf), _("Plague risk: none"));
2015 }
2016
2017 copy_chars_to_utf8_str(pstr, cbuf);
2018 surf = create_text_surf_from_utf8(pstr);
2019 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2020 dest.y += surf->h + adj_size(3);
2021 FREESURFACE(surf);
2022
2023 fc_snprintf(cbuf, sizeof(cbuf), _("Trade routes: "));
2024
2025 copy_chars_to_utf8_str(pstr, cbuf);
2026
2027 surf = create_text_surf_from_utf8(pstr);
2028
2029 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2030
2031 xx = dest.x + surf->w;
2032 dest.y += surf->h + adj_size(3);
2033
2034 FREESURFACE(surf);
2035
2036 step = 0;
2037 dest.x = city_window->size.x + adj_size(10);
2038
2039 trade_routes_iterate(pcity, proute) {
2040 step += proute->value;
2041
2042 if ((trade_city = game_city_by_number(proute->partner))) {
2043 fc_snprintf(cbuf, sizeof(cbuf), "%s: +%d", city_name_get(trade_city),
2044 proute->value);
2045 } else {
2046 fc_snprintf(cbuf, sizeof(cbuf), "%s: +%d", _("Unknown"),
2047 proute->value);
2048 }
2049
2050 copy_chars_to_utf8_str(pstr, cbuf);
2051
2052 surf = create_text_surf_from_utf8(pstr);
2053
2054 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2055
2056 /* Blit trade icon */
2057 dest.x += surf->w + adj_size(3);
2058 dest.y += adj_size(4);
2059 alphablit(icons->trade, NULL, city_window->dst->surface, &dest, 255);
2060 dest.x = city_window->size.x + adj_size(10);
2061 dest.y -= adj_size(4);
2062
2063 dest.y += surf->h;
2064
2065 FREESURFACE(surf);
2067
2068 if (step > 0) {
2069 fc_snprintf(cbuf, sizeof(cbuf), _("Trade: +%d"), step);
2070
2071 copy_chars_to_utf8_str(pstr, cbuf);
2072 surf = create_text_surf_from_utf8(pstr);
2073 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2074
2075 dest.x += surf->w + adj_size(3);
2076 dest.y += adj_size(4);
2077 alphablit(icons->trade, NULL, city_window->dst->surface, &dest, 255);
2078
2079 FREESURFACE(surf);
2080 } else {
2081 fc_snprintf(cbuf, sizeof(cbuf), Q_("?trade:None"));
2082
2083 copy_chars_to_utf8_str(pstr, cbuf);
2084
2085 surf = create_text_surf_from_utf8(pstr);
2086
2087 dest.x = xx;
2088 dest.y -= surf->h + adj_size(3);
2089 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2090
2091 FREESURFACE(surf);
2092 }
2093
2094 FREEUTF8STR(pstr);
2095}
2096
2097/**********************************************************************/
2102static void redraw_happiness_city_dialog(const struct widget *city_window,
2103 struct city *pcity)
2104{
2105 char cbuf[30];
2106 int step, i, j, count;
2107 SDL_Surface *tmp;
2108 utf8_str *pstr = NULL;
2109 SDL_Surface *surf = NULL;
2110 SDL_Rect dest = {0, 0, 0, 0};
2111 struct effect_list *sources = effect_list_new();
2112
2113 fc_snprintf(cbuf, sizeof(cbuf), _("Happiness"));
2114
2117 pstr->style |= TTF_STYLE_BOLD;
2118
2119 surf = create_text_surf_from_utf8(pstr);
2120
2121 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
2122 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
2123 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2124
2125 dest.x = city_window->size.x + adj_size(10);
2126 dest.y += surf->h + 1;
2127
2128 FREESURFACE(surf);
2129 FREEUTF8STR(pstr);
2130
2133 + city_specialists(pcity));
2134
2135 if (count * icons->male_happy->w > adj_size(166)) {
2136 step = (adj_size(166) - icons->male_happy->w) / (count - 1);
2137 } else {
2138 step = icons->male_happy->w;
2139 }
2140
2141 for (j = 0; j < FEELING_LAST; j++) {
2142 if (j == 0 || pcity->feel[CITIZEN_HAPPY][j - 1] != pcity->feel[CITIZEN_HAPPY][j]
2143 || pcity->feel[CITIZEN_CONTENT][j - 1] != pcity->feel[CITIZEN_CONTENT][j]
2144 || pcity->feel[CITIZEN_UNHAPPY][j - 1] != pcity->feel[CITIZEN_UNHAPPY][j]
2145 || pcity->feel[CITIZEN_ANGRY][j - 1] != pcity->feel[CITIZEN_ANGRY][j]) {
2146 int spe, spe_max;
2147
2148 if (j != 0) {
2149 create_line(city_window->dst->surface,
2150 dest.x, dest.y, dest.x + adj_size(176), dest.y,
2152 dest.y += adj_size(5);
2153 }
2154
2155 if (pcity->feel[CITIZEN_HAPPY][j]) {
2156 surf = icons->male_happy;
2157 for (i = 0; i < pcity->feel[CITIZEN_HAPPY][j]; i++) {
2158 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2159 dest.x += step;
2160 if (surf == icons->male_happy) {
2161 surf = icons->female_happy;
2162 } else {
2163 surf = icons->male_happy;
2164 }
2165 }
2166 }
2167
2168 if (pcity->feel[CITIZEN_CONTENT][j]) {
2169 surf = icons->male_content;
2170 for (i = 0; i < pcity->feel[CITIZEN_CONTENT][j]; i++) {
2171 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2172 dest.x += step;
2173 if (surf == icons->male_content) {
2174 surf = icons->female_content;
2175 } else {
2176 surf = icons->male_content;
2177 }
2178 }
2179 }
2180
2181 if (pcity->feel[CITIZEN_UNHAPPY][j]) {
2182 surf = icons->male_unhappy;
2183 for (i = 0; i < pcity->feel[CITIZEN_UNHAPPY][j]; i++) {
2184 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2185 dest.x += step;
2186 if (surf == icons->male_unhappy) {
2187 surf = icons->female_unhappy;
2188 } else {
2189 surf = icons->male_unhappy;
2190 }
2191 }
2192 }
2193
2194 if (pcity->feel[CITIZEN_ANGRY][j]) {
2195 surf = icons->male_angry;
2196 for (i = 0; i < pcity->feel[CITIZEN_ANGRY][j]; i++) {
2197 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2198 dest.x += step;
2199 if (surf == icons->male_angry) {
2200 surf = icons->female_angry;
2201 } else {
2202 surf = icons->male_angry;
2203 }
2204 }
2205 }
2206
2207 spe_max = specialist_count();
2208 for (spe = 0 ; spe < spe_max; spe++) {
2209 if (pcity->specialists[spe]) {
2210 for (i = 0; i < pcity->specialists[spe]; i++) {
2211 alphablit(icons->specialists[spe], NULL, city_window->dst->surface,
2212 &dest, 255);
2213 dest.x += step;
2214 }
2215 }
2216 }
2217
2218 if (j == 1) { /* Luxury effect */
2219 dest.x =
2220 city_window->size.x + adj_size(187) - icons->big_luxury->w - adj_size(2);
2221 count = dest.y;
2222 dest.y += (icons->male_happy->h -
2223 icons->big_luxury->h) / 2;
2224 alphablit(icons->big_luxury, NULL, city_window->dst->surface, &dest, 255);
2225 dest.y = count;
2226 }
2227
2228 if (j == 2) { /* Improvements effects */
2229 int w = -1;
2230 count = 0;
2231
2232 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_CONTENT);
2233
2234 effect_list_iterate(sources, psource) {
2235 requirement_vector_iterate(&(psource->reqs), preq) {
2236 if (preq->source.kind == VUT_IMPROVEMENT) {
2237 tmp = get_building_surface(preq->source.value.building);
2238 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2239 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2240
2241 count += (tmp->h + 1);
2242
2243 if (w < 0) {
2244 w = tmp->w;
2245 }
2246
2247 FREESURFACE(tmp);
2248 }
2251
2252 if (w >= 0) {
2253 dest.x = city_window->size.x + adj_size(187) - w - adj_size(2);
2254 i = dest.y;
2255 dest.y += (icons->male_happy->h - count) / 2;
2256
2257 effect_list_iterate(sources, psource) {
2258 requirement_vector_iterate(&(psource->reqs), preq) {
2259 if (preq->source.kind == VUT_IMPROVEMENT) {
2260 tmp = get_building_surface(preq->source.value.building);
2261 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2262 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2263
2264 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2265 dest.y += (tmp->h + 1);
2266
2267 FREESURFACE(tmp);
2268 }
2271
2272 dest.y = i;
2273 }
2274
2275 effect_list_clear(sources);
2276 }
2277
2278 if (j == 3) { /* police effect */
2279 dest.x = city_window->size.x + adj_size(187) - icons->police->w - adj_size(5);
2280 i = dest.y;
2281 dest.y +=
2282 (icons->male_happy->h - icons->police->h) / 2;
2283 alphablit(icons->police, NULL, city_window->dst->surface, &dest, 255);
2284 dest.y = i;
2285 }
2286
2287 if (j == 4) { /* Wonders effect */
2288 int w = -1;
2289 count = 0;
2290
2291 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_HAPPY);
2292 effect_list_iterate(sources, psource) {
2293 requirement_vector_iterate(&(psource->reqs), preq) {
2294 if (preq->source.kind == VUT_IMPROVEMENT) {
2295 tmp = get_building_surface(preq->source.value.building);
2296 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2297 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2298
2299 count += (tmp->h + 1);
2300
2301 if (w < 0) {
2302 w = tmp->w;
2303 }
2304
2305 FREESURFACE(tmp);
2306 }
2309
2310 effect_list_clear(sources);
2311
2312 get_city_bonus_effects(sources, pcity, NULL, EFT_FORCE_CONTENT);
2313
2314 effect_list_iterate(sources, psource) {
2315 requirement_vector_iterate(&(psource->reqs), preq) {
2316 if (preq->source.kind == VUT_IMPROVEMENT) {
2317 tmp = get_building_surface(preq->source.value.building);
2318 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2319 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2320 count += (tmp->h + 1);
2321
2322 if (w < 0) {
2323 w = tmp->w;
2324 }
2325
2326 FREESURFACE(tmp);
2327 }
2330
2331 effect_list_clear(sources);
2332
2333 get_city_bonus_effects(sources, pcity, NULL, EFT_NO_UNHAPPY);
2334
2335 effect_list_iterate(sources, psource) {
2336 requirement_vector_iterate(&(psource->reqs), preq) {
2337 if (preq->source.kind == VUT_IMPROVEMENT) {
2338 tmp = get_building_surface(preq->source.value.building);
2339 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2340 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2341
2342 count += (tmp->h + 1);
2343
2344 if (w < 0) {
2345 w = tmp->w;
2346 }
2347
2348 FREESURFACE(tmp);
2349 }
2352
2353 effect_list_clear(sources);
2354
2355 if (w >= 0) {
2356 dest.x = city_window->size.x + adj_size(187) - surf->w - adj_size(2);
2357 i = dest.y;
2358 dest.y += (icons->male_happy->h - count) / 2;
2359
2360 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_HAPPY);
2361
2362 effect_list_iterate(sources, psource) {
2363 requirement_vector_iterate(&(psource->reqs), preq) {
2364 if (preq->source.kind == VUT_IMPROVEMENT) {
2365 tmp = get_building_surface(preq->source.value.building);
2366 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2367 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2368
2369 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2370 dest.y += (tmp->h + 1);
2371
2372 FREESURFACE(tmp);
2373 }
2376
2377 effect_list_clear(sources);
2378
2379 get_city_bonus_effects(sources, pcity, NULL, EFT_FORCE_CONTENT);
2380
2381 effect_list_iterate(sources, psource) {
2382 requirement_vector_iterate(&(psource->reqs), preq) {
2383 if (preq->source.kind == VUT_IMPROVEMENT) {
2384 tmp = get_building_surface(preq->source.value.building);
2385 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2386 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2387
2388 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2389 dest.y += (tmp->h + 1);
2390
2391 FREESURFACE(tmp);
2392 }
2395
2396 effect_list_clear(sources);
2397
2398 get_city_bonus_effects(sources, pcity, NULL, EFT_NO_UNHAPPY);
2399
2400 effect_list_iterate(sources, psource) {
2401 requirement_vector_iterate(&(psource->reqs), preq) {
2402 if (preq->source.kind == VUT_IMPROVEMENT) {
2403 tmp = get_building_surface(preq->source.value.building);
2404 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2405 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2406
2407 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2408 dest.y += (tmp->h + 1);
2409
2410 FREESURFACE(tmp);
2411 }
2414
2415 effect_list_clear(sources);
2416
2417 dest.y = i;
2418 }
2419 }
2420
2421 dest.x = city_window->size.x + adj_size(10);
2422 dest.y += icons->male_happy->h + adj_size(5);
2423
2424 }
2425 }
2426
2427 effect_list_destroy(sources);
2428}
2429
2430/**********************************************************************/
2433static void redraw_city_dialog(struct city *pcity)
2434{
2435 char cbuf[40];
2436 int i, step, count, limit;
2437 int cost = 0;
2438 SDL_Rect dest;
2439 struct widget *pwindow = pcity_dlg->end_city_widget_list;
2440 SDL_Surface *buf = NULL, *buf2 = NULL;
2441 utf8_str *pstr = NULL;
2442 int spe, spe_max;
2443
2444 refresh_city_names(pcity);
2445
2446 if ((city_unhappy(pcity) || city_celebrating(pcity) || city_happy(pcity)
2447 || cma_is_city_under_agent(pcity, NULL))
2449 /* City status was changed : NORMAL <-> DISORDER, HAPPY, CELEBR. */
2450
2452
2453#if 0
2454 /* Upd. resource map */
2457#endif
2458
2459 /* Upd. window title */
2461 }
2462
2463 /* Update resource map */
2466
2467 /* Redraw city dlg */
2470
2471 /* ================================================================= */
2472 fc_snprintf(cbuf, sizeof(cbuf), _("City map"));
2473
2476 pstr->style |= TTF_STYLE_BOLD;
2477
2479
2480 dest.x = pwindow->size.x + adj_size(196) + (adj_size(132) - buf->w) / 2;
2481 dest.y = pwindow->size.y + adj_size(49) + (adj_size(13) - buf->h) / 2;
2482
2483 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2484
2486
2487 fc_snprintf(cbuf, sizeof(cbuf), _("Citizens"));
2488
2491
2493
2494 dest.x = pwindow->size.x + adj_size(344) + (adj_size(146) - buf->w) / 2;
2495 dest.y = pwindow->size.y + adj_size(47) + (adj_size(13) - buf->h) / 2;
2496
2497 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2498
2500
2501 fc_snprintf(cbuf, sizeof(cbuf), _("City improvements"));
2502
2505
2507
2508 dest.x = pwindow->size.x + adj_size(504) + (adj_size(132) - buf->w) / 2;
2509 dest.y = pwindow->size.y + adj_size(49) + (adj_size(13) - buf->h) / 2;
2510
2511 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2512
2514
2515 /* ================================================================= */
2516 /* Food label */
2517 fc_snprintf(cbuf, sizeof(cbuf), _("Food: %d per turn"),
2518 pcity->prod[O_FOOD]);
2519
2521
2523
2525
2526 dest.x = pwindow->size.x + adj_size(200);
2527 dest.y = pwindow->size.y + adj_size(228) + (adj_size(16) - buf->h) / 2;
2528
2529 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2530
2532
2533 /* Draw food income */
2534 dest.y = pwindow->size.y + adj_size(246) + (adj_size(16) - icons->big_food->h) / 2;
2535 dest.x = pwindow->size.x + adj_size(203);
2536
2537 if (pcity->surplus[O_FOOD] >= 0) {
2538 count = pcity->prod[O_FOOD] - pcity->surplus[O_FOOD];
2539 } else {
2540 count = pcity->prod[O_FOOD];
2541 }
2542
2543 if (((icons->big_food->w + 1) * count) > adj_size(200)) {
2544 step = (adj_size(200) - icons->big_food->w) / (count - 1);
2545 } else {
2546 step = icons->big_food->w + 1;
2547 }
2548
2549 for (i = 0; i < count; i++) {
2550 alphablit(icons->big_food, NULL, pwindow->dst->surface, &dest, 255);
2551 dest.x += step;
2552 }
2553
2554 fc_snprintf(cbuf, sizeof(cbuf), Q_("?food:Surplus: %d"),
2555 pcity->surplus[O_FOOD]);
2556
2559
2561
2562 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2563 dest.y = pwindow->size.y + adj_size(228) + (adj_size(16) - buf->h) / 2;
2564
2565 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2566
2568
2569 /* Draw surplus of food */
2570 if (pcity->surplus[O_FOOD]) {
2571 if (pcity->surplus[O_FOOD] > 0) {
2572 count = pcity->surplus[O_FOOD];
2573 buf = icons->big_food;
2574 } else {
2575 count = -1 * pcity->surplus[O_FOOD];
2577 }
2578
2579 dest.x = pwindow->size.x + adj_size(423);
2580 dest.y = pwindow->size.y + adj_size(246) + (adj_size(16) - buf->h) / 2;
2581
2582 if (count > 2) {
2583 if (count < 18) {
2584 step = (adj_size(30) - buf->w) / (count - 1);
2585 } else {
2586 step = 1;
2587 count = 17;
2588 }
2589 } else {
2590 step = buf->w + 1;
2591 }
2592
2593 for (i = 0; i < count; i++) {
2594 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2595 dest.x -= step;
2596 }
2597 }
2598
2599 /* ================================================================= */
2600 /* Productions label */
2601 fc_snprintf(cbuf, sizeof(cbuf), _("Production: %d (%d) per turn"),
2602 pcity->surplus[O_SHIELD],
2603 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD]);
2604
2607
2609
2610 dest.x = pwindow->size.x + adj_size(200);
2611 dest.y = pwindow->size.y + adj_size(263) + (adj_size(15) - buf->h) / 2;
2612
2613 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2614
2616
2617 /* Draw productions shields */
2618 if (pcity->surplus[O_SHIELD]) {
2619
2620 if (pcity->surplus[O_SHIELD] > 0) {
2621 count = pcity->surplus[O_SHIELD] + pcity->waste[O_SHIELD];
2622 buf = icons->big_shield;
2623 } else {
2624 count = -1 * pcity->surplus[O_SHIELD];
2626 }
2627
2628 dest.y = pwindow->size.y + adj_size(281) + (adj_size(16) - buf->h) / 2;
2629 dest.x = pwindow->size.x + adj_size(203);
2630
2631 if ((buf->w * count) > adj_size(200)) {
2632 step = (adj_size(200) - buf->w) / (count - 1);
2633 } else {
2634 step = buf->w;
2635 }
2636
2637 for (i = 0; i < count; i++) {
2638 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2639 dest.x += step;
2640 if (i > pcity->surplus[O_SHIELD]) {
2642 }
2643 }
2644 }
2645
2646 /* Support shields label */
2647 fc_snprintf(cbuf, sizeof(cbuf), Q_("?production:Support: %d"),
2648 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD] -
2649 pcity->surplus[O_SHIELD]);
2650
2653
2655
2656 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2657 dest.y = pwindow->size.y + adj_size(263) + (adj_size(15) - buf->h) / 2;
2658
2659 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2660
2662
2663 /* Draw support shields */
2664 if (pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD]) {
2665 dest.x = pwindow->size.x + adj_size(423);
2666 dest.y =
2667 pwindow->size.y + adj_size(281) + (adj_size(16) - icons->big_shield->h) / 2;
2668
2669 if ((icons->big_shield->w + 1) * (pcity->prod[O_SHIELD] -
2670 pcity->surplus[O_SHIELD]) > adj_size(30)) {
2671 step =
2672 (adj_size(30) - icons->big_food->w) / (pcity->prod[O_SHIELD] -
2673 pcity->surplus[O_SHIELD] - 1);
2674 } else {
2675 step = icons->big_shield->w + 1;
2676 }
2677
2678 for (i = 0; i < (pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD]); i++) {
2679 alphablit(icons->big_shield, NULL, pwindow->dst->surface, &dest, 255);
2680 dest.x -= step;
2681 }
2682 }
2683
2684 /* ================================================================= */
2685 /* Trade label */
2686 fc_snprintf(cbuf, sizeof(cbuf), _("Trade: %d per turn"),
2687 pcity->surplus[O_TRADE]);
2688
2691
2693
2694 dest.x = pwindow->size.x + adj_size(200);
2695 dest.y = pwindow->size.y + adj_size(298) + (adj_size(15) - buf->h) / 2;
2696
2697 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2698
2700
2701 /* Draw total (trade - corruption) */
2702 if (pcity->surplus[O_TRADE]) {
2703 dest.y =
2704 pwindow->size.y + adj_size(316) + (adj_size(16) - icons->big_trade->h) / 2;
2705 dest.x = pwindow->size.x + adj_size(203);
2706
2707 if (((icons->big_trade->w + 1) * pcity->surplus[O_TRADE]) > adj_size(200)) {
2708 step = (adj_size(200) - icons->big_trade->w) / (pcity->surplus[O_TRADE] - 1);
2709 } else {
2710 step = icons->big_trade->w + 1;
2711 }
2712
2713 for (i = 0; i < pcity->surplus[O_TRADE]; i++) {
2714 alphablit(icons->big_trade, NULL, pwindow->dst->surface, &dest, 255);
2715 dest.x += step;
2716 }
2717 }
2718
2719 /* Corruption label */
2720 fc_snprintf(cbuf, sizeof(cbuf), _("Corruption: %d"),
2721 pcity->waste[O_TRADE]);
2722
2725
2727
2728 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2729 dest.y = pwindow->size.y + adj_size(298) + (adj_size(15) - buf->h) / 2;
2730
2731 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2732
2734
2735 /* Draw corruption */
2736 if (pcity->waste[O_TRADE] > 0) {
2737 dest.x = pwindow->size.x + adj_size(423);
2738 dest.y =
2739 pwindow->size.y + adj_size(316) + (adj_size(16) - icons->big_trade->h) / 2;
2740
2741 if (((icons->big_trade_corr->w + 1) * pcity->waste[O_TRADE]) > adj_size(30)) {
2742 step =
2743 (adj_size(30) - icons->big_trade_corr->w) / (pcity->waste[O_TRADE] - 1);
2744 } else {
2745 step = icons->big_trade_corr->w + 1;
2746 }
2747
2748 for (i = 0; i < pcity->waste[O_TRADE]; i++) {
2750 &dest, 255);
2751 dest.x -= step;
2752 }
2753 }
2754
2755 /* ================================================================= */
2756 /* Gold label */
2757 fc_snprintf(cbuf, sizeof(cbuf), _("Gold: %d (%d) per turn"),
2758 pcity->surplus[O_GOLD], pcity->prod[O_GOLD]);
2759
2762
2764
2765 dest.x = pwindow->size.x + adj_size(200);
2766 dest.y = pwindow->size.y + adj_size(342) + (adj_size(15) - buf->h) / 2;
2767
2768 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2769
2771
2772 /* Draw coins */
2773 count = pcity->surplus[O_GOLD];
2774 if (count) {
2775
2776 if (count > 0) {
2777 buf = icons->big_coin;
2778 } else {
2779 count *= -1;
2781 }
2782
2783 dest.y = pwindow->size.y + adj_size(359) + (adj_size(16) - buf->h) / 2;
2784 dest.x = pwindow->size.x + adj_size(203);
2785
2786 if ((buf->w * count) > adj_size(110)) {
2787 step = (adj_size(110) - buf->w) / (count - 1);
2788 if (!step) {
2789 step = 1;
2790 count = 97;
2791 }
2792 } else {
2793 step = buf->w;
2794 }
2795
2796 for (i = 0; i < count; i++) {
2797 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2798 dest.x += step;
2799 }
2800
2801 }
2802
2803 /* Upkeep label */
2804 fc_snprintf(cbuf, sizeof(cbuf), _("Upkeep: %d"),
2805 pcity->prod[O_GOLD] - pcity->surplus[O_GOLD]);
2806
2809
2811
2812 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2813 dest.y = pwindow->size.y + adj_size(342) + (adj_size(15) - buf->h) / 2;
2814
2815 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2816
2818
2819 /* Draw upkeep */
2820 count = pcity->surplus[O_GOLD];
2821 if (pcity->prod[O_GOLD] - count) {
2822
2823 dest.x = pwindow->size.x + adj_size(423);
2824 dest.y = pwindow->size.y + adj_size(359)
2825 + (adj_size(16) - icons->big_coin_upkeep->h) / 2;
2826
2827 if (((icons->big_coin_upkeep->w + 1) *
2828 (pcity->prod[O_GOLD] - count)) > adj_size(110)) {
2829 step = (adj_size(110) - icons->big_coin_upkeep->w) /
2830 (pcity->prod[O_GOLD] - count - 1);
2831 } else {
2832 step = icons->big_coin_upkeep->w + 1;
2833 }
2834
2835 for (i = 0; i < (pcity->prod[O_GOLD] - count); i++) {
2837 &dest, 255);
2838 dest.x -= step;
2839 }
2840 }
2841
2842 /* ================================================================= */
2843 /* Science label */
2844 fc_snprintf(cbuf, sizeof(cbuf), _("Science: %d per turn"),
2845 pcity->prod[O_SCIENCE]);
2846
2849
2851
2852 dest.x = pwindow->size.x + adj_size(200);
2853 dest.y = pwindow->size.y + adj_size(376) + (adj_size(15) - buf->h) / 2;
2854
2855 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2856
2858
2859 /* Draw colb */
2860 count = pcity->prod[O_SCIENCE];
2861 if (count) {
2862
2863 dest.y =
2864 pwindow->size.y + adj_size(394) + (adj_size(16) - icons->big_colb->h) / 2;
2865 dest.x = pwindow->size.x + adj_size(203);
2866
2867 if ((icons->big_colb->w * count) > adj_size(235)) {
2868 step = (adj_size(235) - icons->big_colb->w) / (count - 1);
2869 if (!step) {
2870 step = 1;
2871 count = 222;
2872 }
2873 } else {
2874 step = icons->big_colb->w;
2875 }
2876
2877 for (i = 0; i < count; i++) {
2878 alphablit(icons->big_colb, NULL, pwindow->dst->surface, &dest, 255);
2879 dest.x += step;
2880 }
2881 }
2882
2883 /* ================================================================= */
2884 /* Luxury label */
2885 fc_snprintf(cbuf, sizeof(cbuf), _("Luxury: %d per turn"),
2886 pcity->prod[O_LUXURY]);
2887
2890
2892
2893 dest.x = pwindow->size.x + adj_size(200);
2894 dest.y = pwindow->size.y + adj_size(412) + (adj_size(15) - buf->h) / 2;
2895
2896 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2897
2899
2900 /* Draw luxury */
2901 if (pcity->prod[O_LUXURY]) {
2902
2903 dest.y =
2904 pwindow->size.y + adj_size(429) + (adj_size(16) - icons->big_luxury->h) / 2;
2905 dest.x = pwindow->size.x + adj_size(203);
2906
2907 if ((icons->big_luxury->w * pcity->prod[O_LUXURY]) > adj_size(235)) {
2908 step =
2909 (adj_size(235) - icons->big_luxury->w) / (pcity->prod[O_LUXURY] - 1);
2910 } else {
2911 step = icons->big_luxury->w;
2912 }
2913
2914 for (i = 0; i < pcity->prod[O_LUXURY]; i++) {
2915 alphablit(icons->big_luxury, NULL, pwindow->dst->surface, &dest, 255);
2916 dest.x += step;
2917 }
2918 }
2919
2920 /* ================================================================= */
2921 /* Turns to grow label */
2922 count = city_turns_to_grow(pcity);
2923 if (count == 0) {
2924 fc_snprintf(cbuf, sizeof(cbuf), _("City growth: blocked"));
2925 } else if (count == FC_INFINITY) {
2926 fc_snprintf(cbuf, sizeof(cbuf), _("City growth: never"));
2927 } else if (count < 0) {
2928 /* Turns until famine */
2929 fc_snprintf(cbuf, sizeof(cbuf),
2930 _("City shrinks: %d %s"), abs(count),
2931 PL_("turn", "turns", abs(count)));
2932 } else {
2933 fc_snprintf(cbuf, sizeof(cbuf),
2934 _("City growth: %d %s"), count,
2935 PL_("turn", "turns", count));
2936 }
2937
2939
2941
2943
2944 dest.x = pwindow->size.x + adj_size(445) + (adj_size(192) - buf->w) / 2;
2945 dest.y = pwindow->size.y + adj_size(227);
2946
2947 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2948
2950
2951 count = (city_granary_size(city_size_get(pcity))) / 10;
2952
2953 if (count > 12) {
2954 step = (adj_size(168) - icons->big_food->h) / adj_size((11 + count - 12));
2955 i = (count - 1) * step + 14;
2956 } else {
2957 step = icons->big_food->h;
2958 i = count * step;
2959 }
2960
2961 /* food stock */
2962
2963 if (get_city_bonus(pcity, EFT_GROWTH_FOOD) > 0) {
2964 /* with granary */
2965 /* stocks label */
2966 copy_chars_to_utf8_str(pstr, _("Stock"));
2968
2969 dest.x = pwindow->size.x + adj_size(461) + (adj_size(76) - buf->w) / 2;
2970 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
2971
2972 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2973
2975
2976 /* granary label */
2977 copy_chars_to_utf8_str(pstr, _("Granary"));
2979
2980 dest.x = pwindow->size.x + adj_size(549) + (adj_size(76) - buf->w) / 2;
2981 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
2982
2983 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2984
2986
2987 /* draw bcgd granary */
2988 dest.x = pwindow->size.x + adj_size(462);
2989 dest.y = pwindow->size.y + adj_size(260);
2990 dest.w = 70 + 4;
2991 dest.h = i + 4;
2992
2993 fill_rect_alpha(pwindow->dst->surface, &dest,
2995
2996 create_frame(pwindow->dst->surface,
2997 dest.x - 1, dest.y - 1, dest.w, dest.h,
2999
3000 /* draw bcgd stocks*/
3001 dest.x = pwindow->size.x + adj_size(550);
3002 dest.y = pwindow->size.y + adj_size(260);
3003
3004 fill_rect_alpha(pwindow->dst->surface, &dest,
3006
3007 create_frame(pwindow->dst->surface,
3008 dest.x - 1, dest.y - 1, dest.w, dest.h,
3010
3011 /* draw stocks icons */
3013 if (pcity->food_stock + pcity->surplus[O_FOOD] > cost) {
3014 count = cost;
3015 } else {
3016 if (pcity->surplus[O_FOOD] < 0) {
3017 count = pcity->food_stock;
3018 } else {
3019 count = pcity->food_stock + pcity->surplus[O_FOOD];
3020 }
3021 }
3022 cost /= 2;
3023
3024 if (pcity->surplus[O_FOOD] < 0) {
3025 limit = pcity->food_stock + pcity->surplus[O_FOOD];
3026 if (limit < 0) {
3027 limit = 0;
3028 }
3029 } else {
3030 limit = 0xffff;
3031 }
3032
3033 dest.x += 2;
3034 dest.y += 2;
3035 i = 0;
3036 buf = icons->big_food;
3037 while (count && cost) {
3038 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3039 dest.x += buf->w;
3040 count--;
3041 cost--;
3042 i++;
3043 if (dest.x > pwindow->size.x + adj_size(620)) {
3044 dest.x = pwindow->size.x + adj_size(552);
3045 dest.y += step;
3046 }
3047 if (i > limit - 1) {
3049 } else {
3050 if (i > pcity->food_stock - 1) {
3052 }
3053 }
3054 }
3055 /* draw granary icons */
3056 dest.x = pwindow->size.x + adj_size(462) + adj_size(2);
3057 dest.y = pwindow->size.y + adj_size(260) + adj_size(2);
3058
3059 while (count) {
3060 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3061 dest.x += buf->w;
3062 count--;
3063 i++;
3064 if (dest.x > pwindow->size.x + adj_size(532)) {
3065 dest.x = pwindow->size.x + adj_size(464);
3066 dest.y += step;
3067 }
3068 if (i > limit - 1) {
3070 } else {
3071 if (i > pcity->food_stock - 1) {
3073 }
3074 }
3075 }
3076
3077 } else {
3078 /* without granary */
3079 /* stocks label */
3080 copy_chars_to_utf8_str(pstr, _("Stock"));
3082
3083 dest.x = pwindow->size.x + adj_size(461) + (adj_size(144) - buf->w) / 2;
3084 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
3085
3086 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3088
3089 /* food stock */
3090
3091 /* draw bcgd */
3092 dest.x = pwindow->size.x + adj_size(462);
3093 dest.y = pwindow->size.y + adj_size(260);
3094 dest.w = adj_size(144);
3095 dest.h = i + adj_size(4);
3096
3097 fill_rect_alpha(pwindow->dst->surface, &dest,
3099
3100 create_frame(pwindow->dst->surface,
3101 dest.x - 1, dest.y - 1, dest.w, dest.h,
3103
3104 /* draw icons */
3106 if (pcity->food_stock + pcity->surplus[O_FOOD] > cost) {
3107 count = cost;
3108 } else {
3109 if (pcity->surplus[O_FOOD] < 0) {
3110 count = pcity->food_stock;
3111 } else {
3112 count = pcity->food_stock + pcity->surplus[O_FOOD];
3113 }
3114 }
3115
3116 if (pcity->surplus[O_FOOD] < 0) {
3117 limit = pcity->food_stock + pcity->surplus[O_FOOD];
3118 if (limit < 0) {
3119 limit = 0;
3120 }
3121 } else {
3122 limit = 0xffff;
3123 }
3124
3125 dest.x += adj_size(2);
3126 dest.y += adj_size(2);
3127 i = 0;
3128 buf = icons->big_food;
3129 while (count) {
3130 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3131 dest.x += buf->w;
3132 count--;
3133 i++;
3134 if (dest.x > pwindow->size.x + adj_size(602)) {
3135 dest.x = pwindow->size.x + adj_size(464);
3136 dest.y += step;
3137 }
3138 if (i > limit - 1) {
3140 } else {
3141 if (i > pcity->food_stock - 1) {
3143 }
3144 }
3145 }
3146 }
3147 /* ================================================================= */
3148
3149 /* draw productions shields progress */
3150 if (VUT_UTYPE == pcity->production.kind) {
3151 const struct unit_type *punittype = pcity->production.value.utype;
3152
3153 cost = utype_build_shield_cost(pcity, NULL, punittype);
3154 count = cost / 10;
3155
3157 buf = create_text_surf_from_utf8(pstr);
3158
3159 buf2 = get_unittype_surface(punittype, direction8_invalid());
3160 buf2 = zoomSurface(buf2, DEFAULT_ZOOM * ((float)32 / buf2->h),
3161 DEFAULT_ZOOM * ((float)32 / buf2->h), 1);
3162
3163 /* blit unit icon */
3164 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - (buf->w + buf2->w + adj_size(5))) / 2;
3165 dest.y = pwindow->size.y + adj_size(233);
3166
3167 alphablit(buf2, NULL, pwindow->dst->surface, &dest, 255);
3168
3169 dest.y += (buf2->h - buf->h) / 2;
3170 dest.x += buf2->w + adj_size(5);
3171
3172 } else {
3173 const struct impr_type *pimprove = pcity->production.value.building;
3174
3175 if (improvement_has_flag(pimprove, IF_GOLD)) {
3176
3181 }
3182
3183 /* You can't see capitalization progress */
3184 count = 0;
3185
3186 } else {
3187
3188 if (city_can_buy(pcity) && pcity_dlg->buy_button
3192 }
3193
3194 cost = impr_build_shield_cost(pcity, pimprove);
3195 count = cost / 10;
3196 }
3197
3199 buf = create_text_surf_from_utf8(pstr);
3200
3202 buf2 = zoomSurface(buf2, DEFAULT_ZOOM * ((float)32 / buf2->h),
3203 DEFAULT_ZOOM * ((float)32 / buf2->h), 1);
3204
3205 /* blit impr icon */
3206 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - (buf->w + buf2->w + adj_size(5))) / 2;
3207 dest.y = pwindow->size.y + adj_size(233);
3208
3209 alphablit(buf2, NULL, pwindow->dst->surface, &dest, 255);
3210
3211 dest.y += (buf2->h - buf->h) / 2;
3212 dest.x += buf2->w + adj_size(5);
3213 }
3214
3215 /* blit unit/impr name */
3216 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3217
3218 FREESURFACE(buf);
3219 FREESURFACE(buf2);
3220
3221 if (count) {
3222 if (count > 11) {
3223 step = (adj_size(154) - icons->big_shield->h) / adj_size((10 + count - 11));
3224
3225 if (!step) {
3226 step = 1;
3227 }
3228
3229 i = (step * (count - 1)) + icons->big_shield->h;
3230 } else {
3231 step = icons->big_shield->h;
3232 i = count * step;
3233 }
3234
3235 /* draw shield stock background */
3236 dest.x = pwindow->size.x + adj_size(28);
3237 dest.y = pwindow->size.y + adj_size(270);
3238 dest.w = adj_size(144);
3239 dest.h = i + adj_size(4);
3240
3241 fill_rect_alpha(pwindow->dst->surface, &dest,
3243
3244 create_frame(pwindow->dst->surface,
3245 dest.x - 1, dest.y - 1, dest.w, dest.h,
3247
3248 /* draw production progress text */
3249 dest.y = pwindow->size.y + adj_size(270) + dest.h + 1;
3250
3251 if (pcity->shield_stock < cost) {
3252 count = city_production_turns_to_build(pcity, TRUE);
3253 if (count == 999) {
3254 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %s!",
3255 pcity->shield_stock, cost, _("blocked"));
3256 } else {
3257 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %d %s",
3258 pcity->shield_stock, cost, count, PL_("turn", "turns", count));
3259 }
3260 } else {
3261 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %s!",
3262 pcity->shield_stock, cost, _("finished"));
3263 }
3264
3265 copy_chars_to_utf8_str(pstr, cbuf);
3267
3268 buf = create_text_surf_from_utf8(pstr);
3269
3270 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - buf->w) / 2;
3271
3272 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3273
3274 FREEUTF8STR(pstr);
3275 FREESURFACE(buf);
3276
3277 /* draw shield stock */
3278 if (pcity->shield_stock + pcity->surplus[O_SHIELD] <= cost) {
3279 count = pcity->shield_stock + pcity->surplus[O_SHIELD];
3280 } else {
3281 count = cost;
3282 }
3283 dest.x = pwindow->size.x + adj_size(29) + adj_size(2);
3284 dest.y = pwindow->size.y + adj_size(270) + adj_size(2);
3285 i = 0;
3286
3287 buf = icons->big_shield;
3288 while (count > 0) {
3289 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3290 dest.x += buf->w;
3291 count--;
3292 if (dest.x > pwindow->size.x + adj_size(170)) {
3293 dest.x = pwindow->size.x + adj_size(31);
3294 dest.y += step;
3295 }
3296 i++;
3297 if (i > pcity->shield_stock - 1) {
3299 }
3300 }
3301 }
3302
3303 /* count != 0 */
3304 /* ==================================================== */
3305 /* Draw Citizens */
3308 + city_specialists(pcity));
3309
3311
3312 if (count > 13) {
3313 step = (adj_size(440) - buf->w) / (adj_size(12 + count - 13));
3314 } else {
3315 step = buf->w;
3316 }
3317
3319
3320 dest.x = pwindow->size.x + adj_size(198);
3321 dest.y = pwindow->size.y + pwindow->area.y + adj_size(1) + (adj_size(22) - buf->h) / 2;
3322 pcity_dlg->spec_area.x = pwindow->dst->dest_rect.x + dest.x;
3323 pcity_dlg->spec_area.y = pwindow->dst->dest_rect.y + dest.y;
3324 pcity_dlg->spec_area.w = count * step;
3325 pcity_dlg->spec_area.h = buf->h;
3326
3327 if (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]) {
3328 for (i = 0; i < pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]; i++) {
3330
3331 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3332 dest.x += step;
3333 FREESURFACE(buf);
3334 }
3335 }
3336
3337 if (pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]) {
3338 for (i = 0; i < pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]; i++) {
3340
3341 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3342 dest.x += step;
3343 FREESURFACE(buf);
3344 }
3345 }
3346
3347 if (pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]) {
3348 for (i = 0; i < pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]; i++) {
3350
3351 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3352 dest.x += step;
3353 FREESURFACE(buf);
3354 }
3355 }
3356
3357 if (pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]) {
3358 for (i = 0; i < pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]; i++) {
3360
3361 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3362 dest.x += step;
3363 FREESURFACE(buf);
3364 }
3365 }
3366
3367 spe_max = specialist_count();
3368 for (spe = 0; spe < spe_max; spe++) {
3369 if (pcity->specialists[spe] > 0) {
3371
3372 for (i = 0; i < pcity->specialists[spe]; i++) {
3373 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3374 dest.x += step;
3375 }
3376 FREESURFACE(buf);
3377 }
3378 }
3379
3380 /* ==================================================== */
3381
3382
3383 switch (pcity_dlg->page) {
3384 case INFO_PAGE:
3385 redraw_info_city_dialog(pwindow, pcity);
3386 break;
3387
3388 case HAPPINESS_PAGE:
3389 redraw_happiness_city_dialog(pwindow, pcity);
3390 break;
3391
3392 case ARMY_PAGE:
3393 redraw_army_city_dialog(pwindow, pcity);
3394 break;
3395
3396 case SUPPORTED_UNITS_PAGE:
3397 redraw_supported_units_city_dialog(pwindow, pcity);
3398 break;
3399
3400 case MISC_PAGE:
3401 redraw_misc_city_dialog(pwindow, pcity);
3402 break;
3403
3404 default:
3405 break;
3406
3407 }
3408
3409 /* redraw "sell improvement" dialog */
3412
3413 widget_mark_dirty(pwindow);
3414}
3415
3416/* ============================================================== */
3417
3418/**********************************************************************/
3421static void rebuild_imprm_list(struct city *pcity)
3422{
3423 int count = 0;
3424 struct widget *pwindow = pcity_dlg->end_city_widget_list;
3425 struct widget *add_dock, *buf, *last;
3427 utf8_str *pstr = NULL;
3428 struct player *owner = city_owner(pcity);
3429 int prev_y = 0;
3430
3431 if (!pcity_dlg->imprv) {
3432 pcity_dlg->imprv = fc_calloc(1, sizeof(struct advanced_dialog));
3433 }
3434
3435 /* free old list */
3445 }
3446
3447 add_dock = pcity_dlg->add_point;
3448 buf = last = add_dock;
3449
3450 /* Alloc new */
3451 city_built_iterate(pcity, pimprove) {
3453 city_improvement_name_translation(pcity, pimprove),
3456
3457 pstr->style |= TTF_STYLE_BOLD;
3458
3459 logo = get_building_surface(pimprove);
3460 logo = resize_surface_box(logo, adj_size(22), adj_size(22), 1, TRUE, TRUE);
3461
3462 buf = create_iconlabel(logo, pwindow->dst, pstr,
3464
3465 buf->size.x = pwindow->size.x + adj_size(450);
3466 buf->size.y = pwindow->size.y + adj_size(66) + prev_y;
3467
3468 prev_y += buf->size.h;
3469
3470 buf->size.w = adj_size(165);
3472
3473 if (!pcity_dlg->pcity->did_sell
3474 && !is_wonder(pimprove) && (owner == client.conn.playing)) {
3476 }
3477
3478 buf->id = MAX_ID - improvement_number(pimprove) - 3000;
3479 widget_add_as_prev(buf, add_dock);
3480 add_dock = buf;
3481
3482 count++;
3483
3484 if (count > 7) {
3485 set_wflag(buf, WF_HIDDEN);
3486 }
3487
3489
3490 if (count) {
3495
3496 if (count > 7) {
3498
3500
3502 pwindow->size.x + adj_size(635),
3503 pwindow->size.y + adj_size(66),
3504 adj_size(155), TRUE);
3505 }
3506 }
3507}
3508
3509/**********************************************************************/
3512static void rebuild_citydlg_title_str(struct widget *pwindow,
3513 struct city *pcity)
3514{
3515 char cbuf[512];
3516
3517 fc_snprintf(cbuf, sizeof(cbuf),
3518 _("City of %s (Population %s citizens)"),
3519 city_name_get(pcity),
3521
3522 if (city_unhappy(pcity)) {
3523 /* TRANS: preserve leading space */
3524 fc_strlcat(cbuf, _(" - DISORDER"), sizeof(cbuf));
3525 } else {
3526 if (city_celebrating(pcity)) {
3527 /* TRANS: preserve leading space */
3528 fc_strlcat(cbuf, _(" - celebrating"), sizeof(cbuf));
3529 } else {
3530 if (city_happy(pcity)) {
3531 /* TRANS: preserve leading space */
3532 fc_strlcat(cbuf, _(" - happy"), sizeof(cbuf));
3533 }
3534 }
3535 }
3536
3537 if (cma_is_city_under_agent(pcity, NULL)) {
3538 /* TRANS: preserve leading space */
3539 fc_strlcat(cbuf, _(" - under Citizen Governor control."), sizeof(cbuf));
3540 }
3541
3542 copy_chars_to_utf8_str(pwindow->string_utf8, cbuf);
3543}
3544
3545
3546/* ========================= Public ================================== */
3547
3548/**********************************************************************/
3552void real_city_dialog_popup(struct city *pcity)
3553{
3554 struct widget *pwindow = NULL, *buf = NULL;
3556 utf8_str *pstr = NULL;
3557 int cs;
3558 struct player *owner = city_owner(pcity);
3559 SDL_Rect area;
3560
3561 if (pcity_dlg) {
3562 return;
3563 }
3564
3565 menus_update();
3566
3567 pcity_dlg = fc_calloc(1, sizeof(struct city_dialog));
3568 pcity_dlg->pcity = pcity;
3569 pcity_dlg->page = ARMY_PAGE;
3570
3571 pstr = create_utf8_str_fonto(NULL, 0, FONTO_ATTENTION);
3572 pstr->style |= TTF_STYLE_BOLD;
3573 pwindow = create_window(NULL, pstr, adj_size(640), adj_size(480), 0);
3574
3575 rebuild_citydlg_title_str(pwindow, pcity);
3576
3577 pwindow->action = city_dlg_callback;
3578 set_wstate(pwindow, FC_WS_NORMAL);
3579
3581
3583
3584 /* create window background */
3586 if (resize_window(pwindow, logo, NULL, adj_size(640), adj_size(480))) {
3587 FREESURFACE(logo);
3588 }
3589
3590 logo = get_city_gfx();
3591 alphablit(logo, NULL, pwindow->theme, NULL, 255);
3592
3593 area = pwindow->area;
3594
3595 widget_set_position(pwindow,
3596 (main_window_width() - pwindow->size.w) / 2,
3597 (main_window_height() - pwindow->size.h) / 2);
3598
3599 /* ============================================================= */
3600
3601 /* Close dialog button */
3602 buf = create_themeicon(current_theme->small_cancel_icon, pwindow->dst,
3604 buf->info_label = create_utf8_from_char_fonto(_("Close Dialog (Esc)"),
3606 buf->action = exit_city_dlg_callback;
3607 buf->size.x = area.x + area.w - buf->size.w;
3608 buf->size.y = pwindow->size.y + adj_size(2);
3609 buf->key = SDLK_ESCAPE;
3612
3613 /* -------- */
3614
3615 buf = create_themeicon(current_theme->army_icon, pwindow->dst,
3617 buf->info_label = create_utf8_from_char_fonto(_("Present units"),
3619 buf->action = army_city_dlg_callback;
3620 buf->size.x = area.x + adj_size(2) + ((adj_size(183) - 5 * buf->size.w) / 6);
3621 buf->size.y = area.y + adj_size(2);
3624 /* -------- */
3625
3626 buf = create_themeicon(current_theme->support_icon, pwindow->dst,
3628 buf->info_label = create_utf8_from_char_fonto(_("Supported units"),
3631 buf->size.x =
3632 area.x + adj_size(2) + 2 * ((adj_size(183) - 5 * buf->size.w) / 6) + buf->size.w;
3633 buf->size.y = area.y + adj_size(2);
3634
3637 /* -------- */
3638
3639 buf = create_themeicon(current_theme->happy_icon, pwindow->dst,
3641 buf->info_label = create_utf8_from_char_fonto(_("Happiness"),
3643 buf->action = happy_city_dlg_callback;
3644 buf->size.x
3645 = area.x + adj_size(2) + 3 * ((adj_size(183) - 5 * buf->size.w) / 6) + 2 * buf->size.w;
3646 buf->size.y = area.y + adj_size(2);
3649 /* -------- */
3650
3651 buf = create_themeicon(current_theme->info_icon, pwindow->dst,
3653 buf->info_label = create_utf8_from_char_fonto(_("City info"),
3655 buf->action = info_city_dlg_callback;
3656 buf->size.x
3657 = area.x + adj_size(4) + 4 * ((adj_size(183) - 5 * buf->size.w) / 6) + 3 * buf->size.w;
3658 buf->size.y = area.y + adj_size(2);
3661
3662 pcity_dlg->add_point = buf;
3664 /* ===================================================== */
3665 rebuild_imprm_list(pcity);
3666 /* ===================================================== */
3667
3668 logo = get_scaled_city_map(pcity);
3669
3670 buf = create_themelabel(logo, pwindow->dst, NULL,
3671 logo->w, logo->h, WF_SELECT_WITHOUT_BAR);
3672
3673 pcity_dlg->resource_map = buf;
3674
3676 if (!cma_is_city_under_agent(pcity, NULL) && (owner == client.conn.playing)) {
3678 }
3679 buf->size.x = area.x + adj_size(193) + (adj_size(249) - buf->size.w) / 2;
3680 buf->size.y = area.y + adj_size(41) + (adj_size(158) - buf->size.h) / 2;
3682 /* -------- */
3683
3684 buf = create_themeicon(current_theme->options_icon, pwindow->dst,
3686 buf->info_label = create_utf8_from_char_fonto(_("City options"),
3688 buf->action = options_city_dlg_callback;
3689 buf->size.x
3690 = area.x + adj_size(4) + 5 * ((adj_size(183) - 5 * buf->size.w) / 6) + 4 * buf->size.w;
3691 buf->size.y = area.y + adj_size(2);
3692 if (owner == client.conn.playing) {
3694 }
3696 /* -------- */
3697
3698 buf = create_themeicon(current_theme->prod_icon, pwindow->dst,
3700 buf->info_label = create_utf8_from_char_fonto(_("Change production"),
3702 buf->action = change_prod_dlg_callback;
3703 buf->size.x = area.x + adj_size(7);
3704 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3705 if (owner == client.conn.playing) {
3707 }
3708 buf->key = SDLK_c;
3710 /* -------- */
3711
3712 buf = create_themeicon(current_theme->buy_prod_icon, pwindow->dst,
3714 buf->info_label = create_utf8_from_char_fonto(_("Hurry production"),
3716 buf->action = buy_prod_city_dlg_callback;
3717 buf->size.x = area.x + adj_size(7) + (buf->size.w + adj_size(2));
3718 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3719 pcity_dlg->buy_button = buf;
3720 buf->key = SDLK_h;
3721 if (city_can_buy(pcity)) {
3723 }
3725 /* -------- */
3726
3727 buf = create_themeicon(current_theme->cma_icon, pwindow->dst,
3729 buf->info_label = create_utf8_from_char_fonto(_("Citizen Governor"),
3731 buf->action = cma_city_dlg_callback;
3732 buf->key = SDLK_a;
3733 buf->size.x = area.x + adj_size(7) + (buf->size.w + adj_size(2)) * 2;
3734 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3735 if (owner == client.conn.playing) {
3737 }
3739
3740
3741 /* -------- */
3742 buf = create_themeicon(current_theme->l_arrow_icon, pwindow->dst,
3744 buf->info_label = create_utf8_from_char_fonto(_("Previous city"),
3746 buf->action = next_prev_city_dlg_callback;
3747 buf->size.x = area.x + adj_size(220) - buf->size.w - adj_size(8);
3748 buf->size.y = area.y + area.h - buf->size.h;
3749 if (owner == client.conn.playing) {
3751 }
3752 buf->key = SDLK_LEFT;
3753 buf->mod = KMOD_LSHIFT;
3755 /* -------- */
3756
3757 buf = create_themeicon(current_theme->r_arrow_icon, pwindow->dst,
3759 buf->info_label = create_utf8_from_char_fonto(_("Next city"),
3761 buf->action = next_prev_city_dlg_callback;
3762 buf->size.x = area.x + adj_size(420) + adj_size(2);
3763 buf->size.y = area.y + area.h - buf->size.h;
3764 if (owner == client.conn.playing) {
3766 }
3767 buf->key = SDLK_RIGHT;
3768 buf->mod = KMOD_LSHIFT;
3770 /* -------- */
3771
3772 buf = create_edit_from_chars_fonto(NULL, pwindow->dst, city_name_get(pcity),
3773 FONTO_DEFAULT, adj_size(200),
3775 buf->action = new_name_city_dlg_callback;
3776 buf->size.x = area.x + (area.w - buf->size.w) / 2;
3777 buf->size.y = area.y + area.h - buf->size.h - adj_size(2);
3778 if (owner == client.conn.playing) {
3780 }
3781
3784
3786
3787 /* check if Citizen Icons style was loaded */
3788 cs = style_of_city(pcity);
3789
3790 if (cs != icons->style) {
3792 }
3793
3794 /* ===================================================== */
3795 if ((city_unhappy(pcity) || city_celebrating(pcity)
3796 || city_happy(pcity))) {
3798 }
3799 /* ===================================================== */
3800
3801 redraw_city_dialog(pcity);
3802 flush_dirty();
3803}
3804
3805/**********************************************************************/
3808void popdown_city_dialog(struct city *pcity)
3809{
3810 if (city_dialog_is_open(pcity)) {
3812
3813 flush_dirty();
3814
3815 sdl2_client_flags &= ~CF_CITY_STATUS_SPECIAL;
3816 menus_update();
3817 }
3818}
3819
3820/**********************************************************************/
3824{
3825 if (pcity_dlg) {
3827 }
3828}
3829
3830/**********************************************************************/
3834{
3835 if (city_dialog_is_open(pcity)) {
3837 flush_dirty();
3838 }
3839}
3840
3841/**********************************************************************/
3847{
3848 struct city *city_sup = game_city_by_number(punit->homecity);
3849 struct city *city_pre = tile_city(unit_tile(punit));
3850
3851 if (pcity_dlg && ((pcity_dlg->pcity == city_sup)
3852 || (pcity_dlg->pcity == city_pre))) {
3855 flush_dirty();
3856 }
3857}
3858
3859/**********************************************************************/
3862bool city_dialog_is_open(struct city *pcity)
3863{
3864 return (pcity_dlg && (pcity_dlg->pcity == pcity));
3865}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1910
void astr_free(struct astring *astr)
Definition astring.c:153
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_CLR(bv, bit)
Definition bitvector.h:86
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:658
int city_granary_size(int city_size)
Definition city.c:2101
int city_unit_unhappiness(struct unit *punit, int *free_unhappy)
Definition city.c:2940
const char * city_name_get(const struct city *pcity)
Definition city.c:1111
int city_population(const struct city *pcity)
Definition city.c:1165
int city_production_turns_to_build(const struct city *pcity, bool include_shield_stock)
Definition city.c:805
bool city_unhappy(const struct city *pcity)
Definition city.c:1595
bool city_celebrating(const struct city *pcity)
Definition city.c:1614
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2769
bool city_happy(const struct city *pcity)
Definition city.c:1583
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
citizens city_specialists(const struct city *pcity)
Definition city.c:3226
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1965
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:695
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
@ CITIZEN_SPECIALIST
Definition city.h:265
@ CITIZEN_ANGRY
Definition city.h:263
@ CITIZEN_HAPPY
Definition city.h:260
@ CITIZEN_CONTENT
Definition city.h:261
@ CITIZEN_UNHAPPY
Definition city.h:262
#define city_owner(_pcity_)
Definition city.h:543
@ FEELING_FINAL
Definition city.h:276
@ FEELING_LAST
Definition city.h:277
#define city_built_iterate(_pcity, _p)
Definition city.h:801
#define city_built_iterate_end
Definition city.h:807
int city_rename(struct city *pcity, const char *name)
int city_buy_production(struct city *pcity)
int city_toggle_worker(struct city *pcity, int city_x, int city_y)
void city_rotate_specialist(struct city *pcity, int citizen_index)
bool canvas_to_city_pos(int *city_x, int *city_y, int city_radius_sq, int canvas_x, int canvas_y)
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
bool city_can_buy(const struct city *pcity)
struct civclient client
bool can_client_issue_orders(void)
#define client_player()
struct city * get_nearest_city(const struct unit *punit, int *sq_dist)
Definition climisc.c:1101
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:550
void request_unit_fortify(struct unit *punit)
Definition control.c:2213
void unit_focus_set(struct unit *punit)
Definition control.c:502
void request_unit_change_homecity(struct unit *punit)
Definition control.c:1994
void request_unit_sentry(struct unit *punit)
Definition control.c:2202
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:40
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:73
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
int int id
Definition editgui_g.h:28
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
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:1075
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:587
#define effect_list_iterate_end
Definition effects.h:375
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
QString current_theme
Definition fc_client.cpp:65
#define MAX_LEN_NAME
Definition fc_types.h:66
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
@ O_TRADE
Definition fc_types.h:91
@ O_SCIENCE
Definition fc_types.h:91
@ O_LUXURY
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * population_to_text(int thousand_citizen)
Definition game.c:714
struct civ_game game
Definition game.c:57
struct city * game_city_by_number(int id)
Definition game.c:102
void canvas_free(struct canvas *store)
Definition canvas.c:44
struct canvas * canvas_create(int width, int height)
Definition canvas.c:28
void real_city_dialog_popup(struct city *pcity)
Definition citydlg.c:558
bool city_dialog_is_open(struct city *pcity)
Definition citydlg.c:579
void real_city_dialog_refresh(struct city *pcity)
Definition citydlg.c:481
void popdown_all_city_dialogs(void)
Definition citydlg.c:599
void refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.c:538
struct city * owner
Definition citydlg.c:219
@ HAPPINESS_PAGE
Definition citydlg.c:111
void popdown_city_dialog(struct city *pcity)
Definition citydlg.c:587
void flush_dirty(void)
Definition mapview.c:450
static int units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:386
static void redraw_supported_units_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1822
static int activate_and_exit_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:274
static int cancel_buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1092
static int units_orders_dlg_callback(struct widget *button)
Definition citydlg.c:378
static int options_city_dlg_callback(struct widget *button)
Definition citydlg.c:1041
static void redraw_city_dialog(struct city *pcity)
Definition citydlg.c:2433
static int army_city_dlg_callback(struct widget *button)
Definition citydlg.c:831
static void rebuild_imprm_list(struct city *pcity)
Definition citydlg.c:3421
static void redraw_happiness_city_dialog(const struct widget *city_window, struct city *pcity)
Definition citydlg.c:2102
static void redraw_misc_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1787
static void redraw_info_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1936
static int new_name_city_dlg_callback(struct widget *pedit)
Definition citydlg.c:1742
static int sell_imprvm_dlg_cancel_callback(struct widget *cancel_button)
Definition citydlg.c:1372
static int next_prev_city_dlg_callback(struct widget *button)
Definition citydlg.c:1668
static void disable_city_dlg_widgets(void)
Definition citydlg.c:1597
static int sell_imprvm_dlg_ok_callback(struct widget *ok_button)
Definition citydlg.c:1389
static SDL_Surface * create_unit_surface(struct unit *punit, bool support, int w, int h)
Definition citydlg.c:619
static int resource_map_city_dlg_callback(struct widget *map)
Definition citydlg.c:1633
static void refresh_city_names(struct city *pcity)
Definition citydlg.c:1767
void enable_city_dlg_widgets(void)
Definition citydlg.c:1534
static int buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1135
static int upgrade_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:363
static int fortify_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:314
static void redraw_army_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1879
static void popdown_hurry_production_dialog(void)
Definition citydlg.c:1150
static int change_prod_dlg_callback(struct widget *button)
Definition citydlg.c:1352
specialist_type
Definition citydlg.c:109
@ SP_SCIENTIST
Definition citydlg.c:110
@ SP_LAST
Definition citydlg.c:110
@ SP_ELVIS
Definition citydlg.c:110
@ SP_TAXMAN
Definition citydlg.c:110
struct impr_type * get_building_for_effect(enum effect_type effect_type)
Definition citydlg.c:132
void popup_hurry_production_dialog(struct city *pcity, SDL_Surface *pdest)
Definition citydlg.c:1175
static void create_city_options_widget_list(struct city *pcity)
Definition citydlg.c:977
static int supported_unit_city_dlg_callback(struct widget *button)
Definition citydlg.c:851
static int city_comp_by_turn_founded(const void *a, const void *b)
Definition citydlg.c:1657
static int activate_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:257
static void popdown_city_menu_dlg(bool enable_city_dialog_widgets)
Definition citydlg.c:146
static struct small_dialog * hurry_prog_dlg
Definition citydlg.c:115
static int hurry_production_window_callback(struct widget *pwindow)
Definition citydlg.c:1163
static void del_city_dialog(void)
Definition citydlg.c:162
static int ok_buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1109
static int cancel_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:239
static void rebuild_citydlg_title_str(struct widget *pwindow, struct city *pcity)
Definition citydlg.c:3512
static int cma_city_dlg_callback(struct widget *button)
Definition citydlg.c:1063
static int homecity_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:346
static int sentry_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:297
static struct city_dialog * pcity_dlg
static int exit_city_dlg_callback(struct widget *button)
Definition citydlg.c:1076
static int sell_imprvm_dlg_callback(struct widget *impr)
Definition citydlg.c:1423
static int info_city_dlg_callback(struct widget *button)
Definition citydlg.c:873
static int disband_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:331
static int happy_city_dlg_callback(struct widget *button)
Definition citydlg.c:894
static int city_dlg_callback(struct widget *pwindow)
Definition citydlg.c:199
static float city_map_zoom
Definition citydlg.c:113
SDL_Surface * get_scaled_city_map(struct city *pcity)
Definition citydlg.c:1619
static int misc_panel_city_dlg_callback(struct widget *pwidget)
Definition citydlg.c:914
void free_city_units_lists(void)
Definition citydlg.c:818
static void create_present_supported_units_widget_list(struct unit_list *units)
Definition citydlg.c:705
bool is_city_report_open(void)
Definition cityrep.c:1130
void popup_city_cma_dialog(struct city *pcity)
Definition cma_fe.c:891
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:44
void put_window_near_map_tile(struct widget *pwindow, int window_width, int window_height, struct tile *ptile)
Definition dialogs.c:108
void popup_unit_disband_dlg(struct unit *punit, bool city)
Definition dialogs.c:875
void popup_unit_upgrade_dlg(struct unit *punit, bool city)
Definition dialogs.c:680
SDL_Rect get_smaller_surface_rect(SDL_Surface *surf)
Definition graphics.c:936
bool is_in_rect_area(int x, int y, SDL_Rect rect)
Definition graphics.c:925
int main_window_width(void)
Definition graphics.c:685
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, SDL_Color *pcolor)
Definition graphics.c:1378
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
struct sdl2_data main_data
Definition graphics.c:57
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1347
int main_window_height(void)
Definition graphics.c:693
SDL_Surface * resize_surface_box(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth, bool scale_up, bool absolute_dimensions)
Definition graphics.c:1256
#define DEFAULT_ZOOM
Definition graphics.h:198
#define FREESURFACE(ptr)
Definition graphics.h:322
#define adj_surf(surf)
Definition graphics.h:200
Uint32 sdl2_client_flags
Definition gui_main.c:97
#define CF_CHANGED_CITY_NAME
Definition gui_main.h:50
struct widget * selected_widget
Definition widget.c:48
#define CF_CITY_STATUS_SPECIAL
Definition gui_main.h:51
#define adj_size(size)
Definition gui_main.h:138
#define PRESSED_EVENT(event)
Definition gui_main.h:68
SDL_Surface * create_city_map(struct city *pcity)
Definition mapview.c:1196
void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
Definition wldlg.c:1050
@ ID_CITY_DLG_HAPPY_BUTTON
Definition gui_id.h:151
@ ID_CITY_DLG_CHANGE_PROD_BUTTON
Definition gui_id.h:160
@ ID_CITY_DLG_PROD_BUY_BUTTON
Definition gui_id.h:162
@ ID_CITY_DLG_WINDOW
Definition gui_id.h:146
@ ID_CITY_DLG_RESOURCE_MAP
Definition gui_id.h:159
@ ID_CITY_DLG_CMA_BUTTON
Definition gui_id.h:163
@ ID_CITY_DLG_NEXT_BUTTON
Definition gui_id.h:165
@ ID_BUTTON
Definition gui_id.h:29
@ ID_CITY_DLG_OPTIONS_BUTTON
Definition gui_id.h:167
@ ID_CITY_DLG_NAME_EDIT
Definition gui_id.h:166
@ ID_CITY_DLG_SUPPORT_BUTTON
Definition gui_id.h:153
@ ID_LABEL
Definition gui_id.h:27
@ ID_CITY_DLG_ARMY_BUTTON
Definition gui_id.h:152
@ ID_WINDOW
Definition gui_id.h:30
@ ID_REVOLUTION_DLG_WINDOW
Definition gui_id.h:141
@ ID_CITY_DLG_EXIT_BUTTON
Definition gui_id.h:147
@ ID_CITY_DLG_INFO_BUTTON
Definition gui_id.h:150
@ ID_CITY_DLG_PREV_BUTTON
Definition gui_id.h:164
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
void change_fonto_utf8(utf8_str *pstr, enum font_origin origin)
Definition gui_string.c:584
utf8_str * create_utf8_str_fonto(char *in_text, size_t n_alloc, enum font_origin origin)
Definition gui_string.c:241
#define FREEUTF8STR(pstr)
Definition gui_string.h:92
#define SF_CENTER
Definition gui_string.h:40
@ FONTO_DEFAULT
Definition gui_string.h:64
@ FONTO_SLIGHTLY_BIGGER
Definition gui_string.h:65
@ FONTO_ATTENTION
Definition gui_string.h:66
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:107
struct city_icon * icons
void reload_citizens_icons(int style)
SDL_Surface * get_city_gfx(void)
static SDL_Surface * get_building_surface(const struct impr_type *pimprove)
static SDL_Surface * get_citizen_surface(enum citizen_category type, int citizen_index)
static SDL_Surface * get_tax_surface(Output_type_id otype)
static SDL_Surface * get_unittype_surface(const struct unit_type *punittype, enum direction8 facing)
struct impr_type * improvement_by_number(const Impr_type_id id)
int impr_sell_gold(const struct impr_type *pimprove)
bool can_city_sell_building(const struct city *pcity, const struct impr_type *pimprove)
Impr_type_id improvement_number(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 improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
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
void put_unit(const struct unit *punit, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
void center_tile_mapcanvas(const struct tile *ptile)
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
void menus_update(void)
const char * move_points_text(int mp, bool reduce)
Definition movement.c:973
int dsend_packet_city_options_req(struct connection *pc, int city_id16, int city_id32, bv_city_options options)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
#define ARRAY_SIZE(x)
Definition shared.h:85
#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
int step
Definition specpq.h:92
size_t size
Definition specvec.h:72
struct widget * active_widget_list
Definition widget.h:186
struct widget * end_widget_list
Definition widget.h:182
struct widget * begin_widget_list
Definition widget.h:181
struct widget * begin_active_widget_list
Definition widget.h:184
struct widget * end_active_widget_list
Definition widget.h:185
struct scroll_bar * scroll
Definition widget.h:187
SDL_Surface * surf
Definition canvas.h:27
struct widget * resource_map
Definition citydlg.c:99
struct widget * city_name_edit
Definition citydlg.c:100
struct widget * add_point
Definition citydlg.c:97
int citizen_step
Definition citydlg.c:102
enum city_dialog::@211 page
bool lock
Definition citydlg.c:106
struct city * pcity
Definition citydlg.c:137
SDL_Rect spec_area
Definition citydlg.c:104
struct widget * begin_city_widget_list
Definition citydlg.c:83
struct widget * buy_button
Definition citydlg.c:98
QPushButton * buy_button
Definition citydlg.h:477
struct advanced_dialog * panel
Definition citydlg.c:90
struct widget * end_city_menu_widget_list
Definition citydlg.c:94
struct advanced_dialog * imprv
Definition citydlg.c:87
struct widget * begin_city_menu_widget_list
Definition citydlg.c:93
@ HAPPINESS_PAGE
Definition citydlg.c:76
@ SUPPORTED_UNITS_PAGE
Definition citydlg.c:78
struct widget * end_city_widget_list
Definition citydlg.c:84
SDL_Surface * coint
SDL_Surface * police
SDL_Surface * shield
SDL_Surface * male_angry
SDL_Surface * big_colb
SDL_Surface * big_coin
SDL_Surface * female_angry
SDL_Surface * big_food_corr
SDL_Surface * big_shield_corr
SDL_Surface * big_coin_corr
SDL_Surface * specialists[SP_MAX]
SDL_Surface * big_food_surplus
SDL_Surface * female_happy
SDL_Surface * big_trade
SDL_Surface * female_content
SDL_Surface * big_coin_upkeep
SDL_Surface * trade
SDL_Surface * big_luxury
SDL_Surface * food
SDL_Surface * female_unhappy
SDL_Surface * male_content
SDL_Surface * face
SDL_Surface * male_happy
SDL_Surface * big_shield
SDL_Surface * big_shield_surplus
SDL_Surface * male_unhappy
SDL_Surface * big_trade_corr
SDL_Surface * big_food
SDL_Surface * pollution
Definition city.h:309
int surplus[O_LAST]
Definition city.h:343
int food_stock
Definition city.h:354
int pollution
Definition city.h:356
bool did_sell
Definition city.h:367
int id
Definition city.h:315
int waste[O_LAST]
Definition city.h:344
struct unit_list * info_units_present
Definition city.h:457
bv_city_options city_options
Definition city.h:389
struct player * owner
Definition city.h:312
int turn_founded
Definition city.h:372
bool did_buy
Definition city.h:366
struct unit_list * info_units_supported
Definition city.h:456
char * name
Definition city.h:310
struct universal production
Definition city.h:382
int buy_cost
Definition city.h:449
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:321
citizens specialists[SP_MAX]
Definition city.h:324
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
int prod[O_LAST]
Definition city.h:346
struct unit_list * units_supported
Definition city.h:391
struct city::@17::@20 client
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:156
SDL_Surface * surface
Definition graphics.h:229
SDL_Rect dest_rect
Definition graphics.h:228
struct city_list * cities
Definition player.h:281
struct widget * up_left_button
struct widget * pscroll_bar
struct widget * down_right_button
SDL_Event event
Definition graphics.h:217
struct widget * begin_widget_list
Definition widget.h:175
struct widget * end_widget_list
Definition widget.h:176
struct unit_list * units
Definition tile.h:57
int defense_strength
Definition unittype.h:496
int move_rate
Definition unittype.h:497
int attack_strength
Definition unittype.h:495
Definition unit.h:138
int upkeep[O_LAST]
Definition unit.h:148
enum unit_activity activity
Definition unit.h:157
int id
Definition unit.h:145
int hp
Definition unit.h:151
enum direction8 facing
Definition unit.h:142
int homecity
Definition unit.h:146
int veteran
Definition unit.h:152
enum universals_n kind
Definition fc_types.h:758
universals_u value
Definition fc_types.h:757
Uint8 style
Definition gui_string.h:53
SDL_Color fgcol
Definition gui_string.h:57
char * text
Definition gui_string.h:60
struct widget * next
Definition widget.h:113
void * ptr
Definition widget.h:133
utf8_str * info_label
Definition widget.h:122
SDL_Keycode key
Definition widget.h:153
union widget::@214 data
struct gui_layer * dst
Definition widget.h:116
struct widget * prev
Definition widget.h:114
int(* action)(struct widget *)
Definition widget.h:157
struct unit * unit
Definition widget.h:129
struct city * city
Definition widget.h:128
struct container * cont
Definition widget.h:127
SDL_Surface * theme
Definition widget.h:118
utf8_str * string_utf8
Definition widget.h:121
SDL_Rect area
Definition widget.h:149
Uint16 id
Definition widget.h:155
SDL_Rect size
Definition widget.h:145
SDL_Surface * theme2
Definition widget.h:119
int style_of_city(const struct city *pcity)
Definition style.c:202
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:832
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define sz_strlcat(dest, src)
Definition support.h:162
const char * get_nearest_city_text(struct city *pcity, int sq_dist)
Definition text.c:474
const char * unit_description(struct unit *punit)
Definition text.c:508
SDL_Surface * theme_get_background(const struct theme *t, enum theme_background background)
@ BACKGROUND_CITYDLG
@ COLOR_THEME_BACKGROUND
Definition themecolors.h:23
@ COLOR_THEME_CITYDLG_INFOPANEL
Definition themecolors.h:58
@ COLOR_THEME_CITYDLG_SELL
Definition themecolors.h:63
@ COLOR_THEME_CITYDLG_FOODPERTURN
Definition themecolors.h:49
@ COLOR_THEME_CITYDLG_IMPR
Definition themecolors.h:57
@ COLOR_THEME_CITYDLG_BUY
Definition themecolors.h:46
@ COLOR_THEME_CITYDLG_SHIELDSTOCK
Definition themecolors.h:64
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:59
@ COLOR_THEME_CITYDLG_TRADE
Definition themecolors.h:67
@ COLOR_THEME_CITYDLG_PROD
Definition themecolors.h:61
@ COLOR_THEME_CITYDLG_GROWTH
Definition themecolors.h:55
@ COLOR_THEME_CITYDLG_SUPPORT
Definition themecolors.h:66
@ COLOR_THEME_CITYDLG_GRANARY
Definition themecolors.h:54
@ COLOR_THEME_CITYDLG_SCIENCE
Definition themecolors.h:62
@ COLOR_THEME_CITYDLG_CORRUPTION
Definition themecolors.h:48
@ COLOR_THEME_CITYDLG_FOODSTOCK
Definition themecolors.h:50
@ COLOR_THEME_CITYDLG_GOLD
Definition themecolors.h:53
@ COLOR_THEME_CITYDLG_STOCKS
Definition themecolors.h:65
@ COLOR_THEME_CITYDLG_UPKEEP
Definition themecolors.h:68
@ COLOR_THEME_CITYDLG_FRAME
Definition themecolors.h:52
@ COLOR_THEME_CITYDLG_FOOD_SURPLUS
Definition themecolors.h:51
@ COLOR_THEME_CITYDLG_PANEL
Definition themecolors.h:60
@ COLOR_THEME_CHECKBOX_LABEL_TEXT
Definition themecolors.h:24
struct theme * active_theme
Definition themespec.c:154
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:752
int tileset_unit_with_small_upkeep_height(const struct tileset *t)
Definition tilespec.c:834
int tileset_unit_layout_small_offset_y(const struct tileset *t)
Definition tilespec.c:854
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:739
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:716
#define trade_routes_iterate_end
#define trade_routes_iterate(c, proute)
const struct unit_type * utype
Definition fc_types.h:604
const struct impr_type * building
Definition fc_types.h:598
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1175
#define unit_tile(_pu)
Definition unit.h:388
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const char * utype_veteran_name_translation(const struct unit_type *punittype, int level)
Definition unittype.c:2646
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1755
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
void set_group_state(struct widget *begin_group_widget_list, struct widget *end_group_widget_list, enum widget_state state)
Definition widget.c:897
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:585
void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:862
void unselect_widget_action(void)
Definition widget.c:417
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:601
bool select_window_group_dialog(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:997
int setup_vertical_widgets_position(int step, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h, struct widget *begin, struct widget *end)
Definition widget.c:1050
Uint16 redraw_group(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, int add_to_update)
Definition widget.c:719
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:982
void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:1038
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
#define MAX_ID
Definition widget.h:38
@ FC_WS_DISABLED
Definition widget.h:99
@ FC_WS_NORMAL
Definition widget.h:96
bool del_widget_from_vertical_scroll_widget_list(struct advanced_dialog *dlg, struct widget *pwidget) fc__attribute((nonnull(2)))
static void widget_mark_dirty(struct widget *pwidget)
Definition widget.h:286
static void widget_flush(struct widget *pwidget)
Definition widget.h:291
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
enum widget_state get_wstate(const struct widget *pwidget)
Definition widget_core.c:70
@ WF_WIDGET_HAS_INFO_LABEL
Definition widget.h:88
@ WF_ICON_CENTER_RIGHT
Definition widget.h:84
@ WF_FREE_THEME2
Definition widget.h:74
@ WF_SELECT_WITHOUT_BAR
Definition widget.h:89
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
@ WF_HIDDEN
Definition widget.h:68
@ WF_FREE_THEME
Definition widget.h:72
static int widget_redraw(struct widget *pwidget)
Definition widget.h:276
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
struct widget * create_icon_button(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
#define create_icon_button_from_chars_fonto(icon, pdest, char_string, fonto, flags)
#define create_themeicon_button_from_chars_fonto(icon_theme, pdest, char_string, fonto, flags)
struct widget * create_textcheckbox(struct gui_layer *pdest, bool state, utf8_str *pstr, Uint32 flags)
#define create_edit_from_chars_fonto(background, pdest, char_string, fonto, length, flags)
Definition widget_edit.h:29
struct widget * create_themeicon(SDL_Surface *icon_theme, struct gui_layer *pdest, Uint32 flags)
struct widget * create_icon2(SDL_Surface *icon, struct gui_layer *pdest, Uint32 flags)
struct widget * create_themelabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint16 w, Uint16 h, Uint32 flags)
struct widget * create_iconlabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
void setup_vertical_scrollbar_area(struct scroll_bar *scroll, Sint16 start_x, Sint16 start_y, Uint16 height, bool swap_start_x)
Uint32 create_vertical_scrollbar(struct advanced_dialog *dlg, Uint8 step, Uint8 active, bool create_scrollbar, bool create_buttons)
int resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)
struct widget * create_window(struct gui_layer *pdest, utf8_str *title, Uint16 w, Uint16 h, Uint32 flags)