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 /* utility */
19 #include "bitvector.h"
20 #include "fcintl.h"
21 #include "log.h"
22 #include "mem.h"
23 #include "timing.h"
24 
25 /* common */
26 #include "combat.h"
27 #include "game.h"
28 #include "map.h"
29 #include "movement.h"
30 #include "unitlist.h"
31 
32 /* common/aicore */
33 #include "path_finding.h"
34 
35 /* client/include */
36 #include "chatline_g.h"
37 #include "citydlg_g.h"
38 #include "dialogs_g.h"
39 #include "gui_main_g.h"
40 #include "mapctrl_g.h"
41 #include "mapview_g.h"
42 #include "menu_g.h"
43 
44 /* client */
45 #include "audio.h"
46 #include "client_main.h"
47 #include "climap.h"
48 #include "climisc.h"
49 #include "editor.h"
50 #include "goto.h"
51 #include "options.h"
52 #include "overview_common.h"
53 #include "tilespec.h"
54 #include "update_queue.h"
55 
56 #include "control.h"
57 
58 
59 struct client_nuke_data {
60   int *units_id;
61   int units_num;
62   int tile_idx;
63 };
64 
65 /* gui-dep code may adjust depending on tile size etc: */
66 int num_units_below = MAX_NUM_UNITS_BELOW;
67 
68 /* current_focus points to the current unit(s) in focus */
69 static struct unit_list *current_focus = NULL;
70 
71 /* The previously focused unit(s).  Focus can generally be recalled
72  * with keypad 5 (or the equivalent). */
73 static struct unit_list *previous_focus = NULL;
74 
75 /* The priority unit(s) for unit_focus_advance(). */
76 static struct unit_list *urgent_focus_queue = NULL;
77 
78 /* These should be set via set_hover_state() */
79 enum cursor_hover_state hover_state = HOVER_NONE;
80 enum unit_activity connect_activity;
81 struct extra_type *connect_tgt;
82 enum unit_orders goto_last_order; /* Last order for goto */
83 
84 static struct tile *hover_tile = NULL;
85 static struct unit_list *battlegroups[MAX_NUM_BATTLEGROUPS];
86 
87 /* Current moving unit. */
88 static struct unit *punit_moving = NULL;
89 
90 /* units involved in current combat */
91 static struct unit *punit_attacking = NULL;
92 static struct unit *punit_defending = NULL;
93 
94 /* The ID of the unit that currently is in the action selection process.
95  *
96  * The action selection process begins when the client asks the server what
97  * actions a unit can take. It ends when the last follow up question is
98  * answered.
99  *
100  * No common client code using client supports more than one action
101  * selection process at once. The interface between the common client code
102  * and the clients would have to change before that could happen. (See
103  * action_selection_actor_unit() etc)
104  */
105 static int action_selection_in_progress_for = IDENTITY_NUMBER_ZERO;
106 
107 /*
108  * This variable is TRUE iff a NON-AI controlled unit was focused this
109  * turn.
110  */
111 bool non_ai_unit_focus;
112 
113 static void key_unit_clean(enum unit_activity act, enum extra_rmcause rmcause);
114 
115 /*************************************************************************/
116 
117 static struct unit *quickselect(struct tile *ptile,
118                                 enum quickselect_type qtype);
119 
120 /**************************************************************************
121   Called only by client_game_init() in client/client_main.c
122 **************************************************************************/
control_init(void)123 void control_init(void)
124 {
125   int i;
126 
127   current_focus = unit_list_new();
128   previous_focus = unit_list_new();
129   urgent_focus_queue = unit_list_new();
130 
131   for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
132     battlegroups[i] = unit_list_new();
133   }
134   hover_tile = NULL;
135 }
136 
137 /**************************************************************************
138   Called only by client_game_free() in client/client_main.c
139 **************************************************************************/
control_free(void)140 void control_free(void)
141 {
142   int i;
143 
144   unit_list_destroy(current_focus);
145   current_focus = NULL;
146   unit_list_destroy(previous_focus);
147   previous_focus = NULL;
148   unit_list_destroy(urgent_focus_queue);
149   urgent_focus_queue = NULL;
150 
151   for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
152     unit_list_destroy(battlegroups[i]);
153     battlegroups[i] = NULL;
154   }
155 
156   set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
157   free_client_goto();
158 }
159 
160 /**************************************************************************
161   Returns list of units currently in focus.
162 **************************************************************************/
get_units_in_focus(void)163 struct unit_list *get_units_in_focus(void)
164 {
165   return current_focus;
166 }
167 
168 /****************************************************************************
169   Return the number of units currently in focus (0 or more).
170 ****************************************************************************/
get_num_units_in_focus(void)171 int get_num_units_in_focus(void)
172 {
173   return (NULL != current_focus ? unit_list_size(current_focus) : 0);
174 }
175 
176 /**************************************************************************
177   Store the focus unit(s).  This is used so that we can return to the
178   previously focused unit with an appropriate keypress.
179 **************************************************************************/
store_previous_focus(void)180 static void store_previous_focus(void)
181 {
182   if (get_num_units_in_focus() > 0) {
183     unit_list_clear(previous_focus);
184     unit_list_iterate(get_units_in_focus(), punit) {
185       unit_list_append(previous_focus, punit);
186     } unit_list_iterate_end;
187   }
188 }
189 
190 /****************************************************************************
191   Store a priority focus unit.
192 ****************************************************************************/
unit_focus_urgent(struct unit * punit)193 void unit_focus_urgent(struct unit *punit)
194 {
195   unit_list_append(urgent_focus_queue, punit);
196 }
197 
198 /**************************************************************************
199   Do various updates required when the set of units in focus changes.
200 **************************************************************************/
focus_units_changed(void)201 static void focus_units_changed(void)
202 {
203   update_unit_info_label(get_units_in_focus());
204   menus_update();
205   /* Notify the GUI */
206   real_focus_units_changed();
207 }
208 
209 /**************************************************************************
210   Called when a unit is killed; this removes it from the control lists.
211 **************************************************************************/
control_unit_killed(struct unit * punit)212 void control_unit_killed(struct unit *punit)
213 {
214   int i;
215 
216   goto_unit_killed(punit);
217 
218   unit_list_remove(get_units_in_focus(), punit);
219   if (get_num_units_in_focus() < 1) {
220     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
221   }
222 
223   unit_list_remove(previous_focus, punit);
224   unit_list_remove(urgent_focus_queue, punit);
225 
226   for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
227     unit_list_remove(battlegroups[i], punit);
228   }
229 
230   focus_units_changed();
231 }
232 
233 /**************************************************************************
234   Change the battlegroup for this unit.
235 **************************************************************************/
unit_change_battlegroup(struct unit * punit,int battlegroup)236 void unit_change_battlegroup(struct unit *punit, int battlegroup)
237 {
238   if (battlegroup < 0 || battlegroup >= MAX_NUM_BATTLEGROUPS) {
239     battlegroup = BATTLEGROUP_NONE;
240   }
241 
242   if (punit->battlegroup != battlegroup) {
243     if (battlegroup != BATTLEGROUP_NONE) {
244       unit_list_append(battlegroups[battlegroup], punit);
245     }
246     if (punit->battlegroup != BATTLEGROUP_NONE) {
247       unit_list_remove(battlegroups[punit->battlegroup], punit);
248     }
249     punit->battlegroup = battlegroup;
250   }
251 }
252 
253 /**************************************************************************
254   Call this on new units to enter them in the battlegroup lists.
255 **************************************************************************/
unit_register_battlegroup(struct unit * punit)256 void unit_register_battlegroup(struct unit *punit)
257 {
258   if (punit->battlegroup < 0 || punit->battlegroup >= MAX_NUM_BATTLEGROUPS) {
259     punit->battlegroup = BATTLEGROUP_NONE;
260   } else {
261     unit_list_append(battlegroups[punit->battlegroup], punit);
262   }
263 }
264 
265 /**************************************************************************
266   Enter the given hover state.
267 
268     activity => The connect activity (ACTIVITY_IRRIGATE, etc.)
269     order => The last order (ORDER_BUILD_CITY, ORDER_LAST, etc.)
270 **************************************************************************/
set_hover_state(struct unit_list * punits,enum cursor_hover_state state,enum unit_activity activity,struct extra_type * tgt,enum unit_orders order)271 void set_hover_state(struct unit_list *punits, enum cursor_hover_state state,
272 		     enum unit_activity activity,
273                      struct extra_type *tgt,
274 		     enum unit_orders order)
275 {
276   fc_assert_ret((punits && unit_list_size(punits) > 0)
277                 || state == HOVER_NONE);
278   fc_assert_ret(state == HOVER_CONNECT || activity == ACTIVITY_LAST);
279   fc_assert_ret(state == HOVER_GOTO || order == ORDER_LAST);
280   exit_goto_state();
281   hover_state = state;
282   connect_activity = activity;
283   if (tgt) {
284     connect_tgt = tgt;
285   } else {
286     connect_tgt = NULL;
287   }
288   goto_last_order = order;
289 }
290 
291 /**************************************************************************
292   Returns TRUE iff the client should ask the server about what actions a
293   unit can perform.
294 **************************************************************************/
should_ask_server_for_actions(const struct unit * punit)295 bool should_ask_server_for_actions(const struct unit *punit)
296 {
297   return (punit->action_decision_want == ACT_DEC_ACTIVE
298           /* The player is interested in getting a pop up for a mere
299            * arrival. */
300           || (punit->action_decision_want == ACT_DEC_PASSIVE
301               && gui_options.popup_actor_arrival));
302 }
303 
304 /**************************************************************************
305   Returns TRUE iff it is OK to ask the server about what actions a unit
306   can perform.
307 **************************************************************************/
can_ask_server_for_actions(void)308 static bool can_ask_server_for_actions(void)
309 {
310   /* OK as long as no other unit already asked and aren't done yet. */
311   return (action_selection_in_progress_for == IDENTITY_NUMBER_ZERO
312           && action_selection_actor_unit() == IDENTITY_NUMBER_ZERO);
313 }
314 
315 /**************************************************************************
316   Ask the server about what actions punit may be able to perform against
317   it's stored target tile.
318 
319   The server's reply will pop up the action selection dialog unless no
320   alternatives exists.
321 **************************************************************************/
ask_server_for_actions(struct unit * punit)322 static void ask_server_for_actions(struct unit *punit)
323 {
324   fc_assert_ret(punit);
325   fc_assert_ret(punit->action_decision_tile);
326 
327   /* Only one action selection dialog at a time is supported. */
328   fc_assert_msg(action_selection_in_progress_for == IDENTITY_NUMBER_ZERO,
329                 "Unit %d started action selection before unit %d was done",
330                 action_selection_in_progress_for, punit->id);
331   action_selection_in_progress_for = punit->id;
332 
333   dsend_packet_unit_get_actions(&client.conn,
334                                 punit->id,
335                                 IDENTITY_NUMBER_ZERO,
336                                 IDENTITY_NUMBER_ZERO,
337                                 tile_index(punit->action_decision_tile),
338                                 TRUE);
339 }
340 
341 /****************************************************************************
342   Return TRUE iff this unit is in focus.
343 ****************************************************************************/
unit_is_in_focus(const struct unit * punit)344 bool unit_is_in_focus(const struct unit *punit)
345 {
346   return unit_list_search(get_units_in_focus(), punit) != NULL;
347 }
348 
349 /****************************************************************************
350   Return TRUE iff a unit on this tile is in focus.
351 ****************************************************************************/
get_focus_unit_on_tile(const struct tile * ptile)352 struct unit *get_focus_unit_on_tile(const struct tile *ptile)
353 {
354   unit_list_iterate(get_units_in_focus(), punit) {
355     if (unit_tile(punit) == ptile) {
356       return punit;
357     }
358   } unit_list_iterate_end;
359 
360   return NULL;
361 }
362 
363 /****************************************************************************
364   Return head of focus units list.
365 ****************************************************************************/
head_of_units_in_focus(void)366 struct unit *head_of_units_in_focus(void)
367 {
368   return unit_list_get(current_focus, 0);
369 }
370 
371 /****************************************************************************
372   Finds a single focus unit that we can center on.  May return NULL.
373 ****************************************************************************/
find_a_focus_unit_tile_to_center_on(void)374 static struct tile *find_a_focus_unit_tile_to_center_on(void)
375 {
376   struct unit *punit;
377 
378   if (NULL != (punit = get_focus_unit_on_tile(get_center_tile_mapcanvas()))) {
379     return unit_tile(punit);
380   } else if (get_num_units_in_focus() > 0) {
381     return unit_tile(head_of_units_in_focus());
382   } else {
383     return NULL;
384   }
385 }
386 
387 /**************************************************************************
388 Center on the focus unit, if off-screen and auto_center_on_unit is true.
389 **************************************************************************/
auto_center_on_focus_unit(void)390 void auto_center_on_focus_unit(void)
391 {
392   struct tile *ptile = find_a_focus_unit_tile_to_center_on();
393 
394   if (ptile && gui_options.auto_center_on_unit &&
395       !tile_visible_and_not_on_border_mapcanvas(ptile)) {
396     center_tile_mapcanvas(ptile);
397   }
398 }
399 
400 /**************************************************************************
401   Add unit to list of units currently in focus.
402 **************************************************************************/
current_focus_append(struct unit * punit)403 static void current_focus_append(struct unit *punit)
404 {
405   unit_list_append(current_focus, punit);
406 
407   punit->client.focus_status = FOCUS_AVAIL;
408   refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
409 
410   if (should_ask_server_for_actions(punit)
411       && can_ask_server_for_actions()) {
412     ask_server_for_actions(punit);
413   }
414 
415   if (gui_options.unit_selection_clears_orders) {
416     clear_unit_orders(punit);
417   }
418 }
419 
420 /**************************************************************************
421   Remove focus from unit.
422 **************************************************************************/
current_focus_remove(struct unit * punit)423 static void current_focus_remove(struct unit *punit)
424 {
425   /* Close the action selection dialog if the actor unit lose focus. */
426   if (action_selection_actor_unit() == punit->id) {
427     action_selection_close();
428   }
429 
430   unit_list_remove(current_focus, punit);
431   refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
432 }
433 
434 /**************************************************************************
435   Clear all orders for the given unit.
436 **************************************************************************/
clear_unit_orders(struct unit * punit)437 void clear_unit_orders(struct unit *punit)
438 {
439   if (!punit) {
440     return;
441   }
442 
443   if (punit->activity != ACTIVITY_IDLE
444       || punit->ai_controlled)  {
445     punit->ai_controlled = FALSE;
446     refresh_unit_city_dialogs(punit);
447     request_new_unit_activity(punit, ACTIVITY_IDLE);
448   } else if (unit_has_orders(punit)) {
449     /* Clear the focus unit's orders. */
450     request_orders_cleared(punit);
451   }
452 }
453 
454 /**************************************************************************
455   Sets the focus unit directly.  The unit given will be given the
456   focus; if NULL the focus will be cleared.
457 
458   This function is called for several reasons.  Sometimes a fast-focus
459   happens immediately as a result of a client action.  Other times it
460   happens because of a server-sent packet that wakes up a unit.
461 **************************************************************************/
unit_focus_set(struct unit * punit)462 void unit_focus_set(struct unit *punit)
463 {
464   bool focus_changed = FALSE;
465 
466   if (NULL != punit
467       && NULL != client.conn.playing
468       && unit_owner(punit) != client.conn.playing) {
469     /* Callers should make sure this never happens. */
470     return;
471   }
472 
473   /* FIXME: this won't work quite right; for instance activating a
474    * battlegroup twice in a row will store the focus erronously.  The only
475    * solution would be a set_units_focus() */
476   if (!(get_num_units_in_focus() == 1
477 	&& punit == head_of_units_in_focus())) {
478     store_previous_focus();
479     focus_changed = TRUE;
480   }
481 
482   /* Close the action selection dialog if the actor unit lose focus. */
483   unit_list_iterate(current_focus, punit_old) {
484     if (action_selection_actor_unit() == punit_old->id) {
485       action_selection_close();
486     }
487   } unit_list_iterate_end;
488 
489   /* Redraw the old focus unit (to fix blinking or remove the selection
490    * circle). */
491   unit_list_iterate(current_focus, punit_old) {
492     refresh_unit_mapcanvas(punit_old, unit_tile(punit_old), TRUE, FALSE);
493   } unit_list_iterate_end;
494   unit_list_clear(current_focus);
495 
496   if (!can_client_change_view()) {
497     /* This function can be called to set the focus to NULL when
498      * disconnecting.  In this case we don't want any other actions! */
499     fc_assert(punit == NULL);
500     return;
501   }
502 
503   if (NULL != punit) {
504     current_focus_append(punit);
505     auto_center_on_focus_unit();
506   }
507 
508   if (focus_changed) {
509     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
510     focus_units_changed();
511   }
512 }
513 
514 /**************************************************************************
515   Adds this unit to the list of units in focus.
516 **************************************************************************/
unit_focus_add(struct unit * punit)517 void unit_focus_add(struct unit *punit)
518 {
519   if (NULL != punit
520       && NULL != client.conn.playing
521       && unit_owner(punit) != client.conn.playing) {
522     /* Callers should make sure this never happens. */
523     return;
524   }
525 
526   if (NULL == punit || !can_client_change_view()) {
527     return;
528   }
529 
530   if (unit_is_in_focus(punit)) {
531     return;
532   }
533 
534   if (hover_state != HOVER_NONE) {
535     /* Can't continue with current goto if set of focus units
536      * change. Cancel it. */
537     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
538   }
539 
540   current_focus_append(punit);
541   focus_units_changed();
542 }
543 
544 /**************************************************************************
545   Removes this unit from the list of units in focus.
546 **************************************************************************/
unit_focus_remove(struct unit * punit)547 void unit_focus_remove(struct unit *punit)
548 {
549   if (NULL != punit
550       && NULL != client.conn.playing
551       && unit_owner(punit) != client.conn.playing) {
552     /* Callers should make sure this never happens. */
553     return;
554   }
555 
556   if (NULL == punit || !can_client_change_view()) {
557     return;
558   }
559 
560   if (!unit_is_in_focus(punit)) {
561     return;
562   }
563 
564   if (hover_state != HOVER_NONE) {
565     /* Can't continue with current goto if set of focus units
566      * change. Cancel it. */
567     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
568   }
569 
570   current_focus_remove(punit);
571   if (get_num_units_in_focus() > 0) {
572     focus_units_changed();
573   } else {
574     unit_focus_advance();
575   }
576 }
577 
578 /**************************************************************************
579  The only difference is that here we draw the "cross".
580 **************************************************************************/
unit_focus_set_and_select(struct unit * punit)581 void unit_focus_set_and_select(struct unit *punit)
582 {
583   unit_focus_set(punit);
584   if (punit) {
585     put_cross_overlay_tile(unit_tile(punit));
586   }
587 }
588 
589 /**************************************************************************
590  Find the nearest available unit for focus, excluding any current unit
591  in focus unless "accept_current" is TRUE.  If the current focus unit
592  is the only possible unit, or if there is no possible unit, returns NULL.
593 **************************************************************************/
find_best_focus_candidate(bool accept_current)594 static struct unit *find_best_focus_candidate(bool accept_current)
595 {
596   struct tile *ptile = get_center_tile_mapcanvas();
597 
598   if (!get_focus_unit_on_tile(ptile)) {
599     struct unit *pfirst = head_of_units_in_focus();
600 
601     if (pfirst) {
602       ptile = unit_tile(pfirst);
603     }
604   }
605 
606   iterate_outward(ptile, FC_INFINITY, ptile2) {
607     unit_list_iterate(ptile2->units, punit) {
608       if ((!unit_is_in_focus(punit) || accept_current)
609 	  && unit_owner(punit) == client.conn.playing
610 	  && punit->client.focus_status == FOCUS_AVAIL
611 	  && punit->activity == ACTIVITY_IDLE
612 	  && !unit_has_orders(punit)
613 	  && (punit->moves_left > 0 || unit_type_get(punit)->move_rate == 0)
614 	  && !punit->done_moving
615 	  && !punit->ai_controlled) {
616 	return punit;
617       }
618     } unit_list_iterate_end;
619   } iterate_outward_end;
620 
621   return NULL;
622 }
623 
624 /**************************************************************************
625  This function may be called from packhand.c, via unit_focus_update(),
626  as a result of packets indicating change in activity for a unit. Also
627  called when user press the "Wait" command.
628 
629  FIXME: Add feature to focus only units of a certain category.
630 **************************************************************************/
unit_focus_advance(void)631 void unit_focus_advance(void)
632 {
633   struct unit *candidate = NULL;
634   const int num_units_in_old_focus = get_num_units_in_focus();
635 
636   if (NULL == client.conn.playing
637       || !is_player_phase(client.conn.playing, game.info.phase)
638       || !can_client_change_view()) {
639     unit_focus_set(NULL);
640     return;
641   }
642 
643   set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
644 
645   unit_list_iterate(get_units_in_focus(), punit) {
646     /*
647      * Is the unit which just lost focus a non-AI unit? If yes this
648      * enables the auto end turn.
649      */
650     if (!punit->ai_controlled) {
651       non_ai_unit_focus = TRUE;
652       break;
653     }
654   } unit_list_iterate_end;
655 
656   if (unit_list_size(urgent_focus_queue) > 0) {
657     /* Try top of the urgent list. */
658     struct tile *focus_tile = (get_num_units_in_focus() > 0
659                                ? unit_tile(head_of_units_in_focus())
660                                : NULL);
661 
662     unit_list_both_iterate(urgent_focus_queue, plink, punit) {
663       if ((ACTIVITY_IDLE != punit->activity
664            || unit_has_orders(punit))
665           /* This isn't an action decision needed because of an
666            * ORDER_ACTION_MOVE located in the middle of an order. */
667           && !should_ask_server_for_actions(punit)) {
668         /* We have assigned new orders to this unit since, remove it. */
669         unit_list_erase(urgent_focus_queue, plink);
670       } else if (NULL == focus_tile
671                  || focus_tile == unit_tile(punit)) {
672         /* Use the first one found */
673         candidate = punit;
674         break;
675       } else if (NULL == candidate) {
676         candidate = punit;
677       }
678     } unit_list_both_iterate_end;
679 
680     if (NULL != candidate) {
681       unit_list_remove(urgent_focus_queue, candidate);
682 
683       /* Autocenter on Wakeup, regardless of the local option
684        * "auto_center_on_unit". */
685       if (!tile_visible_and_not_on_border_mapcanvas(unit_tile(candidate))) {
686         center_tile_mapcanvas(unit_tile(candidate));
687       }
688     }
689   }
690 
691   if (NULL == candidate) {
692     candidate = find_best_focus_candidate(FALSE);
693 
694     if (!candidate) {
695       /* Try for "waiting" units. */
696       unit_list_iterate(client.conn.playing->units, punit) {
697         if(punit->client.focus_status == FOCUS_WAIT) {
698           punit->client.focus_status = FOCUS_AVAIL;
699         }
700       } unit_list_iterate_end;
701       candidate = find_best_focus_candidate(FALSE);
702 
703       if (!candidate) {
704         /* Accept current focus unit as last resort. */
705         candidate = find_best_focus_candidate(TRUE);
706       }
707     }
708   }
709 
710   unit_focus_set(candidate);
711 
712   /*
713    * Handle auto-turn-done mode: If a unit was in focus (did move),
714    * but now none are (no more to move) and there was at least one
715    * non-AI unit this turn which was focused, then fake a Turn Done
716    * keypress.
717    */
718   if (gui_options.auto_turn_done
719       && num_units_in_old_focus > 0
720       && get_num_units_in_focus() == 0
721       && non_ai_unit_focus) {
722     key_end_turn();
723   }
724 }
725 
726 /**************************************************************************
727  If there is no unit currently in focus, or if the current unit in
728  focus should not be in focus, then get a new focus unit.
729  We let GOTO-ing units stay in focus, so that if they have moves left
730  at the end of the goto, then they are still in focus.
731 **************************************************************************/
unit_focus_update(void)732 void unit_focus_update(void)
733 {
734   if (NULL == client.conn.playing || !can_client_change_view()) {
735     return;
736   }
737 
738   if (!can_ask_server_for_actions()) {
739     fc_assert(get_num_units_in_focus() > 0);
740 
741     /* An actor unit is asking the player what to do. Don't steal his
742      * focus. */
743     return;
744   }
745 
746   /* iterate zero times for no units in focus,
747    * otherwise quit for any of the conditions. */
748   unit_list_iterate(get_units_in_focus(), punit) {
749     if ((punit->activity == ACTIVITY_IDLE
750 	 || punit->activity == ACTIVITY_GOTO
751 	 || unit_has_orders(punit))
752 	&& punit->moves_left > 0
753 	&& !punit->done_moving
754 	&& !punit->ai_controlled) {
755       return;
756     }
757   } unit_list_iterate_end;
758 
759   unit_focus_advance();
760 }
761 
762 /**************************************************************************
763 Return a pointer to a visible unit, if there is one.
764 **************************************************************************/
find_visible_unit(struct tile * ptile)765 struct unit *find_visible_unit(struct tile *ptile)
766 {
767   struct unit *panyowned = NULL, *panyother = NULL, *ptptother = NULL;
768 
769   /* If no units here, return nothing. */
770   if (unit_list_size(ptile->units)==0) {
771     return NULL;
772   }
773 
774   /* If a unit is attacking we should show that on top */
775   if (punit_attacking && same_pos(unit_tile(punit_attacking), ptile)) {
776     unit_list_iterate(ptile->units, punit)
777       if(punit == punit_attacking) return punit;
778     unit_list_iterate_end;
779   }
780 
781   /* If a unit is defending we should show that on top */
782   if (punit_defending && same_pos(unit_tile(punit_defending), ptile)) {
783     unit_list_iterate(ptile->units, punit)
784       if(punit == punit_defending) return punit;
785     unit_list_iterate_end;
786   }
787 
788   /* If the unit in focus is at this tile, show that on top */
789   unit_list_iterate(get_units_in_focus(), punit) {
790     if (punit != punit_moving && unit_tile(punit) == ptile) {
791       return punit;
792     }
793   } unit_list_iterate_end;
794 
795   /* If a city is here, return nothing (unit hidden by city). */
796   if (tile_city(ptile)) {
797     return NULL;
798   }
799 
800   /* Iterate through the units to find the best one we prioritize this way:
801        1: owned transporter.
802        2: any owned unit
803        3: any transporter
804        4: any unit
805      (always return first in stack). */
806   unit_list_iterate(ptile->units, punit)
807     if (unit_owner(punit) == client.conn.playing) {
808       if (!unit_transported(punit)) {
809         if (get_transporter_capacity(punit) > 0) {
810 	  return punit;
811         } else if (!panyowned) {
812 	  panyowned = punit;
813         }
814       }
815     } else if (!ptptother && !unit_transported(punit)) {
816       if (get_transporter_capacity(punit) > 0) {
817 	ptptother = punit;
818       } else if (!panyother) {
819 	panyother = punit;
820       }
821     }
822   unit_list_iterate_end;
823 
824   return (panyowned ? panyowned : (ptptother ? ptptother : panyother));
825 }
826 
827 /**************************************************************************
828   Blink the active unit (if necessary).  Return the time until the next
829   blink (in seconds).
830 **************************************************************************/
blink_active_unit(void)831 double blink_active_unit(void)
832 {
833   static struct timer *blink_timer = NULL;
834   const double blink_time = get_focus_unit_toggle_timeout(tileset);
835 
836   if (get_num_units_in_focus() > 0) {
837     if (!blink_timer || timer_read_seconds(blink_timer) > blink_time) {
838       toggle_focus_unit_state(tileset);
839 
840       /* If we lag, we don't try to catch up.  Instead we just start a
841        * new blink_time on every update. */
842       blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE);
843       timer_start(blink_timer);
844 
845       unit_list_iterate(get_units_in_focus(), punit) {
846 	/* We flush to screen directly here.  This is most likely faster
847 	 * since these drawing operations are all small but may be spread
848 	 * out widely. */
849 	refresh_unit_mapcanvas(punit, unit_tile(punit), FALSE, TRUE);
850       } unit_list_iterate_end;
851     }
852 
853     return blink_time - timer_read_seconds(blink_timer);
854   }
855 
856   return blink_time;
857 }
858 
859 /****************************************************************************
860   Blink the turn done button (if necessary).  Return the time until the next
861   blink (in seconds).
862 ****************************************************************************/
blink_turn_done_button(void)863 double blink_turn_done_button(void)
864 {
865   static struct timer *blink_timer = NULL;
866   const double blink_time = 0.5; /* half-second blink interval */
867 
868   if (NULL != client.conn.playing
869       && client.conn.playing->is_alive
870       && !client.conn.playing->phase_done
871       && is_player_phase(client.conn.playing, game.info.phase)) {
872     if (!blink_timer || timer_read_seconds(blink_timer) > blink_time) {
873       int is_waiting = 0, is_moving = 0;
874       bool blocking_mode;
875       struct option *opt;
876 
877       opt = optset_option_by_name(server_optset, "turnblock");
878       if (opt != NULL) {
879         blocking_mode = option_bool_get(opt);
880       } else {
881         blocking_mode = FALSE;
882       }
883 
884       players_iterate_alive(pplayer) {
885         if ((pplayer->is_connected || blocking_mode)
886             && is_player_phase(pplayer, game.info.phase)) {
887           if (pplayer->phase_done) {
888             is_waiting++;
889           } else {
890             is_moving++;
891           }
892         }
893       } players_iterate_alive_end;
894 
895       if (is_moving == 1 && is_waiting > 0) {
896 	update_turn_done_button(FALSE);	/* stress the slow player! */
897       }
898       blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE);
899       timer_start(blink_timer);
900     }
901     return blink_time - timer_read_seconds(blink_timer);
902   }
903 
904   return blink_time;
905 }
906 
907 /**************************************************************************
908   Update unit icons (and arrow) in the information display, for specified
909   punit as the active unit and other units on the same square.  In practice
910   punit is almost always (or maybe strictly always?) the focus unit.
911 
912   Static vars store some info on current (ie previous) state, to avoid
913   unnecessary redraws; initialise to "flag" values to always redraw first
914   time.  In principle we _might_ need more info (eg ai.control, connecting),
915   but in practice this is enough?
916 
917   Used to store unit_ids for below units, to use for callbacks (now done
918   inside gui-dep set_unit_icon()), but even with ids here they would not
919   be enough information to know whether to redraw -- instead redraw every
920   time.  (Could store enough info to know, but is it worth it?)
921 **************************************************************************/
update_unit_pix_label(struct unit_list * punitlist)922 void update_unit_pix_label(struct unit_list *punitlist)
923 {
924   int i;
925 
926   /* Check for any change in the unit's state.  This assumes that a unit's
927    * orders cannot be changed directly but must be removed and then reset. */
928   if (punitlist && unit_list_size(punitlist) > 0
929       && C_S_OVER != client_state()) {
930     /* There used to be a complicated and bug-prone check here to see if
931      * the unit had actually changed.  This was misguided since the stacked
932      * units (below) are redrawn in any case.  Unless we write a general
933      * system for unit updates here we might as well just redraw it every
934      * time. */
935     struct unit *punit = unit_list_get(punitlist, 0);
936 
937     set_unit_icon(-1, punit);
938 
939     i = 0;			/* index into unit_below_canvas */
940     unit_list_iterate(unit_tile(punit)->units, aunit) {
941       if (aunit != punit) {
942 	if (i < num_units_below) {
943 	  set_unit_icon(i, aunit);
944 	}
945 	i++;
946       }
947     }
948     unit_list_iterate_end;
949 
950     if (i > num_units_below) {
951       set_unit_icons_more_arrow(TRUE);
952     } else {
953       set_unit_icons_more_arrow(FALSE);
954       for(; i < num_units_below; i++) {
955 	set_unit_icon(i, NULL);
956       }
957     }
958   } else {
959     for(i=-1; i<num_units_below; i++) {
960       set_unit_icon(i, NULL);
961     }
962     set_unit_icons_more_arrow(FALSE);
963   }
964 }
965 
966 /**************************************************************************
967   Adjusts way combatants are displayed suitable for combat.
968 **************************************************************************/
set_units_in_combat(struct unit * pattacker,struct unit * pdefender)969 void set_units_in_combat(struct unit *pattacker, struct unit *pdefender)
970 {
971   punit_attacking = pattacker;
972   punit_defending = pdefender;
973 
974   if (unit_is_in_focus(punit_attacking)
975       || unit_is_in_focus(punit_defending)) {
976     /* If one of the units is the focus unit, make sure hidden-focus is
977      * disabled.  We don't just do this as a check later because then
978      * with a blinking unit it would just disappear again right after the
979      * battle. */
980     focus_unit_in_combat(tileset);
981   }
982 }
983 
984 /**************************************************************************
985   The action selection process is no longer in progres for the specified
986   unit. It is safe to let another unit enter it.
987 **************************************************************************/
action_selection_no_longer_in_progress(const int old_actor_id)988 void action_selection_no_longer_in_progress(const int old_actor_id)
989 {
990   /* IDENTITY_NUMBER_ZERO is accepted for cases where the unit is gone
991    * without a trace. */
992   fc_assert_msg(old_actor_id == action_selection_in_progress_for
993                 || old_actor_id == IDENTITY_NUMBER_ZERO,
994                 "Decision taken for %d but selection is for %d.",
995                 old_actor_id, action_selection_in_progress_for);
996 
997   /* Stop objecting to allowing the next unit to ask. */
998   action_selection_in_progress_for = IDENTITY_NUMBER_ZERO;
999 
1000   /* Clean up any client specific assumptions. */
1001   action_selection_no_longer_in_progress_gui_specific(old_actor_id);
1002 }
1003 
1004 /**************************************************************************
1005   Have the server record that a decision no longer is wanted for the
1006   specified unit.
1007 **************************************************************************/
action_decision_clear_want(const int old_actor_id)1008 void action_decision_clear_want(const int old_actor_id)
1009 {
1010   struct unit *old;
1011 
1012   if ((old = game_unit_by_number(old_actor_id))) {
1013     /* Have the server record that a decision no longer is wanted. */
1014     request_do_action(ACTION_COUNT, old_actor_id, IDENTITY_NUMBER_ZERO,
1015                       ACTSIG_UNQUEUE);
1016   }
1017 }
1018 
1019 /**************************************************************************
1020   Move on to the next unit in focus that needs an action decision.
1021 **************************************************************************/
action_selection_next_in_focus(const int old_actor_id)1022 void action_selection_next_in_focus(const int old_actor_id)
1023 {
1024   struct unit *old;
1025 
1026   old = game_unit_by_number(old_actor_id);
1027 
1028   /* Go to the next unit in focus that needs a decision. */
1029   unit_list_iterate(get_units_in_focus(), funit) {
1030     if (old != funit && should_ask_server_for_actions(funit)) {
1031       ask_server_for_actions(funit);
1032       return;
1033     }
1034   } unit_list_iterate_end;
1035 }
1036 
1037 /**************************************************************************
1038   Request that the player makes a decision for the specified unit.
1039 **************************************************************************/
action_decision_request(struct unit * actor_unit)1040 void action_decision_request(struct unit *actor_unit)
1041 {
1042   fc_assert_ret(actor_unit);
1043   fc_assert_ret(actor_unit->action_decision_tile);
1044 
1045   if (!unit_is_in_focus(actor_unit)) {
1046     /* Getting feed back may be urgent. A unit standing next to an enemy
1047      * could be killed while waiting. */
1048     unit_focus_urgent(actor_unit);
1049   } else if (can_client_issue_orders()
1050              && can_ask_server_for_actions()) {
1051     /* No need to wait. The actor unit is in focus. No other actor unit
1052      * is currently asking about action selection. */
1053     ask_server_for_actions(actor_unit);
1054   }
1055 }
1056 
1057 /**************************************************************************
1058   Do a goto with an order at the end (or ORDER_LAST).
1059 **************************************************************************/
request_unit_goto(enum unit_orders last_order)1060 void request_unit_goto(enum unit_orders last_order)
1061 {
1062   struct unit_list *punits = get_units_in_focus();
1063 
1064   if (unit_list_size(punits) == 0) {
1065     return;
1066   }
1067 
1068   if (hover_state != HOVER_GOTO) {
1069     set_hover_state(punits, HOVER_GOTO, ACTIVITY_LAST, NULL,
1070                     last_order);
1071     enter_goto_state(punits);
1072     create_line_at_mouse_pos();
1073     update_unit_info_label(punits);
1074     control_mouse_cursor(NULL);
1075   } else {
1076     fc_assert_ret(goto_is_active());
1077     goto_add_waypoint();
1078   }
1079 }
1080 
1081 /****************************************************************************
1082   Return TRUE if at least one of the units can do an attack at the tile.
1083 ****************************************************************************/
can_units_attack_at(struct unit_list * punits,const struct tile * ptile)1084 static bool can_units_attack_at(struct unit_list *punits,
1085 				const struct tile *ptile)
1086 {
1087   unit_list_iterate(punits, punit) {
1088     if (is_attack_unit(punit)
1089         && can_unit_attack_tile(punit, ptile)) {
1090       return TRUE;
1091     }
1092   } unit_list_iterate_end;
1093 
1094   return FALSE;
1095 }
1096 
1097 /**************************************************************************
1098   Determines which mouse cursor should be used, according to hover_state,
1099   and the information gathered from the tile which is under the mouse
1100   cursor (ptile).
1101 **************************************************************************/
control_mouse_cursor(struct tile * ptile)1102 void control_mouse_cursor(struct tile *ptile)
1103 {
1104   struct unit *punit = NULL;
1105   struct city *pcity = NULL;
1106   struct unit_list *active_units = get_units_in_focus();
1107   enum cursor_type mouse_cursor_type = CURSOR_DEFAULT;
1108 
1109   if (!gui_options.enable_cursor_changes) {
1110     return;
1111   }
1112 
1113   if (C_S_RUNNING != client_state()) {
1114     update_mouse_cursor(CURSOR_DEFAULT);
1115     return;
1116   }
1117 
1118   if (is_server_busy()) {
1119     /* Server will not accept any commands. */
1120     update_mouse_cursor(CURSOR_WAIT);
1121     return;
1122   }
1123 
1124   if (!ptile) {
1125     if (hover_tile) {
1126       /* hover_tile is the tile that was previously under the mouse cursor. */
1127       ptile = hover_tile;
1128     } else {
1129       update_mouse_cursor(CURSOR_DEFAULT);
1130       return;
1131     }
1132   } else {
1133     hover_tile = ptile;
1134   }
1135 
1136   punit = find_visible_unit(ptile);
1137   pcity = ptile ? tile_city(ptile) : NULL;
1138 
1139   switch (hover_state) {
1140   case HOVER_NONE:
1141     if (NULL != punit
1142         && unit_owner(punit) == client_player()) {
1143       /* Set mouse cursor to select a unit.  */
1144       mouse_cursor_type = CURSOR_SELECT;
1145     } else if (NULL != pcity
1146 	       && can_player_see_city_internals(client.conn.playing, pcity)) {
1147       /* Set mouse cursor to select a city. */
1148       mouse_cursor_type = CURSOR_SELECT;
1149     } else {
1150       /* Set default mouse cursor, because nothing selectable found. */
1151     }
1152     break;
1153   case HOVER_GOTO:
1154     /* Determine if the goto is valid, invalid or will attack. */
1155     if (is_valid_goto_destination(ptile)) {
1156       if (can_units_attack_at(active_units, ptile)) {
1157         /* Goto results in military attack. */
1158 	mouse_cursor_type = CURSOR_ATTACK;
1159       } else if (is_enemy_city_tile(ptile, client.conn.playing)) {
1160         /* Goto results in attack of enemy city. */
1161 	mouse_cursor_type = CURSOR_ATTACK;
1162       } else {
1163 	mouse_cursor_type = CURSOR_GOTO;
1164       }
1165     } else {
1166       mouse_cursor_type = CURSOR_INVALID;
1167     }
1168     break;
1169   case HOVER_PATROL:
1170     if (is_valid_goto_destination(ptile)) {
1171       mouse_cursor_type = CURSOR_PATROL;
1172     } else {
1173       mouse_cursor_type = CURSOR_INVALID;
1174     }
1175     break;
1176   case HOVER_CONNECT:
1177     if (is_valid_goto_destination(ptile)) {
1178       mouse_cursor_type = CURSOR_GOTO;
1179     } else {
1180       mouse_cursor_type = CURSOR_INVALID;
1181     }
1182     break;
1183   case HOVER_NUKE:
1184     if (is_valid_goto_destination(ptile)) {
1185       mouse_cursor_type = CURSOR_NUKE;
1186     } else {
1187       mouse_cursor_type = CURSOR_INVALID;
1188     }
1189     break;
1190   case HOVER_PARADROP:
1191     /* FIXME: check for invalid tiles. */
1192     mouse_cursor_type = CURSOR_PARADROP;
1193     break;
1194   case HOVER_ACT_SEL_TGT:
1195     /* Select a tile to target / find targets on. */
1196     mouse_cursor_type = CURSOR_SELECT;
1197     break;
1198   };
1199 
1200   update_mouse_cursor(mouse_cursor_type);
1201 }
1202 
1203 /**************************************************************************
1204   Return TRUE if there are any units doing the activity on the tile.
1205 **************************************************************************/
is_activity_on_tile(struct tile * ptile,enum unit_activity activity)1206 static bool is_activity_on_tile(struct tile *ptile,
1207 				enum unit_activity activity)
1208 {
1209   unit_list_iterate(ptile->units, punit) {
1210     if (punit->activity == activity) {
1211       return TRUE;
1212     }
1213   } unit_list_iterate_end;
1214 
1215   return FALSE;
1216 }
1217 
1218 /**************************************************************************
1219   Fill orders to build recursive roads. This modifies ptile, so virtual
1220   copy of the real tile should be passed.
1221 **************************************************************************/
check_recursive_road_connect(struct tile * ptile,const struct extra_type * pextra,const struct unit * punit,const struct player * pplayer,int rec)1222 int check_recursive_road_connect(struct tile *ptile, const struct extra_type *pextra,
1223                                  const struct unit *punit, const struct player *pplayer, int rec)
1224 {
1225   int activity_mc = 0;
1226   struct terrain *pterrain = tile_terrain(ptile);
1227 
1228   if (rec > MAX_EXTRA_TYPES) {
1229     return -1;
1230   }
1231 
1232   if (!is_extra_caused_by(pextra, EC_ROAD)) {
1233     return -1;
1234   }
1235 
1236   extra_deps_iterate(&(pextra->reqs), pdep) {
1237     if (!tile_has_extra(ptile, pdep)) {
1238       int single_mc;
1239 
1240       single_mc = check_recursive_road_connect(ptile, pdep, punit, pplayer, rec + 1);
1241 
1242       if (single_mc < 0) {
1243         return -1;
1244       }
1245 
1246       activity_mc += single_mc;
1247     }
1248   } extra_deps_iterate_end;
1249 
1250   /* Can build road after that? */
1251   if (punit != NULL) {
1252     if (!can_build_road(extra_road_get(pextra), punit, ptile)) {
1253       return -1;
1254     }
1255   } else if (pplayer != NULL) {
1256     if (!player_can_build_road(extra_road_get(pextra), pplayer, ptile)) {
1257       return -1;
1258     }
1259   }
1260 
1261   tile_add_extra(ptile, pextra);
1262 
1263   activity_mc += terrain_extra_build_time(pterrain, ACTIVITY_GEN_ROAD, pextra);
1264 
1265   return activity_mc;
1266 }
1267 
1268 /**************************************************************************
1269   Return whether the unit can connect with given activity (or with
1270   any activity if activity arg is set to ACTIVITY_IDLE)
1271 
1272   This function is client-specific.
1273 **************************************************************************/
can_unit_do_connect(struct unit * punit,enum unit_activity activity,struct extra_type * tgt)1274 bool can_unit_do_connect(struct unit *punit,
1275                          enum unit_activity activity,
1276                          struct extra_type *tgt)
1277 {
1278   struct tile *ptile = unit_tile(punit);
1279   struct terrain *pterrain = tile_terrain(ptile);
1280   struct road_type *proad = NULL;
1281 
1282   /* HACK: This code duplicates that in
1283    * can_unit_do_activity_targeted_at(). The general logic here is that
1284    * the connect is allowed if both:
1285    * (1) the unit can do that activity type, in general
1286    * (2) either
1287    *     (a) the activity has already been completed at this tile
1288    *     (b) it can be done by the unit at this tile. */
1289   switch (activity) {
1290   case ACTIVITY_GEN_ROAD:
1291     {
1292       struct tile *vtile;
1293       int build_time;
1294 
1295       fc_assert(is_extra_caused_by(tgt, EC_ROAD));
1296 
1297       proad = extra_road_get(tgt);
1298 
1299       if (tile_has_road(ptile, proad)) {
1300         /* This tile has road, can unit build road to other tiles too? */
1301         return are_reqs_active(NULL, NULL, NULL, NULL, NULL,
1302                                punit, unit_type_get(punit), NULL, NULL,
1303                                &tgt->reqs, RPT_POSSIBLE);
1304       }
1305 
1306       /* To start connect, unit must be able to build road to this
1307        * particular tile. */
1308       vtile = tile_virtual_new(ptile);
1309       build_time = check_recursive_road_connect(vtile, tgt, punit, NULL, 0);
1310       tile_virtual_destroy(vtile);
1311 
1312       return build_time >= 0;
1313     }
1314 
1315   case ACTIVITY_IRRIGATE:
1316     /* Special case for irrigation: only irrigate to make S_IRRIGATION,
1317      * never to transform tiles. */
1318     if (!unit_has_type_flag(punit, UTYF_SETTLERS)) {
1319       return FALSE;
1320     }
1321     if (tile_has_extra(ptile, tgt)) {
1322       return are_reqs_active(NULL, NULL, NULL, NULL, NULL,
1323                              punit, unit_type_get(punit), NULL, NULL,
1324                              &tgt->reqs, RPT_POSSIBLE);
1325     }
1326 
1327     return pterrain == pterrain->irrigation_result
1328       && can_be_irrigated(ptile, punit)
1329       && can_build_extra(tgt, punit, ptile)
1330       && !is_activity_on_tile(ptile,
1331                               ACTIVITY_MINE);
1332   default:
1333     break;
1334   }
1335 
1336   return FALSE;
1337 }
1338 
1339 /**************************************************************************
1340   Prompt player for entering destination point for unit connect
1341   (e.g. connecting with roads)
1342 **************************************************************************/
request_unit_connect(enum unit_activity activity,struct extra_type * tgt)1343 void request_unit_connect(enum unit_activity activity,
1344                           struct extra_type *tgt)
1345 {
1346   struct unit_list *punits = get_units_in_focus();
1347 
1348   if (!can_units_do_connect(punits, activity, tgt)) {
1349     return;
1350   }
1351 
1352   if (hover_state != HOVER_CONNECT || connect_activity != activity
1353       || (connect_tgt != tgt
1354           && (activity == ACTIVITY_GEN_ROAD
1355               || activity == ACTIVITY_IRRIGATE))) {
1356     set_hover_state(punits, HOVER_CONNECT, activity, tgt, ORDER_LAST);
1357     enter_goto_state(punits);
1358     create_line_at_mouse_pos();
1359     update_unit_info_label(punits);
1360     control_mouse_cursor(NULL);
1361   } else {
1362     fc_assert_ret(goto_is_active());
1363     goto_add_waypoint();
1364   }
1365 }
1366 
1367 /**************************************************************************
1368   Returns one of the unit of the transporter which can have focus next.
1369 **************************************************************************/
request_unit_unload_all(struct unit * punit)1370 struct unit *request_unit_unload_all(struct unit *punit)
1371 {
1372   struct tile *ptile = unit_tile(punit);
1373   struct unit *plast = NULL;
1374 
1375   if (get_transporter_capacity(punit) == 0) {
1376     create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1377                  _("Only transporter units can be unloaded."));
1378     return NULL;
1379   }
1380 
1381   unit_list_iterate(ptile->units, pcargo) {
1382     if (unit_transport_get(pcargo) == punit) {
1383       request_unit_unload(pcargo);
1384 
1385       if (pcargo->activity == ACTIVITY_SENTRY) {
1386 	request_new_unit_activity(pcargo, ACTIVITY_IDLE);
1387       }
1388 
1389       if (unit_owner(pcargo) == unit_owner(punit)) {
1390 	plast = pcargo;
1391       }
1392     }
1393   } unit_list_iterate_end;
1394 
1395   return plast;
1396 }
1397 
1398 /**************************************************************************
1399   Send unit airlift request to server.
1400 **************************************************************************/
request_unit_airlift(struct unit * punit,struct city * pcity)1401 void request_unit_airlift(struct unit *punit, struct city *pcity)
1402 {
1403   dsend_packet_unit_airlift(&client.conn, punit->id, pcity->id);
1404 }
1405 
1406 /**************************************************************************
1407   Return-and-recover for a particular unit.  This sets the unit to GOTO
1408   the nearest city.
1409 **************************************************************************/
request_unit_return(struct unit * punit)1410 void request_unit_return(struct unit *punit)
1411 {
1412   struct pf_path *path;
1413 
1414   if ((path = path_to_nearest_allied_city(punit))) {
1415     int turns = pf_path_last_position(path)->turn;
1416     int max_hp = unit_type_get(punit)->hp;
1417 
1418     if (punit->hp + turns *
1419         (get_unit_bonus(punit, EFT_UNIT_RECOVER)
1420          - (max_hp * unit_class_get(punit)->hp_loss_pct / 100))
1421 	< max_hp) {
1422       struct unit_order order;
1423 
1424       order.order = ORDER_ACTIVITY;
1425       order.dir = DIR8_ORIGIN;
1426       order.activity = ACTIVITY_SENTRY;
1427       order.target = EXTRA_NONE;
1428       send_goto_path(punit, path, &order);
1429     } else {
1430       send_goto_path(punit, path, NULL);
1431     }
1432     pf_path_destroy(path);
1433   }
1434 }
1435 
1436 /**************************************************************************
1437   Wakes all owned sentried units on tile.
1438 **************************************************************************/
wakeup_sentried_units(struct tile * ptile)1439 void wakeup_sentried_units(struct tile *ptile)
1440 {
1441   if (!can_client_issue_orders()) {
1442     return;
1443   }
1444   unit_list_iterate(ptile->units, punit) {
1445     if (punit->activity == ACTIVITY_SENTRY
1446 	&& unit_owner(punit) == client.conn.playing) {
1447       request_new_unit_activity(punit, ACTIVITY_IDLE);
1448     }
1449   }
1450   unit_list_iterate_end;
1451 }
1452 
1453 /**************************************************************************
1454 (RP:) un-sentry all my own sentried units on punit's tile
1455 **************************************************************************/
request_unit_wakeup(struct unit * punit)1456 void request_unit_wakeup(struct unit *punit)
1457 {
1458   wakeup_sentried_units(unit_tile(punit));
1459 }
1460 
1461 /****************************************************************************
1462   Defines specific hash tables needed for request_unit_select().
1463 ****************************************************************************/
1464 #define SPECHASH_TAG unit_type
1465 #define SPECHASH_IKEY_TYPE struct unit_type *
1466 #define SPECHASH_IDATA_TYPE void *
1467 #include "spechash.h"
1468 
1469 #define SPECHASH_TAG continent
1470 #define SPECHASH_INT_KEY_TYPE
1471 #define SPECHASH_IDATA_TYPE void *
1472 #include "spechash.h"
1473 
1474 /****************************************************************************
1475   Select all units based on the given list of units and the selection modes.
1476 ****************************************************************************/
request_unit_select(struct unit_list * punits,enum unit_select_type_mode seltype,enum unit_select_location_mode selloc)1477 void request_unit_select(struct unit_list *punits,
1478                          enum unit_select_type_mode seltype,
1479                          enum unit_select_location_mode selloc)
1480 {
1481   const struct player *pplayer;
1482   const struct tile *ptile;
1483   struct unit *punit_first;
1484   struct tile_hash *tile_table;
1485   struct unit_type_hash *type_table;
1486   struct continent_hash *cont_table;
1487 
1488   if (!can_client_change_view() || !punits
1489       || unit_list_size(punits) < 1) {
1490     return;
1491   }
1492 
1493   punit_first = unit_list_get(punits, 0);
1494 
1495   if (seltype == SELTYPE_SINGLE) {
1496     unit_focus_set(punit_first);
1497     return;
1498   }
1499 
1500   pplayer = unit_owner(punit_first);
1501   tile_table = tile_hash_new();
1502   type_table = unit_type_hash_new();
1503   cont_table = continent_hash_new();
1504 
1505   unit_list_iterate(punits, punit) {
1506     if (seltype == SELTYPE_SAME) {
1507       unit_type_hash_insert(type_table, unit_type_get(punit), NULL);
1508     }
1509 
1510     ptile = unit_tile(punit);
1511     if (selloc == SELLOC_TILE) {
1512       tile_hash_insert(tile_table, ptile, NULL);
1513     } else if (selloc == SELLOC_CONT) {
1514       continent_hash_insert(cont_table, tile_continent(ptile), NULL);
1515     }
1516   } unit_list_iterate_end;
1517 
1518   if (selloc == SELLOC_TILE) {
1519     tile_hash_iterate(tile_table, hash_tile) {
1520       unit_list_iterate(hash_tile->units, punit) {
1521         if (unit_owner(punit) != pplayer) {
1522           continue;
1523         }
1524         if (seltype == SELTYPE_SAME
1525             && !unit_type_hash_lookup(type_table, unit_type_get(punit), NULL)) {
1526           continue;
1527         }
1528         unit_focus_add(punit);
1529       } unit_list_iterate_end;
1530     } tile_hash_iterate_end;
1531   } else {
1532     unit_list_iterate(pplayer->units, punit) {
1533       ptile = unit_tile(punit);
1534       if ((seltype == SELTYPE_SAME
1535            && !unit_type_hash_lookup(type_table, unit_type_get(punit), NULL))
1536           || (selloc == SELLOC_CONT
1537               && !continent_hash_lookup(cont_table, tile_continent(ptile),
1538                                         NULL))) {
1539         continue;
1540       }
1541 
1542       unit_focus_add(punit);
1543     } unit_list_iterate_end;
1544   }
1545 
1546   tile_hash_destroy(tile_table);
1547   unit_type_hash_destroy(type_table);
1548   continent_hash_destroy(cont_table);
1549 }
1550 
1551 /**************************************************************************
1552   Request an actor unit to do a specific action.
1553   - action    : The action to be requested.
1554   - actor_id  : The unit ID of the actor unit.
1555   - target_id : The ID of the target unit, city or tile.
1556   - value     : For ACTION_SPY_TARGETED_STEAL_TECH or
1557                 ACTION_SPY_TARGETED_SABOTAGE_CITY, the technology or
1558                 building to aim for.
1559 **************************************************************************/
request_do_action(enum gen_action action,int actor_id,int target_id,int value)1560 void request_do_action(enum gen_action action, int actor_id,
1561                        int target_id, int value)
1562 {
1563   dsend_packet_unit_do_action(&client.conn,
1564                               actor_id, target_id, value, action);
1565 }
1566 
1567 /**************************************************************************
1568   Request data for follow up questions about an action the unit can
1569   perform.
1570   - action : The action the follow up question is about.
1571   - actor_id : The unit ID of the acting unit.
1572   - target_id : The ID of the target unit or city.
1573 **************************************************************************/
request_action_details(enum gen_action action,int actor_id,int target_id)1574 void request_action_details(enum gen_action action, int actor_id,
1575                             int target_id)
1576 {
1577   dsend_packet_unit_action_query(&client.conn,
1578                                  actor_id, target_id, action);
1579 }
1580 
1581 /**************************************************************************
1582 Player pressed 'b' or otherwise instructed unit to build or add to city.
1583 If the unit can build a city, we popup the appropriate dialog.
1584 Otherwise, we just send a packet to the server.
1585 If this action is not appropriate, the server will respond
1586 with an appropriate message.  (This is to avoid duplicating
1587 all the server checks and messages here.)
1588 **************************************************************************/
request_unit_build_city(struct unit * punit)1589 void request_unit_build_city(struct unit *punit)
1590 {
1591   if (unit_can_build_city(punit)) {
1592     dsend_packet_city_name_suggestion_req(&client.conn, punit->id);
1593     /* the reply will trigger a dialog to name the new city */
1594   } else {
1595     char name[] = "";
1596     dsend_packet_unit_build_city(&client.conn, punit->id, name);
1597   }
1598 }
1599 
1600 /**************************************************************************
1601   Order a unit to move to a neighboring tile without performing an action.
1602 
1603   Does nothing it the destination tile isn't next to the tile where the
1604   unit currently is located.
1605 **************************************************************************/
request_unit_non_action_move(struct unit * punit,struct tile * dest_tile)1606 void request_unit_non_action_move(struct unit *punit,
1607                                   struct tile *dest_tile)
1608 {
1609   struct packet_unit_orders p;
1610   int dir;
1611 
1612   dir = get_direction_for_step(unit_tile(punit), dest_tile);
1613 
1614   if (dir == -1) {
1615     /* The unit isn't located next to the destination tile. */
1616     return;
1617   }
1618 
1619   memset(&p, 0, sizeof(p));
1620 
1621   p.repeat = FALSE;
1622   p.vigilant = FALSE;
1623 
1624   p.unit_id = punit->id;
1625   p.src_tile = tile_index(unit_tile(punit));
1626   p.dest_tile = tile_index(dest_tile);
1627 
1628   p.length = 1;
1629   p.orders[0] = ORDER_MOVE;
1630   p.dir[0] = dir;
1631   p.activity[0] = ACTIVITY_LAST;
1632   p.target[0] = EXTRA_NONE;
1633 
1634   send_packet_unit_orders(&client.conn, &p);
1635 }
1636 
1637 /**************************************************************************
1638   This function is called whenever the player pressed an arrow key.
1639 
1640   We do NOT take into account that punit might be a caravan or a diplomat
1641   trying to move into a city, or a diplomat going into a tile with a unit;
1642   the server will catch those cases and send the client a package to pop up
1643   a dialog. (the server code has to be there anyway as goto's are entirely
1644   in the server)
1645 **************************************************************************/
request_move_unit_direction(struct unit * punit,int dir)1646 void request_move_unit_direction(struct unit *punit, int dir)
1647 {
1648   struct packet_unit_orders p;
1649   struct tile *dest_tile;
1650 
1651   /* Catches attempts to move off map */
1652   dest_tile = mapstep(unit_tile(punit), dir);
1653   if (!dest_tile) {
1654     return;
1655   }
1656 
1657   if (!can_unit_exist_at_tile(punit, dest_tile)) {
1658     if (request_transport(punit, dest_tile)) {
1659       return;
1660     }
1661   }
1662 
1663   /* The goto system isn't used to send the order because that would
1664    * prevent direction movement from overriding it.
1665    * Example of a situation when overriding the goto system is useful:
1666    * The goto system creates a longer path to make a move legal. The player
1667    * wishes to order the illegal move so the server will explain why the
1668    * short move is illegal. */
1669 
1670   memset(&p, 0, sizeof(p));
1671 
1672   p.repeat = FALSE;
1673   p.vigilant = FALSE;
1674 
1675   p.unit_id = punit->id;
1676   p.src_tile = tile_index(unit_tile(punit));
1677   p.dest_tile = tile_index(dest_tile);
1678 
1679   p.length = 1;
1680   p.orders[0] = ORDER_ACTION_MOVE;
1681   p.dir[0] = dir;
1682   p.activity[0] = ACTIVITY_LAST;
1683   p.target[0] = EXTRA_NONE;
1684 
1685   send_packet_unit_orders(&client.conn, &p);
1686 }
1687 
1688 /**************************************************************************
1689   Send request for unit activity changing to server. If activity has
1690   target, use request_new_unit_activity_targeted() instead.
1691 **************************************************************************/
request_new_unit_activity(struct unit * punit,enum unit_activity act)1692 void request_new_unit_activity(struct unit *punit, enum unit_activity act)
1693 {
1694   request_new_unit_activity_targeted(punit, act, NULL);
1695 }
1696 
1697 /**************************************************************************
1698   Send request for unit activity changing to server. This is for
1699   activities that are targeted to certain special or base type.
1700 **************************************************************************/
request_new_unit_activity_targeted(struct unit * punit,enum unit_activity act,struct extra_type * tgt)1701 void request_new_unit_activity_targeted(struct unit *punit,
1702 					enum unit_activity act,
1703 					struct extra_type *tgt)
1704 {
1705   if (!can_client_issue_orders()) {
1706     return;
1707   }
1708 
1709   if (tgt == NULL) {
1710     dsend_packet_unit_change_activity(&client.conn, punit->id, act, EXTRA_NONE);
1711   } else {
1712     dsend_packet_unit_change_activity(&client.conn, punit->id, act, extra_index(tgt));
1713   }
1714 }
1715 
1716 /**************************************************************************
1717   Send request to disband unit to server.
1718 **************************************************************************/
request_unit_disband(struct unit * punit)1719 void request_unit_disband(struct unit *punit)
1720 {
1721   dsend_packet_unit_disband(&client.conn, punit->id);
1722 }
1723 
1724 /**************************************************************************
1725   Send request to change unit homecity to server.
1726 **************************************************************************/
request_unit_change_homecity(struct unit * punit)1727 void request_unit_change_homecity(struct unit *punit)
1728 {
1729   struct city *pcity=tile_city(unit_tile(punit));
1730 
1731   if (pcity) {
1732     dsend_packet_unit_change_homecity(&client.conn, punit->id, pcity->id);
1733   }
1734 }
1735 
1736 /**************************************************************************
1737   Send request to upgrade unit to server.
1738 **************************************************************************/
request_unit_upgrade(struct unit * punit)1739 void request_unit_upgrade(struct unit *punit)
1740 {
1741   struct city *pcity=tile_city(unit_tile(punit));
1742 
1743   if (pcity) {
1744     dsend_packet_unit_upgrade(&client.conn, punit->id);
1745   }
1746 }
1747 
1748 /**************************************************************************
1749   Sends unit convert packet.
1750 **************************************************************************/
request_unit_convert(struct unit * punit)1751 void request_unit_convert(struct unit *punit)
1752 {
1753   request_new_unit_activity(punit, ACTIVITY_CONVERT);
1754 }
1755 
1756 /****************************************************************************
1757   Call to request (from the server) that the settler unit is put into
1758   autosettler mode.
1759 ****************************************************************************/
request_unit_autosettlers(const struct unit * punit)1760 void request_unit_autosettlers(const struct unit *punit)
1761 {
1762   if (punit && can_unit_do_autosettlers(punit)) {
1763     dsend_packet_unit_autosettlers(&client.conn, punit->id);
1764   } else if (punit) {
1765     create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1766                  _("Only settler units can be put into auto mode."));
1767   }
1768 }
1769 
1770 /****************************************************************************
1771   Send a request to the server that the cargo be loaded into the transporter.
1772 
1773   If ptransporter is NULL a suitable transporter will be chosen.
1774 ****************************************************************************/
request_unit_load(struct unit * pcargo,struct unit * ptrans,struct tile * ptile)1775 void request_unit_load(struct unit *pcargo, struct unit *ptrans,
1776                        struct tile *ptile)
1777 {
1778   if (!ptrans) {
1779     ptrans = transporter_for_unit(pcargo);
1780   }
1781 
1782   if (ptrans
1783       && can_client_issue_orders()
1784       && could_unit_load(pcargo, ptrans)) {
1785     dsend_packet_unit_load(&client.conn, pcargo->id, ptrans->id,
1786                            ptile->index);
1787 
1788     /* Sentry the unit.  Don't request_unit_sentry since this can give a
1789      * recursive loop. */
1790     /* FIXME: Should not sentry if above loading fails (transport moved away,
1791      *        or filled already in server side) */
1792     dsend_packet_unit_change_activity(&client.conn, pcargo->id,
1793                                       ACTIVITY_SENTRY, EXTRA_NONE);
1794   }
1795 }
1796 
1797 /****************************************************************************
1798   Send a request to the server that the cargo be unloaded from its current
1799   transporter.
1800 ****************************************************************************/
request_unit_unload(struct unit * pcargo)1801 void request_unit_unload(struct unit *pcargo)
1802 {
1803   struct unit *ptrans = unit_transport_get(pcargo);
1804 
1805   if (can_client_issue_orders()
1806       && ptrans
1807       && can_unit_unload(pcargo, ptrans)
1808       && can_unit_survive_at_tile(pcargo, unit_tile(pcargo))) {
1809     dsend_packet_unit_unload(&client.conn, pcargo->id, ptrans->id);
1810 
1811     if (unit_owner(pcargo) == client.conn.playing
1812         && pcargo->activity == ACTIVITY_SENTRY) {
1813       /* Activate the unit. */
1814       dsend_packet_unit_change_activity(&client.conn, pcargo->id,
1815                                         ACTIVITY_IDLE, EXTRA_NONE);
1816     }
1817   }
1818 }
1819 
1820 /**************************************************************************
1821   Send request to do caravan action - establishing traderoute or
1822   helping in wonder building - to server.
1823 **************************************************************************/
request_unit_caravan_action(struct unit * punit,enum gen_action action)1824 void request_unit_caravan_action(struct unit *punit,
1825                                  enum gen_action action)
1826 {
1827   struct city *target_city;
1828 
1829   if (!((target_city = tile_city(unit_tile(punit))))) {
1830     return;
1831   }
1832 
1833   if (action == ACTION_TRADE_ROUTE) {
1834     request_do_action(ACTION_TRADE_ROUTE, punit->id,
1835                       target_city->id, 0);
1836   } else if (action == ACTION_HELP_WONDER) {
1837     request_do_action(ACTION_HELP_WONDER, punit->id,
1838                       target_city->id, 0);
1839   } else {
1840     log_error("request_unit_caravan_action() Bad action (%d)", action);
1841   }
1842 }
1843 
1844 /**************************************************************************
1845  Explode nuclear at a tile without enemy units
1846 **************************************************************************/
request_unit_nuke(struct unit_list * punits)1847 void request_unit_nuke(struct unit_list *punits)
1848 {
1849   if (unit_list_size(punits) == 0) {
1850     return;
1851   }
1852 
1853   unit_list_iterate(punits, punit) {
1854     if (!unit_has_type_flag(punit, UTYF_NUCLEAR)) {
1855       create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1856                    _("Only nuclear units can do this."));
1857       return;
1858     }
1859   } unit_list_iterate_end;
1860 
1861   if (hover_state != HOVER_NUKE) {
1862     set_hover_state(punits, HOVER_NUKE, ACTIVITY_LAST, NULL, ORDER_LAST);
1863     enter_goto_state(punits);
1864     create_line_at_mouse_pos();
1865     update_unit_info_label(punits);
1866     control_mouse_cursor(NULL);
1867   } else {
1868     fc_assert_ret(goto_is_active());
1869     goto_add_waypoint();
1870   }
1871 }
1872 
1873 /**************************************************************************
1874   Have the player select what tile to paradrop to. Once selected a
1875   paradrop request will be sent to server.
1876 **************************************************************************/
request_unit_paradrop(struct unit_list * punits)1877 void request_unit_paradrop(struct unit_list *punits)
1878 {
1879   bool can = FALSE;
1880   struct tile *offender = NULL;
1881 
1882   if (unit_list_size(punits) == 0) {
1883     return;
1884   }
1885   unit_list_iterate(punits, punit) {
1886     if (can_unit_paradrop(punit)) {
1887       can = TRUE;
1888       break;
1889     }
1890     if (!offender) { /* Take first offender tile/unit */
1891       offender = unit_tile(punit);
1892     }
1893   } unit_list_iterate_end;
1894   if (can) {
1895     set_hover_state(punits, HOVER_PARADROP, ACTIVITY_LAST, NULL,
1896                     ORDER_LAST);
1897     update_unit_info_label(punits);
1898   } else {
1899     create_event(offender, E_BAD_COMMAND, ftc_client,
1900                  _("Only paratrooper units can do this."));
1901   }
1902 }
1903 
1904 /**************************************************************************
1905   Either start new patrol route planning, or add waypoint to current one.
1906 **************************************************************************/
request_unit_patrol(void)1907 void request_unit_patrol(void)
1908 {
1909   struct unit_list *punits = get_units_in_focus();
1910 
1911   if (unit_list_size(punits) == 0) {
1912     return;
1913   }
1914 
1915   if (hover_state != HOVER_PATROL) {
1916     set_hover_state(punits, HOVER_PATROL, ACTIVITY_LAST, NULL,
1917                     ORDER_LAST);
1918     update_unit_info_label(punits);
1919     enter_goto_state(punits);
1920     create_line_at_mouse_pos();
1921   } else {
1922     fc_assert_ret(goto_is_active());
1923     goto_add_waypoint();
1924   }
1925 }
1926 
1927 /****************************************************************
1928   Try to sentry unit.
1929 *****************************************************************/
request_unit_sentry(struct unit * punit)1930 void request_unit_sentry(struct unit *punit)
1931 {
1932   if(punit->activity!=ACTIVITY_SENTRY &&
1933      can_unit_do_activity(punit, ACTIVITY_SENTRY))
1934     request_new_unit_activity(punit, ACTIVITY_SENTRY);
1935 }
1936 
1937 /****************************************************************
1938   Try to fortify unit.
1939 *****************************************************************/
request_unit_fortify(struct unit * punit)1940 void request_unit_fortify(struct unit *punit)
1941 {
1942   if(punit->activity!=ACTIVITY_FORTIFYING &&
1943      can_unit_do_activity(punit, ACTIVITY_FORTIFYING))
1944     request_new_unit_activity(punit, ACTIVITY_FORTIFYING);
1945 }
1946 
1947 /**************************************************************************
1948   Send pillage request to server.
1949 **************************************************************************/
request_unit_pillage(struct unit * punit)1950 void request_unit_pillage(struct unit *punit)
1951 {
1952   if (!game.info.pillage_select) {
1953     /* Leave choice up to the server */
1954     request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, NULL);
1955   } else {
1956     struct tile *ptile = unit_tile(punit);
1957     bv_extras pspossible;
1958     int count = 0;
1959 
1960     BV_CLR_ALL(pspossible);
1961     extra_type_iterate(potential) {
1962       if (can_unit_do_activity_targeted_at(punit, ACTIVITY_PILLAGE,
1963                                            potential, ptile)) {
1964         BV_SET(pspossible, extra_index(potential));
1965         count++;
1966       }
1967     } extra_type_iterate_end;
1968 
1969     if (count > 1) {
1970       popup_pillage_dialog(punit, pspossible);
1971     } else {
1972       /* Should be only one choice... */
1973       struct extra_type *target = get_preferred_pillage(pspossible);
1974 
1975       if (target != NULL) {
1976         request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, target);
1977       }
1978     }
1979   }
1980 }
1981 
1982 /**************************************************************************
1983  Toggle display of city outlines on the map
1984 **************************************************************************/
request_toggle_city_outlines(void)1985 void request_toggle_city_outlines(void)
1986 {
1987   if (!can_client_change_view()) {
1988     return;
1989   }
1990 
1991   gui_options.draw_city_outlines = !gui_options.draw_city_outlines;
1992   update_map_canvas_visible();
1993 }
1994 
1995 /**************************************************************************
1996  Toggle display of worker output of cities on the map
1997 **************************************************************************/
request_toggle_city_output(void)1998 void request_toggle_city_output(void)
1999 {
2000   if (!can_client_change_view()) {
2001     return;
2002   }
2003 
2004   gui_options.draw_city_output = !gui_options.draw_city_output;
2005   update_map_canvas_visible();
2006 }
2007 
2008 /**************************************************************************
2009  Toggle display of grid lines on the map
2010 **************************************************************************/
request_toggle_map_grid(void)2011 void request_toggle_map_grid(void)
2012 {
2013   if (!can_client_change_view()) {
2014     return;
2015   }
2016 
2017   gui_options.draw_map_grid ^= 1;
2018   update_map_canvas_visible();
2019 }
2020 
2021 /**************************************************************************
2022  Toggle display of national borders on the map
2023 **************************************************************************/
request_toggle_map_borders(void)2024 void request_toggle_map_borders(void)
2025 {
2026   if (!can_client_change_view()) {
2027     return;
2028   }
2029 
2030   gui_options.draw_borders ^= 1;
2031   update_map_canvas_visible();
2032 }
2033 
2034 /**************************************************************************
2035  Toggle display of native tiles on the map
2036 **************************************************************************/
request_toggle_map_native(void)2037 void request_toggle_map_native(void)
2038 {
2039   if (!can_client_change_view()) {
2040     return;
2041   }
2042 
2043   gui_options.draw_native ^= 1;
2044   update_map_canvas_visible();
2045 }
2046 
2047 /**************************************************************************
2048   Toggle display of city full bar.
2049 **************************************************************************/
request_toggle_city_full_bar(void)2050 void request_toggle_city_full_bar(void)
2051 {
2052   if (!can_client_change_view()) {
2053     return;
2054   }
2055 
2056   gui_options.draw_full_citybar ^= 1;
2057   update_map_canvas_visible();
2058 }
2059 
2060 /**************************************************************************
2061  Toggle display of city names
2062 **************************************************************************/
request_toggle_city_names(void)2063 void request_toggle_city_names(void)
2064 {
2065   if (!can_client_change_view()) {
2066     return;
2067   }
2068 
2069   gui_options.draw_city_names ^= 1;
2070   update_map_canvas_visible();
2071 }
2072 
2073  /**************************************************************************
2074  Toggle display of city growth (turns-to-grow)
2075 **************************************************************************/
request_toggle_city_growth(void)2076 void request_toggle_city_growth(void)
2077 {
2078   if (!can_client_change_view()) {
2079     return;
2080   }
2081 
2082   gui_options.draw_city_growth ^= 1;
2083   update_map_canvas_visible();
2084 }
2085 
2086 /**************************************************************************
2087  Toggle display of city productions
2088 **************************************************************************/
request_toggle_city_productions(void)2089 void request_toggle_city_productions(void)
2090 {
2091   if (!can_client_change_view()) {
2092     return;
2093   }
2094 
2095   gui_options.draw_city_productions ^= 1;
2096   update_map_canvas_visible();
2097 }
2098 
2099 /**************************************************************************
2100  Toggle display of city buycost
2101 **************************************************************************/
request_toggle_city_buycost(void)2102 void request_toggle_city_buycost(void)
2103 {
2104   if (!can_client_change_view()) {
2105     return;
2106   }
2107 
2108   gui_options.draw_city_buycost ^= 1;
2109   update_map_canvas_visible();
2110 }
2111 
2112 /**************************************************************************
2113  Toggle display of city trade routes
2114 **************************************************************************/
request_toggle_city_trade_routes(void)2115 void request_toggle_city_trade_routes(void)
2116 {
2117   if (!can_client_change_view()) {
2118     return;
2119   }
2120 
2121   gui_options.draw_city_trade_routes ^= 1;
2122   update_map_canvas_visible();
2123 }
2124 
2125 /**************************************************************************
2126  Toggle display of terrain
2127 **************************************************************************/
request_toggle_terrain(void)2128 void request_toggle_terrain(void)
2129 {
2130   if (!can_client_change_view()) {
2131     return;
2132   }
2133 
2134   gui_options.draw_terrain ^= 1;
2135   update_map_canvas_visible();
2136 }
2137 
2138 /**************************************************************************
2139  Toggle display of coastline
2140 **************************************************************************/
request_toggle_coastline(void)2141 void request_toggle_coastline(void)
2142 {
2143   if (!can_client_change_view()) {
2144     return;
2145   }
2146 
2147   gui_options.draw_coastline ^= 1;
2148   update_map_canvas_visible();
2149 }
2150 
2151 /**************************************************************************
2152  Toggle display of roads and rails
2153 **************************************************************************/
request_toggle_roads_rails(void)2154 void request_toggle_roads_rails(void)
2155 {
2156   if (!can_client_change_view()) {
2157     return;
2158   }
2159 
2160   gui_options.draw_roads_rails ^= 1;
2161   update_map_canvas_visible();
2162 }
2163 
2164 /**************************************************************************
2165  Toggle display of irrigation
2166 **************************************************************************/
request_toggle_irrigation(void)2167 void request_toggle_irrigation(void)
2168 {
2169   if (!can_client_change_view()) {
2170     return;
2171   }
2172 
2173   gui_options.draw_irrigation ^= 1;
2174   update_map_canvas_visible();
2175 }
2176 
2177 /**************************************************************************
2178  Toggle display of mines
2179 **************************************************************************/
request_toggle_mines(void)2180 void request_toggle_mines(void)
2181 {
2182   if (!can_client_change_view()) {
2183     return;
2184   }
2185 
2186   gui_options.draw_mines ^= 1;
2187   update_map_canvas_visible();
2188 }
2189 
2190 /**************************************************************************
2191  Toggle display of bases
2192 **************************************************************************/
request_toggle_bases(void)2193 void request_toggle_bases(void)
2194 {
2195   if (!can_client_change_view()) {
2196     return;
2197   }
2198 
2199   gui_options.draw_fortress_airbase ^= 1;
2200   update_map_canvas_visible();
2201 }
2202 
2203 /**************************************************************************
2204  Toggle display of resources
2205 **************************************************************************/
request_toggle_resources(void)2206 void request_toggle_resources(void)
2207 {
2208   if (!can_client_change_view()) {
2209     return;
2210   }
2211 
2212   gui_options.draw_specials ^= 1;
2213   update_map_canvas_visible();
2214 }
2215 
2216 /**************************************************************************
2217  Toggle display of huts
2218 **************************************************************************/
request_toggle_huts(void)2219 void request_toggle_huts(void)
2220 {
2221   if (!can_client_change_view()) {
2222     return;
2223   }
2224 
2225   gui_options.draw_huts ^= 1;
2226   update_map_canvas_visible();
2227 }
2228 
2229 /**************************************************************************
2230  Toggle display of pollution
2231 **************************************************************************/
request_toggle_pollution(void)2232 void request_toggle_pollution(void)
2233 {
2234   if (!can_client_change_view()) {
2235     return;
2236   }
2237 
2238   gui_options.draw_pollution ^= 1;
2239   update_map_canvas_visible();
2240 }
2241 
2242 /**************************************************************************
2243  Toggle display of cities
2244 **************************************************************************/
request_toggle_cities(void)2245 void request_toggle_cities(void)
2246 {
2247   if (!can_client_change_view()) {
2248     return;
2249   }
2250 
2251   gui_options.draw_cities ^= 1;
2252   update_map_canvas_visible();
2253 }
2254 
2255 /**************************************************************************
2256  Toggle display of units
2257 **************************************************************************/
request_toggle_units(void)2258 void request_toggle_units(void)
2259 {
2260   if (!can_client_change_view()) {
2261     return;
2262   }
2263 
2264   gui_options.draw_units ^= 1;
2265   update_map_canvas_visible();
2266 }
2267 
2268 /**************************************************************************
2269   Toggle display of unit solid background.
2270 **************************************************************************/
request_toggle_unit_solid_bg(void)2271 void request_toggle_unit_solid_bg(void)
2272 {
2273   if (!can_client_change_view()) {
2274     return;
2275   }
2276 
2277   gui_options.solid_color_behind_units ^= 1;
2278   update_map_canvas_visible();
2279 }
2280 
2281 /**************************************************************************
2282   Toggle display of unit shields.
2283 **************************************************************************/
request_toggle_unit_shields(void)2284 void request_toggle_unit_shields(void)
2285 {
2286   if (!can_client_change_view()) {
2287     return;
2288   }
2289 
2290   gui_options.draw_unit_shields ^= 1;
2291   update_map_canvas_visible();
2292 }
2293 
2294 /**************************************************************************
2295  Toggle display of focus unit
2296 **************************************************************************/
request_toggle_focus_unit(void)2297 void request_toggle_focus_unit(void)
2298 {
2299   if (!can_client_change_view()) {
2300     return;
2301   }
2302 
2303   gui_options.draw_focus_unit ^= 1;
2304   update_map_canvas_visible();
2305 }
2306 
2307 /**************************************************************************
2308  Toggle display of fog of war
2309 **************************************************************************/
request_toggle_fog_of_war(void)2310 void request_toggle_fog_of_war(void)
2311 {
2312   if (!can_client_change_view()) {
2313     return;
2314   }
2315 
2316   gui_options.draw_fog_of_war ^= 1;
2317   update_map_canvas_visible();
2318   refresh_overview_canvas();
2319 }
2320 
2321 /**************************************************************************
2322   Center to focus unit.
2323 **************************************************************************/
request_center_focus_unit(void)2324 void request_center_focus_unit(void)
2325 {
2326   struct tile *ptile = find_a_focus_unit_tile_to_center_on();
2327 
2328   if (ptile) {
2329     center_tile_mapcanvas(ptile);
2330   }
2331 }
2332 
2333 /**************************************************************************
2334   Set units in list to waiting focus. If they are current focus units,
2335   advance focus.
2336 **************************************************************************/
request_units_wait(struct unit_list * punits)2337 void request_units_wait(struct unit_list *punits)
2338 {
2339   unit_list_iterate(punits, punit) {
2340     punit->client.focus_status = FOCUS_WAIT;
2341   } unit_list_iterate_end;
2342   if (punits == get_units_in_focus()) {
2343     unit_focus_advance();
2344   }
2345 }
2346 
2347 /**************************************************************************
2348   Set focus units to FOCUS_DONE state.
2349 **************************************************************************/
request_unit_move_done(void)2350 void request_unit_move_done(void)
2351 {
2352   if (get_num_units_in_focus() > 0) {
2353     enum unit_focus_status new_status = FOCUS_DONE;
2354     unit_list_iterate(get_units_in_focus(), punit) {
2355       /* If any of the focused units are busy, keep all of them
2356        * in focus; another tap of the key will dismiss them */
2357       if (punit->activity != ACTIVITY_IDLE) {
2358         new_status = FOCUS_WAIT;
2359       }
2360     } unit_list_iterate_end;
2361     unit_list_iterate(get_units_in_focus(), punit) {
2362       clear_unit_orders(punit);
2363       punit->client.focus_status = new_status;
2364     } unit_list_iterate_end;
2365     if (new_status == FOCUS_DONE) {
2366       unit_focus_advance();
2367     }
2368   }
2369 }
2370 
2371 /**************************************************************************
2372   Called to have the client move a unit from one location to another,
2373   updating the graphics if necessary.  The caller must redraw the target
2374   location after the move.
2375 **************************************************************************/
do_move_unit(struct unit * punit,struct unit * target_unit)2376 void do_move_unit(struct unit *punit, struct unit *target_unit)
2377 {
2378   struct tile *src_tile = unit_tile(punit);
2379   struct tile *dst_tile = unit_tile(target_unit);
2380   bool was_teleported, do_animation;
2381   bool in_focus = unit_is_in_focus(punit);
2382 
2383   was_teleported = !is_tiles_adjacent(src_tile, dst_tile);
2384   do_animation = (!was_teleported && gui_options.smooth_move_unit_msec > 0);
2385 
2386   if (!was_teleported
2387       && punit->activity != ACTIVITY_SENTRY
2388       && !unit_transported(punit)) {
2389     audio_play_sound(unit_type_get(punit)->sound_move,
2390                      unit_type_get(punit)->sound_move_alt);
2391   }
2392 
2393   if (unit_owner(punit) == client.conn.playing
2394       && gui_options.auto_center_on_unit
2395       && !unit_has_orders(punit)
2396       && punit->activity != ACTIVITY_GOTO
2397       && punit->activity != ACTIVITY_SENTRY
2398       && ((gui_options.auto_center_on_automated == TRUE
2399            && punit->ai_controlled == TRUE)
2400           || (punit->ai_controlled == FALSE))
2401       && !tile_visible_and_not_on_border_mapcanvas(dst_tile)) {
2402     center_tile_mapcanvas(dst_tile);
2403   }
2404 
2405   if (hover_state != HOVER_NONE && in_focus) {
2406     /* Cancel current goto/patrol/connect/nuke command. */
2407     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
2408     update_unit_info_label(get_units_in_focus());
2409   }
2410 
2411   unit_list_remove(src_tile->units, punit);
2412 
2413   if (!unit_transported(punit)) {
2414     /* Mark the unit as moving unit, then find_visible_unit() won't return
2415      * it. It is especially useful to don't draw many times the unit when
2416      * refreshing the canvas. */
2417     punit_moving = punit;
2418 
2419     /* We have to refresh the tile before moving.  This will draw
2420      * the tile without the unit (because it was unlinked above). */
2421     refresh_unit_mapcanvas(punit, src_tile, TRUE, FALSE);
2422 
2423     if (gui_options.auto_center_on_automated == FALSE
2424         && punit->ai_controlled == TRUE) {
2425       /* Dont animate automatic units */
2426     } else if (do_animation) {
2427       int dx, dy;
2428 
2429       /* For the duration of the animation the unit exists at neither
2430        * tile. */
2431       map_distance_vector(&dx, &dy, src_tile, dst_tile);
2432       move_unit_map_canvas(punit, src_tile, dx, dy);
2433     }
2434   }
2435 
2436   unit_tile_set(punit, dst_tile);
2437   unit_list_prepend(dst_tile->units, punit);
2438 
2439   if (!unit_transported(punit)) {
2440     /* For find_visible_unit(), see above. */
2441     punit_moving = NULL;
2442 
2443     refresh_unit_mapcanvas(punit, dst_tile, TRUE, FALSE);
2444   }
2445 
2446   /* With the "full" city bar we have to update the city bar when units move
2447    * into or out of a city.  For foreign cities this is handled separately,
2448    * via the occupied field of the short-city packet. */
2449   if (NULL != tile_city(src_tile)
2450       && can_player_see_units_in_city(client.conn.playing, tile_city(src_tile))) {
2451     update_city_description(tile_city(src_tile));
2452   }
2453   if (NULL != tile_city(dst_tile)
2454       && can_player_see_units_in_city(client.conn.playing, tile_city(dst_tile))) {
2455     update_city_description(tile_city(dst_tile));
2456   }
2457 
2458   if (in_focus) {
2459     menus_update();
2460   }
2461 }
2462 
2463 /**************************************************************************
2464   An action selection dialog for the selected units against the specified
2465   tile is wanted.
2466 **************************************************************************/
do_unit_act_sel_vs(struct tile * ptile)2467 static void do_unit_act_sel_vs(struct tile *ptile)
2468 {
2469   unit_list_iterate(get_units_in_focus(), punit) {
2470     if (utype_may_act_at_all(unit_type_get(punit))) {
2471       /* Have the server record that an action decision is wanted for
2472        * this unit against this tile. */
2473       request_do_action(ACTION_COUNT, punit->id, tile_index(ptile),
2474                         ACTSIG_QUEUE);
2475     }
2476   } unit_list_iterate_end;
2477 }
2478 
2479 /**************************************************************************
2480  Handles everything when the user clicked a tile
2481 **************************************************************************/
do_map_click(struct tile * ptile,enum quickselect_type qtype)2482 void do_map_click(struct tile *ptile, enum quickselect_type qtype)
2483 {
2484   struct city *pcity = tile_city(ptile);
2485   struct unit_list *punits = get_units_in_focus();
2486   bool maybe_goto = FALSE;
2487 
2488   if (hover_state != HOVER_NONE) {
2489     switch (hover_state) {
2490     case HOVER_NONE:
2491       break;
2492     case HOVER_GOTO:
2493       do_unit_goto(ptile);
2494       break;
2495     case HOVER_NUKE:
2496       do_unit_nuke(ptile);
2497       break;
2498     case HOVER_PARADROP:
2499       unit_list_iterate(punits, punit) {
2500 	do_unit_paradrop_to(punit, ptile);
2501       } unit_list_iterate_end;
2502       break;
2503     case HOVER_CONNECT:
2504       do_unit_connect(ptile, connect_activity, connect_tgt);
2505       break;
2506     case HOVER_PATROL:
2507       do_unit_patrol_to(ptile);
2508       break;
2509     case HOVER_ACT_SEL_TGT:
2510       do_unit_act_sel_vs(ptile);
2511       break;
2512     }
2513 
2514     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
2515     update_unit_info_label(get_units_in_focus());
2516   }
2517 
2518   /* Bypass stack or city popup if quickselect is specified. */
2519   else if (qtype != SELECT_POPUP && qtype != SELECT_APPEND) {
2520     struct unit *qunit = quickselect(ptile, qtype);
2521     if (qunit) {
2522       unit_focus_set_and_select(qunit);
2523       maybe_goto = gui_options.keyboardless_goto;
2524     }
2525   }
2526   /* Otherwise use popups. */
2527   else if (NULL != pcity
2528            && can_player_see_city_internals(client.conn.playing, pcity)) {
2529     popup_city_dialog(pcity);
2530   }
2531   else if (unit_list_size(ptile->units) == 0
2532            && NULL == pcity
2533            && get_num_units_in_focus() > 0) {
2534     maybe_goto = gui_options.keyboardless_goto;
2535   }
2536   else if (unit_list_size(ptile->units) == 1
2537            && !get_transporter_occupancy(unit_list_get(ptile->units, 0))) {
2538     struct unit *punit = unit_list_get(ptile->units, 0);
2539 
2540     if (unit_owner(punit) == client.conn.playing) {
2541       if(can_unit_do_activity(punit, ACTIVITY_IDLE)) {
2542         maybe_goto = gui_options.keyboardless_goto;
2543 	if (qtype == SELECT_APPEND) {
2544 	  unit_focus_add(punit);
2545 	} else {
2546 	  unit_focus_set_and_select(punit);
2547 	}
2548       }
2549     } else if (pcity) {
2550       /* Don't hide the unit in the city. */
2551       unit_select_dialog_popup(ptile);
2552     }
2553   }
2554   else if(unit_list_size(ptile->units) > 0) {
2555     /* The stack list is always popped up, even if it includes enemy units.
2556      * If the server doesn't want the player to know about them it shouldn't
2557      * tell him!  The previous behavior would only pop up the stack if you
2558      * owned a unit on the tile.  This gave cheating clients an advantage,
2559      * and also showed you allied units if (and only if) you had a unit on
2560      * the tile (inconsistent). */
2561     unit_select_dialog_popup(ptile);
2562   }
2563 
2564   /* See mapctrl_common.c */
2565   keyboardless_goto_start_tile = maybe_goto ? ptile : NULL;
2566   keyboardless_goto_button_down = maybe_goto;
2567   keyboardless_goto_active = FALSE;
2568 }
2569 
2570 /**************************************************************************
2571  Quickselecting a unit is normally done with <control> left, right click,
2572  for the current tile. Bypassing the stack popup is quite convenient,
2573  and can be tactically important in furious multiplayer games.
2574 **************************************************************************/
quickselect(struct tile * ptile,enum quickselect_type qtype)2575 static struct unit *quickselect(struct tile *ptile,
2576                                 enum quickselect_type qtype)
2577 {
2578   int listsize = unit_list_size(ptile->units);
2579   struct unit *panytransporter = NULL,
2580               *panymovesea  = NULL, *panysea  = NULL,
2581               *panymoveland = NULL, *panyland = NULL,
2582               *panymoveunit = NULL, *panyunit = NULL;
2583 
2584   fc_assert_ret_val(qtype > SELECT_POPUP, NULL);
2585 
2586   if (qtype == SELECT_FOCUS) {
2587     return head_of_units_in_focus();
2588   }
2589 
2590   if (listsize == 0) {
2591     return NULL;
2592   } else if (listsize == 1) {
2593     struct unit *punit = unit_list_get(ptile->units, 0);
2594     return (unit_owner(punit) == client.conn.playing) ? punit : NULL;
2595   }
2596 
2597   /*  Quickselect priorities. Units with moves left
2598    *  before exhausted. Focus unit is excluded.
2599    *
2600    *    SEA:  Transporter
2601    *          Sea unit
2602    *          Any unit
2603    *
2604    *    LAND: Military land unit
2605    *          Non-combatant
2606    *          Sea unit
2607    *          Any unit
2608    */
2609 
2610   unit_list_iterate(ptile->units, punit)  {
2611     if (unit_owner(punit) != client.conn.playing || unit_is_in_focus(punit)) {
2612       continue;
2613     }
2614   if (qtype == SELECT_SEA) {
2615     /* Transporter. */
2616     if (get_transporter_capacity(punit)) {
2617       if (punit->moves_left > 0) {
2618         return punit;
2619       } else if (!panytransporter) {
2620         panytransporter = punit;
2621       }
2622     }
2623     /* Any sea, pref. moves left. */
2624     else if (utype_move_type(unit_type_get(punit)) == UMT_SEA) {
2625       if (punit->moves_left > 0) {
2626         if (!panymovesea) {
2627           panymovesea = punit;
2628         }
2629       } else if (!panysea) {
2630           panysea = punit;
2631       }
2632     }
2633   } else if (qtype == SELECT_LAND) {
2634     if (utype_move_type(unit_type_get(punit)) == UMT_LAND) {
2635       if (punit->moves_left > 0) {
2636         if (is_military_unit(punit)) {
2637           return punit;
2638         } else if (!panymoveland) {
2639             panymoveland = punit;
2640         }
2641       } else if (!panyland) {
2642         panyland = punit;
2643       }
2644     }
2645     else if (utype_move_type(unit_type_get(punit)) == UMT_SEA) {
2646       if (punit->moves_left > 0) {
2647         panymovesea = punit;
2648       } else {
2649         panysea = punit;
2650       }
2651     }
2652   }
2653   if (punit->moves_left > 0 && !panymoveunit) {
2654     panymoveunit = punit;
2655   }
2656   if (!panyunit) {
2657     panyunit = punit;
2658   }
2659     } unit_list_iterate_end;
2660 
2661   if (qtype == SELECT_SEA) {
2662     if (panytransporter) {
2663       return panytransporter;
2664     } else if (panymovesea) {
2665       return panymovesea;
2666     } else if (panysea) {
2667       return panysea;
2668     } else if (panymoveunit) {
2669       return panymoveunit;
2670     } else if (panyunit) {
2671       return panyunit;
2672     }
2673   }
2674   else if (qtype == SELECT_LAND) {
2675     if (panymoveland) {
2676       return panymoveland;
2677     } else if (panyland) {
2678       return panyland;
2679     } else if (panymovesea) {
2680       return panymovesea;
2681     } else if (panysea) {
2682       return panysea;
2683     } else if (panymoveunit) {
2684       return panymoveunit;
2685     } else if (panyunit) {
2686       return panyunit;
2687     }
2688   }
2689   return NULL;
2690 }
2691 
2692 /**************************************************************************
2693  Finish the goto mode and let the units stored in goto_map_list move
2694  to a given location.
2695 **************************************************************************/
do_unit_goto(struct tile * ptile)2696 void do_unit_goto(struct tile *ptile)
2697 {
2698   if (hover_state != HOVER_GOTO) {
2699     return;
2700   }
2701 
2702   if (is_valid_goto_draw_line(ptile)) {
2703     send_goto_route();
2704   } else {
2705     create_event(ptile, E_BAD_COMMAND, ftc_client,
2706                  _("Didn't find a route to the destination!"));
2707   }
2708 }
2709 
2710 /****************************************************************************
2711   Destroy the client nuke data.
2712 ****************************************************************************/
client_nuke_data_destroy(void * p)2713 static void client_nuke_data_destroy(void *p)
2714 {
2715   struct client_nuke_data *data = p;
2716 
2717   free(data->units_id);
2718   free(data);
2719 }
2720 
2721 /****************************************************************************
2722   Explode nuclear at a tile without enemy units.
2723 ****************************************************************************/
do_real_unit_nuke(void * p)2724 static void do_real_unit_nuke(void *p)
2725 {
2726   struct client_nuke_data *data = p;
2727   struct tile *ptile = index_to_tile(data->tile_idx);
2728   struct unit *punit;
2729   int i;
2730 
2731   fc_assert_ret(can_client_issue_orders());
2732   fc_assert_ret(ptile != NULL);
2733 
2734   for (i = 0; i < data->units_num; i++) {
2735     /* Ensure we have reached destination. */
2736     punit = player_unit_by_number(client_player(), data->units_id[i]);
2737     if (punit != NULL && unit_tile(punit) == ptile) {
2738       dsend_packet_unit_nuke(&client.conn, punit->id);
2739     }
2740   }
2741 }
2742 
2743 /****************************************************************************
2744   Send units to 'ptile' and nuke there!
2745 ****************************************************************************/
do_unit_nuke(struct tile * ptile)2746 void do_unit_nuke(struct tile *ptile)
2747 {
2748   if (hover_state != HOVER_NUKE) {
2749     return;
2750   }
2751 
2752   if (is_valid_goto_draw_line(ptile)) {
2753     struct client_nuke_data *data = fc_malloc(sizeof(*data));
2754     int last_request_id_used = client.conn.client.last_request_id_used;
2755     int i = 0;
2756 
2757     data->units_id = fc_malloc(sizeof(*data->units_id)
2758                                * get_num_units_in_focus());
2759     unit_list_iterate(get_units_in_focus(), punit) {
2760       data->units_id[i++] = punit->id;
2761     } unit_list_iterate_end;
2762     data->units_num = i;
2763     data->tile_idx = tile_index(ptile);
2764 
2765     send_goto_route();
2766 
2767     if (last_request_id_used != client.conn.client.last_request_id_used) {
2768       /* We sent some packets, let's wait the server to process them to know
2769        * where our units hold. */
2770       update_queue_connect_processing_finished_full
2771           (client.conn.client.last_request_id_used,
2772            do_real_unit_nuke, data, client_nuke_data_destroy);
2773     } else {
2774       /* We didn't sent the packets, that mean that the route was nil, or
2775        * an internal error occurred. Process nuke units now. */
2776       do_real_unit_nuke(data);
2777       client_nuke_data_destroy(data);
2778     }
2779   } else {
2780     create_event(ptile, E_BAD_COMMAND, ftc_client,
2781                  _("Didn't find a route to the destination!"));
2782   }
2783 }
2784 
2785 /**************************************************************************
2786   Paradrop to a location.
2787 **************************************************************************/
do_unit_paradrop_to(struct unit * punit,struct tile * ptile)2788 void do_unit_paradrop_to(struct unit *punit, struct tile *ptile)
2789 {
2790   dsend_packet_unit_paradrop_to(&client.conn, punit->id, tile_index(ptile));
2791 }
2792 
2793 /**************************************************************************
2794   Patrol to a location.
2795 **************************************************************************/
do_unit_patrol_to(struct tile * ptile)2796 void do_unit_patrol_to(struct tile *ptile)
2797 {
2798   if (is_valid_goto_draw_line(ptile)
2799       && !is_non_allied_unit_tile(ptile, client.conn.playing)) {
2800     send_patrol_route();
2801   } else {
2802     create_event(ptile, E_BAD_COMMAND, ftc_client,
2803                  _("Didn't find a route to the destination!"));
2804   }
2805 
2806   set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
2807 }
2808 
2809 /**************************************************************************
2810   "Connect" to the given location.
2811 **************************************************************************/
do_unit_connect(struct tile * ptile,enum unit_activity activity,struct extra_type * tgt)2812 void do_unit_connect(struct tile *ptile,
2813 		     enum unit_activity activity,
2814                      struct extra_type *tgt)
2815 {
2816   if (is_valid_goto_draw_line(ptile)) {
2817     send_connect_route(activity, tgt);
2818   } else {
2819     create_event(ptile, E_BAD_COMMAND, ftc_client,
2820                  _("Didn't find a route to the destination!"));
2821   }
2822 
2823   set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
2824 }
2825 
2826 /**************************************************************************
2827  The 'Escape' key.
2828 **************************************************************************/
key_cancel_action(void)2829 void key_cancel_action(void)
2830 {
2831   cancel_tile_hiliting();
2832 
2833   switch (hover_state) {
2834   case HOVER_GOTO:
2835   case HOVER_PATROL:
2836   case HOVER_CONNECT:
2837   case HOVER_NUKE:
2838     if (goto_pop_waypoint()) {
2839       break;
2840     }
2841     fc__fallthrough; /* else fall through: */
2842   case HOVER_PARADROP:
2843   case HOVER_ACT_SEL_TGT:
2844     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
2845     update_unit_info_label(get_units_in_focus());
2846 
2847     keyboardless_goto_button_down = FALSE;
2848     keyboardless_goto_active = FALSE;
2849     keyboardless_goto_start_tile = NULL;
2850     break;
2851   case HOVER_NONE:
2852     break;
2853   };
2854 }
2855 
2856 /**************************************************************************
2857   Center the mapview on the player's capital, or print a failure message.
2858 **************************************************************************/
key_center_capital(void)2859 void key_center_capital(void)
2860 {
2861   struct city *capital = player_capital(client_player());
2862 
2863   if (capital)  {
2864     /* Center on the tile, and pop up the crosshair overlay. */
2865     center_tile_mapcanvas(capital->tile);
2866     put_cross_overlay_tile(capital->tile);
2867   } else {
2868     create_event(NULL, E_BAD_COMMAND, ftc_client,
2869                  _("Oh my! You seem to have no capital!"));
2870   }
2871 }
2872 
2873 /**************************************************************************
2874   Handle user 'end turn' input.
2875 **************************************************************************/
key_end_turn(void)2876 void key_end_turn(void)
2877 {
2878   send_turn_done();
2879 }
2880 
2881 /**************************************************************************
2882   Recall the previous focus unit(s).  See store_previous_focus().
2883 **************************************************************************/
key_recall_previous_focus_unit(void)2884 void key_recall_previous_focus_unit(void)
2885 {
2886   int i = 0;
2887 
2888   /* Could use unit_list_copy here instead. Just having safe genlists
2889    * wouldn't be sufficient since we don't want to skip units already
2890    * removed from focus... */
2891   unit_list_iterate_safe(previous_focus, punit) {
2892     if (i == 0) {
2893       unit_focus_set(punit);
2894     } else {
2895       unit_focus_add(punit);
2896     }
2897     i++;
2898   } unit_list_iterate_safe_end;
2899 }
2900 
2901 /**************************************************************************
2902   Move the focus unit in the given direction.  Here directions are
2903   defined according to the GUI, so that north is "up" in the interface.
2904 **************************************************************************/
key_unit_move(enum direction8 gui_dir)2905 void key_unit_move(enum direction8 gui_dir)
2906 {
2907   unit_list_iterate(get_units_in_focus(), punit) {
2908     enum direction8 map_dir = gui_to_map_dir(gui_dir);
2909 
2910     request_move_unit_direction(punit, map_dir);
2911   } unit_list_iterate_end;
2912 }
2913 
2914 /**************************************************************************
2915   Handle use 'build city' input.
2916 **************************************************************************/
key_unit_build_city(void)2917 void key_unit_build_city(void)
2918 {
2919   unit_list_iterate(get_units_in_focus(), punit) {
2920     request_unit_build_city(punit);
2921   } unit_list_iterate_end;
2922 }
2923 
2924 /**************************************************************************
2925   Handle user 'help build wonder' input
2926 **************************************************************************/
key_unit_build_wonder(void)2927 void key_unit_build_wonder(void)
2928 {
2929   unit_list_iterate(get_units_in_focus(), punit) {
2930     if (unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2931       request_unit_caravan_action(punit, ACTION_HELP_WONDER);
2932     }
2933   } unit_list_iterate_end;
2934 }
2935 
2936 /**************************************************************************
2937 handle user pressing key for 'Connect' command
2938 **************************************************************************/
key_unit_connect(enum unit_activity activity,struct extra_type * tgt)2939 void key_unit_connect(enum unit_activity activity,
2940                       struct extra_type *tgt)
2941 {
2942   request_unit_connect(activity, tgt);
2943 }
2944 
2945 /**************************************************************************
2946   Handle user 'Do...' input
2947 **************************************************************************/
key_unit_action_select(void)2948 void key_unit_action_select(void)
2949 {
2950   struct tile *ptile;
2951 
2952   unit_list_iterate(get_units_in_focus(), punit) {
2953     if (utype_may_act_at_all(unit_type_get(punit))
2954         && (ptile = unit_tile(punit))) {
2955       /* Have the server record that an action decision is wanted for this
2956        * unit. */
2957       request_do_action(ACTION_COUNT, punit->id, tile_index(ptile),
2958                         ACTSIG_QUEUE);
2959     }
2960   } unit_list_iterate_end;
2961 }
2962 
2963 /**************************************************************************
2964   Have the user select what action the unit(s) in focus should perform to
2965   the targets at the tile the user will specify by clicking on it.
2966 
2967   Will stop asking for a target tile and have each actor unit act against
2968   its own tile if called twice.
2969 **************************************************************************/
key_unit_action_select_tgt(void)2970 void key_unit_action_select_tgt(void)
2971 {
2972   struct unit_list *punits = get_units_in_focus();
2973 
2974   if (hover_state == HOVER_ACT_SEL_TGT) {
2975     /* The 2nd key press means that the actor should target its own
2976      * tile. */
2977     key_unit_action_select();
2978 
2979     /* Target tile selected. Clean up hover state. */
2980     set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, NULL, ORDER_LAST);
2981     update_unit_info_label(punits);
2982 
2983     return;
2984   }
2985 
2986   set_hover_state(punits, HOVER_ACT_SEL_TGT, ACTIVITY_LAST, NULL,
2987                   ORDER_LAST);
2988 }
2989 
2990 /**************************************************************************
2991   Handle user 'unit done' input
2992 **************************************************************************/
key_unit_done(void)2993 void key_unit_done(void)
2994 {
2995   request_unit_move_done();
2996 }
2997 
2998 /**************************************************************************
2999   Handle user 'unit goto' input
3000 **************************************************************************/
key_unit_goto(void)3001 void key_unit_goto(void)
3002 {
3003   request_unit_goto(ORDER_LAST);
3004 }
3005 
3006 /**************************************************************************
3007 Explode nuclear at a tile without enemy units
3008 **************************************************************************/
key_unit_nuke(void)3009 void key_unit_nuke(void)
3010 {
3011   request_unit_nuke(get_units_in_focus());
3012 }
3013 
3014 /**************************************************************************
3015   Handle user 'paradrop' input
3016 **************************************************************************/
key_unit_paradrop(void)3017 void key_unit_paradrop(void)
3018 {
3019   request_unit_paradrop(get_units_in_focus());
3020 }
3021 
3022 /**************************************************************************
3023   Handle user 'patrol' input
3024 **************************************************************************/
key_unit_patrol(void)3025 void key_unit_patrol(void)
3026 {
3027   request_unit_patrol();
3028 }
3029 
3030 /**************************************************************************
3031   Handle user 'establish traderoute' input
3032 **************************************************************************/
key_unit_trade_route(void)3033 void key_unit_trade_route(void)
3034 {
3035   unit_list_iterate(get_units_in_focus(), punit) {
3036     /* TODO: Is falling back on ACTION_MARKETPLACE if not able to establish
3037      * a trade route trade a good idea or an unplecant surprice? */
3038     if (unit_can_do_action(punit, ACTION_TRADE_ROUTE)) {
3039       request_unit_caravan_action(punit, ACTION_TRADE_ROUTE);
3040     }
3041   } unit_list_iterate_end;
3042 }
3043 
3044 /**************************************************************************
3045   Handle user 'unload all' input
3046 **************************************************************************/
key_unit_unload_all(void)3047 void key_unit_unload_all(void)
3048 {
3049   struct unit *pnext_focus = NULL, *plast;
3050 
3051   unit_list_iterate(get_units_in_focus(), punit) {
3052     if ((plast = request_unit_unload_all(punit))) {
3053       pnext_focus = plast;
3054     }
3055   } unit_list_iterate_end;
3056 
3057   if (pnext_focus) {
3058     unit_list_iterate(get_units_in_focus(), punit) {
3059       /* Unfocus the ships, and advance the focus to the last unloaded unit.
3060        * If there is no unit unloaded (which shouldn't happen, but could if
3061        * the caller doesn't check if the transporter is loaded), the we
3062        * don't do anything. */
3063       punit->client.focus_status = FOCUS_WAIT;
3064     } unit_list_iterate_end;
3065     unit_focus_set(pnext_focus);
3066   }
3067 }
3068 
3069 /**************************************************************************
3070   Handle user 'wait' input
3071 **************************************************************************/
key_unit_wait(void)3072 void key_unit_wait(void)
3073 {
3074   request_units_wait(get_units_in_focus());
3075 }
3076 
3077 /**************************************************************************
3078   Handle user 'wakeup others' input
3079 ***************************************************************************/
key_unit_wakeup_others(void)3080 void key_unit_wakeup_others(void)
3081 {
3082   unit_list_iterate(get_units_in_focus(), punit) {
3083     request_unit_wakeup(punit);
3084   } unit_list_iterate_end;
3085 }
3086 
3087 /**************************************************************************
3088   Handle user 'build base of class airbase' input
3089 **************************************************************************/
key_unit_airbase(void)3090 void key_unit_airbase(void)
3091 {
3092   unit_list_iterate(get_units_in_focus(), punit) {
3093     struct base_type *pbase =
3094       get_base_by_gui_type(BASE_GUI_AIRBASE, punit, unit_tile(punit));
3095 
3096     if (pbase) {
3097       struct extra_type *pextra = base_extra_get(pbase);
3098 
3099       request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
3100     }
3101   } unit_list_iterate_end;
3102 }
3103 
3104 /**************************************************************************
3105   Handle user 'autoexplore' input
3106 **************************************************************************/
key_unit_auto_explore(void)3107 void key_unit_auto_explore(void)
3108 {
3109   unit_list_iterate(get_units_in_focus(), punit) {
3110     if (can_unit_do_activity(punit, ACTIVITY_EXPLORE)) {
3111       request_new_unit_activity(punit, ACTIVITY_EXPLORE);
3112     }
3113   } unit_list_iterate_end;
3114 }
3115 
3116 /**************************************************************************
3117   Call to request (from the server) that the focus unit is put into
3118   autosettler mode.
3119 **************************************************************************/
key_unit_auto_settle(void)3120 void key_unit_auto_settle(void)
3121 {
3122   unit_list_iterate(get_units_in_focus(), punit) {
3123     if (can_unit_do_autosettlers(punit)) {
3124       request_unit_autosettlers(punit);
3125     }
3126   } unit_list_iterate_end;
3127 }
3128 
3129 /**************************************************************************
3130   Unit convert key pressed or respective menu entry selected.
3131 **************************************************************************/
key_unit_convert(void)3132 void key_unit_convert(void)
3133 {
3134   unit_list_iterate(get_units_in_focus(), punit) {
3135     request_unit_convert(punit);
3136   } unit_list_iterate_end;
3137 }
3138 
3139 /**************************************************************************
3140   Handle user 'clean fallout' input
3141 **************************************************************************/
key_unit_fallout(void)3142 void key_unit_fallout(void)
3143 {
3144   key_unit_clean(ACTIVITY_FALLOUT, ERM_CLEANFALLOUT);
3145 }
3146 
3147 /**************************************************************************
3148   Handle user 'fortify' input
3149 **************************************************************************/
key_unit_fortify(void)3150 void key_unit_fortify(void)
3151 {
3152   unit_list_iterate(get_units_in_focus(), punit) {
3153     if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) {
3154       request_new_unit_activity(punit, ACTIVITY_FORTIFYING);
3155     }
3156   } unit_list_iterate_end;
3157 }
3158 
3159 /**************************************************************************
3160   Handle user 'build base of class fortress' input
3161 **************************************************************************/
key_unit_fortress(void)3162 void key_unit_fortress(void)
3163 {
3164   unit_list_iterate(get_units_in_focus(), punit) {
3165     struct base_type *pbase =
3166       get_base_by_gui_type(BASE_GUI_FORTRESS, punit, unit_tile(punit));
3167 
3168     if (pbase) {
3169       struct extra_type *pextra = base_extra_get(pbase);
3170 
3171       request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
3172     }
3173   } unit_list_iterate_end;
3174 }
3175 
3176 /**************************************************************************
3177   Handle user 'change homecity' input
3178 **************************************************************************/
key_unit_homecity(void)3179 void key_unit_homecity(void)
3180 {
3181   unit_list_iterate(get_units_in_focus(), punit) {
3182     request_unit_change_homecity(punit);
3183   } unit_list_iterate_end;
3184 }
3185 
3186 /**************************************************************************
3187   Handle user extra building input of given type
3188 **************************************************************************/
key_unit_extra(enum unit_activity act,enum extra_cause cause)3189 static void key_unit_extra(enum unit_activity act, enum extra_cause cause)
3190 {
3191   unit_list_iterate(get_units_in_focus(), punit) {
3192     struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
3193                                                  cause,
3194                                                  unit_owner(punit),
3195                                                  punit);
3196 
3197     if (can_unit_do_activity_targeted(punit, act, tgt)) {
3198       request_new_unit_activity_targeted(punit, act, tgt);
3199     }
3200   } unit_list_iterate_end;
3201 }
3202 
3203 /**************************************************************************
3204   Handle user extra cleaning input of given type
3205 **************************************************************************/
key_unit_clean(enum unit_activity act,enum extra_rmcause rmcause)3206 static void key_unit_clean(enum unit_activity act, enum extra_rmcause rmcause)
3207 {
3208   unit_list_iterate(get_units_in_focus(), punit) {
3209     struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
3210                                                 rmcause,
3211                                                 unit_owner(punit),
3212                                                 punit);
3213 
3214     if (tgt != NULL
3215         && can_unit_do_activity_targeted(punit, act, tgt)) {
3216       request_new_unit_activity_targeted(punit, act, tgt);
3217     }
3218   } unit_list_iterate_end;
3219 }
3220 
3221 /**************************************************************************
3222   Handle user 'irrigate' input
3223 **************************************************************************/
key_unit_irrigate(void)3224 void key_unit_irrigate(void)
3225 {
3226   key_unit_extra(ACTIVITY_IRRIGATE, EC_IRRIGATION);
3227 }
3228 
3229 /**************************************************************************
3230   Handle user 'build mine' input
3231 **************************************************************************/
key_unit_mine(void)3232 void key_unit_mine(void)
3233 {
3234   key_unit_extra(ACTIVITY_MINE, EC_MINE);
3235 }
3236 
3237 /**************************************************************************
3238   Handle user 'pillage' input
3239 **************************************************************************/
key_unit_pillage(void)3240 void key_unit_pillage(void)
3241 {
3242   unit_list_iterate(get_units_in_focus(), punit) {
3243     if (can_unit_do_activity(punit, ACTIVITY_PILLAGE)) {
3244       request_unit_pillage(punit);
3245     }
3246   } unit_list_iterate_end;
3247 }
3248 
3249 /**************************************************************************
3250   Handle user 'clean pollution' input
3251 **************************************************************************/
key_unit_pollution(void)3252 void key_unit_pollution(void)
3253 {
3254   key_unit_clean(ACTIVITY_POLLUTION, ERM_CLEANPOLLUTION);
3255 }
3256 
3257 /**************************************************************************
3258   Handle user 'build road or railroad' input
3259 **************************************************************************/
key_unit_road(void)3260 void key_unit_road(void)
3261 {
3262   unit_list_iterate(get_units_in_focus(), punit) {
3263     struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
3264                                                  EC_ROAD,
3265                                                  unit_owner(punit),
3266                                                  punit);
3267 
3268     if (tgt != NULL
3269         && can_unit_do_activity_targeted(punit, ACTIVITY_GEN_ROAD, tgt)) {
3270       request_new_unit_activity_targeted(punit, ACTIVITY_GEN_ROAD, tgt);
3271     }
3272   } unit_list_iterate_end;
3273 }
3274 
3275 /**************************************************************************
3276   Handle user 'sentry' input
3277 **************************************************************************/
key_unit_sentry(void)3278 void key_unit_sentry(void)
3279 {
3280   unit_list_iterate(get_units_in_focus(), punit) {
3281     if (can_unit_do_activity(punit, ACTIVITY_SENTRY)) {
3282       request_new_unit_activity(punit, ACTIVITY_SENTRY);
3283     }
3284   } unit_list_iterate_end;
3285 }
3286 
3287 /**************************************************************************
3288   Handle user 'transform unit' input
3289 **************************************************************************/
key_unit_transform(void)3290 void key_unit_transform(void)
3291 {
3292   unit_list_iterate(get_units_in_focus(), punit) {
3293     if (can_unit_do_activity(punit, ACTIVITY_TRANSFORM)) {
3294       request_new_unit_activity(punit, ACTIVITY_TRANSFORM);
3295     }
3296   } unit_list_iterate_end;
3297 }
3298 
3299 /****************************************************************************
3300   Assign all focus units to this battlegroup.
3301 ****************************************************************************/
key_unit_assign_battlegroup(int battlegroup,bool append)3302 void key_unit_assign_battlegroup(int battlegroup, bool append)
3303 {
3304   if (NULL != client.conn.playing && can_client_issue_orders()
3305       && battlegroups >= 0 && battlegroup < MAX_NUM_BATTLEGROUPS) {
3306     if (!append) {
3307       unit_list_iterate_safe(battlegroups[battlegroup], punit) {
3308 	if (!unit_is_in_focus(punit)) {
3309 	  punit->battlegroup = BATTLEGROUP_NONE;
3310 	  dsend_packet_unit_battlegroup(&client.conn,
3311 					punit->id, BATTLEGROUP_NONE);
3312 	  refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
3313 	  unit_list_remove(battlegroups[battlegroup], punit);
3314 	}
3315       } unit_list_iterate_safe_end;
3316     }
3317     unit_list_iterate(get_units_in_focus(), punit) {
3318       if (punit->battlegroup != battlegroup) {
3319 	if (punit->battlegroup >= 0
3320 	    && punit->battlegroup < MAX_NUM_BATTLEGROUPS) {
3321 	  unit_list_remove(battlegroups[punit->battlegroup], punit);
3322 	}
3323 	punit->battlegroup = battlegroup;
3324 	dsend_packet_unit_battlegroup(&client.conn,
3325 				      punit->id, battlegroup);
3326 	unit_list_append(battlegroups[battlegroup], punit);
3327 	refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
3328       }
3329     } unit_list_iterate_end;
3330     unit_list_iterate(battlegroups[battlegroup], punit) {
3331       unit_focus_add(punit);
3332     } unit_list_iterate_end;
3333   }
3334 }
3335 
3336 /****************************************************************************
3337   Bring this battlegroup into focus.
3338 ****************************************************************************/
key_unit_select_battlegroup(int battlegroup,bool append)3339 void key_unit_select_battlegroup(int battlegroup, bool append)
3340 {
3341   if (NULL != client.conn.playing && can_client_change_view()
3342       && battlegroups >= 0 && battlegroup < MAX_NUM_BATTLEGROUPS) {
3343     int i = 0;
3344 
3345     if (unit_list_size(battlegroups[battlegroup]) == 0 && !append) {
3346       unit_focus_set(NULL);
3347       return;
3348     }
3349 
3350     /* FIXME: this is very inefficient and can be improved. */
3351     unit_list_iterate(battlegroups[battlegroup], punit) {
3352       if (i == 0 && !append) {
3353 	unit_focus_set(punit);
3354       } else {
3355 	unit_focus_add(punit);
3356       }
3357       i++;
3358     } unit_list_iterate_end;
3359   }
3360 }
3361 
3362 /**************************************************************************
3363   Toggle drawing of city outlines.
3364 **************************************************************************/
key_city_outlines_toggle(void)3365 void key_city_outlines_toggle(void)
3366 {
3367   request_toggle_city_outlines();
3368 }
3369 
3370 /**************************************************************************
3371  Toggle drawing of city output produced by workers of the city.
3372 **************************************************************************/
key_city_output_toggle(void)3373 void key_city_output_toggle(void)
3374 {
3375   request_toggle_city_output();
3376 }
3377 
3378 /**************************************************************************
3379   Handle user 'toggle map grid' input
3380 **************************************************************************/
key_map_grid_toggle(void)3381 void key_map_grid_toggle(void)
3382 {
3383   request_toggle_map_grid();
3384 }
3385 
3386 /**************************************************************************
3387   Toggle map borders on the mapview on/off based on a keypress.
3388 **************************************************************************/
key_map_borders_toggle(void)3389 void key_map_borders_toggle(void)
3390 {
3391   request_toggle_map_borders();
3392 }
3393 
3394 /**************************************************************************
3395   Toggle native tiles on the mapview on/off based on a keypress.
3396 **************************************************************************/
key_map_native_toggle(void)3397 void key_map_native_toggle(void)
3398 {
3399   request_toggle_map_native();
3400 }
3401 
3402 /**************************************************************************
3403   Toggle the "Draw the city bar" option.
3404 **************************************************************************/
key_city_full_bar_toggle(void)3405 void key_city_full_bar_toggle(void)
3406 {
3407   request_toggle_city_full_bar();
3408 }
3409 
3410 /**************************************************************************
3411   Handle user 'toggle city names display' input
3412 **************************************************************************/
key_city_names_toggle(void)3413 void key_city_names_toggle(void)
3414 {
3415   request_toggle_city_names();
3416 }
3417 
3418 /**************************************************************************
3419   Toggles the "show city growth turns" option by passing off the
3420   request to another function...
3421 **************************************************************************/
key_city_growth_toggle(void)3422 void key_city_growth_toggle(void)
3423 {
3424   request_toggle_city_growth();
3425 }
3426 
3427 /**************************************************************************
3428   Toggles the showing of the buy cost of the current production in the
3429   city descriptions.
3430 **************************************************************************/
key_city_buycost_toggle(void)3431 void key_city_buycost_toggle(void)
3432 {
3433   request_toggle_city_buycost();
3434 }
3435 
3436 /**************************************************************************
3437   Handle user 'toggle city production display' input
3438 **************************************************************************/
key_city_productions_toggle(void)3439 void key_city_productions_toggle(void)
3440 {
3441   request_toggle_city_productions();
3442 }
3443 
3444 /**************************************************************************
3445   Handle client request to toggle drawing of trade route information
3446   by the city name for cities visible on the main map view.
3447 **************************************************************************/
key_city_trade_routes_toggle(void)3448 void key_city_trade_routes_toggle(void)
3449 {
3450   request_toggle_city_trade_routes();
3451 }
3452 
3453 /**************************************************************************
3454   Handle user 'toggle terrain display' input
3455 **************************************************************************/
key_terrain_toggle(void)3456 void key_terrain_toggle(void)
3457 {
3458   request_toggle_terrain();
3459 }
3460 
3461 /**************************************************************************
3462   Handle user 'toggle coastline display' input
3463 **************************************************************************/
key_coastline_toggle(void)3464 void key_coastline_toggle(void)
3465 {
3466   request_toggle_coastline();
3467 }
3468 
3469 /**************************************************************************
3470   Handle user 'toggle road/railroad display' input
3471 **************************************************************************/
key_roads_rails_toggle(void)3472 void key_roads_rails_toggle(void)
3473 {
3474   request_toggle_roads_rails();
3475 }
3476 
3477 /**************************************************************************
3478   Handle user 'toggle irrigation display' input
3479 **************************************************************************/
key_irrigation_toggle(void)3480 void key_irrigation_toggle(void)
3481 {
3482   request_toggle_irrigation();
3483 }
3484 
3485 /**************************************************************************
3486   Handle user 'toggle mine display' input
3487 **************************************************************************/
key_mines_toggle(void)3488 void key_mines_toggle(void)
3489 {
3490   request_toggle_mines();
3491 }
3492 
3493 /**************************************************************************
3494   Handle user 'toggle bases display' input
3495 **************************************************************************/
key_bases_toggle(void)3496 void key_bases_toggle(void)
3497 {
3498   request_toggle_bases();
3499 }
3500 
3501 /**************************************************************************
3502   Handle user 'toggle resources display' input
3503 **************************************************************************/
key_resources_toggle(void)3504 void key_resources_toggle(void)
3505 {
3506   request_toggle_resources();
3507 }
3508 
3509 /**************************************************************************
3510   Handle user 'toggle huts display' input
3511 **************************************************************************/
key_huts_toggle(void)3512 void key_huts_toggle(void)
3513 {
3514   request_toggle_huts();
3515 }
3516 
3517 /**************************************************************************
3518   Handle user 'toggle pollution display' input
3519 **************************************************************************/
key_pollution_toggle(void)3520 void key_pollution_toggle(void)
3521 {
3522   request_toggle_pollution();
3523 }
3524 
3525 /**************************************************************************
3526   Handle user 'toggle cities display' input
3527 **************************************************************************/
key_cities_toggle(void)3528 void key_cities_toggle(void)
3529 {
3530   request_toggle_cities();
3531 }
3532 
3533 /**************************************************************************
3534   Handle user 'toggle units display' input
3535 **************************************************************************/
key_units_toggle(void)3536 void key_units_toggle(void)
3537 {
3538   request_toggle_units();
3539 }
3540 
3541 /**************************************************************************
3542   Toggle the "Solid unit background color" option.
3543 **************************************************************************/
key_unit_solid_bg_toggle(void)3544 void key_unit_solid_bg_toggle(void)
3545 {
3546   request_toggle_unit_solid_bg();
3547 }
3548 
3549 /**************************************************************************
3550   Toggle the "Draw shield graphics for units" option.
3551 **************************************************************************/
key_unit_shields_toggle(void)3552 void key_unit_shields_toggle(void)
3553 {
3554   request_toggle_unit_shields();
3555 }
3556 
3557 /**************************************************************************
3558   Handle user 'toggle key units display' input
3559 **************************************************************************/
key_focus_unit_toggle(void)3560 void key_focus_unit_toggle(void)
3561 {
3562   request_toggle_focus_unit();
3563 }
3564 
3565 /**************************************************************************
3566   Handle user 'toggle fog of war display' input
3567 **************************************************************************/
key_fog_of_war_toggle(void)3568 void key_fog_of_war_toggle(void)
3569 {
3570   request_toggle_fog_of_war();
3571 }
3572 
3573 /**************************************************************************
3574   Toggle editor mode in the server.
3575 **************************************************************************/
key_editor_toggle(void)3576 void key_editor_toggle(void)
3577 {
3578   dsend_packet_edit_mode(&client.conn, !game.info.is_edit_mode);
3579 }
3580 
3581 /**************************************************************************
3582   Recalculate borders.
3583 **************************************************************************/
key_editor_recalculate_borders(void)3584 void key_editor_recalculate_borders(void)
3585 {
3586   send_packet_edit_recalculate_borders(&client.conn);
3587 }
3588 
3589 /**************************************************************************
3590   Send a request to the server to toggle fog-of-war for the current
3591   player (only applies in edit mode).
3592 **************************************************************************/
key_editor_toggle_fogofwar(void)3593 void key_editor_toggle_fogofwar(void)
3594 {
3595   if (client_has_player()) {
3596     dsend_packet_edit_toggle_fogofwar(&client.conn, client_player_number());
3597   }
3598 }
3599 
3600 /**************************************************************************
3601   All units ready to build city to the tile should now proceed.
3602 **************************************************************************/
finish_city(struct tile * ptile,const char * name)3603 void finish_city(struct tile *ptile, const char *name)
3604 {
3605   unit_list_iterate(ptile->units, punit) {
3606     if (punit->client.asking_city_name) {
3607       /* Unit will disappear only in case city building still success.
3608        * Cancel city building status just in case something has changed
3609        * to prevent city building in the meanwhile and unit will remain
3610        * alive. */
3611       punit->client.asking_city_name = FALSE;
3612       dsend_packet_unit_build_city(&client.conn, punit->id, name);
3613     }
3614   } unit_list_iterate_end;
3615 }
3616 
3617 /**************************************************************************
3618   Do not build city after all. Cancel city building mark from all units
3619   prepared for it.
3620 **************************************************************************/
cancel_city(struct tile * ptile)3621 void cancel_city(struct tile *ptile)
3622 {
3623   unit_list_iterate(ptile->units, punit) {
3624     punit->client.asking_city_name = FALSE;
3625   } unit_list_iterate_end;
3626 }
3627