Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / client / gui-xaw / action_dialog.c
blob5fe818559d84b7b77b17db8f5eb71d0dd45c1f7e
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996-2005 - Freeciv Development Team
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
21 #include <X11/Intrinsic.h>
22 #include <X11/StringDefs.h>
23 #include <X11/Xaw/Command.h>
24 #include <X11/Xaw/Form.h>
25 #include <X11/Xaw/Label.h>
26 #include <X11/Xaw/List.h>
27 #include <X11/Xaw/SimpleMenu.h>
29 /* utility */
30 #include "astring.h"
31 #include "fcintl.h"
32 #include "log.h"
34 /* common */
35 #include "actions.h"
36 #include "game.h"
37 #include "improvement.h"
38 #include "map.h"
39 #include "movement.h"
40 #include "research.h"
41 #include "tech.h"
42 #include "traderoutes.h"
43 #include "unitlist.h"
45 /* client */
46 #include "client_main.h"
47 #include "control.h"
49 /* client/gui-xaw */
50 #include "citydlg.h"
51 #include "dialogs.h"
52 #include "gui_main.h"
53 #include "gui_stuff.h"
55 /******************************************************************/
56 static Widget spy_tech_shell;
57 static Widget spy_advances_list, spy_advances_list_label;
58 static Widget spy_steal_command;
60 static int spy_tech_shell_is_modal;
61 static int advance_type[A_LAST+1];
62 static int steal_advance = 0;
64 /******************************************************************/
65 static Widget spy_sabotage_shell;
66 static Widget spy_improvements_list, spy_improvements_list_label;
67 static Widget spy_sabotage_command;
69 static int spy_sabotage_shell_is_modal;
70 static int improvement_type[B_LAST+1];
71 static int sabotage_improvement = 0;
73 static Widget diplomat_dialog;
74 int diplomat_id;
75 int diplomat_target_id[ATK_COUNT];
77 #define action_decision_taken(actor_id) \
78 action_selection_no_longer_in_progress(actor_id); \
79 action_decision_clear_want(actor_id); \
80 action_selection_next_in_focus(actor_id);
82 /**************************************************************************
83 User selected enter market place from caravan dialog
84 **************************************************************************/
85 static void caravan_marketplace_callback(Widget w, XtPointer client_data,
86 XtPointer call_data)
88 destroy_message_dialog(w);
89 diplomat_dialog = NULL;
91 if (NULL != game_city_by_number(diplomat_target_id[ATK_CITY])
92 && NULL != game_unit_by_number(diplomat_id)) {
93 request_do_action(ACTION_MARKETPLACE, diplomat_id,
94 diplomat_target_id[ATK_CITY], 0);
97 action_decision_taken(diplomat_id);
100 /****************************************************************
101 User selected traderoute from caravan dialog
102 *****************************************************************/
103 static void caravan_establish_trade_callback(Widget w, XtPointer client_data,
104 XtPointer call_data)
106 destroy_message_dialog(w);
107 diplomat_dialog = NULL;
109 if (NULL != game_city_by_number(diplomat_target_id[ATK_CITY])
110 && NULL != game_unit_by_number(diplomat_id)) {
111 request_do_action(ACTION_TRADE_ROUTE, diplomat_id,
112 diplomat_target_id[ATK_CITY], 0);
115 action_decision_taken(diplomat_id);
118 /****************************************************************
120 *****************************************************************/
121 static void caravan_help_build_wonder_callback(Widget w,
122 XtPointer client_data,
123 XtPointer call_data)
125 destroy_message_dialog(w);
126 diplomat_dialog = NULL;
128 if (NULL != game_city_by_number(diplomat_target_id[ATK_CITY])
129 && NULL != game_unit_by_number(diplomat_id)) {
130 request_do_action(ACTION_HELP_WONDER, diplomat_id,
131 diplomat_target_id[ATK_CITY], 0);
134 action_decision_taken(diplomat_id);
137 /****************************************************************
139 *****************************************************************/
140 static void diplomat_bribe_yes_callback(Widget w, XtPointer client_data,
141 XtPointer call_data)
143 request_do_action(ACTION_SPY_BRIBE_UNIT, diplomat_id,
144 diplomat_target_id[ATK_UNIT], 0);
146 destroy_message_dialog(w);
149 /****************************************************************
151 *****************************************************************/
152 static void diplomat_bribe_no_callback(Widget w, XtPointer client_data,
153 XtPointer call_data)
155 destroy_message_dialog(w);
158 /**************************************************************************
159 Asks the server how much the bribe is
160 **************************************************************************/
161 static void diplomat_bribe_callback(Widget w, XtPointer client_data,
162 XtPointer call_data)
164 destroy_message_dialog(w);
165 diplomat_dialog = NULL;
167 if (NULL != game_unit_by_number(diplomat_id)
168 && NULL != game_unit_by_number(diplomat_target_id[ATK_UNIT])) {
169 request_action_details(ACTION_SPY_BRIBE_UNIT, diplomat_id,
170 diplomat_target_id[ATK_UNIT]);
174 /**************************************************************************
175 Creates and popups the bribe dialog
176 **************************************************************************/
177 void popup_bribe_dialog(struct unit *actor, struct unit *punit, int cost)
179 char tbuf[128], buf[128];
181 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
182 "Treasury contains %d gold.",
183 client_player()->economic.gold),
184 client_player()->economic.gold);
186 if (cost <= client_player()->economic.gold) {
187 fc_snprintf(buf, sizeof(buf),
188 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
189 PL_("Bribe unit for %d gold?\n%s",
190 "Bribe unit for %d gold?\n%s", cost), cost, tbuf);
191 popup_message_dialog(toplevel, "diplomatbribedialog", buf,
192 diplomat_bribe_yes_callback, 0, 0,
193 diplomat_bribe_no_callback, 0, 0,
194 NULL);
195 } else {
196 fc_snprintf(buf, sizeof(buf),
197 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
198 PL_("Bribing the unit costs %d gold.\n%s",
199 "Bribing the unit costs %d gold.\n%s", cost), cost, tbuf);
200 popup_message_dialog(toplevel, "diplomatnogolddialog", buf,
201 diplomat_bribe_no_callback, 0, 0,
202 NULL);
206 /****************************************************************
208 *****************************************************************/
209 static void diplomat_sabotage_callback(Widget w, XtPointer client_data,
210 XtPointer call_data)
212 destroy_message_dialog(w);
213 diplomat_dialog = NULL;
215 if (NULL != game_unit_by_number(diplomat_id)
216 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
217 request_do_action(ACTION_SPY_SABOTAGE_CITY, diplomat_id,
218 diplomat_target_id[ATK_CITY], B_LAST + 1);
221 action_decision_taken(diplomat_id);
224 /****************************************************************
226 *****************************************************************/
227 static void diplomat_embassy_callback(Widget w, XtPointer client_data,
228 XtPointer call_data)
230 destroy_message_dialog(w);
231 diplomat_dialog = NULL;
233 if (NULL != game_unit_by_number(diplomat_id)
234 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
235 request_do_action(ACTION_ESTABLISH_EMBASSY, diplomat_id,
236 diplomat_target_id[ATK_CITY], 0);
239 action_decision_taken(diplomat_id);
242 /****************************************************************
244 *****************************************************************/
245 static void diplomat_investigate_callback(Widget w, XtPointer client_data,
246 XtPointer call_data)
248 destroy_message_dialog(w);
249 diplomat_dialog = NULL;
251 if (NULL != game_city_by_number(diplomat_target_id[ATK_CITY])
252 && NULL != game_unit_by_number(diplomat_id)) {
253 request_do_action(ACTION_SPY_INVESTIGATE_CITY, diplomat_id,
254 diplomat_target_id[ATK_CITY], 0);
257 action_decision_taken(diplomat_id);
260 /****************************************************************
262 *****************************************************************/
263 static void spy_sabotage_unit_callback(Widget w, XtPointer client_data,
264 XtPointer call_data)
266 request_do_action(ACTION_SPY_SABOTAGE_UNIT, diplomat_id,
267 diplomat_target_id[ATK_UNIT], 0);
269 destroy_message_dialog(w);
270 diplomat_dialog = NULL;
273 /****************************************************************
275 *****************************************************************/
276 static void spy_poison_callback(Widget w, XtPointer client_data,
277 XtPointer call_data)
279 destroy_message_dialog(w);
280 diplomat_dialog = NULL;
282 if (NULL != game_unit_by_number(diplomat_id)
283 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
284 request_do_action(ACTION_SPY_POISON, diplomat_id,
285 diplomat_target_id[ATK_CITY], 0);
288 action_decision_taken(diplomat_id);
291 /********************************************************************
292 The player selected "Steal Gold"
293 ********************************************************************/
294 static void spy_steal_gold_callback(Widget w, XtPointer client_data,
295 XtPointer call_data)
297 destroy_message_dialog(w);
298 diplomat_dialog = NULL;
300 if (NULL != game_unit_by_number(diplomat_id)
301 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
302 request_do_action(ACTION_SPY_STEAL_GOLD, diplomat_id,
303 diplomat_target_id[ATK_CITY], 0);
306 action_decision_taken(diplomat_id);
309 /****************************************************************
311 *****************************************************************/
312 static void diplomat_steal_callback(Widget w, XtPointer client_data,
313 XtPointer call_data)
315 destroy_message_dialog(w);
316 diplomat_dialog = NULL;
318 if (NULL != game_unit_by_number(diplomat_id)
319 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
320 request_do_action(ACTION_SPY_STEAL_TECH, diplomat_id,
321 diplomat_target_id[ATK_CITY], A_UNSET);
324 action_decision_taken(diplomat_id);
327 /****************************************************************
329 *****************************************************************/
330 static void spy_close_tech_callback(Widget w, XtPointer client_data,
331 XtPointer call_data)
333 if(spy_tech_shell_is_modal)
334 XtSetSensitive(main_form, TRUE);
335 XtDestroyWidget(spy_tech_shell);
336 spy_tech_shell=0;
338 action_decision_taken(diplomat_id);
341 /****************************************************************
343 *****************************************************************/
344 static void spy_close_sabotage_callback(Widget w, XtPointer client_data,
345 XtPointer call_data)
347 if(spy_sabotage_shell_is_modal)
348 XtSetSensitive(main_form, TRUE);
349 XtDestroyWidget(spy_sabotage_shell);
350 spy_sabotage_shell=0;
352 action_decision_taken(diplomat_id);
355 /****************************************************************
357 *****************************************************************/
358 static void spy_select_tech_callback(Widget w, XtPointer client_data,
359 XtPointer call_data)
361 XawListReturnStruct *ret;
362 ret=XawListShowCurrent(spy_advances_list);
364 if(ret->list_index!=XAW_LIST_NONE && advance_type[ret->list_index] != -1){
365 steal_advance = advance_type[ret->list_index];
366 XtSetSensitive(spy_steal_command, TRUE);
367 return;
369 XtSetSensitive(spy_steal_command, FALSE);
372 /****************************************************************
374 *****************************************************************/
375 static void spy_select_improvement_callback(Widget w, XtPointer client_data,
376 XtPointer call_data)
378 XawListReturnStruct *ret;
379 ret=XawListShowCurrent(spy_improvements_list);
381 if(ret->list_index!=XAW_LIST_NONE){
382 sabotage_improvement = improvement_type[ret->list_index];
383 XtSetSensitive(spy_sabotage_command, TRUE);
384 return;
386 XtSetSensitive(spy_sabotage_command, FALSE);
389 /****************************************************************
391 *****************************************************************/
392 static void spy_steal_callback(Widget w, XtPointer client_data,
393 XtPointer call_data)
395 XtDestroyWidget(spy_tech_shell);
396 spy_tech_shell = 0l;
398 if(!steal_advance){
399 log_error("Bug in spy steal tech code");
400 action_decision_taken(diplomat_id);
401 return;
404 if (NULL != game_unit_by_number(diplomat_id)
405 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
406 if (steal_advance == A_UNSET) {
407 /* This is the untargeted version. */
408 /* FIXME: Don't give the user the untargeted option unless it is
409 * allowed. */
410 request_do_action(ACTION_SPY_STEAL_TECH, diplomat_id,
411 diplomat_target_id[ATK_CITY], steal_advance);
412 } else {
413 /* This is the targeted version. */
414 request_do_action(ACTION_SPY_TARGETED_STEAL_TECH, diplomat_id,
415 diplomat_target_id[ATK_CITY], steal_advance);
419 action_decision_taken(diplomat_id);
422 /****************************************************************
424 *****************************************************************/
425 static void spy_sabotage_callback(Widget w, XtPointer client_data,
426 XtPointer call_data)
428 XtDestroyWidget(spy_sabotage_shell);
429 spy_sabotage_shell = 0l;
431 if (sabotage_improvement < -1) {
432 log_error("Bug in spy sabotage code");
433 action_decision_taken(diplomat_id);
434 return;
437 if (NULL != game_unit_by_number(diplomat_id)
438 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
439 if (sabotage_improvement == B_LAST) {
440 /* This is the untargeted version. */
441 request_do_action(ACTION_SPY_SABOTAGE_CITY, diplomat_id,
442 diplomat_target_id[ATK_CITY],
443 sabotage_improvement + 1);
444 } else {
445 /* This is the targeted version. */
446 request_do_action(ACTION_SPY_TARGETED_SABOTAGE_CITY, diplomat_id,
447 diplomat_target_id[ATK_CITY],
448 sabotage_improvement + 1);
452 action_decision_taken(diplomat_id);
455 /****************************************************************
457 *****************************************************************/
458 static int create_advances_list(struct player *pplayer,
459 struct player *pvictim, bool make_modal)
461 Widget spy_tech_form;
462 Widget close_command;
463 Dimension width1, width2;
464 int j;
466 static const char *advances_can_steal[A_LAST+1];
468 struct unit *actor_unit = game_unit_by_number(diplomat_id);
470 spy_tech_shell =
471 I_T(XtVaCreatePopupShell("spystealtechpopup",
472 (make_modal ? transientShellWidgetClass :
473 topLevelShellWidgetClass),
474 toplevel, NULL));
476 spy_tech_form = XtVaCreateManagedWidget("spystealtechform",
477 formWidgetClass,
478 spy_tech_shell,
479 NULL);
481 spy_advances_list_label =
482 I_L(XtVaCreateManagedWidget("spystealtechlistlabel", labelWidgetClass,
483 spy_tech_form, NULL));
485 spy_advances_list = XtVaCreateManagedWidget("spystealtechlist",
486 listWidgetClass,
487 spy_tech_form,
488 NULL);
490 close_command =
491 I_L(XtVaCreateManagedWidget("spystealtechclosecommand", commandWidgetClass,
492 spy_tech_form, NULL));
494 spy_steal_command =
495 I_L(XtVaCreateManagedWidget("spystealtechcommand", commandWidgetClass,
496 spy_tech_form,
497 XtNsensitive, False,
498 NULL));
501 XtAddCallback(spy_advances_list, XtNcallback, spy_select_tech_callback, NULL);
502 XtAddCallback(close_command, XtNcallback, spy_close_tech_callback, NULL);
503 XtAddCallback(spy_steal_command, XtNcallback, spy_steal_callback, NULL);
504 XtRealizeWidget(spy_tech_shell);
506 /* Now populate the list */
508 j = 0;
509 advances_can_steal[j] = _("NONE");
510 advance_type[j] = -1;
512 if (pvictim) { /* you don't want to know what lag can do -- Syela */
513 const struct research *presearch = research_get(pplayer);
514 const struct research *vresearch = research_get(pvictim);
516 advance_index_iterate(A_FIRST, i) {
517 if (research_invention_state(vresearch, i) == TECH_KNOWN
518 && (research_invention_state(presearch, i) == TECH_UNKNOWN
519 || research_invention_state(presearch, i)
520 == TECH_PREREQS_KNOWN)) {
521 advances_can_steal[j] = advance_name_translation(advance_by_number(i));
522 advance_type[j++] = i;
526 static struct astring str = ASTRING_INIT;
527 /* TRANS: %s is a unit name, e.g., Spy */
528 astr_set(&str, _("At %s's Discretion"),
529 unit_name_translation(actor_unit));
530 advances_can_steal[j] = astr_str(&str);
531 advance_type[j++] = A_UNSET;
533 } advance_index_iterate_end;
535 if(j == 0) j++;
536 advances_can_steal[j] = NULL;
538 XtSetSensitive(spy_steal_command, FALSE);
540 XawListChange(spy_advances_list, (char **)advances_can_steal, 0, 0, 1);
541 XtVaGetValues(spy_advances_list, XtNwidth, &width1, NULL);
542 XtVaGetValues(spy_advances_list_label, XtNwidth, &width2, NULL);
543 XtVaSetValues(spy_advances_list, XtNwidth, MAX(width1,width2), NULL);
544 XtVaSetValues(spy_advances_list_label, XtNwidth, MAX(width1,width2), NULL);
546 return j;
549 /****************************************************************
551 *****************************************************************/
552 static int create_improvements_list(struct player *pplayer,
553 struct city *pcity, bool make_modal)
555 Widget spy_sabotage_form;
556 Widget close_command;
557 Dimension width1, width2;
558 int j;
560 static const char *improvements_can_sabotage[B_LAST+1];
562 struct unit *actor_unit = game_unit_by_number(diplomat_id);
564 spy_sabotage_shell =
565 I_T(XtVaCreatePopupShell("spysabotageimprovementspopup",
566 (make_modal ? transientShellWidgetClass :
567 topLevelShellWidgetClass),
568 toplevel, NULL));
570 spy_sabotage_form = XtVaCreateManagedWidget("spysabotageimprovementsform",
571 formWidgetClass,
572 spy_sabotage_shell,
573 NULL);
575 spy_improvements_list_label =
576 I_L(XtVaCreateManagedWidget("spysabotageimprovementslistlabel",
577 labelWidgetClass,
578 spy_sabotage_form,
579 NULL));
581 spy_improvements_list = XtVaCreateManagedWidget("spysabotageimprovementslist",
582 listWidgetClass,
583 spy_sabotage_form,
584 NULL);
586 close_command =
587 I_L(XtVaCreateManagedWidget("spysabotageimprovementsclosecommand",
588 commandWidgetClass,
589 spy_sabotage_form,
590 NULL));
592 spy_sabotage_command =
593 I_L(XtVaCreateManagedWidget("spysabotageimprovementscommand",
594 commandWidgetClass,
595 spy_sabotage_form,
596 XtNsensitive, False,
597 NULL));
600 XtAddCallback(spy_improvements_list, XtNcallback, spy_select_improvement_callback, NULL);
601 XtAddCallback(close_command, XtNcallback, spy_close_sabotage_callback, NULL);
602 XtAddCallback(spy_sabotage_command, XtNcallback, spy_sabotage_callback, NULL);
603 XtRealizeWidget(spy_sabotage_shell);
605 /* Now populate the list */
607 j = 0;
608 improvements_can_sabotage[j] = _("City Production");
609 improvement_type[j++] = -1;
611 city_built_iterate(pcity, pimprove) {
612 if (pimprove->sabotage > 0) {
613 improvements_can_sabotage[j] = city_improvement_name_translation(pcity, pimprove);
614 improvement_type[j++] = improvement_number(pimprove);
616 } city_built_iterate_end;
618 if(j > 1) {
619 static struct astring str = ASTRING_INIT;
620 /* TRANS: %s is a unit name, e.g., Spy */
621 astr_set(&str, _("At %s's Discretion"),
622 unit_name_translation(actor_unit));
623 improvements_can_sabotage[j] = astr_str(&str);
624 improvement_type[j++] = B_LAST;
625 } else {
626 improvement_type[0] = B_LAST; /* fake "discretion", since must be production */
629 improvements_can_sabotage[j] = NULL;
631 XtSetSensitive(spy_sabotage_command, FALSE);
633 XawListChange(spy_improvements_list, (String *) improvements_can_sabotage,
634 0, 0, 1);
635 XtVaGetValues(spy_improvements_list, XtNwidth, &width1, NULL);
636 XtVaGetValues(spy_improvements_list_label, XtNwidth, &width2, NULL);
637 XtVaSetValues(spy_improvements_list, XtNwidth, MAX(width1,width2), NULL);
638 XtVaSetValues(spy_improvements_list_label, XtNwidth, MAX(width1,width2), NULL);
640 return j;
643 /****************************************************************
645 *****************************************************************/
646 static void spy_steal_popup(Widget w, XtPointer client_data,
647 XtPointer call_data)
649 struct city *pvcity = game_city_by_number(diplomat_target_id[ATK_CITY]);
650 struct player *pvictim = NULL;
652 if(pvcity)
653 pvictim = city_owner(pvcity);
655 /* it is concievable that pvcity will not be found, because something
656 has happened to the city during latency. Therefore we must initialize
657 pvictim to NULL and account for !pvictim in create_advances_list. -- Syela */
659 destroy_message_dialog(w);
660 diplomat_dialog = NULL;
662 if(!spy_tech_shell){
663 Position x, y;
664 Dimension width, height;
665 spy_tech_shell_is_modal=1;
667 create_advances_list(client.conn.playing, pvictim, spy_tech_shell_is_modal);
669 XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
671 XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
672 &x, &y);
673 XtVaSetValues(spy_tech_shell, XtNx, x, XtNy, y, NULL);
675 XtPopup(spy_tech_shell, XtGrabNone);
679 /**************************************************************************
680 Requests up-to-date list of improvements, the return of
681 which will trigger the popup_sabotage_dialog() function.
682 **************************************************************************/
683 static void spy_request_sabotage_list(Widget w, XtPointer client_data,
684 XtPointer call_data)
686 destroy_message_dialog(w);
687 diplomat_dialog = NULL;
689 if (NULL != game_unit_by_number(diplomat_id)
690 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
691 request_action_details(ACTION_SPY_TARGETED_SABOTAGE_CITY, diplomat_id,
692 diplomat_target_id[ATK_CITY]);
696 /**************************************************************************
697 Pops-up the Spy sabotage dialog, upon return of list of
698 available improvements requested by the above function.
699 **************************************************************************/
700 void popup_sabotage_dialog(struct unit *actor, struct city *pcity)
702 if(!spy_sabotage_shell){
703 Position x, y;
704 Dimension width, height;
705 spy_sabotage_shell_is_modal=1;
707 create_improvements_list(client.conn.playing, pcity, spy_sabotage_shell_is_modal);
709 XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
711 XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
712 &x, &y);
713 XtVaSetValues(spy_sabotage_shell, XtNx, x, XtNy, y, NULL);
715 XtPopup(spy_sabotage_shell, XtGrabNone);
719 /****************************************************************
721 *****************************************************************/
722 static void diplomat_incite_yes_callback(Widget w, XtPointer client_data,
723 XtPointer call_data)
725 request_do_action(ACTION_SPY_INCITE_CITY, diplomat_id,
726 diplomat_target_id[ATK_CITY], 0);
728 destroy_message_dialog(w);
730 action_decision_taken(diplomat_id);
733 /****************************************************************
735 *****************************************************************/
736 static void diplomat_incite_no_callback(Widget w, XtPointer client_data,
737 XtPointer call_data)
739 destroy_message_dialog(w);
741 action_decision_taken(diplomat_id);
745 /**************************************************************************
746 Asks the server how much the revolt is going to cost us
747 **************************************************************************/
748 static void diplomat_incite_callback(Widget w, XtPointer client_data,
749 XtPointer call_data)
751 destroy_message_dialog(w);
752 diplomat_dialog = NULL;
754 if (NULL != game_unit_by_number(diplomat_id)
755 && NULL != game_city_by_number(diplomat_target_id[ATK_CITY])) {
756 request_action_details(ACTION_SPY_INCITE_CITY, diplomat_id,
757 diplomat_target_id[ATK_CITY]);
761 /**************************************************************************
762 Popup the yes/no dialog for inciting, since we know the cost now
763 **************************************************************************/
764 void popup_incite_dialog(struct unit *actor, struct city *pcity, int cost)
766 char tbuf[128], buf[128];
768 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
769 "Treasury contains %d gold.",
770 client_player()->economic.gold),
771 client_player()->economic.gold);
773 if (INCITE_IMPOSSIBLE_COST == cost) {
774 fc_snprintf(buf, sizeof(buf), _("You can't incite a revolt in %s."),
775 city_name_get(pcity));
776 popup_message_dialog(toplevel, "diplomatnogolddialog", buf,
777 diplomat_incite_no_callback, 0, 0, NULL);
778 } else if (cost <= client_player()->economic.gold) {
779 fc_snprintf(buf, sizeof(buf),
780 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
781 PL_("Incite a revolt for %d gold?\n%s",
782 "Incite a revolt for %d gold?\n%s", cost), cost, tbuf);
783 diplomat_target_id[ATK_CITY] = pcity->id;
784 popup_message_dialog(toplevel, "diplomatrevoltdialog", buf,
785 diplomat_incite_yes_callback, 0, 0,
786 diplomat_incite_no_callback, 0, 0,
787 NULL);
788 } else {
789 fc_snprintf(buf, sizeof(buf),
790 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
791 PL_("Inciting a revolt costs %d gold.\n%s",
792 "Inciting a revolt costs %d gold.\n%s", cost), cost, tbuf);
793 popup_message_dialog(toplevel, "diplomatnogolddialog", buf,
794 diplomat_incite_no_callback, 0, 0,
795 NULL);
800 /**************************************************************************
801 Callback from action selection dialog for "keep moving".
802 (This should only occur when entering a tile that has an allied city or
803 an allied unit.)
804 **************************************************************************/
805 static void act_sel_keep_moving_callback(Widget w,
806 XtPointer client_data,
807 XtPointer call_data)
809 struct unit *punit;
810 struct tile *ptile;
812 destroy_message_dialog(w);
813 diplomat_dialog = NULL;
815 if ((punit = game_unit_by_number(diplomat_id))
816 && (ptile = (struct tile *)client_data)
817 && !same_pos(unit_tile(punit), ptile)) {
818 request_unit_non_action_move(punit, ptile);
820 action_decision_taken(diplomat_id);
823 /****************************************************************
825 *****************************************************************/
826 static void diplomat_cancel_callback(Widget w, XtPointer a, XtPointer b)
828 destroy_message_dialog(w);
829 diplomat_dialog = NULL;
831 action_decision_taken(diplomat_id);
834 /*************************************************************************
835 Control the display of an action
836 **************************************************************************/
837 static void action_entry(Widget w, int action_id,
838 const struct act_prob *act_probs)
840 Arg arglist[1];
842 if (!action_prob_possible(act_probs[action_id])) {
843 XtSetSensitive(w, FALSE);
846 XtSetArg(arglist[0], "label",
847 action_prepare_ui_name(action_id, "",
848 act_probs[action_id], NULL));
849 XtSetValues(w, arglist, XtNumber(arglist));
852 /**************************************************************************
853 Popup a dialog that allows the player to select what action a unit
854 should take.
855 **************************************************************************/
856 void popup_action_selection(struct unit *actor_unit,
857 struct city *target_city,
858 struct unit *target_unit,
859 struct tile *target_tile,
860 const struct act_prob *act_probs)
862 struct astring text = ASTRING_INIT;
864 struct city *actor_homecity = game_city_by_number(actor_unit->homecity);
866 diplomat_id = actor_unit->id;
868 if (target_unit) {
869 diplomat_target_id[ATK_UNIT] = target_unit->id;
870 } else {
871 diplomat_target_id[ATK_UNIT] = IDENTITY_NUMBER_ZERO;
874 if (target_city) {
875 diplomat_target_id[ATK_CITY] = target_city->id;
876 } else {
877 diplomat_target_id[ATK_CITY] = IDENTITY_NUMBER_ZERO;
880 if (target_city && actor_homecity) {
881 astr_set(&text,
882 _("Your %s from %s reaches the city of %s.\nWhat now?"),
883 unit_name_translation(actor_unit),
884 city_name_get(actor_homecity),
885 city_name_get(target_city));
886 } else if (target_city) {
887 astr_set(&text,
888 _("Your %s has arrived at %s.\nWhat is your command?"),
889 unit_name_translation(actor_unit),
890 city_name_get(target_city));
891 } else {
892 astr_set(&text,
893 /* TRANS: %s is a unit name, e.g., Diplomat, Spy */
894 _("Your %s is waiting for your command."),
895 unit_name_translation(actor_unit));
898 diplomat_dialog =
899 popup_message_dialog(toplevel, "diplomatdialog", astr_str(&text),
900 diplomat_embassy_callback, 0, 1,
901 diplomat_investigate_callback, 0, 1,
902 spy_poison_callback, 0, 1,
903 diplomat_sabotage_callback, 0, 1,
904 spy_request_sabotage_list, 0, 1,
905 diplomat_steal_callback, 0, 1,
906 spy_steal_popup, 0, 1,
907 diplomat_incite_callback, 0, 1,
908 caravan_establish_trade_callback, 0, 0,
909 caravan_marketplace_callback, 0, 0,
910 caravan_help_build_wonder_callback, 0, 0,
911 diplomat_bribe_callback, 0, 0,
912 spy_sabotage_unit_callback, 0, 0,
913 spy_steal_gold_callback, 0, 0,
914 act_sel_keep_moving_callback, target_tile, 1,
915 diplomat_cancel_callback, 0, 0,
916 NULL);
918 action_entry(XtNameToWidget(diplomat_dialog, "*button0"),
919 ACTION_ESTABLISH_EMBASSY,
920 act_probs);
922 action_entry(XtNameToWidget(diplomat_dialog, "*button1"),
923 ACTION_SPY_INVESTIGATE_CITY,
924 act_probs);
926 action_entry(XtNameToWidget(diplomat_dialog, "*button2"),
927 ACTION_SPY_POISON,
928 act_probs);
930 action_entry(XtNameToWidget(diplomat_dialog, "*button3"),
931 ACTION_SPY_SABOTAGE_CITY,
932 act_probs);
934 action_entry(XtNameToWidget(diplomat_dialog, "*button4"),
935 ACTION_SPY_TARGETED_SABOTAGE_CITY,
936 act_probs);
938 action_entry(XtNameToWidget(diplomat_dialog, "*button5"),
939 ACTION_SPY_STEAL_TECH,
940 act_probs);
942 action_entry(XtNameToWidget(diplomat_dialog, "*button6"),
943 ACTION_SPY_TARGETED_STEAL_TECH,
944 act_probs);
946 action_entry(XtNameToWidget(diplomat_dialog, "*button7"),
947 ACTION_SPY_INCITE_CITY,
948 act_probs);
950 action_entry(XtNameToWidget(diplomat_dialog, "*button8"),
951 ACTION_TRADE_ROUTE,
952 act_probs);
954 action_entry(XtNameToWidget(diplomat_dialog, "*button9"),
955 ACTION_MARKETPLACE,
956 act_probs);
958 action_entry(XtNameToWidget(diplomat_dialog, "*button10"),
959 ACTION_HELP_WONDER,
960 act_probs);
962 action_entry(XtNameToWidget(diplomat_dialog, "*button11"),
963 ACTION_SPY_BRIBE_UNIT,
964 act_probs);
966 action_entry(XtNameToWidget(diplomat_dialog, "*button12"),
967 ACTION_SPY_SABOTAGE_UNIT,
968 act_probs);
970 action_entry(XtNameToWidget(diplomat_dialog, "*button13"),
971 ACTION_SPY_STEAL_GOLD,
972 act_probs);
974 if (!(unit_can_move_to_tile(actor_unit, target_tile, FALSE)
975 || (is_military_unit(actor_unit) || is_attack_unit(actor_unit))
976 || (can_unit_bombard(actor_unit) && !is_ocean_tile(target_tile))
977 || (!target_city && unit_has_type_flag(actor_unit,
978 UTYF_CAPTURER)))) {
979 XtSetSensitive(XtNameToWidget(diplomat_dialog, "*button14"), FALSE);
982 astr_free(&text);
985 /**************************************************************************
986 Returns the id of the actor unit currently handled in action selection
987 dialog when the action selection dialog is open.
988 Returns IDENTITY_NUMBER_ZERO if no action selection dialog is open.
989 **************************************************************************/
990 int action_selection_actor_unit(void)
992 if (diplomat_dialog == NULL) {
993 return IDENTITY_NUMBER_ZERO;
996 return diplomat_id;
999 /**************************************************************************
1000 Returns id of the target city of the actions currently handled in action
1001 selection dialog when the action selection dialog is open and it has a
1002 city target. Returns IDENTITY_NUMBER_ZERO if no action selection dialog
1003 is open or no city target is present in the action selection dialog.
1004 **************************************************************************/
1005 int action_selection_target_city(void)
1007 if (diplomat_dialog == NULL) {
1008 return IDENTITY_NUMBER_ZERO;
1011 return diplomat_target_id[ATK_CITY];
1014 /**************************************************************************
1015 Returns id of the target unit of the actions currently handled in action
1016 selection dialog when the action selection dialog is open and it has a
1017 unit target. Returns IDENTITY_NUMBER_ZERO if no action selection dialog
1018 is open or no unit target is present in the action selection dialog.
1019 **************************************************************************/
1020 int action_selection_target_unit(void)
1022 if (diplomat_dialog == NULL) {
1023 return IDENTITY_NUMBER_ZERO;
1026 return diplomat_target_id[ATK_UNIT];
1029 /**************************************************************************
1030 Updates the action selection dialog with new information.
1031 **************************************************************************/
1032 void action_selection_refresh(struct unit *actor_unit,
1033 struct city *target_city,
1034 struct unit *target_unit,
1035 struct tile *target_tile,
1036 const struct act_prob *act_probs)
1038 /* TODO: port me. */
1041 /**************************************************************************
1042 Closes the action selection dialog
1043 **************************************************************************/
1044 void action_selection_close(void)
1046 if (diplomat_dialog != NULL) {
1047 action_selection_no_longer_in_progress(diplomat_id);
1049 XtDestroyWidget(diplomat_dialog);