Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/gui-gtk-4.0/action_dialog.c Source File

Freeciv-3.1

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-4.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 args->actor_unit_id);
428
429 choice_dialog_destroy(act_sel_dialog);
430 free(args);
431}
432
433/**********************************************************************/
436 static void upgrade_callback(GtkWidget *w, gpointer data)
437{
438 struct unit *punit;
439
440 struct action_data *args = act_sel_dialog_data;
441
442 if ((punit = game_unit_by_number(args->actor_unit_id))
443 && NULL != game_city_by_number(args->target_city_id)) {
444 struct unit_list *as_list;
445
446 as_list = unit_list_new();
447 unit_list_append(as_list, punit);
448 popup_upgrade_dialog(as_list);
449 unit_list_destroy(as_list);
450 }
451
452 choice_dialog_destroy(act_sel_dialog);
453 free(args);
454}
455
456/**********************************************************************/
459 static void bribe_response(GtkWidget *w, gint response, gpointer data)
460{
461 struct action_data *args = (struct action_data *)data;
462
463 if (response == GTK_RESPONSE_YES) {
464 request_do_action(args->act_id, args->actor_unit_id,
465 args->target_unit_id, 0, "");
466 }
467
468 gtk_window_destroy(GTK_WINDOW(w));
469 free(args);
470
471 /* The user have answered the follow up question. Move on. */
472 diplomat_queue_handle_secondary();
473}
474
475/**********************************************************************/
478 void popup_bribe_dialog(struct unit *actor, struct unit *punit, int cost,
479 const struct action *paction)
480{
481 GtkWidget *shell;
482 char buf[1024];
483
484 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Treasury contains %d gold.",
485 "Treasury contains %d gold.",
486 client_player()->economic.gold),
487 client_player()->economic.gold);
488
489 if (cost <= client_player()->economic.gold) {
490 shell = gtk_message_dialog_new(NULL, 0,
491 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
492 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
493 PL_("Bribe unit for %d gold?\n%s",
494 "Bribe unit for %d gold?\n%s", cost), cost, buf);
495 gtk_window_set_title(GTK_WINDOW(shell), _("Bribe Enemy Unit"));
496 setup_dialog(shell, toplevel);
497 } else {
498 shell = gtk_message_dialog_new(NULL, 0,
499 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
500 /* TRANS: %s is pre-pluralised "Treasury contains %d gold." */
501 PL_("Bribing the unit costs %d gold.\n%s",
502 "Bribing the unit costs %d gold.\n%s", cost), cost, buf);
503 gtk_window_set_title(GTK_WINDOW(shell), _("Traitors Demand Too Much!"));
504 setup_dialog(shell, toplevel);
505 }
506 gtk_window_present(GTK_WINDOW(shell));
507
508 g_signal_connect(shell, "response", G_CALLBACK(bribe_response),
509 act_data(paction->id, actor->id,
510 0, punit->id, 0,
511 0, 0, 0));
512}
513
514/**********************************************************************/
517 static void spy_advances_response(GtkWidget *w, gint response,
518 gpointer data)
519{
520 struct action_data *args = (struct action_data *)data;
521
522 if (response == GTK_RESPONSE_ACCEPT && args->target_tech_id > 0) {
523 if (NULL != game_unit_by_number(args->actor_unit_id)
524 && NULL != game_city_by_number(args->target_city_id)) {
525 if (args->target_tech_id == A_UNSET) {
526 /* This is the untargeted version. */
527 request_do_action(get_non_targeted_action_id(args->act_id),
528 args->actor_unit_id, args->target_city_id,
529 args->target_tech_id, "");
530 } else {
531 /* This is the targeted version. */
532 request_do_action(args->act_id,
533 args->actor_unit_id, args->target_city_id,
534 args->target_tech_id, "");
535 }
536 }
537 }
538
539 gtk_window_destroy(GTK_WINDOW(spy_tech_shell));
540 spy_tech_shell = NULL;
541 free(data);
542
543 /* The user have answered the follow up question. Move on. */
544 diplomat_queue_handle_secondary();
545}
546
547/**********************************************************************/
550 static void spy_advances_callback(GtkTreeSelection *select,
551 gpointer data)
552{
553 struct action_data *args = (struct action_data *)data;
554
555 GtkTreeModel *model;
556 GtkTreeIter it;
557
558 if (gtk_tree_selection_get_selected(select, &model, &it)) {
559 gtk_tree_model_get(model, &it, 1, &(args->target_tech_id), -1);
560
561 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_tech_shell),
562 GTK_RESPONSE_ACCEPT, TRUE);
563 } else {
564 args->target_tech_id = 0;
565
566 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_tech_shell),
567 GTK_RESPONSE_ACCEPT, FALSE);
568 }
569}
570
571/**********************************************************************/
574 static void create_advances_list(struct player *pplayer,
575 struct player *pvictim,
576 struct action_data *args)
577{
578 GtkWidget *sw, *frame, *label, *vgrid, *view;
579 GtkListStore *store;
580 GtkCellRenderer *rend;
581 GtkTreeViewColumn *col;
582
583 struct unit *actor_unit = game_unit_by_number(args->actor_unit_id);
584
585 spy_tech_shell = gtk_dialog_new_with_buttons(_("Steal Technology"),
586 NULL, 0,
587 _("_Cancel"), GTK_RESPONSE_CANCEL,
588 _("_Steal"), GTK_RESPONSE_ACCEPT,
589 NULL);
590 setup_dialog(spy_tech_shell, toplevel);
591
592 gtk_dialog_set_default_response(GTK_DIALOG(spy_tech_shell),
593 GTK_RESPONSE_ACCEPT);
594
595 frame = gtk_frame_new(_("Select Advance to Steal"));
596 gtk_box_append(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(spy_tech_shell))), frame);
597
598 vgrid = gtk_grid_new();
599 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
600 GTK_ORIENTATION_VERTICAL);
601 gtk_grid_set_row_spacing(GTK_GRID(vgrid), 6);
602 gtk_frame_set_child(GTK_FRAME(frame), vgrid);
603
604 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
605
606 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
607 gtk_widget_set_hexpand(view, TRUE);
608 gtk_widget_set_vexpand(view, TRUE);
609 g_object_unref(store);
610 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
611
612 rend = gtk_cell_renderer_text_new();
613 col = gtk_tree_view_column_new_with_attributes(NULL, rend,
614 "text", 0, NULL);
615 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
616
617 label = g_object_new(GTK_TYPE_LABEL,
618 "use-underline", TRUE,
619 "mnemonic-widget", view,
620 "label", _("_Advances:"),
621 "xalign", 0.0,
622 "yalign", 0.5,
623 NULL);
624 gtk_grid_attach(GTK_GRID(vgrid), label, 0, 0, 1, 1);
625
626 sw = gtk_scrolled_window_new();
627 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
628 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
629
630 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
631 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
632 gtk_widget_set_size_request(sw, -1, 200);
633
634 gtk_grid_attach(GTK_GRID(vgrid), sw, 0, 1, 1, 1);
635
636 /* Now populate the list */
637 if (pvictim) { /* you don't want to know what lag can do -- Syela */
638 const struct research *presearch = research_get(pplayer);
639 const struct research *vresearch = research_get(pvictim);
640 GtkTreeIter it;
641 GValue value = { 0, };
642
643 advance_index_iterate(A_FIRST, i) {
644 if (research_invention_gettable(presearch, i,
645 game.info.tech_steal_allow_holes)
646 && research_invention_state(vresearch, i) == TECH_KNOWN
647 && research_invention_state(presearch, i) != TECH_KNOWN) {
648 gtk_list_store_append(store, &it);
649
650 g_value_init(&value, G_TYPE_STRING);
651 g_value_set_static_string(&value, research_advance_name_translation
652 (presearch, i));
653 gtk_list_store_set_value(store, &it, 0, &value);
654 g_value_unset(&value);
655 gtk_list_store_set(store, &it, 1, i, -1);
656 }
657 } advance_index_iterate_end;
658
659 if (action_prob_possible(actor_unit->client.act_prob_cache[
660 get_non_targeted_action_id(args->act_id)])) {
661 gtk_list_store_append(store, &it);
662
663 g_value_init(&value, G_TYPE_STRING);
664 {
665 struct astring str = ASTRING_INIT;
666 /* TRANS: %s is a unit name, e.g., Spy */
667 astr_set(&str, _("At %s's Discretion"),
668 unit_name_translation(actor_unit));
669 g_value_set_string(&value, astr_str(&str));
670 astr_free(&str);
671 }
672 gtk_list_store_set_value(store, &it, 0, &value);
673 g_value_unset(&value);
674 gtk_list_store_set(store, &it, 1, A_UNSET, -1);
675 }
676 }
677
678 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_tech_shell),
679 GTK_RESPONSE_ACCEPT, FALSE);
680
681 gtk_widget_show(gtk_dialog_get_content_area(GTK_DIALOG(spy_tech_shell)));
682
683 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), "changed",
684 G_CALLBACK(spy_advances_callback), args);
685 g_signal_connect(spy_tech_shell, "response",
686 G_CALLBACK(spy_advances_response), args);
687
688 args->target_tech_id = 0;
689
690 gtk_tree_view_focus(GTK_TREE_VIEW(view));
691}
692
693/**********************************************************************/
696 static void spy_improvements_response(GtkWidget *w, gint response, gpointer data)
697{
698 struct action_data *args = (struct action_data *)data;
699
700 if (response == GTK_RESPONSE_ACCEPT && args->target_building_id > -2) {
701 if (NULL != game_unit_by_number(args->actor_unit_id)
702 && NULL != game_city_by_number(args->target_city_id)) {
703 if (args->target_building_id == B_LAST) {
704 /* This is the untargeted version. */
705 request_do_action(get_non_targeted_action_id(args->act_id),
706 args->actor_unit_id,
707 args->target_city_id,
708 args->target_building_id, "");
709 } else if (args->target_building_id == -1) {
710 /* This is the city production version. */
711 request_do_action(get_production_targeted_action_id(args->act_id),
712 args->actor_unit_id,
713 args->target_city_id,
714 args->target_building_id, "");
715 } else {
716 /* This is the targeted version. */
717 request_do_action(args->act_id,
718 args->actor_unit_id,
719 args->target_city_id,
720 args->target_building_id, "");
721 }
722 }
723 }
724
725 gtk_window_destroy(GTK_WINDOW(spy_sabotage_shell));
726 spy_sabotage_shell = NULL;
727 free(args);
728
729 /* The user have answered the follow up question. Move on. */
730 diplomat_queue_handle_secondary();
731}
732
733/**********************************************************************/
736 static void spy_improvements_callback(GtkTreeSelection *select, gpointer data)
737{
738 struct action_data *args = (struct action_data *)data;
739
740 GtkTreeModel *model;
741 GtkTreeIter it;
742
743 if (gtk_tree_selection_get_selected(select, &model, &it)) {
744 gtk_tree_model_get(model, &it, 1, &(args->target_building_id), -1);
745
746 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_sabotage_shell),
747 GTK_RESPONSE_ACCEPT, TRUE);
748 } else {
749 args->target_building_id = -2;
750
751 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_sabotage_shell),
752 GTK_RESPONSE_ACCEPT, FALSE);
753 }
754}
755
756/**********************************************************************/
759 static void create_improvements_list(struct player *pplayer,
760 struct city *pcity,
761 struct action_data *args)
762{
763 GtkWidget *sw, *frame, *label, *vgrid, *view;
764 GtkListStore *store;
765 GtkCellRenderer *rend;
766 GtkTreeViewColumn *col;
767 GtkTreeIter it;
768
769 struct unit *actor_unit = game_unit_by_number(args->actor_unit_id);
770
771 spy_sabotage_shell = gtk_dialog_new_with_buttons(_("Sabotage Improvements"),
772 NULL, 0,
773 _("_Cancel"), GTK_RESPONSE_CANCEL,
774 _("_Sabotage"), GTK_RESPONSE_ACCEPT,
775 NULL);
776 setup_dialog(spy_sabotage_shell, toplevel);
777
778 gtk_dialog_set_default_response(GTK_DIALOG(spy_sabotage_shell),
779 GTK_RESPONSE_ACCEPT);
780
781 frame = gtk_frame_new(_("Select Improvement to Sabotage"));
782 gtk_box_append(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(spy_sabotage_shell))), frame);
783
784 vgrid = gtk_grid_new();
785 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
786 GTK_ORIENTATION_VERTICAL);
787 gtk_grid_set_row_spacing(GTK_GRID(vgrid), 6);
788 gtk_frame_set_child(GTK_FRAME(frame), vgrid);
789
790 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
791
792 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
793 gtk_widget_set_hexpand(view, TRUE);
794 gtk_widget_set_vexpand(view, TRUE);
795 g_object_unref(store);
796 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
797
798 rend = gtk_cell_renderer_text_new();
799 col = gtk_tree_view_column_new_with_attributes(NULL, rend,
800 "text", 0, NULL);
801 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
802
803 label = g_object_new(GTK_TYPE_LABEL,
804 "use-underline", TRUE,
805 "mnemonic-widget", view,
806 "label", _("_Improvements:"),
807 "xalign", 0.0,
808 "yalign", 0.5,
809 NULL);
810 gtk_grid_attach(GTK_GRID(vgrid), label, 0, 0, 1, 1);
811
812 sw = gtk_scrolled_window_new();
813 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
814 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
815
816 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
817 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
818 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(sw), 200);
819
820 gtk_grid_attach(GTK_GRID(vgrid), sw, 0, 1, 1, 1);
821
822 /* Now populate the list */
823 if (action_prob_possible(actor_unit->client.act_prob_cache[
824 get_production_targeted_action_id(
825 args->act_id)])) {
826 gtk_list_store_append(store, &it);
827 gtk_list_store_set(store, &it, 0, _("City Production"), 1, -1, -1);
828 }
829
830 city_built_iterate(pcity, pimprove) {
831 if (pimprove->sabotage > 0) {
832 gtk_list_store_append(store, &it);
833 gtk_list_store_set(store, &it,
834 0, city_improvement_name_translation(pcity, pimprove),
835 1, improvement_number(pimprove),
836 -1);
837 }
838 } city_built_iterate_end;
839
840 if (action_prob_possible(actor_unit->client.act_prob_cache[
841 get_non_targeted_action_id(args->act_id)])) {
842 struct astring str = ASTRING_INIT;
843
844 gtk_list_store_append(store, &it);
845
846 /* TRANS: %s is a unit name, e.g., Spy */
847 astr_set(&str, _("At %s's Discretion"),
848 unit_name_translation(actor_unit));
849 gtk_list_store_set(store, &it, 0, astr_str(&str), 1, B_LAST, -1);
850
851 astr_free(&str);
852 }
853
854 gtk_dialog_set_response_sensitive(GTK_DIALOG(spy_sabotage_shell),
855 GTK_RESPONSE_ACCEPT, FALSE);
856
857 gtk_widget_show(gtk_dialog_get_content_area(GTK_DIALOG(spy_sabotage_shell)));
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
886has happened to the city during latency. Therefore we must initialize
887pvictim 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, actor->id,
1027 /* Let the server choose the target
1028 * unit. */
1029 IDENTITY_NUMBER_ZERO,
1030 IDENTITY_NUMBER_ZERO,
1031 tgt_tile->index,
1032 action_selection_target_extra(),
1033 REQEST_PLAYER_INITIATED);
1034 } else {
1035 dsend_packet_unit_get_actions(&client.conn,
1036 actor->id, actor->id,
1037 tgt_id, tgt_id,
1038 tgt_tile->index,
1039 action_selection_target_extra(),
1040 REQEST_PLAYER_INITIATED);
1041 }
1042 }
1043 } else {
1044 /* Dialog canceled. This ends the action selection process. */
1045 action_selection_no_longer_in_progress(au_id);
1046 }
1047
1048 gtk_window_destroy(GTK_WINDOW(dlg));
1049}
1050
1051/**********************************************************************/
1054 static void act_sel_new_unit_tgt_callback(GtkWidget *w, gpointer data)
1055{
1056 struct action_data *args = act_sel_dialog_data;
1057
1058 struct unit *punit;
1059 struct unit *tunit;
1060 struct tile *ptile;
1061
1062 if ((punit = game_unit_by_number(args->actor_unit_id))
1063 && (ptile = index_to_tile(&(wld.map), args->target_tile_id))
1064 && (tunit = game_unit_by_number(args->target_unit_id))) {
1065 select_tgt_unit(punit, ptile, ptile->units, tunit,
1066 _("Target unit selection"),
1067 _("Looking for target unit:"),
1068 _("Units at tile:"),
1069 _("Select"),
1070 G_CALLBACK(tgt_unit_change_callback));
1071 }
1072
1073 did_not_decide = TRUE;
1074 action_selection_restart = TRUE;
1075 choice_dialog_destroy(act_sel_dialog);
1076 free(args);
1077}
1078
1079/**********************************************************************/
1082 static void tgt_extra_change_callback(GtkWidget *dlg, gint arg)
1083{
1084 int au_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg), "actor"));
1085
1086 if (arg == GTK_RESPONSE_YES) {
1087 struct unit *actor = game_unit_by_number(au_id);
1088
1089 if (actor != NULL) {
1090 int tgt_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg),
1091 "target"));
1092 struct extra_type *tgt_extra = extra_by_number(tgt_id);
1093 struct tile *tgt_tile = g_object_get_data(G_OBJECT(dlg), "tile");
1094 int tgt_unit = action_selection_target_unit();
1095
1096 if (tgt_extra == NULL) {
1097 /* Make the action dialog pop up again. */
1098 dsend_packet_unit_get_actions(&client.conn,
1099 actor->id, actor->id,
1100 tgt_unit, tgt_unit,
1101 tgt_tile->index,
1102 /* Let the server choose the target
1103 * extra. */
1104 action_selection_target_extra(),
1105 REQEST_PLAYER_INITIATED);
1106 } else {
1107 dsend_packet_unit_get_actions(&client.conn,
1108 actor->id, actor->id,
1109 tgt_unit, tgt_unit,
1110 tgt_tile->index,
1111 tgt_id,
1112 REQEST_PLAYER_INITIATED);
1113 }
1114 }
1115 } else {
1116 /* Dialog canceled. This ends the action selection process. */
1117 action_selection_no_longer_in_progress(au_id);
1118 }
1119
1120 gtk_window_destroy(GTK_WINDOW(dlg));
1121}
1122
1123/**********************************************************************/
1126 static void act_sel_new_extra_tgt_callback(GtkWidget *w, gpointer data)
1127{
1128 struct action_data *args = act_sel_dialog_data;
1129
1130 struct unit *act_unit;
1131 struct extra_type *tgt_extra;
1132 struct tile *tgt_tile;
1133
1134 if ((act_unit = game_unit_by_number(args->actor_unit_id))
1135 && (tgt_tile = index_to_tile(&(wld.map), args->target_tile_id))
1136 && (tgt_extra = extra_by_number(args->target_extra_id))) {
1137 bv_extras potential_targets;
1138
1139 /* Start with the extras at the tile */
1140 potential_targets = *tile_extras(tgt_tile);
1141
1142 extra_type_re_active_iterate(pextra) {
1143 if (BV_ISSET(potential_targets, extra_number(pextra))) {
1144 /* This extra is at the tile. Can anything be done to it? */
1145 if (!utype_can_remove_extra(unit_type_get(act_unit),
1146 pextra)) {
1147 BV_CLR(potential_targets, extra_number(pextra));
1148 }
1149 } else {
1150 /* This extra isn't at the tile yet. Can it be created? */
1151 if (utype_can_create_extra(unit_type_get(act_unit),
1152 pextra)) {
1153 BV_SET(potential_targets, extra_number(pextra));
1154 }
1155 }
1156 } extra_type_re_active_iterate_end;
1157
1158 select_tgt_extra(act_unit, tgt_tile, potential_targets, tgt_extra,
1159 /* TRANS: GTK action selection dialog extra target
1160 * selection dialog title. */
1161 _("Target extra selection"),
1162 /* TRANS: GTK action selection dialog extra target
1163 * selection dialog actor unit label. */
1164 _("Looking for target extra:"),
1165 /* TRANS: GTK action selection dialog extra target
1166 * selection dialog extra list label. */
1167 _("Extra targets:"),
1168 _("Select"),
1169 G_CALLBACK(tgt_extra_change_callback));
1170 }
1171
1172 did_not_decide = TRUE;
1173 action_selection_restart = TRUE;
1174 choice_dialog_destroy(act_sel_dialog);
1175 free(args);
1176}
1177
1178/**********************************************************************/
1181 static void act_sel_location_callback(GtkWidget *w, gpointer data)
1182{
1183 struct action_data *args = act_sel_dialog_data;
1184
1185 struct unit *punit;
1186
1187 if ((punit = game_unit_by_number(args->actor_unit_id))) {
1188 center_tile_mapcanvas(unit_tile(punit));
1189 }
1190}
1191
1192/**********************************************************************/
1195 static void act_sel_wait_callback(GtkWidget *w, gpointer data)
1196{
1197 struct action_data *args = act_sel_dialog_data;
1198
1199 key_unit_wait();
1200
1201 /* the dialog was destroyed when key_unit_wait() resulted in
1202 * action_selection_close() being called. */
1203
1204 free(args);
1205}
1206
1207/**********************************************************************/
1210 static void act_sel_destroy_callback(GtkWidget *w, gpointer data)
1211{
1212 act_sel_dialog = NULL;
1213 diplomat_queue_handle_primary();
1214}
1215
1216/**********************************************************************/
1219 static void act_sel_cancel_callback(GtkWidget *w, gpointer data)
1220{
1221 choice_dialog_destroy(act_sel_dialog);
1222 free(act_sel_dialog_data);
1223}
1224
1225/**********************************************************************/
1228 static void act_sel_close_callback(GtkWidget *w, gpointer data)
1229{
1230 choice_dialog_destroy(act_sel_dialog);
1231 free(act_sel_dialog_data);
1232}
1233
1234/* Mapping from an action to the function to call when its button is
1235 * pushed. */
1236 static const GCallback af_map[ACTION_COUNT] = {
1237 /* Unit acting against a city target. */
1238 [ACTION_SPY_TARGETED_SABOTAGE_CITY] =
1239 (GCallback)request_action_details_callback,
1240 [ACTION_SPY_TARGETED_SABOTAGE_CITY_ESC] =
1241 (GCallback)request_action_details_callback,
1242 [ACTION_SPY_TARGETED_STEAL_TECH] = (GCallback)spy_steal_popup,
1243 [ACTION_SPY_TARGETED_STEAL_TECH_ESC] = (GCallback)spy_steal_esc_popup,
1244 [ACTION_SPY_INCITE_CITY] = (GCallback)request_action_details_callback,
1245 [ACTION_SPY_INCITE_CITY_ESC] = (GCallback)request_action_details_callback,
1246 [ACTION_UPGRADE_UNIT] = (GCallback)upgrade_callback,
1247 [ACTION_STRIKE_BUILDING] = (GCallback)request_action_details_callback,
1248
1249 /* Unit acting against a unit target. */
1250 [ACTION_SPY_BRIBE_UNIT] = (GCallback)request_action_details_callback,
1251
1252 /* Unit acting against all units at a tile. */
1253 /* No special callback functions needed for any unit stack targeted
1254 * actions. */
1255
1256 /* Unit acting against a tile. */
1257 [ACTION_FOUND_CITY] = (GCallback)found_city_callback,
1258
1259 /* Unit acting with no target except itself. */
1260 /* No special callback functions needed for any self targeted actions. */
1261};
1262
1263/**********************************************************************/
1266 static void action_entry(GtkWidget *shl,
1267 action_id act_id,
1268 const struct act_prob *act_probs,
1269 const char *custom,
1270 action_id act_num)
1271{
1272 const gchar *label;
1273 const gchar *tooltip;
1274 GCallback cb;
1275
1276 if (af_map[act_id] == NULL) {
1277 /* No special call back function needed for this action. */
1278 cb = (GCallback)simple_action_callback;
1279 } else {
1280 /* Special action specific callback function specified. */
1281 cb = af_map[act_id];
1282 }
1283
1284 /* Don't show disabled actions. */
1285 if (!action_prob_possible(act_probs[act_id])) {
1286 return;
1287 }
1288
1289 label = action_prepare_ui_name(act_id, "_",
1290 act_probs[act_id],
1291 custom);
1292
1293 tooltip = act_sel_action_tool_tip(action_by_number(act_id),
1294 act_probs[act_id]);
1295
1296 action_button_map[act_id] = choice_dialog_get_number_of_buttons(shl);
1297 choice_dialog_add(shl, label, cb, GINT_TO_POINTER(act_num),
1298 FALSE, tooltip);
1299}
1300
1301/**********************************************************************/
1304 static void action_entry_update(GtkWidget *shl,
1305 action_id act_id,
1306 const struct act_prob *act_probs,
1307 const char *custom,
1308 action_id act_num)
1309{
1310 const gchar *label;
1311 const gchar *tooltip;
1312
1313 /* An action that just became impossible has its button disabled.
1314 * An action that became possible again must be reenabled. */
1315 choice_dialog_button_set_sensitive(act_sel_dialog,
1316 action_button_map[act_id],
1317 action_prob_possible(act_probs[act_id]));
1318
1319 /* The probability may have changed. */
1320 label = action_prepare_ui_name(act_id, "_",
1321 act_probs[act_id], custom);
1322
1323 tooltip = act_sel_action_tool_tip(action_by_number(act_id),
1324 act_probs[act_id]);
1325
1326 choice_dialog_button_set_label(act_sel_dialog,
1327 action_button_map[act_id],
1328 label);
1329 choice_dialog_button_set_tooltip(act_sel_dialog,
1330 action_button_map[act_id],
1331 tooltip);
1332}
1333
1334/**********************************************************************/
1338 void popup_action_selection(struct unit *actor_unit,
1339 struct city *target_city,
1340 struct unit *target_unit,
1341 struct tile *target_tile,
1342 struct extra_type *target_extra,
1343 const struct act_prob *act_probs)
1344{
1345 GtkWidget *shl;
1346 struct astring title = ASTRING_INIT, text = ASTRING_INIT;
1347 struct city *actor_homecity;
1348
1349 int button_id;
1350
1351 act_sel_dialog_data =
1352 act_data(ACTION_ANY, /* Not decided yet */
1353 actor_unit->id,
1354 (target_city) ? target_city->id : IDENTITY_NUMBER_ZERO,
1355 (target_unit) ? target_unit->id : IDENTITY_NUMBER_ZERO,
1356 (target_tile) ? target_tile->index : TILE_INDEX_NONE,
1357 /* No target_building or target_tech supplied. (Dec 2019) */
1358 B_LAST, A_UNSET,
1359 target_extra ? target_extra->id : EXTRA_NONE);
1360
1361 /* Could be caused by the server failing to reply to a request for more
1362 * information or a bug in the client code. */
1363 fc_assert_msg(!is_more_user_input_needed,
1364 "Diplomat queue problem. Is another diplomat window open?");
1365
1366 /* No extra input is required as no action has been chosen yet. */
1367 is_more_user_input_needed = FALSE;
1368
1369 /* No buttons are added yet. */
1370 for (button_id = 0; button_id < BUTTON_COUNT; button_id++) {
1371 action_button_map[button_id] = BUTTON_NOT_THERE;
1372 }
1373
1374 actor_homecity = game_city_by_number(actor_unit->homecity);
1375
1376 actor_unit_id = actor_unit->id;
1377 target_ids[ATK_SELF] = actor_unit_id;
1378 target_ids[ATK_CITY] = target_city ?
1379 target_city->id :
1380 IDENTITY_NUMBER_ZERO;
1381 target_ids[ATK_UNIT] = target_unit ?
1382 target_unit->id :
1383 IDENTITY_NUMBER_ZERO;
1384 target_ids[ATK_UNITS] = target_tile ?
1385 tile_index(target_tile) :
1386 TILE_INDEX_NONE;
1387 target_ids[ATK_TILE] = target_tile ?
1388 tile_index(target_tile) :
1389 TILE_INDEX_NONE;
1390 target_ids[ATK_EXTRAS] = target_tile ?
1391 tile_index(target_tile) :
1392 TILE_INDEX_NONE;
1393 target_extra_id = target_extra ?
1394 extra_number(target_extra) :
1395 EXTRA_NONE;
1396
1397 astr_set(&title,
1398 /* TRANS: %s is a unit name, e.g., Spy */
1399 _("Choose Your %s's Strategy"),
1400 unit_name_translation(actor_unit));
1401
1402 if (target_city && actor_homecity) {
1403 astr_set(&text,
1404 _("Your %s from %s reaches the city of %s.\nWhat now?"),
1405 unit_name_translation(actor_unit),
1406 city_name_get(actor_homecity),
1407 city_name_get(target_city));
1408 } else if (target_city) {
1409 astr_set(&text,
1410 _("Your %s has arrived at %s.\nWhat is your command?"),
1411 unit_name_translation(actor_unit),
1412 city_name_get(target_city));
1413 } else if (target_unit) {
1414 astr_set(&text,
1415 /* TRANS: Your Spy is ready to act against Roman Freight. */
1416 _("Your %s is ready to act against %s %s."),
1417 unit_name_translation(actor_unit),
1418 nation_adjective_for_player(unit_owner(target_unit)),
1419 unit_name_translation(target_unit));
1420 } else {
1421 fc_assert_msg(target_unit || target_city || target_tile,
1422 "No target specified.");
1423 astr_set(&text,
1424 /* TRANS: %s is a unit name, e.g., Diplomat, Spy */
1425 _("Your %s is waiting for your command."),
1426 unit_name_translation(actor_unit));
1427 }
1428
1429 shl = choice_dialog_start(GTK_WINDOW(toplevel), astr_str(&title),
1430 astr_str(&text));
1431
1432 /* Unit acting against a city */
1433
1434 action_iterate(act) {
1435 if (action_id_get_actor_kind(act) == AAK_UNIT
1436 && action_id_get_target_kind(act) == ATK_CITY) {
1437 action_entry(shl, act, act_probs,
1438 get_act_sel_action_custom_text(action_by_number(act),
1439 act_probs[act],
1440 actor_unit,
1441 target_city),
1442 act);
1443 }
1444 } action_iterate_end;
1445
1446 /* Unit acting against another unit */
1447
1448 action_iterate(act) {
1449 if (action_id_get_actor_kind(act) == AAK_UNIT
1450 && action_id_get_target_kind(act) == ATK_UNIT) {
1451 action_entry(shl, act, act_probs,
1452 get_act_sel_action_custom_text(action_by_number(act),
1453 act_probs[act],
1454 actor_unit,
1455 target_city),
1456 act);
1457 }
1458 } action_iterate_end;
1459
1460 /* Unit acting against all units at a tile */
1461
1462 action_iterate(act) {
1463 if (action_id_get_actor_kind(act) == AAK_UNIT
1464 && action_id_get_target_kind(act) == ATK_UNITS) {
1465 action_entry(shl, act, act_probs,
1466 get_act_sel_action_custom_text(action_by_number(act),
1467 act_probs[act],
1468 actor_unit,
1469 target_city),
1470 act);
1471 }
1472 } action_iterate_end;
1473
1474 /* Unit acting against a tile */
1475
1476 action_iterate(act) {
1477 if (action_id_get_actor_kind(act) == AAK_UNIT
1478 && action_id_get_target_kind(act) == ATK_TILE) {
1479 action_entry(shl, act, act_probs,
1480 get_act_sel_action_custom_text(action_by_number(act),
1481 act_probs[act],
1482 actor_unit,
1483 target_city),
1484 act);
1485 }
1486 } action_iterate_end;
1487
1488 /* Unit acting against a tile's extras */
1489
1490 action_iterate(act) {
1491 if (action_id_get_actor_kind(act) == AAK_UNIT
1492 && action_id_get_target_kind(act) == ATK_EXTRAS) {
1493 action_entry(shl, act, act_probs,
1494 get_act_sel_action_custom_text(action_by_number(act),
1495 act_probs[act],
1496 actor_unit,
1497 target_city),
1498 act);
1499 }
1500 } action_iterate_end;
1501
1502 /* Unit acting against itself. */
1503
1504 action_iterate(act) {
1505 if (action_id_get_actor_kind(act) == AAK_UNIT
1506 && action_id_get_target_kind(act) == ATK_SELF) {
1507 action_entry(shl, act, act_probs,
1508 get_act_sel_action_custom_text(action_by_number(act),
1509 act_probs[act],
1510 actor_unit,
1511 target_city),
1512 act);
1513 }
1514 } action_iterate_end;
1515
1516 if (target_unit != NULL
1517 && unit_list_size(target_tile->units) > 1) {
1518 action_button_map[BUTTON_NEW_UNIT_TGT] =
1519 choice_dialog_get_number_of_buttons(shl);
1520 choice_dialog_add(shl, _("Change unit target"),
1521 (GCallback)act_sel_new_unit_tgt_callback,
1522 GINT_TO_POINTER(ACTION_NONE), TRUE, NULL);
1523 }
1524
1525 if (target_extra != NULL) {
1526 action_button_map[BUTTON_NEW_EXTRA_TGT] =
1527 choice_dialog_get_number_of_buttons(shl);
1528 choice_dialog_add(shl, _("Change extra target"),
1529 (GCallback)act_sel_new_extra_tgt_callback,
1530 GINT_TO_POINTER(ACTION_NONE), TRUE, NULL);
1531 }
1532
1533 action_button_map[BUTTON_LOCATION] =
1534 choice_dialog_get_number_of_buttons(shl);
1535 choice_dialog_add(shl, _("Show Location"),
1536 (GCallback)act_sel_location_callback,
1537 GINT_TO_POINTER(ACTION_NONE),
1538 TRUE, NULL);
1539
1540 action_button_map[BUTTON_WAIT] =
1541 choice_dialog_get_number_of_buttons(shl);
1542 choice_dialog_add(shl, _("_Wait"),
1543 (GCallback)act_sel_wait_callback,
1544 GINT_TO_POINTER(ACTION_NONE),
1545 TRUE, NULL);
1546
1547 action_button_map[BUTTON_CANCEL] =
1548 choice_dialog_get_number_of_buttons(shl);
1549 choice_dialog_add(shl, _("_Cancel"),
1550 (GCallback)act_sel_cancel_callback,
1551 GINT_TO_POINTER(ACTION_NONE),
1552 FALSE, NULL);
1553
1554 choice_dialog_end(shl);
1555
1556 act_sel_dialog = shl;
1557
1558 choice_dialog_set_hide(shl, TRUE);
1559 g_signal_connect(shl, "destroy",
1560 G_CALLBACK(act_sel_destroy_callback), NULL);
1561 g_signal_connect(shl, "close-request",
1562 G_CALLBACK(act_sel_close_callback),
1563 GINT_TO_POINTER(ACTION_NONE));
1564
1565 /* Give follow up questions access to action probabilities. */
1566 client_unit_init_act_prob_cache(actor_unit);
1567 action_iterate(act) {
1568 actor_unit->client.act_prob_cache[act] = act_probs[act];
1569 } action_iterate_end;
1570
1571 astr_free(&title);
1572 astr_free(&text);
1573}
1574
1575/**********************************************************************/
1580 int action_selection_actor_unit(void)
1581{
1582 if (act_sel_dialog == NULL) {
1583 return IDENTITY_NUMBER_ZERO;
1584 }
1585 return actor_unit_id;
1586}
1587
1588/**********************************************************************/
1594 int action_selection_target_city(void)
1595{
1596 if (act_sel_dialog == NULL) {
1597 return IDENTITY_NUMBER_ZERO;
1598 }
1599 return target_ids[ATK_CITY];
1600}
1601
1602/**********************************************************************/
1608 int action_selection_target_unit(void)
1609{
1610 if (act_sel_dialog == NULL) {
1611 return IDENTITY_NUMBER_ZERO;
1612 }
1613
1614 return target_ids[ATK_UNIT];
1615}
1616
1617/**********************************************************************/
1623 int action_selection_target_tile(void)
1624{
1625 if (act_sel_dialog == NULL) {
1626 return TILE_INDEX_NONE;
1627 }
1628
1629 return target_ids[ATK_TILE];
1630}
1631
1632/**********************************************************************/
1638 int action_selection_target_extra(void)
1639{
1640 if (act_sel_dialog == NULL) {
1641 return EXTRA_NONE;
1642 }
1643
1644 return target_extra_id;
1645}
1646
1647/**********************************************************************/
1650 void action_selection_refresh(struct unit *actor_unit,
1651 struct city *target_city,
1652 struct unit *target_unit,
1653 struct tile *target_tile,
1654 struct extra_type *target_extra,
1655 const struct act_prob *act_probs)
1656{
1657 if (act_sel_dialog == NULL) {
1658 fc_assert_msg(act_sel_dialog != NULL,
1659 "The action selection dialog should have been open");
1660 return;
1661 }
1662
1663 if (actor_unit->id != action_selection_actor_unit()) {
1664 fc_assert_msg(actor_unit->id == action_selection_actor_unit(),
1665 "The action selection dialog is for another actor unit.");
1666 return;
1667 }
1668
1669 /* A new target may have appeared. */
1670 if (target_city) {
1671 act_sel_dialog_data->target_city_id = target_city->id;
1672 }
1673 if (target_unit) {
1674 act_sel_dialog_data->target_unit_id = target_unit->id;
1675 }
1676 if (target_tile) {
1677 act_sel_dialog_data->target_tile_id = target_tile->index;
1678 }
1679 /* No target_building or target_tech supplied. (Dec 2019) */
1680 if (target_extra) {
1681 act_sel_dialog_data->target_extra_id = target_extra->id;
1682 }
1683
1684 action_iterate(act) {
1685 const char *custom;
1686
1687 if (action_id_get_actor_kind(act) != AAK_UNIT) {
1688 /* Not relevant. */
1689 continue;
1690 }
1691
1692 custom = get_act_sel_action_custom_text(action_by_number(act),
1693 act_probs[act],
1694 actor_unit,
1695 target_city);
1696
1697 if (BUTTON_NOT_THERE == action_button_map[act]) {
1698 /* Add the button (unless its probability is 0). */
1699 action_entry(act_sel_dialog, act, act_probs, custom, act);
1700 } else {
1701 /* Update the existing button. */
1702 action_entry_update(act_sel_dialog, act, act_probs, custom, act);
1703 }
1704 } action_iterate_end;
1705
1706 /* DO NOT change the action_button_map[] for any button to reflect its
1707 * new position. A button keeps its choice dialog internal name when its
1708 * position changes. A button's id number is therefore based on when
1709 * it was added, not on its current position. */
1710
1711 if (BUTTON_NOT_THERE != action_button_map[BUTTON_WAIT]) {
1712 /* Move the wait button below the recently added button. */
1713 choice_dialog_button_move_to_the_end(act_sel_dialog,
1714 action_button_map[BUTTON_WAIT]);
1715 }
1716
1717 if (BUTTON_NOT_THERE != action_button_map[BUTTON_CANCEL]) {
1718 /* Move the cancel button below the recently added button. */
1719 choice_dialog_button_move_to_the_end(act_sel_dialog,
1720 action_button_map[BUTTON_CANCEL]);
1721 }
1722
1723 choice_dialog_end(act_sel_dialog);
1724}
1725
1726/**********************************************************************/
1729 void action_selection_close(void)
1730{
1731 if (act_sel_dialog != NULL) {
1732 did_not_decide = TRUE;
1733 choice_dialog_destroy(act_sel_dialog);
1734 }
1735}
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:1972
action_get_actor_kind
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6709
action_get_sub_target_kind
enum action_sub_target_kind action_get_sub_target_kind(const struct action *paction)
Definition actions.c:1751
action_get_target_kind
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1740
actions.h
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
action_iterate_end
#define action_iterate_end
Definition actions.h:472
action_id_get_actor_kind
#define action_id_get_actor_kind(act_id)
Definition actions.h:651
action_iterate
#define action_iterate(_act_)
Definition actions.h:467
ACTION_ANY
#define ACTION_ANY
Definition actions.h:290
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:655
ACTION_NONE
#define ACTION_NONE
Definition actions.h:293
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astr_set
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
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:657
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1106
INCITE_IMPOSSIBLE_COST
#define INCITE_IMPOSSIBLE_COST
Definition city.h:88
city_owner
#define city_owner(_pcity_)
Definition city.h:543
city_built_iterate
#define city_built_iterate(_pcity, _p)
Definition city.h:798
city_built_iterate_end
#define city_built_iterate_end
Definition city.h:804
client
struct civclient client
Definition client_main.c:149
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:1241
climisc.h
connectdlg_common.h
action_selection_no_longer_in_progress
void action_selection_no_longer_in_progress(const int old_actor_id)
Definition control.c:1032
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:1675
request_action_details
void request_action_details(action_id action, int actor_id, int target_id)
Definition control.c:1695
action_decision_clear_want
void action_decision_clear_want(const int old_actor_id)
Definition control.c:1053
key_unit_wait
void key_unit_wait(void)
Definition control.c:3346
action_selection_next_in_focus
void action_selection_next_in_focus(const int old_actor_id)
Definition control.c:1065
control.h
dialogs_g.h
target_unit
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:55
popup_action_selection
popup_action_selection
Definition dialogs_g.h:54
actor_unit
struct unit * actor_unit
Definition dialogs_g.h:54
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:72
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:72
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:68
target_tile
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:56
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:73
target_city
struct unit struct city * target_city
Definition dialogs_g.h:55
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:73
target_extra
struct unit struct city struct unit struct tile struct extra_type * target_extra
Definition dialogs_g.h:56
extra_number
int extra_number(const struct extra_type *pextra)
Definition extras.c:153
extra_by_number
struct extra_type * extra_by_number(int id)
Definition extras.c:175
EXTRA_NONE
#define EXTRA_NONE
Definition extras.h:82
extra_type_re_active_iterate_end
#define extra_type_re_active_iterate_end
Definition extras.h:305
extra_type_re_active_iterate
#define extra_type_re_active_iterate(_p)
Definition extras.h:301
NO_TARGET
#define NO_TARGET
Definition fc_types.h:324
action_id
int action_id
Definition fc_types.h:359
IDENTITY_NUMBER_ZERO
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:82
PL_
#define PL_(String1, String2, n)
Definition fcintl.h:71
_
#define _(String)
Definition fcintl.h:67
game
struct civ_game game
Definition game.c:57
wld
struct world wld
Definition game.c:58
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:111
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:102
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:1650
incite_response
static void incite_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:954
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:741
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:1136
action_selection_target_tile
int action_selection_target_tile(void)
Definition action_dialog.c:1635
create_improvements_list
static void create_improvements_list(struct player *pplayer, struct city *pcity, struct action_data *args)
Definition action_dialog.c:764
act_sel_destroy_callback
static void act_sel_destroy_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1220
action_selection_actor_unit
int action_selection_actor_unit(void)
Definition action_dialog.c:1592
spy_advances_response
static void spy_advances_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:517
tgt_extra_change_callback
static void tgt_extra_change_callback(GtkWidget *dlg, gint arg)
Definition action_dialog.c:1092
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:882
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:1741
spy_improvements_response
static void spy_improvements_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:701
action_selection_target_city
int action_selection_target_city(void)
Definition action_dialog.c:1606
bribe_response
static void bribe_response(GtkWidget *w, gint response, gpointer data)
Definition action_dialog.c:459
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:1278
spy_steal_esc_popup
static void spy_steal_esc_popup(GtkWidget *w, gpointer data)
Definition action_dialog.c:928
spy_steal_popup
static void spy_steal_popup(GtkWidget *w, gpointer data)
Definition action_dialog.c:918
act_sel_close_callback
static void act_sel_close_callback(GtkWidget *w, gint response_id, gpointer data)
Definition action_dialog.c:1238
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:1191
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:1662
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:574
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:1205
act_sel_new_unit_tgt_callback
static void act_sel_new_unit_tgt_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:1064
tgt_unit_change_callback
static void tgt_unit_change_callback(GtkWidget *dlg, gint arg)
Definition action_dialog.c:1020
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:938
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:1229
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:1316
action_selection_target_unit
int action_selection_target_unit(void)
Definition action_dialog.c:1620
popup_incite_dialog
void popup_incite_dialog(struct unit *actor, struct city *pcity, int cost, const struct action *paction)
Definition action_dialog.c:973
af_map
static const GCallback af_map[ACTION_COUNT]
Definition action_dialog.c:1248
upgrade_callback
static void upgrade_callback(GtkWidget *w, gpointer data)
Definition action_dialog.c:436
spy_advances_callback
static void spy_advances_callback(GtkTreeSelection *select, gpointer data)
Definition action_dialog.c:550
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:1444
toplevel
GtkWidget * toplevel
Definition gui_main.c:124
gtk_tree_view_focus
void gtk_tree_view_focus(GtkTreeView *view)
Definition gui_stuff.c:230
setup_dialog
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:281
shell
static struct gui_dialog * shell
Definition messagedlg.c:39
tooltip
const char * tooltip
Definition repodlgs.c:1314
title
const char * title
Definition repodlgs.c:1313
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:106
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:248
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:192
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:182
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:454
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1222
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:168
REQEST_PLAYER_INITIATED
#define REQEST_PLAYER_INITIATED
Definition packets.h:70
dsend_packet_unit_get_actions
int dsend_packet_unit_get_actions(struct connection *pc, int actor_unit_id16, int actor_unit_id32, int target_unit_id16, int target_unit_id32, int target_tile_id, int target_extra_id, int request_kind)
Definition packets_gen.c:46745
dsend_packet_city_name_suggestion_req
int dsend_packet_city_name_suggestion_req(struct connection *pc, int unit_id16, int unit_id32)
Definition packets_gen.c:30284
packhand.h
research_advance_name_translation
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:271
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:126
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
research_invention_gettable
bool research_invention_gettable(const struct research *presearch, const Tech_type_id tech, bool allow_holes)
Definition research.c:690
research.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
act_prob
Definition fc_types.h:1092
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:379
action::id
action_id id
Definition actions.h:380
action::target_complexity
enum act_tgt_compl target_complexity
Definition actions.h:390
astring
Definition astring.h:36
city
Definition city.h:309
city::id
int id
Definition city.h:315
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:156
extra_type
Definition extras.h:85
packet_game_info::tech_steal_allow_holes
bool tech_steal_allow_holes
Definition packets_gen.h:211
player
Definition player.h:249
research
Definition research.h:39
tile
Definition tile.h:49
tile::index
int index
Definition tile.h:50
tile::units
struct unit_list * units
Definition tile.h:57
unit
Definition unit.h:138
unit::id
int id
Definition unit.h:145
unit::index
int index
Definition unit.h:195
unit::client
struct unit::@80::@82 client
unit::act_prob_cache
struct act_prob * act_prob_cache
Definition unit.h:225
unit::homecity
int homecity
Definition unit.h:146
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:969
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:248
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:244
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:1743
act_sel_action_tool_tip
const char * act_sel_action_tool_tip(const struct action *paction, const struct act_prob prob)
Definition text.c:1820
text.h
tile_index
#define tile_index(_pt_)
Definition tile.h:87
tile_extras
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:119
TILE_INDEX_NONE
#define TILE_INDEX_NONE
Definition tile.h:47
traderoutes.h
unit.h
unit_tile
#define unit_tile(_pu)
Definition unit.h:388
unit_owner
#define unit_owner(_pu)
Definition unit.h:387
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:235
unit_name_translation
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1621
utype_can_create_extra
bool utype_can_create_extra(const struct unit_type *putype, const struct extra_type *pextra)
Definition unittype.c:211