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)
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 ***********************************************************************/
15 #include <fc_config.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>
37 #include "improvement.h"
42 #include "traderoutes.h"
46 #include "client_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
;
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
,
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
,
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
,
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
,
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
,
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
,
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,
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,
206 /****************************************************************
208 *****************************************************************/
209 static void diplomat_sabotage_callback(Widget w
, XtPointer client_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
,
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
,
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
,
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
,
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
,
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
,
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
,
333 if(spy_tech_shell_is_modal
)
334 XtSetSensitive(main_form
, TRUE
);
335 XtDestroyWidget(spy_tech_shell
);
338 action_decision_taken(diplomat_id
);
341 /****************************************************************
343 *****************************************************************/
344 static void spy_close_sabotage_callback(Widget w
, XtPointer client_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
,
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
);
369 XtSetSensitive(spy_steal_command
, FALSE
);
372 /****************************************************************
374 *****************************************************************/
375 static void spy_select_improvement_callback(Widget w
, XtPointer client_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
);
386 XtSetSensitive(spy_sabotage_command
, FALSE
);
389 /****************************************************************
391 *****************************************************************/
392 static void spy_steal_callback(Widget w
, XtPointer client_data
,
395 XtDestroyWidget(spy_tech_shell
);
399 log_error("Bug in spy steal tech code");
400 action_decision_taken(diplomat_id
);
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
410 request_do_action(ACTION_SPY_STEAL_TECH
, diplomat_id
,
411 diplomat_target_id
[ATK_CITY
], steal_advance
);
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
,
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
);
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);
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
;
466 static const char *advances_can_steal
[A_LAST
+1];
468 struct unit
*actor_unit
= game_unit_by_number(diplomat_id
);
471 I_T(XtVaCreatePopupShell("spystealtechpopup",
472 (make_modal
? transientShellWidgetClass
:
473 topLevelShellWidgetClass
),
476 spy_tech_form
= XtVaCreateManagedWidget("spystealtechform",
481 spy_advances_list_label
=
482 I_L(XtVaCreateManagedWidget("spystealtechlistlabel", labelWidgetClass
,
483 spy_tech_form
, NULL
));
485 spy_advances_list
= XtVaCreateManagedWidget("spystealtechlist",
491 I_L(XtVaCreateManagedWidget("spystealtechclosecommand", commandWidgetClass
,
492 spy_tech_form
, NULL
));
495 I_L(XtVaCreateManagedWidget("spystealtechcommand", commandWidgetClass
,
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 */
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
;
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
);
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
;
560 static const char *improvements_can_sabotage
[B_LAST
+1];
562 struct unit
*actor_unit
= game_unit_by_number(diplomat_id
);
565 I_T(XtVaCreatePopupShell("spysabotageimprovementspopup",
566 (make_modal
? transientShellWidgetClass
:
567 topLevelShellWidgetClass
),
570 spy_sabotage_form
= XtVaCreateManagedWidget("spysabotageimprovementsform",
575 spy_improvements_list_label
=
576 I_L(XtVaCreateManagedWidget("spysabotageimprovementslistlabel",
581 spy_improvements_list
= XtVaCreateManagedWidget("spysabotageimprovementslist",
587 I_L(XtVaCreateManagedWidget("spysabotageimprovementsclosecommand",
592 spy_sabotage_command
=
593 I_L(XtVaCreateManagedWidget("spysabotageimprovementscommand",
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 */
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
;
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
;
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
,
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
);
643 /****************************************************************
645 *****************************************************************/
646 static void spy_steal_popup(Widget w
, XtPointer client_data
,
649 struct city
*pvcity
= game_city_by_number(diplomat_target_id
[ATK_CITY
]);
650 struct player
*pvictim
= NULL
;
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
;
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,
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
,
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
){
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,
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
,
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
,
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
,
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,
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,
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
804 **************************************************************************/
805 static void act_sel_keep_moving_callback(Widget w
,
806 XtPointer client_data
,
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
)
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
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
;
869 diplomat_target_id
[ATK_UNIT
] = target_unit
->id
;
871 diplomat_target_id
[ATK_UNIT
] = IDENTITY_NUMBER_ZERO
;
875 diplomat_target_id
[ATK_CITY
] = target_city
->id
;
877 diplomat_target_id
[ATK_CITY
] = IDENTITY_NUMBER_ZERO
;
880 if (target_city
&& actor_homecity
) {
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
) {
888 _("Your %s has arrived at %s.\nWhat is your command?"),
889 unit_name_translation(actor_unit
),
890 city_name_get(target_city
));
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
));
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,
918 action_entry(XtNameToWidget(diplomat_dialog
, "*button0"),
919 ACTION_ESTABLISH_EMBASSY
,
922 action_entry(XtNameToWidget(diplomat_dialog
, "*button1"),
923 ACTION_SPY_INVESTIGATE_CITY
,
926 action_entry(XtNameToWidget(diplomat_dialog
, "*button2"),
930 action_entry(XtNameToWidget(diplomat_dialog
, "*button3"),
931 ACTION_SPY_SABOTAGE_CITY
,
934 action_entry(XtNameToWidget(diplomat_dialog
, "*button4"),
935 ACTION_SPY_TARGETED_SABOTAGE_CITY
,
938 action_entry(XtNameToWidget(diplomat_dialog
, "*button5"),
939 ACTION_SPY_STEAL_TECH
,
942 action_entry(XtNameToWidget(diplomat_dialog
, "*button6"),
943 ACTION_SPY_TARGETED_STEAL_TECH
,
946 action_entry(XtNameToWidget(diplomat_dialog
, "*button7"),
947 ACTION_SPY_INCITE_CITY
,
950 action_entry(XtNameToWidget(diplomat_dialog
, "*button8"),
954 action_entry(XtNameToWidget(diplomat_dialog
, "*button9"),
958 action_entry(XtNameToWidget(diplomat_dialog
, "*button10"),
962 action_entry(XtNameToWidget(diplomat_dialog
, "*button11"),
963 ACTION_SPY_BRIBE_UNIT
,
966 action_entry(XtNameToWidget(diplomat_dialog
, "*button12"),
967 ACTION_SPY_SABOTAGE_UNIT
,
970 action_entry(XtNameToWidget(diplomat_dialog
, "*button13"),
971 ACTION_SPY_STEAL_GOLD
,
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
,
979 XtSetSensitive(XtNameToWidget(diplomat_dialog
, "*button14"), FALSE
);
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
;
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
);