1 /***********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 #include <gtk/gtk.h>
19 
20 /* utility */
21 #include "fcintl.h"
22 
23 /* common */
24 #include "game.h"
25 #include "movement.h"
26 #include "unit.h"
27 
28 /* client */
29 #include "control.h"
30 #include "tilespec.h"
31 
32 /* client/gui-gtk-3.22 */
33 #include "gui_main.h"
34 #include "gui_stuff.h"
35 #include "sprite.h"
36 #include "unitselunitdlg.h"
37 
38 #include "transportdlg.h"
39 
40 struct transport_radio_cb_data {
41   GtkWidget *dlg;
42   int tp_id;
43 };
44 
45 /****************************************************************
46   Handle user response to transport dialog.
47 *****************************************************************/
transport_response_callback(GtkWidget * dlg,gint arg)48 static void transport_response_callback(GtkWidget *dlg, gint arg)
49 {
50   if (arg == GTK_RESPONSE_YES) {
51     struct unit *pcargo =
52       game_unit_by_number(GPOINTER_TO_INT(
53                             g_object_get_data(G_OBJECT(dlg),
54                                               "actor")));
55 
56     if (pcargo != NULL) {
57       int tp_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dlg),
58                                                     "target"));
59       struct tile *ptile = g_object_get_data(G_OBJECT(dlg), "tile");
60 
61       if (tp_id == 0) {
62         /* Load to any */
63         request_unit_load(pcargo, NULL, ptile);
64       } else {
65         struct unit *ptransport = game_unit_by_number(tp_id);
66 
67         if (ptransport != NULL) {
68           /* Still exist */
69           request_unit_load(pcargo, ptransport, ptile);
70         }
71       }
72     }
73   }
74 
75   gtk_widget_destroy(dlg);
76 }
77 
78 /****************************************************************************
79   Handle transport request automatically when there's nothing to
80   choose from. Otherwise open up transport dialog for the unit
81 ****************************************************************************/
request_transport(struct unit * cargo,struct tile * ptile)82 bool request_transport(struct unit *cargo, struct tile *ptile)
83 {
84   int tcount;
85   struct unit_list *potential_transports = unit_list_new();
86   struct unit *best_transport = transporter_for_unit_at(cargo, ptile);
87 
88   unit_list_iterate(ptile->units, ptransport) {
89     if (can_unit_transport(ptransport, cargo)
90         && get_transporter_occupancy(ptransport) < get_transporter_capacity(ptransport)) {
91       unit_list_append(potential_transports, ptransport);
92     }
93   } unit_list_iterate_end;
94 
95   tcount = unit_list_size(potential_transports);
96 
97   if (tcount == 0) {
98     fc_assert(best_transport == NULL);
99     unit_list_destroy(potential_transports);
100 
101     return FALSE; /* Unit was not handled here. */
102   } else if (tcount == 1) {
103     /* There's exactly one potential transport - use it automatically */
104     fc_assert(unit_list_get(potential_transports, 0) == best_transport);
105     request_unit_load(cargo, unit_list_get(potential_transports, 0), ptile);
106 
107     unit_list_destroy(potential_transports);
108 
109     return TRUE;
110   }
111 
112   return select_tgt_unit(cargo, ptile, potential_transports, best_transport,
113                          _("Transport selection"),
114                          _("Looking for transport:"),
115                          _("Transports available:"),
116                          _("Load"),
117                          G_CALLBACK(transport_response_callback));
118 }
119