Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-gtk-5.0/action_dialog.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
action_dialog.c
Go to the documentation of this file.
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.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <gtk/gtk.h>
19
20/* utility */
21#include "astring.h"
22#include "support.h"
23
24/* common */
25#include "actions.h"
26#include "game.h"
27#include "traderoutes.h"
28#include "movement.h"
29#include "research.h"
30#include "unit.h"
31#include "unitlist.h"
32
33/* client */
34#include "dialogs_g.h"
35#include "chatline.h"
36#include "choice_dialog.h"
37#include "client_main.h"
38#include "climisc.h"
39#include "connectdlg_common.h"
40#include "control.h"
41#include "gui_main.h"
42#include "gui_stuff.h"
43#include "mapview.h"
44#include "packhand.h"
45#include "text.h"
46
47/* client/gui-gtk-5.0 */
48#include "citydlg.h"
49#include "dialogs.h"
50#include "unitselextradlg.h"
51#include "unitselunitdlg.h"
52#include "wldlg.h"
53
54/* Locations for non action enabler controlled buttons. */
55#define BUTTON_NEW_UNIT_TGT (ACTION_COUNT + 1)
56#define BUTTON_NEW_EXTRA_TGT (BUTTON_NEW_UNIT_TGT + 1)
57#define BUTTON_LOCATION (BUTTON_NEW_EXTRA_TGT + 1)
58#define BUTTON_WAIT (BUTTON_LOCATION + 1)
59#define BUTTON_CANCEL (BUTTON_WAIT + 1)
60#define BUTTON_COUNT (BUTTON_CANCEL + 1)
61
62#define BUTTON_NOT_THERE -1
63
64
65 static GtkWidget *act_sel_dialog;
66 static int action_button_map[BUTTON_COUNT];
67
68 static int actor_unit_id;
69 static int target_ids[ATK_COUNT];
70 static int target_extra_id;
71 static bool is_more_user_input_needed = FALSE;
72 static bool did_not_decide = FALSE;
73 static bool action_selection_restart = FALSE;
74
75 static GtkWidget *spy_tech_shell;
76
77 static GtkWidget *spy_sabotage_shell;
78
79/* A structure to hold parameters for actions inside the GUI instead of
80 * storing the needed data in a global variable. */
81struct action_data {
82 action_id act_id;
83 int actor_unit_id;
84 int target_city_id;
85 int target_unit_id;
86 int target_tile_id;
87 int target_building_id;
88 int target_tech_id;
89 int target_extra_id;
90};
91
92/* TODO: Maybe this should be in the dialog itself? */
93 static struct action_data *act_sel_dialog_data;
94
95/**********************************************************************/
99 static struct action_data *act_data(action_id act_id,
100 int actor_id,
101 int target_city_id,
102 int target_unit_id,
103 int target_tile_id,
104 int target_building_id,
105 int target_tech_id,
106 int tgt_extra_id)
107{
108 struct action_data *data = fc_malloc(sizeof(*data));
109
110 data->act_id = act_id;
111 data->actor_unit_id = actor_id;
112 data->target_city_id = target_city_id;
113 data->target_unit_id = target_unit_id;
114 data->target_tile_id = target_tile_id;
115 data->target_building_id = target_building_id;
116 data->target_tech_id = target_tech_id;
117 data->target_extra_id = tgt_extra_id;
118
119 return data;
120}
121
122/**********************************************************************/
126 static void diplomat_queue_handle_primary(void)
127{
128 if (!is_more_user_input_needed) {
129 /* The client isn't waiting for information for any unanswered follow
130 * up questions. */
131
132 struct unit *actor_unit;
133
134 if ((actor_unit = game_unit_by_number(actor_unit_id))) {
135 /* The action selection dialog wasn't closed because the actor unit
136 * was lost. */
137
138 /* The probabilities didn't just disappear, right? */
139 fc_assert_action(actor_unit->client.act_prob_cache,
140 client_unit_init_act_prob_cache(actor_unit));
141
142 FC_FREE(actor_unit->client.act_prob_cache);
143 }
144
145 if (action_selection_restart) {
146 /* The action selection dialog was closed but only so it can be
147 * redrawn with fresh data. */
148
149 action_selection_restart = FALSE;
150 } else {
151 /* The action selection process is over, at least for now. */
152 action_selection_no_longer_in_progress(actor_unit_id);
153 }
154
155 if (did_not_decide) {
156 /* The action selection dialog was closed but the player didn't
157 * decide what the unit should do. */
158
159 /* Reset so the next action selection dialog does the right thing. */
160 did_not_decide = FALSE;
161 } else {
162 /* An action, or no action at all, was selected. */
163 action_decision_clear_want(actor_unit_id);
164 action_selection_next_in_focus(actor_unit_id);
165 }
166 }
167}
168
169/**********************************************************************/
173 static void diplomat_queue_handle_secondary(void)
174{
175 /* Stop waiting. Move on to the next queued unit. */
176 is_more_user_input_needed = FALSE;
177 diplomat_queue_handle_primary();
178}
179
180/**********************************************************************/
186 void action_selection_no_longer_in_progress_gui_specific(int actor_id)
187{
188 /* Stop assuming the answer to a follow up question will arrive. */
189 is_more_user_input_needed = FALSE;
190}
191
192/**********************************************************************/
196 static action_id get_non_targeted_action_id(action_id tgt_action_id)
197{
198 /* Don't add an action mapping here unless the non targeted version is
199 * selectable in the targeted version's target selection dialog. */
200 switch ((enum gen_action)tgt_action_id) {
201 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
202 return ACTION_SPY_SABOTAGE_CITY;
203 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
204 return ACTION_SPY_SABOTAGE_CITY_ESC;
205 case ACTION_SPY_TARGETED_STEAL_TECH:
206 return ACTION_SPY_STEAL_TECH;
207 case ACTION_SPY_TARGETED_STEAL_TECH_ESC:
208 return ACTION_SPY_STEAL_TECH_ESC;
209 default:
210 /* No non targeted version found. */
211 return ACTION_NONE;
212 }
213}
214
215/**********************************************************************/
219 static action_id get_production_targeted_action_id(action_id tgt_action_id)
220{
221 /* Don't add an action mapping here unless the non targeted version is
222 * selectable in the targeted version's target selection dialog. */
223 switch ((enum gen_action)tgt_action_id) {
224 case ACTION_SPY_TARGETED_SABOTAGE_CITY:
225 return ACTION_SPY_SABOTAGE_CITY_PRODUCTION;
226 case ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC:
227 return ACTION_SPY_SABOTAGE_CITY_PRODUCTION_ESC;
228 case ACTION_STRIKE_BUILDING:
229 return ACTION_STRIKE_PRODUCTION;
230 default:
231 /* No non targeted version found. */
232 return ACTION_NONE;
233 }
234}
235
236/**********************************************************************/
240 static void simple_action_callback(GtkWidget *w, gpointer data)
241{
242 int actor_id, target_id, sub_target;
243 struct action *paction;
244
245 struct action_data *args = act_sel_dialog_data;
246
247 bool failed = FALSE;
248
249 /* Data */
250 args->act_id = GPOINTER_TO_INT(data);
251 paction = action_by_number(args->act_id);
252
253 /* Actor */
254 fc_assert(action_get_actor_kind(paction) == AAK_UNIT);
255 actor_id = args->actor_unit_id;
256 if (NULL == game_unit_by_number(actor_id)) {
257 /* Probably dead. */
258 failed = TRUE;
259 }
260
261 /* Target */
262 target_id = IDENTITY_NUMBER_ZERO;
263 switch (action_get_target_kind(paction)) {
264 case ATK_CITY:
265 target_id = args->target_city_id;
266 if (NULL == game_city_by_number(target_id)) {
267 /* Probably destroyed. */
268 failed = TRUE;
269 }
270 break;
271 case ATK_UNIT:
272 target_id = args->target_unit_id;
273 if (NULL == game_unit_by_number(target_id)) {
274 /* Probably dead. */
275 failed = TRUE;
276 }
277 break;
278 case ATK_UNITS:
279 case ATK_TILE:
280 case ATK_EXTRAS:
281 target_id = args->target_tile_id;
282 if (NULL == index_to_tile(&(wld.map), target_id)) {
283 /* TODO: Should this be possible at all? If not: add assertion. */
284 failed = TRUE;
285 }
286 break;
287 case ATK_SELF:
288 target_id = IDENTITY_NUMBER_ZERO;
289 break;
290 case ATK_COUNT:
291 fc_assert(action_get_target_kind(paction) != ATK_COUNT);
292 failed = TRUE;
293 }
294
295 /* Sub target. */
296 sub_target = NO_TARGET;
297 if (paction->target_complexity != ACT_TGT_COMPL_SIMPLE) {
298 switch (action_get_sub_target_kind(paction)) {
299 case ASTK_BUILDING:
300 sub_target = args->target_building_id;
301 if (NULL == improvement_by_number(sub_target)) {
302 /* Did the ruleset change? */
303 failed = TRUE;
304 }
305 break;
306 case ASTK_TECH:
307 sub_target = args->target_tech_id;
308 if (NULL == valid_advance_by_number(sub_target)) {
309 /* Did the ruleset change? */
310 failed = TRUE;
311 }
312 break;
313 case ASTK_EXTRA:
314 case ASTK_EXTRA_NOT_THERE:
315 /* TODO: Validate if the extra is there? */
316 sub_target = args->target_extra_id;
317 if (NULL == extra_by_number(sub_target)) {
318 /* Did the ruleset change? */
319 failed = TRUE;
320 }
321 break;
322 case ASTK_NONE:
323 case ASTK_COUNT:
324 /* Shouldn't happen. */
325 fc_assert(action_get_sub_target_kind(paction) != ASTK_NONE);
326 failed = TRUE;
327 break;
328 }
329 }
330
331 /* Send request. */
332 if (!failed) {
333 request_do_action(paction->id, actor_id, target_id, sub_target, "");
334 }
335
336 /* Clean up. */
337 choice_dialog_destroy(act_sel_dialog);
338 /* No follow up questions. */
339 act_sel_dialog_data = NULL;
340 FC_FREE(args);
341}
342
343/**********************************************************************/
347 static void request_action_details_callback(GtkWidget *w, gpointer data)
348{
349 int actor_id, target_id;
350 struct action *paction;
351
352 struct action_data *args = act_sel_dialog_data;
353
354 bool failed = FALSE;
355
356 /* Data */
357 args->act_id = GPOINTER_TO_INT(data);
358 paction = action_by_number(args->act_id);
359
360 /* Actor */
361 fc_assert(action_get_actor_kind(paction) == AAK_UNIT);
362 actor_id = args->actor_unit_id;
363 if (NULL == game_unit_by_number(actor_id)) {
364 /* Probably dead. */
365 failed = TRUE;
366 }
367
368 /* Target */
369 target_id = IDENTITY_NUMBER_ZERO;
370 switch (action_get_target_kind(paction)) {
371 case ATK_CITY:
372 target_id = args->target_city_id;
373 if (NULL == game_city_by_number(target_id)) {
374 /* Probably destroyed. */
375 failed = TRUE;
376 }
377 break;
378 case ATK_UNIT:
379 target_id = args->target_unit_id;
380 if (NULL == game_unit_by_number(target_id)) {
381 /* Probably dead. */
382 failed = TRUE;
383 }
384 break;
385 case ATK_UNITS:
386 case ATK_TILE:
387 case ATK_EXTRAS:
388 target_id = args->target_tile_id;
389 if (NULL == index_to_tile(&(wld.map), target_id)) {
390 /* TODO: Should this be possible at all? If not: add assertion. */
391 failed = TRUE;
392 }
393 break;
394 case ATK_SELF:
395 target_id = IDENTITY_NUMBER_ZERO;
396 break;
397 case ATK_COUNT:
398 fc_assert(action_get_target_kind(paction) != ATK_COUNT);
399 failed = TRUE;
400 }
401
402 /* Send request. */
403 if (!failed) {
404 request_action_details(paction->id, actor_id, target_id);
405 }
406
407 /* Wait for the server's reply before moving on to the next unit that
408 * needs to know what action to take. */
409 is_more_user_input_needed = TRUE;
410
411 /* Clean up. */
412 choice_dialog_destroy(act_sel_dialog);
413 /* No client side follow up questions. */
414 act_sel_dialog_data = NULL;
415 FC_FREE(args);
416}
417
418/**********************************************************************/
421 static void found_city_callback(GtkWidget *w, gpointer data)
422{
423 struct action_data *args = act_sel_dialog_data;
424
425 dsend_packet_city_name_suggestion_req(&client.conn,
426 args->actor_unit_id);
427
428 choice_dialog_destroy(act_sel_dialog);
429 free(args);
430}
431
432/**********************************************************************/
435 static void upgrade_callback(GtkWidget *w, gpointer data)
436{
437 struct unit *punit;
438 struct action_data *args = act_sel_dialog_data;
439
440 if ((punit = game_unit_by_number(args->actor_unit_id))
441 && NULL != game_city_by_number(args->target_city_id)) {
442 struct unit_list *as_list;
443
444 as_list = unit_list_new();
445 unit_list_append(as_list, punit);
446 popup_upgrade_dialog(as_list);
447 unit_list_destroy(as_list);
448 }
449
450 choice_dialog_destroy(act_sel_dialog);
451 free(args);
452}
453
454/**********************************************************************/
457 static void bribe_response(GtkWidget *w, gint response, gpointer data)
458{
459 struct action_data *args = (struct action_data *)data;
460
461 if (response == GTK_RESPONSE_YES) {
462 request_do_action(args->act_id, args->actor_unit_id,
463 args->target_unit_id, 0, "");
464 }
465
466 gtk_window_destroy(GTK_WINDOW(w));
467 free(args);
468
469 /* The user have answered the follow up question. Move on. */
470 diplomat_queue_handle_secondary();
471}
472
473/**********************************************************************/
476 void popup_bribe_dialog(struct unit *actor, struct unit *punit, int cost,
477 const struct action *paction)
478{
479 GtkWidget *shell;
480 char buf[1024];
481
482 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Treasury contains %d gold.",
483 "Treasury contains %d gold.",
484 client_player()->economic.gold),
485 client_player()->economic.gold);
486
487 if (cost <= client_player()->economic.gold) {
488 shell = gtk_message_dialog_new(NULL, 0,
489 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
490 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
491 PL_("Bribe unit for %d gold?\n%s",
492 "Bribe unit for %d gold?\n%s", cost), cost, buf);
493 gtk_window_set_title(GTK_WINDOW(shell), _("Bribe Enemy Unit"));
494 setup_dialog(shell, toplevel);
495 } else {
496 shell = gtk_message_dialog_new(NULL, 0,
497 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
498 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
499 PL_("Bribing the unit costs %d gold.\n%s",
500 "Bribing the unit costs %d gold.\n%s", cost), cost, buf);
501 gtk_window_set_title(GTK_WINDOW(shell), _("Traitors Demand Too Much!"));
502 setup_dialog(shell, toplevel);
503 }
504 gtk_window_present(GTK_WINDOW(shell));
505
506 g_signal_connect(shell, "response", G_CALLBACK(bribe_response),
507 act_data(paction->id, actor->id,
508 0, punit->id, 0,
509 0, 0, 0));
510}
511
512/**********************************************************************/
515 static void spy_advances_response(GtkWidget *w, gint response,
516 gpointer data)
517{
518 struct action_data *args = (struct action_data *)data;
519
520 if (response == GTK_RESPONSE_ACCEPT && args->target_tech_id > 0) {
521 if (NULL != game_unit_by_number(args->actor_unit_id)
522 && NULL != game_city_by_number(args->target_city_id)) {
523 if (args->target_tech_id == A_UNSET) {
524 /* This is the untargeted version. */
525 request_do_action(get_non_targeted_action_id(args->act_id),
526 args->actor_unit_id, args->target_city_id,
527 args->target_tech_id, "");
528 } else {
529 /* This is the targeted version. */
530 request_do_action(args->act_id,
531 args->actor_unit_id, args->target_city_id,
532 args->target_tech_id, "");
533 }
534 }
535 }
536
537 gtk_window_destroy(GTK_WINDOW(spy_tech_shell));
538 spy_tech_shell = NULL;
539 free(data);
540
541 /* The user have answered the follow up question. Move on. */
542 diplomat_queue_handle_secondary();
543}
544
545/**********************************************************************/
548 static void spy_advances_callback(GtkTreeSelection *select,
549 gpointer data)
550{
551 struct action_data *args = (struct action_data *)data;
552
553 GtkTreeModel *model;
554 GtkTreeIter it;
555
556 if (gtk_tree_selection_get_selected(select, &model, &it)) {
557 gtk_tree_model_get(model, &it, 1, &(args->target_tech_id), -1);
558
559 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_tech_shell),
560 GTK_RESPONSE_ACCEPT, TRUE);
561 } else {
562 args->target_tech_id = 0;
563
564 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_tech_shell),
565 GTK_RESPONSE_ACCEPT, FALSE);
566 }
567}
568
569/**********************************************************************/
572 static void create_advances_list(struct player *pplayer,
573 struct player *pvictim,
574 struct action_data *args)
575{
576 GtkWidget *sw, *frame, *label, *vgrid, *view;
577 GtkListStore *store;
578 GtkCellRenderer *rend;
579 GtkTreeViewColumn *col;
580
581 struct unit *actor_unit = game_unit_by_number(args->actor_unit_id);
582
583 spy_tech_shell = gtk_dialog_new_with_buttons(_("Steal Technology"),
584 NULL, 0,
585 _("_Cancel"), GTK_RESPONSE_CANCEL,
586 _("_Steal"), GTK_RESPONSE_ACCEPT,
587 NULL);
588 setup_dialog(spy_tech_shell, toplevel);
589
590 gtk_dialog_set_default_response(GTK_DIALOG(spy_tech_shell),
591 GTK_RESPONSE_ACCEPT);
592
593 frame = gtk_frame_new(_("Select Advance to Steal"));
594 gtk_box_append(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(spy_tech_shell))), frame);
595
596 vgrid = gtk_grid_new();
597 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
598 GTK_ORIENTATION_VERTICAL);
599 gtk_grid_set_row_spacing(GTK_GRID(vgrid), 6);
600 gtk_frame_set_child(GTK_FRAME(frame), vgrid);
601
602 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
603
604 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
605 gtk_widget_set_hexpand(view, TRUE);
606 gtk_widget_set_vexpand(view, TRUE);
607 g_object_unref(store);
608 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
609
610 rend = gtk_cell_renderer_text_new();
611 col = gtk_tree_view_column_new_with_attributes(NULL, rend,
612 "text", 0, NULL);
613 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
614
615 label = g_object_new(GTK_TYPE_LABEL,
616 "use-underline", TRUE,
617 "mnemonic-widget", view,
618 "label", _("_Advances:"),
619 "xalign", 0.0,
620 "yalign", 0.5,
621 NULL);
622 gtk_grid_attach(GTK_GRID(vgrid), label, 0, 0, 1, 1);
623
624 sw = gtk_scrolled_window_new();
625 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
626 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
627
628 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
629 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
630 gtk_widget_set_size_request(sw, -1, 200);
631
632 gtk_grid_attach(GTK_GRID(vgrid), sw, 0, 1, 1, 1);
633
634 /* Now populate the list */
635 if (pvictim) { /* You don't want to know what lag can do -- Syela */
636 const struct research *presearch = research_get(pplayer);
637 const struct research *vresearch = research_get(pvictim);
638 GtkTreeIter it;
639 GValue value = { 0, };
640
641 advance_index_iterate(A_FIRST, i) {
642 if (research_invention_gettable(presearch, i,
643 game.info.tech_steal_allow_holes)
644 && research_invention_state(vresearch, i) == TECH_KNOWN
645 && research_invention_state(presearch, i) != TECH_KNOWN) {
646 gtk_list_store_append(store, &it);
647
648 g_value_init(&value, G_TYPE_STRING);
649 g_value_set_static_string(&value, research_advance_name_translation
650 (presearch, i));
651 gtk_list_store_set_value(store, &it, 0, &value);
652 g_value_unset(&value);
653 gtk_list_store_set(store, &it, 1, i, -1);
654 }
655 } advance_index_iterate_end;
656
657 if (action_prob_possible(actor_unit->client.act_prob_cache[
658 get_non_targeted_action_id(args->act_id)])) {
659 gtk_list_store_append(store, &it);
660
661 g_value_init(&value, G_TYPE_STRING);
662 {
663 struct astring str = ASTRING_INIT;
664 /* TRANS: %s is a unit name, e.g., Spy */
665 astr_set(&str, _("At %s's Discretion"),
666 unit_name_translation(actor_unit));
667 g_value_set_string(&value, astr_str(&str));
668 astr_free(&str);
669 }
670 gtk_list_store_set_value(store, &it, 0, &value);
671 g_value_unset(&value);
672 gtk_list_store_set(store, &it, 1, A_UNSET, -1);
673 }
674 }
675
676 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_tech_shell),
677 GTK_RESPONSE_ACCEPT, FALSE);
678
679 gtk_widget_set_visible(gtk_dialog_get_content_area(GTK_DIALOG(spy_tech_shell)),
680 TRUE);
681
682 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), "changed",
683 G_CALLBACK(spy_advances_callback), args);
684 g_signal_connect(spy_tech_shell, "response",
685 G_CALLBACK(spy_advances_response), args);
686
687 args->target_tech_id = 0;
688
689 gtk_tree_view_focus(GTK_TREE_VIEW(view));
690}
691
692/**********************************************************************/
695 static void spy_improvements_response(GtkWidget *w, gint response, gpointer data)
696{
697 struct action_data *args = (struct action_data *)data;
698
699 if (response == GTK_RESPONSE_ACCEPT && args->target_building_id > -2) {
700 if (NULL != game_unit_by_number(args->actor_unit_id)
701 && NULL != game_city_by_number(args->target_city_id)) {
702 if (args->target_building_id == B_LAST) {
703 /* This is the untargeted version. */
704 request_do_action(get_non_targeted_action_id(args->act_id),
705 args->actor_unit_id,
706 args->target_city_id,
707 args->target_building_id, "");
708 } else if (args->target_building_id == -1) {
709 /* This is the city production version. */
710 request_do_action(get_production_targeted_action_id(args->act_id),
711 args->actor_unit_id,
712 args->target_city_id,
713 args->target_building_id, "");
714 } else {
715 /* This is the targeted version. */
716 request_do_action(args->act_id,
717 args->actor_unit_id,
718 args->target_city_id,
719 args->target_building_id, "");
720 }
721 }
722 }
723
724 gtk_window_destroy(GTK_WINDOW(spy_sabotage_shell));
725 spy_sabotage_shell = NULL;
726 free(args);
727
728 /* The user have answered the follow up question. Move on. */
729 diplomat_queue_handle_secondary();
730}
731
732/**********************************************************************/
735 static void spy_improvements_callback(GtkTreeSelection *select, gpointer data)
736{
737 struct action_data *args = (struct action_data *)data;
738
739 GtkTreeModel *model;
740 GtkTreeIter it;
741
742 if (gtk_tree_selection_get_selected(select, &model, &it)) {
743 gtk_tree_model_get(model, &it, 1, &(args->target_building_id), -1);
744
745 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_sabotage_shell),
746 GTK_RESPONSE_ACCEPT, TRUE);
747 } else {
748 args->target_building_id = -2;
749
750 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_sabotage_shell),
751 GTK_RESPONSE_ACCEPT, FALSE);
752 }
753}
754
755/**********************************************************************/
758 static void create_improvements_list(struct player *pplayer,
759 struct city *pcity,
760 struct action_data *args)
761{
762 GtkWidget *sw, *frame, *label, *vgrid, *view;
763 GtkListStore *store;
764 GtkCellRenderer *rend;
765 GtkTreeViewColumn *col;
766 GtkTreeIter it;
767
768 struct unit *actor_unit = game_unit_by_number(args->actor_unit_id);
769
770 spy_sabotage_shell = gtk_dialog_new_with_buttons(_("Sabotage Improvements"),
771 NULL, 0,
772 _("_Cancel"), GTK_RESPONSE_CANCEL,
773 _("_Sabotage"), GTK_RESPONSE_ACCEPT,
774 NULL);
775 setup_dialog(spy_sabotage_shell, toplevel);
776
777 gtk_dialog_set_default_response(GTK_DIALOG(spy_sabotage_shell),
778 GTK_RESPONSE_ACCEPT);
779
780 frame = gtk_frame_new(_("Select Improvement to Sabotage"));
781 gtk_box_append(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(spy_sabotage_shell))), frame);
782
783 vgrid = gtk_grid_new();
784 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
785 GTK_ORIENTATION_VERTICAL);
786 gtk_grid_set_row_spacing(GTK_GRID(vgrid), 6);
787 gtk_frame_set_child(GTK_FRAME(frame), vgrid);
788
789 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
790
791 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
792 gtk_widget_set_hexpand(view, TRUE);
793 gtk_widget_set_vexpand(view, TRUE);
794 g_object_unref(store);
795 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
796
797 rend = gtk_cell_renderer_text_new();
798 col = gtk_tree_view_column_new_with_attributes(NULL, rend,
799 "text", 0, NULL);
800 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
801
802 label = g_object_new(GTK_TYPE_LABEL,
803 "use-underline", TRUE,
804 "mnemonic-widget", view,
805 "label", _("_Improvements:"),
806 "xalign", 0.0,
807 "yalign", 0.5,
808 NULL);
809 gtk_grid_attach(GTK_GRID(vgrid), label, 0, 0, 1, 1);
810
811 sw = gtk_scrolled_window_new();
812 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
813 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
814
815 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
816 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
817 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(sw), 200);
818
819 gtk_grid_attach(GTK_GRID(vgrid), sw, 0, 1, 1, 1);
820
821 /* Now populate the list */
822 if (action_prob_possible(actor_unit->client.act_prob_cache[
823 get_production_targeted_action_id(
824 args->act_id)])) {
825 gtk_list_store_append(store, &it);
826 gtk_list_store_set(store, &it, 0, _("City Production"), 1, -1, -1);
827 }
828
829 city_built_iterate(pcity, pimprove) {
830 if (pimprove->sabotage > 0) {
831 gtk_list_store_append(store, &it);
832 gtk_list_store_set(store, &it,
833 0, city_improvement_name_translation(pcity, pimprove),
834 1, improvement_number(pimprove),
835 -1);
836 }
837 } city_built_iterate_end;
838
839 if (action_prob_possible(actor_unit->client.act_prob_cache[
840 get_non_targeted_action_id(args->act_id)])) {
841 struct astring str = ASTRING_INIT;
842
843 gtk_list_store_append(store, &it);
844
845 /* TRANS: %s is a unit name, e.g., Spy */
846 astr_set(&str, _("At %s's Discretion"),
847 unit_name_translation(actor_unit));
848 gtk_list_store_set(store, &it, 0, astr_str(&str), 1, B_LAST, -1);
849
850 astr_free(&str);
851 }
852
853 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_sabotage_shell),
854 GTK_RESPONSE_ACCEPT, FALSE);
855
856 gtk_widget_set_visible(gtk_dialog_get_content_area(GTK_DIALOG(spy_sabotage_shell)),
857 TRUE);
858
859 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), "changed",
860 G_CALLBACK(spy_improvements_callback), args);
861 g_signal_connect(spy_sabotage_shell, "response",
862 G_CALLBACK(spy_improvements_response), args);
863
864 args->target_building_id = -2;
865
866 gtk_tree_view_focus(GTK_TREE_VIEW(view));
867}
868
869/**********************************************************************/
872 static void spy_steal_popup_shared(GtkWidget *w, gpointer data)
873{
874 struct action_data *args = (struct action_data *)data;
875
876 args->act_id = args->act_id;
877
878 struct city *pvcity = game_city_by_number(args->target_city_id);
879 struct player *pvictim = NULL;
880
881 if (pvcity) {
882 pvictim = city_owner(pvcity);
883 }
884
885/* It is concievable that pvcity will not be found, because something
886 has happened to the city during latency. Therefore we must initialize
887 pvictim to NULL and account for !pvictim in create_advances_list. -- Syela */
888
889 /* FIXME: Don't discard the second tech choice dialog. */
890 if (!spy_tech_shell) {
891 create_advances_list(client.conn.playing, pvictim, args);
892 gtk_window_present(GTK_WINDOW(spy_tech_shell));
893 } else {
894 free(args);
895 }
896
897 /* Wait for the player's reply before moving on to the next unit that
898 * needs to know what action to take. */
899 is_more_user_input_needed = TRUE;
900
901 choice_dialog_destroy(act_sel_dialog);
902}
903
904/**********************************************************************/
908 static void spy_steal_popup(GtkWidget *w, gpointer data)
909{
910 act_sel_dialog_data->act_id = ACTION_SPY_TARGETED_STEAL_TECH;
911 spy_steal_popup_shared(w, act_sel_dialog_data);
912}
913
914/**********************************************************************/
918 static void spy_steal_esc_popup(GtkWidget *w, gpointer data)
919{
920 act_sel_dialog_data->act_id = ACTION_SPY_TARGETED_STEAL_TECH_ESC;
921 spy_steal_popup_shared(w, act_sel_dialog_data);
922}
923
924/**********************************************************************/
928 void popup_sabotage_dialog(struct unit *actor, struct city *pcity,
929 const struct action *paction)
930{
931 /* FIXME: Don't discard the second target choice dialog. */
932 if (!spy_sabotage_shell) {
933 create_improvements_list(client.conn.playing, pcity,
934 act_data(paction->id,
935 actor->id, pcity->id, 0, 0,
936 0, 0, 0));
937 gtk_window_present(GTK_WINDOW(spy_sabotage_shell));
938 }
939}
940
941/**********************************************************************/
944 static void incite_response(GtkWidget *w, gint response, gpointer data)
945{
946 struct action_data *args = (struct action_data *)data;
947
948 if (response == GTK_RESPONSE_YES) {
949 request_do_action(args->act_id, args->actor_unit_id,
950 args->target_city_id, 0, "");
951 }
952
953 gtk_window_destroy(GTK_WINDOW(w));
954 free(args);
955
956 /* The user have answered the follow up question. Move on. */
957 diplomat_queue_handle_secondary();
958}
959
960/**********************************************************************/
963 void popup_incite_dialog(struct unit *actor, struct city *pcity, int cost,
964 const struct action *paction)
965{
966 GtkWidget *shell;
967 char buf[1024];
968
969 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Treasury contains %d gold.",
970 "Treasury contains %d gold.",
971 client_player()->economic.gold),
972 client_player()->economic.gold);
973
974 if (INCITE_IMPOSSIBLE_COST == cost) {
975 shell = gtk_message_dialog_new(NULL, 0,
976 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
977 _("You can't incite a revolt in %s."),
978 city_name_get(pcity));
979 gtk_window_set_title(GTK_WINDOW(shell), _("City can't be incited!"));
980 setup_dialog(shell, toplevel);
981 } else if (cost <= client_player()->economic.gold) {
982 shell = gtk_message_dialog_new(NULL, 0,
983 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
984 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
985 PL_("Incite a revolt for %d gold?\n%s",
986 "Incite a revolt for %d gold?\n%s", cost), cost, buf);
987 gtk_window_set_title(GTK_WINDOW(shell), _("Incite a Revolt!"));
988 setup_dialog(shell, toplevel);
989 } else {
990 shell = gtk_message_dialog_new(NULL,
991 0,
992 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
993 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
994 PL_("Inciting a revolt costs %d gold.\n%s",
995 "Inciting a revolt costs %d gold.\n%s", cost), cost, buf);
996 gtk_window_set_title(GTK_WINDOW(shell), _("Traitors Demand Too Much!"));
997 setup_dialog(shell, toplevel);
998 }
999 gtk_window_present(GTK_WINDOW(shell));
1000
1001 g_signal_connect(shell, "response", G_CALLBACK(incite_response),
1002 act_data(paction->id, actor->id,
1003 pcity->id, 0, 0,
1004 0, 0, 0));
1005}
1006
1007/**********************************************************************/
1010 static void tgt_unit_change_callback(GtkWidget *dlg, gint arg)
1011{
1012 int au_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg), "actor"));
1013
1014 if (arg == GTK_RESPONSE_YES) {
1015 struct unit *actor = game_unit_by_number(au_id);
1016
1017 if (actor != NULL) {
1018 int tgt_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg),
1019 "target"));
1020 struct unit *tgt_unit = game_unit_by_number(tgt_id);
1021 struct tile *tgt_tile = g_object_get_data(G_OBJECT(dlg), "tile");
1022
1023 if (tgt_unit == NULL) {
1024 /* Make the action dialog pop up again. */
1025 dsend_packet_unit_get_actions(&client.conn,
1026 actor->id,
1027 /* Let the server choose the target
1028 * unit. */
1029 IDENTITY_NUMBER_ZERO,
1030 tgt_tile->index,
1031 action_selection_target_extra(),
1032 REQEST_PLAYER_INITIATED);
1033 } else {
1034 dsend_packet_unit_get_actions(&client.conn,
1035 actor->id,
1036 tgt_id,
1037 tgt_tile->index,
1038 action_selection_target_extra(),
1039 REQEST_PLAYER_INITIATED);
1040 }
1041 }
1042 } else {
1043 /* Dialog canceled. This ends the action selection process. */
1044 action_selection_no_longer_in_progress(au_id);
1045 }
1046
1047 gtk_window_destroy(GTK_WINDOW(dlg));
1048}
1049
1050/**********************************************************************/
1053 static void act_sel_new_unit_tgt_callback(GtkWidget *w, gpointer data)
1054{
1055 struct action_data *args = act_sel_dialog_data;
1056
1057 struct unit *punit;
1058 struct unit *tunit;
1059 struct tile *ptile;
1060
1061 if ((punit = game_unit_by_number(args->actor_unit_id))
1062 && (ptile = index_to_tile(&(wld.map), args->target_tile_id))
1063 && (tunit = game_unit_by_number(args->target_unit_id))) {
1064 select_tgt_unit(punit, ptile, ptile->units, tunit,
1065 _("Target unit selection"),
1066 _("Looking for target unit:"),
1067 _("Units at tile:"),
1068 _("Select"),
1069 G_CALLBACK(tgt_unit_change_callback));
1070 }
1071
1072 did_not_decide = TRUE;
1073 action_selection_restart = TRUE;
1074 choice_dialog_destroy(act_sel_dialog);
1075 free(args);
1076}
1077
1078/**********************************************************************/
1081 static void tgt_extra_change_callback(GtkWidget *dlg, gint arg)
1082{
1083 int au_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg), "actor"));
1084
1085 if (arg == GTK_RESPONSE_YES) {
1086 struct unit *actor = game_unit_by_number(au_id);
1087
1088 if (actor != NULL) {
1089 int tgt_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg),
1090 "target"));
1091 struct extra_type *tgt_extra = extra_by_number(tgt_id);
1092 struct tile *tgt_tile = g_object_get_data(G_OBJECT(dlg), "tile");
1093
1094 if (tgt_extra == NULL) {
1095 /* Make the action dialog pop up again. */
1096 dsend_packet_unit_get_actions(&client.conn,
1097 actor->id,
1098 action_selection_target_unit(),
1099 tgt_tile->index,
1100 /* Let the server choose the target
1101 * extra. */
1102 action_selection_target_extra(),
1103 REQEST_PLAYER_INITIATED);
1104 } else {
1105 dsend_packet_unit_get_actions(&client.conn,
1106 actor->id,
1107 action_selection_target_unit(),
1108 tgt_tile->index,
1109 tgt_id,
1110 REQEST_PLAYER_INITIATED);
1111 }
1112 }
1113 } else {
1114 /* Dialog canceled. This ends the action selection process. */
1115 action_selection_no_longer_in_progress(au_id);
1116 }
1117
1118 gtk_window_destroy(GTK_WINDOW(dlg));
1119}
1120
1121/**********************************************************************/
1124 static void act_sel_new_extra_tgt_callback(GtkWidget *w, gpointer data)
1125{
1126 struct action_data *args = act_sel_dialog_data;
1127
1128 struct unit *act_unit;
1129 struct extra_type *tgt_extra;
1130 struct tile *tgt_tile;
1131
1132 if ((act_unit = game_unit_by_number(args->actor_unit_id))
1133 && (tgt_tile = index_to_tile(&(wld.map), args->target_tile_id))
1134 && (tgt_extra = extra_by_number(args->target_extra_id))) {
1135 bv_extras potential_targets;
1136
1137 /* Start with the extras at the tile */
1138 potential_targets = *tile_extras(tgt_tile);
1139
1140 extra_type_re_active_iterate(pextra) {
1141 if (BV_ISSET(potential_targets, extra_number(pextra))) {
1142 /* This extra is at the tile. Can anything be done to it? */
1143 if (!utype_can_remove_extra(unit_type_get(act_unit),
1144 pextra)) {
1145 BV_CLR(potential_targets, extra_number(pextra));
1146 }
1147 } else {
1148 /* This extra isn't at the tile yet. Can it be created? */
1149 if (utype_can_create_extra(unit_type_get(act_unit),
1150 pextra)) {
1151 BV_SET(potential_targets, extra_number(pextra));
1152 }
1153 }
1154 } extra_type_re_active_iterate_end;
1155
1156 select_tgt_extra(act_unit, tgt_tile, potential_targets, tgt_extra,
1157 /* TRANS: GTK action selection dialog extra target
1158 * selection dialog title. */
1159 _("Target extra selection"),
1160 /* TRANS: GTK action selection dialog extra target
1161 * selection dialog actor unit label. */
1162 _("Looking for target extra:"),
1163 /* TRANS: GTK action selection dialog extra target
1164 * selection dialog extra list label. */
1165 _("Extra targets:"),
1166 _("Select"),
1167 G_CALLBACK(tgt_extra_change_callback));
1168 }
1169
1170 did_not_decide = TRUE;
1171 action_selection_restart = TRUE;
1172 choice_dialog_destroy(act_sel_dialog);
1173 free(args);
1174}
1175
1176/**********************************************************************/
1179 static void act_sel_location_callback(GtkWidget *w, gpointer data)
1180{
1181 struct action_data *args = act_sel_dialog_data;
1182
1183 struct unit *punit;
1184
1185 if ((punit = game_unit_by_number(args->actor_unit_id))) {
1186 center_tile_mapcanvas(unit_tile(punit));
1187 }
1188}
1189
1190/**********************************************************************/
1193 static void act_sel_wait_callback(GtkWidget *w, gpointer data)
1194{
1195 struct action_data *args = act_sel_dialog_data;
1196
1197 key_unit_wait();
1198
1199 /* The dialog was destroyed when key_unit_wait() resulted in
1200 * action_selection_close() being called. */
1201
1202 free(args);
1203}
1204
1205/**********************************************************************/
1208 static void act_sel_destroy_callback(GtkWidget *w, gpointer data)
1209{
1210 act_sel_dialog = NULL;
1211 diplomat_queue_handle_primary();
1212}
1213
1214/**********************************************************************/
1217 static void act_sel_cancel_callback(GtkWidget *w, gpointer data)
1218{
1219 choice_dialog_destroy(act_sel_dialog);
1220 free(act_sel_dialog_data);
1221}
1222
1223/**********************************************************************/
1226 static void act_sel_close_callback(GtkWidget *w, gpointer data)
1227{
1228 choice_dialog_destroy(act_sel_dialog);
1229 free(act_sel_dialog_data);
1230}
1231
1232/* Mapping from an action to the function to call when its button is
1233 * pushed. */
1234 static const GCallback af_map[ACTION_COUNT] = {
1235 /* Unit acting against a city target. */
1236 [ACTION_SPY_TARGETED_SABOTAGE_CITY] =
1237 (GCallback)request_action_details_callback,
1238 [ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC] =
1239 (GCallback)request_action_details_callback,
1240 [ACTION_SPY_TARGETED_STEAL_TECH] = (GCallback)spy_steal_popup,
1241 [ACTION_SPY_TARGETED_STEAL_TECH_ESC] = (GCallback)spy_steal_esc_popup,
1242 [ACTION_SPY_INCITE_CITY] = (GCallback)request_action_details_callback,
1243 [ACTION_SPY_INCITE_CITY_ESC] = (GCallback)request_action_details_callback,
1244 [ACTION_UPGRADE_UNIT] = (GCallback)upgrade_callback,
1245 [ACTION_STRIKE_BUILDING] = (GCallback)request_action_details_callback,
1246
1247 /* Unit acting against a unit target. */
1248 [ACTION_SPY_BRIBE_UNIT] = (GCallback)request_action_details_callback,
1249
1250 /* Unit acting against all units at a tile. */
1251 /* No special callback functions needed for any unit stack targeted
1252 * actions. */
1253
1254 /* Unit acting against a tile. */
1255 [ACTION_FOUND_CITY] = (GCallback)found_city_callback,
1256
1257 /* Unit acting with no target except itself. */
1258 /* No special callback functions needed for any self targeted actions. */
1259};
1260
1261/**********************************************************************/
1264 static void action_entry(GtkWidget *shl,
1265 action_id act_id,
1266 const struct act_prob *act_probs,
1267 const char *custom,
1268 action_id act_num)
1269{
1270 const gchar *label;
1271 const gchar *tooltip;
1272 GCallback cb;
1273
1274 if (af_map[act_id] == NULL) {
1275 /* No special call back function needed for this action. */
1276 cb = (GCallback)simple_action_callback;
1277 } else {
1278 /* Special action specific callback function specified. */
1279 cb = af_map[act_id];
1280 }
1281
1282 /* Don't show disabled actions. */
1283 if (!action_prob_possible(act_probs[act_id])) {
1284 return;
1285 }
1286
1287 label = action_prepare_ui_name(act_id, "_",
1288 act_probs[act_id],
1289 custom);
1290
1291 tooltip = act_sel_action_tool_tip(action_by_number(act_id),
1292 act_probs[act_id]);
1293
1294 action_button_map[act_id] = choice_dialog_get_number_of_buttons(shl);
1295 choice_dialog_add(shl, label, cb, GINT_TO_POINTER(act_num),
1296 FALSE, tooltip);
1297}
1298
1299/**********************************************************************/
1302 static void action_entry_update(GtkWidget *shl,
1303 action_id act_id,
1304 const struct act_prob *act_probs,
1305 const char *custom,
1306 action_id act_num)
1307{
1308 const gchar *label;
1309 const gchar *tooltip;
1310
1311 /* An action that just became impossible has its button disabled.
1312 * An action that became possible again must be re-enabled. */
1313 choice_dialog_button_set_sensitive(act_sel_dialog,
1314 action_button_map[act_id],
1315 action_prob_possible(act_probs[act_id]));
1316
1317 /* The probability may have changed. */
1318 label = action_prepare_ui_name(act_id, "_",
1319 act_probs[act_id], custom);
1320
1321 tooltip = act_sel_action_tool_tip(action_by_number(act_id),
1322 act_probs[act_id]);
1323
1324 choice_dialog_button_set_label(act_sel_dialog,
1325 action_button_map[act_id],
1326 label);
1327 choice_dialog_button_set_tooltip(act_sel_dialog,
1328 action_button_map[act_id],
1329 tooltip);
1330}
1331
1332/**********************************************************************/
1336 void popup_action_selection(struct unit *actor_unit,
1337 struct city *target_city,
1338 struct unit *target_unit,
1339 struct tile *target_tile,
1340 struct extra_type *target_extra,
1341 const struct act_prob *act_probs)
1342{
1343 GtkWidget *shl;
1344 struct astring title = ASTRING_INIT, text = ASTRING_INIT;
1345 struct city *actor_homecity;
1346
1347 int button_id;
1348
1349 act_sel_dialog_data =
1350 act_data(ACTION_ANY, /* Not decided yet */
1351 actor_unit->id,
1352 (target_city) ? target_city->id : IDENTITY_NUMBER_ZERO,
1353 (target_unit) ? target_unit->id : IDENTITY_NUMBER_ZERO,
1354 (target_tile) ? target_tile->index : TILE_INDEX_NONE,
1355 /* No target_building or target_tech supplied. (Dec 2019) */
1356 B_LAST, A_UNSET,
1357 target_extra ? target_extra->id : EXTRA_NONE);
1358
1359 /* Could be caused by the server failing to reply to a request for more
1360 * information or a bug in the client code. */
1361 fc_assert_msg(!is_more_user_input_needed,
1362 "Diplomat queue problem. Is another diplomat window open?");
1363
1364 /* No extra input is required as no action has been chosen yet. */
1365 is_more_user_input_needed = FALSE;
1366
1367 /* No buttons are added yet. */
1368 for (button_id = 0; button_id < BUTTON_COUNT; button_id++) {
1369 action_button_map[button_id] = BUTTON_NOT_THERE;
1370 }
1371
1372 actor_homecity = game_city_by_number(actor_unit->homecity);
1373
1374 actor_unit_id = actor_unit->id;
1375 target_ids[ATK_SELF] = actor_unit_id;
1376 target_ids[ATK_CITY] = target_city ?
1377 target_city->id :
1378 IDENTITY_NUMBER_ZERO;
1379 target_ids[ATK_UNIT] = target_unit ?
1380 target_unit->id :
1381 IDENTITY_NUMBER_ZERO;
1382 target_ids[ATK_UNITS] = target_tile ?
1383 tile_index(target_tile) :
1384 TILE_INDEX_NONE;
1385 target_ids[ATK_TILE] = target_tile ?
1386 tile_index(target_tile) :
1387 TILE_INDEX_NONE;
1388 target_ids[ATK_EXTRAS] = target_tile ?
1389 tile_index(target_tile) :
1390 TILE_INDEX_NONE;
1391 target_extra_id = target_extra ?
1392 extra_number(target_extra) :
1393 EXTRA_NONE;
1394
1395 astr_set(&title,
1396 /* TRANS: %s is a unit name, e.g., Spy */
1397 _("Choose Your %s's Strategy"),
1398 unit_name_translation(actor_unit));
1399
1400 if (target_city && actor_homecity) {
1401 astr_set(&text,
1402 _("Your %s from %s reaches the city of %s.\nWhat now?"),
1403 unit_name_translation(actor_unit),
1404 city_name_get(actor_homecity),
1405 city_name_get(target_city));
1406 } else if (target_city) {
1407 astr_set(&text,
1408 _("Your %s has arrived at %s.\nWhat is your command?"),
1409 unit_name_translation(actor_unit),
1410 city_name_get(target_city));
1411 } else if (target_unit) {
1412 astr_set(&text,
1413 /* TRANS: Your Spy is ready to act against Roman Freight. */
1414 _("Your %s is ready to act against %s %s."),
1415 unit_name_translation(actor_unit),
1416 nation_adjective_for_player(unit_owner(target_unit)),
1417 unit_name_translation(target_unit));
1418 } else {
1419 fc_assert_msg(target_unit || target_city || target_tile,
1420 "No target specified.");
1421 astr_set(&text,
1422 /* TRANS: %s is a unit name, e.g., Diplomat, Spy */
1423 _("Your %s is waiting for your command."),
1424 unit_name_translation(actor_unit));
1425 }
1426
1427 shl = choice_dialog_start(GTK_WINDOW(toplevel), astr_str(&title),
1428 astr_str(&text));
1429
1430 /* Unit acting against a city */
1431
1432 action_iterate(act) {
1433 if (action_id_get_actor_kind(act) == AAK_UNIT
1434 && action_id_get_target_kind(act) == ATK_CITY) {
1435 action_entry(shl, act, act_probs,
1436 get_act_sel_action_custom_text(action_by_number(act),
1437 act_probs[act],
1438 actor_unit,
1439 target_city),
1440 act);
1441 }
1442 } action_iterate_end;
1443
1444 /* Unit acting against another unit */
1445
1446 action_iterate(act) {
1447 if (action_id_get_actor_kind(act) == AAK_UNIT
1448 && action_id_get_target_kind(act) == ATK_UNIT) {
1449 action_entry(shl, act, act_probs,
1450 get_act_sel_action_custom_text(action_by_number(act),
1451 act_probs[act],
1452 actor_unit,
1453 target_city),
1454 act);
1455 }
1456 } action_iterate_end;
1457
1458 /* Unit acting against all units at a tile */
1459
1460 action_iterate(act) {
1461 if (action_id_get_actor_kind(act) == AAK_UNIT
1462 && action_id_get_target_kind(act) == ATK_UNITS) {
1463 action_entry(shl, act, act_probs,
1464 get_act_sel_action_custom_text(action_by_number(act),
1465 act_probs[act],
1466 actor_unit,
1467 target_city),
1468 act);
1469 }
1470 } action_iterate_end;
1471
1472 /* Unit acting against a tile */
1473
1474 action_iterate(act) {
1475 if (action_id_get_actor_kind(act) == AAK_UNIT
1476 && action_id_get_target_kind(act) == ATK_TILE) {
1477 action_entry(shl, act, act_probs,
1478 get_act_sel_action_custom_text(action_by_number(act),
1479 act_probs[act],
1480 actor_unit,
1481 target_city),
1482 act);
1483 }
1484 } action_iterate_end;
1485
1486 /* Unit acting against a tile's extras */
1487
1488 action_iterate(act) {
1489 if (action_id_get_actor_kind(act) == AAK_UNIT
1490 && action_id_get_target_kind(act) == ATK_EXTRAS) {
1491 action_entry(shl, act, act_probs,
1492 get_act_sel_action_custom_text(action_by_number(act),
1493 act_probs[act],
1494 actor_unit,
1495 target_city),
1496 act);
1497 }
1498 } action_iterate_end;
1499
1500 /* Unit acting against itself. */
1501
1502 action_iterate(act) {
1503 if (action_id_get_actor_kind(act) == AAK_UNIT
1504 && action_id_get_target_kind(act) == ATK_SELF) {
1505 action_entry(shl, act, act_probs,
1506 get_act_sel_action_custom_text(action_by_number(act),
1507 act_probs[act],
1508 actor_unit,
1509 target_city),
1510 act);
1511 }
1512 } action_iterate_end;
1513
1514 if (target_unit != NULL
1515 && unit_list_size(target_tile->units) > 1) {
1516 action_button_map[BUTTON_NEW_UNIT_TGT]
1517 = choice_dialog_get_number_of_buttons(shl);
1518 choice_dialog_add(shl, _("Change unit target"),
1519 (GCallback)act_sel_new_unit_tgt_callback,
1520 GINT_TO_POINTER(ACTION_NONE), TRUE, NULL);
1521 }
1522
1523 if (target_extra != NULL) {
1524 action_button_map[BUTTON_NEW_EXTRA_TGT]
1525 = choice_dialog_get_number_of_buttons(shl);
1526 choice_dialog_add(shl, _("Change extra target"),
1527 (GCallback)act_sel_new_extra_tgt_callback,
1528 GINT_TO_POINTER(ACTION_NONE), TRUE, NULL);
1529 }
1530
1531 action_button_map[BUTTON_LOCATION]
1532 = choice_dialog_get_number_of_buttons(shl);
1533 choice_dialog_add(shl, _("Show Location"),
1534 (GCallback)act_sel_location_callback,
1535 GINT_TO_POINTER(ACTION_NONE),
1536 TRUE, NULL);
1537
1538 action_button_map[BUTTON_WAIT]
1539 = choice_dialog_get_number_of_buttons(shl);
1540 choice_dialog_add(shl, _("_Wait"),
1541 (GCallback)act_sel_wait_callback,
1542 GINT_TO_POINTER(ACTION_NONE),
1543 TRUE, NULL);
1544
1545 action_button_map[BUTTON_CANCEL]
1546 = choice_dialog_get_number_of_buttons(shl);
1547 choice_dialog_add(shl, _("_Cancel"),
1548 (GCallback)act_sel_cancel_callback,
1549 GINT_TO_POINTER(ACTION_NONE),
1550 FALSE, NULL);
1551
1552 choice_dialog_end(shl);
1553
1554 act_sel_dialog = shl;
1555
1556 choice_dialog_set_hide(shl, TRUE);
1557 g_signal_connect(shl, "destroy",
1558 G_CALLBACK(act_sel_destroy_callback), NULL);
1559 g_signal_connect(shl, "close-request",
1560 G_CALLBACK(act_sel_close_callback),
1561 GINT_TO_POINTER(ACTION_NONE));
1562
1563 /* Give follow up questions access to action probabilities. */
1564 client_unit_init_act_prob_cache(actor_unit);
1565 action_iterate(act) {
1566 actor_unit->client.act_prob_cache[act] = act_probs[act];
1567 } action_iterate_end;
1568
1569 astr_free(&title);
1570 astr_free(&text);
1571}
1572
1573/**********************************************************************/
1578 int action_selection_actor_unit(void)
1579{
1580 if (act_sel_dialog == NULL) {
1581 return IDENTITY_NUMBER_ZERO;
1582 }
1583 return actor_unit_id;
1584}
1585
1586/**********************************************************************/
1592 int action_selection_target_city(void)
1593{
1594 if (act_sel_dialog == NULL) {
1595 return IDENTITY_NUMBER_ZERO;
1596 }
1597 return target_ids[ATK_CITY];
1598}
1599
1600/**********************************************************************/
1606 int action_selection_target_unit(void)
1607{
1608 if (act_sel_dialog == NULL) {
1609 return IDENTITY_NUMBER_ZERO;
1610 }
1611
1612 return target_ids[ATK_UNIT];
1613}
1614
1615/**********************************************************************/
1621 int action_selection_target_tile(void)
1622{
1623 if (act_sel_dialog == NULL) {
1624 return TILE_INDEX_NONE;
1625 }
1626
1627 return target_ids[ATK_TILE];
1628}
1629
1630/**********************************************************************/
1636 int action_selection_target_extra(void)
1637{
1638 if (act_sel_dialog == NULL) {
1639 return EXTRA_NONE;
1640 }
1641
1642 return target_extra_id;
1643}
1644
1645/**********************************************************************/
1648 void action_selection_refresh(struct unit *actor_unit,
1649 struct city *target_city,
1650 struct unit *target_unit,
1651 struct tile *target_tile,
1652 struct extra_type *target_extra,
1653 const struct act_prob *act_probs)
1654{
1655 if (act_sel_dialog == NULL) {
1656 fc_assert_msg(act_sel_dialog != NULL,
1657 "The action selection dialog should have been open");
1658 return;
1659 }
1660
1661 if (actor_unit->id != action_selection_actor_unit()) {
1662 fc_assert_msg(actor_unit->id == action_selection_actor_unit(),
1663 "The action selection dialog is for another actor unit.");
1664 return;
1665 }
1666
1667 /* A new target may have appeared. */
1668 if (target_city) {
1669 act_sel_dialog_data->target_city_id = target_city->id;
1670 }
1671 if (target_unit) {
1672 act_sel_dialog_data->target_unit_id = target_unit->id;
1673 }
1674 if (target_tile) {
1675 act_sel_dialog_data->target_tile_id = target_tile->index;
1676 }
1677 /* No target_building or target_tech supplied. (Dec 2019) */
1678 if (target_extra) {
1679 act_sel_dialog_data->target_extra_id = target_extra->id;
1680 }
1681
1682 action_iterate(act) {
1683 const char *custom;
1684
1685 if (action_id_get_actor_kind(act) != AAK_UNIT) {
1686 /* Not relevant. */
1687 continue;
1688 }
1689
1690 custom = get_act_sel_action_custom_text(action_by_number(act),
1691 act_probs[act],
1692 actor_unit,
1693 target_city);
1694
1695 if (BUTTON_NOT_THERE == action_button_map[act]) {
1696 /* Add the button (unless its probability is 0). */
1697 action_entry(act_sel_dialog, act, act_probs, custom, act);
1698 } else {
1699 /* Update the existing button. */
1700 action_entry_update(act_sel_dialog, act, act_probs, custom, act);
1701 }
1702 } action_iterate_end;
1703
1704 /* DO NOT change the action_button_map[] for any button to reflect its
1705 * new position. A button keeps its choice dialog internal name when its
1706 * position changes. A button's id number is therefore based on when
1707 * it was added, not on its current position. */
1708
1709 if (BUTTON_NOT_THERE != action_button_map[BUTTON_WAIT]) {
1710 /* Move the wait button below the recently added button. */
1711 choice_dialog_button_move_to_the_end(act_sel_dialog,
1712 action_button_map[BUTTON_WAIT]);
1713 }
1714
1715 if (BUTTON_NOT_THERE != action_button_map[BUTTON_CANCEL]) {
1716 /* Move the cancel button below the recently added button. */
1717 choice_dialog_button_move_to_the_end(act_sel_dialog,
1718 action_button_map[BUTTON_CANCEL]);
1719 }
1720
1721 choice_dialog_end(act_sel_dialog);
1722}
1723
1724/**********************************************************************/
1727 void action_selection_close(void)
1728{
1729 if (act_sel_dialog != NULL) {
1730 did_not_decide = TRUE;
1731 choice_dialog_destroy(act_sel_dialog);
1732 }
1733}
action_prepare_ui_name
const char * action_prepare_ui_name(action_id act_id, const char *mnemonic, const struct act_prob prob, const char *custom)
Definition actions.c:1287
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1073
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5044
action_get_sub_target_kind
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Definition actions.c:1094
action_get_target_kind
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1083
actions.h
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:390
action_iterate_end
#define action_iterate_end
Definition actions.h:209
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:403
action_iterate
#define action_iterate(_act_)
Definition actions.h:205
ACTION_ANY
#define ACTION_ANY
Definition actions.h:52
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:407
ACTION_NONE
#define ACTION_NONE
Definition actions.h:55
astr_free
void astr_free(struct astring *astr)
Definition astring.c:148
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:251
str
#define str
Definition astring.c:76
astring.h
astr_str
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
ASTRING_INIT
#define ASTRING_INIT
Definition astring.h:44
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_CLR
#define BV_CLR(bv, bit)
Definition bitvector.h:86
city_improvement_name_translation
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:663
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
INCITE_IMPOSSIBLE_COST
#define INCITE_IMPOSSIBLE_COST
Definition city.h:96
city_owner
#define city_owner(_pcity_)
Definition city.h:563
city_built_iterate
#define city_built_iterate(_pcity, _p)
Definition city.h:825
city_built_iterate_end
#define city_built_iterate_end
Definition city.h:831
client
struct civclient client
Definition client_main.c:153
client_main.h
client_player
#define client_player()
Definition client_main.h:106
client_unit_init_act_prob_cache
void client_unit_init_act_prob_cache(struct unit *punit)
Definition climisc.c:1248
climisc.h
incite_cost
char * incite_cost
Definition comments.c:74
connectdlg_common.h
action_selection_no_longer_in_progress
void action_selection_no_longer_in_progress(const int old_actor_id)
Definition control.c:1033
request_do_action
void request_do_action(action_id action, int actor_id, int target_id, int sub_tgt, const char *name)
Definition control.c:1704
request_action_details
void request_action_details(action_id action, int actor_id, int target_id)
Definition control.c:1772
action_decision_clear_want
void action_decision_clear_want(const int old_actor_id)
Definition control.c:1054
key_unit_wait
void key_unit_wait(void)
Definition control.c:3515
action_selection_next_in_focus
void action_selection_next_in_focus(const int old_actor_id)
Definition control.c:1066
control.h
dialogs_g.h
target_unit
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:56
popup_action_selection
popup_action_selection
Definition dialogs_g.h:55
actor_unit
struct unit * actor_unit
Definition dialogs_g.h:55
popup_bribe_dialog
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id popup_bribe_dialog
Definition dialogs_g.h:73
actor
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:73
action_selection_no_longer_in_progress_gui_specific
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs action_selection_no_longer_in_progress_gui_specific
Definition dialogs_g.h:69
target_tile
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
target_city
struct unit struct city * target_city
Definition dialogs_g.h:56
cost
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
target_extra
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:57
extra_number
int extra_number(const struct extra_type *pextra)
Definition extras.c:161
extra_by_number
struct extra_type * extra_by_number(int id)
Definition extras.c:183
EXTRA_NONE
#define EXTRA_NONE
Definition extras.h:85
extra_type_re_active_iterate_end
#define extra_type_re_active_iterate_end
Definition extras.h:329
extra_type_re_active_iterate
#define extra_type_re_active_iterate(_p)
Definition extras.h:325
NO_TARGET
#define NO_TARGET
Definition fc_types.h:358
action_id
int action_id
Definition fc_types.h:393
IDENTITY_NUMBER_ZERO
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:92
PL_
#define PL_(String1, String2, n)
Definition fcintl.h:71
_
#define _(String)
Definition fcintl.h:67
game
struct civ_game game
Definition game.c:61
wld
struct world wld
Definition game.c:62
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:115
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:106
game.h
spy_sabotage_shell
static GtkWidget * spy_sabotage_shell
Definition action_dialog.c:77
action_selection_target_extra
int action_selection_target_extra(void)
Definition action_dialog.c:1641
incite_response
static void incite_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:947
action_button_map
static int action_button_map[BUTTON_COUNT]
Definition action_dialog.c:66
spy_improvements_callback
static void spy_improvements_callback(GtkTreeSelection *select, gpointer data)
Definition action_dialog.c:737
actor_unit_id
static int actor_unit_id
Definition action_dialog.c:68
BUTTON_NEW_EXTRA_TGT
#define BUTTON_NEW_EXTRA_TGT
Definition action_dialog.c:56
act_sel_new_extra_tgt_callback
static void act_sel_new_extra_tgt_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1127
action_selection_target_tile
int action_selection_target_tile(void)
Definition action_dialog.c:1626
create_improvements_list
static void create_improvements_list(struct player *pplayer, struct city *pcity, struct action_data *args)
Definition action_dialog.c:760
act_sel_destroy_callback
static void act_sel_destroy_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1211
action_selection_actor_unit
int action_selection_actor_unit(void)
Definition action_dialog.c:1583
spy_advances_response
static void spy_advances_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:516
tgt_extra_change_callback
static void tgt_extra_change_callback(GtkWidget *dlg, gint arg)
Definition action_dialog.c:1084
act_sel_dialog
static GtkWidget * act_sel_dialog
Definition action_dialog.c:65
spy_steal_popup_shared
static void spy_steal_popup_shared(GtkWidget *w, gpointer data)
Definition action_dialog.c:875
diplomat_queue_handle_primary
static void diplomat_queue_handle_primary(void)
Definition action_dialog.c:126
action_selection_close
void action_selection_close(void)
Definition action_dialog.c:1732
spy_improvements_response
static void spy_improvements_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:697
action_selection_target_city
int action_selection_target_city(void)
Definition action_dialog.c:1597
bribe_response
static void bribe_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:458
BUTTON_WAIT
#define BUTTON_WAIT
Definition action_dialog.c:58
action_entry
static void action_entry(GtkWidget *shl, action_id act_id, const struct act_prob *act_probs, const char *custom, action_id act_num)
Definition action_dialog.c:1269
spy_steal_esc_popup
static void spy_steal_esc_popup(GtkWidget *w, gpointer data)
Definition action_dialog.c:921
spy_steal_popup
static void spy_steal_popup(GtkWidget *w, gpointer data)
Definition action_dialog.c:911
act_sel_close_callback
static void act_sel_close_callback(GtkWidget *w, gint response_id, gpointer data)
Definition action_dialog.c:1229
diplomat_queue_handle_secondary
static void diplomat_queue_handle_secondary(void)
Definition action_dialog.c:173
get_non_targeted_action_id
static action_id get_non_targeted_action_id(action_id tgt_action_id)
Definition action_dialog.c:196
request_action_details_callback
static void request_action_details_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:347
action_selection_restart
static bool action_selection_restart
Definition action_dialog.c:73
BUTTON_NEW_UNIT_TGT
#define BUTTON_NEW_UNIT_TGT
Definition action_dialog.c:55
BUTTON_COUNT
#define BUTTON_COUNT
Definition action_dialog.c:60
act_sel_dialog_data
static struct action_data * act_sel_dialog_data
Definition action_dialog.c:93
found_city_callback
static void found_city_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:421
act_sel_location_callback
static void act_sel_location_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1182
action_selection_refresh
void action_selection_refresh(struct unit *actor_unit, struct city *target_city, struct unit *target_unit, struct tile *target_tile, struct extra_type *target_extra, const struct act_prob *act_probs)
Definition action_dialog.c:1653
act_data
static struct action_data * act_data(action_id act_id, int actor_id, int target_city_id, int target_unit_id, int target_tile_id, int target_building_id, int target_tech_id, int tgt_extra_id)
Definition action_dialog.c:99
simple_action_callback
static void simple_action_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:240
create_advances_list
static void create_advances_list(struct player *pplayer, struct player *pvictim, struct action_data *args)
Definition action_dialog.c:573
is_more_user_input_needed
static bool is_more_user_input_needed
Definition action_dialog.c:71
target_extra_id
static int target_extra_id
Definition action_dialog.c:70
act_sel_wait_callback
static void act_sel_wait_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1196
act_sel_new_unit_tgt_callback
static void act_sel_new_unit_tgt_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1056
tgt_unit_change_callback
static void tgt_unit_change_callback(GtkWidget *dlg, gint arg)
Definition action_dialog.c:1013
BUTTON_NOT_THERE
#define BUTTON_NOT_THERE
Definition action_dialog.c:62
get_production_targeted_action_id
static action_id get_production_targeted_action_id(action_id tgt_action_id)
Definition action_dialog.c:219
did_not_decide
static bool did_not_decide
Definition action_dialog.c:72
BUTTON_CANCEL
#define BUTTON_CANCEL
Definition action_dialog.c:59
popup_sabotage_dialog
void popup_sabotage_dialog(struct unit *actor, struct city *pcity, const struct action *paction)
Definition action_dialog.c:931
spy_tech_shell
static GtkWidget * spy_tech_shell
Definition action_dialog.c:75
target_ids
static int target_ids[ATK_COUNT]
Definition action_dialog.c:69
act_sel_cancel_callback
static void act_sel_cancel_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1220
action_entry_update
static void action_entry_update(GtkWidget *shl, action_id act_id, const struct act_prob *act_probs, const char *custom, action_id act_num)
Definition action_dialog.c:1307
action_selection_target_unit
int action_selection_target_unit(void)
Definition action_dialog.c:1611
popup_incite_dialog
void popup_incite_dialog(struct unit *actor, struct city *pcity, int cost, const struct action *paction)
Definition action_dialog.c:966
af_map
static const GCallback af_map[ACTION_COUNT]
Definition action_dialog.c:1239
upgrade_callback
static void upgrade_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:435
spy_advances_callback
static void spy_advances_callback(GtkTreeSelection *select, gpointer data)
Definition action_dialog.c:549
BUTTON_LOCATION
#define BUTTON_LOCATION
Definition action_dialog.c:57
choice_dialog_start
GtkWidget * choice_dialog_start(GtkWindow *parent, const gchar *name, const gchar *text)
Definition choice_dialog.c:103
choice_dialog_end
void choice_dialog_end(GtkWidget *dshell)
Definition choice_dialog.c:194
choice_dialog_get_number_of_buttons
int choice_dialog_get_number_of_buttons(GtkWidget *cd)
Definition choice_dialog.c:38
choice_dialog_button_set_tooltip
void choice_dialog_button_set_tooltip(GtkWidget *cd, int number, const char *tool_tip)
Definition choice_dialog.c:81
choice_dialog_button_move_to_the_end
void choice_dialog_button_move_to_the_end(GtkWidget *cd, const int number)
Definition choice_dialog.c:91
choice_dialog_set_hide
void choice_dialog_set_hide(GtkWidget *dshell, gboolean setting)
Definition choice_dialog.c:207
choice_dialog_add
void choice_dialog_add(GtkWidget *dshell, const gchar *label, GCallback handler, gpointer data, bool meta, const gchar *tool_tip)
Definition choice_dialog.c:158
choice_dialog_button_set_label
void choice_dialog_button_set_label(GtkWidget *cd, int number, const char *label)
Definition choice_dialog.c:71
choice_dialog_button_set_sensitive
void choice_dialog_button_set_sensitive(GtkWidget *cd, int button, gboolean state)
Definition choice_dialog.c:62
popup_upgrade_dialog
void popup_upgrade_dialog(struct unit_list *punits)
Definition dialogs.c:1435
toplevel
GtkWidget * toplevel
Definition gui_main.c:125
gtk_tree_view_focus
void gtk_tree_view_focus(GtkTreeView *view)
Definition gui_stuff.c:236
setup_dialog
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
shell
static struct gui_dialog * shell
Definition messagedlg.c:39
tooltip
const char * tooltip
Definition repodlgs.c:1315
title
const char * title
Definition repodlgs.c:1314
select_tgt_extra
bool select_tgt_extra(struct unit *actor, struct tile *ptile, bv_extras potential_tgt_extras, struct extra_type *suggested_tgt_extra, const gchar *dlg_title, const gchar *actor_label, const gchar *tgt_label, const gchar *do_label, GCallback do_callback)
Definition unitselextradlg.c:107
select_tgt_unit
bool select_tgt_unit(struct unit *actor, struct tile *ptile, struct unit_list *potential_tgt_units, struct unit *suggested_tgt_unit, const gchar *dlg_title, const gchar *actor_label, const gchar *tgt_label, const gchar *do_label, GCallback do_callback)
Definition unitselunitdlg.c:70
choice_dialog_destroy
void choice_dialog_destroy(GtkWidget *dlg)
Definition choice_dialog.c:244
choice_dialog.h
gui_stuff.h
unitselextradlg.h
unitselunitdlg.h
chatline.h
citydlg.h
dialogs.h
gui_main.h
mapview.h
wldlg.h
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:194
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:184
B_LAST
#define B_LAST
Definition improvement.h:42
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_action
#define fc_assert_action(condition, action)
Definition log.h:187
index_to_tile
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:462
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1237
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
movement.h
nation_adjective_for_player
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
REQEST_PLAYER_INITIATED
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
dsend_packet_unit_get_actions
int dsend_packet_unit_get_actions(struct connection *pc, int actor_unit_id, int target_unit_id, int target_tile_id, int target_extra_id, int request_kind)
Definition packets_gen.c:38523
dsend_packet_city_name_suggestion_req
int dsend_packet_city_name_suggestion_req(struct connection *pc, int unit_id)
Definition packets_gen.c:23680
packhand.h
research_advance_name_translation
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:273
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:128
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
research_invention_gettable
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:693
research.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
act_prob
Definition fc_types.h:1220
action_data
Definition action_dialog.c:81
action_data::actor_unit_id
int actor_unit_id
Definition action_dialog.c:83
action_data::target_building_id
int target_building_id
Definition action_dialog.c:87
action_data::target_tech_id
int target_tech_id
Definition action_dialog.c:88
action_data::act_id
action_id act_id
Definition action_dialog.c:82
action_data::target_unit_id
int target_unit_id
Definition action_dialog.c:85
action_data::target_city_id
int target_city_id
Definition action_dialog.c:84
action_data::target_tile_id
int target_tile_id
Definition action_dialog.c:86
action_data::target_extra_id
int target_extra_id
Definition action_dialog.c:89
action
Definition actions.h:106
astring
Definition astring.h:36
city
Definition city.h:320
city::id
int id
Definition city.h:326
civ_game::info
struct packet_game_info info
Definition game.h:89
civclient::conn
struct connection conn
Definition client_main.h:96
connection::playing
struct player * playing
Definition connection.h:151
extra_type
Definition extras.h:88
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:215
player
Definition player.h:249
research
Definition research.h:39
tile
Definition tile.h:50
tile::units
struct unit_list * units
Definition tile.h:58
unit
Definition unit.h:140
unit::client
struct unit::@81::@83 client
unit::id
int id
Definition unit.h:147
unit::index
int index
Definition unit.h:198
unit::act_prob_cache
struct act_prob * act_prob_cache
Definition unit.h:231
unit::homecity
int homecity
Definition unit.h:148
view
Definition mapview_common.h:36
world::map
struct civ_map map
Definition world_object.h:38
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
valid_advance_by_number
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
advance_index_iterate_end
#define advance_index_iterate_end
Definition tech.h:249
A_FIRST
#define A_FIRST
Definition tech.h:44
A_UNSET
#define A_UNSET
Definition tech.h:48
advance_index_iterate
#define advance_index_iterate(_start, _index)
Definition tech.h:245
get_act_sel_action_custom_text
const char * get_act_sel_action_custom_text(struct action *paction, const struct act_prob prob, const struct unit *actor_unit, const struct city *target_city)
Definition text.c:1723
act_sel_action_tool_tip
const char * act_sel_action_tool_tip(const struct action *paction, const struct act_prob prob)
Definition text.c:1802
text.h
tile_index
#define tile_index(_pt_)
Definition tile.h:89
tile_extras
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:121
TILE_INDEX_NONE
#define TILE_INDEX_NONE
Definition tile.h:48
traderoutes.h
unit.h
unit_tile
#define unit_tile(_pu)
Definition unit.h:397
unit_owner
#define unit_owner(_pu)
Definition unit.h:396
unitlist.h
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
utype_can_remove_extra
bool utype_can_remove_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:241
unit_name_translation
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1569
utype_can_create_extra
bool utype_can_create_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:217