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 menu.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 "fcintl.h"
35 #include "log.h"
36
37 /* common */
38 #include "clientutils.h"
39 #include "game.h"
40 #include "road.h"
41 #include "traderoutes.h"
42 #include "unitlist.h"
43
44 /* client */
45 #include "client_main.h" /* client_state */
46 #include "climisc.h"
47 #include "control.h"
48
49 /* gui-sdl2 */
50 #include "dialogs.h"
51 #include "gotodlg.h"
52 #include "graphics.h"
53 #include "gui_iconv.h"
54 #include "gui_id.h"
55 #include "gui_main.h"
56 #include "gui_tilespec.h"
57 #include "mapctrl.h"
58 #include "mapview.h"
59 #include "pages.h"
60 #include "widget.h"
61
62 #include "menu.h"
63
64 extern struct widget *pOptions_Button;
65
66 static struct widget *pBeginOrderWidgetList;
67 static struct widget *pEndOrderWidgetList;
68
69 static struct widget *pOrder_Fallout_Button;
70 static struct widget *pOrder_Pollution_Button;
71 static struct widget *pOrder_Airbase_Button;
72 static struct widget *pOrder_Fortress_Button;
73 static struct widget *pOrder_Build_AddTo_City_Button;
74 static struct widget *pOrder_Mine_Button;
75 static struct widget *pOrder_Irrigation_Button;
76 static struct widget *pOrder_Road_Button;
77 static struct widget *pOrder_Transform_Button;
78 static struct widget *pOrder_Trade_Button;
79
80 #define local_show(ID) \
81 clear_wflag(get_widget_pointer_from_id(pBeginOrderWidgetList, ID, SCAN_FORWARD), \
82 WF_HIDDEN)
83
84 #define local_hide(ID) \
85 set_wflag(get_widget_pointer_from_id(pBeginOrderWidgetList, ID, SCAN_FORWARD), \
86 WF_HIDDEN )
87
88
89 /**************************************************************************
90 User interacted with some unit order widget.
91 **************************************************************************/
unit_order_callback(struct widget * pOrder_Widget)92 static int unit_order_callback(struct widget *pOrder_Widget)
93 {
94 if (PRESSED_EVENT(Main.event)) {
95 struct unit *pUnit = head_of_units_in_focus();
96
97 set_wstate(pOrder_Widget, FC_WS_SELECTED);
98 selected_widget = pOrder_Widget;
99
100 if (!pUnit) {
101 return -1;
102 }
103
104 switch (pOrder_Widget->ID) {
105 case ID_UNIT_ORDER_BUILD_CITY:
106 /* Enable the button for adding to a city in all cases, so we
107 get an eventual error message from the server if we try. */
108 key_unit_build_city();
109 break;
110 case ID_UNIT_ORDER_BUILD_WONDER:
111 key_unit_build_wonder();
112 break;
113 case ID_UNIT_ORDER_ROAD:
114 key_unit_road();
115 break;
116 case ID_UNIT_ORDER_TRADE_ROUTE:
117 key_unit_trade_route();
118 break;
119 case ID_UNIT_ORDER_IRRIGATE:
120 key_unit_irrigate();
121 break;
122 case ID_UNIT_ORDER_MINE:
123 key_unit_mine();
124 break;
125 case ID_UNIT_ORDER_TRANSFORM:
126 key_unit_transform();
127 break;
128 case ID_UNIT_ORDER_FORTRESS:
129 key_unit_fortress();
130 break;
131 case ID_UNIT_ORDER_FORTIFY:
132 key_unit_fortify();
133 break;
134 case ID_UNIT_ORDER_AIRBASE:
135 key_unit_airbase();
136 break;
137 case ID_UNIT_ORDER_POLLUTION:
138 key_unit_pollution();
139 break;
140 case ID_UNIT_ORDER_PARADROP:
141 key_unit_paradrop();
142 break;
143 case ID_UNIT_ORDER_FALLOUT:
144 key_unit_fallout();
145 break;
146 case ID_UNIT_ORDER_SENTRY:
147 key_unit_sentry();
148 break;
149 case ID_UNIT_ORDER_PILLAGE:
150 key_unit_pillage();
151 break;
152 case ID_UNIT_ORDER_HOMECITY:
153 key_unit_homecity();
154 break;
155 case ID_UNIT_ORDER_UNLOAD_TRANSPORTER:
156 key_unit_unload_all();
157 break;
158 case ID_UNIT_ORDER_LOAD:
159 unit_list_iterate(get_units_in_focus(), punit) {
160 request_unit_load(punit, NULL, unit_tile(punit));
161 } unit_list_iterate_end;
162 break;
163 case ID_UNIT_ORDER_UNLOAD:
164 unit_list_iterate(get_units_in_focus(), punit) {
165 request_unit_unload(punit);
166 } unit_list_iterate_end;
167 break;
168 case ID_UNIT_ORDER_WAKEUP_OTHERS:
169 key_unit_wakeup_others();
170 break;
171 case ID_UNIT_ORDER_AUTO_SETTLER:
172 unit_list_iterate(get_units_in_focus(), punit) {
173 request_unit_autosettlers(punit);
174 } unit_list_iterate_end;
175 break;
176 case ID_UNIT_ORDER_AUTO_EXPLORE:
177 key_unit_auto_explore();
178 break;
179 case ID_UNIT_ORDER_CONNECT_IRRIGATE:
180 {
181 struct extra_type_list *extras = extra_type_list_by_cause(EC_IRRIGATION);
182
183 if (extra_type_list_size(extras) > 0) {
184 struct extra_type *pextra;
185
186 pextra = extra_type_list_get(extra_type_list_by_cause(EC_IRRIGATION), 0);
187
188 key_unit_connect(ACTIVITY_IRRIGATE, pextra);
189 }
190 }
191 break;
192 case ID_UNIT_ORDER_CONNECT_ROAD:
193 {
194 struct road_type *proad = road_by_compat_special(ROCO_ROAD);
195
196 if (proad != NULL) {
197 struct extra_type *tgt;
198
199 tgt = road_extra_get(proad);
200
201 key_unit_connect(ACTIVITY_GEN_ROAD, tgt);
202 }
203 }
204 break;
205 case ID_UNIT_ORDER_CONNECT_RAILROAD:
206 {
207 struct road_type *prail = road_by_compat_special(ROCO_RAILROAD);
208
209 if (prail != NULL) {
210 struct extra_type *tgt;
211
212 tgt = road_extra_get(prail);
213
214 key_unit_connect(ACTIVITY_GEN_ROAD, tgt);
215 }
216 }
217 break;
218 case ID_UNIT_ORDER_PATROL:
219 key_unit_patrol();
220 break;
221 case ID_UNIT_ORDER_GOTO:
222 key_unit_goto();
223 break;
224 case ID_UNIT_ORDER_GOTO_CITY:
225 popup_goto_dialog();
226 break;
227 case ID_UNIT_ORDER_AIRLIFT:
228 popup_airlift_dialog();
229 break;
230 case ID_UNIT_ORDER_RETURN:
231 unit_list_iterate(get_units_in_focus(), punit) {
232 request_unit_return(punit);
233 } unit_list_iterate_end;
234 break;
235 case ID_UNIT_ORDER_UPGRADE:
236 popup_unit_upgrade_dlg(pUnit, FALSE);
237 break;
238 case ID_UNIT_ORDER_CONVERT:
239 key_unit_convert();
240 break;
241 case ID_UNIT_ORDER_DISBAND:
242 popup_unit_disband_dlg(pUnit, FALSE);
243 break;
244 case ID_UNIT_ORDER_DIPLOMAT_DLG:
245 key_unit_action_select_tgt();
246 break;
247 case ID_UNIT_ORDER_NUKE:
248 key_unit_nuke();
249 break;
250 case ID_UNIT_ORDER_WAIT:
251 key_unit_wait();
252 flush_dirty();
253 break;
254 case ID_UNIT_ORDER_DONE:
255 key_unit_done();
256 flush_dirty();
257 break;
258
259 default:
260 break;
261 }
262 }
263
264 return -1;
265 }
266
267 /**************************************************************************
268 Refresh order widgets.
269 **************************************************************************/
redraw_order_widgets(void)270 static Uint16 redraw_order_widgets(void)
271 {
272 Uint16 count = 0;
273 struct widget *pTmpWidget = pBeginOrderWidgetList;
274
275 while (TRUE) {
276 if (!(get_wflags(pTmpWidget) & WF_HIDDEN)) {
277 if (get_wflags(pTmpWidget) & WF_RESTORE_BACKGROUND) {
278 refresh_widget_background(pTmpWidget);
279 }
280 widget_redraw(pTmpWidget);
281 widget_mark_dirty(pTmpWidget);
282 count++;
283 }
284
285 if (pTmpWidget == pEndOrderWidgetList) {
286 break;
287 }
288
289 pTmpWidget = pTmpWidget->next;
290 }
291
292 return count;
293 }
294
295 /**************************************************************************
296 Reposition order widgets as they fit.
297 **************************************************************************/
set_new_order_widget_start_pos(void)298 static void set_new_order_widget_start_pos(void)
299 {
300 struct widget *pMiniMap = get_minimap_window_widget();
301 struct widget *pInfoWind = get_unit_info_window_widget();
302 struct widget *pTmpWidget = pBeginOrderWidgetList;
303 Sint16 sx, sy, xx, yy = 0;
304 int count = 0, lines = 1, w = 0, count_on_line;
305
306 xx = pMiniMap->dst->dest_rect.x + pMiniMap->size.w + adj_size(10);
307 w = (pInfoWind->dst->dest_rect.x - adj_size(10)) - xx;
308
309 if (w < (pTmpWidget->size.w + adj_size(10)) * 2) {
310 if (pMiniMap->size.h == pInfoWind->size.h) {
311 xx = 0;
312 w = main_window_width();
313 yy = pInfoWind->size.h;
314 } else {
315 if (pMiniMap->size.h > pInfoWind->size.h) {
316 w = main_window_width() - xx - adj_size(20);
317 if (w < (pTmpWidget->size.w + adj_size(10)) * 2) {
318 xx = 0;
319 w = pMiniMap->size.w;
320 yy = pMiniMap->size.h;
321 } else {
322 yy = pInfoWind->size.h;
323 }
324 } else {
325 w = pInfoWind->dst->dest_rect.x - adj_size(20);
326 if (w < (pTmpWidget->size.w + adj_size(10)) * 2) {
327 xx = pInfoWind->dst->dest_rect.x;
328 w = pInfoWind->size.w;
329 yy = pInfoWind->size.h;
330 } else {
331 xx = adj_size(10);
332 yy = pMiniMap->size.h;
333 }
334 }
335 }
336 }
337
338 count_on_line = w / (pTmpWidget->size.w + adj_size(5));
339
340 /* find how many to reposition */
341 while (TRUE) {
342 if (!(get_wflags(pTmpWidget) & WF_HIDDEN)) {
343 count++;
344 }
345
346 if (pTmpWidget == pEndOrderWidgetList) {
347 break;
348 }
349
350 pTmpWidget = pTmpWidget->next;
351 }
352
353 pTmpWidget = pBeginOrderWidgetList;
354
355 if (count - count_on_line > 0) {
356 lines = (count + (count_on_line - 1)) / count_on_line;
357
358 count = count_on_line - ((count_on_line * lines) - count);
359 }
360
361 sx = xx + (w - count * (pTmpWidget->size.w + adj_size(5))) / 2;
362
363 sy = pTmpWidget->dst->surface->h - yy - lines * (pTmpWidget->size.h + adj_size(5));
364
365 while (TRUE) {
366 if (!(get_wflags(pTmpWidget) & WF_HIDDEN)) {
367 pTmpWidget->size.x = sx;
368 pTmpWidget->size.y = sy;
369
370 count--;
371 sx += (pTmpWidget->size.w + adj_size(5));
372 if (!count) {
373 count = count_on_line;
374 lines--;
375
376 sx = xx + (w - count * (pTmpWidget->size.w + adj_size(5))) / 2;
377
378 sy = pTmpWidget->dst->surface->h - yy - lines * (pTmpWidget->size.h + adj_size(5));
379 }
380 }
381
382 if (pTmpWidget == pEndOrderWidgetList) {
383 break;
384 }
385
386 pTmpWidget = pTmpWidget->next;
387 }
388 }
389
390 /* ================================ PUBLIC ================================ */
391
392 /**************************************************************************
393 Create units order widgets.
394 **************************************************************************/
create_units_order_widgets(void)395 void create_units_order_widgets(void)
396 {
397 struct widget *pBuf = NULL;
398 char cBuf[128];
399 struct road_type *proad;
400 struct road_type *prail;
401
402 /* No orders */
403 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("No Orders"),
404 /* TRANS: "Space" refers to the space bar on a keyboard. */
405 _("Space"));
406 pBuf = create_themeicon(current_theme->ODone_Icon, Main.gui,
407 WF_HIDDEN | WF_RESTORE_BACKGROUND
408 | WF_WIDGET_HAS_INFO_LABEL);
409 set_wstate(pBuf, FC_WS_NORMAL);
410 pBuf->action = unit_order_callback;
411 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
412 pBuf->key = SDLK_SPACE;
413 add_to_gui_list(ID_UNIT_ORDER_DONE, pBuf);
414 /* --------- */
415
416 pEndOrderWidgetList = pBuf;
417
418 /* Wait */
419 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Wait"), "W");
420 pBuf = create_themeicon(current_theme->OWait_Icon, Main.gui,
421 WF_HIDDEN | WF_RESTORE_BACKGROUND
422 | WF_WIDGET_HAS_INFO_LABEL);
423 set_wstate(pBuf, FC_WS_NORMAL);
424 pBuf->action = unit_order_callback;
425 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
426 pBuf->key = SDLK_w;
427 add_to_gui_list(ID_UNIT_ORDER_WAIT, pBuf);
428 /* --------- */
429
430 /* Explode Nuclear */
431 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Explode Nuclear"), "Shift+N");
432 pBuf = create_themeicon(current_theme->ONuke_Icon, Main.gui,
433 WF_HIDDEN | WF_RESTORE_BACKGROUND
434 | WF_WIDGET_HAS_INFO_LABEL);
435 set_wstate(pBuf, FC_WS_NORMAL);
436 pBuf->action = unit_order_callback;
437 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
438 pBuf->key = SDLK_n;
439 pBuf->mod = KMOD_SHIFT;
440 add_to_gui_list(ID_UNIT_ORDER_NUKE, pBuf);
441 /* --------- */
442
443 /* Act against the specified tile. */
444 /* TRANS: Button to bring up the action selection dialog. */
445 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Do..."), "D");
446 pBuf = create_themeicon(current_theme->OSpy_Icon, Main.gui,
447 WF_HIDDEN | WF_RESTORE_BACKGROUND
448 | WF_WIDGET_HAS_INFO_LABEL);
449 set_wstate(pBuf, FC_WS_NORMAL);
450 pBuf->action = unit_order_callback;
451 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
452 pBuf->key = SDLK_d;
453 add_to_gui_list(ID_UNIT_ORDER_DIPLOMAT_DLG, pBuf);
454 /* --------- */
455
456 /* Disband */
457 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Disband Unit"), "Shift+D");
458 pBuf = create_themeicon(current_theme->ODisband_Icon, Main.gui,
459 WF_HIDDEN | WF_RESTORE_BACKGROUND
460 | WF_WIDGET_HAS_INFO_LABEL);
461 set_wstate(pBuf, FC_WS_NORMAL);
462 pBuf->action = unit_order_callback;
463 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
464 pBuf->key = SDLK_d;
465 pBuf->mod = KMOD_SHIFT;
466 add_to_gui_list(ID_UNIT_ORDER_DISBAND, pBuf);
467 /* --------- */
468
469 /* Upgrade */
470 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Upgrade Unit"), "Shift+U");
471 pBuf = create_themeicon(current_theme->Order_Icon, Main.gui,
472 WF_HIDDEN | WF_RESTORE_BACKGROUND
473 | WF_WIDGET_HAS_INFO_LABEL);
474 set_wstate(pBuf, FC_WS_NORMAL);
475 pBuf->action = unit_order_callback;
476 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
477 pBuf->key = SDLK_u;
478 pBuf->mod = KMOD_SHIFT;
479 add_to_gui_list(ID_UNIT_ORDER_UPGRADE, pBuf);
480 /* --------- */
481
482 /* Convert */
483 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Convert Unit"), "Shift+O");
484 pBuf = create_themeicon(current_theme->Order_Icon, Main.gui,
485 WF_HIDDEN | WF_RESTORE_BACKGROUND
486 | WF_WIDGET_HAS_INFO_LABEL);
487 set_wstate(pBuf, FC_WS_NORMAL);
488 pBuf->action = unit_order_callback;
489 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
490 pBuf->key = SDLK_o;
491 pBuf->mod = KMOD_SHIFT;
492 add_to_gui_list(ID_UNIT_ORDER_CONVERT, pBuf);
493 /* --------- */
494
495 /* Return to nearest city */
496 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Return to Nearest City"), "Shift+G");
497 pBuf = create_themeicon(current_theme->OReturn_Icon, Main.gui,
498 WF_HIDDEN | WF_RESTORE_BACKGROUND
499 | WF_WIDGET_HAS_INFO_LABEL);
500 set_wstate(pBuf, FC_WS_NORMAL);
501 pBuf->action = unit_order_callback;
502 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
503 pBuf->key = SDLK_g;
504 pBuf->mod = KMOD_SHIFT;
505 add_to_gui_list(ID_UNIT_ORDER_RETURN, pBuf);
506 /* --------- */
507
508 /* Goto City */
509 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Go to City"), "T");
510 pBuf = create_themeicon(current_theme->OGotoCity_Icon, Main.gui,
511 WF_HIDDEN | WF_RESTORE_BACKGROUND
512 | WF_WIDGET_HAS_INFO_LABEL);
513 set_wstate(pBuf, FC_WS_NORMAL);
514 pBuf->action = unit_order_callback;
515 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
516 pBuf->key = SDLK_t;
517 add_to_gui_list(ID_UNIT_ORDER_GOTO_CITY, pBuf);
518 /* --------- */
519
520 /* Airlift */
521 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Airlift to City"), "T");
522 pBuf = create_themeicon(current_theme->Order_Icon, Main.gui,
523 WF_HIDDEN | WF_RESTORE_BACKGROUND
524 | WF_WIDGET_HAS_INFO_LABEL);
525 set_wstate(pBuf, FC_WS_NORMAL);
526 pBuf->action = unit_order_callback;
527 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
528 pBuf->key = SDLK_t;
529 add_to_gui_list(ID_UNIT_ORDER_AIRLIFT, pBuf);
530 /* --------- */
531
532 /* Goto location */
533 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Go to Tile"), "G");
534 pBuf = create_themeicon(current_theme->OGoto_Icon, Main.gui,
535 WF_HIDDEN | WF_RESTORE_BACKGROUND
536 | WF_WIDGET_HAS_INFO_LABEL);
537 set_wstate(pBuf, FC_WS_NORMAL);
538 pBuf->action = unit_order_callback;
539 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
540 pBuf->key = SDLK_g;
541 add_to_gui_list(ID_UNIT_ORDER_GOTO, pBuf);
542 /* --------- */
543
544 /* Patrol */
545 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Patrol"), "Q");
546 pBuf = create_themeicon(current_theme->OPatrol_Icon, Main.gui,
547 WF_HIDDEN | WF_RESTORE_BACKGROUND
548 | WF_WIDGET_HAS_INFO_LABEL);
549 set_wstate(pBuf, FC_WS_NORMAL);
550 pBuf->action = unit_order_callback;
551 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
552 pBuf->key = SDLK_q;
553 add_to_gui_list(ID_UNIT_ORDER_PATROL, pBuf);
554 /* --------- */
555
556 /* Connect irrigation */
557 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Connect With Irrigation"), "Shift+I");
558 pBuf = create_themeicon(current_theme->OAutoConnect_Icon, Main.gui,
559 WF_HIDDEN | WF_RESTORE_BACKGROUND
560 | WF_WIDGET_HAS_INFO_LABEL);
561 set_wstate(pBuf, FC_WS_NORMAL);
562 pBuf->action = unit_order_callback;
563 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
564 pBuf->key = SDLK_i;
565 pBuf->mod = KMOD_SHIFT;
566 add_to_gui_list(ID_UNIT_ORDER_CONNECT_IRRIGATE, pBuf);
567 /* --------- */
568
569 /* Connect road */
570 proad = road_by_compat_special(ROCO_ROAD);
571
572 if (proad != NULL) {
573 fc_snprintf(cBuf, sizeof(cBuf),
574 _("Connect With %s (%s)"),
575 extra_name_translation(road_extra_get(proad)),
576 "Shift+R");
577 pBuf = create_themeicon(current_theme->OAutoConnect_Icon, Main.gui,
578 WF_HIDDEN | WF_RESTORE_BACKGROUND
579 | WF_WIDGET_HAS_INFO_LABEL);
580 set_wstate(pBuf, FC_WS_NORMAL);
581 pBuf->action = unit_order_callback;
582 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
583 pBuf->key = SDLK_r;
584 pBuf->mod = KMOD_SHIFT;
585 add_to_gui_list(ID_UNIT_ORDER_CONNECT_ROAD, pBuf);
586 }
587 /* --------- */
588
589 /* Connect railroad */
590 prail = road_by_compat_special(ROCO_RAILROAD);
591 if (prail != NULL) {
592 fc_snprintf(cBuf, sizeof(cBuf),
593 _("Connect With %s (%s)"),
594 extra_name_translation(road_extra_get(prail)),
595 "Shift+L");
596 pBuf = create_themeicon(current_theme->OAutoConnect_Icon, Main.gui,
597 WF_HIDDEN | WF_RESTORE_BACKGROUND
598 | WF_WIDGET_HAS_INFO_LABEL);
599 set_wstate(pBuf, FC_WS_NORMAL);
600 pBuf->action = unit_order_callback;
601 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
602 pBuf->key = SDLK_l;
603 pBuf->mod = KMOD_SHIFT;
604 add_to_gui_list(ID_UNIT_ORDER_CONNECT_RAILROAD, pBuf);
605 }
606 /* --------- */
607
608 /* Auto-Explore */
609 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Auto Explore"), "X");
610 pBuf = create_themeicon(current_theme->OAutoExp_Icon, Main.gui,
611 WF_HIDDEN | WF_RESTORE_BACKGROUND
612 | WF_WIDGET_HAS_INFO_LABEL);
613 set_wstate(pBuf, FC_WS_NORMAL);
614 pBuf->action = unit_order_callback;
615 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
616 pBuf->key = SDLK_x;
617 add_to_gui_list(ID_UNIT_ORDER_AUTO_EXPLORE, pBuf);
618 /* --------- */
619
620 /* Auto-Settler */
621 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Auto Settler"), "A");
622
623 pBuf = create_themeicon(current_theme->OAutoSett_Icon, Main.gui,
624 WF_HIDDEN | WF_RESTORE_BACKGROUND
625 | WF_WIDGET_HAS_INFO_LABEL);
626 set_wstate(pBuf, FC_WS_NORMAL);
627 pBuf->action = unit_order_callback;
628 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
629 pBuf->key = SDLK_a;
630 add_to_gui_list(ID_UNIT_ORDER_AUTO_SETTLER, pBuf);
631 /* --------- */
632
633 /* Wake Up Others */
634 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Unsentry All On Tile"), "Shift+S");
635 pBuf = create_themeicon(current_theme->OWakeUp_Icon, Main.gui,
636 WF_HIDDEN | WF_RESTORE_BACKGROUND
637 | WF_WIDGET_HAS_INFO_LABEL);
638 set_wstate(pBuf, FC_WS_NORMAL);
639 pBuf->action = unit_order_callback;
640 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
641 pBuf->key = SDLK_s;
642 pBuf->mod = KMOD_SHIFT;
643 add_to_gui_list(ID_UNIT_ORDER_WAKEUP_OTHERS, pBuf);
644 /* --------- */
645
646 /* Unload */
647 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Unload All From Transporter"), "Shift+T");
648 pBuf = create_themeicon(current_theme->OUnload_Icon, Main.gui,
649 WF_HIDDEN | WF_RESTORE_BACKGROUND
650 | WF_WIDGET_HAS_INFO_LABEL);
651 set_wstate(pBuf, FC_WS_NORMAL);
652 pBuf->action = unit_order_callback;
653 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
654 pBuf->mod = KMOD_SHIFT;
655 pBuf->key = SDLK_t;
656 add_to_gui_list(ID_UNIT_ORDER_UNLOAD_TRANSPORTER, pBuf);
657 /* --------- */
658
659 /* Load */
660 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Load Unit"), "L");
661 pBuf = create_themeicon(current_theme->OLoad_Icon, Main.gui,
662 WF_HIDDEN | WF_RESTORE_BACKGROUND
663 | WF_WIDGET_HAS_INFO_LABEL);
664 set_wstate(pBuf, FC_WS_NORMAL);
665 pBuf->action = unit_order_callback;
666 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
667 pBuf->key = SDLK_l;
668 add_to_gui_list(ID_UNIT_ORDER_LOAD, pBuf);
669 /* --------- */
670
671 /* Unload */
672 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Unload Unit"), "U");
673 pBuf = create_themeicon(current_theme->OUnload_Icon, Main.gui,
674 WF_HIDDEN | WF_RESTORE_BACKGROUND
675 | WF_WIDGET_HAS_INFO_LABEL);
676 set_wstate(pBuf, FC_WS_NORMAL);
677 pBuf->action = unit_order_callback;
678 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
679 pBuf->key = SDLK_u;
680 add_to_gui_list(ID_UNIT_ORDER_UNLOAD, pBuf);
681 /* --------- */
682
683 /* Find Homecity */
684 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Find Home City"), "H");
685 pBuf = create_themeicon(current_theme->OHomeCity_Icon, Main.gui,
686 WF_HIDDEN | WF_RESTORE_BACKGROUND
687 | WF_WIDGET_HAS_INFO_LABEL);
688 set_wstate(pBuf, FC_WS_NORMAL);
689 pBuf->action = unit_order_callback;
690 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
691 pBuf->key = SDLK_h;
692 add_to_gui_list(ID_UNIT_ORDER_HOMECITY, pBuf);
693 /* --------- */
694
695 /* Pillage */
696 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Pillage"), "Shift+P");
697 pBuf = create_themeicon(current_theme->OPillage_Icon, Main.gui,
698 WF_HIDDEN | WF_RESTORE_BACKGROUND
699 | WF_WIDGET_HAS_INFO_LABEL);
700 set_wstate(pBuf, FC_WS_NORMAL);
701 pBuf->action = unit_order_callback;
702 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
703 pBuf->key = SDLK_p;
704 pBuf->mod = KMOD_SHIFT;
705 add_to_gui_list(ID_UNIT_ORDER_PILLAGE, pBuf);
706 /* --------- */
707
708 /* Sentry */
709 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Sentry Unit"), "S");
710 pBuf = create_themeicon(current_theme->OSentry_Icon, Main.gui,
711 WF_HIDDEN | WF_RESTORE_BACKGROUND
712 | WF_WIDGET_HAS_INFO_LABEL);
713 set_wstate(pBuf, FC_WS_NORMAL);
714 pBuf->action = unit_order_callback;
715 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
716 pBuf->key = SDLK_s;
717 add_to_gui_list(ID_UNIT_ORDER_SENTRY, pBuf);
718 /* --------- */
719
720 /* Clean Nuclear Fallout */
721 /* Label will be replaced by real_menus_update() before it's seen */
722 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
723 pBuf = create_themeicon(current_theme->OFallout_Icon, Main.gui,
724 WF_HIDDEN | WF_RESTORE_BACKGROUND
725 | WF_WIDGET_HAS_INFO_LABEL);
726 set_wstate(pBuf, FC_WS_NORMAL);
727 pBuf->action = unit_order_callback;
728 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
729 pBuf->key = SDLK_n;
730 pOrder_Fallout_Button = pBuf;
731 add_to_gui_list(ID_UNIT_ORDER_FALLOUT, pBuf);
732 /* --------- */
733
734 /* Paradrop */
735 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Drop Paratrooper"), "P");
736 pBuf = create_themeicon(current_theme->OParaDrop_Icon, Main.gui,
737 WF_HIDDEN | WF_RESTORE_BACKGROUND
738 | WF_WIDGET_HAS_INFO_LABEL);
739 set_wstate(pBuf, FC_WS_NORMAL);
740 pBuf->action = unit_order_callback;
741 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
742 pBuf->key = SDLK_p;
743 add_to_gui_list(ID_UNIT_ORDER_PARADROP, pBuf);
744 /* --------- */
745
746 /* Clean Pollution */
747 /* Label will be replaced by real_menus_update() before it's seen */
748 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
749 pBuf = create_themeicon(current_theme->OPollution_Icon, Main.gui,
750 WF_HIDDEN | WF_RESTORE_BACKGROUND
751 | WF_WIDGET_HAS_INFO_LABEL);
752 set_wstate(pBuf, FC_WS_NORMAL);
753 pBuf->action = unit_order_callback;
754 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
755 pBuf->key = SDLK_p;
756 pOrder_Pollution_Button = pBuf;
757 add_to_gui_list(ID_UNIT_ORDER_POLLUTION, pBuf);
758 /* --------- */
759
760 /* Build Airbase */
761 /* Label will be replaced by real_menus_update() before it's seen */
762 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
763 pBuf = create_themeicon(current_theme->OAirBase_Icon, Main.gui,
764 WF_HIDDEN | WF_RESTORE_BACKGROUND
765 | WF_WIDGET_HAS_INFO_LABEL);
766 set_wstate(pBuf, FC_WS_NORMAL);
767 pBuf->action = unit_order_callback;
768 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
769 pBuf->key = SDLK_e;
770 pBuf->mod = KMOD_SHIFT;
771 pOrder_Airbase_Button = pBuf;
772 add_to_gui_list(ID_UNIT_ORDER_AIRBASE, pBuf);
773 /* --------- */
774
775 /* Fortify */
776 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Fortify Unit"), "F");
777 pBuf = create_themeicon(current_theme->OFortify_Icon, Main.gui,
778 WF_HIDDEN | WF_RESTORE_BACKGROUND
779 | WF_WIDGET_HAS_INFO_LABEL);
780 set_wstate(pBuf, FC_WS_NORMAL);
781 pBuf->action = unit_order_callback;
782 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
783 pBuf->key = SDLK_f;
784 add_to_gui_list(ID_UNIT_ORDER_FORTIFY, pBuf);
785 /* --------- */
786
787 /* Build Fortress */
788 /* Label will be replaced by real_menus_update() before it's seen */
789 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
790 pBuf = create_themeicon(current_theme->OFortress_Icon, Main.gui,
791 WF_HIDDEN | WF_RESTORE_BACKGROUND
792 | WF_WIDGET_HAS_INFO_LABEL);
793 set_wstate(pBuf, FC_WS_NORMAL);
794 pBuf->action = unit_order_callback;
795 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
796 pBuf->key = SDLK_f;
797 pBuf->mod = KMOD_SHIFT;
798 pOrder_Fortress_Button = pBuf;
799 add_to_gui_list(ID_UNIT_ORDER_FORTRESS, pBuf);
800 /* --------- */
801
802 /* Transform Tile */
803 /* Label will be replaced by real_menus_update() before it's seen */
804 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
805 pBuf = create_themeicon(current_theme->OTransform_Icon, Main.gui,
806 WF_HIDDEN | WF_RESTORE_BACKGROUND
807 | WF_WIDGET_HAS_INFO_LABEL);
808 set_wstate(pBuf, FC_WS_NORMAL);
809 pBuf->action = unit_order_callback;
810 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
811 pBuf->key = SDLK_o;
812 pOrder_Transform_Button = pBuf;
813 add_to_gui_list(ID_UNIT_ORDER_TRANSFORM, pBuf);
814 /* --------- */
815
816 /* Build Mine */
817 /* Label will be replaced by real_menus_update() before it's seen */
818 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
819 pBuf = create_themeicon(current_theme->OMine_Icon, Main.gui,
820 WF_HIDDEN | WF_RESTORE_BACKGROUND
821 | WF_WIDGET_HAS_INFO_LABEL);
822 set_wstate(pBuf, FC_WS_NORMAL);
823 pBuf->action = unit_order_callback;
824 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
825 pBuf->key = SDLK_m;
826 add_to_gui_list(ID_UNIT_ORDER_MINE, pBuf);
827
828 pOrder_Mine_Button = pBuf;
829 /* --------- */
830
831 /* Build Irrigation */
832 /* Label will be replaced by real_menus_update() before it's seen */
833 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
834 pBuf = create_themeicon(current_theme->OIrrigation_Icon, Main.gui,
835 WF_HIDDEN | WF_RESTORE_BACKGROUND
836 | WF_WIDGET_HAS_INFO_LABEL);
837 set_wstate(pBuf, FC_WS_NORMAL);
838 pBuf->action = unit_order_callback;
839 pBuf->key = SDLK_i;
840 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
841 add_to_gui_list(ID_UNIT_ORDER_IRRIGATE, pBuf);
842
843 pOrder_Irrigation_Button = pBuf;
844 /* --------- */
845
846 /* Establish Trade route */
847 /* Label will be replaced by real_menus_update() before it's seen */
848 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
849 pBuf = create_themeicon(current_theme->OTrade_Icon, Main.gui,
850 WF_HIDDEN | WF_RESTORE_BACKGROUND
851 | WF_WIDGET_HAS_INFO_LABEL);
852 set_wstate(pBuf, FC_WS_NORMAL);
853 pBuf->action = unit_order_callback;
854 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
855 pBuf->key = SDLK_r;
856 add_to_gui_list(ID_UNIT_ORDER_TRADE_ROUTE, pBuf);
857
858 pOrder_Trade_Button = pBuf;
859 /* --------- */
860
861 /* Build (Rail-)Road */
862 /* Label will be replaced by real_menus_update() before it's seen */
863 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
864 pBuf = create_themeicon(current_theme->ORoad_Icon, Main.gui,
865 WF_HIDDEN | WF_RESTORE_BACKGROUND
866 | WF_WIDGET_HAS_INFO_LABEL);
867 set_wstate(pBuf, FC_WS_NORMAL);
868 pBuf->action = unit_order_callback;
869 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
870 pBuf->key = SDLK_r;
871 add_to_gui_list(ID_UNIT_ORDER_ROAD, pBuf);
872
873 pOrder_Road_Button = pBuf;
874 /* --------- */
875
876 /* Help Build Wonder */
877 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)",
878 action_id_name_translation(ACTION_HELP_WONDER), "B");
879 pBuf = create_themeicon(current_theme->OWonder_Icon, Main.gui,
880 WF_HIDDEN | WF_RESTORE_BACKGROUND
881 | WF_WIDGET_HAS_INFO_LABEL);
882 set_wstate(pBuf, FC_WS_NORMAL);
883 pBuf->action = unit_order_callback;
884 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
885 pBuf->key = SDLK_b;
886 add_to_gui_list(ID_UNIT_ORDER_BUILD_WONDER, pBuf);
887 /* --------- */
888
889 /* Add to City / Build New City */
890 /* Label will be replaced by real_menus_update() before it's seen */
891 fc_snprintf(cBuf, sizeof(cBuf), "placeholder");
892 pBuf = create_themeicon(current_theme->OBuildCity_Icon, Main.gui,
893 WF_HIDDEN | WF_RESTORE_BACKGROUND
894 | WF_WIDGET_HAS_INFO_LABEL);
895 set_wstate(pBuf, FC_WS_NORMAL);
896 pBuf->action = unit_order_callback;
897 pBuf->info_label = create_utf8_from_char(cBuf, adj_font(10));
898 pBuf->key = SDLK_b;
899 add_to_gui_list(ID_UNIT_ORDER_BUILD_CITY, pBuf);
900
901 pOrder_Build_AddTo_City_Button = pBuf;
902 /* --------- */
903
904 pBeginOrderWidgetList = pBuf;
905
906 SDL_Client_Flags |= CF_ORDERS_WIDGETS_CREATED;
907 }
908
909 /**************************************************************************
910 Free resources allocated for unit order widgets.
911 **************************************************************************/
delete_units_order_widgets(void)912 void delete_units_order_widgets(void)
913 {
914 del_group(pBeginOrderWidgetList, pEndOrderWidgetList);
915
916 pBeginOrderWidgetList = NULL;
917 pEndOrderWidgetList = NULL;
918 SDL_Client_Flags &= ~CF_ORDERS_WIDGETS_CREATED;
919 }
920
921 /**************************************************************************
922 Draw order widgets to their currently correct place.
923 **************************************************************************/
update_order_widgets(void)924 void update_order_widgets(void)
925 {
926 set_new_order_widget_start_pos();
927 redraw_order_widgets();
928 }
929
930 /**************************************************************************
931 Clear unit order widgets from view.
932 **************************************************************************/
undraw_order_widgets(void)933 void undraw_order_widgets(void)
934 {
935 struct widget *pTmpWidget = pBeginOrderWidgetList;
936
937 if (pTmpWidget == NULL) {
938 return;
939 }
940
941 while (TRUE) {
942 if (!(get_wflags(pTmpWidget) & WF_HIDDEN) && (pTmpWidget->gfx)) {
943 widget_undraw(pTmpWidget);
944 widget_mark_dirty(pTmpWidget);
945 }
946
947 if (pTmpWidget == pEndOrderWidgetList) {
948 break;
949 }
950
951 pTmpWidget = pTmpWidget->next;
952 }
953 }
954
955 /* ============================== Native =============================== */
956
957 /**************************************************************************
958 Initialize menus (sensitivity, name, etc.) based on the
959 current state and current ruleset, etc. Call menus_update().
960 **************************************************************************/
real_menus_init(void)961 void real_menus_init(void)
962 {
963 /* PORTME */
964 }
965
966 /**************************************************************************
967 Update all of the menus (sensitivity, etc.) based on the current state.
968 **************************************************************************/
real_menus_update(void)969 void real_menus_update(void)
970 {
971 static Uint16 counter = 0;
972 struct unit_list *punits = NULL;
973 struct unit *pUnit = NULL;
974 static char cBuf[128];
975
976 if ((C_S_RUNNING != client_state())
977 || (get_client_page() != PAGE_GAME)) {
978
979 SDL_Client_Flags |= CF_GAME_JUST_STARTED;
980
981 if (SDL_Client_Flags & CF_MAP_UNIT_W_CREATED) {
982 set_wflag(pOptions_Button, WF_HIDDEN);
983 hide_minimap_window_buttons();
984 hide_unitinfo_window_buttons();
985 }
986
987 if (SDL_Client_Flags & CF_ORDERS_WIDGETS_CREATED) {
988 hide_group(pBeginOrderWidgetList, pEndOrderWidgetList);
989 }
990
991 } else {
992 /* Running state */
993 if (SDL_Client_Flags & CF_MAP_UNIT_W_CREATED) {
994 /* show options button */
995 clear_wflag(pOptions_Button, WF_HIDDEN);
996 widget_redraw(pOptions_Button);
997 widget_mark_dirty(pOptions_Button);
998 }
999
1000 if (NULL == client.conn.playing) {
1001 /* Global observer */
1002 if (SDL_Client_Flags & CF_MAP_UNIT_W_CREATED) {
1003 /* show minimap buttons and unitinfo buttons */
1004 show_minimap_window_buttons();
1005 show_unitinfo_window_buttons();
1006 /* disable minimap buttons and unitinfo buttons */
1007 disable_minimap_window_buttons();
1008 disable_unitinfo_window_buttons();
1009 }
1010
1011 return;
1012
1013 } else {
1014 /* running state with player */
1015
1016 if (get_wstate(pEndOrderWidgetList) == FC_WS_DISABLED) {
1017 enable_group(pBeginOrderWidgetList, pEndOrderWidgetList);
1018 }
1019
1020 if (counter) {
1021 undraw_order_widgets();
1022 }
1023
1024 if (SDL_Client_Flags & CF_GAME_JUST_STARTED) {
1025 SDL_Client_Flags &= ~CF_GAME_JUST_STARTED;
1026
1027 /* show minimap buttons and unitinfo buttons */
1028 show_minimap_window_buttons();
1029 show_unitinfo_window_buttons();
1030
1031 counter = 0;
1032 }
1033 }
1034
1035 punits = get_units_in_focus();
1036 pUnit = unit_list_get(punits, 0);
1037
1038 if (pUnit && !pUnit->ai_controlled) {
1039 struct city *pHomecity;
1040 int time;
1041 struct tile *pTile = unit_tile(pUnit);
1042 struct city *pCity = tile_city(pTile);
1043 struct terrain *pTerrain = tile_terrain(pTile);
1044 struct base_type *pbase;
1045 struct extra_type *pextra;
1046
1047 if (!counter) {
1048 local_show(ID_UNIT_ORDER_GOTO);
1049 local_show(ID_UNIT_ORDER_DISBAND);
1050
1051 local_show(ID_UNIT_ORDER_WAIT);
1052 local_show(ID_UNIT_ORDER_DONE);
1053 }
1054
1055 /* Enable the button for adding to a city in all cases, so we
1056 * get an eventual error message from the server if we try. */
1057
1058 if (unit_can_add_or_build_city(pUnit)) {
1059 if (pCity) {
1060 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Add to City"), "B");
1061 } else {
1062 fc_snprintf(cBuf, sizeof(cBuf),"%s (%s)", _("Build City"), "B");
1063 }
1064 copy_chars_to_utf8_str(pOrder_Build_AddTo_City_Button->info_label,
1065 cBuf);
1066 clear_wflag(pOrder_Build_AddTo_City_Button, WF_HIDDEN);
1067 } else {
1068 set_wflag(pOrder_Build_AddTo_City_Button, WF_HIDDEN);
1069 }
1070
1071 if (unit_can_help_build_wonder_here(pUnit)) {
1072 local_show(ID_UNIT_ORDER_BUILD_WONDER);
1073 } else {
1074 local_hide(ID_UNIT_ORDER_BUILD_WONDER);
1075 }
1076
1077 pextra = next_extra_for_tile(pTile, EC_ROAD,
1078 unit_owner(pUnit), pUnit);
1079 if (pextra != NULL
1080 && can_unit_do_activity_targeted(pUnit, ACTIVITY_GEN_ROAD, pextra)) {
1081 struct road_type *proad = extra_road_get(pextra);
1082 enum road_compat compat = road_compat_special(proad);
1083
1084 time = turns_to_activity_done(pTile, ACTIVITY_GEN_ROAD, pextra, pUnit);
1085
1086 /* TRANS: "Build Railroad (R) 3 turns" */
1087 fc_snprintf(cBuf, sizeof(cBuf), _("Build %s (%s) %d %s"),
1088 extra_name_translation(pextra),
1089 "R", time,
1090 PL_("turn", "turns", time));
1091
1092 if (compat == ROCO_RAILROAD) {
1093 pOrder_Road_Button->theme = current_theme->ORailRoad_Icon;
1094 } else {
1095 pOrder_Road_Button->theme = current_theme->ORoad_Icon;
1096 }
1097 copy_chars_to_utf8_str(pOrder_Road_Button->info_label, cBuf);
1098 clear_wflag(pOrder_Road_Button, WF_HIDDEN);
1099 } else {
1100 set_wflag(pOrder_Road_Button, WF_HIDDEN);
1101 }
1102
1103 /* unit_can_est_trade_route_here(pUnit) */
1104 if (pCity && utype_can_do_action(unit_type_get(pUnit),
1105 ACTION_TRADE_ROUTE)
1106 && (pHomecity = game_city_by_number(pUnit->homecity))
1107 && can_cities_trade(pHomecity, pCity)) {
1108 int revenue = get_caravan_enter_city_trade_bonus(pHomecity, pCity,
1109 TRUE);
1110
1111 if (can_establish_trade_route(pHomecity, pCity)) {
1112 fc_snprintf(cBuf, sizeof(cBuf),
1113 _("%s With %s ( %d one time bonus + %d trade ) (R)"),
1114 action_id_name_translation(ACTION_TRADE_ROUTE),
1115 city_name_get(pHomecity),
1116 revenue,
1117 trade_between_cities(pHomecity, pCity));
1118 } else {
1119 revenue = (revenue + 2) / 3;
1120 fc_snprintf(cBuf, sizeof(cBuf),
1121 _("%s Of %s ( %d one time bonus ) (R)"),
1122 action_id_name_translation(ACTION_MARKETPLACE),
1123 city_name_get(pHomecity),
1124 revenue);
1125 }
1126 copy_chars_to_utf8_str(pOrder_Trade_Button->info_label, cBuf);
1127 clear_wflag(pOrder_Trade_Button, WF_HIDDEN);
1128 } else {
1129 set_wflag(pOrder_Trade_Button, WF_HIDDEN);
1130 }
1131
1132 if (can_unit_do_activity(pUnit, ACTIVITY_IRRIGATE)) {
1133 if (is_build_activity(ACTIVITY_IRRIGATE, pTile)) {
1134 /* Activity results in extra */
1135 struct extra_type *irrig_extra = next_extra_for_tile(pTile, EC_IRRIGATION,
1136 unit_owner(pUnit),
1137 pUnit);
1138
1139 time = turns_to_activity_done(pTile, ACTIVITY_IRRIGATE,
1140 irrig_extra, pUnit);
1141 /* TRANS: "Build Irrigation (I) 5 turns" */
1142 fc_snprintf(cBuf, sizeof(cBuf), _("Build %s (%s) %d %s"),
1143 extra_name_translation(irrig_extra), "I", time,
1144 PL_("turn", "turns", time));
1145 pOrder_Irrigation_Button->theme = current_theme->OIrrigation_Icon;
1146 } else {
1147 /* Activity results in terrain change */
1148 time = turns_to_activity_done(pTile, ACTIVITY_IRRIGATE,
1149 NULL, pUnit);
1150
1151 /* FIXME: get rid of this ruleset-specific hardcoding */
1152 if (!strcmp(terrain_rule_name(pTerrain), "Forest")
1153 || !strcmp(terrain_rule_name(pTerrain), "Jungle")) {
1154 /* set Crop Forest Icon */
1155 fc_snprintf(cBuf, sizeof(cBuf),"%s %s (%s) %d %s",
1156 _("Cut Down to"),
1157 terrain_name_translation(pTerrain->irrigation_result),
1158 "I", time , PL_("turn", "turns", time));
1159 pOrder_Irrigation_Button->theme = current_theme->OCutDownForest_Icon;
1160 } else {
1161 /* TRANS: "Change to Grassland (I) 10 turns" */
1162 fc_snprintf(cBuf, sizeof(cBuf), _("Change to %s (%s) %d %s"),
1163 terrain_name_translation(pTerrain->irrigation_result),
1164 "I", time , PL_("turn", "turns", time));
1165 pOrder_Irrigation_Button->theme = current_theme->OIrrigation_Icon;
1166 }
1167 }
1168
1169 copy_chars_to_utf8_str(pOrder_Irrigation_Button->info_label, cBuf);
1170 clear_wflag(pOrder_Irrigation_Button, WF_HIDDEN);
1171 } else {
1172 set_wflag(pOrder_Irrigation_Button, WF_HIDDEN);
1173 }
1174
1175 if (can_unit_do_activity(pUnit, ACTIVITY_MINE)) {
1176 if (is_build_activity(ACTIVITY_MINE, pTile)) {
1177 /* Activity results in extra */
1178 struct extra_type *mine_extra = next_extra_for_tile(pTile, EC_MINE,
1179 unit_owner(pUnit),
1180 pUnit);
1181
1182 time = turns_to_activity_done(pTile, ACTIVITY_MINE, mine_extra, pUnit);
1183 /* TRANS: "Build Mine (M) 5 turns" */
1184 fc_snprintf(cBuf, sizeof(cBuf), _("Build %s (%s) %d %s"),
1185 extra_name_translation(mine_extra), "M", time,
1186 PL_("turn", "turns", time));
1187 pOrder_Mine_Button->theme = current_theme->OMine_Icon;
1188 } else {
1189 /* Activity results in terrain change */
1190 time = turns_to_activity_done(pTile, ACTIVITY_MINE, NULL, pUnit);
1191
1192 /* FIXME: get rid of this ruleset-specific hardcoding */
1193 if (!strcmp(terrain_rule_name(pTerrain->mining_result), "Forest")) {
1194 /* set Forest Icon -> plant Forest */
1195 fc_snprintf(cBuf, sizeof(cBuf), "%s (%s) %d %s",
1196 _("Plant Forest"), "M", time,
1197 PL_("turn", "turns", time));
1198 pOrder_Mine_Button->theme = current_theme->OPlantForest_Icon;
1199 } else {
1200 /* TRANS: "Change to Swamp (M) 10 turns" */
1201 fc_snprintf(cBuf, sizeof(cBuf), _("Change to %s (%s) %d %s"),
1202 terrain_name_translation(pTerrain->mining_result),
1203 "M", time , PL_("turn", "turns", time));
1204 if (!strcmp(terrain_rule_name(pTerrain->mining_result), "Swamp")) {
1205 /* set Irrigate Icon -> make swamp */
1206 pOrder_Mine_Button->theme = current_theme->OIrrigation_Icon;
1207 } else {
1208 pOrder_Mine_Button->theme = current_theme->OPlantForest_Icon;
1209 }
1210 }
1211 }
1212
1213 copy_chars_to_utf8_str(pOrder_Mine_Button->info_label, cBuf);
1214 clear_wflag(pOrder_Mine_Button, WF_HIDDEN);
1215 } else {
1216 set_wflag(pOrder_Mine_Button, WF_HIDDEN);
1217 }
1218
1219 if (can_unit_do_activity(pUnit, ACTIVITY_TRANSFORM)) {
1220 /* Activity always results in terrain change */
1221 time = turns_to_activity_done(pTile, ACTIVITY_TRANSFORM, NULL, pUnit);
1222 fc_snprintf(cBuf, sizeof(cBuf),"%s %s (%s) %d %s",
1223 _("Transform to"),
1224 terrain_name_translation(pTerrain->transform_result),
1225 "O", time, PL_("turn", "turns", time));
1226 copy_chars_to_utf8_str(pOrder_Transform_Button->info_label, cBuf);
1227 clear_wflag(pOrder_Transform_Button, WF_HIDDEN);
1228 } else {
1229 set_wflag(pOrder_Transform_Button, WF_HIDDEN);
1230 }
1231
1232 pbase = get_base_by_gui_type(BASE_GUI_FORTRESS, pUnit, pTile);
1233 if (pbase != NULL) {
1234 struct extra_type *base_extra = base_extra_get(pbase);
1235
1236 time = turns_to_activity_done(pTile, ACTIVITY_BASE, base_extra, pUnit);
1237 /* TRANS: "Build Fortress (Shift+F) 5 turns" */
1238 fc_snprintf(cBuf, sizeof(cBuf), _("Build %s (%s) %d %s"),
1239 extra_name_translation(base_extra), "Shift+F", time,
1240 PL_("turn", "turns", time));
1241 copy_chars_to_utf8_str(pOrder_Fortress_Button->info_label, cBuf);
1242 clear_wflag(pOrder_Fortress_Button, WF_HIDDEN);
1243 } else {
1244 set_wflag(pOrder_Fortress_Button, WF_HIDDEN);
1245 }
1246
1247 if (can_unit_do_activity(pUnit, ACTIVITY_FORTIFYING)) {
1248 local_show(ID_UNIT_ORDER_FORTIFY);
1249 } else {
1250 local_hide(ID_UNIT_ORDER_FORTIFY);
1251 }
1252
1253 pbase = get_base_by_gui_type(BASE_GUI_AIRBASE, pUnit, pTile);
1254 if (pbase != NULL) {
1255 struct extra_type *base_extra = base_extra_get(pbase);
1256
1257 time = turns_to_activity_done(pTile, ACTIVITY_BASE, base_extra, pUnit);
1258 /* TRANS: "Build Airbase (Shift+E) 5 turns" */
1259 fc_snprintf(cBuf, sizeof(cBuf), _("Build %s (%s) %d %s"),
1260 extra_name_translation(base_extra), "Shift+E", time,
1261 PL_("turn", "turns", time));
1262 copy_chars_to_utf8_str(pOrder_Airbase_Button->info_label, cBuf);
1263 clear_wflag(pOrder_Airbase_Button, WF_HIDDEN);
1264 } else {
1265 set_wflag(pOrder_Airbase_Button, WF_HIDDEN);
1266 }
1267
1268 pextra = prev_extra_in_tile(pTile, ERM_CLEANPOLLUTION,
1269 unit_owner(pUnit), pUnit);
1270 if (pextra != NULL
1271 && can_unit_do_activity_targeted(pUnit, ACTIVITY_POLLUTION, pextra)) {
1272 time = turns_to_activity_done(pTile, ACTIVITY_POLLUTION, pextra,
1273 pUnit);
1274 /* TRANS: "Clean Pollution (P) 3 turns" */
1275 fc_snprintf(cBuf, sizeof(cBuf), _("Clean %s (%s) %d %s"),
1276 extra_name_translation(pextra), "P", time,
1277 PL_("turn", "turns", time));
1278 copy_chars_to_utf8_str(pOrder_Pollution_Button->info_label, cBuf);
1279 clear_wflag(pOrder_Pollution_Button, WF_HIDDEN);
1280 } else {
1281 set_wflag(pOrder_Pollution_Button, WF_HIDDEN);
1282 }
1283
1284 if (can_unit_paradrop(pUnit)) {
1285 local_show(ID_UNIT_ORDER_PARADROP);
1286 } else {
1287 local_hide(ID_UNIT_ORDER_PARADROP);
1288 }
1289
1290 pextra = prev_extra_in_tile(pTile, ERM_CLEANFALLOUT,
1291 unit_owner(pUnit), pUnit);
1292 if (pextra != NULL
1293 && can_unit_do_activity_targeted(pUnit, ACTIVITY_FALLOUT, pextra)) {
1294 time = turns_to_activity_done(pTile, ACTIVITY_FALLOUT, pextra,
1295 pUnit);
1296 /* TRANS: "Clean Fallout (N) 3 turns" */
1297 fc_snprintf(cBuf, sizeof(cBuf), _("Clean %s (%s) %d %s"),
1298 extra_name_translation(pextra), "N", time,
1299 PL_("turn", "turns", time));
1300 copy_chars_to_utf8_str(pOrder_Fallout_Button->info_label, cBuf);
1301 clear_wflag(pOrder_Fallout_Button, WF_HIDDEN);
1302 } else {
1303 set_wflag(pOrder_Fallout_Button, WF_HIDDEN);
1304 }
1305
1306 if (can_unit_do_activity(pUnit, ACTIVITY_SENTRY)) {
1307 local_show(ID_UNIT_ORDER_SENTRY);
1308 } else {
1309 local_hide(ID_UNIT_ORDER_SENTRY);
1310 }
1311
1312 if (can_unit_do_activity(pUnit, ACTIVITY_PILLAGE)) {
1313 local_show(ID_UNIT_ORDER_PILLAGE);
1314 } else {
1315 local_hide(ID_UNIT_ORDER_PILLAGE);
1316 }
1317
1318 if (pCity && can_unit_change_homecity(pUnit)
1319 && pCity->id != pUnit->homecity) {
1320 local_show(ID_UNIT_ORDER_HOMECITY);
1321 } else {
1322 local_hide(ID_UNIT_ORDER_HOMECITY);
1323 }
1324
1325 if (pUnit->client.occupied) {
1326 local_show(ID_UNIT_ORDER_UNLOAD_TRANSPORTER);
1327 } else {
1328 local_hide(ID_UNIT_ORDER_UNLOAD_TRANSPORTER);
1329 }
1330
1331 if (units_can_load(punits)) {
1332 local_show(ID_UNIT_ORDER_LOAD);
1333 } else {
1334 local_hide(ID_UNIT_ORDER_LOAD);
1335 }
1336
1337 if (units_can_unload(punits)) {
1338 local_show(ID_UNIT_ORDER_UNLOAD);
1339 } else {
1340 local_hide(ID_UNIT_ORDER_UNLOAD);
1341 }
1342
1343 if (is_unit_activity_on_tile(ACTIVITY_SENTRY, unit_tile(pUnit))) {
1344 local_show(ID_UNIT_ORDER_WAKEUP_OTHERS);
1345 } else {
1346 local_hide(ID_UNIT_ORDER_WAKEUP_OTHERS);
1347 }
1348
1349 if (can_unit_do_autosettlers(pUnit)) {
1350 local_show(ID_UNIT_ORDER_AUTO_SETTLER);
1351 } else {
1352 local_hide(ID_UNIT_ORDER_AUTO_SETTLER);
1353 }
1354
1355 if (can_unit_do_activity(pUnit, ACTIVITY_EXPLORE)) {
1356 local_show(ID_UNIT_ORDER_AUTO_EXPLORE);
1357 } else {
1358 local_hide(ID_UNIT_ORDER_AUTO_EXPLORE);
1359 }
1360
1361 {
1362 bool conn_possible = FALSE;
1363 struct extra_type_list *extras;
1364
1365 extras = extra_type_list_by_cause(EC_IRRIGATION);
1366
1367 if (extra_type_list_size(extras) > 0) {
1368 struct extra_type *tgt;
1369
1370 tgt = extra_type_list_get(extras, 0);
1371 conn_possible = can_units_do_connect(punits, ACTIVITY_IRRIGATE, tgt);
1372 }
1373
1374 if (conn_possible) {
1375 local_show(ID_UNIT_ORDER_CONNECT_IRRIGATE);
1376 } else {
1377 local_hide(ID_UNIT_ORDER_CONNECT_IRRIGATE);
1378 }
1379 }
1380
1381 {
1382 struct road_type *proad = road_by_compat_special(ROCO_ROAD);
1383 bool road_conn_possible;
1384
1385 if (proad != NULL) {
1386 struct extra_type *tgt;
1387
1388 tgt = road_extra_get(proad);
1389
1390 road_conn_possible = can_unit_do_connect(pUnit, ACTIVITY_GEN_ROAD, tgt);
1391 } else {
1392 road_conn_possible = FALSE;
1393 }
1394
1395 if (road_conn_possible) {
1396 local_show(ID_UNIT_ORDER_CONNECT_ROAD);
1397 } else {
1398 local_hide(ID_UNIT_ORDER_CONNECT_ROAD);
1399 }
1400 }
1401
1402 {
1403 struct road_type *proad = road_by_compat_special(ROCO_RAILROAD);
1404 bool road_conn_possible;
1405
1406 if (proad != NULL) {
1407 struct extra_type *tgt;
1408
1409 tgt = road_extra_get(proad);
1410
1411 road_conn_possible = can_unit_do_connect(pUnit, ACTIVITY_GEN_ROAD, tgt);
1412 } else {
1413 road_conn_possible = FALSE;
1414 }
1415
1416 if (road_conn_possible) {
1417 local_show(ID_UNIT_ORDER_CONNECT_RAILROAD);
1418 } else {
1419 local_hide(ID_UNIT_ORDER_CONNECT_RAILROAD);
1420 }
1421 }
1422
1423 if (unit_can_do_action(pUnit, ACTION_ANY)) {
1424 local_show(ID_UNIT_ORDER_DIPLOMAT_DLG);
1425 } else {
1426 local_hide(ID_UNIT_ORDER_DIPLOMAT_DLG);
1427 }
1428
1429 if (unit_has_type_flag(pUnit, UTYF_NUCLEAR)) {
1430 local_show(ID_UNIT_ORDER_NUKE);
1431 } else {
1432 local_hide(ID_UNIT_ORDER_NUKE);
1433 }
1434
1435 if (pCity && pCity->airlift) {
1436 local_show(ID_UNIT_ORDER_AIRLIFT);
1437 hide(ID_UNIT_ORDER_GOTO_CITY);
1438 } else {
1439 local_show(ID_UNIT_ORDER_GOTO_CITY);
1440 local_hide(ID_UNIT_ORDER_AIRLIFT);
1441 }
1442
1443 if (pCity && can_upgrade_unittype(client.conn.playing,
1444 unit_type_get(pUnit))) {
1445 local_show(ID_UNIT_ORDER_UPGRADE);
1446 } else {
1447 local_hide(ID_UNIT_ORDER_UPGRADE);
1448 }
1449
1450 if (unit_can_convert(pUnit)) {
1451 local_show(ID_UNIT_ORDER_CONVERT);
1452 } else {
1453 local_hide(ID_UNIT_ORDER_CONVERT);
1454 }
1455
1456 set_new_order_widget_start_pos();
1457 counter = redraw_order_widgets();
1458
1459 } else {
1460 if (counter) {
1461 hide_group(pBeginOrderWidgetList, pEndOrderWidgetList);
1462 }
1463
1464 counter = 0;
1465 }
1466 }
1467 }
1468
1469 /**************************************************************************
1470 Disable all unit order buttons.
1471 **************************************************************************/
disable_order_buttons(void)1472 void disable_order_buttons(void)
1473 {
1474 undraw_order_widgets();
1475 disable_group(pBeginOrderWidgetList, pEndOrderWidgetList);
1476 redraw_order_widgets();
1477 }
1478
1479 /**************************************************************************
1480 Enable all unit order buttons.
1481 **************************************************************************/
enable_order_buttons(void)1482 void enable_order_buttons(void)
1483 {
1484 if (can_client_issue_orders()) {
1485 undraw_order_widgets();
1486 enable_group(pBeginOrderWidgetList, pEndOrderWidgetList);
1487 redraw_order_widgets();
1488 }
1489 }
1490