Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/control.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
control.c
Go to the documentation of this file.
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 "astring.h"
20#include "bitvector.h"
21#include "fcintl.h"
22#include "log.h"
23#include "mem.h"
24#include "timing.h"
25
26/* common */
27#include "combat.h"
28#include "game.h"
29#include "map.h"
30#include "movement.h"
31#include "unitlist.h"
32
33/* common/aicore */
34#include "path_finding.h"
35
36/* client/include */
37#include "chatline_g.h"
38#include "citydlg_g.h"
39#include "dialogs_g.h"
40#include "gui_main_g.h"
41#include "mapctrl_g.h"
42#include "mapview_g.h"
43#include "menu_g.h"
44
45/* client */
46#include "audio.h"
47#include "client_main.h"
48#include "climap.h"
49#include "climisc.h"
50#include "editor.h"
51#include "goto.h"
52#include "options.h"
53#include "overview_common.h"
54#include "tilespec.h"
55#include "update_queue.h"
56
57#include "control.h"
58
59
60 struct client_disband_unit_data {
61 int unit_id;
62 int alt;
63};
64
65/* Ways to disband a unit. Sorted by preference. Starts with the worst. */
66/* TODO: Should other actions that consumes the unit be considered?
67 * Join City may be an appealing alternative. Perhaps it should be a
68 * user configurable client option? */
69 static int disband_unit_alternatives[3] = {
70 ACTION_DISBAND_UNIT,
71 ACTION_DISBAND_UNIT_RECOVER,
72 ACTION_HELP_WONDER,
73};
74
75/* gui-dep code may adjust depending on tile size etc: */
76 int num_units_below = MAX_NUM_UNITS_BELOW;
77
78/* current_focus points to the current unit(s) in focus */
79 static struct unit_list *current_focus = NULL;
80
81/* The previously focused unit(s). Focus can generally be recalled
82 * with keypad 5 (or the equivalent). */
83 static struct unit_list *previous_focus = NULL;
84
85/* The priority unit(s) for unit_focus_advance(). */
86 static struct unit_list *urgent_focus_queue = NULL;
87
88/* These should be set via set_hover_state() */
89 enum cursor_hover_state hover_state = HOVER_NONE;
90 enum unit_activity connect_activity;
91 struct extra_type *connect_tgt;
92
93 action_id goto_last_action;
94 int goto_last_tgt;
95 int goto_last_sub_tgt;
96 enum unit_orders goto_last_order; /* Last order for goto */
97
98 static struct tile *hover_tile = NULL;
99 static struct unit_list *battlegroups[MAX_NUM_BATTLEGROUPS];
100
101/* Current moving unit. */
102 static struct unit *punit_moving = NULL;
103
104/* units involved in current combat */
105 static struct unit *punit_attacking = NULL;
106 static struct unit *punit_defending = NULL;
107
108/* The ID of the unit that currently is in the action selection process.
109 *
110 * The action selection process begins when the client asks the server what
111 * actions a unit can take. It ends when the last follow up question is
112 * answered.
113 *
114 * No common client code using client supports more than one action
115 * selection process at once. The interface between the common client code
116 * and the clients would have to change before that could happen. (See
117 * action_selection_actor_unit() etc)
118 */
119 static int action_selection_in_progress_for = IDENTITY_NUMBER_ZERO;
120
121/*
122 * This variable is TRUE iff a NON-AI controlled unit was focused this
123 * turn.
124 */
125 bool non_ai_unit_focus;
126
127static void key_unit_gen_clean(enum unit_activity act, enum extra_rmcause rmcause);
128
129/*************************************************************************/
130
131static struct unit *quickselect(struct tile *ptile,
132 enum quickselect_type qtype);
133
134/**********************************************************************/
137 void control_init(void)
138{
139 int i;
140
141 current_focus = unit_list_new();
142 previous_focus = unit_list_new();
143 urgent_focus_queue = unit_list_new();
144
145 for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
146 battlegroups[i] = unit_list_new();
147 }
148 hover_tile = NULL;
149}
150
151/**********************************************************************/
154 void control_free(void)
155{
156 int i;
157
158 unit_list_destroy(current_focus);
159 current_focus = NULL;
160 unit_list_destroy(previous_focus);
161 previous_focus = NULL;
162 unit_list_destroy(urgent_focus_queue);
163 urgent_focus_queue = NULL;
164
165 for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
166 unit_list_destroy(battlegroups[i]);
167 battlegroups[i] = NULL;
168 }
169
170 clear_hover_state();
171 free_client_goto();
172}
173
174/**********************************************************************/
177 struct unit_list *get_units_in_focus(void)
178{
179 return current_focus;
180}
181
182/**********************************************************************/
185 int get_num_units_in_focus(void)
186{
187 return (NULL != current_focus ? unit_list_size(current_focus) : 0);
188}
189
190/**********************************************************************/
194 static void store_previous_focus(void)
195{
196 if (get_num_units_in_focus() > 0) {
197 unit_list_clear(previous_focus);
198 unit_list_iterate(get_units_in_focus(), punit) {
199 unit_list_append(previous_focus, punit);
200 } unit_list_iterate_end;
201 }
202}
203
204/**********************************************************************/
207 void unit_focus_urgent(struct unit *punit)
208{
209 unit_list_append(urgent_focus_queue, punit);
210}
211
212/**********************************************************************/
215 static void focus_units_changed(void)
216{
217 update_unit_info_label(get_units_in_focus());
218 menus_update();
219 /* Notify the GUI */
220 real_focus_units_changed();
221}
222
223/**********************************************************************/
226 void control_unit_killed(struct unit *punit)
227{
228 int i;
229
230 goto_unit_killed(punit);
231
232 unit_list_remove(get_units_in_focus(), punit);
233 if (get_num_units_in_focus() < 1) {
234 clear_hover_state();
235 }
236
237 unit_list_remove(previous_focus, punit);
238 unit_list_remove(urgent_focus_queue, punit);
239
240 for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
241 unit_list_remove(battlegroups[i], punit);
242 }
243
244 focus_units_changed();
245}
246
247/**********************************************************************/
250 void unit_change_battlegroup(struct unit *punit, int battlegroup)
251{
252 if (battlegroup < 0 || battlegroup >= MAX_NUM_BATTLEGROUPS) {
253 battlegroup = BATTLEGROUP_NONE;
254 }
255
256 if (punit->battlegroup != battlegroup) {
257 if (battlegroup != BATTLEGROUP_NONE) {
258 unit_list_append(battlegroups[battlegroup], punit);
259 }
260 if (punit->battlegroup != BATTLEGROUP_NONE) {
261 unit_list_remove(battlegroups[punit->battlegroup], punit);
262 }
263 punit->battlegroup = battlegroup;
264 }
265}
266
267/**********************************************************************/
270 void unit_register_battlegroup(struct unit *punit)
271{
272 if (punit->battlegroup < 0 || punit->battlegroup >= MAX_NUM_BATTLEGROUPS) {
273 punit->battlegroup = BATTLEGROUP_NONE;
274 } else {
275 unit_list_append(battlegroups[punit->battlegroup], punit);
276 }
277}
278
279/**********************************************************************/
285 void set_hover_state(struct unit_list *punits, enum cursor_hover_state state,
286 enum unit_activity activity,
287 struct extra_type *tgt,
288 int last_tgt,
289 int last_sub_tgt,
290 action_id action,
291 enum unit_orders order)
292{
293 fc_assert_ret((punits && unit_list_size(punits) > 0)
294 || state == HOVER_NONE);
295 fc_assert_ret(state == HOVER_CONNECT || activity == ACTIVITY_LAST);
296 fc_assert_ret((state == HOVER_GOTO || state == HOVER_GOTO_SEL_TGT)
297 || order == ORDER_LAST);
298 fc_assert_ret((state == HOVER_GOTO || state == HOVER_GOTO_SEL_TGT)
299 || action == ACTION_NONE);
300
301 if (!((hover_state == HOVER_GOTO || hover_state == HOVER_GOTO_SEL_TGT)
302 && (state == HOVER_GOTO || state == HOVER_GOTO_SEL_TGT))) {
303 /* Exit goto unless this is a switch between goto states */
304 exit_goto_state();
305 }
306
307 hover_state = state;
308 connect_activity = activity;
309 if (tgt) {
310 connect_tgt = tgt;
311 } else {
312 connect_tgt = NULL;
313 }
314 goto_last_order = order;
315 goto_last_action = action;
316 goto_last_tgt = last_tgt;
317 goto_last_sub_tgt = last_sub_tgt;
318}
319
320/**********************************************************************/
323 void clear_hover_state(void)
324{
325 set_hover_state(NULL, HOVER_NONE,
326 ACTIVITY_LAST, NULL,
327 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
328}
329
330/**********************************************************************/
334 bool should_ask_server_for_actions(const struct unit *punit)
335{
336 return (punit->action_decision_want == ACT_DEC_ACTIVE
337 /* The player is interested in getting a pop up for a mere
338 * arrival. */
339 || (punit->action_decision_want == ACT_DEC_PASSIVE
340 && gui_options.popup_actor_arrival));
341}
342
343/**********************************************************************/
347 static bool can_ask_server_for_actions(void)
348{
349 /* OK as long as no other unit already asked and aren't done yet. */
350 return (action_selection_in_progress_for == IDENTITY_NUMBER_ZERO
351 && action_selection_actor_unit() == IDENTITY_NUMBER_ZERO);
352}
353
354/**********************************************************************/
361 static void ask_server_for_actions(struct unit *punit)
362{
363 fc_assert_ret(punit);
364 fc_assert_ret(punit->action_decision_tile);
365
366 /* Only one action selection dialog at a time is supported. */
367 fc_assert_msg(action_selection_in_progress_for == IDENTITY_NUMBER_ZERO,
368 "Unit %d started action selection before unit %d was done",
369 action_selection_in_progress_for, punit->id);
370 action_selection_in_progress_for = punit->id;
371
372 dsend_packet_unit_get_actions(&client.conn,
373 punit->id, punit->id,
374 IDENTITY_NUMBER_ZERO,
375 IDENTITY_NUMBER_ZERO,
376 tile_index(punit->action_decision_tile),
377 EXTRA_NONE,
378 REQEST_PLAYER_INITIATED);
379}
380
381/**********************************************************************/
384 bool unit_is_in_focus(const struct unit *punit)
385{
386 return unit_list_search(get_units_in_focus(), punit) != NULL;
387}
388
389/**********************************************************************/
392 struct unit *get_focus_unit_on_tile(const struct tile *ptile)
393{
394 unit_list_iterate(get_units_in_focus(), punit) {
395 if (unit_tile(punit) == ptile) {
396 return punit;
397 }
398 } unit_list_iterate_end;
399
400 return NULL;
401}
402
403/**********************************************************************/
406 struct unit *head_of_units_in_focus(void)
407{
408 return unit_list_get(current_focus, 0);
409}
410
411/**********************************************************************/
414 static struct tile *find_a_focus_unit_tile_to_center_on(void)
415{
416 struct unit *punit;
417
418 if (NULL != (punit = get_focus_unit_on_tile(get_center_tile_mapcanvas()))) {
419 return unit_tile(punit);
420 } else if (get_num_units_in_focus() > 0) {
421 return unit_tile(head_of_units_in_focus());
422 } else {
423 return NULL;
424 }
425}
426
427/**********************************************************************/
430 void auto_center_on_focus_unit(void)
431{
432 struct tile *ptile = find_a_focus_unit_tile_to_center_on();
433
434 if (ptile && gui_options.auto_center_on_unit
435 && !tile_visible_and_not_on_border_mapcanvas(ptile)) {
436 center_tile_mapcanvas(ptile);
437 }
438}
439
440/**********************************************************************/
443 static void current_focus_append(struct unit *punit)
444{
445 unit_list_append(current_focus, punit);
446
447 punit->client.focus_status = FOCUS_AVAIL;
448 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
449
450 if (should_ask_server_for_actions(punit)
451 && can_ask_server_for_actions()) {
452 ask_server_for_actions(punit);
453 }
454
455 if (gui_options.unit_selection_clears_orders) {
456 clear_unit_orders(punit);
457 }
458}
459
460/**********************************************************************/
463 static void current_focus_remove(struct unit *punit)
464{
465 /* Close the action selection dialog if the actor unit lose focus. */
466 if (action_selection_actor_unit() == punit->id) {
467 action_selection_close();
468 }
469
470 unit_list_remove(current_focus, punit);
471 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
472}
473
474/**********************************************************************/
477 void clear_unit_orders(struct unit *punit)
478{
479 if (!punit) {
480 return;
481 }
482
483 if (punit->activity != ACTIVITY_IDLE
484 || punit->ssa_controller != SSA_NONE) {
485 punit->ssa_controller = SSA_NONE;
486 refresh_unit_city_dialogs(punit);
487 request_new_unit_activity(punit, ACTIVITY_IDLE);
488 } else if (unit_has_orders(punit)) {
489 /* Clear the focus unit's orders. */
490 request_orders_cleared(punit);
491 }
492}
493
494/**********************************************************************/
502 void unit_focus_set(struct unit *punit)
503{
504 bool focus_changed = FALSE;
505
506 if (NULL != punit
507 && NULL != client.conn.playing
508 && unit_owner(punit) != client.conn.playing) {
509 /* Callers should make sure this never happens. */
510 return;
511 }
512
513 /* FIXME: This won't work quite right; for instance activating a
514 * battlegroup twice in a row will store the focus erroneously. The only
515 * solution would be a set_units_focus() */
516 if (!(get_num_units_in_focus() == 1
517 && punit == head_of_units_in_focus())) {
518 store_previous_focus();
519 focus_changed = TRUE;
520 }
521
522 /* Close the action selection dialog if the actor unit lose focus. */
523 unit_list_iterate(current_focus, punit_old) {
524 if (action_selection_actor_unit() == punit_old->id) {
525 action_selection_close();
526 }
527 } unit_list_iterate_end;
528
529 /* Redraw the old focus unit (to fix blinking or remove the selection
530 * circle). */
531 unit_list_iterate(current_focus, punit_old) {
532 refresh_unit_mapcanvas(punit_old, unit_tile(punit_old), TRUE, FALSE);
533 } unit_list_iterate_end;
534 unit_list_clear(current_focus);
535
536 if (!can_client_change_view()) {
537 /* This function can be called to set the focus to NULL when
538 * disconnecting. In this case we don't want any other actions! */
539 fc_assert(punit == NULL);
540 return;
541 }
542
543 if (NULL != punit) {
544 current_focus_append(punit);
545 auto_center_on_focus_unit();
546 }
547
548 if (focus_changed) {
549 clear_hover_state();
550 focus_units_changed();
551 }
552}
553
554/**********************************************************************/
557 void unit_focus_add(struct unit *punit)
558{
559 if (NULL != punit
560 && NULL != client.conn.playing
561 && unit_owner(punit) != client.conn.playing) {
562 /* Callers should make sure this never happens. */
563 return;
564 }
565
566 if (NULL == punit || !can_client_change_view()) {
567 return;
568 }
569
570 if (unit_is_in_focus(punit)) {
571 return;
572 }
573
574 if (hover_state != HOVER_NONE) {
575 /* Can't continue with current goto if set of focus units
576 * change. Cancel it. */
577 clear_hover_state();
578 }
579
580 current_focus_append(punit);
581 focus_units_changed();
582}
583
584/**********************************************************************/
587 void unit_focus_remove(struct unit *punit)
588{
589 if (NULL != punit
590 && NULL != client.conn.playing
591 && unit_owner(punit) != client.conn.playing) {
592 /* Callers should make sure this never happens. */
593 return;
594 }
595
596 if (NULL == punit || !can_client_change_view()) {
597 return;
598 }
599
600 if (!unit_is_in_focus(punit)) {
601 return;
602 }
603
604 if (hover_state != HOVER_NONE) {
605 /* Can't continue with current goto if set of focus units
606 * change. Cancel it. */
607 clear_hover_state();
608 }
609
610 current_focus_remove(punit);
611 if (get_num_units_in_focus() > 0) {
612 focus_units_changed();
613 } else {
614 unit_focus_advance();
615 }
616}
617
618/**********************************************************************/
621 void unit_focus_set_and_select(struct unit *punit)
622{
623 unit_focus_set(punit);
624 if (punit) {
625 put_cross_overlay_tile(unit_tile(punit));
626 }
627}
628
629/**********************************************************************/
634 static struct unit *find_best_focus_candidate(bool accept_current)
635{
636 struct tile *ptile = get_center_tile_mapcanvas();
637
638 if (!get_focus_unit_on_tile(ptile)) {
639 struct unit *pfirst = head_of_units_in_focus();
640
641 if (pfirst) {
642 ptile = unit_tile(pfirst);
643 }
644 }
645
646 iterate_outward(&(wld.map), ptile, FC_INFINITY, ptile2) {
647 unit_list_iterate(ptile2->units, punit) {
648 if ((!unit_is_in_focus(punit) || accept_current)
649 && unit_owner(punit) == client.conn.playing
650 && punit->client.focus_status == FOCUS_AVAIL
651 && punit->activity == ACTIVITY_IDLE
652 && !unit_has_orders(punit)
653 && (punit->moves_left > 0 || unit_type_get(punit)->move_rate == 0)
654 && !punit->done_moving
655 && punit->ssa_controller == SSA_NONE) {
656 return punit;
657 }
658 } unit_list_iterate_end;
659 } iterate_outward_end;
660
661 return NULL;
662}
663
664/**********************************************************************/
671 void unit_focus_advance(void)
672{
673 struct unit *candidate = NULL;
674 const int num_units_in_old_focus = get_num_units_in_focus();
675
676 if (NULL == client.conn.playing
677 || !is_player_phase(client.conn.playing, game.info.phase)
678 || !can_client_change_view()) {
679 unit_focus_set(NULL);
680 return;
681 }
682
683 clear_hover_state();
684
685 unit_list_iterate(get_units_in_focus(), punit) {
686 /*
687 * Is the unit which just lost focus a non-AI unit? If yes this
688 * enables the auto end turn.
689 */
690 if (punit->ssa_controller == SSA_NONE) {
691 non_ai_unit_focus = TRUE;
692 break;
693 }
694 } unit_list_iterate_end;
695
696 if (unit_list_size(urgent_focus_queue) > 0) {
697 /* Try top of the urgent list. */
698 struct tile *focus_tile = (get_num_units_in_focus() > 0
699 ? unit_tile(head_of_units_in_focus())
700 : NULL);
701
702 unit_list_both_iterate(urgent_focus_queue, plink, punit) {
703 if ((ACTIVITY_IDLE != punit->activity
704 || unit_has_orders(punit))
705 /* This isn't an action decision needed because of an
706 * ORDER_ACTION_MOVE located in the middle of an order. */
707 && !should_ask_server_for_actions(punit)) {
708 /* We have assigned new orders to this unit since, remove it. */
709 unit_list_erase(urgent_focus_queue, plink);
710 } else if (NULL == focus_tile
711 || focus_tile == unit_tile(punit)) {
712 /* Use the first one found */
713 candidate = punit;
714 break;
715 } else if (NULL == candidate) {
716 candidate = punit;
717 }
718 } unit_list_both_iterate_end;
719
720 if (NULL != candidate) {
721 unit_list_remove(urgent_focus_queue, candidate);
722
723 /* Autocenter on Wakeup, regardless of the local option
724 * "auto_center_on_unit". */
725 if (!tile_visible_and_not_on_border_mapcanvas(unit_tile(candidate))) {
726 center_tile_mapcanvas(unit_tile(candidate));
727 }
728 }
729 }
730
731 if (NULL == candidate) {
732 candidate = find_best_focus_candidate(FALSE);
733
734 if (!candidate) {
735 /* Try for "waiting" units. */
736 unit_list_iterate(client.conn.playing->units, punit) {
737 if (punit->client.focus_status == FOCUS_WAIT) {
738 punit->client.focus_status = FOCUS_AVAIL;
739 }
740 } unit_list_iterate_end;
741 candidate = find_best_focus_candidate(FALSE);
742
743 if (!candidate) {
744 /* Accept current focus unit as last resort. */
745 candidate = find_best_focus_candidate(TRUE);
746 }
747 }
748 }
749
750 unit_focus_set(candidate);
751
752 /*
753 * Handle auto-turn-done mode: If a unit was in focus (did move),
754 * but now none are (no more to move) and there was at least one
755 * non-AI unit this turn which was focused, then fake a Turn Done
756 * keypress.
757 */
758 if (gui_options.auto_turn_done
759 && num_units_in_old_focus > 0
760 && get_num_units_in_focus() == 0
761 && non_ai_unit_focus) {
762 key_end_turn();
763 }
764}
765
766/**********************************************************************/
772 void unit_focus_update(void)
773{
774 if (NULL == client.conn.playing || !can_client_change_view()) {
775 return;
776 }
777
778 if (!can_ask_server_for_actions()) {
779 fc_assert(get_num_units_in_focus() > 0);
780
781 /* An actor unit is asking the player what to do. Don't change the
782 * focus. */
783 return;
784 }
785
786 /* iterate zero times for no units in focus,
787 * otherwise quit for any of the conditions. */
788 unit_list_iterate(get_units_in_focus(), punit) {
789 if ((punit->activity == ACTIVITY_IDLE
790 || punit->activity == ACTIVITY_GOTO
791 || unit_has_orders(punit))
792 && punit->moves_left > 0
793 && !punit->done_moving
794 && punit->ssa_controller == SSA_NONE) {
795 return;
796 }
797 } unit_list_iterate_end;
798
799 unit_focus_advance();
800}
801
802/**********************************************************************/
805 struct unit *find_visible_unit(struct tile *ptile)
806{
807 struct unit *panyowned = NULL, *panyother = NULL, *ptptother = NULL;
808
809 /* If no units here, return nothing. */
810 if (unit_list_size(ptile->units) == 0) {
811 return NULL;
812 }
813
814 /* If a unit is attacking we should show that on top */
815 if (punit_attacking && same_pos(unit_tile(punit_attacking), ptile)) {
816 unit_list_iterate(ptile->units, punit) {
817 if (punit == punit_attacking) {
818 return punit;
819 }
820 } unit_list_iterate_end;
821 }
822
823 /* If a unit is defending we should show that on top */
824 if (punit_defending && same_pos(unit_tile(punit_defending), ptile)) {
825 unit_list_iterate(ptile->units, punit) {
826 if (punit == punit_defending) {
827 return punit;
828 }
829 } unit_list_iterate_end;
830 }
831
832 /* If the unit in focus is at this tile, show that on top */
833 unit_list_iterate(get_units_in_focus(), punit) {
834 if (punit != punit_moving && unit_tile(punit) == ptile) {
835 return punit;
836 }
837 } unit_list_iterate_end;
838
839 /* If a city is here, return nothing (unit hidden by city). */
840 if (tile_city(ptile)) {
841 return NULL;
842 }
843
844 /* Iterate through the units to find the best one we prioritize this way:
845 1: owned transporter.
846 2: any owned unit
847 3: any transporter
848 4: any unit
849 (always return first in stack). */
850 unit_list_iterate(ptile->units, punit)
851 if (unit_owner(punit) == client.conn.playing) {
852 if (!unit_transported(punit)) {
853 if (get_transporter_capacity(punit) > 0) {
854 return punit;
855 } else if (!panyowned) {
856 panyowned = punit;
857 }
858 }
859 } else if (!ptptother && !unit_transported(punit)) {
860 if (get_transporter_capacity(punit) > 0) {
861 ptptother = punit;
862 } else if (!panyother) {
863 panyother = punit;
864 }
865 }
866 unit_list_iterate_end;
867
868 return (panyowned ? panyowned : (ptptother ? ptptother : panyother));
869}
870
871/**********************************************************************/
875 double blink_active_unit(void)
876{
877 static struct timer *blink_timer = NULL;
878 const double blink_time = get_focus_unit_toggle_timeout(tileset);
879
880 if (get_num_units_in_focus() > 0) {
881 if (!blink_timer || timer_read_seconds(blink_timer) > blink_time) {
882 toggle_focus_unit_state(tileset);
883
884 /* If we lag, we don't try to catch up. Instead we just start a
885 * new blink_time on every update. */
886 blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE);
887 timer_start(blink_timer);
888
889 unit_list_iterate(get_units_in_focus(), punit) {
890 /* We used to unqueue here, but that's inherently risky
891 * for a function run from a timer - the UI can be in any
892 * inconsistent state. */
893 refresh_unit_mapcanvas(punit, unit_tile(punit), FALSE, FALSE);
894 } unit_list_iterate_end;
895 }
896
897 return blink_time - timer_read_seconds(blink_timer);
898 }
899
900 return blink_time;
901}
902
903/**********************************************************************/
907 double blink_turn_done_button(void)
908{
909 static struct timer *blink_timer = NULL;
910 const double blink_time = 0.5; /* half-second blink interval */
911
912 if (NULL != client.conn.playing
913 && client.conn.playing->is_alive
914 && !client.conn.playing->phase_done
915 && is_player_phase(client.conn.playing, game.info.phase)) {
916 if (!blink_timer || timer_read_seconds(blink_timer) > blink_time) {
917 int is_waiting = 0, is_moving = 0;
918 bool blocking_mode;
919 struct option *opt;
920
921 opt = optset_option_by_name(server_optset, "turnblock");
922 if (opt != NULL) {
923 blocking_mode = option_bool_get(opt);
924 } else {
925 blocking_mode = FALSE;
926 }
927
928 players_iterate_alive(pplayer) {
929 if ((pplayer->is_connected || blocking_mode)
930 && is_player_phase(pplayer, game.info.phase)) {
931 if (pplayer->phase_done) {
932 is_waiting++;
933 } else {
934 is_moving++;
935 }
936 }
937 } players_iterate_alive_end;
938
939 if (is_moving == 1 && is_waiting > 0) {
940 update_turn_done_button(FALSE); /* stress the slow player! */
941 }
942 blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE);
943 timer_start(blink_timer);
944 }
945 return blink_time - timer_read_seconds(blink_timer);
946 }
947
948 return blink_time;
949}
950
951/**********************************************************************/
966 void update_unit_pix_label(struct unit_list *punitlist)
967{
968 int i;
969
970 /* Check for any change in the unit's state. This assumes that a unit's
971 * orders cannot be changed directly but must be removed and then reset. */
972 if (punitlist && unit_list_size(punitlist) > 0
973 && C_S_OVER != client_state()) {
974 /* There used to be a complicated and bug-prone check here to see if
975 * the unit had actually changed. This was misguided since the stacked
976 * units (below) are redrawn in any case. Unless we write a general
977 * system for unit updates here we might as well just redraw it every
978 * time. */
979 struct unit *punit = unit_list_get(punitlist, 0);
980
981 set_unit_icon(-1, punit);
982
983 i = 0; /* index into unit_below_canvas */
984 unit_list_iterate(unit_tile(punit)->units, aunit) {
985 if (aunit != punit) {
986 if (i < num_units_below) {
987 set_unit_icon(i, aunit);
988 }
989 i++;
990 }
991 }
992 unit_list_iterate_end;
993
994 if (i > num_units_below) {
995 set_unit_icons_more_arrow(TRUE);
996 } else {
997 set_unit_icons_more_arrow(FALSE);
998 for (; i < num_units_below; i++) {
999 set_unit_icon(i, NULL);
1000 }
1001 }
1002 } else {
1003 for (i = -1; i < num_units_below; i++) {
1004 set_unit_icon(i, NULL);
1005 }
1006 set_unit_icons_more_arrow(FALSE);
1007 }
1008}
1009
1010/**********************************************************************/
1013 void set_units_in_combat(struct unit *pattacker, struct unit *pdefender)
1014{
1015 punit_attacking = pattacker;
1016 punit_defending = pdefender;
1017
1018 if (unit_is_in_focus(punit_attacking)
1019 || unit_is_in_focus(punit_defending)) {
1020 /* If one of the units is the focus unit, make sure hidden-focus is
1021 * disabled. We don't just do this as a check later because then
1022 * with a blinking unit it would just disappear again right after the
1023 * battle. */
1024 focus_unit_in_combat(tileset);
1025 }
1026}
1027
1028/**********************************************************************/
1032 void action_selection_no_longer_in_progress(const int old_actor_id)
1033{
1034 /* IDENTITY_NUMBER_ZERO is accepted for cases where the unit is gone
1035 * without a trace. */
1036 fc_assert_msg(old_actor_id == action_selection_in_progress_for
1037 || old_actor_id == IDENTITY_NUMBER_ZERO
1038 || action_selection_in_progress_for == IDENTITY_NUMBER_ZERO,
1039 "Decision taken for %d but selection is for %d.",
1040 old_actor_id, action_selection_in_progress_for);
1041
1042 /* Stop objecting to allowing the next unit to ask. */
1043 action_selection_in_progress_for = IDENTITY_NUMBER_ZERO;
1044
1045 /* Clean up any client specific assumptions. */
1046 action_selection_no_longer_in_progress_gui_specific(old_actor_id);
1047}
1048
1049/**********************************************************************/
1053 void action_decision_clear_want(const int old_actor_id)
1054{
1055 if (game_unit_by_number(old_actor_id) != NULL) {
1056 /* Have the server record that a decision no longer is wanted. */
1057 dsend_packet_unit_sscs_set(&client.conn, old_actor_id, old_actor_id,
1058 USSDT_UNQUEUE, IDENTITY_NUMBER_ZERO);
1059 }
1060}
1061
1062/**********************************************************************/
1065 void action_selection_next_in_focus(const int old_actor_id)
1066{
1067 struct unit *old;
1068
1069 old = game_unit_by_number(old_actor_id);
1070
1071 /* Go to the next unit in focus that needs a decision. */
1072 unit_list_iterate(get_units_in_focus(), funit) {
1073 if (old != funit && should_ask_server_for_actions(funit)) {
1074 ask_server_for_actions(funit);
1075 return;
1076 }
1077 } unit_list_iterate_end;
1078}
1079
1080/**********************************************************************/
1083 void action_decision_request(struct unit *actor_unit)
1084{
1085 fc_assert_ret(actor_unit);
1086 fc_assert_ret(actor_unit->action_decision_tile);
1087
1088 if (!unit_is_in_focus(actor_unit)) {
1089 /* Getting feed back may be urgent. A unit standing next to an enemy
1090 * could be killed while waiting. */
1091 unit_focus_urgent(actor_unit);
1092 } else if (can_client_issue_orders()
1093 && can_ask_server_for_actions()) {
1094 /* No need to wait. The actor unit is in focus. No other actor unit
1095 * is currently asking about action selection. */
1096 ask_server_for_actions(actor_unit);
1097 }
1098}
1099
1100/**********************************************************************/
1103 void request_unit_goto(enum unit_orders last_order,
1104 action_id act_id, int sub_tgt_id)
1105{
1106 struct unit_list *punits = get_units_in_focus();
1107
1108 fc_assert_ret(act_id == ACTION_NONE
1109 || last_order == ORDER_PERFORM_ACTION);
1110
1111 if (unit_list_size(punits) == 0) {
1112 return;
1113 }
1114
1115 if (last_order == ORDER_PERFORM_ACTION) {
1116 /* An action has been specified. */
1117 fc_assert_ret(action_id_exists(act_id));
1118
1119 unit_list_iterate(punits, punit) {
1120 if (!unit_can_do_action(punit, act_id)) {
1121 /* This unit can't perform the action specified in the last
1122 * order. */
1123
1124 struct astring astr = ASTRING_INIT;
1125
1126 if (role_units_translations(&astr,
1127 action_id_get_role(act_id),
1128 TRUE)) {
1129 /* ...but other units can perform it. */
1130
1131 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1132 /* TRANS: Only Nuclear or ICBM can do Explode
1133 * Nuclear. */
1134 _("Only %s can do %s."),
1135 astr_str(&astr),
1136 action_id_name_translation(act_id));
1137
1138 astr_free(&astr);
1139 } else {
1140 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1141 /* TRANS: Spy can't do Explode Nuclear. */
1142 _("%s can't do %s."),
1143 unit_name_translation(punit),
1144 action_id_name_translation(act_id));
1145 }
1146
1147 return;
1148 }
1149 } unit_list_iterate_end;
1150 }
1151
1152 if (hover_state != HOVER_GOTO && hover_state != HOVER_GOTO_SEL_TGT) {
1153 set_hover_state(punits, HOVER_GOTO, ACTIVITY_LAST, NULL,
1154 NO_TARGET, sub_tgt_id, act_id, last_order);
1155 enter_goto_state(punits);
1156 create_line_at_mouse_pos();
1157 update_unit_info_label(punits);
1158 control_mouse_cursor(NULL);
1159 } else {
1160 fc_assert_ret(goto_is_active());
1161 /* Adding a long range action in the middle isn't handled yet */
1162 fc_assert_ret(hover_state != HOVER_GOTO_SEL_TGT);
1163 goto_add_waypoint();
1164 }
1165}
1166
1167/**********************************************************************/
1170 static bool can_units_attack_at(struct unit_list *punits,
1171 const struct tile *ptile)
1172{
1173 unit_list_iterate(punits, punit) {
1174 if (is_attack_unit(punit)
1175 && can_unit_attack_tile(punit, NULL, ptile)) {
1176 return TRUE;
1177 }
1178 } unit_list_iterate_end;
1179
1180 return FALSE;
1181}
1182
1183/**********************************************************************/
1188 void control_mouse_cursor(struct tile *ptile)
1189{
1190 struct unit *punit = NULL;
1191 struct city *pcity = NULL;
1192 struct unit_list *active_units = get_units_in_focus();
1193 enum cursor_type mouse_cursor_type = CURSOR_DEFAULT;
1194
1195 if (!gui_options.enable_cursor_changes) {
1196 return;
1197 }
1198
1199 if (C_S_RUNNING != client_state()) {
1200 update_mouse_cursor(CURSOR_DEFAULT);
1201 return;
1202 }
1203
1204 if (is_server_busy()) {
1205 /* Server will not accept any commands. */
1206 update_mouse_cursor(CURSOR_WAIT);
1207 return;
1208 }
1209
1210 if (!ptile) {
1211 if (hover_tile) {
1212 /* hover_tile is the tile that was previously under the mouse cursor. */
1213 ptile = hover_tile;
1214 } else {
1215 update_mouse_cursor(CURSOR_DEFAULT);
1216 return;
1217 }
1218 } else {
1219 hover_tile = ptile;
1220 }
1221
1222 punit = find_visible_unit(ptile);
1223 pcity = ptile ? tile_city(ptile) : NULL;
1224
1225 switch (hover_state) {
1226 case HOVER_NONE:
1227 if (NULL != punit
1228 && unit_owner(punit) == client_player()) {
1229 /* Set mouse cursor to select a unit. */
1230 mouse_cursor_type = CURSOR_SELECT;
1231 } else if (NULL != pcity
1232 && can_player_see_city_internals(client.conn.playing, pcity)) {
1233 /* Set mouse cursor to select a city. */
1234 mouse_cursor_type = CURSOR_SELECT;
1235 } else {
1236 /* Set default mouse cursor, because nothing selectable found. */
1237 }
1238 break;
1239 case HOVER_GOTO:
1240 /* Determine if the goto is valid, invalid, nuke or will attack. */
1241 if (is_valid_goto_destination(ptile)) {
1242 if (action_id_has_result_safe(goto_last_action, ACTRES_NUKE_UNITS)
1243 || action_id_has_result_safe(goto_last_action, ACTRES_NUKE)) {
1244 /* Goto results in nuclear attack. */
1245 mouse_cursor_type = CURSOR_NUKE;
1246 } else if (can_units_attack_at(active_units, ptile)) {
1247 /* Goto results in military attack. */
1248 mouse_cursor_type = CURSOR_ATTACK;
1249 } else if (is_enemy_city_tile(ptile, client.conn.playing)) {
1250 /* Goto results in attack of enemy city. */
1251 mouse_cursor_type = CURSOR_ATTACK;
1252 } else {
1253 mouse_cursor_type = CURSOR_GOTO;
1254 }
1255 } else {
1256 mouse_cursor_type = CURSOR_INVALID;
1257 }
1258 break;
1259 case HOVER_PATROL:
1260 if (is_valid_goto_destination(ptile)) {
1261 mouse_cursor_type = CURSOR_PATROL;
1262 } else {
1263 mouse_cursor_type = CURSOR_INVALID;
1264 }
1265 break;
1266 case HOVER_CONNECT:
1267 if (is_valid_goto_destination(ptile)) {
1268 mouse_cursor_type = CURSOR_GOTO;
1269 } else {
1270 mouse_cursor_type = CURSOR_INVALID;
1271 }
1272 break;
1273 case HOVER_PARADROP:
1274 /* FIXME: check for invalid tiles. */
1275 mouse_cursor_type = CURSOR_PARADROP;
1276 break;
1277 case HOVER_ACT_SEL_TGT:
1278 case HOVER_GOTO_SEL_TGT:
1279 /* Select a tile to target / find targets on. */
1280 mouse_cursor_type = CURSOR_SELECT;
1281 break;
1282 };
1283
1284 update_mouse_cursor(mouse_cursor_type);
1285}
1286
1287/**********************************************************************/
1290 static bool is_activity_on_tile(struct tile *ptile,
1291 enum unit_activity activity)
1292{
1293 unit_list_iterate(ptile->units, punit) {
1294 if (punit->activity == activity) {
1295 return TRUE;
1296 }
1297 } unit_list_iterate_end;
1298
1299 return FALSE;
1300}
1301
1302/**********************************************************************/
1306 int check_recursive_road_connect(struct tile *ptile,
1307 const struct extra_type *pextra,
1308 const struct unit *punit,
1309 const struct player *pplayer, int rec)
1310{
1311 int activity_mc = 0;
1312 struct terrain *pterrain = tile_terrain(ptile);
1313 const struct civ_map *nmap = &(wld.map);
1314
1315 if (rec > MAX_EXTRA_TYPES) {
1316 return -1;
1317 }
1318
1319 if (!is_extra_caused_by(pextra, EC_ROAD)) {
1320 return -1;
1321 }
1322
1323 extra_deps_iterate(&(pextra->reqs), pdep) {
1324 if (!tile_has_extra(ptile, pdep)) {
1325 int single_mc;
1326
1327 single_mc = check_recursive_road_connect(ptile, pdep, punit,
1328 pplayer, rec + 1);
1329
1330 if (single_mc < 0) {
1331 return -1;
1332 }
1333
1334 activity_mc += single_mc;
1335 }
1336 } extra_deps_iterate_end;
1337
1338 /* Can build road after that? */
1339 if (punit != NULL) {
1340 if (!can_build_road(nmap, extra_road_get(pextra), punit, ptile)) {
1341 return -1;
1342 }
1343 } else if (pplayer != NULL) {
1344 if (!player_can_build_road(nmap, extra_road_get(pextra),
1345 pplayer, ptile)) {
1346 return -1;
1347 }
1348 }
1349
1350 tile_add_extra(ptile, pextra);
1351
1352 activity_mc += terrain_extra_build_time(pterrain, ACTIVITY_GEN_ROAD, pextra);
1353
1354 return activity_mc;
1355}
1356
1357/*******************************************************************/
1361 static bool can_be_irrigated(const struct tile *ptile,
1362 const struct unit *punit)
1363{
1364 struct terrain* pterrain = tile_terrain(ptile);
1365 struct universal for_unit = { .kind = VUT_UTYPE,
1366 .value.utype = unit_type_get(punit)};
1367 struct universal for_tile = { .kind = VUT_TERRAIN,
1368 .value.terrain = tile_terrain(ptile)};
1369
1370 if (T_UNKNOWN == pterrain) {
1371 return FALSE;
1372 }
1373
1374 return action_id_univs_not_blocking(ACTION_IRRIGATE,
1375 &for_unit, &for_tile);
1376}
1377
1378/**********************************************************************/
1384 bool can_unit_do_connect(struct unit *punit,
1385 enum unit_activity activity,
1386 struct extra_type *tgt)
1387{
1388 struct tile *ptile = unit_tile(punit);
1389 struct road_type *proad = NULL;
1390 const struct req_context unit_ctxt = {
1391 .unit = punit,
1392 .unittype = unit_type_get(punit),
1393 };
1394
1395 /* HACK: This code duplicates that in
1396 * can_unit_do_activity_targeted_at(). The general logic here is that
1397 * the connect is allowed if both:
1398 * (1) the unit can do that activity type, in general
1399 * (2) either
1400 * (a) the activity has already been completed at this tile
1401 * (b) it can be done by the unit at this tile. */
1402 switch (activity) {
1403 case ACTIVITY_GEN_ROAD:
1404 {
1405 struct tile *vtile;
1406 int build_time;
1407
1408 fc_assert(is_extra_caused_by(tgt, EC_ROAD));
1409
1410 proad = extra_road_get(tgt);
1411
1412 if (tile_has_road(ptile, proad)) {
1413 /* This tile has road, can unit build road to other tiles too? */
1414 return are_reqs_active(&unit_ctxt, NULL, &tgt->reqs, RPT_POSSIBLE);
1415 }
1416
1417 /* To start connect, unit must be able to build road to this
1418 * particular tile. */
1419 vtile = tile_virtual_new(ptile);
1420 build_time = check_recursive_road_connect(vtile, tgt, punit, NULL, 0);
1421 tile_virtual_destroy(vtile);
1422
1423 return build_time >= 0;
1424 }
1425
1426 case ACTIVITY_IRRIGATE:
1427 /* Special case for irrigation: only irrigate to make S_IRRIGATION,
1428 * never to transform tiles. */
1429 if (!unit_has_type_flag(punit, UTYF_SETTLERS)) {
1430 return FALSE;
1431 }
1432 if (tile_has_extra(ptile, tgt)) {
1433 return are_reqs_active(&unit_ctxt, NULL, &tgt->reqs, RPT_POSSIBLE);
1434 }
1435
1436 return can_be_irrigated(ptile, punit)
1437 && can_build_extra(tgt, punit, ptile)
1438 && !is_activity_on_tile(ptile,
1439 ACTIVITY_MINE);
1440 default:
1441 break;
1442 }
1443
1444 return FALSE;
1445}
1446
1447/**********************************************************************/
1451 void request_unit_connect(enum unit_activity activity,
1452 struct extra_type *tgt)
1453{
1454 struct unit_list *punits = get_units_in_focus();
1455
1456 if (!can_units_do_connect(punits, activity, tgt)) {
1457 return;
1458 }
1459
1460 if (hover_state != HOVER_CONNECT || connect_activity != activity
1461 || (connect_tgt != tgt
1462 && (activity == ACTIVITY_GEN_ROAD
1463 || activity == ACTIVITY_IRRIGATE))) {
1464 set_hover_state(punits, HOVER_CONNECT,
1465 activity, tgt, NO_TARGET, NO_TARGET,
1466 ACTION_NONE, ORDER_LAST);
1467 enter_goto_state(punits);
1468 create_line_at_mouse_pos();
1469 update_unit_info_label(punits);
1470 control_mouse_cursor(NULL);
1471 } else {
1472 fc_assert_ret(goto_is_active());
1473 goto_add_waypoint();
1474 }
1475}
1476
1477/**********************************************************************/
1480 struct unit *request_unit_unload_all(struct unit *punit)
1481{
1482 struct tile *ptile = unit_tile(punit);
1483 struct unit *plast = NULL;
1484
1485 if (get_transporter_capacity(punit) == 0) {
1486 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1487 _("Only transporter units can be unloaded."));
1488 return NULL;
1489 }
1490
1491 unit_list_iterate(ptile->units, pcargo) {
1492 if (unit_transport_get(pcargo) == punit) {
1493 request_unit_unload(pcargo);
1494
1495 if (pcargo->activity == ACTIVITY_SENTRY) {
1496 dsend_packet_unit_sscs_set(&client.conn, pcargo->id, pcargo->id,
1497 USSDT_SENTRY, 0);
1498 }
1499
1500 if (unit_owner(pcargo) == unit_owner(punit)) {
1501 plast = pcargo;
1502 }
1503 }
1504 } unit_list_iterate_end;
1505
1506 return plast;
1507}
1508
1509/**********************************************************************/
1512 void request_unit_airlift(struct unit *punit, struct city *pcity)
1513{
1514 request_do_action(ACTION_AIRLIFT, punit->id, pcity->id, 0, "");
1515}
1516
1517/**********************************************************************/
1521 void request_unit_return(struct unit *punit)
1522{
1523 struct pf_path *path;
1524
1525 if ((path = path_to_nearest_allied_city(punit))) {
1526 int turns = pf_path_last_position(path)->turn;
1527 int max_hp = unit_type_get(punit)->hp;
1528
1529 if (punit->hp + turns *
1530 (get_unit_bonus(punit, EFT_UNIT_RECOVER)
1531 - (max_hp * unit_class_get(punit)->hp_loss_pct / 100))
1532 < max_hp) {
1533 struct unit_order order;
1534
1535 order.order = ORDER_ACTIVITY;
1536 order.dir = DIR8_ORIGIN;
1537 order.activity = ACTIVITY_SENTRY;
1538 order.target = NO_TARGET;
1539 order.sub_target = NO_TARGET;
1540 order.action = ACTION_NONE;
1541 send_goto_path(punit, path, &order);
1542 } else {
1543 send_goto_path(punit, path, NULL);
1544 }
1545 pf_path_destroy(path);
1546 }
1547}
1548
1549/**********************************************************************/
1552 void wakeup_sentried_units(struct tile *ptile)
1553{
1554 if (!can_client_issue_orders()) {
1555 return;
1556 }
1557 unit_list_iterate(ptile->units, punit) {
1558 if (punit->activity == ACTIVITY_SENTRY
1559 && unit_owner(punit) == client.conn.playing) {
1560 request_new_unit_activity(punit, ACTIVITY_IDLE);
1561 }
1562 }
1563 unit_list_iterate_end;
1564}
1565
1566/**********************************************************************/
1569 void request_unit_wakeup(struct unit *punit)
1570{
1571 wakeup_sentried_units(unit_tile(punit));
1572}
1573
1574/**************************************************************************
1575 Defines specific hash tables needed for request_unit_select().
1576**************************************************************************/
1577#define SPECHASH_TAG unit_type
1578#define SPECHASH_IKEY_TYPE struct unit_type *
1579#define SPECHASH_IDATA_TYPE void *
1580#include "spechash.h"
1581
1582#define SPECHASH_TAG continent
1583#define SPECHASH_INT_KEY_TYPE
1584#define SPECHASH_IDATA_TYPE void *
1585#include "spechash.h"
1586
1587/**********************************************************************/
1590 void request_unit_select(struct unit_list *punits,
1591 enum unit_select_type_mode seltype,
1592 enum unit_select_location_mode selloc)
1593{
1594 const struct player *pplayer;
1595 const struct tile *ptile;
1596 struct unit *punit_first;
1597 struct tile_hash *tile_table;
1598 struct unit_type_hash *type_table;
1599 struct continent_hash *cont_table;
1600
1601 if (!can_client_change_view() || !punits
1602 || unit_list_size(punits) < 1) {
1603 return;
1604 }
1605
1606 punit_first = unit_list_get(punits, 0);
1607
1608 if (seltype == SELTYPE_SINGLE) {
1609 unit_focus_set(punit_first);
1610 return;
1611 }
1612
1613 pplayer = unit_owner(punit_first);
1614 tile_table = tile_hash_new();
1615 type_table = unit_type_hash_new();
1616 cont_table = continent_hash_new();
1617
1618 unit_list_iterate(punits, punit) {
1619 if (seltype == SELTYPE_SAME) {
1620 unit_type_hash_insert(type_table, unit_type_get(punit), NULL);
1621 }
1622
1623 ptile = unit_tile(punit);
1624 if (selloc == SELLOC_TILE) {
1625 tile_hash_insert(tile_table, ptile, NULL);
1626 } else if (selloc == SELLOC_CONT) {
1627 continent_hash_insert(cont_table, tile_continent(ptile), NULL);
1628 }
1629 } unit_list_iterate_end;
1630
1631 if (selloc == SELLOC_TILE) {
1632 tile_hash_iterate(tile_table, hash_tile) {
1633 unit_list_iterate(hash_tile->units, punit) {
1634 if (unit_owner(punit) != pplayer) {
1635 continue;
1636 }
1637 if (seltype == SELTYPE_SAME
1638 && !unit_type_hash_lookup(type_table, unit_type_get(punit), NULL)) {
1639 continue;
1640 }
1641 unit_focus_add(punit);
1642 } unit_list_iterate_end;
1643 } tile_hash_iterate_end;
1644 } else {
1645 unit_list_iterate(pplayer->units, punit) {
1646 ptile = unit_tile(punit);
1647 if ((seltype == SELTYPE_SAME
1648 && !unit_type_hash_lookup(type_table, unit_type_get(punit), NULL))
1649 || (selloc == SELLOC_CONT
1650 && !continent_hash_lookup(cont_table, tile_continent(ptile),
1651 NULL))) {
1652 continue;
1653 }
1654
1655 unit_focus_add(punit);
1656 } unit_list_iterate_end;
1657 }
1658
1659 tile_hash_destroy(tile_table);
1660 unit_type_hash_destroy(type_table);
1661 continent_hash_destroy(cont_table);
1662}
1663
1664/**********************************************************************/
1675 void request_do_action(action_id action, int actor_id,
1676 int target_id, int sub_tgt, const char *name)
1677{
1678 struct unit *actor_unit = game_unit_by_number(actor_id);
1679
1680 /* Giving an order takes back control. */
1681 request_unit_ssa_set(actor_unit, SSA_NONE);
1682
1683 dsend_packet_unit_do_action(&client.conn,
1684 actor_id, actor_id, target_id, sub_tgt, name,
1685 action);
1686}
1687
1688/**********************************************************************/
1695 void request_action_details(action_id action, int actor_id,
1696 int target_id)
1697{
1698 dsend_packet_unit_action_query(&client.conn,
1699 actor_id, actor_id, target_id, action,
1700 /* Users that need the answer in the
1701 * background should send the packet them
1702 * self. At least for now. */
1703 REQEST_PLAYER_INITIATED);
1704}
1705
1706/**********************************************************************/
1714 void request_unit_build_city(struct unit *punit)
1715{
1716 struct city *pcity;
1717
1718 if ((pcity = tile_city(unit_tile(punit)))) {
1719 /* Try to join the city. */
1720 request_do_action(ACTION_JOIN_CITY, punit->id, pcity->id, 0, "");
1721 } else {
1722 /* The reply will trigger a dialog to name the new city. */
1723 dsend_packet_city_name_suggestion_req(&client.conn, punit->id, punit->id);
1724 }
1725}
1726
1727/**********************************************************************/
1733 void request_unit_non_action_move(struct unit *punit,
1734 struct tile *dest_tile)
1735{
1736 struct packet_unit_orders p;
1737 int dir;
1738
1739 dir = get_direction_for_step(&(wld.map), unit_tile(punit), dest_tile);
1740
1741 if (dir == -1) {
1742 /* The unit isn't located next to the destination tile. */
1743 return;
1744 }
1745
1746 memset(&p, 0, sizeof(p));
1747
1748 p.repeat = FALSE;
1749 p.vigilant = FALSE;
1750
1751 p.unit_id32 = punit->id;
1752 p.unit_id16 = p.unit_id32;
1753 p.src_tile = tile_index(unit_tile(punit));
1754 p.dest_tile = tile_index(dest_tile);
1755
1756 p.length = 1;
1757 p.orders[0].order = ORDER_MOVE;
1758 p.orders[0].dir = dir;
1759 p.orders[0].activity = ACTIVITY_LAST;
1760 p.orders[0].target = NO_TARGET;
1761 p.orders[0].sub_target = NO_TARGET;
1762 p.orders[0].action = ACTION_NONE;
1763
1764 request_unit_ssa_set(punit, SSA_NONE);
1765 send_packet_unit_orders(&client.conn, &p);
1766}
1767
1768/**********************************************************************/
1777 void request_move_unit_direction(struct unit *punit, int dir)
1778{
1779 struct packet_unit_orders p;
1780 struct tile *dest_tile;
1781
1782 /* Catches attempts to move off map */
1783 dest_tile = mapstep(&(wld.map), unit_tile(punit), dir);
1784 if (!dest_tile) {
1785 return;
1786 }
1787
1788 if (!can_unit_exist_at_tile(&(wld.map), punit, dest_tile)) {
1789 if (request_transport(punit, dest_tile)) {
1790 return;
1791 }
1792 }
1793
1794 /* The goto system isn't used to send the order because that would
1795 * prevent direction movement from overriding it.
1796 * Example of a situation when overriding the goto system is useful:
1797 * The goto system creates a longer path to make a move legal. The player
1798 * wishes to order the illegal move so the server will explain why the
1799 * short move is illegal. */
1800
1801 memset(&p, 0, sizeof(p));
1802
1803 p.repeat = FALSE;
1804 p.vigilant = FALSE;
1805
1806 p.unit_id32 = punit->id;
1807 p.unit_id16 = p.unit_id32;
1808 p.src_tile = tile_index(unit_tile(punit));
1809 p.dest_tile = tile_index(dest_tile);
1810
1811 p.length = 1;
1812 p.orders[0].order = (gui_options.popup_last_move_to_allied
1813 ? ORDER_ACTION_MOVE : ORDER_MOVE);
1814 p.orders[0].dir = dir;
1815 p.orders[0].activity = ACTIVITY_LAST;
1816 p.orders[0].target = NO_TARGET;
1817 p.orders[0].sub_target = NO_TARGET;
1818 p.orders[0].action = ACTION_NONE;
1819
1820 request_unit_ssa_set(punit, SSA_NONE);
1821 send_packet_unit_orders(&client.conn, &p);
1822}
1823
1824/**********************************************************************/
1828 void request_new_unit_activity(struct unit *punit, enum unit_activity act)
1829{
1830 request_new_unit_activity_targeted(punit, act, NULL);
1831}
1832
1833/**********************************************************************/
1837 void request_new_unit_activity_targeted(struct unit *punit,
1838 enum unit_activity act,
1839 struct extra_type *tgt)
1840{
1841 if (!can_client_issue_orders()) {
1842 return;
1843 }
1844
1845 /* Callers rely on this to take back control from server side agents. */
1846 request_unit_ssa_set(punit, SSA_NONE);
1847
1848 if (tgt == NULL) {
1849 dsend_packet_unit_change_activity(&client.conn, punit->id, punit->id,
1850 act, EXTRA_NONE);
1851 } else {
1852 dsend_packet_unit_change_activity(&client.conn, punit->id, punit->id,
1853 act, extra_index(tgt));
1854 }
1855}
1856
1857/**********************************************************************/
1860 static void client_disband_unit_data_destroy(void *p)
1861{
1862 struct client_disband_unit_data *data = p;
1863
1864 free(data);
1865}
1866
1867/**********************************************************************/
1870 static void do_disband_alternative(void *p)
1871{
1872 struct unit *punit;
1873 struct city *pcity;
1874 struct tile *ptile;
1875 int last_request_id_used;
1876 struct client_disband_unit_data *next;
1877 struct client_disband_unit_data *data = p;
1878 int act;
1879 const struct civ_map *nmap = &(wld.map);
1880
1881 fc_assert_ret(can_client_issue_orders());
1882
1883 /* Fetch the unit to get rid of. */
1884 punit = player_unit_by_number(client_player(), data->unit_id);
1885
1886 if (punit == NULL) {
1887 /* Success! It is gone. */
1888 return;
1889 }
1890
1891 if (data->alt == -1) {
1892 /* All alternatives have been tried. */
1893 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1894 /* TRANS: Unable to get rid of Leader. */
1895 _("Unable to get rid of %s."),
1896 unit_name_translation(punit));
1897 return;
1898 }
1899
1900 act = disband_unit_alternatives[data->alt];
1901
1902 /* Prepare the data for the next try in case this try fails. */
1903 next = fc_malloc(sizeof(struct client_disband_unit_data));
1904 next->unit_id = data->unit_id;
1905 next->alt = data->alt - 1;
1906
1907 /* Latest request ID before trying to send a request. */
1908 last_request_id_used = client.conn.client.last_request_id_used;
1909
1910 /* Send a request to the server unless it is known to be pointless. */
1911 switch (action_id_get_target_kind(act)) {
1912 case ATK_CITY:
1913 if ((pcity = tile_city(unit_tile(punit)))
1914 && action_prob_possible(action_prob_vs_city(nmap, punit,
1915 act, pcity))) {
1916 request_do_action(act, punit->id, pcity->id, 0, "");
1917 }
1918 break;
1919 case ATK_UNIT:
1920 if (action_prob_possible(action_prob_vs_unit(nmap, punit, act, punit))) {
1921 request_do_action(act, punit->id, punit->id, 0, "");
1922 }
1923 break;
1924 case ATK_UNITS:
1925 if ((ptile = unit_tile(punit))
1926 && action_prob_possible(action_prob_vs_units(punit, act, ptile))) {
1927 request_do_action(act, punit->id, ptile->index, 0, "");
1928 }
1929 break;
1930 case ATK_TILE:
1931 if ((ptile = unit_tile(punit))
1932 && action_prob_possible(action_prob_vs_tile(punit, act, ptile, NULL))) {
1933 request_do_action(act, punit->id, ptile->index, 0, "");
1934 }
1935 break;
1936 case ATK_EXTRAS:
1937 if ((ptile = unit_tile(punit))
1938 && action_prob_possible(action_prob_vs_extras(punit, act,
1939 ptile, NULL))) {
1940 request_do_action(act, punit->id, ptile->index, 0, "");
1941 }
1942 break;
1943 case ATK_SELF:
1944 if (action_prob_possible(action_prob_self(punit, act))) {
1945 request_do_action(act, punit->id, punit->id, 0, "");
1946 }
1947 break;
1948 case ATK_COUNT:
1949 fc_assert(action_id_get_target_kind(act) != ATK_COUNT);
1950 break;
1951 }
1952
1953 if (last_request_id_used != client.conn.client.last_request_id_used) {
1954 /* A request was sent. */
1955
1956 /* Check if it worked. Move on if it didn't. */
1957 update_queue_connect_processing_finished_full
1958 (client.conn.client.last_request_id_used,
1959 do_disband_alternative, next,
1960 client_disband_unit_data_destroy);
1961 } else {
1962 /* No request was sent. */
1963
1964 /* Move on. */
1965 do_disband_alternative(next);
1966
1967 /* Won't be freed by anyone else. */
1968 client_disband_unit_data_destroy(next);
1969 }
1970}
1971
1972/**********************************************************************/
1975 void request_unit_disband(struct unit *punit)
1976{
1977 struct client_disband_unit_data *data;
1978
1979 /* Set up disband data. Start at the end of the array. */
1980 data = fc_malloc(sizeof(struct client_disband_unit_data));
1981 data->unit_id = punit->id;
1982 data->alt = 2;
1983
1984 /* Begin. */
1985 do_disband_alternative(data);
1986
1987 /* Won't be freed by anyone else. */
1988 client_disband_unit_data_destroy(data);
1989}
1990
1991/**********************************************************************/
1994 void request_unit_change_homecity(struct unit *punit)
1995{
1996 struct city *pcity=tile_city(unit_tile(punit));
1997
1998 if (pcity) {
1999 request_do_action(ACTION_HOME_CITY, punit->id, pcity->id, 0, "");
2000 }
2001}
2002
2003/**********************************************************************/
2006 void request_unit_upgrade(struct unit *punit)
2007{
2008 struct city *pcity=tile_city(unit_tile(punit));
2009
2010 if (pcity) {
2011 request_do_action(ACTION_UPGRADE_UNIT, punit->id, pcity->id, 0, "");
2012 }
2013}
2014
2015/**********************************************************************/
2018 void request_unit_convert(struct unit *punit)
2019{
2020 request_new_unit_activity(punit, ACTIVITY_CONVERT);
2021}
2022
2023/**********************************************************************/
2028 void request_unit_ssa_set(const struct unit *punit,
2029 enum server_side_agent agent)
2030{
2031 if (punit) {
2032 dsend_packet_unit_server_side_agent_set(&client.conn, punit->id, punit->id,
2033 agent);
2034 }
2035}
2036
2037/**********************************************************************/
2041 void request_unit_autosettlers(const struct unit *punit)
2042{
2043 if (punit && can_unit_do_autosettlers(punit)) {
2044 request_unit_ssa_set(punit, SSA_AUTOSETTLER);
2045 } else if (punit) {
2046 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
2047 _("Only settler units can be put into auto mode."));
2048 }
2049}
2050
2051/**********************************************************************/
2056 void request_unit_load(struct unit *pcargo, struct unit *ptrans,
2057 struct tile *ptile)
2058{
2059 if (!ptrans) {
2060 ptrans = transporter_for_unit(pcargo);
2061 }
2062
2063 if (ptrans
2064 && can_client_issue_orders()
2065 && could_unit_load(pcargo, ptrans)) {
2066 action_by_result_iterate(paction,
2067 same_pos(unit_tile(pcargo), ptile)
2068 ? ACTRES_TRANSPORT_BOARD
2069 : ACTRES_TRANSPORT_EMBARK) {
2070 if (action_prob_possible(action_prob_vs_unit(&(wld.map), pcargo, paction->id,
2071 ptrans))) {
2072 /* Try the first action that may be legal. */
2073 /* Implement something like do_disband_alternative() if a ruleset
2074 * appears where this isn't good enough. */
2075 request_do_action(paction->id, pcargo->id, ptrans->id, 0, "");
2076 break;
2077 }
2078 } action_by_result_iterate_end;
2079
2080 /* Sentry the unit. */
2081 /* FIXME: Should not sentry if above loading fails (transport moved away,
2082 * or filled already in server side) */
2083 dsend_packet_unit_sscs_set(&client.conn, pcargo->id, pcargo->id,
2084 USSDT_SENTRY, 1);
2085 }
2086}
2087
2088/**********************************************************************/
2092 void request_unit_unload(struct unit *pcargo)
2093{
2094 struct unit *ptrans = unit_transport_get(pcargo);
2095
2096 if (can_client_issue_orders()
2097 && ptrans
2098 && can_unit_unload(pcargo, ptrans)
2099 && can_unit_survive_at_tile(&(wld.map), pcargo, unit_tile(pcargo))) {
2100 if (unit_owner(pcargo) == client.conn.playing) {
2101 request_do_action(ACTION_TRANSPORT_ALIGHT,
2102 pcargo->id, ptrans->id, 0, "");
2103 } else {
2104 request_do_action(ACTION_TRANSPORT_UNLOAD,
2105 ptrans->id, pcargo->id, 0, "");
2106 }
2107
2108 if (unit_owner(pcargo) == client.conn.playing
2109 && pcargo->activity == ACTIVITY_SENTRY) {
2110 /* Activate the unit. */
2111 dsend_packet_unit_sscs_set(&client.conn, pcargo->id, pcargo->id,
2112 USSDT_SENTRY, 0);
2113 }
2114 }
2115}
2116
2117/**********************************************************************/
2121 void request_unit_caravan_action(struct unit *punit, action_id action)
2122{
2123 struct city *target_city;
2124
2125 if (!((target_city = tile_city(unit_tile(punit))))) {
2126 return;
2127 }
2128
2129 if (action == ACTION_TRADE_ROUTE) {
2130 request_do_action(ACTION_TRADE_ROUTE, punit->id,
2131 target_city->id, 0, "");
2132 } else if (action == ACTION_HELP_WONDER) {
2133 request_do_action(ACTION_HELP_WONDER, punit->id,
2134 target_city->id, 0, "");
2135 } else {
2136 log_error("request_unit_caravan_action() Bad action (%d)", action);
2137 }
2138}
2139
2140/**********************************************************************/
2144 void request_unit_paradrop(struct unit_list *punits)
2145{
2146 bool can = FALSE;
2147 struct tile *offender = NULL;
2148
2149 if (unit_list_size(punits) == 0) {
2150 return;
2151 }
2152 unit_list_iterate(punits, punit) {
2153 if (can_unit_paradrop(&(wld.map), punit)) {
2154 can = TRUE;
2155 break;
2156 }
2157 if (!offender) { /* Take first offender tile/unit */
2158 offender = unit_tile(punit);
2159 }
2160 } unit_list_iterate_end;
2161 if (can) {
2162 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
2163 ftc_client,
2164 /* TRANS: paradrop target tile. */
2165 _("Click on a tile to paradrop to it."));
2166
2167 set_hover_state(punits, HOVER_PARADROP, ACTIVITY_LAST, NULL,
2168 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
2169 update_unit_info_label(punits);
2170 } else {
2171 create_event(offender, E_BAD_COMMAND, ftc_client,
2172 _("Only paratrooper units can do this."));
2173 }
2174}
2175
2176/**********************************************************************/
2179 void request_unit_patrol(void)
2180{
2181 struct unit_list *punits = get_units_in_focus();
2182
2183 if (unit_list_size(punits) == 0) {
2184 return;
2185 }
2186
2187 if (hover_state != HOVER_PATROL) {
2188 set_hover_state(punits, HOVER_PATROL, ACTIVITY_LAST, NULL,
2189 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
2190 update_unit_info_label(punits);
2191 enter_goto_state(punits);
2192 create_line_at_mouse_pos();
2193 } else {
2194 fc_assert_ret(goto_is_active());
2195 goto_add_waypoint();
2196 }
2197}
2198
2199/**********************************************************************/
2202 void request_unit_sentry(struct unit *punit)
2203{
2204 if (punit->activity != ACTIVITY_SENTRY
2205 && can_unit_do_activity_client(punit, ACTIVITY_SENTRY)) {
2206 request_new_unit_activity(punit, ACTIVITY_SENTRY);
2207 }
2208}
2209
2210/**********************************************************************/
2213 void request_unit_fortify(struct unit *punit)
2214{
2215 if (punit->activity != ACTIVITY_FORTIFYING
2216 && can_unit_do_activity_client(punit, ACTIVITY_FORTIFYING)) {
2217 request_new_unit_activity(punit, ACTIVITY_FORTIFYING);
2218 }
2219}
2220
2221/**********************************************************************/
2224 void request_unit_pillage(struct unit *punit)
2225{
2226 if (!game.info.pillage_select) {
2227 /* Leave choice up to the server */
2228 request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, NULL);
2229 } else {
2230 bv_extras pspossible;
2231 int count = 0;
2232
2233 BV_CLR_ALL(pspossible);
2234 extra_type_iterate(potential) {
2235 if (can_unit_do_activity_targeted_client(punit, ACTIVITY_PILLAGE,
2236 potential)) {
2237 BV_SET(pspossible, extra_index(potential));
2238 count++;
2239 }
2240 } extra_type_iterate_end;
2241
2242 if (count > 1) {
2243 popup_pillage_dialog(punit, pspossible);
2244 } else {
2245 /* Should be only one choice... */
2246 struct extra_type *target = get_preferred_pillage(pspossible);
2247
2248 if (target != NULL) {
2249 request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, target);
2250 }
2251 }
2252 }
2253}
2254
2255/**********************************************************************/
2258 void request_toggle_city_outlines(void)
2259{
2260 if (!can_client_change_view()) {
2261 return;
2262 }
2263
2264 gui_options.draw_city_outlines = !gui_options.draw_city_outlines;
2265 update_map_canvas_visible();
2266}
2267
2268/**********************************************************************/
2271 void request_toggle_city_output(void)
2272{
2273 if (!can_client_change_view()) {
2274 return;
2275 }
2276
2277 gui_options.draw_city_output = !gui_options.draw_city_output;
2278 update_map_canvas_visible();
2279}
2280
2281/**********************************************************************/
2284 void request_toggle_map_grid(void)
2285{
2286 if (!can_client_change_view()) {
2287 return;
2288 }
2289
2290 gui_options.draw_map_grid ^= 1;
2291 update_map_canvas_visible();
2292}
2293
2294/**********************************************************************/
2297 void request_toggle_map_borders(void)
2298{
2299 if (!can_client_change_view()) {
2300 return;
2301 }
2302
2303 gui_options.draw_borders ^= 1;
2304 update_map_canvas_visible();
2305}
2306
2307/**********************************************************************/
2310 void request_toggle_map_native(void)
2311{
2312 if (!can_client_change_view()) {
2313 return;
2314 }
2315
2316 gui_options.draw_native ^= 1;
2317 update_map_canvas_visible();
2318}
2319
2320/**********************************************************************/
2323 void request_toggle_city_full_bar(void)
2324{
2325 if (!can_client_change_view()) {
2326 return;
2327 }
2328
2329 gui_options.draw_full_citybar ^= 1;
2330 update_map_canvas_visible();
2331}
2332
2333/**********************************************************************/
2336 void request_toggle_city_names(void)
2337{
2338 if (!can_client_change_view()) {
2339 return;
2340 }
2341
2342 gui_options.draw_city_names ^= 1;
2343 update_map_canvas_visible();
2344}
2345
2346/**********************************************************************/
2349 void request_toggle_city_growth(void)
2350{
2351 if (!can_client_change_view()) {
2352 return;
2353 }
2354
2355 gui_options.draw_city_growth ^= 1;
2356 update_map_canvas_visible();
2357}
2358
2359/**********************************************************************/
2362 void request_toggle_city_productions(void)
2363{
2364 if (!can_client_change_view()) {
2365 return;
2366 }
2367
2368 gui_options.draw_city_productions ^= 1;
2369 update_map_canvas_visible();
2370}
2371
2372/**********************************************************************/
2375 void request_toggle_city_buycost(void)
2376{
2377 if (!can_client_change_view()) {
2378 return;
2379 }
2380
2381 gui_options.draw_city_buycost ^= 1;
2382 update_map_canvas_visible();
2383}
2384
2385/**********************************************************************/
2388 void request_toggle_city_trade_routes(void)
2389{
2390 if (!can_client_change_view()) {
2391 return;
2392 }
2393
2394 gui_options.draw_city_trade_routes ^= 1;
2395 update_map_canvas_visible();
2396}
2397
2398/**********************************************************************/
2401 void request_toggle_unit_stack_size(void)
2402{
2403 if (!can_client_change_view()) {
2404 return;
2405 }
2406
2407 gui_options.draw_unit_stack_size ^= 1;
2408 update_map_canvas_visible();
2409}
2410
2411/**********************************************************************/
2414 void request_toggle_terrain(void)
2415{
2416 if (!can_client_change_view()) {
2417 return;
2418 }
2419
2420 gui_options.draw_terrain ^= 1;
2421 update_map_canvas_visible();
2422}
2423
2424/**********************************************************************/
2427 void request_toggle_coastline(void)
2428{
2429 if (!can_client_change_view()) {
2430 return;
2431 }
2432
2433 gui_options.draw_coastline ^= 1;
2434 update_map_canvas_visible();
2435}
2436
2437/**********************************************************************/
2440 void request_toggle_roads_rails(void)
2441{
2442 if (!can_client_change_view()) {
2443 return;
2444 }
2445
2446 gui_options.draw_roads_rails ^= 1;
2447 update_map_canvas_visible();
2448}
2449
2450/**********************************************************************/
2453 void request_toggle_irrigation(void)
2454{
2455 if (!can_client_change_view()) {
2456 return;
2457 }
2458
2459 gui_options.draw_irrigation ^= 1;
2460 update_map_canvas_visible();
2461}
2462
2463/**********************************************************************/
2466 void request_toggle_mines(void)
2467{
2468 if (!can_client_change_view()) {
2469 return;
2470 }
2471
2472 gui_options.draw_mines ^= 1;
2473 update_map_canvas_visible();
2474}
2475
2476/**********************************************************************/
2479 void request_toggle_bases(void)
2480{
2481 if (!can_client_change_view()) {
2482 return;
2483 }
2484
2485 gui_options.draw_fortress_airbase ^= 1;
2486 update_map_canvas_visible();
2487}
2488
2489/**********************************************************************/
2492 void request_toggle_resources(void)
2493{
2494 if (!can_client_change_view()) {
2495 return;
2496 }
2497
2498 gui_options.draw_specials ^= 1;
2499 update_map_canvas_visible();
2500}
2501
2502/**********************************************************************/
2505 void request_toggle_huts(void)
2506{
2507 if (!can_client_change_view()) {
2508 return;
2509 }
2510
2511 gui_options.draw_huts ^= 1;
2512 update_map_canvas_visible();
2513}
2514
2515/**********************************************************************/
2518 void request_toggle_pollution(void)
2519{
2520 if (!can_client_change_view()) {
2521 return;
2522 }
2523
2524 gui_options.draw_pollution ^= 1;
2525 update_map_canvas_visible();
2526}
2527
2528/**********************************************************************/
2531 void request_toggle_cities(void)
2532{
2533 if (!can_client_change_view()) {
2534 return;
2535 }
2536
2537 gui_options.draw_cities ^= 1;
2538 update_map_canvas_visible();
2539}
2540
2541/**********************************************************************/
2544 void request_toggle_units(void)
2545{
2546 if (!can_client_change_view()) {
2547 return;
2548 }
2549
2550 gui_options.draw_units ^= 1;
2551 update_map_canvas_visible();
2552}
2553
2554/**********************************************************************/
2557 void request_toggle_unit_solid_bg(void)
2558{
2559 if (!can_client_change_view()) {
2560 return;
2561 }
2562
2563 gui_options.solid_color_behind_units ^= 1;
2564 update_map_canvas_visible();
2565}
2566
2567/**********************************************************************/
2570 void request_toggle_unit_shields(void)
2571{
2572 if (!can_client_change_view()) {
2573 return;
2574 }
2575
2576 gui_options.draw_unit_shields ^= 1;
2577 update_map_canvas_visible();
2578}
2579
2580/**********************************************************************/
2583 void request_toggle_focus_unit(void)
2584{
2585 if (!can_client_change_view()) {
2586 return;
2587 }
2588
2589 gui_options.draw_focus_unit ^= 1;
2590 update_map_canvas_visible();
2591}
2592
2593/**********************************************************************/
2596 void request_toggle_fog_of_war(void)
2597{
2598 if (!can_client_change_view()) {
2599 return;
2600 }
2601
2602 gui_options.draw_fog_of_war ^= 1;
2603 update_map_canvas_visible();
2604 refresh_overview_canvas();
2605}
2606
2607/**********************************************************************/
2610 void request_center_focus_unit(void)
2611{
2612 struct tile *ptile = find_a_focus_unit_tile_to_center_on();
2613
2614 if (ptile) {
2615 center_tile_mapcanvas(ptile);
2616 }
2617}
2618
2619/**********************************************************************/
2623 void request_units_wait(struct unit_list *punits)
2624{
2625 unit_list_iterate(punits, punit) {
2626 punit->client.focus_status = FOCUS_WAIT;
2627 } unit_list_iterate_end;
2628 if (punits == get_units_in_focus()) {
2629 unit_focus_advance();
2630 }
2631}
2632
2633/**********************************************************************/
2636 void request_unit_move_done(void)
2637{
2638 if (get_num_units_in_focus() > 0) {
2639 enum unit_focus_status new_status = FOCUS_DONE;
2640 unit_list_iterate(get_units_in_focus(), punit) {
2641 /* If any of the focused units are busy, keep all of them
2642 * in focus; another tap of the key will dismiss them */
2643 if (punit->activity != ACTIVITY_IDLE) {
2644 new_status = FOCUS_WAIT;
2645 }
2646 } unit_list_iterate_end;
2647 unit_list_iterate(get_units_in_focus(), punit) {
2648 clear_unit_orders(punit);
2649 punit->client.focus_status = new_status;
2650 } unit_list_iterate_end;
2651 if (new_status == FOCUS_DONE) {
2652 unit_focus_advance();
2653 }
2654 }
2655}
2656
2657/**********************************************************************/
2662 void do_move_unit(struct unit *punit, struct unit *target_unit)
2663{
2664 struct tile *src_tile = unit_tile(punit);
2665 struct tile *dst_tile = unit_tile(target_unit);
2666 bool was_teleported, do_animation;
2667 bool in_focus = unit_is_in_focus(punit);
2668
2669 was_teleported = !is_tiles_adjacent(src_tile, dst_tile);
2670 do_animation = (!was_teleported && gui_options.smooth_move_unit_msec > 0);
2671
2672 if (!was_teleported
2673 && punit->activity != ACTIVITY_SENTRY
2674 && !unit_transported(punit)) {
2675 audio_play_sound(unit_type_get(punit)->sound_move,
2676 unit_type_get(punit)->sound_move_alt);
2677 }
2678
2679 if (unit_owner(punit) == client.conn.playing
2680 && gui_options.auto_center_on_unit
2681 && !unit_has_orders(punit)
2682 && punit->activity != ACTIVITY_GOTO
2683 && punit->activity != ACTIVITY_SENTRY
2684 && ((gui_options.auto_center_on_automated
2685 && punit->ssa_controller != SSA_NONE)
2686 || (punit->ssa_controller == SSA_NONE))
2687 && !tile_visible_and_not_on_border_mapcanvas(dst_tile)) {
2688 center_tile_mapcanvas(dst_tile);
2689 }
2690
2691 if (hover_state != HOVER_NONE && in_focus) {
2692 /* Cancel current goto/patrol/connect/nuke command. */
2693 clear_hover_state();
2694 update_unit_info_label(get_units_in_focus());
2695 }
2696
2697 unit_list_remove(src_tile->units, punit);
2698
2699 if (!unit_transported(punit)) {
2700 /* Mark the unit as moving unit, then find_visible_unit() won't return
2701 * it. It is especially useful to don't draw many times the unit when
2702 * refreshing the canvas. */
2703 punit_moving = punit;
2704
2705 /* We have to refresh the tile before moving. This will draw
2706 * the tile without the unit (because it was unlinked above). */
2707 refresh_unit_mapcanvas(punit, src_tile, TRUE, FALSE);
2708
2709 if (!gui_options.auto_center_on_automated
2710 && punit->ssa_controller != SSA_NONE) {
2711 /* Dont animate automatic units */
2712 } else if (do_animation) {
2713 int dx, dy;
2714
2715 /* For the duration of the animation the unit exists at neither
2716 * tile. */
2717 map_distance_vector(&dx, &dy, src_tile, dst_tile);
2718 move_unit_map_canvas(punit, src_tile, dx, dy);
2719 }
2720 }
2721
2722 unit_tile_set(punit, dst_tile);
2723 unit_list_prepend(dst_tile->units, punit);
2724
2725 if (!unit_transported(punit)) {
2726 /* For find_visible_unit(), see above. */
2727 punit_moving = NULL;
2728
2729 refresh_unit_mapcanvas(punit, dst_tile, TRUE, FALSE);
2730 }
2731
2732 /* With the "full" city bar we have to update the city bar when units move
2733 * into or out of a city. For foreign cities this is handled separately,
2734 * via the occupied field of the short-city packet. */
2735 if (NULL != tile_city(src_tile)
2736 && can_player_see_units_in_city(client.conn.playing, tile_city(src_tile))) {
2737 update_city_description(tile_city(src_tile));
2738 }
2739 if (NULL != tile_city(dst_tile)
2740 && can_player_see_units_in_city(client.conn.playing, tile_city(dst_tile))) {
2741 update_city_description(tile_city(dst_tile));
2742 }
2743
2744 if (in_focus) {
2745 menus_update();
2746 }
2747}
2748
2749/**********************************************************************/
2753 static void do_unit_act_sel_vs(struct tile *ptile)
2754{
2755 unit_list_iterate(get_units_in_focus(), punit) {
2756 if (utype_may_act_at_all(unit_type_get(punit))) {
2757 /* Have the server record that an action decision is wanted for
2758 * this unit against this tile. */
2759 dsend_packet_unit_sscs_set(&client.conn, punit->id, punit->id,
2760 USSDT_QUEUE, tile_index(ptile));
2761 }
2762 } unit_list_iterate_end;
2763}
2764
2765/**********************************************************************/
2768 void do_map_click(struct tile *ptile, enum quickselect_type qtype)
2769{
2770 struct city *pcity = tile_city(ptile);
2771 struct unit_list *punits = get_units_in_focus();
2772 bool maybe_goto = FALSE;
2773
2774 if (hover_state != HOVER_NONE) {
2775 switch (hover_state) {
2776 case HOVER_NONE:
2777 break;
2778 case HOVER_GOTO:
2779 do_unit_goto(ptile);
2780 break;
2781 case HOVER_PARADROP:
2782 unit_list_iterate(punits, punit) {
2783 do_unit_paradrop_to(punit, ptile);
2784 } unit_list_iterate_end;
2785 break;
2786 case HOVER_CONNECT:
2787 do_unit_connect(ptile, connect_activity, connect_tgt);
2788 break;
2789 case HOVER_PATROL:
2790 do_unit_patrol_to(ptile);
2791 break;
2792 case HOVER_ACT_SEL_TGT:
2793 do_unit_act_sel_vs(ptile);
2794 break;
2795 case HOVER_GOTO_SEL_TGT:
2796 fc_assert(action_id_exists(goto_last_action));
2797 do_unit_goto(ptile);
2798 break;
2799 }
2800
2801 clear_hover_state();
2802 update_unit_info_label(get_units_in_focus());
2803 } else if (qtype != SELECT_POPUP && qtype != SELECT_APPEND) {
2804 /* Bypass stack or city popup if quickselect is specified. */
2805 struct unit *qunit = quickselect(ptile, qtype);
2806
2807 if (qunit) {
2808 unit_focus_set_and_select(qunit);
2809 maybe_goto = gui_options.keyboardless_goto;
2810 }
2811 } else if (NULL != pcity
2812 && can_player_see_city_internals(client.conn.playing, pcity)) {
2813 /* Otherwise use popups. */
2814 popup_city_dialog(pcity);
2815 } else if (unit_list_size(ptile->units) == 0
2816 && NULL == pcity
2817 && get_num_units_in_focus() > 0) {
2818 maybe_goto = gui_options.keyboardless_goto;
2819 } else if (unit_list_size(ptile->units) == 1
2820 && !get_transporter_occupancy(unit_list_get(ptile->units, 0))) {
2821 struct unit *punit = unit_list_get(ptile->units, 0);
2822
2823 if (unit_owner(punit) == client.conn.playing) {
2824 if (can_unit_do_activity_client(punit, ACTIVITY_IDLE)) {
2825 maybe_goto = gui_options.keyboardless_goto;
2826 if (qtype == SELECT_APPEND) {
2827 unit_focus_add(punit);
2828 } else {
2829 unit_focus_set_and_select(punit);
2830 }
2831 }
2832 } else if (pcity) {
2833 /* Don't hide the unit in the city. */
2834 unit_select_dialog_popup(ptile);
2835 }
2836 } else if (unit_list_size(ptile->units) > 0) {
2837 /* The stack list is always popped up, even if it includes enemy units.
2838 * If the server doesn't want the player to know about them it shouldn't
2839 * tell them! The previous behavior would only pop up the stack if you
2840 * owned a unit on the tile. This gave cheating clients an advantage,
2841 * and also showed you allied units if (and only if) you had a unit on
2842 * the tile (inconsistent). */
2843 unit_select_dialog_popup(ptile);
2844 }
2845
2846 /* See mapctrl_common.c */
2847 keyboardless_goto_start_tile = maybe_goto ? ptile : NULL;
2848 keyboardless_goto_button_down = maybe_goto;
2849 keyboardless_goto_active = FALSE;
2850}
2851
2852/**********************************************************************/
2857 static struct unit *quickselect(struct tile *ptile,
2858 enum quickselect_type qtype)
2859{
2860 int listsize = unit_list_size(ptile->units);
2861 struct unit *panytransporter = NULL,
2862 *panymovesea = NULL, *panysea = NULL,
2863 *panymoveland = NULL, *panyland = NULL,
2864 *panymoveunit = NULL, *panyunit = NULL;
2865
2866 fc_assert_ret_val(qtype > SELECT_POPUP, NULL);
2867
2868 if (qtype == SELECT_FOCUS) {
2869 return head_of_units_in_focus();
2870 }
2871
2872 if (listsize == 0) {
2873 return NULL;
2874 } else if (listsize == 1) {
2875 struct unit *punit = unit_list_get(ptile->units, 0);
2876 return (unit_owner(punit) == client.conn.playing) ? punit : NULL;
2877 }
2878
2879 /* Quickselect priorities. Units with moves left
2880 * before exhausted. Focus unit is excluded.
2881 *
2882 * SEA: Transporter
2883 * Sea unit
2884 * Any unit
2885 *
2886 * LAND: Military land unit
2887 * Non-combatant
2888 * Sea unit
2889 * Any unit
2890 */
2891
2892 unit_list_iterate(ptile->units, punit) {
2893 if (unit_owner(punit) != client.conn.playing || unit_is_in_focus(punit)) {
2894 continue;
2895 }
2896 if (qtype == SELECT_SEA) {
2897 /* Transporter. */
2898 if (get_transporter_capacity(punit)) {
2899 if (punit->moves_left > 0) {
2900 return punit;
2901 } else if (!panytransporter) {
2902 panytransporter = punit;
2903 }
2904 }
2905 /* Any sea, pref. moves left. */
2906 else if (utype_move_type(unit_type_get(punit)) == UMT_SEA) {
2907 if (punit->moves_left > 0) {
2908 if (!panymovesea) {
2909 panymovesea = punit;
2910 }
2911 } else if (!panysea) {
2912 panysea = punit;
2913 }
2914 }
2915 } else if (qtype == SELECT_LAND) {
2916 if (utype_move_type(unit_type_get(punit)) == UMT_LAND) {
2917 if (punit->moves_left > 0) {
2918 if (is_military_unit(punit)) {
2919 return punit;
2920 } else if (!panymoveland) {
2921 panymoveland = punit;
2922 }
2923 } else if (!panyland) {
2924 panyland = punit;
2925 }
2926 }
2927 else if (utype_move_type(unit_type_get(punit)) == UMT_SEA) {
2928 if (punit->moves_left > 0) {
2929 panymovesea = punit;
2930 } else {
2931 panysea = punit;
2932 }
2933 }
2934 }
2935 if (punit->moves_left > 0 && !panymoveunit) {
2936 panymoveunit = punit;
2937 }
2938 if (!panyunit) {
2939 panyunit = punit;
2940 }
2941 } unit_list_iterate_end;
2942
2943 if (qtype == SELECT_SEA) {
2944 if (panytransporter) {
2945 return panytransporter;
2946 } else if (panymovesea) {
2947 return panymovesea;
2948 } else if (panysea) {
2949 return panysea;
2950 } else if (panymoveunit) {
2951 return panymoveunit;
2952 } else if (panyunit) {
2953 return panyunit;
2954 }
2955 }
2956 else if (qtype == SELECT_LAND) {
2957 if (panymoveland) {
2958 return panymoveland;
2959 } else if (panyland) {
2960 return panyland;
2961 } else if (panymovesea) {
2962 return panymovesea;
2963 } else if (panysea) {
2964 return panysea;
2965 } else if (panymoveunit) {
2966 return panymoveunit;
2967 } else if (panyunit) {
2968 return panyunit;
2969 }
2970 }
2971 return NULL;
2972}
2973
2974/**********************************************************************/
2978 void do_unit_goto(struct tile *ptile)
2979{
2980 fc_assert_ret(hover_state == HOVER_GOTO
2981 || hover_state == HOVER_GOTO_SEL_TGT);
2982 fc_assert_ret(goto_is_active());
2983
2984 if (hover_state == HOVER_GOTO_SEL_TGT) {
2985 send_goto_route();
2986 return;
2987 }
2988
2989 if (is_valid_goto_draw_line(ptile)) {
2990 send_goto_route();
2991 } else {
2992 create_event(ptile, E_BAD_COMMAND, ftc_client,
2993 _("Didn't find a route to the destination!"));
2994 }
2995}
2996
2997/**********************************************************************/
3000 void do_unit_paradrop_to(struct unit *punit, struct tile *ptile)
3001{
3002 struct action *paradrop_action = NULL;
3003
3004 action_iterate(act_id) {
3005 struct action *paction = action_by_number(act_id);
3006
3007 if (!(action_has_result(paction, ACTRES_PARADROP_CONQUER)
3008 || action_has_result(paction, ACTRES_PARADROP))) {
3009 /* Not relevant. */
3010 continue;
3011 }
3012
3013 if (action_prob_possible(
3014 action_prob_unit_vs_tgt(paction, punit,
3015 tile_city(ptile), NULL,
3016 ptile, NULL))) {
3017 if (paradrop_action == NULL) {
3018 /* This is the first possible paradrop action. */
3019 paradrop_action = paction;
3020 } else {
3021 /* More than one paradrop action may be possible. The user must
3022 * choose. Have the server record that an action decision is wanted
3023 * for this unit so the dialog will be brought up. */
3024 dsend_packet_unit_sscs_set(&client.conn, punit->id, punit->id,
3025 USSDT_QUEUE, tile_index(ptile));
3026 return;
3027 }
3028 }
3029 } action_iterate_end;
3030
3031 if (paradrop_action != NULL) {
3032 request_do_action(paradrop_action->id, punit->id,
3033 tile_index(ptile), 0 , "");
3034 }
3035}
3036
3037/**********************************************************************/
3040 void do_unit_patrol_to(struct tile *ptile)
3041{
3042 if (is_valid_goto_draw_line(ptile)
3043 && !is_non_allied_unit_tile(ptile, client.conn.playing)) {
3044 send_patrol_route();
3045 } else {
3046 create_event(ptile, E_BAD_COMMAND, ftc_client,
3047 _("Didn't find a route to the destination!"));
3048 }
3049
3050 clear_hover_state();
3051}
3052
3053/**********************************************************************/
3056 void do_unit_connect(struct tile *ptile,
3057 enum unit_activity activity,
3058 struct extra_type *tgt)
3059{
3060 if (is_valid_goto_draw_line(ptile)) {
3061 send_connect_route(activity, tgt);
3062 } else {
3063 create_event(ptile, E_BAD_COMMAND, ftc_client,
3064 _("Didn't find a route to the destination!"));
3065 }
3066
3067 clear_hover_state();
3068}
3069
3070/**********************************************************************/
3073 void key_cancel_action(void)
3074{
3075 struct unit_list *punits = get_units_in_focus();
3076 cancel_tile_hiliting();
3077
3078 switch (hover_state) {
3079 case HOVER_GOTO_SEL_TGT:
3080 set_hover_state(punits, HOVER_GOTO, connect_activity, connect_tgt,
3081 goto_last_tgt, goto_last_sub_tgt,
3082 goto_last_action, goto_last_order);
3083 break;
3084 case HOVER_GOTO:
3085 case HOVER_PATROL:
3086 case HOVER_CONNECT:
3087 if (goto_pop_waypoint()) {
3088 break;
3089 }
3090 fc__fallthrough; /* else fall through: */
3091 case HOVER_PARADROP:
3092 case HOVER_ACT_SEL_TGT:
3093 clear_hover_state();
3094 update_unit_info_label(get_units_in_focus());
3095
3096 keyboardless_goto_button_down = FALSE;
3097 keyboardless_goto_active = FALSE;
3098 keyboardless_goto_start_tile = NULL;
3099 break;
3100 case HOVER_NONE:
3101 break;
3102 };
3103}
3104
3105/**********************************************************************/
3109 void key_center_capital(void)
3110{
3111 struct city *capital = player_primary_capital(client_player());
3112
3113 if (capital) {
3114 /* Center on the tile, and pop up the crosshair overlay. */
3115 center_tile_mapcanvas(capital->tile);
3116 put_cross_overlay_tile(capital->tile);
3117 } else {
3118 create_event(NULL, E_BAD_COMMAND, ftc_client,
3119 _("Oh my! You seem to have no capital!"));
3120 }
3121}
3122
3123/**********************************************************************/
3126 void key_end_turn(void)
3127{
3128 send_turn_done();
3129}
3130
3131/**********************************************************************/
3134 void key_recall_previous_focus_unit(void)
3135{
3136 int i = 0;
3137
3138 /* Could use unit_list_copy here instead. Just having safe genlists
3139 * wouldn't be sufficient since we don't want to skip units already
3140 * removed from focus... */
3141 unit_list_iterate_safe(previous_focus, punit) {
3142 if (i == 0) {
3143 unit_focus_set(punit);
3144 } else {
3145 unit_focus_add(punit);
3146 }
3147 i++;
3148 } unit_list_iterate_safe_end;
3149}
3150
3151/**********************************************************************/
3155 void key_unit_move(enum direction8 gui_dir)
3156{
3157 unit_list_iterate(get_units_in_focus(), punit) {
3158 enum direction8 map_dir = gui_to_map_dir(gui_dir);
3159
3160 request_move_unit_direction(punit, map_dir);
3161 } unit_list_iterate_end;
3162}
3163
3164/**********************************************************************/
3167 void key_unit_build_city(void)
3168{
3169 unit_list_iterate(get_units_in_focus(), punit) {
3170 request_unit_build_city(punit);
3171 } unit_list_iterate_end;
3172}
3173
3174/**********************************************************************/
3177 void key_unit_build_wonder(void)
3178{
3179 unit_list_iterate(get_units_in_focus(), punit) {
3180 if (unit_can_do_action(punit, ACTION_HELP_WONDER)) {
3181 request_unit_caravan_action(punit, ACTION_HELP_WONDER);
3182 }
3183 } unit_list_iterate_end;
3184}
3185
3186/**********************************************************************/
3189 void key_unit_connect(enum unit_activity activity,
3190 struct extra_type *tgt)
3191{
3192 request_unit_connect(activity, tgt);
3193}
3194
3195/**********************************************************************/
3198 void key_unit_action_select(void)
3199{
3200 struct tile *ptile;
3201
3202 unit_list_iterate(get_units_in_focus(), punit) {
3203 if (utype_may_act_at_all(unit_type_get(punit))
3204 && (ptile = unit_tile(punit))) {
3205 /* Have the server record that an action decision is wanted for this
3206 * unit. */
3207 dsend_packet_unit_sscs_set(&client.conn, punit->id, punit->id,
3208 USSDT_QUEUE, tile_index(ptile));
3209 }
3210 } unit_list_iterate_end;
3211}
3212
3213/**********************************************************************/
3220 void key_unit_action_select_tgt(void)
3221{
3222 struct unit_list *punits = get_units_in_focus();
3223
3224 if (hover_state == HOVER_ACT_SEL_TGT) {
3225 /* The 2nd key press means that the actor should target its own
3226 * tile. */
3227 key_unit_action_select();
3228
3229 /* Target tile selected. Clean up hover state. */
3230 clear_hover_state();
3231 update_unit_info_label(punits);
3232
3233 return;
3234 } else if (hover_state == HOVER_GOTO_SEL_TGT) {
3235 fc_assert(action_id_exists(goto_last_action));
3236
3237 /* We don't support long range actions in the middle of orders yet so
3238 * send it at once. */
3239 send_goto_route();
3240
3241 /* Target tile selected. Clean up hover state. */
3242 clear_hover_state();
3243 update_unit_info_label(punits);
3244
3245 return;
3246 } else if (hover_state == HOVER_GOTO
3247 && action_id_exists(goto_last_action)) {
3248 struct action *paction = action_by_number(goto_last_action);
3249
3250 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
3251 ftc_client,
3252 /* TRANS: Perform action inside a goto. */
3253 _("Click on a tile to do %s against it."),
3254 action_name_translation(paction));
3255
3256 set_hover_state(punits, HOVER_GOTO_SEL_TGT,
3257 connect_activity, connect_tgt,
3258 goto_last_tgt, goto_last_sub_tgt,
3259 goto_last_action, goto_last_order);
3260
3261 return;
3262 }
3263
3264 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
3265 ftc_client,
3266 /* TRANS: "Do..." action selection dialog target. */
3267 _("Click on a tile to act against it. "
3268 "Press 'd' again to act against own tile."));
3269
3270 set_hover_state(punits, HOVER_ACT_SEL_TGT, ACTIVITY_LAST, NULL,
3271 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
3272}
3273
3274/**********************************************************************/
3277 void key_unit_done(void)
3278{
3279 request_unit_move_done();
3280}
3281
3282/**********************************************************************/
3285 void key_unit_goto(void)
3286{
3287 request_unit_goto(ORDER_LAST, ACTION_NONE, -1);
3288}
3289
3290/**********************************************************************/
3293 void key_unit_paradrop(void)
3294{
3295 request_unit_paradrop(get_units_in_focus());
3296}
3297
3298/**********************************************************************/
3301 void key_unit_patrol(void)
3302{
3303 request_unit_patrol();
3304}
3305
3306/**********************************************************************/
3309 void key_unit_trade_route(void)
3310{
3311 unit_list_iterate(get_units_in_focus(), punit) {
3312 /* TODO: Is falling back on ACTION_MARKETPLACE if not able to establish
3313 * a trade route trade a good idea or an unplecant surprice? */
3314 if (unit_can_do_action(punit, ACTION_TRADE_ROUTE)) {
3315 request_unit_caravan_action(punit, ACTION_TRADE_ROUTE);
3316 }
3317 } unit_list_iterate_end;
3318}
3319
3320/**********************************************************************/
3323 void key_unit_unload_all(void)
3324{
3325 struct unit *pnext_focus = NULL, *plast;
3326
3327 unit_list_iterate(get_units_in_focus(), punit) {
3328 if ((plast = request_unit_unload_all(punit))) {
3329 pnext_focus = plast;
3330 }
3331 } unit_list_iterate_end;
3332
3333 if (pnext_focus) {
3334 unit_list_iterate(get_units_in_focus(), punit) {
3335 /* Unfocus the ships, and advance the focus to the last unloaded unit.
3336 * If there is no unit unloaded (which shouldn't happen, but could if
3337 * the caller doesn't check if the transporter is loaded), the we
3338 * don't do anything. */
3339 punit->client.focus_status = FOCUS_WAIT;
3340 } unit_list_iterate_end;
3341 unit_focus_set(pnext_focus);
3342 }
3343}
3344
3345/**********************************************************************/
3348 void key_unit_wait(void)
3349{
3350 request_units_wait(get_units_in_focus());
3351}
3352
3353/**********************************************************************/
3356 void key_unit_wakeup_others(void)
3357{
3358 unit_list_iterate(get_units_in_focus(), punit) {
3359 request_unit_wakeup(punit);
3360 } unit_list_iterate_end;
3361}
3362
3363/**********************************************************************/
3366 void key_unit_airbase(void)
3367{
3368 unit_list_iterate(get_units_in_focus(), punit) {
3369 struct base_type *pbase =
3370 get_base_by_gui_type(BASE_GUI_AIRBASE, punit, unit_tile(punit));
3371
3372 if (pbase) {
3373 struct extra_type *pextra = base_extra_get(pbase);
3374
3375 request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
3376 }
3377 } unit_list_iterate_end;
3378}
3379
3380/**********************************************************************/
3383 void key_unit_auto_explore(void)
3384{
3385 unit_list_iterate(get_units_in_focus(), punit) {
3386 if (can_unit_do_activity_client(punit, ACTIVITY_EXPLORE)) {
3387 request_unit_ssa_set(punit, SSA_AUTOEXPLORE);
3388 }
3389 } unit_list_iterate_end;
3390}
3391
3392/**********************************************************************/
3396 void key_unit_auto_settle(void)
3397{
3398 unit_list_iterate(get_units_in_focus(), punit) {
3399 if (can_unit_do_autosettlers(punit)) {
3400 request_unit_autosettlers(punit);
3401 }
3402 } unit_list_iterate_end;
3403}
3404
3405/**********************************************************************/
3408 void key_unit_convert(void)
3409{
3410 unit_list_iterate(get_units_in_focus(), punit) {
3411 request_unit_convert(punit);
3412 } unit_list_iterate_end;
3413}
3414
3415/**********************************************************************/
3418 void key_unit_fallout(void)
3419{
3420 key_unit_gen_clean(ACTIVITY_FALLOUT, ERM_CLEANFALLOUT);
3421}
3422
3423/**********************************************************************/
3426 void key_unit_fortify(void)
3427{
3428 unit_list_iterate(get_units_in_focus(), punit) {
3429 if (can_unit_do_activity_client(punit, ACTIVITY_FORTIFYING)) {
3430 request_new_unit_activity(punit, ACTIVITY_FORTIFYING);
3431 }
3432 } unit_list_iterate_end;
3433}
3434
3435/**********************************************************************/
3438 void key_unit_fortress(void)
3439{
3440 unit_list_iterate(get_units_in_focus(), punit) {
3441 struct base_type *pbase =
3442 get_base_by_gui_type(BASE_GUI_FORTRESS, punit, unit_tile(punit));
3443
3444 if (pbase) {
3445 struct extra_type *pextra = base_extra_get(pbase);
3446
3447 request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
3448 }
3449 } unit_list_iterate_end;
3450}
3451
3452/**********************************************************************/
3455 void key_unit_homecity(void)
3456{
3457 unit_list_iterate(get_units_in_focus(), punit) {
3458 request_unit_change_homecity(punit);
3459 } unit_list_iterate_end;
3460}
3461
3462/**********************************************************************/
3465 static void key_unit_extra(enum unit_activity act, enum extra_cause cause)
3466{
3467 unit_list_iterate(get_units_in_focus(), punit) {
3468 struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
3469 cause,
3470 unit_owner(punit),
3471 punit);
3472
3473 if (can_unit_do_activity_targeted_client(punit, act, tgt)) {
3474 request_new_unit_activity_targeted(punit, act, tgt);
3475 }
3476 } unit_list_iterate_end;
3477}
3478
3479/**********************************************************************/
3482 static void key_unit_gen_clean(enum unit_activity act,
3483 enum extra_rmcause rmcause)
3484{
3485 unit_list_iterate(get_units_in_focus(), punit) {
3486 struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
3487 rmcause,
3488 unit_owner(punit),
3489 punit);
3490
3491 if (tgt != NULL
3492 && can_unit_do_activity_targeted_client(punit, act, tgt)) {
3493 request_new_unit_activity_targeted(punit, act, tgt);
3494 }
3495 } unit_list_iterate_end;
3496}
3497
3498/**********************************************************************/
3501 void key_unit_irrigate(void)
3502{
3503 key_unit_extra(ACTIVITY_IRRIGATE, EC_IRRIGATION);
3504}
3505
3506/**********************************************************************/
3509 void key_unit_cultivate(void)
3510{
3511 unit_list_iterate(get_units_in_focus(), punit) {
3512 if (can_unit_do_activity_client(punit, ACTIVITY_CULTIVATE)) {
3513 request_new_unit_activity(punit, ACTIVITY_CULTIVATE);
3514 }
3515 } unit_list_iterate_end;
3516}
3517
3518/**********************************************************************/
3521 void key_unit_mine(void)
3522{
3523 key_unit_extra(ACTIVITY_MINE, EC_MINE);
3524}
3525
3526/**********************************************************************/
3529 void key_unit_plant(void)
3530{
3531 unit_list_iterate(get_units_in_focus(), punit) {
3532 if (can_unit_do_activity_client(punit, ACTIVITY_PLANT)) {
3533 request_new_unit_activity(punit, ACTIVITY_PLANT);
3534 }
3535 } unit_list_iterate_end;
3536}
3537
3538/**********************************************************************/
3541 void key_unit_pillage(void)
3542{
3543 unit_list_iterate(get_units_in_focus(), punit) {
3544 if (can_unit_do_activity_client(punit, ACTIVITY_PILLAGE)) {
3545 request_unit_pillage(punit);
3546 }
3547 } unit_list_iterate_end;
3548}
3549
3550/**********************************************************************/
3553 void key_unit_clean(void)
3554{
3555 unit_list_iterate(get_units_in_focus(), punit) {
3556 struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
3557 ERM_CLEANPOLLUTION,
3558 unit_owner(punit),
3559 punit);
3560
3561 if (tgt != NULL
3562 && can_unit_do_activity_targeted_client(punit, ACTIVITY_POLLUTION, tgt)) {
3563 request_new_unit_activity_targeted(punit, ACTIVITY_POLLUTION, tgt);
3564 } else {
3565 tgt = prev_extra_in_tile(unit_tile(punit),
3566 ERM_CLEANFALLOUT,
3567 unit_owner(punit),
3568 punit);
3569
3570 if (tgt != NULL
3571 && can_unit_do_activity_targeted_client(punit, ACTIVITY_FALLOUT, tgt)) {
3572 request_new_unit_activity_targeted(punit, ACTIVITY_FALLOUT, tgt);
3573 }
3574 }
3575 } unit_list_iterate_end;
3576}
3577
3578/**********************************************************************/
3581 void key_unit_pollution(void)
3582{
3583 key_unit_gen_clean(ACTIVITY_POLLUTION, ERM_CLEANPOLLUTION);
3584}
3585
3586/**********************************************************************/
3589 void key_unit_road(void)
3590{
3591 unit_list_iterate(get_units_in_focus(), punit) {
3592 struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
3593 EC_ROAD,
3594 unit_owner(punit),
3595 punit);
3596
3597 if (tgt != NULL
3598 && can_unit_do_activity_targeted_client(punit, ACTIVITY_GEN_ROAD, tgt)) {
3599 request_new_unit_activity_targeted(punit, ACTIVITY_GEN_ROAD, tgt);
3600 }
3601 } unit_list_iterate_end;
3602}
3603
3604/**********************************************************************/
3607 void key_unit_sentry(void)
3608{
3609 unit_list_iterate(get_units_in_focus(), punit) {
3610 if (can_unit_do_activity_client(punit, ACTIVITY_SENTRY)) {
3611 request_new_unit_activity(punit, ACTIVITY_SENTRY);
3612 }
3613 } unit_list_iterate_end;
3614}
3615
3616/**********************************************************************/
3619 void key_unit_transform(void)
3620{
3621 unit_list_iterate(get_units_in_focus(), punit) {
3622 if (can_unit_do_activity_client(punit, ACTIVITY_TRANSFORM)) {
3623 request_new_unit_activity(punit, ACTIVITY_TRANSFORM);
3624 }
3625 } unit_list_iterate_end;
3626}
3627
3628/**********************************************************************/
3631 void key_unit_assign_battlegroup(int battlegroup, bool append)
3632{
3633 if (NULL != client.conn.playing && can_client_issue_orders()
3634 && battlegroups >= 0 && battlegroup < MAX_NUM_BATTLEGROUPS) {
3635 if (!append) {
3636 unit_list_iterate_safe(battlegroups[battlegroup], punit) {
3637 if (!unit_is_in_focus(punit)) {
3638 punit->battlegroup = BATTLEGROUP_NONE;
3639 dsend_packet_unit_sscs_set(&client.conn, punit->id, punit->id,
3640 USSDT_BATTLE_GROUP,
3641 BATTLEGROUP_NONE);
3642 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
3643 unit_list_remove(battlegroups[battlegroup], punit);
3644 }
3645 } unit_list_iterate_safe_end;
3646 }
3647 unit_list_iterate(get_units_in_focus(), punit) {
3648 if (punit->battlegroup != battlegroup) {
3649 if (punit->battlegroup >= 0
3650 && punit->battlegroup < MAX_NUM_BATTLEGROUPS) {
3651 unit_list_remove(battlegroups[punit->battlegroup], punit);
3652 }
3653 punit->battlegroup = battlegroup;
3654 dsend_packet_unit_sscs_set(&client.conn, punit->id, punit->id,
3655 USSDT_BATTLE_GROUP,
3656 battlegroup);
3657 unit_list_append(battlegroups[battlegroup], punit);
3658 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
3659 }
3660 } unit_list_iterate_end;
3661 unit_list_iterate(battlegroups[battlegroup], punit) {
3662 unit_focus_add(punit);
3663 } unit_list_iterate_end;
3664 }
3665}
3666
3667/**********************************************************************/
3670 void key_unit_select_battlegroup(int battlegroup, bool append)
3671{
3672 if (NULL != client.conn.playing && can_client_change_view()
3673 && battlegroups >= 0 && battlegroup < MAX_NUM_BATTLEGROUPS) {
3674 int i = 0;
3675
3676 if (unit_list_size(battlegroups[battlegroup]) == 0 && !append) {
3677 unit_focus_set(NULL);
3678 return;
3679 }
3680
3681 /* FIXME: this is very inefficient and can be improved. */
3682 unit_list_iterate(battlegroups[battlegroup], punit) {
3683 if (i == 0 && !append) {
3684 unit_focus_set(punit);
3685 } else {
3686 unit_focus_add(punit);
3687 }
3688 i++;
3689 } unit_list_iterate_end;
3690 }
3691}
3692
3693/**********************************************************************/
3696 void key_city_outlines_toggle(void)
3697{
3698 request_toggle_city_outlines();
3699}
3700
3701/**********************************************************************/
3704 void key_city_output_toggle(void)
3705{
3706 request_toggle_city_output();
3707}
3708
3709/**********************************************************************/
3712 void key_map_grid_toggle(void)
3713{
3714 request_toggle_map_grid();
3715}
3716
3717/**********************************************************************/
3720 void key_map_borders_toggle(void)
3721{
3722 request_toggle_map_borders();
3723}
3724
3725/**********************************************************************/
3728 void key_map_native_toggle(void)
3729{
3730 request_toggle_map_native();
3731}
3732
3733/**********************************************************************/
3736 void key_city_full_bar_toggle(void)
3737{
3738 request_toggle_city_full_bar();
3739}
3740
3741/**********************************************************************/
3744 void key_city_names_toggle(void)
3745{
3746 request_toggle_city_names();
3747}
3748
3749/**********************************************************************/
3753 void key_city_growth_toggle(void)
3754{
3755 request_toggle_city_growth();
3756}
3757
3758/**********************************************************************/
3762 void key_city_buycost_toggle(void)
3763{
3764 request_toggle_city_buycost();
3765}
3766
3767/**********************************************************************/
3770 void key_city_productions_toggle(void)
3771{
3772 request_toggle_city_productions();
3773}
3774
3775/**********************************************************************/
3779 void key_city_trade_routes_toggle(void)
3780{
3781 request_toggle_city_trade_routes();
3782}
3783
3784/**********************************************************************/
3787 void key_unit_stack_size_toggle(void)
3788{
3789 request_toggle_unit_stack_size();
3790}
3791
3792/**********************************************************************/
3795 void key_terrain_toggle(void)
3796{
3797 request_toggle_terrain();
3798}
3799
3800/**********************************************************************/
3803 void key_coastline_toggle(void)
3804{
3805 request_toggle_coastline();
3806}
3807
3808/**********************************************************************/
3811 void key_roads_rails_toggle(void)
3812{
3813 request_toggle_roads_rails();
3814}
3815
3816/**********************************************************************/
3819 void key_irrigation_toggle(void)
3820{
3821 request_toggle_irrigation();
3822}
3823
3824/**********************************************************************/
3827 void key_mines_toggle(void)
3828{
3829 request_toggle_mines();
3830}
3831
3832/**********************************************************************/
3835 void key_bases_toggle(void)
3836{
3837 request_toggle_bases();
3838}
3839
3840/**********************************************************************/
3843 void key_resources_toggle(void)
3844{
3845 request_toggle_resources();
3846}
3847
3848/**********************************************************************/
3851 void key_huts_toggle(void)
3852{
3853 request_toggle_huts();
3854}
3855
3856/**********************************************************************/
3859 void key_pollution_toggle(void)
3860{
3861 request_toggle_pollution();
3862}
3863
3864/**********************************************************************/
3867 void key_cities_toggle(void)
3868{
3869 request_toggle_cities();
3870}
3871
3872/**********************************************************************/
3875 void key_units_toggle(void)
3876{
3877 request_toggle_units();
3878}
3879
3880/**********************************************************************/
3883 void key_unit_solid_bg_toggle(void)
3884{
3885 request_toggle_unit_solid_bg();
3886}
3887
3888/**********************************************************************/
3891 void key_unit_shields_toggle(void)
3892{
3893 request_toggle_unit_shields();
3894}
3895
3896/**********************************************************************/
3899 void key_focus_unit_toggle(void)
3900{
3901 request_toggle_focus_unit();
3902}
3903
3904/**********************************************************************/
3907 void key_fog_of_war_toggle(void)
3908{
3909 request_toggle_fog_of_war();
3910}
3911
3912/**********************************************************************/
3915 void key_editor_toggle(void)
3916{
3917 dsend_packet_edit_mode(&client.conn, !game.info.is_edit_mode);
3918}
3919
3920/**********************************************************************/
3923 void key_editor_recalculate_borders(void)
3924{
3925 send_packet_edit_recalculate_borders(&client.conn);
3926}
3927
3928/**********************************************************************/
3932 void key_editor_toggle_fogofwar(void)
3933{
3934 if (client_has_player()) {
3935 dsend_packet_edit_toggle_fogofwar(&client.conn, client_player_number());
3936 }
3937}
3938
3939/**********************************************************************/
3942 void finish_city(struct tile *ptile, const char *name)
3943{
3944 unit_list_iterate(ptile->units, punit) {
3945 if (punit->client.asking_city_name) {
3946 /* Unit will disappear only in case city building still success.
3947 * Cancel city building status just in case something has changed
3948 * to prevent city building in the meanwhile and unit will remain
3949 * alive. */
3950 punit->client.asking_city_name = FALSE;
3951 request_do_action(ACTION_FOUND_CITY, punit->id, ptile->index,
3952 0, name);
3953 }
3954 } unit_list_iterate_end;
3955}
3956
3957/**********************************************************************/
3961 void cancel_city(struct tile *ptile)
3962{
3963 unit_list_iterate(ptile->units, punit) {
3964 punit->client.asking_city_name = FALSE;
3965 } unit_list_iterate_end;
3966}
action_name_translation
const char * action_name_translation(const struct action *action)
Definition actions.c:1890
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1910
action_prob_self
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:6380
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6707
action_prob_unit_vs_tgt
struct act_prob action_prob_unit_vs_tgt(const struct action *paction, const struct unit *act_unit, const struct city *tgt_city, const struct unit *tgt_unit, const struct tile *tgt_tile, const struct extra_type *extra_tgt)
Definition actions.c:6402
action_prob_vs_tile
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6225
action_prob_vs_units
struct act_prob action_prob_vs_units(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:6141
action_prob_vs_city
struct act_prob action_prob_vs_city(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:5870
action_prob_vs_extras
struct act_prob action_prob_vs_extras(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6309
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1697
action_prob_vs_unit
struct act_prob action_prob_vs_unit(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5953
action_id_univs_not_blocking
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:950
action_by_result_iterate
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:488
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:448
action_id_get_role
#define action_id_get_role(act_id)
Definition actions.h:708
action_by_result_iterate_end
#define action_by_result_iterate_end
Definition actions.h:492
action_iterate_end
#define action_iterate_end
Definition actions.h:472
action_iterate
#define action_iterate(_act_)
Definition actions.h:467
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:655
action_id_has_result_safe
#define action_id_has_result_safe(act_id, result)
Definition actions.h:668
ACTION_NONE
#define ACTION_NONE
Definition actions.h:293
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astring.h
astr_str
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
ASTRING_INIT
#define ASTRING_INIT
Definition astring.h:44
audio_play_sound
void audio_play_sound(const char *const tag, const char *const alt_tag)
Definition audio.c:521
audio.h
base_extra_get
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:101
get_base_by_gui_type
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:139
bitvector.h
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
chatline_g.h
is_enemy_city_tile
static bool is_enemy_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:705
citydlg_g.h
popup_city_dialog
void popup_city_dialog(struct city *pcity)
Definition update_queue.c:623
client_player_number
int client_player_number(void)
Definition client_main.c:1354
send_turn_done
void send_turn_done(void)
Definition client_main.c:809
client
struct civclient client
Definition client_main.c:149
client_state
enum client_states client_state(void)
Definition client_main.c:1029
can_client_issue_orders
bool can_client_issue_orders(void)
Definition client_main.c:1265
client_has_player
bool client_has_player(void)
Definition client_main.c:1365
is_server_busy
bool is_server_busy(void)
Definition client_main.c:1338
can_client_change_view
bool can_client_change_view(void)
Definition client_main.c:1313
client_main.h
client_player
#define client_player()
Definition client_main.h:106
C_S_RUNNING
@ C_S_RUNNING
Definition client_main.h:47
C_S_OVER
@ C_S_OVER
Definition client_main.h:48
gui_to_map_dir
enum direction8 gui_to_map_dir(enum direction8 gui_dir)
Definition climap.c:59
climap.h
create_event
void create_event(struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition climisc.c:1075
can_units_do_connect
bool can_units_do_connect(struct unit_list *punits, enum unit_activity activity, struct extra_type *tgt)
Definition climisc.c:1224
climisc.h
can_unit_attack_tile
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:271
combat.h
blink_turn_done_button
double blink_turn_done_button(void)
Definition control.c:907
key_coastline_toggle
void key_coastline_toggle(void)
Definition control.c:3803
key_irrigation_toggle
void key_irrigation_toggle(void)
Definition control.c:3819
request_toggle_huts
void request_toggle_huts(void)
Definition control.c:2505
key_unit_sentry
void key_unit_sentry(void)
Definition control.c:3607
request_toggle_city_outlines
void request_toggle_city_outlines(void)
Definition control.c:2258
key_unit_road
void key_unit_road(void)
Definition control.c:3589
request_unit_airlift
void request_unit_airlift(struct unit *punit, struct city *pcity)
Definition control.c:1512
do_move_unit
void do_move_unit(struct unit *punit, struct unit *target_unit)
Definition control.c:2662
request_toggle_resources
void request_toggle_resources(void)
Definition control.c:2492
request_toggle_city_names
void request_toggle_city_names(void)
Definition control.c:2336
key_recall_previous_focus_unit
void key_recall_previous_focus_unit(void)
Definition control.c:3134
request_unit_non_action_move
void request_unit_non_action_move(struct unit *punit, struct tile *dest_tile)
Definition control.c:1733
request_toggle_unit_stack_size
void request_toggle_unit_stack_size(void)
Definition control.c:2401
key_unit_pollution
void key_unit_pollution(void)
Definition control.c:3581
unit_is_in_focus
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:384
key_city_output_toggle
void key_city_output_toggle(void)
Definition control.c:3704
request_toggle_focus_unit
void request_toggle_focus_unit(void)
Definition control.c:2583
request_toggle_city_output
void request_toggle_city_output(void)
Definition control.c:2271
request_unit_return
void request_unit_return(struct unit *punit)
Definition control.c:1521
request_unit_fortify
void request_unit_fortify(struct unit *punit)
Definition control.c:2213
key_unit_build_city
void key_unit_build_city(void)
Definition control.c:3167
key_editor_recalculate_borders
void key_editor_recalculate_borders(void)
Definition control.c:3923
request_unit_unload_all
struct unit * request_unit_unload_all(struct unit *punit)
Definition control.c:1480
key_roads_rails_toggle
void key_roads_rails_toggle(void)
Definition control.c:3811
request_unit_caravan_action
void request_unit_caravan_action(struct unit *punit, action_id action)
Definition control.c:2121
action_selection_no_longer_in_progress
void action_selection_no_longer_in_progress(const int old_actor_id)
Definition control.c:1032
request_toggle_roads_rails
void request_toggle_roads_rails(void)
Definition control.c:2440
goto_last_order
enum unit_orders goto_last_order
Definition control.c:96
request_units_wait
void request_units_wait(struct unit_list *punits)
Definition control.c:2623
request_unit_wakeup
void request_unit_wakeup(struct unit *punit)
Definition control.c:1569
get_focus_unit_on_tile
struct unit * get_focus_unit_on_tile(const struct tile *ptile)
Definition control.c:392
key_focus_unit_toggle
void key_focus_unit_toggle(void)
Definition control.c:3899
request_toggle_map_grid
void request_toggle_map_grid(void)
Definition control.c:2284
action_decision_request
void action_decision_request(struct unit *actor_unit)
Definition control.c:1083
control_free
void control_free(void)
Definition control.c:154
request_toggle_mines
void request_toggle_mines(void)
Definition control.c:2466
set_units_in_combat
void set_units_in_combat(struct unit *pattacker, struct unit *pdefender)
Definition control.c:1013
check_recursive_road_connect
int check_recursive_road_connect(struct tile *ptile, const struct extra_type *pextra, const struct unit *punit, const struct player *pplayer, int rec)
Definition control.c:1306
key_unit_action_select
void key_unit_action_select(void)
Definition control.c:3198
key_unit_auto_explore
void key_unit_auto_explore(void)
Definition control.c:3383
action_selection_in_progress_for
static int action_selection_in_progress_for
Definition control.c:119
do_disband_alternative
static void do_disband_alternative(void *p)
Definition control.c:1870
key_cancel_action
void key_cancel_action(void)
Definition control.c:3073
request_toggle_city_buycost
void request_toggle_city_buycost(void)
Definition control.c:2375
key_unit_auto_settle
void key_unit_auto_settle(void)
Definition control.c:3396
clear_hover_state
void clear_hover_state(void)
Definition control.c:323
request_toggle_map_native
void request_toggle_map_native(void)
Definition control.c:2310
request_unit_patrol
void request_unit_patrol(void)
Definition control.c:2179
num_units_below
int num_units_below
Definition control.c:76
key_unit_connect
void key_unit_connect(enum unit_activity activity, struct extra_type *tgt)
Definition control.c:3189
key_city_full_bar_toggle
void key_city_full_bar_toggle(void)
Definition control.c:3736
request_unit_load
void request_unit_load(struct unit *pcargo, struct unit *ptrans, struct tile *ptile)
Definition control.c:2056
key_bases_toggle
void key_bases_toggle(void)
Definition control.c:3835
do_map_click
void do_map_click(struct tile *ptile, enum quickselect_type qtype)
Definition control.c:2768
key_unit_extra
static void key_unit_extra(enum unit_activity act, enum extra_cause cause)
Definition control.c:3465
key_map_native_toggle
void key_map_native_toggle(void)
Definition control.c:3728
request_toggle_map_borders
void request_toggle_map_borders(void)
Definition control.c:2297
key_resources_toggle
void key_resources_toggle(void)
Definition control.c:3843
punit_attacking
static struct unit * punit_attacking
Definition control.c:105
unit_focus_add
void unit_focus_add(struct unit *punit)
Definition control.c:557
unit_focus_set
void unit_focus_set(struct unit *punit)
Definition control.c:502
do_unit_act_sel_vs
static void do_unit_act_sel_vs(struct tile *ptile)
Definition control.c:2753
request_unit_goto
void request_unit_goto(enum unit_orders last_order, action_id act_id, int sub_tgt_id)
Definition control.c:1103
do_unit_paradrop_to
void do_unit_paradrop_to(struct unit *punit, struct tile *ptile)
Definition control.c:3000
should_ask_server_for_actions
bool should_ask_server_for_actions(const struct unit *punit)
Definition control.c:334
goto_last_tgt
int goto_last_tgt
Definition control.c:94
connect_tgt
struct extra_type * connect_tgt
Definition control.c:91
key_unit_paradrop
void key_unit_paradrop(void)
Definition control.c:3293
can_units_attack_at
static bool can_units_attack_at(struct unit_list *punits, const struct tile *ptile)
Definition control.c:1170
get_units_in_focus
struct unit_list * get_units_in_focus(void)
Definition control.c:177
request_do_action
void request_do_action(action_id action, int actor_id, int target_id, int sub_tgt, const char *name)
Definition control.c:1675
key_end_turn
void key_end_turn(void)
Definition control.c:3126
request_unit_disband
void request_unit_disband(struct unit *punit)
Definition control.c:1975
request_toggle_irrigation
void request_toggle_irrigation(void)
Definition control.c:2453
current_focus
static struct unit_list * current_focus
Definition control.c:79
previous_focus
static struct unit_list * previous_focus
Definition control.c:83
unit_focus_advance
void unit_focus_advance(void)
Definition control.c:671
key_unit_gen_clean
static void key_unit_gen_clean(enum unit_activity act, enum extra_rmcause rmcause)
Definition control.c:3482
request_unit_autosettlers
void request_unit_autosettlers(const struct unit *punit)
Definition control.c:2041
request_unit_pillage
void request_unit_pillage(struct unit *punit)
Definition control.c:2224
request_center_focus_unit
void request_center_focus_unit(void)
Definition control.c:2610
unit_focus_urgent
void unit_focus_urgent(struct unit *punit)
Definition control.c:207
key_unit_shields_toggle
void key_unit_shields_toggle(void)
Definition control.c:3891
key_city_productions_toggle
void key_city_productions_toggle(void)
Definition control.c:3770
can_unit_do_connect
bool can_unit_do_connect(struct unit *punit, enum unit_activity activity, struct extra_type *tgt)
Definition control.c:1384
key_unit_build_wonder
void key_unit_build_wonder(void)
Definition control.c:3177
key_unit_plant
void key_unit_plant(void)
Definition control.c:3529
key_unit_fortress
void key_unit_fortress(void)
Definition control.c:3438
key_unit_mine
void key_unit_mine(void)
Definition control.c:3521
request_unit_change_homecity
void request_unit_change_homecity(struct unit *punit)
Definition control.c:1994
request_toggle_fog_of_war
void request_toggle_fog_of_war(void)
Definition control.c:2596
key_unit_pillage
void key_unit_pillage(void)
Definition control.c:3541
request_unit_unload
void request_unit_unload(struct unit *pcargo)
Definition control.c:2092
key_editor_toggle_fogofwar
void key_editor_toggle_fogofwar(void)
Definition control.c:3932
client_disband_unit_data_destroy
static void client_disband_unit_data_destroy(void *p)
Definition control.c:1860
request_unit_ssa_set
void request_unit_ssa_set(const struct unit *punit, enum server_side_agent agent)
Definition control.c:2028
find_best_focus_candidate
static struct unit * find_best_focus_candidate(bool accept_current)
Definition control.c:634
request_action_details
void request_action_details(action_id action, int actor_id, int target_id)
Definition control.c:1695
quickselect
static struct unit * quickselect(struct tile *ptile, enum quickselect_type qtype)
Definition control.c:2857
connect_activity
enum unit_activity connect_activity
Definition control.c:90
request_toggle_units
void request_toggle_units(void)
Definition control.c:2544
request_new_unit_activity_targeted
void request_new_unit_activity_targeted(struct unit *punit, enum unit_activity act, struct extra_type *tgt)
Definition control.c:1837
update_unit_pix_label
void update_unit_pix_label(struct unit_list *punitlist)
Definition control.c:966
key_unit_irrigate
void key_unit_irrigate(void)
Definition control.c:3501
request_unit_build_city
void request_unit_build_city(struct unit *punit)
Definition control.c:1714
unit_change_battlegroup
void unit_change_battlegroup(struct unit *punit, int battlegroup)
Definition control.c:250
urgent_focus_queue
static struct unit_list * urgent_focus_queue
Definition control.c:86
key_unit_unload_all
void key_unit_unload_all(void)
Definition control.c:3323
key_cities_toggle
void key_cities_toggle(void)
Definition control.c:3867
key_unit_move
void key_unit_move(enum direction8 gui_dir)
Definition control.c:3155
key_city_outlines_toggle
void key_city_outlines_toggle(void)
Definition control.c:3696
key_unit_homecity
void key_unit_homecity(void)
Definition control.c:3455
request_unit_paradrop
void request_unit_paradrop(struct unit_list *punits)
Definition control.c:2144
set_hover_state
void set_hover_state(struct unit_list *punits, enum cursor_hover_state state, enum unit_activity activity, struct extra_type *tgt, int last_tgt, int last_sub_tgt, action_id action, enum unit_orders order)
Definition control.c:285
disband_unit_alternatives
static int disband_unit_alternatives[3]
Definition control.c:69
key_unit_patrol
void key_unit_patrol(void)
Definition control.c:3301
request_toggle_city_full_bar
void request_toggle_city_full_bar(void)
Definition control.c:2323
request_toggle_city_growth
void request_toggle_city_growth(void)
Definition control.c:2349
key_unit_solid_bg_toggle
void key_unit_solid_bg_toggle(void)
Definition control.c:3883
request_toggle_unit_solid_bg
void request_toggle_unit_solid_bg(void)
Definition control.c:2557
key_terrain_toggle
void key_terrain_toggle(void)
Definition control.c:3795
request_unit_sentry
void request_unit_sentry(struct unit *punit)
Definition control.c:2202
key_unit_wakeup_others
void key_unit_wakeup_others(void)
Definition control.c:3356
non_ai_unit_focus
bool non_ai_unit_focus
Definition control.c:125
punit_defending
static struct unit * punit_defending
Definition control.c:106
find_a_focus_unit_tile_to_center_on
static struct tile * find_a_focus_unit_tile_to_center_on(void)
Definition control.c:414
hover_state
enum cursor_hover_state hover_state
Definition control.c:89
key_unit_stack_size_toggle
void key_unit_stack_size_toggle(void)
Definition control.c:3787
store_previous_focus
static void store_previous_focus(void)
Definition control.c:194
key_huts_toggle
void key_huts_toggle(void)
Definition control.c:3851
key_fog_of_war_toggle
void key_fog_of_war_toggle(void)
Definition control.c:3907
request_unit_connect
void request_unit_connect(enum unit_activity activity, struct extra_type *tgt)
Definition control.c:1451
clear_unit_orders
void clear_unit_orders(struct unit *punit)
Definition control.c:477
control_init
void control_init(void)
Definition control.c:137
request_toggle_terrain
void request_toggle_terrain(void)
Definition control.c:2414
action_decision_clear_want
void action_decision_clear_want(const int old_actor_id)
Definition control.c:1053
key_unit_wait
void key_unit_wait(void)
Definition control.c:3348
key_units_toggle
void key_units_toggle(void)
Definition control.c:3875
do_unit_connect
void do_unit_connect(struct tile *ptile, enum unit_activity activity, struct extra_type *tgt)
Definition control.c:3056
goto_last_sub_tgt
int goto_last_sub_tgt
Definition control.c:95
unit_focus_remove
void unit_focus_remove(struct unit *punit)
Definition control.c:587
request_toggle_bases
void request_toggle_bases(void)
Definition control.c:2479
do_unit_patrol_to
void do_unit_patrol_to(struct tile *ptile)
Definition control.c:3040
key_unit_trade_route
void key_unit_trade_route(void)
Definition control.c:3309
request_toggle_coastline
void request_toggle_coastline(void)
Definition control.c:2427
key_unit_select_battlegroup
void key_unit_select_battlegroup(int battlegroup, bool append)
Definition control.c:3670
key_map_grid_toggle
void key_map_grid_toggle(void)
Definition control.c:3712
finish_city
void finish_city(struct tile *ptile, const char *name)
Definition control.c:3942
punit_moving
static struct unit * punit_moving
Definition control.c:102
key_pollution_toggle
void key_pollution_toggle(void)
Definition control.c:3859
head_of_units_in_focus
struct unit * head_of_units_in_focus(void)
Definition control.c:406
is_activity_on_tile
static bool is_activity_on_tile(struct tile *ptile, enum unit_activity activity)
Definition control.c:1290
find_visible_unit
struct unit * find_visible_unit(struct tile *ptile)
Definition control.c:805
can_be_irrigated
static bool can_be_irrigated(const struct tile *ptile, const struct unit *punit)
Definition control.c:1361
key_city_growth_toggle
void key_city_growth_toggle(void)
Definition control.c:3753
key_unit_action_select_tgt
void key_unit_action_select_tgt(void)
Definition control.c:3220
key_unit_fallout
void key_unit_fallout(void)
Definition control.c:3418
battlegroups
static struct unit_list * battlegroups[MAX_NUM_BATTLEGROUPS]
Definition control.c:99
key_city_buycost_toggle
void key_city_buycost_toggle(void)
Definition control.c:3762
get_num_units_in_focus
int get_num_units_in_focus(void)
Definition control.c:185
key_unit_transform
void key_unit_transform(void)
Definition control.c:3619
request_move_unit_direction
void request_move_unit_direction(struct unit *punit, int dir)
Definition control.c:1777
current_focus_append
static void current_focus_append(struct unit *punit)
Definition control.c:443
key_unit_done
void key_unit_done(void)
Definition control.c:3277
current_focus_remove
static void current_focus_remove(struct unit *punit)
Definition control.c:463
hover_tile
static struct tile * hover_tile
Definition control.c:98
key_city_trade_routes_toggle
void key_city_trade_routes_toggle(void)
Definition control.c:3779
focus_units_changed
static void focus_units_changed(void)
Definition control.c:215
request_toggle_city_trade_routes
void request_toggle_city_trade_routes(void)
Definition control.c:2388
unit_focus_set_and_select
void unit_focus_set_and_select(struct unit *punit)
Definition control.c:621
request_unit_convert
void request_unit_convert(struct unit *punit)
Definition control.c:2018
request_toggle_unit_shields
void request_toggle_unit_shields(void)
Definition control.c:2570
key_city_names_toggle
void key_city_names_toggle(void)
Definition control.c:3744
unit_register_battlegroup
void unit_register_battlegroup(struct unit *punit)
Definition control.c:270
request_unit_select
void request_unit_select(struct unit_list *punits, enum unit_select_type_mode seltype, enum unit_select_location_mode selloc)
Definition control.c:1590
unit_focus_update
void unit_focus_update(void)
Definition control.c:772
key_unit_airbase
void key_unit_airbase(void)
Definition control.c:3366
key_unit_goto
void key_unit_goto(void)
Definition control.c:3285
control_mouse_cursor
void control_mouse_cursor(struct tile *ptile)
Definition control.c:1188
key_unit_convert
void key_unit_convert(void)
Definition control.c:3408
key_unit_clean
void key_unit_clean(void)
Definition control.c:3553
key_center_capital
void key_center_capital(void)
Definition control.c:3109
wakeup_sentried_units
void wakeup_sentried_units(struct tile *ptile)
Definition control.c:1552
request_toggle_cities
void request_toggle_cities(void)
Definition control.c:2531
key_unit_fortify
void key_unit_fortify(void)
Definition control.c:3426
key_editor_toggle
void key_editor_toggle(void)
Definition control.c:3915
key_unit_assign_battlegroup
void key_unit_assign_battlegroup(int battlegroup, bool append)
Definition control.c:3631
request_unit_move_done
void request_unit_move_done(void)
Definition control.c:2636
auto_center_on_focus_unit
void auto_center_on_focus_unit(void)
Definition control.c:430
key_unit_cultivate
void key_unit_cultivate(void)
Definition control.c:3509
blink_active_unit
double blink_active_unit(void)
Definition control.c:875
request_unit_upgrade
void request_unit_upgrade(struct unit *punit)
Definition control.c:2006
control_unit_killed
void control_unit_killed(struct unit *punit)
Definition control.c:226
request_toggle_city_productions
void request_toggle_city_productions(void)
Definition control.c:2362
cancel_city
void cancel_city(struct tile *ptile)
Definition control.c:3961
ask_server_for_actions
static void ask_server_for_actions(struct unit *punit)
Definition control.c:361
request_new_unit_activity
void request_new_unit_activity(struct unit *punit, enum unit_activity act)
Definition control.c:1828
request_toggle_pollution
void request_toggle_pollution(void)
Definition control.c:2518
goto_last_action
action_id goto_last_action
Definition control.c:93
key_mines_toggle
void key_mines_toggle(void)
Definition control.c:3827
do_unit_goto
void do_unit_goto(struct tile *ptile)
Definition control.c:2978
action_selection_next_in_focus
void action_selection_next_in_focus(const int old_actor_id)
Definition control.c:1065
can_ask_server_for_actions
static bool can_ask_server_for_actions(void)
Definition control.c:347
key_map_borders_toggle
void key_map_borders_toggle(void)
Definition control.c:3720
control.h
can_unit_do_activity_targeted_client
#define can_unit_do_activity_targeted_client(_punit_, _act_, _tgt_)
Definition control.h:42
MAX_NUM_UNITS_BELOW
#define MAX_NUM_UNITS_BELOW
Definition control.h:285
quickselect_type
quickselect_type
Definition control.h:36
SELECT_LAND
@ SELECT_LAND
Definition control.h:37
SELECT_APPEND
@ SELECT_APPEND
Definition control.h:37
SELECT_SEA
@ SELECT_SEA
Definition control.h:37
SELECT_POPUP
@ SELECT_POPUP
Definition control.h:37
SELECT_FOCUS
@ SELECT_FOCUS
Definition control.h:37
cursor_hover_state
cursor_hover_state
Definition control.h:25
HOVER_GOTO
@ HOVER_GOTO
Definition control.h:27
HOVER_PARADROP
@ HOVER_PARADROP
Definition control.h:28
HOVER_ACT_SEL_TGT
@ HOVER_ACT_SEL_TGT
Definition control.h:31
HOVER_NONE
@ HOVER_NONE
Definition control.h:26
HOVER_CONNECT
@ HOVER_CONNECT
Definition control.h:29
HOVER_PATROL
@ HOVER_PATROL
Definition control.h:30
HOVER_GOTO_SEL_TGT
@ HOVER_GOTO_SEL_TGT
Definition control.h:32
can_unit_do_activity_client
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:40
dialogs_g.h
target_unit
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:55
actor_unit
struct unit * actor_unit
Definition dialogs_g.h:54
action_selection_no_longer_in_progress_gui_specific
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs action_selection_no_longer_in_progress_gui_specific
Definition dialogs_g.h:68
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
target_city
struct unit struct city * target_city
Definition dialogs_g.h:55
editor.h
get_unit_bonus
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:992
next_extra_for_tile
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:740
prev_extra_in_tile
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:765
can_build_extra
bool can_build_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Definition extras.c:507
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:291
extra_deps_iterate
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:338
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:297
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:196
extra_index
#define extra_index(_e_)
Definition extras.h:177
extra_deps_iterate_end
#define extra_deps_iterate_end
Definition extras.h:346
EXTRA_NONE
#define EXTRA_NONE
Definition extras.h:82
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:185
NO_TARGET
#define NO_TARGET
Definition fc_types.h:324
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:585
DIR8_ORIGIN
#define DIR8_ORIGIN
Definition fc_types.h:427
action_id
int action_id
Definition fc_types.h:359
MAX_EXTRA_TYPES
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
IDENTITY_NUMBER_ZERO
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:82
fcintl.h
_
#define _(String)
Definition fcintl.h:67
ftc_client
const struct ft_color ftc_client
Definition featured_text.c:78
game
struct civ_game game
Definition game.c:57
is_player_phase
bool is_player_phase(const struct player *pplayer, int phase)
Definition game.c:687
wld
struct world wld
Definition game.c:58
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:111
game.h
exit_goto_state
void exit_goto_state(void)
Definition goto.c:1019
goto_is_active
bool goto_is_active(void)
Definition goto.c:1056
path_to_nearest_allied_city
struct pf_path * path_to_nearest_allied_city(struct unit *punit)
Definition goto.c:1983
send_patrol_route
void send_patrol_route(void)
Definition goto.c:1647
is_valid_goto_draw_line
bool is_valid_goto_draw_line(struct tile *dest_tile)
Definition goto.c:1335
goto_add_waypoint
bool goto_add_waypoint(void)
Definition goto.c:487
goto_pop_waypoint
bool goto_pop_waypoint(void)
Definition goto.c:524
send_connect_route
void send_connect_route(enum unit_activity activity, struct extra_type *tgt)
Definition goto.c:1713
goto_unit_killed
void goto_unit_killed(struct unit *punit)
Definition goto.c:1037
free_client_goto
void free_client_goto(void)
Definition goto.c:162
enter_goto_state
void enter_goto_state(struct unit_list *punits)
Definition goto.c:998
send_goto_route
void send_goto_route(void)
Definition goto.c:1870
is_valid_goto_destination
bool is_valid_goto_destination(const struct tile *ptile)
Definition goto.c:179
request_orders_cleared
void request_orders_cleared(struct unit *punit)
Definition goto.c:1360
send_goto_path
void send_goto_path(struct unit *punit, struct pf_path *path, struct unit_order *final_order)
Definition goto.c:1530
goto.h
action_selection_actor_unit
int action_selection_actor_unit(void)
Definition action_dialog.c:1592
action_selection_close
void action_selection_close(void)
Definition action_dialog.c:1741
refresh_unit_city_dialogs
void refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.c:538
unit_select_dialog_popup
void unit_select_dialog_popup(struct tile *ptile)
Definition dialogs.c:382
popup_pillage_dialog
void popup_pillage_dialog(struct unit *punit, bv_extras extras)
Definition dialogs.c:343
real_focus_units_changed
void real_focus_units_changed(void)
Definition gui_main.c:1955
set_unit_icons_more_arrow
void set_unit_icons_more_arrow(bool onoff)
Definition gui_main.c:1932
set_unit_icon
void set_unit_icon(int idx, struct unit *punit)
Definition gui_main.c:1902
create_line_at_mouse_pos
void create_line_at_mouse_pos(void)
Definition mapctrl.c:347
update_turn_done_button
void update_turn_done_button(bool do_restore)
Definition mapview.c:75
put_cross_overlay_tile
void put_cross_overlay_tile(struct tile *ptile)
Definition mapview.c:622
update_unit_info_label
void update_unit_info_label(struct unit_list *punits)
Definition mapview.c:258
update_mouse_cursor
void update_mouse_cursor(enum cursor_type new_cursor_type)
Definition mapview.c:240
request_transport
bool request_transport(struct unit *cargo, struct tile *ptile)
Definition transportdlg.c:82
gui_main_g.h
mouse_cursor_type
enum cursor_type mouse_cursor_type
Definition gui_mouse.c:46
name
const char * name
Definition inputfile.c:127
log.h
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_error
#define log_error(message,...)
Definition log.h:103
get_direction_for_step
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1345
is_tiles_adjacent
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:929
same_pos
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
mapstep
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:369
map_distance_vector
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1071
map.h
iterate_outward
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:361
iterate_outward_end
#define iterate_outward_end
Definition map.h:365
keyboardless_goto_button_down
bool keyboardless_goto_button_down
Definition mapctrl_common.c:69
cancel_tile_hiliting
void cancel_tile_hiliting(void)
Definition mapctrl_common.c:310
keyboardless_goto_active
bool keyboardless_goto_active
Definition mapctrl_common.c:70
keyboardless_goto_start_tile
struct tile * keyboardless_goto_start_tile
Definition mapctrl_common.c:71
mapctrl_g.h
update_map_canvas_visible
void update_map_canvas_visible(void)
Definition mapview_common.c:1843
get_center_tile_mapcanvas
struct tile * get_center_tile_mapcanvas(void)
Definition mapview_common.c:1212
move_unit_map_canvas
void move_unit_map_canvas(struct unit *punit, struct tile *src_tile, int dx, int dy)
Definition mapview_common.c:2684
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1222
update_city_description
void update_city_description(struct city *pcity)
Definition mapview_common.c:1863
refresh_unit_mapcanvas
void refresh_unit_mapcanvas(struct unit *punit, struct tile *ptile, bool full_refresh, bool write_to_screen)
Definition mapview_common.c:510
tile_visible_and_not_on_border_mapcanvas
bool tile_visible_and_not_on_border_mapcanvas(struct tile *ptile)
Definition mapview_common.c:1267
mapview_g.h
mem.h
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
menu_g.h
menus_update
void menus_update(void)
Definition update_queue.c:562
can_unit_exist_at_tile
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:304
can_unit_survive_at_tile
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:476
movement.h
server_optset
const struct option_set * server_optset
Definition options.c:4009
option_bool_get
bool option_bool_get(const struct option *poption)
Definition options.c:772
gui_options
struct client_options gui_options
Definition options.c:71
optset_option_by_name
struct option * optset_option_by_name(const struct option_set *poptset, const char *name)
Definition options.c:406
options.h
refresh_overview_canvas
void refresh_overview_canvas(void)
Definition overview_common.c:375
overview_common.h
REQEST_PLAYER_INITIATED
#define REQEST_PLAYER_INITIATED
Definition packets.h:70
dsend_packet_unit_do_action
int dsend_packet_unit_do_action(struct connection *pc, int actor_id16, int actor_id32, int target_id, int sub_tgt_id, const char *name, action_id action_type)
Definition packets_gen.c:45609
dsend_packet_unit_sscs_set
int dsend_packet_unit_sscs_set(struct connection *pc, int unit_id16, int unit_id32, enum unit_ss_data_type type, int value)
Definition packets_gen.c:43126
send_packet_unit_orders
int send_packet_unit_orders(struct connection *pc, const struct packet_unit_orders *packet)
Definition packets_gen.c:43956
send_packet_edit_recalculate_borders
int send_packet_edit_recalculate_borders(struct connection *pc)
Definition packets_gen.c:85204
dsend_packet_unit_get_actions
int dsend_packet_unit_get_actions(struct connection *pc, int actor_unit_id16, int actor_unit_id32, int target_unit_id16, int target_unit_id32, int target_tile_id, int target_extra_id, int request_kind)
Definition packets_gen.c:46745
dsend_packet_unit_action_query
int dsend_packet_unit_action_query(struct connection *pc, int actor_id16, int actor_id32, int target_id, action_id action_type, int request_kind)
Definition packets_gen.c:44859
dsend_packet_unit_server_side_agent_set
int dsend_packet_unit_server_side_agent_set(struct connection *pc, int unit_id16, int unit_id32, enum server_side_agent agent)
Definition packets_gen.c:44346
dsend_packet_unit_change_activity
int dsend_packet_unit_change_activity(struct connection *pc, int unit_id16, int unit_id32, enum unit_activity activity, int target)
Definition packets_gen.c:48102
dsend_packet_city_name_suggestion_req
int dsend_packet_city_name_suggestion_req(struct connection *pc, int unit_id16, int unit_id32)
Definition packets_gen.c:30284
dsend_packet_edit_toggle_fogofwar
int dsend_packet_edit_toggle_fogofwar(struct connection *pc, int player)
Definition packets_gen.c:85400
dsend_packet_edit_mode
int dsend_packet_edit_mode(struct connection *pc, bool state)
Definition packets_gen.c:85177
pf_path_last_position
const struct pf_position * pf_path_last_position(const struct pf_path *path)
Definition path_finding.c:3531
pf_path_destroy
void pf_path_destroy(struct pf_path *path)
Definition path_finding.c:3411
path_finding.h
player_unit_by_number
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
player_primary_capital
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1313
can_player_see_units_in_city
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1113
can_player_see_city_internals
bool can_player_see_city_internals(const struct player *pplayer, const struct city *pcity)
Definition player.c:1129
players_iterate_alive_end
#define players_iterate_alive_end
Definition player.h:545
players_iterate_alive
#define players_iterate_alive(_pplayer)
Definition player.h:540
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:4361
can_build_road
bool can_build_road(const struct civ_map *nmap, struct road_type *proad, const struct unit *punit, const struct tile *ptile)
Definition road.c:295
player_can_build_road
bool player_can_build_road(const struct civ_map *nmap, const struct road_type *proad, const struct player *pplayer, const struct tile *ptile)
Definition road.c:280
FC_INFINITY
#define FC_INFINITY
Definition shared.h:36
spechash.h
action
Definition actions.h:379
action::id
action_id id
Definition actions.h:380
agent
Definition agents.h:40
astring
Definition astring.h:36
base_type
Definition base.h:41
city
Definition city.h:309
city::id
int id
Definition city.h:315
city::capital
enum capital_type capital
Definition city.h:317
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_map
Definition map_types.h:71
civclient::conn
struct connection conn
Definition client_main.h:96
client_disband_unit_data
Definition control.c:60
client_disband_unit_data::unit_id
int unit_id
Definition control.c:61
client_disband_unit_data::alt
int alt
Definition control.c:62
client_options::draw_native
bool draw_native
Definition options.h:207
client_options::enable_cursor_changes
bool enable_cursor_changes
Definition options.h:166
client_options::auto_turn_done
bool auto_turn_done
Definition options.h:157
client_options::draw_specials
bool draw_specials
Definition options.h:199
client_options::draw_city_output
bool draw_city_output
Definition options.h:186
client_options::draw_city_names
bool draw_city_names
Definition options.h:188
client_options::draw_city_productions
bool draw_city_productions
Definition options.h:190
client_options::smooth_move_unit_msec
int smooth_move_unit_msec
Definition options.h:144
client_options::draw_mines
bool draw_mines
Definition options.h:197
client_options::draw_borders
bool draw_borders
Definition options.h:206
client_options::draw_fortress_airbase
bool draw_fortress_airbase
Definition options.h:198
client_options::draw_city_buycost
bool draw_city_buycost
Definition options.h:191
client_options::draw_unit_stack_size
bool draw_unit_stack_size
Definition options.h:210
client_options::draw_irrigation
bool draw_irrigation
Definition options.h:196
client_options::draw_terrain
bool draw_terrain
Definition options.h:193
client_options::draw_units
bool draw_units
Definition options.h:203
client_options::auto_center_on_automated
bool auto_center_on_automated
Definition options.h:149
client_options::draw_fog_of_war
bool draw_fog_of_war
Definition options.h:205
client_options::draw_city_trade_routes
bool draw_city_trade_routes
Definition options.h:192
client_options::unit_selection_clears_orders
bool unit_selection_clears_orders
Definition options.h:168
client_options::draw_unit_shields
bool draw_unit_shields
Definition options.h:209
client_options::draw_cities
bool draw_cities
Definition options.h:202
client_options::draw_map_grid
bool draw_map_grid
Definition options.h:187
client_options::draw_city_growth
bool draw_city_growth
Definition options.h:189
client_options::draw_huts
bool draw_huts
Definition options.h:200
client_options::draw_focus_unit
bool draw_focus_unit
Definition options.h:204
client_options::draw_city_outlines
bool draw_city_outlines
Definition options.h:185
client_options::draw_coastline
bool draw_coastline
Definition options.h:194
client_options::popup_actor_arrival
bool popup_actor_arrival
Definition options.h:161
client_options::draw_full_citybar
bool draw_full_citybar
Definition options.h:208
client_options::draw_roads_rails
bool draw_roads_rails
Definition options.h:195
client_options::draw_pollution
bool draw_pollution
Definition options.h:201
client_options::auto_center_on_unit
bool auto_center_on_unit
Definition options.h:148
client_options::solid_color_behind_units
bool solid_color_behind_units
Definition options.h:142
client_options::popup_last_move_to_allied
bool popup_last_move_to_allied
Definition options.h:163
client_options::keyboardless_goto
bool keyboardless_goto
Definition options.h:165
connection::playing
struct player * playing
Definition connection.h:156
connection::client
struct connection::@57::@62 client
connection::last_request_id_used
int last_request_id_used
Definition connection.h:192
connection::id
int id
Definition connection.h:142
extra_type
Definition extras.h:85
extra_type::reqs
struct requirement_vector reqs
Definition extras.h:102
option
Definition options.c:454
packet_game_info::is_edit_mode
bool is_edit_mode
Definition packets_gen.h:185
packet_game_info::pillage_select
bool pillage_select
Definition packets_gen.h:208
packet_game_info::phase
int phase
Definition packets_gen.h:206
packet_unit_orders
Definition packets_gen.h:722
packet_unit_orders::src_tile
int src_tile
Definition packets_gen.h:725
packet_unit_orders::length
int length
Definition packets_gen.h:726
packet_unit_orders::unit_id16
int unit_id16
Definition packets_gen.h:723
packet_unit_orders::dest_tile
int dest_tile
Definition packets_gen.h:730
packet_unit_orders::repeat
bool repeat
Definition packets_gen.h:727
packet_unit_orders::vigilant
bool vigilant
Definition packets_gen.h:728
packet_unit_orders::unit_id32
int unit_id32
Definition packets_gen.h:724
packet_unit_orders::orders
struct unit_order orders[MAX_LEN_ROUTE]
Definition packets_gen.h:729
pf_path
Definition path_finding.h:344
pf_position::turn
int turn
Definition path_finding.h:329
player
Definition player.h:249
player::units
struct unit_list * units
Definition player.h:282
player::is_alive
bool is_alive
Definition player.h:268
player::phase_done
bool phase_done
Definition player.h:263
req_context
Definition requirements.h:99
req_context::unit
const struct unit * unit
Definition requirements.h:105
road_type
Definition road.h:75
terrain
Definition terrain.h:176
tile
Definition tile.h:49
tile::index
int index
Definition tile.h:50
tile::units
struct unit_list * units
Definition tile.h:57
tileset
Definition tilespec.c:459
timer
Definition timing.c:81
unit_order
Definition unit.h:92
unit_order::activity
enum unit_activity activity
Definition unit.h:94
unit_order::order
enum unit_orders order
Definition unit.h:93
unit_order::action
int action
Definition unit.h:100
unit_order::dir
enum direction8 dir
Definition unit.h:102
unit_order::target
int target
Definition unit.h:97
unit_order::sub_target
int sub_target
Definition unit.h:98
unit_type::hp
int hp
Definition unittype.h:505
unit
Definition unit.h:138
unit::action_decision_want
enum action_decision action_decision_want
Definition unit.h:202
unit::battlegroup
int battlegroup
Definition unit.h:191
unit::activity
enum unit_activity activity
Definition unit.h:157
unit::moves_left
int moves_left
Definition unit.h:150
unit::id
int id
Definition unit.h:145
unit::hp
int hp
Definition unit.h:151
unit::client
struct unit::@80::@82 client
unit::asking_city_name
bool asking_city_name
Definition unit.h:222
unit::done_moving
bool done_moving
Definition unit.h:181
unit::action_decision_tile
struct tile * action_decision_tile
Definition unit.h:203
unit::focus_status
enum unit_focus_status focus_status
Definition unit.h:211
unit::ssa_controller
enum server_side_agent ssa_controller
Definition unit.h:172
universal
Definition fc_types.h:756
universal::kind
enum universals_n kind
Definition fc_types.h:758
world::map
struct civ_map map
Definition world_object.h:38
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc__fallthrough
#define fc__fallthrough
Definition support.h:109
get_preferred_pillage
struct extra_type * get_preferred_pillage(bv_extras extras)
Definition terrain.c:538
terrain_extra_build_time
int terrain_extra_build_time(const struct terrain *pterrain, enum unit_activity activity, const struct extra_type *tgt)
Definition terrain.c:682
T_UNKNOWN
#define T_UNKNOWN
Definition terrain.h:57
tile_add_extra
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:940
tile_virtual_destroy
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1018
tile_has_road
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:829
tile_virtual_new
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:966
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_index
#define tile_index(_pt_)
Definition tile.h:87
tile_hash_iterate
#define tile_hash_iterate(hash, ptile)
Definition tile.h:81
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:109
tile_hash_iterate_end
#define tile_hash_iterate_end
Definition tile.h:83
tile_continent
#define tile_continent(_tile)
Definition tile.h:91
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
get_focus_unit_toggle_timeout
double get_focus_unit_toggle_timeout(const struct tileset *t)
Definition tilespec.c:6261
toggle_focus_unit_state
void toggle_focus_unit_state(struct tileset *t)
Definition tilespec.c:6293
focus_unit_in_combat
void focus_unit_in_combat(struct tileset *t)
Definition tilespec.c:6282
tilespec.h
cursor_type
cursor_type
Definition tilespec.h:285
CURSOR_GOTO
@ CURSOR_GOTO
Definition tilespec.h:286
CURSOR_INVALID
@ CURSOR_INVALID
Definition tilespec.h:291
CURSOR_PATROL
@ CURSOR_PATROL
Definition tilespec.h:287
CURSOR_WAIT
@ CURSOR_WAIT
Definition tilespec.h:295
CURSOR_SELECT
@ CURSOR_SELECT
Definition tilespec.h:290
CURSOR_DEFAULT
@ CURSOR_DEFAULT
Definition tilespec.h:297
CURSOR_PARADROP
@ CURSOR_PARADROP
Definition tilespec.h:288
CURSOR_NUKE
@ CURSOR_NUKE
Definition tilespec.h:289
CURSOR_ATTACK
@ CURSOR_ATTACK
Definition tilespec.h:292
timer_start
void timer_start(struct timer *t)
Definition timing.c:224
timer_read_seconds
double timer_read_seconds(struct timer *t)
Definition timing.c:344
timer_renew
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use)
Definition timing.c:176
timing.h
TIMER_ACTIVE
@ TIMER_ACTIVE
Definition timing.h:45
TIMER_USER
@ TIMER_USER
Definition timing.h:41
get_transporter_occupancy
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1769
is_attack_unit
bool is_attack_unit(const struct unit *punit)
Definition unit.c:310
unit_transport_get
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2427
is_military_unit
bool is_military_unit(const struct unit *punit)
Definition unit.c:322
could_unit_load
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:719
can_unit_do_autosettlers
bool can_unit_do_autosettlers(const struct unit *punit)
Definition unit.c:583
unit_can_do_action
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:331
get_transporter_capacity
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:302
can_unit_paradrop
bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:827
unit_tile_set
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1282
unit_transported
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2411
can_unit_unload
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:771
unit_has_orders
bool unit_has_orders(const struct unit *punit)
Definition unit.c:207
transporter_for_unit
struct unit * transporter_for_unit(const struct unit *pcargo)
Definition unit.c:1898
unit_tile
#define unit_tile(_pu)
Definition unit.h:388
unit_focus_status
unit_focus_status
Definition unit.h:52
FOCUS_AVAIL
@ FOCUS_AVAIL
Definition unit.h:53
FOCUS_DONE
@ FOCUS_DONE
Definition unit.h:53
FOCUS_WAIT
@ FOCUS_WAIT
Definition unit.h:53
BATTLEGROUP_NONE
#define BATTLEGROUP_NONE
Definition unit.h:190
unit_orders
unit_orders
Definition unit.h:37
ORDER_ACTION_MOVE
@ ORDER_ACTION_MOVE
Definition unit.h:45
ORDER_ACTIVITY
@ ORDER_ACTIVITY
Definition unit.h:41
ORDER_MOVE
@ ORDER_MOVE
Definition unit.h:39
ORDER_LAST
@ ORDER_LAST
Definition unit.h:49
ORDER_PERFORM_ACTION
@ ORDER_PERFORM_ACTION
Definition unit.h:47
unit_owner
#define unit_owner(_pu)
Definition unit.h:387
MAX_NUM_BATTLEGROUPS
#define MAX_NUM_BATTLEGROUPS
Definition unit.h:189
is_non_allied_unit_tile
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:423
unitlist.h
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_safe
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
unit_list_both_iterate_end
#define unit_list_both_iterate_end
Definition unitlist.h:37
unit_list_both_iterate
#define unit_list_both_iterate(unitlist, plink, punit)
Definition unitlist.h:34
unit_list_iterate_safe_end
#define unit_list_iterate_safe_end
Definition unitlist.h:61
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
unit_name_translation
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1621
utype_move_type
enum unit_move_type utype_move_type(const struct unit_type *punittype)
Definition unittype.c:1603
utype_may_act_at_all
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:431
unit_class_get
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2546
unit_has_type_flag
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
role_units_translations
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1720
update_queue_connect_processing_finished_full
void update_queue_connect_processing_finished_full(int request_id, uq_callback_t callback, void *data, uq_free_fn_t free_data_func)
Definition update_queue.c:462
update_queue.h